Merge branch '5.2' into 5.3
authorMatthias Schmidt <gravatronics@live.com>
Mon, 10 May 2021 10:19:35 +0000 (12:19 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Mon, 10 May 2021 10:19:35 +0000 (12:19 +0200)
1145 files changed:
.git-blame-ignore-revs [new file with mode: 0644]
README.md
XSD/style.xsd [new file with mode: 0644]
XSD/types.xsd
com.woltlab.wcf/acpMenu.xml
com.woltlab.wcf/clipboardAction.xml
com.woltlab.wcf/defaultStyle.tar
com.woltlab.wcf/files_pre.tar
com.woltlab.wcf/files_preUpdate.tar [deleted file]
com.woltlab.wcf/files_routingCacheBuilder.tar [deleted file]
com.woltlab.wcf/mediaProvider.xml
com.woltlab.wcf/objectType.xml
com.woltlab.wcf/objectTypeDefinition.xml
com.woltlab.wcf/option.xml
com.woltlab.wcf/package.xml
com.woltlab.wcf/page.xml
com.woltlab.wcf/templates/__aclFormField.tpl
com.woltlab.wcf/templates/__audioAttachmentBBCode.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/__checkboxFormField.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/__commentJavaScript.tpl
com.woltlab.wcf/templates/__form.tpl
com.woltlab.wcf/templates/__formContainer.tpl
com.woltlab.wcf/templates/__formField.tpl
com.woltlab.wcf/templates/__labelFormField.tpl
com.woltlab.wcf/templates/__labelSelection.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/__menu.tpl
com.woltlab.wcf/templates/__messageFormPoll.tpl
com.woltlab.wcf/templates/__messageFormPollInline.tpl
com.woltlab.wcf/templates/__messageQuoteManager.tpl
com.woltlab.wcf/templates/__multipleSelectionFormField.tpl
com.woltlab.wcf/templates/__pollOptionsFormField.tpl
com.woltlab.wcf/templates/__singleMediaSelectionFormField.tpl
com.woltlab.wcf/templates/__singleSelectionFormField.tpl
com.woltlab.wcf/templates/__videoAttachmentBBCode.tpl
com.woltlab.wcf/templates/__wysiwygAttachmentFormField.tpl
com.woltlab.wcf/templates/__wysiwygCmsToolbar.tpl
com.woltlab.wcf/templates/__wysiwygPreviewFormButton.tpl
com.woltlab.wcf/templates/accountManagement.tpl
com.woltlab.wcf/templates/aclPermissions.tpl
com.woltlab.wcf/templates/ampArticle.tpl
com.woltlab.wcf/templates/ampFooter.tpl
com.woltlab.wcf/templates/ampHeader.tpl
com.woltlab.wcf/templates/article.tpl
com.woltlab.wcf/templates/articleAdd.tpl
com.woltlab.wcf/templates/articleAddDialog.tpl
com.woltlab.wcf/templates/articleList.tpl
com.woltlab.wcf/templates/articleListItems.tpl
com.woltlab.wcf/templates/attachments.tpl
com.woltlab.wcf/templates/authorSidebarBox.tpl
com.woltlab.wcf/templates/avatarEdit.tpl
com.woltlab.wcf/templates/birthdaySearchableOptionType.tpl
com.woltlab.wcf/templates/boxFollowingsOnline.tpl
com.woltlab.wcf/templates/boxRecentActivity.tpl
com.woltlab.wcf/templates/boxRecentActivitySidebar.tpl
com.woltlab.wcf/templates/boxSidebarCommentList.tpl
com.woltlab.wcf/templates/boxSignedInAs.tpl
com.woltlab.wcf/templates/boxStaffOnline.tpl
com.woltlab.wcf/templates/boxStatistics.tpl
com.woltlab.wcf/templates/boxTodaysBirthdays.tpl
com.woltlab.wcf/templates/boxTodaysFollowingBirthdays.tpl
com.woltlab.wcf/templates/boxUserList.tpl
com.woltlab.wcf/templates/boxUserTrophyList.tpl
com.woltlab.wcf/templates/boxUsersOnline.tpl
com.woltlab.wcf/templates/boxUsersOnlineSidebar.tpl
com.woltlab.wcf/templates/boxWhoWasOnline.tpl
com.woltlab.wcf/templates/categoryArticleList.tpl
com.woltlab.wcf/templates/categoryTrophyList.tpl
com.woltlab.wcf/templates/cms.tpl
com.woltlab.wcf/templates/codeMetaCode.tpl
com.woltlab.wcf/templates/commentEditor.tpl
com.woltlab.wcf/templates/commentList.tpl
com.woltlab.wcf/templates/commentListAddComment.tpl
com.woltlab.wcf/templates/commentResponseEditor.tpl
com.woltlab.wcf/templates/commentResponseList.tpl
com.woltlab.wcf/templates/email_html.tpl
com.woltlab.wcf/templates/email_notification.tpl
com.woltlab.wcf/templates/email_registerNeedActivation.tpl
com.woltlab.wcf/templates/following.tpl
com.woltlab.wcf/templates/fontAwesomeJavaScript.tpl
com.woltlab.wcf/templates/formNotice.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/formSuccess.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/googleMapsJavaScript.tpl
com.woltlab.wcf/templates/groupedUserList.tpl
com.woltlab.wcf/templates/groupedUserReactionList.tpl
com.woltlab.wcf/templates/headInclude.tpl
com.woltlab.wcf/templates/headIncludeJavaScript.tpl
com.woltlab.wcf/templates/headIncludeRobotsMetaTag.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/ignoredUsers.tpl
com.woltlab.wcf/templates/imageViewer.tpl
com.woltlab.wcf/templates/mail.tpl [deleted file]
com.woltlab.wcf/templates/mediaBBCodeTag.tpl
com.woltlab.wcf/templates/mediaEditor.tpl
com.woltlab.wcf/templates/mediaJavaScript.tpl
com.woltlab.wcf/templates/membersList.tpl
com.woltlab.wcf/templates/messageFormAttachments.tpl
com.woltlab.wcf/templates/messageFormPreviewButton.tpl
com.woltlab.wcf/templates/messageFormTabs.tpl
com.woltlab.wcf/templates/messageFormTabsInline.tpl
com.woltlab.wcf/templates/messageQuoteList.tpl
com.woltlab.wcf/templates/messageSidebar.tpl
com.woltlab.wcf/templates/messageUserConsent.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/moderationActivation.tpl
com.woltlab.wcf/templates/moderationArticle.tpl
com.woltlab.wcf/templates/moderationComment.tpl
com.woltlab.wcf/templates/moderationList.tpl
com.woltlab.wcf/templates/moderationQueueList.tpl
com.woltlab.wcf/templates/moderationReport.tpl
com.woltlab.wcf/templates/multipleLanguageInputJavascript.tpl
com.woltlab.wcf/templates/newPassword.tpl
com.woltlab.wcf/templates/notificationList.tpl
com.woltlab.wcf/templates/notificationSettings.tpl
com.woltlab.wcf/templates/notificationUnsubscribe.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/pageFooter.tpl
com.woltlab.wcf/templates/pageHeaderUser.tpl
com.woltlab.wcf/templates/pageMenuMobile.tpl
com.woltlab.wcf/templates/passwordStrengthLanguage.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/poll.tpl
com.woltlab.wcf/templates/pollResult.tpl
com.woltlab.wcf/templates/pollVote.tpl
com.woltlab.wcf/templates/quoteMetaCode.tpl
com.woltlab.wcf/templates/recentActivities.tpl
com.woltlab.wcf/templates/recentActivityList.tpl
com.woltlab.wcf/templates/recentActivityListItem.tpl
com.woltlab.wcf/templates/register.tpl
com.woltlab.wcf/templates/registerActivation.tpl
com.woltlab.wcf/templates/scrollablePageCheckboxList.tpl
com.woltlab.wcf/templates/searchResultList.tpl
com.woltlab.wcf/templates/settings.tpl
com.woltlab.wcf/templates/signatureEdit.tpl
com.woltlab.wcf/templates/spoilerMetaCode.tpl
com.woltlab.wcf/templates/tagInput.tpl
com.woltlab.wcf/templates/tagged.tpl
com.woltlab.wcf/templates/team.tpl
com.woltlab.wcf/templates/trophy.tpl
com.woltlab.wcf/templates/trophyList.tpl
com.woltlab.wcf/templates/unreadArticleList.tpl
com.woltlab.wcf/templates/uploadFieldComponent.tpl
com.woltlab.wcf/templates/user.tpl
com.woltlab.wcf/templates/userBirthdayList.tpl
com.woltlab.wcf/templates/userException.tpl
com.woltlab.wcf/templates/userInformationButtons.tpl
com.woltlab.wcf/templates/userInformationHeadline.tpl
com.woltlab.wcf/templates/userInformationStatistics.tpl
com.woltlab.wcf/templates/userListItem.tpl
com.woltlab.wcf/templates/userMenuSidebar.tpl
com.woltlab.wcf/templates/userNotice.tpl
com.woltlab.wcf/templates/userProfileLikeItem.tpl
com.woltlab.wcf/templates/userProfileLikes.tpl
com.woltlab.wcf/templates/userProfilePreview.tpl
com.woltlab.wcf/templates/userSidebar.tpl
com.woltlab.wcf/templates/usersOnlineInfoBox.tpl
com.woltlab.wcf/templates/usersOnlineList.tpl
com.woltlab.wcf/templates/watchedArticleList.tpl
com.woltlab.wcf/templates/wysiwyg.tpl
com.woltlab.wcf/templates/wysiwygToolbar.tpl
com.woltlab.wcf/update_5.2.sql [deleted file]
com.woltlab.wcf/update_5.3.sql [new file with mode: 0644]
com.woltlab.wcf/userGroupOption.xml
com.woltlab.wcf/userMenu.xml
com.woltlab.wcf/userNotificationEvent.xml
com.woltlab.wcf/userOption.xml
constants.php
defaultStyle/images/stylePreview.png [new file with mode: 0644]
defaultStyle/images/stylePreview@2x.png [new file with mode: 0644]
defaultStyle/style.xml
defaultStyle/stylePreview.png [new file with mode: 0644]
defaultStyle/stylePreview@2x.png [new file with mode: 0644]
defaultStyle/variables.xml
extra/_buildCore.js
extra/_buildExternal.js
extra/compiler.js
extra/examples/wsc-dev-config-52.json [deleted file]
extra/examples/wsc-dev-config-53.json [new file with mode: 0644]
extra/package-lock.json
extra/package.json
spiderList/spiderList.xml
syncTemplates.json
wcfsetup/install.php
wcfsetup/install/files/acp/images/woltlabLogo-tiny.png [new file with mode: 0644]
wcfsetup/install/files/acp/js/WCF.ACP.Style.js
wcfsetup/install/files/acp/js/WCF.ACP.Style.min.js
wcfsetup/install/files/acp/js/WCF.ACP.js
wcfsetup/install/files/acp/js/WCF.ACP.min.js
wcfsetup/install/files/acp/style/acpStyleEditor.css
wcfsetup/install/files/acp/style/layout.scss
wcfsetup/install/files/acp/templates/__aclFormField.tpl
wcfsetup/install/files/acp/templates/__boxAddContent.tpl
wcfsetup/install/files/acp/templates/__boxPipGui.tpl
wcfsetup/install/files/acp/templates/__checkboxFormField.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/__devtoolsMissingLanguageItemStackTrace.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/__devtoolsProjectExcludedPackagesFormField.tpl
wcfsetup/install/files/acp/templates/__devtoolsProjectInstallationJavaScript.tpl
wcfsetup/install/files/acp/templates/__devtoolsProjectInstructionsFormField.tpl
wcfsetup/install/files/acp/templates/__devtoolsProjectOptionalPackagesFormField.tpl
wcfsetup/install/files/acp/templates/__devtoolsProjectRequiredPackagesFormField.tpl
wcfsetup/install/files/acp/templates/__form.tpl
wcfsetup/install/files/acp/templates/__formContainer.tpl
wcfsetup/install/files/acp/templates/__formField.tpl
wcfsetup/install/files/acp/templates/__labelFormField.tpl
wcfsetup/install/files/acp/templates/__menuPipGui.tpl
wcfsetup/install/files/acp/templates/__messageQuoteManager.tpl
wcfsetup/install/files/acp/templates/__multipleSelectionFormField.tpl
wcfsetup/install/files/acp/templates/__objectTypePipGui.tpl
wcfsetup/install/files/acp/templates/__optionEmailSmtpTest.tpl
wcfsetup/install/files/acp/templates/__optionRewriteRules.tpl
wcfsetup/install/files/acp/templates/__optionRewriteTest.tpl
wcfsetup/install/files/acp/templates/__pageAddContent.tpl
wcfsetup/install/files/acp/templates/__pollOptionsFormField.tpl
wcfsetup/install/files/acp/templates/__singleMediaSelectionFormField.tpl
wcfsetup/install/files/acp/templates/__singleSelectionFormField.tpl
wcfsetup/install/files/acp/templates/__wysiwygAttachmentFormField.tpl
wcfsetup/install/files/acp/templates/__wysiwygCmsToolbar.tpl
wcfsetup/install/files/acp/templates/__wysiwygPreviewFormButton.tpl
wcfsetup/install/files/acp/templates/aclPermissions.tpl
wcfsetup/install/files/acp/templates/adAdd.tpl
wcfsetup/install/files/acp/templates/articleAdd.tpl
wcfsetup/install/files/acp/templates/articleAddDialog.tpl
wcfsetup/install/files/acp/templates/articleList.tpl
wcfsetup/install/files/acp/templates/attachmentList.tpl
wcfsetup/install/files/acp/templates/bbcodeAdd.tpl
wcfsetup/install/files/acp/templates/bbcodeMediaProviderAdd.tpl
wcfsetup/install/files/acp/templates/birthdaySearchableOptionType.tpl
wcfsetup/install/files/acp/templates/boxAdd.tpl
wcfsetup/install/files/acp/templates/boxAddDialog.tpl
wcfsetup/install/files/acp/templates/cacheList.tpl
wcfsetup/install/files/acp/templates/captchaQuestionAdd.tpl
wcfsetup/install/files/acp/templates/captchaQuestionList.tpl
wcfsetup/install/files/acp/templates/categoryAdd.tpl
wcfsetup/install/files/acp/templates/codeMetaCode.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/codemirror.tpl
wcfsetup/install/files/acp/templates/contactOptionAdd.tpl
wcfsetup/install/files/acp/templates/contactRecipientAdd.tpl
wcfsetup/install/files/acp/templates/cronjobAdd.tpl
wcfsetup/install/files/acp/templates/cronjobList.tpl
wcfsetup/install/files/acp/templates/cronjobLogList.tpl
wcfsetup/install/files/acp/templates/dataImport.tpl
wcfsetup/install/files/acp/templates/devtoolsMissingLanguageItemList.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/devtoolsNotificationTest.tpl
wcfsetup/install/files/acp/templates/devtoolsProjectList.tpl
wcfsetup/install/files/acp/templates/devtoolsProjectPipEntryList.tpl
wcfsetup/install/files/acp/templates/devtoolsProjectSync.tpl
wcfsetup/install/files/acp/templates/exceptionLogView.tpl
wcfsetup/install/files/acp/templates/fontAwesomeJavaScript.tpl
wcfsetup/install/files/acp/templates/formNotice.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/formSuccess.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/header.tpl
wcfsetup/install/files/acp/templates/imageViewer.tpl
wcfsetup/install/files/acp/templates/index.tpl
wcfsetup/install/files/acp/templates/labelAdd.tpl
wcfsetup/install/files/acp/templates/labelGroupAdd.tpl
wcfsetup/install/files/acp/templates/labelGroupList.tpl
wcfsetup/install/files/acp/templates/labelList.tpl
wcfsetup/install/files/acp/templates/languageAdd.tpl
wcfsetup/install/files/acp/templates/languageItemList.tpl
wcfsetup/install/files/acp/templates/mediaBBCodeTag.tpl
wcfsetup/install/files/acp/templates/mediaEditor.tpl
wcfsetup/install/files/acp/templates/mediaJavaScript.tpl
wcfsetup/install/files/acp/templates/mediaList.tpl
wcfsetup/install/files/acp/templates/menuAdd.tpl
wcfsetup/install/files/acp/templates/menuItemAdd.tpl
wcfsetup/install/files/acp/templates/multipleLanguageInputJavascript.tpl
wcfsetup/install/files/acp/templates/noticeAdd.tpl
wcfsetup/install/files/acp/templates/notificationPresetSettings.tpl
wcfsetup/install/files/acp/templates/package.tpl
wcfsetup/install/files/acp/templates/packageInstallationConfirm.tpl
wcfsetup/install/files/acp/templates/packageInstallationSetup.tpl
wcfsetup/install/files/acp/templates/packageList.tpl
wcfsetup/install/files/acp/templates/packageSearchResultList.tpl
wcfsetup/install/files/acp/templates/packageSearchResultListItems.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/packageStartInstall.tpl
wcfsetup/install/files/acp/templates/packageUpdate.tpl
wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl
wcfsetup/install/files/acp/templates/packageUpdateServerList.tpl
wcfsetup/install/files/acp/templates/packageUpdateUnauthorized.tpl
wcfsetup/install/files/acp/templates/packageUpdateUnauthorizedPurchaseRequired.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/pageAdd.tpl
wcfsetup/install/files/acp/templates/pageAddDialog.tpl
wcfsetup/install/files/acp/templates/pageBoxOrder.tpl
wcfsetup/install/files/acp/templates/pageHeaderUser.tpl
wcfsetup/install/files/acp/templates/paidSubscriptionAdd.tpl
wcfsetup/install/files/acp/templates/paidSubscriptionUserAdd.tpl
wcfsetup/install/files/acp/templates/passwordStrengthLanguage.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/pluginStorePurchasedItems.tpl
wcfsetup/install/files/acp/templates/rebuildData.tpl
wcfsetup/install/files/acp/templates/scrollablePageCheckboxList.tpl
wcfsetup/install/files/acp/templates/sendMailUserBulkProcessing.tpl
wcfsetup/install/files/acp/templates/sitemapList.tpl
wcfsetup/install/files/acp/templates/smileyAdd.tpl
wcfsetup/install/files/acp/templates/stat.tpl
wcfsetup/install/files/acp/templates/styleAdd.tpl
wcfsetup/install/files/acp/templates/styleExport.tpl
wcfsetup/install/files/acp/templates/styleGlobalValues.tpl
wcfsetup/install/files/acp/templates/systemCheck.tpl
wcfsetup/install/files/acp/templates/tagAdd.tpl
wcfsetup/install/files/acp/templates/tagInput.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/tagList.tpl
wcfsetup/install/files/acp/templates/templateAdd.tpl
wcfsetup/install/files/acp/templates/templateGroupAdd.tpl
wcfsetup/install/files/acp/templates/templateGroupList.tpl
wcfsetup/install/files/acp/templates/templateList.tpl
wcfsetup/install/files/acp/templates/trophyAdd.tpl
wcfsetup/install/files/acp/templates/trophyList.tpl
wcfsetup/install/files/acp/templates/uploadFieldComponent.tpl
wcfsetup/install/files/acp/templates/userActivityPointOption.tpl
wcfsetup/install/files/acp/templates/userAdd.tpl
wcfsetup/install/files/acp/templates/userGroupAdd.tpl
wcfsetup/install/files/acp/templates/userGroupAssignmentAdd.tpl
wcfsetup/install/files/acp/templates/userGroupAssignmentList.tpl
wcfsetup/install/files/acp/templates/userList.tpl
wcfsetup/install/files/acp/templates/userMail.tpl
wcfsetup/install/files/acp/templates/userOptionAdd.tpl
wcfsetup/install/files/acp/templates/userOptionCategoryAdd.tpl
wcfsetup/install/files/acp/templates/userRankAdd.tpl
wcfsetup/install/files/acp/templates/userRankList.tpl
wcfsetup/install/files/acp/templates/userSearch.tpl
wcfsetup/install/files/acp/templates/userTrophyAdd.tpl
wcfsetup/install/files/acp/templates/wysiwyg.tpl
wcfsetup/install/files/acp/templates/wysiwygToolbar.tpl
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_deleteRecentActivity.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_prePhpApi.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_preUpdate.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_reactionUpdate.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_reloadOptions.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3.3_db.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_emailConfirmation.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_fixActivationMethod.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_invalidateMailForm.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_orphanedComments.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_packageServer.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_preUpdate.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_sitemaps.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_style.php [new file with mode: 0644]
wcfsetup/install/files/acp/update_com.woltlab.wcf_embeddedObjectOrphans.php [deleted file]
wcfsetup/install/files/acp/update_com.woltlab.wcf_preventMailAbuse.php [deleted file]
wcfsetup/install/files/cli.php
wcfsetup/install/files/font/families/.gitignore [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/LICENSE.txt [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-Bold.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-BoldItalic.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBold.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBoldItalic.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-Italic.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-Light.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-LightItalic.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-Regular.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBold.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBoldItalic.woff2 [new file with mode: 0644]
wcfsetup/install/files/font/families/Open Sans/font.css [new file with mode: 0644]
wcfsetup/install/files/font/getFont.php
wcfsetup/install/files/images/favicon/corsProxy.php
wcfsetup/install/files/images/favicon/default.manifest.json
wcfsetup/install/files/js/3rdParty/pica.js
wcfsetup/install/files/js/3rdParty/prism/README.md
wcfsetup/install/files/js/3rdParty/prism/components.json
wcfsetup/install/files/js/3rdParty/prism/components/prism-actionscript.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-agda.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-al.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-antlr4.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-apl.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-applescript.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-aql.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-asciidoc.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-asm6502.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-aspnet.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-autohotkey.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-bash.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-batch.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-bbcode.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-brightscript.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-c.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-cil.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-clike.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-clojure.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-concurnas.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-cpp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-csharp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-csp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-css-extras.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-css.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-cypher.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-d.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-dart.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-dax.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-dhall.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-diff.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-dns-zone-file.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-docker.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-ebnf.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-editorconfig.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-eiffel.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-ejs.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-elixir.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-elm.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-etlua.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-excel-formula.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-factor.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-firestore-security-rules.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-fsharp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-ftl.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-gdscript.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-gherkin.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-glsl.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-gml.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-go.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-graphql.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-groovy.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-haml.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-handlebars.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-haskell.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-hcl.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-hlsl.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-hpkp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-hsts.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-http.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-iecst.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-ignore.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-io.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-j.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-java.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-javadoc.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-javadoclike.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-javascript.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-jolie.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-jq.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-js-extras.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-js-templates.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-jsdoc.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-json.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-json5.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-jsstacktrace.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-jsx.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-julia.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-kotlin.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-latte.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-less.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-lilypond.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-lisp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-livescript.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-llvm.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-lolcode.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-markdown.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-markup.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-moonscript.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-n4js.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-neon.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-nsis.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-objectivec.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-ocaml.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-opencl.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-oz.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-parigp.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-pascal.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-pascaligo.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-pcaxis.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-peoplecode.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-perl.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-php.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-phpdoc.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-powerquery.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-powershell.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-protobuf.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-pug.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-pure.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-purebasic.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-python.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-q.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-qml.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-qore.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-racket.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-reason.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-regex.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-renpy.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-rest.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-rip.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-robotframework.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-ruby.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-rust.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-sas.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-scala.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-scheme.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-shell-session.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-smali.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-smalltalk.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-solidity.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-solution-file.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-sparql.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-splunk-spl.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-sqf.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-sql.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-stylus.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-swift.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-t4-vb.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-textile.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-toml.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-tt2.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-turtle.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-typescript.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-unrealscript.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-vala.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-velocity.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-visual-basic.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-warpscript.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-wiki.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-xeora.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-xml-doc.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-xquery.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-yaml.js
wcfsetup/install/files/js/3rdParty/prism/components/prism-yang.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/components/prism-zig.js [new file with mode: 0644]
wcfsetup/install/files/js/3rdParty/prism/prism-meta.js
wcfsetup/install/files/js/3rdParty/prism/prism.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabButton.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabCaret.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabPaste.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabSmiley.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabSource.js
wcfsetup/install/files/js/3rdParty/redactor2/redactor.combined.min.js
wcfsetup/install/files/js/3rdParty/redactor2/redactor.js
wcfsetup/install/files/js/3rdParty/zxcvbn.js [new file with mode: 0644]
wcfsetup/install/files/js/WCF.Assets.js
wcfsetup/install/files/js/WCF.Attachment.js
wcfsetup/install/files/js/WCF.Combined.min.js
wcfsetup/install/files/js/WCF.Combined.tiny.min.js
wcfsetup/install/files/js/WCF.ImageViewer.js
wcfsetup/install/files/js/WCF.Label.js
wcfsetup/install/files/js/WCF.Message.js
wcfsetup/install/files/js/WCF.Moderation.js
wcfsetup/install/files/js/WCF.Poll.js
wcfsetup/install/files/js/WCF.User.js
wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/js/WoltLabSuite.Core.min.js
wcfsetup/install/files/js/WoltLabSuite.Core.tiny.min.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Article/InlineEditor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Devtools/Project/Sync.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Delete.js [deleted file]
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Upload.js [deleted file]
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Editor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Favicon/Upload.js [deleted file]
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Image/Upload.js [deleted file]
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/User/Editor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js
wcfsetup/install/files/js/WoltLabSuite/Core/Bbcode/Collapsible.js
wcfsetup/install/files/js/WoltLabSuite/Core/Bootstrap.js
wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js
wcfsetup/install/files/js/WoltLabSuite/Core/Clipboard.js
wcfsetup/install/files/js/WoltLabSuite/Core/Controller/Popover.js
wcfsetup/install/files/js/WoltLabSuite/Core/Controller/User/Notification/Settings.js
wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js
wcfsetup/install/files/js/WoltLabSuite/Core/FileUtil.js
wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Image/ExifUtil.js
wcfsetup/install/files/js/WoltLabSuite/Core/Image/Resizer.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Editor.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Manager/Base.js
wcfsetup/install/files/js/WoltLabSuite/Core/Media/Replace.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Notification/Handler.js
wcfsetup/install/files/js/WoltLabSuite/Core/Template.grammar.jison
wcfsetup/install/files/js/WoltLabSuite/Core/Template.grammar.js
wcfsetup/install/files/js/WoltLabSuite/Core/Template.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Confirmation.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Delete.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/File/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/TwitterEmbed.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/UserConsent.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Mobile.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Action.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/JumpToTop.js [deleted file]
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Abstract.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Reaction/Handler.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Search/Input.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Search/Page.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Tooltip.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/PasswordStrength.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Upload.js
wcfsetup/install/files/js/WoltLabSuite/Core/Wrapper/FacebookSdk.js [new file with mode: 0644]
wcfsetup/install/files/js/require.config.js
wcfsetup/install/files/js/wcf.globalHelper.js
wcfsetup/install/files/lib/acp/action/UserExportGdprAction.class.php
wcfsetup/install/files/lib/acp/action/UserQuickSearchAction.class.php
wcfsetup/install/files/lib/acp/form/AdAddForm.class.php
wcfsetup/install/files/lib/acp/form/ArticleAddForm.class.php
wcfsetup/install/files/lib/acp/form/ArticleCategoryAddForm.class.php
wcfsetup/install/files/lib/acp/form/ArticleEditForm.class.php
wcfsetup/install/files/lib/acp/form/BBCodeAddForm.class.php
wcfsetup/install/files/lib/acp/form/BBCodeMediaProviderAddForm.class.php
wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php
wcfsetup/install/files/lib/acp/form/CaptchaQuestionAddForm.class.php
wcfsetup/install/files/lib/acp/form/ContactOptionAddForm.class.php
wcfsetup/install/files/lib/acp/form/ContactOptionEditForm.class.php
wcfsetup/install/files/lib/acp/form/ContactRecipientAddForm.class.php
wcfsetup/install/files/lib/acp/form/CronjobAddForm.class.php
wcfsetup/install/files/lib/acp/form/DataImportForm.class.php
wcfsetup/install/files/lib/acp/form/FirstTimeSetupForm.class.php
wcfsetup/install/files/lib/acp/form/LabelAddForm.class.php
wcfsetup/install/files/lib/acp/form/LabelGroupAddForm.class.php
wcfsetup/install/files/lib/acp/form/LanguageAddForm.class.php
wcfsetup/install/files/lib/acp/form/MediaCategoryAddForm.class.php
wcfsetup/install/files/lib/acp/form/MenuAddForm.class.php
wcfsetup/install/files/lib/acp/form/MenuItemAddForm.class.php
wcfsetup/install/files/lib/acp/form/NoticeAddForm.class.php
wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php
wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php
wcfsetup/install/files/lib/acp/form/PageAddForm.class.php
wcfsetup/install/files/lib/acp/form/PaidSubscriptionAddForm.class.php
wcfsetup/install/files/lib/acp/form/ReactionTypeAddForm.class.php
wcfsetup/install/files/lib/acp/form/SitemapEditForm.class.php
wcfsetup/install/files/lib/acp/form/SmileyAddForm.class.php
wcfsetup/install/files/lib/acp/form/SmileyCategoryAddForm.class.php
wcfsetup/install/files/lib/acp/form/StyleAddForm.class.php
wcfsetup/install/files/lib/acp/form/StyleEditForm.class.php
wcfsetup/install/files/lib/acp/form/StyleExportForm.class.php
wcfsetup/install/files/lib/acp/form/StyleGlobalValuesForm.class.php
wcfsetup/install/files/lib/acp/form/TagAddForm.class.php
wcfsetup/install/files/lib/acp/form/TemplateAddForm.class.php
wcfsetup/install/files/lib/acp/form/TemplateGroupAddForm.class.php
wcfsetup/install/files/lib/acp/form/TrophyAddForm.class.php
wcfsetup/install/files/lib/acp/form/TrophyCategoryAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserAssignToGroupForm.class.php
wcfsetup/install/files/lib/acp/form/UserEditForm.class.php
wcfsetup/install/files/lib/acp/form/UserGroupAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserGroupAssignmentAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserGroupOptionForm.class.php
wcfsetup/install/files/lib/acp/form/UserGroupPromoteOwnerForm.class.php
wcfsetup/install/files/lib/acp/form/UserMailForm.class.php
wcfsetup/install/files/lib/acp/form/UserOptionAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserOptionCategoryAddForm.class.php
wcfsetup/install/files/lib/acp/form/UserRankAddForm.class.php
wcfsetup/install/files/lib/acp/page/CronjobListPage.class.php
wcfsetup/install/files/lib/acp/page/CronjobLogListPage.class.php
wcfsetup/install/files/lib/acp/page/DevtoolsMissingLanguageItemListPage.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/acp/page/ExceptionLogViewPage.class.php
wcfsetup/install/files/lib/acp/page/IndexPage.class.php
wcfsetup/install/files/lib/acp/page/LabelGroupListPage.class.php
wcfsetup/install/files/lib/acp/page/LabelListPage.class.php
wcfsetup/install/files/lib/acp/page/PackageUpdateServerListPage.class.php
wcfsetup/install/files/lib/acp/page/PluginStorePurchasedItemsPage.class.php
wcfsetup/install/files/lib/acp/page/RebuildDataPage.class.php
wcfsetup/install/files/lib/acp/page/SitemapListPage.class.php
wcfsetup/install/files/lib/acp/page/SystemCheckPage.class.php
wcfsetup/install/files/lib/action/AJAXFileUploadAction.class.php
wcfsetup/install/files/lib/action/ImageProxyAction.class.php
wcfsetup/install/files/lib/action/NotificationDisableAction.class.php
wcfsetup/install/files/lib/action/PollAction.class.php
wcfsetup/install/files/lib/action/TAJAXException.class.php
wcfsetup/install/files/lib/core.functions.php
wcfsetup/install/files/lib/data/AbstractDatabaseObjectAction.class.php
wcfsetup/install/files/lib/data/DatabaseObjectEditor.class.php
wcfsetup/install/files/lib/data/DatabaseObjectList.class.php
wcfsetup/install/files/lib/data/IPopoverAction.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/IPopoverObject.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/article/ArticleAction.class.php
wcfsetup/install/files/lib/data/article/LikeableArticle.class.php
wcfsetup/install/files/lib/data/article/LikeableArticleProvider.class.php
wcfsetup/install/files/lib/data/article/ViewableArticle.class.php
wcfsetup/install/files/lib/data/article/content/ArticleContent.class.php
wcfsetup/install/files/lib/data/attachment/Attachment.class.php
wcfsetup/install/files/lib/data/attachment/AttachmentAction.class.php
wcfsetup/install/files/lib/data/bbcode/media/provider/BBCodeMediaProvider.class.php
wcfsetup/install/files/lib/data/box/content/BoxContent.class.php
wcfsetup/install/files/lib/data/comment/ViewableComment.class.php
wcfsetup/install/files/lib/data/comment/response/ViewableCommentResponse.class.php
wcfsetup/install/files/lib/data/contact/option/ContactOptionAction.class.php
wcfsetup/install/files/lib/data/contact/recipient/ContactRecipient.class.php
wcfsetup/install/files/lib/data/cronjob/I18nCronjobList.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/custom/option/CustomOption.class.php
wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItem.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemAction.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemEditor.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemList.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/event/listener/EventListener.class.php
wcfsetup/install/files/lib/data/label/Label.class.php
wcfsetup/install/files/lib/data/language/Language.class.php
wcfsetup/install/files/lib/data/language/LanguageEditor.class.php
wcfsetup/install/files/lib/data/like/Like.class.php
wcfsetup/install/files/lib/data/media/Media.class.php
wcfsetup/install/files/lib/data/media/MediaAction.class.php
wcfsetup/install/files/lib/data/moderation/queue/ModerationQueueAction.class.php
wcfsetup/install/files/lib/data/moderation/queue/ViewableModerationQueue.class.php
wcfsetup/install/files/lib/data/object/type/SitemapObjectTypeAction.class.php
wcfsetup/install/files/lib/data/package/Package.class.php
wcfsetup/install/files/lib/data/package/installation/plugin/PackageInstallationPluginAction.class.php
wcfsetup/install/files/lib/data/package/update/PackageUpdateAction.class.php
wcfsetup/install/files/lib/data/package/update/server/PackageUpdateServer.class.php
wcfsetup/install/files/lib/data/package/update/server/PackageUpdateServerAction.class.php
wcfsetup/install/files/lib/data/page/Page.class.php
wcfsetup/install/files/lib/data/page/content/PageContent.class.php
wcfsetup/install/files/lib/data/style/Style.class.php
wcfsetup/install/files/lib/data/style/StyleAction.class.php
wcfsetup/install/files/lib/data/style/StyleEditor.class.php
wcfsetup/install/files/lib/data/trophy/Trophy.class.php
wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php
wcfsetup/install/files/lib/data/user/User.class.php
wcfsetup/install/files/lib/data/user/UserAction.class.php
wcfsetup/install/files/lib/data/user/UserBirthdayAction.class.php
wcfsetup/install/files/lib/data/user/UserProfile.class.php
wcfsetup/install/files/lib/data/user/UserProfileAction.class.php
wcfsetup/install/files/lib/data/user/UserRegistrationAction.class.php
wcfsetup/install/files/lib/data/user/avatar/UserAvatarAction.class.php
wcfsetup/install/files/lib/data/user/follow/UserFollowAction.class.php
wcfsetup/install/files/lib/data/user/group/UserGroup.class.php
wcfsetup/install/files/lib/data/user/group/UserGroupAction.class.php
wcfsetup/install/files/lib/data/user/group/option/UserGroupOptionAction.class.php
wcfsetup/install/files/lib/data/user/ignore/UserIgnoreAction.class.php
wcfsetup/install/files/lib/data/user/menu/item/UserMenuItem.class.php
wcfsetup/install/files/lib/data/user/notification/UserNotificationAction.class.php
wcfsetup/install/files/lib/data/user/notification/event/UserNotificationEvent.class.php
wcfsetup/install/files/lib/data/user/notification/event/UserNotificationEventAction.class.php
wcfsetup/install/files/lib/data/user/object/watch/UserObjectWatchAction.class.php
wcfsetup/install/files/lib/data/user/online/UserOnline.class.php
wcfsetup/install/files/lib/data/user/online/UsersOnlineList.class.php
wcfsetup/install/files/lib/data/user/profile/menu/item/UserProfileMenuItem.class.php
wcfsetup/install/files/lib/form/AbstractFormBuilderForm.class.php
wcfsetup/install/files/lib/form/AccountManagementForm.class.php
wcfsetup/install/files/lib/form/ArticleAddForm.class.php
wcfsetup/install/files/lib/form/EmailActivationForm.class.php
wcfsetup/install/files/lib/form/MailForm.class.php [deleted file]
wcfsetup/install/files/lib/form/MessageForm.class.php
wcfsetup/install/files/lib/form/NewPasswordForm.class.php
wcfsetup/install/files/lib/form/NotificationUnsubscribeForm.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/form/RegisterActivationForm.class.php
wcfsetup/install/files/lib/form/RegisterForm.class.php
wcfsetup/install/files/lib/form/RegisterNewActivationCodeForm.class.php
wcfsetup/install/files/lib/form/SettingsForm.class.php
wcfsetup/install/files/lib/form/UserSearchForm.class.php
wcfsetup/install/files/lib/page/AbstractArticlePage.class.php
wcfsetup/install/files/lib/page/AbstractAuthedPage.class.php
wcfsetup/install/files/lib/page/ArticleAmpPage.class.php
wcfsetup/install/files/lib/page/ArticlePage.class.php
wcfsetup/install/files/lib/page/CategoryTrophyListPage.class.php
wcfsetup/install/files/lib/page/MediaPage.class.php
wcfsetup/install/files/lib/page/ModerationListPage.class.php
wcfsetup/install/files/lib/page/PaidSubscriptionListPage.class.php
wcfsetup/install/files/lib/page/TrophyListPage.class.php
wcfsetup/install/files/lib/page/UserPage.class.php
wcfsetup/install/files/lib/system/CLIWCF.class.php
wcfsetup/install/files/lib/system/WCF.class.php
wcfsetup/install/files/lib/system/WCFSetup.class.php
wcfsetup/install/files/lib/system/api/autoload.php
wcfsetup/install/files/lib/system/api/bin/pscss
wcfsetup/install/files/lib/system/api/bin/pscss.bat [deleted file]
wcfsetup/install/files/lib/system/api/chrisjean/php-ico/license.txt
wcfsetup/install/files/lib/system/api/composer.json
wcfsetup/install/files/lib/system/api/composer.lock
wcfsetup/install/files/lib/system/api/composer/ClassLoader.php
wcfsetup/install/files/lib/system/api/composer/InstalledVersions.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/composer/autoload_classmap.php
wcfsetup/install/files/lib/system/api/composer/autoload_files.php
wcfsetup/install/files/lib/system/api/composer/autoload_namespaces.php
wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php
wcfsetup/install/files/lib/system/api/composer/autoload_real.php
wcfsetup/install/files/lib/system/api/composer/autoload_static.php
wcfsetup/install/files/lib/system/api/composer/installed.json
wcfsetup/install/files/lib/system/api/composer/installed.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/composer/platform_check.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/erusev/parsedown/Parsedown.php
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/.php_cs [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/CHANGELOG.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/Dockerfile [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/UPGRADING.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Client.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/ClientInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/CookieJar.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/SetCookie.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/BadResponseException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ClientException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ConnectException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/GuzzleException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/RequestException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/SeekException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ServerException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/TransferException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlFactory.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlHandler.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/EasyHandle.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/MockHandler.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/Proxy.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/StreamHandler.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/HandlerStack.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/MessageFormatter.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Middleware.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Pool.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RedirectMiddleware.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RequestOptions.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RetryMiddleware.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/TransferStats.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/UriTemplate.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Utils.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/functions.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/functions_include.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/CHANGELOG.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/Makefile [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/AggregateException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/CancellationException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/Coroutine.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/EachPromise.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/FulfilledPromise.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/Promise.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/PromiseInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/PromisorInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/RejectedPromise.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/RejectionException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/TaskQueue.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/TaskQueueInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/functions.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/functions_include.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/CHANGELOG.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/AppendStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/BufferStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/CachingStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/DroppingStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/FnStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/InflateStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/LazyOpenStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/LimitStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MessageTrait.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MultipartStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/NoSeekStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/PumpStream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Request.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Response.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Rfc7230.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/ServerRequest.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Stream.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/StreamDecoratorTrait.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/StreamWrapper.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UploadedFile.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Uri.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UriNormalizer.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UriResolver.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/functions.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/functions_include.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/leafo/scssphp/LICENSE.md [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/README.md [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/bin/pscss [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/composer.json [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/example/Server.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/scss.inc.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Base/Range.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Block.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Colors.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Compiler.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Compiler/Environment.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/CompilerException.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/ParserException.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/RangeException.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/ServerException.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Compact.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Compressed.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Crunched.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Debug.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Expanded.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Nested.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/OutputBlock.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Node.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Node/Number.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Parser.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64VLQ.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64VLQEncoder.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/SourceMapGenerator.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Type.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Util.php [deleted file]
wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Version.php [deleted file]
wcfsetup/install/files/lib/system/api/pear/pear_exception/composer.json
wcfsetup/install/files/lib/system/api/psr/http-message/CHANGELOG.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/MessageInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/RequestInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/ResponseInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/ServerRequestInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/StreamInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/UploadedFileInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/psr/http-message/src/UriInterface.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/src/getallheaders.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/LICENSE.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/phpcs.xml.dist [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/scss.inc.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Base/Range.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Block.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Cache.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Colors.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler/Environment.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/CompilerException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/ParserException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/RangeException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/SassException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/SassScriptException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/ServerException.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Compact.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Compressed.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Crunched.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Debug.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Expanded.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Nested.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/OutputBlock.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/Base64.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/Base64VLQ.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Type.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Util.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/css-selector/LICENSE
wcfsetup/install/files/lib/system/api/symfony/css-selector/Node/AbstractNode.php
wcfsetup/install/files/lib/system/api/symfony/css-selector/Parser/Handler/StringHandler.php
wcfsetup/install/files/lib/system/api/symfony/css-selector/XPath/Extension/FunctionExtension.php
wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/Idn.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/bootstrap.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-mbstring/Mbstring.php
wcfsetup/install/files/lib/system/api/symfony/polyfill-mbstring/README.md
wcfsetup/install/files/lib/system/api/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
wcfsetup/install/files/lib/system/api/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
wcfsetup/install/files/lib/system/api/symfony/polyfill-mbstring/bootstrap.php
wcfsetup/install/files/lib/system/api/symfony/polyfill-mbstring/composer.json
wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/LICENSE [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/Php72.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/README.md [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/bootstrap.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/composer.json [new file with mode: 0644]
wcfsetup/install/files/lib/system/application/ApplicationHandler.class.php
wcfsetup/install/files/lib/system/background/job/DownloadStyleLogoJob.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/background/job/NotificationEmailDeliveryBackgroundJob.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/bbcode/AttachmentBBCode.class.php
wcfsetup/install/files/lib/system/bbcode/MediaBBCode.class.php
wcfsetup/install/files/lib/system/bbcode/SimpleMessageParser.class.php
wcfsetup/install/files/lib/system/bbcode/WoltLabSuiteMediaBBCode.class.php
wcfsetup/install/files/lib/system/box/TagCloudBoxController.class.php
wcfsetup/install/files/lib/system/box/TodaysBirthdaysBoxController.class.php
wcfsetup/install/files/lib/system/box/TodaysFollowingBirthdaysBoxController.class.php
wcfsetup/install/files/lib/system/box/UserListBoxController.class.php
wcfsetup/install/files/lib/system/box/UserOnlineListBoxController.class.php
wcfsetup/install/files/lib/system/box/WhoWasOnlineBoxController.class.php
wcfsetup/install/files/lib/system/bulk/processing/user/AbstractUserGroupsUserBulkProcessingAction.class.php
wcfsetup/install/files/lib/system/cache/builder/AbstractSortedUserCacheBuilder.class.php
wcfsetup/install/files/lib/system/cache/builder/EventListenerCacheBuilder.class.php
wcfsetup/install/files/lib/system/cache/builder/UserStatsCacheBuilder.class.php
wcfsetup/install/files/lib/system/cli/command/ImportCLICommand.class.php
wcfsetup/install/files/lib/system/cli/command/PackageCLICommand.class.php
wcfsetup/install/files/lib/system/cli/command/WorkerCLICommand.class.php
wcfsetup/install/files/lib/system/clipboard/action/UserClipboardAction.class.php
wcfsetup/install/files/lib/system/comment/manager/AbstractCommentManager.class.php
wcfsetup/install/files/lib/system/comment/manager/ArticleCommentManager.class.php
wcfsetup/install/files/lib/system/comment/manager/ICommentManager.class.php
wcfsetup/install/files/lib/system/comment/manager/PageCommentManager.class.php
wcfsetup/install/files/lib/system/comment/manager/UserProfileCommentManager.class.php
wcfsetup/install/files/lib/system/condition/UserCoverPhotoCondition.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/condition/UserGroupCondition.class.php
wcfsetup/install/files/lib/system/condition/UserSignatureCondition.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/condition/UserStateCondition.class.php
wcfsetup/install/files/lib/system/condition/UserUserIDCondition.class.php
wcfsetup/install/files/lib/system/condition/user/UserLastActivityTimeIntervalDaysCondition.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/cronjob/DailyCleanUpCronjob.class.php
wcfsetup/install/files/lib/system/cronjob/DailyMailNotificationCronjob.class.php
wcfsetup/install/files/lib/system/cronjob/GetUpdateInfoCronjob.class.php
wcfsetup/install/files/lib/system/database/editor/MySQLDatabaseEditor.class.php
wcfsetup/install/files/lib/system/database/exception/DatabaseQueryExecutionException.class.php
wcfsetup/install/files/lib/system/database/statement/DebugPreparedStatement.class.php
wcfsetup/install/files/lib/system/database/statement/PreparedStatement.class.php
wcfsetup/install/files/lib/system/database/table/DatabaseTableChangeProcessor.class.php
wcfsetup/install/files/lib/system/devtools/DevtoolsSetup.class.php
wcfsetup/install/files/lib/system/email/Email.class.php
wcfsetup/install/files/lib/system/email/EmailGrammar.class.php
wcfsetup/install/files/lib/system/email/transport/SmtpEmailTransport.class.php
wcfsetup/install/files/lib/system/event/IEventListener.class.php
wcfsetup/install/files/lib/system/event/listener/AbstractEventListener.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/event/listener/IParameterizedEventListener.class.php
wcfsetup/install/files/lib/system/exception/HTTPNotFoundException.class.php
wcfsetup/install/files/lib/system/exception/HTTPServerErrorException.class.php
wcfsetup/install/files/lib/system/exception/HTTPUnauthorizedException.class.php
wcfsetup/install/files/lib/system/file/upload/UploadField.class.php
wcfsetup/install/files/lib/system/file/upload/UploadHandler.class.php
wcfsetup/install/files/lib/system/form/builder/FormDocument.class.php
wcfsetup/install/files/lib/system/form/builder/IFormDocument.class.php
wcfsetup/install/files/lib/system/form/builder/container/FormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/container/IFormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/container/SuffixFormFieldContainer.class.php
wcfsetup/install/files/lib/system/form/builder/container/wysiwyg/WysiwygFormContainer.class.php
wcfsetup/install/files/lib/system/form/builder/field/CheckboxFormField.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/form/builder/field/UploadFormField.class.php
wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeImg.class.php
wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeSmall.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeTextParser.class.php
wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMetacodeMarker.class.php
wcfsetup/install/files/lib/system/html/node/AbstractHtmlNodeProcessor.class.php
wcfsetup/install/files/lib/system/html/node/HtmlNodePlainLink.class.php
wcfsetup/install/files/lib/system/html/output/AmpHtmlOutputProcessor.class.php
wcfsetup/install/files/lib/system/html/output/HtmlOutputProcessor.class.php
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeA.class.php
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeImg.class.php
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeKbd.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodePre.class.php
wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeProcessor.class.php
wcfsetup/install/files/lib/system/html/toc/HtmlToc.class.php
wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php
wcfsetup/install/files/lib/system/image/adapter/IImageAdapter.class.php
wcfsetup/install/files/lib/system/image/adapter/IMemoryAwareImageAdapter.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/image/adapter/ImageAdapter.class.php
wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php
wcfsetup/install/files/lib/system/importer/MediaImporter.class.php
wcfsetup/install/files/lib/system/importer/UserGroupImporter.class.php
wcfsetup/install/files/lib/system/importer/UserImporter.class.php
wcfsetup/install/files/lib/system/io/HttpFactory.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/io/RemoteFile.class.php
wcfsetup/install/files/lib/system/io/Tar.class.php
wcfsetup/install/files/lib/system/language/I18nPlural.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/menu/user/UserMenu.class.php
wcfsetup/install/files/lib/system/message/QuickReplyManager.class.php
wcfsetup/install/files/lib/system/message/embedded/object/MessageEmbeddedObjectManager.class.php
wcfsetup/install/files/lib/system/option/ISearchableUserOption.class.php
wcfsetup/install/files/lib/system/option/OptionHandler.class.php
wcfsetup/install/files/lib/system/option/user/FacebookUserOptionOutput.class.php
wcfsetup/install/files/lib/system/option/user/TwitterUserOptionOutput.class.php
wcfsetup/install/files/lib/system/option/user/URLUserOptionOutput.class.php
wcfsetup/install/files/lib/system/option/user/group/UserGroupsUserGroupOptionType.class.php
wcfsetup/install/files/lib/system/package/PackageArchive.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/package/PackageUpdateDispatcher.class.php
wcfsetup/install/files/lib/system/package/PackageUpdateUnauthorizedException.class.php
wcfsetup/install/files/lib/system/package/plugin/EventListenerPackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/ObjectTypePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/plugin/StylePackageInstallationPlugin.class.php
wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php
wcfsetup/install/files/lib/system/page/handler/TUserOnlineLocationPageHandler.class.php
wcfsetup/install/files/lib/system/reaction/ReactionHandler.class.php
wcfsetup/install/files/lib/system/recaptcha/RecaptchaHandlerV2.class.php
wcfsetup/install/files/lib/system/search/SearchResultTextParser.class.php
wcfsetup/install/files/lib/system/search/acp/OptionACPSearchResultProvider.class.php
wcfsetup/install/files/lib/system/search/acp/PackageACPSearchResultProvider.class.php
wcfsetup/install/files/lib/system/search/acp/UserGroupOptionACPSearchResultProvider.class.php
wcfsetup/install/files/lib/system/style/FontManager.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/style/StyleCompiler.class.php
wcfsetup/install/files/lib/system/style/exception/FontDownloadFailed.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/style/scssphp/scss.inc.php
wcfsetup/install/files/lib/system/tagging/TagEngine.class.php
wcfsetup/install/files/lib/system/template/TemplateScriptingCompiler.class.php
wcfsetup/install/files/lib/system/template/plugin/AnchorAttributesFunctionTemplatePlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/template/plugin/IpSearchModifierTemplatePlugin.class.php
wcfsetup/install/files/lib/system/template/plugin/JslangCompilerTemplatePlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/template/plugin/JslangPrefilterTemplatePlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/template/plugin/PluralFunctionTemplatePlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/template/plugin/UserFunctionTemplatePlugin.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/upload/DefaultUploadFileSaveStrategy.class.php
wcfsetup/install/files/lib/system/upload/DefaultUploadFileValidationStrategy.class.php
wcfsetup/install/files/lib/system/upload/MediaReplaceUploadFileValidationStrategy.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/upload/UserCoverPhotoUploadFileValidationStrategy.class.php
wcfsetup/install/files/lib/system/user/activity/event/ArticleCommentResponseUserActivityEvent.class.php
wcfsetup/install/files/lib/system/user/activity/event/PageCommentResponseUserActivityEvent.class.php
wcfsetup/install/files/lib/system/user/activity/event/ProfileCommentResponseUserActivityEvent.class.php
wcfsetup/install/files/lib/system/user/activity/event/TCommentResponseUserActivityEvent.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/user/authentication/AbstractUserAuthentication.class.php
wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php
wcfsetup/install/files/lib/system/user/notification/event/ArticleLikeUserNotificationEvent.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/user/notification/event/UserFollowFollowingUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/notification/event/UserProfileCommentLikeUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/notification/event/UserProfileCommentResponseLikeUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/notification/event/UserProfileCommentResponseOwnerUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/notification/event/UserProfileCommentUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/notification/event/UserRegistrationUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/signature/SignatureCache.class.php
wcfsetup/install/files/lib/system/user/storage/UserStorageHandler.class.php
wcfsetup/install/files/lib/system/worker/DatabaseConvertEncodingWorker.class.php [deleted file]
wcfsetup/install/files/lib/system/worker/SitemapRebuildWorker.class.php
wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php
wcfsetup/install/files/lib/util/CryptoUtil.class.php
wcfsetup/install/files/lib/util/DOMUtil.class.php
wcfsetup/install/files/lib/util/ExceptionLogUtil.class.php
wcfsetup/install/files/lib/util/FileUtil.class.php
wcfsetup/install/files/lib/util/HTTPRequest.class.php
wcfsetup/install/files/lib/util/ImageUtil.class.php
wcfsetup/install/files/lib/util/MessageUtil.class.php
wcfsetup/install/files/lib/util/PasswordUtil.class.php
wcfsetup/install/files/lib/util/StringUtil.class.php
wcfsetup/install/files/lib/util/UserRegistrationUtil.class.php
wcfsetup/install/files/lib/util/exception/HTTPException.class.php
wcfsetup/install/files/options.inc.php
wcfsetup/install/files/style/bbcode/code.scss
wcfsetup/install/files/style/bbcode/inlineCode.scss
wcfsetup/install/files/style/bbcode/media.scss
wcfsetup/install/files/style/icon/icon.scss
wcfsetup/install/files/style/layout/box.scss
wcfsetup/install/files/style/layout/content.scss
wcfsetup/install/files/style/layout/form.scss
wcfsetup/install/files/style/layout/global.scss
wcfsetup/install/files/style/ui/comment.scss
wcfsetup/install/files/style/ui/contentItem.scss
wcfsetup/install/files/style/ui/dropdownInteractive.scss
wcfsetup/install/files/style/ui/embeddedContent.scss
wcfsetup/install/files/style/ui/itemListInput.scss
wcfsetup/install/files/style/ui/media.scss
wcfsetup/install/files/style/ui/menuMobile.scss
wcfsetup/install/files/style/ui/message.scss
wcfsetup/install/files/style/ui/messageGroup.scss
wcfsetup/install/files/style/ui/messageUserConsent.scss [new file with mode: 0644]
wcfsetup/install/files/style/ui/notification.scss [new file with mode: 0644]
wcfsetup/install/files/style/ui/pageAction.scss
wcfsetup/install/files/style/ui/reactions.scss
wcfsetup/install/files/style/ui/redactor.scss
wcfsetup/install/files/style/ui/tabularBox.scss
wcfsetup/install/files/style/ui/tooltip.scss
wcfsetup/install/files/style/ui/trophy.scss
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml
wcfsetup/setup/db/install.sql
wcfsetup/setup/lang/setup_de.xml
wcfsetup/setup/lang/setup_en.xml
wcfsetup/setup/template/stepShowSystemRequirements.tpl

diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644 (file)
index 0000000..40053b9
--- /dev/null
@@ -0,0 +1,2 @@
+6e01c38f9218c5763130f19814f3d5b94cca26be
+9faac4ad4b5d27f9159e531b645ed3f4088adb3a
index 523db126826835c869e142a65148fadab92080c6..5cb966b595eb9a989c7e6fbfebfe3e0badc65559 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,16 +1,12 @@
-# WoltLab Suite Core 5.2
+# WoltLab Suite Core
 
 WoltLab Suite Core is a free CMS and web-framework, designed for awesome websites and communities. Cutting-edge technologies and strict object-oriented programming makes it the ideal choice for developers and communities, and is actively maintained and improved by WoltLab.
 
 _Formerly known as [WoltLab Community Framework](https://community.woltlab.com/thread/249026-introducing-woltlab-suite-3-0/)_
 
-## Version notes
-
-This is the stable version WoltLab Suite 5.2, please refer to the `master` branch to learn more about the development version.
-
 ## About Redactor II
 
-Redactor II is a WYSIWYG-editor created by Imperavi LLC., Copyright (c) 2009-2017. You can make use of Redactor II in any plugin or app for WSC 5.2 free of charge. You are not allowed to extract or re-use the editor (in entirety or in potions) for any other use unless you own a license for Redactor II.
+Redactor II is a WYSIWYG-editor created by Imperavi LLC., Copyright (c) 2009-2017. You can make use of Redactor II in any plugin or app for WSC 5.3 free of charge. You are not allowed to extract or re-use the editor (in entirety or in potions) for any other use unless you own a license for Redactor II.
 
 Please see http://imperavi.com/redactor/license/ for more information.
 
diff --git a/XSD/style.xsd b/XSD/style.xsd
new file mode 100644 (file)
index 0000000..b5eb9b9
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.woltlab.com" targetNamespace="http://www.woltlab.com" elementFormDefault="qualified">
+       <!-- include types -->
+       <xs:include schemaLocation="types.xsd" />
+       
+       <!-- data element -->
+       <xs:element name="style">
+               <xs:complexType>
+                       <xs:choice maxOccurs="unbounded">
+                               <xs:element name="general" type="general" minOccurs="1" maxOccurs="1" />
+                               <xs:element name="author" type="author" minOccurs="0" maxOccurs="1" />
+                               <xs:element name="files" type="files" minOccurs="1" maxOccurs="1" />
+                       </xs:choice>
+               </xs:complexType>
+       </xs:element>
+       
+       <!-- general information element -->
+       <xs:complexType name="general">
+               <xs:choice maxOccurs="unbounded">
+                       <xs:element name="stylename" type="woltlab_varchar" minOccurs="1" maxOccurs="1" />
+                       <xs:element name="packageName" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="date" type="xs:date" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="version" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="apiVersion" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="image" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="image2x" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="copyright" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="license" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="default" type="woltlab_boolean" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="description" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="coverPhoto" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+               </xs:choice>
+       </xs:complexType>
+       
+       <!-- author information element -->
+       <xs:complexType name="author">
+               <xs:choice maxOccurs="unbounded">
+                       <xs:element name="authorname" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+                       <xs:element name="authorurl" type="xs:anyURI" minOccurs="0" maxOccurs="1" />
+               </xs:choice>
+       </xs:complexType>
+       
+       <!-- files information element -->
+       <xs:complexType name="files">
+               <xs:choice maxOccurs="unbounded">
+                       <xs:element name="variables" type="woltlab_varchar" minOccurs="1" maxOccurs="1" />
+                       <xs:element name="images" minOccurs="0" maxOccurs="1">
+                               <xs:complexType>
+                                       <xs:simpleContent>
+                                               <xs:extension base="woltlab_varchar">
+                                                       <xs:attribute name="path" type="xs:string" />
+                                               </xs:extension>
+                                       </xs:simpleContent>
+                               </xs:complexType>
+                       </xs:element>
+                       <xs:element name="templates" type="woltlab_varchar" minOccurs="0" maxOccurs="1" />
+               </xs:choice>
+       </xs:complexType>
+</xs:schema>
index 497b35cb8029d406f4ca54ec30523fdfb8cf65f5..15dcc772d56ffabad657e6c7a4678b6771b278cf 100644 (file)
@@ -29,6 +29,7 @@
                <xs:restriction base="xs:string">
                        <xs:enumeration value="user" />
                        <xs:enumeration value="admin" />
+                       <xs:enumeration value="all" />
                </xs:restriction>
        </xs:simpleType>
 </xs:schema>
\ No newline at end of file
index 01befe972c09c9a91ed0ccb54d730c284e0372aa..1781702140c1b8b7081283f2288d90627712862d 100644 (file)
                        <permissions>admin.configuration.package.canInstallPackage</permissions>
                        <icon>fa-plus</icon>
                </acpmenuitem>
+               <acpmenuitem name="wcf.acp.menu.link.devtools.missingLanguageItem.list">
+                       <controller>wcf\acp\page\DevtoolsMissingLanguageItemListPage</controller>
+                       <parent>wcf.acp.menu.link.devtools</parent>
+                       <permissions>admin.configuration.package.canInstallPackage</permissions>
+               </acpmenuitem>
                <acpmenuitem name="wcf.acp.menu.link.devtools.notificationTest">
                        <controller>wcf\acp\page\DevtoolsNotificationTestPage</controller>
                        <parent>wcf.acp.menu.link.devtools</parent>
                <acpmenuitem name="wcf.acp.menu.link.attachment.list">
                        <controller>wcf\acp\page\AttachmentListPage</controller>
                        <parent>wcf.acp.menu.link.attachment</parent>
-                       <options>module_attachment</options>
                        <permissions>admin.attachment.canManageAttachment</permissions>
                </acpmenuitem>
                <!-- /attachment -->
index 837f6a35c0c82e735434f20834ea7b04b5e57663..e4b159bd48b49a0d07a7cf6972ce7b35623b122e 100644 (file)
                                <page>wcf\acp\page\UserListPage</page>
                        </pages>
                </action>
-               <action name="resendActivationMail">
+               <action name="confirmEmail">
                        <actionclassname>wcf\system\clipboard\action\UserClipboardAction</actionclassname>
                        <showorder>6</showorder>
                        <pages>
                                <page>wcf\acp\page\UserListPage</page>
                        </pages>
                </action>
-               <action name="sendMail">
+               <action name="unconfirmEmail">
                        <actionclassname>wcf\system\clipboard\action\UserClipboardAction</actionclassname>
                        <showorder>7</showorder>
                        <pages>
                                <page>wcf\acp\page\UserListPage</page>
                        </pages>
                </action>
-               <action name="exportMailAddress">
+               <action name="resendActivationMail">
                        <actionclassname>wcf\system\clipboard\action\UserClipboardAction</actionclassname>
                        <showorder>8</showorder>
                        <pages>
                                <page>wcf\acp\page\UserListPage</page>
                        </pages>
                </action>
-               <action name="sendNewPassword">
+               <action name="sendMail">
                        <actionclassname>wcf\system\clipboard\action\UserClipboardAction</actionclassname>
                        <showorder>9</showorder>
                        <pages>
                                <page>wcf\acp\page\UserListPage</page>
                        </pages>
                </action>
+               <action name="exportMailAddress">
+                       <actionclassname>wcf\system\clipboard\action\UserClipboardAction</actionclassname>
+                       <showorder>10</showorder>
+                       <pages>
+                               <page>wcf\acp\page\UserListPage</page>
+                       </pages>
+               </action>
+               <action name="sendNewPassword">
+                       <actionclassname>wcf\system\clipboard\action\UserClipboardAction</actionclassname>
+                       <showorder>11</showorder>
+                       <pages>
+                               <page>wcf\acp\page\UserListPage</page>
+                       </pages>
+               </action>
                <action name="revertContentChanges">
                        <actionclassname>wcf\system\clipboard\action\UserContentClipboardAction</actionclassname>
-                       <showorder>10</showorder>
+                       <showorder>12</showorder>
                        <pages>
                                <page>wcf\acp\page\UserListPage</page>
                        </pages>
index 88d9bd8dab56d4a62e8708790c2f33be3a5ad982..b79614b48242814ffb19f8d0ce6874022a83cb84 100644 (file)
Binary files a/com.woltlab.wcf/defaultStyle.tar and b/com.woltlab.wcf/defaultStyle.tar differ
index 2b8779b986eee31e22198d858ea00ecf499dde2e..16706c2a6b571a32fcaf68c49b36d31a4b399f6a 100644 (file)
Binary files a/com.woltlab.wcf/files_pre.tar and b/com.woltlab.wcf/files_pre.tar differ
diff --git a/com.woltlab.wcf/files_preUpdate.tar b/com.woltlab.wcf/files_preUpdate.tar
deleted file mode 100644 (file)
index e3c6f25..0000000
Binary files a/com.woltlab.wcf/files_preUpdate.tar and /dev/null differ
diff --git a/com.woltlab.wcf/files_routingCacheBuilder.tar b/com.woltlab.wcf/files_routingCacheBuilder.tar
deleted file mode 100644 (file)
index 3fb6dcb..0000000
Binary files a/com.woltlab.wcf/files_routingCacheBuilder.tar and /dev/null differ
index 134bfa6e7fed3c278ffbb98fc513cca5211dc298..a2f8e45a3e04a97c43a3ffd7aee716eac24ce1c2 100644 (file)
@@ -18,11 +18,6 @@ https?://(?:.+?\.)?youtube.com/shorts/(?P<ID>[a-zA-Z0-9_-]+)]]></regex>
 https?://vimeo\.com/groups/[^/]+/videos/(?P<ID>\d+)]]></regex>
                        <html><![CDATA[<div class="videoContainer"><iframe src="https://player.vimeo.com/video/{$ID}" allowfullscreen></iframe></div>]]></html>
                </provider>
-               <provider name="veoh">
-                       <title>Veoh</title>
-                       <regex><![CDATA[http://(?:www\.)?veoh\.com/watch/v(?P<ID>\d+[a-zA-Z0-9]+)]]></regex>
-                       <html><![CDATA[<object width="410" height="341" id="veohFlashPlayer" name="veohFlashPlayer" type="application/x-shockwave-flash" data="http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1308&amp;permalinkId=v{$ID}&amp;player=videodetailsembedded&amp;videoAutoPlay=0&amp;id=anonymous"><param name="movie" value="http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1308&amp;permalinkId=v{$ID}&amp;player=videodetailsembedded&amp;videoAutoPlay=0&amp;id=anonymous" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="wmode" value="transparent" /></object>]]></html>
-               </provider>
                <provider name="dailymotion">
                        <title>Dailymotion</title>
                        <regex><![CDATA[https?://(?:www\.)?dailymotion\.com/video/(?P<ID>[a-zA-Z0-9_-]+)]]></regex>
@@ -72,9 +67,15 @@ https?://www.twitch.tv/[a-zA-Z0-9]+/v/(?<VIDEO>[0-9]+)]]></regex>
                <provider name="twitter-tweet">
                        <title>Twitter Tweet</title>
                        <regex><![CDATA[https://twitter.com/(?<USERNAME>[0-9a-zA-Z_]+)/status/(?<ID>[0-9]+)]]></regex>
-                       <html><![CDATA[<script>window.twttr=function(t,e,r){var n,i=t.getElementsByTagName(e)[0],w=window.twttr||{};return t.getElementById(r)?w:((n=t.createElement(e)).id=r,n.src="https://platform.twitter.com/widgets.js",i.parentNode.insertBefore(n,i),w._e=[],w.ready=function(t){w._e.push(t)},w)}(document,"script","twitter-wjs");</script>
-<div data-wsc-twitter-tweet="{$ID}"></div>
-<script>twttr.ready(function(t){elBySelAll("[data-wsc-twitter-tweet]",void 0,function(t){elData(t,"wsc-twitter-tweet")&&(twttr.widgets.createTweet(elData(t,"wsc-twitter-tweet"),t,{dnt:!0}),elData(t,"wsc-twitter-tweet",""))})});</script>]]></html>
+                       <html><![CDATA[<div data-wsc-twitter-tweet="{$ID}"><a href="https://twitter.com/{$USERNAME}/status/{$ID}/" class="externalURL" rel="nofollow ugc">https://twitter.com/{$USERNAME}/status/{$ID}/</a></div>
+<script>require(["WoltLabSuite/Core/Ui/Message/TwitterEmbed"],function(t){t.embedAll()});</script>]]></html>
+               </provider>
+               <provider name="facebook-video">
+                       <title>Facebook Video</title>
+                       <regex><![CDATA[(?<HREF>https?://(www\.)?facebook\.com/watch/\?v=(?<ID>[0-9]+))
+(?<HREF>https?://(www\.)?facebook\.com/[a-zA-Z0-9_-]+/videos/(?<ID>[0-9]+)/)]]></regex>
+                       <html><![CDATA[<div class="fb-video" data-href="{$HREF}" data-allowfullscreen="true">{$HREF}</div>
+<script>require(['WoltLabSuite/Core/Wrapper/FacebookSdk'],function(FB){FB.XFBML.parse()})</script>]]></html>
                </provider>
        </import>
        
@@ -83,5 +84,6 @@ https?://www.twitch.tv/[a-zA-Z0-9]+/v/(?<VIDEO>[0-9]+)]]></regex>
                <provider name="twitch-channel" />
                <provider name="twitch-clip" />
                <provider name="twitch-video" />
+               <provider name="veoh" />
        </delete>
 </data>
index 6dddcb0c42c12d576213d4aa04e659de52b4b579..50c20e882ad7e9f98bec50de780b243015ee7c56 100644 (file)
                        <classname>wcf\system\user\notification\object\type\ArticleUserNotificationObjectType</classname>
                        <category>com.woltlab.wcf.page</category>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.likeableArticle.notification</name>
+                       <definitionname>com.woltlab.wcf.notification.objectType</definitionname>
+                       <classname>wcf\system\user\notification\object\type\LikeUserNotificationObjectType</classname>
+                       <category>com.woltlab.wcf.page</category>
+               </type>
                <type>
                        <name>com.woltlab.wcf.article.recentActivityEvent</name>
                        <definitionname>com.woltlab.wcf.user.recentActivityEvent</definitionname>
                </type>
                <!-- /importers -->
                <!-- rebuild data workers -->
-               <type>
-                       <name>com.woltlab.wcf.databaseConvertEncoding</name>
-                       <definitionname>com.woltlab.wcf.rebuildData</definitionname>
-                       <classname>wcf\system\worker\DatabaseConvertEncodingWorker</classname>
-                       <nicevalue>-200</nicevalue>
-               </type>
                <type>
                        <name>com.woltlab.wcf.like</name>
                        <definitionname>com.woltlab.wcf.rebuildData</definitionname>
                        <classname>wcf\system\condition\UserAvatarCondition</classname>
                        <conditiongroup>general</conditiongroup>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.signature</name>
+                       <definitionname>com.woltlab.wcf.condition.userGroupAssignment</definitionname>
+                       <classname>wcf\system\condition\UserSignatureCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
+               <type>
+                       <name>com.woltlab.wcf.coverPhoto</name>
+                       <definitionname>com.woltlab.wcf.condition.userGroupAssignment</definitionname>
+                       <classname>wcf\system\condition\UserCoverPhotoCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
                <type>
                        <name>com.woltlab.wcf.state</name>
                        <definitionname>com.woltlab.wcf.condition.userGroupAssignment</definitionname>
                        <classname>wcf\system\condition\UserAvatarCondition</classname>
                        <conditiongroup>general</conditiongroup>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.signature</name>
+                       <definitionname>com.woltlab.wcf.condition.trophy</definitionname>
+                       <classname>wcf\system\condition\UserSignatureCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
+               <type>
+                       <name>com.woltlab.wcf.coverPhoto</name>
+                       <definitionname>com.woltlab.wcf.condition.trophy</definitionname>
+                       <classname>wcf\system\condition\UserCoverPhotoCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
                <type>
                        <name>com.woltlab.wcf.state</name>
                        <definitionname>com.woltlab.wcf.condition.trophy</definitionname>
                        <definitionname>com.woltlab.wcf.bulkProcessing.user.action</definitionname>
                        <classname>wcf\system\bulk\processing\user\ExportMailAddressUserBulkProcessingAction</classname>
                        <action>exportMailAddress</action>
-                       <permissions>admin.user.canMailUser</permissions>
+                       <permissions>admin.user.canEditMailAddress</permissions>
                </type>
                <!-- /user bulk processing actions -->
                <!-- user bulk processing conditions -->
                        <classname>wcf\system\condition\UserAvatarCondition</classname>
                        <conditiongroup>general</conditiongroup>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.signature</name>
+                       <definitionname>com.woltlab.wcf.bulkProcessing.user.condition</definitionname>
+                       <classname>wcf\system\condition\UserSignatureCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
+               <type>
+                       <name>com.woltlab.wcf.coverPhoto</name>
+                       <definitionname>com.woltlab.wcf.bulkProcessing.user.condition</definitionname>
+                       <classname>wcf\system\condition\UserCoverPhotoCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
                <type>
                        <name>com.woltlab.wcf.state</name>
                        <definitionname>com.woltlab.wcf.bulkProcessing.user.condition</definitionname>
                        <classname>wcf\system\condition\UserRegistrationDateIntervalCondition</classname>
                        <conditiongroup>general</conditiongroup>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.lastActivityTime</name>
+                       <definitionname>com.woltlab.wcf.condition.userSearch</definitionname>
+                       <classname>wcf\system\condition\UserTimestampPropertyCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+                       <propertyname>lastActivityTime</propertyname>
+               </type>
                <type>
                        <name>com.woltlab.wcf.avatar</name>
                        <definitionname>com.woltlab.wcf.condition.userSearch</definitionname>
                        <classname>wcf\system\condition\UserAvatarCondition</classname>
                        <conditiongroup>general</conditiongroup>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.signature</name>
+                       <definitionname>com.woltlab.wcf.condition.userSearch</definitionname>
+                       <classname>wcf\system\condition\UserSignatureCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
+               <type>
+                       <name>com.woltlab.wcf.coverPhoto</name>
+                       <definitionname>com.woltlab.wcf.condition.userSearch</definitionname>
+                       <classname>wcf\system\condition\UserCoverPhotoCondition</classname>
+                       <conditiongroup>general</conditiongroup>
+               </type>
                <type>
                        <name>com.woltlab.wcf.state</name>
                        <definitionname>com.woltlab.wcf.condition.userSearch</definitionname>
                        <classname>wcf\system\condition\user\trophy\UserTrophyExcludedTrophyCategoriesCondition</classname>
                </type>
                <!-- /trophy list box condition -->
+               <!-- today's birthday list box condition -->
+               <type>
+                       <name>com.woltlab.wcf.lastActivityTimeIntervalDays</name>
+                       <definitionname>com.woltlab.wcf.box.todaysBirthdays.condition</definitionname>
+                       <classname>wcf\system\condition\user\UserLastActivityTimeIntervalDaysCondition</classname>
+                       <ignoreZeroTime>1</ignoreZeroTime>
+               </type>
+               <!-- /today's birthday box condition -->
+               <!-- today's birthday of followed users list box condition -->
+               <type>
+                       <name>com.woltlab.wcf.lastActivityTimeIntervalDays</name>
+                       <definitionname>com.woltlab.wcf.box.todaysFollowingBirthdays.condition</definitionname>
+                       <classname>wcf\system\condition\user\UserLastActivityTimeIntervalDaysCondition</classname>
+                       <ignoreZeroTime>1</ignoreZeroTime>
+               </type>
+               <!-- /today's birthday of followed box condition -->
+               <!-- user list box condition -->
+               <type>
+                       <name>com.woltlab.wcf.userGroup</name>
+                       <definitionname>com.woltlab.wcf.box.userList.condition</definitionname>
+                       <classname>wcf\system\condition\UserGroupCondition</classname>
+               </type>
+               <!-- /user list box condition -->
+               <!-- user online list box condition -->
+               <type>
+                       <name>com.woltlab.wcf.userGroup</name>
+                       <definitionname>com.woltlab.wcf.box.userOnlineList.condition</definitionname>
+                       <classname>wcf\system\condition\UserGroupCondition</classname>
+               </type>
+               <!-- /user online list box condition -->
                <!-- media -->
                <type>
                        <name>com.woltlab.wcf.media.caption</name>
                <type name="com.woltlab.wcf.dislike">
                        <definitionname>com.woltlab.wcf.statDailyHandler</definitionname>
                </type>
+               <type name="com.woltlab.wcf.databaseConvertEncoding">
+                       <definitionname>com.woltlab.wcf.rebuildData</definitionname>
+               </type>
        </delete>
 </data>
index 4f666e40e2e602f5392aed8bce96333a451a4630..356ef92b23ed76ea34d9f36b9d487043f7bf5228 100644 (file)
                        <name>com.woltlab.wcf.box.recentActivityList.condition</name>
                        <interfacename>wcf\system\condition\IObjectListCondition</interfacename>
                </definition>
+               <definition>
+                       <name>com.woltlab.wcf.box.todaysBirthdays.condition</name>
+                       <interfacename>wcf\system\condition\IObjectCondition</interfacename>
+               </definition>
+               <definition>
+                       <name>com.woltlab.wcf.box.todaysFollowingBirthdays.condition</name>
+                       <interfacename>wcf\system\condition\IObjectCondition</interfacename>
+               </definition>
+               <definition>
+                       <name>com.woltlab.wcf.box.userList.condition</name>
+                       <interfacename>wcf\system\condition\IObjectListCondition</interfacename>
+               </definition>
                <definition>
                        <name>com.woltlab.wcf.box.userTrophyList.condition</name>
                        <interfacename>wcf\system\condition\IObjectListCondition</interfacename>
                </definition>
+               <definition>
+                       <name>com.woltlab.wcf.box.userOnlineList.condition</name>
+                       <interfacename>wcf\system\condition\IObjectListCondition</interfacename>
+               </definition>
                <!-- /box conditions -->
                <definition>
                        <name>com.woltlab.wcf.sitemap.object</name>
index b3d8b68d701909e1354101ca9936fed85684c831..fa74801d8d3e387810458ca8f9728774da219f4e 100644 (file)
                        </category>
                        <category name="message.attachment">
                                <parent>message</parent>
-                               <options>module_attachment</options>
                        </category>
                        <category name="message.attachment.autoscale">
                                <parent>message.attachment</parent>
                                <optiontype>boolean</optiontype>
                                <defaultvalue>1</defaultvalue>
                        </option>
+                       <option name="module_amp">
+                               <categoryname>module.content</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>1</defaultvalue>
+                       </option>
                        <option name="module_smiley">
                                <categoryname>module.customization</categoryname>
                                <optiontype>boolean</optiontype>
                                <optiontype>boolean</optiontype>
                                <defaultvalue>1</defaultvalue>
                        </option>
-                       <option name="external_link_rel_nofollow">
-                               <categoryname>general.page</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                       </option>
                        <option name="external_link_target_blank">
                                <categoryname>general.page</categoryname>
                                <optiontype>boolean</optiontype>
@@ -595,7 +594,7 @@ private:wcf.acp.option.exception_privacy.private</selectoptions>
                        <option name="cookie_prefix">
                                <categoryname>general.system.cookie</categoryname>
                                <optiontype>text</optiontype>
-                               <defaultvalue>wsc52_</defaultvalue>
+                               <defaultvalue>wsc_</defaultvalue>
                                <validationpattern>^[a-zA-Z0-9_]+$</validationpattern>
                        </option>
                        <!-- /general.system.cookie-->
@@ -915,6 +914,11 @@ physical:wcf.acp.option.google_maps_type.physical</selectoptions>
                                <optiontype>textareaI18n</optiontype>
                                <supporti18n>1</supporti18n>
                        </option>
+                       <option name="mail_signature_html">
+                               <categoryname>general.mail.general</categoryname>
+                               <optiontype>textareaI18n</optiontype>
+                               <supporti18n>1</supporti18n>
+                       </option>
                        <!-- /general.mail.general -->
                        <!-- general.mail.send -->
                        <option name="mail_send_method">
@@ -1008,12 +1012,6 @@ redis:wcf.acp.option.cache_source_type.redis</selectoptions>
                                <optiontype>text</optiontype>
                        </option>
                        <!-- /general.payment -->
-                       <option name="attachment_enable_thumbnails">
-                               <categoryname>message.attachment</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                               <enableoptions>attachment_retain_dimensions,attachment_thumbnail_height,attachment_thumbnail_width</enableoptions>
-                       </option>
                        <option name="attachment_retain_dimensions">
                                <categoryname>message.attachment</categoryname>
                                <optiontype>boolean</optiontype>
@@ -1163,36 +1161,12 @@ XING</selectoptions>
                                <optiontype>textarea</optiontype>
                        </option>
                        <!-- /message.censorship -->
-                       <option name="register_enable_password_security_check">
-                               <categoryname>user.password</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <enableoptions>register_password_min_length,register_password_must_contain_lower_case,register_password_must_contain_upper_case,register_password_must_contain_digit,register_password_must_contain_special_char</enableoptions>
-                       </option>
-                       <option name="register_password_min_length">
-                               <categoryname>user.password</categoryname>
-                               <optiontype>integer</optiontype>
-                               <defaultvalue>8</defaultvalue>
-                               <minvalue>0</minvalue>
-                               <suffix>chars</suffix>
-                       </option>
-                       <option name="register_password_must_contain_lower_case">
-                               <categoryname>user.password</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                       </option>
-                       <option name="register_password_must_contain_upper_case">
-                               <categoryname>user.password</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                       </option>
-                       <option name="register_password_must_contain_digit">
-                               <categoryname>user.password</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                       </option>
-                       <option name="register_password_must_contain_special_char">
+                       <option name="password_min_score">
                                <categoryname>user.password</categoryname>
-                               <optiontype>boolean</optiontype>
+                               <optiontype>select</optiontype>
+                               <selectoptions>0:wcf.acp.option.password_min_score.0
+1:wcf.acp.option.password_min_score.1
+2:wcf.acp.option.password_min_score.2</selectoptions>
                                <defaultvalue>1</defaultvalue>
                        </option>
                        <!-- /user.password -->
@@ -1235,7 +1209,8 @@ XING</selectoptions>
                                <defaultvalue>1</defaultvalue>
                                <selectoptions>0:wcf.acp.option.register_activation_method.disabled
 1:wcf.acp.option.register_activation_method.byUser
-2:wcf.acp.option.register_activation_method.byAdmin</selectoptions>
+2:wcf.acp.option.register_activation_method.byAdmin
+3:wcf.acp.option.register_activation_method.byUserAndAdmin</selectoptions>
                        </option>
                        <option name="register_username_min_length">
                                <categoryname>user.register</categoryname>
@@ -1487,12 +1462,6 @@ DESC:wcf.global.sortOrder.descending</selectoptions>
                                <optiontype>boolean</optiontype>
                                <defaultvalue>0</defaultvalue>
                        </option>
-                       <option name="message_sidebar_enable_user_online_marking">
-                               <categoryname>message.sidebar</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                               <options>module_users_online</options>
-                       </option>
                        <option name="message_sidebar_enable_trophy_points">
                                <categoryname>message.sidebar</categoryname>
                                <optiontype>boolean</optiontype>
@@ -1546,6 +1515,19 @@ ruby
 rust
 go</defaultvalue>
                        </option>
+                       <option name="message_enable_user_consent">
+                               <categoryname>message.general</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>1</defaultvalue>
+                       </option>
+                       <option name="modification_log_expiration">
+                               <categoryname>message.general</categoryname>
+                               <optiontype>integer</optiontype>
+                               <defaultvalue>0</defaultvalue>
+                               <minvalue>0</minvalue>
+                               <maxvalue>365</maxvalue>
+                               <suffix>days</suffix>
+                       </option>
                        <!-- /message.general -->
                        <option name="search_results_per_page">
                                <categoryname>message.search</categoryname>
@@ -1751,9 +1733,14 @@ DESC:wcf.global.sortOrder.descending</selectoptions>
                </options>
        </import>
        <delete>
-               <option name="attachment_storage" />
-               <option name="like_allow_for_own_content" />
-               <option name="like_enable_dislike" />
-               <option name="module_attachment"/>
+               <option name="attachment_enable_thumbnails" />
+               <option name="message_sidebar_enable_user_online_marking" />
+               <option name="register_enable_password_security_check" />
+               <option name="register_password_min_length" />
+               <option name="register_password_must_contain_lower_case" />
+               <option name="register_password_must_contain_upper_case" />
+               <option name="register_password_must_contain_digit" />
+               <option name="register_password_must_contain_special_char" />
+               <option name="external_link_rel_nofollow" />
        </delete>
 </data>
index 7eccf83a59a0bc95f781a804b803fa48ae4af24f..49ae6accfb7ac9b0c3a26057a8d38b152644d641 100644 (file)
@@ -5,8 +5,8 @@
                <packagedescription>Free CMS and web-framework, designed for awesome websites and communities.</packagedescription>
                <packagedescription language="de">Freies CMS und Web-Framework, das eindrucksvolle Websites und Communities ermöglicht.</packagedescription>
                <isapplication>1</isapplication>
-               <version>5.2.14</version> <!-- codename: hurricane -->
-               <date>2021-04-04</date>
+               <version>5.3.7</version>
+               <date>2021-04-16</date>
        </packageinformation>
        
        <authorinformation>
                <instruction type="script">acp/post_install.php</instruction>
        </instructions>
        
-       <instructions type="update" fromversion="3.1.*">
-               <instruction type="file">files_preUpdate.tar</instruction>
-               <instruction type="script" flushCache="false">acp/update_com.woltlab.wcf_5.2_preUpdate.php</instruction>
-               
-               <!-- Contains a few PIP-scripts, \wcf\data\option\OptionEditor and \wcf\system\database\table\* -->
+       <instructions type="update" fromversion="5.2.*">
+               <!-- We need to deploy `lib/core.functions.php` and `lib/system/api/*` first, otherwise
+                    Guzzle can not be found during the development of the regular file PIP. -->
                <instruction type="file" run="standalone">files_pre.tar</instruction>
                
-               <!-- Required language categories for the reactions. -->
-               <instruction type="language" run="standalone" />
+               <!-- Verify that there are no duplicate usernames and warn about them if any are found. -->
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3_preUpdate.php</instruction>
                
-               <instruction type="script" flushCache="false">acp/update_com.woltlab.wcf_5.2_prePhpApi.php</instruction>
+               <!-- Deploy the database changes as early as possible to avoid any conflicts by calls to
+                    tables that do not exist in 5.2, in particular `wcfN_devtools_missing_language_item`.-->
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3.php</instruction>
                
-               <instruction type="script" flushCache="false">acp/update_com.woltlab.wcf_5.2.php</instruction>
+               <instruction type="file" />
+               <instruction type="acpTemplate" />
+               <instruction type="template" />
                
-               <!-- Convert likes to reactions. -->
-               <instruction type="script" flushCache="false">acp/update_com.woltlab.wcf_5.2_reactionUpdate.php</instruction>
+               <instruction type="option" run="standalone" />
                
-               <!-- Delete all likeable recent activity events, because they don't have the reactionType stored. -->
-               <instruction type="script" flushCache="false">acp/update_com.woltlab.wcf_5.2_deleteRecentActivity.php</instruction>
+               <instruction type="acpMenu" />
+               <instruction type="clipboardAction" />
+               <instruction type="mediaProvider" />
+               <instruction type="userGroupOption" />
+               <instruction type="userMenu" />
+               <instruction type="page" />
                
-               <instruction type="file" run="standalone">files_routingCacheBuilder.tar</instruction>
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3_emailConfirmation.php</instruction>
                
-               <instruction type="sql">update_5.2.sql</instruction>
+               <!-- The internal data structure of sitemaps have been modified, this script must be run before
+                    the `objectType` pip to prevent any data corruption. -->
+               <instruction type="script">acp/update_com.woltlab.wcf_5.3_sitemaps.php</instruction>
                
-               <instruction type="option" />
-               <instruction type="script">acp/update_com.woltlab.wcf_5.2_reloadOptions.php</instruction>
+               <instruction type="objectTypeDefinition" />
+               <instruction type="objectType" />
                
-               <instruction type="coreObject" />
+               <instruction type="userNotificationEvent" />
+               <instruction type="userOption" />
                
-               <instruction type="file" run="standalone" />
-               <instruction type="template" run="standalone" />
-               <instruction type="acpTemplate" run="standalone" />
+               <instruction type="language" />
                
-               <instruction type="acpMenu" />
-               <instruction type="userGroupOption" />
-               <instruction type="cronjob" />
-               <instruction type="clipboardAction" />
-               <instruction type="objectTypeDefinition" />
-               <instruction type="objectType" />
-               <instruction type="acpSearchProvider" />
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3_invalidateMailForm.php</instruction>
                
-               <instruction type="userOption" run="standalone" />
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3_fixActivationMethod.php</instruction>
                
-               <instruction type="bbcode" />
-               <instruction type="userMenu" />
-               <instruction type="userNotificationEvent" />
-               <instruction type="page" />
-               <instruction type="menu" />
-               <instruction type="menuItem" />
-               <instruction type="box" />
-               <instruction type="mediaProvider" />
-               <instruction type="templateListener" />
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3_orphanedComments.php</instruction>
+               
+               <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.3_style.php</instruction>
                
                <instruction type="style" run="standalone">defaultStyle.tar</instruction>
                
-               <instruction type="script">acp/update_com.woltlab.wcf_preventMailAbuse.php</instruction>
-       </instructions>
-       
-       <instructions type="update" fromversion="5.2.13">
-               <instruction type="acpTemplate">acptemplates_update.tar</instruction>
-               <instruction type="file">files_update.tar</instruction>
-               <instruction type="template">templates_update.tar</instruction>
+               <!-- This SQL step purges the legacy package servers, this must come last to make sure that an early
+                    abort of the core upgrade does not brick the installation. -->
+               <instruction type="sql">update_5.3.sql</instruction>
                
-               <instruction type="mediaProvider" />
-               <instruction type="page" />
+               <instruction type="script">acp/update_com.woltlab.wcf_5.3_packageServer.php</instruction>
        </instructions>
+
+       <instructions type="update" fromversion="5.3.6">
+       <instruction type="file">files_update.tar</instruction>
+       
+       <instruction type="language" />
+</instructions>
 </package>
index b0ea789eb25320d3550dbeacedddbac010997072..f15cefa08775631906eaf9393dcd05bcc48c918f 100644 (file)
                                <title>Kennwort vergessen</title>
                        </content>
                </page>
-               <page identifier="com.woltlab.wcf.Mail">
-                       <pageType>system</pageType>
-                       <controller>wcf\form\MailForm</controller>
-                       <name language="de">E-Mail-Formular</name>
-                       <name language="en">Mail Form</name>
-                       <requireObjectID>1</requireObjectID>
-                       <content language="en">
-                               <title>Mail Form</title>
-                       </content>
-                       <content language="de">
-                               <title>E-Mail-Formular</title>
-                       </content>
-               </page>
                <page identifier="com.woltlab.wcf.NewPassword">
                        <pageType>system</pageType>
                        <controller>wcf\form\NewPasswordForm</controller>
                                <title>Benachrichtigungseinstellungen</title>
                        </content>
                </page>
+               <page identifier="com.woltlab.wcf.NotificationUnsubscribe">
+                       <pageType>system</pageType>
+                       <controller>wcf\form\NotificationUnsubscribeForm</controller>
+                       <name language="de">E-Mail-Benachrichtigungen abbestellen</name>
+                       <name language="en">Unsubscribe Email Notifications</name>
+                       <parent>com.woltlab.wcf.AccountManagement</parent>
+                       <excludeFromLandingPage>1</excludeFromLandingPage>
+                       <content language="en">
+                               <title>Unsubscribe Email Notifications</title>
+                       </content>
+                       <content language="de">
+                               <title>E-Mail-Benachrichtigungen abbestellen</title>
+                       </content>
+               </page>
                <page identifier="com.woltlab.wcf.Register">
                        <pageType>system</pageType>
                        <controller>wcf\form\RegisterForm</controller>
                        <hasFixedParent>1</hasFixedParent>
                        <parent>com.woltlab.wcf.AccountManagement</parent>
                        <options>module_paid_subscription</options>
+                       <permissions>user.profile.payment.canBuyPaidSubscription</permissions>
                        <content language="en">
                                <title>Paid Subscriptions</title>
                        </content>
 <li><a href="https://support.mozilla.org/en-US/kb/cookies-information-websites-store-on-your-computer" class="externalURL" rel="nofollow">Mozilla Firefox</a></li>
 <li><a href="https://blogs.opera.com/news/2015/08/how-to-manage-cookies-in-opera/" class="externalURL" rel="nofollow">Opera</a></li>
 <li><a href="https://support.apple.com/kb/ph17191?locale=en_US" class="externalURL" rel="nofollow">Safari</a></li>
-<li><a href="https://windows.microsoft.com/en-US/internet-explorer/delete-manage-cookies" class="externalURL" rel="nofollow">Windows Internet Explorer</a></li>
 </ul>]]></content>
                                <customURL>cookie-policy</customURL>
                        </content>
 <li><a href="https://support.mozilla.org/de/kb/cookies-informationen-websites-auf-ihrem-computer" class="externalURL" rel="nofollow">Mozilla Firefox</a></li>
 <li><a href="https://blogs.opera.com/germany/2016/03/cookies-aktivieren-opera/" class="externalURL" rel="nofollow">Opera</a></li>
 <li><a href="https://support.apple.com/de-de/guide/safari/manage-cookies-and-website-data-sfri11471/" class="externalURL" rel="nofollow">Safari</a></li>
-<li><a href="http://windows.microsoft.com/de-DE/internet-explorer/delete-manage-cookies" class="externalURL" rel="nofollow">Windows Internet Explorer</a></li>
 </ul>]]></content>
                                <customURL>cookie-richtlinie</customURL>
                        </content>
@@ -751,18 +751,16 @@ Email: [email address of the responsible party]</p><p><br></p><p>The controller
 <h2>5. Plug-ins and Tools</h2>
 <h3>YouTube</h3> <p>Our website uses plug-ins of the YouTube platform, which is operated by Google. The website operator is Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Ireland.</p><p><br></p><p>If you visit a page on our website into which a YouTube plug-in has been integrated, a connection with YouTube’s servers will be established. As a result, the YouTube server will be notified, which of our pages you have visited.</p><p><br></p><p>Furthermore, YouTube will be able to place various cookies on your device. With the assistance of these cookies, YouTube will be able to obtain information about our website visitor. Among other things, this information will be used to generate video statistics with the aim of improving the user friendliness of the site and to prevent attempts to commit fraud. These cookies will stay on your device until you delete them.</p><p><br></p><p>If you are logged into your YouTube account while you visit our site, you enable YouTube to directly allocate your browsing patterns to your personal profile. You have the option to prevent this by logging out of your YouTube account.</p><p><br></p><p>The use of YouTube is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how YouTube handles user data, please consult the YouTube Data Privacy Policy under: <a href="https://policies.google.com/privacy?hl=en" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=en</a>.</p>
 <h3>Vimeo</h3> <p>Our website uses plug-ins of the video portal Vimeo. The provider is Vimeo Inc., 555 West 18th Street, New York, New York 10011, USA.</p><p><br></p><p>If you visit one of the pages on our website into which a Vimeo plug-in has been integrated, a connection to Vimeo’s servers will be established. As a consequence, the Vimeo server will receive information as to which of our pages you have visited. Moreover, Vimeo will receive your IP address. This will also happen if you are not logged into Vimeo or do not have an account with Vimeo. The information recorded by Vimeo will be transmitted to Vimeo’s server in the United States.</p><p><br></p><p>If you are logged into your Vimeo account, you enable Vimeo to directly allocate your browsing patterns to your personal profile. You can prevent this by logging out of your Vimeo account.</p><p><br></p><p>The use of Vimeo is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how Vimeo handles user data, please consult the Vimeo Data Privacy Policy under: <a href="https://vimeo.com/privacy" target="_blank" rel="noopener">https://vimeo.com/privacy</a>.</p>
-<h3>Google Web Fonts</h3> <p>To ensure that fonts used on this website are uniform, this website uses so-called Web Fonts provided by Google. When you access a page on our website, your browser will load the required web fonts into your browser cache to correctly display text and fonts.</p><p><br></p><p>To do this, the browser you use will have to establish a connection with Google’s servers. As a result, Google will learn that your IP address was used to access our website. The use of Google Web Fonts is based on our interest in presenting our online content in a uniform and appealing way. According to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>If your browser should not support Web Fonts, a standard font installed on your computer will be used.</p><p><br></p><p>For more information on Google Web Fonts, please follow this link: <a href="https://developers.google.com/fonts/faq" target="_blank" rel="noopener">https://developers.google.com/fonts/faq</a> and consult Google’s Data Privacy Declaration under: <a href="https://policies.google.com/privacy?hl=en" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=en</a>.</p>
 <h3>Google Maps</h3> <p>Via an API, this website uses the mapping service Google Maps. The provider is Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Ireland.</p><p><br></p><p>To enable the use of the Google Maps features, your IP address must be stored. As a rule, this information is transferred to one of Google’s servers in the United States, where it is archived. The operator of this website has no control over the data transfer.</p><p><br></p><p>We use Google Maps to present our online content in an appealing manner and to make the locations disclosed on our website easy to find. This constitutes a legitimate interest as defined in Art. 6 Sect. 1 lit. f GDPR.</p><p><br></p><p>For more information on the handling of user data, please review Google’s Data Privacy Declaration under: <a href="https://policies.google.com/privacy?hl=en" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=en</a>.</p>
 <h3>Google reCAPTCHA</h3> <p>We use “Google reCAPTCHA” (hereinafter referred to as “reCAPTCHA”) on our websites. The provider is Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Ireland (“Google”).</p><p><br></p><p>The purpose of reCAPTCHA is to determine whether data entered on our websites (e.g. information entered into a contact form) is being provided by a human user or by an automated program. To determine this, reCAPTCHA analyses the behaviour of the website visitors based on a variety of parameters. This analysis is triggered automatically as soon as the website visitor enters the site. For this analysis, reCAPTCHA evaluates a variety of data (e.g. IP address, time the website visitor spent on the site or cursor movements initiated by the user). The data tracked during such analyses are forwarded to Google.</p><p><br></p><p>reCAPTCHA analyses run entirely in the background. Website visitors are not alerted that an analysis is underway.</p><p><br></p><p>The data is processed on the basis of Art. 6 Sect. 1 lit. f GDPR. It is in the website operators legitimate interest, to protect the operator’s web content against misuse by automated industrial espionage systems and against SPAM.</p><p><br></p><p>For more information about Google reCAPTCHA and to review the Data Privacy Declaration of Google, please follow these links: <a href="https://policies.google.com/privacy?hl=en" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=en</a> and <a href="https://www.google.com/recaptcha/intro/android.html" target="_blank" rel="noopener">https://www.google.com/recaptcha/intro/android.html</a>.</p>
 <h3>SoundCloud</h3> <p>We may have integrated plug-ins of the social network SoundCloud (SoundCloud Limited, Berners House, 47-48 Berners Street, London W1T 3NF, Great Britain) into our websites. You will be able to recognise such SoundCloud plug-ins by checking for the SoundCloud logo on the respective pages.</p><p><br></p><p>Whenever you visit one of our websites, a direct connection between your browser and the SoundCloud server will be established immediately after the plug-in has been activated. As a result, SoundCloud will be notified that you have used your IP address to visit our site. If you click the “Like” button or the “Share” button while you are logged into your Sound Cloud user account, you can link the content of our websites to your SoundCloud profile and/or share the content. Consequently, SoundCloud will be able to allocate the visit to our website to your user account. We emphasize that we as the provider of the websites do not have any knowledge of the data transferred and the use of this data by SoundCloud.</p><p><br></p><p>We use SoundCloud on the basis of Art. 6 Sect. 1 lit. f GDPR. The website operator has a legitimate interest in attaining the highest level of visibility on social media.</p><p><br></p><p>For more information about this, please consult SoundCloud’s Data Privacy Declaration at: <a href="https://soundcloud.com/pages/privacy" target="_blank" rel="noopener">https://soundcloud.com/pages/privacy</a>.</p><p><br></p><p>If you prefer not to have your visit to our websites allocated to your SoundCloud user account by SoundCloud, please log out of your SoundCloud user account before you activate content of the SoundCloud plug-in.</p>
-<h3>Veoh</h3> <p>Our website uses plug-ins of the video portal Veoh. The provider is FC2, 4730 South Fort Apache Road, Suite 300, Las Vegas, NV 89147, USA.</p><p><br></p><p>If you visit one of the pages on our website into which a Veoh plug-in has been integrated, a connection to Veoh’s servers will be established. As a consequence, the Veoh server will receive information as to which of our pages you have visited. Moreover, Veoh will receive your IP address. This will also happen if you are not logged into Veoh or do not have an account with Veoh. The information recorded by Veoh will be transmitted to Veoh’s server in the United States.</p><p><br></p><p>If you are logged into your Veoh account, you enable Veoh to directly allocate your browsing patterns to your personal profile. You can prevent this by logging out of your Veoh account.</p><p><br></p><p>The use of Veoh is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how Veoh handles user data, please consult the Veoh Data Privacy Policy under: <a href="https://www.veoh.com/corporate/privacy-policy" target="_blank" rel="noopener">https://www.veoh.com/corporate/privacy-policy</a>.</p>
 <h3>Dailymotion</h3> <p>Our website uses plug-ins of the video portal Dailymotion. The provider is Dailymotion, 140 boulevard Malesherbes, 75017 Paris, France.</p><p><br></p><p>If you visit one of the pages on our website into which a Dailymotion plug-in has been integrated, a connection to Dailymotion’s servers will be established. As a consequence, the Dailymotion server will receive information as to which of our pages you have visited. Moreover, Dailymotion will receive your IP address. This will also happen if you are not logged into Dailymotion or do not have an account with Dailymotion.</p><p><br></p><p>If you are logged into your Dailymotion account, you enable Dailymotion to directly allocate your browsing patterns to your personal profile. You can prevent this by logging out of your Dailymotion account.</p><p><br></p><p>The use of Dailymotion is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how Dailymotion handles user data, please consult the Dailymotion Data Privacy Policy under: <a href="https://www.dailymotion.com/legal/privacy" target="_blank" rel="noopener">https://www.dailymotion.com/legal/privacy</a>.</p>
 <h3>GitHub</h3> <p>Our website uses plug-ins of the portal GitHub. The provider is GitHub, Inc, 88 Colin P Kelly Jr St, San Francisco, CA 94107, USA.</p><p><br></p><p>If you visit one of the pages on our website into which a GitHub plug-in has been integrated, a connection to GitHub’s servers will be established. As a consequence, the GitHub server will receive information as to which of our pages you have visited. Moreover, GitHub will receive your IP address. This will also happen if you are not logged into GitHub or do not have an account with GitHub. The information recorded by GitHub will be transmitted to GitHub’s server in the United States.</p><p><br></p><p>If you are logged into your GitHub account, you enable GitHub to directly allocate your browsing patterns to your personal profile. You can prevent this by logging out of your GitHub account.</p><p><br></p><p>The use of GitHub is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how GitHub handles user data, please consult the GitHub Data Privacy Policy under: <a href="https://help.github.com/articles/github-privacy-statement/" target="_blank" rel="noopener">https://help.github.com/articles/github-privacy-statement/</a>.</p>
 <h3>Spotify</h3> <p>Our website uses plug-ins provided by Spotify. The provider is Spotify AB, Birger Jarlsgatan 61, 113 56 Stockholm, Sweden.</p><p><br></p><p>If you visit one of our pages featuring a Spotify plugin, a connection to the Spotify servers is established. Here the Spotify server is informed about which of our pages you have visited. In addition, Spotify will receive your IP address. This also applies if you are not logged in to Spotify when you visit our website or do not have a Spotify account.</p><p><br></p><p>If you are logged in to your Spotify account, Spotify allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Spotify account.</p><p><br></p><p>The use of Spotify is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Spotify Privacy Policy at <a href="https://www.spotify.com/de/legal/privacy-policy/" target="_blank" rel="noopener">https://www.spotify.com/de/legal/privacy-policy/</a>.</p>
 <h3>Instagram</h3> <p>Our website uses plug-ins provided by Instagram. The provider is Instagram Inc., 1601 Willow Road, Menlo Park, CA 94025, USA.</p><p><br></p><p>If you visit one of our pages featuring a Instagram plugin, a connection to the Instagram servers is established. Here the Instagram server is informed about which of our pages you have visited. In addition, Instagram will receive your IP address. This also applies if you are not logged in to Instagram when you visit our website or do not have a Instagram account. The information is transmitted to a Instagram server in the US, where it is stored.</p><p><br></p><p>If you are logged in to your Instagram account, Instagram allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Instagram account.</p><p><br></p><p>The use of Instagram is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Instagram Privacy Policy at <a href="https://instagram.com/about/legal/privacy/" target="_blank" rel="noopener">https://instagram.com/about/legal/privacy/</a>.</p>
-<h3>Imgur</h3> <p>Our website uses plug-ins provided by Imgur. The provider is Imgur, Inc., 415 Jackson Street, 2nd Floor, Suite 200, San Francisco, CA 94111, USA.</p><p><br></p><p>If you visit one of our pages featuring a Imgur plugin, a connection to the Imgur servers is established. Here the Imgur server is informed about which of our pages you have visited. In addition, Imgur will receive your IP address. This also applies if you are not logged in to Imgur when you visit our website or do not have a Imgur account. The information is transmitted to a Imgur server in the US, where it is stored.</p><p><br></p><p>If you are logged in to your Imgur account, Imgur allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Imgur account.</p><p><br></p><p>The use of Imgur is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Imgur Privacy Policy at <a href="https://imgur.com/privacy" target="_blank" rel="noopener">https://imgur.com/privacy</a>.</p>
 <h3>Twitch</h3> <p>Our website uses plug-ins provided by Twitch. The provider is Twitch Interactive, Inc., 225 Bush Street, 6th Floor, San Francisco, CA 94104, USA.</p><p><br></p><p>If you visit one of our pages featuring a Twitch plugin, a connection to the Twitch servers is established. Here the Twitch server is informed about which of our pages you have visited. In addition, Twitch will receive your IP address. This also applies if you are not logged in to Twitch when you visit our website or do not have a Twitch account. The information is transmitted to a Twitch server in the US, where it is stored.</p><p><br></p><p>If you are logged in to your Twitch account, Twitch allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Twitch account.</p><p><br></p><p>The use of Twitch is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Twitch Privacy Policy at <a href="https://www.twitch.tv/p/legal/privacy-policy/" target="_blank" rel="noopener">https://www.twitch.tv/p/legal/privacy-policy/</a>.</p>
-<h3>Twitter</h3> <p>Our website uses plug-ins provided by Twitter. The provider is  Twitter Inc., 1355 Market Street, Suite 900, San Francisco, CA 94103, USA.</p><p><br></p><p>If you visit one of our pages featuring a Twitter plugin, a connection to the Twitter servers is established. Here the Twitter server is informed about which of our pages you have visited. In addition, Twitter will receive your IP address. This also applies if you are not logged in to Twitter when you visit our website or do not have a Twitter account. The information is transmitted to a Twitter server in the US, where it is stored.</p><p><br></p><p>If you are logged in to your Twitter account, Twitter allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Twitter account.</p><p><br></p><p>The use of Twitter is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Twitter Privacy Policy at <a href="https://twitter.com/en/privacy" target="_blank" rel="noopener">https://twitter.com/en/privacy</a>.</p>
+<h3>Twitter</h3> <p>Our website uses plug-ins provided by Twitter. The provider is Twitter Inc., 1355 Market Street, Suite 900, San Francisco, CA 94103, USA.</p><p><br></p><p>If you visit one of our pages featuring a Twitter plugin, a connection to the Twitter servers is established. Here the Twitter server is informed about which of our pages you have visited. In addition, Twitter will receive your IP address. This also applies if you are not logged in to Twitter when you visit our website or do not have a Twitter account. The information is transmitted to a Twitter server in the US, where it is stored.</p><p><br></p><p>If you are logged in to your Twitter account, Twitter allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Twitter account.</p><p><br></p><p>The use of Twitter is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Twitter Privacy Policy at <a href="https://twitter.com/en/privacy" target="_blank" rel="noopener">https://twitter.com/en/privacy</a>.</p>
+<h3>Facebook</h3> <p>Our website uses plug-ins provided by Facebook. The provider is Facebook Ireland Limited, 4 Grand Canal Square, Dublin 2, Ireland.</p><p><br></p><p>If you visit one of our pages featuring a Facebook plugin, a connection to the Facebook servers is established. Here the Facebook server is informed about which of our pages you have visited. In addition, Facebook will receive your IP address. This also applies if you are not logged in to Facebook when you visit our website or do not have a Facebook account. The information is transmitted to a Facebook server in the US, where it is stored.</p><p><br></p><p>If you are logged in to your Facebook account, Facebook allows you to associate your browsing behavior directly with your personal profile. You can prevent this by logging out of your Facebook account.</p><p><br></p><p>The use of Facebook is based on our interest in presenting our online content in an appealing manner. Pursuant to Art. 6 Sect. 1 lit. f GDPR, this is a legitimate interest.</p><p><br></p><p>For more information on how to handle user data, please refer to the Facebook Privacy Policy at <a href="https://www.facebook.com/about/privacy/" target="_blank" rel="noopener">https://www.facebook.com/about/privacy/</a>.</p>
 
 <h2>6. Payment service providers</h2>
 <h3>PayPal</h3> <p>Among other options, we offer payment via PayPal on our website. The provider of this payment processing service is PayPal (Europe) S.à.r.l. et Cie, S.C.A., 22-24 Boulevard Royal, L-2449 Luxembourg (hereinafter referred to as “PayPal”).</p><p><br></p><p>If you choose payment via PayPal, we will share the payment information you enter with PayPal.</p><p><br></p><p>The legal basis for the sharing of your data with PayPal is Art. 6 Sect. 1 lit. a GDPR (consent) as well as Art. 6 Sect. 1 lit. b GDPR (processing for the fulfilment of a contract). You have the option to at any time revoke your consent to the processing of your data. Such a revocation shall not have any impact on the effectiveness of data processing transactions that occurred in the past.</p>]]></content>
@@ -803,18 +801,16 @@ E-Mail: [E-Mail-Adresse der verantwortlichen Stelle]</p><p><br></p><p>Verantwort
 <h2>5. Plugins und Tools</h2>
 <h3>YouTube</h3> <p>Unsere Website nutzt Plugins der von Google betriebenen Seite YouTube. Betreiber der Seiten ist die Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Irland.</p><p><br></p><p>Wenn Sie eine unserer mit einem YouTube-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von YouTube hergestellt. Dabei wird dem YouTube-Server mitgeteilt, welche unserer Seiten Sie besucht haben.</p><p><br></p><p>Des Weiteren kann Youtube verschiedene Cookies auf Ihrem Endgerät speichern. Mit Hilfe dieser Cookies kann Youtube Informationen über Besucher unserer Website erhalten. Diese Informationen werden u. a. verwendet, um Videostatistiken zu erfassen, die Anwenderfreundlichkeit zu verbessern und Betrugsversuchen vorzubeugen. Die Cookies verbleiben auf Ihrem Endgerät, bis Sie sie löschen.</p><p><br></p><p>Wenn Sie in Ihrem YouTube-Account eingeloggt sind, ermöglichen Sie YouTube, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem YouTube-Account ausloggen.</p><p><br></p><p>Die Nutzung von YouTube erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne von Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von YouTube unter: <a href="https://policies.google.com/privacy?hl=de" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=de</a>.</p>
 <h3>Vimeo</h3> <p>Unsere Website nutzt Plugins des Videoportals Vimeo. Anbieter ist die Vimeo Inc., 555 West 18th Street, New York, New York 10011, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem Vimeo-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Vimeo hergestellt. Dabei wird dem Vimeo-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Vimeo Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Vimeo eingeloggt sind oder keinen Account bei Vimeo besitzen. Die von Vimeo erfassten Informationen werden an den Vimeo-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Vimeo-Account eingeloggt sind, ermöglichen Sie Vimeo, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Vimeo-Account ausloggen.</p><p><br></p><p>Die Nutzung von Vimeo erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Vimeo unter: <a href="https://vimeo.com/privacy" target="_blank" rel="noopener">https://vimeo.com/privacy</a>.</p>
-<h3>Google Web Fonts</h3> <p>Diese Seite nutzt zur einheitlichen Darstellung von Schriftarten so genannte Web Fonts, die von Google bereitgestellt werden. Beim Aufruf einer Seite lädt Ihr Browser die benötigten Web Fonts in ihren Browsercache, um Texte und Schriftarten korrekt anzuzeigen.</p><p><br></p><p>Zu diesem Zweck muss der von Ihnen verwendete Browser Verbindung zu den Servern von Google aufnehmen. Hierdurch erlangt Google Kenntnis darüber, dass über Ihre IP-Adresse unsere Website aufgerufen wurde. Die Nutzung von Google Web Fonts erfolgt im Interesse einer einheitlichen und ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne von Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Wenn Ihr Browser Web Fonts nicht unterstützt, wird eine Standardschrift von Ihrem Computer genutzt.</p><p><br></p><p>Weitere Informationen zu Google Web Fonts finden Sie unter <a href="https://developers.google.com/fonts/faq" target="_blank" rel="noopener">https://developers.google.com/fonts/faq</a> und in der Datenschutzerklärung von Google: <a href="https://policies.google.com/privacy?hl=de" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=de</a>.</p>
 <h3>Google Maps</h3> <p>Diese Seite nutzt über eine API den Kartendienst Google Maps. Anbieter ist die Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Irland.</p><p><br></p><p>Zur Nutzung der Funktionen von Google Maps ist es notwendig, Ihre IP Adresse zu speichern. Diese Informationen werden in der Regel an einen Server von Google in den USA übertragen und dort gespeichert. Der Anbieter dieser Seite hat keinen Einfluss auf diese Datenübertragung.</p><p><br></p><p>Die Nutzung von Google Maps erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote und an einer leichten Auffindbarkeit der von uns auf der Website angegebenen Orte. Dies stellt ein berechtigtes Interesse im Sinne von Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Mehr Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Google: <a href="https://policies.google.com/privacy?hl=de" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=de</a>.</p>
 <h3>Google reCAPTCHA</h3> <p>Wir nutzen “Google reCAPTCHA” (im Folgenden “reCAPTCHA”) auf unseren Websites. Anbieter ist die Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Irland (“Google”).</p><p><br></p><p>Mit reCAPTCHA soll überprüft werden, ob die Dateneingabe auf unseren Websites (z.B. in einem Kontaktformular) durch einen Menschen oder durch ein automatisiertes Programm erfolgt. Hierzu analysiert reCAPTCHA das Verhalten des Websitebesuchers anhand verschiedener Merkmale. Diese Analyse beginnt automatisch, sobald der Websitebesucher die Website betritt. Zur Analyse wertet reCAPTCHA verschiedene Informationen aus (z.B. IP-Adresse, Verweildauer des Websitebesuchers auf der Website oder vom Nutzer getätigte Mausbewegungen). Die bei der Analyse erfassten Daten werden an Google weitergeleitet.</p><p><br></p><p>Die reCAPTCHA-Analysen laufen vollständig im Hintergrund. Websitebesucher werden nicht darauf hingewiesen, dass eine Analyse stattfindet.</p><p><br></p><p>Die Datenverarbeitung erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO. Der Websitebetreiber hat ein berechtigtes Interesse daran, seine Webangebote vor missbräuchlicher automatisierter Ausspähung und vor SPAM zu schützen.</p><p><br></p><p>Weitere Informationen zu Google reCAPTCHA sowie die Datenschutzerklärung von Google entnehmen Sie folgenden Links: <a href="https://policies.google.com/privacy?hl=de" target="_blank" rel="noopener">https://policies.google.com/privacy?hl=de</a> und <a href="https://www.google.com/recaptcha/intro/android.html" target="_blank" rel="noopener">https://www.google.com/recaptcha/intro/android.html</a>.</p>
 <h3>SoundCloud</h3> <p>Auf unseren Seiten können Plugins des sozialen Netzwerks SoundCloud (SoundCloud Limited, Berners House, 47-48 Berners Street, London W1T 3NF, Großbritannien.) integriert sein. Die SoundCloud-Plugins erkennen Sie an dem SoundCloud-Logo auf den betroffenen Seiten.</p><p><br></p><p>Wenn Sie unsere Seiten besuchen, wird nach Aktivierung des Plugin eine direkte Verbindung zwischen Ihrem Browser und dem SoundCloud-Server hergestellt. SoundCloud erhält dadurch die Information, dass Sie mit Ihrer IP-Adresse unsere Seite besucht haben. Wenn Sie den “Like-Button” oder “Share-Button” anklicken während Sie in Ihrem SoundCloud- Benutzerkonto eingeloggt sind, können Sie die Inhalte unserer Seiten mit Ihrem SoundCloud-Profil verlinken und/oder teilen. Dadurch kann SoundCloud Ihrem Benutzerkonto den Besuch unserer Seiten zuordnen. Wir weisen darauf hin, dass wir als Anbieter der Seiten keine Kenntnis vom Inhalt der übermittelten Daten sowie deren Nutzung durch SoundCloud erhalten.</p><p><br></p><p>Die Nutzung von SoundCloud erfolgt auf Grundlage des Art. 6 Abs. 1 lit. f DSGVO. Der Websitebetreiber hat ein berechtigtes Interesse an einer möglichst umfangreichen Sichtbarkeit in den Sozialen Medien.</p><p><br></p><p>Weitere Informationen hierzu finden Sie in der Datenschutzerklärung von SoundCloud unter: <a href="https://soundcloud.com/pages/privacy" target="_blank" rel="noopener">https://soundcloud.com/pages/privacy</a>.</p><p><br></p><p>Wenn Sie nicht wünschen, dass SoundCloud den Besuch unserer Seiten Ihrem SoundCloud- Benutzerkonto zuordnet, loggen Sie sich bitte aus Ihrem SoundCloud-Benutzerkonto aus bevor Sie Inhalte des SoundCloud-Plugins aktivieren.</p>
-<h3>Veoh</h3> <p>Unsere Website nutzt Plugins des Videoportals Veoh. Anbieter ist die FC2, 4730 South Fort Apache Road, Suite 300, Las Vegas, NV 89147, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem Veoh-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Veoh hergestellt. Dabei wird dem Veoh-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Veoh Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Veoh eingeloggt sind oder keinen Account bei Veoh besitzen. Die von Veoh erfassten Informationen werden an den Veoh-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Veoh-Account eingeloggt sind, ermöglichen Sie Veoh, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Veoh-Account ausloggen.</p><p><br></p><p>Die Nutzung von Veoh erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Veoh unter: <a href="https://www.veoh.com/corporate/privacy-policy" target="_blank" rel="noopener">https://www.veoh.com/corporate/privacy-policy</a>.</p>
 <h3>Dailymotion</h3> <p>Unsere Website nutzt Plugins des Videoportals Dailymotion. Anbieter ist Dailymotion, 140 boulevard Malesherbes, 75017 Paris, Frankreich.</p><p><br></p><p>Wenn Sie eine unserer mit einem Dailymotion-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Dailymotion hergestellt. Dabei wird dem Dailymotion-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Dailymotion Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Dailymotion eingeloggt sind oder keinen Account bei Dailymotion besitzen.</p><p><br></p><p>Wenn Sie in Ihrem Dailymotion-Account eingeloggt sind, ermöglichen Sie Dailymotion, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Dailymotion-Account ausloggen.</p><p><br></p><p>Die Nutzung von Dailymotion erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Dailymotion unter: <a href="https://www.dailymotion.com/legal/privacy" target="_blank" rel="noopener">https://www.dailymotion.com/legal/privacy</a>.</p>
 <h3>GitHub</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes GitHub. Anbieter ist GitHub, Inc, 88 Colin P Kelly Jr St, San Francisco, CA 94107, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem GitHub-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von GitHub hergestellt. Dabei wird dem GitHub-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt GitHub Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei GitHub eingeloggt sind oder keinen Account bei GitHub besitzen. Die von GitHub erfassten Informationen werden an den GitHub-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem GitHub-Account eingeloggt sind, ermöglichen Sie GitHub, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem GitHub-Account ausloggen.</p><p><br></p><p>Die Nutzung von GitHub erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von GitHub unter: <a href="https://help.github.com/articles/github-privacy-statement/" target="_blank" rel="noopener">https://help.github.com/articles/github-privacy-statement/</a>.</p>
 <h3>Spotify</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes Spotify. Anbieter ist die Spotify AB, Birger Jarlsgatan 61, 113 56 Stockholm, Schweden.</p><p><br></p><p>Wenn Sie eine unserer mit einem Spotify-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Spotify hergestellt. Dabei wird dem Spotify-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Spotify Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Spotify eingeloggt sind oder keinen Account bei Spotify besitzen.</p><p><br></p><p>Wenn Sie in Ihrem Spotify-Account eingeloggt sind, ermöglichen Sie Spotify, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Spotify-Account ausloggen.</p><p><br></p><p>Die Nutzung von Spotify erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Spotify unter: <a href="https://www.spotify.com/de/legal/privacy-policy/" target="_blank" rel="noopener">https://www.spotify.com/de/legal/privacy-policy/</a>.</p>
 <h3>Instagram</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes Instagram. Anbieter ist Instagram Inc., 1601 Willow Road, Menlo Park, CA 94025, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem Instagram-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Instagram hergestellt. Dabei wird dem Instagram-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Instagram Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Instagram eingeloggt sind oder keinen Account bei Instagram besitzen. Die von Instagram erfassten Informationen werden an den Instagram-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Instagram-Account eingeloggt sind, ermöglichen Sie Instagram, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Instagram-Account ausloggen.</p><p><br></p><p>Die Nutzung von Instagram erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Instagram unter: <a href="https://instagram.com/about/legal/privacy/" target="_blank" rel="noopener">https://instagram.com/about/legal/privacy/</a>.</p>
-<h3>Imgur</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes Imgur. Anbieter ist Imgur, Inc., 415 Jackson Street, 2nd Floor, Suite 200, San Francisco, CA 94111, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem Imgur-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Imgur hergestellt. Dabei wird dem Imgur-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Imgur Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Imgur eingeloggt sind oder keinen Account bei Imgur besitzen. Die von Imgur erfassten Informationen werden an den Imgur-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Imgur-Account eingeloggt sind, ermöglichen Sie Imgur, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Imgur-Account ausloggen.</p><p><br></p><p>Die Nutzung von Imgur erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Imgur unter: <a href="https://imgur.com/privacy" target="_blank" rel="noopener">https://imgur.com/privacy</a>.</p>
 <h3>Twitch</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes Twitch. Anbieter ist Twitch Interactive, Inc., 225 Bush Street, 6th Floor, San Francisco, CA 94104, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem Twitch-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Twitch hergestellt. Dabei wird dem Twitch-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Twitch Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Twitch eingeloggt sind oder keinen Account bei Twitch besitzen. Die von Twitch erfassten Informationen werden an den Twitch-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Twitch-Account eingeloggt sind, ermöglichen Sie Twitch, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Twitch-Account ausloggen.</p><p><br></p><p>Die Nutzung von Twitch erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Twitch unter: <a href="https://www.twitch.tv/p/legal/privacy-policy/" target="_blank" rel="noopener">https://www.twitch.tv/p/legal/privacy-policy/</a>.</p>
 <h3>Twitter</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes Twitter. Anbieter ist Twitter Inc., 1355 Market Street, Suite 900, San Francisco, CA 94103, USA.</p><p><br></p><p>Wenn Sie eine unserer mit einem Twitter-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Twitter hergestellt. Dabei wird dem Twitter-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Twitter Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Twitter eingeloggt sind oder keinen Account bei Twitter besitzen. Die von Twitter erfassten Informationen werden an den Twitter-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Twitter-Account eingeloggt sind, ermöglichen Sie Twitter, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Twitter-Account ausloggen.</p><p><br></p><p>Die Nutzung von Twitter erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Twitter unter: <a href="https://twitter.com/de/privacy" target="_blank" rel="noopener">https://twitter.com/de/privacy</a>.</p>
+<h3>Facebook</h3> <p>Unsere Website nutzt Plugins des Online-Dienstes Facebook. Anbieter ist Facebook Ireland Limited, 4 Grand Canal Square, Dublin 2, Irland.</p><p><br></p><p>Wenn Sie eine unserer mit einem Facebook-Plugin ausgestatteten Seiten besuchen, wird eine Verbindung zu den Servern von Facebook hergestellt. Dabei wird dem Facebook-Server mitgeteilt, welche unserer Seiten Sie besucht haben. Zudem erlangt Facebook Ihre IP-Adresse. Dies gilt auch dann, wenn Sie nicht bei Facebook eingeloggt sind oder keinen Account bei Facebook besitzen. Die von Facebook erfassten Informationen werden an den Facebook-Server in den USA übermittelt.</p><p><br></p><p>Wenn Sie in Ihrem Facebook-Account eingeloggt sind, ermöglichen Sie Facebook, Ihr Surfverhalten direkt Ihrem persönlichen Profil zuzuordnen. Dies können Sie verhindern, indem Sie sich aus Ihrem Facebook-Account ausloggen.</p><p><br></p><p>Die Nutzung von Facebook erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote. Dies stellt ein berechtigtes Interesse im Sinne des Art. 6 Abs. 1 lit. f DSGVO dar.</p><p><br></p><p>Weitere Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Facebook unter: <a href="https://de-de.facebook.com/about/privacy/" target="_blank" rel="noopener">https://de-de.facebook.com/about/privacy/</a>.</p>
 
 <h2>6. Zahlungsanbieter</h2>
 <h3>PayPal</h3> <p>Auf unserer Website bieten wir u.a. die Bezahlung via PayPal an. Anbieter dieses Zahlungsdienstes ist die PayPal (Europe) S.à.r.l. et Cie, S.C.A., 22-24 Boulevard Royal, L-2449 Luxembourg (im Folgenden “PayPal”).</p><p><br></p><p>Wenn Sie die Bezahlung via PayPal auswählen, werden die von Ihnen eingegebenen Zahlungsdaten an PayPal übermittelt.</p><p><br></p><p>Die Übermittlung Ihrer Daten an PayPal erfolgt auf Grundlage von Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) und Art. 6 Abs. 1 lit. b DSGVO (Verarbeitung zur Erfüllung eines Vertrags). Sie haben die Möglichkeit, Ihre Einwilligung zur Datenverarbeitung jederzeit zu widerrufen. Ein Widerruf wirkt sich auf die Wirksamkeit von in der Vergangenheit liegenden Datenverarbeitungsvorgängen nicht aus.</p>]]></content>
@@ -822,4 +818,7 @@ E-Mail: [E-Mail-Adresse der verantwortlichen Stelle]</p><p><br></p><p>Verantwort
                        </content>
                </page>
        </import>
+       <delete>
+               <page identifier="com.woltlab.wcf.Mail" />
+       </delete>
 </data>
index 9fbd05189346bbdd7e25ad7ae9a3ccc8bdab1942..a09076a9f7812775516542806434d403e1647819 100644 (file)
@@ -2,4 +2,4 @@
        {include file='aclPermissions'}
 {/if}
 
-{include file='aclPermissionJavaScript' containerID=$field->getPrefixedId()|concat:'Container' categoryName=$field->getCategoryName() objectID=$field->getObjectID() objectTypeID=$field->getObjectType()->objectTypeID aclFormBuilderMode=true aclValuesFieldName=$field->getPrefixedId()}
+{include file='aclPermissionJavaScript' containerID=$field->getPrefixedId()|concat:'Container' categoryName=$field->getCategoryName() objectID=$field->getObjectID() objectTypeID=$field->getObjectType()->objectTypeID aclFormBuilderMode=$field->getDocument()->isAjax() aclValuesFieldName=$field->getPrefixedId()}
diff --git a/com.woltlab.wcf/templates/__audioAttachmentBBCode.tpl b/com.woltlab.wcf/templates/__audioAttachmentBBCode.tpl
new file mode 100644 (file)
index 0000000..1adb76e
--- /dev/null
@@ -0,0 +1,22 @@
+<span class="mediaBBCode">
+       <audio src="{$attachment->getLink()}" style="display: none;" id="attachmentAudio_{$attachmentIdentifier}" controls></audio>
+       
+       <span class="mediaBBCodeCaption">
+               <a href="{$attachment->getLink()}">{$attachment->filename}</a>
+       </span>
+</span>
+
+<script data-relocate="true">
+       (function () {
+               {* try to determine if browser might be able to play audio *}
+               var audio = elById('attachmentAudio_{@$attachmentIdentifier}');
+               var canPlayType = audio.canPlayType('{$attachment->fileType}');
+               
+               if (canPlayType === '') {
+                       elRemove(audio);
+               }
+               else {
+                       elShow(audio);
+               }
+       })();
+</script>
diff --git a/com.woltlab.wcf/templates/__checkboxFormField.tpl b/com.woltlab.wcf/templates/__checkboxFormField.tpl
new file mode 100644 (file)
index 0000000..af2e22d
--- /dev/null
@@ -0,0 +1,14 @@
+<dl id="{@$field->getPrefixedId()}Container" {if !$field->getClasses()|empty} class="{implode from=$field->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{foreach from=$field->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{if !$field->checkDependencies()} style="display: none;"{/if}>
+       <dt></dt>
+       <dd>
+               <label>
+                       <input type="checkbox" id="{@$field->getPrefixedId()}" name="{@$field->getPrefixedId()}" value="1"{if $field->isRequired()} required{/if}{if $field->isImmutable()} disabled{/if}{if $field->getValue()} checked{/if}>
+                       {@$field->getLabel()}{if $field->isRequired()} <span class="formFieldRequired">*</span>{/if}
+               </label>
+               
+               {include file='__formFieldDescription'}
+               {include file='__formFieldErrors'}
+               {include file='__formFieldDependencies'}
+               {include file='__formFieldDataHandler'}
+       </dd>
+</dl>
index 3e6d952a8ad9779b0b0ef960efa28bd033ae1a8c..7cace22764022319c7088f02909e0b99f1a09ffa 100644 (file)
@@ -1,17 +1,17 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.comment.add': '{lang}wcf.comment.add{/lang}',
-                       'wcf.comment.button.response.add': '{lang}wcf.comment.button.response.add{/lang}',
-                       'wcf.comment.delete.confirmMessage': '{lang}wcf.comment.delete.confirmMessage{/lang}',
-                       'wcf.comment.description': '{lang}wcf.comment.description{/lang}',
-                       'wcf.comment.guestDialog.title': '{lang}wcf.comment.guestDialog.title{/lang}',
-                       'wcf.comment.more': '{lang}wcf.comment.more{/lang}',
-                       'wcf.comment.response.add': '{lang}wcf.comment.response.add{/lang}',
-                       'wcf.comment.response.more': '{lang}wcf.comment.response.more{/lang}',
-                       'wcf.message.error.editorAlreadyInUse': '{lang}wcf.message.error.editorAlreadyInUse{/lang}',
-                       'wcf.moderation.report.reportContent': '{lang}wcf.moderation.report.reportContent{/lang}',
-                       'wcf.moderation.report.success': '{lang}wcf.moderation.report.success{/lang}'
+                       'wcf.comment.add': '{jslang}wcf.comment.add{/jslang}',
+                       'wcf.comment.button.response.add': '{jslang}wcf.comment.button.response.add{/jslang}',
+                       'wcf.comment.delete.confirmMessage': '{jslang}wcf.comment.delete.confirmMessage{/jslang}',
+                       'wcf.comment.description': '{jslang}wcf.comment.description{/jslang}',
+                       'wcf.comment.guestDialog.title': '{jslang}wcf.comment.guestDialog.title{/jslang}',
+                       'wcf.comment.more': '{jslang}wcf.comment.more{/jslang}',
+                       'wcf.comment.response.add': '{jslang}wcf.comment.response.add{/jslang}',
+                       'wcf.comment.response.more': '{jslang}wcf.comment.response.more{/jslang}',
+                       'wcf.message.error.editorAlreadyInUse': '{jslang}wcf.message.error.editorAlreadyInUse{/jslang}',
+                       'wcf.moderation.report.reportContent': '{jslang}wcf.moderation.report.reportContent{/jslang}',
+                       'wcf.moderation.report.success': '{jslang}wcf.moderation.report.success{/jslang}'
                });
                
                new {if $commentHandlerClass|isset}{@$commentHandlerClass}{else}WCF.Comment.Handler{/if}('{@$commentContainerID}');
@@ -28,7 +28,8 @@
                                        // selectors
                                        containerSelector: '#{@$commentContainerID} .commentResponse',
                                        summaryListSelector: '.reactionSummaryList',
-                                       isButtonGroupNavigation: true
+                                       isButtonGroupNavigation: true,
+                                       buttonSelector: '.reactButtonCommentResponse'
                                });
                        });
                {/if}
index 53fb5116bfbca5182160b3fe4aa7298805d7929e..d263258794ebb3d08fa00c78e29fbd4a746c2da7 100644 (file)
 {/if}
 
 {if $form->showsSuccessMessage()}
-       <p class="success">{@$form->getSuccessMessage()}</p>
+       <p class="success">
+               <span>{@$form->getSuccessMessage()}</span>
+               {if !$objectEditLink|empty}
+                       <span>{lang}wcf.global.success.add.editCreatedObject{/lang}</span>
+               {/if}
+       </p>
 {/if}
 
 {if $form->isAjax()}
        </form>
 {/if}
 
+{if $form->needsRequiredFieldsInfo()}
+       <div class="section requiredFieldsInfo">
+               <p><span class="formFieldRequired">*</span> {lang}wcf.global.form.required{/lang}</p>
+               
+               {event name='requiredFieldsInfo'}
+       </div>
+{/if}
+
 <script data-relocate="true">
        {* after all dependencies have been added, check them *}
        require(['WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager'], function(FormBuilderFieldDependencyManager) {
index eec1c6606bafb02b1a7f00040ff9c4a65e161d2b..b7ff418e62a84edc09bac06d4757d816b50fca80 100644 (file)
@@ -6,11 +6,11 @@
        {if $container->getLabel() !== null}
                {if $container->getDescription() !== null}
                        <header class="sectionHeader">
-                               <h2 class="sectionTitle">{@$container->getLabel()}</h2>
+                               <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
                                <p class="sectionDescription">{@$container->getDescription()}</p>
                        </header>
                {else}
-                       <h2 class="sectionTitle">{@$container->getLabel()}</h2>
+                       <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
                {/if}
        {/if}
        
index 752234e70ef002a27e58a2983a466990c10298c6..0f752fcb9e3bc805eacf8c69028c18399ef0e14c 100644 (file)
@@ -3,7 +3,7 @@
        *}{foreach from=$field->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{*
        *}{if !$field->checkDependencies()} style="display: none;"{/if}{*
 *}>
-       <dt>{if $field->getLabel() !== null}<label for="{@$field->getPrefixedId()}">{@$field->getLabel()}</label>{/if}</dt>
+       <dt>{if $field->getLabel() !== null}<label for="{@$field->getPrefixedId()}">{@$field->getLabel()}</label>{if $field->isRequired()} <span class="formFieldRequired">*</span>{/if}{/if}</dt>
        <dd>
                {@$field->getFieldHtml()}
                
index 90bde6516f307ddc3b32f678cdb75cd9f26470ec..a3ca75b729cf5359c43f1e36e46b9fa6ba0de937 100644 (file)
@@ -7,7 +7,7 @@
                        <ul class="scrollableDropdownMenu">
                                {foreach from=$field->getLabelGroup() item=label}
                                        <li data-label-id="{@$label->labelID}">
-                                               <span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span>
+                                               <span>{@$label->render()}</span>
                                        </li>
                                {/foreach}
                        </ul>
@@ -26,8 +26,8 @@
 <script data-relocate="true">
        require(['Dom/Util', 'Language', 'WoltLabSuite/Core/Form/Builder/Field/Controller/Label'], function(DomUtil, Language, FormBuilderFieldLabel) {
                Language.addObject({
-                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
-                       'wcf.label.withoutSelection': '{lang}wcf.label.withoutSelection{/lang}'
+                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
+                       'wcf.label.withoutSelection': '{jslang}wcf.label.withoutSelection{/jslang}'
                });
                
                new FormBuilderFieldLabel(
diff --git a/com.woltlab.wcf/templates/__labelSelection.tpl b/com.woltlab.wcf/templates/__labelSelection.tpl
new file mode 100644 (file)
index 0000000..eb42c97
--- /dev/null
@@ -0,0 +1,32 @@
+{foreach from=$labelGroups item=labelGroup}
+       {if $labelGroup|count}
+               <dt><label>{$labelGroup->getTitle()}</label></dt>
+               <dd>
+                       <ul class="labelList jsOnly">
+                               <li class="dropdown labelChooser" id="labelGroup{@$labelGroup->groupID}" data-group-id="{@$labelGroup->groupID}">
+                                       <div class="dropdownToggle" data-toggle="labelGroup{@$labelGroup->groupID}"><span class="badge label">{lang}wcf.label.none{/lang}</span></div>
+                                       <div class="dropdownMenu">
+                                               <ul class="scrollableDropdownMenu">
+                                                       {foreach from=$labelGroup item=label}
+                                                               <li data-label-id="{@$label->labelID}"><span>{@$label->render()}</span></li>
+                                                       {/foreach}
+                                               </ul>
+                                       </div>
+                               </li>
+                       </ul>
+                       {if $noLabelSelectionNoScript|empty}
+                               <noscript>
+                                       {foreach from=$labelGroups item=labelGroup}
+                                               <select name="labelIDs[{@$labelGroup->groupID}]">
+                                                       <option value="0">{lang}wcf.label.none{/lang}</option>
+                                                       <option value="-1">{lang}wcf.label.withoutSelection{/lang}</option>
+                                                       {foreach from=$labelGroup item=label}
+                                                               <option value="{@$label->labelID}"{if $labelIDs[$labelGroup->groupID]|isset && $labelIDs[$labelGroup->groupID] == $label->labelID} selected{/if}>{$label->getTitle()}</option>
+                                                       {/foreach}
+                                               </select>
+                                       {/foreach}
+                               </noscript>
+                       {/if}
+               </dd>
+       {/if}
+{/foreach}
index fcc255f6b04d71d9f7b2663f36ec34f2c1124671..5bdd92d00db4a1fdf96d092d29bff0fd408d455a 100644 (file)
@@ -4,7 +4,7 @@
                
                {foreach from=$menuItemNodeList item=menuItemNode}
                        <li class="{if $menuItemNode->isActiveNode()}active{/if}{if $menuItemNode->hasChildren()} boxMenuHasChildren{/if}" data-identifier="{@$menuItemNode->identifier}">
-                               <a href="{$menuItemNode->getURL()}" class="boxMenuLink"{if $menuItemNode->isExternalLink()}{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}{/if}{if $menuItemNode->isActiveNode()} aria-current="page"{/if}>
+                               <a {anchorAttributes url=$menuItemNode->getURL() appendClassname=false} class="boxMenuLink"{if $menuItemNode->isActiveNode()} aria-current="page"{/if}>
                                        <span class="boxMenuLinkTitle">{$menuItemNode->getTitle()}</span>
                                        {if $menuItemNode->getOutstandingItems() > 0}
                                                <span class="boxMenuLinkOutstandingItems badge badgeUpdate" aria-label="{lang}wcf.page.menu.outstandingItems{/lang}">{#$menuItemNode->getOutstandingItems()}</span>
index e1d8fddc0c933cfaab14724a64cc66798aba6944..c03f5b9f89038e28917dfdcd68c58cbff119bb34 100644 (file)
@@ -2,8 +2,8 @@
        <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.poll.button.addOption': '{lang}wcf.poll.button.addOption{/lang}',
-                               'wcf.poll.button.removeOption': '{lang}wcf.poll.button.removeOption{/lang}'
+                               'wcf.poll.button.addOption': '{jslang}wcf.poll.button.addOption{/jslang}',
+                               'wcf.poll.button.removeOption': '{jslang}wcf.poll.button.removeOption{/jslang}'
                        });
                        
                        new WCF.Poll.Management('pollOptionContainer', [ {implode from=$pollOptions item=pollOption}{ optionID: {@$pollOption[optionID]}, optionValue: '{$pollOption[optionValue]|encodeJS}' }{/implode} ], {@POLL_MAX_OPTIONS});
index 48f4719005a44061f7a2b3855283baa40adf45c8..20c654c789c3d0da8784c33966b9ff2b54920f0b 100644 (file)
@@ -2,10 +2,10 @@
        <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.poll.button.addOption': '{lang}wcf.poll.button.addOption{/lang}',
-                               'wcf.poll.button.removeOption': '{lang}wcf.poll.button.removeOption{/lang}',
-                               'wcf.poll.endTime.error.invalid': '{lang}wcf.poll.endTime.error.invalid{/lang}',
-                               'wcf.poll.maxVotes.error.invalid': '{lang}wcf.poll.maxVotes.error.invalid{/lang}'
+                               'wcf.poll.button.addOption': '{jslang}wcf.poll.button.addOption{/jslang}',
+                               'wcf.poll.button.removeOption': '{jslang}wcf.poll.button.removeOption{/jslang}',
+                               'wcf.poll.endTime.error.invalid': '{jslang}wcf.poll.endTime.error.invalid{/jslang}',
+                               'wcf.poll.maxVotes.error.invalid': '{jslang}wcf.poll.maxVotes.error.invalid{/jslang}'
                        });
                        
                        new WCF.Poll.Management(
@@ -70,4 +70,4 @@
                
                {event name='fields'}
        </div>
-{/if}
\ No newline at end of file
+{/if}
index fd0798d128460f82fa181a63153db1e9385ac5d0..e8c9c7b0da358c1050ef9509139adb93c7f78a48 100644 (file)
@@ -1,12 +1,12 @@
 WCF.Language.addObject({
-       'wcf.message.quote.insertAllQuotes': '{lang}wcf.message.quote.insertAllQuotes{/lang}',
-       'wcf.message.quote.insertSelectedQuotes': '{lang}wcf.message.quote.insertSelectedQuotes{/lang}',
-       'wcf.message.quote.manageQuotes': '{lang}wcf.message.quote.manageQuotes{/lang}',
-       'wcf.message.quote.quoteSelected': '{lang}wcf.message.quote.quoteSelected{/lang}',
-       'wcf.message.quote.quoteAndReply': '{lang}wcf.message.quote.quoteAndReply{/lang}',
-       'wcf.message.quote.removeAllQuotes': '{lang}wcf.message.quote.removeAllQuotes{/lang}',
-       'wcf.message.quote.removeSelectedQuotes': '{lang}wcf.message.quote.removeSelectedQuotes{/lang}',
-       'wcf.message.quote.showQuotes': '{lang}wcf.message.quote.showQuotes{/lang}'
+       'wcf.message.quote.insertAllQuotes': '{jslang}wcf.message.quote.insertAllQuotes{/jslang}',
+       'wcf.message.quote.insertSelectedQuotes': '{jslang}wcf.message.quote.insertSelectedQuotes{/jslang}',
+       'wcf.message.quote.manageQuotes': '{jslang}wcf.message.quote.manageQuotes{/jslang}',
+       'wcf.message.quote.quoteSelected': '{jslang}wcf.message.quote.quoteSelected{/jslang}',
+       'wcf.message.quote.quoteAndReply': '{jslang}wcf.message.quote.quoteAndReply{/jslang}',
+       'wcf.message.quote.removeAllQuotes': '{jslang}wcf.message.quote.removeAllQuotes{/jslang}',
+       'wcf.message.quote.removeSelectedQuotes': '{jslang}wcf.message.quote.removeSelectedQuotes{/jslang}',
+       'wcf.message.quote.showQuotes': '{jslang __literal=true}wcf.message.quote.showQuotes{/jslang}'
 });
 
 {if !$wysiwygSelector|isset}{assign var=wysiwygSelector value=''}{/if}
index 81e6cdcc7d7ded7ffbc0fa638077c5cbcfca4ce4..c13cdd7bef5f13bec5ed0100501fa81d94b8baa4 100644 (file)
@@ -2,13 +2,13 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                        Language.addObject({
-                               'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                               'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                               'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                               'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                               'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                               'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                               'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                               'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                               'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                               'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                               'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                               'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                               'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                               'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                        });
                        
                        new UiItemListFilter('{@$field->getPrefixedId()}_list');
index 6e3460dc2339285ddf1d9509c331883a2568c878..f18e9187627b79476da384aa9b52a3eb708bafcc 100644 (file)
@@ -10,9 +10,9 @@
                'WoltLabSuite/Core/Ui/Poll/Editor'
        ], function(DomTraverse, DomUtil, EventHandler, Language, FormBuilderManager, UiPollEditor) {
                Language.addObject({
-                       'wcf.poll.button.addOption': '{lang}wcf.poll.button.addOption{/lang}',
-                       'wcf.poll.button.removeOption': '{lang}wcf.poll.button.removeOption{/lang}',
-                       'wcf.poll.maxVotes.error.invalid': '{lang}wcf.poll.maxVotes.error.invalid{/lang}'
+                       'wcf.poll.button.addOption': '{jslang}wcf.poll.button.addOption{/jslang}',
+                       'wcf.poll.button.removeOption': '{jslang}wcf.poll.button.removeOption{/jslang}',
+                       'wcf.poll.maxVotes.error.invalid': '{jslang}wcf.poll.maxVotes.error.invalid{/jslang}'
                });
                
                var pollEditor = new UiPollEditor(
index f7c87c079d3ec92d64b4bf22cb9d90db1f7ed7de..80a54f9ef59405826a0aaca26e399cfe3aa159c3 100644 (file)
@@ -28,7 +28,7 @@
                        new MediaManagerSelect({
                                buttonClass: 'jsMediaSelectButton_{@$field->getPrefixedId()}',
                                {if $field->isImageOnly()}
-                                       dialogTitle: '{lang}wcf.media.chooseImage{/lang}',
+                                       dialogTitle: '{jslang}wcf.media.chooseImage{/jslang}',
                                        imagesOnly: 1
                                {/if}
                        });
index c3209915a6fda7dc309a26d358e190210a375bd0..6c4f0aad706a182ef7aa5f98dc3bde5f5fa74ed5 100644 (file)
@@ -2,13 +2,13 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                        Language.addObject({
-                               'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                               'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                               'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                               'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                               'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                               'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                               'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                               'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                               'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                               'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                               'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                               'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                               'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                               'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                        });
                        
                        new UiItemListFilter('{@$field->getPrefixedId()}_list');
index 4343043bfbc99c7a0d03c3d267647133ff454353..2521c6c5681f0a04068dc129af27297e2e3c6936 100644 (file)
@@ -1,19 +1,22 @@
-<span id="attachmentVideo_{@$attachmentIdentifier}" class="videoContainer" style="display: none;">
-       <video src="{link controller='Attachment' object=$attachment}{/link}" controls></video>
+<span class="mediaBBCode">
+       <video src="{$attachment->getLink()}" style="display: none;" id="attachmentVideo_{$attachmentIdentifier}" controls></video>
+       
+       <span class="mediaBBCodeCaption">
+               <a href="{$attachment->getLink()}">{$attachment->filename}</a>
+       </span>
 </span>
 
-<a id="attachmentVideoLink_{@$attachmentIdentifier}" href="{link controller='Attachment' object=$attachment}{/link}">{$attachment->filename}</a>
-
 <script data-relocate="true">
-       {* try to determine if browser might be able to play video *}
-       var video = elById('attachmentVideo_{@$attachmentIdentifier}');
-       var canPlayType = elCreate('video').canPlayType('{$attachment->fileType}');
-       
-       if (canPlayType === '') {
-               elRemove(video);
-       }
-       else {
-               elShow(video);
-               elRemove(elById('attachmentVideoLink_{@$attachmentIdentifier}'));
-       }
+       (function () {
+               {* try to determine if browser might be able to play video *}
+               var video = elById('attachmentVideo_{@$attachmentIdentifier}');
+               var canPlayType = video.canPlayType('{$attachment->fileType}');
+               
+               if (canPlayType === '') {
+                       elRemove(video);
+               }
+               else {
+                       elShow(video);
+               }
+       })();
 </script>
index 03a1f583e2150ea6da7658b2f4243865d30f064d..a23046b3b6938fd8a58434f9eba6d422fac4531b 100644 (file)
@@ -1,7 +1,6 @@
 <ul id="{@$field->getPrefixedID()}_attachmentList" {*
        *}class="formAttachmentList"{*
-       *}{if !$field->getAttachmentHandler()->getAttachmentList()|count} style="display: none"{/if} {*
-       *}data-enable-thumbnails="{if ATTACHMENT_ENABLE_THUMBNAILS}true{else}false{/if}"{*
+       *}{if !$field->getAttachmentHandler()->getAttachmentList()|count} style="display: none"{/if}{*
 *}>
        {foreach from=$field->getAttachmentHandler()->getAttachmentList() item=$attachment}
                <li class="box64" {*
                        *}data-is-image="{@$attachment->isImage}"{*
                *}>
                        {if $attachment->tinyThumbnailType}
-                               <img src="{link controller='Attachment' object=$attachment}tiny=1{/link}" alt="" class="attachmentTinyThumbnail">
+                               <img src="{$attachment->getThumbnailLink('tiny')}" alt="" class="attachmentTinyThumbnail">
                        {else}
                                <span class="icon icon64 fa-{@$attachment->getIconName()}"></span>
                        {/if}
                        
                        <div>
                                <div>
-                                       <p><a href="{link controller='Attachment' object=$attachment}{/link}" target="_blank"{if $attachment->isImage} title="{$attachment->filename}" class="jsImageViewer"{/if}>{$attachment->filename}</a></p>
+                                       <p><a href="{$attachment->getLink()}" target="_blank"{if $attachment->isImage} title="{$attachment->filename}" class="jsImageViewer"{/if}>{$attachment->filename}</a></p>
                                        <small>{@$attachment->filesize|filesize}</small>
                                </div>
                                
@@ -26,9 +25,9 @@
                                        <li><span class="button small jsDeleteButton" data-object-id="{@$attachment->attachmentID}" data-confirm-message="{lang}wcf.attachment.delete.sure{/lang}">{lang}wcf.global.button.delete{/lang}</span></li>
                                        {if $attachment->isImage}
                                                {if $attachment->thumbnailType}
-                                                       <li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="{@$attachment->attachmentID}" data-url="{link controller='Attachment' object=$attachment}thumbnail=1{/link}">{lang}wcf.attachment.insertThumbnail{/lang}</span></li>
+                                                       <li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="{@$attachment->attachmentID}" data-url="{$attachment->getThumbnailLink('thumbnail')}">{lang}wcf.attachment.insertThumbnail{/lang}</span></li>
                                                {/if}
-                                               <li><span class="button small jsButtonAttachmentInsertFull" data-object-id="{@$attachment->attachmentID}" data-url="{link controller='Attachment' object=$attachment}{/link}">{lang}wcf.attachment.insertFull{/lang}</span></li>
+                                               <li><span class="button small jsButtonAttachmentInsertFull" data-object-id="{@$attachment->attachmentID}" data-url="{$attachment->getLink()}">{lang}wcf.attachment.insertFull{/lang}</span></li>
                                        {else}
                                                <li><span class="button small jsButtonInsertAttachment" data-object-id="{@$attachment->attachmentID}">{lang}wcf.attachment.insert{/lang}</span></li>
                                        {/if}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.attachment.upload.error.invalidExtension': '{lang}wcf.attachment.upload.error.invalidExtension{/lang}',
-                       'wcf.attachment.upload.error.tooLarge': '{lang}wcf.attachment.upload.error.tooLarge{/lang}',
-                       'wcf.attachment.upload.error.reachedLimit': '{lang}wcf.attachment.upload.error.reachedLimit{/lang}',
-                       'wcf.attachment.upload.error.reachedRemainingLimit': '{lang}wcf.attachment.upload.error.reachedRemainingLimit{/lang}',
-                       'wcf.attachment.upload.error.uploadFailed': '{lang}wcf.attachment.upload.error.uploadFailed{/lang}',
-                       'wcf.attachment.upload.error.uploadPhpLimit': '{lang}wcf.attachment.upload.error.uploadPhpLimit{/lang}',
-                       'wcf.attachment.insert': '{lang}wcf.attachment.insert{/lang}',
-                       'wcf.attachment.insertAll': '{lang}wcf.attachment.insertAll{/lang}',
-                       'wcf.attachment.insertFull': '{lang}wcf.attachment.insertFull{/lang}',
-                       'wcf.attachment.insertThumbnail': '{lang}wcf.attachment.insertThumbnail{/lang}',
-                       'wcf.attachment.delete.sure': '{lang}wcf.attachment.delete.sure{/lang}'
+                       'wcf.attachment.upload.error.invalidExtension': '{jslang}wcf.attachment.upload.error.invalidExtension{/jslang}',
+                       'wcf.attachment.upload.error.tooLarge': '{jslang}wcf.attachment.upload.error.tooLarge{/jslang}',
+                       'wcf.attachment.upload.error.reachedLimit': '{jslang}wcf.attachment.upload.error.reachedLimit{/jslang}',
+                       'wcf.attachment.upload.error.reachedRemainingLimit': '{jslang}wcf.attachment.upload.error.reachedRemainingLimit{/jslang}',
+                       'wcf.attachment.upload.error.uploadFailed': '{jslang}wcf.attachment.upload.error.uploadFailed{/jslang}',
+                       'wcf.attachment.upload.error.uploadPhpLimit': '{jslang}wcf.attachment.upload.error.uploadPhpLimit{/jslang}',
+                       'wcf.attachment.insert': '{jslang}wcf.attachment.insert{/jslang}',
+                       'wcf.attachment.insertAll': '{jslang}wcf.attachment.insertAll{/jslang}',
+                       'wcf.attachment.insertFull': '{jslang}wcf.attachment.insertFull{/jslang}',
+                       'wcf.attachment.insertThumbnail': '{jslang}wcf.attachment.insertThumbnail{/jslang}',
+                       'wcf.attachment.delete.sure': '{jslang}wcf.attachment.delete.sure{/jslang}'
                });
                
                new WCF.Attachment.Upload(
index 81f2deba4b30d10a424842d760faeb5b9bc17369..2299dd3e19d17f42e0303fb4158f5f926b16559e 100644 (file)
@@ -1,16 +1,16 @@
 <script data-relocate="true">
        require(['Language'], function (Language) {
                Language.addObject({
-                       'wcf.article.search': '{lang}wcf.article.search{/lang}',
-                       'wcf.article.search.error.tooShort': '{lang}wcf.article.search.error.tooShort{/lang}',
-                       'wcf.article.search.error.noResults': '{lang}wcf.article.search.error.noResults{/lang}',
-                       'wcf.article.search.name': '{lang}wcf.article.search.name{/lang}',
-                       'wcf.article.search.results': '{lang}wcf.article.search.results{/lang}',
-                       'wcf.page.search': '{lang}wcf.page.search{/lang}',
-                       'wcf.page.search.error.tooShort': '{lang}wcf.page.search.error.tooShort{/lang}',
-                       'wcf.page.search.error.noResults': '{lang}wcf.page.search.error.noResults{/lang}',
-                       'wcf.page.search.name': '{lang}wcf.page.search.name{/lang}',
-                       'wcf.page.search.results': '{lang}wcf.page.search.results{/lang}',
+                       'wcf.article.search': '{jslang}wcf.article.search{/jslang}',
+                       'wcf.article.search.error.tooShort': '{jslang}wcf.article.search.error.tooShort{/jslang}',
+                       'wcf.article.search.error.noResults': '{jslang}wcf.article.search.error.noResults{/jslang}',
+                       'wcf.article.search.name': '{jslang}wcf.article.search.name{/jslang}',
+                       'wcf.article.search.results': '{jslang}wcf.article.search.results{/jslang}',
+                       'wcf.page.search': '{jslang}wcf.page.search{/jslang}',
+                       'wcf.page.search.error.tooShort': '{jslang}wcf.page.search.error.tooShort{/jslang}',
+                       'wcf.page.search.error.noResults': '{jslang}wcf.page.search.error.noResults{/jslang}',
+                       'wcf.page.search.name': '{jslang}wcf.page.search.name{/jslang}',
+                       'wcf.page.search.results': '{jslang}wcf.page.search.results{/jslang}',
                });
        })
 </script>
@@ -20,8 +20,8 @@
        , '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabPage.js?v={@LAST_UPDATE_TIME}'
 {/capture}
 {capture append='__redactorConfig'}
-       buttonOptions.woltlabArticle = { icon: 'fa-file-word-o', title: '{lang}wcf.editor.button.article{/lang}' };
-       buttonOptions.woltlabPage = { icon: 'fa-file-text-o', title: '{lang}wcf.editor.button.page{/lang}' };
+       buttonOptions.woltlabArticle = { icon: 'fa-file-word-o', title: '{jslang}wcf.editor.button.article{/jslang}' };
+       buttonOptions.woltlabPage = { icon: 'fa-file-text-o', title: '{jslang}wcf.editor.button.page{/jslang}' };
        
        buttons.push('woltlabPage');
        buttons.push('woltlabArticle');
index 6501f1538e653fa352041977842197e1fead799b..d61999dfcd6ce5d7fa1fbcacb9b242a91dcf9c77 100644 (file)
@@ -7,7 +7,7 @@
 <script data-relocate="true">
        require(['Language'], function(Language) {
                Language.addObject({
-                       'wcf.global.preview': '{lang}wcf.global.preview{/lang}'
+                       'wcf.global.preview': '{jslang}wcf.global.preview{/jslang}'
                });
                
                new WCF.Message.DefaultPreview({
index cc35e9d75f238ceb60f91792500c6f9c742ba13a..291ce150b110fcf4168a361f39d54843dee65ce3 100644 (file)
                        </dl>
                        
                        {event name='changePasswordFields'}
+                       
+                       <script data-relocate="true">
+                               require(['WoltLabSuite/Core/Ui/User/PasswordStrength', 'Language'], function (PasswordStrength, Language) {
+                                       {include file='passwordStrengthLanguage'}
+                                       
+                                       var relatedInputs = [];
+                                       if (elById('username')) relatedInputs.push(elById('username'));
+                                       if (elById('email')) relatedInputs.push(elById('email'));
+                                       
+                                       new PasswordStrength(elById('newPassword'), {
+                                               relatedInputs: relatedInputs,
+                                               staticDictionary: [
+                                                       '{$__wcf->user->username|encodeJS}',
+                                                       '{$__wcf->user->email|encodeJS}',
+                                               ]
+                                       });
+                               })
+                       </script>
                </section>
        {/if}
        
                        
                        {event name='changeEmailFields'}
                        
-                       {if REGISTER_ACTIVATION_METHOD == 1 && $__wcf->getUser()->reactivationCode != 0}
+                       {if $__wcf->user->mustSelfEmailConfirm() && $__wcf->getUser()->reactivationCode != 0}
                                <dl>
                                        <dt></dt>
                                        <dd>
index bff372d5e1ecd32cdfef9471f7e46e2e8dfb4206..a1a07d3483f662ee48af03476010f3ff52f9893b 100644 (file)
@@ -1,11 +1,11 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acl.option.deny': '{lang}wcf.acl.option.deny{/lang}',
-                       'wcf.acl.option.fullAccess': '{lang}wcf.acl.option.fullAccess{/lang}',
-                       'wcf.acl.option.grant': '{lang}wcf.acl.option.grant{/lang}',
-                       'wcf.acl.search.user.description': '{lang}wcf.acl.search.user.description{/lang}',
-                       'wcf.acl.search.description': '{lang}wcf.acl.search.description{/lang}'
+                       'wcf.acl.option.deny': '{jslang}wcf.acl.option.deny{/jslang}',
+                       'wcf.acl.option.fullAccess': '{jslang}wcf.acl.option.fullAccess{/jslang}',
+                       'wcf.acl.option.grant': '{jslang}wcf.acl.option.grant{/jslang}',
+                       'wcf.acl.search.user.description': '{jslang}wcf.acl.search.user.description{/jslang}',
+                       'wcf.acl.search.description': '{jslang}wcf.acl.search.description{/jslang}'
                });
        });
-</script>
\ No newline at end of file
+</script>
index 160f460e893489da307404eb42fc158de6655925..dff84764197b3c2f58df70e53b41bafd8b14022e 100644 (file)
@@ -1,6 +1,10 @@
-{capture assign='pageTitle'}{$articleContent->title}{/capture}
+{capture assign='pageTitle'}{if $articleContent->metaTitle}{$articleContent->metaTitle}{else}{$articleContent->title}{/if}{/capture}
 
 {capture assign='headContent'}
+       {if $articleContent->metaDescription}
+               <meta name="description" content="{$articleContent->metaDescription}">
+       {/if}
+       
        <script type="application/ld+json">
                {
                        "@context": "http://schema.org",
index 68dfff497e7def488d945626cd67d68bf54a535b..b94e36991c37ce6f5a93e639773065249dc28a58 100644 (file)
                                {/foreach}
                        </ol>
                        {if $__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.FooterMenu')}
-                               <ol>
-                                       {foreach from=$__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.FooterMenu')->getMenu()->getMenuItemNodeList() item=menuItemNode}
-                                               <li><a href="{$menuItemNode->getURL()}">{$menuItemNode->getTitle()}</a></li>
-                                       {/foreach}
-                               </ol>
+                               {hascontent}
+                                       <ol>
+                                               {content}       
+                                                       {foreach from=$__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.FooterMenu')->getMenu()->getMenuItemNodeList() item=menuItemNode}
+                                                               {if $menuItemNode->getDepth() == 1 || $menuItemNode->getParentNode()->isActiveNode()}
+                                                               <li>
+                                                                       <a href="{$menuItemNode->getURL()}">{$menuItemNode->getTitle()}</a>
+               
+                                                                       {if $menuItemNode->hasChildren() && $menuItemNode->isActiveNode()}<ol>{else}</li>{/if}
+               
+                                                                       {if !$menuItemNode->hasChildren() && $menuItemNode->isLastSibling()}
+                                                                               {@"</ol></li>"|str_repeat:$menuItemNode->getOpenParentNodes()}
+                                                                       {/if}
+                                                               {/if}
+                                                       {/foreach}
+                                               {/content}
+                                       </ol>
+                               {/hascontent}
                        {/if}
                        <h3>{lang}wcf.menu.page.location{/lang}</h3>
                        <ol class="breadcrumbs">
index 31b3c23fc383bea21527f7b026152ac804bcd6a5..78ca050c65d7fb53329ef1028b1beee57455749c 100644 (file)
                                overflow: auto;
                                padding: 10px;
                        }
+                       
+                       .unknownDimensionContainer {
+                               position: relative;
+                               width: 384px;
+                               height: 216px;
+                               max-width: 100%;
+                               display: inline-block;
+                       }
+                       
+                       .unknownDimensionContainer amp-img img {
+                               object-fit: contain;
+                       }
                </style>
                {literal}<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>{/literal}
                <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
index 9cb2f6d7926a13792c57488d470eeb9d21564181..536662ae5b3a2848b17859c2ceb69726ef5245c6 100644 (file)
@@ -1,4 +1,4 @@
-{capture assign='pageTitle'}{$articleContent->title}{/capture}
+{capture assign='pageTitle'}{if $articleContent->metaTitle}{$articleContent->metaTitle}{else}{$articleContent->title}{/if}{/capture}
 
 {assign var='__mainItemScope' value='itemprop="mainEntity" itemscope itemtype="http://schema.org/Article"'}
 
@@ -12,7 +12,7 @@
                                                <span class="icon icon16 fa-tags"></span>
                                                <ul class="labelList">
                                                        {foreach from=$article->getLabels() item=label}
-                                                               <li><span class="label badge{if $label->getClassNames()} {$label->getClassNames()}{/if}">{$label->getTitle()}</span></li>
+                                                               <li>{@$label->render()}</li>
                                                        {/foreach}
                                                </ul>
                                        </li>
@@ -21,8 +21,8 @@
                                <li itemprop="author" itemscope itemtype="http://schema.org/Person">
                                        <span class="icon icon16 fa-user"></span>
                                        {if $article->userID}
-                                               <a href="{link controller='User' id=$article->userID title=$article->username}{/link}" class="userLink" data-user-id="{@$article->userID}" itemprop="url">
-                                                       <span itemprop="name">{$article->username}</span>
+                                               <a href="{$article->getUserProfile()->getLink()}" class="userLink" data-object-id="{@$article->userID}" itemprop="url">
+                                                       <span itemprop="name">{@$article->getUserProfile()->getFormattedUsername()}</span>
                                                </a>
                                        {else}
                                                <span itemprop="name">{$article->username}</span>
                        {/if}
                {/foreach}
        {/if}
-       <link rel="amphtml" href="{link controller='ArticleAmp' object=$articleContent}{/link}">
+       {if MODULE_AMP}
+               <link rel="amphtml" href="{link controller='ArticleAmp' object=$articleContent}{/link}">
+       {/if}
 {/capture}
 
 {include file='header'}
                                        {event name='afterAboutAuthorText'}
                                        
                                        <div class="articleAboutAuthorUsername">
-                                               <a href="{link controller='User' object=$article->getUserProfile()->getDecoratedObject()}{/link}" class="username userLink" data-user-id="{@$article->getUserProfile()->userID}">{if MESSAGE_SIDEBAR_ENABLE_USER_ONLINE_MARKING}{@$article->getUserProfile()->getFormattedUsername()}{else}{$article->getUserProfile()->username}{/if}</a>
+                                               {user object=$article->getUserProfile() class='username'}
                                                
                                                {if MODULE_USER_RANK}
                                                        {if $article->getUserProfile()->getUserTitle()}
        <section class="section relatedArticles">
                <h2 class="sectionTitle">{lang}wcf.article.relatedArticles{/lang}</h2>
                
-               <ul class="articleList">
-                       {foreach from=$relatedArticles item='relatedArticle'}
-                               <li>
-                                       <a href="{$relatedArticle->getLink()}">
-                                               {if $relatedArticle->getTeaserImage() && $relatedArticle->getTeaserImage()->hasThumbnail('tiny')}
-                                                       <div class="box128">
-                                                               <div class="articleListImage">{@$relatedArticle->getTeaserImage()->getThumbnailTag('tiny')}</div>
-                                               {/if}
-                                               
-                                               <div>
-                                                       <div class="containerHeadline">
-                                                               <h3 class="articleListTitle">{$relatedArticle->getTitle()}</h3>
-                                                               <ul class="inlineList articleListMetaData">
-                                                                       <li>
-                                                                               <span class="icon icon16 fa-clock-o"></span>
-                                                                               {@$relatedArticle->time|time}
-                                                                       </li>
-                                                                       
-                                                                       {if $relatedArticle->enableComments}
-                                                                               <li>
-                                                                                       <span class="icon icon16 fa-comments"></span>
-                                                                                       {lang article=$relatedArticle}wcf.article.articleComments{/lang}
-                                                                               </li>
-                                                                       {/if}
-                                                               </ul>
-                                                       </div>
-                                                       
-                                                       <div class="containerContent articleListTeaser">
-                                                               {@$relatedArticle->getFormattedTeaser()}
-                                                       </div>
-                                               </div>
-                                                               
-                                               {if $relatedArticle->getTeaserImage() && $relatedArticle->getTeaserImage()->hasThumbnail('tiny')}
-                                                       </div>
-                                               {/if}
-                                       </a>
-                               </li>
-                       {/foreach}
-               </ul>
+               {include file='articleListItems' objects=$relatedArticles}
        </section>
 {/if}
 
        <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.moderation.report.reportContent': '{lang}wcf.moderation.report.reportContent{/lang}',
-                               'wcf.moderation.report.success': '{lang}wcf.moderation.report.success{/lang}'
+                               'wcf.moderation.report.reportContent': '{jslang}wcf.moderation.report.reportContent{/jslang}',
+                               'wcf.moderation.report.success': '{jslang}wcf.moderation.report.success{/jslang}'
                        });
                        new WCF.Moderation.Report.Content('com.woltlab.wcf.article', '.jsReportArticle');
                });
index 5169e7cf3b62348070359a33a3ac8235e2e52435..9462b1603f8d4a5b465820bed908cb0709c51ecf 100644 (file)
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Ui/User/Search/Input', 'WoltLabSuite/Core/Acp/Ui/Article/InlineEditor'], function(Language, UiUserSearchInput, AcpUiArticleInlineEditor) {
                Language.addObject({
-                       'wcf.acp.article.i18n.source': '{lang}wcf.acp.article.i18n.source{/lang}',
-                       'wcf.acp.article.i18n.toI18n.confirmMessage': '{lang}wcf.acp.article.i18n.toI18n.confirmMessage{/lang}',
-                       'wcf.acp.article.i18n.fromI18n.confirmMessage': '{lang}wcf.acp.article.i18n.fromI18n.confirmMessage{/lang}',
-                       'wcf.message.status.deleted': '{lang}wcf.message.status.deleted{/lang}',
+                       'wcf.acp.article.i18n.source': '{jslang}wcf.acp.article.i18n.source{/jslang}',
+                       'wcf.acp.article.i18n.toI18n.confirmMessage': '{jslang}wcf.acp.article.i18n.toI18n.confirmMessage{/jslang}',
+                       'wcf.acp.article.i18n.fromI18n.confirmMessage': '{jslang}wcf.acp.article.i18n.fromI18n.confirmMessage{/jslang}',
+                       'wcf.message.status.deleted': '{jslang}wcf.message.status.deleted{/jslang}',
                });
                
                new UiUserSearchInput(elBySel('input[name="username"]'));
@@ -84,7 +84,7 @@
                
                require(['WoltLabSuite/Core/Media/Manager/Select'], function(MediaManagerSelect) {
                        new MediaManagerSelect({
-                               dialogTitle: '{lang}wcf.media.chooseImage{/lang}',
+                               dialogTitle: '{jslang}wcf.media.chooseImage{/jslang}',
                                imagesOnly: 1
                        });
                });
        {@$__contentHeader}
 {/if}
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success" role="status">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $action == 'edit'}
        <p class="info jsArticleNoticeTrash"{if !$article->isDeleted} style="display: none;"{/if}>{lang}wcf.acp.article.trash.notice{/lang}</p>
                                                                        <div class="dropdownMenu">
                                                                                <ul class="scrollableDropdownMenu">
                                                                                        {foreach from=$labelGroup item=label}
-                                                                                               <li data-label-id="{@$label->labelID}"><span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span></li>
+                                                                                               <li data-label-id="{@$label->labelID}"><span>{@$label->render()}</span></li>
                                                                                        {/foreach}
                                                                                </ul>
                                                                        </div>
                                </dd>
                        </dl>
                        
+                       <dl{if $errorField == 'metaTitle'} class="formError"{/if}>
+                               <dt><label for="metaTitle0">{lang}wcf.acp.article.metaTitle{/lang}</label></dt>
+                               <dd>
+                                       <input type="text" id="metaTitle0" name="metaTitle[0]" value="{if !$metaTitle[0]|empty}{$metaTitle[0]}{/if}" class="long" maxlength="255">
+                                       {if $errorField == 'metaTitle'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.article.metaTitle.error.{@$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
+                       </dl>
+                       
+                       <dl{if $errorField == 'metaDescription'} class="formError"{/if}>
+                               <dt><label for="metaDescription0">{lang}wcf.acp.article.metaDescription{/lang}</label></dt>
+                               <dd>
+                                       <input type="text" id="metaDescription0" name="metaDescription[0]" value="{if !$metaDescription[0]|empty}{$metaDescription[0]}{/if}" class="long" maxlength="255">
+                                       {if $errorField == 'metaDescription'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.article.metaDescription.error.{@$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
+                       </dl>
+                       
                        {if MODULE_TAGGING}
-                               <dl class="jsOnly">
-                                       <dt><label for="tagSearchInput">{lang}wcf.tagging.tags{/lang}</label></dt>
-                                       <dd>
-                                               <input id="tagSearchInput" type="text" value="" class="long">
-                                               <small>{lang}wcf.tagging.tags.description{/lang}</small>
-                                       </dd>
-                               </dl>
-                               
-                               <script data-relocate="true">
-                                       require(['WoltLabSuite/Core/Ui/ItemList'], function(UiItemList) {
-                                               UiItemList.init(
-                                                       'tagSearchInput',
-                                                       [{if !$tags[0]|empty}{implode from=$tags[0] item=tag}'{@$tag|encodeJS}'{/implode}{/if}],
-                                                       {
-                                                               ajax: {
-                                                                       className: 'wcf\\data\\tag\\TagAction'
-                                                               },
-                                                               maxLength: {@TAGGING_MAX_TAG_LENGTH},
-                                                               submitFieldName: 'tags[0][]'
-                                                       }
-                                               );
-                                       });
-                               </script>
+                               {include file='tagInput' tagInputSuffix='0' tagSubmitFieldName='tags[0][]' tags=$tags[0] sandbox=true}
                        {/if}
                        
                        {event name='informationFields'}
                                                        </dd>
                                                </dl>
                                                
+                                               <dl{if $errorField == 'metaTitle'|concat:$availableLanguage->languageID} class="formError"{/if}>
+                                                       <dt><label for="metaTitle{@$availableLanguage->languageID}">{lang}wcf.acp.article.metaTitle{/lang}</label></dt>
+                                                       <dd>
+                                                               <input type="text" id="metaTitle{@$availableLanguage->languageID}" name="metaTitle[{@$availableLanguage->languageID}]" value="{if !$metaTitle[$availableLanguage->languageID]|empty}{$metaTitle[$availableLanguage->languageID]}{/if}" class="long" maxlength="255">
+                                                               {if $errorField == 'metaTitle'|concat:$availableLanguage->languageID}
+                                                                       <small class="innerError">
+                                                                               {if $errorType == 'empty'}
+                                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                                               {else}
+                                                                                       {lang}wcf.acp.article.metaTitle.error.{@$errorType}{/lang}
+                                                                               {/if}
+                                                                       </small>
+                                                               {/if}
+                                                       </dd>
+                                               </dl>
+                                               
+                                               <dl{if $errorField == 'metaDescription'|concat:$availableLanguage->languageID} class="formError"{/if}>
+                                                       <dt><label for="metaDescription{@$availableLanguage->languageID}">{lang}wcf.acp.article.metaDescription{/lang}</label></dt>
+                                                       <dd>
+                                                               <input type="text" id="metaDescription{@$availableLanguage->languageID}" name="metaDescription[{@$availableLanguage->languageID}]" value="{if !$metaDescription[$availableLanguage->languageID]|empty}{$metaDescription[$availableLanguage->languageID]}{/if}" class="long" maxlength="255">
+                                                               {if $errorField == 'metaDescription'|concat:$availableLanguage->languageID}
+                                                                       <small class="innerError">
+                                                                               {if $errorType == 'empty'}
+                                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                                               {else}
+                                                                                       {lang}wcf.acp.article.metaDescription.error.{@$errorType}{/lang}
+                                                                               {/if}
+                                                                       </small>
+                                                               {/if}
+                                                       </dd>
+                                               </dl>
+                                               
                                                {if MODULE_TAGGING}
-                                                       <dl class="jsOnly">
-                                                               <dt><label for="tagSearchInput{@$availableLanguage->languageID}">{lang}wcf.tagging.tags{/lang}</label></dt>
-                                                               <dd>
-                                                                       <input id="tagSearchInput{@$availableLanguage->languageID}" type="text" value="" class="long">
-                                                                       <small>{lang}wcf.tagging.tags.description{/lang}</small>
-                                                               </dd>
-                                                       </dl>
-                                                       
-                                                       <script data-relocate="true">
-                                                               require(['WoltLabSuite/Core/Ui/ItemList'], function(UiItemList) {
-                                                                       UiItemList.init(
-                                                                               'tagSearchInput{@$availableLanguage->languageID}',
-                                                                               [{if !$tags[$availableLanguage->languageID]|empty}{implode from=$tags[$availableLanguage->languageID] item=tag}'{@$tag|encodeJS}'{/implode}{/if}],
-                                                                               {
-                                                                                       ajax: {
-                                                                                               className: 'wcf\\data\\tag\\TagAction'
-                                                                                       },
-                                                                                       maxLength: {@TAGGING_MAX_TAG_LENGTH},
-                                                                                       submitFieldName: 'tags[{@$availableLanguage->languageID}][]'
-                                                                               }
-                                                                       );
-                                                               });
-                                                       </script>
+                                                       {assign var='tagSubmitFieldName' value='tags['|concat:$availableLanguage->languageID:'][]'}
+                                                       {include file='tagInput' tagInputSuffix=$availableLanguage->languageID tagSubmitFieldName=$tagSubmitFieldName tags=$tags[$availableLanguage->languageID] sandbox=true}
                                                {/if}
                                                
                                                {event name='informationFieldsMultilingual'}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
+                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
                });
                
                {if !$labelGroups|empty}
index 35cb520d5655e7b61bc9ce4311b2b382877dbcf1..a0a5fcf75291dbbf3d294e7c4aaa5411e6dd421e 100644 (file)
@@ -18,7 +18,7 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Article/Add'], function(Language, AcpUiArticleAdd) {
                Language.addObject({
-                       'wcf.acp.article.add': '{lang}wcf.acp.article.add{/lang}'
+                       'wcf.acp.article.add': '{jslang}wcf.acp.article.add{/jslang}'
                });
                
                AcpUiArticleAdd.init('{link controller='ArticleAdd' encode=false}{literal}isMultilingual={$isMultilingual}{/literal}{if $categoryID}&categoryID={@$categoryID}{/if}{/link}');
index ecccf4db062804000a6db9a34a12a11661df8ceb..64dd9f0852159095305df5b379db5be75f172e99 100644 (file)
@@ -24,8 +24,8 @@
        <li class="dropdown jsOnly">
                <a href="#" class="button dropdownToggle"><span class="icon icon16 fa-sort-amount-asc"></span> <span>{lang}wcf.article.button.sort{/lang}</span></a>
                <ul class="dropdownMenu">
-                       <li><a href="{link controller='ArticleList'}pageNo={@$pageNo}&sortField=title&sortOrder={if $sortField == 'title' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.title{/lang}{if $sortField == 'title'} <span class="icon icon16 fa-caret-{if $sortOrder == 'ASC'}up{else}down{/if}"></span>{/if}</a></li>
-                       <li><a href="{link controller='ArticleList'}pageNo={@$pageNo}&sortField=time&sortOrder={if $sortField == 'time' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.date{/lang}{if $sortField == 'time'} <span class="icon icon16 fa-caret-{if $sortOrder == 'ASC'}up{else}down{/if}"></span>{/if}</a></li>
+                       <li><a href="{link controller='ArticleList'}pageNo={@$pageNo}{if $user}&userID={@$user->userID}{/if}&sortField=title&sortOrder={if $sortField == 'title' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.title{/lang}{if $sortField == 'title'} <span class="icon icon16 fa-caret-{if $sortOrder == 'ASC'}up{else}down{/if}"></span>{/if}</a></li>
+                       <li><a href="{link controller='ArticleList'}pageNo={@$pageNo}{if $user}&userID={@$user->userID}{/if}&sortField=time&sortOrder={if $sortField == 'time' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.date{/lang}{if $sortField == 'time'} <span class="icon icon16 fa-caret-{if $sortOrder == 'ASC'}up{else}down{/if}"></span>{/if}</a></li>
                        
                        {event name='sortOptions'}
                </ul>
                                
                                <div class="boxContent">
                                        <dl>
-                                               {foreach from=$labelGroups item=labelGroup}
-                                                       {if $labelGroup|count}
-                                                               <dt><label>{$labelGroup->getTitle()}</label></dt>
-                                                               <dd>
-                                                                       <ul class="labelList jsOnly">
-                                                                               <li class="dropdown labelChooser" id="labelGroup{@$labelGroup->groupID}" data-group-id="{@$labelGroup->groupID}">
-                                                                                       <div class="dropdownToggle" data-toggle="labelGroup{@$labelGroup->groupID}"><span class="badge label">{lang}wcf.label.none{/lang}</span></div>
-                                                                                       <div class="dropdownMenu">
-                                                                                               <ul class="scrollableDropdownMenu">
-                                                                                                       {foreach from=$labelGroup item=label}
-                                                                                                               <li data-label-id="{@$label->labelID}"><span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span></li>
-                                                                                                       {/foreach}
-                                                                                               </ul>
-                                                                                       </div>
-                                                                               </li>
-                                                                       </ul>
-                                                                       <noscript>
-                                                                               {foreach from=$labelGroups item=labelGroup}
-                                                                                       <select name="labelIDs[{@$labelGroup->groupID}]">
-                                                                                               <option value="0">{lang}wcf.label.none{/lang}</option>
-                                                                                               <option value="-1">{lang}wcf.label.withoutSelection{/lang}</option>
-                                                                                               {foreach from=$labelGroup item=label}
-                                                                                                       <option value="{@$label->labelID}"{if $labelIDs[$labelGroup->groupID]|isset && $labelIDs[$labelGroup->groupID] == $label->labelID} selected{/if}>{$label->getTitle()}</option>
-                                                                                               {/foreach}
-                                                                                       </select>
-                                                                               {/foreach}
-                                                                       </noscript>
-                                                               </dd>
-                                                       {/if}
-                                               {/foreach}
+                                               {include file='__labelSelection'}
                                        </dl>
                                        <div class="formSubmit">
                                                <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
@@ -89,8 +60,8 @@
                <script data-relocate="true">
                        $(function() {
                                WCF.Language.addObject({
-                                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
-                                       'wcf.label.withoutSelection': '{lang}wcf.label.withoutSelection{/lang}'
+                                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
+                                       'wcf.label.withoutSelection': '{jslang}wcf.label.withoutSelection{/jslang}'
                                });
                                
                                new WCF.Label.Chooser({ {implode from=$labelIDs key=groupID item=labelID}{@$groupID}: {@$labelID}{/implode} }, '#sidebarForm', undefined, true);
 {include file='header'}
 
 {assign var='additionalLinkParameters' value=''}
+{if $user}{capture append='additionalLinkParameters'}&userID={@$user->userID}{/capture}{/if}
 {if $labelIDs|count}{capture append='additionalLinkParameters'}{foreach from=$labelIDs key=labelGroupID item=labelID}&labelIDs[{@$labelGroupID}]={@$labelID}{/foreach}{/capture}{/if}
 
 {hascontent}
index 52ee0194bd3d939a585f8f16d0979305407681fc..ae5f39bab58d0ef75d6015670c276c3529918ca3 100644 (file)
@@ -22,7 +22,7 @@
                                        {if $article->hasLabels()}
                                                <div class="contentItemLabels">
                                                        {foreach from=$article->getLabels() item=label}
-                                                               <span class="label badge contentItemLabel{if $label->getClassNames()} {$label->getClassNames()}{/if}">{$label->getTitle()}</span>
+                                                               {@$label->render('contentItemLabel')}
                                                        {/foreach}
                                                </div>
                                        {/if}
@@ -45,7 +45,7 @@
                                <div class="contentItemMetaContent">
                                        <div class="contentItemMetaAuthor">
                                                {if $article->userID}
-                                                       <a href="{$article->getUserProfile()->getLink()}" class="userLink" data-user-id="{@$article->userID}">{$article->getUserProfile()->username}</a>
+                                                       {user object=$article->getUserProfile()}
                                                {else}
                                                        {$article->username}
                                                {/if}
                                                        {include file='__topReaction' cachedReactions=$article->cachedReactions render='short'}
                                                </div>
                                        {/if}
-                                       <div class="contentItemMetaIcon">
-                                               <span class="icon icon16 fa-comments"></span>
-                                               <span aria-label="{$article->getDiscussionProvider()->getDiscussionCountPhrase()}">
-                                                       {$article->getDiscussionProvider()->getDiscussionCount()}
-                                               </span>
-                                       </div>
-                                       
+                                       {if $article->getDiscussionProvider()->getDiscussionCountPhrase()}{* empty phrase indicates that comments are disabled *}
+                                               <div class="contentItemMetaIcon">
+                                                       <span class="icon icon16 fa-comments"></span>
+                                                       <span aria-label="{$article->getDiscussionProvider()->getDiscussionCountPhrase()}">
+                                                               {$article->getDiscussionProvider()->getDiscussionCount()}
+                                                       </span>
+                                               </div>
+                                       {/if}
+
                                        {event name='contentItemMetaIcons'}
                                </div>
                        </div>
index 01b0d47a21fa9ac3b60c0ff0f01552513ace1286..5f698562add257be75e8ad58753900716392337a 100644 (file)
@@ -9,15 +9,15 @@
                                                {if $attachment->showAsImage() && !$attachment->isEmbedded()}
                                                        <li class="attachmentThumbnail" data-attachment-id="{@$attachment->attachmentID}">
                                                                {if $attachment->hasThumbnail()}
-                                                                       <a href="{link controller='Attachment' object=$attachment}{/link}"{if $attachment->canDownload()} class="jsImageViewer" title="{$attachment->filename}"{/if}>
+                                                                       <a href="{$attachment->getLink()}"{if $attachment->canDownload()} class="jsImageViewer" title="{$attachment->filename}"{/if}>
                                                                {/if}
                                                                
                                                                <div class="attachmentThumbnailContainer">
                                                                        <span class="attachmentThumbnailImage">
                                                                                {if $attachment->hasThumbnail()}
-                                                                                       <img src="{link controller='Attachment' object=$attachment}thumbnail=1{/link}" alt="" {if $attachment->thumbnailWidth >= ATTACHMENT_THUMBNAIL_WIDTH && $attachment->thumbnailHeight >= ATTACHMENT_THUMBNAIL_HEIGHT} class="attachmentThumbnailImageScalable"{/if}>
+                                                                                       <img src="{$attachment->getThumbnailLink('thumbnail')}" alt="" {if $attachment->thumbnailWidth >= ATTACHMENT_THUMBNAIL_WIDTH && $attachment->thumbnailHeight >= ATTACHMENT_THUMBNAIL_HEIGHT} class="attachmentThumbnailImageScalable"{/if}>
                                                                                {else}
-                                                                                       <img src="{link controller='Attachment' object=$attachment}{/link}" alt="" {if $attachment->width >= ATTACHMENT_THUMBNAIL_WIDTH && $attachment->height >= ATTACHMENT_THUMBNAIL_HEIGHT} class="attachmentThumbnailImageScalable"{/if}>
+                                                                                       <img src="{$attachment->getLink()}" alt="" {if $attachment->width >= ATTACHMENT_THUMBNAIL_WIDTH && $attachment->height >= ATTACHMENT_THUMBNAIL_HEIGHT} class="attachmentThumbnailImageScalable"{/if}>
                                                                                {/if}
                                                                        </span>
                                                                
                                        {foreach from=$attachmentList->getGroupedObjects($objectID) item=attachment}
                                                {if $attachment->showAsFile() && !$attachment->isEmbedded()}
                                                        <li class="box32" data-attachment-id="{@$attachment->attachmentID}">
-                                                               <a href="{link controller='Attachment' object=$attachment}{/link}"><span class="icon icon32 fa-{@$attachment->getIconName()}"></span></a>
+                                                               <a href="{$attachment->getLink()}"><span class="icon icon32 fa-{@$attachment->getIconName()}"></span></a>
                                                                
                                                                <div>
-                                                                       <p><a href="{link controller='Attachment' object=$attachment}{/link}">{$attachment->filename}</a></p>
+                                                                       <p><a href="{$attachment->getLink()}">{$attachment->filename}</a></p>
                                                                        <small>{lang}wcf.attachment.file.info{/lang}</small>
                                                                </div>
                                                        </li>
index b2ce6b48bdc208c486850a242a721e1db83e31a7..b7b18321e01ad94dd5564fd1aa625d3dff2ef197 100644 (file)
@@ -4,7 +4,13 @@
                
                <div>
                        <div class="containerHeadline">
-                               <h3>{if $userProfile->userID}<a href="{link controller='User' object=$userProfile}{/link}">{$userProfile->username}</a>{else}{$userProfile->username}{/if}</h3>
+                               <h3>
+                                       {if $userProfile->userID}
+                                               {user object=$userProfile}
+                                       {else}
+                                               {$userProfile->username}
+                                       {/if}
+                               </h3>
                                {if MODULE_USER_RANK}
                                        {if $userProfile->getUserTitle()}
                                                <p><span class="badge userTitleBadge{if $userProfile->getRank() && $userProfile->getRank()->cssClassName} {@$userProfile->getRank()->cssClassName}{/if}">{$userProfile->getUserTitle()}</span></p>
@@ -22,4 +28,4 @@
                        {/if}
                </div>
        </div>
-</div>
\ No newline at end of file
+</div>
index 0ebe55c32878ec7a55daad86215085b9a09b8a32..fe7d1d8f6f7c0a2b8574f7761f1cd8e66c7a5fa0 100644 (file)
        <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.user.avatar.upload.error.invalidExtension': '{lang}wcf.user.avatar.upload.error.invalidExtension{/lang}',
-                               'wcf.user.avatar.upload.error.tooSmall': '{lang}wcf.user.avatar.upload.error.tooSmall{/lang}',
-                               'wcf.user.avatar.upload.error.tooLarge': '{lang}wcf.user.avatar.upload.error.tooLarge{/lang}',
-                               'wcf.user.avatar.upload.error.uploadFailed': '{lang}wcf.user.avatar.upload.error.uploadFailed{/lang}',
-                               'wcf.user.avatar.upload.error.badImage': '{lang}wcf.user.avatar.upload.error.badImage{/lang}',
-                               'wcf.user.avatar.upload.success': '{lang}wcf.user.avatar.upload.success{/lang}'
+                               'wcf.user.avatar.upload.error.invalidExtension': '{jslang}wcf.user.avatar.upload.error.invalidExtension{/jslang}',
+                               'wcf.user.avatar.upload.error.tooSmall': '{jslang}wcf.user.avatar.upload.error.tooSmall{/jslang}',
+                               'wcf.user.avatar.upload.error.tooLarge': '{jslang}wcf.user.avatar.upload.error.tooLarge{/jslang}',
+                               'wcf.user.avatar.upload.error.uploadFailed': '{jslang}wcf.user.avatar.upload.error.uploadFailed{/jslang}',
+                               'wcf.user.avatar.upload.error.badImage': '{jslang}wcf.user.avatar.upload.error.badImage{/jslang}',
+                               'wcf.user.avatar.upload.success': '{jslang}wcf.user.avatar.upload.success{/jslang}'
                        });
                        
                        {if !$__wcf->user->disableAvatar}
index 11d7b4290c6d68f321fd8225d4464170a253f0ca..0ec0ee57b9d7042da6128039bc8df68ff5905380 100644 (file)
@@ -3,6 +3,6 @@
 
 <script data-relocate="true">
 $(function() {
-       $('#{$option->optionName}').parents('dl:eq(0)').find('> dt > label').text('{lang}wcf.user.birthday.age{/lang}');
+       $('#{$option->optionName}').parents('dl:eq(0)').find('> dt > label').text('{jslang}wcf.user.birthday.age{/jslang}');
 });
-</script>
\ No newline at end of file
+</script>
index cf328bf506648582e029036933033d9b151b3977..f92609a2cf088ecef53875d66be33e76921c07d6 100644 (file)
@@ -1,10 +1,10 @@
 <ul class="sidebarItemList">
        {foreach from=$usersOnlineList item=userOnline}
                <li class="box32">
-                       <a href="{link controller='User' object=$userOnline}{/link}" aria-hidden="true">{@$userOnline->getAvatar()->getImageTag(32)}</a>
+                       {user object=$userOnline type='avatar32' ariaHidden='true'}
                        
                        <div class="sidebarItemTitle">
-                               <h3><a href="{link controller='User' object=$userOnline}{/link}" class="userLink" data-user-id="{@$userOnline->userID}">{$userOnline->username}</a></h3>
+                               <h3>{user object=$userOnline}</h3>
                                <small>{@$userOnline->lastActivityTime|time}</small>
                        </div>
                </li>
index eae61fc7983da2c1c90f8f86db02a2a39feffc85..abc41fcf1d864564c11b5f935e639663af920205 100644 (file)
@@ -32,8 +32,8 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Ui/User/Activity/Recent'], function (Language, UiUserActivityRecent) {
                Language.addObject({
-                       'wcf.user.recentActivity.more': '{lang}wcf.user.recentActivity.more{/lang}',
-                       'wcf.user.recentActivity.noMoreEntries': '{lang}wcf.user.recentActivity.noMoreEntries{/lang}'
+                       'wcf.user.recentActivity.more': '{jslang}wcf.user.recentActivity.more{/jslang}',
+                       'wcf.user.recentActivity.noMoreEntries': '{jslang}wcf.user.recentActivity.noMoreEntries{/jslang}'
                });
                
                new UiUserActivityRecent('boxRecentActivity{@$boxID}');
index 69151ea38844bcc318b7ecb17f818a7f2c434c22..e9ba482580f5d12e1163e2b1348e439ed144c7c8 100644 (file)
@@ -1,11 +1,11 @@
 <ul class="sidebarItemList">
        {foreach from=$eventList item=event}
                <li class="box24{if $__wcf->getUserProfileHandler()->isIgnoredUser($event->getUserProfile()->userID)} ignoredUserContent{/if}">
-                       <a href="{link controller='User' object=$event->getUserProfile()}{/link}" title="{$event->getUserProfile()->username}">{@$event->getUserProfile()->getAvatar()->getImageTag(24)}</a>
+                       {user object=$event->getUserProfile() type='avatar24'}
                        
                        <div class="sidebarItemTitle">
                                <h3>
-                                       <a href="{link controller='User' object=$event->getUserProfile()}{/link}" class="userLink" data-user-id="{@$event->getUserProfile()->userID}">{$event->getUserProfile()->username}</a>
+                                       {user object=$event->getUserProfile()}
                                        <small class="separatorLeft">{@$event->time|time}</small>
                                </h3>
                                <small>{@$event->getTitle()}</small>
index ef1531678a6cc40ee5009b78fb4661f46e145e0a..e47a933bf12d42099f2d5ac0ac14e9495b2e2c4b 100644 (file)
@@ -5,8 +5,12 @@
                                <h3><a href="{$boxComment->getLink()}">{$boxComment->title}</a></h3>
                        </div>
                        
-                       <p><small>{@$boxComment->getExcerpt(50)}</small></p>
-                       <p><small>{if $boxComment->userID}<a href="{link controller='User' object=$boxComment->getUserProfile()}{/link}" class="userLink" data-user-id="{@$boxComment->userID}">{$boxComment->username}</a>{else}{$boxComment->username}{/if} <span class="separatorLeft">{@$boxComment->time|time}</span></small></p>
+                       <div class="sidebarCommentContent">
+                               <small>{@$boxComment->getExcerpt(50)}</small>
+                       </div>
+                       <div>
+                               <small>{if $boxComment->userID}{user object=$boxComment->getUserProfile()}{else}{$boxComment->username}{/if} <span class="separatorLeft">{@$boxComment->time|time}</span></small>
+                       </div>
                </li>
        {/foreach}
 </ul>
index cf7bfb3b007362370cc909cf995bce231187cedf..bcc9659ab34951f1679feb2ce97a6608605f1cdd 100644 (file)
@@ -5,7 +5,7 @@
                <div class="containerHeadline">
                        <h3>
                                {event name='beforeUsername'}
-                               <a href="{link controller='User' object=$__wcf->user}{/link}">{$__wcf->user->username}</a>
+                               {user object=$__wcf->getUserProfileHandler()->getUserProfile()}
                        </h3>
                        {if MODULE_USER_RANK}
                                {if $__wcf->getUserProfileHandler()->getUserTitle()}
index 6e464e7e2cc8c6226bc4a37c92305e7270126fb6..99d6cf9ac6ec005a8b4374821b8b1df27baa42d6 100644 (file)
@@ -1,12 +1,12 @@
 <ul class="sidebarItemList">
        {foreach from=$usersOnlineList item=userOnline}
                <li class="box32">
-                       <a href="{link controller='User' object=$userOnline}{/link}" aria-hidden="true">{@$userOnline->getAvatar()->getImageTag(32)}</a>
+                       {user object=$userOnline type='avatar32' ariaHidden='true'}
                        
                        <div class="sidebarItemTitle">
                                <h3>
                                        {event name='beforeUsername'}
-                                       <a href="{link controller='User' object=$userOnline}{/link}" class="userLink" data-user-id="{@$userOnline->userID}">{$userOnline->username}</a>
+                                       {user object=$userOnline}
                                </h3>
                                {if MODULE_USER_RANK}
                                        {if $userOnline->getUserTitle()}
index 449883cbdea928d4e456fc294eafa717fb1bc98e..9a1f8dbfea393141d52030ed7d9fb6e3ff887208 100644 (file)
@@ -11,6 +11,6 @@
        
        {if $statistics[newestMember]}
                <dt>{lang}wcf.user.newestMember{/lang}</dt>
-               <dd><a href="{link controller='User' object=$statistics[newestMember]}{/link}" class="userLink" data-user-id="{$statistics[newestMember]->userID}">{$statistics[newestMember]}</a></dd>
+               <dd>{user object=$statistics[newestMember]}</dd>
        {/if}
 </dl>
index 8c7a0daac97933bd361f77506b447253c71d674d..93a37da6f6d49255c725f5f735a601f257375e3f 100644 (file)
@@ -1,10 +1,10 @@
 <ul class="sidebarItemList">
        {foreach from=$birthdayUserProfiles item=birthdayUserProfile}
                <li class="box32">
-                       <a href="{link controller='User' object=$birthdayUserProfile}{/link}" aria-hidden="true">{@$birthdayUserProfile->getAvatar()->getImageTag(32)}</a>
+                       {user object=$birthdayUserProfile type='avatar32' ariaHidden='true'}
                        
                        <div class="sidebarItemTitle">
-                               <h3><a href="{link controller='User' object=$birthdayUserProfile}{/link}" class="userLink" data-user-id="{@$birthdayUserProfile->userID}">{$birthdayUserProfile->username}</a></h3>
+                               <h3>{user object=$birthdayUserProfile}</h3>
                                <small>{$birthdayUserProfile->getBirthday()}</small>
                        </div>
                </li>
                        var $todaysBirthdays = null;
                        $('.jsTodaysBirthdays').click(function() {
                                if ($todaysBirthdays === null) {
-                                       $todaysBirthdays = new WCF.User.List('wcf\\data\\user\\UserBirthdayAction', '{@$box->getTitle()|encodeJS} ({@TIME_NOW|date})', { date: '{@TIME_NOW|date:'Y-m-d'}' });
+                                       $todaysBirthdays = new WCF.User.List('wcf\\data\\user\\UserBirthdayAction', '{@$box->getTitle()|encodeJS} ({@TIME_NOW|date})', {
+                                               date: '{@TIME_NOW|date:'Y-m-d'}',
+                                               sortField: '{$sortField}',
+                                               sortOrder: '{$sortOrder}'
+                                       });
                                }
                                $todaysBirthdays.open();
                        });
                });
        </script>
-{/if}
\ No newline at end of file
+{/if}
index 657133e1e655a33c248692b5b8d838c7cf058d3d..5e5be36819ef42bee28802190bfae68a6a7bca88 100644 (file)
@@ -1,10 +1,10 @@
 <ul class="sidebarItemList">
        {foreach from=$birthdayUserProfiles item=birthdayUserProfile}
                <li class="box32">
-                       <a href="{link controller='User' object=$birthdayUserProfile}{/link}" aria-hidden="true">{@$birthdayUserProfile->getAvatar()->getImageTag(32)}</a>
+                       {user object=$birthdayUserProfile type='avatar32' ariaHidden='true'}
                        
                        <div class="sidebarItemTitle">
-                               <h3><a href="{link controller='User' object=$birthdayUserProfile}{/link}" class="userLink" data-user-id="{@$birthdayUserProfile->userID}">{$birthdayUserProfile->username}</a></h3>
+                               <h3>{user object=$birthdayUserProfile}</h3>
                                <small>{$birthdayUserProfile->getBirthday()}</small>
                        </div>
                </li>
index 69b4f987e36b928d195b194122400d65dfd9ebdf..68b66c197fe83e01855700c0aea559feea64303c 100644 (file)
@@ -1,10 +1,10 @@
 <ul class="sidebarItemList">
        {foreach from=$boxUsers item=boxUser}
                <li class="box24">
-                       <a href="{link controller='User' object=$boxUser}{/link}" aria-hidden="true">{@$boxUser->getAvatar()->getImageTag(24)}</a>
+                       {user object=$boxUser type='avatar24' ariaHidden='true'}
                        
                        <div class="sidebarItemTitle">
-                               <h3><a href="{link controller='User' object=$boxUser}{/link}" class="userLink" data-user-id="{@$boxUser->userID}">{$boxUser->username}</a></h3>
+                               <h3>{user object=$boxUser}</h3>
                                {capture assign='__boxUserLanguageItem'}{lang __optional=true}wcf.user.boxList.description.{$boxSortField}{/lang}{/capture}
                                {if $__boxUserLanguageItem}
                                        <small>{@$__boxUserLanguageItem}</small>
index 061b4b924b132bf24fe75d8ede34c8f63381e69b..bf16e8657f35eb0d06ae87d93e472a8777dd3acf 100644 (file)
@@ -9,7 +9,7 @@
                                                <a href="{$boxUserTrophy->getTrophy()->getLink()}">{$boxUserTrophy->getTrophy()->getTitle()}</a>
                                        </h3>
                                        <small>
-                                               {@$boxUserTrophy->getUserProfile()->getAnchorTag()}
+                                               {user object=$boxUserTrophy->getUserProfile()}
                                                <span class="separatorLeft">{@$boxUserTrophy->time|time}</span>
                                        </small>
                                </div>
@@ -24,7 +24,7 @@
 
                                <div class="sidebarItemTitle">
                                        <h3><a href="{$boxUserTrophy->getTrophy()->getLink()}">{$boxUserTrophy->getTrophy()->getTitle()}</a></h3>
-                                       <small>{if !$boxUserTrophy->getDescription()|empty}<p>{@$boxUserTrophy->getDescription()}</p>{/if}<p>{@$boxUserTrophy->getUserProfile()->getAnchorTag()} <span class="separatorLeft">{@$boxUserTrophy->time|time}</span></p></small>
+                                       <small>{if !$boxUserTrophy->getDescription()|empty}<p>{@$boxUserTrophy->getDescription()}</p>{/if}<p>{user object=$boxUserTrophy->getUserProfile()} <span class="separatorLeft">{@$boxUserTrophy->time|time}</span></p></small>
                                </div>
                        </li>
                {/foreach}
index cb88c70db4ff26a9a32c566932f410e7f6eb3319..e6f63aee507fde66bde5e2e4aba76e901678d501 100644 (file)
@@ -6,7 +6,7 @@
 {if $usersOnlineList|count}
        <ul class="inlineList commaSeparated">
                {foreach from=$usersOnlineList->getObjects() item=userOnline}
-                       <li><a href="{link controller='User' object=$userOnline->getDecoratedObject()}{/link}" class="userLink" data-user-id="{@$userOnline->userID}">{@$userOnline->getFormattedUsername()}</a></li>
+                       <li>{user object=$userOnline}</li>
                {/foreach}
        </ul>
 {/if}
index 79c45ba9b4077a9170ad9c1b5ea910a3b45c848b..f713a8a1605223e6b365c9750298882820cecbd5 100644 (file)
@@ -1,7 +1,7 @@
 <ul class="inlineList commaSeparated small">
        {foreach from=$usersOnlineList->getObjects() item=userOnline}
-               <li><a href="{link controller='User' object=$userOnline->getDecoratedObject()}{/link}" class="userLink" data-user-id="{@$userOnline->userID}">{@$userOnline->getFormattedUsername()}</a></li>
+               <li>{user object=$userOnline}</li>
        {/foreach}
 </ul>
 
-<p><small>{lang}wcf.user.usersOnline.detail{/lang}{if USERS_ONLINE_RECORD && $__showRecord} <span class="separatorLeft">{lang}wcf.user.usersOnline.record{/lang}</span>{/if}</small></p>
\ No newline at end of file
+<p><small>{lang}wcf.user.usersOnline.detail{/lang}{if USERS_ONLINE_RECORD && $__showRecord} <span class="separatorLeft">{lang}wcf.user.usersOnline.record{/lang}</span>{/if}</small></p>
index f3424ad78c4d7b525064c39e8c4965c5b5808326..f9a1fd45c2bc2896a5f14ab75c64aaaab5601ca0 100644 (file)
@@ -1,13 +1,13 @@
 {if $whoWasOnlineList|count < 29}
        <ul class="userAvatarList">
                {foreach from=$whoWasOnlineList item=userOnline}
-                       <li><a href="{link controller='User' object=$userOnline}{/link}" title="{$userOnline->username} ({@$userOnline->lastActivityTime|date:$whoWasOnlineTimeFormat})" class="jsTooltip">{@$userOnline->getAvatar()->getImageTag(48)}</a></li>
+                       <li><a href="{$userOnline->getLink()}" title="{$userOnline->username} ({@$userOnline->lastActivityTime|date:$whoWasOnlineTimeFormat})" class="jsTooltip">{@$userOnline->getAvatar()->getImageTag(48)}</a></li>
                {/foreach}
        </ul>
 {else}
        <ul class="inlineList commaSeparated">
                {foreach from=$whoWasOnlineList item=userOnline}
-                       <li><a href="{link controller='User' object=$userOnline->getDecoratedObject()}{/link}" class="userLink" data-user-id="{@$userOnline->userID}">{@$userOnline->getFormattedUsername()}</a> ({@$userOnline->lastActivityTime|date:$whoWasOnlineTimeFormat})</li>
+                       <li>{user object=$userOnline} ({@$userOnline->lastActivityTime|date:$whoWasOnlineTimeFormat})</li>
                {/foreach}
        </ul>
 {/if}
index dedc0181d4d6daafa79d3ee901038635f2184524..60b3e32636355329e17f13f5e5a0f8078a5d9e37 100644 (file)
                                
                                <div class="boxContent">
                                        <dl>
-                                               {foreach from=$labelGroups item=labelGroup}
-                                                       {if $labelGroup|count}
-                                                               <dt><label>{$labelGroup->getTitle()}</label></dt>
-                                                               <dd>
-                                                                       <ul class="labelList jsOnly">
-                                                                               <li class="dropdown labelChooser" id="labelGroup{@$labelGroup->groupID}" data-group-id="{@$labelGroup->groupID}">
-                                                                                       <div class="dropdownToggle" data-toggle="labelGroup{@$labelGroup->groupID}"><span class="badge label">{lang}wcf.label.none{/lang}</span></div>
-                                                                                       <div class="dropdownMenu">
-                                                                                               <ul class="scrollableDropdownMenu">
-                                                                                                       {foreach from=$labelGroup item=label}
-                                                                                                               <li data-label-id="{@$label->labelID}"><span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span></li>
-                                                                                                       {/foreach}
-                                                                                               </ul>
-                                                                                       </div>
-                                                                               </li>
-                                                                       </ul>
-                                                                       <noscript>
-                                                                               {foreach from=$labelGroups item=labelGroup}
-                                                                                       <select name="labelIDs[{@$labelGroup->groupID}]">
-                                                                                               <option value="0">{lang}wcf.label.none{/lang}</option>
-                                                                                               <option value="-1">{lang}wcf.label.withoutSelection{/lang}</option>
-                                                                                               {foreach from=$labelGroup item=label}
-                                                                                                       <option value="{@$label->labelID}"{if $labelIDs[$labelGroup->groupID]|isset && $labelIDs[$labelGroup->groupID] == $label->labelID} selected{/if}>{$label->getTitle()}</option>
-                                                                                               {/foreach}
-                                                                                       </select>
-                                                                               {/foreach}
-                                                                       </noscript>
-                                                               </dd>
-                                                       {/if}
-                                               {/foreach}
+                                               {include file='__labelSelection'}
                                        </dl>
                                        <div class="formSubmit">
                                                <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
@@ -87,8 +58,8 @@
                <script data-relocate="true">
                        $(function() {
                                WCF.Language.addObject({
-                                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
-                                       'wcf.label.withoutSelection': '{lang}wcf.label.withoutSelection{/lang}'
+                                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
+                                       'wcf.label.withoutSelection': '{jslang}wcf.label.withoutSelection{/jslang}'
                                });
                                
                                new WCF.Label.Chooser({ {implode from=$labelIDs key=groupID item=labelID}{@$groupID}: {@$labelID}{/implode} }, '#sidebarForm', undefined, true);
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.objectWatch.manageSubscription': '{lang}wcf.user.objectWatch.manageSubscription{/lang}'
+                       'wcf.user.objectWatch.manageSubscription': '{jslang}wcf.user.objectWatch.manageSubscription{/jslang}'
                });
                
                new WCF.User.ObjectWatch.Subscribe();
index eac8c8707c72416de635d40fc365e596b40077c3..3a39651634857c4ad43402ac5738b4c1ad817bf9 100644 (file)
        </div>
 {/hascontent}
 
-<div class="section">
-       <div{if $categories|count > 1} class="tabMenuContent"{/if}>
-               {if $objects|count}
-                       <ol class="section containerList trophyCategoryList tripleColumned">
-                               {foreach from=$objects item=trophy}
-                                       <li class="box64">
-                                               <div>{@$trophy->renderTrophy(64)}</div>
-                                               
-                                               <div class="sidebarItemTitle">
-                                                       <h3><a href="{$trophy->getLink()}">{@$trophy->getTitle()}</a></h3>
-                                                       {if !$trophy->getDescription()|empty}<small>{@$trophy->getDescription()}</small>{/if}
-                                               </div>
-                                       </li>
-                               {/foreach}
-                       </ol>
-               {else}
-                       <p class="info" role="status">{lang}wcf.global.noItems{/lang}</p>
-               {/if}
+{if $objects|count}
+       <div class="section sectionContainerList">
+               <ol class="containerList trophyCategoryList doubleColumned">
+                       {foreach from=$objects item=trophy}
+                               <li class="box64">
+                                       <div>{@$trophy->renderTrophy(64)}</div>
+                                       
+                                       <div class="containerHeadline">
+                                               <h3><a href="{$trophy->getLink()}">{@$trophy->getTitle()}</a></h3>
+                                               {if !$trophy->getDescription()|empty}<p><small>{@$trophy->getDescription()}</small></p>{/if}
+                                               <p><small>{lang items=$trophy->awarded}wcf.user.trophy.trophyAwarded{/lang}</small></p>
+                                       </div>
+                               </li>
+                       {/foreach}
+               </ol>
        </div>
-</div>
+{else}
+       <p class="info" role="status">{lang}wcf.global.noItems{/lang}</p>
+{/if}
 
 <footer class="contentFooter">
        {hascontent}
@@ -67,4 +66,4 @@
        {/hascontent}
 </footer>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 9d57054d28557474c43d72e903ac09f33373ed57..17f33755a5991f7bb19639219663072eead3af2d 100644 (file)
@@ -6,9 +6,7 @@
 {capture assign='headContent'}
        {if $page->isMultilingual && $page->getPageLanguages()|count > 1}
                {foreach from=$page->getPageLanguages() item='pageLanguage'}
-                       {if $pageLanguage->getLanguage()}
-                               <link rel="alternate" hreflang="{$pageLanguage->getLanguage()->languageCode}" href="{$pageLanguage->getLink()}">
-                       {/if}
+                       <link rel="alternate" hreflang="{$pageLanguage->getLanguage()->languageCode}" href="{$pageLanguage->getLink()}">
                {/foreach}
        {/if}
 {/capture}
                        </a>
                        <ul class="dropdownMenu">
                                {foreach from=$page->getPageLanguages() item='pageLanguage'}
-                                       {if $pageLanguage->getLanguage()}
-                                               <li class="boxFlag">
-                                                       <a class="box24" href="{$pageLanguage->getLink()}">
-                                                               <span><img src="{$pageLanguage->getLanguage()->getIconPath()}" alt="" class="iconFlag"></span>
-                                                               <span>{$pageLanguage->getLanguage()->languageName}</span>
-                                                       </a>
-                                               </li>
-                                       {/if}
+                                       <li class="boxFlag">
+                                               <a class="box24" href="{$pageLanguage->getLink()}">
+                                                       <span><img src="{$pageLanguage->getLanguage()->getIconPath()}" alt="" class="iconFlag"></span>
+                                                       <span>{$pageLanguage->getLanguage()->languageName}</span>
+                                               </a>
+                                       </li>
                                {/foreach}
                        </ul>
                </li>
index f67cace6f3dabf8ae2194c62164b1b3291e0ec62..35c0c8c4b1024148651ed0c8c7afd6c17efa073c 100644 (file)
@@ -1,16 +1,19 @@
 <div class="codeBox collapsibleBbcode jsCollapsibleBbcode {if $lines > 10} collapsed{/if}">
-       <div>
-               <div class="codeBoxHeader">
-                       <div class="codeBoxHeadline">{$title}{if $filename}: {$filename}{/if}</div>
-               </div>
+       <div class="codeBoxHeader">
+               <div class="codeBoxHeadline">{$title}{if $filename}: {$filename}{/if}</div>
                
-               {assign var='lineNumber' value=$startLineNumber}
-               <pre class="codeBoxCode"><code{if $language} class="language-{$language}"{/if}>{foreach from=$content item=line}{*
-                       *}{assign var='codeLineID' value='codeLine_'|concat:$lineNumber:'_':$codeID}{*
-                       *}<div class="codeBoxLine" id="{$codeLineID}"><a href="{@$__wcf->getAnchor($codeLineID)}" class="lineAnchor" title="{@$lineNumber}"></a><span>{$line}</span></div>{*
-                       *}{assign var='lineNumber' value=$lineNumber+1}{*
-               *}{/foreach}</code></pre>
+               {if !$isAmp && $lines > 10}
+                       <span class="toggleButton icon icon24 fa-expand jsTooltip pointer" title="{lang}wcf.bbcode.button.showAll{/lang}" data-title-collapse="{lang}wcf.bbcode.button.collapse{/lang}" data-title-expand="{lang}wcf.bbcode.button.showAll{/lang}"></span>
+               {/if}
        </div>
+       
+       {assign var='lineNumber' value=$startLineNumber}
+       <pre class="codeBoxCode collapsibleBbcodeOverflow"><code{if $language} class="language-{$language}"{/if}>{foreach from=$content item=line}{*
+               *}{assign var='codeLineID' value='codeLine_'|concat:$lineNumber:'_':$codeID}{*
+               *}<span class="codeBoxLine" id="{$codeLineID}"><a href="{@$__wcf->getAnchor($codeLineID)}" class="lineAnchor" title="{@$lineNumber}"></a><span>{$line}</span></span>{*
+               *}{assign var='lineNumber' value=$lineNumber+1}{*
+       *}{/foreach}</code></pre>
+       
        {if !$isAmp && $lines > 10}
                <span class="toggleButton" data-title-collapse="{lang}wcf.bbcode.button.collapse{/lang}" data-title-expand="{lang}wcf.bbcode.button.showAll{/lang}">{lang}wcf.bbcode.button.showAll{/lang}</span>
        {/if}
@@ -19,8 +22,8 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Bbcode/Collapsible', 'WoltLabSuite/Core/Bbcode/Code'], function (Language, BbcodeCollapsible, BbcodeCode) {
                        Language.addObject({
-                               'wcf.message.bbcode.code.copy': '{lang}wcf.message.bbcode.code.copy{/lang}',
-                               'wcf.message.bbcode.code.copy.success': '{lang}wcf.message.bbcode.code.copy.success{/lang}'
+                               'wcf.message.bbcode.code.copy': '{jslang}wcf.message.bbcode.code.copy{/jslang}',
+                               'wcf.message.bbcode.code.copy.success': '{jslang}wcf.message.bbcode.code.copy.success{/jslang}'
                        });
                        BbcodeCollapsible.observe();
                        BbcodeCode.processAll();
index 2729e622a1e50a29a11c7e55858613848ed1f7bd..0e59727e94c6731a1f8efcb634ce0c36caf18798 100644 (file)
@@ -3,7 +3,7 @@
           data-disable-attachments="true"
           data-disable-media="true"
 >{$comment->message}</textarea>
-{*include file='messageFormTabsInline'*}
+{include file='messageFormTabsInline'}
 
 <div class="formSubmit">
        <button class="buttonPrimary" data-type="save" accesskey="s">{lang}wcf.global.button.submit{/lang}</button>
index d76ce5ac2751b21e0fddc3fae0e28c81a7380e42..6e577321e56a37598582229a3706d6a57433a6bd 100644 (file)
@@ -14,9 +14,7 @@
                >
                        <div class="box48{if $__wcf->getUserProfileHandler()->isIgnoredUser($comment->userID)} ignoredUserContent{/if}">
                                {if $comment->userID}
-                                       <a href="{link controller='User' object=$comment->getUserProfile()}{/link}" title="{$comment->getUserProfile()->username}">
-                                               {@$comment->getUserProfile()->getAvatar()->getImageTag(48)}
-                                       </a>
+                                       {user object=$comment->getUserProfile() type='avatar48' title=$comment->getUserProfile()->username}
                                {else}
                                        {@$comment->getUserProfile()->getAvatar()->getImageTag(48)}
                                {/if}
@@ -28,8 +26,8 @@
                                                <div class="containerHeadline">
                                                        <h3 itemprop="author" itemscope itemtype="http://schema.org/Person">
                                                                {if $comment->userID}
-                                                                       <a href="{link controller='User' object=$comment->getUserProfile()}{/link}" class="userLink" data-user-id="{@$comment->userID}" itemprop="url">
-                                                                               <span itemprop="name">{$comment->username}</span>
+                                                                       <a href="{$comment->getUserProfile()->getLink()}" class="userLink" data-object-id="{@$comment->userID}" itemprop="url">
+                                                                               <span itemprop="name">{@$comment->getUserProfile()->getFormattedUsername()}</span>
                                                                        </a>
                                                                {else}
                                                                        <span itemprop="name">{$comment->username}</span>
                                                                {if $comment->isDisabled}
                                                                        <span class="badge label green jsIconDisabled">{lang}wcf.message.status.disabled{/lang}</span>
                                                                {/if}
+                                                               
+                                                               {if $commentManager->isContentAuthor($comment)}
+                                                                       <span class="badge label">{lang}wcf.comment.objectAuthor{/lang}</span>
+                                                               {/if}
                                                        </h3>
                                                </div>
                                                
index 0534cc8c8a5ed6b69a774b736c5a261205f0a351..9efcc2da8034586560350467fec75318faf45b3b 100644 (file)
@@ -10,6 +10,7 @@
                                  data-disable-attachments="true"
                                  data-disable-media="true"
                        ></textarea>
+                       {include file='messageFormTabsInline'}
                        
                        {* in-template call for full backwards-compatibility *}
                        {$commentList->getCommentManager()->setDisallowedBBCodes()}
@@ -40,6 +41,7 @@
                                          data-disable-attachments="true"
                                          data-disable-media="true"
                                ></textarea>
+                               {include file='messageFormTabsInline' wysiwygSelector=$_commentResponseWysiwygSelector}
                                
                                {* in-template call for full backwards-compatibility *}
                                {$commentList->getCommentManager()->setDisallowedBBCodes()}
index c8a0b0beca9cf7b755f4b33c0ad9ce76ddd72cd0..6dbae7762ab74e84c109719c447436039a27106d 100644 (file)
@@ -3,7 +3,7 @@
           data-disable-attachments="true"
           data-disable-media="true"
 >{$response->message}</textarea>
-{*include file='messageFormTabsInline'*}
+{include file='messageFormTabsInline'}
 
 <div class="formSubmit">
        <button class="buttonPrimary" data-type="save" accesskey="s">{lang}wcf.global.button.submit{/lang}</button>
index 09a6215a53f4199e8531642de0506079d1aadf78..90fd8b28e1b068cc71d6f4a508e2e3eed895e9e8 100644 (file)
@@ -7,9 +7,7 @@
                <li class="commentResponse jsCommentResponse" data-response-id="{@$response->responseID}" {@$__wcf->getReactionHandler()->getDataAttributes('com.woltlab.wcf.comment.response', $response->responseID)} data-can-edit="{if $response->isEditable()}true{else}false{/if}" data-can-delete="{if $response->isDeletable()}true{else}false{/if}" data-user-id="{@$response->userID}">
                        <div class="box32{if $__wcf->getUserProfileHandler()->isIgnoredUser($response->userID)} ignoredUserContent{/if}">
                                {if $response->userID}
-                                       <a href="{link controller='User' object=$response->getUserProfile()}{/link}" title="{$response->getUserProfile()->username}">
-                                               {@$response->getUserProfile()->getAvatar()->getImageTag(32)}
-                                       </a>
+                                       {user object=$response->getUserProfile() type='avatar32' title=$response->getUserProfile()->username}
                                {else}
                                        {@$response->getUserProfile()->getAvatar()->getImageTag(32)}
                                {/if}
@@ -20,8 +18,8 @@
                                        <div class="containerHeadline">
                                                <h3 itemprop="author" itemscope itemtype="http://schema.org/Person">
                                                        {if $response->userID}
-                                                               <a href="{link controller='User' object=$response->getUserProfile()}{/link}" class="userLink" data-user-id="{@$response->userID}" itemprop="url">
-                                                                       <span itemprop="name">{$response->username}</span>
+                                                               <a href="{$response->getUserProfile()->getLink()}" class="userLink" data-object-id="{@$response->userID}" itemprop="url">
+                                                                       <span itemprop="name">{@$response->getUserProfile()->getFormattedUsername()}</span>
                                                                </a>
                                                        {else}
                                                                <span itemprop="name">{$response->username}</span>
                                                        {if $response->isDisabled}
                                                                <span class="badge label green jsIconDisabled">{lang}wcf.message.status.disabled{/lang}</span>
                                                        {/if}
+                                                       
+                                                       {if $commentManager->isContentAuthor($response)}
+                                                               <span class="badge label">{lang}wcf.comment.objectAuthor{/lang}</span>
+                                                       {/if}
                                                </h3>
                                        </div>
                                        
@@ -48,7 +50,7 @@
                                                                <li class="jsReportCommentResponse jsOnly" data-object-id="{@$response->responseID}"><a href="#" title="{lang}wcf.moderation.report.reportContent{/lang}" class="jsTooltip"><span class="icon icon16 fa-exclamation-triangle"></span> <span class="invisible">{lang}wcf.moderation.report.reportContent{/lang}</span></a></li>
                                                        {/if}
                                                        
-                                                       {if MODULE_LIKE && $commentManager->supportsLike() && $__wcf->session->getPermission('user.like.canLike') && $response->userID != $__wcf->user->userID}<li class="jsOnly"><a href="#" class="reactButton jsTooltip {if $likeData[response][$response->responseID]|isset && $likeData[response][$response->responseID]->reactionTypeID} active{/if}" title="{lang}wcf.reactions.react{/lang}" data-reaction-type-id="{if $likeData[response][$response->responseID]|isset && $likeData[response][$response->responseID]->reactionTypeID}{$likeData[response][$response->responseID]->reactionTypeID}{else}0{/if}"><span class="icon icon16 fa-smile-o"></span> <span class="invisible">{lang}wcf.reactions.react{/lang}</span></a></li>{/if}
+                                                       {if MODULE_LIKE && $commentManager->supportsLike() && $__wcf->session->getPermission('user.like.canLike') && $response->userID != $__wcf->user->userID}<li class="jsOnly"><a href="#" class="reactButtonCommentResponse jsTooltip {if $likeData[response][$response->responseID]|isset && $likeData[response][$response->responseID]->reactionTypeID} active{/if}" title="{lang}wcf.reactions.react{/lang}" data-reaction-type-id="{if $likeData[response][$response->responseID]|isset && $likeData[response][$response->responseID]->reactionTypeID}{$likeData[response][$response->responseID]->reactionTypeID}{else}0{/if}"><span class="icon icon16 fa-smile-o"></span> <span class="invisible">{lang}wcf.reactions.react{/lang}</span></a></li>{/if}
                                                        
                                                        {event name='commentOptions'}
                                                </ul>
index b668b486dd3699156e0c94e8aea239b5e18580e8..673b2d4e49c0bdcfb572394895402ec0557282e8 100644 (file)
        {hascontent}
        <span style="font-size: 0;">-- <br></span>
        {content}
+       {if MAIL_SIGNATURE_HTML|language}
+       {@MAIL_SIGNATURE_HTML|language}
+       {else}
        {@MAIL_SIGNATURE|language|newlineToBreak}
-       {/content}
-       {/hascontent}
-       {/capture}
+       {/if}
+       {/content}{/hascontent}{/capture}
        {include file='email_paddingHelper' block=true class='footer' content=$footer sandbox=true}
        
        <table>{* Do not remove: This table is needed by certain less able email clients to properly support background colors. Don't ask. *}</table>
index ce08b7779ab31b42a0bf372495ba2f0f4c594c1b..2cacef03c05b388cd1a4f2602d96c78633b6a56a 100644 (file)
@@ -20,7 +20,7 @@
 
        {capture assign=button}
        <a href="{link controller='NotificationConfirm' isHtmlEmail=true id=$event->getNotification()->notificationID}{/link}">
-               {lang}wcf.user.notification.markAsConfirmed{/lang}
+               {lang}wcf.user.notification.mail.jumpToContent{/lang}
        </a>
        {/capture}
        {include file='email_paddingHelper' class='button' outerClass='paragraphMargin' content=$button sandbox=true}
index c81f8313d17ca78d92acede0aa3f24eb9ed624b0..31185e0ccd310295786b944b104f640cbb4cba1d 100644 (file)
@@ -7,7 +7,7 @@
        {lang}wcf.user.register.needActivation.mail.html.intro{/lang}
 
        {capture assign=button}
-       <a href="{link controller='RegisterActivation' isHtmlEmail=true}u={@$mailbox->getUser()->userID}&a={@$mailbox->getUser()->activationCode}{/link}">
+       <a href="{link controller='RegisterActivation' isHtmlEmail=true}u={@$mailbox->getUser()->userID}&a={@$mailbox->getUser()->emailConfirmed}{/link}">
                {lang}wcf.user.register.needActivation.mail.html.activate{/lang}
        </a>
        {/capture}
index bd85e2c00e3c07edc4634f6b4ca7b049fdb52fac..9693ce6b1b9e8c65c70d30013c8251f4d867f319 100644 (file)
@@ -16,8 +16,8 @@
                        {foreach from=$objects item=user}
                                <li class="jsFollowing">
                                        <div class="box48">
-                                               <a href="{link controller='User' object=$user}{/link}" title="{$user->username}">{@$user->getAvatar()->getImageTag(48)}</a>
-                                                       
+                                               {user object=$user type='avatar48' title=$user->username}
+                                               
                                                <div class="details userInformation">
                                                        {include file='userInformationHeadline'}
                                                        
index 7bc89c3680d4b8fb088bc12dd9effea4b3d8d10a..f7088beb4ad5c7826a8992f5ee4bb6473a2654f7 100644 (file)
@@ -1,10 +1,10 @@
 <script>
        require(['Language', 'WoltLabSuite/Core/Ui/Style/FontAwesome'], function (Language, UiStyleFontAwesome) {
                Language.addObject({
-                       'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                       'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                       'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                       'wcf.global.fontAwesome.selectIcon': '{lang}wcf.global.fontAwesome.selectIcon{/lang}'
+                       'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                       'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                       'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                       'wcf.global.fontAwesome.selectIcon': '{jslang}wcf.global.fontAwesome.selectIcon{/jslang}'
                });
                
                UiStyleFontAwesome.setup({@$__wcf->getStyleHandler()->getIcons(true)});
diff --git a/com.woltlab.wcf/templates/formNotice.tpl b/com.woltlab.wcf/templates/formNotice.tpl
new file mode 100644 (file)
index 0000000..f63d721
--- /dev/null
@@ -0,0 +1,3 @@
+{include file='formError'}
+
+{include file='formSuccess'}
diff --git a/com.woltlab.wcf/templates/formSuccess.tpl b/com.woltlab.wcf/templates/formSuccess.tpl
new file mode 100644 (file)
index 0000000..a8347ae
--- /dev/null
@@ -0,0 +1,9 @@
+{if $success|isset}
+       <p class="success" role="status">
+               <span>{lang}wcf.global.success.{$action}{/lang}</span>
+       
+               {if $action == 'add' && !$objectEditLink|empty}
+                       <span>{lang}wcf.global.success.add.editCreatedObject{/lang}</span>
+               {/if}
+       </p>
+{/if}
index 36c1cc79d5a826ae0861c6b14b8a8b0babc30766..0d3bcfbbf49664a636b6a45cd1bba4891669378e 100644 (file)
@@ -7,20 +7,20 @@
        <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.map.noLocationSuggestions': '{lang}wcf.map.noLocationSuggestions{/lang}',
-                               'wcf.map.route.error.not_found': '{lang}wcf.map.route.error.not_found{/lang}',
-                               'wcf.map.route.error.over_query_limit': '{lang}wcf.map.route.error.over_query_limit{/lang}',
-                               'wcf.map.route.error.request_denied': '{lang}wcf.map.route.error.request_denied{/lang}',
-                               'wcf.map.route.origin': '{lang}wcf.map.route.origin{/lang}',
-                               'wcf.map.route.planner': '{lang}wcf.map.route.planner{/lang}',
-                               'wcf.map.route.travelMode': '{lang}wcf.map.route.travelMode{/lang}',
-                               'wcf.map.route.travelMode.bicycling': '{lang}wcf.map.route.travelMode.bicycling{/lang}',
-                               'wcf.map.route.travelMode.driving': '{lang}wcf.map.route.travelMode.driving{/lang}',
-                               'wcf.map.route.travelMode.transit': '{lang}wcf.map.route.travelMode.transit{/lang}',
-                               'wcf.map.route.travelMode.walking': '{lang}wcf.map.route.travelMode.walking{/lang}',
-                               'wcf.map.route.viewOnGoogleMaps': '{lang}wcf.map.route.viewOnGoogleMaps{/lang}',
-                               'wcf.map.showLocationSuggestions': '{lang}wcf.map.showLocationSuggestions{/lang}',
-                               'wcf.map.useLocationSuggestion': '{lang}wcf.map.useLocationSuggestion{/lang}'
+                               'wcf.map.noLocationSuggestions': '{jslang}wcf.map.noLocationSuggestions{/jslang}',
+                               'wcf.map.route.error.not_found': '{jslang}wcf.map.route.error.not_found{/jslang}',
+                               'wcf.map.route.error.over_query_limit': '{jslang}wcf.map.route.error.over_query_limit{/jslang}',
+                               'wcf.map.route.error.request_denied': '{jslang}wcf.map.route.error.request_denied{/jslang}',
+                               'wcf.map.route.origin': '{jslang}wcf.map.route.origin{/jslang}',
+                               'wcf.map.route.planner': '{jslang}wcf.map.route.planner{/jslang}',
+                               'wcf.map.route.travelMode': '{jslang}wcf.map.route.travelMode{/jslang}',
+                               'wcf.map.route.travelMode.bicycling': '{jslang}wcf.map.route.travelMode.bicycling{/jslang}',
+                               'wcf.map.route.travelMode.driving': '{jslang}wcf.map.route.travelMode.driving{/jslang}',
+                               'wcf.map.route.travelMode.transit': '{jslang}wcf.map.route.travelMode.transit{/jslang}',
+                               'wcf.map.route.travelMode.walking': '{jslang}wcf.map.route.travelMode.walking{/jslang}',
+                               'wcf.map.route.viewOnGoogleMaps': '{jslang}wcf.map.route.viewOnGoogleMaps{/jslang}',
+                               'wcf.map.showLocationSuggestions': '{jslang}wcf.map.showLocationSuggestions{/jslang}',
+                               'wcf.map.useLocationSuggestion': '{jslang}wcf.map.useLocationSuggestion{/jslang}'
                        });
                        
                        WCF.Location.GoogleMaps.Settings.set({
index dc8a742f20b90ce8858bc36d9a5bbb99677b8194..89c21e99415f998f90605e2c7ac83da42c2e4ad5 100644 (file)
 <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                               'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                               'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                               'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                               'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                               'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                               'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                               'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                        });
                        
                        new WCF.User.Action.Follow($('.jsGroupedUserList > li'));
                        new WCF.User.Action.Ignore($('.jsGroupedUserList > li'));
                });
-</script>
\ No newline at end of file
+</script>
index 25a5a5d0c2597d4831a141270a5dfa084f3125d1..e55095362c425c28bc5cefa767ee5ae23cf8aadd 100644 (file)
 <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                               'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                               'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                               'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                               'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                               'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                               'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                               'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                        });
                        
                        new WCF.User.Action.Follow($('.jsGroupedUserList > li'));
                        new WCF.User.Action.Ignore($('.jsGroupedUserList > li'));
                });
-</script>
\ No newline at end of file
+</script>
index f822ef17b891a56389bc4850b2b4b073583ecf6e..744e17f52ccb7976014f198489a99efd030c956e 100644 (file)
@@ -1,14 +1,11 @@
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta name="format-detection" content="telephone=no">
-{if $allowSpidersToIndexThisPage|empty && ($__wcf->getActivePage() == null || !$__wcf->getActivePage()->allowSpidersToIndex)}<meta name="robots" content="noindex,nofollow">{/if}
+{include file='headIncludeRobotsMetaTag'}
 {implode from=$__wcf->getMetaTagHandler() item=__metaTag glue="\n"}{@$__metaTag}{/implode}
 {event name='metaTags'}
 
 <!-- Stylesheets -->
-{if $__wcf->getStyleHandler()->getStyle()->getVariable('useGoogleFont')}
-       <link href='//fonts.googleapis.com/css?family={$__wcf->getStyleHandler()->getStyle()->getVariable('wcfFontFamilyGoogle')|urlencode}:400,300,600' rel='stylesheet' type='text/css'>
-{/if}
 {@$__wcf->getStyleHandler()->getStylesheet()}
 {event name='stylesheets'}
 
@@ -17,7 +14,7 @@
 <script data-relocate="true">
        WCF.Language.addObject({
                {* dummy language item to preserve compatibility with WCF 2.0, move this to headIncludeJavaScript *}
-               'wcf.global.error.title': '{lang}wcf.global.error.title{/lang}'
+               'wcf.global.error.title': '{jslang}wcf.global.error.title{/jslang}'
                
                {* DEPRECATED -- PLEASE USE javascriptLanguageImport@headIncludeJavaScript *}
                {event name='javascriptLanguageImport'}
index 03e128c4f8713d824900685fdbdd1f13cb85e41a..634055da280f990758c676cb48ead72409abbfab 100644 (file)
@@ -52,93 +52,93 @@ window.addEventListener('pageshow', function(event) {
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/BootstrapFrontend', 'User'], function(Language, BootstrapFrontend, User) {
                Language.addObject({
-                       '__days': [ '{lang}wcf.date.day.sunday{/lang}', '{lang}wcf.date.day.monday{/lang}', '{lang}wcf.date.day.tuesday{/lang}', '{lang}wcf.date.day.wednesday{/lang}', '{lang}wcf.date.day.thursday{/lang}', '{lang}wcf.date.day.friday{/lang}', '{lang}wcf.date.day.saturday{/lang}' ],
-                       '__daysShort': [ '{lang}wcf.date.day.sun{/lang}', '{lang}wcf.date.day.mon{/lang}', '{lang}wcf.date.day.tue{/lang}', '{lang}wcf.date.day.wed{/lang}', '{lang}wcf.date.day.thu{/lang}', '{lang}wcf.date.day.fri{/lang}', '{lang}wcf.date.day.sat{/lang}' ],
-                       '__months': [ '{lang}wcf.date.month.january{/lang}', '{lang}wcf.date.month.february{/lang}', '{lang}wcf.date.month.march{/lang}', '{lang}wcf.date.month.april{/lang}', '{lang}wcf.date.month.may{/lang}', '{lang}wcf.date.month.june{/lang}', '{lang}wcf.date.month.july{/lang}', '{lang}wcf.date.month.august{/lang}', '{lang}wcf.date.month.september{/lang}', '{lang}wcf.date.month.october{/lang}', '{lang}wcf.date.month.november{/lang}', '{lang}wcf.date.month.december{/lang}' ], 
-                       '__monthsShort': [ '{lang}wcf.date.month.short.jan{/lang}', '{lang}wcf.date.month.short.feb{/lang}', '{lang}wcf.date.month.short.mar{/lang}', '{lang}wcf.date.month.short.apr{/lang}', '{lang}wcf.date.month.short.may{/lang}', '{lang}wcf.date.month.short.jun{/lang}', '{lang}wcf.date.month.short.jul{/lang}', '{lang}wcf.date.month.short.aug{/lang}', '{lang}wcf.date.month.short.sep{/lang}', '{lang}wcf.date.month.short.oct{/lang}', '{lang}wcf.date.month.short.nov{/lang}', '{lang}wcf.date.month.short.dec{/lang}' ],
-                       'wcf.clipboard.item.unmarkAll': '{lang}wcf.clipboard.item.unmarkAll{/lang}',
-                       'wcf.clipboard.item.markAll': '{lang}wcf.clipboard.item.markAll{/lang}',
-                       'wcf.clipboard.item.mark': '{lang}wcf.clipboard.item.mark{/lang}',
-                       'wcf.date.relative.now': '{lang __literal=true}wcf.date.relative.now{/lang}',
-                       'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang __literal=true}wcf.date.relative.minutes{/lang}{/capture}{@$relativeMinutes|encodeJS}',
-                       'wcf.date.relative.hours': '{capture assign=relativeHours}{lang __literal=true}wcf.date.relative.hours{/lang}{/capture}{@$relativeHours|encodeJS}',
-                       'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang __literal=true}wcf.date.relative.pastDays{/lang}{/capture}{@$relativePastDays|encodeJS}',
-                       'wcf.date.dateFormat': '{"wcf.date.dateFormat"|language|encodeJS}',
-                       'wcf.date.dateTimeFormat': '{lang}wcf.date.dateTimeFormat{/lang}',
-                       'wcf.date.shortDateTimeFormat': '{lang}wcf.date.shortDateTimeFormat{/lang}',
-                       'wcf.date.hour': '{lang}wcf.date.hour{/lang}',
-                       'wcf.date.minute': '{lang}wcf.date.minute{/lang}',
-                       'wcf.date.timeFormat': '{lang}wcf.date.timeFormat{/lang}',
-                       'wcf.date.firstDayOfTheWeek': '{lang}wcf.date.firstDayOfTheWeek{/lang}',
-                       'wcf.global.button.add': '{lang}wcf.global.button.add{/lang}',
-                       'wcf.global.button.cancel': '{lang}wcf.global.button.cancel{/lang}',
-                       'wcf.global.button.close': '{lang}wcf.global.button.close{/lang}',
-                       'wcf.global.button.collapsible': '{lang}wcf.global.button.collapsible{/lang}',
-                       'wcf.global.button.delete': '{lang}wcf.global.button.delete{/lang}',
-                       'wcf.global.button.disable': '{lang}wcf.global.button.disable{/lang}',
-                       'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}',
-                       'wcf.global.button.edit': '{lang}wcf.global.button.edit{/lang}',
-                       'wcf.global.button.enable': '{lang}wcf.global.button.enable{/lang}',
-                       'wcf.global.button.hide': '{lang}wcf.global.button.hide{/lang}',
-                       'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
-                       'wcf.global.button.next': '{lang}wcf.global.button.next{/lang}',
-                       'wcf.global.button.preview': '{lang}wcf.global.button.preview{/lang}',
-                       'wcf.global.button.reset': '{lang}wcf.global.button.reset{/lang}',
-                       'wcf.global.button.save': '{lang}wcf.global.button.save{/lang}',
-                       'wcf.global.button.search': '{lang}wcf.global.button.search{/lang}',
-                       'wcf.global.button.submit': '{lang}wcf.global.button.submit{/lang}',
-                       'wcf.global.button.upload': '{lang}wcf.global.button.upload{/lang}',
-                       'wcf.global.confirmation.cancel': '{lang}wcf.global.confirmation.cancel{/lang}',
-                       'wcf.global.confirmation.confirm': '{lang}wcf.global.confirmation.confirm{/lang}',
-                       'wcf.global.confirmation.title': '{lang}wcf.global.confirmation.title{/lang}',
-                       'wcf.global.decimalPoint': '{capture assign=decimalPoint}{lang}wcf.global.decimalPoint{/lang}{/capture}{$decimalPoint|encodeJS}',
-                       'wcf.global.error.timeout': '{lang}wcf.global.error.timeout{/lang}',
-                       'wcf.global.form.error.empty': '{lang}wcf.global.form.error.empty{/lang}',
-                       'wcf.global.form.error.greaterThan': '{lang __literal=true}wcf.global.form.error.greaterThan{/lang}',
-                       'wcf.global.form.error.lessThan': '{lang __literal=true}wcf.global.form.error.lessThan{/lang}',
-                       'wcf.global.form.error.multilingual': '{lang}wcf.global.form.error.multilingual{/lang}',
-                       'wcf.global.form.input.maxItems': '{lang}wcf.global.form.input.maxItems{/lang}',
-                       'wcf.global.language.noSelection': '{lang}wcf.global.language.noSelection{/lang}',
-                       'wcf.global.loading': '{lang}wcf.global.loading{/lang}',
-                       'wcf.global.noSelection': '{lang}wcf.global.noSelection{/lang}',
-                       'wcf.global.select': '{lang}wcf.global.select{/lang}',
-                       'wcf.page.jumpTo': '{lang}wcf.page.jumpTo{/lang}',
-                       'wcf.page.jumpTo.description': '{lang}wcf.page.jumpTo.description{/lang}',
-                       'wcf.global.page.pagination': '{lang}wcf.global.page.pagination{/lang}',
-                       'wcf.global.page.next': '{capture assign=pageNext}{lang}wcf.global.page.next{/lang}{/capture}{@$pageNext|encodeJS}',
-                       'wcf.global.page.previous': '{capture assign=pagePrevious}{lang}wcf.global.page.previous{/lang}{/capture}{@$pagePrevious|encodeJS}',
-                       'wcf.global.pageDirection': '{lang}wcf.global.pageDirection{/lang}',
-                       'wcf.global.reason': '{lang}wcf.global.reason{/lang}',
-                       'wcf.global.scrollUp': '{lang}wcf.global.scrollUp{/lang}',
-                       'wcf.global.success': '{lang}wcf.global.success{/lang}',
-                       'wcf.global.success.add': '{lang}wcf.global.success.add{/lang}',
-                       'wcf.global.success.edit': '{lang}wcf.global.success.edit{/lang}',
-                       'wcf.global.thousandsSeparator': '{capture assign=thousandsSeparator}{lang}wcf.global.thousandsSeparator{/lang}{/capture}{@$thousandsSeparator|encodeJS}',
-                       'wcf.page.pagePosition': '{lang __literal=true}wcf.page.pagePosition{/lang}',
-                       'wcf.style.changeStyle': '{lang}wcf.style.changeStyle{/lang}',
-                       'wcf.user.activityPoint': '{lang}wcf.user.activityPoint{/lang}',
-                       'wcf.user.panel.markAllAsRead': '{lang}wcf.user.panel.markAllAsRead{/lang}',
-                       'wcf.user.panel.markAsRead': '{lang}wcf.user.panel.markAsRead{/lang}',
-                       'wcf.user.panel.settings': '{lang}wcf.user.panel.settings{/lang}',
-                       'wcf.user.panel.showAll': '{lang}wcf.user.panel.showAll{/lang}',
-                       'wcf.menu.page': '{lang}wcf.menu.page{/lang}',
-                       'wcf.menu.user': '{lang}wcf.menu.user{/lang}',
-                       'wcf.global.button.showMenu': '{lang}wcf.global.button.showMenu{/lang}',
-                       'wcf.global.button.hideMenu': '{lang}wcf.global.button.hideMenu{/lang}',
-                       'wcf.date.datePicker': '{lang}wcf.date.datePicker{/lang}',
-                       'wcf.date.datePicker.previousMonth': '{lang}wcf.date.datePicker.previousMonth{/lang}',
-                       'wcf.date.datePicker.nextMonth': '{lang}wcf.date.datePicker.nextMonth{/lang}',
-                       'wcf.date.datePicker.month': '{lang}wcf.date.datePicker.month{/lang}',
-                       'wcf.date.datePicker.year': '{lang}wcf.date.datePicker.year{/lang}',
-                       'wcf.date.datePicker.hour': '{lang}wcf.date.datePicker.hour{/lang}',
-                       'wcf.date.datePicker.minute': '{lang}wcf.date.datePicker.minute{/lang}'
+                       '__days': [ '{jslang}wcf.date.day.sunday{/jslang}', '{jslang}wcf.date.day.monday{/jslang}', '{jslang}wcf.date.day.tuesday{/jslang}', '{jslang}wcf.date.day.wednesday{/jslang}', '{jslang}wcf.date.day.thursday{/jslang}', '{jslang}wcf.date.day.friday{/jslang}', '{jslang}wcf.date.day.saturday{/jslang}' ],
+                       '__daysShort': [ '{jslang}wcf.date.day.sun{/jslang}', '{jslang}wcf.date.day.mon{/jslang}', '{jslang}wcf.date.day.tue{/jslang}', '{jslang}wcf.date.day.wed{/jslang}', '{jslang}wcf.date.day.thu{/jslang}', '{jslang}wcf.date.day.fri{/jslang}', '{jslang}wcf.date.day.sat{/jslang}' ],
+                       '__months': [ '{jslang}wcf.date.month.january{/jslang}', '{jslang}wcf.date.month.february{/jslang}', '{jslang}wcf.date.month.march{/jslang}', '{jslang}wcf.date.month.april{/jslang}', '{jslang}wcf.date.month.may{/jslang}', '{jslang}wcf.date.month.june{/jslang}', '{jslang}wcf.date.month.july{/jslang}', '{jslang}wcf.date.month.august{/jslang}', '{jslang}wcf.date.month.september{/jslang}', '{jslang}wcf.date.month.october{/jslang}', '{jslang}wcf.date.month.november{/jslang}', '{jslang}wcf.date.month.december{/jslang}' ], 
+                       '__monthsShort': [ '{jslang}wcf.date.month.short.jan{/jslang}', '{jslang}wcf.date.month.short.feb{/jslang}', '{jslang}wcf.date.month.short.mar{/jslang}', '{jslang}wcf.date.month.short.apr{/jslang}', '{jslang}wcf.date.month.short.may{/jslang}', '{jslang}wcf.date.month.short.jun{/jslang}', '{jslang}wcf.date.month.short.jul{/jslang}', '{jslang}wcf.date.month.short.aug{/jslang}', '{jslang}wcf.date.month.short.sep{/jslang}', '{jslang}wcf.date.month.short.oct{/jslang}', '{jslang}wcf.date.month.short.nov{/jslang}', '{jslang}wcf.date.month.short.dec{/jslang}' ],
+                       'wcf.clipboard.item.unmarkAll': '{jslang}wcf.clipboard.item.unmarkAll{/jslang}',
+                       'wcf.clipboard.item.markAll': '{jslang}wcf.clipboard.item.markAll{/jslang}',
+                       'wcf.clipboard.item.mark': '{jslang}wcf.clipboard.item.mark{/jslang}',
+                       'wcf.date.relative.now': '{jslang __literal=true}wcf.date.relative.now{/jslang}',
+                       'wcf.date.relative.minutes': '{jslang __literal=true}wcf.date.relative.minutes{/jslang}',
+                       'wcf.date.relative.hours': '{jslang __literal=true}wcf.date.relative.hours{/jslang}',
+                       'wcf.date.relative.pastDays': '{jslang __literal=true}wcf.date.relative.pastDays{/jslang}',
+                       'wcf.date.dateFormat': '{jslang}wcf.date.dateFormat{/jslang}',
+                       'wcf.date.dateTimeFormat': '{jslang}wcf.date.dateTimeFormat{/jslang}',
+                       'wcf.date.shortDateTimeFormat': '{jslang}wcf.date.shortDateTimeFormat{/jslang}',
+                       'wcf.date.hour': '{jslang}wcf.date.hour{/jslang}',
+                       'wcf.date.minute': '{jslang}wcf.date.minute{/jslang}',
+                       'wcf.date.timeFormat': '{jslang}wcf.date.timeFormat{/jslang}',
+                       'wcf.date.firstDayOfTheWeek': '{jslang}wcf.date.firstDayOfTheWeek{/jslang}',
+                       'wcf.global.button.add': '{jslang}wcf.global.button.add{/jslang}',
+                       'wcf.global.button.cancel': '{jslang}wcf.global.button.cancel{/jslang}',
+                       'wcf.global.button.close': '{jslang}wcf.global.button.close{/jslang}',
+                       'wcf.global.button.collapsible': '{jslang}wcf.global.button.collapsible{/jslang}',
+                       'wcf.global.button.delete': '{jslang}wcf.global.button.delete{/jslang}',
+                       'wcf.global.button.disable': '{jslang}wcf.global.button.disable{/jslang}',
+                       'wcf.global.button.disabledI18n': '{jslang}wcf.global.button.disabledI18n{/jslang}',
+                       'wcf.global.button.edit': '{jslang}wcf.global.button.edit{/jslang}',
+                       'wcf.global.button.enable': '{jslang}wcf.global.button.enable{/jslang}',
+                       'wcf.global.button.hide': '{jslang}wcf.global.button.hide{/jslang}',
+                       'wcf.global.button.insert': '{jslang}wcf.global.button.insert{/jslang}',
+                       'wcf.global.button.next': '{jslang}wcf.global.button.next{/jslang}',
+                       'wcf.global.button.preview': '{jslang}wcf.global.button.preview{/jslang}',
+                       'wcf.global.button.reset': '{jslang}wcf.global.button.reset{/jslang}',
+                       'wcf.global.button.save': '{jslang}wcf.global.button.save{/jslang}',
+                       'wcf.global.button.search': '{jslang}wcf.global.button.search{/jslang}',
+                       'wcf.global.button.submit': '{jslang}wcf.global.button.submit{/jslang}',
+                       'wcf.global.button.upload': '{jslang}wcf.global.button.upload{/jslang}',
+                       'wcf.global.confirmation.cancel': '{jslang}wcf.global.confirmation.cancel{/jslang}',
+                       'wcf.global.confirmation.confirm': '{jslang}wcf.global.confirmation.confirm{/jslang}',
+                       'wcf.global.confirmation.title': '{jslang}wcf.global.confirmation.title{/jslang}',
+                       'wcf.global.decimalPoint': '{jslang}wcf.global.decimalPoint{/jslang}',
+                       'wcf.global.error.timeout': '{jslang}wcf.global.error.timeout{/jslang}',
+                       'wcf.global.form.error.empty': '{jslang}wcf.global.form.error.empty{/jslang}',
+                       'wcf.global.form.error.greaterThan': '{jslang __literal=true}wcf.global.form.error.greaterThan{/jslang}',
+                       'wcf.global.form.error.lessThan': '{jslang __literal=true}wcf.global.form.error.lessThan{/jslang}',
+                       'wcf.global.form.error.multilingual': '{jslang}wcf.global.form.error.multilingual{/jslang}',
+                       'wcf.global.form.input.maxItems': '{jslang}wcf.global.form.input.maxItems{/jslang}',
+                       'wcf.global.language.noSelection': '{jslang}wcf.global.language.noSelection{/jslang}',
+                       'wcf.global.loading': '{jslang}wcf.global.loading{/jslang}',
+                       'wcf.global.noSelection': '{jslang}wcf.global.noSelection{/jslang}',
+                       'wcf.global.select': '{jslang}wcf.global.select{/jslang}',
+                       'wcf.page.jumpTo': '{jslang}wcf.page.jumpTo{/jslang}',
+                       'wcf.page.jumpTo.description': '{jslang}wcf.page.jumpTo.description{/jslang}',
+                       'wcf.global.page.pagination': '{jslang}wcf.global.page.pagination{/jslang}',
+                       'wcf.global.page.next': '{jslang}wcf.global.page.next{/jslang}',
+                       'wcf.global.page.previous': '{jslang}wcf.global.page.previous{/jslang}',
+                       'wcf.global.pageDirection': '{jslang}wcf.global.pageDirection{/jslang}',
+                       'wcf.global.reason': '{jslang}wcf.global.reason{/jslang}',
+                       'wcf.global.scrollUp': '{jslang}wcf.global.scrollUp{/jslang}',
+                       'wcf.global.success': '{jslang}wcf.global.success{/jslang}',
+                       'wcf.global.success.add': '{jslang}wcf.global.success.add{/jslang}',
+                       'wcf.global.success.edit': '{jslang}wcf.global.success.edit{/jslang}',
+                       'wcf.global.thousandsSeparator': '{jslang}wcf.global.thousandsSeparator{/jslang}',
+                       'wcf.page.pagePosition': '{jslang __literal=true}wcf.page.pagePosition{/jslang}',
+                       'wcf.style.changeStyle': '{jslang}wcf.style.changeStyle{/jslang}',
+                       'wcf.user.activityPoint': '{jslang}wcf.user.activityPoint{/jslang}',
+                       'wcf.user.panel.markAllAsRead': '{jslang}wcf.user.panel.markAllAsRead{/jslang}',
+                       'wcf.user.panel.markAsRead': '{jslang}wcf.user.panel.markAsRead{/jslang}',
+                       'wcf.user.panel.settings': '{jslang}wcf.user.panel.settings{/jslang}',
+                       'wcf.user.panel.showAll': '{jslang}wcf.user.panel.showAll{/jslang}',
+                       'wcf.menu.page': '{jslang}wcf.menu.page{/jslang}',
+                       'wcf.menu.user': '{jslang}wcf.menu.user{/jslang}',
+                       'wcf.global.button.showMenu': '{jslang}wcf.global.button.showMenu{/jslang}',
+                       'wcf.global.button.hideMenu': '{jslang}wcf.global.button.hideMenu{/jslang}',
+                       'wcf.date.datePicker': '{jslang}wcf.date.datePicker{/jslang}',
+                       'wcf.date.datePicker.previousMonth': '{jslang}wcf.date.datePicker.previousMonth{/jslang}',
+                       'wcf.date.datePicker.nextMonth': '{jslang}wcf.date.datePicker.nextMonth{/jslang}',
+                       'wcf.date.datePicker.month': '{jslang}wcf.date.datePicker.month{/jslang}',
+                       'wcf.date.datePicker.year': '{jslang}wcf.date.datePicker.year{/jslang}',
+                       'wcf.date.datePicker.hour': '{jslang}wcf.date.datePicker.hour{/jslang}',
+                       'wcf.date.datePicker.minute': '{jslang}wcf.date.datePicker.minute{/jslang}'
                        {if MODULE_LIKE}
-                               ,'wcf.like.button.like': '{lang}wcf.like.button.like{/lang}',
-                               'wcf.like.button.dislike': '{lang}wcf.like.button.dislike{/lang}',
-                               'wcf.like.tooltip': '{lang}wcf.like.jsTooltip{/lang}',
-                               'wcf.like.summary': '{lang}wcf.like.summary{/lang}',
-                               'wcf.like.details': '{lang}wcf.like.details{/lang}',
-                               'wcf.reactions.react': '{lang}wcf.reactions.react{/lang}'
+                               ,'wcf.like.button.like': '{jslang}wcf.like.button.like{/jslang}',
+                               'wcf.like.button.dislike': '{jslang}wcf.like.button.dislike{/jslang}',
+                               'wcf.like.tooltip': '{jslang}wcf.like.jsTooltip{/jslang}',
+                               'wcf.like.summary': '{jslang}wcf.like.summary{/jslang}',
+                               'wcf.like.details': '{jslang}wcf.like.details{/jslang}',
+                               'wcf.reactions.react': '{jslang}wcf.reactions.react{/jslang}'
                        {/if}
                        
                        {event name='javascriptLanguageImport'}
diff --git a/com.woltlab.wcf/templates/headIncludeRobotsMetaTag.tpl b/com.woltlab.wcf/templates/headIncludeRobotsMetaTag.tpl
new file mode 100644 (file)
index 0000000..bb1bf50
--- /dev/null
@@ -0,0 +1 @@
+{if ($allowSpidersToIndexThisPage|empty && ($__wcf->getActivePage() == null || !$__wcf->getActivePage()->allowSpidersToIndex)) || ($allowSpidersToIndexThisPage|isset && $allowSpidersToIndexThisPage == false)}<meta name="robots" content="noindex">{/if}
index d18f90b77433aa3dc5c5f4468f2fbd23913a266c..9987b329a4744a53b4bf6a0883e3c096ea336a98 100644 (file)
@@ -16,8 +16,8 @@
                        {foreach from=$objects item=user}
                                <li class="jsIgnoredUser">
                                        <div class="box48">
-                                               <a href="{link controller='User' object=$user}{/link}" title="{$user->username}">{@$user->getAvatar()->getImageTag(48)}</a>
-                                                       
+                                               {user object=$user type='avatar48' title=$user->username}
+                                               
                                                <div class="details userInformation">
                                                        {include file='userInformationHeadline'}
                                                        
index ae530070d8bb6fec3c5ffaf97ec9332aee9ea273..595b0723c089408cea60b7f537016303403baea5 100644 (file)
@@ -3,14 +3,14 @@
                var $imageViewer = null;
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.imageViewer.button.enlarge': '{lang}wcf.imageViewer.button.enlarge{/lang}',
-                               'wcf.imageViewer.button.full': '{lang}wcf.imageViewer.button.full{/lang}',
-                               'wcf.imageViewer.seriesIndex': '{lang __literal=true}wcf.imageViewer.seriesIndex{/lang}',
-                               'wcf.imageViewer.counter': '{lang}wcf.imageViewer.counter{/lang}',
-                               'wcf.imageViewer.close': '{lang}wcf.imageViewer.close{/lang}',
-                               'wcf.imageViewer.enlarge': '{lang}wcf.imageViewer.enlarge{/lang}',
-                               'wcf.imageViewer.next': '{lang}wcf.imageViewer.next{/lang}',
-                               'wcf.imageViewer.previous': '{lang}wcf.imageViewer.previous{/lang}'
+                               'wcf.imageViewer.button.enlarge': '{jslang}wcf.imageViewer.button.enlarge{/jslang}',
+                               'wcf.imageViewer.button.full': '{jslang}wcf.imageViewer.button.full{/jslang}',
+                               'wcf.imageViewer.seriesIndex': '{jslang __literal=true}wcf.imageViewer.seriesIndex{/jslang}',
+                               'wcf.imageViewer.counter': '{jslang}wcf.imageViewer.counter{/jslang}',
+                               'wcf.imageViewer.close': '{jslang}wcf.imageViewer.close{/jslang}',
+                               'wcf.imageViewer.enlarge': '{jslang}wcf.imageViewer.enlarge{/jslang}',
+                               'wcf.imageViewer.next': '{jslang}wcf.imageViewer.next{/jslang}',
+                               'wcf.imageViewer.previous': '{jslang}wcf.imageViewer.previous{/jslang}'
                        });
                        
                        $imageViewer = new WCF.ImageViewer();
@@ -28,4 +28,4 @@
        </script>
        
        {assign var=__imageViewerLoaded value=true}
-{/if}
\ No newline at end of file
+{/if}
diff --git a/com.woltlab.wcf/templates/mail.tpl b/com.woltlab.wcf/templates/mail.tpl
deleted file mode 100644 (file)
index 6c64a29..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-{include file='header'}
-
-{include file='formError'}
-
-<form method="post" action="{link controller='Mail' object=$user}{/link}">
-       <section class="section">
-               <h2 class="sectionTitle">{lang}wcf.user.mail.information{/lang}</h2>
-               
-               <dl{if $errorField == 'subject'} class="formError"{/if}>
-                       <dt><label for="subject">{lang}wcf.user.mail.subject{/lang}</label></dt>
-                       <dd>
-                               <input type="text" id="subject" name="subject" value="{$subject}" required class="long">
-                               {if $errorField == 'subject'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {else}
-                                                       {lang}wcf.user.mail.subject.error.{@$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                       </dd>
-               </dl>
-               
-               {if $__wcf->user->userID}
-                       <dl>
-                               <dt></dt>
-                               <dd><label><input type="checkbox" name="showAddress" value="1"{if $showAddress == 1} checked{/if}> {lang}wcf.user.mail.showAddress{/lang}</label></dd>
-                       </dl>
-               {else}
-                       <dl{if $errorField == 'email'} class="formError"{/if}>
-                               <dt><label for="email">{lang}wcf.user.mail.senderEmail{/lang}</label></dt>
-                               <dd>
-                                       <input type="email" id="email" name="email" value="{$email}" required class="medium">
-                                       {if $errorField == 'email'}
-                                               <small class="innerError">
-                                                       {if $errorType == 'empty'}
-                                                               {lang}wcf.global.form.error.empty{/lang}
-                                                       {elseif $errorType == 'invalid'}
-                                                               {lang}wcf.user.email.error.invalid{/lang}
-                                                       {else}
-                                                               {lang}wcf.user.mail.senderEmail.error.{@$errorType}{/lang}
-                                                       {/if}
-                                               </small>
-                                       {/if}
-                               </dd>
-                       </dl>
-               {/if}
-               
-               {event name='informationFields'}
-       </section>
-       
-       <section class="section">
-               <h2 class="sectionTitle">{lang}wcf.user.mail.message{/lang}</h2>
-               
-               <dl class="wide{if $errorField == 'message'} formError{/if}">
-                       <dd>
-                               <textarea rows="15" cols="40" name="message" id="message" required>{$message}</textarea>
-                               {if $errorField == 'message'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {else}
-                                                       {lang}wcf.user.mail.message.error.{@$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                       </dd>
-               </dl>
-               
-               {event name='messageFields'}
-       </section>
-       
-       {event name='sections'}
-       
-       {include file='captcha' supportsAsyncCaptcha=true}
-       
-       <div class="formSubmit">
-               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
-               {@SECURITY_TOKEN_INPUT_TAG}
-       </div>
-</form>
-
-{include file='footer'}
index 01a0c795410ca43da94f55210bce72cd3f0c668d..975e4bbf55a764940ed46f1f1872122650389439 100644 (file)
@@ -8,11 +8,13 @@
        
        {if $media->caption}
                <span class="mediaBBCodeCaption">
-                       {if $media->captionEnableHtml}
-                               {@$media->caption}
-                       {else}
-                               {$media->caption}
-                       {/if}
+                       <span class="mediaBBCodeCaptionAlignment">
+                               {if $media->captionEnableHtml}
+                                       {@$media->caption}
+                               {else}
+                                       {$media->caption}
+                               {/if}
+                       </span>
                </span>
        {/if}
 </span>
index e6ffc7cfcbecfeb7262b1b2ab2b70d32d4192ddd..e25e443cbd132694152dcd4b92c4f2f8731de3c7 100644 (file)
@@ -1,3 +1,7 @@
+<ul class="mediaEditorButtons buttonGroup">
+       <li><div class="mediaManagerMediaReplaceButton"></div></li>
+</ul>
+
 {if $media->isImage && $media->hasThumbnail('small')}
        <div class="mediaThumbnail">
                {@$media->getThumbnailTag('small')}
@@ -24,7 +28,7 @@
                {/if}
                
                <dt>{lang}wcf.media.uploader{/lang}</dt>
-               <dd id="mediaUploader">{@$media->getUserProfile()->getAnchorTag()}</dd>
+               <dd id="mediaUploader">{user object=$media->getUserProfile()}</dd>
                
                <dt>{lang}wcf.media.downloads{/lang}</dt>
                <dd id="mediaDownloads">{#$media->downloads}</dd>
index b8c5d5fed709a7c058bcf4f20459512b3b25a3b2..b9016db0778247eafaa6b19b9c61a67c869d782e 100644 (file)
@@ -1,24 +1,28 @@
 {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
        require(['Language', 'Permission'], function(Language, Permission) {
                Language.addObject({
-                       'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
-                       'wcf.media.button.select': '{lang}wcf.media.button.select{/lang}', 
-                       'wcf.media.delete.confirmMessage': '{lang __encode=true __literal=true}wcf.media.delete.confirmMessage{/lang}',
-                       'wcf.media.insert': '{lang}wcf.media.insert{/lang}',
-                       'wcf.media.insert.imageSize': '{lang}wcf.media.insert.imageSize{/lang}',
-                       'wcf.media.insert.imageSize.small': '{lang}wcf.media.insert.imageSize.small{/lang}',
-                       'wcf.media.insert.imageSize.medium': '{lang}wcf.media.insert.imageSize.medium{/lang}',
-                       'wcf.media.insert.imageSize.large': '{lang}wcf.media.insert.imageSize.large{/lang}',
-                       'wcf.media.insert.imageSize.original': '{lang}wcf.media.insert.imageSize.original{/lang}',
-                       'wcf.media.manager': '{lang}wcf.media.manager{/lang}',
-                       'wcf.media.edit': '{lang}wcf.media.edit{/lang}',
-                       'wcf.media.button.insert': '{lang}wcf.media.button.insert{/lang}',
-                       'wcf.media.search.info.searchStringThreshold': '{lang __literal=true}wcf.media.search.info.searchStringThreshold{/lang}',
-                       'wcf.media.search.noResults': '{lang}wcf.media.search.noResults{/lang}',
-                       'wcf.media.upload.error.noImage': '{lang}wcf.media.upload.error.noImage{/lang}',
-                       'wcf.media.upload.error.uploadFailed': '{lang}wcf.media.upload.error.uploadFailed{/lang}',
-                       'wcf.media.upload.success': '{lang}wcf.media.upload.success{/lang}',
-                       'wcf.media.setCategory': '{lang}wcf.media.setCategory{/lang}'
+                       'wcf.global.button.insert': '{jslang}wcf.global.button.insert{/jslang}',
+                       'wcf.media.button.replaceFile': '{jslang}wcf.media.button.replaceFile{/jslang}',
+                       'wcf.media.button.select': '{jslang}wcf.media.button.select{/jslang}',
+                       'wcf.media.delete.confirmMessage': '{jslang __encode=true __literal=true}wcf.media.delete.confirmMessage{/jslang}',
+                       'wcf.media.imageDimensions.value': '{jslang __literal=true}wcf.media.imageDimensions.value{/jslang}',
+                       'wcf.media.insert': '{jslang}wcf.media.insert{/jslang}',
+                       'wcf.media.insert.imageSize': '{jslang}wcf.media.insert.imageSize{/jslang}',
+                       'wcf.media.insert.imageSize.small': '{jslang}wcf.media.insert.imageSize.small{/jslang}',
+                       'wcf.media.insert.imageSize.medium': '{jslang}wcf.media.insert.imageSize.medium{/jslang}',
+                       'wcf.media.insert.imageSize.large': '{jslang}wcf.media.insert.imageSize.large{/jslang}',
+                       'wcf.media.insert.imageSize.original': '{jslang}wcf.media.insert.imageSize.original{/jslang}',
+                       'wcf.media.manager': '{jslang}wcf.media.manager{/jslang}',
+                       'wcf.media.edit': '{jslang}wcf.media.edit{/jslang}',
+                       'wcf.media.button.insert': '{jslang}wcf.media.button.insert{/jslang}',
+                       'wcf.media.search.info.searchStringThreshold': '{jslang __literal=true}wcf.media.search.info.searchStringThreshold{/jslang}',
+                       'wcf.media.search.noResults': '{jslang}wcf.media.search.noResults{/jslang}',
+                       'wcf.media.upload.error.differentFileExtension': '{jslang}wcf.media.upload.error.differentFileExtension{/jslang}',
+                       'wcf.media.upload.error.differentFileType': '{jslang}wcf.media.upload.error.differentFileType{/jslang}',
+                       'wcf.media.upload.error.noImage': '{jslang}wcf.media.upload.error.noImage{/jslang}',
+                       'wcf.media.upload.error.uploadFailed': '{jslang}wcf.media.upload.error.uploadFailed{/jslang}',
+                       'wcf.media.upload.success': '{jslang}wcf.media.upload.success{/jslang}',
+                       'wcf.media.setCategory': '{jslang}wcf.media.setCategory{/jslang}'
                });
                
                Permission.add('admin.content.cms.canManageMedia', {if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}true{else}false{/if});
index cc0f1a0c6a7eebba08fc68574638be104141ee56..9fc6744d3636af06ba046178e13c68a832015079 100644 (file)
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                       'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                       'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                       'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                       'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                       'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                       'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                });
                
                new WCF.User.Action.Follow($('.userList > li'));
index 38a3c7cdd00a123a576799b839af7750eb367ee4..59fdac98ced8ef7e1f2a9b04f600afd9a5a877f6 100644 (file)
@@ -1,24 +1,24 @@
 <div class="jsOnly formAttachmentContent messageTabMenuContent" id="attachments_{if $wysiwygSelector|isset}{$wysiwygSelector}{else}text{/if}">
-       <ul class="formAttachmentList clearfix"{if !$attachmentHandler->getAttachmentList()|count} style="display: none"{/if} data-enable-thumbnails="{if ATTACHMENT_ENABLE_THUMBNAILS}true{else}false{/if}">
+       <ul class="formAttachmentList clearfix"{if !$attachmentHandler->getAttachmentList()|count} style="display: none"{/if}>
                {foreach from=$attachmentHandler->getAttachmentList() item=$attachment}
                        <li class="box64" data-object-id="{@$attachment->attachmentID}" data-height="{@$attachment->height}" data-width="{@$attachment->width}" data-is-image="{@$attachment->isImage}">
                                {if $attachment->tinyThumbnailType}
-                                       <img src="{link controller='Attachment' object=$attachment}tiny=1{/link}" alt="" class="attachmentTinyThumbnail">
+                                       <img src="{$attachment->getThumbnailLink('tiny')}" alt="" class="attachmentTinyThumbnail">
                                {else}
                                        <span class="icon icon64 fa-{@$attachment->getIconName()}"></span>
                                {/if}
                                
                                <div>
                                        <div>
-                                               <p><a href="{link controller='Attachment' object=$attachment}{/link}" target="_blank"{if $attachment->isImage} title="{$attachment->filename}" class="jsImageViewer"{/if}>{$attachment->filename}</a></p>
+                                               <p><a href="{$attachment->getLink()}" target="_blank"{if $attachment->isImage} title="{$attachment->filename}" class="jsImageViewer"{/if}>{$attachment->filename}</a></p>
                                                <small>{@$attachment->filesize|filesize}</small>
                                        </div>
                                        
                                        <ul class="buttonGroup">
                                                <li><span class="button small jsDeleteButton" data-object-id="{@$attachment->attachmentID}" data-confirm-message="{lang}wcf.attachment.delete.sure{/lang}">{lang}wcf.global.button.delete{/lang}</span></li>
                                                {if $attachment->isImage}
-                                                       {if $attachment->thumbnailType}<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="{@$attachment->attachmentID}" data-url="{link controller='Attachment' object=$attachment}thumbnail=1{/link}">{lang}wcf.attachment.insertThumbnail{/lang}</span></li>{/if}
-                                                       <li><span class="button small jsButtonAttachmentInsertFull" data-object-id="{@$attachment->attachmentID}" data-url="{link controller='Attachment' object=$attachment}{/link}">{lang}wcf.attachment.insertFull{/lang}</span></li>
+                                                       {if $attachment->thumbnailType}<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="{@$attachment->attachmentID}" data-url="{$attachment->getThumbnailLink('thumbnail')}">{lang}wcf.attachment.insertThumbnail{/lang}</span></li>{/if}
+                                                       <li><span class="button small jsButtonAttachmentInsertFull" data-object-id="{@$attachment->attachmentID}" data-url="{$attachment->getLink()}">{lang}wcf.attachment.insertFull{/lang}</span></li>
                                                {else}
                                                        <li><span class="button small jsButtonInsertAttachment" data-object-id="{@$attachment->attachmentID}">{lang}wcf.attachment.insert{/lang}</span></li>
                                                {/if}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.attachment.upload.error.invalidExtension': '{lang}wcf.attachment.upload.error.invalidExtension{/lang}',
-                       'wcf.attachment.upload.error.tooLarge': '{lang}wcf.attachment.upload.error.tooLarge{/lang}',
-                       'wcf.attachment.upload.error.reachedLimit': '{lang}wcf.attachment.upload.error.reachedLimit{/lang}',
-                       'wcf.attachment.upload.error.reachedRemainingLimit': '{lang}wcf.attachment.upload.error.reachedRemainingLimit{/lang}',
-                       'wcf.attachment.upload.error.uploadFailed': '{lang}wcf.attachment.upload.error.uploadFailed{/lang}',
-                       'wcf.attachment.upload.error.uploadPhpLimit': '{lang}wcf.attachment.upload.error.uploadPhpLimit{/lang}',
-                       'wcf.attachment.insert': '{lang}wcf.attachment.insert{/lang}',
-                       'wcf.attachment.insertAll': '{lang}wcf.attachment.insertAll{/lang}',
-                       'wcf.attachment.insertFull': '{lang}wcf.attachment.insertFull{/lang}',
-                       'wcf.attachment.insertThumbnail': '{lang}wcf.attachment.insertThumbnail{/lang}',
-                       'wcf.attachment.delete.sure': '{lang}wcf.attachment.delete.sure{/lang}'
+                       'wcf.attachment.upload.error.invalidExtension': '{jslang}wcf.attachment.upload.error.invalidExtension{/jslang}',
+                       'wcf.attachment.upload.error.tooLarge': '{jslang}wcf.attachment.upload.error.tooLarge{/jslang}',
+                       'wcf.attachment.upload.error.reachedLimit': '{jslang}wcf.attachment.upload.error.reachedLimit{/jslang}',
+                       'wcf.attachment.upload.error.reachedRemainingLimit': '{jslang}wcf.attachment.upload.error.reachedRemainingLimit{/jslang}',
+                       'wcf.attachment.upload.error.uploadFailed': '{jslang}wcf.attachment.upload.error.uploadFailed{/jslang}',
+                       'wcf.attachment.upload.error.uploadPhpLimit': '{jslang}wcf.attachment.upload.error.uploadPhpLimit{/jslang}',
+                       'wcf.attachment.insert': '{jslang}wcf.attachment.insert{/jslang}',
+                       'wcf.attachment.insertAll': '{jslang}wcf.attachment.insertAll{/jslang}',
+                       'wcf.attachment.insertFull': '{jslang}wcf.attachment.insertFull{/jslang}',
+                       'wcf.attachment.insertThumbnail': '{jslang}wcf.attachment.insertThumbnail{/jslang}',
+                       'wcf.attachment.delete.sure': '{jslang}wcf.attachment.delete.sure{/jslang}'
                });
                
                new WCF.Attachment.Upload(
index 00175333c511f8f41e581988d4e5b6ffdba5b060..8ed77481822bfc8ec1a504b085e35a09e5db3518 100644 (file)
@@ -8,7 +8,7 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.global.preview': '{lang}wcf.global.preview{/lang}' 
+                       'wcf.global.preview': '{jslang}wcf.global.preview{/jslang}' 
                });
                
                new WCF.Message.DefaultPreview({
@@ -18,4 +18,4 @@
                        messageObjectID: '{$previewMessageObjectID}'
                });
        });
-</script>
\ No newline at end of file
+</script>
index 58901643d72ed63ed753596e6183e216d968f7dc..618d2bc649b01ba134b93da6813bb052542fe8a1 100644 (file)
@@ -5,7 +5,9 @@
        <nav class="messageTabMenuNavigation jsOnly">
                <ul>
                        {if MODULE_SMILEY && !$smileyCategories|empty}<li data-name="smilies"><a><span class="icon icon16 fa-smile-o"></span> <span>{lang}wcf.message.smilies{/lang}</span></a></li>{/if}
-                       {if MODULE_ATTACHMENT && !$attachmentHandler|empty && $attachmentHandler->canUpload()}<li data-name="attachments"><a><span class="icon icon16 fa-paperclip"></span> <span>{lang}wcf.attachment.attachments{/lang}</span></a></li>{/if}
+                       {if !$attachmentHandler|empty && $attachmentHandler->canUpload()}
+                               <li data-name="attachments"><a><span class="icon icon16 fa-paperclip"></span> <span>{lang}wcf.attachment.attachments{/lang}</span></a></li>
+                       {/if}
                        {if $__messageFormSettings}<li data-name="settings"><a><span class="icon icon16 fa-cog"></span> <span>{lang}wcf.message.settings{/lang}</span></a></li>{/if}
                        {if $__showPoll|isset && $__showPoll}<li data-name="poll"><a><span class="icon icon16 fa-bar-chart"></span> <span>{lang}wcf.poll.management{/lang}</span></a></li>{/if}
                        {event name='tabMenuTabs'}
@@ -13,7 +15,9 @@
        </nav>
        
        {if MODULE_SMILEY && !$smileyCategories|empty}{include file='messageFormSmilies'}{/if}
-       {if MODULE_ATTACHMENT && !$attachmentHandler|empty && $attachmentHandler->canUpload()}{include file='messageFormAttachments'}{/if}
+       {if !$attachmentHandler|empty && $attachmentHandler->canUpload()}
+               {include file='messageFormAttachments'}
+       {/if}
        
        {if $__messageFormSettings}{@$__messageFormSettings}{/if}
        {include file='__messageFormPoll'}
index 1211facae1a6b5fccaa567d865d198bf5b341450..4e3b62250a62a0aeda5f90d46baac6eb70eb21d3 100644 (file)
@@ -9,7 +9,9 @@
        <nav class="messageTabMenuNavigation jsOnly">
                <ul>
                        {if MODULE_SMILEY && !$smileyCategories|empty}<li data-name="smilies"><a><span class="icon icon16 fa-smile-o"></span> <span>{lang}wcf.message.smilies{/lang}</span></a></li>{/if}
-                       {if MODULE_ATTACHMENT && !$attachmentHandler|empty && $attachmentHandler->canUpload()}<li data-name="attachments"><a><span class="icon icon16 fa-paperclip"></span> <span>{lang}wcf.attachment.attachments{/lang}</span></a></li>{/if}
+                       {if !$attachmentHandler|empty && $attachmentHandler->canUpload()}
+                               <li data-name="attachments"><a><span class="icon icon16 fa-paperclip"></span> <span>{lang}wcf.attachment.attachments{/lang}</span></a></li>
+                       {/if}
                        {if $__messageFormSettingsInlineContent}<li data-name="settings"><a><span class="icon icon16 fa-cog"></span> <span>{lang}wcf.message.settings{/lang}</span></a></li>{/if}
                        {if $__showPoll|isset && $__showPoll}<li data-name="poll"><a><span class="icon icon16 fa-bar-chart"></span> <span>{lang}wcf.poll.management{/lang}</span></a></li>{/if}
                        {event name='tabMenuTabs'}
@@ -17,7 +19,9 @@
        </nav>
        
        {if MODULE_SMILEY && !$smileyCategories|empty}{include file='messageFormSmilies'}{/if}
-       {if MODULE_ATTACHMENT && !$attachmentHandler|empty && $attachmentHandler->canUpload()}{include file='messageFormAttachments'}{/if}
+       {if !$attachmentHandler|empty && $attachmentHandler->canUpload()}
+               {include file='messageFormAttachments'}
+       {/if}
        
        {if $__messageFormSettingsInlineContent}{@$__messageFormSettingsInlineContent}{/if}
        
index aca61802a9aeacd4b845a537b85e19e3267783bd..4ca4c8c1b1b6bfa8711fb4f2458bb60453efd7d0 100644 (file)
@@ -5,7 +5,7 @@
                        <header class="messageHeader">
                                <div class="box32 messageHeaderWrapper">
                                        {if $userProfiles[$message->getUserID()]|isset}
-                                               <a href="{link controller='User' object=$userProfiles[$message->getUserID()]}{/link}" aria-hidden="true">{@$userProfiles[$message->getUserID()]->getAvatar()->getImageTag(32)}</a>
+                                               {user object=$userProfiles[$message->getUserID()] type='avatar32' ariaHidden='true'}
                                        {else}
                                                <span><img src="{@$__wcf->getPath()}images/avatars/avatar-default.svg" alt="" class="userAvatarImage" style="width: 32px; height: 32px"></span>
                                        {/if}
                                                </h2>
                                                
                                                <ul class="messageHeaderMetaData">
-                                                       <li>{if $userProfiles[$message->getUserID()]|isset}<a href="{link controller='User' object=$userProfiles[$message->getUserID()]}{/link}">{$message->getUsername()}</a>{else}<span class="username">{$message->getUsername()}</span>{/if}</li>
+                                                       <li>
+                                                               {if $userProfiles[$message->getUserID()]|isset}
+                                                                       {user object=$userProfiles[$message->getUserID()]}
+                                                               {else}
+                                                                       <span class="username">{$message->getUsername()}</span>
+                                                               {/if}
+                                                       </li>
                                                        <li><span class="messagePublicationTime">{@$message->getTime()|time}</span></li>
                                                        
                                                        {event name='messageHeaderMetaData'}
@@ -60,4 +66,4 @@
                        </div>
                </div>
        </article>
-{/foreach}
\ No newline at end of file
+{/foreach}
index 2dda86da1031d448870d81a4553d5ce7c7bbcefd..4362e984f8e2f7a6ecd3d1fd036d01ecc4116b4a 100644 (file)
                        
                        {if $userProfile->getAvatar()}
                                <div class="userAvatar">
-                                       <a href="{link controller='User' object=$userProfile->getDecoratedObject()}{/link}" aria-hidden="true">{@$userProfile->getAvatar()->getImageTag(128)}</a>
+                                       {user object=$userProfile type='avatar128' ariaHidden='true'}
                                        
                                        {if MESSAGE_SIDEBAR_ENABLE_ONLINE_STATUS && !$isReply && $userProfile->isOnline()}<span class="badge green badgeOnline" title="{lang}wcf.user.online.title{/lang}">{lang}wcf.user.online{/lang}</span>{/if}
                                </div>
                        {/if}
                        
                        <div class="messageAuthorContainer">
-                               <a href="{link controller='User' object=$userProfile->getDecoratedObject()}{/link}" class="username userLink" data-user-id="{@$userProfile->userID}"{if $enableMicrodata} itemprop="url"{/if}>
-                                       <span{if $enableMicrodata} itemprop="name"{/if}>{if MESSAGE_SIDEBAR_ENABLE_USER_ONLINE_MARKING}{@$userProfile->getFormattedUsername()}{else}{$username}{/if}</span>
+                               <a href="{$userProfile->getLink()}" class="username userLink" data-object-id="{@$userProfile->userID}"{if $enableMicrodata} itemprop="url"{/if}>
+                                       <span{if $enableMicrodata} itemprop="name"{/if}>{@$userProfile->getFormattedUsername()}</span>
                                </a>
                                {if !$isReply}
                                        {if $userProfile->banned}<span class="icon icon16 fa-lock jsTooltip jsUserBanned" title="{lang user=$userProfile}wcf.user.banned{/lang}"></span>{/if}
@@ -91,7 +91,7 @@
                                        <dl class="plain dataList">
                                                {content}
                                                        {if MODULE_LIKE && MESSAGE_SIDEBAR_ENABLE_LIKES_RECEIVED && !$isReply && $userProfile->likesReceived}
-                                                               <dt><a href="{link controller='User' object=$userProfile}{/link}#likes" class="jsTooltip" title="{lang user=$userProfile}wcf.like.showLikesReceived{/lang}">{lang}wcf.like.likesReceived{/lang}</a></dt>
+                                                               <dt><a href="{$userProfile->getLink()}#likes" class="jsTooltip" title="{lang user=$userProfile}wcf.like.showLikesReceived{/lang}">{lang}wcf.like.likesReceived{/lang}</a></dt>
                                                                <dd>{#$userProfile->likesReceived}</dd>
                                                        {/if}
                                                        
diff --git a/com.woltlab.wcf/templates/messageUserConsent.tpl b/com.woltlab.wcf/templates/messageUserConsent.tpl
new file mode 100644 (file)
index 0000000..0cd19d9
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="messageUserConsent" data-payload="{$payload}">
+       <div class="messageUserConsentHeader">
+               <span class="messageUserConsentTitle">{lang}wcf.message.user.consent.title{/lang}</span>
+               <a href="{$url}" class="messageUserConsentHost externalURL">{$host}</a>
+       </div>
+       <div class="messageUserConsentDescription">{lang}wcf.message.user.consent.description{/lang}</div>
+       <div class="messageUserConsentButtonContainer">
+               <button class="small jsButtonMessageUserConsentEnable">{lang}wcf.message.user.consent.button.enable{/lang}</button>
+       </div>
+       <div class="messageUserConsentNotice">{lang}wcf.message.user.consent.notice{/lang}</div>
+</div>
index 7e5875b0479eee3cbd1bfde572ce3d07e7c52711..4c1bd05f0c94e1ba552d36c99068a4fb0f9b5c6d 100644 (file)
@@ -17,7 +17,7 @@
                                <dd>
                                        <span>
                                                {if $queue->assignedUserID}
-                                                       <a href="{link controller='User' id=$assignedUserID}{/link}" class="userLink" data-user-id="{@$assignedUserID}">{$queue->assignedUsername}</a>
+                                                       <a href="{link controller='User' id=$assignedUserID}{/link}" class="userLink" data-object-id="{@$assignedUserID}">{$queue->assignedUsername}</a>
                                                {else}
                                                        {lang}wcf.moderation.assignedUser.nobody{/lang}
                                                {/if}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.moderation.activation.enableContent.confirmMessage': '{lang}wcf.moderation.activation.enableContent.confirmMessage{/lang}',
-                       'wcf.moderation.activation.removeContent.confirmMessage': '{lang}wcf.moderation.activation.removeContent.confirmMessage{/lang}',
-                       'wcf.moderation.assignedUser': '{lang}wcf.moderation.assignedUser{/lang}',
-                       'wcf.moderation.assignedUser.error.notAffected': '{lang}wcf.moderation.assignedUser.error.notAffected{/lang}',
-                       'wcf.moderation.status.outstanding': '{lang}wcf.moderation.status.outstanding{/lang}',
-                       'wcf.moderation.status.processing': '{lang}wcf.moderation.status.processing{/lang}',
-                       'wcf.user.username.error.notFound': '{lang __literal=true}wcf.user.username.error.notFound{/lang}'
+                       'wcf.moderation.activation.enableContent.confirmMessage': '{jslang}wcf.moderation.activation.enableContent.confirmMessage{/jslang}',
+                       'wcf.moderation.activation.removeContent.confirmMessage': '{jslang}wcf.moderation.activation.removeContent.confirmMessage{/jslang}',
+                       'wcf.moderation.assignedUser': '{jslang}wcf.moderation.assignedUser{/jslang}',
+                       'wcf.moderation.assignedUser.error.notAffected': '{jslang}wcf.moderation.assignedUser.error.notAffected{/jslang}',
+                       'wcf.moderation.status.outstanding': '{jslang}wcf.moderation.status.outstanding{/jslang}',
+                       'wcf.moderation.status.processing': '{jslang}wcf.moderation.status.processing{/jslang}',
+                       'wcf.user.username.error.notFound': '{jslang __literal=true}wcf.user.username.error.notFound{/jslang}'
                });
                
                new WCF.Moderation.Activation.Management({@$queue->queueID}, '{link controller='ModerationList' encode=false}{/link}');
index ba03e64ce0f84ed64c5bafa15ea78f288537c864..f5c1048e0ea9e1ac810c2eaa7baf5dfea1c58982 100644 (file)
@@ -3,7 +3,7 @@
                <header class="messageHeader">
                        <div class="box32 messageHeaderWrapper">
                                {if $article->getUserProfile()->userID}
-                                       <a href="{link controller='User' object=$article->getUserProfile()->getDecoratedObject()}{/link}" aria-hidden="true">{@$article->getUserProfile()->getAvatar()->getImageTag(32)}</a>
+                                       {user object=$article->getUserProfile() type='avatar32' ariaHidden='true'}
                                {else}
                                        <span>{@$article->getUserProfile()->getAvatar()->getImageTag(32)}</span>
                                {/if}
@@ -16,7 +16,7 @@
                                        <ul class="messageHeaderMetaData">
                                                <li>
                                                        {if $article->getUserProfile()->userID}
-                                                               <a href="{link controller='User' object=$article->getUserProfile()->getDecoratedObject()}{/link}" class="username">{$article->getUserProfile()}</a>
+                                                               {user object=$article->getUserProfile() class='username'}
                                                        {else}
                                                                {$article->getUserProfile()->username}
                                                        {/if}
index 54dca5a1ab92bb37aec804162982905120914575..e5b99e771a97817b11e021218655526925622496 100644 (file)
@@ -3,7 +3,7 @@
                <header class="messageHeader">
                        <div class="box32 messageHeaderWrapper">
                                {if $message->userID}
-                                       <a href="{link controller='User' object=$message->getUserProfile()->getDecoratedObject()}{/link}" aria-hidden="true">{@$message->getUserProfile()->getAvatar()->getImageTag(32)}</a>
+                                       {user object=$message->getUserProfile() type='avatar32' ariaHidden='true'}
                                {else}
                                        <span>{@$message->getUserProfile()->getAvatar()->getImageTag(32)}</span>
                                {/if}
@@ -16,7 +16,7 @@
                                        <ul class="messageHeaderMetaData">
                                                <li>
                                                        {if $message->userID}
-                                                               <a href="{link controller='User' object=$message->getUserProfile()->getDecoratedObject()}{/link}" class="username">{$message->getUsername()}</a>
+                                                               {user object=$message->getUserProfile() class='username'}
                                                        {else}
                                                                {$message->getUsername()}
                                                        {/if}
index 3ac04c656b870f00b8c309689f254c1c2c603eeb..a417d26de268197d31c7be30b4a00ad624d781c1 100644 (file)
@@ -3,47 +3,6 @@
 {capture assign='contentTitle'}{if $status == 2}{lang}wcf.moderation.doneItems{/lang}{else}{lang}wcf.moderation.outstandingItems{/lang}{/if} <span class="badge">{#$items}</span>{/capture}
 
 {capture assign='sidebarRight'}
-       <section class="box" data-static-box-identifier="com.woltlab.wcf.ModerationListFilters">
-               {* moderation type *}
-               <h2 class="boxTitle">{lang}wcf.moderation.filterByType{/lang}</h2>
-               
-               <nav class="boxContent">
-                       <ul class="boxMenu">
-                               <li{if $definitionID == 0} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID=0&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.type.all{/lang}</a></li>
-                               {foreach from=$availableDefinitions key=__definitionID item=definitionName}
-                                       <li{if $definitionID == $__definitionID} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID={@$__definitionID}&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.type.{$definitionName}{/lang}</a></li>
-                               {/foreach}
-                               
-                               {event name='sidebarModerationType'}
-                       </ul>
-               </nav>
-               
-               {* assigned user *}
-               <h2 class="boxTitle">{lang}wcf.moderation.filterByUser{/lang}</h2>
-               
-               <nav class="boxContent">
-                       <ul class="boxMenu">
-                               <li{if $assignedUserID == -1} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID=-1&status={@$status}&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.filterByUser.allEntries{/lang}</a></li>
-                               <li{if $assignedUserID == 0} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID=0&status={@$status}&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.filterByUser.nobody{/lang}</a></li>
-                               <li{if $assignedUserID == $__wcf->getUser()->userID} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$__wcf->getUser()->userID}&status={@$status}&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.filterByUser.myself{/lang}</a></li>
-                               
-                               {event name='sidebarAssignedUser'}
-                       </ul>
-               </nav>
-               
-               {* status *}
-               <h2 class="boxTitle">{lang}wcf.moderation.status{/lang}</h2>
-               
-               <nav class="boxContent">
-                       <ul class="boxMenu">
-                               <li{if $status == -1} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status=-1&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.status.outstanding{/lang}</a></li>
-                               <li{if $status == 2} class="active"{/if}><a class="boxMenuLink" href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status=2&pageNo={@$pageNo}&sortField={@$sortField}&sortOrder={@$sortOrder}{/link}">{lang}wcf.moderation.status.done{/lang}</a></li>
-                               
-                               {event name='sidebarStatus'}
-                       </ul>
-               </nav>
-       </section>
-       
        {event name='sidebarBoxes'}
 {/capture}
 
                <ol class="tabularList">
                        <li class="tabularListRow tabularListRowHead">
                                <ol class="tabularListColumns">
-                                       <li class="columnSubject">{lang}wcf.moderation.title{/lang}</li>
-                                       <li class="columnStats{if $sortField == 'comments'} active {@$sortOrder}{/if}"><a href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField=comments&sortOrder={if $sortField == 'comments' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.comments{/lang}</a></li>
-                                       <li class="columnLastPost{if $sortField === 'lastChangeTime'} active {@$sortOrder}{/if}"><a href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField=lastChangeTime&sortOrder={if $sortField == 'lastChangeTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.moderation.lastChangeTime{/lang}</a></li>
-                                       
-                                       {event name='columnHeads'}
+                                       <li class="columnSort">
+                                               <ul class="inlineList">
+                                                       <li>
+                                                               <a href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField={$sortField}&sortOrder={if $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">
+                                                                       <span class="icon icon16 fa-sort-amount-{$sortOrder|strtolower} jsTooltip" title="{lang}wcf.search.sortBy{/lang} ({lang}wcf.global.sortOrder.{if $sortOrder === 'ASC'}ascending{else}descending{/if}{/lang})"></span>
+                                                               </a>
+                                                       </li>
+                                                       <li>
+                                                               <div class="dropdown">
+                                                                       <span class="dropdownToggle">{lang}wcf.moderation.{$sortField}{/lang}</span>
+               
+                                                                       <ul class="dropdownMenu">
+                                                                               {foreach from=$validSortFields item=_sortField}
+                                                                                       <li{if $_sortField === $sortField} class="active"{/if}><a href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField={$_sortField}&sortOrder={if $sortField == $_sortField && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.moderation.{$_sortField}{/lang}</a></li>
+                                                                               {/foreach}
+                                                                       </ul>
+                                                               </div>
+                                                       </li>
+                                               </ul>
+                                       </li>
+                                       {hascontent}
+                                               <li class="columnFilter">
+                                                       <ul class="inlineList">
+                                                               {content}
+                                                                       {if $definitionID}
+                                                                               <li>
+                                                                                       <span class="icon icon16 fa-tag jsTooltip" title="{lang}wcf.moderation.filterByType{/lang}"></span>
+                                                                                       {lang}wcf.moderation.type.{$availableDefinitions[$definitionID]}{/lang}
+                                                                               </li>
+                                                                       {/if}
+                                                                       
+                                                                       {if !$assignedUserID || $assignedUserID == $__wcf->getUser()->userID}
+                                                                               <li>
+                                                                                       <span class="icon icon16 fa-user jsTooltip" title="{lang}wcf.moderation.filterByUser{/lang}"></span>
+                                                                                       {if !$assignedUserID}
+                                                                                               {lang}wcf.moderation.filterByUser.nobody{/lang}
+                                                                                       {else}
+                                                                                               {lang}wcf.moderation.filterByUser.myself{/lang}
+                                                                                       {/if}
+                                                                               </li>
+                                                                       {/if}
+                                                                       
+                                                                       {if $status == -1 || $status == 2}
+                                                                               <li>
+                                                                                       {if $status == -1}
+                                                                                               <span class="icon icon16 fa-circle-o jsTooltip" title="{lang}wcf.moderation.status{/lang}"></span>
+                                                                                               {lang}wcf.moderation.status.outstanding{/lang}
+                                                                                       {else}
+                                                                                               <span class="icon icon16 fa-check-circle-o jsTooltip" title="{lang}wcf.moderation.status{/lang}"></span>
+                                                                                               {lang}wcf.moderation.status.done{/lang}
+                                                                                       {/if}
+                                                                               </li>
+                                                                       {/if}
+                                                               {/content}
+                                                       </ul>
+                                               </li>
+                                       {/hascontent}
+                                       <li class="columnApplyFilter jsOnly">
+                                               <button class="small jsStaticDialog" data-dialog-id="moderationListSortFilter"><span class="icon icon16 fa-filter"></span> {lang}wcf.global.filter{/lang}</button>
+                                       </li>
                                </ol>
                        </li>
                        
                                                        </h3>
                                                        
                                                        <ul class="inlineList dotSeparated small messageGroupInfo">
-                                                               <li class="messageGroupAuthor">{if $entry->getAffectedObject()->getUserID()}<a href="{link controller='User' id=$entry->getAffectedObject()->getUserID() title=$entry->getAffectedObject()->getUsername()}{/link}" class="userLink" data-user-id="{@$entry->getAffectedObject()->getUserID()}">{$entry->getAffectedObject()->getUsername()}</a>{else}{$entry->getAffectedObject()->getUsername()}{/if}</li>
+                                                               <li class="messageGroupAuthor">{if $entry->getAffectedObject()->getUserID()}{user object=$entry->getUserProfile()}{else}{$entry->getAffectedObject()->getUsername()}{/if}</li>
                                                                <li class="messageGroupTime">{@$entry->getAffectedObject()->getTime()|time}</li>
                                                                <li>{lang}wcf.moderation.type.{@$entry->getObjectTypeName()}{/lang}</li>
                                                                
                                                        
                                                        {if $entry->assignedUserID}
                                                                <small class="moderationQueueEntryAssignedUser">
-                                                                       {lang}wcf.moderation.assignedUser{/lang}: <a href="{link controller='User' id=$entry->assignedUserID}{/link}" class="userLink" data-user-id="{@$entry->assignedUserID}">{$entry->assignedUsername}</a>
+                                                                       {lang}wcf.moderation.assignedUser{/lang}: <a href="{link controller='User' id=$entry->assignedUserID}{/link}" class="userLink" data-object-id="{@$entry->assignedUserID}">{$entry->assignedUsername}</a>
                                                                </small>
                                                        {/if}
                                                        
                                                        {event name='moderationQueueEntryData'}
                                                </li>
-                                               <li class="columnStats">{@$entry->comments|shortUnit}</li>
-                                               <li class="columnLastPost">
+                                               <li class="columnStats">
+                                                       <dl class="plain statsDataList">
+                                                               <dt>{lang}wcf.global.comments{/lang}</dt>
+                                                               <dd>{@$entry->comments|shortUnit}</dd>
+                                                       </dl>
+                                                       
+                                                       <div class="messageGroupListStatsSimple">{if $entry->comments}<span class="icon icon16 fa-comment-o" aria-label="{lang}wcf.global.comments{/lang}"></span> {@$entry->comments|shortUnit}{/if}</div>
+                                               </li>
+                                               <li class="columnLastPost columnDate">
                                                        {if $entry->lastChangeTime}{@$entry->lastChangeTime|time}{/if}
                                                </li>
                                                
                {/hascontent}
        </footer>
 {else}
-       <p class="info" role="status">{lang}wcf.global.noItems{/lang}</p>
+       <p class="info" role="status">{lang}wcf.moderation.noEntries{/lang}</p>
 {/if}
 
+<div id="moderationListSortFilter" class="jsStaticDialogContent" data-title="{lang}wcf.moderation.filter{/lang}">
+       <form method="post" action="{link controller='ModerationList'}{/link}">
+               <div class="section">
+                       <dl>
+                               <dt><label for="definitionID">{lang}wcf.moderation.filterByType{/lang}</label></dt>
+                               <dd>
+                                       <select name="definitionID" id="definitionID">
+                                               <option value="0">{lang}wcf.moderation.type.all{/lang}</option>
+                                               {foreach from=$availableDefinitions key=__definitionID item=definitionName}
+                                                       <option value="{$__definitionID}"{if $__definitionID == $definitionID} selected{/if}>{lang}wcf.moderation.type.{$definitionName}{/lang}</option>
+                                               {/foreach}
+
+                                               {event name='filterModerationType'}
+                                       </select>
+                               </dd>
+                       </dl>
+                       
+                       <dl>
+                               <dt><label for="assignedUserID">{lang}wcf.moderation.filterByUser{/lang}</label></dt>
+                               <dd>
+                                       <select name="assignedUserID" id="assignedUserID">
+                                               <option value="-1"{if $assignedUserID == -1} selected{/if}>{lang}wcf.moderation.filterByUser.allEntries{/lang}</option>
+                                               <option value="0"{if $assignedUserID == 0} selected{/if}>{lang}wcf.moderation.filterByUser.nobody{/lang}</option>
+                                               <option value="{@$__wcf->getUser()->userID}"{if $assignedUserID == $__wcf->getUser()->userID} selected{/if}>{lang}wcf.moderation.filterByUser.myself{/lang}</option>
+                                               
+                                               {event name='filterAssignedUser'}
+                                       </select>
+                               </dd>
+                       </dl>
+
+                       <dl>
+                               <dt><label for="status">{lang}wcf.moderation.status{/lang}</label></dt>
+                               <dd>
+                                       <select name="status" id="status">
+                                               <option value="-1"{if $status == -1} selected{/if}>{lang}wcf.moderation.status.outstanding{/lang}</option>
+                                               <option value="2"{if $status == 2} selected{/if}>{lang}wcf.moderation.status.done{/lang}</option>
+                                               
+                                               {event name='filterStatus'}
+                                       </select>
+                               </dd>
+                       </dl>
+               </div>
+
+               <div class="formSubmit">
+                       <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
+                       <a href="{link controller='ModerationList'}{/link}" class="button">{lang}wcf.global.button.reset{/lang}</a>
+                       <input type="hidden" name="sortField" value="{$sortField}">
+                       <input type="hidden" name="sortOrder" value="{$sortOrder}">
+               </div>
+       </form>
+</div>
+
 <script data-relocate="true">
        $(function() {
                new WCF.Moderation.Queue.MarkAsRead();
index ff9081ac9c94c20fbf983dafd8800353d0b9bdc3..b47d25449a3b14324cd5c73d7c3b6d6a3576913e 100644 (file)
@@ -9,8 +9,8 @@
                                        <span class="badge label">{$queue->getLabel()}</span>
                                        <a href="{@$queue->getLink()}">{$queue->getAffectedObject()->getTitle()}</a>
                                </h3>
-                               <small>{if $queue->getUserProfile()->userID}<a href="{link controller='User' object=$queue->getUserProfile()->getDecoratedObject()}{/link}">{$queue->getAffectedObject()->getUsername()}</a>{else}{$queue->getAffectedObject()->getUsername()}{/if} <span class="separatorLeft">{@$queue->lastChangeTime|time}</span></small>
+                               <small>{if $queue->getUserProfile()->userID}{user object=$queue->getUserProfile()}{else}{$queue->getAffectedObject()->getUsername()}{/if} <span class="separatorLeft">{@$queue->lastChangeTime|time}</span></small>
                        </div>
                </div>
        </li>
-{/foreach}
\ No newline at end of file
+{/foreach}
index 35d30bd7b6e46d2f47f3b5443b3ed43c4fb5db83..8c3942d792e733c50fbce7265dd42995b2368af5 100644 (file)
@@ -17,7 +17,7 @@
                                <dd>
                                        <span>
                                                {if $queue->assignedUserID}
-                                                       <a href="{link controller='User' id=$assignedUserID}{/link}" class="userLink" data-user-id="{@$assignedUserID}">{$queue->assignedUsername}</a>
+                                                       <a href="{link controller='User' id=$assignedUserID}{/link}" class="userLink" data-object-id="{@$assignedUserID}">{$queue->assignedUsername}</a>
                                                {else}
                                                        {lang}wcf.moderation.assignedUser.nobody{/lang}
                                                {/if}
 
 {include file='formError'}
 
-<section class="section">
-       <header class="sectionHeader">
-               <h2 class="sectionTitle">{lang}wcf.moderation.report.reportedContent{/lang}</h2>
-               <p class="sectionDescription">{lang}wcf.moderation.type.{@$queue->getObjectTypeName()}{/lang}</p>
-       </header>
-       
-       {@$reportedContent}
-</section>
-
 <section class="section">
        <h2 class="sectionTitle">{lang}wcf.moderation.report.reportedBy{/lang}</h2>
        
        <div class="box32">
                {if $reportUser->userID}
-                       <a href="{link controller='User' object=$reportUser}{/link}" title="{$reportUser->username}">
-                               {@$reportUser->getAvatar()->getImageTag(32)}
-                       </a>
+                       {user object=$reportUser type='avatar32' title=$reportUser->username}
                {else}
                        <span>{@$reportUser->getAvatar()->getImageTag(32)}</span>
                {/if}
@@ -79,7 +68,7 @@
                        <div class="containerHeadline">
                                <h3>
                                        {if $reportUser->userID}
-                                               <a href="{link controller='User' object=$reportUser}{/link}" class="userLink" data-user-id="{@$reportUser->userID}">{$reportUser->username}</a>
+                                               {user object=$reportUser}
                                        {else}
                                                {lang}wcf.user.guest{/lang}
                                        {/if}
        </div>
 </section>
 
+<section class="section">
+       <header class="sectionHeader">
+               <h2 class="sectionTitle">{lang}wcf.moderation.report.reportedContent{/lang}</h2>
+               <p class="sectionDescription">{lang}wcf.moderation.type.{@$queue->getObjectTypeName()}{/lang}</p>
+       </header>
+       
+       {@$reportedContent}
+</section>
+
 {include file='__commentJavaScript' commentContainerID='moderationQueueCommentList'}
 
 <section id="comments" class="section sectionContainerList moderationComments">
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.moderation.assignedUser': '{lang}wcf.moderation.assignedUser{/lang}',
-                       'wcf.moderation.assignedUser.error.notAffected': '{lang}wcf.moderation.assignedUser.error.notAffected{/lang}',
-                       'wcf.moderation.report.removeContent.confirmMessage': '{lang}wcf.moderation.report.removeContent.confirmMessage{/lang}',
-                       'wcf.moderation.report.removeContent.reason': '{lang}wcf.moderation.report.removeContent.reason{/lang}',
-                       'wcf.moderation.report.removeReport.confirmMessage': '{lang}wcf.moderation.report.removeReport.confirmMessage{/lang}',
-                       'wcf.moderation.report.removeReport.markAsJustified': '{lang}wcf.moderation.report.removeReport.markAsJustified{/lang}',
-                       'wcf.moderation.status.outstanding': '{lang}wcf.moderation.status.outstanding{/lang}',
-                       'wcf.moderation.status.processing': '{lang}wcf.moderation.status.processing{/lang}',
-                       'wcf.user.username.error.notFound': '{lang __literal=true}wcf.user.username.error.notFound{/lang}'
+                       'wcf.moderation.assignedUser': '{jslang}wcf.moderation.assignedUser{/jslang}',
+                       'wcf.moderation.assignedUser.error.notAffected': '{jslang}wcf.moderation.assignedUser.error.notAffected{/jslang}',
+                       'wcf.moderation.report.removeContent.confirmMessage': '{jslang}wcf.moderation.report.removeContent.confirmMessage{/jslang}',
+                       'wcf.moderation.report.removeContent.reason': '{jslang}wcf.moderation.report.removeContent.reason{/jslang}',
+                       'wcf.moderation.report.removeReport.confirmMessage': '{jslang}wcf.moderation.report.removeReport.confirmMessage{/jslang}',
+                       'wcf.moderation.report.removeReport.markAsJustified': '{jslang}wcf.moderation.report.removeReport.markAsJustified{/jslang}',
+                       'wcf.moderation.status.outstanding': '{jslang}wcf.moderation.status.outstanding{/jslang}',
+                       'wcf.moderation.status.processing': '{jslang}wcf.moderation.status.processing{/jslang}',
+                       'wcf.user.username.error.notFound': '{jslang __literal=true}wcf.user.username.error.notFound{/jslang}'
                });
                
                new WCF.Moderation.Report.Management({@$queue->queueID}, '{link controller='ModerationList' encode=false}{/link}');
index 2570fd2dd5943c18d3f9cbec2fd36b2cf717034d..875d3f0106aee835cae49fe09ab4065b989fbb65 100644 (file)
@@ -2,7 +2,7 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Language/Input', 'WoltLabSuite/Core/Language/Text'], function(Language, LanguageInput, LanguageText) {
                        Language.addObject({
-                               'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}'
+                               'wcf.global.button.disabledI18n': '{jslang}wcf.global.button.disabledI18n{/jslang}'
                        });
                        
                        var availableLanguages = { {implode from=$availableLanguages key=languageID item=languageName}{@$languageID}: '{$languageName}'{/implode} };
index fd9759106057f4fc899b79b6132c047def45b3b8..2e9aa25a005e73c767459928bfd04d96dcf55db2 100644 (file)
                </dl>
                
                {event name='fields'}
+               
+               <script data-relocate="true">
+                       require(['WoltLabSuite/Core/Ui/User/PasswordStrength', 'Language'], function (PasswordStrength, Language) {
+                               {include file='passwordStrengthLanguage'}
+                               
+                               new PasswordStrength(elById('newPassword'), {
+                                       staticDictionary: [
+                                               '{$user->username|encodeJS}',
+                                               '{$user->email|encodeJS}',
+                                       ]
+                               });
+                       })
+               </script>
        </div>
        
        {event name='sections'}
index 0d765897166509cf4afcf8e30a88a6004175fd64..33338e7f138bf9646c37636f4fca017cf9401221 100644 (file)
@@ -80,7 +80,7 @@
                                                                <ul class="userAvatarList small">
                                                                        {foreach from=$notification[event]->getAuthors() item=author}
                                                                                {if $author->userID}
-                                                                                       <li class="jsTooltip" title="{$author->username}"><a href="{link controller='User' object=$author}{/link}">{@$author->getAvatar()->getImageTag(24)}</a></li>
+                                                                                       <li class="jsTooltip" title="{$author->username}">{user object=$author type='avatar24'}</li>
                                                                                {/if}
                                                                        {/foreach}
                                                                </ul>
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.notification.markAsConfirmed': '{lang}wcf.user.notification.markAsConfirmed{/lang}',
-                       'wcf.user.notification.markAllAsConfirmed.confirmMessage': '{lang}wcf.user.notification.markAllAsConfirmed.confirmMessage{/lang}'
+                       'wcf.user.notification.markAsConfirmed': '{jslang}wcf.user.notification.markAsConfirmed{/jslang}',
+                       'wcf.user.notification.markAllAsConfirmed.confirmMessage': '{jslang}wcf.user.notification.markAllAsConfirmed.confirmMessage{/jslang}'
                });
                
                new WCF.Notification.List();
index cfb7071b4a432716cbcab4474175601524e81e9c..629f904441a4dba15e4f3a19f14373ff8a72bc82 100644 (file)
@@ -2,8 +2,6 @@
 
 {capture assign='contentTitle'}{lang}wcf.user.menu.settings{/lang}: {lang}wcf.user.notification.notifications{/lang}{/capture}
 
-{capture assign='contentDescription'}{lang}wcf.user.notification.notifications.description{/lang}{/capture}
-
 {include file='userMenuSidebar'}
 
 {include file='header' __disableAds=true __sidebarLeftHasMenu=true}
 {/if}
 
 <form method="post" action="{link controller='NotificationSettings'}{/link}" id="notificationSettings">
-       {foreach from=$events key='eventCategory' item='eventList'}
-               <section class="section">
-                       <h2 class="sectionTitle">{lang}wcf.user.notification.{$eventCategory}{/lang}</h2>
-                       
-                       <dl>
+       <div class="section">
+               {foreach from=$events key='eventCategory' item='eventList'}
+                       <div class="notificationSettings">
+                               <div class="notificationSettingsCategory">
+                                       <div class="notificationSettingsEvent">{lang}wcf.user.notification.{$eventCategory}{/lang}</div>
+                                       <div class="notificationSettingsState">{lang}wcf.user.notification.status.active{/lang}</div>
+                                       <div class="notificationSettingsEmail">{lang}wcf.user.notification.status.email{/lang}</div>
+                               </div>
                                {foreach from=$eventList item=event}
-                                       <dt>{lang}wcf.user.notification.{$event->objectType}.{$event->eventName}{/lang}</dt>
-                                       <dd>
-                                               <ol class="flexibleButtonGroup" data-object-id="{@$event->eventID}">
-                                                       <li>
-                                                               <input type="radio" id="settings_{@$event->eventID}_disabled" name="settings[{@$event->eventID}][enabled]" value="0"{if $settings[$event->eventID][enabled]|empty} checked{/if}>
-                                                               <label for="settings_{@$event->eventID}_disabled" class="red">
-                                                                       <span class="icon icon16 fa-times"></span>
-                                                                       {lang}wcf.user.notification.notifications.disabled{/lang}
-                                                               </label>
-                                                       </li>
-                                                       <li class="spaceAfter">
-                                                               <input type="radio" id="settings_{@$event->eventID}_enabled" name="settings[{@$event->eventID}][enabled]" value="1"{if !$settings[$event->eventID][enabled]|empty} checked{/if}>
-                                                               <label for="settings_{@$event->eventID}_enabled" class="green">
-                                                                       <span class="icon icon16 fa-bell"></span>
-                                                                       {lang}wcf.user.notification.notifications.enabled{/lang}
-                                                               </label>
-                                                       </li>
+                                       <div class="notificationSettingsItem">
+                                               <div class="notificationSettingsEvent">
+                                                       <label for="settings_{@$event->eventID}">{lang}wcf.user.notification.{$event->objectType}.{$event->eventName}{/lang}</label>
+                                               </div>
+                                               <div class="notificationSettingsState">
+                                                       <label>
+                                                               <input type="checkbox" id="settings_{@$event->eventID}" name="settings[{@$event->eventID}][enabled]" class="jsCheckboxNotificationSettingsState" value="1" data-object-id="{@$event->eventID}"{if !$settings[$event->eventID][enabled]|empty} checked{/if}>
+                                                               <span class="icon icon24 fa-bell green pointer"></span>
+                                                               <span class="icon icon24 fa-bell-slash red pointer"></span>
+                                                       </label>
+                                               </div>
+                                               <div class="notificationSettingsEmail">
                                                        {if $event->supportsEmailNotification()}
-                                                               <li class="notificationSettingsEmail{if !$settings[$event->eventID][enabled]|empty} active{/if}">
-                                                                       <input type="hidden" id="settings_{$event->eventID}_mailNotificationType" name="settings[{@$event->eventID}][mailNotificationType]" value="{$settings[$event->eventID][mailNotificationType]}">
-                                                                       <a{if $settings[$event->eventID][mailNotificationType] !== 'none'} class="active yellow"{/if}>
-                                                                               <span class="icon icon16 fa-envelope-o"></span>
-                                                                               <span class="title">{lang}wcf.user.notification.mailNotificationType.{$settings[$event->eventID][mailNotificationType]}{/lang}</span>
-                                                                               <span class="icon icon16 fa-caret-down"></span>
-                                                                       </a>
-                                                               </li>
+                                                               <input type="hidden" id="settings_{$event->eventID}_mailNotificationType" name="settings[{@$event->eventID}][mailNotificationType]" value="{$settings[$event->eventID][mailNotificationType]}">
+                                                               <a href="#" class="notificationSettingsEmailType jsTooltip{if $settings[$event->eventID][enabled]|empty} disabled{/if}" role="button" title="{lang}wcf.user.notification.mailNotificationType.{@$settings[$event->eventID][mailNotificationType]}{/lang}" data-object-id="{@$event->eventID}">
+                                                                       {if $settings[$event->eventID][mailNotificationType] === 'none'}
+                                                                               <span class="icon icon24 fa-times red jsIconNotificationSettingsEmailType"></span>
+                                                                       {else}
+                                                                               <span class="icon icon24 {if $settings[$event->eventID][mailNotificationType] === 'instant'}fa-flash{else}fa-clock-o{/if} green jsIconNotificationSettingsEmailType"></span>
+                                                                       {/if}
+                                                                       <span class="icon icon16 fa-caret-down"></span>
+                                                               </a>
                                                        {/if}
-                                               </ol>
-                                       </dd>
+                                               </div>
+                                       </div>
                                {/foreach}
-                       </dl>
-               </section>
-       {/foreach}
+                       </div>
+               {/foreach}
+       </div>
        
        {event name='sections'}
        
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Controller/User/Notification/Settings'], function(Language, ControllerUserNotificationSettings) {
                Language.addObject({
-                       'wcf.user.notification.mailNotificationType.daily': '{lang}wcf.user.notification.mailNotificationType.daily{/lang}',
-                       'wcf.user.notification.mailNotificationType.instant': '{lang}wcf.user.notification.mailNotificationType.instant{/lang}',
-                       'wcf.user.notification.mailNotificationType.none': '{lang}wcf.user.notification.mailNotificationType.none{/lang}'
+                       'wcf.user.notification.mailNotificationType.daily': '{jslang}wcf.user.notification.mailNotificationType.daily{/jslang}',
+                       'wcf.user.notification.mailNotificationType.instant': '{jslang}wcf.user.notification.mailNotificationType.instant{/jslang}',
+                       'wcf.user.notification.mailNotificationType.none': '{jslang}wcf.user.notification.mailNotificationType.none{/jslang}'
                });
                
-               ControllerUserNotificationSettings.setup();
+               ControllerUserNotificationSettings.init();
        });
 </script>
 
diff --git a/com.woltlab.wcf/templates/notificationUnsubscribe.tpl b/com.woltlab.wcf/templates/notificationUnsubscribe.tpl
new file mode 100644 (file)
index 0000000..d09fd53
--- /dev/null
@@ -0,0 +1,29 @@
+{include file='header' __disableAds=true}
+
+<p class="info" role="status">{lang}wcf.user.notification.mail.unsubscribe.description{/lang}</p>
+
+{include file='formError'}
+
+<form method="post" action="{link controller='NotificationUnsubscribe' userID=$user->userID token=$token}{/link}">
+       <div class="section">
+               <dl{if $errorField == 'eventID'} class="formError"{/if}>
+                       <dt><label for="eventID">{lang}wcf.user.notification.mail.unsubscribe.event{/lang}</label></dt>
+                       <dd>
+                               {if $event !== null}
+                                       <label><input type="radio" id="eventID" name="eventID" value="{$event->eventID}" checked> {lang}wcf.user.notification.{$event->getObjectType()->objectType}.{$event->eventName}{/lang}</label>
+                               {/if}
+                               <label><input type="radio" name="eventID" value="0"{if $event === null} checked{/if}> {lang}wcf.user.notification.mail.unsubscribe.event.all{/lang}</label>
+                       </dd>
+               </dl>
+               
+               {event name='fields'}
+       </div>
+
+       <div class="formSubmit">
+               <input type="submit" value="{lang}wcf.user.notification.mail.unsubscribe.confirm{/lang}" accesskey="s">
+               {* The tag is not technically required, but the POST data would be empty otherwise. *}
+               {@SECURITY_TOKEN_INPUT_TAG}
+       </div>
+</form>
+
+{include file='footer' __disableAds=true}
index f4aca1d74495460d275e3842894eca800df1bb75..c7062323ee057913a95905c42187133619403f5f 100644 (file)
@@ -8,6 +8,13 @@
                        errorType: {if $errorType|empty}(empty){else}{$errorType|print_r:true}{/if}
                
                -->
+               {if ENABLE_DEBUG_MODE}
+                       <script>
+                               console.debug('FORM_VALIDATION_FAILED');
+                               console.debug('errorField:', '{if $errorField|empty}(empty){else}{$errorField|json_encode}{/if}');
+                               console.debug('errorType:', '{if $errorType|empty}(empty){else}{$errorType|json_encode}{/if}');
+                       </script>
+               {/if}
        {/if}
        
        {assign var=__boxesFooter value=$__wcf->getBoxHandler()->getBoxes('footer')}
index 3432a0a627ba773268cc7253c5f322787b84e03d..14009f1a208dfa4f0eb91092fd2e6767bc06a0b4 100644 (file)
@@ -7,7 +7,7 @@
                {if $__wcf->user->userID}
                        <!-- user menu -->
                        <li id="userMenu">
-                               <a class="jsTooltip" href="{link controller='User' object=$__wcf->user}{/link}" title="{lang}wcf.user.controlPanel{/lang}">{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32)} <span>{lang}wcf.user.userNote{/lang}</span></a>
+                               <a class="jsTooltip" href="{$__wcf->user->getLink()}" title="{lang}wcf.user.controlPanel{/lang}">{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32)} <span>{lang}wcf.user.userNote{/lang}</span></a>
                                <div class="interactiveDropdown interactiveDropdownStatic interactiveDropdownUserMenu">
                                        <div class="interactiveDropdownHeader">
                                                <span class="interactiveDropdownTitle">{lang}wcf.user.controlPanel{/lang}</span>
                                                <ul class="interactiveDropdownItems interactiveDropdownItemsUserMenu">
                                                        <li>
                                                                <div class="box48">
-                                                                       <a href="{link controller='User' object=$__wcf->user}{/link}" aria-hidden="true">{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(48)}</a>
+                                                                       {user object=$__wcf->getUserProfileHandler()->getUserProfile() type='avatar48' ariaHidden='true'}
                                                                        
                                                                        <div class="containerHeadline">
                                                                                <h3>
-                                                                                       <a href="{link controller='User' object=$__wcf->user}{/link}">{$__wcf->user->username}</a>
+                                                                                       {user object=$__wcf->getUserProfileHandler()->getUserProfile()}
                                                                                        {if MODULE_USER_RANK}
                                                                                                {if $__wcf->getUserProfileHandler()->getUserTitle()}
                                                                                                        <span class="badge userTitleBadge{if $__wcf->getUserProfileHandler()->getRank() && $__wcf->getUserProfileHandler()->getRank()->cssClassName} {@$__wcf->getUserProfileHandler()->getRank()->cssClassName}{/if}">{$__wcf->getUserProfileHandler()->getUserTitle()}</span>
@@ -40,7 +40,7 @@
                                                                                </h3>
                                                                                
                                                                                <ul class="inlineList dotSeparated">
-                                                                                       <li><a href="{link controller='User' object=$__wcf->user}{/link}">{lang}wcf.user.myProfile{/lang}</a></li>
+                                                                                       <li><a href="{$__wcf->user->getLink()}">{lang}wcf.user.myProfile{/lang}</a></li>
                                                                                        {if $__wcf->getUserProfileHandler()->canEditOwnProfile()}<li><a href="{link controller='User' object=$__wcf->user}editOnInit=true#about{/link}" class="jsUserPanelEditProfile">{lang}wcf.user.editProfile{/lang}</a></li>{/if}
                                                                                        {if $__wcf->session->getPermission('admin.general.canUseAcp')}<li><a href="{link isACP=true}{/link}">{lang}wcf.global.acp.short{/lang}</a></li>{/if}
                                                                                </ul>
@@ -71,7 +71,7 @@
                                                        {event name='userMenuItemsAfter'}
                                                </ul>
                                        </div>
-                                       <a class="interactiveDropdownShowAll" href="{link controller='Logout'}t={@SECURITY_TOKEN}{/link}" onclick="WCF.Dropdown.Interactive.Handler.close('userMenu'); WCF.System.Confirmation.show('{lang}wcf.user.logout.sure{/lang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;">{lang}wcf.user.logout{/lang}</a>
+                                       <a class="interactiveDropdownShowAll" href="{link controller='Logout'}t={@SECURITY_TOKEN}{/link}" onclick="WCF.Dropdown.Interactive.Handler.close('userMenu'); WCF.System.Confirmation.show('{jslang}wcf.user.logout.sure{/jslang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;">{lang}wcf.user.logout{/lang}</a>
                                </div>
                                <script data-relocate="true">
                                        $(function() {
                                                <script data-relocate="true">
                                                        $(function() {
                                                                new WCF.User.Panel.Notification({
-                                                                       noItems: '{lang}wcf.user.notification.noMoreNotifications{/lang}',
+                                                                       noItems: '{jslang}wcf.user.notification.noMoreNotifications{/jslang}',
                                                                        settingsLink: '{link controller='NotificationSettings' encode=false}{/link}',
                                                                        showAllLink: '{link controller='NotificationList' encode=false}{/link}',
-                                                                       title: '{lang}wcf.user.notification.notifications{/lang}'
+                                                                       title: '{jslang}wcf.user.notification.notifications{/jslang}'
                                                                });
                                                        });
                                                </script>
                                        <script data-relocate="true">
                                                $(function() {
                                                        WCF.Language.addObject({
-                                                               'wcf.user.button.login': '{lang}wcf.user.button.login{/lang}',
-                                                               'wcf.user.button.register': '{lang}wcf.user.button.register{/lang}',
-                                                               'wcf.user.login': '{lang}wcf.user.login{/lang}'
+                                                               'wcf.user.button.login': '{jslang}wcf.user.button.login{/jslang}',
+                                                               'wcf.user.button.register': '{jslang}wcf.user.button.register{/jslang}',
+                                                               'wcf.user.login': '{jslang}wcf.user.login{/jslang}'
                                                        });
                                                        new WCF.User.Login(true);
                                                });
                                                <script data-relocate="true">
                                                        $(function() {
                                                                new WCF.User.Panel.Moderation({
-                                                                       deletedContent: '{lang}wcf.moderation.showDeletedContent{/lang}',
+                                                                       deletedContent: '{jslang}wcf.moderation.showDeletedContent{/jslang}',
                                                                        deletedContentLink: '{link controller='DeletedContentList' encode=false}{/link}',
-                                                                       noItems: '{lang}wcf.moderation.noMoreItems{/lang}',
+                                                                       noItems: '{jslang}wcf.moderation.noMoreItems{/jslang}',
                                                                        showAllLink: '{link controller='ModerationList' encode=false}{/link}',
-                                                                       title: '{lang}wcf.moderation.moderation{/lang}'
+                                                                       title: '{jslang}wcf.moderation.moderation{/jslang}'
                                                                });
                                                        });
                                                </script>
index 587d4cd3ea989ad276c04803126acb81aedc56ae..bab64312f58dfd116a4932eafc8a1b0fb0dce868 100644 (file)
                                
                                {if $menuItemNode->hasChildren()}<ol class="menuOverlayItemList">{else}</li>{/if}
                                        
-                                       {if !$menuItemNode->hasChildren() && $menuItemNode->isLastSibling()}
-                                               {@"</ol></li>"|str_repeat:$menuItemNode->getOpenParentNodes()}
-                                       {/if}
+                               {if !$menuItemNode->hasChildren() && $menuItemNode->isLastSibling()}
+                                       {@"</ol></li>"|str_repeat:$menuItemNode->getOpenParentNodes()}
+                               {/if}
                {/foreach}
+
+                {if $__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.FooterMenu')}
+                       {hascontent}
+                               <li class="menuOverlayItemSpacer"></li>
+                               {content}       
+                                       {foreach from=$__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.FooterMenu')->getMenu()->getMenuItemNodeList() item=menuItemNode}
+                                               {* Does not use `data-identifier` to prevent compatibility issues. See https://github.com/WoltLab/WCF/pull/2813 *}
+                                               <li class="menuOverlayItem" data-mobile-identifier="{@$menuItemNode->identifier}">
+                                                       {assign var=__outstandingItems value=$menuItemNode->getOutstandingItems()}
+                                                       <a href="{$menuItemNode->getURL()}" class="menuOverlayItemLink{if $__outstandingItems} menuOverlayItemBadge{/if}{if $menuItemNode->isActiveNode()} active{/if}"{if $menuItemNode->isExternalLink() && EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}>
+                                                               <span class="menuOverlayItemTitle">{$menuItemNode->getTitle()}</span>
+                                                               {if $__outstandingItems}
+                                                                       <span class="badge badgeUpdate">{#$__outstandingItems}</span>
+                                                               {/if}
+                                                       </a>
+                       
+                                                       {if $menuItemNode->hasChildren()}<ol class="menuOverlayItemList">{else}</li>{/if}
+                       
+                                                       {if !$menuItemNode->hasChildren() && $menuItemNode->isLastSibling()}
+                                                               {@"</ol></li>"|str_repeat:$menuItemNode->getOpenParentNodes()}
+                                                       {/if}
+                                       {/foreach}
+                               {/content}
+                       {/hascontent}
+               {/if}
+
                <li class="menuOverlayItemSpacer"></li>
                <li class="menuOverlayItem" data-more="com.woltlab.wcf.search">
                        <a href="#" class="menuOverlayItemLink box24">
@@ -63,7 +89,7 @@
                        {* logged-in *}
                        <li class="menuOverlayTitle">{lang}wcf.menu.user{/lang}</li>
                        <li class="menuOverlayItem">
-                               <a href="{link controller='User' object=$__wcf->user}{/link}" class="menuOverlayItemLink box24">
+                               <a href="{$__wcf->user->getLink()}" class="menuOverlayItemLink box24">
                                        {@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(24)}
                                        <span class="menuOverlayItemTitle">{$__wcf->user->username}</span>
                                </a>
                                <li class="menuOverlayItem" data-more="com.woltlab.wcf.login">
                                        <a href="#" class="menuOverlayItemLink box24">
                                                <span class="icon icon24 fa-sign-in"></span>
-                                               <span class="menuOverlayItemTitle">{lang}wcf.user.login{/lang}</span>
-                                       </a>
-                               </li>
-                       {/if}
-                       {if !REGISTER_DISABLED}
-                               <li class="menuOverlayItem">
-                                       <a href="{link controller='Register'}{/link}" class="menuOverlayItemLink box24">
-                                               <span class="icon icon24 fa-user-plus"></span>
-                                               <span class="menuOverlayItemTitle">{lang}wcf.user.register{/lang}</span>
+                                               <span class="menuOverlayItemTitle">{lang}wcf.user.loginOrRegister{/lang}</span>
                                        </a>
                                </li>
                        {/if}
diff --git a/com.woltlab.wcf/templates/passwordStrengthLanguage.tpl b/com.woltlab.wcf/templates/passwordStrengthLanguage.tpl
new file mode 100644 (file)
index 0000000..7bc7f02
--- /dev/null
@@ -0,0 +1,30 @@
+Language.addObject({
+       'wcf.user.password.strength': '{jslang}wcf.user.password.strength{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.use_words_avoid_common_phrases': '{jslang}wcf.user.password.zxcvbn.suggestions.use_words_avoid_common_phrases{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.no_need_for_symbols_digits_uppercase': '{jslang}wcf.user.password.zxcvbn.suggestions.no_need_for_symbols_digits_uppercase{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.add_word_uncommon_better': '{jslang}wcf.user.password.zxcvbn.suggestions.add_word_uncommon_better{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.use_longer_keyboard_pattern': '{jslang}wcf.user.password.zxcvbn.suggestions.use_longer_keyboard_pattern{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_repeat': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_repeat{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_sequence': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_sequence{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_recent_year': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_recent_year{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_associated_year': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_associated_year{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_date': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_date{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.start_upper': '{jslang}wcf.user.password.zxcvbn.suggestions.start_upper{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.all_upper': '{jslang}wcf.user.password.zxcvbn.suggestions.all_upper{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.reversed': '{jslang}wcf.user.password.zxcvbn.suggestions.reversed{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.l33t': '{jslang}wcf.user.password.zxcvbn.suggestions.l33t{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.straight_row': '{jslang}wcf.user.password.zxcvbn.warnings.straight_row{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.short_keyboard_pattern': '{jslang}wcf.user.password.zxcvbn.warnings.short_keyboard_pattern{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.repeat_single_char': '{jslang}wcf.user.password.zxcvbn.warnings.repeat_single_char{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.repeat': '{jslang}wcf.user.password.zxcvbn.warnings.repeat{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.sequence': '{jslang}wcf.user.password.zxcvbn.warnings.sequence{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.recent_year': '{jslang}wcf.user.password.zxcvbn.warnings.recent_year{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.date': '{jslang}wcf.user.password.zxcvbn.warnings.date{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.top_10': '{jslang}wcf.user.password.zxcvbn.warnings.top_10{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.top_100': '{jslang}wcf.user.password.zxcvbn.warnings.top_100{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.common': '{jslang}wcf.user.password.zxcvbn.warnings.common{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.common_alike': '{jslang}wcf.user.password.zxcvbn.warnings.common_alike{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.sole_word': '{jslang}wcf.user.password.zxcvbn.warnings.sole_word{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.sole_name': '{jslang}wcf.user.password.zxcvbn.warnings.sole_name{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.name': '{jslang}wcf.user.password.zxcvbn.warnings.name{/jslang}',
+});
index f95bcb514ffc954aa17c6cc8da1681b0a14e16d6..a897291f212ff1f316ee54ea9b9a9cfda213cc83 100644 (file)
@@ -9,7 +9,7 @@
 
 <div class="pollContainer{if POLL_FULL_WIDTH} pollContainerFullWidth{/if}" data-poll-id="{@$poll->pollID}" data-can-vote="{if $poll->canVote()}1{else}0{/if}" data-can-view-result="{if $poll->canSeeResult()}1{else}0{/if}" data-can-view-participants="{if $poll->canViewParticipants()}true{else}false{/if}" data-in-vote="{if $poll->canVote() && !$poll->isParticipant()}1{else}0{/if}" data-question="{$poll->question}" data-max-votes="{@$poll->maxVotes}" data-is-public="{if $poll->isPublic}true{else}false{/if}">
        <section>
-               <h2>{$poll->question} <span class="badge jsTooltip" title="{lang}wcf.poll.totalVotes{/lang}">{#$poll->votes}</span></h2>
+               <h2>{$poll->question} <span class="badge jsTooltip jsPollTotalVotes" title="{lang}wcf.poll.totalVotes{/lang}">{#$poll->votes}</span></h2>
                
                <div class="pollInnerContainer">
                        {if !$__wcf->getUser()->userID}
index ba91fc32c31c69d34937c71ee19e30fd0826a115..5c3b239a6647cd8d10cf1026c47925f2518b816a 100644 (file)
@@ -10,4 +10,8 @@
                        </div>
                </li>
        {/foreach}
-</ol>
\ No newline at end of file
+</ol>
+
+{if $poll->endTime && !$poll->isFinished()}
+       <p><small>{lang}wcf.poll.endTimeInfo{/lang}</small></p>
+{/if}
index 804431ceba1ed57c80dd424426f78ff2c5c634ed..f2701a307c7a56832df84e8e3c68d7d54489dbd1 100644 (file)
@@ -12,6 +12,7 @@
 {if $poll->canVote()}
        {if $poll->maxVotes > 1}<p><small>{lang}wcf.poll.multipleVotes{/lang}</small></p>{/if}
        {if $poll->endTime}<p><small>{lang}wcf.poll.endTimeInfo{/lang}</small></p>{/if}
+       {if $poll->isPublic}<p><small>{lang}wcf.poll.isPublic{/lang}</small></p>{/if}
 {else}
        <p><small>{lang}wcf.poll.restrictedResult{/lang}</small></p>
-{/if}
\ No newline at end of file
+{/if}
index 12e9ade38607863c52feb5ac15a0bf98da90215a..7b15fea581967540f84e779afa90f066a890f19a 100644 (file)
@@ -1,7 +1,7 @@
 <blockquote class="quoteBox collapsibleBbcode jsCollapsibleBbcode{if $collapseQuote} collapsed{/if}{if !$quoteAuthorObject} quoteBoxSimple{/if}"{if $quoteLink} cite="{$quoteLink}"{/if}>
        <div class="quoteBoxIcon">
                {if $quoteAuthorObject}
-                       <a href="{link controller='User' object=$quoteAuthorObject}{/link}" class="userLink" data-user-id="{@$quoteAuthorObject->userID}" aria-hidden="true">{@$quoteAuthorObject->getAvatar()->getImageTag(64)}</a>
+                       <a href="{$quoteAuthorObject->getLink()}" class="userLink" data-object-id="{@$quoteAuthorObject->userID}" aria-hidden="true">{@$quoteAuthorObject->getAvatar()->getImageTag(64)}</a>
                {else}
                        <span class="quoteBoxQuoteSymbol"></span>
                {/if}
@@ -11,7 +11,7 @@
                <span class="quoteBoxTitle">
                        {if $quoteAuthor}
                                {if $quoteLink}
-                                       <a href="{@$quoteLink}"{if $isExternalQuoteLink} class="externalURL"{if EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK}rel="{if EXTERNAL_LINK_REL_NOFOLLOW}nofollow{/if} {if EXTERNAL_LINK_TARGET_BLANK}noopener noreferrer{/if}"{/if}{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}{/if}>{lang}wcf.bbcode.quote.title{/lang}</a>
+                                       <a {anchorAttributes url=$quoteLink isUgc=true}>{lang}wcf.bbcode.quote.title{/lang}</a>
                                {else}
                                        {lang}wcf.bbcode.quote.title{/lang}
                                {/if}
index e11431254926cb861c79b5604801e197db12af01..cb05498a4fe6854039ac3ec39f839768d05bd4f9 100644 (file)
@@ -2,8 +2,8 @@
        <script data-relocate="true">
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.user.recentActivity.more': '{lang}wcf.user.recentActivity.more{/lang}',
-                               'wcf.user.recentActivity.noMoreEntries': '{lang}wcf.user.recentActivity.noMoreEntries{/lang}'
+                               'wcf.user.recentActivity.more': '{jslang}wcf.user.recentActivity.more{/jslang}',
+                               'wcf.user.recentActivity.noMoreEntries': '{jslang}wcf.user.recentActivity.noMoreEntries{/jslang}'
                        });
                        
                        new WCF.User.RecentActivityLoader({@$userID});
index 0577fd9c4ab0c99d95335739cd3eb4a7b7b07388..c55b2b40a911cbe6c55c16238910c4d2f7d79d0e 100644 (file)
@@ -23,8 +23,8 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.recentActivity.more': '{lang}wcf.user.recentActivity.more{/lang}',
-                       'wcf.user.recentActivity.noMoreEntries': '{lang}wcf.user.recentActivity.noMoreEntries{/lang}'
+                       'wcf.user.recentActivity.more': '{jslang}wcf.user.recentActivity.more{/jslang}',
+                       'wcf.user.recentActivity.noMoreEntries': '{jslang}wcf.user.recentActivity.noMoreEntries{/jslang}'
                });
                
                new WCF.User.RecentActivityLoader(null);
index 8923575ec435e9232f8fe8adac2a90b687041131..dcb5e9d4cb626489de7abcc7f80d669e4bc236dd 100644 (file)
@@ -1,13 +1,13 @@
 {foreach from=$eventList item=event}
        <li>
                <div class="box48{if $__wcf->getUserProfileHandler()->isIgnoredUser($event->getUserProfile()->userID)} ignoredUserContent{/if}">
-                       <a href="{link controller='User' object=$event->getUserProfile()}{/link}" title="{$event->getUserProfile()->username}" aria-hidden="true">{@$event->getUserProfile()->getAvatar()->getImageTag(48)}</a>
+                       {user object=$event->getUserProfile() type='avatar48' title=$event->getUserProfile()->username ariaHidden='true'}
                        
                        <div>
                                <div class="containerHeadline">
                                        <h3>
                                                {event name='beforeUsername'}
-                                               <a href="{link controller='User' object=$event->getUserProfile()}{/link}" class="userLink" data-user-id="{@$event->getUserProfile()->userID}">{$event->getUserProfile()->username}</a>
+                                               {user object=$event->getUserProfile()}
                                                <small class="separatorLeft">{@$event->time|time}</small>
                                        </h3>
                                        <div>{@$event->getTitle()}</div>
index 7946618a2ca3d8e0508e54fc3bacd10910c987f4..b660a6c8d8baed043b02dee09827444300b0c2f7 100644 (file)
                                                                LanguageChooser.init('languageIDContainer', 'languageID', {@$languageID}, $languages);
                                                                
                                                                var small = elCreate('small');
-                                                               small.innerHTML = '{lang}wcf.user.language.description{/lang}';
+                                                               small.innerHTML = '{jslang}wcf.user.language.description{/jslang}';
                                                                elById('languageIDContainer').appendChild(small);
                                                        });
                                                });
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.global.form.error.empty': '{lang}wcf.global.form.error.empty{/lang}',
-                       'wcf.user.username.error.invalid': '{lang}wcf.user.username.error.invalid{/lang}',
-                       'wcf.user.username.error.notUnique': '{lang}wcf.user.username.error.notUnique{/lang}',
-                       'wcf.user.email.error.invalid' : '{lang}wcf.user.email.error.invalid{/lang}',
-                       'wcf.user.email.error.notUnique' : '{lang}wcf.user.email.error.notUnique{/lang}',
-                       'wcf.user.confirmEmail.error.notEqual' : '{lang}wcf.user.confirmEmail.error.notEqual{/lang}',
-                       'wcf.user.password.error.notSecure' : '{lang}wcf.user.password.error.notSecure{/lang}',
-                       'wcf.user.confirmPassword.error.notEqual' : '{lang}wcf.user.confirmPassword.error.notEqual{/lang}'
+                       'wcf.global.form.error.empty': '{jslang}wcf.global.form.error.empty{/jslang}',
+                       'wcf.user.username.error.invalid': '{jslang}wcf.user.username.error.invalid{/jslang}',
+                       'wcf.user.username.error.notUnique': '{jslang}wcf.user.username.error.notUnique{/jslang}',
+                       'wcf.user.email.error.invalid' : '{jslang}wcf.user.email.error.invalid{/jslang}',
+                       'wcf.user.email.error.notUnique' : '{jslang}wcf.user.email.error.notUnique{/jslang}',
+                       'wcf.user.confirmEmail.error.notEqual' : '{jslang}wcf.user.confirmEmail.error.notEqual{/jslang}',
+                       'wcf.user.password.error.notSecure' : '{jslang}wcf.user.password.error.notSecure{/jslang}',
+                       'wcf.user.confirmPassword.error.notEqual' : '{jslang}wcf.user.confirmPassword.error.notEqual{/jslang}'
                });
                
                new WCF.User.Registration.Validation.EmailAddress($('#{@$randomFieldNames[email]}'), $('#{@$randomFieldNames[confirmEmail]}'), null);
-               new WCF.User.Registration.Validation.Password($('#{@$randomFieldNames[password]}'), $('#{@$randomFieldNames[confirmPassword]}'), null);
                new WCF.User.Registration.Validation.Username($('#{@$randomFieldNames[username]}'), null, {
                        minlength: {@REGISTER_USERNAME_MIN_LENGTH},
                        maxlength: {@REGISTER_USERNAME_MAX_LENGTH}
                });
+               
+               require(['WoltLabSuite/Core/Ui/User/PasswordStrength', 'Language'], function (PasswordStrength, Language) {
+                       {include file='passwordStrengthLanguage'}
+                       
+                       new PasswordStrength(elById('{@$randomFieldNames[password]}'), {
+                               relatedInputs: [
+                                       elById('{@$randomFieldNames[username]}'),
+                                       elById('{@$randomFieldNames[email]}')
+                               ]
+                       });
+               })
        });
 </script>
 
index 2711ff0a9e4cc3f18929c1973c5e413b59fa4cfd..b7c87f54e2b3c51f2099b3cd76be651df55f1745 100644 (file)
@@ -1,6 +1,6 @@
 {include file='header' __disableAds=true}
 
-{if $__wcf->user->userID && $__wcf->user->activationCode}<p class="info" role="status">{lang}wcf.user.registerActivation.info{/lang}</p>{/if}
+{if $__wcf->user->userID && !$__wcf->user->isEmailConfirmed()}<p class="info" role="status">{lang}wcf.user.registerActivation.info{/lang}</p>{/if}
 
 {include file='formError'}
 
@@ -21,7 +21,7 @@
                <dl{if $errorField == 'activationCode'} class="formError"{/if}>
                        <dt><label for="activationCode">{lang}wcf.user.activationCode{/lang}</label></dt>
                        <dd>
-                               <input type="text" id="activationCode" maxlength="9" name="activationCode" value="{@$activationCode}" required class="medium">
+                               <input type="text" id="activationCode" maxlength="40" name="activationCode" value="{@$activationCode}" required class="medium">
                                {if $errorField == 'activationCode'}
                                        <small class="innerError">
                                                {if $errorType == 'invalid'}{lang}wcf.user.activationCode.error.invalid{/lang}{/if}
index 18a6e86269b90f4d44cff7cefb2585a31054a310..d248dab4116383b487b73eb415a8a3034343a67c 100644 (file)
@@ -1,13 +1,13 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                Language.addObject({
-                       'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                       'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                       'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                       'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                       'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                       'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                       'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                       'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                       'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                       'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                       'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                       'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                       'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                       'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                });
                
                new UiItemListFilter('{@$pageCheckboxListContainerID}');
index 73cfcb75a4c99a178dc776a60ae82864cb2fb2bd..e58afa75c498ebfdfd0afd6713c7bde02983b128 100644 (file)
@@ -8,7 +8,7 @@
                                        {if $_messageCustomIcon === ''}
                                                {if $message->getUserProfile()}
                                                        {if $message->getUserProfile()->userID}
-                                                               <a href="{link controller='User' object=$message->getUserProfile()}{/link}" title="{$message->getUserProfile()->username}" aria-hidden="true">{@$message->getUserProfile()->getAvatar()->getImageTag(48)}</a>
+                                                               {user object=$message->getUserProfile() type='avatar48' title=$message->getUserProfile()->username ariaHidden='true'}
                                                        {else}
                                                                <p>{@$message->getUserProfile()->getAvatar()->getImageTag(48)}</p>
                                                        {/if}
                                                        {if $message->getUserProfile() || $message->getTime() || $message->getContainerTitle()}
                                                                <ul class="inlineList dotSeparated">
                                                                        {if $message->getUserProfile()}
-                                                                               <li>{if $message->getUserProfile()->userID}<a href="{link controller='User' object=$message->getUserProfile()}{/link}" class="userLink" data-user-id="{@$message->getUserProfile()->userID}">{$message->getUserProfile()->username}</a>{else}{$message->getUserProfile()->username}{/if}</li>
+                                                                               <li>
+                                                                                       {if $message->getUserProfile()->userID}
+                                                                                               {user object=$message->getUserProfile()}
+                                                                                       {else}
+                                                                                               {$message->getUserProfile()->username}
+                                                                                       {/if}
+                                                                               </li>
                                                                        {/if}
                                                                        {if $message->getTime()}
                                                                                <li><small>{@$message->getTime()|time}</small></li>
index d8a122335f68a23662dd7434b353578adb0e0dfa..9cac179e73aa04fe28dc61278190aed14fe699ea 100644 (file)
@@ -36,7 +36,7 @@
                                                                        LanguageChooser.init('languageIDContainer', 'languageID', {@$languageID}, $languages);
                                                                        
                                                                        var small = elCreate('small');
-                                                                       small.innerHTML = '{lang}wcf.user.language.description{/lang}';
+                                                                       small.innerHTML = '{jslang}wcf.user.language.description{/jslang}';
                                                                        elById('languageIDContainer').appendChild(small);
                                                                });
                                                        });
index 2049c5bff9da67af4516685ebe19183f0efbf9f7..45065e2eb8efeb66545f1397445d462cc8908943 100644 (file)
@@ -69,7 +69,7 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.global.preview': '{lang}wcf.global.preview{/lang}'
+                       'wcf.global.preview': '{jslang}wcf.global.preview{/jslang}'
                });
                
                new WCF.User.SignaturePreview('wcf\\data\\user\\UserProfileAction', 'text', 'previewButton');
index aef1d4232de47fcf67367a8a5f3705523f77ed33..6dfa845694747c583e5534dab00b92f0b103c8ca 100644 (file)
@@ -10,8 +10,8 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Bbcode/Spoiler'], function (Language, BbcodeSpoiler) {
                Language.addObject({
-                       'wcf.bbcode.spoiler.hide' : '{lang}wcf.bbcode.spoiler.hide{/lang}',
-                       'wcf.bbcode.spoiler.show' : '{lang}wcf.bbcode.spoiler.show{/lang}'
+                       'wcf.bbcode.spoiler.hide' : '{jslang}wcf.bbcode.spoiler.hide{/jslang}',
+                       'wcf.bbcode.spoiler.show' : '{jslang}wcf.bbcode.spoiler.show{/jslang}'
                });
                
                BbcodeSpoiler.observe();
index c2e67bb4b4de9af1a1186a41703ed7d429fcae87..3c5059507ac10c778b7ce96890db5087fdadfa53 100644 (file)
@@ -17,7 +17,7 @@
                                                className: 'wcf\\data\\tag\\TagAction'
                                        },
                                        maxLength: {@TAGGING_MAX_TAG_LENGTH},
-                                       submitFieldName: 'tags[]'
+                                       submitFieldName: '{if $tagSubmitFieldName|isset}{@$tagSubmitFieldName}{else}tags[]{/if}'
                                }
                        );
                });
index 131d78c42071b2cb1a47e80ab73c5950fe51d333..989e846cd4d6a7aed5c06d6e130018ab1d0aff3a 100644 (file)
@@ -12,7 +12,7 @@
        <link rel="canonical" href="{link controller='Tagged' object=$tag}objectType={@$objectType}{if $pageNo > 1}&pageNo={@$pageNo}{/if}{/link}">
 {/capture}
 
-{capture assign='sidebarLeft'}
+{capture assign='sidebarRight'}
        <section class="box" data-static-box-identifier="com.woltlab.wcf.TaggedMenu">
                <h2 class="boxTitle">{lang}wcf.tagging.objectTypes{/lang}</h2>
                
index 5be88c3716823a78a486a85a3d4944524e16cdb3..e8b47c96de10cf17f98eb9b2c6bc866291606a51 100644 (file)
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                       'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                       'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                       'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                       'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                       'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                       'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                });
                
                new WCF.User.Action.Follow($('.userList > li'));
index 621d4dfb451fbdaee11cc7c571c1b4286b98f86a..460b73e33012382f6b72ecb67b02a765c8bfba0d 100644 (file)
 {/hascontent}
 
 {if $objects|count}
-       <ol class="section containerList trophyCategoryList tripleColumned">
-               {foreach from=$objects item=userTrophy}
-                       <li class="box64">
-                               <div>{@$userTrophy->getUserProfile()->getAvatar()->getImageTag(64)}</div>
-
-                               <div class="sidebarItemTitle">
-                                       <h3>{@$userTrophy->getUserProfile()->getAnchorTag()}</h3>
-                                       <small>{if !$userTrophy->getDescription()|empty}<span class="separatorRight">{@$userTrophy->getDescription()}</span> {/if}{@$userTrophy->time|time}</small>
-                               </div>
-                       </li>
-               {/foreach}
-       </ol>
+       <div class="section sectionContainerList">
+               <ol class="containerList trophyCategoryList doubleColumned">
+                       {foreach from=$objects item=userTrophy}
+                               <li class="box64">
+                                       <div>{@$userTrophy->getUserProfile()->getAvatar()->getImageTag(64)}</div>
+       
+                                       <div class="containerHeadline">
+                                               <h3>{user object=$userTrophy->getUserProfile()}</h3>
+                                               <small>{if !$userTrophy->getDescription()|empty}<span class="separatorRight">{@$userTrophy->getDescription()}</span> {/if}{@$userTrophy->time|time}</small>
+                                       </div>
+                               </li>
+                       {/foreach}
+               </ol>
+       </div>
 {else}
        <p class="info" role="status">{lang}wcf.global.noItems{/lang}</p>
 {/if}
@@ -71,4 +73,4 @@
        {/hascontent}
 </footer>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 811a2b800918de93ecbb20c2cae1a5def60657e6..f88727cb2c576a9d8ddf877d65aff8a7b614bc28 100644 (file)
        </div>
 {/hascontent}
 
-<div class="section">
-       <div{if $categories|count > 1} class="tabMenuContent"{/if}>
-               {if $objects|count}
-                       <ol class="section containerList trophyCategoryList tripleColumned">
-                               {foreach from=$objects item=trophy}
-                                       <li class="box64">
-                                               <div>{@$trophy->renderTrophy(64)}</div>
-
-                                               <div class="sidebarItemTitle">
-                                                       <h3><a href="{$trophy->getLink()}">{@$trophy->getTitle()}</a></h3>
-                                                       {if !$trophy->getDescription()|empty}<small>{@$trophy->getDescription()}</small>{/if}
-                                               </div>
-                                       </li>
-                               {/foreach}
-                       </ol>
-               {else}
-                       <p class="info" role="status">{lang}wcf.global.noItems{/lang}</p>
-               {/if}
+{if $objects|count}
+       <div class="section sectionContainerList">
+               <ol class="containerList trophyCategoryList doubleColumned">
+                       {foreach from=$objects item=trophy}
+                               <li class="box64">
+                                       <div>{@$trophy->renderTrophy(64)}</div>
+                                       
+                                       <div class="containerHeadline">
+                                               <h3><a href="{$trophy->getLink()}">{@$trophy->getTitle()}</a></h3>
+                                               {if !$trophy->getDescription()|empty}<p><small>{@$trophy->getDescription()}</small></p>{/if}
+                                               <p><small>{lang items=$trophy->awarded}wcf.user.trophy.trophyAwarded{/lang}</small></p>
+                                       </div>
+                               </li>
+                       {/foreach}
+               </ol>
        </div>
-</div>
+{else}
+       <p class="info" role="status">{lang}wcf.global.noItems{/lang}</p>
+{/if}
 
 <footer class="contentFooter">
        {hascontent}
@@ -62,4 +61,4 @@
        {/hascontent}
 </footer>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index e0851c72b129faf3d2898f2ab09a7cb6e18b3b5c..26f5e56607d2c6b066ee0707b9deed4dae69ea86 100644 (file)
                                
                                <div class="boxContent">
                                        <dl>
-                                               {foreach from=$labelGroups item=labelGroup}
-                                                       {if $labelGroup|count}
-                                                               <dt><label>{$labelGroup->getTitle()}</label></dt>
-                                                               <dd>
-                                                                       <ul class="labelList jsOnly">
-                                                                               <li class="dropdown labelChooser" id="labelGroup{@$labelGroup->groupID}" data-group-id="{@$labelGroup->groupID}">
-                                                                                       <div class="dropdownToggle" data-toggle="labelGroup{@$labelGroup->groupID}"><span class="badge label">{lang}wcf.label.none{/lang}</span></div>
-                                                                                       <div class="dropdownMenu">
-                                                                                               <ul class="scrollableDropdownMenu">
-                                                                                                       {foreach from=$labelGroup item=label}
-                                                                                                               <li data-label-id="{@$label->labelID}"><span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span></li>
-                                                                                                       {/foreach}
-                                                                                               </ul>
-                                                                                       </div>
-                                                                               </li>
-                                                                       </ul>
-                                                                       <noscript>
-                                                                               {foreach from=$labelGroups item=labelGroup}
-                                                                                       <select name="labelIDs[{@$labelGroup->groupID}]">
-                                                                                               <option value="0">{lang}wcf.label.none{/lang}</option>
-                                                                                               <option value="-1">{lang}wcf.label.withoutSelection{/lang}</option>
-                                                                                               {foreach from=$labelGroup item=label}
-                                                                                                       <option value="{@$label->labelID}"{if $labelIDs[$labelGroup->groupID]|isset && $labelIDs[$labelGroup->groupID] == $label->labelID} selected{/if}>{$label->getTitle()}</option>
-                                                                                               {/foreach}
-                                                                                       </select>
-                                                                               {/foreach}
-                                                                       </noscript>
-                                                               </dd>
-                                                       {/if}
-                                               {/foreach}
+                                               {include file='__labelSelection'}
                                        </dl>
                                        <div class="formSubmit">
                                                <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
@@ -64,8 +35,8 @@
                <script data-relocate="true">
                        $(function() {
                                WCF.Language.addObject({
-                                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
-                                       'wcf.label.withoutSelection': '{lang}wcf.label.withoutSelection{/lang}'
+                                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
+                                       'wcf.label.withoutSelection': '{jslang}wcf.label.withoutSelection{/jslang}'
                                });
                                
                                new WCF.Label.Chooser({ {implode from=$labelIDs key=groupID item=labelID}{@$groupID}: {@$labelID}{/implode} }, '#sidebarForm', undefined, true);
index 7c8d41f40e685fe1b25e76962f6f25ad5785231e..c2ec24b9bf8c77b84499dddcdba1ccbcdca6fe5f 100644 (file)
 <script data-relocate="true">
        require(['WoltLabSuite/Core/Ui/File/Upload', 'Language'], function(Upload, Language) {
                Language.addObject({
-                       'wcf.upload.error.reachedRemainingLimit': '{lang __literal=true}wcf.upload.error.reachedRemainingLimit{/lang}',
-                       'wcf.upload.error.noImage': '{lang}wcf.upload.error.noImage{/lang}',
-                       'wcf.upload.error.uploadFailed': '{lang}wcf.upload.error.uploadFailed{/lang}',
+                       'wcf.upload.error.reachedRemainingLimit': '{jslang __literal=true}wcf.upload.error.reachedRemainingLimit{/jslang}',
+                       'wcf.upload.error.noImage': '{jslang}wcf.upload.error.noImage{/jslang}',
+                       'wcf.upload.error.uploadFailed': '{jslang}wcf.upload.error.uploadFailed{/jslang}',
                });
                
                new Upload("{$uploadFieldId}UploadButtonDiv", "{$uploadFieldId}uploadFileList", {
                        internalId: '{$uploadField->getInternalId()}',
                        {if $uploadField->getMaxFiles()}maxFiles: {$uploadField->getMaxFiles()},{/if}
-                       imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if}
+                       imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if},
+                       {if $uploadField->getAcceptableFiles()}
+                               acceptableFiles: [
+                                       {implode from=$uploadField->getAcceptableFiles() item=accept}'{$accept|encodeJS}'{/implode}
+                               ],
+                       {/if}
                });
        });
 </script>
index b69b4fad726dc10572cdd76b402b3405c8e82f08..e1a24d9ada74e23c65c53a1de47234f0d5037485 100644 (file)
@@ -6,39 +6,39 @@
                {if $__wcf->getUser()->userID && $__wcf->getUser()->userID != $user->userID}
                        require(['Language', 'WoltLabSuite/Core/Ui/User/Editor', 'WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Ignore', 'WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Follow'], function(Language, UiUserEditor, UiUserProfileMenuItemIgnore, UiUserProfileMenuItemFollow) {
                                Language.addObject({
-                                       'wcf.acp.user.disable': '{lang}wcf.acp.user.disable{/lang}',
-                                       'wcf.acp.user.enable': '{lang}wcf.acp.user.enable{/lang}',
-                                       'wcf.user.ban': '{lang}wcf.user.ban{/lang}',
-                                       'wcf.user.banned': '{"wcf.user.banned"|language|encodeJS}',
-                                       'wcf.user.ban.confirmMessage': '{lang}wcf.user.ban.confirmMessage{/lang}',
-                                       'wcf.user.ban.expires': '{lang}wcf.user.ban.expires{/lang}',
-                                       'wcf.user.ban.expires.description': '{lang}wcf.user.ban.expires.description{/lang}',
-                                       'wcf.user.ban.neverExpires': '{lang}wcf.user.ban.neverExpires{/lang}',
-                                       'wcf.user.ban.reason.description': '{lang}wcf.user.ban.reason.description{/lang}',
-                                       'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                                       'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                                       'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}',
-                                       'wcf.user.disableAvatar': '{lang}wcf.user.disableAvatar{/lang}',
-                                       'wcf.user.disableAvatar.confirmMessage': '{lang}wcf.user.disableAvatar.confirmMessage{/lang}',
-                                       'wcf.user.disableAvatar.expires': '{lang}wcf.user.disableAvatar.expires{/lang}',
-                                       'wcf.user.disableAvatar.expires.description': '{lang}wcf.user.disableAvatar.expires.description{/lang}',
-                                       'wcf.user.disableAvatar.neverExpires': '{lang}wcf.user.disableAvatar.neverExpires{/lang}',
-                                       'wcf.user.disableCoverPhoto': '{lang}wcf.user.disableCoverPhoto{/lang}',
-                                       'wcf.user.disableCoverPhoto.confirmMessage': '{lang}wcf.user.disableCoverPhoto.confirmMessage{/lang}',
-                                       'wcf.user.disableCoverPhoto.expires': '{lang}wcf.user.disableCoverPhoto.expires{/lang}',
-                                       'wcf.user.disableCoverPhoto.expires.description': '{lang}wcf.user.disableCoverPhoto.expires.description{/lang}',
-                                       'wcf.user.disableCoverPhoto.neverExpires': '{lang}wcf.user.disableCoverPhoto.neverExpires{/lang}',
-                                       'wcf.user.disableSignature': '{lang}wcf.user.disableSignature{/lang}',
-                                       'wcf.user.disableSignature.confirmMessage': '{lang}wcf.user.disableSignature.confirmMessage{/lang}',
-                                       'wcf.user.disableSignature.expires': '{lang}wcf.user.disableSignature.expires{/lang}',
-                                       'wcf.user.disableSignature.expires.description': '{lang}wcf.user.disableSignature.expires.description{/lang}',
-                                       'wcf.user.disableSignature.neverExpires': '{lang}wcf.user.disableSignature.neverExpires{/lang}',
-                                       'wcf.user.edit': '{lang}wcf.user.edit{/lang}',
-                                       'wcf.user.enableAvatar': '{lang}wcf.user.enableAvatar{/lang}',
-                                       'wcf.user.enableCoverPhoto': '{lang}wcf.user.enableCoverPhoto{/lang}',
-                                       'wcf.user.enableSignature': '{lang}wcf.user.enableSignature{/lang}',
-                                       'wcf.user.unban': '{lang}wcf.user.unban{/lang}'
+                                       'wcf.acp.user.disable': '{jslang}wcf.acp.user.disable{/jslang}',
+                                       'wcf.acp.user.enable': '{jslang}wcf.acp.user.enable{/jslang}',
+                                       'wcf.user.ban': '{jslang}wcf.user.ban{/jslang}',
+                                       'wcf.user.banned': '{jslang}wcf.user.banned{/jslang}',
+                                       'wcf.user.ban.confirmMessage': '{jslang}wcf.user.ban.confirmMessage{/jslang}',
+                                       'wcf.user.ban.expires': '{jslang}wcf.user.ban.expires{/jslang}',
+                                       'wcf.user.ban.expires.description': '{jslang}wcf.user.ban.expires.description{/jslang}',
+                                       'wcf.user.ban.neverExpires': '{jslang}wcf.user.ban.neverExpires{/jslang}',
+                                       'wcf.user.ban.reason.description': '{jslang}wcf.user.ban.reason.description{/jslang}',
+                                       'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                                       'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                                       'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                                       'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}',
+                                       'wcf.user.disableAvatar': '{jslang}wcf.user.disableAvatar{/jslang}',
+                                       'wcf.user.disableAvatar.confirmMessage': '{jslang}wcf.user.disableAvatar.confirmMessage{/jslang}',
+                                       'wcf.user.disableAvatar.expires': '{jslang}wcf.user.disableAvatar.expires{/jslang}',
+                                       'wcf.user.disableAvatar.expires.description': '{jslang}wcf.user.disableAvatar.expires.description{/jslang}',
+                                       'wcf.user.disableAvatar.neverExpires': '{jslang}wcf.user.disableAvatar.neverExpires{/jslang}',
+                                       'wcf.user.disableCoverPhoto': '{jslang}wcf.user.disableCoverPhoto{/jslang}',
+                                       'wcf.user.disableCoverPhoto.confirmMessage': '{jslang}wcf.user.disableCoverPhoto.confirmMessage{/jslang}',
+                                       'wcf.user.disableCoverPhoto.expires': '{jslang}wcf.user.disableCoverPhoto.expires{/jslang}',
+                                       'wcf.user.disableCoverPhoto.expires.description': '{jslang}wcf.user.disableCoverPhoto.expires.description{/jslang}',
+                                       'wcf.user.disableCoverPhoto.neverExpires': '{jslang}wcf.user.disableCoverPhoto.neverExpires{/jslang}',
+                                       'wcf.user.disableSignature': '{jslang}wcf.user.disableSignature{/jslang}',
+                                       'wcf.user.disableSignature.confirmMessage': '{jslang}wcf.user.disableSignature.confirmMessage{/jslang}',
+                                       'wcf.user.disableSignature.expires': '{jslang}wcf.user.disableSignature.expires{/jslang}',
+                                       'wcf.user.disableSignature.expires.description': '{jslang}wcf.user.disableSignature.expires.description{/jslang}',
+                                       'wcf.user.disableSignature.neverExpires': '{jslang}wcf.user.disableSignature.neverExpires{/jslang}',
+                                       'wcf.user.edit': '{jslang}wcf.user.edit{/jslang}',
+                                       'wcf.user.enableAvatar': '{jslang}wcf.user.enableAvatar{/jslang}',
+                                       'wcf.user.enableCoverPhoto': '{jslang}wcf.user.enableCoverPhoto{/jslang}',
+                                       'wcf.user.enableSignature': '{jslang}wcf.user.enableSignature{/jslang}',
+                                       'wcf.user.unban': '{jslang}wcf.user.unban{/jslang}'
                                });
                                
                                {if $isAccessible}
@@ -58,7 +58,7 @@
                $(function() {
                        {if $__wcf->getUser()->userID && $__wcf->getUser()->userID != $user->userID}
                                WCF.Language.addObject({
-                                       'wcf.user.activityPoint': '{lang}wcf.user.activityPoint{/lang}'
+                                       'wcf.user.activityPoint': '{jslang}wcf.user.activityPoint{/jslang}'
                                });
                        {/if}
                        
@@ -66,7 +66,7 @@
                        
                        {if $user->canEdit() || ($__wcf->getUser()->userID == $user->userID && $user->canEditOwnProfile())}
                                WCF.Language.addObject({
-                                       'wcf.user.editProfile': '{lang}wcf.user.editProfile{/lang}'
+                                       'wcf.user.editProfile': '{jslang}wcf.user.editProfile{/jslang}'
                                });
                                
                                var userProfileEditor = new WCF.User.Profile.Editor({@$user->userID}, {if $editOnInit}true{else}false{/if});
                        
                        {if $__wcf->session->getPermission('user.profile.canReportContent')}
                                WCF.Language.addObject({
-                                       'wcf.moderation.report.reportContent': '{lang}wcf.user.profile.report{/lang}',
-                                       'wcf.moderation.report.success': '{lang}wcf.moderation.report.success{/lang}'
+                                       'wcf.moderation.report.reportContent': '{jslang}wcf.user.profile.report{/jslang}',
+                                       'wcf.moderation.report.success': '{jslang}wcf.moderation.report.success{/jslang}'
                                });
                                new WCF.Moderation.Report.Content('com.woltlab.wcf.user', '.jsReportUser');
                        {/if}
                        </h1>
                        
                        <div class="contentHeaderDescription">
-                               {if MODULE_TROPHY && $__wcf->session->getPermission('user.profile.trophy.canSeeTrophies') && ($user->isAccessible('canViewTrophies') || $user->userID == $__wcf->session->userID) && $user->getSpecialTrophies()|count}
+                               {if MODULE_TROPHY && $__wcf->session->getPermission('user.profile.trophy.canSeeTrophies') && ($user->isAccessible('canViewTrophies') || $user->userID == $__wcf->session->userID) && $specialTrophyCount}
                                        <div class="specialTrophyUserContainer">
                                                <ul>
                                                        {foreach from=$user->getSpecialTrophies() item=trophy}
                                                                <li><a href="{@$trophy->getLink()}">{@$trophy->renderTrophy(32, true)}</a></li>
                                                        {/foreach}
+                                                       {if $user->trophyPoints > $specialTrophyCount}
+                                                               <li><a href="#" class="jsTooltip userTrophyOverlayList" data-user-id="{$user->userID}" title="{lang}wcf.user.trophy.showTrophies{/lang}" role="button">{lang trophyCount=$user->trophyPoints-$specialTrophyCount}wcf.user.trophy.showMoreTrophies{/lang}</a></li>
+                                                       {/if}
                                                </ul>
                                        </div>
                                {/if}
                                                                {if $user->userID != $__wcf->user->userID}
                                                                        {if $user->isAccessible('canViewEmailAddress') || $__wcf->session->getPermission('admin.user.canEditMailAddress')}
                                                                                <li><a href="mailto:{@$user->getEncodedEmail()}">{lang}wcf.user.button.mail{/lang}</a></li>
-                                                                       {elseif $user->isAccessible('canMail') && $__wcf->session->getPermission('user.profile.canMail')}
-                                                                               <li><a href="{link controller='Mail' object=$user}{/link}">{lang}wcf.user.button.mail{/lang}</a></li>
                                                                        {/if}
                                                                {/if}
                                                                
                                                                        {if $__wcf->session->getPermission('admin.user.canDisableAvatar')}<li><a href="#" class="jsButtonUserDisableAvatar">{lang}wcf.user.{if $user->disableAvatar}enable{else}disable{/if}Avatar{/lang}</a></li>{/if}
                                                                        {if $__wcf->session->getPermission('admin.user.canDisableSignature')}<li><a href="#" class="jsButtonUserDisableSignature">{lang}wcf.user.{if $user->disableSignature}enable{else}disable{/if}Signature{/lang}</a></li>{/if}
                                                                        {if MODULE_USER_COVER_PHOTO && $__wcf->session->getPermission('admin.user.canDisableCoverPhoto')}<li><a href="#" class="jsButtonUserDisableCoverPhoto">{lang}wcf.user.{if $user->disableCoverPhoto}enable{else}disable{/if}CoverPhoto{/lang}</a></li>{/if}
-                                                                       {if $__wcf->session->getPermission('admin.user.canEnableUser')}<li><a href="#" class="jsButtonUserEnable">{lang}wcf.acp.user.{if $user->activationCode}enable{else}disable{/if}{/lang}</a></li>{/if}
+                                                                       {if $__wcf->session->getPermission('admin.user.canEnableUser')}<li><a href="#" class="jsButtonUserEnable">{lang}wcf.acp.user.{if $user->pendingActivation()}enable{else}disable{/if}{/lang}</a></li>{/if}
                                                                        
                                                                        {if $__wcf->session->getPermission('admin.general.canUseAcp') && $__wcf->session->getPermission('admin.user.canEditUser')}<li><a href="{link controller='UserEdit' object=$user isACP=true}{/link}" class="jsUserInlineEditor">{lang}wcf.user.edit{/lang}</a></li>{/if}
                                                                {/if}
                <script data-relocate="true">
                        require(['Language', 'WoltLabSuite/Core/Ui/User/CoverPhoto/Upload'], function (Language, UiUserCoverPhotoUpload) {
                                Language.addObject({
-                                       'wcf.user.coverPhoto.delete.confirmMessage': '{lang}wcf.user.coverPhoto.delete.confirmMessage{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.fileExtension': '{lang}wcf.user.coverPhoto.upload.error.fileExtension{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.tooLarge': '{lang}wcf.user.coverPhoto.upload.error.tooLarge{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.uploadFailed': '{lang}wcf.user.coverPhoto.upload.error.uploadFailed{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.badImage': '{lang}wcf.user.coverPhoto.upload.error.badImage{/lang}'
+                                       'wcf.user.coverPhoto.delete.confirmMessage': '{jslang}wcf.user.coverPhoto.delete.confirmMessage{/jslang}',
+                                       'wcf.user.coverPhoto.upload.error.fileExtension': '{jslang}wcf.user.coverPhoto.upload.error.fileExtension{/jslang}',
+                                       'wcf.user.coverPhoto.upload.error.tooLarge': '{jslang}wcf.user.coverPhoto.upload.error.tooLarge{/jslang}',
+                                       'wcf.user.coverPhoto.upload.error.uploadFailed': '{jslang}wcf.user.coverPhoto.upload.error.uploadFailed{/jslang}',
+                                       'wcf.user.coverPhoto.upload.error.badImage': '{jslang}wcf.user.coverPhoto.upload.error.badImage{/jslang}'
                                });
                                
                                {if !$__wcf->user->disableCoverPhoto}
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Ui/User/CoverPhoto/Delete'], function (Language, UiUserCoverPhotoDelete) {
                        Language.addObject({
-                               'wcf.user.coverPhoto.delete.confirmMessage': '{lang}wcf.user.coverPhoto.delete.confirmMessage{/lang}'
+                               'wcf.user.coverPhoto.delete.confirmMessage': '{jslang}wcf.user.coverPhoto.delete.confirmMessage{/jslang}'
                        });
                        
                        UiUserCoverPhotoDelete.init({@$user->userID});
index c0af1b6fccb33938ebd456f741387623237f77ab..2ad11bec3574eb9af4de46e64fe772ee9a06edb5 100644 (file)
@@ -4,11 +4,11 @@
                        {foreach from=$users item=user}
                                <li data-object-id="{@$user->userID}">
                                        <div class="box48">
-                                               <a href="{link controller='User' object=$user}{/link}" title="{$user->username}" aria-hidden="true">{@$user->getAvatar()->getImageTag(48)}</a>
+                                               {user object=$user type='avatar48' title=$user->username ariaHidden='true'}
                                                
                                                <div class="details userInformation">
                                                        <div class="containerHeadline">
-                                                               <h3><a href="{link controller='User' object=$user}{/link}">{$user->username}</a>{if MODULE_USER_RANK}
+                                                               <h3>{user object=$user}{if MODULE_USER_RANK}
                                                                        {if $user->getUserTitle()}
                                                                                <span class="badge userTitleBadge{if $user->getRank() && $user->getRank()->cssClassName} {@$user->getRank()->cssClassName}{/if}">{$user->getUserTitle()}</span>
                                                                        {/if}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                       'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                       'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                       'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                       'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                       'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                       'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                });
                
                new WCF.User.Action.Follow($('.jsGroupedUserList > li'));
index 4dcaedff48469f5d6368d0d15a629491c3fa0fb3..2382c4d7b394407cd31f0224cd5a4d43954d12af 100644 (file)
        Stacktrace:
        {$stacktrace}
        -->
+       <script>
+               console.debug('{$name|encodeJS} thrown in {$file|encodeJS} ({@$line})');
+               console.debug('Stacktrace:\n{@$stacktrace|encodeJS}');
+       </script>
 {/if}
 
 {include file='footer' __disableAds=true}
index baa38d23fb69a2c6c15080fce826c8b33d644ce6..066564ce60602b13852914283dd8e130ce97a58f 100644 (file)
@@ -3,14 +3,12 @@
                <ul class="buttonList iconList">
                        {content}
                                {if $user->homepage && $user->homepage != 'http://'}
-                                       <li><a class="jsTooltip" href="{$user->homepage}" title="{lang}wcf.user.option.homepage{/lang}"{if EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK} rel="{if EXTERNAL_LINK_REL_NOFOLLOW}nofollow{/if}{if EXTERNAL_LINK_TARGET_BLANK}{if EXTERNAL_LINK_REL_NOFOLLOW} {/if}noopener noreferrer{/if}"{/if}{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}><span class="icon icon16 fa-home"></span> <span class="invisible">{lang}wcf.user.option.homepage{/lang}</span></a></li>
+                                       <li><a class="jsTooltip" title="{lang}wcf.user.option.homepage{/lang}" {anchorAttributes url=$user->homepage appendClassname=false isUgc=true}><span class="icon icon16 fa-home"></span> <span class="invisible">{lang}wcf.user.option.homepage{/lang}</span></a></li>
                                {/if}
                                
                                {if $user->userID != $__wcf->user->userID}
                                        {if $user->isAccessible('canViewEmailAddress')}
                                                <li><a class="jsTooltip" href="mailto:{@$user->getEncodedEmail()}" title="{lang}wcf.user.button.mail{/lang}"><span class="icon icon16 fa-envelope-o"></span> <span class="invisible">{lang}wcf.user.button.mail{/lang}</span></a></li>
-                                       {elseif $user->isAccessible('canMail') && $__wcf->session->getPermission('user.profile.canMail')}
-                                               <li><a class="jsTooltip" href="{link controller='Mail' object=$user}{/link}" title="{lang}wcf.user.button.mail{/lang}"><span class="icon icon16 fa-envelope-o"></span> <span class="invisible">{lang}wcf.user.button.mail{/lang}</span></a></li>
                                        {/if}
                                {/if}
                                
index b353ee698c170e8e176629cfbab0f19458310a86..bf8832024a61c623c2bc21fbbe664ca20f79aac2 100644 (file)
@@ -1,5 +1,5 @@
 <div class="containerHeadline">
-       <h3><a href="{link controller='User' object=$user}{/link}" class="username userLink" data-user-id="{@$user->userID}">{$user->username}</a>{if $user->banned} <span class="icon icon16 fa-lock jsTooltip jsUserBanned" title="{lang}wcf.user.banned{/lang}"></span>{/if}
+       <h3>{user object=$user class='username'}{if $user->banned} <span class="icon icon16 fa-lock jsTooltip jsUserBanned" title="{lang}wcf.user.banned{/lang}"></span>{/if}
                {if MODULE_USER_RANK}
                        {if $user->getUserTitle()}
                                <span class="badge userTitleBadge{if $user->getRank() && $user->getRank()->cssClassName} {@$user->getRank()->cssClassName}{/if}">{$user->getUserTitle()}</span>
index 77290840fb6be0fe38a0801aa8442bd527fa4ead..2a5799ba51415c2bd37e7d86292d83e159fb9092 100644 (file)
@@ -3,7 +3,7 @@
 {event name='statistics'}
 
 {if MODULE_LIKE && $user->likesReceived}
-       <dt>{if $__wcf->getSession()->getPermission('user.profile.canViewUserProfile') && !$user->isProtected()}<a href="{link controller='User' object=$user}{/link}#likes" class="jsTooltip" title="{lang}wcf.like.showLikesReceived{/lang}">{lang}wcf.like.reactionsReceived{/lang}</a>{else}{lang}wcf.like.reactionsReceived{/lang}{/if}</dt>
+       <dt>{if $__wcf->getSession()->getPermission('user.profile.canViewUserProfile') && !$user->isProtected()}<a href="{$user->getLink()}#likes" class="jsTooltip" title="{lang}wcf.like.showLikesReceived{/lang}">{lang}wcf.like.reactionsReceived{/lang}</a>{else}{lang}wcf.like.reactionsReceived{/lang}{/if}</dt>
        <dd>{#$user->likesReceived}</dd>
 {/if}
 
index 8f42dd8d6be7752bcb7c8c0b8ac04502b9aa7b07..7ff5925921e3cff1de50cf8e54e9635751a30fd2 100644 (file)
@@ -1,9 +1,9 @@
 <li data-object-id="{@$user->userID}">
        <div class="box48">
-               <a href="{link controller='User' object=$user}{/link}" title="{$user->username}" aria-hidden="true">{@$user->getAvatar()->getImageTag(48)}</a>
+               {user object=$user type='avatar48' title=$user->username ariaHidden='true'}
                
                <div class="details userInformation">
                        {include file='userInformation'}
                </div>
        </div>
-</li>
\ No newline at end of file
+</li>
index a94cd4e9bc702defc42aa9b6c6f4d6f56665ab13..7c7f50640f01623d07923dfa3116380a2c009986 100644 (file)
@@ -1,15 +1,6 @@
 {capture assign='sidebarLeft'}
        {assign var=__userMenuActiveItems value=$__wcf->getUserMenu()->getActiveMenuItems()}
        
-       <script data-relocate="true">
-               $(function() {
-                       // mobile safari hover workaround
-                       if ($(window).width() <= 800) {
-                               $('.sidebar').addClass('mobileSidebar').hover(function() { });
-                       }
-               });
-       </script>
-       
        <section class="box" data-static-box-identifier="com.woltlab.wcf.UserMenu">
                {foreach from=$__wcf->getUserMenu()->getMenuItems('') item=menuCategory}
                        <h2 class="boxTitle">{$menuCategory->getTitle()}</h2>
index 9ddcdff1e83697d7ca048566a995d5b9f2400b93..a30c4ecd5fe48fce75a4ca3330dad7ff005502c3 100644 (file)
                <p class="info" role="status">{lang}wcf.page.availableUpdates{/lang}</p>
        {/if}
        
-       {if $__wcf->user->activationCode && REGISTER_ACTIVATION_METHOD == 1 && $templateName != 'registerActivation' && $templateName != 'register' && $templateName != 'redirect' && $__wcf->user->getBlacklistMatches()|empty}
-               <p class="warning" role="status">{lang}wcf.user.register.needActivation{/lang}</p>
+       {if $templateName != 'registerActivation' && $templateName != 'register' && $templateName != 'redirect' && $__wcf->user->getBlacklistMatches()|empty}
+               {if $__wcf->user->requiresEmailActivation()}
+                       <p class="warning" role="status">{lang}wcf.user.register.needActivation{/lang}</p>
+               {elseif $__wcf->user->requiresAdminActivation()}
+                       <p class="warning" role="status">{lang}wcf.user.register.needAdminActivation{/lang}</p>
+               {elseif !$__wcf->user->isEmailConfirmed()}
+                       <p class="warning" role="status">{lang}wcf.user.register.needEmailConfirmation{/lang}</p>
+               {/if}
        {/if}
        
        {hascontent}
index 37f666e605db421e92effa151040f0410c6f11af..f283638476cb9821d1786ea2c5a7443d8be48367 100644 (file)
@@ -1,12 +1,12 @@
 {foreach from=$likeList item=like}
        <li>
                <div class="box48">
-                       <a href="{link controller='User' object=$like->getUserProfile()}{/link}" title="{$like->getUserProfile()->username}" aria-hidden="true">{@$like->getUserProfile()->getAvatar()->getImageTag(48)}</a>
+                       {user object=$like->getUserProfile() type='avatar48' title=$like->getUserProfile()->username ariaHidden='true'}
                        
                        <div>
                                <div class="containerHeadline">
                                        <h3>
-                                               <a href="{link controller='User' object=$like->getUserProfile()}{/link}" class="userLink" data-user-id="{@$like->getUserProfile()->userID}">{$like->getUserProfile()->username}</a>
+                                               {user object=$like->getUserProfile()}
                                                <small class="separatorLeft">{@$like->time|time}</small>
                                        </h3>
                                        <div>{@$like->getTitle()}</div>
index 64f0b3c93d50c2aa136fc612adf20cc6c143f35b..079379322797d57f1cbdc8ab01dc0902fcd886c2 100644 (file)
@@ -1,8 +1,8 @@
 <script data-relocate="true">
        require(['WoltLabSuite/Core/Ui/Reaction/Profile/Loader', 'Language'], function(UiReactionProfileLoader, Language) {
                Language.addObject({
-                       'wcf.like.reaction.noMoreEntries': '{lang}wcf.like.reaction.noMoreEntries{/lang}',
-                       'wcf.like.reaction.more': '{lang}wcf.like.reaction.more{/lang}'
+                       'wcf.like.reaction.noMoreEntries': '{jslang}wcf.like.reaction.noMoreEntries{/jslang}',
+                       'wcf.like.reaction.more': '{jslang}wcf.like.reaction.more{/jslang}'
                });
                
                new UiReactionProfileLoader({@$userID});
@@ -26,4 +26,4 @@
        </li>
        
        {include file='userProfileLikeItem'}
-</ul>
\ No newline at end of file
+</ul>
index e5c9e049b7282275944e32fdb4bf7af933ae96c9..217ac915dfe102cf9185440d1cfc5818851e559c 100644 (file)
@@ -2,7 +2,7 @@
        <p>{lang}wcf.user.unknownUser{/lang}</p>
 {else}
        <div class="box128 userProfilePreview">
-               <a href="{link controller='User' object=$user}{/link}" title="{$user->username}" class="userProfilePreviewAvatar">
+               <a href="{$user->getLink()}" title="{$user->username}" class="userProfilePreviewAvatar">
                        {@$user->getAvatar()->getImageTag(128)}
                        
                        {if $user->isOnline()}<span class="badge green badgeOnline">{lang}wcf.user.online{/lang}</span>{/if}
@@ -10,7 +10,7 @@
                
                <div class="userInformation">
                        {include file='userInformation' disableDialogLinks=true}
-
+                       
                        {if MODULE_TROPHY && $__wcf->session->getPermission('user.profile.trophy.canSeeTrophies') && ($user->isAccessible('canViewTrophies') || $user->userID == $__wcf->session->userID) && $user->getSpecialTrophies()|count}
                                <div class="specialTrophyUserContainer">
                                        <ul>
                        <script data-relocate="true">
                                $(function() {
                                        WCF.Language.addObject({
-                                               'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                                               'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                                               'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                                               'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                                               'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                                               'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                                               'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                                               'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                                        });
                                        
                                        new WCF.User.Action.Follow($('.userInformation'));
index 218b0a959680100808c475c3e080f738b03222bf..f49abe2a59a6b010f73887fec98ffd7d2ab04a05 100644 (file)
@@ -6,7 +6,7 @@
                        <div class="boxContent">
                                <ul class="userAvatarList">
                                        {foreach from=$following item=followingUser}
-                                               <li><a href="{link controller='User' object=$followingUser}{/link}" title="{$followingUser->username}" class="jsTooltip">{@$followingUser->getAvatar()->getImageTag(48)}</a></li>
+                                               <li>{user object=$followingUser type='avatar48' title=$followingUser->username class='jsTooltip'}</li>
                                        {/foreach}
                                </ul>
                                
@@ -24,7 +24,7 @@
                        <div class="boxContent">
                                <ul class="userAvatarList">
                                        {foreach from=$followers item=follower}
-                                               <li><a href="{link controller='User' object=$follower}{/link}" title="{$follower->username}" class="jsTooltip">{@$follower->getAvatar()->getImageTag(48)}</a></li>
+                                               <li>{user object=$follower type='avatar48' title=$follower->username class='jsTooltip'}</li>
                                        {/foreach}
                                </ul>
                                        
@@ -42,7 +42,7 @@
                        <div class="boxContent">
                                <ul class="userAvatarList">
                                        {foreach from=$visitors item=visitor}
-                                               <li><a href="{link controller='User' object=$visitor}{/link}" title="{$visitor->username} ({@$visitor->time|plainTime})" class="jsTooltip">{@$visitor->getAvatar()->getImageTag(48)}</a></li>
+                                               <li><a href="{$visitor->getLink()}" title="{$visitor->username} ({@$visitor->time|plainTime})" class="jsTooltip">{@$visitor->getAvatar()->getImageTag(48)}</a></li>
                                        {/foreach}
                                </ul>
                                        
index 1fb2b929ceb0820843f8fc880c236d4bd4d1335a..889dad480bac94e7a66ad8564716e7cf91ab5fc9 100644 (file)
@@ -12,7 +12,7 @@
                        {if $usersOnlineList|count}
                                <ul class="inlineList commaSeparated">
                                        {foreach from=$usersOnlineList->getObjects() item=userOnline}
-                                               <li><a href="{link controller='User' object=$userOnline->getDecoratedObject()}{/link}" class="userLink" data-user-id="{@$userOnline->userID}">{@$userOnline->getFormattedUsername()}</a></li>
+                                               <li>{user object=$userOnline}</li>
                                        {/foreach}
                                </ul>
                        {/if}
index 466594bff0a023917b4727c5f57117f0881a222a..513ef58d08ed28303309df85b8b64a258f47e090 100644 (file)
                {capture append=usersOnlineList}
                        <li>
                                <div class="box48">
-                                       <a href="{link controller='User' object=$user}{/link}" title="{$user->username}" aria-hidden="true">{@$user->getAvatar()->getImageTag(48)}</a>
+                                       {user object=$user type='avatar48' title=$user->username ariaHidden='true'}
                                        
                                        <div class="details userInformation">
                                                <div class="containerHeadline">
-                                                       <h3><a href="{link controller='User' object=$user}{/link}" class="username">{@$user->getFormattedUsername()}</a>
+                                                       <h3>{user object=$user}
                                                                {if MODULE_USER_RANK}
                                                                        {if $user->getUserTitle()}
                                                                                <span class="badge userTitleBadge{if $user->getRank() && $user->getRank()->cssClassName} {@$user->getRank()->cssClassName}{/if}">{$user->getUserTitle()}</span>
                                        
                                        <div class="details userInformation">
                                                <div class="containerHeadline">
-                                                       <h3>{if $user->getSpider()->spiderURL}<a href="{$user->getSpider()->spiderURL}" class="externalURL"{if EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK} rel="{if EXTERNAL_LINK_REL_NOFOLLOW}nofollow{/if}{if EXTERNAL_LINK_TARGET_BLANK}{if EXTERNAL_LINK_REL_NOFOLLOW} {/if}noopener noreferrer{/if}"{/if}{if EXTERNAL_LINK_TARGET_BLANK} target="_blank"{/if}>{$user->getSpider()->spiderName}</a>{else}{$user->getSpider()->spiderName}{/if}</h3>
+                                                       <h3>{if $user->getSpider()->spiderURL}<a {anchorAttributes url=$user->getSpider()->spiderURL}>{$user->getSpider()->spiderName}</a>{else}{$user->getSpider()->spiderName}{/if}</h3>
                                                        {@$locationData}
                                                </div>
                                                
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.user.button.follow': '{lang}wcf.user.button.follow{/lang}',
-                       'wcf.user.button.ignore': '{lang}wcf.user.button.ignore{/lang}',
-                       'wcf.user.button.unfollow': '{lang}wcf.user.button.unfollow{/lang}',
-                       'wcf.user.button.unignore': '{lang}wcf.user.button.unignore{/lang}'
+                       'wcf.user.button.follow': '{jslang}wcf.user.button.follow{/jslang}',
+                       'wcf.user.button.ignore': '{jslang}wcf.user.button.ignore{/jslang}',
+                       'wcf.user.button.unfollow': '{jslang}wcf.user.button.unfollow{/jslang}',
+                       'wcf.user.button.unignore': '{jslang}wcf.user.button.unignore{/jslang}'
                });
                
                new WCF.User.Action.Follow($('.userList > li'));
index b3c83701f107d80b0c3c119fa457c5ecea9fa758..3249368cd9ced53d91d3fdced6856e49214111d4 100644 (file)
                                
                                <div class="boxContent">
                                        <dl>
-                                               {foreach from=$labelGroups item=labelGroup}
-                                                       {if $labelGroup|count}
-                                                               <dt><label>{$labelGroup->getTitle()}</label></dt>
-                                                               <dd>
-                                                                       <ul class="labelList jsOnly">
-                                                                               <li class="dropdown labelChooser" id="labelGroup{@$labelGroup->groupID}" data-group-id="{@$labelGroup->groupID}">
-                                                                                       <div class="dropdownToggle" data-toggle="labelGroup{@$labelGroup->groupID}"><span class="badge label">{lang}wcf.label.none{/lang}</span></div>
-                                                                                       <div class="dropdownMenu">
-                                                                                               <ul class="scrollableDropdownMenu">
-                                                                                                       {foreach from=$labelGroup item=label}
-                                                                                                               <li data-label-id="{@$label->labelID}"><span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span></li>
-                                                                                                       {/foreach}
-                                                                                               </ul>
-                                                                                       </div>
-                                                                               </li>
-                                                                       </ul>
-                                                                       <noscript>
-                                                                               {foreach from=$labelGroups item=labelGroup}
-                                                                                       <select name="labelIDs[{@$labelGroup->groupID}]">
-                                                                                               <option value="0">{lang}wcf.label.none{/lang}</option>
-                                                                                               <option value="-1">{lang}wcf.label.withoutSelection{/lang}</option>
-                                                                                               {foreach from=$labelGroup item=label}
-                                                                                                       <option value="{@$label->labelID}"{if $labelIDs[$labelGroup->groupID]|isset && $labelIDs[$labelGroup->groupID] == $label->labelID} selected{/if}>{$label->getTitle()}</option>
-                                                                                               {/foreach}
-                                                                                       </select>
-                                                                               {/foreach}
-                                                                       </noscript>
-                                                               </dd>
-                                                       {/if}
-                                               {/foreach}
+                                               {include file='__labelSelection'}
                                        </dl>
                                        <div class="formSubmit">
                                                <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
@@ -62,8 +33,8 @@
                <script data-relocate="true">
                        $(function() {
                                WCF.Language.addObject({
-                                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
-                                       'wcf.label.withoutSelection': '{lang}wcf.label.withoutSelection{/lang}'
+                                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
+                                       'wcf.label.withoutSelection': '{jslang}wcf.label.withoutSelection{/jslang}'
                                });
                                
                                new WCF.Label.Chooser({ {implode from=$labelIDs key=groupID item=labelID}{@$groupID}: {@$labelID}{/implode} }, '#sidebarForm', undefined, true);
index 9c4b1046495914b6807a38824ebaeb5419ca1af0..17c5ce2844058fd60397c44a86d0ee183795c416 100644 (file)
        ], function () {
                require(['Environment', 'Language', 'WoltLabSuite/Core/Ui/Redactor/Autosave', 'WoltLabSuite/Core/Ui/Redactor/Metacode'], function(Environment, Language, UiRedactorAutosave, UiRedactorMetacode) {
                        Language.addObject({
-                               'wcf.attachment.dragAndDrop.dropHere': '{lang}wcf.attachment.dragAndDrop.dropHere{/lang}',
-                               'wcf.attachment.dragAndDrop.dropNow': '{lang}wcf.attachment.dragAndDrop.dropNow{/lang}',
+                               'wcf.attachment.dragAndDrop.dropHere': '{jslang}wcf.attachment.dragAndDrop.dropHere{/jslang}',
+                               'wcf.attachment.dragAndDrop.dropNow': '{jslang}wcf.attachment.dragAndDrop.dropNow{/jslang}',
                                
-                               'wcf.editor.autosave.discard': '{lang}wcf.editor.autosave.discard{/lang}',
-                               'wcf.editor.autosave.keep': '{lang}wcf.editor.autosave.keep{/lang}',
-                               'wcf.editor.autosave.restored': '{lang}wcf.editor.autosave.restored{/lang}',
+                               'wcf.editor.autosave.discard': '{jslang}wcf.editor.autosave.discard{/jslang}',
+                               'wcf.editor.autosave.keep': '{jslang}wcf.editor.autosave.keep{/jslang}',
+                               'wcf.editor.autosave.restored': '{jslang}wcf.editor.autosave.restored{/jslang}',
                                
-                               'wcf.editor.code.edit': '{lang}wcf.editor.code.edit{/lang}',
-                               'wcf.editor.code.file': '{lang}wcf.editor.code.file{/lang}',
-                               'wcf.editor.code.file.description': '{lang}wcf.editor.code.file.description{/lang}',
-                               'wcf.editor.code.highlighter': '{lang}wcf.editor.code.highlighter{/lang}',
-                               'wcf.editor.code.highlighter.description': '{lang}wcf.editor.code.highlighter.description{/lang}',
-                               'wcf.editor.code.highlighter.detect': '{lang}wcf.editor.code.highlighter.detect{/lang}',
-                               'wcf.editor.code.highlighter.plain': '{lang}wcf.editor.code.highlighter.plain{/lang}',
-                               'wcf.editor.code.line': '{lang}wcf.editor.code.line{/lang}',
-                               'wcf.editor.code.line.description': '{lang}wcf.editor.code.line.description{/lang}',
-                               'wcf.editor.code.title': '{lang __literal=true}wcf.editor.code.title{/lang}',
+                               'wcf.editor.code.edit': '{jslang}wcf.editor.code.edit{/jslang}',
+                               'wcf.editor.code.file': '{jslang}wcf.editor.code.file{/jslang}',
+                               'wcf.editor.code.file.description': '{jslang}wcf.editor.code.file.description{/jslang}',
+                               'wcf.editor.code.highlighter': '{jslang}wcf.editor.code.highlighter{/jslang}',
+                               'wcf.editor.code.highlighter.description': '{jslang}wcf.editor.code.highlighter.description{/jslang}',
+                               'wcf.editor.code.highlighter.detect': '{jslang}wcf.editor.code.highlighter.detect{/jslang}',
+                               'wcf.editor.code.highlighter.plain': '{jslang}wcf.editor.code.highlighter.plain{/jslang}',
+                               'wcf.editor.code.line': '{jslang}wcf.editor.code.line{/jslang}',
+                               'wcf.editor.code.line.description': '{jslang}wcf.editor.code.line.description{/jslang}',
+                               'wcf.editor.code.title': '{jslang __literal=true}wcf.editor.code.title{/jslang}',
                                
-                               'wcf.editor.html.description': '{lang}wcf.editor.html.description{/lang}',
-                               'wcf.editor.html.title': '{lang}wcf.editor.html.title{/lang}',
+                               'wcf.editor.html.description': '{jslang}wcf.editor.html.description{/jslang}',
+                               'wcf.editor.html.title': '{jslang}wcf.editor.html.title{/jslang}',
                                
-                               'wcf.editor.image.edit': '{lang}wcf.editor.image.edit{/lang}',
-                               'wcf.editor.image.insert': '{lang}wcf.editor.image.insert{/lang}',
-                               'wcf.editor.image.link': '{lang}wcf.editor.image.link{/lang}',
-                               'wcf.editor.image.link.error.invalid': '{lang}wcf.editor.image.link.error.invalid{/lang}',
-                               'wcf.editor.image.float': '{lang}wcf.editor.image.float{/lang}',
-                               'wcf.editor.image.float.left': '{lang}wcf.editor.image.float.left{/lang}',
-                               'wcf.editor.image.float.right': '{lang}wcf.editor.image.float.right{/lang}',
-                               'wcf.editor.image.source': '{lang}wcf.editor.image.source{/lang}',
-                               'wcf.editor.image.source.error.blocked': '{lang}wcf.editor.image.source.error.blocked{/lang}',
-                               'wcf.editor.image.source.error.insecure': '{lang}wcf.editor.image.source.error.insecure{/lang}',
-                               'wcf.editor.image.source.error.invalid': '{lang}wcf.editor.image.source.error.invalid{/lang}',
+                               'wcf.editor.image.edit': '{jslang}wcf.editor.image.edit{/jslang}',
+                               'wcf.editor.image.insert': '{jslang}wcf.editor.image.insert{/jslang}',
+                               'wcf.editor.image.link': '{jslang}wcf.editor.image.link{/jslang}',
+                               'wcf.editor.image.link.error.invalid': '{jslang}wcf.editor.image.link.error.invalid{/jslang}',
+                               'wcf.editor.image.float': '{jslang}wcf.editor.image.float{/jslang}',
+                               'wcf.editor.image.float.left': '{jslang}wcf.editor.image.float.left{/jslang}',
+                               'wcf.editor.image.float.right': '{jslang}wcf.editor.image.float.right{/jslang}',
+                               'wcf.editor.image.source': '{jslang}wcf.editor.image.source{/jslang}',
+                               'wcf.editor.image.source.error.blocked': '{jslang}wcf.editor.image.source.error.blocked{/jslang}',
+                               'wcf.editor.image.source.error.insecure': '{jslang}wcf.editor.image.source.error.insecure{/jslang}',
+                               'wcf.editor.image.source.error.invalid': '{jslang}wcf.editor.image.source.error.invalid{/jslang}',
                                
-                               'wcf.editor.link.add': '{lang}wcf.editor.link.add{/lang}',
-                               'wcf.editor.link.edit': '{lang}wcf.editor.link.edit{/lang}',
-                               'wcf.editor.link.error.invalid': '{lang}wcf.editor.link.error.invalid{/lang}',
-                               'wcf.editor.link.url': '{lang}wcf.editor.link.url{/lang}',
-                               'wcf.editor.link.text': '{lang}wcf.editor.link.text{/lang}',
+                               'wcf.editor.link.add': '{jslang}wcf.editor.link.add{/jslang}',
+                               'wcf.editor.link.edit': '{jslang}wcf.editor.link.edit{/jslang}',
+                               'wcf.editor.link.error.invalid': '{jslang}wcf.editor.link.error.invalid{/jslang}',
+                               'wcf.editor.link.url': '{jslang}wcf.editor.link.url{/jslang}',
+                               'wcf.editor.link.text': '{jslang}wcf.editor.link.text{/jslang}',
                                
-                               'wcf.editor.list.indent': '{lang}wcf.editor.list.indent{/lang}',
-                               'wcf.editor.list.outdent': '{lang}wcf.editor.list.outdent{/lang}',
+                               'wcf.editor.list.indent': '{jslang}wcf.editor.list.indent{/jslang}',
+                               'wcf.editor.list.outdent': '{jslang}wcf.editor.list.outdent{/jslang}',
                                
-                               'wcf.editor.quote.author': '{lang}wcf.editor.quote.author{/lang}',
-                               'wcf.editor.quote.edit': '{lang}wcf.editor.quote.edit{/lang}',
-                               'wcf.editor.quote.title': '{lang __literal=true}wcf.editor.quote.title{/lang}',
-                               'wcf.editor.quote.url': '{lang}wcf.editor.quote.url{/lang}',
-                               'wcf.editor.quote.url.description': '{lang}wcf.editor.quote.url.description{/lang}',
-                               'wcf.editor.quote.url.error.invalid': '{lang}wcf.editor.quote.url.error.invalid{/lang}',
+                               'wcf.editor.quote.author': '{jslang}wcf.editor.quote.author{/jslang}',
+                               'wcf.editor.quote.edit': '{jslang}wcf.editor.quote.edit{/jslang}',
+                               'wcf.editor.quote.title': '{jslang __literal=true}wcf.editor.quote.title{/jslang}',
+                               'wcf.editor.quote.url': '{jslang}wcf.editor.quote.url{/jslang}',
+                               'wcf.editor.quote.url.description': '{jslang}wcf.editor.quote.url.description{/jslang}',
+                               'wcf.editor.quote.url.error.invalid': '{jslang}wcf.editor.quote.url.error.invalid{/jslang}',
                                
-                               'wcf.editor.table.cols': '{lang}wcf.editor.table.cols{/lang}',
-                               'wcf.editor.table.insertTable': '{lang}wcf.editor.table.insertTable{/lang}',
-                               'wcf.editor.table.rows': '{lang}wcf.editor.table.rows{/lang}',
+                               'wcf.editor.table.cols': '{jslang}wcf.editor.table.cols{/jslang}',
+                               'wcf.editor.table.insertTable': '{jslang}wcf.editor.table.insertTable{/jslang}',
+                               'wcf.editor.table.rows': '{jslang}wcf.editor.table.rows{/jslang}',
                                
-                               'wcf.editor.source.error.active': '{lang}wcf.editor.source.error.active{/lang}',
+                               'wcf.editor.source.error.active': '{jslang}wcf.editor.source.error.active{/jslang}',
                                
-                               'wcf.editor.spoiler.label': '{lang}wcf.editor.spoiler.label{/lang}',
-                               'wcf.editor.spoiler.label.description': '{lang}wcf.editor.spoiler.label.description{/lang}',
-                               'wcf.editor.spoiler.edit': '{lang}wcf.editor.spoiler.edit{/lang}',
-                               'wcf.editor.spoiler.title': '{lang __literal=true}wcf.editor.spoiler.title{/lang}'
+                               'wcf.editor.spoiler.label': '{jslang}wcf.editor.spoiler.label{/jslang}',
+                               'wcf.editor.spoiler.label.description': '{jslang}wcf.editor.spoiler.label.description{/jslang}',
+                               'wcf.editor.spoiler.edit': '{jslang}wcf.editor.spoiler.edit{/jslang}',
+                               'wcf.editor.spoiler.title': '{jslang __literal=true}wcf.editor.spoiler.title{/jslang}'
                        });
                        
                        var allowedInlineStyles = [], buttons = [], buttonMobile = [], buttonOptions = [], customButtons = [];
                        var config = {
                                buttons: buttons,
                                clipboardImageUpload: {if $__wcf->getBBCodeHandler()->isAvailableBBCode('attach')}true{else}false{/if},
-                               direction: '{lang}wcf.global.pageDirection{/lang}',
+                               direction: '{jslang}wcf.global.pageDirection{/jslang}',
                                formatting: ['p', 'h2', 'h3', 'h4'],
                                imageCaption: false,
                                imageUpload: {if $__wcf->getBBCodeHandler()->isAvailableBBCode('attach')}true{else}false{/if},
                                langs: {
                                        wsc: {
                                                // general
-                                               edit: '{lang}wcf.global.button.edit{/lang}',
+                                               edit: '{jslang}wcf.global.button.edit{/jslang}',
                                                
                                                // formatting dropdown
-                                               heading2: '{lang}wcf.editor.format.heading2{/lang}',
-                                               heading3: '{lang}wcf.editor.format.heading3{/lang}',
-                                               heading4: '{lang}wcf.editor.format.heading4{/lang}',
-                                               paragraph: '{lang}wcf.editor.format.paragraph{/lang}',
+                                               heading2: '{jslang}wcf.editor.format.heading2{/jslang}',
+                                               heading3: '{jslang}wcf.editor.format.heading3{/jslang}',
+                                               heading4: '{jslang}wcf.editor.format.heading4{/jslang}',
+                                               paragraph: '{jslang}wcf.editor.format.paragraph{/jslang}',
                                                
                                                // links
-                                               'link-edit': '{lang}wcf.editor.link.edit{/lang}',
-                                               'link-insert': '{lang}wcf.editor.link.add{/lang}',
-                                               unlink: '{lang}wcf.editor.link.unlink{/lang}',
+                                               'link-edit': '{jslang}wcf.editor.link.edit{/jslang}',
+                                               'link-insert': '{jslang}wcf.editor.link.add{/jslang}',
+                                               unlink: '{jslang}wcf.editor.link.unlink{/jslang}',
                                                
                                                // text alignment
-                                               'align-center': '{lang}wcf.editor.alignment.center{/lang}',
-                                               'align-justify': '{lang}wcf.editor.alignment.justify{/lang}',
-                                               'align-left': '{lang}wcf.editor.alignment.left{/lang}',
-                                               'align-right': '{lang}wcf.editor.alignment.right{/lang}',
+                                               'align-center': '{jslang}wcf.editor.alignment.center{/jslang}',
+                                               'align-justify': '{jslang}wcf.editor.alignment.justify{/jslang}',
+                                               'align-left': '{jslang}wcf.editor.alignment.left{/jslang}',
+                                               'align-right': '{jslang}wcf.editor.alignment.right{/jslang}',
                                                
                                                // table plugin
-                                               'add-head': '{lang}wcf.editor.table.addHead{/lang}',
-                                               'delete-column': '{lang}wcf.editor.table.deleteColumn{/lang}',
-                                               'delete-head': '{lang}wcf.editor.table.deleteHead{/lang}',
-                                               'delete-row': '{lang}wcf.editor.table.deleteRow{/lang}',
-                                               'delete-table': '{lang}wcf.editor.table.deleteTable{/lang}',
-                                               'insert-table': '{lang}wcf.editor.table.insertTable{/lang}',
-                                               'insert-column-left': '{lang}wcf.editor.table.insertColumnLeft{/lang}',
-                                               'insert-column-right': '{lang}wcf.editor.table.insertColumnRight{/lang}',
-                                               'insert-row-above': '{lang}wcf.editor.table.insertRowAbove{/lang}',
-                                               'insert-row-below': '{lang}wcf.editor.table.insertRowBelow{/lang}',
+                                               'add-head': '{jslang}wcf.editor.table.addHead{/jslang}',
+                                               'delete-column': '{jslang}wcf.editor.table.deleteColumn{/jslang}',
+                                               'delete-head': '{jslang}wcf.editor.table.deleteHead{/jslang}',
+                                               'delete-row': '{jslang}wcf.editor.table.deleteRow{/jslang}',
+                                               'delete-table': '{jslang}wcf.editor.table.deleteTable{/jslang}',
+                                               'insert-table': '{jslang}wcf.editor.table.insertTable{/jslang}',
+                                               'insert-column-left': '{jslang}wcf.editor.table.insertColumnLeft{/jslang}',
+                                               'insert-column-right': '{jslang}wcf.editor.table.insertColumnRight{/jslang}',
+                                               'insert-row-above': '{jslang}wcf.editor.table.insertRowAbove{/jslang}',
+                                               'insert-row-below': '{jslang}wcf.editor.table.insertRowBelow{/jslang}',
                                                
                                                // size
-                                               'remove-size': '{lang}wcf.editor.button.size.removeSize{/lang}',
+                                               'remove-size': '{jslang}wcf.editor.button.size.removeSize{/jslang}',
                                                
                                                // color
-                                               'remove-color': '{lang}wcf.editor.button.color.removeColor{/lang}',
+                                               'remove-color': '{jslang}wcf.editor.button.color.removeColor{/jslang}',
                                                
                                                // font
-                                               'remove-font': '{lang}wcf.editor.button.font.removeFont{/lang}'
+                                               'remove-font': '{jslang}wcf.editor.button.font.removeFont{/jslang}'
                                        }
                                },
                                linkify: false,
index 155af844e2d4b833ee13b695980cd5af905ef747..f06eb7348d77367177865e2275218be50c1e4292 100644 (file)
@@ -1,25 +1,25 @@
 buttonOptions = {
-       alignment: { icon: 'fa-align-left', title: '{lang}wcf.editor.button.alignment{/lang}' },
-       bold: { icon: 'fa-bold', title: '{lang}wcf.editor.button.bold{/lang}' },
-       deleted: { icon: 'fa-strikethrough', title: '{lang}wcf.editor.button.strikethrough{/lang}' },
-       format: { icon: 'fa-header', title: '{lang}wcf.editor.button.format{/lang}' },
-       html: { icon: 'fa-file-code-o', title: '{lang}wcf.editor.button.html{/lang}' },
-       italic: { icon: 'fa-italic', title: '{lang}wcf.editor.button.italic{/lang}' },
-       link: { icon: 'fa-link', title: '{lang}wcf.editor.button.link{/lang}' },
-       lists: { icon: 'fa-list', title: '{lang}wcf.editor.button.lists{/lang}' },
-       redo: { icon: 'fa-repeat', title: '{lang}wcf.editor.button.redo{/lang}' },
-       subscript: { icon: 'fa-subscript', title: '{lang}wcf.editor.button.subscript{/lang}' },
-       superscript: { icon: 'fa-superscript', title: '{lang}wcf.editor.button.superscript{/lang}' },
-       table: { icon: 'fa-table', title: '{lang}wcf.editor.button.table{/lang}' },
-       underline: { icon: 'fa-underline', title: '{lang}wcf.editor.button.underline{/lang}' },
-       undo: { icon: 'fa-undo', title: '{lang}wcf.editor.button.undo{/lang}' },
-       woltlabColor: { icon: 'fa-paint-brush', title: '{lang}wcf.editor.button.color{/lang}' },
-       woltlabFont: { icon: 'fa-font', title: '{lang}wcf.editor.button.font{/lang}' },
-       woltlabFullscreen: { icon: 'fa-expand', title: '{lang}wcf.editor.button.fullscreen{/lang}' },
-       woltlabImage: { icon: 'fa-picture-o', title: '{lang}wcf.editor.button.image{/lang}' },
-       woltlabMedia: { icon: 'fa-file-o', title: '{lang}wcf.editor.button.media{/lang}' },
-       woltlabQuote: { icon: 'fa-comment', title: '{lang}wcf.editor.button.quote{/lang}' },
-       woltlabSize: { icon: 'fa-text-height', title: '{lang}wcf.editor.button.size{/lang}' }
+       alignment: { icon: 'fa-align-left', title: '{jslang}wcf.editor.button.alignment{/jslang}' },
+       bold: { icon: 'fa-bold', title: '{jslang}wcf.editor.button.bold{/jslang}' },
+       deleted: { icon: 'fa-strikethrough', title: '{jslang}wcf.editor.button.strikethrough{/jslang}' },
+       format: { icon: 'fa-header', title: '{jslang}wcf.editor.button.format{/jslang}' },
+       html: { icon: 'fa-file-code-o', title: '{jslang}wcf.editor.button.html{/jslang}' },
+       italic: { icon: 'fa-italic', title: '{jslang}wcf.editor.button.italic{/jslang}' },
+       link: { icon: 'fa-link', title: '{jslang}wcf.editor.button.link{/jslang}' },
+       lists: { icon: 'fa-list', title: '{jslang}wcf.editor.button.lists{/jslang}' },
+       redo: { icon: 'fa-repeat', title: '{jslang}wcf.editor.button.redo{/jslang}' },
+       subscript: { icon: 'fa-subscript', title: '{jslang}wcf.editor.button.subscript{/jslang}' },
+       superscript: { icon: 'fa-superscript', title: '{jslang}wcf.editor.button.superscript{/jslang}' },
+       table: { icon: 'fa-table', title: '{jslang}wcf.editor.button.table{/jslang}' },
+       underline: { icon: 'fa-underline', title: '{jslang}wcf.editor.button.underline{/jslang}' },
+       undo: { icon: 'fa-undo', title: '{jslang}wcf.editor.button.undo{/jslang}' },
+       woltlabColor: { icon: 'fa-paint-brush', title: '{jslang}wcf.editor.button.color{/jslang}' },
+       woltlabFont: { icon: 'fa-font', title: '{jslang}wcf.editor.button.font{/jslang}' },
+       woltlabFullscreen: { icon: 'fa-expand', title: '{jslang}wcf.editor.button.fullscreen{/jslang}' },
+       woltlabImage: { icon: 'fa-picture-o', title: '{jslang}wcf.editor.button.image{/jslang}' },
+       woltlabMedia: { icon: 'fa-file-o', title: '{jslang}wcf.editor.button.media{/jslang}' },
+       woltlabQuote: { icon: 'fa-comment', title: '{jslang}wcf.editor.button.quote{/jslang}' },
+       woltlabSize: { icon: 'fa-text-height', title: '{jslang}wcf.editor.button.size{/jslang}' }
 };
 
 buttonMobile = ['format', 'bold', 'italic', 'underline', 'lists', 'link', 'woltlabImage'];
diff --git a/com.woltlab.wcf/update_5.2.sql b/com.woltlab.wcf/update_5.2.sql
deleted file mode 100644 (file)
index 896f750..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-INSERT IGNORE INTO wcf1_style_variable (variableName, defaultValue) VALUES ('wcfEditorTableBorder', 'rgba(221, 221, 221, 1)');
-INSERT IGNORE INTO wcf1_style_variable (variableName, defaultValue) VALUES ('wcfPageThemeColor', ''); -- uses `$wcfHeaderBackground` if left empty
diff --git a/com.woltlab.wcf/update_5.3.sql b/com.woltlab.wcf/update_5.3.sql
new file mode 100644 (file)
index 0000000..852fab8
--- /dev/null
@@ -0,0 +1 @@
+DELETE FROM wcf1_style_variable WHERE variableName = 'useGoogleFont';
index 65b8422b994d2a7fcfd8e7ee18dd49efd5b0f131..227c57a8807aee80df14cde0c74616674680625d 100644 (file)
@@ -21,6 +21,9 @@
                        <category name="user.profile.trophy">
                                <parent>user.profile</parent>
                        </category>
+                       <category name="user.profile.payment">
+                               <parent>user.profile</parent>
+                       </category>
                        <category name="user.message">
                                <parent>user</parent>
                        </category>
                                <categoryname>admin.content</categoryname>
                                <optiontype>boolean</optiontype>
                                <defaultvalue>0</defaultvalue>
-                               <options>module_attachment</options>
                                <admindefaultvalue>1</admindefaultvalue>
                                <usersonly>1</usersonly>
                        </option>
                        <option name="user.attachment.maxSize">
                                <categoryname>user.message.attachment</categoryname>
                                <optiontype>fileSize</optiontype>
-                               <defaultvalue>1000000</defaultvalue>
+                               <defaultvalue>2000000</defaultvalue>
                                <minvalue>10000</minvalue>
                        </option>
                        <option name="user.attachment.allowedExtensions">
@@ -612,7 +614,7 @@ pdf</defaultvalue>
                        <option name="user.contactForm.attachment.maxSize">
                                <categoryname>user.message.contactForm</categoryname>
                                <optiontype>fileSize</optiontype>
-                               <defaultvalue>1000000</defaultvalue>
+                               <defaultvalue>2000000</defaultvalue>
                                <minvalue>10000</minvalue>
                        </option>
                        <option name="user.contactForm.attachment.allowedExtensions">
@@ -663,11 +665,6 @@ pdf</defaultvalue>
                        </option>
                        <!-- /user.signature -->
                        <!-- user.profile -->
-                       <option name="user.profile.canMail">
-                               <categoryname>user.profile</categoryname>
-                               <optiontype>boolean</optiontype>
-                               <defaultvalue>0</defaultvalue>
-                       </option>
                        <option name="user.profile.canChangeEmail">
                                <categoryname>user.profile</categoryname>
                                <optiontype>boolean</optiontype>
@@ -749,6 +746,12 @@ pdf</defaultvalue>
                                <defaultvalue>1</defaultvalue>
                                <usersonly>1</usersonly>
                        </option>
+                       <option name="user.profile.canHideOnlineStatus">
+                               <categoryname>user.profile</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>1</defaultvalue>
+                               <usersonly>1</usersonly>
+                       </option>
                        <option name="user.profile.avatar.canSeeAvatars">
                                <categoryname>user.profile.avatar</categoryname>
                                <optiontype>boolean</optiontype>
@@ -804,10 +807,16 @@ png</defaultvalue>
                        <option name="user.profile.trophy.maxUserSpecialTrophies">
                                <categoryname>user.profile.trophy</categoryname>
                                <optiontype>integer</optiontype>
-                               <defaultvalue>3</defaultvalue>
+                               <defaultvalue>5</defaultvalue>
                                <options>module_trophy</options>
                                <minvalue>0</minvalue>
-                               <maxvalue>5</maxvalue>
+                               <usersonly>1</usersonly>
+                       </option>
+                       <option name="user.profile.payment.canBuyPaidSubscription">
+                               <categoryname>user.profile.payment</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>1</defaultvalue>
+                               <options>module_paid_subscription</options>
                                <usersonly>1</usersonly>
                        </option>
                        <!-- /user.profile -->
@@ -1010,4 +1019,7 @@ png</defaultvalue>
                        </option>
                </options>
        </import>
+       <delete>
+               <option name="user.profile.canMail" />
+       </delete>
 </data>
index caaa8a7b38987583b81f2c92f215f36c6e36683c..0bca42fdb92f8a3dfa47e1464779f08407e14166 100644 (file)
@@ -37,6 +37,7 @@
                        <controller>wcf\page\PaidSubscriptionListPage</controller>
                        <parent>wcf.user.menu.settings</parent>
                        <options>module_paid_subscription</options>
+                       <permissions>user.profile.payment.canBuyPaidSubscription</permissions>
                </usermenuitem>
                <!-- /settings -->
                <!-- community -->
index 9e261f709350361beb64c6c8a58f758ca26eae7c..e278e90ec8f14f8ded4805b1938d7a00d1734994 100644 (file)
                        <preset>1</preset>
                        <options>module_article</options>
                </event>
+               <event>
+                       <name>like</name>
+                       <objecttype>com.woltlab.wcf.likeableArticle.notification</objecttype>
+                       <classname>wcf\system\user\notification\event\ArticleLikeUserNotificationEvent</classname>
+                       <preset>1</preset>
+               </event>
                
                <event>
                        <name>registration</name>
index 7d6bfe93eb416d717231dd30b001984dcade8d71..4bfee239d7143a4b3b4266e657faca59f0fd19e3 100644 (file)
@@ -77,7 +77,8 @@
                                <defaultvalue>0</defaultvalue>
                                <selectoptions>0:wcf.global.noDeclaration
 1:wcf.user.gender.male
-2:wcf.user.gender.female</selectoptions>
+2:wcf.user.gender.female
+3:wcf.user.gender.other</selectoptions>
                                <outputclass>wcf\system\option\user\SelectOptionsUserOptionOutput</outputclass>
                                <searchable>1</searchable>
                                <visible>15</visible>
                                <visible>15</visible>
                                <editable>3</editable>
                        </option>
-                       <option name="icq">
-                               <categoryname>profile.contact</categoryname>
-                               <optiontype>text</optiontype>
-                               <validationpattern>^$|^([0-9](-| )?)+[0-9]$</validationpattern>
-                               <searchable>1</searchable>
-                               <visible>15</visible>
-                               <editable>3</editable>
-                               <isdisabled>1</isdisabled>
-                               <contentpattern>^(\d{3})-(\d{3})-(\d{3})$</contentpattern>
-                       </option>
                        <option name="skype">
                                <categoryname>profile.contact</categoryname>
                                <optiontype>text</optiontype>
 2:wcf.user.access.following
 3:wcf.user.access.nobody</selectoptions>
                                <editable>3</editable>
+                               <permissions>user.profile.canHideOnlineStatus</permissions>
                        </option>
                        <option name="canViewProfile">
                                <categoryname>settings.privacy.content</categoryname>
 3:wcf.user.access.nobody</selectoptions>
                                <editable>3</editable>
                        </option>
+                       <option name="enableEmbeddedMedia">
+                               <categoryname>settings.privacy.content</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>0</defaultvalue>
+                               <editable>3</editable>
+                               <options>message_enable_user_consent</options>
+                       </option>
                        <!-- settings.privacy.messaging -->
                        <option name="canViewEmailAddress">
                                <categoryname>settings.privacy.messaging</categoryname>
                                <selectoptions>0:wcf.user.access.everyone
 1:wcf.user.access.registered
 2:wcf.user.access.following
-3:wcf.user.access.nobody</selectoptions>
-                               <editable>3</editable>
-                       </option>
-                       <option name="canMail">
-                               <categoryname>settings.privacy.messaging</categoryname>
-                               <optiontype>select</optiontype>
-                               <defaultvalue>1</defaultvalue>
-                               <selectoptions>0:wcf.user.access.everyone
-1:wcf.user.access.registered
-2:wcf.user.access.following
 3:wcf.user.access.nobody</selectoptions>
                                <editable>3</editable>
                        </option>
                        </option>
                </options>
        </import>
+       <delete>
+               <option name="canMail" />
+       </delete>
 </data>
index 61605901e2b7a3f7c822342e62379916dc90b705..3c4b10db4ddf2149e1c5cc56421ce89a1d4eae6e 100644 (file)
@@ -109,6 +109,7 @@ define('MAIL_FROM_NAME', '');
 define('MAIL_FROM_ADDRESS', '');
 define('MAIL_ADMIN_ADDRESS', '');
 define('MAIL_SIGNATURE', '');
+define('MAIL_SIGNATURE_HTML', '');
 define('MAIL_SEND_METHOD', 'php');
 define('MAIL_SMTP_HOST', '');
 define('MAIL_SMTP_PORT', 25);
@@ -141,11 +142,7 @@ define('IMAGE_PROXY_HOST_WHITELIST', '');
 define('ENABLE_CENSORSHIP', 0);
 define('CENSORED_WORDS', '');
 define('REGISTER_ENABLE_PASSWORD_SECURITY_CHECK', 0);
-define('REGISTER_PASSWORD_MIN_LENGTH', 8);
-define('REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE', 1);
-define('REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE', 1);
-define('REGISTER_PASSWORD_MUST_CONTAIN_DIGIT', 1);
-define('REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR', 1);
+define('PASSWORD_MIN_SCORE', 1);
 define('REGISTER_FORBIDDEN_USERNAMES', '');
 define('REGISTER_FORBIDDEN_EMAILS', '');
 define('REGISTER_ALLOWED_EMAILS', '');
@@ -263,3 +260,5 @@ define('BLACKLIST_SFS_EMAIL_ADDRESS', 'moreThanOnce');
 define('BLACKLIST_SFS_IP_ADDRESS', '90percentile');
 define('BLACKLIST_SFS_ACTION', 'disable');
 define('ENABLE_ENTERPRISE_MODE', 0);
+define('MESSAGE_ENABLE_USER_CONSENT', 1);
+define('MODIFICATION_LOG_EXPIRATION', 0);
diff --git a/defaultStyle/images/stylePreview.png b/defaultStyle/images/stylePreview.png
new file mode 100644 (file)
index 0000000..a188330
Binary files /dev/null and b/defaultStyle/images/stylePreview.png differ
diff --git a/defaultStyle/images/stylePreview@2x.png b/defaultStyle/images/stylePreview@2x.png
new file mode 100644 (file)
index 0000000..c6d707b
Binary files /dev/null and b/defaultStyle/images/stylePreview@2x.png differ
index a4fba4794f460f15d08ac64134a157538be920b8..f49d4818cae638a8e5c9c1575107651d6dc1c14a 100644 (file)
@@ -1,20 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<style xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/maelstrom/style.xsd">
+<style xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/2019/style.xsd">
        <general>
-               <stylename>Lantia Default Style</stylename>
-               <date>2015-10-22</date>
-               <copyright>WoltLab GmbH</copyright>
-               <license>GNU Lesser General Public License</license>
-               <version>3.0.0 Alpha 1</version>
-               <image>stylePreview-defaultStyle.png</image>
+               <stylename><![CDATA[WoltLab Suite Core 5.2]]></stylename>
+               <packageName><![CDATA[com.woltlab.wcf]]></packageName>
+               <date><![CDATA[2019-01-30]]></date>
+               <version><![CDATA[5.2.0]]></version>
+               <apiVersion><![CDATA[5.2]]></apiVersion>
+               <image><![CDATA[stylePreview.png]]></image>
+               <image2x><![CDATA[stylePreview@2x.png]]></image2x>
+               <copyright><![CDATA[WoltLab GmbH]]></copyright>
+               <license><![CDATA[GNU Lesser General Public License]]></license>
        </general>
-       
        <author>
-               <authorname>Alexander Ebert, Marcel Werk</authorname>
-               <authorurl>https://www.woltlab.com</authorurl>
+               <authorname><![CDATA[Alexander Ebert, Marcel Werk]]></authorname>
+               <authorurl><![CDATA[https://www.woltlab.com]]></authorurl>
        </author>
-       
        <files>
-               <variables>variables.xml</variables>
+               <variables><![CDATA[variables.xml]]></variables>
+               <images path="images/style-1/"><![CDATA[images.tar]]></images>
        </files>
 </style>
diff --git a/defaultStyle/stylePreview.png b/defaultStyle/stylePreview.png
new file mode 100644 (file)
index 0000000..a188330
Binary files /dev/null and b/defaultStyle/stylePreview.png differ
diff --git a/defaultStyle/stylePreview@2x.png b/defaultStyle/stylePreview@2x.png
new file mode 100644 (file)
index 0000000..c6d707b
Binary files /dev/null and b/defaultStyle/stylePreview@2x.png differ
index 249739e2dfb6224094c363cd548c40b3cd50f160..f2790dcc2a50f796342233a3e57ecfa7e7b84aaf 100644 (file)
@@ -1,2 +1,2 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<variables xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/maelstrom/styleVariables.xsd"/>
+<variables xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/2019/styleVariables.xsd"/>
index 2338f1837bc18f21464b3f85628f1924f41a77b3..089cc46a1ab6db99c3122d7e7286b47c38bebb9d 100644 (file)
@@ -3,49 +3,49 @@ const compiler = require("./compiler");
 const fs = require("fs");
 
 function compile(destination, files, overrides) {
-    let minifiedData = [];
+       let minifiedData = [];
 
-    files.forEach(filename => {
-        minifiedData.push({
-            filename: filename,
-            content: compiler.compile(filename, overrides)
-        });
-    });
+       files.forEach((filename) => {
+               minifiedData.push({
+                       filename: filename,
+                       content: compiler.compile(fs.readFileSync(process.cwd() + `/${filename}`, "utf-8"), overrides),
+               });
+       });
 
-    let content = `// ${destination} -- DO NOT EDIT\n\n`;
+       let content = `// ${destination} -- DO NOT EDIT\n\n`;
 
-    minifiedData.forEach(fileData => {
-        content += `// ${fileData.filename}\n`;
-        content += `(function (window, undefined) { ${fileData.content.code} })(this);`;
-        content += "\n\n";
-    });
+       minifiedData.forEach((fileData) => {
+               content += `// ${fileData.filename}\n`;
+               content += `(function (window, undefined) { ${fileData.content.code} })(this);`;
+               content += "\n\n";
+       });
 
-    fs.writeFileSync(destination, content);
-};
+       fs.writeFileSync(destination, content);
+}
 
 //
 // step 1) build `WCF.Combined.min.js` and `WCF.Combined.tiny.min.js`
 //
 process.chdir("../wcfsetup/install/files/js/");
-[true, false].forEach(COMPILER_TARGET_DEFAULT => {
-    let output = "WCF.Combined" + (COMPILER_TARGET_DEFAULT ? "" : ".tiny") + ".min.js";
-    console.time(output);
-    {
-        let data = fs.readFileSync(".buildOrder", "utf8");
-        let files = data
-            .trim()
-            .split(/\r?\n/)
-            .map(filename => `${filename}.js`);
-
-        compile(output, files, {
-            compress: {
-                global_defs: {
-                    COMPILER_TARGET_DEFAULT: COMPILER_TARGET_DEFAULT
-                }
-            }
-        });
-    }
-    console.timeEnd(output);
+[true, false].forEach((COMPILER_TARGET_DEFAULT) => {
+       let output = "WCF.Combined" + (COMPILER_TARGET_DEFAULT ? "" : ".tiny") + ".min.js";
+       console.time(output);
+       {
+               let data = fs.readFileSync(".buildOrder", "utf8");
+               let files = data
+                       .trim()
+                       .split(/\r?\n/)
+                       .map((filename) => `${filename}.js`);
+
+               compile(output, files, {
+                       compress: {
+                               global_defs: {
+                                       COMPILER_TARGET_DEFAULT: COMPILER_TARGET_DEFAULT,
+                               },
+                       },
+               });
+       }
+       console.timeEnd(output);
 });
 
 //
@@ -56,49 +56,52 @@ process.chdir("3rdParty/redactor2/");
 
 console.time(redactorCombined);
 {
-    let files = ['redactor.js'];
-    fs.readdirSync("./plugins/").forEach(file => {
-        file = `plugins/${file}`;
-        let stat = fs.statSync(file);
-        if (stat.isFile() && !stat.isSymbolicLink()) {
-            files.push(file);
-        }
-    });
-
-    compile(redactorCombined, files);
+       let files = ["redactor.js"];
+       fs.readdirSync("./plugins/").forEach((file) => {
+               file = `plugins/${file}`;
+               let stat = fs.statSync(file);
+               if (stat.isFile() && !stat.isSymbolicLink()) {
+                       files.push(file);
+               }
+       });
+
+       compile(redactorCombined, files);
 }
 console.timeEnd(redactorCombined);
 
 //
 // step3) build rjs
 //
-const rjsCmd = (process.platform === "win32") ? "r.js.cmd" : "r.js";
+const rjsCmd = process.platform === "win32" ? "r.js.cmd" : "r.js";
 process.chdir("../../");
 
 {
-    let configFile = "require.build.js";
-    let outFilename = require(process.cwd() + `/${configFile}`).out;
-
-    const promisePolyfill = fs.readFileSync("./3rdParty/polyfill/promise.min.js");
-
-    [true, false].forEach(COMPILER_TARGET_DEFAULT => {
-        let overrides = "uglify2.compress.global_defs.COMPILER_TARGET_DEFAULT=" + (COMPILER_TARGET_DEFAULT ? "true" : "false");
-        if (!COMPILER_TARGET_DEFAULT) {
-            outFilename = outFilename.replace(/\.min\.js$/, '.tiny.min.js');
-            overrides += " out=" + outFilename;
-        }
-
-        console.time(outFilename);
-        childProcess.execSync(`${rjsCmd} -o ${configFile} ${overrides}`, {
-            cwd: process.cwd(),
-            stdio: [0, 1, 2]
-        });
-        console.timeEnd(outFilename);
-
-        // prepend the promise polyfill
-        let content = `// promise.min.js\n${promisePolyfill}\n\n// ${outFilename}\n` + fs.readFileSync(outFilename);
-        fs.writeFileSync(outFilename, content);
-    });
+       let configFile = "require.build.js";
+       let outFilename = require(process.cwd() + `/${configFile}`).out;
+
+       const promisePolyfill = fs.readFileSync("./3rdParty/polyfill/promise.min.js");
+
+       [true, false].forEach((COMPILER_TARGET_DEFAULT) => {
+               let overrides =
+                       "uglify2.compress.global_defs.COMPILER_TARGET_DEFAULT=" +
+                       (COMPILER_TARGET_DEFAULT ? "true" : "false");
+               if (!COMPILER_TARGET_DEFAULT) {
+                       outFilename = outFilename.replace(/\.min\.js$/, ".tiny.min.js");
+                       overrides += " out=" + outFilename;
+               }
+
+               console.time(outFilename);
+               childProcess.execSync(`${rjsCmd} -o ${configFile} ${overrides}`, {
+                       cwd: process.cwd(),
+                       stdio: [0, 1, 2],
+               });
+               console.timeEnd(outFilename);
+
+               // prepend the promise polyfill
+               let content =
+                       `// promise.min.js\n${promisePolyfill}\n\n// ${outFilename}\n` + fs.readFileSync(outFilename);
+               fs.writeFileSync(outFilename, content);
+       });
 }
 
 //
@@ -107,19 +110,19 @@ process.chdir("../../");
 process.chdir("../acp/js/");
 
 fs.readdirSync("./")
-    .filter(filename => {
-        let stat = fs.statSync(filename);
-        if (stat.isFile() && !stat.isSymbolicLink()) {
-            return filename.match(/\.js$/) && !filename.match(/\.min\.js$/);
-        }
-
-        return false;
-    })
-    .forEach(filename => {
-        console.time(filename);
-        {
-            let output = compiler.compile(process.cwd() + `/${filename}`);
-            fs.writeFileSync(filename.replace(/\.js$/, '.min.js'), output.code);
-        }
-        console.timeEnd(filename);
-    });
+       .filter((filename) => {
+               let stat = fs.statSync(filename);
+               if (stat.isFile() && !stat.isSymbolicLink()) {
+                       return filename.match(/\.js$/) && !filename.match(/\.min\.js$/);
+               }
+
+               return false;
+       })
+       .forEach((filename) => {
+               console.time(filename);
+               {
+                       let output = compiler.compile(fs.readFileSync(process.cwd() + `/${filename}`, "utf-8"));
+                       fs.writeFileSync(filename.replace(/\.js$/, ".min.js"), output.code);
+               }
+               console.timeEnd(filename);
+       });
index 99f54517e276a7405f955a755b540590b1287404..c62a97e52539aa8672c334491cd54ff69b7f849a 100644 (file)
@@ -44,7 +44,7 @@ fs.readdirSync("./")
                         let outFilename = filename.replace(/\.js$/, (COMPILER_TARGET_DEFAULT ? "" : ".tiny") + ".min.js");
                         console.time(outFilename);
                         {
-                            let output = compiler.compile(path + filename, {
+                            let output = compiler.compile(fs.readFileSync(path + filename, 'utf-8'), {
                                 compress: {
                                     global_defs: {
                                         COMPILER_TARGET_DEFAULT: COMPILER_TARGET_DEFAULT
index b700ebc9cfafeebdb38ce2ded6882f691eda135b..f5f18eb6ce7a2d407fae78c4b8a65d7823e16238 100644 (file)
@@ -14,7 +14,6 @@ const uglifyJsConfig = {
         hoist_vars: true,
         if_return: true,
         join_vars: true,
-        cascade: true,
         /* this is basically the `--define` argument */
         global_defs: {
             COMPILER_TARGET_DEFAULT: false
@@ -30,4 +29,4 @@ module.exports = {
             filename,
             Object.assign(uglifyJsConfig, overrides));
     }
-}
\ No newline at end of file
+}
diff --git a/extra/examples/wsc-dev-config-52.json b/extra/examples/wsc-dev-config-52.json
deleted file mode 100644 (file)
index 605aa81..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-    "setup": {
-        "database": {
-            "auto": true,
-            "host": "localhost",
-            "password": "root",
-            "username": "root",
-            "dbNumber": "2"
-        },
-        "useDefaultInstallPath": true,
-        "forceStaticCookiePrefix": true
-    },
-    "configuration": {
-        "option": {
-            "captcha_type": "",
-            "module_cookie_policy_page": "0"
-        },
-        "devtools": {
-            "importFromPath": "C:/inetpub/wwwroot/wcf/"
-        }
-    },
-    "user": [
-        {
-            "username": "test",
-            "password": "test",
-            "email": "test@example.com"
-        },
-        {
-            "username": "test2",
-            "password": "test",
-            "email": "test2@example.com"
-        }
-    ]
-}
diff --git a/extra/examples/wsc-dev-config-53.json b/extra/examples/wsc-dev-config-53.json
new file mode 100644 (file)
index 0000000..605aa81
--- /dev/null
@@ -0,0 +1,34 @@
+{
+    "setup": {
+        "database": {
+            "auto": true,
+            "host": "localhost",
+            "password": "root",
+            "username": "root",
+            "dbNumber": "2"
+        },
+        "useDefaultInstallPath": true,
+        "forceStaticCookiePrefix": true
+    },
+    "configuration": {
+        "option": {
+            "captcha_type": "",
+            "module_cookie_policy_page": "0"
+        },
+        "devtools": {
+            "importFromPath": "C:/inetpub/wwwroot/wcf/"
+        }
+    },
+    "user": [
+        {
+            "username": "test",
+            "password": "test",
+            "email": "test@example.com"
+        },
+        {
+            "username": "test2",
+            "password": "test",
+            "email": "test2@example.com"
+        }
+    ]
+}
index 3eaa4c47b26ef0a70c4172b8541374e0cf4f8c44..f571786fa98f42bd9d6a64c50b6ecb67ebd71232 100644 (file)
   "lockfileVersion": 1,
   "dependencies": {
     "@types/md5-file": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/md5-file/-/md5-file-4.0.0.tgz",
-      "integrity": "sha512-t+qg7R25oYo6z3iWI+9CRky2mgQ51RGvLqlCPV+xa6dKp0YDomv0TArLK/CdcReFZwQHn/YMNRZx+4AUWXPtlg==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/md5-file/-/md5-file-4.0.2.tgz",
+      "integrity": "sha512-8gacRfEqLrmZ6KofpFfxyjsm/LYepeWUWUJGaf5A9W9J5B2/dRZMdkDqFDL6YDa9IweH12IO76jO7mpsK2B3wg==",
       "dev": true
     },
     "@types/node": {
-      "version": "10.12.15",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz",
-      "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==",
+      "version": "14.6.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz",
+      "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==",
       "dev": true
     },
-    "align-text": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
-      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
-      "requires": {
-        "kind-of": "^3.0.2",
-        "longest": "^1.0.1",
-        "repeat-string": "^1.5.2"
-      }
-    },
-    "arrify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
+    "arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
     },
     "buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
       "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
     },
-    "camelcase": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
-      "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
-    },
-    "center-align": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
-      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
-      "requires": {
-        "align-text": "^0.1.3",
-        "lazy-cache": "^1.0.3"
-      }
-    },
-    "cliui": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
-      "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
-      "requires": {
-        "center-align": "^0.1.1",
-        "right-align": "^0.1.1",
-        "wordwrap": "0.0.2"
-      }
-    },
-    "decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
-    },
     "diff": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
-      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
-    },
-    "is-buffer": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
-    },
-    "kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "requires": {
-        "is-buffer": "^1.1.5"
-      }
-    },
-    "lazy-cache": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
-      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
-    },
-    "longest": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
-      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
     },
     "make-error": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
-      "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g=="
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
     },
     "md5-file": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz",
-      "integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz",
+      "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==",
       "dev": true
     },
-    "minimist": {
-      "version": "1.2.0",
-      "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
-    },
-    "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "requires": {
-        "minimist": "0.0.8"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
-        }
-      }
-    },
-    "repeat-string": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
-    },
     "requirejs": {
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
       "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg=="
     },
-    "right-align": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
-      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
-      "requires": {
-        "align-text": "^0.1.1"
-      }
-    },
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
     },
     "source-map-support": {
-      "version": "0.5.9",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz",
-      "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==",
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
       "requires": {
         "buffer-from": "^1.0.0",
         "source-map": "^0.6.0"
       }
     },
     "ts-node": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz",
-      "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==",
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
+      "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
       "requires": {
-        "arrify": "^1.0.0",
-        "buffer-from": "^1.1.0",
-        "diff": "^3.1.0",
+        "arg": "^4.1.0",
+        "diff": "^4.0.1",
         "make-error": "^1.1.1",
-        "minimist": "^1.2.0",
-        "mkdirp": "^0.5.1",
-        "source-map-support": "^0.5.6",
-        "yn": "^2.0.0"
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
       }
     },
     "typescript": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz",
-      "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz",
+      "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==",
       "dev": true
     },
     "uglify-js": {
-      "version": "2.8.29",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
-      "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
-      "requires": {
-        "source-map": "~0.5.1",
-        "uglify-to-browserify": "~1.0.0",
-        "yargs": "~3.10.0"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
-        }
-      }
-    },
-    "uglify-to-browserify": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
-      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
-      "optional": true
-    },
-    "window-size": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
-      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
-    },
-    "wordwrap": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
-      "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
-    },
-    "yargs": {
-      "version": "3.10.0",
-      "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
-      "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
-      "requires": {
-        "camelcase": "^1.0.2",
-        "cliui": "^2.1.0",
-        "decamelize": "^1.0.0",
-        "window-size": "0.1.0"
-      }
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.1.tgz",
+      "integrity": "sha512-RjxApKkrPJB6kjJxQS3iZlf///REXWYxYJxO/MpmlQzVkDWVI3PSnCBWezMecmTU/TRkNxrl8bmsfFQCp+LO+Q=="
     },
     "yn": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
-      "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo="
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
     }
   }
 }
index 70f7c5e7c49e44295a95d34fb530d3d577b74111..df5267d164882376167da821207a91247e9482b3 100644 (file)
@@ -1,13 +1,13 @@
 {
   "dependencies": {
     "requirejs": "^2.3.6",
-    "ts-node": "^7.0.1",
-    "uglify-js": "^2.0.0"
+    "ts-node": "^8.10.2",
+    "uglify-js": "^3.10.1"
   },
   "devDependencies": {
-    "@types/md5-file": "^4.0.0",
-    "@types/node": "^10.12.15",
-    "md5-file": "^4.0.0",
-    "typescript": "^3.2.2"
+    "@types/md5-file": "^4.0.2",
+    "@types/node": "^14.6.0",
+    "md5-file": "^5.0.0",
+    "typescript": "^4.0.2"
   }
 }
index 1abd13f0ccb24f85dca9b7f626c6700dc38b1d94..6223b81ccdfd504ac51e27ab110cdfcb8e2430b0 100644 (file)
        <spider ident="DNAbot/1.0">
                <name>DNAbot</name>
        </spider>
+       <spider ident="DotBot/1.1">
+               <name>Moz DotBot</name>
+               <url>http://www.opensiteexplorer.org/dotbot</url>
+       </spider>
        <spider ident="DragonBot/1.0 libwww/5.0">
                <name>DragonBot</name>
        </spider>
                <name>Google Stackdriver Monitoring</name>
                <url>https://cloud.google.com/monitoring/alerts/uptime-checks</url>
        </spider>
+       <spider ident="Google-Ads-Creatives-Assistant">
+               <name>Google-Ads-Creatives-Assistant</name>
+       </spider>
+       <spider ident="Google-AdWords-Express">
+               <name>Google-AdWords-Express</name>
+       </spider>
+       <spider ident="AdsBot-Google">
+               <name>Google Ads-Bot</name>
+               <url>http://www.google.com/adsbot.html</url>
+       </spider>
        <spider ident="Gpostbot">
                <name>Gpostbot</name>
                <url>http://www.gpost.info/help.php?c=bot</url>
        <spider ident="PageBoy">
                <name>PageBoy</name>
        </spider>
+       <spider ident="Pandalytics">
+               <name>Pandalytics</name>
+               <url>https://domainsbot.com/pandalytics/</url>
+       </spider>
        <spider ident="ParaSite">
                <name>ParaSite</name>
        </spider>
                <name>Sensis Web Crawler</name>
                <url>http://www.sensis.com.au/help.do</url>
        </spider>
+       <spider ident="SentiBot">
+               <name>SentiBot</name>
+               <url>http://www.sentibot.eu</url>
+       </spider>
+       <spider ident="SeznamBot/3.2">
+               <name>Seznam Bot</name>
+               <url>http://napoveda.seznam.cz/en/seznambot-intro/</url>
+       </spider>
        <spider ident="SG-Scout">
                <name>SG-Scout</name>
        </spider>
index 11db7532e8ec3be259f6d10aac8353f94f83bac1..c490d47c3f6a0fdbdeacf888bce6ad728bae1770 100644 (file)
@@ -6,6 +6,7 @@
   "templates": [
     "__aclFormField",
     "__booleanFormField",
+    "__checkboxFormField",
     "__contentLanguageFormField",
     "__dateFormField",
     "__emailFormField",
     "categoryOptionList",
     "checkboxesOptionType",
     "checkboxesSearchableOptionType",
+    "codeMetaCode",
     "fontAwesomeJavaScript",
     "formError",
+    "formNotice",
+    "formSuccess",
     "languageChooser",
     "mediaBBCodeTag",
     "mediaManager",
     "multipleLanguageInputJavascript",
+    "passwordStrengthLanguage",
     "radioButtonSearchableOptionType",
     "recaptcha",
     "scrollablePageCheckboxList",
index 21e6de138cd73d4af8040d8b8069d1a79765648d..a5e55f737a792e5c9f302df5ebfe5bed42ffb18b 100644 (file)
@@ -929,14 +929,10 @@ class Tar {
                $this->file->seek($header['offset']);
                
                // read data
-               $content = '';
-               $n = floor($header['size'] / 512);
-               for ($i = 0; $i < $n; $i++) {
-                       $content .= $this->file->read(512);
-               }
-               if (($header['size'] % 512) != 0) {
-                       $buffer = $this->file->read(512);
-                       $content .= substr($buffer, 0, $header['size'] % 512);
+               $content = $this->file->read($header['size']);
+               
+               if (strlen($content) != $header['size']) {
+                       throw new SystemException("Could not untar file '".$header['filename']."' to string. Maybe the archive is truncated?");
                }
                
                return $content;
diff --git a/wcfsetup/install/files/acp/images/woltlabLogo-tiny.png b/wcfsetup/install/files/acp/images/woltlabLogo-tiny.png
new file mode 100644 (file)
index 0000000..5321b6e
Binary files /dev/null and b/wcfsetup/install/files/acp/images/woltlabLogo-tiny.png differ
index dfc9b6def4dcb098e81a6943ac9a5129909eea91..bb3873be97ba2cb3abe6879353d92ddc37cdda35 100644 (file)
@@ -162,299 +162,6 @@ WCF.ACP.Style.ImageUpload = WCF.Upload.extend({
        }
 });
 
-/**
- * Handles the logo upload.
- * 
- * @param      string          tmpHash
- */
-WCF.ACP.Style.LogoUpload = WCF.Upload.extend({
-       /**
-        * upload button
-        * @var jQuery
-        */
-       _button: null,
-       
-       /**
-        * image path
-        * @var jQuery
-        */
-       _imagePath: null,
-       
-       /**
-        * logo
-        * @var jQuery
-        */
-       _logo: null,
-       
-       /**
-        * page logo input field
-        * @var jQuery
-        */
-       _pageLogo: null,
-       
-       /**
-        * tmp hash
-        * @var string
-        */
-       _tmpHash: '',
-       
-       /**
-        * absolute path to WCF directory
-        * @var string
-        */
-       _wcfPath: '',
-       
-       /**
-        * @see WCF.Upload.init()
-        */
-       init: function(tmpHash, wcfPath) {
-               this._tmpHash = tmpHash;
-               this._wcfPath = wcfPath;
-               
-               this._button = $('#uploadLogo');
-               this._image = $('#styleLogo');
-               this._imagePath = $('#imagePath');
-               this._pageLogo = $('#pageLogo');
-               
-               this._super(this._button, undefined, 'wcf\\data\\style\\StyleAction', { action: 'uploadLogo' });
-               
-               if (!this._image.attr('src').length) {
-                       this._updateLogo();
-               }
-               
-               this._pageLogo.blur($.proxy(this._updateLogo, this));
-       },
-       
-       /**
-        * Updates the logo preview.
-        */
-       _updateLogo: function() {
-               var $src = this._pageLogo.val();
-               if ($src.length) {
-                       if (!$src.match(/^https?:\/\//)) {
-                               var $path = this._imagePath.val();
-                               if (!$path) {
-                                       $path = 'images/';
-                               }
-                               
-                               $path = this._wcfPath + $path.replace(/^\/?images\/?/, '');
-                               if ($path.substr(-1) !== '/') {
-                                       $path += '/';
-                               }
-                               
-                               $src = $path + $src;
-                       }
-               }
-               else {
-                       // no logo defined, fallback to application logo
-                       $src = WCF_PATH + 'images/default-logo.png';
-                       $('#pageLogoWidth').val(281);
-                       $('#pageLogoHeight').val(40);
-               }
-               
-               this._image.attr('src', $src + '?timestamp=' + Date.now());
-       },
-       
-       /**
-        * @see WCF.Upload._initFile()
-        */
-       _initFile: function(file) {
-               return this._image;
-       },
-       
-       /**
-        * @see WCF.Upload._getParameters()
-        */
-       _getParameters: function() {
-               return {
-                       tmpHash: this._tmpHash
-               };
-       },
-       
-       /**
-        * @see WCF.Upload._success()
-        */
-       _success: function(uploadID, data) {
-               if (data.returnValues.url) {
-                       // show image
-                       this._image.attr('src', data.returnValues.url + '?timestamp=' + Date.now());
-                       this._pageLogo.val(data.returnValues.url);
-                       
-                       // hide error
-                       this._button.next('.innerError').remove();
-                       
-                       $('#pageLogoWidth').val(data.returnValues.width);
-                       $('#pageLogoHeight').val(data.returnValues.height);
-                       
-                       // show success message
-                       var $notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'));
-                       $notification.show();
-               }
-               else if (data.returnValues.errorType) {
-                       // show error
-                       this._getInnerErrorElement().text(WCF.Language.get('wcf.acp.style.image.error.' + data.returnValues.errorType));
-               }
-       },
-       
-       /**
-        * Returns error display element.
-        * 
-        * @return      jQuery
-        */
-       _getInnerErrorElement: function() {
-               var $span = this._button.next('.innerError');
-               if (!$span.length) {
-                       $span = $('<small class="innerError" />').insertAfter(this._button);
-               }
-               
-               return $span;
-       }
-});
-
-/**
- * Handles the mobile logo upload.
- *
- * @param      string          tmpHash
- */
-WCF.ACP.Style.LogoUploadMobile = WCF.Upload.extend({
-       /**
-        * upload button
-        * @var jQuery
-        */
-       _button: null,
-       
-       /**
-        * image path
-        * @var jQuery
-        */
-       _imagePath: null,
-       
-       /**
-        * logo
-        * @var jQuery
-        */
-       _logo: null,
-       
-       /**
-        * page logo input field
-        * @var jQuery
-        */
-       _pageLogo: null,
-       
-       /**
-        * tmp hash
-        * @var string
-        */
-       _tmpHash: '',
-       
-       /**
-        * absolute path to WCF directory
-        * @var string
-        */
-       _wcfPath: '',
-       
-       /**
-        * @see WCF.Upload.init()
-        */
-       init: function(tmpHash, wcfPath) {
-               this._tmpHash = tmpHash;
-               this._wcfPath = wcfPath;
-               
-               this._button = $('#uploadLogoMobile');
-               this._image = $('#styleLogoMobile');
-               this._imagePath = $('#imagePath');
-               this._pageLogo = $('#pageLogoMobile');
-               
-               this._super(this._button, undefined, 'wcf\\data\\style\\StyleAction', { action: 'uploadLogoMobile' });
-               
-               if (!this._image.attr('src').length) {
-                       this._updateLogo();
-               }
-               
-               this._pageLogo.blur($.proxy(this._updateLogo, this));
-       },
-       
-       /**
-        * Updates the logo preview.
-        */
-       _updateLogo: function() {
-               var $src = this._pageLogo.val();
-               if ($src.length) {
-                       if (!$src.match(/^https?:\/\//)) {
-                               var $path = this._imagePath.val();
-                               if (!$path) {
-                                       $path = 'images/';
-                               }
-                               
-                               $path = this._wcfPath + $path.replace(/^\/?images\/?/, '');
-                               if ($path.substr(-1) !== '/') {
-                                       $path += '/';
-                               }
-                               
-                               $src = $path + $src;
-                       }
-               }
-               else {
-                       // no logo defined, fallback to application logo
-                       $src = WCF_PATH + 'images/default-logo-small.png';
-               }
-               
-               this._image.attr('src', $src + '?timestamp=' + Date.now());
-       },
-       
-       /**
-        * @see WCF.Upload._initFile()
-        */
-       _initFile: function(file) {
-               return this._image;
-       },
-       
-       /**
-        * @see WCF.Upload._getParameters()
-        */
-       _getParameters: function() {
-               return {
-                       tmpHash: this._tmpHash
-               };
-       },
-       
-       /**
-        * @see WCF.Upload._success()
-        */
-       _success: function(uploadID, data) {
-               if (data.returnValues.url) {
-                       // show image
-                       this._image.attr('src', data.returnValues.url + '?timestamp=' + Date.now());
-                       this._pageLogo.val(data.returnValues.url);
-                       
-                       // hide error
-                       this._button.next('.innerError').remove();
-                       
-                       // show success message
-                       var $notification = new WCF.System.Notification(WCF.Language.get('wcf.global.success'));
-                       $notification.show();
-               }
-               else if (data.returnValues.errorType) {
-                       // show error
-                       this._getInnerErrorElement().text(WCF.Language.get('wcf.acp.style.image.error.' + data.returnValues.errorType));
-               }
-       },
-       
-       /**
-        * Returns error display element.
-        *
-        * @return      jQuery
-        */
-       _getInnerErrorElement: function() {
-               var $span = this._button.next('.innerError');
-               if (!$span.length) {
-                       $span = $('<small class="innerError" />').insertAfter(this._button);
-               }
-               
-               return $span;
-       }
-});
-
 /**
  * Handles style list management buttons.
  */
index 03c30a7aa695078f9ac880df2f24c846fc76484a..97711a3b811f41a39f7e4fff88f60496be0535d5 100644 (file)
@@ -1 +1 @@
-WCF.ACP.Style={},WCF.ACP.Style.CopyStyle=Class.extend({_styleID:0,init:function(t){this._styleID=t;var e=this;$(".jsCopyStyle").click(function(){WCF.System.Confirmation.show(WCF.Language.get("wcf.acp.style.copyStyle.confirmMessage"),$.proxy(e._copy,e),void 0,void 0,!0)})},_copy:function(t){"confirm"===t&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"copy",className:"wcf\\data\\style\\StyleAction",objectIDs:[this._styleID]},success:$.proxy(this._success,this)})},_success:function(t,e,s){window.location=t.returnValues.redirectURL}}),WCF.ACP.Style.ImageUpload=WCF.Upload.extend({_button:null,_image:null,_styleID:0,_tmpHash:"",init:function(t,e){this._styleID=parseInt(t)||0,this._tmpHash=e,this._button=$("#uploadImage"),this._image=$("#styleImage"),this._super(this._button,void 0,"wcf\\data\\style\\StyleAction")},_initFile:function(t){return this._image},_getParameters:function(){return{styleID:this._styleID,tmpHash:this._tmpHash}},_success:function(t,e){if(e.returnValues.url){this._image.attr("src",e.returnValues.url+"?timestamp="+Date.now()),this._button.next(".innerError").remove();new WCF.System.Notification(WCF.Language.get("wcf.global.success")).show()}else e.returnValues.errorType&&this._getInnerErrorElement().text(WCF.Language.get("wcf.acp.style.image.error."+e.returnValues.errorType))},_getInnerErrorElement:function(){var t=this._button.next(".innerError");return t.length||(t=$('<small class="innerError" />').insertAfter(this._button)),t}}),WCF.ACP.Style.LogoUpload=WCF.Upload.extend({_button:null,_imagePath:null,_logo:null,_pageLogo:null,_tmpHash:"",_wcfPath:"",init:function(t,e){this._tmpHash=t,this._wcfPath=e,this._button=$("#uploadLogo"),this._image=$("#styleLogo"),this._imagePath=$("#imagePath"),this._pageLogo=$("#pageLogo"),this._super(this._button,void 0,"wcf\\data\\style\\StyleAction",{action:"uploadLogo"}),this._image.attr("src").length||this._updateLogo(),this._pageLogo.blur($.proxy(this._updateLogo,this))},_updateLogo:function(){var t=this._pageLogo.val();if(t.length){if(!t.match(/^https?:\/\//)){var e=this._imagePath.val();e||(e="images/"),e=this._wcfPath+e.replace(/^\/?images\/?/,""),"/"!==e.substr(-1)&&(e+="/"),t=e+t}}else t=WCF_PATH+"images/default-logo.png",$("#pageLogoWidth").val(281),$("#pageLogoHeight").val(40);this._image.attr("src",t+"?timestamp="+Date.now())},_initFile:function(t){return this._image},_getParameters:function(){return{tmpHash:this._tmpHash}},_success:function(t,e){if(e.returnValues.url){this._image.attr("src",e.returnValues.url+"?timestamp="+Date.now()),this._pageLogo.val(e.returnValues.url),this._button.next(".innerError").remove(),$("#pageLogoWidth").val(e.returnValues.width),$("#pageLogoHeight").val(e.returnValues.height);new WCF.System.Notification(WCF.Language.get("wcf.global.success")).show()}else e.returnValues.errorType&&this._getInnerErrorElement().text(WCF.Language.get("wcf.acp.style.image.error."+e.returnValues.errorType))},_getInnerErrorElement:function(){var t=this._button.next(".innerError");return t.length||(t=$('<small class="innerError" />').insertAfter(this._button)),t}}),WCF.ACP.Style.LogoUploadMobile=WCF.Upload.extend({_button:null,_imagePath:null,_logo:null,_pageLogo:null,_tmpHash:"",_wcfPath:"",init:function(t,e){this._tmpHash=t,this._wcfPath=e,this._button=$("#uploadLogoMobile"),this._image=$("#styleLogoMobile"),this._imagePath=$("#imagePath"),this._pageLogo=$("#pageLogoMobile"),this._super(this._button,void 0,"wcf\\data\\style\\StyleAction",{action:"uploadLogoMobile"}),this._image.attr("src").length||this._updateLogo(),this._pageLogo.blur($.proxy(this._updateLogo,this))},_updateLogo:function(){var t=this._pageLogo.val();if(t.length){if(!t.match(/^https?:\/\//)){var e=this._imagePath.val();e||(e="images/"),e=this._wcfPath+e.replace(/^\/?images\/?/,""),"/"!==e.substr(-1)&&(e+="/"),t=e+t}}else t=WCF_PATH+"images/default-logo-small.png";this._image.attr("src",t+"?timestamp="+Date.now())},_initFile:function(t){return this._image},_getParameters:function(){return{tmpHash:this._tmpHash}},_success:function(t,e){if(e.returnValues.url){this._image.attr("src",e.returnValues.url+"?timestamp="+Date.now()),this._pageLogo.val(e.returnValues.url),this._button.next(".innerError").remove();new WCF.System.Notification(WCF.Language.get("wcf.global.success")).show()}else e.returnValues.errorType&&this._getInnerErrorElement().text(WCF.Language.get("wcf.acp.style.image.error."+e.returnValues.errorType))},_getInnerErrorElement:function(){var t=this._button.next(".innerError");return t.length||(t=$('<small class="innerError" />').insertAfter(this._button)),t}}),WCF.ACP.Style.List=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".styleList .buttonList").each($.proxy(function(t,e){var s=$(e),i=s.data("styleID"),a=this;s.find(".jsSetAsDefault").click(function(t){t.preventDefault(),a._click("setAsDefault",i)}),s.find(".jsDelete").click(function(t){a._delete(t,i)})},this))},_click:function(t,e){this._proxy.setOption("data",{actionName:t,className:"wcf\\data\\style\\StyleAction",objectIDs:[e]}),this._proxy.sendRequest()},_delete:function(t,e){t.preventDefault();var s=$(t.currentTarget).data("confirmMessageHtml");if(s){var i=this;WCF.System.Confirmation.show(s,function(t){"confirm"===t&&i._click("delete",e)},void 0,void 0,!0)}else this._click("delete",e)},_success:function(t,e,s){window.location.reload()}});
\ No newline at end of file
+WCF.ACP.Style={},WCF.ACP.Style.CopyStyle=Class.extend({_styleID:0,init:function(t){this._styleID=t;var e=this;$(".jsCopyStyle").click(function(){WCF.System.Confirmation.show(WCF.Language.get("wcf.acp.style.copyStyle.confirmMessage"),$.proxy(e._copy,e),void 0,void 0,!0)})},_copy:function(t){"confirm"===t&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"copy",className:"wcf\\data\\style\\StyleAction",objectIDs:[this._styleID]},success:$.proxy(this._success,this)})},_success:function(t,e,s){window.location=t.returnValues.redirectURL}}),WCF.ACP.Style.ImageUpload=WCF.Upload.extend({_button:null,_image:null,_styleID:0,_tmpHash:"",init:function(t,e){this._styleID=parseInt(t)||0,this._tmpHash=e,this._button=$("#uploadImage"),this._image=$("#styleImage"),this._super(this._button,void 0,"wcf\\data\\style\\StyleAction")},_initFile:function(t){return this._image},_getParameters:function(){return{styleID:this._styleID,tmpHash:this._tmpHash}},_success:function(t,e){e.returnValues.url?(this._image.attr("src",e.returnValues.url+"?timestamp="+Date.now()),this._button.next(".innerError").remove(),new WCF.System.Notification(WCF.Language.get("wcf.global.success")).show()):e.returnValues.errorType&&this._getInnerErrorElement().text(WCF.Language.get("wcf.acp.style.image.error."+e.returnValues.errorType))},_getInnerErrorElement:function(){var t=this._button.next(".innerError");return t.length||(t=$('<small class="innerError" />').insertAfter(this._button)),t}}),WCF.ACP.Style.List=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".styleList .buttonList").each($.proxy(function(t,e){var s=$(e),n=s.data("styleID"),i=this;s.find(".jsSetAsDefault").click(function(t){t.preventDefault(),i._click("setAsDefault",n)}),s.find(".jsDelete").click(function(t){i._delete(t,n)})},this))},_click:function(t,e){this._proxy.setOption("data",{actionName:t,className:"wcf\\data\\style\\StyleAction",objectIDs:[e]}),this._proxy.sendRequest()},_delete:function(t,e){t.preventDefault();var s,n=$(t.currentTarget).data("confirmMessageHtml");n?(s=this,WCF.System.Confirmation.show(n,function(t){"confirm"===t&&s._click("delete",e)},void 0,void 0,!0)):this._click("delete",e)},_success:function(t,e,s){window.location.reload()}});
\ No newline at end of file
index 8b25007f8ede4ba20025ec3461828f35bacad7d6..c3466880274bfabe8166a7316ce5400cde056604 100644 (file)
@@ -1005,6 +1005,8 @@ WCF.ACP.Package.Update.Search = Class.extend({
        
        /**
         * Handles clicks on the search button.
+        * 
+        * @param {Event} event
         */
        _click: function(event) {
                event.preventDefault();
@@ -2068,7 +2070,8 @@ WCF.ACP.Stat.Chart = Class.extend({
                                        $("#chartTooltip").html(item.series.xaxis.tickFormatter(item.datapoint[0], item.series.xaxis) + ', ' + WCF.String.formatNumeric(item.datapoint[1]) + ' ' + item.series.label).show();
                                        UiAlignment.set($("#chartTooltip")[0], span, {
                                                verticalOffset: 5,
-                                               horizontal: 'center'
+                                               horizontal: 'center',
+                                               vertical: 'top'
                                        });
                                }
                                else {
index 4972b930ca4559574ca9884834dda876086463b2..f056a9fa4745b714834ecad39705621b94ae721a 100644 (file)
@@ -1,2 +1 @@
-WCF.ACP={},WCF.ACP.Application={},WCF.ACP.Cronjob={},WCF.ACP.Cronjob.ExecutionHandler=Class.extend({_notification:null,_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsCronjobRow .jsExecuteButton").click($.proxy(this._click,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success"),"success")},_click:function(e){this._proxy.setOption("data",{actionName:"execute",className:"wcf\\data\\cronjob\\CronjobAction",objectIDs:[$(e.target).data("objectID")]}),this._proxy.sendRequest()},_success:function(e,t,a){$(".jsCronjobRow").each($.proxy(function(t,a){var i=$(a).find(".jsExecuteButton"),n=i.data("objectID");if(WCF.inArray(n,e.objectIDs))return e.returnValues[n]&&($(a).find("td.columnNextExec").html(e.returnValues[n].formatted),$(a).wcfHighlight()),this._notification.show(),!1},this))}}),WCF.ACP.Cronjob.LogList=Class.extend({_dialog:null,init:function(){$(".jsCronjobLogDelete").click(function(){WCF.System.Confirmation.show(WCF.Language.get("wcf.acp.cronjob.log.clear.confirm"),function(e){"confirm"==e&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"clearAll",className:"wcf\\data\\cronjob\\log\\CronjobLogAction"},success:function(){window.location.reload()}})})}),$(".jsCronjobError").click($.proxy(this._showError,this))},_showError:function(e){var t=$(e.currentTarget);null===this._dialog?(this._dialog=$('<div style="overflow: auto"><pre>'+t.next().html()+"</pre></div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.cronjob.log.error.details")})):(this._dialog.html("<pre>"+t.next().html()+"</pre>"),this._dialog.wcfDialog("open"))}}),WCF.ACP.Package={},WCF.ACP.Package.Installation=Class.extend({_actionName:"InstallPackage",_additionalRequestParameters:{},_allowRollback:!1,_dialog:null,_dialogTitle:"",_proxy:null,_queueID:0,_shouldRender:!1,init:function(e,t,a,i,n){this._actionName=t||"InstallPackage",this._allowRollback=!0===a,this._queueID=e,this._additionalRequestParameters=n||{},this._dialogTitle="wcf.acp.package."+(i?"update":"install")+".title","UninstallPackage"===this._actionName&&(this._dialogTitle="wcf.acp.package.uninstallation.title"),this._initProxy(),this._init()},_initProxy:function(){for(var e="",t=this._actionName.split(/([A-Z][a-z0-9]+)/),a=0,i=t.length;a<i;a++){var n=t[a];n.length&&(e.length&&(e+="-"),e+=n.toLowerCase())}this._proxy=new WCF.Action.Proxy({failure:$.proxy(this._failure,this),showLoadingOverlay:!1,success:$.proxy(this._success,this),url:"index.php?"+e+"/&t="+SECURITY_TOKEN})},_init:function(){$("#submitButton").click($.proxy(this.prepareInstallation,this))},_failure:function(){null!==this._dialog&&($("#packageInstallationProgress").removeAttr("value"),this._setIcon("times")),this._allowRollback&&null!==this._dialog&&this._purgeTemplateContent($.proxy(function(){var e=$('<div class="formSubmit" />').appendTo($("#packageInstallationInnerContent"));$('<button class="buttonPrimary">'+WCF.Language.get("wcf.acp.package.installation.rollback")+"</button>").appendTo(e).click($.proxy(this._rollback,this)),$("#packageInstallationInnerContentContainer").show(),this._dialog.wcfDialog("render")},this))},_rollback:function(e){this._setIcon("spinner"),e&&$(e.currentTarget).disable(),this._executeStep("rollback")},prepareInstallation:function(){document.activeElement&&document.activeElement.blur(),this._proxy.setOption("data",this._getParameters()),this._proxy.sendRequest()},_getParameters:function(){return $.extend({},this._additionalRequestParameters,{queueID:this._queueID,step:"prepare"})},_success:function(e,t,a){if(this._shouldRender=!1,"function"==typeof window._trackPackageStep&&window._trackPackageStep(this._actionName,e),null===this._dialog&&(this._dialog=$('<div id="package'+("UninstallPackage"===this._actionName?"Uni":"I")+'nstallationDialog" />').hide().appendTo(document.body),this._dialog.wcfDialog({closable:!1,title:WCF.Language.get(this._dialogTitle)})),this._setIcon("spinner"),"rollback"==e.step)return this._dialog.wcfDialog("close"),this._dialog.remove(),void new WCF.PeriodicalExecuter(function(t){t.stop(),(new WCF.ACP.Package.Uninstallation).start(e.packageID)},200);if(e.queueID&&(this._queueID=e.queueID),e.template&&!e.ignoreTemplate&&(this._dialog.html(e.template),this._shouldRender=!0),e.progress&&($("#packageInstallationProgress").attr("value",e.progress).text(e.progress+"%"),$("#packageInstallationProgressLabel").text(e.progress+"%")),e.currentAction&&$("#packageInstallationAction").html(e.currentAction),"success"===e.step)return this._setIcon("check"),void this._purgeTemplateContent($.proxy(function(){var t=$('<div class="formSubmit" />').appendTo($("#packageInstallationInnerContent")),a=$('<button class="buttonPrimary">'+WCF.Language.get("wcf.global.button.next")+"</button>").appendTo(t).click(function(){$(this).disable(),window.location=e.redirectLocation});$("#packageInstallationInnerContentContainer").show(),$(document).keydown(function(e){e.which===$.ui.keyCode.ENTER&&a.trigger("click")}),this._dialog.wcfDialog("render")},this));if(e.innerTemplate){var i=this;if($("#packageInstallationInnerContent").html(e.innerTemplate).find("input").keyup(function(t){t.keyCode===$.ui.keyCode.ENTER&&i._submit(e)}),e.step&&e.node){$("#packageInstallationProgress").removeAttr("value"),this._setIcon("question");var n=$('<div class="formSubmit" />').appendTo($("#packageInstallationInnerContent"));$('<button class="buttonPrimary">'+WCF.Language.get("wcf.global.button.next")+"</button>").appendTo(n).click($.proxy(function(t){$(t.currentTarget).disable(),this._submit(e)},this))}return $("#packageInstallationInnerContentContainer").show(),void this._dialog.wcfDialog("render")}this._purgeTemplateContent($.proxy(function(){this._shouldRender&&this._dialog.wcfDialog("render"),e.step&&e.node&&this._executeStep(e.step,e.node)},this))},_submit:function(e){this._setIcon("spinner");var t={};$("#packageInstallationInnerContent input").each(function(e,a){var i=$(a),n=i.attr("type");if("checkbox"!=n&&"radio"!=n||i.prop("checked")){var s=i.attr("name");s.match(/(.*)\[([^[]*)\]$/)?(s=RegExp.$1,$key=RegExp.$2,void 0===t[s]&&($key?t[s]={}:t[s]=[]),$key?t[s][$key]=i.val():t[s].push(i.val())):t[s]=i.val()}}),this._executeStep(e.step,e.node,t)},_purgeTemplateContent:function(e){$("#packageInstallationInnerContent").children().length&&($("#packageInstallationInnerContentContainer").hide(),$("#packageInstallationInnerContent").empty(),this._shouldRender=!0),e()},_executeStep:function(e,t,a){a||(a={});var i=$.extend({},this._additionalRequestParameters,{node:t,queueID:this._queueID,step:e},a);this._proxy.setOption("data",i),this._proxy.sendRequest()},_setIcon:function(e){this._dialog.find(".jsPackageInstallationStatus").removeClass("fa-check fa-question fa-times fa-spinner").addClass("fa-"+e)}}),WCF.ACP.Package.Installation.Cancel=Class.extend({init:function(e){$("#backButton").click(function(){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"cancelInstallation",className:"wcf\\data\\package\\installation\\queue\\PackageInstallationQueueAction",objectIDs:[e]},success:function(e){window.location=e.returnValues.url}})})}}),WCF.ACP.Package.Uninstallation=WCF.ACP.Package.Installation.extend({_elements:null,_packageID:0,_wcfPackageListURL:"",init:function(e,t){this._elements=e,this._packageID=0,this._wcfPackageListURL=t,void 0!==this._elements&&this._elements.length&&this._super(0,"UninstallPackage")},start:function(e){this._actionName="UninstallPackage",this._packageID=e,this._queueID=0,this._dialogTitle="wcf.acp.package.uninstallation.title",this._initProxy(),this.prepareInstallation()},_init:function(){this._elements.click($.proxy(this._showConfirmationDialog,this))},_showConfirmationDialog:function(e){var t=$(e.currentTarget);if(t.data("isApplication")&&this._wcfPackageListURL)return void(window.location=WCF.String.unescapeHTML(this._wcfPackageListURL.replace(/{packageID}/,t.data("objectID"))));var a=this;WCF.System.Confirmation.show(t.data("confirmMessage"),function(e){"confirm"===e&&(a._packageID=t.data("objectID"),a.prepareInstallation())},void 0,void 0,!0)},_getParameters:function(){return{packageID:this._packageID,step:"prepare"}}}),WCF.ACP.Package.Server={},WCF.ACP.Package.Server.Installation=Class.extend({_proxy:null,_selectedPackage:"",init:function(){this._dialog=null,this._selectedPackage=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},bind:function(){$(".jsButtonPackageInstall").removeClass("jsButtonPackageInstall").click($.proxy(this._click,this))},_click:function(e){var t=$(e.currentTarget);WCF.System.Confirmation.show(t.data("confirmMessage"),$.proxy(function(e){"confirm"===e&&(this._selectedPackage=t.data("package"),this._selectedPackageVersion=t.data("packageVersion"),this._prepareInstallation())},this),void 0,void 0,!0)},_success:function(e){if(e.returnValues.queueID){null!==this._dialog&&this._dialog.wcfDialog("close");new WCF.ACP.Package.Installation(e.returnValues.queueID,void 0,!1).prepareInstallation()}else e.returnValues.template&&(null===this._dialog?(this._dialog=$("<div>"+e.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.update.unauthorized")})):this._dialog.html(e.returnValues.template).wcfDialog("open"),this._dialog.find(".formSubmit > button").click($.proxy(this._submitAuthentication,this)))},_submitAuthentication:function(e){var t=$("#packageUpdateServerUsername"),a=$("#packageUpdateServerPassword");t.next("small.innerError").remove(),a.next("small.innerError").remove();var i=!0;""===$.trim(t.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(t),i=!1),""===$.trim(a.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(a),i=!1),i&&this._prepareInstallation($(e.currentTarget).data("packageUpdateServerID"))},_prepareInstallation:function(e){var t={packages:{}};t.packages[this._selectedPackage]=this._selectedPackageVersion,e&&(t.authData={packageUpdateServerID:e,password:$.trim($("#packageUpdateServerPassword").val()),saveCredentials:!!$("#packageUpdateServerSaveCredentials:checked").length,username:$.trim($("#packageUpdateServerUsername").val())}),this._proxy.setOption("data",{actionName:"prepareInstallation",className:"wcf\\data\\package\\update\\PackageUpdateAction",parameters:t}),this._proxy.sendRequest()}}),WCF.ACP.Package.Update={},WCF.ACP.Package.Update.Manager=Class.extend({_dialog:null,_proxy:null,_submitButton:null,init:function(){this._dialog=null,this._submitButton=$(".formSubmit > button").click($.proxy(this._click,this)),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsPackageUpdate").each($.proxy(function(e,t){var a=$(t);a.find("input[type=checkbox]").data("packageUpdate",a).change($.proxy(this._change,this))},this))},_change:function(e){var t=$(e.currentTarget);t.is(":checked")?(t.data("packageUpdate").find("select").enable(),t.data("packageUpdate").find("dl").removeClass("disabled"),this._submitButton.enable()):(t.data("packageUpdate").find("select").disable(),t.data("packageUpdate").find("dl").addClass("disabled"),$("input[type=checkbox]:checked").length?this._submitButton.enable():this._submitButton.disable())},_click:function(e,t){var a={};if($(".jsPackageUpdate").each($.proxy(function(e,t){var i=$(t);i.find("input[type=checkbox]:checked").length&&(a[i.data("package")]=i.find("select").val())},this)),$.getLength(a)){this._submitButton.disable();var i={packages:a};t&&(i.authData={packageUpdateServerID:t,password:$.trim($("#packageUpdateServerPassword").val()),saveCredentials:!!$("#packageUpdateServerSaveCredentials:checked").length,username:$.trim($("#packageUpdateServerUsername").val())}),this._proxy.setOption("data",{actionName:"prepareUpdate",className:"wcf\\data\\package\\update\\PackageUpdateAction",parameters:i}),this._proxy.sendRequest()}},_success:function(e,t,a){if(e.returnValues.queueID){null!==this._dialog&&this._dialog.wcfDialog("close");new WCF.ACP.Package.Installation(e.returnValues.queueID,void 0,!1,!0).prepareInstallation()}else e.returnValues.excludedPackages?(null===this._dialog?(this._dialog=$("<div>"+e.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.update.excludedPackages")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.acp.package.update.excludedPackages")),this._dialog.html(e.returnValues.template).wcfDialog("open")),this._submitButton.enable()):e.returnValues.template&&(null===this._dialog?(this._dialog=$("<div>"+e.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.update.unauthorized")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.acp.package.update.unauthorized")),this._dialog.html(e.returnValues.template).wcfDialog("open")),this._dialog.find(".formSubmit > button").click($.proxy(this._submitAuthentication,this)))},_submitAuthentication:function(e){var t=$("#packageUpdateServerUsername"),a=$("#packageUpdateServerPassword");t.next("small.innerError").remove(),a.next("small.innerError").remove();var i=!0;""===$.trim(t.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(t),i=!1),""===$.trim(a.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(a),i=!1),i&&this._click(void 0,$(e.currentTarget).data("packageUpdateServerID"))}}),WCF.ACP.Package.Update.Search=Class.extend({_button:null,_dialog:null,init:function(e){this._dialog=null,!0==!e&&$('<li><a href="#" class="button jsButtonSearchForUpdates"><span class="icon icon16 fa-refresh"></span> <span>'+WCF.Language.get("wcf.acp.package.searchForUpdates")+"</span></a></li>").prependTo($(".contentHeaderNavigation > ul")),this._button=elBySel(".jsButtonSearchForUpdates"),this._button&&this._button.addEventListener("click",this._click.bind(this))},_click:function(e){e.preventDefault(),this._button.classList.contains("disabled")||(this._button.classList.add("disabled"),null===this._dialog?new WCF.Action.Proxy({autoSend:!0,data:{actionName:"searchForUpdates",className:"wcf\\data\\package\\update\\PackageUpdateAction",parameters:{ignoreCache:1}},success:$.proxy(this._success,this)}):this._dialog.wcfDialog("open"))},_success:function(e,t,a){if("function"==typeof window._trackSearchForUpdates)return void window._trackSearchForUpdates(e);e.returnValues.url?window.location=e.returnValues.url:(this._dialog=$("<div>"+WCF.Language.get("wcf.acp.package.searchForUpdates.noResults")+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.searchForUpdates")}),this._button.classList.remove("disabled"))}}),WCF.ACP.PluginStore={},WCF.ACP.PluginStore.PurchasedItems={},WCF.ACP.PluginStore.PurchasedItems.Search=Class.extend({_dialog:null,_proxy:null,init:function(){this._dialog=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$('<li><a class="button"><span class="icon icon16 fa-shopping-cart" /> <span>'+WCF.Language.get("wcf.acp.pluginStore.purchasedItems.button.search")+"</span></a></li>").prependTo($(".contentHeaderNavigation > ul")).click($.proxy(this._click,this))},_click:function(){this._proxy.setOption("data",{actionName:"searchForPurchasedItems",className:"wcf\\data\\package\\PackageAction"}),this._proxy.sendRequest()},_success:function(e,t,a){if(e.returnValues.template){null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.template).wcfDialog({title:WCF.Language.get("wcf.acp.pluginStore.authorization")})):(this._dialog.html(e.returnValues.template),this._dialog.wcfDialog("open"));var i=this._dialog.find("button").click($.proxy(this._submit,this));this._dialog.find("input").keyup(function(e){if(e.which==$.ui.keyCode.ENTER)return i.trigger("click"),!1})}else e.returnValues.noResults?null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.noResults).wcfDialog({title:WCF.Language.get("wcf.acp.pluginStore.purchasedItems")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.acp.pluginStore.purchasedItems")),this._dialog.html(e.returnValues.noResults),this._dialog.wcfDialog("open")):e.returnValues.noSSL?null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.noSSL).wcfDialog({title:WCF.Language.get("wcf.global.error.title")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.global.error.title")),this._dialog.html(e.returnValues.noSSL),this._dialog.wcfDialog("open")):e.returnValues.redirectURL&&(window.location=e.returnValues.redirectURL)},_submit:function(){this._dialog.wcfDialog("close"),this._proxy.setOption("data",{actionName:"searchForPurchasedItems",className:"wcf\\data\\package\\PackageAction",parameters:{password:$("#pluginStorePassword").val(),username:$("#pluginStoreUsername").val()}}),this._proxy.sendRequest()}}),WCF.ACP.Worker=Class.extend({init:function(e,t,a,i,n){if("function"==typeof n)throw new Error("The callback parameter is no longer supported, please migrate to 'WoltLabSuite/Core/Acp/Ui/Worker'.");require(["WoltLabSuite/Core/Acp/Ui/Worker"],function(n){new n({dialogId:e,dialogTitle:a,className:t,parameters:i})})}}),WCF.ACP.Category={},WCF.ACP.Category.Collapsible=WCF.Collapsible.SimpleRemote.extend({init:function(e){var t=$('.formSubmit > button[data-type="submit"]');t&&t.click($.proxy(this._sort,this)),this._super(e)},_getButtonContainer:function(e){return $("#"+e+" > .buttons")},_getContainers:function(){return $(".jsCategory").has("ol").has("li")},_getTarget:function(e){return $("#"+e+" > ol")},_sort:function(){$(".collapsibleButton").remove(),this._containers={},this._containerData={};var e=this._getContainers();0==e.length&&console.debug("[WCF.ACP.Category.Collapsible] Empty container set given, aborting."),e.each($.proxy(function(e,t){var a=$(t),i=a.wcfIdentify();this._containers[i]=a,this._initContainer(i)},this))}}),WCF.ACP.Search=WCF.Search.Base.extend({_delay:250,_providerName:"",init:function(){this._className="wcf\\data\\acp\\search\\provider\\ACPSearchProviderAction",this._super("#pageHeaderSearch input[name=q]"),$("#pageHeaderSearch > form").on("submit",function(e){e.preventDefault()}),WCF.Dropdown.getDropdownMenu("pageHeaderSearchType").find("a[data-provider-name]").on("click",$.proxy(function(e){e.preventDefault();var t=$(e.target);$(".pageHeaderSearchType > .button > .pageHeaderSearchTypeLabel").text(t.text());var a=this._providerName;if(this._providerName="everywhere"!=t.data("providerName")?t.data("providerName"):"",a!=this._providerName){var i=$.trim(this._searchInput.val());if(i){var n={data:{excludedSearchValues:this._excludedSearchValues,searchString:i}};this._queryServer(n)}}},this))},_createListItem:function(e){this._list.children("li").length>0&&$('<li class="dropdownDivider" />').appendTo(this._list),$('<li class="dropdownText">'+e.title+"</li>").appendTo(this._list);for(var t in e.items){var a=e.items[t];$('<li><a href="'+a.link+'"><span>'+WCF.String.escapeHTML(a.title)+"</span>"+(a.subtitle?"<small>"+WCF.String.escapeHTML(a.subtitle)+"</small>":"")+"</a></li>").appendTo(this._list),this._itemCount++}},_openDropdown:function(){this._list.find("small").each(function(e,t){for(;t.scrollWidth>t.clientWidth;)t.innerText="… "+t.innerText.substr(3)})},_handleEmptyResult:function(){return $('<li class="dropdownText">'+WCF.Language.get("wcf.acp.search.noResults")+"</li>").appendTo(this._list),!0},_highlightSelectedElement:function(){this._list.find("li").removeClass("dropdownNavigationItem"),this._list.find("li:not(.dropdownDivider):not(.dropdownText)").eq(this._itemIndex).addClass("dropdownNavigationItem")},_selectElement:function(e){if(-1===this._itemIndex)return!1;window.location=this._list.find("li.dropdownNavigationItem > a").attr("href")},_success:function(e){this._super(e);var t=elById("pageHeaderSearch");this._list[0].style.setProperty("top",t.offsetTop+t.clientHeight+"px","important"),this._list.addClass("acpSearchDropdown")},_getParameters:function(e){return e.data.providerName=this._providerName,e}}),WCF.ACP.User={},WCF.ACP.User.BanHandler={_callback:null,_dialog:null,_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsBanButton").click($.proxy(function(e){var t=$(e.currentTarget);t.data("banned")?this.unban([t.data("objectID")]):this.ban([t.data("objectID")])},this)),require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.user",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.user.ban"===e.data.actionName&&this.ban(e.data.parameters.objectIDs)},unban:function(e){this._proxy.setOption("data",{actionName:"unban",className:"wcf\\data\\user\\UserAction",objectIDs:e}),this._proxy.sendRequest()},ban:function(e){null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.append($('<div class="section"><dl><dt><label for="userBanReason">'+WCF.Language.get("wcf.acp.user.banReason")+'</label></dt><dd><textarea id="userBanReason" cols="40" rows="3" /><small>'+WCF.Language.get("wcf.acp.user.banReason.description")+'</small></dd></dl><dl><dt></dt><dd><label for="userBanNeverExpires"><input type="checkbox" name="userBanNeverExpires" id="userBanNeverExpires" checked> '+WCF.Language.get("wcf.acp.user.ban.neverExpires")+'</label></dd></dl><dl id="userBanExpiresSettings" style="display: none;"><dt><label for="userBanExpires">'+WCF.Language.get("wcf.acp.user.ban.expires")+'</label></dt><dd><input type="date" name="userBanExpires" id="userBanExpires" class="medium" min="'+new Date(1e3*TIME_NOW).toISOString()+'" data-ignore-timezone="true" /><small>'+WCF.Language.get("wcf.acp.user.ban.expires.description")+"</small></dd></dl></div>")),this._dialog.append($('<div class="formSubmit"><button class="buttonPrimary" accesskey="s">'+WCF.Language.get("wcf.global.button.submit")+"</button></div>")),this._dialog.find("#userBanNeverExpires").change(function(){$("#userBanExpiresSettings").toggle()}),this._dialog.find("button").click($.proxy(this._submit,this))):($("#userBanReason").val(""),$("#userBanNeverExpires").prop("checked",!0),$("#userBanExpiresSettings").hide(),$("#userBanExpiresDatePicker, #userBanExpires").val("")),this._dialog.data("userIDs",e),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.user.ban.sure")})},_submit:function(){this._dialog.find(".innerError").remove();var e="";if(!$("#userBanNeverExpires").is(":checked")){var e=$("#userBanExpiresDatePicker").val();if(!e)return void this._dialog.find("#userBanExpiresSettings > dd > small").prepend($('<small class="innerError" />').text(WCF.Language.get("wcf.global.form.error.empty")))}this._proxy.setOption("data",{actionName:"ban",className:"wcf\\data\\user\\UserAction",objectIDs:this._dialog.data("userIDs"),parameters:{banReason:$("#userBanReason").val(),banExpires:e}}),this._proxy.sendRequest()},_success:function(e,t,a){elBySelAll(".jsUserRow",void 0,function(t){var a=parseInt(elData(t,"object-id"),10);-1!==e.objectIDs.indexOf(a)&&elData(t,"banned","ban"===e.actionName)}),$(".jsBanButton").each(function(t,a){var i=$(a);WCF.inArray(i.data("objectID"),e.objectIDs)&&("unban"==e.actionName?i.data("banned",!1).attr("data-tooltip",i.data("banMessage")).removeClass("fa-lock").addClass("fa-unlock"):i.data("banned",!0).attr("data-tooltip",i.data("unbanMessage")).removeClass("fa-unlock").addClass("fa-lock"))}),(new WCF.System.Notification).show(),WCF.Clipboard.reload(),"ban"==e.actionName&&this._dialog.wcfDialog("close"),WCF.System.Event.fireEvent("com.woltlab.wcf.acp.user","refresh",{userIds:e.objectIDs})}},WCF.ACP.User.Group={},WCF.ACP.User.Group.Copy=Class.extend({_groupID:0,init:function(e){this._groupID=e,$(".jsButtonUserGroupCopy").click($.proxy(this._click,this))},_click:function(){var e=$('<div class="section" />');e.append($('<dl class="wide"><dt /><dd><label><input type="checkbox" id="copyMembers" value="1" /> '+WCF.Language.get("wcf.acp.group.copy.copyMembers")+"</label><small>"+WCF.Language.get("wcf.acp.group.copy.copyMembers.description")+"</small></dd></dl>")),e.append($('<dl class="wide"><dt /><dd><label><input type="checkbox" id="copyUserGroupOptions" value="1" /> '+WCF.Language.get("wcf.acp.group.copy.copyUserGroupOptions")+"</label><small>"+WCF.Language.get("wcf.acp.group.copy.copyUserGroupOptions.description")+"</small></dd></dl>")),e.append($('<dl class="wide"><dt /><dd><label><input type="checkbox" id="copyACLOptions" value="1" /> '+WCF.Language.get("wcf.acp.group.copy.copyACLOptions")+"</label><small>"+WCF.Language.get("wcf.acp.group.copy.copyACLOptions.description")+"</small></dd></dl>")),WCF.System.Confirmation.show(WCF.Language.get("wcf.acp.group.copy.confirmMessage"),$.proxy(function(e){"confirm"===e&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"copy",className:"wcf\\data\\user\\group\\UserGroupAction",objectIDs:[this._groupID],parameters:{copyACLOptions:$("#copyACLOptions").is(":checked"),copyMembers:$("#copyMembers").is(":checked"),copyUserGroupOptions:$("#copyUserGroupOptions").is(":checked")}},success:function(e){window.location=e.returnValues.redirectURL}})},this),"",e,!0)}}),WCF.ACP.User.EnableHandler={_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsEnableButton").click($.proxy(function(e){var t=$(e.currentTarget);t.data("enabled")?this.disable([t.data("objectID")]):this.enable([t.data("objectID")])},this)),require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.user",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.user.enable"===e.data.actionName&&this.enable(e.data.parameters.objectIDs)},disable:function(e){this._proxy.setOption("data",{actionName:"disable",className:"wcf\\data\\user\\UserAction",objectIDs:e}),this._proxy.sendRequest()},enable:function(e){this._proxy.setOption("data",{actionName:"enable",className:"wcf\\data\\user\\UserAction",objectIDs:e}),this._proxy.sendRequest()},_success:function(e,t,a){elBySelAll(".jsUserRow",void 0,function(t){var a=parseInt(elData(t,"object-id"),10);-1!==e.objectIDs.indexOf(a)&&elData(t,"enabled","enable"===e.actionName)}),$(".jsEnableButton").each(function(t,a){var i=$(a);WCF.inArray(i.data("objectID"),e.objectIDs)&&("disable"==e.actionName?i.data("enabled",!1).attr("data-tooltip",i.data("enableMessage")).removeClass("fa-check-square-o").addClass("fa-square-o"):i.data("enabled",!0).attr("data-tooltip",i.data("disableMessage")).removeClass("fa-square-o").addClass("fa-check-square-o"))}),(new WCF.System.Notification).show(function(){window.location.reload()}),WCF.System.Event.fireEvent("com.woltlab.wcf.acp.user","refresh",{userIds:e.objectIDs})}},WCF.ACP.User.SendNewPasswordHandler={init:function(){require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.user",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.user.sendNewPassword"===e.data.actionName&&WCF.System.Confirmation.show(e.data.parameters.confirmMessage,function(t){"confirm"===t&&new WCF.ACP.Worker("sendingNewPasswords","wcf\\system\\worker\\SendNewPasswordWorker",WCF.Language.get("wcf.acp.user.sendNewPassword.workerTitle"),{userIDs:e.data.parameters.objectIDs})})}},WCF.ACP.Import={},WCF.ACP.Import.Manager=Class.extend({_currentAction:"",_dialog:null,_index:-1,_objectTypes:[],_proxy:null,_redirectURL:"",init:function(e,t){this._currentAction="",this._index=-1,this._objectTypes=e,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this),url:"index.php?worker-proxy/&t="+SECURITY_TOKEN}),this._redirectURL=t,this._invoke()},_invoke:function(){if(++this._index>=this._objectTypes.length){this._dialog.find(".fa-spinner").removeClass("fa-spinner").addClass("fa-check"),this._dialog.find("h1").text(WCF.Language.get("wcf.acp.dataImport.completed"));var e=$('<div class="formSubmit" />').appendTo(this._dialog.find("#workerContainer"));$("<button>"+WCF.Language.get("wcf.global.button.next")+"</button>").click($.proxy(function(){new WCF.Action.Proxy({autoSend:!0,data:{noRedirect:1},dataType:"html",success:$.proxy(function(){window.location=this._redirectURL},this),url:"index.php?cache-clear/&t="+SECURITY_TOKEN})},this)).appendTo(e),this._dialog.wcfDialog("render")}else this._run(WCF.Language.get("wcf.acp.dataImport.data."+this._objectTypes[this._index]),this._objectTypes[this._index])},_run:function(e,t){this._currentAction=e,this._proxy.setOption("data",{className:"wcf\\system\\worker\\ImportWorker",parameters:{objectType:t}}),this._proxy.sendRequest()},_success:function(e){null===this._dialog&&(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.wcfDialog({closable:!1,title:WCF.Language.get("wcf.acp.dataImport")})),e.template&&this._dialog.html(e.template),this._currentAction&&this._dialog.find("h1").text(this._currentAction),this._dialog.find("progress").attr("value",e.progress).text(e.progress+"%").next("span").text(e.progress+"%"),e.progress<100?(this._proxy.setOption("data",{className:e.className,loopCount:e.loopCount,parameters:e.parameters}),this._proxy.sendRequest()):this._invoke()}}),WCF.ACP.Stat={},WCF.ACP.Stat.Chart=Class.extend({init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$("#statRefreshButton").click($.proxy(this._refresh,this)),this._refresh()},_refresh:function(){var e=[];$("input[name=objectTypeID]:checked").each(function(){e.push($(this).val())}),e.length&&(this._proxy.setOption("data",{className:"wcf\\data\\stat\\daily\\StatDailyAction",actionName:"getData",parameters:{startDate:$("#startDateDatePicker").val(),endDate:$("#endDateDatePicker").val(),value:$("input[name=value]:checked").val(),dateGrouping:$("input[name=dateGrouping]:checked").val(),objectTypeIDs:e}}),this._proxy.sendRequest())},_success:function(e){switch($("input[name=dateGrouping]:checked").val()){case"yearly":var t=[1,"year"],a=WCF.Language.get("wcf.acp.stat.timeFormat.yearly");break;case"monthly":var t=[1,"month"],a=WCF.Language.get("wcf.acp.stat.timeFormat.monthly");break;case"weekly":var t=[7,"day"],a=WCF.Language.get("wcf.acp.stat.timeFormat.weekly");break;default:var t=[1,"day"],a=WCF.Language.get("wcf.acp.stat.timeFormat.daily")}var i={series:{lines:{show:!0},points:{show:!0}},grid:{hoverable:!0},xaxis:{mode:"time",minTickSize:t,timeformat:a,monthNames:WCF.Language.get("__monthsShort")},yaxis:{min:0,tickDecimals:0,tickFormatter:function(e){return WCF.String.addThousandsSeparator(e)}}},n=[];for(var s in e.returnValues){for(var o=e.returnValues[s],r=0;r<o.data.length;r++)o.data[r][0]*=1e3;n.push(o)}$.plot("#chart",n,i),require(["Ui/Alignment"],function(e){var t=elCreate("span");t.style.setProperty("position","absolute",""),document.body.appendChild(t),$("#chart").on("plothover",function(a,i,n){n?(t.style.setProperty("top",n.pageY+"px",""),t.style.setProperty("left",n.pageX+"px",""),$("#chartTooltip").html(n.series.xaxis.tickFormatter(n.datapoint[0],n.series.xaxis)+", "+WCF.String.formatNumeric(n.datapoint[1])+" "+n.series.label).show(),e.set($("#chartTooltip")[0],t,{verticalOffset:5,horizontal:"center"})):$("#chartTooltip").hide()})}),n.length||$("#chart").append('<p style="position: absolute; font-size: 1.2rem; text-align: center; top: 50%; margin-top: -20px; width: 100%">'+WCF.Language.get("wcf.acp.stat.noData")+"</p>"),elBySel(".contentHeader > .contentTitle").scrollIntoView({behavior:"smooth"})}}),WCF.ACP.Ad={},WCF.ACP.Ad.LocationHandler=Class.extend({_pageConditions:null,_pageInputs:[],_pageSelectionContainer:null,init:function(e){this._variablesDescriptions=e,
-this._pageConditions=$("#pageConditions"),this._pageInputs=$('input[name="pageIDs[]"]'),this._variablesDescriptionsList=$("#ad").next("small").children("ul"),this._pageSelectionContainer=$(this._pageInputs[0]).parents("dl:eq(0)"),this._hidePageSelection(!0),$("#objectTypeID").on("change",$.proxy(this._setPageController,this)),this._setPageController(),$("#adForm").submit($.proxy(this._submit,this))},_hidePageSelection:function(e){this._pageSelectionContainer.prev("dl").hide(),this._pageSelectionContainer.hide(),this._pageSelectionContainer.next("dl").css("margin-top",0);var t=this._pageSelectionContainer.parent("section");if(!t.children("dl:visible").length){t.hide();var a=t.next("section");a&&(a.css("margin-top",0),e&&require(["EventHandler"],function(e){e.add("com.woltlab.wcf.pageConditionDependence","checkVisivility",function(){t.is(":visible")?a.css("margin-top","40px"):a.css("margin-top",0)})}))}},_showPageSelection:function(){this._pageSelectionContainer.prev("dl").show(),this._pageSelectionContainer.show(),this._pageSelectionContainer.next("dl").css("margin-top","40px");var e=this._pageSelectionContainer.parent("section");e.show();var t=e.next("section");t&&t.css("margin-top","40px")},_setPageController:function(){var e=$("#objectTypeID").find("option:checked"),t=e.parent();t.is("optgroup")&&"com.woltlab.wcf.global"===t.data("categoryName")?this._showPageSelection():(this._hidePageSelection(),require(["Core"],function(t){for(var a,i,n=0,s=this._pageInputs.length;n<s;n++)a=this._pageInputs[n],i=!1,e.data("page")&&elData(a,"identifier")===e.data("page")?(a.checked||(i=!0),a.checked=!0):(a.checked&&(i=!0),a.checked=!1),i&&t.triggerEvent(this._pageInputs[n],"change")}.bind(this))),this._variablesDescriptionsList.children(":not(.jsDefaultItem)").remove();var a=$("#objectTypeID").val();a in this._variablesDescriptions&&(this._variablesDescriptionsList[0].innerHTML+=this._variablesDescriptions[a])},_submit:function(){if(this._pageConditions.is(":hidden"))this._pageConditions.find("select, input").remove();else if(this._pageSelectionContainer.is(":hidden"))for(var e=0,t=this._pageInputs.length;e<t;e++)this._pageInputs[e].checked=!1}}),WCF.ACP.Tag={},WCF.ACP.Tag.SetAsSynonymsHandler=Class.extend({_dialog:null,_objectIDs:[],init:function(){require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.tag",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.tag.setAsSynonyms"===e.data.actionName&&(this._objectIDs=e.data.parameters.objectIDs,null===this._dialog&&(this._dialog=$('<div id="setAsSynonymsDialog" />').hide().appendTo(document.body),this._dialog.wcfDialog({closable:!1,title:WCF.Language.get("wcf.acp.tag.setAsSynonyms")})),this._dialog.html(e.data.parameters.template),$button=this._dialog.find('button[data-type="submit"]').disable().click($.proxy(this._submit,this)),this._dialog.find("input[type=radio]").change(function(){$button.enable()}))},_submit:function(){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"setAsSynonyms",className:"wcf\\data\\tag\\TagAction",objectIDs:this._objectIDs,parameters:{tagID:this._dialog.find('input[name="tagID"]:checked').val()}},success:$.proxy(function(){this._dialog.wcfDialog("close"),(new WCF.System.Notification).show(function(){window.location.reload()})},this)})}});
\ No newline at end of file
+WCF.ACP={},WCF.ACP.Application={},WCF.ACP.Cronjob={},WCF.ACP.Cronjob.ExecutionHandler=Class.extend({_notification:null,_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsCronjobRow .jsExecuteButton").click($.proxy(this._click,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success"),"success")},_click:function(e){this._proxy.setOption("data",{actionName:"execute",className:"wcf\\data\\cronjob\\CronjobAction",objectIDs:[$(e.target).data("objectID")]}),this._proxy.sendRequest()},_success:function(i,e,t){$(".jsCronjobRow").each($.proxy(function(e,t){var a=$(t).find(".jsExecuteButton").data("objectID");if(WCF.inArray(a,i.objectIDs))return i.returnValues[a]&&($(t).find("td.columnNextExec").html(i.returnValues[a].formatted),$(t).wcfHighlight()),this._notification.show(),!1},this))}}),WCF.ACP.Cronjob.LogList=Class.extend({_dialog:null,init:function(){$(".jsCronjobLogDelete").click(function(){WCF.System.Confirmation.show(WCF.Language.get("wcf.acp.cronjob.log.clear.confirm"),function(e){"confirm"==e&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"clearAll",className:"wcf\\data\\cronjob\\log\\CronjobLogAction"},success:function(){window.location.reload()}})})}),$(".jsCronjobError").click($.proxy(this._showError,this))},_showError:function(e){var t=$(e.currentTarget);null===this._dialog?(this._dialog=$('<div style="overflow: auto"><pre>'+t.next().html()+"</pre></div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.cronjob.log.error.details")})):(this._dialog.html("<pre>"+t.next().html()+"</pre>"),this._dialog.wcfDialog("open"))}}),WCF.ACP.Package={},WCF.ACP.Package.Installation=Class.extend({_actionName:"InstallPackage",_additionalRequestParameters:{},_allowRollback:!1,_dialog:null,_dialogTitle:"",_proxy:null,_queueID:0,_shouldRender:!1,init:function(e,t,a,i,n){this._actionName=t||"InstallPackage",this._allowRollback=!0===a,this._queueID=e,this._additionalRequestParameters=n||{},this._dialogTitle="wcf.acp.package."+(i?"update":"install")+".title","UninstallPackage"===this._actionName&&(this._dialogTitle="wcf.acp.package.uninstallation.title"),this._initProxy(),this._init()},_initProxy:function(){for(var e="",t=this._actionName.split(/([A-Z][a-z0-9]+)/),a=0,i=t.length;a<i;a++){var n=t[a];n.length&&(e.length&&(e+="-"),e+=n.toLowerCase())}this._proxy=new WCF.Action.Proxy({failure:$.proxy(this._failure,this),showLoadingOverlay:!1,success:$.proxy(this._success,this),url:"index.php?"+e+"/&t="+SECURITY_TOKEN})},_init:function(){$("#submitButton").click($.proxy(this.prepareInstallation,this))},_failure:function(){null!==this._dialog&&($("#packageInstallationProgress").removeAttr("value"),this._setIcon("times")),this._allowRollback&&null!==this._dialog&&this._purgeTemplateContent($.proxy(function(){var e=$('<div class="formSubmit" />').appendTo($("#packageInstallationInnerContent"));$('<button class="buttonPrimary">'+WCF.Language.get("wcf.acp.package.installation.rollback")+"</button>").appendTo(e).click($.proxy(this._rollback,this)),$("#packageInstallationInnerContentContainer").show(),this._dialog.wcfDialog("render")},this))},_rollback:function(e){this._setIcon("spinner"),e&&$(e.currentTarget).disable(),this._executeStep("rollback")},prepareInstallation:function(){document.activeElement&&document.activeElement.blur(),this._proxy.setOption("data",this._getParameters()),this._proxy.sendRequest()},_getParameters:function(){return $.extend({},this._additionalRequestParameters,{queueID:this._queueID,step:"prepare"})},_success:function(a,e,t){if(this._shouldRender=!1,"function"==typeof window._trackPackageStep&&window._trackPackageStep(this._actionName,a),null===this._dialog&&(this._dialog=$('<div id="package'+("UninstallPackage"===this._actionName?"Uni":"I")+'nstallationDialog" />').hide().appendTo(document.body),this._dialog.wcfDialog({closable:!1,title:WCF.Language.get(this._dialogTitle)})),this._setIcon("spinner"),"rollback"==a.step)return this._dialog.wcfDialog("close"),this._dialog.remove(),void new WCF.PeriodicalExecuter(function(e){e.stop(),(new WCF.ACP.Package.Uninstallation).start(a.packageID)},200);if(a.queueID&&(this._queueID=a.queueID),a.template&&!a.ignoreTemplate&&(this._dialog.html(a.template),this._shouldRender=!0),a.progress&&($("#packageInstallationProgress").attr("value",a.progress).text(a.progress+"%"),$("#packageInstallationProgressLabel").text(a.progress+"%")),a.currentAction&&$("#packageInstallationAction").html(a.currentAction),"success"===a.step)return this._setIcon("check"),void this._purgeTemplateContent($.proxy(function(){var e=$('<div class="formSubmit" />').appendTo($("#packageInstallationInnerContent")),t=$('<button class="buttonPrimary">'+WCF.Language.get("wcf.global.button.next")+"</button>").appendTo(e).click(function(){$(this).disable(),window.location=a.redirectLocation});$("#packageInstallationInnerContentContainer").show(),$(document).keydown(function(e){e.which===$.ui.keyCode.ENTER&&t.trigger("click")}),this._dialog.wcfDialog("render")},this));if(a.innerTemplate){var i,n=this;return $("#packageInstallationInnerContent").html(a.innerTemplate).find("input").keyup(function(e){e.keyCode===$.ui.keyCode.ENTER&&n._submit(a)}),a.step&&a.node&&($("#packageInstallationProgress").removeAttr("value"),this._setIcon("question"),i=$('<div class="formSubmit" />').appendTo($("#packageInstallationInnerContent")),$('<button class="buttonPrimary">'+WCF.Language.get("wcf.global.button.next")+"</button>").appendTo(i).click($.proxy(function(e){$(e.currentTarget).disable(),this._submit(a)},this))),$("#packageInstallationInnerContentContainer").show(),void this._dialog.wcfDialog("render")}this._purgeTemplateContent($.proxy(function(){this._shouldRender&&this._dialog.wcfDialog("render"),a.step&&a.node&&this._executeStep(a.step,a.node)},this))},_submit:function(e){this._setIcon("spinner");var s={};$("#packageInstallationInnerContent input").each(function(e,t){var a,i=$(t),n=i.attr("type");("checkbox"!=n&&"radio"!=n||i.prop("checked"))&&((a=i.attr("name")).match(/(.*)\[([^[]*)\]$/)?(a=RegExp.$1,$key=RegExp.$2,void 0===s[a]&&($key?s[a]={}:s[a]=[]),$key?s[a][$key]=i.val():s[a].push(i.val())):s[a]=i.val())}),this._executeStep(e.step,e.node,s)},_purgeTemplateContent:function(e){$("#packageInstallationInnerContent").children().length&&($("#packageInstallationInnerContentContainer").hide(),$("#packageInstallationInnerContent").empty(),this._shouldRender=!0),e()},_executeStep:function(e,t,a){a=a||{};var i=$.extend({},this._additionalRequestParameters,{node:t,queueID:this._queueID,step:e},a);this._proxy.setOption("data",i),this._proxy.sendRequest()},_setIcon:function(e){this._dialog.find(".jsPackageInstallationStatus").removeClass("fa-check fa-question fa-times fa-spinner").addClass("fa-"+e)}}),WCF.ACP.Package.Installation.Cancel=Class.extend({init:function(e){$("#backButton").click(function(){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"cancelInstallation",className:"wcf\\data\\package\\installation\\queue\\PackageInstallationQueueAction",objectIDs:[e]},success:function(e){window.location=e.returnValues.url}})})}}),WCF.ACP.Package.Uninstallation=WCF.ACP.Package.Installation.extend({_elements:null,_packageID:0,_wcfPackageListURL:"",init:function(e,t){this._elements=e,this._packageID=0,this._wcfPackageListURL=t,void 0!==this._elements&&this._elements.length&&this._super(0,"UninstallPackage")},start:function(e){this._actionName="UninstallPackage",this._packageID=e,this._queueID=0,this._dialogTitle="wcf.acp.package.uninstallation.title",this._initProxy(),this.prepareInstallation()},_init:function(){this._elements.click($.proxy(this._showConfirmationDialog,this))},_showConfirmationDialog:function(e){var t,a=$(e.currentTarget);a.data("isApplication")&&this._wcfPackageListURL?window.location=WCF.String.unescapeHTML(this._wcfPackageListURL.replace(/{packageID}/,a.data("objectID"))):(t=this,WCF.System.Confirmation.show(a.data("confirmMessage"),function(e){"confirm"===e&&(t._packageID=a.data("objectID"),t.prepareInstallation())},void 0,void 0,!0))},_getParameters:function(){return{packageID:this._packageID,step:"prepare"}}}),WCF.ACP.Package.Server={},WCF.ACP.Package.Server.Installation=Class.extend({_proxy:null,_selectedPackage:"",init:function(){this._dialog=null,this._selectedPackage=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},bind:function(){$(".jsButtonPackageInstall").removeClass("jsButtonPackageInstall").click($.proxy(this._click,this))},_click:function(e){var t=$(e.currentTarget);WCF.System.Confirmation.show(t.data("confirmMessage"),$.proxy(function(e){"confirm"===e&&(this._selectedPackage=t.data("package"),this._selectedPackageVersion=t.data("packageVersion"),this._prepareInstallation())},this),void 0,void 0,!0)},_success:function(e){e.returnValues.queueID?(null!==this._dialog&&this._dialog.wcfDialog("close"),new WCF.ACP.Package.Installation(e.returnValues.queueID,void 0,!1).prepareInstallation()):e.returnValues.template&&(null===this._dialog?(this._dialog=$("<div>"+e.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.update.unauthorized")})):this._dialog.html(e.returnValues.template).wcfDialog("open"),this._dialog.find(".formSubmit > button").click($.proxy(this._submitAuthentication,this)))},_submitAuthentication:function(e){var t=$("#packageUpdateServerUsername"),a=$("#packageUpdateServerPassword");t.next("small.innerError").remove(),a.next("small.innerError").remove();var i=!0;""===$.trim(t.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(t),i=!1),""===$.trim(a.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(a),i=!1),i&&this._prepareInstallation($(e.currentTarget).data("packageUpdateServerID"))},_prepareInstallation:function(e){var t={packages:{}};t.packages[this._selectedPackage]=this._selectedPackageVersion,e&&(t.authData={packageUpdateServerID:e,password:$.trim($("#packageUpdateServerPassword").val()),saveCredentials:!!$("#packageUpdateServerSaveCredentials:checked").length,username:$.trim($("#packageUpdateServerUsername").val())}),this._proxy.setOption("data",{actionName:"prepareInstallation",className:"wcf\\data\\package\\update\\PackageUpdateAction",parameters:t}),this._proxy.sendRequest()}}),WCF.ACP.Package.Update={},WCF.ACP.Package.Update.Manager=Class.extend({_dialog:null,_proxy:null,_submitButton:null,init:function(){this._dialog=null,this._submitButton=$(".formSubmit > button").click($.proxy(this._click,this)),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsPackageUpdate").each($.proxy(function(e,t){var a=$(t);a.find("input[type=checkbox]").data("packageUpdate",a).change($.proxy(this._change,this))},this))},_change:function(e){var t=$(e.currentTarget);t.is(":checked")?(t.data("packageUpdate").find("select").enable(),t.data("packageUpdate").find("dl").removeClass("disabled"),this._submitButton.enable()):(t.data("packageUpdate").find("select").disable(),t.data("packageUpdate").find("dl").addClass("disabled"),$("input[type=checkbox]:checked").length?this._submitButton.enable():this._submitButton.disable())},_click:function(e,t){var a,i={};$(".jsPackageUpdate").each($.proxy(function(e,t){var a=$(t);a.find("input[type=checkbox]:checked").length&&(i[a.data("package")]=a.find("select").val())},this)),$.getLength(i)&&(this._submitButton.disable(),a={packages:i},t&&(a.authData={packageUpdateServerID:t,password:$.trim($("#packageUpdateServerPassword").val()),saveCredentials:!!$("#packageUpdateServerSaveCredentials:checked").length,username:$.trim($("#packageUpdateServerUsername").val())}),this._proxy.setOption("data",{actionName:"prepareUpdate",className:"wcf\\data\\package\\update\\PackageUpdateAction",parameters:a}),this._proxy.sendRequest())},_success:function(e,t,a){e.returnValues.queueID?(null!==this._dialog&&this._dialog.wcfDialog("close"),new WCF.ACP.Package.Installation(e.returnValues.queueID,void 0,!1,!0).prepareInstallation()):e.returnValues.excludedPackages?(null===this._dialog?(this._dialog=$("<div>"+e.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.update.excludedPackages")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.acp.package.update.excludedPackages")),this._dialog.html(e.returnValues.template).wcfDialog("open")),this._submitButton.enable()):e.returnValues.template&&(null===this._dialog?(this._dialog=$("<div>"+e.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.update.unauthorized")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.acp.package.update.unauthorized")),this._dialog.html(e.returnValues.template).wcfDialog("open")),this._dialog.find(".formSubmit > button").click($.proxy(this._submitAuthentication,this)))},_submitAuthentication:function(e){var t=$("#packageUpdateServerUsername"),a=$("#packageUpdateServerPassword");t.next("small.innerError").remove(),a.next("small.innerError").remove();var i=!0;""===$.trim(t.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(t),i=!1),""===$.trim(a.val())&&($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(a),i=!1),i&&this._click(void 0,$(e.currentTarget).data("packageUpdateServerID"))}}),WCF.ACP.Package.Update.Search=Class.extend({_button:null,_dialog:null,init:function(e){!(this._dialog=null)==!e&&$('<li><a href="#" class="button jsButtonSearchForUpdates"><span class="icon icon16 fa-refresh"></span> <span>'+WCF.Language.get("wcf.acp.package.searchForUpdates")+"</span></a></li>").prependTo($(".contentHeaderNavigation > ul")),this._button=elBySel(".jsButtonSearchForUpdates"),this._button&&this._button.addEventListener("click",this._click.bind(this))},_click:function(e){e.preventDefault(),this._button.classList.contains("disabled")||(this._button.classList.add("disabled"),null===this._dialog?new WCF.Action.Proxy({autoSend:!0,data:{actionName:"searchForUpdates",className:"wcf\\data\\package\\update\\PackageUpdateAction",parameters:{ignoreCache:1}},success:$.proxy(this._success,this)}):this._dialog.wcfDialog("open"))},_success:function(e,t,a){"function"!=typeof window._trackSearchForUpdates?e.returnValues.url?window.location=e.returnValues.url:(this._dialog=$("<div>"+WCF.Language.get("wcf.acp.package.searchForUpdates.noResults")+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.package.searchForUpdates")}),this._button.classList.remove("disabled")):window._trackSearchForUpdates(e)}}),WCF.ACP.PluginStore={},WCF.ACP.PluginStore.PurchasedItems={},WCF.ACP.PluginStore.PurchasedItems.Search=Class.extend({_dialog:null,_proxy:null,init:function(){this._dialog=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$('<li><a class="button"><span class="icon icon16 fa-shopping-cart" /> <span>'+WCF.Language.get("wcf.acp.pluginStore.purchasedItems.button.search")+"</span></a></li>").prependTo($(".contentHeaderNavigation > ul")).click($.proxy(this._click,this))},_click:function(){this._proxy.setOption("data",{actionName:"searchForPurchasedItems",className:"wcf\\data\\package\\PackageAction"}),this._proxy.sendRequest()},_success:function(e,t,a){var i;e.returnValues.template?(null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.template).wcfDialog({title:WCF.Language.get("wcf.acp.pluginStore.authorization")})):(this._dialog.html(e.returnValues.template),this._dialog.wcfDialog("open")),i=this._dialog.find("button").click($.proxy(this._submit,this)),this._dialog.find("input").keyup(function(e){if(e.which==$.ui.keyCode.ENTER)return i.trigger("click"),!1})):e.returnValues.noResults?null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.noResults).wcfDialog({title:WCF.Language.get("wcf.acp.pluginStore.purchasedItems")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.acp.pluginStore.purchasedItems")),this._dialog.html(e.returnValues.noResults),this._dialog.wcfDialog("open")):e.returnValues.noSSL?null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.noSSL).wcfDialog({title:WCF.Language.get("wcf.global.error.title")})):(this._dialog.wcfDialog("option","title",WCF.Language.get("wcf.global.error.title")),this._dialog.html(e.returnValues.noSSL),this._dialog.wcfDialog("open")):e.returnValues.redirectURL&&(window.location=e.returnValues.redirectURL)},_submit:function(){this._dialog.wcfDialog("close"),this._proxy.setOption("data",{actionName:"searchForPurchasedItems",className:"wcf\\data\\package\\PackageAction",parameters:{password:$("#pluginStorePassword").val(),username:$("#pluginStoreUsername").val()}}),this._proxy.sendRequest()}}),WCF.ACP.Worker=Class.extend({init:function(t,a,i,n,e){if("function"==typeof e)throw new Error("The callback parameter is no longer supported, please migrate to 'WoltLabSuite/Core/Acp/Ui/Worker'.");require(["WoltLabSuite/Core/Acp/Ui/Worker"],function(e){new e({dialogId:t,dialogTitle:i,className:a,parameters:n})})}}),WCF.ACP.Category={},WCF.ACP.Category.Collapsible=WCF.Collapsible.SimpleRemote.extend({init:function(e){var t=$('.formSubmit > button[data-type="submit"]');t&&t.click($.proxy(this._sort,this)),this._super(e)},_getButtonContainer:function(e){return $("#"+e+" > .buttons")},_getContainers:function(){return $(".jsCategory").has("ol").has("li")},_getTarget:function(e){return $("#"+e+" > ol")},_sort:function(){$(".collapsibleButton").remove(),this._containers={},this._containerData={};var e=this._getContainers();0==e.length&&console.debug("[WCF.ACP.Category.Collapsible] Empty container set given, aborting."),e.each($.proxy(function(e,t){var a=$(t),i=a.wcfIdentify();this._containers[i]=a,this._initContainer(i)},this))}}),WCF.ACP.Search=WCF.Search.Base.extend({_delay:250,_providerName:"",init:function(){this._className="wcf\\data\\acp\\search\\provider\\ACPSearchProviderAction",this._super("#pageHeaderSearch input[name=q]"),$("#pageHeaderSearch > form").on("submit",function(e){e.preventDefault()}),WCF.Dropdown.getDropdownMenu("pageHeaderSearchType").find("a[data-provider-name]").on("click",$.proxy(function(e){e.preventDefault();var t=$(e.target);$(".pageHeaderSearchType > .button > .pageHeaderSearchTypeLabel").text(t.text());var a,i,n=this._providerName;this._providerName="everywhere"!=t.data("providerName")?t.data("providerName"):"",n==this._providerName||(a=$.trim(this._searchInput.val()))&&(i={data:{excludedSearchValues:this._excludedSearchValues,searchString:a}},this._queryServer(i))},this))},_createListItem:function(e){for(var t in 0<this._list.children("li").length&&$('<li class="dropdownDivider" />').appendTo(this._list),$('<li class="dropdownText">'+e.title+"</li>").appendTo(this._list),e.items){var a=e.items[t];$('<li><a href="'+a.link+'"><span>'+WCF.String.escapeHTML(a.title)+"</span>"+(a.subtitle?"<small>"+WCF.String.escapeHTML(a.subtitle)+"</small>":"")+"</a></li>").appendTo(this._list),this._itemCount++}},_openDropdown:function(){this._list.find("small").each(function(e,t){for(;t.scrollWidth>t.clientWidth;)t.innerText="… "+t.innerText.substr(3)})},_handleEmptyResult:function(){return $('<li class="dropdownText">'+WCF.Language.get("wcf.acp.search.noResults")+"</li>").appendTo(this._list),!0},_highlightSelectedElement:function(){this._list.find("li").removeClass("dropdownNavigationItem"),this._list.find("li:not(.dropdownDivider):not(.dropdownText)").eq(this._itemIndex).addClass("dropdownNavigationItem")},_selectElement:function(e){if(-1===this._itemIndex)return!1;window.location=this._list.find("li.dropdownNavigationItem > a").attr("href")},_success:function(e){this._super(e);var t=elById("pageHeaderSearch");this._list[0].style.setProperty("top",t.offsetTop+t.clientHeight+"px","important"),this._list.addClass("acpSearchDropdown")},_getParameters:function(e){return e.data.providerName=this._providerName,e}}),WCF.ACP.User={},WCF.ACP.User.BanHandler={_callback:null,_dialog:null,_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsBanButton").click($.proxy(function(e){var t=$(e.currentTarget);t.data("banned")?this.unban([t.data("objectID")]):this.ban([t.data("objectID")])},this)),require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.user",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.user.ban"===e.data.actionName&&this.ban(e.data.parameters.objectIDs)},unban:function(e){this._proxy.setOption("data",{actionName:"unban",className:"wcf\\data\\user\\UserAction",objectIDs:e}),this._proxy.sendRequest()},ban:function(e){null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.append($('<div class="section"><dl><dt><label for="userBanReason">'+WCF.Language.get("wcf.acp.user.banReason")+'</label></dt><dd><textarea id="userBanReason" cols="40" rows="3" /><small>'+WCF.Language.get("wcf.acp.user.banReason.description")+'</small></dd></dl><dl><dt></dt><dd><label for="userBanNeverExpires"><input type="checkbox" name="userBanNeverExpires" id="userBanNeverExpires" checked> '+WCF.Language.get("wcf.acp.user.ban.neverExpires")+'</label></dd></dl><dl id="userBanExpiresSettings" style="display: none;"><dt><label for="userBanExpires">'+WCF.Language.get("wcf.acp.user.ban.expires")+'</label></dt><dd><input type="date" name="userBanExpires" id="userBanExpires" class="medium" min="'+new Date(1e3*TIME_NOW).toISOString()+'" data-ignore-timezone="true" /><small>'+WCF.Language.get("wcf.acp.user.ban.expires.description")+"</small></dd></dl></div>")),this._dialog.append($('<div class="formSubmit"><button class="buttonPrimary" accesskey="s">'+WCF.Language.get("wcf.global.button.submit")+"</button></div>")),this._dialog.find("#userBanNeverExpires").change(function(){$("#userBanExpiresSettings").toggle()}),this._dialog.find("button").click($.proxy(this._submit,this))):($("#userBanReason").val(""),$("#userBanNeverExpires").prop("checked",!0),$("#userBanExpiresSettings").hide(),$("#userBanExpiresDatePicker, #userBanExpires").val("")),this._dialog.data("userIDs",e),this._dialog.wcfDialog({title:WCF.Language.get("wcf.acp.user.ban.sure")})},_submit:function(){this._dialog.find(".innerError").remove();var e="";if(!$("#userBanNeverExpires").is(":checked")&&!(e=$("#userBanExpiresDatePicker").val()))return void this._dialog.find("#userBanExpiresSettings > dd > small").prepend($('<small class="innerError" />').text(WCF.Language.get("wcf.global.form.error.empty")));this._proxy.setOption("data",{actionName:"ban",className:"wcf\\data\\user\\UserAction",objectIDs:this._dialog.data("userIDs"),parameters:{banReason:$("#userBanReason").val(),banExpires:e}}),this._proxy.sendRequest()},_success:function(i,e,t){elBySelAll(".jsUserRow",void 0,function(e){var t=parseInt(elData(e,"object-id"),10);-1!==i.objectIDs.indexOf(t)&&elData(e,"banned","ban"===i.actionName)}),$(".jsBanButton").each(function(e,t){var a=$(t);WCF.inArray(a.data("objectID"),i.objectIDs)&&("unban"==i.actionName?a.data("banned",!1).attr("data-tooltip",a.data("banMessage")).removeClass("fa-lock").addClass("fa-unlock"):a.data("banned",!0).attr("data-tooltip",a.data("unbanMessage")).removeClass("fa-unlock").addClass("fa-lock"))}),(new WCF.System.Notification).show(),WCF.Clipboard.reload(),"ban"==i.actionName&&this._dialog.wcfDialog("close"),WCF.System.Event.fireEvent("com.woltlab.wcf.acp.user","refresh",{userIds:i.objectIDs})}},WCF.ACP.User.Group={},WCF.ACP.User.Group.Copy=Class.extend({_groupID:0,init:function(e){this._groupID=e,$(".jsButtonUserGroupCopy").click($.proxy(this._click,this))},_click:function(){var e=$('<div class="section" />');e.append($('<dl class="wide"><dt /><dd><label><input type="checkbox" id="copyMembers" value="1" /> '+WCF.Language.get("wcf.acp.group.copy.copyMembers")+"</label><small>"+WCF.Language.get("wcf.acp.group.copy.copyMembers.description")+"</small></dd></dl>")),e.append($('<dl class="wide"><dt /><dd><label><input type="checkbox" id="copyUserGroupOptions" value="1" /> '+WCF.Language.get("wcf.acp.group.copy.copyUserGroupOptions")+"</label><small>"+WCF.Language.get("wcf.acp.group.copy.copyUserGroupOptions.description")+"</small></dd></dl>")),e.append($('<dl class="wide"><dt /><dd><label><input type="checkbox" id="copyACLOptions" value="1" /> '+WCF.Language.get("wcf.acp.group.copy.copyACLOptions")+"</label><small>"+WCF.Language.get("wcf.acp.group.copy.copyACLOptions.description")+"</small></dd></dl>")),WCF.System.Confirmation.show(WCF.Language.get("wcf.acp.group.copy.confirmMessage"),$.proxy(function(e){"confirm"===e&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"copy",className:"wcf\\data\\user\\group\\UserGroupAction",objectIDs:[this._groupID],parameters:{copyACLOptions:$("#copyACLOptions").is(":checked"),copyMembers:$("#copyMembers").is(":checked"),copyUserGroupOptions:$("#copyUserGroupOptions").is(":checked")}},success:function(e){window.location=e.returnValues.redirectURL}})},this),"",e,!0)}}),WCF.ACP.User.EnableHandler={_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".jsEnableButton").click($.proxy(function(e){var t=$(e.currentTarget);t.data("enabled")?this.disable([t.data("objectID")]):this.enable([t.data("objectID")])},this)),require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.user",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.user.enable"===e.data.actionName&&this.enable(e.data.parameters.objectIDs)},disable:function(e){this._proxy.setOption("data",{actionName:"disable",className:"wcf\\data\\user\\UserAction",objectIDs:e}),this._proxy.sendRequest()},enable:function(e){this._proxy.setOption("data",{actionName:"enable",className:"wcf\\data\\user\\UserAction",objectIDs:e}),this._proxy.sendRequest()},_success:function(i,e,t){elBySelAll(".jsUserRow",void 0,function(e){var t=parseInt(elData(e,"object-id"),10);-1!==i.objectIDs.indexOf(t)&&elData(e,"enabled","enable"===i.actionName)}),$(".jsEnableButton").each(function(e,t){var a=$(t);WCF.inArray(a.data("objectID"),i.objectIDs)&&("disable"==i.actionName?a.data("enabled",!1).attr("data-tooltip",a.data("enableMessage")).removeClass("fa-check-square-o").addClass("fa-square-o"):a.data("enabled",!0).attr("data-tooltip",a.data("disableMessage")).removeClass("fa-square-o").addClass("fa-check-square-o"))}),(new WCF.System.Notification).show(function(){window.location.reload()}),WCF.System.Event.fireEvent("com.woltlab.wcf.acp.user","refresh",{userIds:i.objectIDs})}},WCF.ACP.User.SendNewPasswordHandler={init:function(){require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.user",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(t){"com.woltlab.wcf.user.sendNewPassword"===t.data.actionName&&WCF.System.Confirmation.show(t.data.parameters.confirmMessage,function(e){"confirm"===e&&new WCF.ACP.Worker("sendingNewPasswords","wcf\\system\\worker\\SendNewPasswordWorker",WCF.Language.get("wcf.acp.user.sendNewPassword.workerTitle"),{userIDs:t.data.parameters.objectIDs})})}},WCF.ACP.Import={},WCF.ACP.Import.Manager=Class.extend({_currentAction:"",_dialog:null,_index:-1,_objectTypes:[],_proxy:null,_redirectURL:"",init:function(e,t){this._currentAction="",this._index=-1,this._objectTypes=e,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this),url:"index.php?worker-proxy/&t="+SECURITY_TOKEN}),this._redirectURL=t,this._invoke()},_invoke:function(){var e;this._index++,this._index>=this._objectTypes.length?(this._dialog.find(".fa-spinner").removeClass("fa-spinner").addClass("fa-check"),this._dialog.find("h1").text(WCF.Language.get("wcf.acp.dataImport.completed")),e=$('<div class="formSubmit" />').appendTo(this._dialog.find("#workerContainer")),$("<button>"+WCF.Language.get("wcf.global.button.next")+"</button>").click($.proxy(function(){new WCF.Action.Proxy({autoSend:!0,data:{noRedirect:1},dataType:"html",success:$.proxy(function(){window.location=this._redirectURL},this),url:"index.php?cache-clear/&t="+SECURITY_TOKEN})},this)).appendTo(e),this._dialog.wcfDialog("render")):this._run(WCF.Language.get("wcf.acp.dataImport.data."+this._objectTypes[this._index]),this._objectTypes[this._index])},_run:function(e,t){this._currentAction=e,this._proxy.setOption("data",{className:"wcf\\system\\worker\\ImportWorker",parameters:{objectType:t}}),this._proxy.sendRequest()},_success:function(e){null===this._dialog&&(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.wcfDialog({closable:!1,title:WCF.Language.get("wcf.acp.dataImport")})),e.template&&this._dialog.html(e.template),this._currentAction&&this._dialog.find("h1").text(this._currentAction),this._dialog.find("progress").attr("value",e.progress).text(e.progress+"%").next("span").text(e.progress+"%"),e.progress<100?(this._proxy.setOption("data",{className:e.className,loopCount:e.loopCount,parameters:e.parameters}),this._proxy.sendRequest()):this._invoke()}}),WCF.ACP.Stat={},WCF.ACP.Stat.Chart=Class.extend({init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$("#statRefreshButton").click($.proxy(this._refresh,this)),this._refresh()},_refresh:function(){var e=[];$("input[name=objectTypeID]:checked").each(function(){e.push($(this).val())}),e.length&&(this._proxy.setOption("data",{className:"wcf\\data\\stat\\daily\\StatDailyAction",actionName:"getData",parameters:{startDate:$("#startDateDatePicker").val(),endDate:$("#endDateDatePicker").val(),value:$("input[name=value]:checked").val(),dateGrouping:$("input[name=dateGrouping]:checked").val(),objectTypeIDs:e}}),this._proxy.sendRequest())},_success:function(e){switch($("input[name=dateGrouping]:checked").val()){case"yearly":var t=[1,"year"],a=WCF.Language.get("wcf.acp.stat.timeFormat.yearly");break;case"monthly":t=[1,"month"],a=WCF.Language.get("wcf.acp.stat.timeFormat.monthly");break;case"weekly":t=[7,"day"],a=WCF.Language.get("wcf.acp.stat.timeFormat.weekly");break;default:t=[1,"day"],a=WCF.Language.get("wcf.acp.stat.timeFormat.daily")}var i={series:{lines:{show:!0},points:{show:!0}},grid:{hoverable:!0},xaxis:{mode:"time",minTickSize:t,timeformat:a,monthNames:WCF.Language.get("__monthsShort")},yaxis:{min:0,tickDecimals:0,tickFormatter:function(e){return WCF.String.addThousandsSeparator(e)}}},n=[];for(var s in e.returnValues){for(var o=e.returnValues[s],r=0;r<o.data.length;r++)o.data[r][0]*=1e3;n.push(o)}$.plot("#chart",n,i),require(["Ui/Alignment"],function(i){var n=elCreate("span");n.style.setProperty("position","absolute",""),document.body.appendChild(n),$("#chart").on("plothover",function(e,t,a){a?(n.style.setProperty("top",a.pageY+"px",""),n.style.setProperty("left",a.pageX+"px",""),$("#chartTooltip").html(a.series.xaxis.tickFormatter(a.datapoint[0],a.series.xaxis)+", "+WCF.String.formatNumeric(a.datapoint[1])+" "+a.series.label).show(),i.set($("#chartTooltip")[0],n,{verticalOffset:5,horizontal:"center",vertical:"top"})):$("#chartTooltip").hide()})}),n.length||$("#chart").append('<p style="position: absolute; font-size: 1.2rem; text-align: center; top: 50%; margin-top: -20px; width: 100%">'+WCF.Language.get("wcf.acp.stat.noData")+"</p>"),elBySel(".contentHeader > .contentTitle").scrollIntoView({behavior:"smooth"})}}),WCF.ACP.Ad={},WCF.ACP.Ad.LocationHandler=Class.extend({_pageConditions:null,_pageInputs:[],_pageSelectionContainer:null,init:function(e){this._variablesDescriptions=e,this._pageConditions=$("#pageConditions"),this._pageInputs=$('input[name="pageIDs[]"]'),this._variablesDescriptionsList=$("#ad").next("small").children("ul"),this._pageSelectionContainer=$(this._pageInputs[0]).parents("dl:eq(0)"),this._hidePageSelection(!0),$("#objectTypeID").on("change",$.proxy(this._setPageController,this)),this._setPageController(),$("#adForm").submit($.proxy(this._submit,this))},_hidePageSelection:function(e){this._pageSelectionContainer.prev("dl").hide(),this._pageSelectionContainer.hide(),this._pageSelectionContainer.next("dl").css("margin-top",0);var t,a=this._pageSelectionContainer.parent("section");a.children("dl:visible").length||(a.hide(),(t=a.next("section"))&&(t.css("margin-top",0),e&&require(["EventHandler"],function(e){e.add("com.woltlab.wcf.pageConditionDependence","checkVisivility",function(){a.is(":visible")?t.css("margin-top","40px"):t.css("margin-top",0)})})))},_showPageSelection:function(){this._pageSelectionContainer.prev("dl").show(),this._pageSelectionContainer.show(),this._pageSelectionContainer.next("dl").css("margin-top","40px");var e=this._pageSelectionContainer.parent("section");e.show();var t=e.next("section");t&&t.css("margin-top","40px")},_setPageController:function(){var s=$("#objectTypeID").find("option:checked"),e=s.parent();e.is("optgroup")&&"com.woltlab.wcf.global"===e.data("categoryName")?this._showPageSelection():(this._hidePageSelection(),require(["Core"],function(e){for(var t,a,i=0,n=this._pageInputs.length;i<n;i++)t=this._pageInputs[i],a=!1,s.data("page")&&elData(t,"identifier")===s.data("page")?(t.checked||(a=!0),t.checked=!0):(t.checked&&(a=!0),t.checked=!1),a&&e.triggerEvent(this._pageInputs[i],"change")}.bind(this))),this._variablesDescriptionsList.children(":not(.jsDefaultItem)").remove();var t=$("#objectTypeID").val();t in this._variablesDescriptions&&(this._variablesDescriptionsList[0].innerHTML+=this._variablesDescriptions[t])},_submit:function(){if(this._pageConditions.is(":hidden"))this._pageConditions.find("select, input").remove();else if(this._pageSelectionContainer.is(":hidden"))for(var e=0,t=this._pageInputs.length;e<t;e++)this._pageInputs[e].checked=!1}}),WCF.ACP.Tag={},WCF.ACP.Tag.SetAsSynonymsHandler=Class.extend({_dialog:null,_objectIDs:[],init:function(){require(["EventHandler"],function(e){e.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.tag",this._clipboardAction.bind(this))}.bind(this))},_clipboardAction:function(e){"com.woltlab.wcf.tag.setAsSynonyms"===e.data.actionName&&(this._objectIDs=e.data.parameters.objectIDs,null===this._dialog&&(this._dialog=$('<div id="setAsSynonymsDialog" />').hide().appendTo(document.body),this._dialog.wcfDialog({closable:!1,title:WCF.Language.get("wcf.acp.tag.setAsSynonyms")})),this._dialog.html(e.data.parameters.template),$button=this._dialog.find('button[data-type="submit"]').disable().click($.proxy(this._submit,this)),this._dialog.find("input[type=radio]").change(function(){$button.enable()}))},_submit:function(){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"setAsSynonyms",className:"wcf\\data\\tag\\TagAction",objectIDs:this._objectIDs,parameters:{tagID:this._dialog.find('input[name="tagID"]:checked').val()}},success:$.proxy(function(){this._dialog.wcfDialog("close"),(new WCF.System.Notification).show(function(){window.location.reload()})},this)})}});
\ No newline at end of file
index 816939242519b5cd9011a3a34333f13af83e6407..f06877540f4b435c8eff257aae12679033d93b4e 100644 (file)
@@ -98,9 +98,13 @@ html[dir="rtl"] #spStatus > li > div { border-right: 5px solid #000; }
 .spSidebarBox { background-color: rgb(217, 237, 247); margin-bottom: 10px; padding: 10px; }
 .spColor { align-items: center; }
 .spColor:not(:first-child) { margin-top: 5px; }
+html:not(.touch) .spColor:hover .spColorBox { border: 2px dashed #6e7792; left: -2px; padding: 2px; position: relative; }
 .spColorBox { background-color: #fff; border: 1px solid #ccc; padding: 1px; }
 html[dir="ltr"] .spColorBox { margin-right: 10px !important; }
+html[dir="ltr"]:not(.touch) .spColor:hover .spColorBox { margin-right: 6px !important; }
 html[dir="rtl"] .spColorBox { margin-left: 10px !important; }
+html[dir="rtl"]:not(.touch) .spColor:hover .spColorBox { margin-left: 6px !important; }
+html:not(.touch) .spColorBox { cursor: pointer; }
 .spColorBox > span { display: block; height: 24px; width: 24px; }
 .spVariable, .spDescription { display: block; font-size: 12px; }
 .spVariable { font-family: Consolas, Courier, monospace; }
@@ -174,4 +178,5 @@ html[dir="rtl"] .spColorBox { margin-left: 10px !important; }
         #spWindow.spColorPalette + #spSidebar .spSidebarBox { break-inside: avoid; display: block !important; page-break-inside: avoid; position: relative; }
        #spWindow.spColorPalette + #spSidebar .spSidebarBox[data-category="none"], #spWindow.spColorPalette + #spSidebar .spSidebarBox.spSidebarBoxCategorySelection { display: none !important; }
        #spWindow.spColorPalette + #spSidebar .spSidebarBox::before { color: rgb(125, 130, 135); content: attr(data-category); display: block; font-family: Consolas, Courier, monospace; font-size: 1.2rem; margin-bottom: 10px; }
+       #spWindow.spColorPalette + #spSidebar .spSidebarBox[data-category="apiVersion"]::before { display: none; }
 }
index b0ced58e065a43a463828b4e65e45c8529646c6d..69b4b4a1d7d66ceef11262b100677726280e9045 100644 (file)
@@ -466,6 +466,28 @@ $wcfAcpSubMenuWidth: 300px;
 }
 
 /* Search for Packages */
+.packageSearchResultRow {
+       .columnText {
+               padding: 15px 10px;
+       }
+       
+       td.columnIcon {
+               position: relative;
+               width: 44px;
+               
+               a {
+                       align-items: center;
+                       bottom: 5px;
+                       display: flex;
+                       justify-content: center;
+                       left: 0;
+                       position: absolute;
+                       right: 0;
+                       top: 5px;
+               }
+       }
+}
+
 .packageSearchName {
        @include wcfFontHeadline;
        @include wcfFontBold;
@@ -474,15 +496,32 @@ $wcfAcpSubMenuWidth: 300px;
 .packageSearchVersion {
        color: $wcfContentDimmedText;
        font-weight: 400;
-       padding-left: 5px;
+}
+
+.packageSearchDescription {
+       margin-top: 3px;
 }
 
 .packageSearchPackage {
        color: $wcfContentDimmedText;
        font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
-       font-weight: 400;
-       
-       @include wcfFontSmall;
+}
+
+.packageSearchAuthor,
+.packageSearchLicense {
+       white-space: nowrap;
+}
+
+.packageSearchAuthorWoltlab::before {
+       background-image: url(../../acp/images/woltlabLogo-tiny.png);
+       background-size: contain;
+       content: "";
+       display: inline-block;
+       height: 12px;
+       margin-right: 2px;
+       position: relative;
+       top: 1px;
+       width: 22px;
 }
 
 #packageSearchResultContainer {
@@ -523,3 +562,9 @@ $wcfAcpSubMenuWidth: 300px;
        
        @include wcfFontHeadline;
 }
+
+.exceptionContainer {
+       &.collapsed .exceptionDetails {
+               display: none;
+       }
+}
index 9fbd05189346bbdd7e25ad7ae9a3ccc8bdab1942..a09076a9f7812775516542806434d403e1647819 100644 (file)
@@ -2,4 +2,4 @@
        {include file='aclPermissions'}
 {/if}
 
-{include file='aclPermissionJavaScript' containerID=$field->getPrefixedId()|concat:'Container' categoryName=$field->getCategoryName() objectID=$field->getObjectID() objectTypeID=$field->getObjectType()->objectTypeID aclFormBuilderMode=true aclValuesFieldName=$field->getPrefixedId()}
+{include file='aclPermissionJavaScript' containerID=$field->getPrefixedId()|concat:'Container' categoryName=$field->getCategoryName() objectID=$field->getObjectID() objectTypeID=$field->getObjectType()->objectTypeID aclFormBuilderMode=$field->getDocument()->isAjax() aclValuesFieldName=$field->getPrefixedId()}
index fc615ab6e2520bedfdeba9c07b78ae465650df8f..cf7319cad98bd8521d204fa8b6a707b0113ebe3c 100644 (file)
                        AcpUiCodeMirrorPage
                ) {
                        Language.addObject({
-                               'wcf.page.search': '{lang}wcf.page.search{/lang}',
-                               'wcf.page.search.error.tooShort': '{lang}wcf.page.search.error.tooShort{/lang}',
-                               'wcf.page.search.error.noResults': '{lang}wcf.page.search.error.noResults{/lang}',
-                               'wcf.page.search.name': '{lang}wcf.page.search.name{/lang}',
-                               'wcf.page.search.results': '{lang}wcf.page.search.results{/lang}',
+                               'wcf.page.search': '{jslang}wcf.page.search{/jslang}',
+                               'wcf.page.search.error.tooShort': '{jslang}wcf.page.search.error.tooShort{/jslang}',
+                               'wcf.page.search.error.noResults': '{jslang}wcf.page.search.error.noResults{/jslang}',
+                               'wcf.page.search.name': '{jslang}wcf.page.search.name{/jslang}',
+                               'wcf.page.search.results': '{jslang}wcf.page.search.results{/jslang}',
                        });
                        
                        new AcpUiCodeMirrorMedia('content{@$languageID}');
index 8b7ce83734caf4eaca7239b22c2e931b7bc41422..14e7ee04ea54d83e2b2ec4dd23d61c1cf5b43efc 100644 (file)
@@ -1,8 +1,8 @@
 <script data-relocate="true">
        require(['Language'], function(Language) {
                Language.addObject({
-                       'wcf.acp.pip.box.visibilityExceptions.hiddenEverywhere': '{lang}wcf.acp.pip.box.visibilityExceptions.hiddenEverywhere{/lang}',
-                       'wcf.acp.pip.box.visibilityExceptions.visibleEverywhere': '{lang}wcf.acp.pip.box.visibilityExceptions.visibleEverywhere{/lang}'
+                       'wcf.acp.pip.box.visibilityExceptions.hiddenEverywhere': '{jslang}wcf.acp.pip.box.visibilityExceptions.hiddenEverywhere{/jslang}',
+                       'wcf.acp.pip.box.visibilityExceptions.visibleEverywhere': '{jslang}wcf.acp.pip.box.visibilityExceptions.visibleEverywhere{/jslang}'
                });
                
                var visibleEverywhere = elById('visibleEverywhere');
diff --git a/wcfsetup/install/files/acp/templates/__checkboxFormField.tpl b/wcfsetup/install/files/acp/templates/__checkboxFormField.tpl
new file mode 100644 (file)
index 0000000..af2e22d
--- /dev/null
@@ -0,0 +1,14 @@
+<dl id="{@$field->getPrefixedId()}Container" {if !$field->getClasses()|empty} class="{implode from=$field->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{foreach from=$field->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{if !$field->checkDependencies()} style="display: none;"{/if}>
+       <dt></dt>
+       <dd>
+               <label>
+                       <input type="checkbox" id="{@$field->getPrefixedId()}" name="{@$field->getPrefixedId()}" value="1"{if $field->isRequired()} required{/if}{if $field->isImmutable()} disabled{/if}{if $field->getValue()} checked{/if}>
+                       {@$field->getLabel()}{if $field->isRequired()} <span class="formFieldRequired">*</span>{/if}
+               </label>
+               
+               {include file='__formFieldDescription'}
+               {include file='__formFieldErrors'}
+               {include file='__formFieldDependencies'}
+               {include file='__formFieldDataHandler'}
+       </dd>
+</dl>
diff --git a/wcfsetup/install/files/acp/templates/__devtoolsMissingLanguageItemStackTrace.tpl b/wcfsetup/install/files/acp/templates/__devtoolsMissingLanguageItemStackTrace.tpl
new file mode 100644 (file)
index 0000000..39ef0cd
--- /dev/null
@@ -0,0 +1,29 @@
+<span class="icon icon16 fa-align-justify jsTooltip pointer jsOutputFormatToggle" title="{lang}wcf.acp.devtools.missingLanguageItem.stackTrace.toggleOutputFormat{/lang}" style="margin-bottom: 10px"></span>
+
+<pre>{*
+       *}{foreach from=$stackTrace item=stackEntry name=stackEntries}{*
+               *}#{$tpl[foreach][stackEntries][iteration]} {$stackEntry[file]} ({$stackEntry[line]}):
+{*             *}    {$stackEntry['class']}{$stackEntry['type']}{$stackEntry['function']}({*
+                               *}{foreach from=$stackEntry['args'] item=stackEntryArg name=stackEntryArgs}{*
+                                       *}{assign var='argType' value=$stackEntryArg|gettype}{*
+                                       *}{if $argType === 'integer' || $argType === 'double'}{*
+                                               *}{$stackEntryArg}{*
+                                       *}{elseif $argType === 'NULL'}{*
+                                               *}null{*
+                                       *}{elseif $argType === 'string'}{*
+                                               *}'{$stackEntryArg}'{*
+                                       *}{elseif $argType === 'boolean'}{*
+                                               *}{if $stackEntryArg}true{else}false{/if}{*
+                                       *}{elseif $argType === 'array'}{*
+                                               *}[{if $stackEntryArg|count > 5}{$stackEntryArg|count} items{else}{implode from=$stackEntryArg|array_keys item=stackEntryKey}{$stackEntryKey} => {/implode}{/if}]{*
+                                       *}{elseif $argType === 'object'}{*
+                                               *}{$item|get_class}{*
+                                       *}{elseif $argType === 'resource'}{*
+                                               *}resource({$item|get_resource_type}){*
+                                       *}{elseif $argType === 'resource (closed)'}{*
+                                               *}resource (closed){*
+                                       *}{/if}{if !$tpl[foreach][stackEntryArgs][last]},{/if}{*
+                               *}{/foreach}{*
+                       *})
+{*     *}{/foreach}{*
+*}</pre>
index cbc3d856b237f25004b972ae42d2f3a8067d339c..4dbd802c3ab4e20b6a427ca76fe92db370f77759 100644 (file)
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/ExcludedPackages'], function(Language, ExcludedPackagesFormField) {
                Language.addObject({
-                       'wcf.acp.devtools.project.packageIdentifier.error.duplicate': '{lang}wcf.acp.devtools.project.packageIdentifier.error.duplicate{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.format': '{lang}wcf.acp.devtools.project.packageIdentifier.error.format{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.maximumLength': '{lang}wcf.acp.devtools.project.packageIdentifier.error.maximumLength{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.minimumLength': '{lang}wcf.acp.devtools.project.packageIdentifier.error.minimumLength{/lang}',
-                       'wcf.acp.devtools.project.packageVersion.error.format': '{lang}wcf.acp.devtools.project.packageVersion.error.format{/lang}',
-                       'wcf.acp.devtools.project.packageVersion.error.maximumLength': '{lang}wcf.acp.devtools.project.packageVersion.error.maximumLength{/lang}',
-                       'wcf.acp.devtools.project.excludedPackage.excludedPackage': '{capture assign=__languageItem}{lang __literal=true}wcf.acp.devtools.project.excludedPackage.excludedPackage{/lang}{/capture}{@$__languageItem|encodeJS}'
+                       'wcf.acp.devtools.project.packageIdentifier.error.duplicate': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.duplicate{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.format': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.format{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.maximumLength': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.maximumLength{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.minimumLength': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.minimumLength{/jslang}',
+                       'wcf.acp.devtools.project.packageVersion.error.format': '{jslang}wcf.acp.devtools.project.packageVersion.error.format{/jslang}',
+                       'wcf.acp.devtools.project.packageVersion.error.maximumLength': '{jslang}wcf.acp.devtools.project.packageVersion.error.maximumLength{/jslang}',
+                       'wcf.acp.devtools.project.excludedPackage.excludedPackage': '{jslang __literal=true}wcf.acp.devtools.project.excludedPackage.excludedPackage{/jslang}'
                });
                
                new ExcludedPackagesFormField('{@$field->getPrefixedId()}', [
index 7c93c450ce5ce40d29ffbd7dba5dbe69f29ca12a..a8bd9c71bb984fd0da6455b7f882867eedea3fee 100644 (file)
@@ -2,8 +2,8 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Devtools/Project/Installation/Confirmation'], function(Language, DevtoolsProjectInstallationConfirmation) {
                        Language.addObject({
-                               'wcf.acp.devtools.project.installPackage.confirmMessage': '{lang __literal=true}wcf.acp.devtools.project.installPackage.confirmMessage{/lang}',
-                               'wcf.acp.package.install.title': '{lang}wcf.acp.package.install.title{/lang}'
+                               'wcf.acp.devtools.project.installPackage.confirmMessage': '{jslang __literal=true}wcf.acp.devtools.project.installPackage.confirmMessage{/jslang}',
+                               'wcf.acp.package.install.title': '{jslang}wcf.acp.package.install.title{/jslang}'
                        });
                        
                        DevtoolsProjectInstallationConfirmation.init({@$project->projectID}, '{@$project->name|encodeJS}');
index aeb87111c17d4a7fa9da91cb13b6932564f77c8e..fb739e6174db50a12a75810620dffa893bd8e4c9 100644 (file)
                Template
        ) {
                Language.addObject({
-                       'wcf.acp.devtools.project.instruction.delete.confirmMessages': '{lang}wcf.acp.devtools.project.instruction.delete.confirmMessages{/lang}',
-                       'wcf.acp.devtools.project.instruction.edit': '{lang}wcf.acp.devtools.project.instruction.edit{/lang}',
-                       'wcf.acp.devtools.project.instruction.instruction': '{capture assign=__languageItem}{lang __literal=true}wcf.acp.devtools.project.instruction.instruction{/lang}{/capture}{@$__languageItem|encodeJS}',
-                       'wcf.acp.devtools.project.instruction.value.description': '{lang}wcf.acp.devtools.project.instruction.value.description{/lang}',
-                       'wcf.acp.devtools.project.instruction.value.description.defaultFilename': '{lang __literal=true}wcf.acp.devtools.project.instruction.value.description.defaultFilename{/lang}',
-                       'wcf.acp.devtools.project.instructions.delete.confirmMessages': '{lang}wcf.acp.devtools.project.instructions.delete.confirmMessages{/lang}',
-                       'wcf.acp.devtools.project.instructions.edit': '{lang}wcf.acp.devtools.project.instructions.edit{/lang}',
-                       'wcf.acp.devtools.project.instructions.instructions.description': '{lang}wcf.acp.devtools.project.instructions.instructions.description{/lang}',
-                       'wcf.acp.devtools.project.instructions.type.install.title': '{lang}wcf.acp.devtools.project.instructions.type.install.title{/lang}',
-                       'wcf.acp.devtools.project.instructions.type.update.error.duplicate': '{lang}wcf.acp.devtools.project.instructions.type.update.error.duplicate{/lang}',
-                       'wcf.acp.devtools.project.instructions.type.update.title': '{lang __literal=true}wcf.acp.devtools.project.instructions.type.update.title{/lang}',
-                       'wcf.global.form.error.noValidSelection': '{lang}wcf.global.form.error.noValidSelection{/lang}'
+                       'wcf.acp.devtools.project.instruction.delete.confirmMessages': '{jslang}wcf.acp.devtools.project.instruction.delete.confirmMessages{/jslang}',
+                       'wcf.acp.devtools.project.instruction.edit': '{jslang}wcf.acp.devtools.project.instruction.edit{/jslang}',
+                       'wcf.acp.devtools.project.instruction.instruction': '{jslang __literal=true}wcf.acp.devtools.project.instruction.instruction{/jslang}',
+                       'wcf.acp.devtools.project.instruction.value.description': '{jslang}wcf.acp.devtools.project.instruction.value.description{/jslang}',
+                       'wcf.acp.devtools.project.instruction.value.description.defaultFilename': '{jslang __literal=true}wcf.acp.devtools.project.instruction.value.description.defaultFilename{/jslang}',
+                       'wcf.acp.devtools.project.instructions.delete.confirmMessages': '{jslang}wcf.acp.devtools.project.instructions.delete.confirmMessages{/jslang}',
+                       'wcf.acp.devtools.project.instructions.edit': '{jslang}wcf.acp.devtools.project.instructions.edit{/jslang}',
+                       'wcf.acp.devtools.project.instructions.instructions.description': '{jslang}wcf.acp.devtools.project.instructions.instructions.description{/jslang}',
+                       'wcf.acp.devtools.project.instructions.type.install.title': '{jslang}wcf.acp.devtools.project.instructions.type.install.title{/jslang}',
+                       'wcf.acp.devtools.project.instructions.type.update.error.duplicate': '{jslang}wcf.acp.devtools.project.instructions.type.update.error.duplicate{/jslang}',
+                       'wcf.acp.devtools.project.instructions.type.update.title': '{jslang __literal=true}wcf.acp.devtools.project.instructions.type.update.title{/jslang}',
+                       'wcf.global.form.error.noValidSelection': '{jslang}wcf.global.form.error.noValidSelection{/jslang}'
                });
                
                var instructionsTemplate = new Template('{@$instructionsTemplate|encodeJS}');
index 38eb82cbe62ad375db07b5a2114a2d2a0f691538..d6ad6838c73c97236f15e8c149bd9b9a6e78d28f 100644 (file)
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/OptionalPackages'], function(Language, OptionalPackagesFormField) {
                Language.addObject({
-                       'wcf.acp.devtools.project.packageIdentifier.error.duplicate': '{lang}wcf.acp.devtools.project.packageIdentifier.error.duplicate{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.format': '{lang}wcf.acp.devtools.project.packageIdentifier.error.format{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.maximumLength': '{lang}wcf.acp.devtools.project.packageIdentifier.error.maximumLength{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.minimumLength': '{lang}wcf.acp.devtools.project.packageIdentifier.error.minimumLength{/lang}',
-                       'wcf.acp.devtools.project.packageVersion.error.format': '{lang}wcf.acp.devtools.project.packageVersion.error.format{/lang}',
-                       'wcf.acp.devtools.project.packageVersion.error.maximumLength': '{lang}wcf.acp.devtools.project.packageVersion.error.maximumLength{/lang}',
-                       'wcf.acp.devtools.project.optionalPackage.optionalPackage': '{lang __literal=true}wcf.acp.devtools.project.optionalPackage.optionalPackage{/lang}'
+                       'wcf.acp.devtools.project.packageIdentifier.error.duplicate': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.duplicate{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.format': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.format{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.maximumLength': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.maximumLength{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.minimumLength': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.minimumLength{/jslang}',
+                       'wcf.acp.devtools.project.packageVersion.error.format': '{jslang}wcf.acp.devtools.project.packageVersion.error.format{/jslang}',
+                       'wcf.acp.devtools.project.packageVersion.error.maximumLength': '{jslang}wcf.acp.devtools.project.packageVersion.error.maximumLength{/jslang}',
+                       'wcf.acp.devtools.project.optionalPackage.optionalPackage': '{jslang __literal=true}wcf.acp.devtools.project.optionalPackage.optionalPackage{/jslang}'
                });
                
                new OptionalPackagesFormField('{@$field->getPrefixedId()}', [
index 463248163022aaa4022c8360d4e95821388dc2df..916f4833fb9d6a8a3c2aff1015a41c50cee205fe 100644 (file)
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/RequiredPackages'], function(Language, RequiredPackagesFormField) {
                Language.addObject({
-                       'wcf.acp.devtools.project.packageIdentifier.error.duplicate': '{lang}wcf.acp.devtools.project.packageIdentifier.error.duplicate{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.format': '{lang}wcf.acp.devtools.project.packageIdentifier.error.format{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.maximumLength': '{lang}wcf.acp.devtools.project.packageIdentifier.error.maximumLength{/lang}',
-                       'wcf.acp.devtools.project.packageIdentifier.error.minimumLength': '{lang}wcf.acp.devtools.project.packageIdentifier.error.minimumLength{/lang}',
-                       'wcf.acp.devtools.project.packageVersion.error.format': '{lang}wcf.acp.devtools.project.packageVersion.error.format{/lang}',
-                       'wcf.acp.devtools.project.packageVersion.error.maximumLength': '{lang}wcf.acp.devtools.project.packageVersion.error.maximumLength{/lang}',
-                       'wcf.acp.devtools.project.requiredPackage.requiredPackage': '{capture assign=__languageItem}{lang __literal=true}wcf.acp.devtools.project.requiredPackage.requiredPackage{/lang}{/capture}{@$__languageItem|encodeJS}'
+                       'wcf.acp.devtools.project.packageIdentifier.error.duplicate': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.duplicate{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.format': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.format{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.maximumLength': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.maximumLength{/jslang}',
+                       'wcf.acp.devtools.project.packageIdentifier.error.minimumLength': '{jslang}wcf.acp.devtools.project.packageIdentifier.error.minimumLength{/jslang}',
+                       'wcf.acp.devtools.project.packageVersion.error.format': '{jslang}wcf.acp.devtools.project.packageVersion.error.format{/jslang}',
+                       'wcf.acp.devtools.project.packageVersion.error.maximumLength': '{jslang}wcf.acp.devtools.project.packageVersion.error.maximumLength{/jslang}',
+                       'wcf.acp.devtools.project.requiredPackage.requiredPackage': '{jslang __literal=true}wcf.acp.devtools.project.requiredPackage.requiredPackage{/jslang}'
                });
                
                new RequiredPackagesFormField('{@$field->getPrefixedId()}', [
index 53fb5116bfbca5182160b3fe4aa7298805d7929e..d263258794ebb3d08fa00c78e29fbd4a746c2da7 100644 (file)
 {/if}
 
 {if $form->showsSuccessMessage()}
-       <p class="success">{@$form->getSuccessMessage()}</p>
+       <p class="success">
+               <span>{@$form->getSuccessMessage()}</span>
+               {if !$objectEditLink|empty}
+                       <span>{lang}wcf.global.success.add.editCreatedObject{/lang}</span>
+               {/if}
+       </p>
 {/if}
 
 {if $form->isAjax()}
        </form>
 {/if}
 
+{if $form->needsRequiredFieldsInfo()}
+       <div class="section requiredFieldsInfo">
+               <p><span class="formFieldRequired">*</span> {lang}wcf.global.form.required{/lang}</p>
+               
+               {event name='requiredFieldsInfo'}
+       </div>
+{/if}
+
 <script data-relocate="true">
        {* after all dependencies have been added, check them *}
        require(['WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager'], function(FormBuilderFieldDependencyManager) {
index eec1c6606bafb02b1a7f00040ff9c4a65e161d2b..b7ff418e62a84edc09bac06d4757d816b50fca80 100644 (file)
@@ -6,11 +6,11 @@
        {if $container->getLabel() !== null}
                {if $container->getDescription() !== null}
                        <header class="sectionHeader">
-                               <h2 class="sectionTitle">{@$container->getLabel()}</h2>
+                               <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
                                <p class="sectionDescription">{@$container->getDescription()}</p>
                        </header>
                {else}
-                       <h2 class="sectionTitle">{@$container->getLabel()}</h2>
+                       <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
                {/if}
        {/if}
        
index 752234e70ef002a27e58a2983a466990c10298c6..0f752fcb9e3bc805eacf8c69028c18399ef0e14c 100644 (file)
@@ -3,7 +3,7 @@
        *}{foreach from=$field->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{*
        *}{if !$field->checkDependencies()} style="display: none;"{/if}{*
 *}>
-       <dt>{if $field->getLabel() !== null}<label for="{@$field->getPrefixedId()}">{@$field->getLabel()}</label>{/if}</dt>
+       <dt>{if $field->getLabel() !== null}<label for="{@$field->getPrefixedId()}">{@$field->getLabel()}</label>{if $field->isRequired()} <span class="formFieldRequired">*</span>{/if}{/if}</dt>
        <dd>
                {@$field->getFieldHtml()}
                
index 90bde6516f307ddc3b32f678cdb75cd9f26470ec..a3ca75b729cf5359c43f1e36e46b9fa6ba0de937 100644 (file)
@@ -7,7 +7,7 @@
                        <ul class="scrollableDropdownMenu">
                                {foreach from=$field->getLabelGroup() item=label}
                                        <li data-label-id="{@$label->labelID}">
-                                               <span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span>
+                                               <span>{@$label->render()}</span>
                                        </li>
                                {/foreach}
                        </ul>
@@ -26,8 +26,8 @@
 <script data-relocate="true">
        require(['Dom/Util', 'Language', 'WoltLabSuite/Core/Form/Builder/Field/Controller/Label'], function(DomUtil, Language, FormBuilderFieldLabel) {
                Language.addObject({
-                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
-                       'wcf.label.withoutSelection': '{lang}wcf.label.withoutSelection{/lang}'
+                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
+                       'wcf.label.withoutSelection': '{jslang}wcf.label.withoutSelection{/jslang}'
                });
                
                new FormBuilderFieldLabel(
index a5086f51f623182804096d611f49d211c71da275..14e9b3421adb4a1689c1602ee59e8b646bc77a84 100644 (file)
@@ -1,8 +1,8 @@
 <script data-relocate="true">
        require(['Language'], function(Language) {
                Language.addObject({
-                       'wcf.acp.pip.menu.boxVisibilityExceptions.hiddenEverywhere': '{lang}wcf.acp.pip.menu.boxVisibilityExceptions.hiddenEverywhere{/lang}',
-                       'wcf.acp.pip.menu.boxVisibilityExceptions.visibleEverywhere': '{lang}wcf.acp.pip.menu.boxVisibilityExceptions.visibleEverywhere{/lang}'
+                       'wcf.acp.pip.menu.boxVisibilityExceptions.hiddenEverywhere': '{jslang}wcf.acp.pip.menu.boxVisibilityExceptions.hiddenEverywhere{/jslang}',
+                       'wcf.acp.pip.menu.boxVisibilityExceptions.visibleEverywhere': '{jslang}wcf.acp.pip.menu.boxVisibilityExceptions.visibleEverywhere{/jslang}'
                });
                
                var boxVisibleEverywhere = elById('boxVisibleEverywhere');
index fd0798d128460f82fa181a63153db1e9385ac5d0..e8c9c7b0da358c1050ef9509139adb93c7f78a48 100644 (file)
@@ -1,12 +1,12 @@
 WCF.Language.addObject({
-       'wcf.message.quote.insertAllQuotes': '{lang}wcf.message.quote.insertAllQuotes{/lang}',
-       'wcf.message.quote.insertSelectedQuotes': '{lang}wcf.message.quote.insertSelectedQuotes{/lang}',
-       'wcf.message.quote.manageQuotes': '{lang}wcf.message.quote.manageQuotes{/lang}',
-       'wcf.message.quote.quoteSelected': '{lang}wcf.message.quote.quoteSelected{/lang}',
-       'wcf.message.quote.quoteAndReply': '{lang}wcf.message.quote.quoteAndReply{/lang}',
-       'wcf.message.quote.removeAllQuotes': '{lang}wcf.message.quote.removeAllQuotes{/lang}',
-       'wcf.message.quote.removeSelectedQuotes': '{lang}wcf.message.quote.removeSelectedQuotes{/lang}',
-       'wcf.message.quote.showQuotes': '{lang}wcf.message.quote.showQuotes{/lang}'
+       'wcf.message.quote.insertAllQuotes': '{jslang}wcf.message.quote.insertAllQuotes{/jslang}',
+       'wcf.message.quote.insertSelectedQuotes': '{jslang}wcf.message.quote.insertSelectedQuotes{/jslang}',
+       'wcf.message.quote.manageQuotes': '{jslang}wcf.message.quote.manageQuotes{/jslang}',
+       'wcf.message.quote.quoteSelected': '{jslang}wcf.message.quote.quoteSelected{/jslang}',
+       'wcf.message.quote.quoteAndReply': '{jslang}wcf.message.quote.quoteAndReply{/jslang}',
+       'wcf.message.quote.removeAllQuotes': '{jslang}wcf.message.quote.removeAllQuotes{/jslang}',
+       'wcf.message.quote.removeSelectedQuotes': '{jslang}wcf.message.quote.removeSelectedQuotes{/jslang}',
+       'wcf.message.quote.showQuotes': '{jslang __literal=true}wcf.message.quote.showQuotes{/jslang}'
 });
 
 {if !$wysiwygSelector|isset}{assign var=wysiwygSelector value=''}{/if}
index 81e6cdcc7d7ded7ffbc0fa638077c5cbcfca4ce4..c13cdd7bef5f13bec5ed0100501fa81d94b8baa4 100644 (file)
@@ -2,13 +2,13 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                        Language.addObject({
-                               'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                               'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                               'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                               'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                               'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                               'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                               'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                               'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                               'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                               'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                               'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                               'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                               'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                               'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                        });
                        
                        new UiItemListFilter('{@$field->getPrefixedId()}_list');
index 8630716113d7983d9ec2ffb5836ab8ab4269ca5b..672065ee66bb4f009558a90edf9bac3891b033d9 100644 (file)
@@ -1,9 +1,9 @@
 <script data-relocate="true">
        require(['Language'], function(Language) {
                Language.addObject({
-                       'wcf.form.field.className.description.interface': '{lang __literal=true}wcf.form.field.className.description.interface{/lang}',
+                       'wcf.form.field.className.description.interface': '{jslang __literal=true}wcf.form.field.className.description.interface{/jslang}',
                        {implode from=$definitionNames item=definitionName}
-                               'wcf.acp.pip.objectType.definitionName.{@$definitionName}.description': '{lang __literal=true __optional=true}wcf.acp.pip.objectType.definitionName.{@$definitionName}.description{/lang}'
+                               'wcf.acp.pip.objectType.definitionName.{@$definitionName}.description': '{jslang __literal=true __optional=true}wcf.acp.pip.objectType.definitionName.{@$definitionName}.description{/jslang}'
                        {/implode}
                });
                
@@ -31,4 +31,4 @@
                
                definitionID.addEventListener('change', update);
        });
-</script>
\ No newline at end of file
+</script>
index 6a22dc1a4a6cf582cd7d2bf43c1e4405981bf6d9..d591f5266a8dcc1832aecc39f24e5ca3aef6d362 100644 (file)
@@ -2,13 +2,13 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Option/EmailSmtpTest'], function (Language, AcpUiOptionEmailSmtpTest) {
                        Language.addObject({
-                               'wcf.acp.email.smtp.test': '{lang}wcf.acp.email.smtp.test{/lang}',
-                               'wcf.acp.email.smtp.test.description': '{lang}wcf.acp.email.smtp.test.description{/lang}',
-                               'wcf.acp.email.smtp.test.error.empty.host': '{lang}wcf.acp.email.smtp.test.error.empty.host{/lang}',
-                               'wcf.acp.email.smtp.test.error.empty.password': '{lang}wcf.acp.email.smtp.test.error.empty.password{/lang}',
-                               'wcf.acp.email.smtp.test.error.empty.user': '{lang}wcf.acp.email.smtp.test.error.empty.user{/lang}',
-                               'wcf.acp.email.smtp.test.run': '{lang}wcf.acp.email.smtp.test.run{/lang}',
-                               'wcf.acp.email.smtp.test.run.success': '{lang}wcf.acp.email.smtp.test.run.success{/lang}'
+                               'wcf.acp.email.smtp.test': '{jslang}wcf.acp.email.smtp.test{/jslang}',
+                               'wcf.acp.email.smtp.test.description': '{jslang}wcf.acp.email.smtp.test.description{/jslang}',
+                               'wcf.acp.email.smtp.test.error.empty.host': '{jslang}wcf.acp.email.smtp.test.error.empty.host{/jslang}',
+                               'wcf.acp.email.smtp.test.error.empty.password': '{jslang}wcf.acp.email.smtp.test.error.empty.password{/jslang}',
+                               'wcf.acp.email.smtp.test.error.empty.user': '{jslang}wcf.acp.email.smtp.test.error.empty.user{/jslang}',
+                               'wcf.acp.email.smtp.test.run': '{jslang}wcf.acp.email.smtp.test.run{/jslang}',
+                               'wcf.acp.email.smtp.test.run.success': '{jslang}wcf.acp.email.smtp.test.run.success{/jslang}'
                        });
                        
                        AcpUiOptionEmailSmtpTest.init();
index 2fc30b1bfda768a62d1334c4ebe0f75122c0fa45..7b0b73168d6526627994ad6bc20e58a93682f796 100644 (file)
@@ -2,9 +2,9 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Option/RewriteGenerator'], function (Language, AcpUiOptionRewriteGenerator) {
                        Language.addObject({
-                               'wcf.acp.rewrite': '{lang}wcf.acp.rewrite{/lang}',
-                               'wcf.acp.rewrite.description': '{lang}wcf.acp.rewrite.description{/lang}',
-                               'wcf.acp.rewrite.generate': '{lang}wcf.acp.rewrite.generate{/lang}'
+                               'wcf.acp.rewrite': '{jslang}wcf.acp.rewrite{/jslang}',
+                               'wcf.acp.rewrite.description': '{jslang}wcf.acp.rewrite.description{/jslang}',
+                               'wcf.acp.rewrite.generate': '{jslang}wcf.acp.rewrite.generate{/jslang}'
                        });
 
                        AcpUiOptionRewriteGenerator.init();
index b8ec64cd98dbe8ddb7ac2db83df2bd4be9d8b351..b34f5c6bd0829f397e7dae6b7fa0d87714c0f6fd 100644 (file)
@@ -26,9 +26,9 @@
        <script data-relocate="true">
                require(['Dictionary', 'Language', 'WoltLabSuite/Core/Acp/Ui/Option/RewriteTest'], function (Dictionary, Language, AcpUiOptionRewriteTest) {
                        Language.addObject({
-                               'wcf.acp.option.url_omit_index_php': '{lang}wcf.acp.option.url_omit_index_php{/lang}',
-                               'wcf.acp.option.url_omit_index_php.test.status.failure': '{lang}wcf.acp.option.url_omit_index_php.test.status.failure{/lang}',
-                               'wcf.acp.option.url_omit_index_php.test.status.success': '{lang}wcf.acp.option.url_omit_index_php.test.status.success{/lang}'
+                               'wcf.acp.option.url_omit_index_php': '{jslang}wcf.acp.option.url_omit_index_php{/jslang}',
+                               'wcf.acp.option.url_omit_index_php.test.status.failure': '{jslang}wcf.acp.option.url_omit_index_php.test.status.failure{/jslang}',
+                               'wcf.acp.option.url_omit_index_php.test.status.success': '{jslang}wcf.acp.option.url_omit_index_php.test.status.success{/jslang}'
                        });
                        
                        var apps = Dictionary.fromObject({
index 59ebbb5e73aac9de715393ad8ee5c1f9aae9b34c..bbcdea079bb16b872cc39cb816b7792b973ab278 100644 (file)
                        AcpUiCodeMirrorPage
                ) {
                        Language.addObject({
-                               'wcf.page.search': '{lang}wcf.page.search{/lang}',
-                               'wcf.page.search.error.tooShort': '{lang}wcf.page.search.error.tooShort{/lang}',
-                               'wcf.page.search.error.noResults': '{lang}wcf.page.search.error.noResults{/lang}',
-                               'wcf.page.search.name': '{lang}wcf.page.search.name{/lang}',
-                               'wcf.page.search.results': '{lang}wcf.page.search.results{/lang}',
+                               'wcf.page.search': '{jslang}wcf.page.search{/jslang}',
+                               'wcf.page.search.error.tooShort': '{jslang}wcf.page.search.error.tooShort{/jslang}',
+                               'wcf.page.search.error.noResults': '{jslang}wcf.page.search.error.noResults{/jslang}',
+                               'wcf.page.search.name': '{jslang}wcf.page.search.name{/jslang}',
+                               'wcf.page.search.results': '{jslang}wcf.page.search.results{/jslang}',
                        });
                        
                        new AcpUiCodeMirrorMedia('{@$__pageContentID}');
index 6e3460dc2339285ddf1d9509c331883a2568c878..f18e9187627b79476da384aa9b52a3eb708bafcc 100644 (file)
@@ -10,9 +10,9 @@
                'WoltLabSuite/Core/Ui/Poll/Editor'
        ], function(DomTraverse, DomUtil, EventHandler, Language, FormBuilderManager, UiPollEditor) {
                Language.addObject({
-                       'wcf.poll.button.addOption': '{lang}wcf.poll.button.addOption{/lang}',
-                       'wcf.poll.button.removeOption': '{lang}wcf.poll.button.removeOption{/lang}',
-                       'wcf.poll.maxVotes.error.invalid': '{lang}wcf.poll.maxVotes.error.invalid{/lang}'
+                       'wcf.poll.button.addOption': '{jslang}wcf.poll.button.addOption{/jslang}',
+                       'wcf.poll.button.removeOption': '{jslang}wcf.poll.button.removeOption{/jslang}',
+                       'wcf.poll.maxVotes.error.invalid': '{jslang}wcf.poll.maxVotes.error.invalid{/jslang}'
                });
                
                var pollEditor = new UiPollEditor(
index f7c87c079d3ec92d64b4bf22cb9d90db1f7ed7de..80a54f9ef59405826a0aaca26e399cfe3aa159c3 100644 (file)
@@ -28,7 +28,7 @@
                        new MediaManagerSelect({
                                buttonClass: 'jsMediaSelectButton_{@$field->getPrefixedId()}',
                                {if $field->isImageOnly()}
-                                       dialogTitle: '{lang}wcf.media.chooseImage{/lang}',
+                                       dialogTitle: '{jslang}wcf.media.chooseImage{/jslang}',
                                        imagesOnly: 1
                                {/if}
                        });
index c3209915a6fda7dc309a26d358e190210a375bd0..6c4f0aad706a182ef7aa5f98dc3bde5f5fa74ed5 100644 (file)
@@ -2,13 +2,13 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                        Language.addObject({
-                               'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                               'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                               'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                               'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                               'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                               'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                               'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                               'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                               'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                               'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                               'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                               'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                               'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                               'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                        });
                        
                        new UiItemListFilter('{@$field->getPrefixedId()}_list');
index 03a1f583e2150ea6da7658b2f4243865d30f064d..a23046b3b6938fd8a58434f9eba6d422fac4531b 100644 (file)
@@ -1,7 +1,6 @@
 <ul id="{@$field->getPrefixedID()}_attachmentList" {*
        *}class="formAttachmentList"{*
-       *}{if !$field->getAttachmentHandler()->getAttachmentList()|count} style="display: none"{/if} {*
-       *}data-enable-thumbnails="{if ATTACHMENT_ENABLE_THUMBNAILS}true{else}false{/if}"{*
+       *}{if !$field->getAttachmentHandler()->getAttachmentList()|count} style="display: none"{/if}{*
 *}>
        {foreach from=$field->getAttachmentHandler()->getAttachmentList() item=$attachment}
                <li class="box64" {*
                        *}data-is-image="{@$attachment->isImage}"{*
                *}>
                        {if $attachment->tinyThumbnailType}
-                               <img src="{link controller='Attachment' object=$attachment}tiny=1{/link}" alt="" class="attachmentTinyThumbnail">
+                               <img src="{$attachment->getThumbnailLink('tiny')}" alt="" class="attachmentTinyThumbnail">
                        {else}
                                <span class="icon icon64 fa-{@$attachment->getIconName()}"></span>
                        {/if}
                        
                        <div>
                                <div>
-                                       <p><a href="{link controller='Attachment' object=$attachment}{/link}" target="_blank"{if $attachment->isImage} title="{$attachment->filename}" class="jsImageViewer"{/if}>{$attachment->filename}</a></p>
+                                       <p><a href="{$attachment->getLink()}" target="_blank"{if $attachment->isImage} title="{$attachment->filename}" class="jsImageViewer"{/if}>{$attachment->filename}</a></p>
                                        <small>{@$attachment->filesize|filesize}</small>
                                </div>
                                
@@ -26,9 +25,9 @@
                                        <li><span class="button small jsDeleteButton" data-object-id="{@$attachment->attachmentID}" data-confirm-message="{lang}wcf.attachment.delete.sure{/lang}">{lang}wcf.global.button.delete{/lang}</span></li>
                                        {if $attachment->isImage}
                                                {if $attachment->thumbnailType}
-                                                       <li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="{@$attachment->attachmentID}" data-url="{link controller='Attachment' object=$attachment}thumbnail=1{/link}">{lang}wcf.attachment.insertThumbnail{/lang}</span></li>
+                                                       <li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="{@$attachment->attachmentID}" data-url="{$attachment->getThumbnailLink('thumbnail')}">{lang}wcf.attachment.insertThumbnail{/lang}</span></li>
                                                {/if}
-                                               <li><span class="button small jsButtonAttachmentInsertFull" data-object-id="{@$attachment->attachmentID}" data-url="{link controller='Attachment' object=$attachment}{/link}">{lang}wcf.attachment.insertFull{/lang}</span></li>
+                                               <li><span class="button small jsButtonAttachmentInsertFull" data-object-id="{@$attachment->attachmentID}" data-url="{$attachment->getLink()}">{lang}wcf.attachment.insertFull{/lang}</span></li>
                                        {else}
                                                <li><span class="button small jsButtonInsertAttachment" data-object-id="{@$attachment->attachmentID}">{lang}wcf.attachment.insert{/lang}</span></li>
                                        {/if}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.attachment.upload.error.invalidExtension': '{lang}wcf.attachment.upload.error.invalidExtension{/lang}',
-                       'wcf.attachment.upload.error.tooLarge': '{lang}wcf.attachment.upload.error.tooLarge{/lang}',
-                       'wcf.attachment.upload.error.reachedLimit': '{lang}wcf.attachment.upload.error.reachedLimit{/lang}',
-                       'wcf.attachment.upload.error.reachedRemainingLimit': '{lang}wcf.attachment.upload.error.reachedRemainingLimit{/lang}',
-                       'wcf.attachment.upload.error.uploadFailed': '{lang}wcf.attachment.upload.error.uploadFailed{/lang}',
-                       'wcf.attachment.upload.error.uploadPhpLimit': '{lang}wcf.attachment.upload.error.uploadPhpLimit{/lang}',
-                       'wcf.attachment.insert': '{lang}wcf.attachment.insert{/lang}',
-                       'wcf.attachment.insertAll': '{lang}wcf.attachment.insertAll{/lang}',
-                       'wcf.attachment.insertFull': '{lang}wcf.attachment.insertFull{/lang}',
-                       'wcf.attachment.insertThumbnail': '{lang}wcf.attachment.insertThumbnail{/lang}',
-                       'wcf.attachment.delete.sure': '{lang}wcf.attachment.delete.sure{/lang}'
+                       'wcf.attachment.upload.error.invalidExtension': '{jslang}wcf.attachment.upload.error.invalidExtension{/jslang}',
+                       'wcf.attachment.upload.error.tooLarge': '{jslang}wcf.attachment.upload.error.tooLarge{/jslang}',
+                       'wcf.attachment.upload.error.reachedLimit': '{jslang}wcf.attachment.upload.error.reachedLimit{/jslang}',
+                       'wcf.attachment.upload.error.reachedRemainingLimit': '{jslang}wcf.attachment.upload.error.reachedRemainingLimit{/jslang}',
+                       'wcf.attachment.upload.error.uploadFailed': '{jslang}wcf.attachment.upload.error.uploadFailed{/jslang}',
+                       'wcf.attachment.upload.error.uploadPhpLimit': '{jslang}wcf.attachment.upload.error.uploadPhpLimit{/jslang}',
+                       'wcf.attachment.insert': '{jslang}wcf.attachment.insert{/jslang}',
+                       'wcf.attachment.insertAll': '{jslang}wcf.attachment.insertAll{/jslang}',
+                       'wcf.attachment.insertFull': '{jslang}wcf.attachment.insertFull{/jslang}',
+                       'wcf.attachment.insertThumbnail': '{jslang}wcf.attachment.insertThumbnail{/jslang}',
+                       'wcf.attachment.delete.sure': '{jslang}wcf.attachment.delete.sure{/jslang}'
                });
                
                new WCF.Attachment.Upload(
index 81f2deba4b30d10a424842d760faeb5b9bc17369..2299dd3e19d17f42e0303fb4158f5f926b16559e 100644 (file)
@@ -1,16 +1,16 @@
 <script data-relocate="true">
        require(['Language'], function (Language) {
                Language.addObject({
-                       'wcf.article.search': '{lang}wcf.article.search{/lang}',
-                       'wcf.article.search.error.tooShort': '{lang}wcf.article.search.error.tooShort{/lang}',
-                       'wcf.article.search.error.noResults': '{lang}wcf.article.search.error.noResults{/lang}',
-                       'wcf.article.search.name': '{lang}wcf.article.search.name{/lang}',
-                       'wcf.article.search.results': '{lang}wcf.article.search.results{/lang}',
-                       'wcf.page.search': '{lang}wcf.page.search{/lang}',
-                       'wcf.page.search.error.tooShort': '{lang}wcf.page.search.error.tooShort{/lang}',
-                       'wcf.page.search.error.noResults': '{lang}wcf.page.search.error.noResults{/lang}',
-                       'wcf.page.search.name': '{lang}wcf.page.search.name{/lang}',
-                       'wcf.page.search.results': '{lang}wcf.page.search.results{/lang}',
+                       'wcf.article.search': '{jslang}wcf.article.search{/jslang}',
+                       'wcf.article.search.error.tooShort': '{jslang}wcf.article.search.error.tooShort{/jslang}',
+                       'wcf.article.search.error.noResults': '{jslang}wcf.article.search.error.noResults{/jslang}',
+                       'wcf.article.search.name': '{jslang}wcf.article.search.name{/jslang}',
+                       'wcf.article.search.results': '{jslang}wcf.article.search.results{/jslang}',
+                       'wcf.page.search': '{jslang}wcf.page.search{/jslang}',
+                       'wcf.page.search.error.tooShort': '{jslang}wcf.page.search.error.tooShort{/jslang}',
+                       'wcf.page.search.error.noResults': '{jslang}wcf.page.search.error.noResults{/jslang}',
+                       'wcf.page.search.name': '{jslang}wcf.page.search.name{/jslang}',
+                       'wcf.page.search.results': '{jslang}wcf.page.search.results{/jslang}',
                });
        })
 </script>
@@ -20,8 +20,8 @@
        , '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabPage.js?v={@LAST_UPDATE_TIME}'
 {/capture}
 {capture append='__redactorConfig'}
-       buttonOptions.woltlabArticle = { icon: 'fa-file-word-o', title: '{lang}wcf.editor.button.article{/lang}' };
-       buttonOptions.woltlabPage = { icon: 'fa-file-text-o', title: '{lang}wcf.editor.button.page{/lang}' };
+       buttonOptions.woltlabArticle = { icon: 'fa-file-word-o', title: '{jslang}wcf.editor.button.article{/jslang}' };
+       buttonOptions.woltlabPage = { icon: 'fa-file-text-o', title: '{jslang}wcf.editor.button.page{/jslang}' };
        
        buttons.push('woltlabPage');
        buttons.push('woltlabArticle');
index 6501f1538e653fa352041977842197e1fead799b..d61999dfcd6ce5d7fa1fbcacb9b242a91dcf9c77 100644 (file)
@@ -7,7 +7,7 @@
 <script data-relocate="true">
        require(['Language'], function(Language) {
                Language.addObject({
-                       'wcf.global.preview': '{lang}wcf.global.preview{/lang}'
+                       'wcf.global.preview': '{jslang}wcf.global.preview{/jslang}'
                });
                
                new WCF.Message.DefaultPreview({
index 5f4986b0ba58b2ba9f86d81ab86fd665d75d2f0b..00f6601f2d1b4d78f75ebf00209f4f197a7ce78c 100644 (file)
@@ -2,11 +2,11 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acl.option.deny': '{lang}wcf.acl.option.deny{/lang}',
-                       'wcf.acl.option.fullAccess': '{lang}wcf.acl.option.fullAccess{/lang}',
-                       'wcf.acl.option.grant': '{lang}wcf.acl.option.grant{/lang}',
-                       'wcf.acl.search.user.description': '{lang}wcf.acl.search.user.description{/lang}',
-                       'wcf.acl.search.description': '{lang}wcf.acl.search.description{/lang}',
+                       'wcf.acl.option.deny': '{jslang}wcf.acl.option.deny{/jslang}',
+                       'wcf.acl.option.fullAccess': '{jslang}wcf.acl.option.fullAccess{/jslang}',
+                       'wcf.acl.option.grant': '{jslang}wcf.acl.option.grant{/jslang}',
+                       'wcf.acl.search.user.description': '{jslang}wcf.acl.search.user.description{/jslang}',
+                       'wcf.acl.search.description': '{jslang}wcf.acl.search.description{/jslang}',
                });
        });
-</script>
\ No newline at end of file
+</script>
index c0e121044667e38d5eb211cc697942e40a98218f..02ff107231afa3ff1dc21687d169d06c064222d9 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form id="adForm" method="post" action="{if $action == 'add'}{link controller='AdAdd'}{/link}{else}{link controller='AdEdit' object=$adObject}{/link}{/if}">
        <div class="section">
index 5169e7cf3b62348070359a33a3ac8235e2e52435..9462b1603f8d4a5b465820bed908cb0709c51ecf 100644 (file)
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Ui/User/Search/Input', 'WoltLabSuite/Core/Acp/Ui/Article/InlineEditor'], function(Language, UiUserSearchInput, AcpUiArticleInlineEditor) {
                Language.addObject({
-                       'wcf.acp.article.i18n.source': '{lang}wcf.acp.article.i18n.source{/lang}',
-                       'wcf.acp.article.i18n.toI18n.confirmMessage': '{lang}wcf.acp.article.i18n.toI18n.confirmMessage{/lang}',
-                       'wcf.acp.article.i18n.fromI18n.confirmMessage': '{lang}wcf.acp.article.i18n.fromI18n.confirmMessage{/lang}',
-                       'wcf.message.status.deleted': '{lang}wcf.message.status.deleted{/lang}',
+                       'wcf.acp.article.i18n.source': '{jslang}wcf.acp.article.i18n.source{/jslang}',
+                       'wcf.acp.article.i18n.toI18n.confirmMessage': '{jslang}wcf.acp.article.i18n.toI18n.confirmMessage{/jslang}',
+                       'wcf.acp.article.i18n.fromI18n.confirmMessage': '{jslang}wcf.acp.article.i18n.fromI18n.confirmMessage{/jslang}',
+                       'wcf.message.status.deleted': '{jslang}wcf.message.status.deleted{/jslang}',
                });
                
                new UiUserSearchInput(elBySel('input[name="username"]'));
@@ -84,7 +84,7 @@
                
                require(['WoltLabSuite/Core/Media/Manager/Select'], function(MediaManagerSelect) {
                        new MediaManagerSelect({
-                               dialogTitle: '{lang}wcf.media.chooseImage{/lang}',
+                               dialogTitle: '{jslang}wcf.media.chooseImage{/jslang}',
                                imagesOnly: 1
                        });
                });
        {@$__contentHeader}
 {/if}
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success" role="status">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $action == 'edit'}
        <p class="info jsArticleNoticeTrash"{if !$article->isDeleted} style="display: none;"{/if}>{lang}wcf.acp.article.trash.notice{/lang}</p>
                                                                        <div class="dropdownMenu">
                                                                                <ul class="scrollableDropdownMenu">
                                                                                        {foreach from=$labelGroup item=label}
-                                                                                               <li data-label-id="{@$label->labelID}"><span><span class="badge label{if $label->getClassNames()} {@$label->getClassNames()}{/if}">{$label->getTitle()}</span></span></li>
+                                                                                               <li data-label-id="{@$label->labelID}"><span>{@$label->render()}</span></li>
                                                                                        {/foreach}
                                                                                </ul>
                                                                        </div>
                                </dd>
                        </dl>
                        
+                       <dl{if $errorField == 'metaTitle'} class="formError"{/if}>
+                               <dt><label for="metaTitle0">{lang}wcf.acp.article.metaTitle{/lang}</label></dt>
+                               <dd>
+                                       <input type="text" id="metaTitle0" name="metaTitle[0]" value="{if !$metaTitle[0]|empty}{$metaTitle[0]}{/if}" class="long" maxlength="255">
+                                       {if $errorField == 'metaTitle'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.article.metaTitle.error.{@$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
+                       </dl>
+                       
+                       <dl{if $errorField == 'metaDescription'} class="formError"{/if}>
+                               <dt><label for="metaDescription0">{lang}wcf.acp.article.metaDescription{/lang}</label></dt>
+                               <dd>
+                                       <input type="text" id="metaDescription0" name="metaDescription[0]" value="{if !$metaDescription[0]|empty}{$metaDescription[0]}{/if}" class="long" maxlength="255">
+                                       {if $errorField == 'metaDescription'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.article.metaDescription.error.{@$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
+                       </dl>
+                       
                        {if MODULE_TAGGING}
-                               <dl class="jsOnly">
-                                       <dt><label for="tagSearchInput">{lang}wcf.tagging.tags{/lang}</label></dt>
-                                       <dd>
-                                               <input id="tagSearchInput" type="text" value="" class="long">
-                                               <small>{lang}wcf.tagging.tags.description{/lang}</small>
-                                       </dd>
-                               </dl>
-                               
-                               <script data-relocate="true">
-                                       require(['WoltLabSuite/Core/Ui/ItemList'], function(UiItemList) {
-                                               UiItemList.init(
-                                                       'tagSearchInput',
-                                                       [{if !$tags[0]|empty}{implode from=$tags[0] item=tag}'{@$tag|encodeJS}'{/implode}{/if}],
-                                                       {
-                                                               ajax: {
-                                                                       className: 'wcf\\data\\tag\\TagAction'
-                                                               },
-                                                               maxLength: {@TAGGING_MAX_TAG_LENGTH},
-                                                               submitFieldName: 'tags[0][]'
-                                                       }
-                                               );
-                                       });
-                               </script>
+                               {include file='tagInput' tagInputSuffix='0' tagSubmitFieldName='tags[0][]' tags=$tags[0] sandbox=true}
                        {/if}
                        
                        {event name='informationFields'}
                                                        </dd>
                                                </dl>
                                                
+                                               <dl{if $errorField == 'metaTitle'|concat:$availableLanguage->languageID} class="formError"{/if}>
+                                                       <dt><label for="metaTitle{@$availableLanguage->languageID}">{lang}wcf.acp.article.metaTitle{/lang}</label></dt>
+                                                       <dd>
+                                                               <input type="text" id="metaTitle{@$availableLanguage->languageID}" name="metaTitle[{@$availableLanguage->languageID}]" value="{if !$metaTitle[$availableLanguage->languageID]|empty}{$metaTitle[$availableLanguage->languageID]}{/if}" class="long" maxlength="255">
+                                                               {if $errorField == 'metaTitle'|concat:$availableLanguage->languageID}
+                                                                       <small class="innerError">
+                                                                               {if $errorType == 'empty'}
+                                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                                               {else}
+                                                                                       {lang}wcf.acp.article.metaTitle.error.{@$errorType}{/lang}
+                                                                               {/if}
+                                                                       </small>
+                                                               {/if}
+                                                       </dd>
+                                               </dl>
+                                               
+                                               <dl{if $errorField == 'metaDescription'|concat:$availableLanguage->languageID} class="formError"{/if}>
+                                                       <dt><label for="metaDescription{@$availableLanguage->languageID}">{lang}wcf.acp.article.metaDescription{/lang}</label></dt>
+                                                       <dd>
+                                                               <input type="text" id="metaDescription{@$availableLanguage->languageID}" name="metaDescription[{@$availableLanguage->languageID}]" value="{if !$metaDescription[$availableLanguage->languageID]|empty}{$metaDescription[$availableLanguage->languageID]}{/if}" class="long" maxlength="255">
+                                                               {if $errorField == 'metaDescription'|concat:$availableLanguage->languageID}
+                                                                       <small class="innerError">
+                                                                               {if $errorType == 'empty'}
+                                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                                               {else}
+                                                                                       {lang}wcf.acp.article.metaDescription.error.{@$errorType}{/lang}
+                                                                               {/if}
+                                                                       </small>
+                                                               {/if}
+                                                       </dd>
+                                               </dl>
+                                               
                                                {if MODULE_TAGGING}
-                                                       <dl class="jsOnly">
-                                                               <dt><label for="tagSearchInput{@$availableLanguage->languageID}">{lang}wcf.tagging.tags{/lang}</label></dt>
-                                                               <dd>
-                                                                       <input id="tagSearchInput{@$availableLanguage->languageID}" type="text" value="" class="long">
-                                                                       <small>{lang}wcf.tagging.tags.description{/lang}</small>
-                                                               </dd>
-                                                       </dl>
-                                                       
-                                                       <script data-relocate="true">
-                                                               require(['WoltLabSuite/Core/Ui/ItemList'], function(UiItemList) {
-                                                                       UiItemList.init(
-                                                                               'tagSearchInput{@$availableLanguage->languageID}',
-                                                                               [{if !$tags[$availableLanguage->languageID]|empty}{implode from=$tags[$availableLanguage->languageID] item=tag}'{@$tag|encodeJS}'{/implode}{/if}],
-                                                                               {
-                                                                                       ajax: {
-                                                                                               className: 'wcf\\data\\tag\\TagAction'
-                                                                                       },
-                                                                                       maxLength: {@TAGGING_MAX_TAG_LENGTH},
-                                                                                       submitFieldName: 'tags[{@$availableLanguage->languageID}][]'
-                                                                               }
-                                                                       );
-                                                               });
-                                                       </script>
+                                                       {assign var='tagSubmitFieldName' value='tags['|concat:$availableLanguage->languageID:'][]'}
+                                                       {include file='tagInput' tagInputSuffix=$availableLanguage->languageID tagSubmitFieldName=$tagSubmitFieldName tags=$tags[$availableLanguage->languageID] sandbox=true}
                                                {/if}
                                                
                                                {event name='informationFieldsMultilingual'}
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.label.none': '{lang}wcf.label.none{/lang}',
+                       'wcf.label.none': '{jslang}wcf.label.none{/jslang}',
                });
                
                {if !$labelGroups|empty}
index 35cb520d5655e7b61bc9ce4311b2b382877dbcf1..a0a5fcf75291dbbf3d294e7c4aaa5411e6dd421e 100644 (file)
@@ -18,7 +18,7 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Article/Add'], function(Language, AcpUiArticleAdd) {
                Language.addObject({
-                       'wcf.acp.article.add': '{lang}wcf.acp.article.add{/lang}'
+                       'wcf.acp.article.add': '{jslang}wcf.acp.article.add{/jslang}'
                });
                
                AcpUiArticleAdd.init('{link controller='ArticleAdd' encode=false}{literal}isMultilingual={$isMultilingual}{/literal}{if $categoryID}&categoryID={@$categoryID}{/if}{/link}');
index d9d4c904c28d8f3eb466eb31e67f7b5ea5becd53..1ead92767f7e3193ca8143011ddcf0b853bd74df 100644 (file)
@@ -4,9 +4,9 @@
        require(['Language', 'WoltLabSuite/Core/Controller/Clipboard', 'WoltLabSuite/Core/Ui/User/Search/Input', 'WoltLabSuite/Core/Acp/Ui/Article/InlineEditor'],
                function(Language, ControllerClipboard, UiUserSearchInput, AcpUiArticleInlineEditor) {
                Language.addObject({
-                       'wcf.acp.article.publicationStatus.unpublished': '{lang}wcf.acp.article.publicationStatus.unpublished{/lang}',
-                       'wcf.acp.article.setCategory': '{lang}wcf.acp.article.setCategory{/lang}',
-                       'wcf.message.status.deleted': '{lang}wcf.message.status.deleted{/lang}'
+                       'wcf.acp.article.publicationStatus.unpublished': '{jslang}wcf.acp.article.publicationStatus.unpublished{/jslang}',
+                       'wcf.acp.article.setCategory': '{jslang}wcf.acp.article.setCategory{/jslang}',
+                       'wcf.message.status.deleted': '{jslang}wcf.message.status.deleted{/jslang}'
                });
                
                new UiUserSearchInput(elBySel('input[name="username"]'));
                                                                        {if $article->hasLabels()}
                                                                                <ul class="labelList" style="float: right; padding-left: 7px;">
                                                                                        {foreach from=$article->getLabels() item=label}
-                                                                                               <li><span class="badge label{if $label->getClassNames()} {$label->getClassNames()}{/if}">{$label->getTitle()}</span></li>
+                                                                                               <li>{@$label->render()}</li>
                                                                                        {/foreach}
                                                                                </ul>
                                                                        {/if}
index cab157246cf2cbd723ff4c2f84300b31d3a06d25..276dea3b51c5cebbadeece6d6962aabad3618b18 100644 (file)
                                                <td class="columnID columnAttachmentID">{@$attachment->attachmentID}</td>
                                                <td class="columnTitle columnFilename">
                                                        <div class="box64">
-                                                               <a href="{link controller='Attachment' id=$attachment->attachmentID}{/link}"{if $attachment->isImage} class="jsImageViewer" title="{$attachment->filename}"{/if}>
+                                                               <a href="{$attachment->getLink()}"{if $attachment->isImage} class="jsImageViewer" title="{$attachment->filename}"{/if}>
                                                                        {if $attachment->tinyThumbnailType}
-                                                                               <img src="{link controller='Attachment' id=$attachment->attachmentID}tiny=1{/link}" class="attachmentTinyThumbnail" alt="">
+                                                                               <img src="{$attachment->getThumbnailLink('tiny')}" class="attachmentTinyThumbnail" alt="">
                                                                        {else}
                                                                                <span class="icon icon64 fa-{@$attachment->getIconName()}"></span>
                                                                        {/if}
                                                                </a>
                                                                
                                                                <div>
-                                                                       <p><a href="{link controller='Attachment' id=$attachment->attachmentID}{/link}">{$attachment->filename|tableWordwrap}</a></p>
+                                                                       <p><a href="{$attachment->getLink()}">{$attachment->filename|tableWordwrap}</a></p>
                                                                        <p><small>{if $attachment->userID}{if $__wcf->session->getPermission('admin.user.canEditUser')}<a href="{link controller='UserEdit' id=$attachment->userID}{/link}">{$attachment->username}</a>{else}{$attachment->username}{/if}{else}{lang}wcf.user.guest{/lang}{/if}</small></p>
                                                                        {if $attachment->getContainerObject()}<p><small><a href="{$attachment->getContainerObject()->getLink()}">{$attachment->getContainerObject()->getTitle()|tableWordwrap}</a></small></p>{/if}
                                                                </div>
index 166ac3802ae723ef5fa3d1a39db52fd06fe559d4..3abd4a11bcbfedc16ce6d09e1b82a8bf027cced1 100644 (file)
        <p class="info">{lang}wcf.acp.bbcode.add.userGroupOptionInfo{/lang}</p>
 {/if}
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='BBCodeAdd'}{/link}{else}{link controller='BBCodeEdit' object=$bbcode}{/link}{/if}">
        <div class="section">
index b4ae4ba487a643c8b678132eced5dcb013d4b60f..910f4c969347e3d9f7fca31ce66c679185b52590 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='BBCodeMediaProviderAdd'}{/link}{else}{link controller='BBCodeMediaProviderEdit' object=$mediaProvider}{/link}{/if}">
        <div class="section">
@@ -99,4 +95,4 @@
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 4177a184b8e4768adca8438cae9a4f2b9f1c0f44..19be7d8a8eafc6da33c7a2206410c161a8e5b6ea 100644 (file)
@@ -3,6 +3,6 @@
 
 <script data-relocate="true">
 $(function() {
-       $('#{$option->optionName}_age_from').parents('dl:eq(0)').find('> dt > label').text('{lang}wcf.user.birthday.age{/lang}').attr('for', '{$option->optionName}_age_from');
+       $('#{$option->optionName}_age_from').parents('dl:eq(0)').find('> dt > label').text('{jslang}wcf.user.birthday.age{/jslang}').attr('for', '{$option->optionName}_age_from');
 });
-</script>
\ No newline at end of file
+</script>
index 16d172d9f18490f8b29969e7e30f913bf0196e28..acacfdeb58bcdb30182ed5d574deb8deffd63a44 100644 (file)
        
        require(['Dictionary', 'Language', 'WoltLabSuite/Core/Acp/Ui/Box/Handler'], function(Dictionary, Language, AcpUiBoxHandler) {
                Language.addObject({
-                       'wcf.page.pageObjectID': '{lang}wcf.page.pageObjectID{/lang}',
+                       'wcf.page.pageObjectID': '{jslang}wcf.page.pageObjectID{/jslang}',
                        {foreach from=$pageNodeList item=pageNode}
                                {capture assign='pageObjectIDLanguageItem'}{lang __optional=true}wcf.page.pageObjectID.{@$pageNode->identifier}{/lang}{/capture}
                                {if $pageObjectIDLanguageItem}
-                                       'wcf.page.pageObjectID.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem}',
+                                       'wcf.page.pageObjectID.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem|encodeJS}',
                                {/if}
                                {capture assign='pageObjectIDLanguageItem'}{lang __optional=true}wcf.page.pageObjectID.search.{@$pageNode->identifier}{/lang}{/capture}
                                {if $pageObjectIDLanguageItem}
-                                       'wcf.page.pageObjectID.search.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem}',
+                                       'wcf.page.pageObjectID.search.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem|encodeJS}',
                                {/if}
                        {/foreach}
-                       'wcf.page.pageObjectID.search.noResults': '{lang}wcf.page.pageObjectID.search.noResults{/lang}',
-                       'wcf.page.pageObjectID.search.results': '{lang}wcf.page.pageObjectID.search.results{/lang}',
-                       'wcf.page.pageObjectID.search.terms': '{lang}wcf.page.pageObjectID.search.terms{/lang}'
+                       'wcf.page.pageObjectID.search.noResults': '{jslang}wcf.page.pageObjectID.search.noResults{/jslang}',
+                       'wcf.page.pageObjectID.search.results': '{jslang}wcf.page.pageObjectID.search.results{/jslang}',
+                       'wcf.page.pageObjectID.search.terms': '{jslang}wcf.page.pageObjectID.search.terms{/jslang}'
                });
                
                var handlers = new Dictionary();
@@ -38,7 +38,7 @@
        {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
                require(['WoltLabSuite/Core/Media/Manager/Select'], function(MediaManagerSelect) {
                        new MediaManagerSelect({
-                               dialogTitle: '{lang}wcf.media.chooseImage{/lang}',
+                               dialogTitle: '{jslang}wcf.media.chooseImage{/jslang}',
                                imagesOnly: 1
                        });
                });
@@ -47,7 +47,7 @@
        {if $action === 'edit'}
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Box/Copy'], function (Language, AcpUiBoxCopy) {
                        Language.addObject({
-                               'wcf.acp.box.copy': '{lang}wcf.acp.box.copy{/lang}'
+                               'wcf.acp.box.copy': '{jslang}wcf.acp.box.copy{/jslang}'
                        });
                        
                        AcpUiBoxCopy.init();
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $action == 'edit' && !$lastVersion|empty}
        <p class="info">{lang}wcf.acp.box.lastVersion{/lang}</p>
index d7d22ea9bca4211241e29a98971bf3da837bc381..679f71fd062e26102fbee6e4c8bb30011078c935 100644 (file)
@@ -34,7 +34,7 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Box/Add'], function(Language, AcpUiBoxAdd) {
                Language.addObject({
-                       'wcf.acp.box.add': '{lang}wcf.acp.box.add{/lang}'
+                       'wcf.acp.box.add': '{jslang}wcf.acp.box.add{/jslang}'
                });
                
                AcpUiBoxAdd.init('{link controller='BoxAdd' encode=false}{literal}boxType={$boxType}&isMultilingual={$isMultilingual}{/literal}{/link}', {@$availableLanguages|count});
index 3689a8e28fdc442b55160084eeee03f688584d79..939389ef1b641dd0197197cdb5b366fbeb3fa840 100644 (file)
@@ -16,7 +16,7 @@
                        <ul>
                                {content}
                                        {if $cacheData.files}
-                                               <li><a onclick="WCF.System.Confirmation.show('{lang}wcf.acp.cache.clear.sure{/lang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;" href="{link controller='CacheClear'}{/link}" class="button"><span class="icon icon16 fa-times"></span> <span>{lang}wcf.acp.cache.button.clear{/lang}</span></a></li>
+                                               <li><a onclick="WCF.System.Confirmation.show('{jslang}wcf.acp.cache.clear.sure{/jslang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;" href="{link controller='CacheClear'}{/link}" class="button"><span class="icon icon16 fa-times"></span> <span>{lang}wcf.acp.cache.button.clear{/lang}</span></a></li>
                                        {/if}
                                        
                                        {event name='contentHeaderNavigation'}
                        <ul>
                                {content}
                                        {if $cacheData.files}
-                                               <li><a onclick="WCF.System.Confirmation.show('{lang}wcf.acp.cache.clear.sure{/lang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;" href="{link controller='CacheClear'}{/link}" class="button"><span class="icon icon16 fa-times"></span> <span>{lang}wcf.acp.cache.button.clear{/lang}</span></a></li>
+                                               <li><a onclick="WCF.System.Confirmation.show('{jslang}wcf.acp.cache.clear.sure{/jslang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;" href="{link controller='CacheClear'}{/link}" class="button"><span class="icon icon16 fa-times"></span> <span>{lang}wcf.acp.cache.button.clear{/lang}</span></a></li>
                                        {/if}
                                        
                                        {event name='contentFooterNavigation'}
index eee5ffbbc65c91e1e9e8ac9cdb54e1f13d0e5eca..e5910ec8b8bec7172c30f5bf33883e494bc6ec09 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form id="adForm" method="post" action="{if $action == 'add'}{link controller='CaptchaQuestionAdd'}{/link}{else}{link controller='CaptchaQuestionEdit' id=$captchaQuestion->questionID}{/link}{/if}">
        <div class="section">
index 7d2d372d0e9b6b9e11578ac2088f7b82387fd8fa..4835179d0c47d24fa5534631aac57508677a2195 100644 (file)
@@ -12,7 +12,7 @@
                                options.updatePageNumber = -1;
                        {/if}
                {else}
-                       options.emptyMessage = '{lang}wcf.global.noItems{/lang}';
+                       options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
                {/if}
                
                new WCF.Table.EmptyTableHandler($('#captchaQuestionTabelContainer'), 'jsQuestionRow', options);
@@ -39,7 +39,7 @@
        </div>
 {/hascontent}
 
-{hascontent}
+{if $objects|count}
        <div id="captchaQuestionTabelContainer" class="section tabularBox">
                <table class="table">
                        <thead>
                        </thead>
                        
                        <tbody>
-                               {content}
-                                       {foreach from=$objects item='question'}
-                                               <tr class="jsQuestionRow">
-                                                       <td class="columnIcon">
-                                                               <span class="icon icon16 fa-{if !$question->isDisabled}check-{/if}square-o jsToggleButton jsTooltip pointer" title="{lang}wcf.global.button.{if $question->isDisabled}enable{else}disable{/if}{/lang}" data-object-id="{@$question->questionID}"></span>
-                                                               <a href="{link controller='CaptchaQuestionEdit' id=$question->questionID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
-                                                               <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$question->questionID}" data-confirm-message-html="{lang __encode=true}wcf.acp.captcha.question.delete.confirmMessage{/lang}"></span>
-                                                               
-                                                               {event name='rowButtons'}
-                                                       </td>
-                                                       <td class="columnID columnQuestionID">{$question->questionID}</td>
-                                                       <td class="columnText columnQuestion"><a href="{link controller='CaptchaQuestionEdit' id=$question->questionID}{/link}">{$question->getQuestion()}</a></td>
+                               {foreach from=$objects item='question'}
+                                       <tr class="jsQuestionRow">
+                                               <td class="columnIcon">
+                                                       <span class="icon icon16 fa-{if !$question->isDisabled}check-{/if}square-o jsToggleButton jsTooltip pointer" title="{lang}wcf.global.button.{if $question->isDisabled}enable{else}disable{/if}{/lang}" data-object-id="{@$question->questionID}"></span>
+                                                       <a href="{link controller='CaptchaQuestionEdit' id=$question->questionID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
+                                                       <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$question->questionID}" data-confirm-message-html="{lang __encode=true}wcf.acp.captcha.question.delete.confirmMessage{/lang}"></span>
                                                        
-                                                       {event name='columns'}
-                                               </tr>
-                                       {/foreach}
-                               {/content}
+                                                       {event name='rowButtons'}
+                                               </td>
+                                               <td class="columnID columnQuestionID">{$question->questionID}</td>
+                                               <td class="columnText columnQuestion"><a href="{link controller='CaptchaQuestionEdit' id=$question->questionID}{/link}">{$question->getQuestion()}</a></td>
+                                               
+                                               {event name='columns'}
+                                       </tr>
+                               {/foreach}
                        </tbody>
                </table>
        </div>
-{hascontentelse}
-       <p class="info">{lang}wcf.global.noItems{/lang}</p>
-{/hascontent}
-
-<footer class="contentFooter">
-       {hascontent}
-               <div class="paginationBottom">
-                       {content}{@$pagesLinks}{/content}
-               </div>
-       {/hascontent}
        
-       <nav class="contentFooterNavigation">
-               <ul>
-                       <li><a href="{link controller='CaptchaQuestionAdd'}{/link}" class="button"><span class="icon icon16 fa-plus"></span> <span>{lang}wcf.acp.captcha.question.add{/lang}</span></a></li>
-                       
-                       {event name='contentFooterNavigation'}
-               </ul>
-       </nav>
-</footer>
+       <footer class="contentFooter">
+               {hascontent}
+                       <div class="paginationBottom">
+                               {content}{@$pagesLinks}{/content}
+                       </div>
+               {/hascontent}
+               
+               <nav class="contentFooterNavigation">
+                       <ul>
+                               <li><a href="{link controller='CaptchaQuestionAdd'}{/link}" class="button"><span class="icon icon16 fa-plus"></span> <span>{lang}wcf.acp.captcha.question.add{/lang}</span></a></li>
+                               
+                               {event name='contentFooterNavigation'}
+                       </ul>
+               </nav>
+       </footer>
+{else}
+       <p class="info">{lang}wcf.global.noItems{/lang}</p>
+{/if}
 
 {include file='footer'}
\ No newline at end of file
index 8297538c72ddd1181d7f940076dd98d50141cffd..812033c80f794e1ab062f6184fcf3273a263db15 100644 (file)
        {/hascontent}
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{@$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller=$addController application=$objectType->getProcessor()->getApplication()}{/link}{else}{link controller=$editController application=$objectType->getProcessor()->getApplication() object=$category}{/link}{/if}">
        {event name='beforeSections'}
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
diff --git a/wcfsetup/install/files/acp/templates/codeMetaCode.tpl b/wcfsetup/install/files/acp/templates/codeMetaCode.tpl
new file mode 100644 (file)
index 0000000..35c0c8c
--- /dev/null
@@ -0,0 +1,32 @@
+<div class="codeBox collapsibleBbcode jsCollapsibleBbcode {if $lines > 10} collapsed{/if}">
+       <div class="codeBoxHeader">
+               <div class="codeBoxHeadline">{$title}{if $filename}: {$filename}{/if}</div>
+               
+               {if !$isAmp && $lines > 10}
+                       <span class="toggleButton icon icon24 fa-expand jsTooltip pointer" title="{lang}wcf.bbcode.button.showAll{/lang}" data-title-collapse="{lang}wcf.bbcode.button.collapse{/lang}" data-title-expand="{lang}wcf.bbcode.button.showAll{/lang}"></span>
+               {/if}
+       </div>
+       
+       {assign var='lineNumber' value=$startLineNumber}
+       <pre class="codeBoxCode collapsibleBbcodeOverflow"><code{if $language} class="language-{$language}"{/if}>{foreach from=$content item=line}{*
+               *}{assign var='codeLineID' value='codeLine_'|concat:$lineNumber:'_':$codeID}{*
+               *}<span class="codeBoxLine" id="{$codeLineID}"><a href="{@$__wcf->getAnchor($codeLineID)}" class="lineAnchor" title="{@$lineNumber}"></a><span>{$line}</span></span>{*
+               *}{assign var='lineNumber' value=$lineNumber+1}{*
+       *}{/foreach}</code></pre>
+       
+       {if !$isAmp && $lines > 10}
+               <span class="toggleButton" data-title-collapse="{lang}wcf.bbcode.button.collapse{/lang}" data-title-expand="{lang}wcf.bbcode.button.showAll{/lang}">{lang}wcf.bbcode.button.showAll{/lang}</span>
+       {/if}
+</div>
+{if !$isAmp}
+       <script data-relocate="true">
+               require(['Language', 'WoltLabSuite/Core/Bbcode/Collapsible', 'WoltLabSuite/Core/Bbcode/Code'], function (Language, BbcodeCollapsible, BbcodeCode) {
+                       Language.addObject({
+                               'wcf.message.bbcode.code.copy': '{jslang}wcf.message.bbcode.code.copy{/jslang}',
+                               'wcf.message.bbcode.code.copy.success': '{jslang}wcf.message.bbcode.code.copy.success{/jslang}'
+                       });
+                       BbcodeCollapsible.observe();
+                       BbcodeCode.processAll();
+               });
+       </script>
+{/if}
index fe7b64c74b73050e7ebc91688a31b131f1bdf342..5a27c7e6f730bdf61ad8e54d10af8edd06059982 100644 (file)
                                        }
                                });
                        }
+                       
+                       var scrollOffsetStorage = element;
+                       do {
+                               scrollOffsetStorage = scrollOffsetStorage.nextElementSibling;
+                       } while (scrollOffsetStorage && !scrollOffsetStorage.classList.contains('codeMirrorScrollOffset'));
+                       if (scrollOffsetStorage) {
+                               element.codemirror.scrollTo(null, scrollOffsetStorage.value);
+                               element.codemirror.on('scroll', function (cm) {
+                                       scrollOffsetStorage.value = cm.getScrollInfo().top;
+                               });
+                       }
                });
        });
 </script>
index 1468dd671967b03f274ff9ab190863077deea171..5e4803ba424b4d6cdf8daf1f98e53eef4c5213e4 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action === 'add'}{link controller='ContactOptionAdd'}{/link}{else}{link controller='ContactOptionEdit' id=$optionID}{/link}{/if}">
        {include file='customOptionAdd'}
index 6bab6a3ea413bea9fdce2fea018909abb698df74..33d099241ad411524f9cee75edd701077ebec488 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{@$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action === 'add'}{link controller='ContactRecipientAdd'}{/link}{else}{link controller='ContactRecipientEdit' id=$recipientID}{/link}{/if}">
        <div class="section">
index fe3baef0b0b7738c11c424c9529faf1cccebc16c..944cb961a26a0cbc9ef5327370bd7182ad84e497 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
 <p class="info">{lang}wcf.acp.cronjob.intro{/lang}</p>
 
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='CronjobAdd'}{/link}{else}{link controller='CronjobEdit' id=$cronjobID}{/link}{/if}">
        <div class="section">
index 762a4c15267b5a0b86f43e966d7517450235719b..4da31508f86d5c07b119ef26e432a418d50f39a9 100644 (file)
@@ -41,7 +41,7 @@
                                        <th class="columnDate columnStartDom{if $sortField == 'startDom'} active {@$sortOrder}{/if}" title="{lang}wcf.acp.cronjob.startDom{/lang}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=startDom&sortOrder={if $sortField == 'startDom' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.startDomShort{/lang}</a></th>
                                        <th class="columnDate columnStartMonth{if $sortField == 'startMonth'} active {@$sortOrder}{/if}" title="{lang}wcf.acp.cronjob.startMonth{/lang}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=startMonth&sortOrder={if $sortField == 'startMonth' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.startMonthShort{/lang}</a></th>
                                        <th class="columnDate columnStartDow{if $sortField == 'startDow'} active {@$sortOrder}{/if}" title="{lang}wcf.acp.cronjob.startDow{/lang}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=startDow&sortOrder={if $sortField == 'startDow' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.startDowShort{/lang}</a></th>
-                                       <th class="columnText columnDescription">{lang}wcf.acp.cronjob.description{/lang}</th>
+                                       <th class="columnText columnDescription{if $sortField == 'descriptionI18n'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=descriptionI18n&sortOrder={if $sortField == 'descriptionI18n' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.description{/lang}</a></th>
                                        <th class="columnDate columnNextExec{if $sortField == 'nextExec'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobList'}pageNo={@$pageNo}&sortField=nextExec&sortOrder={if $sortField == 'nextExec' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.nextExec{/lang}</a></th>
                                        
                                        {event name='columnHeads'}
@@ -84,7 +84,7 @@
                                                        <td class="columnDate columnStartDom">{$cronjob->startDom|truncate:30}</td>
                                                        <td class="columnDate columnStartMonth">{$cronjob->startMonth|truncate:30}</td>
                                                        <td class="columnDate columnStartDow">{$cronjob->startDow|truncate:30}</td>
-                                                       <td class="columnText columnDescription" title="{$cronjob->getDescription()}">
+                                                       <td class="columnText columnDescription">
                                                                {if $cronjob->isEditable()}
                                                                        <a title="{lang}wcf.acp.cronjob.edit{/lang}" href="{link controller='CronjobEdit' id=$cronjob->cronjobID}{/link}">{$cronjob->getDescription()}</a>
                                                                {else}
index 3c86a6e744d310ba7c4c0d40b4a79cc8138db2f8..9d3852c637f02ece6588283d33bb6667b8ee30ce 100644 (file)
@@ -3,8 +3,8 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.cronjob.log.clear.confirm': '{lang}wcf.acp.cronjob.log.clear.confirm{/lang}',
-                       'wcf.acp.cronjob.log.error.details': '{lang}wcf.acp.cronjob.log.error.details{/lang}'
+                       'wcf.acp.cronjob.log.clear.confirm': '{jslang}wcf.acp.cronjob.log.clear.confirm{/jslang}',
+                       'wcf.acp.cronjob.log.error.details': '{jslang}wcf.acp.cronjob.log.error.details{/jslang}'
                });
                
                new WCF.ACP.Cronjob.LogList();
        {/hascontent}
 </header>
 
+<form method="post" action="{link controller='CronjobLogList'}{/link}">
+       <section class="section">
+               <h2 class="sectionTitle">{lang}wcf.global.filter{/lang}</h2>
+               
+               <div class="row rowColGap formGrid">
+                       <dl class="col-xs-12 col-md-4">
+                               <dt></dt>
+                               <dd>
+                                       <select name="cronjobID" aria-label="{lang}wcf.acp.cronjob.description{/lang}">
+                                               <option value="0">{lang}wcf.acp.cronjob.description{/lang}</option>
+                                               {foreach from=$availableCronjobs item=availableCronjob}
+                                                       <option value="{@$availableCronjob->cronjobID}"{if $availableCronjob->cronjobID == $cronjobID} selected{/if}>{$availableCronjob->description|language}</option>
+                                               {/foreach}
+                                       </select>
+                               </dd>
+                       </dl>
+                       
+                       <dl class="col-xs-12 col-md-4">
+                               <dt></dt>
+                               <dd>
+                                       <select name="success" aria-label="{lang}wcf.acp.cronjob.log.status{/lang}">
+                                               <option value="-1">{lang}wcf.acp.cronjob.log.status{/lang}</option>
+                                               <option value="1"{if $success == 1} selected{/if}>{lang}wcf.acp.cronjob.log.success{/lang}</option>
+                                               <option value="0"{if $success == 0} selected{/if}>{lang}wcf.acp.cronjob.log.error{/lang}</option>
+                                       </select>
+                               </dd>
+                       </dl>
+                       
+                       {event name='filterFields'}
+               </div>
+               
+               <div class="formSubmit">
+                       <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
+                       {@SECURITY_TOKEN_INPUT_TAG}
+               </div>
+       </section>
+</form>
+
+{assign var='linkParameters' value=''}
+{if $cronjobID}{capture append=linkParameters}&cronjobID={@$cronjobID}{/capture}{/if}
+{if $success != -1}{capture append=linkParameters}&success={@$success}{/capture}{/if}
+
 {hascontent}
        <div class="paginationTop">
-               {content}{pages print=true assign=pagesLinks controller="CronjobLogList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
+               {content}{pages print=true assign=pagesLinks controller="CronjobLogList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder$linkParameters"}{/content}
        </div>
 {/hascontent}
 
                <table class="table">
                        <thead>
                                <tr>
-                                       <th class="columnID columnCronjobID{if $sortField == 'cronjobID'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=cronjobID&sortOrder={if $sortField == 'cronjobID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
-                                       <th class="columnTitle columnClassName{if $sortField == 'className'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=className&sortOrder={if $sortField == 'className' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.className{/lang}</a></th>
-                                       <th class="columnText columnDescription{if $sortField == 'description'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=description&sortOrder={if $sortField == 'description' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.description{/lang}</a></th>
-                                       <th class="columnDate columnExecTime{if $sortField == 'execTime'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=execTime&sortOrder={if $sortField == 'execTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.log.execTime{/lang}</a></th>
-                                       <th class="columnText columnSuccess{if $sortField == 'success'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=success&sortOrder={if $sortField == 'success' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.cronjob.log.status{/lang}</a></th>
+                                       <th class="columnID columnCronjobID{if $sortField == 'cronjobID'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=cronjobID&sortOrder={if $sortField == 'cronjobID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
+                                       <th class="columnTitle columnClassName{if $sortField == 'className'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=className&sortOrder={if $sortField == 'className' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.acp.cronjob.className{/lang}</a></th>
+                                       <th class="columnText columnDescription{if $sortField == 'description'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=description&sortOrder={if $sortField == 'description' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.acp.cronjob.description{/lang}</a></th>
+                                       <th class="columnDate columnExecTime{if $sortField == 'execTime'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=execTime&sortOrder={if $sortField == 'execTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.acp.cronjob.log.execTime{/lang}</a></th>
+                                       <th class="columnText columnSuccess{if $sortField == 'success'} active {@$sortOrder}{/if}"><a href="{link controller='CronjobLogList'}pageNo={@$pageNo}&sortField=success&sortOrder={if $sortField == 'success' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.acp.cronjob.log.status{/lang}</a></th>
                                        
                                        {event name='columnHeads'}
                                </tr>
index 048f49a55ea0e34fca55919dc4a93d7f262bb984..1eecc1cf348338b7437762124af79768d2d06a5b 100644 (file)
@@ -4,9 +4,9 @@
        $(function() {
                {if $queue|isset}
                        WCF.Language.addObject({
-                               'wcf.acp.dataImport': '{lang}wcf.acp.dataImport{/lang}',
-                               'wcf.acp.dataImport.completed': '{lang}wcf.acp.dataImport.completed{/lang}',
-                               {implode from=$importers item=importer}'wcf.acp.dataImport.data.{@$importer}': '{lang}wcf.acp.dataImport.data.{@$importer}{/lang}'{/implode}
+                               'wcf.acp.dataImport': '{jslang}wcf.acp.dataImport{/jslang}',
+                               'wcf.acp.dataImport.completed': '{jslang}wcf.acp.dataImport.completed{/jslang}',
+                               {implode from=$importers item=importer}'wcf.acp.dataImport.data.{@$importer}': '{jslang}wcf.acp.dataImport.data.{@$importer}{/jslang}'{/implode}
                        });
                        
                        var $queues = [ {implode from=$queue item=item}'{@$item}'{/implode} ];
 
 {include file='formError'}
 
-{if $showInnoDBWarning}
-       <p class="warning">{lang}wcf.acp.index.innoDBWarning{/lang}</p>
-{/if}
-
 {if !$exporterName}
        {if !$availableExporters|count}
                <p class="info">{lang}wcf.acp.dataImport.selectExporter.noExporters{/lang}</p>
@@ -65,7 +61,7 @@
                        <script data-relocate="true">
                                $(function() {
                                        $('#deleteMapping').click(function() {
-                                               WCF.System.Confirmation.show('{lang}wcf.acp.dataImport.existingMapping.confirmMessage{/lang}', function(action) {
+                                               WCF.System.Confirmation.show('{jslang}wcf.acp.dataImport.existingMapping.confirmMessage{/jslang}', function(action) {
                                                        if (action === 'confirm') {
                                                                new WCF.Action.Proxy({
                                                                        autoSend: true,
diff --git a/wcfsetup/install/files/acp/templates/devtoolsMissingLanguageItemList.tpl b/wcfsetup/install/files/acp/templates/devtoolsMissingLanguageItemList.tpl
new file mode 100644 (file)
index 0000000..177b362
--- /dev/null
@@ -0,0 +1,139 @@
+{include file='header' pageTitle='wcf.acp.menu.link.devtools.missingLanguageItem.list'}
+
+<header class="contentHeader">
+       <div class="contentHeaderTitle">
+               <h1 class="contentTitle">{lang}wcf.acp.menu.link.devtools.missingLanguageItem.list{/lang}{if $items} <span class="badge badgeInverse">{#$items}</span>{/if}</h1>
+       </div>
+       
+       {hascontent}
+               <nav class="contentHeaderNavigation">
+                       <ul>
+                               {content}
+                                       {if $items}
+                                               <li><a href="#" id="clearMissingLanguageItemLog" class="button"><span class="icon icon16 fa-times"></span> <span>{lang}wcf.acp.devtools.missingLanguageItem.clearLog{/lang}</span></a></li>
+                                       {/if}
+                                       
+                                       {event name='contentHeaderNavigation'}
+                               {/content}
+                       </ul>
+               </nav>
+       {/hascontent}
+</header>
+
+{hascontent}
+       <div class="paginationTop">
+               {content}
+                       {pages print=true assign=pagesLinks controller='DevtoolsMissingLanguageItemList' link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}
+               {/content}
+       </div>
+{/hascontent}
+
+{if $items}
+       <div id="missingLanguageItemTable" class="section tabularBox">
+               <table class="table">
+                       <thead>
+                               <tr>
+                                       <th class="columnID{if $sortField === 'itemID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='DevtoolsMissingLanguageItemList'}sortField=itemID&sortOrder={if $sortField === 'itemID' && $sortOrder === 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
+                                       <th class="columnText{if $sortField === 'languageID'} active {@$sortOrder}{/if}"><a href="{link controller='DevtoolsMissingLanguageItemList'}sortField=languageID&sortOrder={if $sortField === 'languageID' && $sortOrder === 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.devtools.missingLanguageItem.languageID{/lang}</a></th>
+                                       <th class="columnText{if $sortField === 'languageItem'} active {@$sortOrder}{/if}"><a href="{link controller='DevtoolsMissingLanguageItemList'}sortField=languageItem&sortOrder={if $sortField === 'languageItem' && $sortOrder === 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.devtools.missingLanguageItem.languageItem{/lang}</a></th>
+                                       <th class="columnText{if $sortField === 'lastTime'} active {@$sortOrder}{/if}"><a href="{link controller='DevtoolsMissingLanguageItemList'}sortField=lastTime&sortOrder={if $sortField === 'lastTime' && $sortOrder === 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.devtools.missingLanguageItem.lastTime{/lang}</a></th>
+                                       
+                                       {event name='columnHeads'}
+                               </tr>
+                       </thead>
+                       
+                       <tbody>
+                               {foreach from=$objects item=logEntry}
+                                       <tr class="jsObjectRow">
+                                               <td class="columnIcon">
+                                                       <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$logEntry->getObjectID()}" data-confirm-message-html="{lang __encode=true}wcf.acp.devtools.missingLanguageItem.delete.confirmMessage{/lang}"></span>
+                                                       <span class="icon icon16 fa-align-justify jsStackTraceButton jsTooltip pointer" title="{lang}wcf.acp.devtools.missingLanguageItem.showStackTrace{/lang}" data-stack-trace="{$logEntry->getStackTrace()}"></span>
+                                               </td>
+                                               <td class="columnID">{@$logEntry->getObjectID()}</td>
+                                               <td class="columnText">{if $logEntry->getLanguage()}{$logEntry->getLanguage()}{else}{$logEntry->languageID}{/if}</td>
+                                               <td class="columnText">{$logEntry->languageItem}</td>
+                                               <td class="columnDate">{@$logEntry->lastTime|time}</td>
+                                       </tr>
+                               {/foreach}
+                       </tbody>
+               </table>
+       </div>
+
+       <footer class="contentFooter">
+               {hascontent}
+                       <div class="paginationBottom">
+                               {content}{@$pagesLinks}{/content}
+                       </div>
+               {/hascontent}
+               
+               {hascontent}
+                       <nav class="contentFooterNavigation">
+                               <ul>
+                                       {content}
+                                               {event name='contentFooterNavigation'}
+                                       {/content}
+                               </ul>
+                       </nav>
+               {/hascontent}
+       </footer>
+       
+       <script data-relocate="true">
+               require(['Ajax', 'Ui/Confirmation', 'Ui/Dialog'], function(Ajax, UiConfirmation, UiDialog) {
+                       new WCF.Action.Delete('wcf\\data\\devtools\\missing\\language\\item\\DevtoolsMissingLanguageItemAction', '.jsObjectRow');
+                       
+                       elBySelAll('.jsStackTraceButton', undefined, function(button) {
+                               button.addEventListener('click', function(event) {
+                                       var dialog = UiDialog.openStatic(
+                                               'logEntryStackTrace',
+                                               elData(event.currentTarget, 'stack-trace'),
+                                               {
+                                                       title: '{jslang}wcf.acp.devtools.missingLanguageItem.stackTrace{/jslang}',
+                                               }
+                                       );
+                                       
+                                       elBySel('.jsOutputFormatToggle', dialog.dialog).addEventListener('click', function(event) {
+                                               var pre = event.currentTarget.nextElementSibling;
+                                               if (pre.style.whiteSpace) {
+                                                       pre.style.whiteSpace = '';
+                                               }
+                                               else {
+                                                       pre.style.whiteSpace = 'pre-wrap';
+                                               }
+                                       });
+                               });
+                       });
+                       
+                       elById('clearMissingLanguageItemLog').addEventListener('click', function() {
+                               UiConfirmation.show({
+                                       'confirm': function() {
+                                               Ajax.apiOnce({
+                                                       data: {
+                                                               actionName: 'clearLog',
+                                                               className: 'wcf\\data\\devtools\\missing\\language\\item\\DevtoolsMissingLanguageItemAction',
+                                                       },
+                                                       success: function() {
+                                                               window.location.reload();
+                                                       }
+                                               });
+                                       },
+                                       'message': '{jslang}wcf.acp.devtools.missingLanguageItem.clearLog.confirmMessage{/jslang}',
+                               });
+                       });
+                       
+                       var options = { };
+                       {if $pages > 1}
+                               options.refreshPage = true;
+                               {if $pages == $pageNo}
+                                       options.updatePageNumber = -1;
+                               {/if}
+                       {else}
+                               options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
+                       {/if}
+                       new WCF.Table.EmptyTableHandler($('#missingLanguageItemTable'), 'jsObjectRow', options);
+               });
+       </script>
+{else}
+       <p class="info">{lang}wcf.global.noItems{/lang}</p>
+{/if}
+
+{include file='footer'}
index 09acf84468888a774683097e6947f725de173dc2..d35fccfceffee2d7f8086449b7a61894585fa296 100644 (file)
@@ -32,7 +32,7 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Devtools/Notification/Test'], function(Language, AcpUiDevtoolsNotificationTest) {
                Language.addObject({
-                       'wcf.acp.devtools.notificationTest.button.test': '{lang}wcf.acp.devtools.notificationTest.button.test{/lang}'
+                       'wcf.acp.devtools.notificationTest.button.test': '{jslang}wcf.acp.devtools.notificationTest.button.test{/jslang}'
                });
                
                AcpUiDevtoolsNotificationTest.init();
index a8fa0ec2779cf33c3f0ab575577481d57adf2247..a7390ecf7c5425e6b1d2bd8d733ac00db33587eb 100644 (file)
@@ -6,7 +6,7 @@
        });
        
        require(['WoltLabSuite/Core/Acp/Ui/Devtools/Project/QuickSetup', 'Language'], function(AcpUiDevtoolsProjectQuickSetup, Language) {
-               Language.add('wcf.acp.devtools.project.quickSetup', '{lang}wcf.acp.devtools.project.quickSetup{/lang}');
+               Language.add('wcf.acp.devtools.project.quickSetup', '{jslang}wcf.acp.devtools.project.quickSetup{/jslang}');
                
                AcpUiDevtoolsProjectQuickSetup.init();
        });
index 7e4ed668d593035ceaaae6b52d9c1022fa26a0e7..0cecbc0ed584c455a43cce28f8e3588a11df4979 100644 (file)
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Devtools/Project/Pip/Entry/List'], function(Language, DevtoolsProjectPipEntryList) {
                Language.addObject({
-                       'wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction': '{lang}wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction{/lang}',
-                       'wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction.description': '{lang}wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction.description{/lang}',
-                       'wcf.acp.devtools.project.pip.entry.delete.confirmMessage': '{lang}wcf.acp.devtools.project.pip.entry.delete.confirmMessage{/lang}'
+                       'wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction': '{jslang}wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction{/jslang}',
+                       'wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction.description': '{jslang}wcf.acp.devtools.project.pip.entry.delete.addDeleteInstruction.description{/jslang}',
+                       'wcf.acp.devtools.project.pip.entry.delete.confirmMessage': '{jslang}wcf.acp.devtools.project.pip.entry.delete.confirmMessage{/jslang}'
                });
                
                new DevtoolsProjectPipEntryList('devtoolsProjectPipEntryList', '{@$project->projectID}', '{@$pip}', '{@$entryType}', {if $pipObject->getPip()->supportsDeleteInstruction()}true{else}false{/if});
index 74fc4f537862ce0d49382dab1495041466dccea8..3207e95996bde738abfb72b5c1836bca0f1a5dbf 100644 (file)
@@ -81,8 +81,8 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Devtools/Project/Sync'], function(Language, AcpUiDevtoolsProjectSync) {
                        Language.addObject({
-                               'wcf.acp.devtools.sync.status.failure': '{lang}wcf.acp.devtools.sync.status.failure{/lang}',
-                               'wcf.acp.devtools.sync.syncAll': '{lang}wcf.acp.devtools.sync.syncAll{/lang}'
+                               'wcf.acp.devtools.sync.status.failure': '{jslang}wcf.acp.devtools.sync.status.failure{/jslang}',
+                               'wcf.acp.devtools.sync.syncAll': '{jslang}wcf.acp.devtools.sync.syncAll{/jslang}'
                        });
                        
                        AcpUiDevtoolsProjectSync.init({$object->projectID});
index a52593dea89eb89e56696733d607fa75d06e6550..7a26735b7615d0d0cde4bb7a0daee97e1a125c09 100644 (file)
                $('.jsCopyException').click(function () {
                        $(this).select();
                });
+               
+               elBySelAll('.exceptionContainer', undefined, function (container) {
+                       var button = elBySel('.collapsibleButton', container);
+                       button.addEventListener('click', function (event) {
+                               if (container.classList.toggle('collapsed')) {
+                                       button.classList.add('fa-chevron-right');
+                                       button.classList.remove('fa-chevron-down');
+                               }
+                               else {
+                                       button.classList.remove('fa-chevron-right');
+                                       button.classList.add('fa-chevron-down');
+                               }
+                       });
+               })
        });
 </script>
 
 {if !$logFiles|empty}
        {if $logFile}
                {foreach from=$exceptions item='exception' key='exceptionKey'}
-                       <section id="{$exceptionKey}" class="section">
-                               <h2 class="sectionTitle">{$exception[message]}</h2>
-                               
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.date{/lang}</dt>
-                                       <dd>{$exception[date]|plainTime}</dd>
-                               </dl>
+                       <section id="{$exceptionKey}" class="section exceptionContainer{if $exception[collapsed]|isset && $exception[collapsed]} collapsed{/if}">
+                               <h2 class="sectionTitle">
+                                       <span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-{if $exception[collapsed]|isset && $exception[collapsed]}right{else}down{/if}" title="{lang}wcf.global.button.collapsible{/lang}"></span>
+                                       {$exception[message]}
+                               </h2>
                                
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.requestURI{/lang}</dt>
-                                       <dd>{$exception[requestURI]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.referrer{/lang}</dt>
-                                       <dd>{$exception[referrer]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.userAgent{/lang}</dt>
-                                       <dd>{$exception[userAgent]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.memory{/lang}</dt>
-                                       <dd>{$exception[peakMemory]|filesizeBinary} / {if $exception[maxMemory] == -1}&infin;{else}{$exception[maxMemory]|filesizeBinary}{/if}</dd>
-                               </dl>
-                               {foreach from=$exception[chain] item=chain}
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.message{/lang}</dt>
-                                       <dd>{$chain[message]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.class{/lang}</dt>
-                                       <dd>{$chain[class]}</dd>
-                               </dl>
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.file{/lang}</dt>
-                                       <dd>{$chain[file]} ({$chain[line]})</dd>
-                               </dl>
-                               {if !$chain[information]|empty}
-                                       {foreach from=$chain[information] item=extraInformation}
-                                               <dl>
-                                                       <dt>{$extraInformation[0]}</dt>
-                                                       <dd>{$extraInformation[1]}</dd>
-                                               </dl>
+                               <div class="exceptionDetails">
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.date{/lang}</dt>
+                                               <dd>{$exception[date]|plainTime}</dd>
+                                       </dl>
+                                       
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.requestURI{/lang}</dt>
+                                               <dd>{$exception[requestURI]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.referrer{/lang}</dt>
+                                               <dd>{$exception[referrer]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.userAgent{/lang}</dt>
+                                               <dd>{$exception[userAgent]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.memory{/lang}</dt>
+                                               <dd>{$exception[peakMemory]|filesizeBinary} / {if $exception[maxMemory] == -1}&infin;{else}{$exception[maxMemory]|filesizeBinary}{/if}</dd>
+                                       </dl>
+                                       {foreach from=$exception[chain] item=chain}
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.message{/lang}</dt>
+                                               <dd>{$chain[message]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.class{/lang}</dt>
+                                               <dd>{$chain[class]}</dd>
+                                       </dl>
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.file{/lang}</dt>
+                                               <dd>{$chain[file]} ({$chain[line]})</dd>
+                                       </dl>
+                                       {if !$chain[information]|empty}
+                                               {foreach from=$chain[information] item=extraInformation}
+                                                       <dl>
+                                                               <dt>{$extraInformation[0]}</dt>
+                                                               <dd>{$extraInformation[1]}</dd>
+                                                       </dl>
+                                               {/foreach}
+                                       {/if}
+                                       <dl>
+                                               <dt>{lang}wcf.acp.exceptionLog.exception.stacktrace{/lang}</dt>
+                                               <dd>
+                                                       <ol start="0" class="nativeList">
+                                                               {foreach from=$chain[stack] item=stack}
+                                                               <li>{$stack[file]} ({$stack[line]}): {$stack[class]}{$stack[type]}{$stack[function]}(&hellip;)</li>
+                                                               {/foreach}
+                                                       </ol>
+                                               </dd>
+                                       </dl>
                                        {/foreach}
-                               {/if}
-                               <dl>
-                                       <dt>{lang}wcf.acp.exceptionLog.exception.stacktrace{/lang}</dt>
-                                       <dd>
-                                               <ol start="0" class="nativeList">
-                                                       {foreach from=$chain[stack] item=stack}
-                                                       <li>{$stack[file]} ({$stack[line]}): {$stack[class]}{$stack[type]}{$stack[function]}(&hellip;)</li>
-                                                       {/foreach}
-                                               </ol>
-                                       </dd>
-                               </dl>
-                               {/foreach}
-                               <dl>
-                                       <dt><label for="copyException{$exceptionKey}">{lang}wcf.acp.exceptionLog.exception.copy{/lang}</label></dt>
-                                       <dd><textarea id="copyException{$exceptionKey}" rows="5" cols="40" class="jsCopyException" readonly>{$exception[0]}</textarea></dd>
-                               </dl>
+                                       <dl>
+                                               <dt><label for="copyException{$exceptionKey}">{lang}wcf.acp.exceptionLog.exception.copy{/lang}</label></dt>
+                                               <dd><textarea id="copyException{$exceptionKey}" rows="5" cols="40" class="jsCopyException" readonly>{$exception[0]}</textarea></dd>
+                                       </dl>
+                               </div>
                        </section>
                {/foreach}
 
index 7bc89c3680d4b8fb088bc12dd9effea4b3d8d10a..f7088beb4ad5c7826a8992f5ee4bb6473a2654f7 100644 (file)
@@ -1,10 +1,10 @@
 <script>
        require(['Language', 'WoltLabSuite/Core/Ui/Style/FontAwesome'], function (Language, UiStyleFontAwesome) {
                Language.addObject({
-                       'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                       'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                       'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                       'wcf.global.fontAwesome.selectIcon': '{lang}wcf.global.fontAwesome.selectIcon{/lang}'
+                       'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                       'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                       'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                       'wcf.global.fontAwesome.selectIcon': '{jslang}wcf.global.fontAwesome.selectIcon{/jslang}'
                });
                
                UiStyleFontAwesome.setup({@$__wcf->getStyleHandler()->getIcons(true)});
diff --git a/wcfsetup/install/files/acp/templates/formNotice.tpl b/wcfsetup/install/files/acp/templates/formNotice.tpl
new file mode 100644 (file)
index 0000000..f63d721
--- /dev/null
@@ -0,0 +1,3 @@
+{include file='formError'}
+
+{include file='formSuccess'}
diff --git a/wcfsetup/install/files/acp/templates/formSuccess.tpl b/wcfsetup/install/files/acp/templates/formSuccess.tpl
new file mode 100644 (file)
index 0000000..a8347ae
--- /dev/null
@@ -0,0 +1,9 @@
+{if $success|isset}
+       <p class="success" role="status">
+               <span>{lang}wcf.global.success.{$action}{/lang}</span>
+       
+               {if $action == 'add' && !$objectEditLink|empty}
+                       <span>{lang}wcf.global.success.add.editCreatedObject{/lang}</span>
+               {/if}
+       </p>
+{/if}
index c84b94656cfb7457ce6957ee1b2379ffe84be6b1..4fa712bd6551506dc35d0c9f698f18bed94ad613 100644 (file)
@@ -4,13 +4,12 @@
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noindex">
-       <title>{if $pageTitle|isset}{@$pageTitle|language} - {/if}{lang}wcf.global.acp{/lang}{if PACKAGE_ID} - {PAGE_TITLE|language}{/if}</title>
+       <title>{if $pageTitle|isset}{@$pageTitle|language} - {/if}{jslang}wcf.global.acp{/jslang}{if PACKAGE_ID} - {PAGE_TITLE|language}{/if}</title>
        
        {* work-around for Microsoft Edge that sometimes does not apply this style, if it was set via an external stylesheet *}
        <style>ol, ul { list-style: none; }</style>
        
        <!-- Stylesheets -->
-       <link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600" rel="stylesheet">
        {@$__wcf->getStyleHandler()->getStylesheet(true)}
        {event name='stylesheets'}
        
        <script>
                require(['Language', 'WoltLabSuite/Core/Acp/Bootstrap', 'User'], function(Language, AcpBootstrap, User) {
                        Language.addObject({
-                               '__days': [ '{lang}wcf.date.day.sunday{/lang}', '{lang}wcf.date.day.monday{/lang}', '{lang}wcf.date.day.tuesday{/lang}', '{lang}wcf.date.day.wednesday{/lang}', '{lang}wcf.date.day.thursday{/lang}', '{lang}wcf.date.day.friday{/lang}', '{lang}wcf.date.day.saturday{/lang}' ],
-                               '__daysShort': [ '{lang}wcf.date.day.sun{/lang}', '{lang}wcf.date.day.mon{/lang}', '{lang}wcf.date.day.tue{/lang}', '{lang}wcf.date.day.wed{/lang}', '{lang}wcf.date.day.thu{/lang}', '{lang}wcf.date.day.fri{/lang}', '{lang}wcf.date.day.sat{/lang}' ],
-                               '__months': [ '{lang}wcf.date.month.january{/lang}', '{lang}wcf.date.month.february{/lang}', '{lang}wcf.date.month.march{/lang}', '{lang}wcf.date.month.april{/lang}', '{lang}wcf.date.month.may{/lang}', '{lang}wcf.date.month.june{/lang}', '{lang}wcf.date.month.july{/lang}', '{lang}wcf.date.month.august{/lang}', '{lang}wcf.date.month.september{/lang}', '{lang}wcf.date.month.october{/lang}', '{lang}wcf.date.month.november{/lang}', '{lang}wcf.date.month.december{/lang}' ], 
-                               '__monthsShort': [ '{lang}wcf.date.month.short.jan{/lang}', '{lang}wcf.date.month.short.feb{/lang}', '{lang}wcf.date.month.short.mar{/lang}', '{lang}wcf.date.month.short.apr{/lang}', '{lang}wcf.date.month.short.may{/lang}', '{lang}wcf.date.month.short.jun{/lang}', '{lang}wcf.date.month.short.jul{/lang}', '{lang}wcf.date.month.short.aug{/lang}', '{lang}wcf.date.month.short.sep{/lang}', '{lang}wcf.date.month.short.oct{/lang}', '{lang}wcf.date.month.short.nov{/lang}', '{lang}wcf.date.month.short.dec{/lang}' ],
-                               'wcf.acp.search.noResults': '{lang}wcf.acp.search.noResults{/lang}',
-                               'wcf.clipboard.item.unmarkAll': '{lang}wcf.clipboard.item.unmarkAll{/lang}',
-                               'wcf.clipboard.item.markAll': '{lang}wcf.clipboard.item.markAll{/lang}',
-                               'wcf.clipboard.item.mark': '{lang}wcf.clipboard.item.mark{/lang}',
-                               'wcf.date.relative.now': '{lang __literal=true}wcf.date.relative.now{/lang}',
-                               'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang __literal=true}wcf.date.relative.minutes{/lang}{/capture}{@$relativeMinutes|encodeJS}',
-                               'wcf.date.relative.hours': '{capture assign=relativeHours}{lang __literal=true}wcf.date.relative.hours{/lang}{/capture}{@$relativeHours|encodeJS}',
-                               'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang __literal=true}wcf.date.relative.pastDays{/lang}{/capture}{@$relativePastDays|encodeJS}',
-                               'wcf.date.dateFormat': '{"wcf.date.dateFormat"|language|encodeJS}',
-                               'wcf.date.dateTimeFormat': '{lang}wcf.date.dateTimeFormat{/lang}',
-                               'wcf.date.shortDateTimeFormat': '{lang}wcf.date.shortDateTimeFormat{/lang}',
-                               'wcf.date.hour': '{lang}wcf.date.hour{/lang}',
-                               'wcf.date.minute': '{lang}wcf.date.minute{/lang}',
-                               'wcf.date.timeFormat': '{lang}wcf.date.timeFormat{/lang}',
-                               'wcf.date.firstDayOfTheWeek': '{lang}wcf.date.firstDayOfTheWeek{/lang}',
-                               'wcf.global.button.add': '{lang}wcf.global.button.add{/lang}',
-                               'wcf.global.button.cancel': '{lang}wcf.global.button.cancel{/lang}',
-                               'wcf.global.button.close': '{lang}wcf.global.button.close{/lang}',
-                               'wcf.global.button.collapsible': '{lang}wcf.global.button.collapsible{/lang}',
-                               'wcf.global.button.delete': '{lang}wcf.global.button.delete{/lang}',
-                               'wcf.global.button.disable': '{lang}wcf.global.button.disable{/lang}',
-                               'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}',
-                               'wcf.global.button.edit': '{lang}wcf.global.button.edit{/lang}',
-                               'wcf.global.button.enable': '{lang}wcf.global.button.enable{/lang}',
-                               'wcf.global.button.hide': '{lang}wcf.global.button.hide{/lang}',
-                               'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
-                               'wcf.global.button.next': '{lang}wcf.global.button.next{/lang}',
-                               'wcf.global.button.preview': '{lang}wcf.global.button.preview{/lang}',
-                               'wcf.global.button.reset': '{lang}wcf.global.button.reset{/lang}',
-                               'wcf.global.button.save': '{lang}wcf.global.button.save{/lang}',
-                               'wcf.global.button.search': '{lang}wcf.global.button.search{/lang}',
-                               'wcf.global.button.submit': '{lang}wcf.global.button.submit{/lang}',
-                               'wcf.global.button.upload': '{lang}wcf.global.button.upload{/lang}',
-                               'wcf.global.confirmation.cancel': '{lang}wcf.global.confirmation.cancel{/lang}',
-                               'wcf.global.confirmation.confirm': '{lang}wcf.global.confirmation.confirm{/lang}',
-                               'wcf.global.confirmation.title': '{lang}wcf.global.confirmation.title{/lang}',
-                               'wcf.global.decimalPoint': '{capture assign=decimalPoint}{lang}wcf.global.decimalPoint{/lang}{/capture}{$decimalPoint|encodeJS}',
-                               'wcf.global.error.timeout': '{lang}wcf.global.error.timeout{/lang}',
-                               'wcf.global.error.title': '{lang}wcf.global.error.title{/lang}',
-                               'wcf.global.form.error.empty': '{lang}wcf.global.form.error.empty{/lang}',
-                               'wcf.global.form.error.greaterThan': '{lang __literal=true}wcf.global.form.error.greaterThan{/lang}',
-                               'wcf.global.form.error.lessThan': '{lang __literal=true}wcf.global.form.error.lessThan{/lang}',
-                               'wcf.global.form.error.multilingual': '{lang}wcf.global.form.error.multilingual{/lang}',
-                               'wcf.global.form.input.maxItems': '{lang}wcf.global.form.input.maxItems{/lang}',
-                               'wcf.global.language.noSelection': '{lang}wcf.global.language.noSelection{/lang}',
-                               'wcf.global.loading': '{lang}wcf.global.loading{/lang}',
-                               'wcf.global.noSelection': '{lang}wcf.global.noSelection{/lang}',
-                               'wcf.global.select': '{lang}wcf.global.select{/lang}',
-                               'wcf.page.jumpTo': '{lang}wcf.page.jumpTo{/lang}',
-                               'wcf.page.jumpTo.description': '{lang}wcf.page.jumpTo.description{/lang}',
-                               'wcf.global.page.pagination': '{lang}wcf.global.page.pagination{/lang}',
-                               'wcf.global.page.next': '{capture assign=pageNext}{lang}wcf.global.page.next{/lang}{/capture}{@$pageNext|encodeJS}',
-                               'wcf.global.page.previous': '{capture assign=pagePrevious}{lang}wcf.global.page.previous{/lang}{/capture}{@$pagePrevious|encodeJS}',
-                               'wcf.global.pageDirection': '{lang}wcf.global.pageDirection{/lang}',
-                               'wcf.global.reason': '{lang}wcf.global.reason{/lang}',
-                               'wcf.global.scrollUp': '{lang}wcf.global.scrollUp{/lang}',
-                               'wcf.global.success': '{lang}wcf.global.success{/lang}',
-                               'wcf.global.success.add': '{lang}wcf.global.success.add{/lang}',
-                               'wcf.global.success.edit': '{lang}wcf.global.success.edit{/lang}',
-                               'wcf.global.thousandsSeparator': '{capture assign=thousandsSeparator}{lang}wcf.global.thousandsSeparator{/lang}{/capture}{@$thousandsSeparator|encodeJS}',
-                               'wcf.page.pagePosition': '{lang __literal=true}wcf.page.pagePosition{/lang}',
-                               'wcf.menu.page': '{lang}wcf.menu.page{/lang}',
-                               'wcf.menu.user': '{lang}wcf.menu.user{/lang}',
-                               'wcf.date.datePicker': '{lang}wcf.date.datePicker{/lang}',
-                               'wcf.date.datePicker.previousMonth': '{lang}wcf.date.datePicker.previousMonth{/lang}',
-                               'wcf.date.datePicker.nextMonth': '{lang}wcf.date.datePicker.nextMonth{/lang}',
-                               'wcf.date.datePicker.month': '{lang}wcf.date.datePicker.month{/lang}',
-                               'wcf.date.datePicker.year': '{lang}wcf.date.datePicker.year{/lang}',
-                               'wcf.date.datePicker.hour': '{lang}wcf.date.datePicker.hour{/lang}',
-                               'wcf.date.datePicker.minute': '{lang}wcf.date.datePicker.minute{/lang}'
+                               '__days': [ '{jslang}wcf.date.day.sunday{/jslang}', '{jslang}wcf.date.day.monday{/jslang}', '{jslang}wcf.date.day.tuesday{/jslang}', '{jslang}wcf.date.day.wednesday{/jslang}', '{jslang}wcf.date.day.thursday{/jslang}', '{jslang}wcf.date.day.friday{/jslang}', '{jslang}wcf.date.day.saturday{/jslang}' ],
+                               '__daysShort': [ '{jslang}wcf.date.day.sun{/jslang}', '{jslang}wcf.date.day.mon{/jslang}', '{jslang}wcf.date.day.tue{/jslang}', '{jslang}wcf.date.day.wed{/jslang}', '{jslang}wcf.date.day.thu{/jslang}', '{jslang}wcf.date.day.fri{/jslang}', '{jslang}wcf.date.day.sat{/jslang}' ],
+                               '__months': [ '{jslang}wcf.date.month.january{/jslang}', '{jslang}wcf.date.month.february{/jslang}', '{jslang}wcf.date.month.march{/jslang}', '{jslang}wcf.date.month.april{/jslang}', '{jslang}wcf.date.month.may{/jslang}', '{jslang}wcf.date.month.june{/jslang}', '{jslang}wcf.date.month.july{/jslang}', '{jslang}wcf.date.month.august{/jslang}', '{jslang}wcf.date.month.september{/jslang}', '{jslang}wcf.date.month.october{/jslang}', '{jslang}wcf.date.month.november{/jslang}', '{jslang}wcf.date.month.december{/jslang}' ], 
+                               '__monthsShort': [ '{jslang}wcf.date.month.short.jan{/jslang}', '{jslang}wcf.date.month.short.feb{/jslang}', '{jslang}wcf.date.month.short.mar{/jslang}', '{jslang}wcf.date.month.short.apr{/jslang}', '{jslang}wcf.date.month.short.may{/jslang}', '{jslang}wcf.date.month.short.jun{/jslang}', '{jslang}wcf.date.month.short.jul{/jslang}', '{jslang}wcf.date.month.short.aug{/jslang}', '{jslang}wcf.date.month.short.sep{/jslang}', '{jslang}wcf.date.month.short.oct{/jslang}', '{jslang}wcf.date.month.short.nov{/jslang}', '{jslang}wcf.date.month.short.dec{/jslang}' ],
+                               'wcf.acp.search.noResults': '{jslang}wcf.acp.search.noResults{/jslang}',
+                               'wcf.clipboard.item.unmarkAll': '{jslang}wcf.clipboard.item.unmarkAll{/jslang}',
+                               'wcf.clipboard.item.markAll': '{jslang}wcf.clipboard.item.markAll{/jslang}',
+                               'wcf.clipboard.item.mark': '{jslang}wcf.clipboard.item.mark{/jslang}',
+                               'wcf.date.relative.now': '{jslang __literal=true}wcf.date.relative.now{/jslang}',
+                               'wcf.date.relative.minutes': '{jslang __literal=true}wcf.date.relative.minutes{/jslang}',
+                               'wcf.date.relative.hours': '{jslang __literal=true}wcf.date.relative.hours{/jslang}',
+                               'wcf.date.relative.pastDays': '{jslang __literal=true}wcf.date.relative.pastDays{/jslang}',
+                               'wcf.date.dateFormat': '{jslang}wcf.date.dateFormat{/jslang}',
+                               'wcf.date.dateTimeFormat': '{jslang}wcf.date.dateTimeFormat{/jslang}',
+                               'wcf.date.shortDateTimeFormat': '{jslang}wcf.date.shortDateTimeFormat{/jslang}',
+                               'wcf.date.hour': '{jslang}wcf.date.hour{/jslang}',
+                               'wcf.date.minute': '{jslang}wcf.date.minute{/jslang}',
+                               'wcf.date.timeFormat': '{jslang}wcf.date.timeFormat{/jslang}',
+                               'wcf.date.firstDayOfTheWeek': '{jslang}wcf.date.firstDayOfTheWeek{/jslang}',
+                               'wcf.global.button.add': '{jslang}wcf.global.button.add{/jslang}',
+                               'wcf.global.button.cancel': '{jslang}wcf.global.button.cancel{/jslang}',
+                               'wcf.global.button.close': '{jslang}wcf.global.button.close{/jslang}',
+                               'wcf.global.button.collapsible': '{jslang}wcf.global.button.collapsible{/jslang}',
+                               'wcf.global.button.delete': '{jslang}wcf.global.button.delete{/jslang}',
+                               'wcf.global.button.disable': '{jslang}wcf.global.button.disable{/jslang}',
+                               'wcf.global.button.disabledI18n': '{jslang}wcf.global.button.disabledI18n{/jslang}',
+                               'wcf.global.button.edit': '{jslang}wcf.global.button.edit{/jslang}',
+                               'wcf.global.button.enable': '{jslang}wcf.global.button.enable{/jslang}',
+                               'wcf.global.button.hide': '{jslang}wcf.global.button.hide{/jslang}',
+                               'wcf.global.button.insert': '{jslang}wcf.global.button.insert{/jslang}',
+                               'wcf.global.button.next': '{jslang}wcf.global.button.next{/jslang}',
+                               'wcf.global.button.preview': '{jslang}wcf.global.button.preview{/jslang}',
+                               'wcf.global.button.reset': '{jslang}wcf.global.button.reset{/jslang}',
+                               'wcf.global.button.save': '{jslang}wcf.global.button.save{/jslang}',
+                               'wcf.global.button.search': '{jslang}wcf.global.button.search{/jslang}',
+                               'wcf.global.button.submit': '{jslang}wcf.global.button.submit{/jslang}',
+                               'wcf.global.button.upload': '{jslang}wcf.global.button.upload{/jslang}',
+                               'wcf.global.confirmation.cancel': '{jslang}wcf.global.confirmation.cancel{/jslang}',
+                               'wcf.global.confirmation.confirm': '{jslang}wcf.global.confirmation.confirm{/jslang}',
+                               'wcf.global.confirmation.title': '{jslang}wcf.global.confirmation.title{/jslang}',
+                               'wcf.global.decimalPoint': '{jslang}wcf.global.decimalPoint{/jslang}',
+                               'wcf.global.error.timeout': '{jslang}wcf.global.error.timeout{/jslang}',
+                               'wcf.global.error.title': '{jslang}wcf.global.error.title{/jslang}',
+                               'wcf.global.form.error.empty': '{jslang}wcf.global.form.error.empty{/jslang}',
+                               'wcf.global.form.error.greaterThan': '{jslang __literal=true}wcf.global.form.error.greaterThan{/jslang}',
+                               'wcf.global.form.error.lessThan': '{jslang __literal=true}wcf.global.form.error.lessThan{/jslang}',
+                               'wcf.global.form.error.multilingual': '{jslang}wcf.global.form.error.multilingual{/jslang}',
+                               'wcf.global.form.input.maxItems': '{jslang}wcf.global.form.input.maxItems{/jslang}',
+                               'wcf.global.language.noSelection': '{jslang}wcf.global.language.noSelection{/jslang}',
+                               'wcf.global.loading': '{jslang}wcf.global.loading{/jslang}',
+                               'wcf.global.noSelection': '{jslang}wcf.global.noSelection{/jslang}',
+                               'wcf.global.select': '{jslang}wcf.global.select{/jslang}',
+                               'wcf.page.jumpTo': '{jslang}wcf.page.jumpTo{/jslang}',
+                               'wcf.page.jumpTo.description': '{jslang}wcf.page.jumpTo.description{/jslang}',
+                               'wcf.global.page.pagination': '{jslang}wcf.global.page.pagination{/jslang}',
+                               'wcf.global.page.next': '{jslang}wcf.global.page.next{/jslang}',
+                               'wcf.global.page.previous': '{jslang}wcf.global.page.previous{/jslang}',
+                               'wcf.global.pageDirection': '{jslang}wcf.global.pageDirection{/jslang}',
+                               'wcf.global.reason': '{jslang}wcf.global.reason{/jslang}',
+                               'wcf.global.scrollUp': '{jslang}wcf.global.scrollUp{/jslang}',
+                               'wcf.global.success': '{jslang}wcf.global.success{/jslang}',
+                               'wcf.global.success.add': '{jslang}wcf.global.success.add{/jslang}',
+                               'wcf.global.success.edit': '{jslang}wcf.global.success.edit{/jslang}',
+                               'wcf.global.thousandsSeparator': '{jslang}wcf.global.thousandsSeparator{/jslang}',
+                               'wcf.page.pagePosition': '{jslang __literal=true}wcf.page.pagePosition{/jslang}',
+                               'wcf.menu.page': '{jslang}wcf.menu.page{/jslang}',
+                               'wcf.menu.user': '{jslang}wcf.menu.user{/jslang}',
+                               'wcf.date.datePicker': '{jslang}wcf.date.datePicker{/jslang}',
+                               'wcf.date.datePicker.previousMonth': '{jslang}wcf.date.datePicker.previousMonth{/jslang}',
+                               'wcf.date.datePicker.nextMonth': '{jslang}wcf.date.datePicker.nextMonth{/jslang}',
+                               'wcf.date.datePicker.month': '{jslang}wcf.date.datePicker.month{/jslang}',
+                               'wcf.date.datePicker.year': '{jslang}wcf.date.datePicker.year{/jslang}',
+                               'wcf.date.datePicker.hour': '{jslang}wcf.date.datePicker.hour{/jslang}',
+                               'wcf.date.datePicker.minute': '{jslang}wcf.date.datePicker.minute{/jslang}'
                                {event name='javascriptLanguageImport'}
                        });
                        
index d49e18a9a178b7d8771a9b3bc8754bfa3dd6887e..7845bf54eb57cc1f6e631f91bab8abe87c13c128 100644 (file)
@@ -3,14 +3,14 @@
                var $imageViewer = null;
                $(function() {
                        WCF.Language.addObject({
-                               'wcf.imageViewer.button.enlarge': '{lang}wcf.imageViewer.button.enlarge{/lang}',
-                               'wcf.imageViewer.button.full': '{lang}wcf.imageViewer.button.full{/lang}',
-                               'wcf.imageViewer.seriesIndex': '{lang __literal=true}wcf.imageViewer.seriesIndex{/lang}',
-                               'wcf.imageViewer.counter': '{lang}wcf.imageViewer.counter{/lang}',
-                               'wcf.imageViewer.close': '{lang}wcf.imageViewer.close{/lang}',
-                               'wcf.imageViewer.enlarge': '{lang}wcf.imageViewer.enlarge{/lang}',
-                               'wcf.imageViewer.next': '{lang}wcf.imageViewer.next{/lang}',
-                               'wcf.imageViewer.previous': '{lang}wcf.imageViewer.previous{/lang}'
+                               'wcf.imageViewer.button.enlarge': '{jslang}wcf.imageViewer.button.enlarge{/jslang}',
+                               'wcf.imageViewer.button.full': '{jslang}wcf.imageViewer.button.full{/jslang}',
+                               'wcf.imageViewer.seriesIndex': '{jslang __literal=true}wcf.imageViewer.seriesIndex{/jslang}',
+                               'wcf.imageViewer.counter': '{jslang}wcf.imageViewer.counter{/jslang}',
+                               'wcf.imageViewer.close': '{jslang}wcf.imageViewer.close{/jslang}',
+                               'wcf.imageViewer.enlarge': '{jslang}wcf.imageViewer.enlarge{/jslang}',
+                               'wcf.imageViewer.next': '{jslang}wcf.imageViewer.next{/jslang}',
+                               'wcf.imageViewer.previous': '{jslang}wcf.imageViewer.previous{/jslang}'
                        });
                        
                        $imageViewer = new WCF.ImageViewer();
@@ -28,4 +28,4 @@
        </script>
        
        {assign var=__imageViewerLoaded value=true}
-{/if}
\ No newline at end of file
+{/if}
index f1121605943a824fb482b18d8d0f213132b51717..6c7d8c8aefa38dd2463db0b272e22114257760f3 100644 (file)
 
 {event name='userNotice'}
 
-{*if ENABLE_PLUGINSTORE_WIDGET}
-       <div id="pluginstore"></div>
-       <script data-relocate="true" src="https://assets.woltlab.com/widget/pluginstore/featuredFiles.min.js"></script>
-{/if*}
-
 <div class="section tabMenuContainer" data-active="{if ENABLE_WOLTLAB_NEWS}news{else}system{/if}" data-store="activeTabMenuItem">
        <nav class="tabMenu">
                <ul>
                                        </dl>
                                {/if}
                                
+                               {if $server[innodbFlushLogAtTrxCommit] !== false}
+                                       <dl>
+                                               <dt>innodb_flush_log_at_trx_commit</dt>
+                                               <dd>{$server[innodbFlushLogAtTrxCommit]}</dd>
+                                       </dl>
+                               {/if}
+                               
                                {event name='serverFields'}
                        </section>
                
index 15ad58751169efbe26fa877588a98e841dc61b3c..f6fb5eba48ccf557491fad348fcb65abaee65d5e 100644 (file)
@@ -1,18 +1,27 @@
 {include file='header' pageTitle='wcf.acp.label.'|concat:$action}
 
-<script data-relocate="true" src="{@$__wcf->getPath()}js/WCF.Label.js?v={@LAST_UPDATE_TIME}"></script>
 <script data-relocate="true">
-       $(function() {
-               WCF.Language.addObject({
-                       'wcf.acp.label.defaultValue': '{lang}wcf.acp.label.defaultValue{/lang}'
+       (function() {
+               var previews = [];
+               elBySelAll('#labelList .jsLabelPreview', undefined, function(preview) {
+                       previews.push(preview);
                });
                
-               new WCF.Label.ACPList();
+               var input = elById('label');
+               function updatePreview() {
+                       var value = input.value.trim() || '{jslang}wcf.acp.label.defaultValue{/jslang}';
+                       previews.forEach(function(preview) {
+                               preview.textContent = value;
+                       });
+               }
+               input.addEventListener('input', updatePreview, { passive: true });
                
-               $('#customCssClassName').click(function() {
-                       $(this).parents('li').find('input[type=radio]').click();
+               updatePreview();
+               
+               elById('customCssClassName').addEventListener('focus', function () {
+                       elBySel('.jsCustomCssClassName').checked = true;
                });
-       });
+       })();
 </script>
 
 <header class="contentHeader">
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $labelGroupList|count}
        <form method="post" action="{if $action == 'add'}{link controller='LabelAdd'}{/link}{else}{link controller='LabelEdit' object=$label}{/link}{/if}">
@@ -93,9 +98,9 @@
                                        <ul id="labelList" class="inlineList">
                                                {foreach from=$availableCssClassNames item=className}
                                                        {if $className == 'custom'}
-                                                               <li class="labelCustomClass"><input type="radio" name="cssClassName" value="custom"{if $cssClassName == 'custom'} checked{/if}> <span><input type="text" id="customCssClassName" name="customCssClassName" value="{$customCssClassName}" class="long"></span></li>
+                                                               <li class="labelCustomClass"><input type="radio" name="cssClassName" class="jsCustomCssClassName" value="custom"{if $cssClassName == 'custom'} checked{/if}> <span><input type="text" id="customCssClassName" name="customCssClassName" value="{$customCssClassName}" class="long"></span></li>
                                                        {else}
-                                                               <li><label><input type="radio" name="cssClassName" value="{$className}"{if $cssClassName == $className} checked{/if}> <span class="badge label{if $className != 'none'} {$className}{/if}">Label</span></label></li>
+                                                               <li><label><input type="radio" name="cssClassName" value="{$className}"{if $cssClassName == $className} checked{/if}> <span class="badge label{if $className != 'none'} {$className}{/if} jsLabelPreview">Label</span></label></li>
                                                        {/if}
                                                {/foreach}
                                        </ul>
index 0f02a1be1a14f455436c1e4b6608822fd4b6fbb9..afc3860bbd0189df1cf98e08875e8eaad6bf2bf4 100644 (file)
        
        <nav class="contentHeaderNavigation">
                <ul>
-                       <li><a href="{link controller='LabelGroupList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.menu.link.label.group.list{/lang}</span></a></li>
+                       {if $action == 'edit'}
+                               <li><a href="{link controller='LabelList' id=$groupID}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.label.list{/lang}</span></a></li>
+                       {/if}
+                       <li><a href="{link controller='LabelGroupList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.label.group.list{/lang}</span></a></li>
                        
                        {event name='contentHeaderNavigation'}
                </ul>
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='LabelGroupAdd'}{/link}{else}{link controller='LabelGroupEdit' object=$labelGroup}{/link}{/if}">
        <div class="section tabMenuContainer">
index eaa7ef5671512bacaa1186026b06c3dcdcedd90b..83d0011bbb5c37484d8cc0201388e73848f23ed2 100644 (file)
@@ -11,7 +11,7 @@
                                options.updatePageNumber = -1;
                        {/if}
                {else}
-                       options.emptyMessage = '{lang}wcf.global.noItems{/lang}';
+                       options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
                {/if}
                
                new WCF.Table.EmptyTableHandler($('#labelGroupTableContainer'), 'jsLabelGroupRow', options);
        </nav>
 </header>
 
+<form action="{link controller='LabelGroupList'}{/link}" method="post">
+       <section class="section">
+               <h2 class="sectionTitle">{lang}wcf.acp.label.filter{/lang}</h2>
+               
+               <div class="row rowColGap formGrid">
+                       <dl class="col-xs-12 col-md-4">
+                               <dt></dt>
+                               <dd>
+                                       <input type="text" id="groupName" name="groupName" value="{$groupName}" placeholder="{lang}wcf.global.title{/lang}" class="long">
+                               </dd>
+                       </dl>
+                       
+                       <dl class="col-xs-12 col-md-4">
+                               <dt></dt>
+                               <dd>
+                                       <input type="text" id="groupDescription" name="groupDescription" value="{$groupDescription}" placeholder="{lang}wcf.global.description{/lang}"  class="long">
+                               </dd>
+                       </dl>
+               </div>
+       </section>
+       
+       <div class="formSubmit">
+               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
+               {@SECURITY_TOKEN_INPUT_TAG}
+       </div>
+</form>
+
 {hascontent}
        <div class="paginationTop">
-               {content}{pages print=true assign=pagesLinks controller="LabelGroupList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}{/content}
+               {content}
+                       {assign var='linkParameters' value=''}
+                       {if $groupName}
+                               {append var='linkParameters' value='&groupName='}
+                               {append var='linkParameters' value=$groupName|rawurlencode}
+                       {/if}
+                       {if $groupDescription}
+                               {append var='linkParameters' value='&groupDescription='}
+                               {append var='linkParameters' value=$groupDescription|rawurlencode}
+                       {/if}
+                   
+                       {pages print=true assign=pagesLinks controller="LabelGroupList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder$linkParameters"}
+               {/content}
        </div>
 {/hascontent}
 
                <table class="table">
                        <thead>
                                <tr>
-                                       <th class="columnID columnLabelGroupID{if $sortField == 'groupID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=groupID&sortOrder={if $sortField == 'groupID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
-                                       <th class="columnTitle columnGroupName{if $sortField == 'groupName'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=groupName&sortOrder={if $sortField == 'groupName' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.title{/lang}</a></th>
-                                       <th class="columnText columnGroupDescription{if $sortField == 'groupDescription'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=groupDescription&sortOrder={if $sortField == 'groupDescription' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.description{/lang}</a></th>
-                                       <th class="columnDigits columnShowOrder{if $sortField == 'showOrder'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=showOrder&sortOrder={if $sortField == 'showOrder' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.showOrder{/lang}</a></th>
+                                       <th class="columnID columnLabelGroupID{if $sortField == 'groupID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=groupID&sortOrder={if $sortField == 'groupID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
+                                       <th class="columnTitle columnGroupName{if $sortField == 'groupName'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=groupName&sortOrder={if $sortField == 'groupName' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.title{/lang}</a></th>
+                                       <th class="columnText columnGroupDescription{if $sortField == 'groupDescription'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=groupDescription&sortOrder={if $sortField == 'groupDescription' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.description{/lang}</a></th>
+                                       <th class="columnDigits columnLabels{if $sortField == 'labels'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=labels&sortOrder={if $sortField == 'labels' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.acp.label.list{/lang}</a></th>
+                                       <th class="columnDigits columnShowOrder{if $sortField == 'showOrder'} active {@$sortOrder}{/if}"><a href="{link controller='LabelGroupList'}pageNo={@$pageNo}&sortField=showOrder&sortOrder={if $sortField == 'showOrder' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{@$linkParameters}{/link}">{lang}wcf.global.showOrder{/lang}</a></th>
                                        
                                        {event name='columnHeads'}
                                </tr>
                                                <td class="columnID">{@$group->groupID}</td>
                                                <td class="columnTitle columnGroupName"><a href="{link controller='LabelGroupEdit' object=$group}{/link}">{$group}</a></td>
                                                <td class="columnText columnGroupDescription">{$group->groupDescription}</td>
+                                               <td class="columnDigits columnLabels"><a href="{link controller='LabelList' id=$group->groupID}{/link}">{#$group->labels}</a></td>
                                                <td class="columnDigits columnShowOrder">{@$group->showOrder}</td>
                                                
                                                {event name='columns'}
index 88f856bcdd01aa6e28585920e596ad70e2403192..6ea46a20568790ab0d5fa91369f51a64cd4e5eaa 100644 (file)
@@ -11,7 +11,7 @@
                                options.updatePageNumber = -1;
                        {/if}
                {else}
-                       options.emptyMessage = '{lang}wcf.global.noItems{/lang}';
+                       options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
                {/if}
                
                new WCF.Table.EmptyTableHandler($('#labelTableContainer'), 'jsLabelRow', options);
index bfb0d90f32f221d5e3893d1a741faaa47f6fd32d..099ec958b5df9fda6d444b07fdaaecb08cec2068 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{@$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'edit'}{link controller='LanguageEdit' id=$languageID}{/link}{else}{link controller='LanguageAdd'}{/link}{/if}">
        <section class="section">
index f2da135f2dbacaa1cb393e822f4b505a919428c0..f037ff91531934372ca3b51e43f8aa42dc9cd058 100644 (file)
@@ -3,7 +3,7 @@
 <script data-relocate="true" src="{@$__wcf->getPath()}acp/js/WCF.ACP.Language.js?v={@LAST_UPDATE_TIME}"></script>
 <script data-relocate="true">
        $(function() {
-               WCF.Language.add('wcf.acp.language.item.delete.confirmMessage', '{lang}wcf.acp.language.item.delete.confirmMessage{/lang}');
+               WCF.Language.add('wcf.acp.language.item.delete.confirmMessage', '{jslang}wcf.acp.language.item.delete.confirmMessage{/jslang}');
                
                new WCF.ACP.Language.ItemList();
        });
index 01a0c795410ca43da94f55210bce72cd3f0c668d..975e4bbf55a764940ed46f1f1872122650389439 100644 (file)
@@ -8,11 +8,13 @@
        
        {if $media->caption}
                <span class="mediaBBCodeCaption">
-                       {if $media->captionEnableHtml}
-                               {@$media->caption}
-                       {else}
-                               {$media->caption}
-                       {/if}
+                       <span class="mediaBBCodeCaptionAlignment">
+                               {if $media->captionEnableHtml}
+                                       {@$media->caption}
+                               {else}
+                                       {$media->caption}
+                               {/if}
+                       </span>
                </span>
        {/if}
 </span>
index e6ffc7cfcbecfeb7262b1b2ab2b70d32d4192ddd..e25e443cbd132694152dcd4b92c4f2f8731de3c7 100644 (file)
@@ -1,3 +1,7 @@
+<ul class="mediaEditorButtons buttonGroup">
+       <li><div class="mediaManagerMediaReplaceButton"></div></li>
+</ul>
+
 {if $media->isImage && $media->hasThumbnail('small')}
        <div class="mediaThumbnail">
                {@$media->getThumbnailTag('small')}
@@ -24,7 +28,7 @@
                {/if}
                
                <dt>{lang}wcf.media.uploader{/lang}</dt>
-               <dd id="mediaUploader">{@$media->getUserProfile()->getAnchorTag()}</dd>
+               <dd id="mediaUploader">{user object=$media->getUserProfile()}</dd>
                
                <dt>{lang}wcf.media.downloads{/lang}</dt>
                <dd id="mediaDownloads">{#$media->downloads}</dd>
index bfa7c9750b9afc31aa4cc8e01340a4273076c564..b9016db0778247eafaa6b19b9c61a67c869d782e 100644 (file)
@@ -1,24 +1,28 @@
 {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
        require(['Language', 'Permission'], function(Language, Permission) {
                Language.addObject({
-                       'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
-                       'wcf.media.button.select': '{lang}wcf.media.button.select{/lang}',
-                       'wcf.media.delete.confirmMessage': '{lang __encode=true __literal=true}wcf.media.delete.confirmMessage{/lang}',
-                       'wcf.media.insert': '{lang}wcf.media.insert{/lang}',
-                       'wcf.media.insert.imageSize': '{lang}wcf.media.insert.imageSize{/lang}',
-                       'wcf.media.insert.imageSize.small': '{lang}wcf.media.insert.imageSize.small{/lang}',
-                       'wcf.media.insert.imageSize.medium': '{lang}wcf.media.insert.imageSize.medium{/lang}',
-                       'wcf.media.insert.imageSize.large': '{lang}wcf.media.insert.imageSize.large{/lang}',
-                       'wcf.media.insert.imageSize.original': '{lang}wcf.media.insert.imageSize.original{/lang}',
-                       'wcf.media.manager': '{lang}wcf.media.manager{/lang}',
-                       'wcf.media.edit': '{lang}wcf.media.edit{/lang}',
-                       'wcf.media.button.insert': '{lang}wcf.media.button.insert{/lang}',
-                       'wcf.media.search.info.searchStringThreshold': '{lang __literal=true}wcf.media.search.info.searchStringThreshold{/lang}',
-                       'wcf.media.search.noResults': '{lang}wcf.media.search.noResults{/lang}',
-                       'wcf.media.upload.error.noImage': '{lang}wcf.media.upload.error.noImage{/lang}',
-                       'wcf.media.upload.error.uploadFailed': '{lang}wcf.media.upload.error.uploadFailed{/lang}',
-                       'wcf.media.upload.success': '{lang}wcf.media.upload.success{/lang}',
-                       'wcf.media.setCategory': '{lang}wcf.media.setCategory{/lang}'
+                       'wcf.global.button.insert': '{jslang}wcf.global.button.insert{/jslang}',
+                       'wcf.media.button.replaceFile': '{jslang}wcf.media.button.replaceFile{/jslang}',
+                       'wcf.media.button.select': '{jslang}wcf.media.button.select{/jslang}',
+                       'wcf.media.delete.confirmMessage': '{jslang __encode=true __literal=true}wcf.media.delete.confirmMessage{/jslang}',
+                       'wcf.media.imageDimensions.value': '{jslang __literal=true}wcf.media.imageDimensions.value{/jslang}',
+                       'wcf.media.insert': '{jslang}wcf.media.insert{/jslang}',
+                       'wcf.media.insert.imageSize': '{jslang}wcf.media.insert.imageSize{/jslang}',
+                       'wcf.media.insert.imageSize.small': '{jslang}wcf.media.insert.imageSize.small{/jslang}',
+                       'wcf.media.insert.imageSize.medium': '{jslang}wcf.media.insert.imageSize.medium{/jslang}',
+                       'wcf.media.insert.imageSize.large': '{jslang}wcf.media.insert.imageSize.large{/jslang}',
+                       'wcf.media.insert.imageSize.original': '{jslang}wcf.media.insert.imageSize.original{/jslang}',
+                       'wcf.media.manager': '{jslang}wcf.media.manager{/jslang}',
+                       'wcf.media.edit': '{jslang}wcf.media.edit{/jslang}',
+                       'wcf.media.button.insert': '{jslang}wcf.media.button.insert{/jslang}',
+                       'wcf.media.search.info.searchStringThreshold': '{jslang __literal=true}wcf.media.search.info.searchStringThreshold{/jslang}',
+                       'wcf.media.search.noResults': '{jslang}wcf.media.search.noResults{/jslang}',
+                       'wcf.media.upload.error.differentFileExtension': '{jslang}wcf.media.upload.error.differentFileExtension{/jslang}',
+                       'wcf.media.upload.error.differentFileType': '{jslang}wcf.media.upload.error.differentFileType{/jslang}',
+                       'wcf.media.upload.error.noImage': '{jslang}wcf.media.upload.error.noImage{/jslang}',
+                       'wcf.media.upload.error.uploadFailed': '{jslang}wcf.media.upload.error.uploadFailed{/jslang}',
+                       'wcf.media.upload.success': '{jslang}wcf.media.upload.success{/jslang}',
+                       'wcf.media.setCategory': '{jslang}wcf.media.setCategory{/jslang}'
                });
                
                Permission.add('admin.content.cms.canManageMedia', {if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}true{else}false{/if});
index c9ac52018d6c18c255ea17407d6f20006d5f9649..cda3c98fa70ad2d3ae8596df8e4268d86fd1f1af 100644 (file)
@@ -5,8 +5,8 @@
        
        require(['Language', 'WoltLabSuite/Core/Controller/Media/List'], function (Language, ControllerMediaList) {
                Language.addObject({
-                       'wcf.media.delete.confirmMessage': '{lang __literal=true}wcf.media.delete.confirmMessage{/lang}',
-                       'wcf.media.setCategory': '{lang}wcf.media.setCategory{/lang}'
+                       'wcf.media.delete.confirmMessage': '{jslang __literal=true}wcf.media.delete.confirmMessage{/jslang}',
+                       'wcf.media.setCategory': '{jslang}wcf.media.setCategory{/jslang}'
                });
                
                ControllerMediaList.init({
index ec311ca0099a71ad8e482f64ff6e30d5e66e807e..a2c026f9b8ff3cba2ab9c264732942ee840f157b 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='MenuAdd'}{/link}{else}{link controller='MenuEdit' id=$menuID}{/link}{/if}">
        {if $action == 'edit' && $menu->identifier == 'com.woltlab.wcf.MainMenu'}
index 016a949ca167f0f976d3023dbd0bf3a5fc4ecbf1..a03de68d6174b504dbbb143d5d79a1529241420a 100644 (file)
@@ -3,20 +3,20 @@
 <script data-relocate="true">
        require(['Dictionary', 'Language', 'WoltLabSuite/Core/Acp/Ui/Menu/Item/Handler'], function(Dictionary, Language, AcpUiMenuItemHandler) {
                Language.addObject({
-                       'wcf.page.pageObjectID': '{lang}wcf.page.pageObjectID{/lang}',
+                       'wcf.page.pageObjectID': '{jslang}wcf.page.pageObjectID{/jslang}',
                        {foreach from=$pageNodeList item=pageNode}
                                {capture assign='pageObjectIDLanguageItem'}{lang __optional=true}wcf.page.pageObjectID.{@$pageNode->identifier}{/lang}{/capture}
                                {if $pageObjectIDLanguageItem}
-                                       'wcf.page.pageObjectID.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem}',
+                                       'wcf.page.pageObjectID.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem|encodeJS}',
                                {/if}
                                {capture assign='pageObjectIDLanguageItem'}{lang __optional=true}wcf.page.pageObjectID.search.{@$pageNode->identifier}{/lang}{/capture}
                                {if $pageObjectIDLanguageItem}
-                                       'wcf.page.pageObjectID.search.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem}',
+                                       'wcf.page.pageObjectID.search.{@$pageNode->identifier}': '{@$pageObjectIDLanguageItem|encodeJS}',
                                {/if}
                        {/foreach}
-                       'wcf.page.pageObjectID.search.noResults': '{lang}wcf.page.pageObjectID.search.noResults{/lang}',
-                       'wcf.page.pageObjectID.search.results': '{lang}wcf.page.pageObjectID.search.results{/lang}',
-                       'wcf.page.pageObjectID.search.terms': '{lang}wcf.page.pageObjectID.search.terms{/lang}'
+                       'wcf.page.pageObjectID.search.noResults': '{jslang}wcf.page.pageObjectID.search.noResults{/jslang}',
+                       'wcf.page.pageObjectID.search.results': '{jslang}wcf.page.pageObjectID.search.results{/jslang}',
+                       'wcf.page.pageObjectID.search.terms': '{jslang}wcf.page.pageObjectID.search.terms{/jslang}'
                });
                
                var handlers = new Dictionary();
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='MenuItemAdd'}{/link}{else}{link controller='MenuItemEdit' id=$itemID}{/link}{/if}">
        <div class="section">
@@ -75,7 +71,7 @@
                <dl{if $errorField == 'title'} class="formError"{/if}>
                        <dt><label for="title">{lang}wcf.global.name{/lang}</label></dt>
                        <dd>
-                               <input type="text" name="title" id="title" value="{$i18nPlainValues['title']}" class="long" required>
+                               <input type="text" name="title" id="title" value="{$i18nPlainValues['title']}" maxlength="255" class="long" required>
                                {if $errorField == 'title'}
                                        <small class="innerError">
                                                {if $errorType == 'empty' || $errorType == 'multilingual'}
index 2570fd2dd5943c18d3f9cbec2fd36b2cf717034d..875d3f0106aee835cae49fe09ab4065b989fbb65 100644 (file)
@@ -2,7 +2,7 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Language/Input', 'WoltLabSuite/Core/Language/Text'], function(Language, LanguageInput, LanguageText) {
                        Language.addObject({
-                               'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}'
+                               'wcf.global.button.disabledI18n': '{jslang}wcf.global.button.disabledI18n{/jslang}'
                        });
                        
                        var availableLanguages = { {implode from=$availableLanguages key=languageID item=languageName}{@$languageID}: '{$languageName}'{/implode} };
index f782945984b0ea1ce09bcfeadb25bf8696e6fc3f..1c17444399b808b143b04fd9d0a12002b61fa1c2 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form id="formContainer" method="post" action="{if $action == 'add'}{link controller='NoticeAdd'}{/link}{else}{link controller='NoticeEdit' object=$notice}{/link}{/if}">
        <div class="section">
index df207db9a3073a78ad479649c536cf5941d174d9..abeedd8c1783b0bfc6f11b55397fae94b3fc491e 100644 (file)
@@ -3,12 +3,12 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Controller/User/Notification/Settings'], function(Language, ControllerUserNotificationSettings) {
                Language.addObject({
-                       'wcf.user.notification.mailNotificationType.daily': '{lang}wcf.user.notification.mailNotificationType.daily{/lang}',
-                       'wcf.user.notification.mailNotificationType.instant': '{lang}wcf.user.notification.mailNotificationType.instant{/lang}',
-                       'wcf.user.notification.mailNotificationType.none': '{lang}wcf.user.notification.mailNotificationType.none{/lang}'
+                       'wcf.user.notification.mailNotificationType.daily': '{jslang}wcf.user.notification.mailNotificationType.daily{/jslang}',
+                       'wcf.user.notification.mailNotificationType.instant': '{jslang}wcf.user.notification.mailNotificationType.instant{/jslang}',
+                       'wcf.user.notification.mailNotificationType.none': '{jslang}wcf.user.notification.mailNotificationType.none{/jslang}'
                });
                
-               ControllerUserNotificationSettings.setup();
+               ControllerUserNotificationSettings.init();
        });
 </script>
 
        <p class="success">{lang}wcf.global.success.edit{/lang}</p>
 {/if}
 
-<form method="post" action="{link controller='NotificationPresetSettings'}{/link}">
-       <div id="notificationSettings">
-               <div class="section">
-                       <dl>
-                               <dt></dt>
-                               <dd>
-                                       <label><input type="checkbox" name="applyChangesToExistingUsers" value="1"{if $applyChangesToExistingUsers} checked{/if}> {lang}wcf.acp.user.notificationPresetSettings.applyChangesToExistingUsers{/lang}</label>
-                                       <small>{lang}wcf.acp.user.notificationPresetSettings.applyChangesToExistingUsers.description{/lang}</small>
-                               </dd>
-                       </dl>
-               </div>
-               
+<form method="post" action="{link controller='NotificationPresetSettings'}{/link}" id="notificationSettings">
+       <div class="section">
+               <dl>
+                       <dt></dt>
+                       <dd>
+                               <label><input type="checkbox" name="applyChangesToExistingUsers" value="1"{if $applyChangesToExistingUsers} checked{/if}> {lang}wcf.acp.user.notificationPresetSettings.applyChangesToExistingUsers{/lang}</label>
+                               <small>{lang}wcf.acp.user.notificationPresetSettings.applyChangesToExistingUsers.description{/lang}</small>
+                       </dd>
+               </dl>
+       </div>
+       
+       <div class="section">
                {foreach from=$events key='eventCategory' item='eventList'}
-                       <section class="section">
-                               <h2 class="sectionTitle">{lang}wcf.user.notification.{$eventCategory}{/lang}</h2>
-                               
-                               <dl>
-                                       {foreach from=$eventList item=event}
-                                               <dt>{lang}wcf.user.notification.{$event->objectType}.{$event->eventName}{/lang}</dt>
-                                               <dd>
-                                                       <ol class="flexibleButtonGroup" data-object-id="{@$event->eventID}">
-                                                               <li>
-                                                                       <input type="radio" id="settings_{@$event->eventID}_disabled" name="settings[{@$event->eventID}][enabled]" value="0"{if $settings[$event->eventID][enabled]|empty} checked{/if}>
-                                                                       <label for="settings_{@$event->eventID}_disabled" class="red">
-                                                                               <span class="icon icon16 fa-times"></span>
-                                                                               {lang}wcf.user.notification.notifications.disabled{/lang}
-                                                                       </label>
-                                                               </li>
-                                                               <li class="spaceAfter">
-                                                                       <input type="radio" id="settings_{@$event->eventID}_enabled" name="settings[{@$event->eventID}][enabled]" value="1"{if !$settings[$event->eventID][enabled]|empty} checked{/if}>
-                                                                       <label for="settings_{@$event->eventID}_enabled" class="green">
-                                                                               <span class="icon icon16 fa-bell"></span>
-                                                                               {lang}wcf.user.notification.notifications.enabled{/lang}
-                                                                       </label>
-                                                               </li>
-                                                               {if $event->supportsEmailNotification()}
-                                                                       <li class="notificationSettingsEmail{if !$settings[$event->eventID][enabled]|empty} active{/if}">
-                                                                               <input type="hidden" id="settings_{$event->eventID}_mailNotificationType" name="settings[{@$event->eventID}][mailNotificationType]" value="{$settings[$event->eventID][mailNotificationType]}">
-                                                                               <a{if $settings[$event->eventID][mailNotificationType] !== 'none'} class="active yellow"{/if}>
-                                                                                       <span class="icon icon16 fa-envelope-o"></span>
-                                                                                       <span class="title">{lang}wcf.user.notification.mailNotificationType.{$settings[$event->eventID][mailNotificationType]}{/lang}</span>
-                                                                                       <span class="icon icon16 fa-caret-down"></span>
-                                                                               </a>
-                                                                       </li>
-                                                               {/if}
-                                                       </ol>
-                                               </dd>
-                                       {/foreach}
-                               </dl>
-                       </section>
+                       <div class="notificationSettings">
+                               <div class="notificationSettingsCategory">
+                                       <div class="notificationSettingsEvent">{lang}wcf.user.notification.{$eventCategory}{/lang}</div>
+                                       <div class="notificationSettingsState">{lang}wcf.user.notification.status.active{/lang}</div>
+                                       <div class="notificationSettingsEmail">{lang}wcf.user.notification.status.email{/lang}</div>
+                               </div>
+                               {foreach from=$eventList item=event}
+                                       <div class="notificationSettingsItem">
+                                               <div class="notificationSettingsEvent">
+                                                       <label for="settings_{@$event->eventID}">{lang}wcf.user.notification.{$event->objectType}.{$event->eventName}{/lang}</label>
+                                               </div>
+                                               <div class="notificationSettingsState">
+                                                       <label>
+                                                               <input type="checkbox" id="settings_{@$event->eventID}" name="settings[{@$event->eventID}][enabled]" class="jsCheckboxNotificationSettingsState" value="1" data-object-id="{@$event->eventID}"{if !$settings[$event->eventID][enabled]|empty} checked{/if}>
+                                                               <span class="icon icon24 fa-bell green pointer"></span>
+                                                               <span class="icon icon24 fa-bell-slash red pointer"></span>
+                                                       </label>
+                                               </div>
+                                               <div class="notificationSettingsEmail">
+                                                       {if $event->supportsEmailNotification()}
+                                                               <input type="hidden" id="settings_{$event->eventID}_mailNotificationType" name="settings[{@$event->eventID}][mailNotificationType]" value="{$settings[$event->eventID][mailNotificationType]}">
+                                                               <a href="#" class="notificationSettingsEmailType jsTooltip{if $settings[$event->eventID][enabled]|empty} disabled{/if}" role="button" title="{lang}wcf.user.notification.mailNotificationType.{@$settings[$event->eventID][mailNotificationType]}{/lang}" data-object-id="{@$event->eventID}">
+                                                                       {if $settings[$event->eventID][mailNotificationType] === 'none'}
+                                                                               <span class="icon icon24 fa-times red jsIconNotificationSettingsEmailType"></span>
+                                                                       {else}
+                                                                               <span class="icon icon24 {if $settings[$event->eventID][mailNotificationType] === 'instant'}fa-flash{else}fa-clock-o{/if} green jsIconNotificationSettingsEmailType"></span>
+                                                                       {/if}
+                                                                       <span class="icon icon16 fa-caret-down"></span>
+                                                               </a>
+                                                       {/if}
+                                               </div>
+                                       </div>
+                               {/foreach}
+                       </div>
                {/foreach}
-               
-               {event name='sections'}
        </div>
        
+       {event name='sections'}
+       
        <div class="formSubmit">
                <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
                {@SECURITY_TOKEN_INPUT_TAG}
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 2c2155fb9d06e476ca5116c7c5cf18a7bbdf4d13..be9dc6b9e0b36267a07af787c52862c24307d557 100644 (file)
@@ -3,7 +3,7 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.package.uninstallation.title': '{lang}wcf.acp.package.uninstallation.title{/lang}'
+                       'wcf.acp.package.uninstallation.title': '{jslang}wcf.acp.package.uninstallation.title{/jslang}'
                });
                
                new WCF.ACP.Package.Uninstallation($('.jsUninstallButton'), {if PACKAGE_ID > 1}'{link controller='PackageList' forceWCF=true encode=false}packageID={literal}{packageID}{/literal}{/link}'{else}null{/if});
index 7965260a9a5486b7f927bb4df0e8734729b35d54..738edee4dd8b784bedcf13d8f33ebbb1b3ece3d6 100644 (file)
@@ -4,10 +4,10 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.package.install.title': '{lang}wcf.acp.package.install.title{/lang}',
-                       'wcf.acp.package.installation.rollback': '{lang}wcf.acp.package.installation.rollback{/lang}',
-                       'wcf.acp.package.uninstallation.title': '{lang}wcf.acp.package.uninstallation.title{/lang}',
-                       'wcf.acp.package.update.title': '{lang}wcf.acp.package.update.title{/lang}'
+                       'wcf.acp.package.install.title': '{jslang}wcf.acp.package.install.title{/jslang}',
+                       'wcf.acp.package.installation.rollback': '{jslang}wcf.acp.package.installation.rollback{/jslang}',
+                       'wcf.acp.package.uninstallation.title': '{jslang}wcf.acp.package.uninstallation.title{/jslang}',
+                       'wcf.acp.package.update.title': '{jslang}wcf.acp.package.update.title{/jslang}'
                });
                
                new WCF.ACP.Package.Installation({@$queue->queueID}, undefined, {if $queue->action == 'install'}{if $queue->isApplication}false{else}true{/if}, false{else}false, true{/if});
index 43d0fae82804bb9839547fff36beb2059933db78..78433d5cf7c86797d2d343b9448d7a51068bf799 100644 (file)
@@ -8,7 +8,7 @@
 </style>
 <script data-relocate="true">
        $(function() {
-               WCF.Language.add('wcf.acp.package.install.title', '{lang}wcf.acp.package.install.title{/lang}');
+               WCF.Language.add('wcf.acp.package.install.title', '{jslang}wcf.acp.package.install.title{/jslang}');
                
                var $installation = new WCF.ACP.Package.Installation({@$queueID});
                $installation.prepareInstallation();
index f6b2e5c4285e021fd7092a6d013b046c2db6b2dc..29a593c17515dc95e8cc1bf257ef1b39b1f18993 100644 (file)
@@ -3,13 +3,13 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.package.searchForUpdates': '{lang}wcf.acp.package.searchForUpdates{/lang}',
-                       'wcf.acp.package.searchForUpdates.noResults': '{lang}wcf.acp.package.searchForUpdates.noResults{/lang}',
-                       'wcf.acp.package.uninstallation.title': '{lang}wcf.acp.package.uninstallation.title{/lang}',
-                       'wcf.acp.pluginStore.authorization': '{lang}wcf.acp.pluginStore.authorization{/lang}',
-                       'wcf.acp.pluginStore.purchasedItems': '{lang}wcf.acp.pluginStore.purchasedItems{/lang}',
-                       'wcf.acp.pluginStore.purchasedItems.button.search': '{lang}wcf.acp.pluginStore.purchasedItems.button.search{/lang}',
-                       'wcf.acp.pluginStore.purchasedItems.noResults': '{lang}wcf.acp.pluginStore.purchasedItems.noResults{/lang}'
+                       'wcf.acp.package.searchForUpdates': '{jslang}wcf.acp.package.searchForUpdates{/jslang}',
+                       'wcf.acp.package.searchForUpdates.noResults': '{jslang}wcf.acp.package.searchForUpdates.noResults{/jslang}',
+                       'wcf.acp.package.uninstallation.title': '{jslang}wcf.acp.package.uninstallation.title{/jslang}',
+                       'wcf.acp.pluginStore.authorization': '{jslang}wcf.acp.pluginStore.authorization{/jslang}',
+                       'wcf.acp.pluginStore.purchasedItems': '{jslang}wcf.acp.pluginStore.purchasedItems{/jslang}',
+                       'wcf.acp.pluginStore.purchasedItems.button.search': '{jslang}wcf.acp.pluginStore.purchasedItems.button.search{/jslang}',
+                       'wcf.acp.pluginStore.purchasedItems.noResults': '{jslang}wcf.acp.pluginStore.purchasedItems.noResults{/jslang}'
                });
                
                {if $__wcf->session->getPermission('admin.configuration.package.canUninstallPackage')}
index 1acc835d3df085f0e4c339bfd7ff7e9a566d2e1d..830ab94022a5fe4d778ca2b6b398da96ae16de4c 100644 (file)
        </thead>
        
        <tbody>
-               <tr>
-                       <td colspan="5"><small>{lang count=$trustedSources|count}wcf.acp.package.search.result.trusted{/lang}</small></td>
-               </tr>
-               {foreach from=$trustedSources item=$package}
-                       <tr class="jsPackageRow">
-                               <td class="columnIcon">
-                                       <a href="#" class="jsInstallPackage" data-confirm-message="{lang __encode=true}wcf.acp.package.install.confirmMessage{/lang}" data-package="{$package->package}" data-package-version="{$package->getAccessibleVersion()->packageVersion}"><span class="icon icon16 fa-plus jsTooltip" title="{lang}wcf.acp.package.button.installPackage{/lang}"></span></a>
-                               </td>
-                               <td class="columnTitle" title="{$package->packageDescription}">
-                                       <div class="packageSearchName">{$package->packageName} <span class="packageSearchVersion">{$package->getAccessibleVersion()->packageVersion}</span></div>
-                                       <span class="packageSearchPackage">{$package->package}</span>
-                               </td>
-                               <td class="columnText">{if $package->authorURL}<a href="{$package->authorURL}" class="externalURL">{$package->author}</a>{else}{$package->author}{/if}</td>
-                               <td class="columnText">{if $package->getAccessibleVersion()->licenseURL}<a href="{$package->getAccessibleVersion()->licenseURL}" class="externalURL">{$package->getAccessibleVersion()->license}</a>{else}{$package->getAccessibleVersion()->license}{/if}</td>
-                               <td class="columnDate">{@$package->getAccessibleVersion()->packageDate|time}</td>
+               {if $officialPackages|count}
+                       <tr>
+                               <td colspan="5"><small>{lang count=$officialPackages|count}wcf.acp.package.search.result.official{/lang}</small></td>
+                       </tr>
+                       {include file='packageSearchResultListItems' packages=$officialPackages}
+               {/if}
+               {if $trustedSources|count}
+                       <tr>
+                               <td colspan="5"><small>{lang count=$trustedSources|count}wcf.acp.package.search.result.trusted{/lang}</small></td>
                        </tr>
-               {/foreach}
-               {hascontent}
+                       {include file='packageSearchResultListItems' packages=$trustedSources}
+               {/if}
+               {if $thirdPartySources|count}
                        <tr>
                                <td colspan="5"><small>{lang count=$thirdPartySources|count}wcf.acp.package.search.result.thirdParty{/lang}</small></td>
                        </tr>
-                       {content}
-                               {foreach from=$thirdPartySources item=$package}
-                                       <tr class="jsPackageRow">
-                                               <td class="columnIcon">
-                                                       <a href="#" class="jsInstallPackage" data-confirm-message="{lang __encode=true}wcf.acp.package.install.confirmMessage{/lang}" data-package="{$package->package}" data-package-version="{$package->getAccessibleVersion()->packageVersion}"><span class="icon icon16 fa-plus jsTooltip" title="{lang}wcf.acp.package.button.installPackage{/lang}"></span></a>
-                                               </td>
-                                               <td class="columnTitle" title="{$package->packageDescription}">
-                                                       <div class="packageSearchName">{$package->packageName} <span class="packageSearchVersion">{$package->getAccessibleVersion()->packageVersion}</span></div>
-                                                       <span class="packageSearchPackage">{$package->package}</span>
-                                               </td>
-                                               <td class="columnText">{if $package->authorURL}<a href="{$package->authorURL}" class="externalURL">{$package->author}</a>{else}{$package->author}{/if}</td>
-                                               <td class="columnText">{if $package->getAccessibleVersion()->licenseURL}<a href="{$package->getAccessibleVersion()->licenseURL}" class="externalURL">{$package->getAccessibleVersion()->license}</a>{else}{$package->getAccessibleVersion()->license}{/if}</td>
-                                               <td class="columnDate">{@$package->getAccessibleVersion()->packageDate|time}</td>
-                                       </tr>
-                               {/foreach}
-                       {/content}
-               {/hascontent}
+                       {include file='packageSearchResultListItems' packages=$thirdPartySources}
+               {/if}
        </tbody>
 </table>
diff --git a/wcfsetup/install/files/acp/templates/packageSearchResultListItems.tpl b/wcfsetup/install/files/acp/templates/packageSearchResultListItems.tpl
new file mode 100644 (file)
index 0000000..3059f48
--- /dev/null
@@ -0,0 +1,18 @@
+{foreach from=$packages item=$package}
+       <tr class="jsPackageRow packageSearchResultRow">
+               <td class="columnIcon">
+                       <a href="#" class="jsInstallPackage jsTooltip" data-confirm-message="{lang __encode=true}wcf.acp.package.install.confirmMessage{/lang}" data-package="{$package->package}" data-package-version="{$package->getAccessibleVersion()->packageVersion}" title="{lang}wcf.acp.package.button.installPackage{/lang}"><span class="icon icon24 fa-plus"></span></a>
+               </td>
+               <td class="columnText">
+                       <div class="packageSearchName">{$package->packageName} <span class="packageSearchVersion">{$package->getAccessibleVersion()->packageVersion}</span></div>
+                       <div class="packageSearchDescription small">{$package->packageDescription}</div>
+                       <span class="packageSearchPackage small">{$package->package}</span>
+                       {if $package->pluginStoreFileID}
+                               <span class="packageSearchPluginStorePage separatorLeft small"><a href="https://pluginstore.woltlab.com/file/{@$package->pluginStoreFileID}/" class="externalURL jsTooltip" title="{lang}wcf.acp.pluginStore.file.link{/lang}">{lang}wcf.acp.pluginStore.file{/lang}</a></span>
+                       {/if}
+               </td>
+               <td class="columnText small packageSearchAuthor{if $package->getUpdateServer()->isWoltLabUpdateServer()} packageSearchAuthorWoltlab{/if}" title="{$package->author}">{if $package->authorURL}<a href="{$package->authorURL}" class="externalURL">{$package->author|truncate:30}</a>{else}{$package->author|truncate:30}{/if}</td>
+               <td class="columnText small packageSearchLicense" title="{$package->getAccessibleVersion()->license}">{if $package->getAccessibleVersion()->licenseURL}<a href="{$package->getAccessibleVersion()->licenseURL}" class="externalURL">{$package->getAccessibleVersion()->license|truncate:30}</a>{else}{$package->getAccessibleVersion()->license|truncate:30}{/if}</td>
+               <td class="columnDate packageSearchDate">{@$package->getAccessibleVersion()->packageDate|time}</td>
+       </tr>
+{/foreach}
index b98f34f2d37b8e764984972f6ec9503a1b9ac9b9..7d00a8247a71ff81a063f1e6c4b0cff11b002efc 100644 (file)
@@ -8,8 +8,8 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Package/Search'], function(Language, AcpUiPackageSearch) {
                Language.addObject({
-                       'wcf.acp.package.install.title': '{lang}wcf.acp.package.install.title{/lang}',
-                       'wcf.acp.package.update.unauthorized': '{lang}wcf.acp.package.update.unauthorized{/lang}'
+                       'wcf.acp.package.install.title': '{jslang}wcf.acp.package.install.title{/jslang}',
+                       'wcf.acp.package.update.unauthorized': '{jslang}wcf.acp.package.update.unauthorized{/jslang}'
                });
                
                new AcpUiPackageSearch();
index b9887464aa83f71aa501f9fc891665af2c15bf15..df5532a95387a1048b44ecffa4335692bb1f3ffb 100644 (file)
@@ -3,9 +3,9 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.package.update.excludedPackages': '{lang}wcf.acp.package.update.excludedPackages{/lang}',
-                       'wcf.acp.package.update.title': '{lang}wcf.acp.package.update.title{/lang}',
-                       'wcf.acp.package.update.unauthorized': '{lang}wcf.acp.package.update.unauthorized{/lang}'
+                       'wcf.acp.package.update.excludedPackages': '{jslang}wcf.acp.package.update.excludedPackages{/jslang}',
+                       'wcf.acp.package.update.title': '{jslang}wcf.acp.package.update.title{/jslang}',
+                       'wcf.acp.package.update.unauthorized': '{jslang}wcf.acp.package.update.unauthorized{/jslang}'
                })
                
                new WCF.ACP.Package.Update.Manager();
index 55cdbec297993737a175e7b3ebfd19cfcaa196d5..860461c2b989ab190332b0f66567232d0b4dddc3 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
 {if $packageUpdateServer|isset && $packageUpdateServer->errorMessage}
        <p class="warning">{lang}wcf.acp.updateServer.lastErrorMessage{/lang}<br>{$packageUpdateServer->errorMessage}</p>
 {/if}
 
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='PackageUpdateServerAdd'}{/link}{else}{link controller='PackageUpdateServerEdit' id=$packageUpdateServerID}{/link}{/if}">
        <div class="section">
                <dl{if $errorField == 'serverURL'} class="formError"{/if}>
                        <dt><label for="serverURL">{lang}wcf.acp.updateServer.serverURL{/lang}</label></dt>
                        <dd>
-                               <input type="url" id="serverURL" name="serverURL" value="{$serverURL}" required autofocus class="long">
+                               <input type="url" id="serverURL" name="serverURL" value="{$serverURL}" required autofocus class="long"{if $action != 'add'} readonly{/if}>
                                {if $errorField == 'serverURL'}
                                        <small class="innerError">
                                                {if $errorType == 'empty'}
                                                        {lang}wcf.global.form.error.empty{/lang}
+                                               {elseif $errorType[duplicate]|isset}
+                                                       {lang}wcf.acp.updateServer.serverURL.error.duplicate{/lang}
                                                {else}
                                                        {lang}wcf.acp.updateServer.serverURL.error.{@$errorType}{/lang}
                                                {/if}
@@ -53,7 +51,7 @@
                <dl>
                        <dt><label for="loginPassword">{lang}wcf.acp.updateServer.loginPassword{/lang}</label></dt>
                        <dd>
-                               <input type="password" id="loginPassword" name="loginPassword" value="{$loginPassword}" class="medium" autocomplete="off">
+                               <input type="password" id="loginPassword" name="loginPassword" value="{$loginPassword}" class="medium" autocomplete="off"{if $action != 'add' && $loginUsername} placeholder="{lang}wcf.acp.updateServer.loginPassword.noChange{/lang}"{/if}>
                                <small>{lang}wcf.acp.updateServer.loginPassword.description{/lang}</small>
                        </dd>
                </dl>
index dcd60c2baa2d17d7588b0b4a9687499a8fd7e0c2..df6d3cee4b664ddf67c3bc52994741b4196f50f1 100644 (file)
@@ -34,6 +34,7 @@
                                <tr>
                                        <th class="columnID columnPackageUpdateServerID{if $sortField == 'packageUpdateServerID'} active {@$sortOrder}{/if}" colspan="2"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=packageUpdateServerID&sortOrder={if $sortField == 'packageUpdateServerID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}</a></th>
                                        <th class="columnTitle columnServerURL{if $sortField == 'serverURL'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=serverURL&sortOrder={if $sortField == 'serverURL' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.serverURL{/lang}</a></th>
+                                       <th class="columnLoginUsername{if $sortField == 'loginUsername'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=loginUsername&sortOrder={if $sortField == 'loginUsername' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.loginUsername{/lang}</a></th>
                                        <th class="columnDigits columnPackages{if $sortField == 'packages'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=packages&sortOrder={if $sortField == 'packages' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.packages{/lang}</a></th>
                                        <th class="columnStatus{if $sortField == 'status'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=status&sortOrder={if $sortField == 'status' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.status{/lang}</a></th>
                                        <th class="columnText columnErrorText{if $sortField == 'errorMessage'} active {@$sortOrder}{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=errorMessage&sortOrder={if $sortField == 'errorMessage' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.errorMessage{/lang}</a></th>
                                {foreach from=$objects item=updateServer}
                                        <tr class="jsUpdateServerRow">
                                                <td class="columnIcon">
-                                                       <span class="icon icon16 fa-{if !$updateServer->isDisabled}check-{/if}square-o jsToggleButton jsTooltip pointer" title="{lang}wcf.global.button.{if !$updateServer->isDisabled}disable{else}enable{/if}{/lang}" data-object-id="{@$updateServer->packageUpdateServerID}"></span>
+                                                       {if $updateServer->canDisable()}
+                                                               <span class="icon icon16 fa-{if !$updateServer->isDisabled}check-{/if}square-o jsToggleButton jsTooltip pointer" title="{lang}wcf.global.button.{if !$updateServer->isDisabled}disable{else}enable{/if}{/lang}" data-object-id="{@$updateServer->packageUpdateServerID}"></span>
+                                                       {else}
+                                                               <span class="icon icon16 fa-check-square-o disabled"></span>
+                                                       {/if}
                                                        <a href="{link controller='PackageUpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
-                                                       <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$updateServer->packageUpdateServerID}" data-confirm-message-html="{lang __encode=true}wcf.acp.updateServer.delete.sure{/lang}"></span>
+                                                       <span class="icon icon16 fa-times {if $updateServer->canDelete()}jsDeleteButton jsTooltip pointer{else}disabled{/if}"{if $updateServer->canDelete()} title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$updateServer->packageUpdateServerID}" data-confirm-message-html="{lang __encode=true}wcf.acp.updateServer.delete.sure{/lang}"{/if}></span>
                                                        
                                                        {event name='itemButtons'}
                                                </td>
                                                <td class="columnID columnPackageUpdateServerID">{@$updateServer->packageUpdateServerID}</td>
                                                <td class="columnTitle columnServerURL"><a href="{link controller='PackageUpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}" title="{lang}wcf.acp.updateServer.edit{/lang}">{$updateServer->serverURL}</a></td>
+                                               <td class="columnLoginUsername">{$updateServer->loginUsername}</td>
                                                <td class="columnDigits columnPackages">{#$updateServer->packages}</td>
                                                <td class="columnStatus"><span class="badge{if $updateServer->status == 'online'} green{else} red{/if}">{@$updateServer->status}</span></td>
                                                <td class="columnText columnErrorText" title="{@$updateServer->errorMessage}">{@$updateServer->errorMessage|truncate:"30"}</td>
index cb4b8523e081fc45807a7b486c26933cb68d3bb3..1b4d00c7cf0262615db62512b7ac2ee6878c75db 100644 (file)
@@ -36,7 +36,7 @@
        
        <dl>
                <dt><label for="packageUpdateServerPassword">{lang}wcf.acp.package.update.{if $updateServer->requiresLicense()}serialNo{else}password{/if}{/lang}</label></dt>
-               <dd><input type="{if $updateServer->requiresLicense()}text{else}password{/if}" id="packageUpdateServerPassword" value="{if $serverAuthData[password]|isset}{$serverAuthData[password]}{/if}" class="long"></dd>
+               <dd><input type="{if $updateServer->requiresLicense()}text{else}password{/if}" id="packageUpdateServerPassword" value="" class="long"></dd>
        </dl>
        
        <dl>
@@ -47,4 +47,4 @@
 
 <div class="formSubmit">
        <button data-package-update-server-id="{@$updateServer->packageUpdateServerID}">{lang}wcf.global.button.submit{/lang}</button>
-</div>
\ No newline at end of file
+</div>
diff --git a/wcfsetup/install/files/acp/templates/packageUpdateUnauthorizedPurchaseRequired.tpl b/wcfsetup/install/files/acp/templates/packageUpdateUnauthorizedPurchaseRequired.tpl
new file mode 100644 (file)
index 0000000..ec9c849
--- /dev/null
@@ -0,0 +1,9 @@
+<section class="section">
+       <h2 class="sectionTitle">{lang}wcf.acp.package.update.purchaseRequired{/lang}</h2>
+
+       <p>{lang packageName=$packageName}wcf.acp.package.update.purchaseRequired.description{/lang}</p>
+</section>
+<div class="formSubmit">
+       <a href="https://pluginstore.woltlab.com/file/{$pluginStoreFileID}" target="_blank" class="button buttonPrimary">{lang}wcf.acp.package.update.purchaseRequired.button.purchase{/lang}</a>
+       <button style="display: none">{* dummy button for compatibility with the JS module *}</button>
+</div>
\ No newline at end of file
index d7f4c53b975a21626ae262daf91a26b8a540c180..1b654e345debdb58cc9df4bfa8ea70a198610f08 100644 (file)
@@ -54,7 +54,7 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Page/Copy'], function (Language, AcpUiPageCopy) {
                        Language.addObject({
-                               'wcf.acp.page.copy': '{lang}wcf.acp.page.copy{/lang}'
+                               'wcf.acp.page.copy': '{jslang}wcf.acp.page.copy{/jslang}'
                        });
                        
                        AcpUiPageCopy.init();
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
-
 {if $action == 'edit' && !$lastVersion|empty}
        <p class="info">{lang}wcf.acp.page.lastVersion{/lang}</p>
 {/if}
 
+{include file='formNotice'}
+
 <form method="post" action="{if $action == 'add'}{link controller='PageAdd'}{/link}{else}{link controller='PageEdit' id=$pageID}{/link}{/if}">
        <div class="section tabMenuContainer" data-active="{$activeTabMenuItem}" data-store="activeTabMenuItem" id="pageTabMenuContainer">
                <nav class="tabMenu">
                                                                        </dd>
                                                                </dl>
                                                                
+                                                               {event name='informationFieldsMultilingual'}
+                                                               
                                                                {if $pageType != 'system'}
                                                                        {assign var='__errorFieldName' value='content_'|concat:$availableLanguage->languageID}
                                                                        <dl{if $errorField == $__errorFieldName} class="formError"{/if}>
                                                                                </dd>
                                                                        </dl>
                                                                        
+                                                                       {event name='messageFieldsMultilingual'}
+                                                                       
                                                                        {if $pageType == 'text'}
                                                                                {include file='messageFormTabs' wysiwygContainerID='content'|concat:$availableLanguage->languageID}
                                                                        {/if}
                                                                                        {/if}
                                                                                </dd>
                                                                        </dl>
+                                                                       
+                                                                       {event name='metaFieldsMultilingual'}
                                                                {/if}
                                                        </div>
                                                </div>
                                                <script data-relocate="true">
                                                        require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                                                                Language.addObject({
-                                                                       'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                                                                       'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                                                                       'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                                                                       'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                                                                       'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                                                                       'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                                                                       'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                                                                       'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                                                                       'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                                                                       'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                                                                       'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                                                                       'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                                                                       'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                                                                       'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                                                                });
                                                                
                                                                new UiItemListFilter('boxVisibilitySettings');
index a437a9dbb03b5ac22d030bf00348c59ba8b48a0e..07abf24d391873095454d775fe0ebc441e775975 100644 (file)
@@ -32,7 +32,7 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Page/Add'], function(Language, AcpUiPageAdd) {
                Language.addObject({
-                       'wcf.acp.page.add': '{lang}wcf.acp.page.add{/lang}'
+                       'wcf.acp.page.add': '{jslang}wcf.acp.page.add{/jslang}'
                });
                
                AcpUiPageAdd.init('{link controller='PageAdd' encode=false}{literal}pageType={$pageType}&isMultilingual={$isMultilingual}{/literal}{/link}', {@$availableLanguages|count});
index e223de7cd418246b969769058a13bc6a0e7f2b0b..39e74ffd6e85d9f118fdbbd1b07ea3afea48a409 100644 (file)
 <script data-relocate="true">
        require(['Dictionary', 'Language', 'WoltLabSuite/Core/Acp/Ui/Page/BoxOrder'], function (Dictionary, Language, AcpUiPageBoxOrder) {
                Language.addObject({
-                       'wcf.acp.box.isDisabled': '{lang}wcf.acp.box.isDisabled{/lang}',
-                       'wcf.acp.page.boxOrder.discard.confirmMessage': '{lang}wcf.acp.page.boxOrder.discard.confirmMessage{/lang}'
+                       'wcf.acp.box.isDisabled': '{jslang}wcf.acp.box.isDisabled{/jslang}',
+                       'wcf.acp.page.boxOrder.discard.confirmMessage': '{jslang}wcf.acp.page.boxOrder.discard.confirmMessage{/jslang}'
                });
                
                var boxes = new Dictionary();
index b6c6f003376b9bb21a06dc51443ebb8617192b93..a510b43a7c07f0de1b3a1b7a99308ff7af0f10fe 100644 (file)
@@ -5,14 +5,14 @@
                                <li id="userMenu" class="dropdown">
                                        <a href="#" class="dropdownToggle jsTooltip" title="{$__wcf->user->username}">{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32)}</a>
                                        <ul class="dropdownMenu" data-dropdown-alignment-horizontal="right">
-                                               <li><a href="{link controller='User' object=$__wcf->user forceFrontend=true}{/link}">{lang}wcf.user.myProfile{/lang}</a></li>
+                                               <li><a href="{$__wcf->user->getLink()}">{lang}wcf.user.myProfile{/lang}</a></li>
                                                {if $__wcf->getUserProfileHandler()->canEditOwnProfile()}<li><a href="{link controller='User' object=$__wcf->user forceFrontend=true}editOnInit=true#about{/link}">{lang}wcf.user.editProfile{/lang}</a></li>{/if}
                                                <li><a href="{link controller='Settings' forceFrontend=true}{/link}">{lang}wcf.user.menu.settings{/lang}</a></li>
                                                
                                                {event name='userMenuItems'}
                                                
                                                <li class="dropdownDivider"></li>
-                                               <li><a href="{link controller='Logout'}t={@SECURITY_TOKEN}{/link}" onclick="WCF.System.Confirmation.show('{lang}wcf.user.logout.sure{/lang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;">{lang}wcf.user.logout{/lang}</a></li>
+                                               <li><a href="{link controller='Logout'}t={@SECURITY_TOKEN}{/link}" onclick="WCF.System.Confirmation.show('{jslang}wcf.user.logout.sure{/jslang}', $.proxy(function (action) { if (action == 'confirm') window.location.href = $(this).attr('href'); }, this)); return false;">{lang}wcf.user.logout{/lang}</a></li>
                                        </ul>
                                </li>
                                
index 387ababbc65e8a46a0532c846c921c64becb7f2d..664e27c74889d310d7495b77ed546ab68190a135 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='PaidSubscriptionAdd'}{/link}{else}{link controller='PaidSubscriptionEdit' id=$subscriptionID}{/link}{/if}">
        <div class="section">
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 30832b927ff5664a401c355b070e4db41fe17633..91c9eda940292155b65aa4dcca5340d4cb17c72a 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='PaidSubscriptionUserAdd' id=$subscriptionID}{/link}{else}{link controller='PaidSubscriptionUserEdit' id=$subscriptionUserID}{/link}{/if}">
        <div class="section">
diff --git a/wcfsetup/install/files/acp/templates/passwordStrengthLanguage.tpl b/wcfsetup/install/files/acp/templates/passwordStrengthLanguage.tpl
new file mode 100644 (file)
index 0000000..7bc7f02
--- /dev/null
@@ -0,0 +1,30 @@
+Language.addObject({
+       'wcf.user.password.strength': '{jslang}wcf.user.password.strength{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.use_words_avoid_common_phrases': '{jslang}wcf.user.password.zxcvbn.suggestions.use_words_avoid_common_phrases{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.no_need_for_symbols_digits_uppercase': '{jslang}wcf.user.password.zxcvbn.suggestions.no_need_for_symbols_digits_uppercase{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.add_word_uncommon_better': '{jslang}wcf.user.password.zxcvbn.suggestions.add_word_uncommon_better{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.use_longer_keyboard_pattern': '{jslang}wcf.user.password.zxcvbn.suggestions.use_longer_keyboard_pattern{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_repeat': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_repeat{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_sequence': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_sequence{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_recent_year': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_recent_year{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_associated_year': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_associated_year{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.avoid_date': '{jslang}wcf.user.password.zxcvbn.suggestions.avoid_date{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.start_upper': '{jslang}wcf.user.password.zxcvbn.suggestions.start_upper{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.all_upper': '{jslang}wcf.user.password.zxcvbn.suggestions.all_upper{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.reversed': '{jslang}wcf.user.password.zxcvbn.suggestions.reversed{/jslang}',
+       'wcf.user.password.zxcvbn.suggestions.l33t': '{jslang}wcf.user.password.zxcvbn.suggestions.l33t{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.straight_row': '{jslang}wcf.user.password.zxcvbn.warnings.straight_row{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.short_keyboard_pattern': '{jslang}wcf.user.password.zxcvbn.warnings.short_keyboard_pattern{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.repeat_single_char': '{jslang}wcf.user.password.zxcvbn.warnings.repeat_single_char{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.repeat': '{jslang}wcf.user.password.zxcvbn.warnings.repeat{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.sequence': '{jslang}wcf.user.password.zxcvbn.warnings.sequence{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.recent_year': '{jslang}wcf.user.password.zxcvbn.warnings.recent_year{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.date': '{jslang}wcf.user.password.zxcvbn.warnings.date{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.top_10': '{jslang}wcf.user.password.zxcvbn.warnings.top_10{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.top_100': '{jslang}wcf.user.password.zxcvbn.warnings.top_100{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.common': '{jslang}wcf.user.password.zxcvbn.warnings.common{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.common_alike': '{jslang}wcf.user.password.zxcvbn.warnings.common_alike{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.sole_word': '{jslang}wcf.user.password.zxcvbn.warnings.sole_word{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.sole_name': '{jslang}wcf.user.password.zxcvbn.warnings.sole_name{/jslang}',
+       'wcf.user.password.zxcvbn.warnings.name': '{jslang}wcf.user.password.zxcvbn.warnings.name{/jslang}',
+});
index cda6026a2aca646868facef262513c97a0318eee..8a997b5f189c9b6d80de1039110c253b6e39eb63 100644 (file)
@@ -3,10 +3,10 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.package.install.title': '{lang}wcf.acp.package.install.title{/lang}',
-                       'wcf.acp.package.searchForUpdates': '{lang}wcf.acp.package.searchForUpdates{/lang}',
-                       'wcf.acp.package.searchForUpdates.noResults': '{lang}wcf.acp.package.searchForUpdates.noResults{/lang}',
-                       'wcf.acp.package.update.unauthorized': '{lang}wcf.acp.package.update.unauthorized{/lang}'
+                       'wcf.acp.package.install.title': '{jslang}wcf.acp.package.install.title{/jslang}',
+                       'wcf.acp.package.searchForUpdates': '{jslang}wcf.acp.package.searchForUpdates{/jslang}',
+                       'wcf.acp.package.searchForUpdates.noResults': '{jslang}wcf.acp.package.searchForUpdates.noResults{/jslang}',
+                       'wcf.acp.package.update.unauthorized': '{jslang}wcf.acp.package.update.unauthorized{/jslang}'
                });
                
                var $installer = new WCF.ACP.Package.Server.Installation();
        <h1 class="contentTitle">{lang}wcf.acp.pluginStore.purchasedItems{/lang}</h1>
 </header>
 
-{foreach from=$wcfMajorReleases item=wcfMajorRelease}
-       {if !$productData[$wcfMajorRelease]|empty}
-               <section class="section tabularBox">
-                       <h2 class="sectionTitle">{lang}wcf.acp.pluginStore.purchasedItems.wcfMajorRelease{/lang}</h2>
-                       
-                       {if !$updateServers[$wcfMajorRelease]|isset}
-                               <p class="warning">{lang}wcf.acp.pluginStore.purchasedItems.updateServer.missing{/lang}</p>
-                       {else if $updateServers[$wcfMajorRelease]->isDisabled}
-                               <p class="warning">{lang}wcf.acp.pluginStore.purchasedItems.updateServer.disabled{/lang}</p>
-                       {else if $updateServers[$wcfMajorRelease]->lastUpdateTime == 0}
-                               <p class="warning">{lang}wcf.acp.pluginStore.purchasedItems.updateServer.requireUpdate{/lang}</p>
-                       {/if}
-                       
-                       <table class="table">
-                               <thead>
-                                       <tr>
-                                               <th class="columnText" colspan="2">{lang}wcf.acp.package.name{/lang}</th>
-                                               <th class="columnText">{lang}wcf.acp.package.author{/lang}</th>
-                                               <th class="columnText">{lang}wcf.acp.package.version{/lang}</th>
-                                               <th class="columnText">{lang}wcf.acp.package.installedVersion{/lang}</th>
-                                       </tr>
-                               </thead>
-                               
-                               <tbody>
-                                       {foreach from=$productData[$wcfMajorRelease] item=product}
-                                               <tr>
-                                                       <td class="columnIcon">
-                                                               {if $product[status] == 'install'}
-                                                                       <a class="jsButtonPackageInstall" data-confirm-message="{lang __encode=true}wcf.acp.pluginStore.purchasedItems.status.install.confirmMessage{/lang}" data-package="{$product[package]}" data-package-version="{$product[version][available]}"><span class="icon icon16 fa-plus jsTooltip" title="{lang}wcf.acp.package.button.installPackage{/lang}"></span></a>
-                                                               {else if $product[status] == 'update'}
-                                                                       <a class="jsButtonPackageUpdate"><span class="icon icon16 fa-refresh jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.update{/lang}"></span></a>
-                                                               {else if $product[status] == 'upToDate'}
-                                                                       <span class="icon icon16 fa-check green jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.upToDate{/lang}"></span>
-                                                               {else if $product[status] == 'requireUpdate'}
-                                                                       <span class="icon icon16 fa-ban red jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.requireUpdate{/lang}"></span>
-                                                               {else}
-                                                                       <span class="icon icon16 fa-ban red jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.unavailable{/lang}"></span>
-                                                               {/if}
-                                                       </td>
-                                                       <td class="columnText"><a href="{$product[pluginStoreURL]}" class="externalURL">{$product[packageName]}</a></td>
-                                                       <td class="columnText">{if $product[authorURL]}<a href="{$product[authorURL]}" class="externalURL">{$product[author]}</a>{else}{$product[author]}{/if}</td>
-                                                       <td class="columnText">{$product[version][available]}</td>
-                                                       <td class="columnText">{if $product[version][installed]}{$product[version][installed]}{else}-{/if}</td>
-                                               </tr>
-                                       {/foreach}
-                               </tbody>
-                       </table>
-               </section>
-       {/if}
-{/foreach}
+{if !$fetchedPackageServers}
+       <p class="warning">{lang}wcf.acp.pluginStore.purchasedItems.updateServer.requireUpdate{/lang}</p>
+{/if}
+
+<section class="section tabularBox">
+       <table class="table">
+               <thead>
+                       <tr>
+                               <th class="columnText" colspan="2">{lang}wcf.acp.package.name{/lang}</th>
+                               <th class="columnText">{lang}wcf.acp.package.author{/lang}</th>
+                               <th class="columnText">{lang}wcf.acp.package.version{/lang}</th>
+                               <th class="columnText">{lang}wcf.acp.package.installedVersion{/lang}</th>
+                       </tr>
+               </thead>
+               
+               <tbody>
+                       {foreach from=$productData item=product}
+                               <tr>
+                                       <td class="columnIcon">
+                                               {if $product[status] == 'install'}
+                                                       <a class="jsButtonPackageInstall" data-confirm-message="{lang __encode=true}wcf.acp.pluginStore.purchasedItems.status.install.confirmMessage{/lang}" data-package="{$product[package]}" data-package-version="{$product[version][available]}"><span class="icon icon16 fa-plus jsTooltip" title="{lang}wcf.acp.package.button.installPackage{/lang}"></span></a>
+                                               {elseif $product[status] == 'update'}
+                                                       <a class="jsButtonPackageUpdate"><span class="icon icon16 fa-refresh jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.update{/lang}"></span></a>
+                                               {elseif $product[status] == 'upToDate'}
+                                                       <span class="icon icon16 fa-check green jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.upToDate{/lang}"></span>
+                                               {elseif $product[status] == 'requireUpdate'}
+                                                       <span class="icon icon16 fa-ban red jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.requireUpdate{/lang}"></span>
+                                               {else}
+                                                       <span class="icon icon16 fa-ban red jsTooltip" title="{lang}wcf.acp.pluginStore.purchasedItems.status.unavailable{/lang}"></span>
+                                               {/if}
+                                       </td>
+                                       <td class="columnText"><a href="{$product[pluginStoreURL]}" class="externalURL">{$product[packageName]}</a></td>
+                                       <td class="columnText">{if $product[authorURL]}<a href="{$product[authorURL]}" class="externalURL">{$product[author]}</a>{else}{$product[author]}{/if}</td>
+                                       <td class="columnText">{$product[version][available]}</td>
+                                       <td class="columnText">{if $product[version][installed]}{$product[version][installed]}{else}-{/if}</td>
+                               </tr>
+                       {/foreach}
+               </tbody>
+       </table>
+</section>
 
 {include file='footer'}
index 85c8bd03c507aed70a3b903f8c01ef8d0d9a8ff7..fdd5e27b12def96a30698310a131f9d34c657e2b 100644 (file)
@@ -2,7 +2,7 @@
 
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Worker'], function (Language, AcpUiWorker) {
-               Language.add('wcf.acp.worker.abort.confirmMessage', '{lang}wcf.acp.worker.abort.confirmMessage{/lang}');
+               Language.add('wcf.acp.worker.abort.confirmMessage', '{jslang}wcf.acp.worker.abort.confirmMessage{/jslang}');
                
                elBySelAll('.jsRebuildDataWorker', undefined, function (button) {
                        if (button.classList.contains('disabled')) return;
        {/hascontent}
 </header>
 
-{if $showInnoDBWarning}
-       <p class="warning">{lang}wcf.acp.index.innoDBWarning{/lang}</p>
-{/if}
-
 {event name='afterContentHeader'}
 
 <section class="section">
index 18a6e86269b90f4d44cff7cefb2585a31054a310..d248dab4116383b487b73eb415a8a3034343a67c 100644 (file)
@@ -1,13 +1,13 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Ui/ItemList/Filter'], function(Language, UiItemListFilter) {
                Language.addObject({
-                       'wcf.global.filter.button.visibility': '{lang}wcf.global.filter.button.visibility{/lang}',
-                       'wcf.global.filter.button.clear': '{lang}wcf.global.filter.button.clear{/lang}',
-                       'wcf.global.filter.error.noMatches': '{lang}wcf.global.filter.error.noMatches{/lang}',
-                       'wcf.global.filter.placeholder': '{lang}wcf.global.filter.placeholder{/lang}',
-                       'wcf.global.filter.visibility.activeOnly': '{lang}wcf.global.filter.visibility.activeOnly{/lang}',
-                       'wcf.global.filter.visibility.highlightActive': '{lang}wcf.global.filter.visibility.highlightActive{/lang}',
-                       'wcf.global.filter.visibility.showAll': '{lang}wcf.global.filter.visibility.showAll{/lang}'
+                       'wcf.global.filter.button.visibility': '{jslang}wcf.global.filter.button.visibility{/jslang}',
+                       'wcf.global.filter.button.clear': '{jslang}wcf.global.filter.button.clear{/jslang}',
+                       'wcf.global.filter.error.noMatches': '{jslang}wcf.global.filter.error.noMatches{/jslang}',
+                       'wcf.global.filter.placeholder': '{jslang}wcf.global.filter.placeholder{/jslang}',
+                       'wcf.global.filter.visibility.activeOnly': '{jslang}wcf.global.filter.visibility.activeOnly{/jslang}',
+                       'wcf.global.filter.visibility.highlightActive': '{jslang}wcf.global.filter.visibility.highlightActive{/jslang}',
+                       'wcf.global.filter.visibility.showAll': '{jslang}wcf.global.filter.visibility.showAll{/jslang}'
                });
                
                new UiItemListFilter('{@$pageCheckboxListContainerID}');
index f6709d7e7f001e71759c203f11d68b6317071c17..9933270a0e793e29766f58e4ea024791122f9d1a 100644 (file)
@@ -57,7 +57,7 @@
 {if !$mailID|empty}
        <script data-relocate="true">
                require(['Language'], function(Language) {
-                       Language.add('wcf.acp.worker.abort.confirmMessage', '{lang}wcf.acp.worker.abort.confirmMessage{/lang}');
+                       Language.add('wcf.acp.worker.abort.confirmMessage', '{jslang}wcf.acp.worker.abort.confirmMessage{/jslang}');
                        
                        new WCF.ACP.Worker('mail', 'wcf\\system\\worker\\MailWorker', '', {
                                mailID: {@$mailID}
index 5283e18389573d634eed0a863494ca32d4f9bc91..67163ebc978bc5c2c9e719bec921c1f368ff75bd 100644 (file)
 
 <script data-relocate="true">
        require(['Language'], function(Language) {
-               Language.add('wcf.acp.worker.abort.confirmMessage', '{lang}wcf.acp.worker.abort.confirmMessage{/lang}');
+               Language.add('wcf.acp.worker.abort.confirmMessage', '{jslang}wcf.acp.worker.abort.confirmMessage{/jslang}');
                
                elById('sitemapRebuildButton').addEventListener(WCF_CLICK_EVENT, function () {
-                       new WCF.ACP.Worker('sitemapRebuild', 'wcf\\system\\worker\\SitemapRebuildWorker', '{lang}wcf.acp.rebuildData.com.woltlab.wcf.sitemap{/lang}', {
+                       new WCF.ACP.Worker('sitemapRebuild', 'wcf\\system\\worker\\SitemapRebuildWorker', '{jslang}wcf.acp.rebuildData.com.woltlab.wcf.sitemap{/jslang}', {
                                forceRebuild: true
                        });
                });
index 391495a1cdcec22aefbf4107f73f6e25145a7059..e3480b01100d58b98f954756d8d02fc5f2bbf00d 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='SmileyAdd'}{/link}{else}{link controller='SmileyEdit' id=$smiley->smileyID}{/link}{/if}" enctype="multipart/form-data">
        <section class="section">
index 94b2488570a29f5d09897644da1cbc67bab5b944..ba01ac7b72b70282c555ed0ef5c571e9f2c17d3c 100644 (file)
@@ -6,11 +6,11 @@
 <script data-relocate="true">
        $(function() {
                WCF.Language.addObject({
-                       'wcf.acp.stat.timeFormat.daily': '{lang}wcf.acp.stat.timeFormat.daily{/lang}',
-                       'wcf.acp.stat.timeFormat.weekly': '{lang}wcf.acp.stat.timeFormat.weekly{/lang}',
-                       'wcf.acp.stat.timeFormat.monthly': '{lang}wcf.acp.stat.timeFormat.monthly{/lang}',
-                       'wcf.acp.stat.timeFormat.yearly': '{lang}wcf.acp.stat.timeFormat.yearly{/lang}',
-                       'wcf.acp.stat.noData': '{lang}wcf.acp.stat.noData{/lang}'
+                       'wcf.acp.stat.timeFormat.daily': '{jslang}wcf.acp.stat.timeFormat.daily{/jslang}',
+                       'wcf.acp.stat.timeFormat.weekly': '{jslang}wcf.acp.stat.timeFormat.weekly{/jslang}',
+                       'wcf.acp.stat.timeFormat.monthly': '{jslang}wcf.acp.stat.timeFormat.monthly{/jslang}',
+                       'wcf.acp.stat.timeFormat.yearly': '{jslang}wcf.acp.stat.timeFormat.yearly{/jslang}',
+                       'wcf.acp.stat.noData': '{jslang}wcf.acp.stat.noData{/jslang}'
                });
                
                new WCF.ACP.Stat.Chart();
index 1b240fe994db894da14d836b0fd0ac4b2a3fd159..8a7295a2ffaeac2643e86f6990402bce5032457a 100644 (file)
@@ -5,64 +5,29 @@
 {js application='wcf' acp='true' file='WCF.ACP.Style'}
 {js application='wcf' file='WCF.ColorPicker' bundle='WCF.Combined'}
 <script data-relocate="true">
-       require([
-               'WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Delete', 'WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Upload', 'WoltLabSuite/Core/Acp/Ui/Style/Favicon/Upload', 'WoltLabSuite/Core/Acp/Ui/Style/Image/Upload',
-               'WoltLabSuite/Core/Acp/Ui/Style/Editor', 'WoltLabSuite/Core/Ui/Toggle/Input', 'Language'
-       ], function(
-               AcpUiStyleCoverPhotoDelete, AcpUiStyleCoverPhotoUpload, AcpUiStyleFaviconUpload, AcpUiStyleImageUpload,
-               AcpUiStyleEditor, UiToggleInput, Language
-       ) {
+       require(['WoltLabSuite/Core/Acp/Ui/Style/Editor'], function(AcpUiStyleEditor) {
                AcpUiStyleEditor.setup({
                        isTainted: {if $isTainted}true{else}false{/if},
                        styleId: {if $action === 'edit'}{@$style->styleID}{else}0{/if},
                        styleRuleMap: styleRuleMap
                });
-               
-               new AcpUiStyleImageUpload({if $action == 'add'}0{else}{@$style->styleID}{/if}, '{$tmpHash}', false);
-               new AcpUiStyleImageUpload({if $action == 'add'}0{else}{@$style->styleID}{/if}, '{$tmpHash}', true);
-               
-               new UiToggleInput('input[name="useGoogleFont"]', {
-                       show: ['#wcfFontFamilyGoogleContainer']
-               });
-               
-               {if $action === 'edit'}
-                       new AcpUiStyleFaviconUpload({@$style->styleID});
-                       
-                       {if MODULE_USER_COVER_PHOTO}
-                               Language.addObject({
-                                       'wcf.acp.style.coverPhoto.delete.confirmMessage': '{lang}wcf.acp.style.coverPhoto.delete.confirmMessage{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.invalidExtension': '{lang}wcf.user.coverPhoto.upload.error.invalidExtension{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.minHeight': '{lang}wcf.user.coverPhoto.upload.error.minHeight{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.minWidth': '{lang}wcf.user.coverPhoto.upload.error.minWidth{/lang}',
-                                       'wcf.user.coverPhoto.upload.error.uploadFailed': '{lang}wcf.user.coverPhoto.upload.error.uploadFailed{/lang}'
-                               });
-                               
-                               AcpUiStyleCoverPhotoDelete.init({@$style->styleID});
-                               new AcpUiStyleCoverPhotoUpload({@$style->styleID});
-                       {/if}
-               {/if}
        });
        
        $(function() {
                new WCF.ColorPicker('.jsColorPicker');
                
                WCF.Language.addObject({
-                       'wcf.style.colorPicker': '{lang}wcf.style.colorPicker{/lang}',
-                       'wcf.style.colorPicker.new': '{lang}wcf.style.colorPicker.new{/lang}',
-                       'wcf.style.colorPicker.current': '{lang}wcf.style.colorPicker.current{/lang}',
-                       'wcf.style.colorPicker.button.apply': '{lang}wcf.style.colorPicker.button.apply{/lang}',
-                       'wcf.acp.style.favicon.error.dimensions': '{lang}wcf.acp.style.favicon.error.dimensions{/lang}',
-                       'wcf.acp.style.favicon.error.invalidExtension': '{lang}wcf.acp.style.favicon.error.invalidExtension{/lang}',
-                       'wcf.acp.style.image.error.invalidExtension': '{lang}wcf.acp.style.image.error.invalidExtension{/lang}'
+                       'wcf.style.colorPicker': '{jslang}wcf.style.colorPicker{/jslang}',
+                       'wcf.style.colorPicker.new': '{jslang}wcf.style.colorPicker.new{/jslang}',
+                       'wcf.style.colorPicker.current': '{jslang}wcf.style.colorPicker.current{/jslang}',
+                       'wcf.style.colorPicker.button.apply': '{jslang}wcf.style.colorPicker.button.apply{/jslang}'
                });
-               new WCF.ACP.Style.LogoUpload('{$tmpHash}', '{@$__wcf->getPath()}images/');
-               new WCF.ACP.Style.LogoUploadMobile('{$tmpHash}', '{@$__wcf->getPath()}images/');
                
                {if $action == 'edit'}
                        new WCF.ACP.Style.CopyStyle({@$style->styleID});
                        
                        WCF.Language.addObject({
-                               'wcf.acp.style.copyStyle.confirmMessage': '{@"wcf.acp.style.copyStyle.confirmMessage"|language|encodeJS}'
+                               'wcf.acp.style.copyStyle.confirmMessage': '{jslang}wcf.acp.style.copyStyle.confirmMessage{/jslang}'
                        });
                {/if}
                
        <p class="info">{lang}wcf.acp.style.protected{/lang}</p>
 {/if}
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='StyleAdd'}{/link}{else}{link controller='StyleEdit' id=$styleID}{/link}{/if}">
        <div class="section tabMenuContainer" data-active="{$activeTabMenuItem}" data-store="activeTabMenuItem" id="styleTabMenuContainer">
                                        <dd>
                                                <select name="apiVersion" id="apiVersion"{if !$isTainted} disabled{/if}>
                                                        {foreach from=$supportedApiVersions item=supportedApiVersion}
-                                                               <option value="{$supportedApiVersion}"{if $supportedApiVersion === $apiVersion} selected{/if}>{$supportedApiVersion} ({lang}wcf.acp.style.apiVersion.{if $supportedApiVersion === $recommendedApiVersion}recommended{else}deprecated{/if}{/lang})</option>
+                                                               <option value="{$supportedApiVersion}"{if $supportedApiVersion === $apiVersion} selected{/if}>{$supportedApiVersionsCompatibility[$supportedApiVersion]} ({lang}wcf.acp.style.apiVersion.{if $supportedApiVersion === $recommendedApiVersion}recommended{else}deprecated{/if}{/lang})</option>
                                                        {/foreach}
                                                </select>
                                                <small>{lang}wcf.acp.style.apiVersion.description{/lang}</small>
                                <dl{if $errorField == 'image'} class="formError"{/if}>
                                        <dt><label for="image">{lang}wcf.acp.style.image{/lang}</label></dt>
                                        <dd>
-                                               <div class="selectedImagePreview">
-                                                       <img src="{if $action == 'add'}{@$__wcf->getPath()}images/stylePreview.png{else}{@$style->getPreviewImage()}{/if}" alt="" id="styleImage">
-                                               </div>
-                                               <div id="uploadImage"></div>
+                                               {@$__wcf->getUploadHandler()->renderField('image')}
+                                               {if $errorField == 'image'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {elseif $errorType == 'invalid'}
+                                                                       {lang}wcf.upload.error.noImage{/lang}
+                                                               {else}
+                                                                       {lang}wcf.acp.style.image.error.{$errorType}{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
                                                <small>{lang}wcf.acp.style.image.description{/lang}</small>
                                        </dd>
                                </dl>
-                               <dl{if $errorField == 'image'} class="formError"{/if}>
+                               <dl{if $errorField == 'image2x'} class="formError"{/if}>
                                        <dt><label for="image2x">{lang}wcf.acp.style.image2x{/lang}</label></dt>
                                        <dd>
-                                               <div class="selectedImagePreview">
-                                                       <img src="{if $action == 'add'}{@$__wcf->getPath()}images/stylePreview@2x.png{else}{@$style->getPreviewImage2x()}{/if}" alt="" id="styleImage2x">
-                                               </div>
-                                               <div id="uploadImage2x"></div>
+                                               {@$__wcf->getUploadHandler()->renderField('image2x')}
+                                               {if $errorField == 'image2x'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {elseif $errorType == 'invalid'}
+                                                                       {lang}wcf.upload.error.noImage{/lang}
+                                                               {else}
+                                                                       {lang}wcf.acp.style.image2x.error.{$errorType}{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
                                                <small>{lang}wcf.acp.style.image2x.description{/lang}</small>
                                        </dd>
                                </dl>
                                                <dd>
                                                        <select name="templateGroupID" id="templateGroupID">
                                                                <option value="0">{lang}wcf.acp.template.group.default{/lang}</option>
-                                                               {foreach from=$availableTemplateGroups item=templateGroup}
-                                                                       <option value="{@$templateGroup->templateGroupID}"{if $templateGroup->templateGroupID == $templateGroupID} selected{/if}>{$templateGroup->getName()}</option>
-                                                               {/foreach}
+                                                               {htmlOptions options=$availableTemplateGroups selected=$templateGroupID disableEncoding=true}
                                                        </select>
                                                        {if $errorField == 'templateGroupID'}
                                                                <small class="innerError">
                                                </dd>
                                        </dl>
                                {/if}
-                               <dl{if $errorField == 'imagePath'} class="formError"{/if}>
-                                       <dt><label for="imagePath">{lang}wcf.acp.style.imagePath{/lang}</label></dt>
+                               
+                               <dl{if $errorField == 'customAssets'} class="formError"{/if}>
+                                       <dt><label for="customAssets">{lang}wcf.acp.style.customAssets{/lang}</label></dt>
                                        <dd>
-                                               <input type="text" name="imagePath" id="imagePath" value="{$imagePath}" class="long">
-                                               {if $errorField == 'imagePath'}
+                                               {@$__wcf->getUploadHandler()->renderField('customAssets')}
+                                               {if $errorField == 'customAssets'}
                                                        <small class="innerError">
                                                                {if $errorType == 'empty'}
                                                                        {lang}wcf.global.form.error.empty{/lang}
                                                                {else}
-                                                                       {lang}wcf.acp.style.imagePath.error.{$errorType}{/lang}
+                                                                       {lang}wcf.acp.style.customAssets.error.{$errorType}{/lang}
                                                                {/if}
                                                        </small>
                                                {/if}
-                                               <small>{lang}wcf.acp.style.imagePath.description{/lang}</small>
+                                               <small>{lang}wcf.acp.style.customAssets.description{/lang}</small>
                                        </dd>
                                </dl>
                                
                                {event name='fileFields'}
                        </section>
                        
-                       {if $action === 'edit'}
-                               <section class="section">
-                                       <h2 class="sectionTitle">{lang}wcf.acp.style.general.favicon{/lang}</h2>
-                                       
-                                       <dl>
-                                               <dt><label for="favicon">{lang}wcf.acp.style.favicon{/lang}</label></dt>
-                                               <dd>
-                                                       <div class="selectedFaviconPreview">
-                                                               <img src="{@$style->getFaviconAppleTouchIcon()}" alt="" id="faviconImage" style="height: 32px; width: 32px;">
-                                                       </div>
-                                                       <div id="uploadFavicon"></div>
-                                                       <small>{lang}wcf.acp.style.favicon.description{/lang}</small>
-                                               </dd>
-                                       </dl>
-                                       
-                                       {event name='faviconFields'}
-                               </section>
+                       <section class="section">
+                               <h2 class="sectionTitle">{lang}wcf.acp.style.general.favicon{/lang}</h2>
                                
-                               <section class="section">
-                                       <header class="sectionHeader">
-                                               <h2 class="sectionTitle">{lang}wcf.acp.style.general.coverPhoto{/lang}</h2>
-                                               <p class="sectionDescription">{lang}wcf.acp.style.general.coverPhoto.description{/lang}</p>
-                                       </header>
-                                       
-                                       <dl>
-                                               <dt><label for="coverPhoto">{lang}wcf.acp.style.coverPhoto{/lang}</label></dt>
-                                               <dd>
-                                                       <div id="coverPhotoPreview" style="background-image: url({@$__wcf->getPath()}images/coverPhotos/{@$style->getCoverPhoto()})"></div>
-                                                       <div id="uploadCoverPhoto">
-                                                               <a href="#" class="button jsButtonDeleteCoverPhoto"{if !$style->coverPhotoExtension} style="display:none"{/if}>{lang}wcf.global.button.delete{/lang}</a>
-                                                       </div>
-                                                       <small>{lang}wcf.acp.style.coverPhoto.description{/lang}</small>
-                                               </dd>
-                                       </dl>
-                                       
-                                       {event name='coverPhotoFields'}
-                               </section>
-                       {/if}
+                               <dl{if $errorField == 'image'} class="formError"{/if}>
+                                       <dt><label for="favicon">{lang}wcf.acp.style.favicon{/lang}</label></dt>
+                                       <dd>
+                                               {@$__wcf->getUploadHandler()->renderField('favicon')}
+                                               {if $errorField == 'favicon'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {elseif $errorType == 'minWidth' || $errorType == 'minHeight' || $errorType == 'maxWidth' || $errorType == 'maxHeight'}
+                                                                       {lang}wcf.acp.style.favicon.error.dimensions{/lang}
+                                                               {elseif $errorType == 'invalid'}
+                                                                       {lang}wcf.upload.error.noImage{/lang}
+                                                               {else}
+                                                                       {lang}wcf.acp.style.favicon.error.{$errorType}{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
+                                               <small>{lang}wcf.acp.style.favicon.description{/lang}</small>
+                                       </dd>
+                               </dl>
+                               
+                               {event name='faviconFields'}
+                       </section>
+                       
+                       <section class="section">
+                               <header class="sectionHeader">
+                                       <h2 class="sectionTitle">{lang}wcf.acp.style.general.coverPhoto{/lang}</h2>
+                                       <p class="sectionDescription">{lang}wcf.acp.style.general.coverPhoto.description{/lang}</p>
+                               </header>
+                               
+                               <dl{if $errorField == 'coverPhoto'} class="formError"{/if}>
+                                       <dt><label for="coverPhoto">{lang}wcf.acp.style.coverPhoto{/lang}</label></dt>
+                                       <dd>
+                                               {@$__wcf->getUploadHandler()->renderField('coverPhoto')}
+                                               {if $errorField == 'coverPhoto'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {elseif $errorType == 'minWidth' || $errorType == 'minHeight'}
+                                                                       {lang}wcf.image.coverPhoto.upload.error.{$errorType}{/lang}
+                                                               {elseif $errorType == 'invalid'}
+                                                                       {lang}wcf.upload.error.noImage{/lang}
+                                                               {else}
+                                                                       {lang}wcf.acp.style.coverPhoto.error.{$errorType}{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
+                                               <small>{lang}wcf.acp.style.coverPhoto.description{/lang}</small>
+                                       </dd>
+                               </dl>
+                               
+                               {event name='coverPhotoFields'}
+                       </section>
                        
                        {event name='generalFieldsets'}
                </div>
                                <dl>
                                        <dt><label for="pageLogo">{lang}wcf.acp.style.globals.pageLogo{/lang}</label></dt>
                                        <dd>
-                                               <div class="selectedImagePreview">
-                                                       <img src="" alt="" id="styleLogo" style="max-width: 100%">
-                                               </div>
-                                               <div id="uploadLogo"></div>
-                                       </dd>
-                                       <dd>
-                                               <input type="text" name="pageLogo" id="pageLogo" value="{$variables[pageLogo]}" class="long">
+                                               {@$__wcf->getUploadHandler()->renderField('pageLogo')}
                                                <small>{lang}wcf.acp.style.globals.pageLogo.description{/lang}</small>
+                                               <script data-relocate="true">
+                                               elBySel('#pageLogouploadFileList').addEventListener('change', function (ev) {
+                                                       var img = elBySel('#pageLogouploadFileList img');
+                                                       if (!img) return;
+                                                       
+                                                       function updateSizes() {
+                                                               elById('pageLogoWidth').value = img.width;
+                                                               elById('pageLogoHeight').value = img.height;
+                                                       }
+                                                       img.addEventListener('load', updateSizes);
+                                                       if (img.complete) {
+                                                               updateSizes();
+                                                       }
+                                               })
+                                               </script>
                                        </dd>
                                </dl>
                                
                                <dl>
                                        <dt><label for="pageLogoMobile">{lang}wcf.acp.style.globals.pageLogoMobile{/lang}</label></dt>
                                        <dd>
-                                               <div class="selectedImagePreview">
-                                                       <img src="" alt="" id="styleLogoMobile" style="max-width: 100%">
-                                               </div>
-                                               <div id="uploadLogoMobile"></div>
-                                       </dd>
-                                       <dd>
-                                               <input type="text" name="pageLogoMobile" id="pageLogoMobile" value="{$variables[pageLogoMobile]}" class="long">
+                                               {@$__wcf->getUploadHandler()->renderField('pageLogoMobile')}
                                                <small>{lang}wcf.acp.style.globals.pageLogoMobile.description{/lang}</small>
                                        </dd>
                                </dl>
                                        </dd>
                                </dl>
                                
-                               <dl>
-                                       <dt></dt>
-                                       <dd><label>
-                                               <input type="checkbox" id="useGoogleFont" name="useGoogleFont" value="1"{if !$variables[useGoogleFont]|empty} checked{/if}>
-                                               <span>{lang}wcf.acp.style.globals.useGoogleFont{/lang}</span>
-                                       </label></dd>
-                               </dl>
-                               <dl id="wcfFontFamilyGoogleContainer">
+                               <dl id="wcfFontFamilyGoogleContainer"{if $errorField == 'wcfFontFamilyGoogle'} class="formError"{/if}>
                                        <dt><label for="wcfFontFamilyGoogle">{lang}wcf.acp.style.globals.fontFamilyGoogle{/lang}</label></dt>
                                        <dd>
                                                <input type="text" id="wcfFontFamilyGoogle" name="wcfFontFamilyGoogle" value="{$variables[wcfFontFamilyGoogle]}" class="medium">
+                                               <small>{lang}wcf.acp.style.globals.fontFamilyGoogle.description{/lang}</small>
+                                               {if $errorField == 'wcfFontFamilyGoogle'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {else}
+                                                                       {lang}wcf.acp.style.globals.fontFamilyGoogle.error.{$errorType}{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
                                        </dd>
                                </dl>
                                <dl>
                                                        
                                                        <div class="spSidebarBox" data-category="none">
                                                                <p>{lang}wcf.acp.style.colors.description{/lang}</p>
-                                                               <p><br></p>
-                                                               <p><sup class="spApiVersion">3.1</sup> <small>{lang version='3.1'}wcf.acp.style.colors.description.apiVersion{/lang}</small></p>
-                                                               <p><sup class="spApiVersion">5.2</sup> <small>{lang version='5.2'}wcf.acp.style.colors.description.apiVersion{/lang}</small></p>
                                                        </div>
                                                        
                                                        {foreach from=$colors key=spCategory item=spColors}
                                                                        </ul>
                                                                </div>
                                                        {/foreach}
+                                                       
+                                                       <div class="spSidebarBox" data-category="apiVersion" style="display: none;">
+                                                               <p><sup class="spApiVersion">3.1</sup> <small>{lang version='3.1'}wcf.acp.style.colors.description.apiVersion{/lang}</small></p>
+                                                               <p><sup class="spApiVersion">5.2</sup> <small>{lang version='5.2'}wcf.acp.style.colors.description.apiVersion{/lang}</small></p>
+                                                       </div>
                                                </div>
                                        </div>
                                </div>
                                
                                {* custom declarations *}
                                <div id="advanced-custom" class="tabMenuContent">
-                                       <section class="section">
+                                       <section class="section"{if $errorField == 'individualScss'} formError{/if}>
                                                <h2 class="sectionTitle">{lang}wcf.acp.style.advanced.individualScss{/lang}</h2>
                                                
                                                <dl class="wide">
                                                        <dd>
                                                                <div dir="ltr">
                                                                        <textarea id="individualScssCustom" rows="20" cols="40" name="individualScssCustom">{$variables[individualScssCustom]}</textarea>
+                                                                       <input class="codeMirrorScrollOffset" name="scrollOffsets[individualScssCustom]" value="{if $scrollOffsets[individualScssCustom]|isset}{$scrollOffsets[individualScssCustom]}{else}0{/if}" type="hidden">
                                                                </div>
                                                                <small>{lang}wcf.acp.style.advanced.individualScss.description{/lang}</small>
                                                        </dd>
+                                                       {if $errorField == 'individualScss'}
+                                                               <small class="innerError">
+                                                                       {lang}wcf.acp.style.advanced.individualScss.error{/lang}
+                                                               </small>
+                                                       {/if}
                                                </dl>
                                        </section>
                                        
                                                        <dd>
                                                                <div dir="ltr">
                                                                        <textarea id="overrideScssCustom" rows="20" cols="40" name="overrideScssCustom">{$variables[overrideScssCustom]}</textarea>
+                                                                       <input class="codeMirrorScrollOffset" name="scrollOffsets[overrideScssCustom]" value="{if $scrollOffsets[overrideScssCustom]|isset}{$scrollOffsets[overrideScssCustom]}{else}0{/if}" type="hidden">
                                                                </div>
                                                                {if $errorField == 'overrideScssCustom'}
                                                                        <small class="innerError">
                                <div id="advanced-original" class="tabMenuContent">
                        {/if}
                        
-                       <section class="section">
+                       <section class="section{if $errorField == 'individualScss' && $isTainted} formError{/if}">
                                <h2 class="sectionTitle">{lang}wcf.acp.style.advanced.individualScss{/lang}{if !$isTainted} ({lang}wcf.acp.style.protected.less{/lang}){/if}</h2>
                                
                                <dl class="wide">
                                        <dd>
                                                <div dir="ltr">
                                                        <textarea id="individualScss" rows="20" cols="40" name="individualScss">{$variables[individualScss]}</textarea>
+                                                       <input class="codeMirrorScrollOffset" name="scrollOffsets[individualScss]" value="{if $scrollOffsets[individualScss]|isset}{$scrollOffsets[individualScss]}{else}0{/if}" type="hidden">
                                                </div>
                                                <small>{lang}wcf.acp.style.advanced.individualScss.description{/lang}</small>
                                        </dd>
+                                       {if $errorField == 'individualScss' && $isTainted}
+                                               <small class="innerError">
+                                                       {lang}wcf.acp.style.advanced.individualScss.error{/lang}
+                                               </small>
+                                       {/if}
                                </dl>
                        </section>
                        
                                        <dd>
                                                <div dir="ltr">
                                                        <textarea id="overrideScss" rows="20" cols="40" name="overrideScss">{$variables[overrideScss]}</textarea>
+                                                       <input class="codeMirrorScrollOffset" name="scrollOffsets[overrideScss]" value="{if $scrollOffsets[overrideScss]|isset}{$scrollOffsets[overrideScss]}{else}0{/if}" type="hidden">
                                                </div>
                                                {if $errorField == 'overrideScss'}
                                                        <small class="innerError">
index cd4d96cf4fce63bbfb68bead45b2249465714cb6..c1a24859f33a89e8eeb9e280e4ecc80bb9e4da1b 100644 (file)
                        <p class="sectionDescription">{lang}wcf.acp.style.exportStyle.components.description{/lang}</p>
                </header>
                
-               <dl>
-                       <dt></dt>
-                       <dd>
-                               <label><input type="checkbox" name="exportImages" value="1"{if $exportImages} checked{/if}{if !$canExportImages} disabled{/if}> <span>{lang}wcf.acp.style.exportImages{/lang}</span></label>
-                       </dd>
-               </dl>
                <dl>
                        <dt></dt>
                        <dd>
@@ -65,4 +59,4 @@
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 0408d87e34e2161cd78d6c453a89ffec5ae3f1dd..aa087b1a1547c96517205443d4d57cd51a6316f5 100644 (file)
 {/if}
 
 <form method="post" action="{link controller='StyleGlobalValues'}{/link}">
-       <div class="section">
+       <div class="section"{if $errorField == 'styles'} formError{/if}>
                <dl>
                        <dt>{lang}wcf.acp.style.globalValues.input{/lang}</dt>
                        <dd>
                                <div dir="ltr">
                                        <textarea id="styles" rows="20" cols="40" name="styles" style="visibility: hidden">{$styles}</textarea>
+                                       <input class="codeMirrorScrollOffset" name="stylesScrollOffset" value="{$stylesScrollOffset}" type="hidden">
                                </div>
                        </dd>
+                       {if $errorField == 'styles'}
+                               <small class="innerError">
+                                       {lang}wcf.acp.style.globalValues.input.error{/lang}
+                               </small>
+                       {/if}
                </dl>
                {include file='codemirror' codemirrorMode='text/x-less' codemirrorSelector='#styles'}
        </div>
index ae4b1a0229ba68306c06f90a198e6dc3e8bfb337..4a61d864249ef9c386eb13f50a2408fa8bcc84bb 100644 (file)
                        <small>{lang}wcf.acp.systemCheck.php.sha256.description{/lang}</small>
                </dd>
        </dl>
+       
+       <dl{if !$results[php][gd][result]} class="formError"{/if}>
+               <dt>{lang}wcf.acp.systemCheck.php.gd{/lang}</dt>
+               <dd>
+                       {if $results[php][gd][result]}
+                               {@$statusOk} {lang}wcf.acp.systemCheck.pass{/lang}
+                       {else}
+                               <ul class="nativeList">
+                                       {if !$results[php][gd][jpeg]}
+                                               <li>{@$statusInsufficient} <kbd>jpeg</kbd></li>
+                                       {/if}
+                                       {if !$results[php][gd][png]}
+                                               <li>{@$statusInsufficient} <kbd>png</kbd></li>
+                                       {/if}
+                               </ul>
+                       {/if}
+                       <small>{lang}wcf.acp.systemCheck.php.gd.description{/lang}</small>
+               </dd>
+       </dl>
 </section>
 
 <section class="section">
index 2f1b2c97bdb1281e560bdc418ec4a76bf5853eb9..b24a0d22f21a0b2f4bd1e82199fdfbf75d1e77ff 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='TagAdd'}{/link}{else}{link controller='TagEdit' object=$tagObj}{/link}{/if}">
        <div class="section">
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
diff --git a/wcfsetup/install/files/acp/templates/tagInput.tpl b/wcfsetup/install/files/acp/templates/tagInput.tpl
new file mode 100644 (file)
index 0000000..3c50595
--- /dev/null
@@ -0,0 +1,25 @@
+{if $__wcf->session->getPermission('user.tag.canViewTag')}
+       <dl class="jsOnly">
+               <dt><label for="tagSearchInput{if $tagInputSuffix|isset}{@$tagInputSuffix}{/if}">{lang}wcf.tagging.tags{/lang}</label></dt>
+               <dd>
+                       <input id="tagSearchInput{if $tagInputSuffix|isset}{@$tagInputSuffix}{/if}" type="text" value="" class="long">
+                       <small>{lang}wcf.tagging.tags.description{/lang}</small>
+               </dd>
+       </dl>
+       
+       <script data-relocate="true">
+               require(['WoltLabSuite/Core/Ui/ItemList'], function(UiItemList) {
+                       UiItemList.init(
+                               'tagSearchInput{if $tagInputSuffix|isset}{@$tagInputSuffix}{/if}',
+                               [{if $tags|isset && $tags|count}{implode from=$tags item=tag}'{@$tag|encodeJS}'{/implode}{/if}],
+                               {
+                                       ajax: {
+                                               className: 'wcf\\data\\tag\\TagAction'
+                                       },
+                                       maxLength: {@TAGGING_MAX_TAG_LENGTH},
+                                       submitFieldName: '{if $tagSubmitFieldName|isset}{@$tagSubmitFieldName}{else}tags[]{/if}'
+                               }
+                       );
+               });
+       </script>
+{/if}
index de3c56865e2cb1c98d34072ec5350ce905ab676b..7077b8350570e97e53a029eed9430c989dd05d7f 100644 (file)
@@ -2,7 +2,7 @@
 
 <script data-relocate="true">
        require(['WoltLabSuite/Core/Controller/Clipboard', 'Language'], function(ControllerClipboard, Language) {
-               Language.add('wcf.acp.tag.setAsSynonyms', '{lang}wcf.acp.tag.setAsSynonyms{/lang}');
+               Language.add('wcf.acp.tag.setAsSynonyms', '{jslang}wcf.acp.tag.setAsSynonyms{/jslang}');
                
                var deleteAction = new WCF.Action.Delete('wcf\\data\\tag\\TagAction', '.jsTagRow');
                deleteAction.setCallback(ControllerClipboard.reload.bind(ControllerClipboard));
index c79ea5bdc0573b89173a30a1fb4c3daaec8191f2..889849eec76840acefea05b10d6030c9caf2a948 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $availableTemplateGroups|count}
        <form method="post" action="{if $action == 'add'}{link controller='TemplateAdd'}{/link}{else}{link controller='TemplateEdit' id=$templateID}{/link}{/if}">
index 90607ee32a0ee3dc79676e3d603767e86cbe71f2..29a6f07203ae3875ff9e434a6247e113ed6a5398 100644 (file)
@@ -4,12 +4,12 @@
        <script data-relocate="true">
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/Template/Group/Copy'], function (Language, AcpUiTemplateGroupCopy) {
                        Language.addObject({
-                               'wcf.acp.template.group.copy': '{lang}wcf.acp.template.group.copy{/lang}',
-                               'wcf.acp.template.group.name.error.notUnique': '{lang}wcf.acp.template.group.name.error.notUnique{/lang}',
-                               'wcf.acp.template.group.folderName': '{lang}wcf.acp.template.group.folderName{/lang}',
-                               'wcf.acp.template.group.folderName.error.invalid': '{lang}wcf.acp.template.group.folderName.error.invalid{/lang}',
-                               'wcf.acp.template.group.folderName.error.notUnique': '{lang}wcf.acp.template.group.folderName.error.notUnique{/lang}',
-                               'wcf.global.name': '{lang}wcf.global.name{/lang}'
+                               'wcf.acp.template.group.copy': '{jslang}wcf.acp.template.group.copy{/jslang}',
+                               'wcf.acp.template.group.name.error.notUnique': '{jslang}wcf.acp.template.group.name.error.notUnique{/jslang}',
+                               'wcf.acp.template.group.folderName': '{jslang}wcf.acp.template.group.folderName{/jslang}',
+                               'wcf.acp.template.group.folderName.error.invalid': '{jslang}wcf.acp.template.group.folderName.error.invalid{/jslang}',
+                               'wcf.acp.template.group.folderName.error.notUnique': '{jslang}wcf.acp.template.group.folderName.error.notUnique{/jslang}',
+                               'wcf.global.name': '{jslang}wcf.global.name{/jslang}'
                        });
                        
                        AcpUiTemplateGroupCopy.init({$templateGroupID});
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='TemplateGroupAdd'}{/link}{else}{link controller='TemplateGroupEdit' id=$templateGroupID}{/link}{/if}">
        <div class="section">
index 3e25e849ff445166039622e1440d8bc13343612c..3b43cd9e8223457a826e2bc5795b5dfbca4691c7 100644 (file)
@@ -6,12 +6,12 @@
                
                var options = { };
                {if $pages > 1}
-               options.refreshPage = true;
-               {if $pages == $pageNo}
-               options.updatePageNumber = -1;
-               {/if}
+                       options.refreshPage = true;
+                       {if $pages == $pageNo}
+                               options.updatePageNumber = -1;
+                       {/if}
                {else}
-               options.emptyMessage = '{lang}wcf.global.noItems{/lang}';
+                       options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
                {/if}
                
                new WCF.Table.EmptyTableHandler($('#templateGroupTableContainer'), 'jsTemplateGroupRow', options);
index df6906e419683678018203d11dddea019fe1fb16..94340d9139360cd49bbc236d0a0398b943795480 100644 (file)
@@ -11,7 +11,7 @@
                                options.updatePageNumber = -1;
                        {/if}
                {else}
-                       options.emptyMessage = '{lang}wcf.global.noItems{/lang}';
+                       options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
                {/if}
                
                new WCF.Table.EmptyTableHandler($('#templateTableContainer'), 'jsTemplateRow', options);
index 0c87dfde3afbcfe606054863e36096dcb340cd10..1c636c05630a843d344bea2d82d62508e6147198 100644 (file)
@@ -6,15 +6,15 @@
 <script data-relocate="true">
        require(['Language', 'WoltLabSuite/Core/Acp/Ui/Trophy/Badge'], function (Language, BadgeHandler) {
                Language.addObject({
-                       'wcf.style.colorPicker': '{lang}wcf.style.colorPicker{/lang}',
-                       'wcf.style.colorPicker.new': '{lang}wcf.style.colorPicker.new{/lang}',
-                       'wcf.style.colorPicker.current': '{lang}wcf.style.colorPicker.current{/lang}',
-                       'wcf.style.colorPicker.button.apply': '{lang}wcf.style.colorPicker.button.apply{/lang}',
-                       'wcf.acp.style.image.error.invalidExtension': '{lang}wcf.acp.style.image.error.invalidExtension{/lang}',
-                       'wcf.acp.trophy.badge.edit': '{lang}wcf.acp.trophy.badge.edit{/lang}',
-                       'wcf.acp.trophy.imageUpload.error.notSquared': '{lang}wcf.acp.trophy.imageUpload.error.notSquared{/lang}',
-                       'wcf.acp.trophy.imageUpload.error.tooSmall': '{lang}wcf.acp.trophy.imageUpload.error.tooSmall{/lang}',
-                       'wcf.acp.trophy.imageUpload.error.noImage': '{lang}wcf.acp.trophy.imageUpload.error.noImage{/lang}'
+                       'wcf.style.colorPicker': '{jslang}wcf.style.colorPicker{/jslang}',
+                       'wcf.style.colorPicker.new': '{jslang}wcf.style.colorPicker.new{/jslang}',
+                       'wcf.style.colorPicker.current': '{jslang}wcf.style.colorPicker.current{/jslang}',
+                       'wcf.style.colorPicker.button.apply': '{jslang}wcf.style.colorPicker.button.apply{/jslang}',
+                       'wcf.acp.style.image.error.invalidExtension': '{jslang}wcf.acp.style.image.error.invalidExtension{/jslang}',
+                       'wcf.acp.trophy.badge.edit': '{jslang}wcf.acp.trophy.badge.edit{/jslang}',
+                       'wcf.acp.trophy.imageUpload.error.notSquared': '{jslang}wcf.acp.trophy.imageUpload.error.notSquared{/jslang}',
+                       'wcf.acp.trophy.imageUpload.error.tooSmall': '{jslang}wcf.acp.trophy.imageUpload.error.tooSmall{/jslang}',
+                       'wcf.acp.trophy.imageUpload.error.noImage': '{jslang}wcf.acp.trophy.imageUpload.error.noImage{/jslang}'
                });
                
                elBySel('select[name=type]').addEventListener('change', function () {
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $trophyCategories|count}
        <form id="trophyForm" method="post" action="{if $action == 'add'}{link controller='TrophyAdd'}{/link}{else}{link controller='TrophyEdit' id=$trophy->getObjectID()}{/link}{/if}">
index 6765947df2f5eb23d9923eb63fc4393dd5d371fe..b666f6501e98225666f0e6c3c705a944d09239fa 100644 (file)
@@ -42,6 +42,7 @@
                        {foreach from=$objects item='trophy'}
                                <li class="sortableNode sortableNoNesting trophyRow" data-object-id="{@$trophy->trophyID}">
                                        <span class="sortableNodeLabel">
+                                               {@$trophy->renderTrophy(32)}
                                                <a href="{link controller='TrophyEdit' object=$trophy}{/link}">{$trophy->getTitle()}</a>
                                                
                                                <span class="statusDisplay sortableButtonContainer">
index 7c8d41f40e685fe1b25e76962f6f25ad5785231e..c2ec24b9bf8c77b84499dddcdba1ccbcdca6fe5f 100644 (file)
 <script data-relocate="true">
        require(['WoltLabSuite/Core/Ui/File/Upload', 'Language'], function(Upload, Language) {
                Language.addObject({
-                       'wcf.upload.error.reachedRemainingLimit': '{lang __literal=true}wcf.upload.error.reachedRemainingLimit{/lang}',
-                       'wcf.upload.error.noImage': '{lang}wcf.upload.error.noImage{/lang}',
-                       'wcf.upload.error.uploadFailed': '{lang}wcf.upload.error.uploadFailed{/lang}',
+                       'wcf.upload.error.reachedRemainingLimit': '{jslang __literal=true}wcf.upload.error.reachedRemainingLimit{/jslang}',
+                       'wcf.upload.error.noImage': '{jslang}wcf.upload.error.noImage{/jslang}',
+                       'wcf.upload.error.uploadFailed': '{jslang}wcf.upload.error.uploadFailed{/jslang}',
                });
                
                new Upload("{$uploadFieldId}UploadButtonDiv", "{$uploadFieldId}uploadFileList", {
                        internalId: '{$uploadField->getInternalId()}',
                        {if $uploadField->getMaxFiles()}maxFiles: {$uploadField->getMaxFiles()},{/if}
-                       imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if}
+                       imagePreview: {if !$uploadField->supportMultipleFiles() && $uploadField->isImageOnly()}true{else}false{/if},
+                       {if $uploadField->getAcceptableFiles()}
+                               acceptableFiles: [
+                                       {implode from=$uploadField->getAcceptableFiles() item=accept}'{$accept|encodeJS}'{/implode}
+                               ],
+                       {/if}
                });
        });
 </script>
index ede9b08d0b81c1f3805c33a9f7594f11f6081d99..6f05581eaafdb1097b2b5f08262fd2a4d681e446 100644 (file)
@@ -2,10 +2,10 @@
 
 <script data-relocate="true">
        $(function() {
-               WCF.Language.add('wcf.acp.worker.abort.confirmMessage', '{lang}wcf.acp.worker.abort.confirmMessage{/lang}');
+               WCF.Language.add('wcf.acp.worker.abort.confirmMessage', '{jslang}wcf.acp.worker.abort.confirmMessage{/jslang}');
                
                $('#updateEvents').click(function () {
-                       new WCF.ACP.Worker('events', 'wcf\\system\\worker\\UserActivityPointUpdateEventsWorker', '{lang}wcf.acp.user.activityPoint.updateEvents{/lang}');
+                       new WCF.ACP.Worker('events', 'wcf\\system\\worker\\UserActivityPointUpdateEventsWorker', '{jslang}wcf.acp.user.activityPoint.updateEvents{/jslang}');
                });
        });
 </script>
@@ -54,4 +54,4 @@
        </div>
 </form>
 
-{include file='footer'}
\ No newline at end of file
+{include file='footer'}
index 3ca491e1e1a9b8523c355c2aeffff3841f7d3d84..70fca46bd4ef94129ae10e7f656ebdaa738ba088 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
 {if $userID|isset && $__wcf->user->userID == $userID}
        <p class="warning">{lang}wcf.acp.user.edit.warning.selfEdit{/lang}</p>
 {/if}
 
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{@$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='UserAdd'}{/link}{else}{link controller='UserEdit' id=$userID}{/link}{/if}">
        <div class="section tabMenuContainer">
                                                        </dd>
                                                </dl>
                                                
+                                               <script data-relocate="true">
+                                                       require(['WoltLabSuite/Core/Ui/User/PasswordStrength', 'Language'], function (PasswordStrength, Language) {
+                                                               {include file='passwordStrengthLanguage'}
+                                                               
+                                                               var relatedInputs = [];
+                                                               if (elById('username')) relatedInputs.push(elById('username'));
+                                                               if (elById('email')) relatedInputs.push(elById('email'));
+                                                               
+                                                               new PasswordStrength(elById('password'), {
+                                                                       relatedInputs: relatedInputs,
+                                                                       staticDictionary: [
+                                                                               '{$__wcf->user->username|encodeJS}',
+                                                                               '{$__wcf->user->email|encodeJS}',
+                                                                               {if $user|isset}
+                                                                                       '{$user->username|encodeJS}',
+                                                                                       '{$user->email|encodeJS}',
+                                                                               {/if}
+                                                                       ]
+                                                               });
+                                                       })
+                                               </script>
+                                               
                                                {event name='passwordFields'}
                                        </section>
                                {/if}
                                        <section class="section">
                                                <h2 class="sectionTitle">{lang}wcf.user.option.category.{@$categoryLevel2[object]->categoryName}{/lang}</h2>
                                                
-                                               {if $categoryLevel2[object]->categoryName == 'settings.general' && $availableLanguages|count > 1}
-                                                       <dl>
-                                                               <dt><label for="languageID">{lang}wcf.user.language{/lang}</label></dt>
-                                                               <dd>
-                                                                       {htmlOptions options=$availableLanguages selected=$languageID name=languageID id=languageID disableEncoding=true}
-                                                               </dd>
-                                                       </dl>
+                                               {if $categoryLevel2[object]->categoryName == 'settings.general'}
+                                                       {if $availableLanguages|count > 1}
+                                                               <dl>
+                                                                       <dt><label for="languageID">{lang}wcf.user.language{/lang}</label></dt>
+                                                                       <dd>
+                                                                               {htmlOptions options=$availableLanguages selected=$languageID name=languageID id=languageID disableEncoding=true}
+                                                                       </dd>
+                                                               </dl>
+                                                               
+                                                               {if $availableContentLanguages|count > 1}
+                                                                       <dl>
+                                                                               <dt>
+                                                                                       <label>{lang}wcf.user.visibleLanguages{/lang}</label>
+                                                                               </dt>
+                                                                               <dd>
+                                                                                       {foreach from=$availableContentLanguages key=availableLanguageID item=availableLanguage}
+                                                                                               <label><input type="checkbox" name="visibleLanguages[]" value="{@$availableLanguageID}"{if $availableLanguageID|in_array:$visibleLanguages} checked{/if}> {@$availableLanguage}</label>
+                                                                                       {/foreach}
+                                                                               </dd>
+                                                                       </dl>
+                                                               {/if}
+                                                       {/if}
                                                        
-                                                       {if $availableContentLanguages|count > 1}
+                                                       {if $action === 'edit' && $availableStyles|count > 1}
                                                                <dl>
-                                                                       <dt>
-                                                                               <label>{lang}wcf.user.visibleLanguages{/lang}</label>
-                                                                       </dt>
+                                                                       <dt><label for="styleID">{lang}wcf.user.style{/lang}</label></dt>
                                                                        <dd>
-                                                                               {foreach from=$availableContentLanguages key=availableLanguageID item=availableLanguage}
-                                                                                       <label><input type="checkbox" name="visibleLanguages[]" value="{@$availableLanguageID}"{if $availableLanguageID|in_array:$visibleLanguages} checked{/if}> {@$availableLanguage}</label>
-                                                                               {/foreach}
+                                                                               <select id="styleID" name="styleID">
+                                                                                       <option value="0">{lang}wcf.global.defaultValue{/lang}</option>
+                                                                                       {foreach from=$availableStyles item=style}
+                                                                                               <option value="{@$style->styleID}"{if $style->styleID == $styleID} selected{/if}>{$style->styleName}</option>
+                                                                                       {/foreach}
+                                                                               </select>
+                                                                               {if $errorField === 'styleID'}
+                                                                                       <small class="innerError">
+                                                                                               {if $errorType === 'empty' || $errorType === 'noValidSelection'}
+                                                                                                       {lang}wcf.global.form.error.{@$errorType}{/lang}
+                                                                                               {else}
+                                                                                                       {lang}wcf.user.style.error.{@$errorType.password}{/lang}
+                                                                                               {/if}
+                                                                                       </small>
+                                                                               {/if}
+                                                                               <small>{lang}wcf.user.style.description{/lang}</small>
                                                                        </dd>
                                                                </dl>
                                                        {/if}
                                <script data-relocate="true">
                                        $(function() {
                                                WCF.Language.addObject({
-                                                       'wcf.user.avatar.upload.error.invalidExtension': '{lang}wcf.user.avatar.upload.error.invalidExtension{/lang}',
-                                                       'wcf.user.avatar.upload.error.tooSmall': '{lang}wcf.user.avatar.upload.error.tooSmall{/lang}',
-                                                       'wcf.user.avatar.upload.error.tooLarge': '{lang}wcf.user.avatar.upload.error.tooLarge{/lang}',
-                                                       'wcf.user.avatar.upload.error.uploadFailed': '{lang}wcf.user.avatar.upload.error.uploadFailed{/lang}',
-                                                       'wcf.user.avatar.upload.error.badImage': '{lang}wcf.user.avatar.upload.error.badImage{/lang}',
-                                                       'wcf.user.avatar.upload.success': '{lang}wcf.user.avatar.upload.success{/lang}'
+                                                       'wcf.user.avatar.upload.error.invalidExtension': '{jslang}wcf.user.avatar.upload.error.invalidExtension{/jslang}',
+                                                       'wcf.user.avatar.upload.error.tooSmall': '{jslang}wcf.user.avatar.upload.error.tooSmall{/jslang}',
+                                                       'wcf.user.avatar.upload.error.tooLarge': '{jslang}wcf.user.avatar.upload.error.tooLarge{/jslang}',
+                                                       'wcf.user.avatar.upload.error.uploadFailed': '{jslang}wcf.user.avatar.upload.error.uploadFailed{/jslang}',
+                                                       'wcf.user.avatar.upload.error.badImage': '{jslang}wcf.user.avatar.upload.error.badImage{/jslang}',
+                                                       'wcf.user.avatar.upload.success': '{jslang}wcf.user.avatar.upload.success{/jslang}'
                                                });
                                                
                                                new WCF.User.Avatar.Upload({@$user->userID});
                        if (input) {
                                var icon = elCreate('span');
                                icon.className = 'icon icon16 fa-shield jsTooltip';
-                               icon.title = '{lang}wcf.acp.group.type.owner{/lang}';
+                               icon.title = '{jslang}wcf.acp.group.type.owner{/jslang}';
                                input.parentNode.appendChild(icon);
                                
                                {if $user->userID == $__wcf->user->userID}
index 4827efa5163baea8ed847d63138ae5ab9ae6a735..f2f535d85f7d6fd01e97775ae27d439e41f23c1c 100644 (file)
@@ -4,15 +4,15 @@
        $(function() {
                new WCF.Option.Handler();
                
-               {if $action == 'edit' && $group->groupType == 4 && $__wcf->session->getPermission('admin.user.canAddGroup')}
+               {if $action == 'edit' && $group->canCopy()}
                        WCF.Language.addObject({
-                               'wcf.acp.group.copy.confirmMessage': '{lang}wcf.acp.group.copy.confirmMessage{/lang}',
-                               'wcf.acp.group.copy.copyACLOptions': '{lang}wcf.acp.group.copy.copyACLOptions{/lang}',
-                               'wcf.acp.group.copy.copyACLOptions.description': '{lang}wcf.acp.group.copy.copyACLOptions.description{/lang}',
-                               'wcf.acp.group.copy.copyMembers': '{lang}wcf.acp.group.copy.copyMembers{/lang}',
-                               'wcf.acp.group.copy.copyMembers.description': '{lang}wcf.acp.group.copy.copyMembers.description{/lang}',
-                               'wcf.acp.group.copy.copyUserGroupOptions': '{lang}wcf.acp.group.copy.copyUserGroupOptions{/lang}',
-                               'wcf.acp.group.copy.copyUserGroupOptions.description': '{lang}wcf.acp.group.copy.copyUserGroupOptions.description{/lang}'
+                               'wcf.acp.group.copy.confirmMessage': '{jslang}wcf.acp.group.copy.confirmMessage{/jslang}',
+                               'wcf.acp.group.copy.copyACLOptions': '{jslang}wcf.acp.group.copy.copyACLOptions{/jslang}',
+                               'wcf.acp.group.copy.copyACLOptions.description': '{jslang}wcf.acp.group.copy.copyACLOptions.description{/jslang}',
+                               'wcf.acp.group.copy.copyMembers': '{jslang}wcf.acp.group.copy.copyMembers{/jslang}',
+                               'wcf.acp.group.copy.copyMembers.description': '{jslang}wcf.acp.group.copy.copyMembers.description{/jslang}',
+                               'wcf.acp.group.copy.copyUserGroupOptions': '{jslang}wcf.acp.group.copy.copyUserGroupOptions{/jslang}',
+                               'wcf.acp.group.copy.copyUserGroupOptions.description': '{jslang}wcf.acp.group.copy.copyUserGroupOptions.description{/jslang}'
                        });
                        
                        new WCF.ACP.User.Group.Copy({@$groupID});
@@ -53,7 +53,7 @@
                                        </li>
                                {/if}
                                
-                               {if $__wcf->session->getPermission('admin.user.canAddGroup') && $group->groupType == 4}
+                               {if $group->canCopy()}
                                        <li><a class="jsButtonUserGroupCopy button"><span class="icon icon16 fa-copy"></span> <span>{lang}wcf.acp.group.button.copy{/lang}</span></a></li>
                                {/if}
                        {/if}
@@ -65,8 +65,6 @@
        </nav>
 </header>
 
-{include file='formError'}
-
 {if VISITOR_USE_TINY_BUILD && $groupIsGuest}
        <p class="warning">{lang}wcf.acp.group.excludedInTinyBuild.notice{/lang}</p>
 {/if}
@@ -79,9 +77,7 @@
        <p class="warning">{lang}wcf.acp.group.edit.warning.selfIsMember{/lang}</p>
 {/if}
 
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{@$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='UserGroupAdd'}{/link}{else}{link controller='UserGroupEdit' id=$groupID}{/link}{/if}">
        <div class="section">
index fe1221ee474d311935d27befe0de8ed02d21e769..920154e47d482c477a645f2558758e843c8c0683 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{@$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='UserGroupAssignmentAdd'}{/link}{else}{link controller='UserGroupAssignmentEdit' object=$assignment}{/link}{/if}">
        <div class="section">
index 3bb963690fa36d6311f6566f94a509a5f2ceb7f1..e8a6d4e577bc45822751bc6b1c7620ec5b817b5e 100644 (file)
@@ -12,7 +12,7 @@
                                options.updatePageNumber = -1;
                        {/if}
                {else}
-                       options.emptyMessage = '{lang}wcf.global.noItems{/lang}';
+                       options.emptyMessage = '{jslang}wcf.global.noItems{/jslang}';
                {/if}
                
                new WCF.Table.EmptyTableHandler($('#userGroupAssignmentTableContainer'), 'jsUserGroupAssignmentRow', options);
index ed812f2703973bbce2246fda3ab8e13d33c73332..c9836f053c8529a5dc2d22885fd967e0078a1918 100644 (file)
                new WCF.Table.EmptyTableHandler($('#userTableContainer'), 'jsUserRow', options);
                
                WCF.Language.addObject({
-                       'wcf.acp.user.banReason': '{lang}wcf.acp.user.banReason{/lang}',
-                       'wcf.acp.user.banReason.description': '{lang}wcf.acp.user.banReason.description{/lang}',
-                       'wcf.acp.user.ban.sure': '{lang}wcf.acp.user.ban.sure{/lang}',
-                       'wcf.acp.user.ban.expires': '{lang}wcf.acp.user.ban.expires{/lang}',
-                       'wcf.acp.user.ban.expires.description': '{lang}wcf.acp.user.ban.expires.description{/lang}',
-                       'wcf.acp.user.ban.neverExpires': '{lang}wcf.acp.user.ban.neverExpires{/lang}',
-                       'wcf.acp.user.sendNewPassword.workerTitle': '{lang}wcf.acp.user.sendNewPassword.workerTitle{/lang}',
-                       'wcf.acp.worker.abort.confirmMessage': '{lang}wcf.acp.worker.abort.confirmMessage{/lang}',
-                       'wcf.acp.content.removeContent': '{lang}wcf.acp.content.removeContent{/lang}',
-                       'wcf.user.status.banned': '{lang}wcf.user.status.banned{/lang}',
-                       'wcf.user.status.isDisabled': '{lang}wcf.user.status.isDisabled{/lang}'
+                       'wcf.acp.user.banReason': '{jslang}wcf.acp.user.banReason{/jslang}',
+                       'wcf.acp.user.banReason.description': '{jslang}wcf.acp.user.banReason.description{/jslang}',
+                       'wcf.acp.user.ban.sure': '{jslang}wcf.acp.user.ban.sure{/jslang}',
+                       'wcf.acp.user.ban.expires': '{jslang}wcf.acp.user.ban.expires{/jslang}',
+                       'wcf.acp.user.ban.expires.description': '{jslang}wcf.acp.user.ban.expires.description{/jslang}',
+                       'wcf.acp.user.ban.neverExpires': '{jslang}wcf.acp.user.ban.neverExpires{/jslang}',
+                       'wcf.acp.user.sendNewPassword.workerTitle': '{jslang}wcf.acp.user.sendNewPassword.workerTitle{/jslang}',
+                       'wcf.acp.worker.abort.confirmMessage': '{jslang}wcf.acp.worker.abort.confirmMessage{/jslang}',
+                       'wcf.acp.content.removeContent': '{jslang}wcf.acp.content.removeContent{/jslang}',
+                       'wcf.user.status.banned': '{jslang}wcf.user.status.banned{/jslang}',
+                       'wcf.user.status.isDisabled': '{jslang}wcf.user.status.isDisabled{/jslang}'
                });
                WCF.ACP.User.BanHandler.init();
                
@@ -47,7 +47,7 @@
                
                require(['Language', 'WoltLabSuite/Core/Acp/Ui/User/Editor'], function (Language, AcpUiUserList) {
                        Language.addObject({
-                               'wcf.acp.user.action.sendNewPassword.confirmMessage': '{lang}wcf.acp.user.action.sendNewPassword.confirmMessage{/lang}'
+                               'wcf.acp.user.action.sendNewPassword.confirmMessage': '{jslang}wcf.acp.user.action.sendNewPassword.confirmMessage{/jslang}'
                        });
                        
                        AcpUiUserList.init();
                        
                        <tbody>
                                {foreach from=$users item=user}
-                                       <tr class="jsUserRow jsClipboardObject" data-object-id="{@$user->userID}" data-banned="{if $user->banned}true{else}false{/if}" data-enabled="{if !$user->activationCode}true{else}false{/if}">
+                                       <tr class="jsUserRow jsClipboardObject" data-object-id="{@$user->userID}" data-banned="{if $user->banned}true{else}false{/if}" data-enabled="{if !$user->activationCode}true{else}false{/if}" data-email-confirmed="{if $user->isEmailConfirmed()}true{else}false{/if}">
                                                <td class="columnMark"><input type="checkbox" class="jsClipboardItem" data-object-id="{@$user->userID}"></td>
                                                <td class="columnIcon">
                                                        <div class="dropdown" id="userListDropdown{@$user->userID}">
                                                                        {event name='dropdownItems'}
                                                                        
                                                                        {if $user->userID !== $__wcf->user->userID}
+                                                                               {if $user->accessible && $__wcf->session->getPermission('admin.user.canEnableUser')}
+                                                                                       <li><a href="#" class="jsConfirmEmailToggle" data-confirm-email-message="{lang}wcf.acp.user.action.confirmEmail{/lang}" data-unconfirm-email-message="{lang}wcf.acp.user.action.unconfirmEmail{/lang}">{lang}wcf.acp.user.action.{if $user->isEmailConfirmed()}un{/if}confirmEmail{/lang}</a></li>
+                                                                               {/if}
+                                                                               
                                                                                {if $__wcf->session->getPermission('admin.user.canMailUser')}
                                                                                        <li><a href="{link controller='UserMail' id=$user->userID}{/link}">{lang}wcf.acp.user.action.sendMail{/lang}</a></li>
                                                                                {/if}
index b9caa76bcc05cc1f3d0eb535c5c2cdc268824a25..8cc0673d896d7a9ded22d269a40a5cf4bee81401 100644 (file)
@@ -11,7 +11,7 @@
 {if $mailID|isset}
        <script data-relocate="true">
                $(function() {
-                       WCF.Language.add('wcf.acp.worker.abort.confirmMessage', '{lang}wcf.acp.worker.abort.confirmMessage{/lang}');
+                       WCF.Language.add('wcf.acp.worker.abort.confirmMessage', '{jslang}wcf.acp.worker.abort.confirmMessage{/jslang}');
                        
                        new WCF.ACP.Worker('mail', 'wcf\\system\\worker\\MailWorker', '', {
                                mailID: {@$mailID}
index df8f6fcc1a749f03f9c998b4437b633da82bf3e8..30517b4aa1fac0261ea6adf39b39320e9d758adb 100644 (file)
 
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if !$availableCategories|empty}
        <form method="post" action="{if $action == 'add'}{link controller='UserOptionAdd'}{/link}{else}{link controller='UserOptionEdit' id=$optionID}{/link}{/if}">
index b2f81558c3b682774cbfe2946aa6652d0c18cc65..d1a5fdbcc8f1f66287924947c17083418c014bd1 100644 (file)
 
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='UserOptionCategoryAdd'}{/link}{else}{link controller='UserOptionCategoryEdit' id=$categoryID}{/link}{/if}">
        <div class="section">
index 7758939831ea3003aaa1bfff48ff004b885932a5..16aea12523028714e40aaea28f9ab263cdfd741c 100644 (file)
@@ -1,11 +1,27 @@
 {include file='header' pageTitle='wcf.acp.user.rank.'|concat:$action}
 
 <script data-relocate="true">
-       $(function() {
-               $('#customCssClassName').click(function() {
-                       $(this).parents('li').find('input[type=radio]').click();
+       (function() {
+               var previews = [];
+               elBySelAll('#labelList .jsRankPreview', undefined, function(preview) {
+                       previews.push(preview);
                });
-       });
+               
+               var input = elById('rankTitle');
+               function updatePreview() {
+                       var value = input.value.trim() || '{jslang}wcf.acp.user.rank.title{/jslang}';
+                       previews.forEach(function(preview) {
+                               preview.textContent = value;
+                       });
+               }
+               input.addEventListener('input', updatePreview, { passive: true });
+               
+               updatePreview();
+               
+               elById('customCssClassName').addEventListener('focus', function () {
+                       elBySel('.jsCustomCssClassName').checked = true;
+               });
+       })();
 </script>
 
 <header class="contentHeader">
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 <form method="post" action="{if $action == 'add'}{link controller='UserRankAdd'}{/link}{else}{link controller='UserRankEdit' id=$rankID}{/link}{/if}">
        <div class="section">
@@ -55,9 +67,9 @@
                                <ul id="labelList">
                                        {foreach from=$availableCssClassNames item=className}
                                                {if $className == 'custom'}
-                                                       <li class="labelCustomClass"><input type="radio" name="cssClassName" value="custom"{if $cssClassName == 'custom'} checked{/if}> <span><input type="text" id="customCssClassName" name="customCssClassName" value="{$customCssClassName}" class="long"></span></li>
+                                                       <li class="labelCustomClass"><input type="radio" name="cssClassName" class="jsCustomCssClassName" value="custom"{if $cssClassName == 'custom'} checked{/if}> <span><input type="text" id="customCssClassName" name="customCssClassName" value="{$customCssClassName}" class="long"></span></li>
                                                {else}
-                                                       <li><label><input type="radio" name="cssClassName" value="{$className}"{if $cssClassName == $className} checked{/if}> <span class="badge label{if $className != 'none'} {$className}{/if}">{lang}wcf.acp.user.rank.title{/lang}</span></label></li>
+                                                       <li><label><input type="radio" name="cssClassName" value="{$className}"{if $cssClassName == $className} checked{/if}> <span class="badge label{if $className != 'none'} {$className}{/if} jsRankPreview">{lang}wcf.acp.user.rank.title{/lang}</span></label></li>
                                                {/if}
                                        {/foreach}
                                </ul>
                                        <option value="0">{lang}wcf.global.noSelection{/lang}</option>
                                        <option value="1"{if $requiredGender == 1} selected{/if}>{lang}wcf.user.gender.male{/lang}</option>
                                        <option value="2"{if $requiredGender == 2} selected{/if}>{lang}wcf.user.gender.female{/lang}</option>
+                                       <option value="3"{if $requiredGender == 3} selected{/if}>{lang}wcf.user.gender.other{/lang}</option>
                                </select>
                                {if $errorField == 'requiredGender'}
                                        <small class="innerError">
index 0aa2d4765d40dc1fae18cd6a9315036e6f8e12b6..b50e287632fa6a08ca5d62bc3be108bab6b8d44e 100644 (file)
                                                <td class="columnTitle columnRankTitle"><a href="{link controller='UserRankEdit' id=$userRank->rankID}{/link}" title="{lang}wcf.acp.user.rank.edit{/lang}" class="badge label{if $userRank->cssClassName} {$userRank->cssClassName}{/if}">{$userRank->getTitle()}</a></td>
                                                <td class="columnText columnRankImage">{if $userRank->rankImage}{@$userRank->getImage()}{/if}</td>
                                                <td class="columnText columnGroupID">{$userRank->groupName|language}</td>
-                                               <td class="columnText columnRequiredGender">{if $userRank->requiredGender}{if $userRank->requiredGender == 1}{lang}wcf.user.gender.male{/lang}{else}{lang}wcf.user.gender.female{/lang}{/if}{/if}</td>
+                                               <td class="columnText columnRequiredGender">
+                                                       {if $userRank->requiredGender}
+                                                               {if $userRank->requiredGender == 1}
+                                                                       {lang}wcf.user.gender.male{/lang}
+                                                               {elseif $userRank->requiredGender == 2}
+                                                                       {lang}wcf.user.gender.female{/lang}
+                                                               {else}
+                                                                       {lang}wcf.user.gender.other{/lang}
+                                                               {/if}
+                                                       {/if}
+                                               </td>
                                                <td class="columnDigits columnRequiredPoints">{#$userRank->requiredPoints}</td>
                                                
                                                {event name='columns'}
index 68203e0ad965193868da2d534236ebc3097e8a8a..5a5a86733a08a6a1772651c72121f1cbe9d20a5a 100644 (file)
@@ -19,6 +19,7 @@
                                        <li><a href="{link controller='UserQuickSearch'}mode=banned{/link}">{lang}wcf.acp.user.quickSearch.banned{/lang}</a></li>
                                        <li><a href="{link controller='UserQuickSearch'}mode=newest{/link}">{lang}wcf.acp.user.quickSearch.newest{/lang}</a></li>
                                        <li><a href="{link controller='UserQuickSearch'}mode=disabled{/link}">{lang}wcf.acp.user.quickSearch.disabled{/lang}</a></li>
+                                       <li><a href="{link controller='UserQuickSearch'}mode=pendingActivation{/link}">{lang}wcf.acp.user.quickSearch.pendingActivation{/lang}</a></li>
                                        <li><a href="{link controller='UserQuickSearch'}mode=disabledAvatars{/link}">{lang}wcf.acp.user.quickSearch.disabledAvatars{/lang}</a></li>
                                        <li><a href="{link controller='UserQuickSearch'}mode=disabledSignatures{/link}">{lang}wcf.acp.user.quickSearch.disabledSignatures{/lang}</a></li>
                                        
index bf114a1a3745245445b4f69b062d42c397707005..769d0934161c62e720f6bfce04481cb45e49441e 100644 (file)
        </nav>
 </header>
 
-{include file='formError'}
-
-{if $success|isset}
-       <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
-{/if}
+{include file='formNotice'}
 
 {if $hasSuitableTrophy}
        <form method="post" action="{if $action == 'add'}{link controller='UserTrophyAdd'}{/link}{else}{link controller='UserTrophyEdit' id=$userTrophy->getObjectID()}{/link}{/if}">
index 9c4b1046495914b6807a38824ebaeb5419ca1af0..17c5ce2844058fd60397c44a86d0ee183795c416 100644 (file)
        ], function () {
                require(['Environment', 'Language', 'WoltLabSuite/Core/Ui/Redactor/Autosave', 'WoltLabSuite/Core/Ui/Redactor/Metacode'], function(Environment, Language, UiRedactorAutosave, UiRedactorMetacode) {
                        Language.addObject({
-                               'wcf.attachment.dragAndDrop.dropHere': '{lang}wcf.attachment.dragAndDrop.dropHere{/lang}',
-                               'wcf.attachment.dragAndDrop.dropNow': '{lang}wcf.attachment.dragAndDrop.dropNow{/lang}',
+                               'wcf.attachment.dragAndDrop.dropHere': '{jslang}wcf.attachment.dragAndDrop.dropHere{/jslang}',
+                               'wcf.attachment.dragAndDrop.dropNow': '{jslang}wcf.attachment.dragAndDrop.dropNow{/jslang}',
                                
-                               'wcf.editor.autosave.discard': '{lang}wcf.editor.autosave.discard{/lang}',
-                               'wcf.editor.autosave.keep': '{lang}wcf.editor.autosave.keep{/lang}',
-                               'wcf.editor.autosave.restored': '{lang}wcf.editor.autosave.restored{/lang}',
+                               'wcf.editor.autosave.discard': '{jslang}wcf.editor.autosave.discard{/jslang}',
+                               'wcf.editor.autosave.keep': '{jslang}wcf.editor.autosave.keep{/jslang}',
+                               'wcf.editor.autosave.restored': '{jslang}wcf.editor.autosave.restored{/jslang}',
                                
-                               'wcf.editor.code.edit': '{lang}wcf.editor.code.edit{/lang}',
-                               'wcf.editor.code.file': '{lang}wcf.editor.code.file{/lang}',
-                               'wcf.editor.code.file.description': '{lang}wcf.editor.code.file.description{/lang}',
-                               'wcf.editor.code.highlighter': '{lang}wcf.editor.code.highlighter{/lang}',
-                               'wcf.editor.code.highlighter.description': '{lang}wcf.editor.code.highlighter.description{/lang}',
-                               'wcf.editor.code.highlighter.detect': '{lang}wcf.editor.code.highlighter.detect{/lang}',
-                               'wcf.editor.code.highlighter.plain': '{lang}wcf.editor.code.highlighter.plain{/lang}',
-                               'wcf.editor.code.line': '{lang}wcf.editor.code.line{/lang}',
-                               'wcf.editor.code.line.description': '{lang}wcf.editor.code.line.description{/lang}',
-                               'wcf.editor.code.title': '{lang __literal=true}wcf.editor.code.title{/lang}',
+                               'wcf.editor.code.edit': '{jslang}wcf.editor.code.edit{/jslang}',
+                               'wcf.editor.code.file': '{jslang}wcf.editor.code.file{/jslang}',
+                               'wcf.editor.code.file.description': '{jslang}wcf.editor.code.file.description{/jslang}',
+                               'wcf.editor.code.highlighter': '{jslang}wcf.editor.code.highlighter{/jslang}',
+                               'wcf.editor.code.highlighter.description': '{jslang}wcf.editor.code.highlighter.description{/jslang}',
+                               'wcf.editor.code.highlighter.detect': '{jslang}wcf.editor.code.highlighter.detect{/jslang}',
+                               'wcf.editor.code.highlighter.plain': '{jslang}wcf.editor.code.highlighter.plain{/jslang}',
+                               'wcf.editor.code.line': '{jslang}wcf.editor.code.line{/jslang}',
+                               'wcf.editor.code.line.description': '{jslang}wcf.editor.code.line.description{/jslang}',
+                               'wcf.editor.code.title': '{jslang __literal=true}wcf.editor.code.title{/jslang}',
                                
-                               'wcf.editor.html.description': '{lang}wcf.editor.html.description{/lang}',
-                               'wcf.editor.html.title': '{lang}wcf.editor.html.title{/lang}',
+                               'wcf.editor.html.description': '{jslang}wcf.editor.html.description{/jslang}',
+                               'wcf.editor.html.title': '{jslang}wcf.editor.html.title{/jslang}',
                                
-                               'wcf.editor.image.edit': '{lang}wcf.editor.image.edit{/lang}',
-                               'wcf.editor.image.insert': '{lang}wcf.editor.image.insert{/lang}',
-                               'wcf.editor.image.link': '{lang}wcf.editor.image.link{/lang}',
-                               'wcf.editor.image.link.error.invalid': '{lang}wcf.editor.image.link.error.invalid{/lang}',
-                               'wcf.editor.image.float': '{lang}wcf.editor.image.float{/lang}',
-                               'wcf.editor.image.float.left': '{lang}wcf.editor.image.float.left{/lang}',
-                               'wcf.editor.image.float.right': '{lang}wcf.editor.image.float.right{/lang}',
-                               'wcf.editor.image.source': '{lang}wcf.editor.image.source{/lang}',
-                               'wcf.editor.image.source.error.blocked': '{lang}wcf.editor.image.source.error.blocked{/lang}',
-                               'wcf.editor.image.source.error.insecure': '{lang}wcf.editor.image.source.error.insecure{/lang}',
-                               'wcf.editor.image.source.error.invalid': '{lang}wcf.editor.image.source.error.invalid{/lang}',
+                               'wcf.editor.image.edit': '{jslang}wcf.editor.image.edit{/jslang}',
+                               'wcf.editor.image.insert': '{jslang}wcf.editor.image.insert{/jslang}',
+                               'wcf.editor.image.link': '{jslang}wcf.editor.image.link{/jslang}',
+                               'wcf.editor.image.link.error.invalid': '{jslang}wcf.editor.image.link.error.invalid{/jslang}',
+                               'wcf.editor.image.float': '{jslang}wcf.editor.image.float{/jslang}',
+                               'wcf.editor.image.float.left': '{jslang}wcf.editor.image.float.left{/jslang}',
+                               'wcf.editor.image.float.right': '{jslang}wcf.editor.image.float.right{/jslang}',
+                               'wcf.editor.image.source': '{jslang}wcf.editor.image.source{/jslang}',
+                               'wcf.editor.image.source.error.blocked': '{jslang}wcf.editor.image.source.error.blocked{/jslang}',
+                               'wcf.editor.image.source.error.insecure': '{jslang}wcf.editor.image.source.error.insecure{/jslang}',
+                               'wcf.editor.image.source.error.invalid': '{jslang}wcf.editor.image.source.error.invalid{/jslang}',
                                
-                               'wcf.editor.link.add': '{lang}wcf.editor.link.add{/lang}',
-                               'wcf.editor.link.edit': '{lang}wcf.editor.link.edit{/lang}',
-                               'wcf.editor.link.error.invalid': '{lang}wcf.editor.link.error.invalid{/lang}',
-                               'wcf.editor.link.url': '{lang}wcf.editor.link.url{/lang}',
-                               'wcf.editor.link.text': '{lang}wcf.editor.link.text{/lang}',
+                               'wcf.editor.link.add': '{jslang}wcf.editor.link.add{/jslang}',
+                               'wcf.editor.link.edit': '{jslang}wcf.editor.link.edit{/jslang}',
+                               'wcf.editor.link.error.invalid': '{jslang}wcf.editor.link.error.invalid{/jslang}',
+                               'wcf.editor.link.url': '{jslang}wcf.editor.link.url{/jslang}',
+                               'wcf.editor.link.text': '{jslang}wcf.editor.link.text{/jslang}',
                                
-                               'wcf.editor.list.indent': '{lang}wcf.editor.list.indent{/lang}',
-                               'wcf.editor.list.outdent': '{lang}wcf.editor.list.outdent{/lang}',
+                               'wcf.editor.list.indent': '{jslang}wcf.editor.list.indent{/jslang}',
+                               'wcf.editor.list.outdent': '{jslang}wcf.editor.list.outdent{/jslang}',
                                
-                               'wcf.editor.quote.author': '{lang}wcf.editor.quote.author{/lang}',
-                               'wcf.editor.quote.edit': '{lang}wcf.editor.quote.edit{/lang}',
-                               'wcf.editor.quote.title': '{lang __literal=true}wcf.editor.quote.title{/lang}',
-                               'wcf.editor.quote.url': '{lang}wcf.editor.quote.url{/lang}',
-                               'wcf.editor.quote.url.description': '{lang}wcf.editor.quote.url.description{/lang}',
-                               'wcf.editor.quote.url.error.invalid': '{lang}wcf.editor.quote.url.error.invalid{/lang}',
+                               'wcf.editor.quote.author': '{jslang}wcf.editor.quote.author{/jslang}',
+                               'wcf.editor.quote.edit': '{jslang}wcf.editor.quote.edit{/jslang}',
+                               'wcf.editor.quote.title': '{jslang __literal=true}wcf.editor.quote.title{/jslang}',
+                               'wcf.editor.quote.url': '{jslang}wcf.editor.quote.url{/jslang}',
+                               'wcf.editor.quote.url.description': '{jslang}wcf.editor.quote.url.description{/jslang}',
+                               'wcf.editor.quote.url.error.invalid': '{jslang}wcf.editor.quote.url.error.invalid{/jslang}',
                                
-                               'wcf.editor.table.cols': '{lang}wcf.editor.table.cols{/lang}',
-                               'wcf.editor.table.insertTable': '{lang}wcf.editor.table.insertTable{/lang}',
-                               'wcf.editor.table.rows': '{lang}wcf.editor.table.rows{/lang}',
+                               'wcf.editor.table.cols': '{jslang}wcf.editor.table.cols{/jslang}',
+                               'wcf.editor.table.insertTable': '{jslang}wcf.editor.table.insertTable{/jslang}',
+                               'wcf.editor.table.rows': '{jslang}wcf.editor.table.rows{/jslang}',
                                
-                               'wcf.editor.source.error.active': '{lang}wcf.editor.source.error.active{/lang}',
+                               'wcf.editor.source.error.active': '{jslang}wcf.editor.source.error.active{/jslang}',
                                
-                               'wcf.editor.spoiler.label': '{lang}wcf.editor.spoiler.label{/lang}',
-                               'wcf.editor.spoiler.label.description': '{lang}wcf.editor.spoiler.label.description{/lang}',
-                               'wcf.editor.spoiler.edit': '{lang}wcf.editor.spoiler.edit{/lang}',
-                               'wcf.editor.spoiler.title': '{lang __literal=true}wcf.editor.spoiler.title{/lang}'
+                               'wcf.editor.spoiler.label': '{jslang}wcf.editor.spoiler.label{/jslang}',
+                               'wcf.editor.spoiler.label.description': '{jslang}wcf.editor.spoiler.label.description{/jslang}',
+                               'wcf.editor.spoiler.edit': '{jslang}wcf.editor.spoiler.edit{/jslang}',
+                               'wcf.editor.spoiler.title': '{jslang __literal=true}wcf.editor.spoiler.title{/jslang}'
                        });
                        
                        var allowedInlineStyles = [], buttons = [], buttonMobile = [], buttonOptions = [], customButtons = [];
                        var config = {
                                buttons: buttons,
                                clipboardImageUpload: {if $__wcf->getBBCodeHandler()->isAvailableBBCode('attach')}true{else}false{/if},
-                               direction: '{lang}wcf.global.pageDirection{/lang}',
+                               direction: '{jslang}wcf.global.pageDirection{/jslang}',
                                formatting: ['p', 'h2', 'h3', 'h4'],
                                imageCaption: false,
                                imageUpload: {if $__wcf->getBBCodeHandler()->isAvailableBBCode('attach')}true{else}false{/if},
                                langs: {
                                        wsc: {
                                                // general
-                                               edit: '{lang}wcf.global.button.edit{/lang}',
+                                               edit: '{jslang}wcf.global.button.edit{/jslang}',
                                                
                                                // formatting dropdown
-                                               heading2: '{lang}wcf.editor.format.heading2{/lang}',
-                                               heading3: '{lang}wcf.editor.format.heading3{/lang}',
-                                               heading4: '{lang}wcf.editor.format.heading4{/lang}',
-                                               paragraph: '{lang}wcf.editor.format.paragraph{/lang}',
+                                               heading2: '{jslang}wcf.editor.format.heading2{/jslang}',
+                                               heading3: '{jslang}wcf.editor.format.heading3{/jslang}',
+                                               heading4: '{jslang}wcf.editor.format.heading4{/jslang}',
+                                               paragraph: '{jslang}wcf.editor.format.paragraph{/jslang}',
                                                
                                                // links
-                                               'link-edit': '{lang}wcf.editor.link.edit{/lang}',
-                                               'link-insert': '{lang}wcf.editor.link.add{/lang}',
-                                               unlink: '{lang}wcf.editor.link.unlink{/lang}',
+                                               'link-edit': '{jslang}wcf.editor.link.edit{/jslang}',
+                                               'link-insert': '{jslang}wcf.editor.link.add{/jslang}',
+                                               unlink: '{jslang}wcf.editor.link.unlink{/jslang}',
                                                
                                                // text alignment
-                                               'align-center': '{lang}wcf.editor.alignment.center{/lang}',
-                                               'align-justify': '{lang}wcf.editor.alignment.justify{/lang}',
-                                               'align-left': '{lang}wcf.editor.alignment.left{/lang}',
-                                               'align-right': '{lang}wcf.editor.alignment.right{/lang}',
+                                               'align-center': '{jslang}wcf.editor.alignment.center{/jslang}',
+                                               'align-justify': '{jslang}wcf.editor.alignment.justify{/jslang}',
+                                               'align-left': '{jslang}wcf.editor.alignment.left{/jslang}',
+                                               'align-right': '{jslang}wcf.editor.alignment.right{/jslang}',
                                                
                                                // table plugin
-                                               'add-head': '{lang}wcf.editor.table.addHead{/lang}',
-                                               'delete-column': '{lang}wcf.editor.table.deleteColumn{/lang}',
-                                               'delete-head': '{lang}wcf.editor.table.deleteHead{/lang}',
-                                               'delete-row': '{lang}wcf.editor.table.deleteRow{/lang}',
-                                               'delete-table': '{lang}wcf.editor.table.deleteTable{/lang}',
-                                               'insert-table': '{lang}wcf.editor.table.insertTable{/lang}',
-                                               'insert-column-left': '{lang}wcf.editor.table.insertColumnLeft{/lang}',
-                                               'insert-column-right': '{lang}wcf.editor.table.insertColumnRight{/lang}',
-                                               'insert-row-above': '{lang}wcf.editor.table.insertRowAbove{/lang}',
-                                               'insert-row-below': '{lang}wcf.editor.table.insertRowBelow{/lang}',
+                                               'add-head': '{jslang}wcf.editor.table.addHead{/jslang}',
+                                               'delete-column': '{jslang}wcf.editor.table.deleteColumn{/jslang}',
+                                               'delete-head': '{jslang}wcf.editor.table.deleteHead{/jslang}',
+                                               'delete-row': '{jslang}wcf.editor.table.deleteRow{/jslang}',
+                                               'delete-table': '{jslang}wcf.editor.table.deleteTable{/jslang}',
+                                               'insert-table': '{jslang}wcf.editor.table.insertTable{/jslang}',
+                                               'insert-column-left': '{jslang}wcf.editor.table.insertColumnLeft{/jslang}',
+                                               'insert-column-right': '{jslang}wcf.editor.table.insertColumnRight{/jslang}',
+                                               'insert-row-above': '{jslang}wcf.editor.table.insertRowAbove{/jslang}',
+                                               'insert-row-below': '{jslang}wcf.editor.table.insertRowBelow{/jslang}',
                                                
                                                // size
-                                               'remove-size': '{lang}wcf.editor.button.size.removeSize{/lang}',
+                                               'remove-size': '{jslang}wcf.editor.button.size.removeSize{/jslang}',
                                                
                                                // color
-                                               'remove-color': '{lang}wcf.editor.button.color.removeColor{/lang}',
+                                               'remove-color': '{jslang}wcf.editor.button.color.removeColor{/jslang}',
                                                
                                                // font
-                                               'remove-font': '{lang}wcf.editor.button.font.removeFont{/lang}'
+                                               'remove-font': '{jslang}wcf.editor.button.font.removeFont{/jslang}'
                                        }
                                },
                                linkify: false,
index 155af844e2d4b833ee13b695980cd5af905ef747..f06eb7348d77367177865e2275218be50c1e4292 100644 (file)
@@ -1,25 +1,25 @@
 buttonOptions = {
-       alignment: { icon: 'fa-align-left', title: '{lang}wcf.editor.button.alignment{/lang}' },
-       bold: { icon: 'fa-bold', title: '{lang}wcf.editor.button.bold{/lang}' },
-       deleted: { icon: 'fa-strikethrough', title: '{lang}wcf.editor.button.strikethrough{/lang}' },
-       format: { icon: 'fa-header', title: '{lang}wcf.editor.button.format{/lang}' },
-       html: { icon: 'fa-file-code-o', title: '{lang}wcf.editor.button.html{/lang}' },
-       italic: { icon: 'fa-italic', title: '{lang}wcf.editor.button.italic{/lang}' },
-       link: { icon: 'fa-link', title: '{lang}wcf.editor.button.link{/lang}' },
-       lists: { icon: 'fa-list', title: '{lang}wcf.editor.button.lists{/lang}' },
-       redo: { icon: 'fa-repeat', title: '{lang}wcf.editor.button.redo{/lang}' },
-       subscript: { icon: 'fa-subscript', title: '{lang}wcf.editor.button.subscript{/lang}' },
-       superscript: { icon: 'fa-superscript', title: '{lang}wcf.editor.button.superscript{/lang}' },
-       table: { icon: 'fa-table', title: '{lang}wcf.editor.button.table{/lang}' },
-       underline: { icon: 'fa-underline', title: '{lang}wcf.editor.button.underline{/lang}' },
-       undo: { icon: 'fa-undo', title: '{lang}wcf.editor.button.undo{/lang}' },
-       woltlabColor: { icon: 'fa-paint-brush', title: '{lang}wcf.editor.button.color{/lang}' },
-       woltlabFont: { icon: 'fa-font', title: '{lang}wcf.editor.button.font{/lang}' },
-       woltlabFullscreen: { icon: 'fa-expand', title: '{lang}wcf.editor.button.fullscreen{/lang}' },
-       woltlabImage: { icon: 'fa-picture-o', title: '{lang}wcf.editor.button.image{/lang}' },
-       woltlabMedia: { icon: 'fa-file-o', title: '{lang}wcf.editor.button.media{/lang}' },
-       woltlabQuote: { icon: 'fa-comment', title: '{lang}wcf.editor.button.quote{/lang}' },
-       woltlabSize: { icon: 'fa-text-height', title: '{lang}wcf.editor.button.size{/lang}' }
+       alignment: { icon: 'fa-align-left', title: '{jslang}wcf.editor.button.alignment{/jslang}' },
+       bold: { icon: 'fa-bold', title: '{jslang}wcf.editor.button.bold{/jslang}' },
+       deleted: { icon: 'fa-strikethrough', title: '{jslang}wcf.editor.button.strikethrough{/jslang}' },
+       format: { icon: 'fa-header', title: '{jslang}wcf.editor.button.format{/jslang}' },
+       html: { icon: 'fa-file-code-o', title: '{jslang}wcf.editor.button.html{/jslang}' },
+       italic: { icon: 'fa-italic', title: '{jslang}wcf.editor.button.italic{/jslang}' },
+       link: { icon: 'fa-link', title: '{jslang}wcf.editor.button.link{/jslang}' },
+       lists: { icon: 'fa-list', title: '{jslang}wcf.editor.button.lists{/jslang}' },
+       redo: { icon: 'fa-repeat', title: '{jslang}wcf.editor.button.redo{/jslang}' },
+       subscript: { icon: 'fa-subscript', title: '{jslang}wcf.editor.button.subscript{/jslang}' },
+       superscript: { icon: 'fa-superscript', title: '{jslang}wcf.editor.button.superscript{/jslang}' },
+       table: { icon: 'fa-table', title: '{jslang}wcf.editor.button.table{/jslang}' },
+       underline: { icon: 'fa-underline', title: '{jslang}wcf.editor.button.underline{/jslang}' },
+       undo: { icon: 'fa-undo', title: '{jslang}wcf.editor.button.undo{/jslang}' },
+       woltlabColor: { icon: 'fa-paint-brush', title: '{jslang}wcf.editor.button.color{/jslang}' },
+       woltlabFont: { icon: 'fa-font', title: '{jslang}wcf.editor.button.font{/jslang}' },
+       woltlabFullscreen: { icon: 'fa-expand', title: '{jslang}wcf.editor.button.fullscreen{/jslang}' },
+       woltlabImage: { icon: 'fa-picture-o', title: '{jslang}wcf.editor.button.image{/jslang}' },
+       woltlabMedia: { icon: 'fa-file-o', title: '{jslang}wcf.editor.button.media{/jslang}' },
+       woltlabQuote: { icon: 'fa-comment', title: '{jslang}wcf.editor.button.quote{/jslang}' },
+       woltlabSize: { icon: 'fa-text-height', title: '{jslang}wcf.editor.button.size{/jslang}' }
 };
 
 buttonMobile = ['format', 'bold', 'italic', 'underline', 'lists', 'link', 'woltlabImage'];
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2.php
deleted file mode 100644 (file)
index d346c96..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-<?php
-use wcf\system\database\table\column\BinaryDatabaseTableColumn;
-use wcf\system\database\table\column\CharDatabaseTableColumn;
-use wcf\system\database\table\column\DateDatabaseTableColumn;
-use wcf\system\database\table\column\DatetimeDatabaseTableColumn;
-use wcf\system\database\table\column\DefaultFalseBooleanDatabaseTableColumn;
-use wcf\system\database\table\column\DefaultTrueBooleanDatabaseTableColumn;
-use wcf\system\database\table\column\EnumDatabaseTableColumn;
-use wcf\system\database\table\column\IntDatabaseTableColumn;
-use wcf\system\database\table\column\MediumtextDatabaseTableColumn;
-use wcf\system\database\table\column\NotNullInt10DatabaseTableColumn;
-use wcf\system\database\table\column\NotNullVarchar255DatabaseTableColumn;
-use wcf\system\database\table\column\ObjectIdDatabaseTableColumn;
-use wcf\system\database\table\column\SmallintDatabaseTableColumn;
-use wcf\system\database\table\column\TextDatabaseTableColumn;
-use wcf\system\database\table\DatabaseTable;
-use wcf\system\database\table\DatabaseTableChangeProcessor;
-use wcf\system\database\table\index\DatabaseTableForeignKey;
-use wcf\system\database\table\index\DatabaseTableIndex;
-use wcf\system\database\table\index\DatabaseTablePrimaryIndex;
-use wcf\system\package\plugin\ScriptPackageInstallationPlugin;
-use wcf\system\WCF;
-
-/**
- * Updates the database table layout from WoltLab Suite Core 3.1 to 5.2.
- * 
- * TODO: untested, potentially incomplete
- *
- * @author     Matthias Schmidt
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- */
-
-$tables = [
-       DatabaseTable::create('wcf1_bbcode_media_provider')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('isDisabled')
-               ]),
-       
-       DatabaseTable::create('wcf1_blacklist_status')
-               ->columns([
-                       DateDatabaseTableColumn::create('date')
-                               ->notNull(),
-                       DefaultFalseBooleanDatabaseTableColumn::create('delta1'),
-                       DefaultFalseBooleanDatabaseTableColumn::create('delta2'),
-                       DefaultFalseBooleanDatabaseTableColumn::create('delta3'),
-                       DefaultFalseBooleanDatabaseTableColumn::create('delta4')
-               ])
-               ->indices([
-                       DatabaseTableIndex::create('day')
-                               ->type(DatabaseTableIndex::UNIQUE_TYPE)
-                               ->columns(['date']),
-               ]),
-       
-       DatabaseTable::create('wcf1_blacklist_entry')
-               ->columns([
-                       EnumDatabaseTableColumn::create('type')
-                               ->enumValues(['email', 'ipv4', 'ipv6','username']),
-                       BinaryDatabaseTableColumn::create('hash')
-                               ->length(32),
-                       DatetimeDatabaseTableColumn::create('lastSeen')
-                               ->notNull(),
-                       SmallintDatabaseTableColumn::create('occurrences')
-                               ->length(5)
-                               ->notNull()
-               ])
-               ->indices([
-                       DatabaseTableIndex::create('entry')
-                               ->type(DatabaseTableIndex::UNIQUE_TYPE)
-                               ->columns(['type', 'hash']),
-                       DatabaseTableIndex::create('numberOfReports')
-                               ->columns(['type', 'occurrences'])
-               ]),
-       
-       DatabaseTable::create('wcf1_box')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('isDisabled')
-               ]),
-       
-       DatabaseTable::create('wcf1_category')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('descriptionUseHtml')
-               ]),
-       
-       DatabaseTable::create('wcf1_comment')
-               ->columns([
-                       MediumtextDatabaseTableColumn::create('message')
-                               ->notNull()
-               ]),
-       
-       DatabaseTable::create('wcf1_comment_response')
-               ->columns([
-                       MediumtextDatabaseTableColumn::create('message')
-                               ->notNull()
-               ]),
-       
-       DatabaseTable::create('wcf1_contact_attachment')
-               ->columns([
-                       NotNullInt10DatabaseTableColumn::create('attachmentID'),
-                       CharDatabaseTableColumn::create('accessKey')
-                               ->length(40)
-                               ->notNull()
-               ])
-               ->foreignKeys([
-                       DatabaseTableForeignKey::create()
-                               ->columns(['attachmentID'])
-                               ->referencedTable('wcf1_attachment')
-                               ->referencedColumns(['attachmentID'])
-                               ->onDelete('CASCADE')
-               ]),
-       
-       DatabaseTable::create('wcf1_language_item')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('isCustomLanguageItem')
-               ]),
-       
-       DatabaseTable::create('wcf1_like')
-               ->columns([
-                       NotNullInt10DatabaseTableColumn::create('reactionTypeID')
-               ]),
-       
-       DatabaseTable::create('wcf1_like_object')
-               ->columns([
-                       TextDatabaseTableColumn::create('cachedReactions')
-               ]),
-       
-       DatabaseTable::create('wcf1_media')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('captionEnableHtml'),
-                       NotNullInt10DatabaseTableColumn::create('downloads')
-                               ->defaultValue(0),
-                       NotNullInt10DatabaseTableColumn::create('lastDownloadTime')
-                               ->defaultValue(0)
-               ]),
-       
-       DatabaseTable::create('wcf1_page')
-               ->columns([
-                       IntDatabaseTableColumn::create('overrideApplicationPackageID')
-                               ->length(10),
-                       DefaultFalseBooleanDatabaseTableColumn::create('enableShareButtons')
-               ])
-               ->foreignKeys([
-                       DatabaseTableForeignKey::create()
-                               ->columns(['overrideApplicationPackageID'])
-                               ->referencedTable('wcf1_package')
-                               ->referencedColumns(['packageID'])
-                               ->onDelete('SET NULL')
-               ]),
-       
-       DatabaseTable::create('wcf1_package')
-               ->indices([
-                       DatabaseTableIndex::create('package')
-                               ->type(DatabaseTableIndex::UNIQUE_TYPE)
-                               ->columns(['package'])
-               ]),
-       
-       DatabaseTable::create('wcf1_reaction_type')
-               ->columns([
-                       ObjectIdDatabaseTableColumn::create('reactionTypeID'),
-                       NotNullVarchar255DatabaseTableColumn::create('title'),
-                       NotNullInt10DatabaseTableColumn::create('showOrder')
-                               ->defaultValue(0),
-                       NotNullVarchar255DatabaseTableColumn::create('iconFile')
-                               ->defaultValue(''),
-                       DefaultTrueBooleanDatabaseTableColumn::create('isAssignable')
-               ])
-               ->indices([
-                       DatabaseTablePrimaryIndex::create()
-                               ->columns(['reactionTypeID'])
-               ]),
-       
-       DatabaseTable::create('wcf1_style')
-               ->columns([
-                       EnumDatabaseTableColumn::create('apiVersion')
-                               ->notNull()
-                               ->enumValues(['3.0', '3.1', '5.2'])
-                               ->defaultValue('3.0')
-               ]),
-       
-       DatabaseTable::create('wcf1_trophy')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('revokeAutomatically'),
-                       DefaultFalseBooleanDatabaseTableColumn::create('trophyUseHtml'),
-                       NotNullInt10DatabaseTableColumn::create('showOrder')
-                               ->defaultValue(0)
-               ]),
-       
-       DatabaseTable::create('wcf1_user')
-               ->columns([
-                       NotNullInt10DatabaseTableColumn::create('articles')
-                               ->defaultValue(0),
-                       NotNullVarchar255DatabaseTableColumn::create('blacklistMatches')
-                               ->defaultValue('')
-               ]),
-       
-       DatabaseTable::create('wcf1_user_group')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('allowMention')
-               ]),
-       
-       DatabaseTable::create('wcf1_user_trophy')
-               ->columns([
-                       DefaultFalseBooleanDatabaseTableColumn::create('trophyUseHtml')
-               ]),
-];
-
-(new DatabaseTableChangeProcessor(
-       /** @var ScriptPackageInstallationPlugin $this */
-       $this->installation->getPackage(),
-       $tables,
-       WCF::getDB()->getEditor())
-)->process();
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_deleteRecentActivity.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_deleteRecentActivity.php
deleted file mode 100644 (file)
index 6cca64c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
- * This script deletes all recent activity events for likes. Running this script is necessary after an update to version 5.2,
- * because with this version the reaction system was introduced and the events there were changed so that they contain the
- * reaction type, which is not present in previous fired events. Older events will otherwise throw an error.
- *
- * @author     Joshua Ruesweg
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core
- */
-
-$definitionList = new \wcf\data\object\type\definition\ObjectTypeDefinitionList();
-$definitionList->getConditionBuilder()->add('definitionName = ?', ['com.woltlab.wcf.user.recentActivityEvent']);
-$definitionList->readObjects();
-$definition = $definitionList->current();
-
-$sql = "SELECT  objectTypeID
-       FROM    wcf". WCF_N ."_object_type
-       WHERE   objectType LIKE '%likeable%'
-       AND     definitionID = ?";
-$statement = \wcf\system\WCF::getDB()->prepareStatement($sql);
-$statement->execute([$definition->definitionID]);
-$objectTypeIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
-
-$conditionBuilder = new \wcf\system\database\util\PreparedStatementConditionBuilder();
-$conditionBuilder->add('objectTypeID IN (?)', [$objectTypeIDs]);
-
-$sql = "DELETE FROM wcf". WCF_N ."_user_activity_event ".$conditionBuilder;
-$statement = \wcf\system\WCF::getDB()->prepareStatement($sql);
-$statement->execute($conditionBuilder->getParameters());
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_prePhpApi.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_prePhpApi.php
deleted file mode 100644 (file)
index 1f9df9d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-use wcf\system\WCF;
-
-// This script ensures that an upgrade that failed during the SQL changes can be repeated without requiring a rollback.
-
-$dbEditor = WCF::getDB()->getEditor();
-$existingColumns = $dbEditor->getColumns('wcf'.WCF_N.'_package_installation_sql_log');
-$hasIsDoneColumn = false;
-foreach ($existingColumns as $column) {
-       if ($column['name'] === 'isDone') {
-               $hasIsDoneColumn = true;
-               break;
-       }
-}
-
-if (!$hasIsDoneColumn) {
-       $dbEditor->addColumn('wcf'.WCF_N.'_package_installation_sql_log', 'isDone', [
-               'type' => 'tinyint',
-               'length' => 1,
-               'notNull' => 1,
-               'default' => 1,
-       ]);
-}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_preUpdate.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_preUpdate.php
deleted file mode 100644 (file)
index 956fb80..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-use wcf\data\package\Package;
-use wcf\system\exception\SystemException;
-use wcf\system\WCF;
-
-/**
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core
- */
-if (Package::compareVersion(WCF_VERSION, '3.1.11', '<')) {
-       if (WCF::getLanguage()->getFixedLanguageCode() == 'de') {
-               throw new SystemException("Die Aktualisierung erfordert WoltLab Suite Core (com.woltlab.wcf) in Version 3.1.11 oder höher.");
-       }
-       else {
-               throw new SystemException("The update requires WoltLab Suite Core (com.woltlab.wcf) in version 3.1.11 or newer.");
-       }
-}
-
-$requiredPHPVersion = '7.0.22';
-$comparePhpVersion = preg_replace('/^(\d+\.\d+\.\d+).*$/', '\\1', phpversion());
-if (version_compare($comparePhpVersion, $requiredPHPVersion) === -1) {
-       if (WCF::getLanguage()->getFixedLanguageCode() == 'de') {
-               throw new SystemException("Die Aktualisierung erfordert PHP in Version {$requiredPHPVersion} oder höher.");
-       }
-       else {
-               throw new SystemException("The update requires PHP in version {$requiredPHPVersion} or newer.");
-       }
-}
-
-// check sql version
-$sqlVersion = WCF::getDB()->getVersion();
-$compareSQLVersion = preg_replace('/^(\d+\.\d+\.\d+).*$/', '\\1', $sqlVersion);
-if (stripos($sqlVersion, 'MariaDB') === false) {
-       // For MySQL 8.0, MySQL 8.0.14+ is required
-       // https://bugs.mysql.com/bug.php?id=88718
-       if ($compareSQLVersion[0] === '8') {
-               // MySQL 8.0.14+
-               if (!(version_compare($compareSQLVersion, '8.0.14') >= 0)) {
-                       if (WCF::getLanguage()->getFixedLanguageCode() == 'de') {
-                               throw new SystemException("Ihre eingesetzte Version von MySQL 8 enthält einen bekannten Fehler und verhindert eine Aktualisierung, es wird mindestens MySQL 8.0.14 oder höher benötigt.");
-                       }
-                       else {
-                               throw new SystemException("The version of MySQL 8 that you are using contains a known bug that prevents an upgrade, MySQL 8.0.14 or newer is required.");
-                       }
-               }
-       }
-}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_reactionUpdate.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_reactionUpdate.php
deleted file mode 100644 (file)
index 4c43385..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-use wcf\data\language\item\LanguageItemEditor;
-use wcf\data\like\Like;
-use wcf\data\option\OptionEditor;
-use wcf\system\language\LanguageFactory;
-use wcf\system\WCF;
-
-// !!!!!!!!!
-// HEADS UP!    The columns for wcf1_like, wcf1_like_object and the wcf1_reaction_type table must already exists, before calling this script.
-// HEADS UP!    The foreign key for the wcf1_like table will be created within this script, after providing real values for the reactionTypeID
-// HEADS UP!    column. Also this script provides the basic reactionTypes.
-// !!!!!!!!!
-
-/**
- * @author     Joshua Ruesweg
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core
- */
-
-OptionEditor::import([
-       'like_show_summary' => 1,
-]);
-
-try {
-       WCF::getDB()->beginTransaction();
-       
-       $reactions = ['like', 'thanks', 'haha', 'confused', 'sad'];
-       if (LIKE_ENABLE_DISLIKE) {
-               // Remove the existing phrase in case a previous upgrade attempt has failed.
-               $sql = "DELETE FROM     wcf".WCF_N."_language_item
-                       WHERE           languageItem = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute(['wcf.reactionType.title6']);
-               
-               $reactions[] = 'thumbsDown';
-               
-               $sql = "SELECT  languageCategoryID
-                       FROM    wcf".WCF_N."_language_category
-                       WHERE   languageCategory = ?";
-               $statement = WCF::getDB()->prepareStatement($sql, 1);
-               $statement->execute(['wcf.reactionType']);
-               $languageCategoryID = $statement->fetchSingleColumn();
-               
-               // Create a custom phrase for this reaction, it needs to be "manually" added
-               // because it would otherwise conflict with the next reaction created by the
-               // user, *if* there are no dislikes.
-               foreach (LanguageFactory::getInstance()->getLanguages() as $language) {
-                       LanguageItemEditor::create([
-                               'languageID' => $language->languageID,
-                               'languageItem' => 'wcf.reactionType.title6',
-                               'languageItemValue' => ($language->getFixedLanguageCode() === 'de' ? 'Gefällt mir nicht' : 'Dislike'),
-                               'languageCategoryID' => $languageCategoryID,
-                               'packageID' => 1,
-                       ]);
-               }
-       }
-       
-       $sql = "INSERT IGNORE INTO      wcf".WCF_N."_reaction_type
-                                       (reactionTypeID, title, showOrder, iconFile)
-               VALUES                  (?, ?, ?, ?)";
-       $statement = WCF::getDB()->prepareStatement($sql);
-       for ($i = 0, $length = count($reactions); $i < $length; $i++) {
-               $reactionTypeID = $i + 1;
-               
-               $statement->execute([
-                       $reactionTypeID,
-                       "wcf.reactionType.title{$reactionTypeID}",
-                       $reactionTypeID,
-                       "{$reactions[$i]}.svg",
-               ]);
-       }
-       
-       // Update the existing (dis)likes.
-       $likeValues = [Like::LIKE => 1];
-       if (LIKE_ENABLE_DISLIKE) $likeValues[Like::DISLIKE] = 6;
-       
-       $sql = "UPDATE  wcf".WCF_N."_like
-               SET     reactionTypeID = ?
-               WHERE   likeValue = ?";
-       $statement = WCF::getDB()->prepareStatement($sql);
-       foreach ($likeValues as $likeValue => $reactionTypeID) {
-               $statement->execute([
-                       $reactionTypeID,
-                       $likeValue,
-               ]);
-       }
-       
-       // Delete outdated or unsupported likes.
-       WCF::getDB()->prepareStatement("DELETE FROM wcf".WCF_N."_like WHERE reactionTypeID = 0")->execute();
-       
-       // Adjust the like objects by moving all dislikes into regular likes/cumulativeLikes.
-       $sql = "UPDATE  wcf".WCF_N."_like_object
-               SET     likes = likes + dislikes,
-                       cumulativeLikes = likes,
-                       dislikes = 0";
-       WCF::getDB()->prepareStatement($sql)->execute();
-       
-       $dbEditor = WCF::getDB()->getEditor();
-       $foreignKeys = $dbEditor->getForeignKeys('wcf'.WCF_N.'_like');
-       $expectedKey = 'fe5076ee92a558ce8177e3afbfc3dafc_fk';
-       $hasExpectedKey = false;
-       
-       // Find the previously added foreign key, in case the upgrade was interrupted before.
-       foreach ($foreignKeys as $indexName => $definition) {
-               if ($indexName === $expectedKey) {
-                       $hasExpectedKey = true;
-                       break;
-               }
-               
-               if ($definition['referencedTable'] === 'wcf'.WCF_N.'_reaction_type') {
-                       if (count($definition['columns']) === 1 && $definition['columns'][0] === 'reactionTypeID') {
-                               $dbEditor->dropForeignKey('wcf'.WCF_N.'_like', $indexName);
-                       }
-               }
-       }
-       
-       if (!$hasExpectedKey) {
-               $dbEditor->addForeignKey('wcf' . WCF_N . '_like', $expectedKey, [
-                       'columns' => 'reactionTypeID',
-                       'referencedColumns' => 'reactionTypeID',
-                       'referencedTable' => 'wcf'.WCF_N.'_reaction_type',
-                       'ON DELETE' => 'CASCADE',
-               ]);
-       }
-       
-       WCF::getDB()->commitTransaction();
-}
-catch (Exception $e) {
-       WCF::getDB()->rollBackTransaction();
-       
-       throw $e;
-}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_reloadOptions.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.2_reloadOptions.php
deleted file mode 100644 (file)
index ea2e7f4..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-namespace wcf\acp;
-use wcf\data\option\OptionEditor;
-
-OptionEditor::resetCache();
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3.3_db.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3.3_db.php
new file mode 100644 (file)
index 0000000..387d26a
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+use wcf\system\database\table\column\EnumDatabaseTableColumn;
+use wcf\system\database\table\DatabaseTableChangeProcessor;
+use wcf\system\database\table\PartialDatabaseTable;
+use wcf\system\package\plugin\ScriptPackageInstallationPlugin;
+use wcf\system\WCF;
+
+/**
+ * Updates the database table layout from WoltLab Suite Core 5.3.2 to 5.3.3.
+ *
+ * @author  Matthias Schmidt
+ * @copyright   2001-2021 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ */
+
+$tables = [
+       PartialDatabaseTable::create('wcf1_event_listener')
+               ->columns([
+                       EnumDatabaseTableColumn::create('environment')
+                               ->enumValues(['user', 'admin', 'all'])
+               ]),
+];
+
+(new DatabaseTableChangeProcessor(
+/** @var ScriptPackageInstallationPlugin $this */
+       $this->installation->getPackage(),
+       $tables,
+       WCF::getDB()->getEditor())
+)->process();
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3.php
new file mode 100644 (file)
index 0000000..c77c206
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+use wcf\system\database\table\column\CharDatabaseTableColumn;
+use wcf\system\database\table\column\EnumDatabaseTableColumn;
+use wcf\system\database\table\column\IntDatabaseTableColumn;
+use wcf\system\database\table\column\MediumtextDatabaseTableColumn;
+use wcf\system\database\table\column\NotNullInt10DatabaseTableColumn;
+use wcf\system\database\table\column\NotNullVarchar191DatabaseTableColumn;
+use wcf\system\database\table\column\NotNullVarchar255DatabaseTableColumn;
+use wcf\system\database\table\column\ObjectIdDatabaseTableColumn;
+use wcf\system\database\table\DatabaseTable;
+use wcf\system\database\table\DatabaseTableChangeProcessor;
+use wcf\system\database\table\PartialDatabaseTable;
+use wcf\system\database\table\index\DatabaseTableForeignKey;
+use wcf\system\database\table\index\DatabaseTableIndex;
+use wcf\system\package\plugin\ScriptPackageInstallationPlugin;
+use wcf\system\WCF;
+
+/**
+ * Updates the database table layout from WoltLab Suite Core 5.2 to 5.3.
+ * 
+ * @author     Florian Gail
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core
+ */
+
+$tables = [
+       PartialDatabaseTable::create('wcf1_article_content')
+               ->columns([
+                       NotNullVarchar255DatabaseTableColumn::create('metaTitle')
+                               ->defaultValue(''),
+                       NotNullVarchar255DatabaseTableColumn::create('metaDescription')
+                               ->defaultValue(''),
+               ]),
+       DatabaseTable::create('wcf1_devtools_missing_language_item')
+               ->columns([
+                       ObjectIdDatabaseTableColumn::create('itemID'),
+                       IntDatabaseTableColumn::create('languageID'),
+                       NotNullVarchar191DatabaseTableColumn::create('languageItem'),
+                       NotNullInt10DatabaseTableColumn::create('lastTime'),
+                       MediumtextDatabaseTableColumn::create('stackTrace')
+                               ->notNull()
+               ])
+               ->indices([
+                       DatabaseTableIndex::create()
+                               ->type(DatabaseTableIndex::UNIQUE_TYPE)
+                               ->columns(['languageID', 'languageItem']),
+               ])
+               ->foreignKeys([
+                       DatabaseTableForeignKey::create()
+                               ->columns(['languageID'])
+                               ->referencedTable('wcf1_language')
+                               ->referencedColumns(['languageID'])
+                               ->onDelete('SET NULL')
+               ]),
+       PartialDatabaseTable::create('wcf1_event_listener')
+               ->columns([
+                       EnumDatabaseTableColumn::create('environment')
+                               ->enumValues(['user', 'admin', 'all'])
+               ]),
+       PartialDatabaseTable::create('wcf1_media')
+               ->columns([
+                       NotNullInt10DatabaseTableColumn::create('fileUpdateTime')
+                               ->defaultValue(0)
+               ]),
+       PartialDatabaseTable::create('wcf1_user')
+               ->columns([
+                       CharDatabaseTableColumn::create('emailConfirmed')
+                               ->length(40),
+                       NotNullVarchar255DatabaseTableColumn::create('password')
+                               ->defaultValue('invalid:'),
+               ])
+               ->indices([
+                       DatabaseTableIndex::create('username')
+                               ->type(DatabaseTableIndex::UNIQUE_TYPE)
+                               ->columns(['username']),
+               ]),
+];
+
+(new DatabaseTableChangeProcessor(
+/** @var ScriptPackageInstallationPlugin $this */
+       $this->installation->getPackage(),
+       $tables,
+       WCF::getDB()->getEditor())
+)->process();
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_emailConfirmation.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_emailConfirmation.php
new file mode 100644 (file)
index 0000000..4ad2593
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+use wcf\system\WCF;
+
+/**
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core
+ */
+
+// HEADS UP: This script must be executed, AFTER the SQL tables are changed. 
+
+$sql = "UPDATE  wcf". WCF_N ."_user 
+       SET     emailConfirmed = activationCode
+       WHERE   activationCode <> 0";
+
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute();
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_fixActivationMethod.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_fixActivationMethod.php
new file mode 100644 (file)
index 0000000..70e6b12
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+use wcf\data\option\OptionEditor;
+
+// Legacy versions handled disabled option values incorrectly, causing them to be unset
+// instead of maintaining the previously selected value. As a result, installations that
+// disabled the registration in WoltLab Suite 3.1 without enabling it again may have an
+// empty string value set for the activation method.
+//
+// See https://github.com/WoltLab/WCF/issues/3723
+if (!is_numeric(REGISTER_ACTIVATION_METHOD)) {
+       OptionEditor::import([
+               'register_activation_method' => 0,
+       ]);
+}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_invalidateMailForm.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_invalidateMailForm.php
new file mode 100644 (file)
index 0000000..ecf9ca0
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+use wcf\system\WCF;
+
+/**
+ * Removes the files belonging to the old MailForm in order to make this completely non-functional.
+ * 
+ * @author     Tim Duesterhus, Florian Gail
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core
+ */
+
+if (file_exists(WCF_DIR . 'lib/form/MailForm.class.php')) {
+       unlink(WCF_DIR . 'lib/form/MailForm.class.php');
+}
+
+// At this point the MailForm.class.php must be absent. Either the unlink() succeeded or
+// the file already was gone.
+$sql = "DELETE FROM    wcf".WCF_N."_package_installation_file_log
+       WHERE           packageID = ?
+                       AND filename = ?";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute([
+       $this->installation->getPackageID(),
+       'lib/form/MailForm.class.php'
+]);
+
+if (file_exists(WCF_DIR . 'templates/mail.tpl')) {
+       unlink(WCF_DIR . 'templates/mail.tpl');
+}
+
+$sql = "DELETE FROM    wcf".WCF_N."_template
+       WHERE           packageID = ?
+                       AND templateName = ?";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute([
+       $this->installation->getPackageID(),
+       'mail'
+]);
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_orphanedComments.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_orphanedComments.php
new file mode 100644 (file)
index 0000000..7ab0dcb
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+namespace wcf\acp;
+
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\comment\CommentHandler;
+use wcf\system\WCF;
+
+// Earlier versions did remove moderation queues without taking care of
+// comments associated with them.
+$commentObjectTypeID = ObjectTypeCache::getInstance()->getObjectTypeIDByName(
+       "com.woltlab.wcf.comment.commentableContent",
+       "com.woltlab.wcf.moderation.queue"
+);
+
+$sql = "SELECT  DISTINCT objectID
+        FROM    wcf" . WCF_N . "_comment
+        WHERE   objectTypeID = ?
+        AND     objectID NOT IN (
+                        SELECT  queueID
+                        FROM    wcf" . WCF_N . "_moderation_queue
+                )";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute([$commentObjectTypeID]);
+$objectIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
+
+if (!empty($objectIDs)) {
+       CommentHandler::getInstance()->deleteObjects("com.woltlab.wcf.moderation.queue", $objectIDs);
+}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_packageServer.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_packageServer.php
new file mode 100644 (file)
index 0000000..5a1cd9f
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace wcf\acp;
+use wcf\data\package\update\server\PackageUpdateServerEditor;
+use wcf\system\WCF;
+
+// Do not use the `PackageUpdateServer` classes because we need to access
+// the raw server URL that is implicitly rewritten in 5.3.
+$sql = "SELECT  *
+       FROM    wcf" . WCF_N . "_package_update_server
+       WHERE   LOWER(serverURL) REGEXP 'https?://(store|update)\.woltlab\.com/.*'";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute();
+
+$deleteServerIDs = [];
+while ($row = $statement->fetchArray()) {
+       if (!preg_match("~^https?://(?:store|update)\.woltlab\.com/5\.3/~", $row["serverURL"])) {
+               $deleteServerIDs[] = $row["packageUpdateServerID"];
+       }
+}
+
+if (!empty($deleteServerIDs)) {
+       PackageUpdateServerEditor::deleteAll($deleteServerIDs);
+}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_preUpdate.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_preUpdate.php
new file mode 100644 (file)
index 0000000..924bbcd
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+namespace wcf\acp;
+use wcf\system\WCF;
+
+/**
+ * Checks for any duplicate usernames and aborts the upgrade if any are found. Afterwards a basic
+ * check is executed to validate if the database encoding was properly converted following an
+ * upgrade to WoltLab Suite 3.0.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core
+ */
+
+$sql = "SELECT          username, COUNT(username)
+       FROM            wcf" . WCF_N . "_user
+       GROUP BY        username
+       HAVING          COUNT(username) > ?";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute([1]);
+$usernames = $statement->fetchList('username');
+
+if (!empty($usernames)) {
+       if (WCF::getLanguage()->getFixedLanguageCode() === 'de') {
+               $message = "Ein oder mehr Benutzernamen sind mehrfach gegeben, diese Konten müssen zusammengeführt oder gelöscht werden: %s";
+       }
+       else {
+               $message = "One or more usernames exist multiple times, these accounts must be merged or deleted: %s";
+       }
+       
+       throw new \RuntimeException(sprintf($message, implode(', ', $usernames)));
+}
+
+// Verify that the database encoding has been converted before upgrading to 5.3, since we removed this
+// now obsolete worker with this version.
+$sql = "SHOW FULL COLUMNS FROM wcf".WCF_N."_user_storage";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute();
+
+$requireConversion = true;
+while ($row = $statement->fetchArray()) {
+       if ($row['Field'] === 'field') {
+               if (preg_match('~^utf8mb4~', $row['Collation'])) {
+                       $requireConversion = false;
+               }
+       }
+}
+
+if ($requireConversion) {
+       if (WCF::getLanguage()->getFixedLanguageCode() === 'de') {
+               $message = "Die Datenbanktabellen wurden noch nicht auf utf8mb4 konvertiert, dies ist für das Upgrade unbedingt erforderlich.";
+       }
+       else {
+               $message = "The database tables have not yet been converted to utf8mb4, this is absolutely necessary for the upgrade";
+       }
+       
+       throw new \RuntimeException($message);
+}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_sitemaps.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_sitemaps.php
new file mode 100644 (file)
index 0000000..ad22f09
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\registry\RegistryHandler;
+use wcf\system\worker\SitemapRebuildWorker;
+
+/**
+ * @author     Joshua Ruesweg
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core
+ */
+
+// HEADS UP: This script must be executed, BEFORE the objectType-PIP is executed.  
+
+$sitemapObjects = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.sitemap.object');
+
+foreach ($sitemapObjects as $sitemapObject) {
+       RegistryHandler::getInstance()->set('com.woltlab.wcf', SitemapRebuildWorker::REGISTRY_PREFIX . $sitemapObject->objectType, serialize([
+               'priority' => $sitemapObject->priority,
+               'changeFreq' => $sitemapObject->changeFreq,
+               'rebuildTime' => $sitemapObject->rebuildTime,
+               'isDisabled' => $sitemapObject->isDisabled,
+       ]));
+}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_style.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_style.php
new file mode 100644 (file)
index 0000000..888aea4
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+
+use wcf\data\style\StyleEditor;
+use wcf\data\style\StyleList;
+use wcf\system\background\BackgroundQueueHandler;
+use wcf\system\background\job\DownloadStyleLogoJob;
+use wcf\util\FileUtil;
+use wcf\util\Url;
+
+/**
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core
+ */
+
+$styleList = new StyleList();
+$styleList->readObjects();
+
+foreach ($styleList as $style) {
+       $style->loadVariables();
+       $variables = $style->getVariables();
+       $styleEditor = new StyleEditor($style);
+       
+       // 1) Move existing asset path folder out of the way.
+       // It's unlikely that one exists, but having an existing folder will create a small mess.
+       $assetBackupPath = FileUtil::removeTrailingSlash($style->getAssetPath()) . '.old53/';
+       if (file_exists($style->getAssetPath())) {
+               if (file_exists($assetBackupPath)) {
+                       // If the assetBackupPath exists then we have one of the following situations.
+                       // 
+                       // 1) The source installation is configured pretty strangely.
+                       //    This situation can be ignored due to its unlikelyness.
+                       // 2) The style was successfully migrated, but the update failed at a later point.
+                       //    There is no harm in skipping this style.
+                       // 3) The style was unsuccessfully migrated and failed in steps 3 to 7.
+                       //    To reach this situation this script has to fail twice (except in the unlikely situation that the assetPath existed previously).
+                       //    It's unlikely that it succeeds this time. To skipping this style is a sane option.
+                       //    Also the administrator is able to manually fix up the style later, because nothing is deleted.
+                       //
+                       // Concluding: This is a sufficiently reliable test to check whether this script was executed.
+                       continue;
+               }
+               rename($style->getAssetPath(), $assetBackupPath);
+       }
+       
+       // 2) Create asset folder.
+       FileUtil::makePath($style->getAssetPath());
+       
+       // 3) If the file had a custom image folder we need to copy all files into the asset folder.
+       // Moving the files is unsafe, because multiple styles can share a single image folder.
+       $srcPath = FileUtil::addTrailingSlash(WCF_DIR.$style->imagePath);
+       if ($srcPath !== WCF_DIR && $srcPath !== WCF_DIR.'images/') {
+               if ($srcPath == $style->getAssetPath()) {
+                       $srcPath = $assetBackupPath;
+               }
+               
+               if (file_exists($srcPath)) {
+                       $iterator = new \RecursiveIteratorIterator(
+                               new \RecursiveDirectoryIterator(
+                                       $srcPath,
+                                       \FilesystemIterator::SKIP_DOTS
+                               ),
+                               \RecursiveIteratorIterator::SELF_FIRST
+                       );
+                       foreach ($iterator as $file) {
+                               /** @var \SplFileInfo $file */
+                               if (!$file->isFile()) continue;
+                               
+                               $relative = FileUtil::getRelativePath($srcPath, $file->getPath());
+                               FileUtil::makePath($style->getAssetPath() . $relative);
+                               copy($file->getPathname(), $style->getAssetPath() . $relative . $file->getBasename());
+                       }
+               }
+       }
+       $styleEditor->update([
+               'imagePath' => FileUtil::unifyDirSeparator(FileUtil::getRelativePath(WCF_DIR, $style->getAssetPath())),
+       ]);
+       
+       // 4) Copy style previews into the asset folder.
+       // Moving *should* be safe here, unless the admin manually edited the style, but better play safe.
+       if ($style->image && file_exists(WCF_DIR . 'images/' . $style->image)) {
+               $extension = pathinfo($style->image, PATHINFO_EXTENSION);
+               $newName =  'stylePreview.' . $extension;
+               copy(
+                       WCF_DIR . 'images/' . $style->image,
+                       $style->getAssetPath() . $newName
+               );
+               $styleEditor->update([
+                       'image' => FileUtil::getRelativePath(WCF_DIR.'images/', $style->getAssetPath()) . $newName,
+               ]);
+       }
+
+       if ($style->image2x && file_exists(WCF_DIR . 'images/' . $style->image2x)) {
+               $extension = pathinfo($style->image2x, PATHINFO_EXTENSION);
+               $newName = 'stylePreview@2x.' . $extension;
+               copy(
+                       WCF_DIR . 'images/' . $style->image2x,
+                       $style->getAssetPath() . $newName
+               );
+               $styleEditor->update([
+                       'image2x' => FileUtil::getRelativePath(WCF_DIR.'images/', $style->getAssetPath()) . $newName,
+               ]);
+       }
+       
+       // 5) Copy coverPhotos into the asset folder.
+       // Moving is safe here, but for consistency we are copying.
+       if (file_exists(WCF_DIR . 'images/coverPhotos/' . $style->styleID . '.' . $style->coverPhotoExtension)) {
+               copy(
+                       WCF_DIR . 'images/coverPhotos/' . $style->styleID . '.' . $style->coverPhotoExtension,
+                       $style->getAssetPath() . 'coverPhoto.' . $style->coverPhotoExtension
+               );
+       }
+       
+       // 6) Copy favicon related files into the asset folder.
+       // Moving is safe here, but for consistency we are copying.
+       foreach ([
+               'android-chrome-192x192.png',
+               'android-chrome-256x256.png',
+               'apple-touch-icon.png',
+               'browserconfig.xml',
+               'favicon.ico',
+               'favicon-template.png',
+               'manifest.json',
+               'mstile-150x150.png',
+       ] as $filename) {
+               if (file_exists(WCF_DIR . 'images/favicon/' . $style->styleID . '.' . $filename)) {
+                       copy(
+                               WCF_DIR . 'images/favicon/' . $style->styleID . '.' . $filename,
+                               $style->getAssetPath() . $filename
+                       );
+               }
+       }
+       
+       // 7) Copy styleLogo.
+       // Moving is unsafe, we cannot even guarantee that the logo is a file on the local filesystem.
+       $queueDownload = false;
+       foreach (['pageLogo', 'pageLogoMobile'] as $type) {
+               if (empty($variables[$type])) continue;
+               if (Url::is($variables[$type])) {
+                       $queueDownload = true;
+                       continue;
+               }
+               
+               $srcPath = WCF_DIR . 'images/' . $variables[$type];
+               if (!file_exists($srcPath)) {
+                       $srcPath = WCF_DIR . $style->imagePath . '/' . $style->getVariable($type);
+                       if (!file_exists($srcPath)) {
+                               continue;
+                       }
+               }
+               copy(
+                       $srcPath,
+                       $style->getAssetPath() . basename($srcPath)
+               );
+               $variables[$type] = basename($srcPath);
+       }
+       $styleEditor->setVariables($variables);
+       if ($queueDownload) {
+               BackgroundQueueHandler::getInstance()->enqueueIn(new DownloadStyleLogoJob($style), 150);
+       }
+}
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_embeddedObjectOrphans.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_embeddedObjectOrphans.php
deleted file mode 100644 (file)
index cb91e30..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-use wcf\data\object\type\ObjectTypeCache;
-use wcf\system\WCF;
-
-// 1) Articles
-$articleContentObjectTypeID = ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.message', 'com.woltlab.wcf.article.content');
-
-$sql = "DELETE FROM    wcf".WCF_N."_message_embedded_object
-       WHERE           messageObjectTypeID = ?
-               AND     messageID NOT IN (
-                       SELECT  articleContentID
-                       FROM    wcf".WCF_N."_article_content
-               )";
-$statement = WCF::getDB()->prepareStatement($sql);
-$statement->execute([$articleContentObjectTypeID]);
-
-// 2) Pages
-$pageContentObjectTypeID = ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.message', 'com.woltlab.wcf.page.content');
-
-$sql = "DELETE FROM    wcf".WCF_N."_message_embedded_object
-       WHERE           messageObjectTypeID = ?
-               AND     messageID NOT IN (
-                       SELECT  pageContentID
-                       FROM    wcf".WCF_N."_page_content
-               )";
-$statement = WCF::getDB()->prepareStatement($sql);
-$statement->execute([$pageContentObjectTypeID]);
-
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_preventMailAbuse.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_preventMailAbuse.php
deleted file mode 100644 (file)
index dfc68f8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-namespace wcf\acp;
-use wcf\system\WCF;
-
-$sql = "UPDATE  wcf".WCF_N."_user_group_option_value
-       SET     optionValue = ?
-       WHERE   optionID = (
-               SELECT  optionID
-               FROM    wcf".WCF_N."_user_group_option
-               WHERE   optionName = ?
-       )";
-$statement = WCF::getDB()->prepareStatement($sql);
-$statement->execute([
-       0,
-       'user.profile.canMail',
-]);
index b36780114577aad42058b075e68fef67be667409..806f136d728b9fc67a71f3886bb415a8b1cfc1c0 100644 (file)
@@ -8,8 +8,9 @@
  * @package    WoltLabSuite\Core
  */
 if (PHP_SAPI !== 'cli') exit;
-// define the wcf-root-dir
-define('WCF_DIR', dirname(__FILE__).'/');
+
+// include config
+require_once(__DIR__.'/app.config.inc.php');
 
 // initiate wcf core
 require_once(WCF_DIR.'lib/system/WCF.class.php');
diff --git a/wcfsetup/install/files/font/families/.gitignore b/wcfsetup/install/files/font/families/.gitignore
new file mode 100644 (file)
index 0000000..9aee505
--- /dev/null
@@ -0,0 +1,5 @@
+*
+!Open Sans
+!Open Sans/
+!Open Sans/*
+!.gitignore
diff --git a/wcfsetup/install/files/font/families/Open Sans/LICENSE.txt b/wcfsetup/install/files/font/families/Open Sans/LICENSE.txt
new file mode 100644 (file)
index 0000000..75b5248
--- /dev/null
@@ -0,0 +1,202 @@
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-Bold.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Bold.woff2
new file mode 100644 (file)
index 0000000..dcc95a6
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Bold.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-BoldItalic.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-BoldItalic.woff2
new file mode 100644 (file)
index 0000000..3830441
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-BoldItalic.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBold.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBold.woff2
new file mode 100644 (file)
index 0000000..c35f87b
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBold.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBoldItalic.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBoldItalic.woff2
new file mode 100644 (file)
index 0000000..181f8a7
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-ExtraBoldItalic.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-Italic.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Italic.woff2
new file mode 100644 (file)
index 0000000..cff0ff1
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Italic.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-Light.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Light.woff2
new file mode 100644 (file)
index 0000000..979ec09
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Light.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-LightItalic.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-LightItalic.woff2
new file mode 100644 (file)
index 0000000..e32e49f
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-LightItalic.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-Regular.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Regular.woff2
new file mode 100644 (file)
index 0000000..603d8b2
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-Regular.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBold.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBold.woff2
new file mode 100644 (file)
index 0000000..3c2aac2
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBold.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBoldItalic.woff2 b/wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBoldItalic.woff2
new file mode 100644 (file)
index 0000000..0a8919b
Binary files /dev/null and b/wcfsetup/install/files/font/families/Open Sans/OpenSans-SemiBoldItalic.woff2 differ
diff --git a/wcfsetup/install/files/font/families/Open Sans/font.css b/wcfsetup/install/files/font/families/Open Sans/font.css
new file mode 100644 (file)
index 0000000..7c2b71c
--- /dev/null
@@ -0,0 +1,85 @@
+/* Font Family: Open Sans
+ * Designed by: Steve Matteson
+ * License: APACHE2
+ */
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: normal;
+       font-weight: 300;
+       src: local('Open Sans Light'), local('OpenSans-Light'),  url(getFont("OpenSans-Light.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: italic;
+       font-weight: 300;
+       src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),  url(getFont("OpenSans-LightItalic.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: normal;
+       font-weight: 400;
+       src: local('Open Sans Regular'), local('OpenSans-Regular'),  url(getFont("OpenSans-Regular.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: italic;
+       font-weight: 400;
+       src: local('Open Sans Italic'), local('OpenSans-Italic'),  url(getFont("OpenSans-Italic.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: normal;
+       font-weight: 600;
+       src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),  url(getFont("OpenSans-SemiBold.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: italic;
+       font-weight: 600;
+       src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),  url(getFont("OpenSans-SemiBoldItalic.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: normal;
+       font-weight: 700;
+       src: local('Open Sans Bold'), local('OpenSans-Bold'),  url(getFont("OpenSans-Bold.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: italic;
+       font-weight: 700;
+       src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),  url(getFont("OpenSans-BoldItalic.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: normal;
+       font-weight: 800;
+       src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'),  url(getFont("OpenSans-ExtraBold.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
+@font-face {
+       /* Copyright: Digitized data copyright  2010-2011, Google Corporation. */
+       font-family: 'Open Sans';
+       font-style: italic;
+       font-weight: 800;
+       src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'),  url(getFont("OpenSans-ExtraBoldItalic.woff2", "Open%20Sans", "1595938323")) format('woff2');
+}
+
index e2c313ff2e5531461eca1b7ef847094b43f73725..fc3523954a074907d27d441bec40e95440474308 100644 (file)
@@ -6,8 +6,8 @@
  *  - Firefox and Internet Explorer refuse to load fonts from different domains unless allowed by 'Access-Control-Allow-Origin'
  *  - Chrome sometimes does not properly cache fonts, resulting in strange rendering bugs
  * 
- * @author     Alexander Ebert, Sascha Greuel
- * @copyright  2001-2019 WoltLab GmbH
+ * @author     Tim Duesterhus, Alexander Ebert, Sascha Greuel
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  */
 
@@ -21,49 +21,67 @@ $types = [
        'woff2' => 'font/woff2' // the specs at http://dev.w3.org/webfonts/WOFF2/spec/ are not perfectly clear, but font/woff2 seems to be the most sane one and is currently used by Google Fonts
 ];
 
-if (!empty($_GET['type'])) {
-       // get parameters
-       $type = $_GET['type'];
-       $font = (!empty($_GET['font']) ? basename($_GET['font']) : 'fontawesome-webfont');
-       
-       if (isset($types[$type])) {
-               if (file_exists($font . '.' . $type)) {
-                       $filename = $font . '.' . $type;
-                       $filemtime = filemtime($filename);
-                       
-                       $etag = '"' . md5($filemtime . $filename) . '"';
-                       $clientEtag = (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : '';
-                       $clientLastModified = (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) ? trim($_SERVER['HTTP_IF_MODIFIED_SINCE']) : 0;
-                       $clientLastModified = @strtotime($clientLastModified);
-                       
-                       // ignore request if client seems to already have fetched this file
-                       if (($clientLastModified && $clientEtag) ? (($clientLastModified == $filemtime) && ($clientEtag == $etag)) : ($clientLastModified == $filemtime) ) {
-                               header("HTTP/1.1 304 Not Modified");
-                               exit;
-                       }
-                       
-                       $data = file_get_contents($filename);
-                       
-                       // send cache and type headers
-                       // allow font fetching from all domains (CORS)
-                       header('Access-Control-Allow-Origin: *');
-                       header('Content-Type: ' . $types[$type]);
-                       header('Cache-Control: max-age=31536000, public');
-                       header('ETag: ' . $etag);
-                       header('Expires: ' . gmdate("D, d M Y H:i:s", time() + 31536000) . ' GMT');
-                       header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $filemtime) . ' GMT');
-                       header('Content-Length: ' . strlen($data));
-                       
-                       die($data);
-               }
-               
-               header("HTTP/1.1 400 Bad Request");
-               die("Invalid font '" . htmlentities($font) . "' given");
-       }
-       
+function badRequest($reason) {
        header("HTTP/1.1 400 Bad Request");
-       die("Invalid type '" . htmlentities($type) . "' given");
+       header("Content-Type: text/plain");
+       die($reason);
+}
+
+function notFound($reason = "Unable to find font.") {
+       header("HTTP/1.1 404 Not Found");
+       header("Content-Type: text/plain");
+       die($reason);
+}
+
+if (empty($_GET['filename'])) {
+       if (empty($_GET['type'])) {
+               badRequest('Neither filename nor type is given.');
+       }
+       $filename = (!empty($_GET['font']) ? basename($_GET['font']) : 'fontawesome-webfont').'.'.$_GET['type'];
+}
+else {
+       $filename = __DIR__.'/';
+       if (!empty($_GET['family'])) {
+               $filename .= 'families/'.basename($_GET['family']).'/';
+       }
+       $filename .= basename($_GET['filename']);
+}
+
+$type = pathinfo($filename, PATHINFO_EXTENSION);
+
+if (!isset($types[$type])) {
+       badRequest('Invalid type given.');
+}
+
+if (!is_readable($filename)) {
+       notFound();
+}
+
+$filemtime = filemtime($filename);
+
+$etag = '"' . md5($filemtime . $filename) . '"';
+$clientEtag = (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : '';
+$clientLastModified = (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) ? trim($_SERVER['HTTP_IF_MODIFIED_SINCE']) : 0;
+$clientLastModified = @strtotime($clientLastModified);
+
+// ignore request if client seems to already have fetched this file
+if (($clientLastModified && $clientEtag) ? (($clientLastModified == $filemtime) && ($clientEtag == $etag)) : ($clientLastModified == $filemtime) ) {
+       header("HTTP/1.1 304 Not Modified");
+       exit;
 }
 
-header("HTTP/1.1 400 Bad Request");
-die("Missing type parameter");
+$data = file_get_contents($filename);
+
+// send cache and type headers
+// allow font fetching from all domains (CORS)
+const MAX_AGE = 86400 * 14;
+
+header('Access-Control-Allow-Origin: *');
+header('Content-Type: ' . $types[$type]);
+header('Cache-Control: max-age=' . MAX_AGE . ', public');
+header('ETag: ' . $etag);
+header('Expires: ' . gmdate("D, d M Y H:i:s", time() + MAX_AGE) . ' GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $filemtime) . ' GMT');
+header('Content-Length: ' . strlen($data));
+
+die($data);
index 94550bf66df39123327ddb9a68412f5866489441..cbd0c70c473bdb649a4bc5bcb64ed0fde7940935 100644 (file)
@@ -17,7 +17,12 @@ if (!empty($_GET['type']) || !isset($types[$_GET['type']])) {
        $type = $_GET['type'];
        $styleID = (!empty($_GET['styleID'])) ? intval($_GET['styleID']) : 'default';
        if ($styleID === 'default' || $styleID > 0) {
-               $filename = $styleID . '.' . $types[$type]['filename'];
+               if ($styleID === 'default') {
+                       $filename = 'default.' . $types[$type]['filename'];
+               }
+               else {
+                       $filename = '../style-'.$styleID.'/'.$types[$type]['filename'];
+               }
                if (file_exists($filename)) {
                        $filemtime = filemtime($filename);
                        
@@ -34,6 +39,10 @@ if (!empty($_GET['type']) || !isset($types[$_GET['type']])) {
                        
                        $data = file_get_contents($filename);
                        
+                       if ($styleID !== 'default') {
+                               $data = str_replace('src": "', 'src": "../style-'.$styleID."/", $data);
+                       }
+                       
                        // send cache and type headers
                        // allow font fetching from all domains (CORS)
                        header('Access-Control-Allow-Origin: *');
index 8306a2f8ac76e84d33723d549ee74f823bd896e1..4116c586f7260787f42d653de768f4a4a4e4228f 100644 (file)
@@ -14,5 +14,5 @@
     ],
     "theme_color": "#ffffff",
     "background_color": "#ffffff",
-    "display": "browser"
+    "display": "standalone"
 }
index 08c620e46eed51b578e1dd1764a5dc09a5b0ab15..d1c5e545c5436d97e5bfc829bd8534002283fccd 100644 (file)
@@ -1,79 +1,58 @@
-/* (The MIT License)
-
-Copyright (C) 2014-2017 by Vitaly Puzrin
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE. */
-/* pica 5.0.0 nodeca/pica */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pica = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+/* pica 5.1.0 nodeca/pica */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pica = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
 // Collection of math functions
 //
 // 1. Combine components together
 // 2. Has async init to load wasm modules
 //
-               'use strict';
-               
-               var inherits = require('inherits');
-               
-               var Multimath = require('multimath');
-               
-               var mm_unsharp_mask = require('multimath/lib/unsharp_mask');
-               
-               var mm_resize = require('./mm_resize');
-               
-               function MathLib(requested_features) {
-                       var __requested_features = requested_features || [];
-                       
-                       var features = {
-                               js: __requested_features.indexOf('js') >= 0,
-                               wasm: __requested_features.indexOf('wasm') >= 0
-                       };
-                       Multimath.call(this, features);
-                       this.features = {
-                               js: features.js,
-                               wasm: features.wasm && this.has_wasm
-                       };
-                       this.use(mm_unsharp_mask);
-                       this.use(mm_resize);
-               }
-               
-               inherits(MathLib, Multimath);
-               
-               MathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {
-                       var result = this.resize(options, cache);
-                       
-                       if (options.unsharpAmount) {
-                               this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);
-                       }
-                       
-                       return result;
-               };
-               
-               module.exports = MathLib;
-               
-       },{"./mm_resize":4,"inherits":15,"multimath":16,"multimath/lib/unsharp_mask":19}],2:[function(require,module,exports){
+'use strict';
+
+var inherits = require('inherits');
+
+var Multimath = require('multimath');
+
+var mm_unsharp_mask = require('multimath/lib/unsharp_mask');
+
+var mm_resize = require('./mm_resize');
+
+function MathLib(requested_features) {
+  var __requested_features = requested_features || [];
+
+  var features = {
+    js: __requested_features.indexOf('js') >= 0,
+    wasm: __requested_features.indexOf('wasm') >= 0
+  };
+  Multimath.call(this, features);
+  this.features = {
+    js: features.js,
+    wasm: features.wasm && this.has_wasm()
+  };
+  this.use(mm_unsharp_mask);
+  this.use(mm_resize);
+}
+
+inherits(MathLib, Multimath);
+
+MathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {
+  var result = this.resize(options, cache);
+
+  if (options.unsharpAmount) {
+    this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);
+  }
+
+  return result;
+};
+
+module.exports = MathLib;
+
+},{"./mm_resize":4,"inherits":15,"multimath":16,"multimath/lib/unsharp_mask":19}],2:[function(require,module,exports){
 // Resize convolvers, pure JS implementation
 //
-               'use strict'; // Precision of fixed FP values
+'use strict'; // Precision of fixed FP values
 //var FIXED_FRAC_BITS = 14;
-               
-               function clampTo8(i) {
-                       return i < 0 ? 0 : i > 255 ? 255 : i;
-               } // Convolve image in horizontal directions and transpose output. In theory,
+
+function clampTo8(i) {
+  return i < 0 ? 0 : i > 255 ? 255 : i;
+} // Convolve image in horizontal directions and transpose output. In theory,
 // transpose allow:
 //
 // - use the same convolver for both passes (this fails due different
@@ -82,192 +61,192 @@ THE SOFTWARE. */
 //
 // But in real life this doesn't work :)
 //
-               
-               
-               function convolveHorizontally(src, dest, srcW, srcH, destW, filters) {
-                       var r, g, b, a;
-                       var filterPtr, filterShift, filterSize;
-                       var srcPtr, srcY, destX, filterVal;
-                       var srcOffset = 0,
-                               destOffset = 0; // For each row
-                       
-                       for (srcY = 0; srcY < srcH; srcY++) {
-                               filterPtr = 0; // Apply precomputed filters to each destination row point
-                               
-                               for (destX = 0; destX < destW; destX++) {
-                                       // Get the filter that determines the current output pixel.
-                                       filterShift = filters[filterPtr++];
-                                       filterSize = filters[filterPtr++];
-                                       srcPtr = srcOffset + filterShift * 4 | 0;
-                                       r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
-                                       
-                                       for (; filterSize > 0; filterSize--) {
-                                               filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
-                                               // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
-                                               
-                                               a = a + filterVal * src[srcPtr + 3] | 0;
-                                               b = b + filterVal * src[srcPtr + 2] | 0;
-                                               g = g + filterVal * src[srcPtr + 1] | 0;
-                                               r = r + filterVal * src[srcPtr] | 0;
-                                               srcPtr = srcPtr + 4 | 0;
-                                       } // Bring this value back in range. All of the filter scaling factors
-                                       // are in fixed point with FIXED_FRAC_BITS bits of fractional part.
-                                       //
-                                       // (!) Add 1/2 of value before clamping to get proper rounding. In other
-                                       // case brightness loss will be noticeable if you resize image with white
-                                       // border and place it on white background.
-                                       //
-                                       
-                                       
-                                       dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       dest[destOffset] = clampTo8(r + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       destOffset = destOffset + srcH * 4 | 0;
-                               }
-                               
-                               destOffset = (srcY + 1) * 4 | 0;
-                               srcOffset = (srcY + 1) * srcW * 4 | 0;
-                       }
-               } // Technically, convolvers are the same. But input array and temporary
+
+
+function convolveHorizontally(src, dest, srcW, srcH, destW, filters) {
+  var r, g, b, a;
+  var filterPtr, filterShift, filterSize;
+  var srcPtr, srcY, destX, filterVal;
+  var srcOffset = 0,
+      destOffset = 0; // For each row
+
+  for (srcY = 0; srcY < srcH; srcY++) {
+    filterPtr = 0; // Apply precomputed filters to each destination row point
+
+    for (destX = 0; destX < destW; destX++) {
+      // Get the filter that determines the current output pixel.
+      filterShift = filters[filterPtr++];
+      filterSize = filters[filterPtr++];
+      srcPtr = srcOffset + filterShift * 4 | 0;
+      r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
+
+      for (; filterSize > 0; filterSize--) {
+        filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
+        // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
+
+        a = a + filterVal * src[srcPtr + 3] | 0;
+        b = b + filterVal * src[srcPtr + 2] | 0;
+        g = g + filterVal * src[srcPtr + 1] | 0;
+        r = r + filterVal * src[srcPtr] | 0;
+        srcPtr = srcPtr + 4 | 0;
+      } // Bring this value back in range. All of the filter scaling factors
+      // are in fixed point with FIXED_FRAC_BITS bits of fractional part.
+      //
+      // (!) Add 1/2 of value before clamping to get proper rounding. In other
+      // case brightness loss will be noticeable if you resize image with white
+      // border and place it on white background.
+      //
+
+
+      dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      dest[destOffset] = clampTo8(r + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      destOffset = destOffset + srcH * 4 | 0;
+    }
+
+    destOffset = (srcY + 1) * 4 | 0;
+    srcOffset = (srcY + 1) * srcW * 4 | 0;
+  }
+} // Technically, convolvers are the same. But input array and temporary
 // buffer can be of different type (especially, in old browsers). So,
 // keep code in separate functions to avoid deoptimizations & speed loss.
-               
-               
-               function convolveVertically(src, dest, srcW, srcH, destW, filters) {
-                       var r, g, b, a;
-                       var filterPtr, filterShift, filterSize;
-                       var srcPtr, srcY, destX, filterVal;
-                       var srcOffset = 0,
-                               destOffset = 0; // For each row
-                       
-                       for (srcY = 0; srcY < srcH; srcY++) {
-                               filterPtr = 0; // Apply precomputed filters to each destination row point
-                               
-                               for (destX = 0; destX < destW; destX++) {
-                                       // Get the filter that determines the current output pixel.
-                                       filterShift = filters[filterPtr++];
-                                       filterSize = filters[filterPtr++];
-                                       srcPtr = srcOffset + filterShift * 4 | 0;
-                                       r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
-                                       
-                                       for (; filterSize > 0; filterSize--) {
-                                               filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
-                                               // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
-                                               
-                                               a = a + filterVal * src[srcPtr + 3] | 0;
-                                               b = b + filterVal * src[srcPtr + 2] | 0;
-                                               g = g + filterVal * src[srcPtr + 1] | 0;
-                                               r = r + filterVal * src[srcPtr] | 0;
-                                               srcPtr = srcPtr + 4 | 0;
-                                       } // Bring this value back in range. All of the filter scaling factors
-                                       // are in fixed point with FIXED_FRAC_BITS bits of fractional part.
-                                       //
-                                       // (!) Add 1/2 of value before clamping to get proper rounding. In other
-                                       // case brightness loss will be noticeable if you resize image with white
-                                       // border and place it on white background.
-                                       //
-                                       
-                                       
-                                       dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       dest[destOffset] = clampTo8(r + (1 << 13) >> 14
-                                               /*FIXED_FRAC_BITS*/
-                                       );
-                                       destOffset = destOffset + srcH * 4 | 0;
-                               }
-                               
-                               destOffset = (srcY + 1) * 4 | 0;
-                               srcOffset = (srcY + 1) * srcW * 4 | 0;
-                       }
-               }
-               
-               module.exports = {
-                       convolveHorizontally: convolveHorizontally,
-                       convolveVertically: convolveVertically
-               };
-               
-       },{}],3:[function(require,module,exports){
+
+
+function convolveVertically(src, dest, srcW, srcH, destW, filters) {
+  var r, g, b, a;
+  var filterPtr, filterShift, filterSize;
+  var srcPtr, srcY, destX, filterVal;
+  var srcOffset = 0,
+      destOffset = 0; // For each row
+
+  for (srcY = 0; srcY < srcH; srcY++) {
+    filterPtr = 0; // Apply precomputed filters to each destination row point
+
+    for (destX = 0; destX < destW; destX++) {
+      // Get the filter that determines the current output pixel.
+      filterShift = filters[filterPtr++];
+      filterSize = filters[filterPtr++];
+      srcPtr = srcOffset + filterShift * 4 | 0;
+      r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
+
+      for (; filterSize > 0; filterSize--) {
+        filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
+        // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
+
+        a = a + filterVal * src[srcPtr + 3] | 0;
+        b = b + filterVal * src[srcPtr + 2] | 0;
+        g = g + filterVal * src[srcPtr + 1] | 0;
+        r = r + filterVal * src[srcPtr] | 0;
+        srcPtr = srcPtr + 4 | 0;
+      } // Bring this value back in range. All of the filter scaling factors
+      // are in fixed point with FIXED_FRAC_BITS bits of fractional part.
+      //
+      // (!) Add 1/2 of value before clamping to get proper rounding. In other
+      // case brightness loss will be noticeable if you resize image with white
+      // border and place it on white background.
+      //
+
+
+      dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      dest[destOffset] = clampTo8(r + (1 << 13) >> 14
+      /*FIXED_FRAC_BITS*/
+      );
+      destOffset = destOffset + srcH * 4 | 0;
+    }
+
+    destOffset = (srcY + 1) * 4 | 0;
+    srcOffset = (srcY + 1) * srcW * 4 | 0;
+  }
+}
+
+module.exports = {
+  convolveHorizontally: convolveHorizontally,
+  convolveVertically: convolveVertically
+};
+
+},{}],3:[function(require,module,exports){
 // This is autogenerated file from math.wasm, don't edit.
 //
-               'use strict';
-               /* eslint-disable max-len */
-               
-               module.exports = 'AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQQEAXAAAAcZAghjb252b2x2ZQAACmNvbnZvbHZlSFYAAQkBAArmAwLBAwEQfwJAIANFDQAgBEUNACAFQQRqIRVBACEMQQAhDQNAIA0hDkEAIRFBACEHA0AgB0ECaiESAn8gBSAHQQF0IgdqIgZBAmouAQAiEwRAQQAhCEEAIBNrIRQgFSAHaiEPIAAgDCAGLgEAakECdGohEEEAIQlBACEKQQAhCwNAIBAoAgAiB0EYdiAPLgEAIgZsIAtqIQsgB0H/AXEgBmwgCGohCCAHQRB2Qf8BcSAGbCAKaiEKIAdBCHZB/wFxIAZsIAlqIQkgD0ECaiEPIBBBBGohECAUQQFqIhQNAAsgEiATagwBC0EAIQtBACEKQQAhCUEAIQggEgshByABIA5BAnRqIApBgMAAakEOdSIGQf8BIAZB/wFIG0EQdEGAgPwHcUEAIAZBAEobIAtBgMAAakEOdSIGQf8BIAZB/wFIG0EYdEEAIAZBAEobciAJQYDAAGpBDnUiBkH/ASAGQf8BSBtBCHRBgP4DcUEAIAZBAEobciAIQYDAAGpBDnUiBkH/ASAGQf8BSBtB/wFxQQAgBkEAShtyNgIAIA4gA2ohDiARQQFqIhEgBEcNAAsgDCACaiEMIA1BAWoiDSADRw0ACwsLIQACQEEAIAIgAyAEIAUgABAAIAJBACAEIAUgBiABEAALCw==';
-               
-       },{}],4:[function(require,module,exports){
-               'use strict';
-               
-               module.exports = {
-                       name: 'resize',
-                       fn: require('./resize'),
-                       wasm_fn: require('./resize_wasm'),
-                       wasm_src: require('./convolve_wasm_base64')
-               };
-               
-       },{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(require,module,exports){
-               'use strict';
-               
-               var createFilters = require('./resize_filter_gen');
-               
-               var convolveHorizontally = require('./convolve').convolveHorizontally;
-               
-               var convolveVertically = require('./convolve').convolveVertically;
-               
-               function resetAlpha(dst, width, height) {
-                       var ptr = 3,
-                               len = width * height * 4 | 0;
-                       
-                       while (ptr < len) {
-                               dst[ptr] = 0xFF;
-                               ptr = ptr + 4 | 0;
-                       }
-               }
-               
-               module.exports = function resize(options) {
-                       var src = options.src;
-                       var srcW = options.width;
-                       var srcH = options.height;
-                       var destW = options.toWidth;
-                       var destH = options.toHeight;
-                       var scaleX = options.scaleX || options.toWidth / options.width;
-                       var scaleY = options.scaleY || options.toHeight / options.height;
-                       var offsetX = options.offsetX || 0;
-                       var offsetY = options.offsetY || 0;
-                       var dest = options.dest || new Uint8Array(destW * destH * 4);
-                       var quality = typeof options.quality === 'undefined' ? 3 : options.quality;
-                       var alpha = options.alpha || false;
-                       var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),
-                               filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);
-                       var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.
-                       // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep
-                       // vertical and horizontal passes separately to avoid deoptimization.
-                       
-                       convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);
-                       convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.
-                       // !!! Note, canvas data is not premultipled. We don't need other
-                       // alpha corrections.
-                       
-                       if (!alpha) resetAlpha(dest, destW, destH);
-                       return dest;
-               };
-               
-       },{"./convolve":2,"./resize_filter_gen":6}],6:[function(require,module,exports){
+'use strict';
+/* eslint-disable max-len */
+
+module.exports = 'AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQQEAXAAAAcZAghjb252b2x2ZQAACmNvbnZvbHZlSFYAAQkBAArmAwLBAwEQfwJAIANFDQAgBEUNACAFQQRqIRVBACEMQQAhDQNAIA0hDkEAIRFBACEHA0AgB0ECaiESAn8gBSAHQQF0IgdqIgZBAmouAQAiEwRAQQAhCEEAIBNrIRQgFSAHaiEPIAAgDCAGLgEAakECdGohEEEAIQlBACEKQQAhCwNAIBAoAgAiB0EYdiAPLgEAIgZsIAtqIQsgB0H/AXEgBmwgCGohCCAHQRB2Qf8BcSAGbCAKaiEKIAdBCHZB/wFxIAZsIAlqIQkgD0ECaiEPIBBBBGohECAUQQFqIhQNAAsgEiATagwBC0EAIQtBACEKQQAhCUEAIQggEgshByABIA5BAnRqIApBgMAAakEOdSIGQf8BIAZB/wFIG0EQdEGAgPwHcUEAIAZBAEobIAtBgMAAakEOdSIGQf8BIAZB/wFIG0EYdEEAIAZBAEobciAJQYDAAGpBDnUiBkH/ASAGQf8BSBtBCHRBgP4DcUEAIAZBAEobciAIQYDAAGpBDnUiBkH/ASAGQf8BSBtB/wFxQQAgBkEAShtyNgIAIA4gA2ohDiARQQFqIhEgBEcNAAsgDCACaiEMIA1BAWoiDSADRw0ACwsLIQACQEEAIAIgAyAEIAUgABAAIAJBACAEIAUgBiABEAALCw==';
+
+},{}],4:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+  name: 'resize',
+  fn: require('./resize'),
+  wasm_fn: require('./resize_wasm'),
+  wasm_src: require('./convolve_wasm_base64')
+};
+
+},{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(require,module,exports){
+'use strict';
+
+var createFilters = require('./resize_filter_gen');
+
+var convolveHorizontally = require('./convolve').convolveHorizontally;
+
+var convolveVertically = require('./convolve').convolveVertically;
+
+function resetAlpha(dst, width, height) {
+  var ptr = 3,
+      len = width * height * 4 | 0;
+
+  while (ptr < len) {
+    dst[ptr] = 0xFF;
+    ptr = ptr + 4 | 0;
+  }
+}
+
+module.exports = function resize(options) {
+  var src = options.src;
+  var srcW = options.width;
+  var srcH = options.height;
+  var destW = options.toWidth;
+  var destH = options.toHeight;
+  var scaleX = options.scaleX || options.toWidth / options.width;
+  var scaleY = options.scaleY || options.toHeight / options.height;
+  var offsetX = options.offsetX || 0;
+  var offsetY = options.offsetY || 0;
+  var dest = options.dest || new Uint8Array(destW * destH * 4);
+  var quality = typeof options.quality === 'undefined' ? 3 : options.quality;
+  var alpha = options.alpha || false;
+  var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),
+      filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);
+  var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.
+  // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep
+  // vertical and horizontal passes separately to avoid deoptimization.
+
+  convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);
+  convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.
+  // !!! Note, canvas data is not premultipled. We don't need other
+  // alpha corrections.
+
+  if (!alpha) resetAlpha(dest, destW, destH);
+  return dest;
+};
+
+},{"./convolve":2,"./resize_filter_gen":6}],6:[function(require,module,exports){
 // Calculate convolution filters for each destination point,
 // and pack data to Int16Array:
 //
@@ -277,335 +256,335 @@ THE SOFTWARE. */
 // - length - filter length (in src points)
 // - data - filter values sequence
 //
-               'use strict';
-               
-               var FILTER_INFO = require('./resize_filter_info'); // Precision of fixed FP values
-               
-               
-               var FIXED_FRAC_BITS = 14;
-               
-               function toFixedPoint(num) {
-                       return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));
-               }
-               
-               module.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {
-                       var filterFunction = FILTER_INFO[quality].filter;
-                       var scaleInverted = 1.0 / scale;
-                       var scaleClamped = Math.min(1.0, scale); // For upscale
-                       // Filter window (averaging interval), scaled to src image
-                       
-                       var srcWindow = FILTER_INFO[quality].win / scaleClamped;
-                       var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;
-                       var leftNotEmpty, rightNotEmpty, filterShift, filterSize;
-                       var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);
-                       var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);
-                       var packedFilterPtr = 0;
-                       var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values
-                       
-                       for (destPixel = 0; destPixel < destSize; destPixel++) {
-                               // Scaling should be done relative to central pixel point
-                               srcPixel = (destPixel + 0.5) * scaleInverted + offset;
-                               srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));
-                               srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));
-                               filterElementSize = srcLast - srcFirst + 1;
-                               floatFilter = new Float32Array(filterElementSize);
-                               fxpFilter = new Int16Array(filterElementSize);
-                               total = 0.0; // Fill filter values for calculated range
-                               
-                               for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {
-                                       floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);
-                                       total += floatVal;
-                                       floatFilter[idx] = floatVal;
-                               } // Normalize filter, convert to fixed point and accumulate conversion error
-                               
-                               
-                               filterTotal = 0;
-                               
-                               for (idx = 0; idx < floatFilter.length; idx++) {
-                                       filterVal = floatFilter[idx] / total;
-                                       filterTotal += filterVal;
-                                       fxpFilter[idx] = toFixedPoint(filterVal);
-                               } // Compensate normalization error, to minimize brightness drift
-                               
-                               
-                               fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //
-                               // Now pack filter to useable form
-                               //
-                               // 1. Trim heading and tailing zero values, and compensate shitf/length
-                               // 2. Put all to single array in this format:
-                               //
-                               //    [ pos shift, data length, value1, value2, value3, ... ]
-                               //
-                               
-                               leftNotEmpty = 0;
-                               
-                               while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {
-                                       leftNotEmpty++;
-                               }
-                               
-                               if (leftNotEmpty < fxpFilter.length) {
-                                       rightNotEmpty = fxpFilter.length - 1;
-                                       
-                                       while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {
-                                               rightNotEmpty--;
-                                       }
-                                       
-                                       filterShift = srcFirst + leftNotEmpty;
-                                       filterSize = rightNotEmpty - leftNotEmpty + 1;
-                                       packedFilter[packedFilterPtr++] = filterShift; // shift
-                                       
-                                       packedFilter[packedFilterPtr++] = filterSize; // size
-                                       
-                                       if (!slowCopy) {
-                                               packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);
-                                               packedFilterPtr += filterSize;
-                                       } else {
-                                               // fallback for old IE < 11, without subarray/set methods
-                                               for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {
-                                                       packedFilter[packedFilterPtr++] = fxpFilter[idx];
-                                               }
-                                       }
-                               } else {
-                                       // zero data, write header only
-                                       packedFilter[packedFilterPtr++] = 0; // shift
-                                       
-                                       packedFilter[packedFilterPtr++] = 0; // size
-                               }
-                       }
-                       
-                       return packedFilter;
-               };
-               
-       },{"./resize_filter_info":7}],7:[function(require,module,exports){
+'use strict';
+
+var FILTER_INFO = require('./resize_filter_info'); // Precision of fixed FP values
+
+
+var FIXED_FRAC_BITS = 14;
+
+function toFixedPoint(num) {
+  return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));
+}
+
+module.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {
+  var filterFunction = FILTER_INFO[quality].filter;
+  var scaleInverted = 1.0 / scale;
+  var scaleClamped = Math.min(1.0, scale); // For upscale
+  // Filter window (averaging interval), scaled to src image
+
+  var srcWindow = FILTER_INFO[quality].win / scaleClamped;
+  var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;
+  var leftNotEmpty, rightNotEmpty, filterShift, filterSize;
+  var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);
+  var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);
+  var packedFilterPtr = 0;
+  var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values
+
+  for (destPixel = 0; destPixel < destSize; destPixel++) {
+    // Scaling should be done relative to central pixel point
+    srcPixel = (destPixel + 0.5) * scaleInverted + offset;
+    srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));
+    srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));
+    filterElementSize = srcLast - srcFirst + 1;
+    floatFilter = new Float32Array(filterElementSize);
+    fxpFilter = new Int16Array(filterElementSize);
+    total = 0.0; // Fill filter values for calculated range
+
+    for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {
+      floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);
+      total += floatVal;
+      floatFilter[idx] = floatVal;
+    } // Normalize filter, convert to fixed point and accumulate conversion error
+
+
+    filterTotal = 0;
+
+    for (idx = 0; idx < floatFilter.length; idx++) {
+      filterVal = floatFilter[idx] / total;
+      filterTotal += filterVal;
+      fxpFilter[idx] = toFixedPoint(filterVal);
+    } // Compensate normalization error, to minimize brightness drift
+
+
+    fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //
+    // Now pack filter to useable form
+    //
+    // 1. Trim heading and tailing zero values, and compensate shitf/length
+    // 2. Put all to single array in this format:
+    //
+    //    [ pos shift, data length, value1, value2, value3, ... ]
+    //
+
+    leftNotEmpty = 0;
+
+    while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {
+      leftNotEmpty++;
+    }
+
+    if (leftNotEmpty < fxpFilter.length) {
+      rightNotEmpty = fxpFilter.length - 1;
+
+      while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {
+        rightNotEmpty--;
+      }
+
+      filterShift = srcFirst + leftNotEmpty;
+      filterSize = rightNotEmpty - leftNotEmpty + 1;
+      packedFilter[packedFilterPtr++] = filterShift; // shift
+
+      packedFilter[packedFilterPtr++] = filterSize; // size
+
+      if (!slowCopy) {
+        packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);
+        packedFilterPtr += filterSize;
+      } else {
+        // fallback for old IE < 11, without subarray/set methods
+        for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {
+          packedFilter[packedFilterPtr++] = fxpFilter[idx];
+        }
+      }
+    } else {
+      // zero data, write header only
+      packedFilter[packedFilterPtr++] = 0; // shift
+
+      packedFilter[packedFilterPtr++] = 0; // size
+    }
+  }
+
+  return packedFilter;
+};
+
+},{"./resize_filter_info":7}],7:[function(require,module,exports){
 // Filter definitions to build tables for
 // resizing convolvers.
 //
 // Presets for quality 0..3. Filter functions + window size
 //
-               'use strict';
-               
-               module.exports = [{
-                       // Nearest neibor (Box)
-                       win: 0.5,
-                       filter: function filter(x) {
-                               return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;
-                       }
-               }, {
-                       // Hamming
-                       win: 1.0,
-                       filter: function filter(x) {
-                               if (x <= -1.0 || x >= 1.0) {
-                                       return 0.0;
-                               }
-                               
-                               if (x > -1.19209290E-07 && x < 1.19209290E-07) {
-                                       return 1.0;
-                               }
-                               
-                               var xpi = x * Math.PI;
-                               return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));
-                       }
-               }, {
-                       // Lanczos, win = 2
-                       win: 2.0,
-                       filter: function filter(x) {
-                               if (x <= -2.0 || x >= 2.0) {
-                                       return 0.0;
-                               }
-                               
-                               if (x > -1.19209290E-07 && x < 1.19209290E-07) {
-                                       return 1.0;
-                               }
-                               
-                               var xpi = x * Math.PI;
-                               return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);
-                       }
-               }, {
-                       // Lanczos, win = 3
-                       win: 3.0,
-                       filter: function filter(x) {
-                               if (x <= -3.0 || x >= 3.0) {
-                                       return 0.0;
-                               }
-                               
-                               if (x > -1.19209290E-07 && x < 1.19209290E-07) {
-                                       return 1.0;
-                               }
-                               
-                               var xpi = x * Math.PI;
-                               return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);
-                       }
-               }];
-               
-       },{}],8:[function(require,module,exports){
-               'use strict';
-               
-               var createFilters = require('./resize_filter_gen');
-               
-               function resetAlpha(dst, width, height) {
-                       var ptr = 3,
-                               len = width * height * 4 | 0;
-                       
-                       while (ptr < len) {
-                               dst[ptr] = 0xFF;
-                               ptr = ptr + 4 | 0;
-                       }
-               }
-               
-               function asUint8Array(src) {
-                       return new Uint8Array(src.buffer, 0, src.byteLength);
-               }
-               
-               var IS_LE = true; // should not crash everything on module load in old browsers
-               
-               try {
-                       IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;
-               } catch (__) {}
-               
-               function copyInt16asLE(src, target, target_offset) {
-                       if (IS_LE) {
-                               target.set(asUint8Array(src), target_offset);
-                               return;
-                       }
-                       
-                       for (var ptr = target_offset, i = 0; i < src.length; i++) {
-                               var data = src[i];
-                               target[ptr++] = data & 0xFF;
-                               target[ptr++] = data >> 8 & 0xFF;
-                       }
-               }
-               
-               module.exports = function resize_wasm(options) {
-                       var src = options.src;
-                       var srcW = options.width;
-                       var srcH = options.height;
-                       var destW = options.toWidth;
-                       var destH = options.toHeight;
-                       var scaleX = options.scaleX || options.toWidth / options.width;
-                       var scaleY = options.scaleY || options.toHeight / options.height;
-                       var offsetX = options.offsetX || 0.0;
-                       var offsetY = options.offsetY || 0.0;
-                       var dest = options.dest || new Uint8Array(destW * destH * 4);
-                       var quality = typeof options.quality === 'undefined' ? 3 : options.quality;
-                       var alpha = options.alpha || false;
-                       var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),
-                               filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.
-                       
-                       var src_offset = 0; // buffer between convolve passes
-                       
-                       var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));
-                       
-                       var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);
-                       
-                       var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);
-                       
-                       var alloc_bytes = filtersY_offset + filtersY.byteLength;
-                       
-                       var instance = this.__instance('resize', alloc_bytes); //
-                       // Fill memory block with data to process
-                       //
-                       
-                       
-                       var mem = new Uint8Array(this.__memory.buffer);
-                       var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome
-                       
-                       var src32 = new Uint32Array(src.buffer);
-                       mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so
-                       // speed difference is not significant vs direct .set()
-                       
-                       copyInt16asLE(filtersX, mem, filtersX_offset);
-                       copyInt16asLE(filtersY, mem, filtersY_offset); //
-                       // Now call webassembly method
-                       // emsdk does method names with '_'
-                       
-                       var fn = instance.exports.convolveHV || instance.exports._convolveHV;
-                       fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //
-                       // Copy data back to typed array
-                       //
-                       // 32-bit copy is much faster in chrome
-                       
-                       var dest32 = new Uint32Array(dest.buffer);
-                       dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.
-                       // !!! Note, canvas data is not premultipled. We don't need other
-                       // alpha corrections.
-                       
-                       if (!alpha) resetAlpha(dest, destW, destH);
-                       return dest;
-               };
-               
-       },{"./resize_filter_gen":6}],9:[function(require,module,exports){
-               'use strict';
-               
-               var GC_INTERVAL = 100;
-               
-               function Pool(create, idle) {
-                       this.create = create;
-                       this.available = [];
-                       this.acquired = {};
-                       this.lastId = 1;
-                       this.timeoutId = 0;
-                       this.idle = idle || 2000;
-               }
-               
-               Pool.prototype.acquire = function () {
-                       var _this = this;
-                       
-                       var resource;
-                       
-                       if (this.available.length !== 0) {
-                               resource = this.available.pop();
-                       } else {
-                               resource = this.create();
-                               resource.id = this.lastId++;
-                               
-                               resource.release = function () {
-                                       return _this.release(resource);
-                               };
-                       }
-                       
-                       this.acquired[resource.id] = resource;
-                       return resource;
-               };
-               
-               Pool.prototype.release = function (resource) {
-                       var _this2 = this;
-                       
-                       delete this.acquired[resource.id];
-                       resource.lastUsed = Date.now();
-                       this.available.push(resource);
-                       
-                       if (this.timeoutId === 0) {
-                               this.timeoutId = setTimeout(function () {
-                                       return _this2.gc();
-                               }, GC_INTERVAL);
-                       }
-               };
-               
-               Pool.prototype.gc = function () {
-                       var _this3 = this;
-                       
-                       var now = Date.now();
-                       this.available = this.available.filter(function (resource) {
-                               if (now - resource.lastUsed > _this3.idle) {
-                                       resource.destroy();
-                                       return false;
-                               }
-                               
-                               return true;
-                       });
-                       
-                       if (this.available.length !== 0) {
-                               this.timeoutId = setTimeout(function () {
-                                       return _this3.gc();
-                               }, GC_INTERVAL);
-                       } else {
-                               this.timeoutId = 0;
-                       }
-               };
-               
-               module.exports = Pool;
-               
-       },{}],10:[function(require,module,exports){
+'use strict';
+
+module.exports = [{
+  // Nearest neibor (Box)
+  win: 0.5,
+  filter: function filter(x) {
+    return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;
+  }
+}, {
+  // Hamming
+  win: 1.0,
+  filter: function filter(x) {
+    if (x <= -1.0 || x >= 1.0) {
+      return 0.0;
+    }
+
+    if (x > -1.19209290E-07 && x < 1.19209290E-07) {
+      return 1.0;
+    }
+
+    var xpi = x * Math.PI;
+    return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));
+  }
+}, {
+  // Lanczos, win = 2
+  win: 2.0,
+  filter: function filter(x) {
+    if (x <= -2.0 || x >= 2.0) {
+      return 0.0;
+    }
+
+    if (x > -1.19209290E-07 && x < 1.19209290E-07) {
+      return 1.0;
+    }
+
+    var xpi = x * Math.PI;
+    return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);
+  }
+}, {
+  // Lanczos, win = 3
+  win: 3.0,
+  filter: function filter(x) {
+    if (x <= -3.0 || x >= 3.0) {
+      return 0.0;
+    }
+
+    if (x > -1.19209290E-07 && x < 1.19209290E-07) {
+      return 1.0;
+    }
+
+    var xpi = x * Math.PI;
+    return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);
+  }
+}];
+
+},{}],8:[function(require,module,exports){
+'use strict';
+
+var createFilters = require('./resize_filter_gen');
+
+function resetAlpha(dst, width, height) {
+  var ptr = 3,
+      len = width * height * 4 | 0;
+
+  while (ptr < len) {
+    dst[ptr] = 0xFF;
+    ptr = ptr + 4 | 0;
+  }
+}
+
+function asUint8Array(src) {
+  return new Uint8Array(src.buffer, 0, src.byteLength);
+}
+
+var IS_LE = true; // should not crash everything on module load in old browsers
+
+try {
+  IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;
+} catch (__) {}
+
+function copyInt16asLE(src, target, target_offset) {
+  if (IS_LE) {
+    target.set(asUint8Array(src), target_offset);
+    return;
+  }
+
+  for (var ptr = target_offset, i = 0; i < src.length; i++) {
+    var data = src[i];
+    target[ptr++] = data & 0xFF;
+    target[ptr++] = data >> 8 & 0xFF;
+  }
+}
+
+module.exports = function resize_wasm(options) {
+  var src = options.src;
+  var srcW = options.width;
+  var srcH = options.height;
+  var destW = options.toWidth;
+  var destH = options.toHeight;
+  var scaleX = options.scaleX || options.toWidth / options.width;
+  var scaleY = options.scaleY || options.toHeight / options.height;
+  var offsetX = options.offsetX || 0.0;
+  var offsetY = options.offsetY || 0.0;
+  var dest = options.dest || new Uint8Array(destW * destH * 4);
+  var quality = typeof options.quality === 'undefined' ? 3 : options.quality;
+  var alpha = options.alpha || false;
+  var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),
+      filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.
+
+  var src_offset = 0; // buffer between convolve passes
+
+  var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));
+
+  var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);
+
+  var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);
+
+  var alloc_bytes = filtersY_offset + filtersY.byteLength;
+
+  var instance = this.__instance('resize', alloc_bytes); //
+  // Fill memory block with data to process
+  //
+
+
+  var mem = new Uint8Array(this.__memory.buffer);
+  var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome
+
+  var src32 = new Uint32Array(src.buffer);
+  mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so
+  // speed difference is not significant vs direct .set()
+
+  copyInt16asLE(filtersX, mem, filtersX_offset);
+  copyInt16asLE(filtersY, mem, filtersY_offset); //
+  // Now call webassembly method
+  // emsdk does method names with '_'
+
+  var fn = instance.exports.convolveHV || instance.exports._convolveHV;
+  fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //
+  // Copy data back to typed array
+  //
+  // 32-bit copy is much faster in chrome
+
+  var dest32 = new Uint32Array(dest.buffer);
+  dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.
+  // !!! Note, canvas data is not premultipled. We don't need other
+  // alpha corrections.
+
+  if (!alpha) resetAlpha(dest, destW, destH);
+  return dest;
+};
+
+},{"./resize_filter_gen":6}],9:[function(require,module,exports){
+'use strict';
+
+var GC_INTERVAL = 100;
+
+function Pool(create, idle) {
+  this.create = create;
+  this.available = [];
+  this.acquired = {};
+  this.lastId = 1;
+  this.timeoutId = 0;
+  this.idle = idle || 2000;
+}
+
+Pool.prototype.acquire = function () {
+  var _this = this;
+
+  var resource;
+
+  if (this.available.length !== 0) {
+    resource = this.available.pop();
+  } else {
+    resource = this.create();
+    resource.id = this.lastId++;
+
+    resource.release = function () {
+      return _this.release(resource);
+    };
+  }
+
+  this.acquired[resource.id] = resource;
+  return resource;
+};
+
+Pool.prototype.release = function (resource) {
+  var _this2 = this;
+
+  delete this.acquired[resource.id];
+  resource.lastUsed = Date.now();
+  this.available.push(resource);
+
+  if (this.timeoutId === 0) {
+    this.timeoutId = setTimeout(function () {
+      return _this2.gc();
+    }, GC_INTERVAL);
+  }
+};
+
+Pool.prototype.gc = function () {
+  var _this3 = this;
+
+  var now = Date.now();
+  this.available = this.available.filter(function (resource) {
+    if (now - resource.lastUsed > _this3.idle) {
+      resource.destroy();
+      return false;
+    }
+
+    return true;
+  });
+
+  if (this.available.length !== 0) {
+    this.timeoutId = setTimeout(function () {
+      return _this3.gc();
+    }, GC_INTERVAL);
+  } else {
+    this.timeoutId = 0;
+  }
+};
+
+module.exports = Pool;
+
+},{}],10:[function(require,module,exports){
 // Add intermediate resizing steps when scaling down by a very large factor.
 //
 // For example, when resizing 10000x10000 down to 10x10, it'll resize it to
@@ -618,640 +597,646 @@ THE SOFTWARE. */
 // Also, adding intermediate steps can speed up processing if we use lower
 // quality algorithms for first stages.
 //
-               'use strict'; // min size = 0 results in infinite loop,
+'use strict'; // min size = 0 results in infinite loop,
 // min size = 1 can consume large amount of memory
-               
-               var MIN_INNER_TILE_SIZE = 2;
-               
-               module.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {
-                       var scaleX = toWidth / fromWidth;
-                       var scaleY = toHeight / fromHeight; // derived from createRegions equation:
-                       // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;
-                       
-                       var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,
-                       // it could only happen because of invalid options
-                       
-                       if (minScale > 0.5) return [[toWidth, toHeight]];
-                       var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,
-                       // stageCount can be zero or be negative when enlarging the image
-                       
-                       if (stageCount <= 1) return [[toWidth, toHeight]];
-                       var result = [];
-                       
-                       for (var i = 0; i < stageCount; i++) {
-                               var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));
-                               var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));
-                               result.push([width, height]);
-                       }
-                       
-                       return result;
-               };
-               
-       },{}],11:[function(require,module,exports){
+
+var MIN_INNER_TILE_SIZE = 2;
+
+module.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {
+  var scaleX = toWidth / fromWidth;
+  var scaleY = toHeight / fromHeight; // derived from createRegions equation:
+  // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;
+
+  var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,
+  // it could only happen because of invalid options
+
+  if (minScale > 0.5) return [[toWidth, toHeight]];
+  var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,
+  // stageCount can be zero or be negative when enlarging the image
+
+  if (stageCount <= 1) return [[toWidth, toHeight]];
+  var result = [];
+
+  for (var i = 0; i < stageCount; i++) {
+    var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));
+    var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));
+    result.push([width, height]);
+  }
+
+  return result;
+};
+
+},{}],11:[function(require,module,exports){
 // Split original image into multiple 1024x1024 chunks to reduce memory usage
 // (images have to be unpacked into typed arrays for resizing) and allow
 // parallel processing of multiple tiles at a time.
 //
-               'use strict';
-               /*
               * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil
               * functions which take into account floating point arithmetic errors.
               * Those errors can cause undesired increments/decrements of sizes and offsets:
               * Math.ceil(36 / (36 / 500)) = 501
               * pixelCeil(36 / (36 / 500)) = 500
               */
-               
-               var PIXEL_EPSILON = 1e-5;
-               
-               function pixelFloor(x) {
-                       var nearest = Math.round(x);
-                       
-                       if (Math.abs(x - nearest) < PIXEL_EPSILON) {
-                               return nearest;
-                       }
-                       
-                       return Math.floor(x);
-               }
-               
-               function pixelCeil(x) {
-                       var nearest = Math.round(x);
-                       
-                       if (Math.abs(x - nearest) < PIXEL_EPSILON) {
-                               return nearest;
-                       }
-                       
-                       return Math.ceil(x);
-               }
-               
-               module.exports = function createRegions(options) {
-                       var scaleX = options.toWidth / options.width;
-                       var scaleY = options.toHeight / options.height;
-                       var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;
-                       var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen
-                       
-                       if (innerTileWidth < 1 || innerTileHeight < 1) {
-                               throw new Error('Internal error in pica: target tile width/height is too small.');
-                       }
-                       
-                       var x, y;
-                       var innerX, innerY, toTileWidth, toTileHeight;
-                       var tiles = [];
-                       var tile; // we go top-to-down instead of left-to-right to make image displayed from top to
-                       // doesn in the browser
-                       
-                       for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {
-                               for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {
-                                       x = innerX - options.destTileBorder;
-                                       
-                                       if (x < 0) {
-                                               x = 0;
-                                       }
-                                       
-                                       toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;
-                                       
-                                       if (x + toTileWidth >= options.toWidth) {
-                                               toTileWidth = options.toWidth - x;
-                                       }
-                                       
-                                       y = innerY - options.destTileBorder;
-                                       
-                                       if (y < 0) {
-                                               y = 0;
-                                       }
-                                       
-                                       toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;
-                                       
-                                       if (y + toTileHeight >= options.toHeight) {
-                                               toTileHeight = options.toHeight - y;
-                                       }
-                                       
-                                       tile = {
-                                               toX: x,
-                                               toY: y,
-                                               toWidth: toTileWidth,
-                                               toHeight: toTileHeight,
-                                               toInnerX: innerX,
-                                               toInnerY: innerY,
-                                               toInnerWidth: innerTileWidth,
-                                               toInnerHeight: innerTileHeight,
-                                               offsetX: x / scaleX - pixelFloor(x / scaleX),
-                                               offsetY: y / scaleY - pixelFloor(y / scaleY),
-                                               scaleX: scaleX,
-                                               scaleY: scaleY,
-                                               x: pixelFloor(x / scaleX),
-                                               y: pixelFloor(y / scaleY),
-                                               width: pixelCeil(toTileWidth / scaleX),
-                                               height: pixelCeil(toTileHeight / scaleY)
-                                       };
-                                       tiles.push(tile);
-                               }
-                       }
-                       
-                       return tiles;
-               };
-               
-       },{}],12:[function(require,module,exports){
-               'use strict';
-               
-               function objClass(obj) {
-                       return Object.prototype.toString.call(obj);
-               }
-               
-               module.exports.isCanvas = function isCanvas(element) {
-                       //return (element.nodeName && element.nodeName.toLowerCase() === 'canvas') ||
-                       var cname = objClass(element);
-                       return cname === '[object HTMLCanvasElement]'
-                               /* browser */
-                               || cname === '[object Canvas]'
-                               /* node-canvas */
-                               ;
-               };
-               
-               module.exports.isImage = function isImage(element) {
-                       //return element.nodeName && element.nodeName.toLowerCase() === 'img';
-                       return objClass(element) === '[object HTMLImageElement]';
-               };
-               
-               module.exports.limiter = function limiter(concurrency) {
-                       var active = 0,
-                               queue = [];
-                       
-                       function roll() {
-                               if (active < concurrency && queue.length) {
-                                       active++;
-                                       queue.shift()();
-                               }
-                       }
-                       
-                       return function limit(fn) {
-                               return new Promise(function (resolve, reject) {
-                                       queue.push(function () {
-                                               fn().then(function (result) {
-                                                       resolve(result);
-                                                       active--;
-                                                       roll();
-                                               }, function (err) {
-                                                       reject(err);
-                                                       active--;
-                                                       roll();
-                                               });
-                                       });
-                                       roll();
-                               });
-                       };
-               };
-               
-               module.exports.cib_quality_name = function cib_quality_name(num) {
-                       switch (num) {
-                               case 0:
-                                       return 'pixelated';
-                               
-                               case 1:
-                                       return 'low';
-                               
-                               case 2:
-                                       return 'medium';
-                       }
-                       
-                       return 'high';
-               };
-               
-               module.exports.cib_support = function cib_support() {
-                       return Promise.resolve().then(function () {
-                               if (typeof createImageBitmap === 'undefined' || typeof document === 'undefined') {
-                                       return false;
-                               }
-                               
-                               var c = document.createElement('canvas');
-                               c.width = 100;
-                               c.height = 100;
-                               return createImageBitmap(c, 0, 0, 100, 100, {
-                                       resizeWidth: 10,
-                                       resizeHeight: 10,
-                                       resizeQuality: 'high'
-                               }).then(function (bitmap) {
-                                       var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize
-                                       // detection for basic ImageBitmap.
-                                       //
-                                       // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap
-                                       // old Crome 51 has ImageBitmap without .close(). Then this code
-                                       // will throw and return 'false' as expected.
-                                       //
-                                       
-                                       bitmap.close();
-                                       c = null;
-                                       return status;
-                               });
-                       }).catch(function () {
-                               return false;
-                       });
-               };
-               
-       },{}],13:[function(require,module,exports){
+'use strict';
+/*
+ * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil
+ * functions which take into account floating point arithmetic errors.
+ * Those errors can cause undesired increments/decrements of sizes and offsets:
+ * Math.ceil(36 / (36 / 500)) = 501
+ * pixelCeil(36 / (36 / 500)) = 500
+ */
+
+var PIXEL_EPSILON = 1e-5;
+
+function pixelFloor(x) {
+  var nearest = Math.round(x);
+
+  if (Math.abs(x - nearest) < PIXEL_EPSILON) {
+    return nearest;
+  }
+
+  return Math.floor(x);
+}
+
+function pixelCeil(x) {
+  var nearest = Math.round(x);
+
+  if (Math.abs(x - nearest) < PIXEL_EPSILON) {
+    return nearest;
+  }
+
+  return Math.ceil(x);
+}
+
+module.exports = function createRegions(options) {
+  var scaleX = options.toWidth / options.width;
+  var scaleY = options.toHeight / options.height;
+  var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;
+  var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen
+
+  if (innerTileWidth < 1 || innerTileHeight < 1) {
+    throw new Error('Internal error in pica: target tile width/height is too small.');
+  }
+
+  var x, y;
+  var innerX, innerY, toTileWidth, toTileHeight;
+  var tiles = [];
+  var tile; // we go top-to-down instead of left-to-right to make image displayed from top to
+  // doesn in the browser
+
+  for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {
+    for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {
+      x = innerX - options.destTileBorder;
+
+      if (x < 0) {
+        x = 0;
+      }
+
+      toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;
+
+      if (x + toTileWidth >= options.toWidth) {
+        toTileWidth = options.toWidth - x;
+      }
+
+      y = innerY - options.destTileBorder;
+
+      if (y < 0) {
+        y = 0;
+      }
+
+      toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;
+
+      if (y + toTileHeight >= options.toHeight) {
+        toTileHeight = options.toHeight - y;
+      }
+
+      tile = {
+        toX: x,
+        toY: y,
+        toWidth: toTileWidth,
+        toHeight: toTileHeight,
+        toInnerX: innerX,
+        toInnerY: innerY,
+        toInnerWidth: innerTileWidth,
+        toInnerHeight: innerTileHeight,
+        offsetX: x / scaleX - pixelFloor(x / scaleX),
+        offsetY: y / scaleY - pixelFloor(y / scaleY),
+        scaleX: scaleX,
+        scaleY: scaleY,
+        x: pixelFloor(x / scaleX),
+        y: pixelFloor(y / scaleY),
+        width: pixelCeil(toTileWidth / scaleX),
+        height: pixelCeil(toTileHeight / scaleY)
+      };
+      tiles.push(tile);
+    }
+  }
+
+  return tiles;
+};
+
+},{}],12:[function(require,module,exports){
+'use strict';
+
+function objClass(obj) {
+  return Object.prototype.toString.call(obj);
+}
+
+module.exports.isCanvas = function isCanvas(element) {
+  //return (element.nodeName && element.nodeName.toLowerCase() === 'canvas') ||
+  var cname = objClass(element);
+  return cname === '[object HTMLCanvasElement]'
+  /* browser */
+  || cname === '[object Canvas]'
+  /* node-canvas */
+  ;
+};
+
+module.exports.isImage = function isImage(element) {
+  //return element.nodeName && element.nodeName.toLowerCase() === 'img';
+  return objClass(element) === '[object HTMLImageElement]';
+};
+
+module.exports.limiter = function limiter(concurrency) {
+  var active = 0,
+      queue = [];
+
+  function roll() {
+    if (active < concurrency && queue.length) {
+      active++;
+      queue.shift()();
+    }
+  }
+
+  return function limit(fn) {
+    return new Promise(function (resolve, reject) {
+      queue.push(function () {
+        fn().then(function (result) {
+          resolve(result);
+          active--;
+          roll();
+        }, function (err) {
+          reject(err);
+          active--;
+          roll();
+        });
+      });
+      roll();
+    });
+  };
+};
+
+module.exports.cib_quality_name = function cib_quality_name(num) {
+  switch (num) {
+    case 0:
+      return 'pixelated';
+
+    case 1:
+      return 'low';
+
+    case 2:
+      return 'medium';
+  }
+
+  return 'high';
+};
+
+module.exports.cib_support = function cib_support() {
+  return Promise.resolve().then(function () {
+    if (typeof createImageBitmap === 'undefined' || typeof document === 'undefined') {
+      return false;
+    }
+
+    var c = document.createElement('canvas');
+    c.width = 100;
+    c.height = 100;
+    return createImageBitmap(c, 0, 0, 100, 100, {
+      resizeWidth: 10,
+      resizeHeight: 10,
+      resizeQuality: 'high'
+    }).then(function (bitmap) {
+      var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize
+      // detection for basic ImageBitmap.
+      //
+      // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap
+      // old Crome 51 has ImageBitmap without .close(). Then this code
+      // will throw and return 'false' as expected.
+      //
+
+      bitmap.close();
+      c = null;
+      return status;
+    });
+  })["catch"](function () {
+    return false;
+  });
+};
+
+},{}],13:[function(require,module,exports){
 // Web Worker wrapper for image resize function
-               'use strict';
-               
-               module.exports = function () {
-                       var MathLib = require('./mathlib');
-                       
-                       var mathLib;
-                       /* eslint-disable no-undef */
-                       
-                       onmessage = function onmessage(ev) {
-                               var opts = ev.data.opts;
-                               if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,
-                               // because polyfills are not propagated to webworker.
-                               
-                               var result = mathLib.resizeAndUnsharp(opts);
-                               postMessage({
-                                       result: result
-                               }, [result.buffer]);
-                       };
-               };
-               
-       },{"./mathlib":1}],14:[function(require,module,exports){
+'use strict';
+
+module.exports = function () {
+  var MathLib = require('./mathlib');
+
+  var mathLib;
+  /* eslint-disable no-undef */
+
+  onmessage = function onmessage(ev) {
+    var opts = ev.data.opts;
+    if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,
+    // because polyfills are not propagated to webworker.
+
+    var result = mathLib.resizeAndUnsharp(opts);
+    postMessage({
+      result: result
+    }, [result.buffer]);
+  };
+};
+
+},{"./mathlib":1}],14:[function(require,module,exports){
 // Calculate Gaussian blur of an image using IIR filter
 // The method is taken from Intel's white paper and code example attached to it:
 // https://software.intel.com/en-us/articles/iir-gaussian-blur-filter
 // -implementation-using-intel-advanced-vector-extensions
-               
-               var a0, a1, a2, a3, b1, b2, left_corner, right_corner;
-               
-               function gaussCoef(sigma) {
-                       if (sigma < 0.5) {
-                               sigma = 0.5;
-                       }
-                       
-                       var a = Math.exp(0.726 * 0.726) / sigma,
-                               g1 = Math.exp(-a),
-                               g2 = Math.exp(-2 * a),
-                               k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);
-                       
-                       a0 = k;
-                       a1 = k * (a - 1) * g1;
-                       a2 = k * (a + 1) * g1;
-                       a3 = -k * g2;
-                       b1 = 2 * g1;
-                       b2 = -g2;
-                       left_corner = (a0 + a1) / (1 - b1 - b2);
-                       right_corner = (a2 + a3) / (1 - b1 - b2);
-                       
-                       // Attempt to force type to FP32.
-                       return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);
-               }
-               
-               function convolveMono16(src, out, line, coeff, width, height) {
-                       // takes src image and writes the blurred and transposed result into out
-                       
-                       var prev_src, curr_src, curr_out, prev_out, prev_prev_out;
-                       var src_index, out_index, line_index;
-                       var i, j;
-                       var coeff_a0, coeff_a1, coeff_b1, coeff_b2;
-                       
-                       for (i = 0; i < height; i++) {
-                               src_index = i * width;
-                               out_index = i;
-                               line_index = 0;
-                               
-                               // left to right
-                               prev_src = src[src_index];
-                               prev_prev_out = prev_src * coeff[6];
-                               prev_out = prev_prev_out;
-                               
-                               coeff_a0 = coeff[0];
-                               coeff_a1 = coeff[1];
-                               coeff_b1 = coeff[4];
-                               coeff_b2 = coeff[5];
-                               
-                               for (j = 0; j < width; j++) {
-                                       curr_src = src[src_index];
-                                       
-                                       curr_out = curr_src * coeff_a0 +
-                                               prev_src * coeff_a1 +
-                                               prev_out * coeff_b1 +
-                                               prev_prev_out * coeff_b2;
-                                       
-                                       prev_prev_out = prev_out;
-                                       prev_out = curr_out;
-                                       prev_src = curr_src;
-                                       
-                                       line[line_index] = prev_out;
-                                       line_index++;
-                                       src_index++;
-                               }
-                               
-                               src_index--;
-                               line_index--;
-                               out_index += height * (width - 1);
-                               
-                               // right to left
-                               prev_src = src[src_index];
-                               prev_prev_out = prev_src * coeff[7];
-                               prev_out = prev_prev_out;
-                               curr_src = prev_src;
-                               
-                               coeff_a0 = coeff[2];
-                               coeff_a1 = coeff[3];
-                               
-                               for (j = width - 1; j >= 0; j--) {
-                                       curr_out = curr_src * coeff_a0 +
-                                               prev_src * coeff_a1 +
-                                               prev_out * coeff_b1 +
-                                               prev_prev_out * coeff_b2;
-                                       
-                                       prev_prev_out = prev_out;
-                                       prev_out = curr_out;
-                                       
-                                       prev_src = curr_src;
-                                       curr_src = src[src_index];
-                                       
-                                       out[out_index] = line[line_index] + prev_out;
-                                       
-                                       src_index--;
-                                       line_index--;
-                                       out_index -= height;
-                               }
-                       }
-               }
-               
-               
-               function blurMono16(src, width, height, radius) {
-                       // Quick exit on zero radius
-                       if (!radius) { return; }
-                       
-                       var out      = new Uint16Array(src.length),
-                               tmp_line = new Float32Array(Math.max(width, height));
-                       
-                       var coeff = gaussCoef(radius);
-                       
-                       convolveMono16(src, out, tmp_line, coeff, width, height, radius);
-                       convolveMono16(out, src, tmp_line, coeff, height, width, radius);
-               }
-               
-               module.exports = blurMono16;
-               
-       },{}],15:[function(require,module,exports){
-               if (typeof Object.create === 'function') {
-                       // implementation from standard node.js 'util' module
-                       module.exports = function inherits(ctor, superCtor) {
-                               ctor.super_ = superCtor
-                               ctor.prototype = Object.create(superCtor.prototype, {
-                                       constructor: {
-                                               value: ctor,
-                                               enumerable: false,
-                                               writable: true,
-                                               configurable: true
-                                       }
-                               });
-                       };
-               } else {
-                       // old school shim for old browsers
-                       module.exports = function inherits(ctor, superCtor) {
-                               ctor.super_ = superCtor
-                               var TempCtor = function () {}
-                               TempCtor.prototype = superCtor.prototype
-                               ctor.prototype = new TempCtor()
-                               ctor.prototype.constructor = ctor
-                       }
-               }
-               
-       },{}],16:[function(require,module,exports){
-               'use strict';
-               
-               
-               var assign         = require('object-assign');
-               var base64decode   = require('./lib/base64decode');
-               var hasWebAssembly = require('./lib/wa_detect');
-               
-               
-               var DEFAULT_OPTIONS = {
-                       js: true,
-                       wasm: true
-               };
-               
-               
-               function MultiMath(options) {
-                       if (!(this instanceof MultiMath)) return new MultiMath(options);
-                       
-                       var opts = assign({}, DEFAULT_OPTIONS, options || {});
-                       
-                       this.options         = opts;
-                       
-                       this.__cache         = {};
-                       this.has_wasm        = hasWebAssembly();
-                       
-                       this.__init_promise  = null;
-                       this.__modules       = opts.modules || {};
-                       this.__memory        = null;
-                       this.__wasm          = {};
-                       
-                       this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);
-                       
-                       if (!this.options.js && !this.options.wasm) {
-                               throw new Error('mathlib: at least "js" or "wasm" should be enabled');
-                       }
-               }
-               
-               
-               MultiMath.prototype.use = function (module) {
-                       this.__modules[module.name] = module;
-                       
-                       // Pin the best possible implementation
-                       if (!this.has_wasm || !this.options.wasm || !module.wasm_fn) {
-                               this[module.name] = module.fn;
-                       } else {
-                               this[module.name] = module.wasm_fn;
-                       }
-                       
-                       return this;
-               };
-               
-               
-               MultiMath.prototype.init = function () {
-                       if (this.__init_promise) return this.__init_promise;
-                       
-                       if (!this.options.js && this.options.wasm && !this.has_wasm) {
-                               return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));
-                       }
-                       
-                       var self = this;
-                       
-                       this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {
-                                       var module = self.__modules[name];
-                                       
-                                       if (!self.has_wasm || !self.options.wasm || !module.wasm_fn) return null;
-                                       
-                                       // If already compiled - exit
-                                       if (self.__wasm[name]) return null;
-                                       
-                                       // Compile wasm source
-                                       return WebAssembly.compile(self.__base64decode(module.wasm_src))
-                                               .then(function (m) { self.__wasm[name] = m; });
-                               }))
-                               .then(function () { return self; });
-                       
-                       return this.__init_promise;
-               };
 
+var a0, a1, a2, a3, b1, b2, left_corner, right_corner;
 
-////////////////////////////////////////////////////////////////////////////////
-// Methods below are for internal use from plugins
+function gaussCoef(sigma) {
+  if (sigma < 0.5) {
+    sigma = 0.5;
+  }
 
+  var a = Math.exp(0.726 * 0.726) / sigma,
+      g1 = Math.exp(-a),
+      g2 = Math.exp(-2 * a),
+      k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);
 
-// Simple decode base64 to typed array. Useful to load embedded webassembly
-// code. You probably don't need to call this method directly.
-//
-               MultiMath.prototype.__base64decode = base64decode;
+  a0 = k;
+  a1 = k * (a - 1) * g1;
+  a2 = k * (a + 1) * g1;
+  a3 = -k * g2;
+  b1 = 2 * g1;
+  b2 = -g2;
+  left_corner = (a0 + a1) / (1 - b1 - b2);
+  right_corner = (a2 + a3) / (1 - b1 - b2);
 
+  // Attempt to force type to FP32.
+  return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);
+}
 
-// Increase current memory to include specified number of bytes. Do nothing if
-// size is already ok. You probably don't need to call this method directly,
-// because it will be invoked from `.__instance()`.
-//
-               MultiMath.prototype.__reallocate = function mem_grow_to(bytes) {
-                       if (!this.__memory) {
-                               this.__memory = new WebAssembly.Memory({
-                                       initial: Math.ceil(bytes / (64 * 1024))
-                               });
-                               return this.__memory;
-                       }
-                       
-                       var mem_size = this.__memory.buffer.byteLength;
-                       
-                       if (mem_size < bytes) {
-                               this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));
-                       }
-                       
-                       return this.__memory;
-               };
+function convolveMono16(src, out, line, coeff, width, height) {
+  // takes src image and writes the blurred and transposed result into out
 
+  var prev_src, curr_src, curr_out, prev_out, prev_prev_out;
+  var src_index, out_index, line_index;
+  var i, j;
+  var coeff_a0, coeff_a1, coeff_b1, coeff_b2;
 
-// Returns instantinated webassembly item by name, with specified memory size
-// and environment.
-// - use cache if available
-// - do sync module init, if async init was not called earlier
-// - allocate memory if not enougth
-// - can export functions to webassembly via "env_extra",
-//   for example, { exp: Math.exp }
-//
-               MultiMath.prototype.__instance = function instance(name, memsize, env_extra) {
-                       if (memsize) this.__reallocate(memsize);
-                       
-                       // If .init() was not called, do sync compile
-                       if (!this.__wasm[name]) {
-                               var module = this.__modules[name];
-                               this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));
-                       }
-                       
-                       if (!this.__cache[name]) {
-                               var env_base = {
-                                       memoryBase: 0,
-                                       memory: this.__memory,
-                                       tableBase: 0,
-                                       table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
-                               };
-                               
-                               this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {
-                                       env: assign(env_base, env_extra || {})
-                               });
-                       }
-                       
-                       return this.__cache[name];
-               };
+  for (i = 0; i < height; i++) {
+    src_index = i * width;
+    out_index = i;
+    line_index = 0;
 
+    // left to right
+    prev_src = src[src_index];
+    prev_prev_out = prev_src * coeff[6];
+    prev_out = prev_prev_out;
 
-// Helper to calculate memory aligh for pointers. Webassembly does not require
-// this, but you may wish to experiment. Default base = 8;
-//
-               MultiMath.prototype.__align = function align(number, base) {
-                       base = base || 8;
-                       var reminder = number % base;
-                       return number + (reminder ? base - reminder : 0);
-               };
-               
-               
-               module.exports = MultiMath;
-               
-       },{"./lib/base64decode":17,"./lib/wa_detect":23,"object-assign":24}],17:[function(require,module,exports){
-// base64 decode str -> Uint8Array, to load WA modules
-//
-               'use strict';
-               
-               
-               var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-               
-               
-               module.exports = function base64decode(str) {
-                       var input = str.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
-                               max   = input.length;
-                       
-                       var out = new Uint8Array((max * 3) >> 2);
-                       
-                       // Collect by 6*4 bits (3 bytes)
-                       
-                       var bits = 0;
-                       var ptr  = 0;
-                       
-                       for (var idx = 0; idx < max; idx++) {
-                               if ((idx % 4 === 0) && idx) {
-                                       out[ptr++] = (bits >> 16) & 0xFF;
-                                       out[ptr++] = (bits >> 8) & 0xFF;
-                                       out[ptr++] = bits & 0xFF;
-                               }
-                               
-                               bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));
-                       }
-                       
-                       // Dump tail
-                       
-                       var tailbits = (max % 4) * 6;
-                       
-                       if (tailbits === 0) {
-                               out[ptr++] = (bits >> 16) & 0xFF;
-                               out[ptr++] = (bits >> 8) & 0xFF;
-                               out[ptr++] = bits & 0xFF;
-                       } else if (tailbits === 18) {
-                               out[ptr++] = (bits >> 10) & 0xFF;
-                               out[ptr++] = (bits >> 2) & 0xFF;
-                       } else if (tailbits === 12) {
-                               out[ptr++] = (bits >> 4) & 0xFF;
-                       }
-                       
-                       return out;
-               };
-               
-       },{}],18:[function(require,module,exports){
-// Calculates 16-bit precision HSL lightness from 8-bit rgba buffer
-//
-               'use strict';
-               
-               
-               module.exports = function hsl_l16_js(img, width, height) {
-                       var size = width * height;
-                       var out = new Uint16Array(size);
-                       var r, g, b, min, max;
-                       for (var i = 0; i < size; i++) {
-                               r = img[4 * i];
-                               g = img[4 * i + 1];
-                               b = img[4 * i + 2];
-                               max = (r >= g && r >= b) ? r : (g >= b && g >= r) ? g : b;
-                               min = (r <= g && r <= b) ? r : (g <= b && g <= r) ? g : b;
-                               out[i] = (max + min) * 257 >> 1;
-                       }
-                       return out;
-               };
-               
-       },{}],19:[function(require,module,exports){
-               'use strict';
-               
-               module.exports = {
-                       name:     'unsharp_mask',
-                       fn:       require('./unsharp_mask'),
-                       wasm_fn:  require('./unsharp_mask_wasm'),
-                       wasm_src: require('./unsharp_mask_wasm_base64')
-               };
-               
-       },{"./unsharp_mask":20,"./unsharp_mask_wasm":21,"./unsharp_mask_wasm_base64":22}],20:[function(require,module,exports){
+    coeff_a0 = coeff[0];
+    coeff_a1 = coeff[1];
+    coeff_b1 = coeff[4];
+    coeff_b2 = coeff[5];
+
+    for (j = 0; j < width; j++) {
+      curr_src = src[src_index];
+
+      curr_out = curr_src * coeff_a0 +
+                 prev_src * coeff_a1 +
+                 prev_out * coeff_b1 +
+                 prev_prev_out * coeff_b2;
+
+      prev_prev_out = prev_out;
+      prev_out = curr_out;
+      prev_src = curr_src;
+
+      line[line_index] = prev_out;
+      line_index++;
+      src_index++;
+    }
+
+    src_index--;
+    line_index--;
+    out_index += height * (width - 1);
+
+    // right to left
+    prev_src = src[src_index];
+    prev_prev_out = prev_src * coeff[7];
+    prev_out = prev_prev_out;
+    curr_src = prev_src;
+
+    coeff_a0 = coeff[2];
+    coeff_a1 = coeff[3];
+
+    for (j = width - 1; j >= 0; j--) {
+      curr_out = curr_src * coeff_a0 +
+                 prev_src * coeff_a1 +
+                 prev_out * coeff_b1 +
+                 prev_prev_out * coeff_b2;
+
+      prev_prev_out = prev_out;
+      prev_out = curr_out;
+
+      prev_src = curr_src;
+      curr_src = src[src_index];
+
+      out[out_index] = line[line_index] + prev_out;
+
+      src_index--;
+      line_index--;
+      out_index -= height;
+    }
+  }
+}
+
+
+function blurMono16(src, width, height, radius) {
+  // Quick exit on zero radius
+  if (!radius) { return; }
+
+  var out      = new Uint16Array(src.length),
+      tmp_line = new Float32Array(Math.max(width, height));
+
+  var coeff = gaussCoef(radius);
+
+  convolveMono16(src, out, tmp_line, coeff, width, height, radius);
+  convolveMono16(out, src, tmp_line, coeff, height, width, radius);
+}
+
+module.exports = blurMono16;
+
+},{}],15:[function(require,module,exports){
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    if (superCtor) {
+      ctor.super_ = superCtor
+      ctor.prototype = Object.create(superCtor.prototype, {
+        constructor: {
+          value: ctor,
+          enumerable: false,
+          writable: true,
+          configurable: true
+        }
+      })
+    }
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    if (superCtor) {
+      ctor.super_ = superCtor
+      var TempCtor = function () {}
+      TempCtor.prototype = superCtor.prototype
+      ctor.prototype = new TempCtor()
+      ctor.prototype.constructor = ctor
+    }
+  }
+}
+
+},{}],16:[function(require,module,exports){
+'use strict';
+
+
+var assign         = require('object-assign');
+var base64decode   = require('./lib/base64decode');
+var hasWebAssembly = require('./lib/wa_detect');
+
+
+var DEFAULT_OPTIONS = {
+  js: true,
+  wasm: true
+};
+
+
+function MultiMath(options) {
+  if (!(this instanceof MultiMath)) return new MultiMath(options);
+
+  var opts = assign({}, DEFAULT_OPTIONS, options || {});
+
+  this.options         = opts;
+
+  this.__cache         = {};
+
+  this.__init_promise  = null;
+  this.__modules       = opts.modules || {};
+  this.__memory        = null;
+  this.__wasm          = {};
+
+  this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);
+
+  if (!this.options.js && !this.options.wasm) {
+    throw new Error('mathlib: at least "js" or "wasm" should be enabled');
+  }
+}
+
+
+MultiMath.prototype.has_wasm = hasWebAssembly;
+
+
+MultiMath.prototype.use = function (module) {
+  this.__modules[module.name] = module;
+
+  // Pin the best possible implementation
+  if (this.options.wasm && this.has_wasm() && module.wasm_fn) {
+    this[module.name] = module.wasm_fn;
+  } else {
+    this[module.name] = module.fn;
+  }
+
+  return this;
+};
+
+
+MultiMath.prototype.init = function () {
+  if (this.__init_promise) return this.__init_promise;
+
+  if (!this.options.js && this.options.wasm && !this.has_wasm()) {
+    return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));
+  }
+
+  var self = this;
+
+  this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {
+    var module = self.__modules[name];
+
+    if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;
+
+    // If already compiled - exit
+    if (self.__wasm[name]) return null;
+
+    // Compile wasm source
+    return WebAssembly.compile(self.__base64decode(module.wasm_src))
+      .then(function (m) { self.__wasm[name] = m; });
+  }))
+    .then(function () { return self; });
+
+  return this.__init_promise;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Methods below are for internal use from plugins
+
+
+// Simple decode base64 to typed array. Useful to load embedded webassembly
+// code. You probably don't need to call this method directly.
+//
+MultiMath.prototype.__base64decode = base64decode;
+
+
+// Increase current memory to include specified number of bytes. Do nothing if
+// size is already ok. You probably don't need to call this method directly,
+// because it will be invoked from `.__instance()`.
+//
+MultiMath.prototype.__reallocate = function mem_grow_to(bytes) {
+  if (!this.__memory) {
+    this.__memory = new WebAssembly.Memory({
+      initial: Math.ceil(bytes / (64 * 1024))
+    });
+    return this.__memory;
+  }
+
+  var mem_size = this.__memory.buffer.byteLength;
+
+  if (mem_size < bytes) {
+    this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));
+  }
+
+  return this.__memory;
+};
+
+
+// Returns instantinated webassembly item by name, with specified memory size
+// and environment.
+// - use cache if available
+// - do sync module init, if async init was not called earlier
+// - allocate memory if not enougth
+// - can export functions to webassembly via "env_extra",
+//   for example, { exp: Math.exp }
+//
+MultiMath.prototype.__instance = function instance(name, memsize, env_extra) {
+  if (memsize) this.__reallocate(memsize);
+
+  // If .init() was not called, do sync compile
+  if (!this.__wasm[name]) {
+    var module = this.__modules[name];
+    this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));
+  }
+
+  if (!this.__cache[name]) {
+    var env_base = {
+      memoryBase: 0,
+      memory: this.__memory,
+      tableBase: 0,
+      table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
+    };
+
+    this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {
+      env: assign(env_base, env_extra || {})
+    });
+  }
+
+  return this.__cache[name];
+};
+
+
+// Helper to calculate memory aligh for pointers. Webassembly does not require
+// this, but you may wish to experiment. Default base = 8;
+//
+MultiMath.prototype.__align = function align(number, base) {
+  base = base || 8;
+  var reminder = number % base;
+  return number + (reminder ? base - reminder : 0);
+};
+
+
+module.exports = MultiMath;
+
+},{"./lib/base64decode":17,"./lib/wa_detect":23,"object-assign":24}],17:[function(require,module,exports){
+// base64 decode str -> Uint8Array, to load WA modules
+//
+'use strict';
+
+
+var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+
+module.exports = function base64decode(str) {
+  var input = str.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
+      max   = input.length;
+
+  var out = new Uint8Array((max * 3) >> 2);
+
+  // Collect by 6*4 bits (3 bytes)
+
+  var bits = 0;
+  var ptr  = 0;
+
+  for (var idx = 0; idx < max; idx++) {
+    if ((idx % 4 === 0) && idx) {
+      out[ptr++] = (bits >> 16) & 0xFF;
+      out[ptr++] = (bits >> 8) & 0xFF;
+      out[ptr++] = bits & 0xFF;
+    }
+
+    bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));
+  }
+
+  // Dump tail
+
+  var tailbits = (max % 4) * 6;
+
+  if (tailbits === 0) {
+    out[ptr++] = (bits >> 16) & 0xFF;
+    out[ptr++] = (bits >> 8) & 0xFF;
+    out[ptr++] = bits & 0xFF;
+  } else if (tailbits === 18) {
+    out[ptr++] = (bits >> 10) & 0xFF;
+    out[ptr++] = (bits >> 2) & 0xFF;
+  } else if (tailbits === 12) {
+    out[ptr++] = (bits >> 4) & 0xFF;
+  }
+
+  return out;
+};
+
+},{}],18:[function(require,module,exports){
+// Calculates 16-bit precision HSL lightness from 8-bit rgba buffer
+//
+'use strict';
+
+
+module.exports = function hsl_l16_js(img, width, height) {
+  var size = width * height;
+  var out = new Uint16Array(size);
+  var r, g, b, min, max;
+  for (var i = 0; i < size; i++) {
+    r = img[4 * i];
+    g = img[4 * i + 1];
+    b = img[4 * i + 2];
+    max = (r >= g && r >= b) ? r : (g >= b && g >= r) ? g : b;
+    min = (r <= g && r <= b) ? r : (g <= b && g <= r) ? g : b;
+    out[i] = (max + min) * 257 >> 1;
+  }
+  return out;
+};
+
+},{}],19:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+  name:     'unsharp_mask',
+  fn:       require('./unsharp_mask'),
+  wasm_fn:  require('./unsharp_mask_wasm'),
+  wasm_src: require('./unsharp_mask_wasm_base64')
+};
+
+},{"./unsharp_mask":20,"./unsharp_mask_wasm":21,"./unsharp_mask_wasm_base64":22}],20:[function(require,module,exports){
 // Unsharp mask filter
 //
 // http://stackoverflow.com/a/23322820/1031804
@@ -1261,963 +1246,963 @@ THE SOFTWARE. */
 // Image is converted from RGB to HSL, unsharp mask is applied to the
 // lightness channel and then image is converted back to RGB.
 //
-               'use strict';
-               
-               
-               var glur_mono16 = require('glur/mono16');
-               var hsl_l16     = require('./hsl_l16');
-               
-               
-               module.exports = function unsharp(img, width, height, amount, radius, threshold) {
-                       var r, g, b;
-                       var h, s, l;
-                       var min, max;
-                       var m1, m2, hShifted;
-                       var diff, iTimes4;
-                       
-                       if (amount === 0 || radius < 0.5) {
-                               return;
-                       }
-                       if (radius > 2.0) {
-                               radius = 2.0;
-                       }
-                       
-                       var lightness = hsl_l16(img, width, height);
-                       
-                       var blured = new Uint16Array(lightness); // copy, because blur modify src
-                       
-                       glur_mono16(blured, width, height, radius);
-                       
-                       var amountFp = (amount / 100 * 0x1000 + 0.5)|0;
-                       var thresholdFp = (threshold * 257)|0;
-                       
-                       var size = width * height;
-                       
-                       /* eslint-disable indent */
-                       for (var i = 0; i < size; i++) {
-                               diff = 2 * (lightness[i] - blured[i]);
-                               
-                               if (Math.abs(diff) >= thresholdFp) {
-                                       iTimes4 = i * 4;
-                                       r = img[iTimes4];
-                                       g = img[iTimes4 + 1];
-                                       b = img[iTimes4 + 2];
-                                       
-                                       // convert RGB to HSL
-                                       // take RGB, 8-bit unsigned integer per each channel
-                                       // save HSL, H and L are 16-bit unsigned integers, S is 12-bit unsigned integer
-                                       // math is taken from here: http://www.easyrgb.com/index.php?X=MATH&H=18
-                                       // and adopted to be integer (fixed point in fact) for sake of performance
-                                       max = (r >= g && r >= b) ? r : (g >= r && g >= b) ? g : b; // min and max are in [0..0xff]
-                                       min = (r <= g && r <= b) ? r : (g <= r && g <= b) ? g : b;
-                                       l = (max + min) * 257 >> 1; // l is in [0..0xffff] that is caused by multiplication by 257
-                                       
-                                       if (min === max) {
-                                               h = s = 0;
-                                       } else {
-                                               s = (l <= 0x7fff) ?
-                                                       (((max - min) * 0xfff) / (max + min))|0 :
-                                                       (((max - min) * 0xfff) / (2 * 0xff - max - min))|0; // s is in [0..0xfff]
-                                               // h could be less 0, it will be fixed in backward conversion to RGB, |h| <= 0xffff / 6
-                                               h = (r === max) ? (((g - b) * 0xffff) / (6 * (max - min)))|0
-                                                       : (g === max) ? 0x5555 + ((((b - r) * 0xffff) / (6 * (max - min)))|0) // 0x5555 == 0xffff / 3
-                                                               : 0xaaaa + ((((r - g) * 0xffff) / (6 * (max - min)))|0); // 0xaaaa == 0xffff * 2 / 3
-                                       }
-                                       
-                                       // add unsharp mask mask to the lightness channel
-                                       l += (amountFp * diff + 0x800) >> 12;
-                                       if (l > 0xffff) {
-                                               l = 0xffff;
-                                       } else if (l < 0) {
-                                               l = 0;
-                                       }
-                                       
-                                       // convert HSL back to RGB
-                                       // for information about math look above
-                                       if (s === 0) {
-                                               r = g = b = l >> 8;
-                                       } else {
-                                               m2 = (l <= 0x7fff) ? (l * (0x1000 + s) + 0x800) >> 12 :
-                                                       l  + (((0xffff - l) * s + 0x800) >>  12);
-                                               m1 = 2 * l - m2 >> 8;
-                                               m2 >>= 8;
-                                               // save result to RGB channels
-                                               // R channel
-                                               hShifted = (h + 0x5555) & 0xffff; // 0x5555 == 0xffff / 3
-                                               r = (hShifted >= 0xaaaa) ? m1 // 0xaaaa == 0xffff * 2 / 3
-                                                       : (hShifted >= 0x7fff) ?  m1 + ((m2 - m1) * 6 * (0xaaaa - hShifted) + 0x8000 >> 16)
-                                                               : (hShifted >= 0x2aaa) ? m2 // 0x2aaa == 0xffff / 6
-                                                                       : m1 + ((m2 - m1) * 6 * hShifted + 0x8000 >> 16);
-                                               // G channel
-                                               hShifted = h & 0xffff;
-                                               g = (hShifted >= 0xaaaa) ? m1 // 0xaaaa == 0xffff * 2 / 3
-                                                       : (hShifted >= 0x7fff) ?  m1 + ((m2 - m1) * 6 * (0xaaaa - hShifted) + 0x8000 >> 16)
-                                                               : (hShifted >= 0x2aaa) ? m2 // 0x2aaa == 0xffff / 6
-                                                                       : m1 + ((m2 - m1) * 6 * hShifted + 0x8000 >> 16);
-                                               // B channel
-                                               hShifted = (h - 0x5555) & 0xffff;
-                                               b = (hShifted >= 0xaaaa) ? m1 // 0xaaaa == 0xffff * 2 / 3
-                                                       : (hShifted >= 0x7fff) ?  m1 + ((m2 - m1) * 6 * (0xaaaa - hShifted) + 0x8000 >> 16)
-                                                               : (hShifted >= 0x2aaa) ? m2 // 0x2aaa == 0xffff / 6
-                                                                       : m1 + ((m2 - m1) * 6 * hShifted + 0x8000 >> 16);
-                                       }
-                                       
-                                       img[iTimes4] = r;
-                                       img[iTimes4 + 1] = g;
-                                       img[iTimes4 + 2] = b;
-                               }
-                       }
-               };
-               
-       },{"./hsl_l16":18,"glur/mono16":14}],21:[function(require,module,exports){
-               'use strict';
-               
-               
-               module.exports = function unsharp(img, width, height, amount, radius, threshold) {
-                       if (amount === 0 || radius < 0.5) {
-                               return;
-                       }
-                       
-                       if (radius > 2.0) {
-                               radius = 2.0;
-                       }
-                       
-                       var pixels = width * height;
-                       
-                       var img_bytes_cnt        = pixels * 4;
-                       var hsl_bytes_cnt        = pixels * 2;
-                       var blur_bytes_cnt       = pixels * 2;
-                       var blur_line_byte_cnt   = Math.max(width, height) * 4; // float32 array
-                       var blur_coeffs_byte_cnt = 8 * 4; // float32 array
-                       
-                       var img_offset         = 0;
-                       var hsl_offset         = img_bytes_cnt;
-                       var blur_offset        = hsl_offset + hsl_bytes_cnt;
-                       var blur_tmp_offset    = blur_offset + blur_bytes_cnt;
-                       var blur_line_offset   = blur_tmp_offset + blur_bytes_cnt;
-                       var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;
-                       
-                       var instance = this.__instance(
-                               'unsharp_mask',
-                               img_bytes_cnt + hsl_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt,
-                               { exp: Math.exp }
-                       );
-                       
-                       // 32-bit copy is much faster in chrome
-                       var img32 = new Uint32Array(img.buffer);
-                       var mem32 = new Uint32Array(this.__memory.buffer);
-                       mem32.set(img32);
-                       
-                       // HSL
-                       var fn = instance.exports.hsl_l16 || instance.exports._hsl_l16;
-                       fn(img_offset, hsl_offset, width, height);
-                       
-                       // BLUR
-                       fn = instance.exports.blurMono16 || instance.exports._blurMono16;
-                       fn(hsl_offset, blur_offset, blur_tmp_offset,
-                               blur_line_offset, blur_coeffs_offset, width, height, radius);
-                       
-                       // UNSHARP
-                       fn = instance.exports.unsharp || instance.exports._unsharp;
-                       fn(img_offset, img_offset, hsl_offset,
-                               blur_offset, width, height, amount, threshold);
-                       
-                       // 32-bit copy is much faster in chrome
-                       img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));
-               };
-               
-       },{}],22:[function(require,module,exports){
+'use strict';
+
+
+var glur_mono16 = require('glur/mono16');
+var hsl_l16     = require('./hsl_l16');
+
+
+module.exports = function unsharp(img, width, height, amount, radius, threshold) {
+  var r, g, b;
+  var h, s, l;
+  var min, max;
+  var m1, m2, hShifted;
+  var diff, iTimes4;
+
+  if (amount === 0 || radius < 0.5) {
+    return;
+  }
+  if (radius > 2.0) {
+    radius = 2.0;
+  }
+
+  var lightness = hsl_l16(img, width, height);
+
+  var blured = new Uint16Array(lightness); // copy, because blur modify src
+
+  glur_mono16(blured, width, height, radius);
+
+  var amountFp = (amount / 100 * 0x1000 + 0.5)|0;
+  var thresholdFp = (threshold * 257)|0;
+
+  var size = width * height;
+
+  /* eslint-disable indent */
+  for (var i = 0; i < size; i++) {
+    diff = 2 * (lightness[i] - blured[i]);
+
+    if (Math.abs(diff) >= thresholdFp) {
+      iTimes4 = i * 4;
+      r = img[iTimes4];
+      g = img[iTimes4 + 1];
+      b = img[iTimes4 + 2];
+
+      // convert RGB to HSL
+      // take RGB, 8-bit unsigned integer per each channel
+      // save HSL, H and L are 16-bit unsigned integers, S is 12-bit unsigned integer
+      // math is taken from here: http://www.easyrgb.com/index.php?X=MATH&H=18
+      // and adopted to be integer (fixed point in fact) for sake of performance
+      max = (r >= g && r >= b) ? r : (g >= r && g >= b) ? g : b; // min and max are in [0..0xff]
+      min = (r <= g && r <= b) ? r : (g <= r && g <= b) ? g : b;
+      l = (max + min) * 257 >> 1; // l is in [0..0xffff] that is caused by multiplication by 257
+
+      if (min === max) {
+        h = s = 0;
+      } else {
+        s = (l <= 0x7fff) ?
+          (((max - min) * 0xfff) / (max + min))|0 :
+          (((max - min) * 0xfff) / (2 * 0xff - max - min))|0; // s is in [0..0xfff]
+        // h could be less 0, it will be fixed in backward conversion to RGB, |h| <= 0xffff / 6
+        h = (r === max) ? (((g - b) * 0xffff) / (6 * (max - min)))|0
+          : (g === max) ? 0x5555 + ((((b - r) * 0xffff) / (6 * (max - min)))|0) // 0x5555 == 0xffff / 3
+          : 0xaaaa + ((((r - g) * 0xffff) / (6 * (max - min)))|0); // 0xaaaa == 0xffff * 2 / 3
+      }
+
+      // add unsharp mask mask to the lightness channel
+      l += (amountFp * diff + 0x800) >> 12;
+      if (l > 0xffff) {
+        l = 0xffff;
+      } else if (l < 0) {
+        l = 0;
+      }
+
+      // convert HSL back to RGB
+      // for information about math look above
+      if (s === 0) {
+        r = g = b = l >> 8;
+      } else {
+        m2 = (l <= 0x7fff) ? (l * (0x1000 + s) + 0x800) >> 12 :
+          l  + (((0xffff - l) * s + 0x800) >>  12);
+        m1 = 2 * l - m2 >> 8;
+        m2 >>= 8;
+        // save result to RGB channels
+        // R channel
+        hShifted = (h + 0x5555) & 0xffff; // 0x5555 == 0xffff / 3
+        r = (hShifted >= 0xaaaa) ? m1 // 0xaaaa == 0xffff * 2 / 3
+          : (hShifted >= 0x7fff) ?  m1 + ((m2 - m1) * 6 * (0xaaaa - hShifted) + 0x8000 >> 16)
+          : (hShifted >= 0x2aaa) ? m2 // 0x2aaa == 0xffff / 6
+          : m1 + ((m2 - m1) * 6 * hShifted + 0x8000 >> 16);
+        // G channel
+        hShifted = h & 0xffff;
+        g = (hShifted >= 0xaaaa) ? m1 // 0xaaaa == 0xffff * 2 / 3
+          : (hShifted >= 0x7fff) ?  m1 + ((m2 - m1) * 6 * (0xaaaa - hShifted) + 0x8000 >> 16)
+          : (hShifted >= 0x2aaa) ? m2 // 0x2aaa == 0xffff / 6
+          : m1 + ((m2 - m1) * 6 * hShifted + 0x8000 >> 16);
+        // B channel
+        hShifted = (h - 0x5555) & 0xffff;
+        b = (hShifted >= 0xaaaa) ? m1 // 0xaaaa == 0xffff * 2 / 3
+          : (hShifted >= 0x7fff) ?  m1 + ((m2 - m1) * 6 * (0xaaaa - hShifted) + 0x8000 >> 16)
+          : (hShifted >= 0x2aaa) ? m2 // 0x2aaa == 0xffff / 6
+          : m1 + ((m2 - m1) * 6 * hShifted + 0x8000 >> 16);
+      }
+
+      img[iTimes4] = r;
+      img[iTimes4 + 1] = g;
+      img[iTimes4 + 2] = b;
+    }
+  }
+};
+
+},{"./hsl_l16":18,"glur/mono16":14}],21:[function(require,module,exports){
+'use strict';
+
+
+module.exports = function unsharp(img, width, height, amount, radius, threshold) {
+  if (amount === 0 || radius < 0.5) {
+    return;
+  }
+
+  if (radius > 2.0) {
+    radius = 2.0;
+  }
+
+  var pixels = width * height;
+
+  var img_bytes_cnt        = pixels * 4;
+  var hsl_bytes_cnt        = pixels * 2;
+  var blur_bytes_cnt       = pixels * 2;
+  var blur_line_byte_cnt   = Math.max(width, height) * 4; // float32 array
+  var blur_coeffs_byte_cnt = 8 * 4; // float32 array
+
+  var img_offset         = 0;
+  var hsl_offset         = img_bytes_cnt;
+  var blur_offset        = hsl_offset + hsl_bytes_cnt;
+  var blur_tmp_offset    = blur_offset + blur_bytes_cnt;
+  var blur_line_offset   = blur_tmp_offset + blur_bytes_cnt;
+  var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;
+
+  var instance = this.__instance(
+    'unsharp_mask',
+    img_bytes_cnt + hsl_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt,
+    { exp: Math.exp }
+  );
+
+  // 32-bit copy is much faster in chrome
+  var img32 = new Uint32Array(img.buffer);
+  var mem32 = new Uint32Array(this.__memory.buffer);
+  mem32.set(img32);
+
+  // HSL
+  var fn = instance.exports.hsl_l16 || instance.exports._hsl_l16;
+  fn(img_offset, hsl_offset, width, height);
+
+  // BLUR
+  fn = instance.exports.blurMono16 || instance.exports._blurMono16;
+  fn(hsl_offset, blur_offset, blur_tmp_offset,
+    blur_line_offset, blur_coeffs_offset, width, height, radius);
+
+  // UNSHARP
+  fn = instance.exports.unsharp || instance.exports._unsharp;
+  fn(img_offset, img_offset, hsl_offset,
+    blur_offset, width, height, amount, threshold);
+
+  // 32-bit copy is much faster in chrome
+  img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));
+};
+
+},{}],22:[function(require,module,exports){
 // This is autogenerated file from math.wasm, don't edit.
 //
-               'use strict';
-               
-               /* eslint-disable max-len */
-               module.exports = 'AGFzbQEAAAABMQZgAXwBfGACfX8AYAZ/f39/f38AYAh/f39/f39/fQBgBH9/f38AYAh/f39/f39/fwACGQIDZW52A2V4cAAAA2VudgZtZW1vcnkCAAEDBgUBAgMEBQQEAXAAAAdMBRZfX2J1aWxkX2dhdXNzaWFuX2NvZWZzAAEOX19nYXVzczE2X2xpbmUAAgpibHVyTW9ubzE2AAMHaHNsX2wxNgAEB3Vuc2hhcnAABQkBAAqJEAXZAQEGfAJAIAFE24a6Q4Ia+z8gALujIgOaEAAiBCAEoCIGtjgCECABIANEAAAAAAAAAMCiEAAiBbaMOAIUIAFEAAAAAAAA8D8gBKEiAiACoiAEIAMgA6CiRAAAAAAAAPA/oCAFoaMiArY4AgAgASAEIANEAAAAAAAA8L+gIAKioiIHtjgCBCABIAQgA0QAAAAAAADwP6AgAqKiIgO2OAIIIAEgBSACoiIEtow4AgwgASACIAegIAVEAAAAAAAA8D8gBqGgIgKjtjgCGCABIAMgBKEgAqO2OAIcCwu3AwMDfwR9CHwCQCADKgIUIQkgAyoCECEKIAMqAgwhCyADKgIIIQwCQCAEQX9qIgdBAEgiCA0AIAIgAC8BALgiDSADKgIYu6IiDiAJuyIQoiAOIAq7IhGiIA0gAyoCBLsiEqIgAyoCALsiEyANoqCgoCIPtjgCACACQQRqIQIgAEECaiEAIAdFDQAgBCEGA0AgAiAOIBCiIA8iDiARoiANIBKiIBMgAC8BALgiDaKgoKAiD7Y4AgAgAkEEaiECIABBAmohACAGQX9qIgZBAUoNAAsLAkAgCA0AIAEgByAFbEEBdGogAEF+ai8BACIIuCINIAu7IhGiIA0gDLsiEqKgIA0gAyoCHLuiIg4gCrsiE6KgIA4gCbsiFKKgIg8gAkF8aioCALugqzsBACAHRQ0AIAJBeGohAiAAQXxqIQBBACAFQQF0ayEHIAEgBSAEQQF0QXxqbGohBgNAIAghAyAALwEAIQggBiANIBGiIAO4Ig0gEqKgIA8iECAToqAgDiAUoqAiDyACKgIAu6CrOwEAIAYgB2ohBiAAQX5qIQAgAkF8aiECIBAhDiAEQX9qIgRBAUoNAAsLCwvfAgIDfwZ8AkAgB0MAAAAAWw0AIARE24a6Q4Ia+z8gB0MAAAA/l7ujIgyaEAAiDSANoCIPtjgCECAEIAxEAAAAAAAAAMCiEAAiDraMOAIUIAREAAAAAAAA8D8gDaEiCyALoiANIAwgDKCiRAAAAAAAAPA/oCAOoaMiC7Y4AgAgBCANIAxEAAAAAAAA8L+gIAuioiIQtjgCBCAEIA0gDEQAAAAAAADwP6AgC6KiIgy2OAIIIAQgDiALoiINtow4AgwgBCALIBCgIA5EAAAAAAAA8D8gD6GgIgujtjgCGCAEIAwgDaEgC6O2OAIcIAYEQCAFQQF0IQogBiEJIAIhCANAIAAgCCADIAQgBSAGEAIgACAKaiEAIAhBAmohCCAJQX9qIgkNAAsLIAVFDQAgBkEBdCEIIAUhAANAIAIgASADIAQgBiAFEAIgAiAIaiECIAFBAmohASAAQX9qIgANAAsLC7wBAQV/IAMgAmwiAwRAQQAgA2shBgNAIAAoAgAiBEEIdiIHQf8BcSECAn8gBEH/AXEiAyAEQRB2IgRB/wFxIgVPBEAgAyIIIAMgAk8NARoLIAQgBCAHIAIgA0kbIAIgBUkbQf8BcQshCAJAIAMgAk0EQCADIAVNDQELIAQgByAEIAMgAk8bIAIgBUsbQf8BcSEDCyAAQQRqIQAgASADIAhqQYECbEEBdjsBACABQQJqIQEgBkEBaiIGDQALCwvTBgEKfwJAIAazQwAAgEWUQwAAyEKVu0QAAAAAAADgP6CqIQ0gBSAEbCILBEAgB0GBAmwhDgNAQQAgAi8BACADLwEAayIGQQF0IgdrIAcgBkEASBsgDk8EQCAAQQJqLQAAIQUCfyAALQAAIgYgAEEBai0AACIESSIJRQRAIAYiCCAGIAVPDQEaCyAFIAUgBCAEIAVJGyAGIARLGwshCAJ/IAYgBE0EQCAGIgogBiAFTQ0BGgsgBSAFIAQgBCAFSxsgCRsLIgogCGoiD0GBAmwiEEEBdiERQQAhDAJ/QQAiCSAIIApGDQAaIAggCmsiCUH/H2wgD0H+AyAIayAKayAQQYCABEkbbSEMIAYgCEYEQCAEIAVrQf//A2wgCUEGbG0MAQsgBSAGayAGIARrIAQgCEYiBhtB//8DbCAJQQZsbUHVqgFBqtUCIAYbagshCSARIAcgDWxBgBBqQQx1aiIGQQAgBkEAShsiBkH//wMgBkH//wNIGyEGAkACfwJAIAxB//8DcSIFBEAgBkH//wFKDQEgBUGAIGogBmxBgBBqQQx2DAILIAZBCHYiBiEFIAYhBAwCCyAFIAZB//8Dc2xBgBBqQQx2IAZqCyIFQQh2IQcgBkEBdCAFa0EIdiIGIQQCQCAJQdWqAWpB//8DcSIFQanVAksNACAFQf//AU8EQEGq1QIgBWsgByAGa2xBBmxBgIACakEQdiAGaiEEDAELIAchBCAFQanVAEsNACAFIAcgBmtsQQZsQYCAAmpBEHYgBmohBAsCfyAGIgUgCUH//wNxIghBqdUCSw0AGkGq1QIgCGsgByAGa2xBBmxBgIACakEQdiAGaiAIQf//AU8NABogByIFIAhBqdUASw0AGiAIIAcgBmtsQQZsQYCAAmpBEHYgBmoLIQUgCUGr1QJqQf//A3EiCEGp1QJLDQAgCEH//wFPBEBBqtUCIAhrIAcgBmtsQQZsQYCAAmpBEHYgBmohBgwBCyAIQanVAEsEQCAHIQYMAQsgCCAHIAZrbEEGbEGAgAJqQRB2IAZqIQYLIAEgBDoAACABQQFqIAU6AAAgAUECaiAGOgAACyADQQJqIQMgAkECaiECIABBBGohACABQQRqIQEgC0F/aiILDQALCwsL';
-               
-       },{}],23:[function(require,module,exports){
+'use strict';
+
+/* eslint-disable max-len */
+module.exports = 'AGFzbQEAAAABMQZgAXwBfGACfX8AYAZ/f39/f38AYAh/f39/f39/fQBgBH9/f38AYAh/f39/f39/fwACGQIDZW52A2V4cAAAA2VudgZtZW1vcnkCAAEDBgUBAgMEBQQEAXAAAAdMBRZfX2J1aWxkX2dhdXNzaWFuX2NvZWZzAAEOX19nYXVzczE2X2xpbmUAAgpibHVyTW9ubzE2AAMHaHNsX2wxNgAEB3Vuc2hhcnAABQkBAAqJEAXZAQEGfAJAIAFE24a6Q4Ia+z8gALujIgOaEAAiBCAEoCIGtjgCECABIANEAAAAAAAAAMCiEAAiBbaMOAIUIAFEAAAAAAAA8D8gBKEiAiACoiAEIAMgA6CiRAAAAAAAAPA/oCAFoaMiArY4AgAgASAEIANEAAAAAAAA8L+gIAKioiIHtjgCBCABIAQgA0QAAAAAAADwP6AgAqKiIgO2OAIIIAEgBSACoiIEtow4AgwgASACIAegIAVEAAAAAAAA8D8gBqGgIgKjtjgCGCABIAMgBKEgAqO2OAIcCwu3AwMDfwR9CHwCQCADKgIUIQkgAyoCECEKIAMqAgwhCyADKgIIIQwCQCAEQX9qIgdBAEgiCA0AIAIgAC8BALgiDSADKgIYu6IiDiAJuyIQoiAOIAq7IhGiIA0gAyoCBLsiEqIgAyoCALsiEyANoqCgoCIPtjgCACACQQRqIQIgAEECaiEAIAdFDQAgBCEGA0AgAiAOIBCiIA8iDiARoiANIBKiIBMgAC8BALgiDaKgoKAiD7Y4AgAgAkEEaiECIABBAmohACAGQX9qIgZBAUoNAAsLAkAgCA0AIAEgByAFbEEBdGogAEF+ai8BACIIuCINIAu7IhGiIA0gDLsiEqKgIA0gAyoCHLuiIg4gCrsiE6KgIA4gCbsiFKKgIg8gAkF8aioCALugqzsBACAHRQ0AIAJBeGohAiAAQXxqIQBBACAFQQF0ayEHIAEgBSAEQQF0QXxqbGohBgNAIAghAyAALwEAIQggBiANIBGiIAO4Ig0gEqKgIA8iECAToqAgDiAUoqAiDyACKgIAu6CrOwEAIAYgB2ohBiAAQX5qIQAgAkF8aiECIBAhDiAEQX9qIgRBAUoNAAsLCwvfAgIDfwZ8AkAgB0MAAAAAWw0AIARE24a6Q4Ia+z8gB0MAAAA/l7ujIgyaEAAiDSANoCIPtjgCECAEIAxEAAAAAAAAAMCiEAAiDraMOAIUIAREAAAAAAAA8D8gDaEiCyALoiANIAwgDKCiRAAAAAAAAPA/oCAOoaMiC7Y4AgAgBCANIAxEAAAAAAAA8L+gIAuioiIQtjgCBCAEIA0gDEQAAAAAAADwP6AgC6KiIgy2OAIIIAQgDiALoiINtow4AgwgBCALIBCgIA5EAAAAAAAA8D8gD6GgIgujtjgCGCAEIAwgDaEgC6O2OAIcIAYEQCAFQQF0IQogBiEJIAIhCANAIAAgCCADIAQgBSAGEAIgACAKaiEAIAhBAmohCCAJQX9qIgkNAAsLIAVFDQAgBkEBdCEIIAUhAANAIAIgASADIAQgBiAFEAIgAiAIaiECIAFBAmohASAAQX9qIgANAAsLC7wBAQV/IAMgAmwiAwRAQQAgA2shBgNAIAAoAgAiBEEIdiIHQf8BcSECAn8gBEH/AXEiAyAEQRB2IgRB/wFxIgVPBEAgAyIIIAMgAk8NARoLIAQgBCAHIAIgA0kbIAIgBUkbQf8BcQshCAJAIAMgAk0EQCADIAVNDQELIAQgByAEIAMgAk8bIAIgBUsbQf8BcSEDCyAAQQRqIQAgASADIAhqQYECbEEBdjsBACABQQJqIQEgBkEBaiIGDQALCwvTBgEKfwJAIAazQwAAgEWUQwAAyEKVu0QAAAAAAADgP6CqIQ0gBSAEbCILBEAgB0GBAmwhDgNAQQAgAi8BACADLwEAayIGQQF0IgdrIAcgBkEASBsgDk8EQCAAQQJqLQAAIQUCfyAALQAAIgYgAEEBai0AACIESSIJRQRAIAYiCCAGIAVPDQEaCyAFIAUgBCAEIAVJGyAGIARLGwshCAJ/IAYgBE0EQCAGIgogBiAFTQ0BGgsgBSAFIAQgBCAFSxsgCRsLIgogCGoiD0GBAmwiEEEBdiERQQAhDAJ/QQAiCSAIIApGDQAaIAggCmsiCUH/H2wgD0H+AyAIayAKayAQQYCABEkbbSEMIAYgCEYEQCAEIAVrQf//A2wgCUEGbG0MAQsgBSAGayAGIARrIAQgCEYiBhtB//8DbCAJQQZsbUHVqgFBqtUCIAYbagshCSARIAcgDWxBgBBqQQx1aiIGQQAgBkEAShsiBkH//wMgBkH//wNIGyEGAkACfwJAIAxB//8DcSIFBEAgBkH//wFKDQEgBUGAIGogBmxBgBBqQQx2DAILIAZBCHYiBiEFIAYhBAwCCyAFIAZB//8Dc2xBgBBqQQx2IAZqCyIFQQh2IQcgBkEBdCAFa0EIdiIGIQQCQCAJQdWqAWpB//8DcSIFQanVAksNACAFQf//AU8EQEGq1QIgBWsgByAGa2xBBmxBgIACakEQdiAGaiEEDAELIAchBCAFQanVAEsNACAFIAcgBmtsQQZsQYCAAmpBEHYgBmohBAsCfyAGIgUgCUH//wNxIghBqdUCSw0AGkGq1QIgCGsgByAGa2xBBmxBgIACakEQdiAGaiAIQf//AU8NABogByIFIAhBqdUASw0AGiAIIAcgBmtsQQZsQYCAAmpBEHYgBmoLIQUgCUGr1QJqQf//A3EiCEGp1QJLDQAgCEH//wFPBEBBqtUCIAhrIAcgBmtsQQZsQYCAAmpBEHYgBmohBgwBCyAIQanVAEsEQCAHIQYMAQsgCCAHIAZrbEEGbEGAgAJqQRB2IAZqIQYLIAEgBDoAACABQQFqIAU6AAAgAUECaiAGOgAACyADQQJqIQMgAkECaiECIABBBGohACABQQRqIQEgC0F/aiILDQALCwsL';
+
+},{}],23:[function(require,module,exports){
 // Detect WebAssembly support.
 // - Check global WebAssembly object
 // - Try to load simple module (can be disabled via CSP)
 //
-               'use strict';
-               
-               
-               var wa;
-               
-               
-               module.exports = function hasWebAssembly() {
-                       // use cache if called before;
-                       if (typeof wa !== 'undefined') return wa;
-                       
-                       wa = false;
-                       
-                       if (typeof WebAssembly === 'undefined') return wa;
-                       
-                       // If WebAssenbly is disabled, code can throw on compile
-                       try {
-                               // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js
-                               // Additional check that WA internals are correct
-                               
-                               /* eslint-disable comma-spacing, max-len */
-                               var bin      = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);
-                               var module   = new WebAssembly.Module(bin);
-                               var instance = new WebAssembly.Instance(module, {});
-                               
-                               // test storing to and loading from a non-zero location via a parameter.
-                               // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations
-                               if (instance.exports.test(4) !== 0) wa = true;
-                               
-                               return wa;
-                       } catch (__) {}
-                       
-                       return wa;
-               };
-               
-       },{}],24:[function(require,module,exports){
-               /*
-               object-assign
-               (c) Sindre Sorhus
-               @license MIT
-               */
-               
-               'use strict';
-               /* eslint-disable no-unused-vars */
-               var getOwnPropertySymbols = Object.getOwnPropertySymbols;
-               var hasOwnProperty = Object.prototype.hasOwnProperty;
-               var propIsEnumerable = Object.prototype.propertyIsEnumerable;
-               
-               function toObject(val) {
-                       if (val === null || val === undefined) {
-                               throw new TypeError('Object.assign cannot be called with null or undefined');
-                       }
-                       
-                       return Object(val);
+'use strict';
+
+
+var wa;
+
+
+module.exports = function hasWebAssembly() {
+  // use cache if called before;
+  if (typeof wa !== 'undefined') return wa;
+
+  wa = false;
+
+  if (typeof WebAssembly === 'undefined') return wa;
+
+  // If WebAssenbly is disabled, code can throw on compile
+  try {
+    // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js
+    // Additional check that WA internals are correct
+
+    /* eslint-disable comma-spacing, max-len */
+    var bin      = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);
+    var module   = new WebAssembly.Module(bin);
+    var instance = new WebAssembly.Instance(module, {});
+
+    // test storing to and loading from a non-zero location via a parameter.
+    // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations
+    if (instance.exports.test(4) !== 0) wa = true;
+
+    return wa;
+  } catch (__) {}
+
+  return wa;
+};
+
+},{}],24:[function(require,module,exports){
+/*
+object-assign
+(c) Sindre Sorhus
+@license MIT
+*/
+
+'use strict';
+/* eslint-disable no-unused-vars */
+var getOwnPropertySymbols = Object.getOwnPropertySymbols;
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var propIsEnumerable = Object.prototype.propertyIsEnumerable;
+
+function toObject(val) {
+       if (val === null || val === undefined) {
+               throw new TypeError('Object.assign cannot be called with null or undefined');
+       }
+
+       return Object(val);
+}
+
+function shouldUseNative() {
+       try {
+               if (!Object.assign) {
+                       return false;
                }
-               
-               function shouldUseNative() {
-                       try {
-                               if (!Object.assign) {
-                                       return false;
-                               }
-                               
-                               // Detect buggy property enumeration order in older V8 versions.
-                               
-                               // https://bugs.chromium.org/p/v8/issues/detail?id=4118
-                               var test1 = new String('abc');  // eslint-disable-line no-new-wrappers
-                               test1[5] = 'de';
-                               if (Object.getOwnPropertyNames(test1)[0] === '5') {
-                                       return false;
-                               }
-                               
-                               // https://bugs.chromium.org/p/v8/issues/detail?id=3056
-                               var test2 = {};
-                               for (var i = 0; i < 10; i++) {
-                                       test2['_' + String.fromCharCode(i)] = i;
-                               }
-                               var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
-                                       return test2[n];
-                               });
-                               if (order2.join('') !== '0123456789') {
-                                       return false;
-                               }
-                               
-                               // https://bugs.chromium.org/p/v8/issues/detail?id=3056
-                               var test3 = {};
-                               'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
-                                       test3[letter] = letter;
-                               });
-                               if (Object.keys(Object.assign({}, test3)).join('') !==
-                                       'abcdefghijklmnopqrst') {
-                                       return false;
-                               }
-                               
-                               return true;
-                       } catch (err) {
-                               // We don't expect any of the above to throw, but better to be safe.
-                               return false;
-                       }
+
+               // Detect buggy property enumeration order in older V8 versions.
+
+               // https://bugs.chromium.org/p/v8/issues/detail?id=4118
+               var test1 = new String('abc');  // eslint-disable-line no-new-wrappers
+               test1[5] = 'de';
+               if (Object.getOwnPropertyNames(test1)[0] === '5') {
+                       return false;
                }
-               
-               module.exports = shouldUseNative() ? Object.assign : function (target, source) {
-                       var from;
-                       var to = toObject(target);
-                       var symbols;
-                       
-                       for (var s = 1; s < arguments.length; s++) {
-                               from = Object(arguments[s]);
-                               
-                               for (var key in from) {
-                                       if (hasOwnProperty.call(from, key)) {
-                                               to[key] = from[key];
-                                       }
-                               }
-                               
-                               if (getOwnPropertySymbols) {
-                                       symbols = getOwnPropertySymbols(from);
-                                       for (var i = 0; i < symbols.length; i++) {
-                                               if (propIsEnumerable.call(from, symbols[i])) {
-                                                       to[symbols[i]] = from[symbols[i]];
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       return to;
-               };
-               
-       },{}],25:[function(require,module,exports){
-               var bundleFn = arguments[3];
-               var sources = arguments[4];
-               var cache = arguments[5];
-               
-               var stringify = JSON.stringify;
-               
-               module.exports = function (fn, options) {
-                       var wkey;
-                       var cacheKeys = Object.keys(cache);
-                       
-                       for (var i = 0, l = cacheKeys.length; i < l; i++) {
-                               var key = cacheKeys[i];
-                               var exp = cache[key].exports;
-                               // Using babel as a transpiler to use esmodule, the export will always
-                               // be an object with the default export as a property of it. To ensure
-                               // the existing api and babel esmodule exports are both supported we
-                               // check for both
-                               if (exp === fn || exp && exp.default === fn) {
-                                       wkey = key;
-                                       break;
-                               }
-                       }
-                       
-                       if (!wkey) {
-                               wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
-                               var wcache = {};
-                               for (var i = 0, l = cacheKeys.length; i < l; i++) {
-                                       var key = cacheKeys[i];
-                                       wcache[key] = key;
-                               }
-                               sources[wkey] = [
-                                       'function(require,module,exports){' + fn + '(self); }',
-                                       wcache
-                               ];
-                       }
-                       var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
-                       
-                       var scache = {}; scache[wkey] = wkey;
-                       sources[skey] = [
-                               'function(require,module,exports){' +
-                               // try to call default if defined to also support babel esmodule exports
-                               'var f = require(' + stringify(wkey) + ');' +
-                               '(f.default ? f.default : f)(self);' +
-                               '}',
-                               scache
-                       ];
-                       
-                       var workerSources = {};
-                       resolveSources(skey);
-                       
-                       function resolveSources(key) {
-                               workerSources[key] = true;
-                               
-                               for (var depPath in sources[key][1]) {
-                                       var depKey = sources[key][1][depPath];
-                                       if (!workerSources[depKey]) {
-                                               resolveSources(depKey);
-                                       }
-                               }
-                       }
-                       
-                       var src = '(' + bundleFn + ')({'
-                               + Object.keys(workerSources).map(function (key) {
-                                       return stringify(key) + ':['
-                                               + sources[key][0]
-                                               + ',' + stringify(sources[key][1]) + ']'
-                                               ;
-                               }).join(',')
-                               + '},{},[' + stringify(skey) + '])'
-                       ;
-                       
-                       var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
-                       
-                       var blob = new Blob([src], { type: 'text/javascript' });
-                       if (options && options.bare) { return blob; }
-                       var workerUrl = URL.createObjectURL(blob);
-                       var worker = new Worker(workerUrl);
-                       worker.objectURL = workerUrl;
-                       return worker;
-               };
-               
-       },{}],"/":[function(require,module,exports){
-               'use strict';
-               
-               function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
-               
-               function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
-               
-               function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
-               
-               function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
-               
-               var assign = require('object-assign');
-               
-               var webworkify = require('webworkify');
-               
-               var MathLib = require('./lib/mathlib');
-               
-               var Pool = require('./lib/pool');
-               
-               var utils = require('./lib/utils');
-               
-               var worker = require('./lib/worker');
-               
-               var createStages = require('./lib/stepper');
-               
-               var createRegions = require('./lib/tiler'); // Deduplicate pools & limiters with the same configs
-// when user creates multiple pica instances.
-               
-               
-               var singletones = {};
-               var NEED_SAFARI_FIX = false;
-               
-               try {
-                       if (typeof navigator !== 'undefined' && navigator.userAgent) {
-                               NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;
-                       }
-               } catch (e) {}
-               
-               var concurrency = 1;
-               
-               if (typeof navigator !== 'undefined') {
-                       concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);
+
+               // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+               var test2 = {};
+               for (var i = 0; i < 10; i++) {
+                       test2['_' + String.fromCharCode(i)] = i;
                }
-               
-               var DEFAULT_PICA_OPTS = {
-                       tile: 1024,
-                       concurrency: concurrency,
-                       features: ['js', 'wasm', 'ww'],
-                       idle: 2000
-               };
-               var DEFAULT_RESIZE_OPTS = {
-                       quality: 3,
-                       alpha: false,
-                       unsharpAmount: 0,
-                       unsharpRadius: 0.0,
-                       unsharpThreshold: 0
-               };
-               var CAN_NEW_IMAGE_DATA;
-               var CAN_CREATE_IMAGE_BITMAP;
-               
-               function workerFabric() {
-                       return {
-                               value: webworkify(worker),
-                               destroy: function destroy() {
-                                       this.value.terminate();
-                                       
-                                       if (typeof window !== 'undefined') {
-                                               var url = window.URL || window.webkitURL || window.mozURL || window.msURL;
-                                               
-                                               if (url && url.revokeObjectURL && this.value.objectURL) {
-                                                       url.revokeObjectURL(this.value.objectURL);
-                                               }
-                                       }
-                               }
-                       };
-               } ////////////////////////////////////////////////////////////////////////////////
-// API methods
-               
-               
-               function Pica(options) {
-                       if (!(this instanceof Pica)) return new Pica(options);
-                       this.options = assign({}, DEFAULT_PICA_OPTS, options || {});
-                       var limiter_key = "lk_".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates
-                       // multiple pica instances.
-                       
-                       this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);
-                       if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js
-                       
-                       this.features = {
-                               js: false,
-                               // pure JS implementation, can be disabled for testing
-                               wasm: false,
-                               // webassembly implementation for heavy functions
-                               cib: false,
-                               // resize via createImageBitmap (only FF at this moment)
-                               ww: false // webworkers
-                               
-                       };
-                       this.__workersPool = null; // Store requested features for webworkers
-                       
-                       this.__requested_features = [];
-                       this.__mathlib = null;
+               var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
+                       return test2[n];
+               });
+               if (order2.join('') !== '0123456789') {
+                       return false;
                }
-               
-               Pica.prototype.init = function () {
-                       var _this = this;
-                       
-                       if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy
-                       
-                       if (CAN_NEW_IMAGE_DATA !== false && CAN_NEW_IMAGE_DATA !== true) {
-                               CAN_NEW_IMAGE_DATA = false;
-                               
-                               if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {
-                                       try {
-                                               /* eslint-disable no-new */
-                                               new ImageData(new Uint8ClampedArray(400), 10, 10);
-                                               CAN_NEW_IMAGE_DATA = true;
-                                       } catch (__) {}
-                               }
-                       } // ImageBitmap can be effective in 2 places:
-                       //
-                       // 1. Threaded jpeg unpack (basic)
-                       // 2. Built-in resize (blocked due problem in chrome, see issue #89)
-                       //
-                       // For basic use we also need ImageBitmap wo support .close() method,
-                       // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap
-                       
-                       
-                       if (CAN_CREATE_IMAGE_BITMAP !== false && CAN_CREATE_IMAGE_BITMAP !== true) {
-                               CAN_CREATE_IMAGE_BITMAP = false;
-                               
-                               if (typeof ImageBitmap !== 'undefined') {
-                                       if (ImageBitmap.prototype && ImageBitmap.prototype.close) {
-                                               CAN_CREATE_IMAGE_BITMAP = true;
-                                       } else {
-                                               this.debug('ImageBitmap does not support .close(), disabled');
-                                       }
-                               }
-                       }
-                       
-                       var features = this.options.features.slice();
-                       
-                       if (features.indexOf('all') >= 0) {
-                               features = ['cib', 'wasm', 'js', 'ww'];
+
+               // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+               var test3 = {};
+               'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
+                       test3[letter] = letter;
+               });
+               if (Object.keys(Object.assign({}, test3)).join('') !==
+                               'abcdefghijklmnopqrst') {
+                       return false;
+               }
+
+               return true;
+       } catch (err) {
+               // We don't expect any of the above to throw, but better to be safe.
+               return false;
+       }
+}
+
+module.exports = shouldUseNative() ? Object.assign : function (target, source) {
+       var from;
+       var to = toObject(target);
+       var symbols;
+
+       for (var s = 1; s < arguments.length; s++) {
+               from = Object(arguments[s]);
+
+               for (var key in from) {
+                       if (hasOwnProperty.call(from, key)) {
+                               to[key] = from[key];
                        }
-                       
-                       this.__requested_features = features;
-                       this.__mathlib = new MathLib(features); // Check WebWorker support if requested
-                       
-                       if (features.indexOf('ww') >= 0) {
-                               if (typeof window !== 'undefined' && 'Worker' in window) {
-                                       // IE <= 11 don't allow to create webworkers from string. We should check it.
-                                       // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11
-                                       try {
-                                               var wkr = require('webworkify')(function () {});
-                                               
-                                               wkr.terminate();
-                                               this.features.ww = true; // pool uniqueness depends on pool config + webworker config
-                                               
-                                               var wpool_key = "wp_".concat(JSON.stringify(this.options));
-                                               
-                                               if (singletones[wpool_key]) {
-                                                       this.__workersPool = singletones[wpool_key];
-                                               } else {
-                                                       this.__workersPool = new Pool(workerFabric, this.options.idle);
-                                                       singletones[wpool_key] = this.__workersPool;
-                                               }
-                                       } catch (__) {}
+               }
+
+               if (getOwnPropertySymbols) {
+                       symbols = getOwnPropertySymbols(from);
+                       for (var i = 0; i < symbols.length; i++) {
+                               if (propIsEnumerable.call(from, symbols[i])) {
+                                       to[symbols[i]] = from[symbols[i]];
                                }
                        }
-                       
-                       var initMath = this.__mathlib.init().then(function (mathlib) {
-                               // Copy detected features
-                               assign(_this.features, mathlib.features);
-                       });
-                       
-                       var checkCibResize;
-                       
-                       if (!CAN_CREATE_IMAGE_BITMAP) {
-                               checkCibResize = Promise.resolve(false);
-                       } else {
-                               checkCibResize = utils.cib_support().then(function (status) {
-                                       if (_this.features.cib && features.indexOf('cib') < 0) {
-                                               _this.debug('createImageBitmap() resize supported, but disabled by config');
-                                               
-                                               return;
-                                       }
-                                       
-                                       if (features.indexOf('cib') >= 0) _this.features.cib = status;
-                               });
-                       } // Init math lib. That's async because can load some
-                       
-                       
-                       this.__initPromise = Promise.all([initMath, checkCibResize]).then(function () {
-                               return _this;
-                       });
-                       return this.__initPromise;
-               };
-               
-               Pica.prototype.resize = function (from, to, options) {
-                       var _this2 = this;
-                       
-                       this.debug('Start resize...');
-                       var opts = assign({}, DEFAULT_RESIZE_OPTS);
-                       
-                       if (!isNaN(options)) {
-                               opts = assign(opts, {
-                                       quality: options
-                               });
-                       } else if (options) {
-                               opts = assign(opts, options);
-                       }
-                       
-                       opts.toWidth = to.width;
-                       opts.toHeight = to.height;
-                       opts.width = from.naturalWidth || from.width;
-                       opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop
-                       
-                       if (to.width === 0 || to.height === 0) {
-                               return Promise.reject(new Error("Invalid output size: ".concat(to.width, "x").concat(to.height)));
-                       }
-                       
-                       if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;
-                       var canceled = false;
-                       var cancelToken = null;
-                       
-                       if (opts.cancelToken) {
-                               // Wrap cancelToken to avoid successive resolve & set flag
-                               cancelToken = opts.cancelToken.then(function (data) {
-                                       canceled = true;
-                                       throw data;
-                               }, function (err) {
-                                       canceled = true;
-                                       throw err;
-                               });
-                       }
-                       
-                       var DEST_TILE_BORDER = 3; // Max possible filter window size
-                       
-                       var destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));
-                       return this.init().then(function () {
-                               if (canceled) return cancelToken; // if createImageBitmap supports resize, just do it and return
-                               
-                               if (_this2.features.cib) {
-                                       var toCtx = to.getContext('2d', {
-                                               alpha: Boolean(opts.alpha)
-                                       });
-                                       
-                                       _this2.debug('Resize via createImageBitmap()');
-                                       
-                                       return createImageBitmap(from, {
-                                               resizeWidth: opts.toWidth,
-                                               resizeHeight: opts.toHeight,
-                                               resizeQuality: utils.cib_quality_name(opts.quality)
-                                       }).then(function (imageBitmap) {
-                                               if (canceled) return cancelToken; // if no unsharp - draw directly to output canvas
-                                               
-                                               if (!opts.unsharpAmount) {
-                                                       toCtx.drawImage(imageBitmap, 0, 0);
-                                                       imageBitmap.close();
-                                                       toCtx = null;
-                                                       
-                                                       _this2.debug('Finished!');
-                                                       
-                                                       return to;
-                                               }
-                                               
-                                               _this2.debug('Unsharp result');
-                                               
-                                               var tmpCanvas = document.createElement('canvas');
-                                               tmpCanvas.width = opts.toWidth;
-                                               tmpCanvas.height = opts.toHeight;
-                                               var tmpCtx = tmpCanvas.getContext('2d', {
-                                                       alpha: Boolean(opts.alpha)
-                                               });
-                                               tmpCtx.drawImage(imageBitmap, 0, 0);
-                                               imageBitmap.close();
-                                               var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);
-                                               
-                                               _this2.__mathlib.unsharp(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);
-                                               
-                                               toCtx.putImageData(iData, 0, 0);
-                                               iData = tmpCtx = tmpCanvas = toCtx = null;
-                                               
-                                               _this2.debug('Finished!');
-                                               
-                                               return to;
-                                       });
-                               } //
-                               // No easy way, let's resize manually via arrays
-                               //
-                               // Share cache between calls:
-                               //
-                               // - wasm instance
-                               // - wasm memory object
-                               //
-                               
-                               
-                               var cache = {}; // Call resizer in webworker or locally, depending on config
-                               
-                               var invokeResize = function invokeResize(opts) {
-                                       return Promise.resolve().then(function () {
-                                               if (!_this2.features.ww) return _this2.__mathlib.resizeAndUnsharp(opts, cache);
-                                               return new Promise(function (resolve, reject) {
-                                                       var w = _this2.__workersPool.acquire();
-                                                       
-                                                       if (cancelToken) cancelToken.catch(function (err) {
-                                                               return reject(err);
-                                                       });
-                                                       
-                                                       w.value.onmessage = function (ev) {
-                                                               w.release();
-                                                               if (ev.data.err) reject(ev.data.err);else resolve(ev.data.result);
-                                                       };
-                                                       
-                                                       w.value.postMessage({
-                                                               opts: opts,
-                                                               features: _this2.__requested_features,
-                                                               preload: {
-                                                                       wasm_nodule: _this2.__mathlib.__
-                                                               }
-                                                       }, [opts.src.buffer]);
-                                               });
-                                       });
-                               };
-                               
-                               var tileAndResize = function tileAndResize(from, to, opts) {
-                                       var srcCtx;
-                                       var srcImageBitmap;
-                                       var toCtx;
-                                       
-                                       var processTile = function processTile(tile) {
-                                               return _this2.__limit(function () {
-                                                       if (canceled) return cancelToken;
-                                                       var srcImageData; // Extract tile RGBA buffer, depending on input type
-                                                       
-                                                       if (utils.isCanvas(from)) {
-                                                               _this2.debug('Get tile pixel data'); // If input is Canvas - extract region data directly
-                                                               
-                                                               
-                                                               srcImageData = srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height);
-                                                       } else {
-                                                               // If input is Image or decoded to ImageBitmap,
-                                                               // draw region to temporary canvas and extract data from it
-                                                               //
-                                                               // Note! Attempt to reuse this canvas causes significant slowdown in chrome
-                                                               //
-                                                               _this2.debug('Draw tile imageBitmap/image to temporary canvas');
-                                                               
-                                                               var tmpCanvas = document.createElement('canvas');
-                                                               tmpCanvas.width = tile.width;
-                                                               tmpCanvas.height = tile.height;
-                                                               var tmpCtx = tmpCanvas.getContext('2d', {
-                                                                       alpha: Boolean(opts.alpha)
-                                                               });
-                                                               tmpCtx.globalCompositeOperation = 'copy';
-                                                               tmpCtx.drawImage(srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);
-                                                               
-                                                               _this2.debug('Get tile pixel data');
-                                                               
-                                                               srcImageData = tmpCtx.getImageData(0, 0, tile.width, tile.height);
-                                                               tmpCtx = tmpCanvas = null;
-                                                       }
-                                                       
-                                                       var o = {
-                                                               src: srcImageData.data,
-                                                               width: tile.width,
-                                                               height: tile.height,
-                                                               toWidth: tile.toWidth,
-                                                               toHeight: tile.toHeight,
-                                                               scaleX: tile.scaleX,
-                                                               scaleY: tile.scaleY,
-                                                               offsetX: tile.offsetX,
-                                                               offsetY: tile.offsetY,
-                                                               quality: opts.quality,
-                                                               alpha: opts.alpha,
-                                                               unsharpAmount: opts.unsharpAmount,
-                                                               unsharpRadius: opts.unsharpRadius,
-                                                               unsharpThreshold: opts.unsharpThreshold
-                                                       };
-                                                       
-                                                       _this2.debug('Invoke resize math');
-                                                       
-                                                       return Promise.resolve().then(function () {
-                                                               return invokeResize(o);
-                                                       }).then(function (result) {
-                                                               if (canceled) return cancelToken;
-                                                               srcImageData = null;
-                                                               var toImageData;
-                                                               
-                                                               _this2.debug('Convert raw rgba tile result to ImageData');
-                                                               
-                                                               if (CAN_NEW_IMAGE_DATA) {
-                                                                       // this branch is for modern browsers
-                                                                       // If `new ImageData()` & Uint8ClampedArray suported
-                                                                       toImageData = new ImageData(new Uint8ClampedArray(result), tile.toWidth, tile.toHeight);
-                                                               } else {
-                                                                       // fallback for `node-canvas` and old browsers
-                                                                       // (IE11 has ImageData but does not support `new ImageData()`)
-                                                                       toImageData = toCtx.createImageData(tile.toWidth, tile.toHeight);
-                                                                       
-                                                                       if (toImageData.data.set) {
-                                                                               toImageData.data.set(result);
-                                                                       } else {
-                                                                               // IE9 don't have `.set()`
-                                                                               for (var i = toImageData.data.length - 1; i >= 0; i--) {
-                                                                                       toImageData.data[i] = result[i];
-                                                                               }
-                                                                       }
-                                                               }
-                                                               
-                                                               _this2.debug('Draw tile');
-                                                               
-                                                               if (NEED_SAFARI_FIX) {
-                                                                       // Safari draws thin white stripes between tiles without this fix
-                                                                       toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);
-                                                               } else {
-                                                                       toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);
-                                                               }
-                                                               
-                                                               return null;
-                                                       });
-                                               });
-                                       }; // Need to normalize data source first. It can be canvas or image.
-                                       // If image - try to decode in background if possible
-                                       
-                                       
-                                       return Promise.resolve().then(function () {
-                                               toCtx = to.getContext('2d', {
-                                                       alpha: Boolean(opts.alpha)
-                                               });
-                                               
-                                               if (utils.isCanvas(from)) {
-                                                       srcCtx = from.getContext('2d', {
-                                                               alpha: Boolean(opts.alpha)
-                                                       });
-                                                       return null;
-                                               }
-                                               
-                                               if (utils.isImage(from)) {
-                                                       // try do decode image in background for faster next operations
-                                                       if (!CAN_CREATE_IMAGE_BITMAP) return null;
-                                                       
-                                                       _this2.debug('Decode image via createImageBitmap');
-                                                       
-                                                       return createImageBitmap(from).then(function (imageBitmap) {
-                                                               srcImageBitmap = imageBitmap;
-                                                       });
-                                               }
-                                               
-                                               throw new Error('".from" should be image or canvas');
-                                       }).then(function () {
-                                               if (canceled) return cancelToken;
-                                               
-                                               _this2.debug('Calculate tiles'); //
-                                               // Here we are with "normalized" source,
-                                               // follow to tiling
-                                               //
-                                               
-                                               
-                                               var regions = createRegions({
-                                                       width: opts.width,
-                                                       height: opts.height,
-                                                       srcTileSize: _this2.options.tile,
-                                                       toWidth: opts.toWidth,
-                                                       toHeight: opts.toHeight,
-                                                       destTileBorder: destTileBorder
-                                               });
-                                               var jobs = regions.map(function (tile) {
-                                                       return processTile(tile);
-                                               });
-                                               
-                                               function cleanup() {
-                                                       if (srcImageBitmap) {
-                                                               srcImageBitmap.close();
-                                                               srcImageBitmap = null;
-                                                       }
-                                               }
-                                               
-                                               _this2.debug('Process tiles');
-                                               
-                                               return Promise.all(jobs).then(function () {
-                                                       _this2.debug('Finished!');
-                                                       
-                                                       cleanup();
-                                                       return to;
-                                               }, function (err) {
-                                                       cleanup();
-                                                       throw err;
-                                               });
-                                       });
-                               };
-                               
-                               var processStages = function processStages(stages, from, to, opts) {
-                                       if (canceled) return cancelToken;
-                                       
-                                       var _stages$shift = stages.shift(),
-                                               _stages$shift2 = _slicedToArray(_stages$shift, 2),
-                                               toWidth = _stages$shift2[0],
-                                               toHeight = _stages$shift2[1];
-                                       
-                                       var isLastStage = stages.length === 0;
-                                       opts = assign({}, opts, {
-                                               toWidth: toWidth,
-                                               toHeight: toHeight,
-                                               // only use user-defined quality for the last stage,
-                                               // use simpler (Hamming) filter for the first stages where
-                                               // scale factor is large enough (more than 2-3)
-                                               quality: isLastStage ? opts.quality : Math.min(1, opts.quality)
-                                       });
-                                       var tmpCanvas;
-                                       
-                                       if (!isLastStage) {
-                                               // create temporary canvas
-                                               tmpCanvas = document.createElement('canvas');
-                                               tmpCanvas.width = toWidth;
-                                               tmpCanvas.height = toHeight;
-                                       }
-                                       
-                                       return tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {
-                                               if (isLastStage) return to;
-                                               opts.width = toWidth;
-                                               opts.height = toHeight;
-                                               return processStages(stages, tmpCanvas, to, opts);
-                                       });
-                               };
-                               
-                               var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this2.options.tile, destTileBorder);
-                               return processStages(stages, from, to, opts);
-                       });
-               }; // RGBA buffer resize
+               }
+       }
+
+       return to;
+};
+
+},{}],25:[function(require,module,exports){
+var bundleFn = arguments[3];
+var sources = arguments[4];
+var cache = arguments[5];
+
+var stringify = JSON.stringify;
+
+module.exports = function (fn, options) {
+    var wkey;
+    var cacheKeys = Object.keys(cache);
+
+    for (var i = 0, l = cacheKeys.length; i < l; i++) {
+        var key = cacheKeys[i];
+        var exp = cache[key].exports;
+        // Using babel as a transpiler to use esmodule, the export will always
+        // be an object with the default export as a property of it. To ensure
+        // the existing api and babel esmodule exports are both supported we
+        // check for both
+        if (exp === fn || exp && exp.default === fn) {
+            wkey = key;
+            break;
+        }
+    }
+
+    if (!wkey) {
+        wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
+        var wcache = {};
+        for (var i = 0, l = cacheKeys.length; i < l; i++) {
+            var key = cacheKeys[i];
+            wcache[key] = key;
+        }
+        sources[wkey] = [
+            'function(require,module,exports){' + fn + '(self); }',
+            wcache
+        ];
+    }
+    var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
+
+    var scache = {}; scache[wkey] = wkey;
+    sources[skey] = [
+        'function(require,module,exports){' +
+            // try to call default if defined to also support babel esmodule exports
+            'var f = require(' + stringify(wkey) + ');' +
+            '(f.default ? f.default : f)(self);' +
+        '}',
+        scache
+    ];
+
+    var workerSources = {};
+    resolveSources(skey);
+
+    function resolveSources(key) {
+        workerSources[key] = true;
+
+        for (var depPath in sources[key][1]) {
+            var depKey = sources[key][1][depPath];
+            if (!workerSources[depKey]) {
+                resolveSources(depKey);
+            }
+        }
+    }
+
+    var src = '(' + bundleFn + ')({'
+        + Object.keys(workerSources).map(function (key) {
+            return stringify(key) + ':['
+                + sources[key][0]
+                + ',' + stringify(sources[key][1]) + ']'
+            ;
+        }).join(',')
+        + '},{},[' + stringify(skey) + '])'
+    ;
+
+    var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
+
+    var blob = new Blob([src], { type: 'text/javascript' });
+    if (options && options.bare) { return blob; }
+    var workerUrl = URL.createObjectURL(blob);
+    var worker = new Worker(workerUrl);
+    worker.objectURL = workerUrl;
+    return worker;
+};
+
+},{}],"/":[function(require,module,exports){
+'use strict';
+
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
+
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
+
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+var assign = require('object-assign');
+
+var webworkify = require('webworkify');
+
+var MathLib = require('./lib/mathlib');
+
+var Pool = require('./lib/pool');
+
+var utils = require('./lib/utils');
+
+var worker = require('./lib/worker');
+
+var createStages = require('./lib/stepper');
+
+var createRegions = require('./lib/tiler'); // Deduplicate pools & limiters with the same configs
+// when user creates multiple pica instances.
+
+
+var singletones = {};
+var NEED_SAFARI_FIX = false;
+
+try {
+  if (typeof navigator !== 'undefined' && navigator.userAgent) {
+    NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;
+  }
+} catch (e) {}
+
+var concurrency = 1;
+
+if (typeof navigator !== 'undefined') {
+  concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);
+}
+
+var DEFAULT_PICA_OPTS = {
+  tile: 1024,
+  concurrency: concurrency,
+  features: ['js', 'wasm', 'ww'],
+  idle: 2000
+};
+var DEFAULT_RESIZE_OPTS = {
+  quality: 3,
+  alpha: false,
+  unsharpAmount: 0,
+  unsharpRadius: 0.0,
+  unsharpThreshold: 0
+};
+var CAN_NEW_IMAGE_DATA;
+var CAN_CREATE_IMAGE_BITMAP;
+
+function workerFabric() {
+  return {
+    value: webworkify(worker),
+    destroy: function destroy() {
+      this.value.terminate();
+
+      if (typeof window !== 'undefined') {
+        var url = window.URL || window.webkitURL || window.mozURL || window.msURL;
+
+        if (url && url.revokeObjectURL && this.value.objectURL) {
+          url.revokeObjectURL(this.value.objectURL);
+        }
+      }
+    }
+  };
+} ////////////////////////////////////////////////////////////////////////////////
+// API methods
+
+
+function Pica(options) {
+  if (!(this instanceof Pica)) return new Pica(options);
+  this.options = assign({}, DEFAULT_PICA_OPTS, options || {});
+  var limiter_key = "lk_".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates
+  // multiple pica instances.
+
+  this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);
+  if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js
+
+  this.features = {
+    js: false,
+    // pure JS implementation, can be disabled for testing
+    wasm: false,
+    // webassembly implementation for heavy functions
+    cib: false,
+    // resize via createImageBitmap (only FF at this moment)
+    ww: false // webworkers
+
+  };
+  this.__workersPool = null; // Store requested features for webworkers
+
+  this.__requested_features = [];
+  this.__mathlib = null;
+}
+
+Pica.prototype.init = function () {
+  var _this = this;
+
+  if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy
+
+  if (CAN_NEW_IMAGE_DATA !== false && CAN_NEW_IMAGE_DATA !== true) {
+    CAN_NEW_IMAGE_DATA = false;
+
+    if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {
+      try {
+        /* eslint-disable no-new */
+        new ImageData(new Uint8ClampedArray(400), 10, 10);
+        CAN_NEW_IMAGE_DATA = true;
+      } catch (__) {}
+    }
+  } // ImageBitmap can be effective in 2 places:
+  //
+  // 1. Threaded jpeg unpack (basic)
+  // 2. Built-in resize (blocked due problem in chrome, see issue #89)
+  //
+  // For basic use we also need ImageBitmap wo support .close() method,
+  // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap
+
+
+  if (CAN_CREATE_IMAGE_BITMAP !== false && CAN_CREATE_IMAGE_BITMAP !== true) {
+    CAN_CREATE_IMAGE_BITMAP = false;
+
+    if (typeof ImageBitmap !== 'undefined') {
+      if (ImageBitmap.prototype && ImageBitmap.prototype.close) {
+        CAN_CREATE_IMAGE_BITMAP = true;
+      } else {
+        this.debug('ImageBitmap does not support .close(), disabled');
+      }
+    }
+  }
+
+  var features = this.options.features.slice();
+
+  if (features.indexOf('all') >= 0) {
+    features = ['cib', 'wasm', 'js', 'ww'];
+  }
+
+  this.__requested_features = features;
+  this.__mathlib = new MathLib(features); // Check WebWorker support if requested
+
+  if (features.indexOf('ww') >= 0) {
+    if (typeof window !== 'undefined' && 'Worker' in window) {
+      // IE <= 11 don't allow to create webworkers from string. We should check it.
+      // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11
+      try {
+        var wkr = require('webworkify')(function () {});
+
+        wkr.terminate();
+        this.features.ww = true; // pool uniqueness depends on pool config + webworker config
+
+        var wpool_key = "wp_".concat(JSON.stringify(this.options));
+
+        if (singletones[wpool_key]) {
+          this.__workersPool = singletones[wpool_key];
+        } else {
+          this.__workersPool = new Pool(workerFabric, this.options.idle);
+          singletones[wpool_key] = this.__workersPool;
+        }
+      } catch (__) {}
+    }
+  }
+
+  var initMath = this.__mathlib.init().then(function (mathlib) {
+    // Copy detected features
+    assign(_this.features, mathlib.features);
+  });
+
+  var checkCibResize;
+
+  if (!CAN_CREATE_IMAGE_BITMAP) {
+    checkCibResize = Promise.resolve(false);
+  } else {
+    checkCibResize = utils.cib_support().then(function (status) {
+      if (_this.features.cib && features.indexOf('cib') < 0) {
+        _this.debug('createImageBitmap() resize supported, but disabled by config');
+
+        return;
+      }
+
+      if (features.indexOf('cib') >= 0) _this.features.cib = status;
+    });
+  } // Init math lib. That's async because can load some
+
+
+  this.__initPromise = Promise.all([initMath, checkCibResize]).then(function () {
+    return _this;
+  });
+  return this.__initPromise;
+};
+
+Pica.prototype.resize = function (from, to, options) {
+  var _this2 = this;
+
+  this.debug('Start resize...');
+  var opts = assign({}, DEFAULT_RESIZE_OPTS);
+
+  if (!isNaN(options)) {
+    opts = assign(opts, {
+      quality: options
+    });
+  } else if (options) {
+    opts = assign(opts, options);
+  }
+
+  opts.toWidth = to.width;
+  opts.toHeight = to.height;
+  opts.width = from.naturalWidth || from.width;
+  opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop
+
+  if (to.width === 0 || to.height === 0) {
+    return Promise.reject(new Error("Invalid output size: ".concat(to.width, "x").concat(to.height)));
+  }
+
+  if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;
+  var canceled = false;
+  var cancelToken = null;
+
+  if (opts.cancelToken) {
+    // Wrap cancelToken to avoid successive resolve & set flag
+    cancelToken = opts.cancelToken.then(function (data) {
+      canceled = true;
+      throw data;
+    }, function (err) {
+      canceled = true;
+      throw err;
+    });
+  }
+
+  var DEST_TILE_BORDER = 3; // Max possible filter window size
+
+  var destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));
+  return this.init().then(function () {
+    if (canceled) return cancelToken; // if createImageBitmap supports resize, just do it and return
+
+    if (_this2.features.cib) {
+      var toCtx = to.getContext('2d', {
+        alpha: Boolean(opts.alpha)
+      });
+
+      _this2.debug('Resize via createImageBitmap()');
+
+      return createImageBitmap(from, {
+        resizeWidth: opts.toWidth,
+        resizeHeight: opts.toHeight,
+        resizeQuality: utils.cib_quality_name(opts.quality)
+      }).then(function (imageBitmap) {
+        if (canceled) return cancelToken; // if no unsharp - draw directly to output canvas
+
+        if (!opts.unsharpAmount) {
+          toCtx.drawImage(imageBitmap, 0, 0);
+          imageBitmap.close();
+          toCtx = null;
+
+          _this2.debug('Finished!');
+
+          return to;
+        }
+
+        _this2.debug('Unsharp result');
+
+        var tmpCanvas = document.createElement('canvas');
+        tmpCanvas.width = opts.toWidth;
+        tmpCanvas.height = opts.toHeight;
+        var tmpCtx = tmpCanvas.getContext('2d', {
+          alpha: Boolean(opts.alpha)
+        });
+        tmpCtx.drawImage(imageBitmap, 0, 0);
+        imageBitmap.close();
+        var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);
+
+        _this2.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);
+
+        toCtx.putImageData(iData, 0, 0);
+        iData = tmpCtx = tmpCanvas = toCtx = null;
+
+        _this2.debug('Finished!');
+
+        return to;
+      });
+    } //
+    // No easy way, let's resize manually via arrays
+    //
+    // Share cache between calls:
+    //
+    // - wasm instance
+    // - wasm memory object
+    //
+
+
+    var cache = {}; // Call resizer in webworker or locally, depending on config
+
+    var invokeResize = function invokeResize(opts) {
+      return Promise.resolve().then(function () {
+        if (!_this2.features.ww) return _this2.__mathlib.resizeAndUnsharp(opts, cache);
+        return new Promise(function (resolve, reject) {
+          var w = _this2.__workersPool.acquire();
+
+          if (cancelToken) cancelToken["catch"](function (err) {
+            return reject(err);
+          });
+
+          w.value.onmessage = function (ev) {
+            w.release();
+            if (ev.data.err) reject(ev.data.err);else resolve(ev.data.result);
+          };
+
+          w.value.postMessage({
+            opts: opts,
+            features: _this2.__requested_features,
+            preload: {
+              wasm_nodule: _this2.__mathlib.__
+            }
+          }, [opts.src.buffer]);
+        });
+      });
+    };
+
+    var tileAndResize = function tileAndResize(from, to, opts) {
+      var srcCtx;
+      var srcImageBitmap;
+      var toCtx;
+
+      var processTile = function processTile(tile) {
+        return _this2.__limit(function () {
+          if (canceled) return cancelToken;
+          var srcImageData; // Extract tile RGBA buffer, depending on input type
+
+          if (utils.isCanvas(from)) {
+            _this2.debug('Get tile pixel data'); // If input is Canvas - extract region data directly
+
+
+            srcImageData = srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height);
+          } else {
+            // If input is Image or decoded to ImageBitmap,
+            // draw region to temporary canvas and extract data from it
+            //
+            // Note! Attempt to reuse this canvas causes significant slowdown in chrome
+            //
+            _this2.debug('Draw tile imageBitmap/image to temporary canvas');
+
+            var tmpCanvas = document.createElement('canvas');
+            tmpCanvas.width = tile.width;
+            tmpCanvas.height = tile.height;
+            var tmpCtx = tmpCanvas.getContext('2d', {
+              alpha: Boolean(opts.alpha)
+            });
+            tmpCtx.globalCompositeOperation = 'copy';
+            tmpCtx.drawImage(srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);
+
+            _this2.debug('Get tile pixel data');
+
+            srcImageData = tmpCtx.getImageData(0, 0, tile.width, tile.height);
+            tmpCtx = tmpCanvas = null;
+          }
+
+          var o = {
+            src: srcImageData.data,
+            width: tile.width,
+            height: tile.height,
+            toWidth: tile.toWidth,
+            toHeight: tile.toHeight,
+            scaleX: tile.scaleX,
+            scaleY: tile.scaleY,
+            offsetX: tile.offsetX,
+            offsetY: tile.offsetY,
+            quality: opts.quality,
+            alpha: opts.alpha,
+            unsharpAmount: opts.unsharpAmount,
+            unsharpRadius: opts.unsharpRadius,
+            unsharpThreshold: opts.unsharpThreshold
+          };
+
+          _this2.debug('Invoke resize math');
+
+          return Promise.resolve().then(function () {
+            return invokeResize(o);
+          }).then(function (result) {
+            if (canceled) return cancelToken;
+            srcImageData = null;
+            var toImageData;
+
+            _this2.debug('Convert raw rgba tile result to ImageData');
+
+            if (CAN_NEW_IMAGE_DATA) {
+              // this branch is for modern browsers
+              // If `new ImageData()` & Uint8ClampedArray suported
+              toImageData = new ImageData(new Uint8ClampedArray(result), tile.toWidth, tile.toHeight);
+            } else {
+              // fallback for `node-canvas` and old browsers
+              // (IE11 has ImageData but does not support `new ImageData()`)
+              toImageData = toCtx.createImageData(tile.toWidth, tile.toHeight);
+
+              if (toImageData.data.set) {
+                toImageData.data.set(result);
+              } else {
+                // IE9 don't have `.set()`
+                for (var i = toImageData.data.length - 1; i >= 0; i--) {
+                  toImageData.data[i] = result[i];
+                }
+              }
+            }
+
+            _this2.debug('Draw tile');
+
+            if (NEED_SAFARI_FIX) {
+              // Safari draws thin white stripes between tiles without this fix
+              toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);
+            } else {
+              toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);
+            }
+
+            return null;
+          });
+        });
+      }; // Need to normalize data source first. It can be canvas or image.
+      // If image - try to decode in background if possible
+
+
+      return Promise.resolve().then(function () {
+        toCtx = to.getContext('2d', {
+          alpha: Boolean(opts.alpha)
+        });
+
+        if (utils.isCanvas(from)) {
+          srcCtx = from.getContext('2d', {
+            alpha: Boolean(opts.alpha)
+          });
+          return null;
+        }
+
+        if (utils.isImage(from)) {
+          // try do decode image in background for faster next operations
+          if (!CAN_CREATE_IMAGE_BITMAP) return null;
+
+          _this2.debug('Decode image via createImageBitmap');
+
+          return createImageBitmap(from).then(function (imageBitmap) {
+            srcImageBitmap = imageBitmap;
+          });
+        }
+
+        throw new Error('".from" should be image or canvas');
+      }).then(function () {
+        if (canceled) return cancelToken;
+
+        _this2.debug('Calculate tiles'); //
+        // Here we are with "normalized" source,
+        // follow to tiling
+        //
+
+
+        var regions = createRegions({
+          width: opts.width,
+          height: opts.height,
+          srcTileSize: _this2.options.tile,
+          toWidth: opts.toWidth,
+          toHeight: opts.toHeight,
+          destTileBorder: destTileBorder
+        });
+        var jobs = regions.map(function (tile) {
+          return processTile(tile);
+        });
+
+        function cleanup() {
+          if (srcImageBitmap) {
+            srcImageBitmap.close();
+            srcImageBitmap = null;
+          }
+        }
+
+        _this2.debug('Process tiles');
+
+        return Promise.all(jobs).then(function () {
+          _this2.debug('Finished!');
+
+          cleanup();
+          return to;
+        }, function (err) {
+          cleanup();
+          throw err;
+        });
+      });
+    };
+
+    var processStages = function processStages(stages, from, to, opts) {
+      if (canceled) return cancelToken;
+
+      var _stages$shift = stages.shift(),
+          _stages$shift2 = _slicedToArray(_stages$shift, 2),
+          toWidth = _stages$shift2[0],
+          toHeight = _stages$shift2[1];
+
+      var isLastStage = stages.length === 0;
+      opts = assign({}, opts, {
+        toWidth: toWidth,
+        toHeight: toHeight,
+        // only use user-defined quality for the last stage,
+        // use simpler (Hamming) filter for the first stages where
+        // scale factor is large enough (more than 2-3)
+        quality: isLastStage ? opts.quality : Math.min(1, opts.quality)
+      });
+      var tmpCanvas;
+
+      if (!isLastStage) {
+        // create temporary canvas
+        tmpCanvas = document.createElement('canvas');
+        tmpCanvas.width = toWidth;
+        tmpCanvas.height = toHeight;
+      }
+
+      return tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {
+        if (isLastStage) return to;
+        opts.width = toWidth;
+        opts.height = toHeight;
+        return processStages(stages, tmpCanvas, to, opts);
+      });
+    };
+
+    var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this2.options.tile, destTileBorder);
+    return processStages(stages, from, to, opts);
+  });
+}; // RGBA buffer resize
 //
-               
-               
-               Pica.prototype.resizeBuffer = function (options) {
-                       var _this3 = this;
-                       
-                       var opts = assign({}, DEFAULT_RESIZE_OPTS, options);
-                       return this.init().then(function () {
-                               return _this3.__mathlib.resizeAndUnsharp(opts);
-                       });
-               };
-               
-               Pica.prototype.toBlob = function (canvas, mimeType, quality) {
-                       mimeType = mimeType || 'image/png';
-                       return new Promise(function (resolve) {
-                               if (canvas.toBlob) {
-                                       canvas.toBlob(function (blob) {
-                                               return resolve(blob);
-                                       }, mimeType, quality);
-                                       return;
-                               } // Fallback for old browsers
-                               
-                               
-                               var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);
-                               var len = asString.length;
-                               var asBuffer = new Uint8Array(len);
-                               
-                               for (var i = 0; i < len; i++) {
-                                       asBuffer[i] = asString.charCodeAt(i);
-                               }
-                               
-                               resolve(new Blob([asBuffer], {
-                                       type: mimeType
-                               }));
-                       });
-               };
-               
-               Pica.prototype.debug = function () {};
-               
-               module.exports = Pica;
-               
-       },{"./lib/mathlib":1,"./lib/pool":9,"./lib/stepper":10,"./lib/tiler":11,"./lib/utils":12,"./lib/worker":13,"object-assign":24,"webworkify":25}]},{},[])("/")
+
+
+Pica.prototype.resizeBuffer = function (options) {
+  var _this3 = this;
+
+  var opts = assign({}, DEFAULT_RESIZE_OPTS, options);
+  return this.init().then(function () {
+    return _this3.__mathlib.resizeAndUnsharp(opts);
+  });
+};
+
+Pica.prototype.toBlob = function (canvas, mimeType, quality) {
+  mimeType = mimeType || 'image/png';
+  return new Promise(function (resolve) {
+    if (canvas.toBlob) {
+      canvas.toBlob(function (blob) {
+        return resolve(blob);
+      }, mimeType, quality);
+      return;
+    } // Fallback for old browsers
+
+
+    var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);
+    var len = asString.length;
+    var asBuffer = new Uint8Array(len);
+
+    for (var i = 0; i < len; i++) {
+      asBuffer[i] = asString.charCodeAt(i);
+    }
+
+    resolve(new Blob([asBuffer], {
+      type: mimeType
+    }));
+  });
+};
+
+Pica.prototype.debug = function () {};
+
+module.exports = Pica;
+
+},{"./lib/mathlib":1,"./lib/pool":9,"./lib/stepper":10,"./lib/tiler":11,"./lib/utils":12,"./lib/worker":13,"object-assign":24,"webworkify":25}]},{},[])("/")
 });
index 30ff9fa5ad1963cb794649d0491888628dea100b..2478355c9d062a9e5033cc5fed827f8069d83a0d 100644 (file)
@@ -1,28 +1,32 @@
-# [Prism](http://prismjs.com/)
+# [Prism](https://prismjs.com/)
 
 [![Build Status](https://travis-ci.org/PrismJS/prism.svg?branch=master)](https://travis-ci.org/PrismJS/prism)
+[![npm](https://img.shields.io/npm/dw/prismjs.svg)](https://www.npmjs.com/package/prismjs)
 
-Prism is a lightweight, robust, elegant syntax highlighting library. It's a spin-off project from [Dabblet](http://dabblet.com/).
+Prism is a lightweight, robust, elegant syntax highlighting library. It's a spin-off project from [Dabblet](https://dabblet.com/).
 
-You can learn more on http://prismjs.com/.
+You can learn more on [prismjs.com](https://prismjs.com/).
 
-Why another syntax highlighter?: http://lea.verou.me/2012/07/introducing-prism-an-awesome-new-syntax-highlighter/#more-1841
+[Why another syntax highlighter?](https://lea.verou.me/2012/07/introducing-prism-an-awesome-new-syntax-highlighter/#more-1841)
+
+[More themes for Prism!](https://github.com/PrismJS/prism-themes)
 
 ## Contribute to Prism!
 
 Prism depends on community contributions to expand and cover a wider array of use cases. If you like it, considering giving back by sending a pull request. Here are a few tips:
 
-- Read the [documentation](http://prismjs.com/extending.html). Prism was designed to be extensible.
-- Do not edit `prism.js`, it’s just the version of Prism used by the Prism website and is built automatically. Limit your changes to the unminified files in the components/ folder. The minified files are also generated automatically.
-- The build system uses [gulp](https://github.com/gulpjs/gulp) to minify the files and build `prism.js`. Having gulp installed, you just need to run the command `gulp`.
+- Read the [documentation](https://prismjs.com/extending.html). Prism was designed to be extensible.
+- Do not edit `prism.js`, it’s just the version of Prism used by the Prism website and is built automatically. Limit your changes to the unminified files in the `components/` folder. `prism.js` and all minified files are also generated automatically by our build system.
+- The build system uses [gulp](https://github.com/gulpjs/gulp) to minify the files and build `prism.js`. With all of Prism's dependencies installed, you just need to run the command `npm run build`.
 - Please follow the code conventions used in the files already. For example, I use [tabs for indentation and spaces for alignment](http://lea.verou.me/2012/01/why-tabs-are-clearly-superior/). Opening braces are on the same line, closing braces on their own line regardless of construct. There is a space before the opening brace. etc etc.
 - Please try to err towards more smaller PRs rather than few huge PRs. If a PR includes changes I want to merge and changes I don't, handling it becomes difficult.
 - My time is very limited these days, so it might take a long time to review longer PRs (short ones are usually merged very quickly), especially those modifying the Prism Core. This doesn't mean your PR is rejected.
 - If you contribute a new language definition, you will be responsible for handling bug reports about that language definition.
-- If you add a new language definition, theme or plugin, you need to add it to `components.js` as well, so that it becomes available to the download build page.
+- If you [add a new language definition](https://prismjs.com/extending.html#creating-a-new-language-definition) or plugin, you need to add it to `components.json` as well and rebuild Prism by running `npm run build`, so that it becomes available to the download build page. For new languages, please also add a few [tests](https://prismjs.com/test-suite.html) and an example in the `examples/` folder.
+- Go to [prism-themes](https://github.com/PrismJS/prism-themes) if you want to add a new theme.
 
 Thank you so much for contributing!!
 
 ## Translations
 
-* [![中文说明](http://awesomes.oss-cn-beijing.aliyuncs.com/readme.png)](http://www.awesomes.cn/repo/PrismJS/prism)
+* [![中文说明](http://awesomes.oss-cn-beijing.aliyuncs.com/readme.png)](https://www.awesomes.cn/repo/PrismJS/prism)
index 2f8c5a6080bd1e4311843662c021348749f6e32b..0ae297ea2184e7364a0e1e0fd6864631d77b8a51 100644 (file)
                },
                "markup": {
                        "title": "Markup",
-                       "alias": ["html", "xml", "svg", "mathml"],
+                       "alias": ["html", "xml", "svg", "mathml", "ssml", "atom", "rss"],
                        "aliasTitles": {
                                "html": "HTML",
                                "xml": "XML",
                                "svg": "SVG",
-                               "mathml": "MathML"
+                               "mathml": "MathML",
+                               "ssml": "SSML",
+                               "atom": "Atom",
+                               "rss": "RSS"
                        },
                        "option": "default"
                },
                "css": {
                        "title": "CSS",
                        "option": "default",
-                       "peerDependencies": "markup"
+                       "modify": "markup"
                },
                "clike": {
                        "title": "C-like",
-                       "option": "default",
-                       "overrideExampleHeader": true
+                       "option": "default"
                },
                "javascript": {
                        "title": "JavaScript",
                        "require": "clike",
-                       "peerDependencies": "markup",
+                       "modify": "markup",
                        "alias": "js",
                        "option": "default"
                },
                        "owner": "dellagustin"
                },
                "abnf": {
-                       "title": "Augmented Backus–Naur form",
+                       "title": "ABNF",
                        "owner": "RunDevelopment"
                },
                "actionscript": {
                        "title": "ActionScript",
                        "require": "javascript",
-                       "peerDependencies": "markup",
+                       "modify": "markup",
                        "owner": "Golmote"
                },
                "ada": {
                        "title": "Ada",
                        "owner": "Lucretia"
                },
+               "agda": {
+                       "title": "Agda",
+                       "owner": "xy-ren"
+               },
+               "al": {
+                       "title": "AL",
+                       "owner": "RunDevelopment"
+               },
+               "antlr4": {
+                       "title": "ANTLR4",
+                       "alias": "g4",
+                       "owner": "RunDevelopment"
+               },
                "apacheconf": {
                        "title": "Apache Configuration",
                        "owner": "GuiTeK"
                        "title": "AppleScript",
                        "owner": "Golmote"
                },
+               "aql": {
+                       "title": "AQL",
+                       "owner": "RunDevelopment"
+               },
                "arduino": {
                        "title": "Arduino",
                        "require": "cpp",
                        "owner": "Golmote"
                },
                "asciidoc": {
-                       "alias": "adoc",
+                       "alias": "adoc",
                        "title": "AsciiDoc",
                        "owner": "Golmote"
                },
-               "asm6502": {
-                       "title": "6502 Assembly",
-                       "owner": "kzurawel"
-               },
                "aspnet": {
                        "title": "ASP.NET (C#)",
                        "require": ["markup", "csharp"],
                        "owner": "nauzilus"
                },
+               "asm6502": {
+                       "title": "6502 Assembly",
+                       "owner": "kzurawel"
+               },
                "autohotkey": {
                        "title": "AutoHotkey",
                        "owner": "aviaryan"
                        "title": "Batch",
                        "owner": "Golmote"
                },
+               "bbcode": {
+                       "title": "BBcode",
+                       "alias": "shortcode",
+                       "aliasTitles": {
+                               "shortcode": "Shortcode"
+                       },
+                       "owner": "RunDevelopment"
+               },
                "bison": {
                        "title": "Bison",
                        "require": "c",
                        "owner": "Golmote"
                },
                "bnf": {
-                       "title": "Backus–Naur form",
+                       "title": "BNF",
                        "alias": "rbnf",
                        "aliasTitles": {
-                               "rbnf": "Routing Backus–Naur form"
+                               "rbnf": "RBNF"
                        },
                        "owner": "RunDevelopment"
                },
                        "title": "Brainfuck",
                        "owner": "Golmote"
                },
+               "brightscript": {
+                       "title": "BrightScript",
+                       "owner": "RunDevelopment"
+               },
                "bro": {
                        "title": "Bro",
                        "owner": "wayward710"
                        "title": "CIL",
                        "owner": "sbrl"
                },
+               "clojure": {
+                       "title": "Clojure",
+                       "owner": "troglotit"
+               },
+               "cmake": {
+                       "title": "CMake",
+                       "owner": "mjrogozinski"
+               },
                "coffeescript": {
                        "title": "CoffeeScript",
                        "require": "javascript",
                        "alias": "coffee",
                        "owner": "R-osey"
                },
-               "cmake": {
-                       "title": "CMake",
-                       "owner": "mjrogozinski"
+               "concurnas": {
+                       "title": "Concurnas",
+                       "alias": "conc",
+                       "owner": "jasontatton"
                },
-               "clojure": {
-                       "title": "Clojure",
-                       "owner": "troglotit"
+               "csp": {
+                       "title": "Content-Security-Policy",
+                       "owner": "ScottHelme"
                },
                "crystal": {
                        "title": "Crystal",
                        "require": "ruby",
                        "owner": "MakeNowJust"
                },
-               "csp": {
-                       "title": "Content-Security-Policy",
-                       "owner": "ScottHelme"
-               },
                "css-extras": {
                        "title": "CSS Extras",
                        "require": "css",
+                       "modify": "css",
                        "owner": "milesj"
                },
+               "cypher": {
+                       "title": "Cypher",
+                       "owner": "RunDevelopment"
+               },
                "d": {
                        "title": "D",
                        "require": "clike",
                        "require": "clike",
                        "owner": "Golmote"
                },
+               "dax": {
+                       "title": "DAX",
+                       "owner": "peterbud"
+               },
+               "dhall": {
+                       "title": "Dhall",
+                       "owner": "RunDevelopment"
+               },
                "diff": {
                        "title": "Diff",
                        "owner": "uranusjr"
                        "alias": "jinja2",
                        "owner": "romanvm"
                },
+               "dns-zone-file": {
+                       "title": "DNS zone file",
+                       "owner": "RunDevelopment",
+                       "alias": "dns-zone"
+               },
                "docker": {
                        "title": "Docker",
                        "alias": "dockerfile",
                        "owner": "JustinBeckwith"
                },
                "ebnf": {
-                       "title": "Extended Backus–Naur form",
+                       "title": "EBNF",
                        "owner": "RunDevelopment"
                },
+               "editorconfig": {
+                       "title": "EditorConfig",
+                       "owner": "osipxd"
+               },
                "eiffel": {
                        "title": "Eiffel",
                        "owner": "Conaclos"
                "ejs": {
                        "title": "EJS",
                        "require": ["javascript", "markup-templating"],
-                       "owner": "RunDevelopment"
+                       "owner": "RunDevelopment",
+                       "alias": "eta",
+                       "aliasTitles": {
+                               "eta": "Eta"
+                       }
                },
                "elixir": {
                        "title": "Elixir",
                        "title": "Elm",
                        "owner": "zwilias"
                },
+               "etlua": {
+                       "title": "Embedded Lua templating",
+                       "require": ["lua", "markup-templating"],
+                       "owner": "RunDevelopment"
+               },
                "erb": {
                        "title": "ERB",
                        "require": ["ruby", "markup-templating"],
                        "title": "Erlang",
                        "owner": "Golmote"
                },
+               "excel-formula": {
+                       "title": "Excel Formula",
+                       "alias": ["xlsx", "xls"],
+                       "owner": "RunDevelopment"
+               },
                "fsharp": {
                        "title": "F#",
                        "require": "clike",
                        "owner": "simonreynolds7"
                },
+               "factor": {
+                       "title": "Factor",
+                       "owner": "catb0t"
+               },
+               "firestore-security-rules": {
+                       "title": "Firestore security rules",
+                       "require": "clike",
+                       "owner": "RunDevelopment"
+               },
                "flow": {
                        "title": "Flow",
                        "require": "javascript",
                        "title": "Fortran",
                        "owner": "Golmote"
                },
+               "ftl": {
+                       "title": "FreeMarker Template Language",
+                       "require": "markup-templating",
+                       "owner": "RunDevelopment"
+               },
+               "gml": {
+                       "title": "GameMaker Language",
+                       "alias": "gamemakerlanguage",
+                       "require": "clike",
+                       "owner": "LiarOnce"
+               },
                "gcode": {
                        "title": "G-code",
                        "owner": "RunDevelopment"
                },
+               "gdscript": {
+                       "title": "GDScript",
+                       "owner": "RunDevelopment"
+               },
                "gedcom": {
                        "title": "GEDCOM",
                        "owner": "Golmote"
                },
                "glsl": {
                        "title": "GLSL",
-                       "require": "clike",
+                       "require": "c",
                        "owner": "Golmote"
                },
-               "gml": {
-                       "title": "GameMaker Language",
-                       "alias": "gamemakerlanguage",
-                       "require": "clike",
-                       "owner": "LiarOnce"
-               },
                "go": {
                        "title": "Go",
                        "require": "clike",
                },
                "graphql": {
                        "title": "GraphQL",
+                       "optional": ["markdown"],
                        "owner": "Golmote"
                },
                "groovy": {
                "haml": {
                        "title": "Haml",
                        "require": "ruby",
-                       "peerDependencies": [
+                       "optional": [
                                "css",
+                               "css-extras",
                                "coffeescript",
                                "erb",
                                "javascript",
                                "less",
                                "markdown",
-                               "ruby",
                                "scss",
                                "textile"
                        ],
                        "title": "HCL",
                        "owner": "outsideris"
                },
+               "hlsl": {
+                       "title": "HLSL",
+                       "require": "c",
+                       "owner": "RunDevelopment"
+               },
                "http": {
                        "title": "HTTP",
-                       "peerDependencies": [
+                       "optional": [
+                               "css",
                                "javascript",
+                               "json",
                                "markup"
                        ],
                        "owner": "danielgtaylor"
                        "title": "Icon",
                        "owner": "Golmote"
                },
+               "ignore": {
+                       "title": ".ignore",
+                       "owner": "osipxd",
+                       "alias": [
+                               "gitignore",
+                               "hgignore",
+                               "npmignore"
+                       ],
+                       "aliasTitles": {
+                               "gitignore": ".gitignore",
+                               "hgignore": ".hgignore",
+                               "npmignore": ".npmignore"
+                       }
+               },
                "inform7": {
                        "title": "Inform 7",
                        "owner": "Golmote"
                "javadoc": {
                        "title": "JavaDoc",
                        "require": ["markup", "java", "javadoclike"],
-                       "peerDependencies": [
-                               "scala"
-                       ],
+                       "modify": "java",
+                       "optional": "scala",
                        "owner": "RunDevelopment"
                },
                "javadoclike": {
                        "title": "JavaDoc-like",
-                       "peerDependencies": [
+                       "modify": [
                                "java",
                                "javascript",
                                "php"
                },
                "jsdoc": {
                        "title": "JSDoc",
-                       "require": ["javascript", "javadoclike"],
-                       "peerDependencies": [
+                       "require": ["javascript", "javadoclike", "typescript"],
+                       "modify": "javascript",
+                       "optional": [
                                "actionscript",
                                "coffeescript"
                        ],
                "js-extras": {
                        "title": "JS Extras",
                        "require": "javascript",
-                       "peerDependencies": [
+                       "modify": "javascript",
+                       "optional": [
                                "actionscript",
                                "coffeescript",
                                "flow",
                },
                "json": {
                        "title": "JSON",
+                       "alias": "webmanifest",
+                       "aliasTitles": {
+                               "webmanifest": "Web App Manifest"
+                       },
                        "owner": "CupOfTea696"
                },
+               "json5": {
+                       "title": "JSON5",
+                       "require": "json",
+                       "owner": "RunDevelopment"
+               },
                "jsonp": {
                        "title": "JSONP",
                        "require": "json",
                        "owner": "RunDevelopment"
                },
-               "json5": {
-                       "title": "JSON5",
-                       "require": "json",
+               "jsstacktrace": {
+                       "title": "JS stack trace",
+                       "owner": "sbrl"
+               },
+               "js-templates": {
+                       "title": "JS Templates",
+                       "require": "javascript",
+                       "modify": "javascript",
+                       "optional": [
+                               "css",
+                               "css-extras",
+                               "graphql",
+                               "markdown",
+                               "markup"
+                       ],
                        "owner": "RunDevelopment"
                },
                "julia": {
                },
                "kotlin": {
                        "title": "Kotlin",
+                       "alias": ["kt", "kts"],
+                       "aliasTitles": {
+                               "kts": "Kotlin Script"
+                       },
                        "require": "clike",
                        "owner": "Golmote"
                },
                        },
                        "owner": "japborst"
                },
+               "latte": {
+                       "title": "Latte",
+                       "require": ["clike", "markup-templating", "php"],
+                       "owner": "nette"
+               },
                "less": {
                        "title": "Less",
                        "require": "css",
+                       "optional": "css-extras",
                        "owner": "Golmote"
                },
+               "lilypond": {
+                       "title": "LilyPond",
+                       "require": "scheme",
+                       "alias": "ly",
+                       "owner": "RunDevelopment"
+               },
                "liquid": {
                        "title": "Liquid",
                        "owner": "cinhtau"
                        "title": "LiveScript",
                        "owner": "Golmote"
                },
+               "llvm": {
+                       "title": "LLVM IR",
+                       "owner": "porglezomp"
+               },
                "lolcode": {
                        "title": "LOLCODE",
                        "owner": "Golmote"
                        "title": "Monkey",
                        "owner": "Golmote"
                },
+               "moonscript": {
+                       "title": "MoonScript",
+                       "alias": "moon",
+                       "owner": "RunDevelopment"
+               },
                "n1ql": {
                        "title": "N1QL",
                        "owner": "TMWilds"
                "n4js": {
                        "title": "N4JS",
                        "require": "javascript",
-                       "peerDependencies": [
-                               "jsdoc"
-                       ],
+                       "optional": "jsdoc",
                        "alias": "n4jsd",
                        "owner": "bsmith-n4"
                },
                        "title": "NASM",
                        "owner": "rbmj"
                },
+               "neon": {
+                       "title": "NEON",
+                       "owner": "nette"
+               },
                "nginx": {
                        "title": "nginx",
                        "owner": "westonganger",
                "objectivec": {
                        "title": "Objective-C",
                        "require": "c",
+                       "alias": "objc",
                        "owner": "uranusjr"
                },
                "ocaml": {
                },
                "opencl": {
                        "title": "OpenCL",
-                       "require": "cpp",
-                       "peerDependencies": [
+                       "require": "c",
+                       "modify": [
                                "c",
                                "cpp"
                        ],
-                       "overrideExampleHeader": true,
                        "owner": "Milania1"
                },
                "oz": {
                        },
                        "owner": "Golmote"
                },
+               "pascaligo": {
+                       "title": "Pascaligo",
+                       "owner": "DefinitelyNotAGoat"
+               },
+               "pcaxis": {
+                       "title": "PC-Axis",
+                       "alias": "px",
+                       "owner": "RunDevelopment"
+               },
+               "peoplecode": {
+                       "title": "PeopleCode",
+                       "alias": "pcode",
+                       "owner": "RunDevelopment"
+               },
                "perl": {
                        "title": "Perl",
                        "owner": "Golmote"
                "phpdoc": {
                        "title": "PHPDoc",
                        "require": ["php", "javadoclike"],
+                       "modify": "php",
                        "owner": "RunDevelopment"
                },
                "php-extras": {
                        "title": "PHP Extras",
                        "require": "php",
+                       "modify": "php",
                        "owner": "milesj"
                },
                "plsql": {
                        "require": "sql",
                        "owner": "Golmote"
                },
+               "powerquery": {
+                       "title": "PowerQuery",
+                       "alias": ["pq", "mscript"],
+                       "owner": "peterbud"
+               },
                "powershell": {
                        "title": "PowerShell",
                        "owner": "nauzilus"
                "pug": {
                        "title": "Pug",
                        "require": ["markup", "javascript"],
-                       "peerDependencies": [
+                       "optional": [
                                "coffeescript",
                                "ejs",
                                "handlebars",
                },
                "pure": {
                        "title": "Pure",
-                       "peerDependencies": [
+                       "optional": [
                                "c",
                                "cpp",
                                "fortran"
                        ],
                        "owner": "Golmote"
                },
+               "purebasic": {
+                       "title": "PureBasic",
+                       "require": "clike",
+                       "alias": "pbfasm",
+                       "owner": "HeX0R101"
+               },
                "python": {
                        "title": "Python",
                        "alias": "py",
                        "title": "Q (kdb+ database)",
                        "owner": "Golmote"
                },
+               "qml": {
+                       "title": "QML",
+                       "require": "javascript",
+                       "owner": "RunDevelopment"
+               },
                "qore": {
                        "title": "Qore",
                        "require": "clike",
                        "title": "R",
                        "owner": "Golmote"
                },
+               "racket": {
+                       "title": "Racket",
+                       "require": "scheme",
+                       "alias": "rkt",
+                       "owner": "RunDevelopment"
+               },
                "jsx": {
                        "title": "React JSX",
                        "require": ["markup", "javascript"],
-                       "peerDependencies": [
+                       "optional": [
                                "jsdoc",
-                               "js-extras"
+                               "js-extras",
+                               "js-templates"
                        ],
                        "owner": "vkbansal"
                },
                        "title": "React TSX",
                        "require": ["jsx", "typescript"]
                },
-               "renpy": {
-                       "title": "Ren'py",
-                       "owner": "HyuchiaDiego"
-               },
                "reason": {
                        "title": "Reason",
                        "require": "clike",
                },
                "regex": {
                        "title": "Regex",
-                       "peerDependencies": [
+                       "modify": [
                                "actionscript",
                                "coffeescript",
                                "flow",
                        ],
                        "owner": "RunDevelopment"
                },
+               "renpy": {
+                       "title": "Ren'py",
+                       "alias": "rpy",
+                       "owner": "HyuchiaDiego"
+               },
                "rest": {
                        "title": "reST (reStructuredText)",
                        "owner": "Golmote"
                        "title": "Roboconf",
                        "owner": "Golmote"
                },
+               "robotframework": {
+                       "title": "Robot Framework",
+                       "alias": "robot",
+                       "owner": "RunDevelopment"
+               },
                "ruby": {
                        "title": "Ruby",
                        "require": "clike",
                },
                "sas": {
                        "title": "SAS",
+                       "optional": ["groovy", "lua", "sql"],
                        "owner": "Golmote"
                },
                "sass": {
                "scss": {
                        "title": "Sass (Scss)",
                        "require": "css",
+                       "optional": "css-extras",
                        "owner": "MoOx"
                },
                "scala": {
                        "require": "bash",
                        "owner": "RunDevelopment"
                },
+               "smali": {
+                       "title": "Smali",
+                       "owner": "RunDevelopment"
+               },
                "smalltalk": {
                        "title": "Smalltalk",
                        "owner": "Golmote"
                        "require": "markup-templating",
                        "owner": "Golmote"
                },
-               "sql": {
-                       "title": "SQL",
-                       "owner": "multipetros"
+               "solidity": {
+                       "title": "Solidity (Ethereum)",
+                       "alias": "sol",
+                       "require": "clike",
+                       "owner": "glachaud"
+               },
+               "solution-file": {
+                       "title": "Solution file",
+                       "alias": "sln",
+                       "owner": "RunDevelopment"
                },
                "soy": {
                        "title": "Soy (Closure Template)",
                        "require": "markup-templating",
                        "owner": "Golmote"
                },
+               "sparql": {
+                       "title": "SPARQL",
+                       "require": "turtle",
+                       "owner": "Triply-Dev",
+                       "alias": "rq"
+               },
+               "splunk-spl": {
+                       "title": "Splunk SPL",
+                       "owner": "RunDevelopment"
+               },
+               "sqf": {
+                       "title": "SQF: Status Quo Function (Arma 3)",
+                       "require": "clike",
+                       "owner": "RunDevelopment"
+               },
+               "sql": {
+                       "title": "SQL",
+                       "owner": "multipetros"
+               },
+               "iecst": {
+                       "title": "Structured Text (IEC 61131-3)",
+                       "owner": "serhioromano"
+               },
                "stylus": {
                        "title": "Stylus",
                        "owner": "vkbansal"
                        "require": "clike",
                        "owner": "chrischares"
                },
+               "t4-templating": {
+                       "title": "T4 templating",
+                       "owner": "RunDevelopment"
+               },
+               "t4-cs": {
+                       "title": "T4 Text Templates (C#)",
+                       "require": ["t4-templating", "csharp"],
+                       "alias": "t4",
+                       "owner": "RunDevelopment"
+               },
+               "t4-vb": {
+                       "title": "T4 Text Templates (VB)",
+                       "require": ["t4-templating", "vbnet"],
+                       "owner": "RunDevelopment"
+               },
                "tap": {
                        "title": "TAP",
                        "owner": "isaacs",
                        "title": "Tcl",
                        "owner": "PeterChaplin"
                },
+               "tt2": {
+                       "title": "Template Toolkit 2",
+                       "require": ["clike", "markup-templating"],
+                       "owner": "gflohr"
+               },
                "textile": {
                        "title": "Textile",
                        "require": "markup",
-                       "peerDependencies": "css",
+                       "optional": "css",
                        "owner": "Golmote"
                },
                "toml": {
                        "title": "TOML",
                        "owner": "RunDevelopment"
                },
-               "tt2": {
-                       "title": "Template Toolkit 2",
-                       "require": ["clike", "markup-templating"],
-                       "owner": "gflohr"
+               "turtle": {
+                       "title": "Turtle",
+                       "alias": "trig",
+                       "aliasTitles": {
+                               "trig": "TriG"
+                       },
+                       "owner": "jakubklimek"
                },
                "twig": {
                        "title": "Twig",
                "typescript": {
                        "title": "TypeScript",
                        "require": "javascript",
+                       "optional": "js-templates",
                        "alias": "ts",
                        "owner": "vkbansal"
                },
-               "t4-cs": {
-                       "title": "T4 Text Templates (C#)",
-                       "require": ["t4-templating", "csharp"],
-                       "alias": "t4",
-                       "owner": "RunDevelopment"
-               },
-               "t4-vb": {
-                       "title": "T4 Text Templates (VB)",
-                       "require": ["t4-templating", "visual-basic"],
-                       "owner": "RunDevelopment"
-               },
-               "t4-templating": {
-                       "title": "T4 templating",
+               "unrealscript": {
+                       "title": "UnrealScript",
+                       "alias": ["uscript", "uc"],
                        "owner": "RunDevelopment"
                },
                "vala": {
                },
                "visual-basic": {
                        "title": "Visual Basic",
-                       "alias": "vb",
+                       "alias": ["vb", "vba"],
+                       "aliasTitles": {
+                               "vba": "VBA"
+                       },
                        "owner": "Golmote"
                },
+               "warpscript": {
+                       "title": "WarpScript",
+                       "owner": "RunDevelopment"
+               },
                "wasm": {
                        "title": "WebAssembly",
                        "owner": "Golmote"
                        },
                        "owner": "freakmaxi"
                },
+               "xml-doc": {
+                       "title": "XML doc (.net)",
+                       "require": "markup",
+                       "modify": ["csharp", "fsharp", "vbnet"],
+                       "owner": "RunDevelopment"
+               },
                "xojo": {
                        "title": "Xojo (REALbasic)",
                        "owner": "Golmote"
                        "title": "YAML",
                        "alias": "yml",
                        "owner": "hason"
+               },
+               "yang": {
+                       "title": "YANG",
+                       "owner": "RunDevelopment"
+               },
+               "zig": {
+                       "title": "Zig",
+                       "owner": "RunDevelopment"
                }
        },
        "plugins": {
                        "path": "plugins/{id}/prism-{id}",
                        "link": "plugins/{id}/"
                },
-               "line-highlight": "Line Highlight",
+               "line-highlight": {
+                       "title": "Line Highlight",
+                       "description": "Highlights specific lines and/or line ranges."
+               },
                "line-numbers": {
                        "title": "Line Numbers",
+                       "description": "Line number at the beginning of code lines.",
                        "owner": "kuba-kubula"
                },
                "show-invisibles": {
                        "title": "Show Invisibles",
-                       "after": [
+                       "description": "Show hidden characters such as tabs and line breaks.",
+                       "optional": [
                                "autolinker",
                                "data-uri-highlight"
                        ]
                },
-               "autolinker": "Autolinker",
-               "wpd": "WebPlatform Docs",
+               "autolinker": {
+                       "title": "Autolinker",
+                       "description": "Converts URLs and emails in code to clickable links. Parses Markdown links in comments."
+               },
+               "wpd": {
+                       "title": "WebPlatform Docs",
+                       "description": "Makes tokens link to <a href=\"https://webplatform.github.io/docs/\">WebPlatform.org documentation</a>. The links open in a new tab."
+               },
                "custom-class": {
                        "title": "Custom Class",
+                       "description": "This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",
                        "owner": "dvkndn",
                        "noCSS": true
                },
                "file-highlight": {
                        "title": "File Highlight",
+                       "description": "Fetch external files and highlight them with Prism. Used on the Prism website itself.",
                        "noCSS": true
                },
                "show-language": {
                        "title": "Show Language",
+                       "description": "Display the highlighted language in code blocks (inline code does not show the label).",
                        "owner": "nauzilus",
                        "noCSS": true,
                        "require": "toolbar"
                },
                "jsonp-highlight": {
                        "title": "JSONP Highlight",
+                       "description": "Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",
                        "noCSS": true,
                        "owner": "nauzilus"
                },
                "highlight-keywords": {
                        "title": "Highlight Keywords",
+                       "description": "Adds special CSS classes for each keyword matched in the code. For example, the keyword <code>if</code> will have the class <code>keyword-if</code> as well. You can have fine grained control over the appearance of each keyword by providing your own CSS rules.",
                        "owner": "vkbansal",
                        "noCSS": true
                },
                "remove-initial-line-feed": {
                        "title": "Remove initial line feed",
+                       "description": "Removes the initial line feed in code blocks.",
                        "owner": "Golmote",
                        "noCSS": true
                },
+               "inline-color": {
+                       "title": "Inline color",
+                       "description": "Adds a small inline preview for colors in style sheets.",
+                       "require": "css-extras",
+                       "owner": "RunDevelopment"
+               },
                "previewers": {
                        "title": "Previewers",
+                       "description": "Previewers for angles, colors, gradients, easing and time.",
+                       "require": "css-extras",
                        "owner": "Golmote"
                },
                "autoloader": {
                        "title": "Autoloader",
+                       "description": "Automatically loads the needed languages to highlight the code blocks.",
                        "owner": "Golmote",
                        "noCSS": true
                },
                "keep-markup": {
                        "title": "Keep Markup",
+                       "description": "Prevents custom markup from being dropped out during highlighting.",
                        "owner": "Golmote",
-                       "after": "normalize-whitespace",
+                       "optional": "normalize-whitespace",
                        "noCSS": true
                },
                "command-line": {
                        "title": "Command Line",
+                       "description": "Display a command line with a prompt and, optionally, the output/response from the commands.",
                        "owner": "chriswells0"
                },
-               "unescaped-markup": "Unescaped Markup",
+               "unescaped-markup": {
+                       "title": "Unescaped Markup",
+                       "description": "Write markup without having to escape anything."
+               },
                "normalize-whitespace": {
                        "title": "Normalize Whitespace",
+                       "description": "Supports multiple operations to normalize whitespace in code blocks.",
                        "owner": "zeitgeist87",
-                       "after": "unescaped-markup",
+                       "optional": "unescaped-markup",
                        "noCSS": true
                },
                "data-uri-highlight": {
                        "title": "Data-URI Highlight",
+                       "description": "Highlights data-URI contents.",
                        "owner": "Golmote",
                        "noCSS": true
                },
                "toolbar": {
                        "title": "Toolbar",
+                       "description": "Attach a toolbar for plugins to easily register buttons on the top of a code block.",
                        "owner": "mAAdhaTTah"
                },
                "copy-to-clipboard": {
                        "title": "Copy to Clipboard Button",
+                       "description": "Add a button that copies the code block to the clipboard when clicked.",
                        "owner": "mAAdhaTTah",
                        "require": "toolbar",
                        "noCSS": true
+               },
+               "download-button": {
+                       "title": "Download Button",
+                       "description": "A button in the toolbar of a code block adding a convenient way to download a code file.",
+                       "owner": "Golmote",
+                       "require": "toolbar",
+                       "noCSS": true
+               },
+               "match-braces": {
+                       "title": "Match braces",
+                       "description": "Highlights matching braces.",
+                       "owner": "RunDevelopment"
+               },
+               "diff-highlight": {
+                       "title": "Diff Highlight",
+                       "description": "Highlights the code inside diff blocks.",
+                       "owner": "RunDevelopment",
+                       "require": "diff"
+               },
+               "filter-highlight-all": {
+                       "title": "Filter highlightAll",
+                       "description": "Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",
+                       "owner": "RunDevelopment",
+                       "noCSS": true
+               },
+               "treeview": {
+                       "title": "Treeview",
+                       "description": "A language with special styles to highlight file system tree structures.",
+                       "owner": "Golmote"
                }
        }
 }
index 1451060228b194aea991e5463c8bda15f35fd7e6..6d3f49db732580dbf37a4598a023deaa3a3070be 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-javascript","prism/components/prism-markup"], function () {
+define(["prism/prism","prism/components/prism-javascript"], function () {
 Prism.languages.actionscript = Prism.languages.extend('javascript',  {
        'keyword': /\b(?:as|break|case|catch|class|const|default|delete|do|else|extends|finally|for|function|if|implements|import|in|instanceof|interface|internal|is|native|new|null|package|private|protected|public|return|super|switch|this|throw|try|typeof|use|var|void|while|with|dynamic|each|final|get|include|namespace|native|override|set|static)\b/,
        'operator': /\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/
@@ -10,10 +10,9 @@ if (Prism.languages.markup) {
                'xml': {
                        pattern: /(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,
                        lookbehind: true,
-                       inside: {
-                               rest: Prism.languages.markup
-                       }
+                       inside: Prism.languages.markup
                }
        });
 }
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-agda.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-agda.js
new file mode 100644 (file)
index 0000000..072ffa3
--- /dev/null
@@ -0,0 +1,27 @@
+define(["prism/prism"], function () {
+(function (Prism) {
+
+       Prism.languages.agda = {
+               'comment': /\{-[\s\S]*?(?:-\}|$)|--.*/,
+               'string': {
+                       pattern: /"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,
+                       greedy: true,
+               },
+               'punctuation': /[(){}⦃⦄.;@]/,
+               'class-name': {
+                       pattern: /((?:data|record) +)\S+/,
+                       lookbehind: true,
+               },
+               'function': {
+                       pattern: /(^[ \t]*)[^:\r\n]+?(?=:)/m,
+                       lookbehind: true,
+               },
+               'operator': {
+                       pattern: /(^\s*|\s)(?:[=|:∀→λ\\?_]|->)(?=\s)/,
+                       lookbehind: true,
+               },
+               'keyword': /\b(?:Set|abstract|constructor|data|eta-equality|field|forall|forall|hiding|import|in|inductive|infix|infixl|infixr|instance|let|macro|module|mutual|no-eta-equality|open|overlap|pattern|postulate|primitive|private|public|quote|quoteContext|quoteGoal|quoteTerm|record|renaming|rewrite|syntax|tactic|unquote|unquoteDecl|unquoteDef|using|variable|where|with)\b/,
+       };
+}(Prism));
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-al.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-al.js
new file mode 100644 (file)
index 0000000..ce98312
--- /dev/null
@@ -0,0 +1,28 @@
+define(["prism/prism"], function () {
+// based on https://github.com/microsoft/AL/blob/master/grammar/alsyntax.tmlanguage
+
+Prism.languages.al = {
+       'comment': /\/\/.*|\/\*[\s\S]*?\*\//,
+       'string': {
+               pattern: /'(?:''|[^'\r\n])*'(?!')|"(?:""|[^"\r\n])*"(?!")/,
+               greedy: true
+       },
+       'function': {
+               pattern: /(\b(?:event|procedure|trigger)\s+|(?:^|[^.])\.\s*)[a-z_]\w*(?=\s*\()/i,
+               lookbehind: true
+       },
+       'keyword': [
+               // keywords
+               /\b(?:array|asserterror|begin|break|case|do|downto|else|end|event|exit|for|foreach|function|if|implements|in|indataset|interface|internal|local|of|procedure|program|protected|repeat|runonclient|securityfiltering|suppressdispose|temporary|then|to|trigger|until|var|while|with|withevents)\b/i,
+               // objects and metadata that are used like keywords
+               /\b(?:action|actions|addafter|addbefore|addfirst|addlast|area|assembly|chartpart|codeunit|column|controladdin|cuegroup|customizes|dataitem|dataset|dotnet|elements|enum|enumextension|extends|field|fieldattribute|fieldelement|fieldgroup|fieldgroups|fields|filter|fixed|grid|group|key|keys|label|labels|layout|modify|moveafter|movebefore|movefirst|movelast|page|pagecustomization|pageextension|part|profile|query|repeater|report|requestpage|schema|separator|systempart|table|tableelement|tableextension|textattribute|textelement|type|usercontrol|value|xmlport)\b/i
+       ],
+       'number': /\b(?:0x[\da-f]+|(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)(?:F|U(?:LL?)?|LL?)?\b/i,
+       'boolean': /\b(?:false|true)\b/i,
+       'variable': /\b(?:Curr(?:FieldNo|Page|Report)|RequestOptionsPage|x?Rec)\b/,
+       'class-name': /\b(?:automation|biginteger|bigtext|blob|boolean|byte|char|clienttype|code|completiontriggererrorlevel|connectiontype|database|dataclassification|datascope|date|dateformula|datetime|decimal|defaultlayout|dialog|dictionary|dotnetassembly|dotnettypedeclaration|duration|errorinfo|errortype|executioncontext|executionmode|fieldclass|fieldref|fieldtype|file|filterpagebuilder|guid|httpclient|httpcontent|httpheaders|httprequestmessage|httpresponsemessage|instream|integer|joker|jsonarray|jsonobject|jsontoken|jsonvalue|keyref|list|moduledependencyinfo|moduleinfo|none|notification|notificationscope|objecttype|option|outstream|pageresult|record|recordid|recordref|reportformat|securityfilter|sessionsettings|tableconnectiontype|tablefilter|testaction|testfield|testfilterfield|testpage|testpermissions|testrequestpage|text|textbuilder|textconst|textencoding|time|transactionmodel|transactiontype|variant|verbosity|version|view|views|webserviceactioncontext|webserviceactionresultcode|xmlattribute|xmlattributecollection|xmlcdata|xmlcomment|xmldeclaration|xmldocument|xmldocumenttype|xmlelement|xmlnamespacemanager|xmlnametable|xmlnode|xmlnodelist|xmlprocessinginstruction|xmlreadoptions|xmltext|xmlwriteoptions)\b/i,
+       'operator': /\.\.|:[=:]|[-+*/]=?|<>|[<>]=?|=|\b(?:and|div|mod|not|or|xor)\b/i,
+       'punctuation': /[()\[\]{}:.;,]/
+};
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-antlr4.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-antlr4.js
new file mode 100644 (file)
index 0000000..32c20bf
--- /dev/null
@@ -0,0 +1,68 @@
+define(["prism/prism"], function () {
+Prism.languages.antlr4 = {
+       'comment': /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
+       'string': {
+               pattern: /'(?:\\.|[^\\'\r\n])*'/,
+               greedy: true
+       },
+       'character-class': {
+               pattern: /\[(?:\\.|[^\\\]\r\n])*\]/,
+               greedy: true,
+               alias: 'regex',
+               inside: {
+                       'range': {
+                               pattern: /([^[]|(?:^|[^\\])(?:\\\\)*\\\[)-(?!\])/,
+                               lookbehind: true,
+                               alias: 'punctuation'
+                       },
+                       'escape': /\\(?:u(?:[a-fA-F\d]{4}|\{[a-fA-F\d]+\})|[pP]\{[=\w-]+\}|[^\r\nupP])/,
+                       'punctuation': /[\[\]]/
+               }
+       },
+       'action': {
+               pattern: /\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}/,
+               greedy: true,
+               inside: {
+                       'content': {
+                               // this might be C, C++, Python, Java, C#, or any other language ANTLR4 compiles to
+                               pattern: /(\{)[\s\S]+(?=\})/,
+                               lookbehind: true
+                       },
+                       'punctuation': /[{}]/
+               }
+       },
+       'command': {
+               pattern: /(->\s*)(?:\s*(?:,\s*)?\b[a-z]\w*(?:\s*\([^()\r\n]*\))?)+(?=\s*;)/i,
+               lookbehind: true,
+               inside: {
+                       'function': /\b\w+(?=\s*(?:[,(]|$))/,
+                       'punctuation': /[,()]/
+               }
+       },
+       'annotation': {
+               pattern: /@\w+(?:::\w+)*/,
+               alias: 'keyword'
+       },
+       'label': {
+               pattern: /#[ \t]*\w+/,
+               alias: 'punctuation'
+       },
+       'keyword': /\b(?:catch|channels|finally|fragment|grammar|import|lexer|locals|mode|options|parser|returns|throws|tokens)\b/,
+       'definition': [
+               {
+                       pattern: /\b[a-z]\w*(?=\s*:)/,
+                       alias: ['rule', 'class-name']
+               },
+               {
+                       pattern: /\b[A-Z]\w*(?=\s*:)/,
+                       alias: ['token', 'constant']
+               },
+       ],
+       'constant': /\b[A-Z][A-Z_]*\b/,
+       'operator': /\.\.|->|[|~]|[*+?]\??/,
+       'punctuation': /[;:()=]/
+};
+
+Prism.languages.g4 = Prism.languages.antlr4;
+
+return Prism; })
\ No newline at end of file
index 3a6dfa4ef9cb45eba465fbbc0215a629b2942ded..78c65fecffe9f8dca4a9b83f6b2ce68594a0acb5 100644 (file)
@@ -5,7 +5,7 @@ Prism.languages.apl = {
                pattern: /'(?:[^'\r\n]|'')*'/,
                greedy: true
        },
-       'number': /¯?(?:\d*\.?\d+(?:e[+¯]?\d+)?|¯|∞)(?:j¯?(?:\d*\.?\d+(?:e[+¯]?\d+)?|¯|∞))?/i,
+       'number': /¯?(?:\d*\.?\b\d+(?:e[+¯]?\d+)?|¯|∞)(?:j¯?(?:\d*\.?\d+(?:e[+¯]?\d+)?|¯|∞))?/i,
        'statement': /:[A-Z][a-z][A-Za-z]*\b/,
        'system-function': {
                pattern: /⎕[A-Z]+/i,
@@ -18,7 +18,7 @@ Prism.languages.apl = {
                alias: 'operator'
        },
        'dyadic-operator': {
-               pattern: /[.⍣⍠⍤∘⌸@⌺]/,
+               pattern: /[.⍣⍠⍤∘⌸@⌺]/,
                alias: 'operator'
        },
        'assignment': {
@@ -31,4 +31,5 @@ Prism.languages.apl = {
                alias: 'builtin'
        }
 };
+
 return Prism; })
\ No newline at end of file
index 7b8b1a442b05d0f59cdd678acbda2bb0baf3d05c..1ccec1b2b6dc1c2accdae0c78b0dacea4c39868f 100644 (file)
@@ -2,7 +2,7 @@ define(["prism/prism"], function () {
 Prism.languages.applescript = {
        'comment': [
                // Allow one level of nesting
-               /\(\*(?:\(\*[\s\S]*?\*\)|[\s\S])*?\*\)/,
+               /\(\*(?:\(\*(?:[^*]|\*(?!\)))*\*\)|(?!\(\*)[\s\S])*?\*\)/,
                /--.+/,
                /#.+/
        ],
@@ -19,4 +19,5 @@ Prism.languages.applescript = {
        },
        'punctuation': /[{}():,¬«»《》]/
 };
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-aql.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-aql.js
new file mode 100644 (file)
index 0000000..8b5bfe6
--- /dev/null
@@ -0,0 +1,44 @@
+define(["prism/prism"], function () {
+Prism.languages.aql = {
+       'comment': /\/\/.*|\/\*[\s\S]*?\*\//,
+       'property': {
+               pattern: /([{,]\s*)(?:(?!\d)\w+|(["'´`])(?:(?!\2)[^\\\r\n]|\\.)*\2)(?=\s*:)/,
+               lookbehind: true,
+               greedy: true
+       },
+       'string': {
+               pattern: /(["'´`])(?:(?!\1)[^\\\r\n]|\\.)*\1/,
+               greedy: true
+       },
+       'variable': /@@?\w+/,
+       'keyword': [
+               {
+                       pattern: /(\bWITH\s+)COUNT(?=\s+INTO\b)/i,
+                       lookbehind: true
+               },
+               /\b(?:AGGREGATE|ALL|AND|ANY|ASC|COLLECT|DESC|DISTINCT|FILTER|FOR|GRAPH|IN|INBOUND|INSERT|INTO|K_SHORTEST_PATHS|LET|LIKE|LIMIT|NONE|NOT|NULL|OR|OUTBOUND|REMOVE|REPLACE|RETURN|SHORTEST_PATH|SORT|UPDATE|UPSERT|WITH)\b/i,
+               // pseudo keywords get a lookbehind to avoid false positives
+               {
+                       pattern: /(^|[^\w.[])(?:KEEP|PRUNE|SEARCH|TO)\b/i,
+                       lookbehind: true
+               },
+               {
+                       pattern: /(^|[^\w.[])(?:CURRENT|NEW|OLD)\b/,
+                       lookbehind: true
+               },
+               {
+                       pattern: /\bOPTIONS(?=\s*{)/i
+               }
+       ],
+       'function': /(?!\d)\w+(?=\s*\()/,
+       'boolean': /(?:true|false)/i,
+       'range': {
+               pattern: /\.\./,
+               alias: 'operator'
+       },
+       'number': /(?:\B\.\d+|\b(?:0|[1-9]\d*)(?:\.\d+)?)(?:e[+-]?\d+)?/i,
+       'operator': /\*{2,}|[=!]~|[!=<>]=?|&&|\|\||[-+*/%]/,
+       'punctuation': /::|[?.:,;()[\]{}]/
+};
+
+return Prism; })
\ No newline at end of file
index f7dcc99e553aa679669c800cd0d85c0ceffdf0e5..a7540b25ab787af3f18bebc348e70f068f6b5e9a 100644 (file)
@@ -150,7 +150,7 @@ define(["prism/prism"], function () {
                        Those do not have the restrictions of the constrained quotes.
                        They are, in order: __emphasis__, **strong**, ++monospace++, +++passthrough+++, ##unquoted##, $$passthrough$$, ~subscript~, ^superscript^, {attribute-reference}, [[anchor]], [[[bibliography anchor]]], <<xref>>, (((indexes))) and ((indexes))
                         */
-                       pattern: /(^|[^\\])(?:(?:\B\[(?:[^\]\\"]|(["'])(?:(?!\2)[^\\]|\\.)*\2|\\.)*\])?(?:\b_(?!\s)(?: _|[^_\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: _|[^_\\\r\n]|\\.)+)*_\b|\B``(?!\s).+?(?:(?:\r?\n|\r).+?)*''\B|\B`(?!\s)(?: ['`]|.)+?(?:(?:\r?\n|\r)(?: ['`]|.)+?)*['`]\B|\B(['*+#])(?!\s)(?: \3|(?!\3)[^\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: \3|(?!\3)[^\\\r\n]|\\.)+)*\3\B)|(?:\[(?:[^\]\\"]|(["'])(?:(?!\4)[^\\]|\\.)*\4|\\.)*\])?(?:(__|\*\*|\+\+\+?|##|\$\$|[~^]).+?(?:(?:\r?\n|\r).+?)*\5|\{[^}\r\n]+\}|\[\[\[?.+?(?:(?:\r?\n|\r).+?)*\]?\]\]|<<.+?(?:(?:\r?\n|\r).+?)*>>|\(\(\(?.+?(?:(?:\r?\n|\r).+?)*\)?\)\)))/m,
+                       pattern: /(^|[^\\])(?:(?:\B\[(?:[^\]\\"]|(["'])(?:(?!\2)[^\\]|\\.)*\2|\\.)*\])?(?:\b_(?!\s)(?: _|[^_\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: _|[^_\\\r\n]|\\.)+)*_\b|\B``(?!\s).+?(?:(?:\r?\n|\r).+?)*''\B|\B`(?!\s)(?:[^`'\s]|\s+\S)+['`]\B|\B(['*+#])(?!\s)(?: \3|(?!\3)[^\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: \3|(?!\3)[^\\\r\n]|\\.)+)*\3\B)|(?:\[(?:[^\]\\"]|(["'])(?:(?!\4)[^\\]|\\.)*\4|\\.)*\])?(?:(__|\*\*|\+\+\+?|##|\$\$|[~^]).+?(?:(?:\r?\n|\r).+?)*\5|\{[^}\r\n]+\}|\[\[\[?.+?(?:(?:\r?\n|\r).+?)*\]?\]\]|<<.+?(?:(?:\r?\n|\r).+?)*>>|\(\(\(?.+?(?:(?:\r?\n|\r).+?)*\)?\)\)))/m,
                        lookbehind: true,
                        inside: {
                                'attributes': attributes,
index d02c3529df2b14d8e264567ca3cbe0ea22f195db..9a8a20b4d68804b77714023a085a7229a0495fde 100644 (file)
@@ -7,19 +7,19 @@ Prism.languages.asm6502 = {
        },
        'string': /(["'`])(?:\\.|(?!\1)[^\\\r\n])*\1/,
        'opcode': {
-    pattern: /\b(?:adc|and|asl|bcc|bcs|beq|bit|bmi|bne|bpl|brk|bvc|bvs|clc|cld|cli|clv|cmp|cpx|cpy|dec|dex|dey|eor|inc|inx|iny|jmp|jsr|lda|ldx|ldy|lsr|nop|ora|pha|php|pla|plp|rol|ror|rti|rts|sbc|sec|sed|sei|sta|stx|sty|tax|tay|tsx|txa|txs|tya|ADC|AND|ASL|BCC|BCS|BEQ|BIT|BMI|BNE|BPL|BRK|BVC|BVS|CLC|CLD|CLI|CLV|CMP|CPX|CPY|DEC|DEX|DEY|EOR|INC|INX|INY|JMP|JSR|LDA|LDX|LDY|LSR|NOP|ORA|PHA|PHP|PLA|PLP|ROL|ROR|RTI|RTS|SBC|SEC|SED|SEI|STA|STX|STY|TAX|TAY|TSX|TXA|TXS|TYA)\b/,
+               pattern: /\b(?:adc|and|asl|bcc|bcs|beq|bit|bmi|bne|bpl|brk|bvc|bvs|clc|cld|cli|clv|cmp|cpx|cpy|dec|dex|dey|eor|inc|inx|iny|jmp|jsr|lda|ldx|ldy|lsr|nop|ora|pha|php|pla|plp|rol|ror|rti|rts|sbc|sec|sed|sei|sta|stx|sty|tax|tay|tsx|txa|txs|tya|ADC|AND|ASL|BCC|BCS|BEQ|BIT|BMI|BNE|BPL|BRK|BVC|BVS|CLC|CLD|CLI|CLV|CMP|CPX|CPY|DEC|DEX|DEY|EOR|INC|INX|INY|JMP|JSR|LDA|LDX|LDY|LSR|NOP|ORA|PHA|PHP|PLA|PLP|ROL|ROR|RTI|RTS|SBC|SEC|SED|SEI|STA|STX|STY|TAX|TAY|TSX|TXA|TXS|TYA)\b/,
                alias: 'property'
        },
        'hexnumber': {
-               pattern: /#?\$[\da-f]{2,4}/i,
+               pattern: /#?\$[\da-f]{2,4}\b/i,
                alias: 'string'
        },
        'binarynumber': {
-               pattern: /#?%[01]+/,
+               pattern: /#?%[01]+\b/,
                alias: 'string'
        },
        'decimalnumber': {
-               pattern: /#?\d+/,
+               pattern: /#?\b\d+\b/,
                alias: 'string'
        },
        'register': {
index 936f30163140c1956e44abce6a4497b4339c2a6b..e15e8d93fd282ece8cd217e61202c77e43a6ffc7 100644 (file)
@@ -1,16 +1,24 @@
 define(["prism/prism","prism/components/prism-markup","prism/components/prism-csharp"], function () {
 Prism.languages.aspnet = Prism.languages.extend('markup', {
-       'page-directive tag': {
+       'page-directive': {
                pattern: /<%\s*@.*%>/i,
+               alias: 'tag',
                inside: {
-                       'page-directive tag': /<%\s*@\s*(?:Assembly|Control|Implements|Import|Master(?:Type)?|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i,
+                       'page-directive': {
+                               pattern: /<%\s*@\s*(?:Assembly|Control|Implements|Import|Master(?:Type)?|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i,
+                               alias: 'tag'
+                       },
                        rest: Prism.languages.markup.tag.inside
                }
        },
-       'directive tag': {
+       'directive': {
                pattern: /<%.*%>/i,
+               alias: 'tag',
                inside: {
-                       'directive tag': /<%\s*?[$=%#:]{0,2}|%>/i,
+                       'directive': {
+                               pattern: /<%\s*?[$=%#:]{0,2}|%>/i,
+                               alias: 'tag'
+                       },
                        rest: Prism.languages.csharp
                }
        }
@@ -20,19 +28,24 @@ Prism.languages.aspnet.tag.pattern = /<(?!%)\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:(
 
 // match directives of attribute value foo="<% Bar %>"
 Prism.languages.insertBefore('inside', 'punctuation', {
-       'directive tag': Prism.languages.aspnet['directive tag']
+       'directive': Prism.languages.aspnet['directive']
 }, Prism.languages.aspnet.tag.inside["attr-value"]);
 
 Prism.languages.insertBefore('aspnet', 'comment', {
-       'asp comment': /<%--[\s\S]*?--%>/
+       'asp-comment': {
+               pattern: /<%--[\s\S]*?--%>/,
+               alias: ['asp', 'comment']
+       }
 });
 
 // script runat="server" contains csharp, not javascript
 Prism.languages.insertBefore('aspnet', Prism.languages.javascript ? 'script' : 'tag', {
-       'asp script': {
+       'asp-script': {
                pattern: /(<script(?=.*runat=['"]?server['"]?)[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,
                lookbehind: true,
+               alias: ['asp', 'script'],
                inside: Prism.languages.csharp || {}
        }
 });
+
 return Prism; })
\ No newline at end of file
index 8ea73dab48ab43858d9b6122b0d9a4a798b1e409..fb829a54cfc7784b512c5dfc27e9d001333ca34d 100644 (file)
@@ -1,29 +1,37 @@
 define(["prism/prism"], function () {
 // NOTES - follows first-first highlight method, block is locked after highlight, different from SyntaxHl
-Prism.languages.autohotkey= {
-       'comment': {
-               pattern: /(^[^";\n]*("[^"\n]*?"[^"\n]*?)*)(?:;.*$|^\s*\/\*[\s\S]*\n\*\/)/m,
-               lookbehind: true
-       },
+Prism.languages.autohotkey = {
+       'comment': [
+               {
+                       pattern: /(^|\s);.*/,
+                       lookbehind: true
+               },
+               {
+                       pattern: /(^\s*)\/\*[^\r\n]*(?:[\r\n](?![ \t]*\*\/)|[^\r\n])*(?:[\r\n][ \t]*\*\/)?/m,
+                       lookbehind: true,
+                       greedy: true
+               }
+       ],
        'string': /"(?:[^"\n\r]|"")*"/m,
-       'function': /[^(); \t,\n+*\-=?>:\\\/<&%\[\]]+?(?=\()/m,  //function - don't use .*\) in the end bcoz string locks it
-       'tag': /^[ \t]*[^\s:]+?(?=:(?:[^:]|$))/m,  //labels
+       'tag': /^[ \t]*[^\s:]+?(?=:(?:[^:]|$))/m, //labels
        'variable': /%\w+%/,
        'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,
        'operator': /\?|\/\/?=?|:=|\|[=|]?|&[=&]?|\+[=+]?|-[=-]?|\*[=*]?|<(?:<=?|>|=)?|>>?=?|[.^!=~]=?|\b(?:AND|NOT|OR)\b/,
-       'punctuation': /[{}[\]():,]/,
        'boolean': /\b(?:true|false)\b/,
 
-       'selector': /\b(?:AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,
+       'selector': /\b(?:AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetRegView|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,
 
-       'constant': /\b(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\b/i,
+       'constant': /\b(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_fileencoding|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_is64bitos|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|a_priorkey|programfiles|a_programfiles|a_programs|a_programscommon|a_ptrsize|a_regview|a_screendpi|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scripthwnd|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\b/i,
 
-       'builtin': /\b(?:abs|acos|asc|asin|atan|ceil|chr|class|cos|dllcall|exp|fileexist|Fileopen|floor|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|IsObject|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|strsplit|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist|__New|__Call|__Get|__Set)\b/i,
+       'builtin': /\b(?:abs|acos|asc|asin|atan|ceil|chr|class|comobjactive|comobjarray|comobjconnect|comobjcreate|comobjerror|comobjflags|comobjget|comobjquery|comobjtype|comobjvalue|cos|dllcall|exp|fileexist|Fileopen|floor|format|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|IsObject|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|ltrim|rtrim|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|strreplace|sb_seticon|sb_setparts|sb_settext|strsplit|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist|__New|__Call|__Get|__Set)\b/i,
 
        'symbol': /\b(?:alt|altdown|altup|appskey|backspace|browser_back|browser_favorites|browser_forward|browser_home|browser_refresh|browser_search|browser_stop|bs|capslock|ctrl|ctrlbreak|ctrldown|ctrlup|del|delete|down|end|enter|esc|escape|f1|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f2|f20|f21|f22|f23|f24|f3|f4|f5|f6|f7|f8|f9|home|ins|insert|joy1|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy2|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy3|joy30|joy31|joy32|joy4|joy5|joy6|joy7|joy8|joy9|joyaxes|joybuttons|joyinfo|joyname|joypov|joyr|joyu|joyv|joyx|joyy|joyz|lalt|launch_app1|launch_app2|launch_mail|launch_media|lbutton|lcontrol|lctrl|left|lshift|lwin|lwindown|lwinup|mbutton|media_next|media_play_pause|media_prev|media_stop|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadadd|numpadclear|numpaddel|numpaddiv|numpaddot|numpaddown|numpadend|numpadenter|numpadhome|numpadins|numpadleft|numpadmult|numpadpgdn|numpadpgup|numpadright|numpadsub|numpadup|pgdn|pgup|printscreen|ralt|rbutton|rcontrol|rctrl|right|rshift|rwin|rwindown|rwinup|scrolllock|shift|shiftdown|shiftup|space|tab|up|volume_down|volume_mute|volume_up|wheeldown|wheelleft|wheelright|wheelup|xbutton1|xbutton2)\b/i,
 
-       'important': /#\b(?:AllowSameLineComments|ClipboardTimeout|CommentFlag|ErrorStdOut|EscapeChar|HotkeyInterval|HotkeyModifierTimeout|Hotstring|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Include|IncludeAgain|InstallKeybdHook|InstallMouseHook|KeyHistory|LTrim|MaxHotkeysPerInterval|MaxMem|MaxThreads|MaxThreadsBuffer|MaxThreadsPerHotkey|NoEnv|NoTrayIcon|Persistent|SingleInstance|UseHook|WinActivateForce)\b/i,
+       'important': /#\b(?:AllowSameLineComments|ClipboardTimeout|CommentFlag|DerefChar|ErrorStdOut|EscapeChar|HotkeyInterval|HotkeyModifierTimeout|Hotstring|If|IfTimeout|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Include|IncludeAgain|InputLevel|InstallKeybdHook|InstallMouseHook|KeyHistory|MaxHotkeysPerInterval|MaxMem|MaxThreads|MaxThreadsBuffer|MaxThreadsPerHotkey|MenuMaskKey|NoEnv|NoTrayIcon|Persistent|SingleInstance|UseHook|Warn|WinActivateForce)\b/i,
 
-       'keyword': /\b(?:Abort|AboveNormal|Add|ahk_class|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Checkbox|Checked|CheckedGray|Choose|ChooseString|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Expand|ExStyle|FileSystem|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Region|Relative|Rename|Report|Resize|Restore|Retry|RGB|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab2|TabStop|Text|Theme|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|TryAgain|Type|UnCheck|underline|Unicode|Unlock|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i
+       'keyword': /\b(?:Abort|AboveNormal|Add|ahk_class|ahk_exe|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Checkbox|Checked|CheckedGray|Choose|ChooseString|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Expand|ExStyle|FileSystem|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Region|Relative|Rename|Report|Resize|Restore|Retry|RGB|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab2|TabStop|Text|Theme|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|TryAgain|Throw|Try|Catch|Finally|Type|UnCheck|underline|Unicode|Unlock|Until|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i,
+       'function': /[^(); \t,\n+*\-=?>:\\\/<&%\[\]]+?(?=\()/m,
+       'punctuation': /[{}[\]():,]/
 };
+
 return Prism; })
\ No newline at end of file
index d68ecde857d1ac11fcffaa16201a454f0a4a6ceb..1fd9b86eb951b6fd14940c0546298a491693efca 100644 (file)
@@ -108,7 +108,7 @@ define(["prism/prism"], function () {
                'string': [
                        // Support for Here-documents https://en.wikipedia.org/wiki/Here_document
                        {
-                               pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)(?:[\s\S])*?(?:\r?\n|\r)\2/,
+                               pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/,
                                lookbehind: true,
                                greedy: true,
                                inside: insideString
@@ -116,13 +116,14 @@ define(["prism/prism"], function () {
                        // Here-document with quotes around the tag
                        // → No expansion (so no “inside”).
                        {
-                               pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)(?:[\s\S])*?(?:\r?\n|\r)\3/,
+                               pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/,
                                lookbehind: true,
                                greedy: true
                        },
                        // “Normal” string
                        {
-                               pattern: /(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/,
+                               pattern: /(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\2)[^\\])*\2/,
+                               lookbehind: true,
                                greedy: true,
                                inside: insideString
                        }
@@ -133,7 +134,7 @@ define(["prism/prism"], function () {
                },
                'variable': insideString.variable,
                'function': {
-                       pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,
+                       pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,
                        lookbehind: true
                },
                'keyword': {
index 42184819a8f856468bfa8ef3774bdcb0147acc16..18c1cb1b32ec5efadcc66d5460bb827acd841ced 100644 (file)
@@ -8,7 +8,7 @@ define(["prism/prism"], function () {
                        'punctuation': /:/
                }
        };
-       var string = /"[^"]*"/;
+       var string = /"(?:[\\"]"|[^"])*"(?!")/;
        var number = /(?:\b|-)\d+\b/;
 
        Prism.languages.batch = {
@@ -77,7 +77,7 @@ define(["prism/prism"], function () {
                        },
                        {
                                // Other commands
-                               pattern: /((?:^|[&(])[ \t]*@?)\w+\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,
+                               pattern: /((?:^|[&(])[ \t]*@?)\w+\b(?:"(?:[\\"]"|[^"])*"(?!")|[^"^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,
                                lookbehind: true,
                                inside: {
                                        'keyword': /^\w+\b/i,
@@ -98,4 +98,5 @@ define(["prism/prism"], function () {
                'punctuation': /[()']/
        };
 }(Prism));
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-bbcode.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-bbcode.js
new file mode 100644 (file)
index 0000000..bd4e9dc
--- /dev/null
@@ -0,0 +1,31 @@
+define(["prism/prism"], function () {
+Prism.languages.bbcode = {
+       'tag': {
+               pattern: /\[\/?[^\s=\]]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'"\]=]+))?(?:\s+[^\s=\]]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'"\]=]+))*\s*\]/,
+               inside: {
+                       'tag': {
+                               pattern: /^\[\/?[^\s=\]]+/,
+                               inside: {
+                                       'punctuation': /^\[\/?/
+                               }
+                       },
+                       'attr-value': {
+                               pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'"\]=]+)/i,
+                               inside: {
+                                       'punctuation': [
+                                               /^=/,
+                                               {
+                                                       pattern: /^(\s*)["']|["']$/,
+                                                       lookbehind: true
+                                               }
+                                       ]
+                               }
+                       },
+                       'punctuation': /\]/,
+                       'attr-name': /[^\s=\]]+/
+               }
+       }
+};
+
+Prism.languages.shortcode = Prism.languages.bbcode;
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-brightscript.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-brightscript.js
new file mode 100644 (file)
index 0000000..4d1c1be
--- /dev/null
@@ -0,0 +1,47 @@
+define(["prism/prism"], function () {
+Prism.languages.brightscript = {
+       'comment': /(?:\brem|').*/i,
+       'directive-statement': {
+               pattern: /(^[\t ]*)#(?:const|else(?:[\t ]+if)?|end[\t ]+if|error|if).*/im,
+               lookbehind: true,
+               alias: 'property',
+               inside: {
+                       'error-message': {
+                               pattern: /(^#error).+/,
+                               lookbehind: true
+                       },
+                       'directive': {
+                               pattern: /^#(?:const|else(?:[\t ]+if)?|end[\t ]+if|error|if)/,
+                               alias: 'keyword'
+                       },
+                       'expression': {
+                               pattern: /[\s\S]+/,
+                               inside: null // see below
+                       }
+               }
+       },
+       'property': {
+               pattern: /([\r\n{,][\t ]*)(?:(?!\d)\w+|"(?:[^"\r\n]|"")*"(?!"))(?=[ \t]*:)/,
+               lookbehind: true,
+               greedy: true
+       },
+       'string': {
+               pattern: /"(?:[^"\r\n]|"")*"(?!")/,
+               greedy: true
+       },
+       'class-name': {
+               pattern: /(\bAs[\t ]+)\w+/i,
+               lookbehind: true
+       },
+       'keyword': /\b(?:As|Dim|Each|Else|Elseif|End|Exit|For|Function|Goto|If|In|Print|Return|Step|Stop|Sub|Then|To|While)\b/i,
+       'boolean': /\b(?:true|false)\b/i,
+       'function': /\b(?!\d)\w+(?=[\t ]*\()/i,
+       'number': /(?:\b\d+(?:\.\d+)?(?:[ed][+-]\d+)?|&h[a-f\d]+)\b[%&!#]?/i,
+       'operator': /--|\+\+|>>=?|<<=?|<>|[-+*/\\<>]=?|[:^=?]|\b(?:and|mod|not|or)\b/i,
+       'punctuation': /[.,;()[\]{}]/,
+       'constant': /\b(?:LINE_NUM)\b/i
+};
+
+Prism.languages.brightscript['directive-statement'].inside.expression.inside = Prism.languages.brightscript;
+
+return Prism; })
\ No newline at end of file
index 0855b32514bb792d2d0c03cfdf71f38be301b3ff..26f9c5338e168cd44514d23185b0723ebcd13a04 100644 (file)
@@ -1,10 +1,15 @@
 define(["prism/prism","prism/components/prism-clike"], function () {
 Prism.languages.c = Prism.languages.extend('clike', {
+       'comment': {
+               pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,
+               greedy: true
+       },
        'class-name': {
-               pattern: /(\b(?:enum|struct)\s+)\w+/,
+               pattern: /(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+/,
                lookbehind: true
        },
-       'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
+       'keyword': /\b(?:__attribute__|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
+       'function': /[a-z_]\w*(?=\s*\()/i,
        'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/,
        'number': /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i
 });
@@ -13,20 +18,31 @@ Prism.languages.insertBefore('c', 'string', {
        'macro': {
                // allow for multiline macro definitions
                // spaces after the # character compile fine with gcc
-               pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,
+               pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,
                lookbehind: true,
+               greedy: true,
                alias: 'property',
                inside: {
-                       // highlight the path of the include statement as a string
-                       'string': {
-                               pattern: /(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/,
-                               lookbehind: true
-                       },
+                       'string': [
+                               {
+                                       // highlight the path of the include statement as a string
+                                       pattern: /^(#\s*include\s*)<[^>]+>/,
+                                       lookbehind: true
+                               },
+                               Prism.languages.c['string']
+                       ],
+                       'comment': Prism.languages.c['comment'],
                        // highlight macro directives as keywords
                        'directive': {
-                               pattern: /(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
+                               pattern: /^(#\s*)[a-z]+/,
                                lookbehind: true,
                                alias: 'keyword'
+                       },
+                       'directive-hash': /^#/,
+                       'punctuation': /##|\\(?=[\r\n])/,
+                       'expression': {
+                               pattern: /\S[\s\S]*/,
+                               inside: Prism.languages.c
                        }
                }
        },
index 0456f5ab58e523fd6f61aa86de11f2fd31ee1f19..220c8a8d81313a464fcd1f2978d5f55922fd4521 100644 (file)
@@ -1,29 +1,29 @@
 define(["prism/prism"], function () {
 Prism.languages.cil = {
        'comment': /\/\/.*/,
-       
+
        'string': {
                pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
                greedy: true
        },
-       
+
        'directive': {
                pattern: /(^|\W)\.[a-z]+(?=\s)/,
                lookbehind: true,
                alias: 'class-name'
        },
-       
+
        // Actually an assembly reference
        'variable': /\[[\w\.]+\]/,
-       
-       
+
+
        'keyword': /\b(?:abstract|ansi|assembly|auto|autochar|beforefieldinit|bool|bstr|byvalstr|catch|char|cil|class|currency|date|decimal|default|enum|error|explicit|extends|extern|famandassem|family|famorassem|final(?:ly)?|float32|float64|hidebysig|iant|idispatch|implements|import|initonly|instance|u?int(?:8|16|32|64)?|interface|iunknown|literal|lpstr|lpstruct|lptstr|lpwstr|managed|method|native(?:Type)?|nested|newslot|object(?:ref)?|pinvokeimpl|private|privatescope|public|reqsecobj|rtspecialname|runtime|sealed|sequential|serializable|specialname|static|string|struct|syschar|tbstr|unicode|unmanagedexp|unsigned|value(?:type)?|variant|virtual|void)\b/,
-       
-       'function': /\b(?:(?:constrained|unaligned|volatile|readonly|tail|no)\.)?(?:conv\.(?:[iu][1248]?|ovf\.[iu][1248]?(?:\.un)?|r\.un|r4|r8)|ldc\.(?:i4(?:\.[0-9]+|\.[mM]1|\.s)?|i8|r4|r8)|ldelem(?:\.[iu][1248]?|\.r[48]|\.ref|a)?|ldind\.(?:[iu][1248]?|r[48]|ref)|stelem\.?(?:i[1248]?|r[48]|ref)?|stind\.(i[1248]?|r[48]|ref)?|end(?:fault|filter|finally)|ldarg(?:\.[0-3s]|a(?:\.s)?)?|ldloc(?:\.[0-9]+|\.s)?|sub(?:\.ovf(?:\.un)?)?|mul(?:\.ovf(?:\.un)?)?|add(?:\.ovf(?:\.un)?)?|stloc(?:\.[0-3s])?|refany(?:type|val)|blt(?:\.un)?(?:\.s)?|ble(?:\.un)?(?:\.s)?|bgt(?:\.un)?(?:\.s)?|bge(?:\.un)?(?:\.s)?|unbox(?:\.any)?|init(?:blk|obj)|call(?:i|virt)?|brfalse(?:\.s)?|bne\.un(?:\.s)?|ldloca(?:\.s)?|brzero(?:\.s)?|brtrue(?:\.s)?|brnull(?:\.s)?|brinst(?:\.s)?|starg(?:\.s)?|leave(?:\.s)?|shr(?:\.un)?|rem(?:\.un)?|div(?:\.un)?|clt(?:\.un)?|alignment|ldvirtftn|castclass|beq(?:\.s)?|mkrefany|localloc|ckfinite|rethrow|ldtoken|ldsflda|cgt\.un|arglist|switch|stsfld|sizeof|newobj|newarr|ldsfld|ldnull|ldflda|isinst|throw|stobj|stloc|stfld|ldstr|ldobj|ldlen|ldftn|ldfld|cpobj|cpblk|break|br\.s|xor|shl|ret|pop|not|nop|neg|jmp|dup|clt|cgt|ceq|box|and|or|br)\b/,
-       
+
+       'function': /\b(?:(?:constrained|unaligned|volatile|readonly|tail|no)\.)?(?:conv\.(?:[iu][1248]?|ovf\.[iu][1248]?(?:\.un)?|r\.un|r4|r8)|ldc\.(?:i4(?:\.[0-9]+|\.[mM]1|\.s)?|i8|r4|r8)|ldelem(?:\.[iu][1248]?|\.r[48]|\.ref|a)?|ldind\.(?:[iu][1248]?|r[48]|ref)|stelem\.?(?:i[1248]?|r[48]|ref)?|stind\.(?:i[1248]?|r[48]|ref)?|end(?:fault|filter|finally)|ldarg(?:\.[0-3s]|a(?:\.s)?)?|ldloc(?:\.[0-9]+|\.s)?|sub(?:\.ovf(?:\.un)?)?|mul(?:\.ovf(?:\.un)?)?|add(?:\.ovf(?:\.un)?)?|stloc(?:\.[0-3s])?|refany(?:type|val)|blt(?:\.un)?(?:\.s)?|ble(?:\.un)?(?:\.s)?|bgt(?:\.un)?(?:\.s)?|bge(?:\.un)?(?:\.s)?|unbox(?:\.any)?|init(?:blk|obj)|call(?:i|virt)?|brfalse(?:\.s)?|bne\.un(?:\.s)?|ldloca(?:\.s)?|brzero(?:\.s)?|brtrue(?:\.s)?|brnull(?:\.s)?|brinst(?:\.s)?|starg(?:\.s)?|leave(?:\.s)?|shr(?:\.un)?|rem(?:\.un)?|div(?:\.un)?|clt(?:\.un)?|alignment|ldvirtftn|castclass|beq(?:\.s)?|mkrefany|localloc|ckfinite|rethrow|ldtoken|ldsflda|cgt\.un|arglist|switch|stsfld|sizeof|newobj|newarr|ldsfld|ldnull|ldflda|isinst|throw|stobj|stloc|stfld|ldstr|ldobj|ldlen|ldftn|ldfld|cpobj|cpblk|break|br\.s|xor|shl|ret|pop|not|nop|neg|jmp|dup|clt|cgt|ceq|box|and|or|br)\b/,
+
        'boolean': /\b(?:true|false)\b/,
        'number': /\b-?(?:0x[0-9a-fA-F]+|[0-9]+)(?:\.[0-9a-fA-F]+)?\b/i,
-       
+
        'punctuation': /[{}[\];(),:=]|IL_[0-9A-Za-z]+/
 }
 
index 6a56b59d9e350a33e551086520ca3feee31b14ff..324331bbc33bc49f5f629e0336ad1b65b9c2cd65 100644 (file)
@@ -16,17 +16,17 @@ Prism.languages.clike = {
                greedy: true
        },
        'class-name': {
-               pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,
+               pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,
                lookbehind: true,
                inside: {
-                       punctuation: /[.\\]/
+                       'punctuation': /[.\\]/
                }
        },
        'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
        'boolean': /\b(?:true|false)\b/,
        'function': /\w+(?=\()/,
        'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
-       'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
+       'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
        'punctuation': /[{}[\];(),.:]/
 };
 
index 51d5fba659116b0725e03559fd194c6a8503174c..fc875167fca86fc518c083f87a3539b0e12c8ba0 100644 (file)
@@ -1,16 +1,19 @@
 define(["prism/prism"], function () {
 // Copied from https://github.com/jeluard/prism-clojure
 Prism.languages.clojure = {
-       comment: /;+.*/,
-       string: /"(?:\\.|[^\\"\r\n])*"/,
-       operator: /(?:::|[:|'])\b[a-z][\w*+!?-]*\b/i, //used for symbols and keywords
-       keyword: {
+       'comment': /;.*/,
+       'string': {
+               pattern: /"(?:[^"\\]|\\.)*"/,
+               greedy: true
+       },
+       'operator': /(?:::|[:|'])\b[a-z][\w*+!?-]*\b/i, //used for symbols and keywords
+       'keyword': {
                pattern: /([^\w+*'?-])(?:def|if|do|let|\.\.|quote|var|->>|->|fn|loop|recur|throw|try|monitor-enter|\.|new|set!|def\-|defn|defn\-|defmacro|defmulti|defmethod|defstruct|defonce|declare|definline|definterface|defprotocol|==|defrecord|>=|deftype|<=|defproject|ns|\*|\+|\-|\/|<|=|>|accessor|agent|agent-errors|aget|alength|all-ns|alter|and|append-child|apply|array-map|aset|aset-boolean|aset-byte|aset-char|aset-double|aset-float|aset-int|aset-long|aset-short|assert|assoc|await|await-for|bean|binding|bit-and|bit-not|bit-or|bit-shift-left|bit-shift-right|bit-xor|boolean|branch\?|butlast|byte|cast|char|children|class|clear-agent-errors|comment|commute|comp|comparator|complement|concat|conj|cons|constantly|cond|if-not|construct-proxy|contains\?|count|create-ns|create-struct|cycle|dec|deref|difference|disj|dissoc|distinct|doall|doc|dorun|doseq|dosync|dotimes|doto|double|down|drop|drop-while|edit|end\?|ensure|eval|every\?|false\?|ffirst|file-seq|filter|find|find-doc|find-ns|find-var|first|float|flush|for|fnseq|frest|gensym|get-proxy-class|get|hash-map|hash-set|identical\?|identity|if-let|import|in-ns|inc|index|insert-child|insert-left|insert-right|inspect-table|inspect-tree|instance\?|int|interleave|intersection|into|into-array|iterate|join|key|keys|keyword|keyword\?|last|lazy-cat|lazy-cons|left|lefts|line-seq|list\*|list|load|load-file|locking|long|loop|macroexpand|macroexpand-1|make-array|make-node|map|map-invert|map\?|mapcat|max|max-key|memfn|merge|merge-with|meta|min|min-key|name|namespace|neg\?|new|newline|next|nil\?|node|not|not-any\?|not-every\?|not=|ns-imports|ns-interns|ns-map|ns-name|ns-publics|ns-refers|ns-resolve|ns-unmap|nth|nthrest|or|parse|partial|path|peek|pop|pos\?|pr|pr-str|print|print-str|println|println-str|prn|prn-str|project|proxy|proxy-mappings|quot|rand|rand-int|range|re-find|re-groups|re-matcher|re-matches|re-pattern|re-seq|read|read-line|reduce|ref|ref-set|refer|rem|remove|remove-method|remove-ns|rename|rename-keys|repeat|replace|replicate|resolve|rest|resultset-seq|reverse|rfirst|right|rights|root|rrest|rseq|second|select|select-keys|send|send-off|seq|seq-zip|seq\?|set|short|slurp|some|sort|sort-by|sorted-map|sorted-map-by|sorted-set|special-symbol\?|split-at|split-with|str|string\?|struct|struct-map|subs|subvec|symbol|symbol\?|sync|take|take-nth|take-while|test|time|to-array|to-array-2d|tree-seq|true\?|union|up|update-proxy|val|vals|var-get|var-set|var\?|vector|vector-zip|vector\?|when|when-first|when-let|when-not|with-local-vars|with-meta|with-open|with-out-str|xml-seq|xml-zip|zero\?|zipmap|zipper)(?=[^\w+*'?-])/,
                lookbehind: true
        },
-       boolean: /\b(?:true|false|nil)\b/,
-       number: /\b[0-9A-Fa-f]+\b/,
-       punctuation: /[{}\[\](),]/
+       'boolean': /\b(?:true|false|nil)\b/,
+       'number': /\b[\da-f]+\b/i,
+       'punctuation': /[{}\[\](),]/
 };
 
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-concurnas.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-concurnas.js
new file mode 100644 (file)
index 0000000..b1eab06
--- /dev/null
@@ -0,0 +1,50 @@
+define(["prism/prism"], function () {
+Prism.languages.concurnas = {
+       'comment': [
+               {
+                       pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
+                       lookbehind: true
+               },
+               {
+                       pattern: /(^|[^\\:])\/\/.*/,
+                       lookbehind: true,
+                       greedy: true
+               }
+       ],
+       'langext': {
+               pattern: /\w+\s*\|\|[\s\S]+?\|\|/,
+               greedy: true,
+               alias: 'string'
+       },
+       'function': {
+               pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/,
+               lookbehind: true
+       },
+       'keyword': /\b(?:abstract|actor|also|annotation|assert|async|await|bool|boolean|break|byte|case|catch|changed|char|class|closed|constant|continue|def|default|del|double|elif|else|enum|every|extends|false|finally|float|for|from|global|gpudef|gpukernel|if|import|in|init|inject|int|lambda|local|long|loop|match|new|nodefault|null|of|onchange|open|out|override|package|parfor|parforsync|post|pre|private|protected|provide|provider|public|return|shared|short|single|size_t|sizeof|super|sync|this|throw|trait|trans|transient|true|try|typedef|unchecked|using|val|var|void|while|with)\b/,
+       'boolean': /\b(?:false|true)\b/,
+       'number': /\b0b[01][01_]*L?\b|\b0x[\da-f_]*\.?[\da-f_p+-]+\b|(?:\b\d[\d_]*\.?[\d_]*|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfls]?/i,
+       'punctuation': /[{}[\];(),.:]/,
+       'operator': /<==|>==|=>|->|<-|<>|\^|&==|&<>|!|\?|\?:|\.\?|\+\+|--|[-+*/=<>]=?|\b(?:and|as|band|bor|bxor|comp|is|isnot|mod|or)\b=?/,
+       'annotation': {
+               pattern: /@(?:\w+:)?(?:\w*|\[[^\]]+\])/,
+               alias: 'builtin'
+       }
+};
+
+Prism.languages.insertBefore('concurnas', 'langext', {
+       'string': {
+               pattern: /[rs]?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
+               greedy: true,
+               inside: {
+                       'interpolation': {
+                               pattern: /((?:^|[^\\])(?:\\{2})*){(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
+                               lookbehind: true,
+                               inside: Prism.languages.concurnas
+                       },
+                       'string': /[\s\S]+/
+               }
+       }
+});
+
+Prism.languages.conc = Prism.languages.concurnas;
+return Prism; })
\ No newline at end of file
index 278a7892c9398564e3d4f3133489a316a0f135ba..9df6f8a221d24f3931b6c70235161a251afbde20 100644 (file)
@@ -1,24 +1,59 @@
 define(["prism/prism","prism/components/prism-c"], function () {
-Prism.languages.cpp = Prism.languages.extend('c', {
-       'class-name': {
-               pattern: /(\b(?:class|enum|struct)\s+)\w+/,
-               lookbehind: true
-       },
-       'keyword': /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
-       'number': {
-               pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,
-               greedy: true
-       },
-       'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
-       'boolean': /\b(?:true|false)\b/
-});
+(function (Prism) {
 
-Prism.languages.insertBefore('cpp', 'string', {
-       'raw-string': {
-               pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
-               alias: 'string',
-               greedy: true
-       }
-});
+       var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/;
+
+       Prism.languages.cpp = Prism.languages.extend('c', {
+               'class-name': [
+                       {
+                               pattern: RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source
+                                       .replace(/<keyword>/g, function () { return keyword.source; })),
+                               lookbehind: true
+                       },
+                       // This is intended to capture the class name of method implementations like:
+                       //   void foo::bar() const {}
+                       // However! The `foo` in the above example could also be a namespace, so we only capture the class name if
+                       // it starts with an uppercase letter. This approximation should give decent results.
+                       /\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,
+                       // This will capture the class name before destructors like:
+                       //   Foo::~Foo() {}
+                       /\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,
+                       // This also intends to capture the class name of method implementations but here the class has template
+                       // parameters, so it can't be a namespace (until C++ adds generic namespaces).
+                       /\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/
+               ],
+               'keyword': keyword,
+               'number': {
+                       pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,
+                       greedy: true
+               },
+               'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
+               'boolean': /\b(?:true|false)\b/
+       });
+
+       Prism.languages.insertBefore('cpp', 'string', {
+               'raw-string': {
+                       pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
+                       alias: 'string',
+                       greedy: true
+               }
+       });
+
+       Prism.languages.insertBefore('cpp', 'class-name', {
+               // the base clause is an optional list of parent classes
+               // https://en.cppreference.com/w/cpp/language/class
+               'base-clause': {
+                       pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)(?:[^;{}"'])+?(?=\s*[;{])/,
+                       lookbehind: true,
+                       greedy: true,
+                       inside: Prism.languages.extend('cpp', {})
+               }
+       });
+       Prism.languages.insertBefore('inside', 'operator', {
+               // All untokenized words that are not namespaces should be class names
+               'class-name': /\b[a-z_]\w*\b(?!\s*::)/i
+       }, Prism.languages.cpp['base-clause']);
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
index 6bc59dd76011920881594d1a7272d6baeb7a4804..9161bc6cd4d590ba3742c9800fb2bc227dc46b68 100644 (file)
 define(["prism/prism","prism/components/prism-clike"], function () {
-Prism.languages.csharp = Prism.languages.extend('clike', {
-       'keyword': /\b(?:abstract|add|alias|as|ascending|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|do|double|dynamic|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|from|get|global|goto|group|if|implicit|in|int|interface|internal|into|is|join|let|lock|long|namespace|new|null|object|operator|orderby|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|select|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|value|var|virtual|void|volatile|where|while|yield)\b/,
-       'string': [
-               {
-                       pattern: /@("|')(?:\1\1|\\[\s\S]|(?!\1)[^\\])*\1/,
-                       greedy: true
-               },
-               {
-                       pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*?\1/,
-                       greedy: true
+(function (Prism) {
+
+       /**
+        * Replaces all placeholders "<<n>>" of given pattern with the n-th replacement (zero based).
+        *
+        * Note: This is a simple text based replacement. Be careful when using backreferences!
+        *
+        * @param {string} pattern the given pattern.
+        * @param {string[]} replacements a list of replacement which can be inserted into the given pattern.
+        * @returns {string} the pattern with all placeholders replaced with their corresponding replacements.
+        * @example replace(/a<<0>>a/.source, [/b+/.source]) === /a(?:b+)a/.source
+        */
+       function replace(pattern, replacements) {
+               return pattern.replace(/<<(\d+)>>/g, function (m, index) {
+                       return '(?:' + replacements[+index] + ')';
+               });
+       }
+       /**
+        * @param {string} pattern
+        * @param {string[]} replacements
+        * @param {string} [flags]
+        * @returns {RegExp}
+        */
+       function re(pattern, replacements, flags) {
+               return RegExp(replace(pattern, replacements), flags || '');
+       }
+
+       /**
+        * Creates a nested pattern where all occurrences of the string `<<self>>` are replaced with the pattern itself.
+        *
+        * @param {string} pattern
+        * @param {number} depthLog2
+        * @returns {string}
+        */
+       function nested(pattern, depthLog2) {
+               for (var i = 0; i < depthLog2; i++) {
+                       pattern = pattern.replace(/<<self>>/g, function () { return '(?:' + pattern + ')'; });
+               }
+               return pattern.replace(/<<self>>/g, '[^\\s\\S]');
+       }
+
+       // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
+       var keywordKinds = {
+               // keywords which represent a return or variable type
+               type: 'bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void',
+               // keywords which are used to declare a type
+               typeDeclaration: 'class enum interface struct',
+               // contextual keywords
+               // ("var" and "dynamic" are missing because they are used like types)
+               contextual: 'add alias and ascending async await by descending from get global group into join let nameof not notnull on or orderby partial remove select set unmanaged value when where where',
+               // all other keywords
+               other: 'abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield'
+       };
+
+       // keywords
+       function keywordsToPattern(words) {
+               return '\\b(?:' + words.trim().replace(/ /g, '|') + ')\\b';
+       }
+       var typeDeclarationKeywords = keywordsToPattern(keywordKinds.typeDeclaration);
+       var keywords = RegExp(keywordsToPattern(keywordKinds.type + ' ' + keywordKinds.typeDeclaration + ' ' + keywordKinds.contextual + ' ' + keywordKinds.other));
+       var nonTypeKeywords = keywordsToPattern(keywordKinds.typeDeclaration + ' ' + keywordKinds.contextual + ' ' + keywordKinds.other);
+       var nonContextualKeywords = keywordsToPattern(keywordKinds.type + ' ' + keywordKinds.typeDeclaration + ' ' + keywordKinds.other);
+
+       // types
+       var generic = nested(/<(?:[^<>;=+\-*/%&|^]|<<self>>)*>/.source, 2); // the idea behind the other forbidden characters is to prevent false positives. Same for tupleElement.
+       var nestedRound = nested(/\((?:[^()]|<<self>>)*\)/.source, 2);
+       var name = /@?\b[A-Za-z_]\w*\b/.source;
+       var genericName = replace(/<<0>>(?:\s*<<1>>)?/.source, [name, generic]);
+       var identifier = replace(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source, [nonTypeKeywords, genericName]);
+       var array = /\[\s*(?:,\s*)*\]/.source;
+       var typeExpressionWithoutTuple = replace(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source, [identifier, array]);
+       var tupleElement = replace(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source, [generic, nestedRound, array])
+       var tuple = replace(/\(<<0>>+(?:,<<0>>+)+\)/.source, [tupleElement]);
+       var typeExpression = replace(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source, [tuple, identifier, array]);
+
+       var typeInside = {
+               'keyword': keywords,
+               'punctuation': /[<>()?,.:[\]]/
+       };
+
+       // strings & characters
+       // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#character-literals
+       // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#string-literals
+       var character = /'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source; // simplified pattern
+       var regularString = /"(?:\\.|[^\\"\r\n])*"/.source;
+       var verbatimString = /@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;
+
+
+       Prism.languages.csharp = Prism.languages.extend('clike', {
+               'string': [
+                       {
+                               pattern: re(/(^|[^$\\])<<0>>/.source, [verbatimString]),
+                               lookbehind: true,
+                               greedy: true
+                       },
+                       {
+                               pattern: re(/(^|[^@$\\])<<0>>/.source, [regularString]),
+                               lookbehind: true,
+                               greedy: true
+                       },
+                       {
+                               pattern: RegExp(character),
+                               greedy: true,
+                               alias: 'character'
+                       }
+               ],
+               'class-name': [
+                       {
+                               // Using static
+                               // using static System.Math;
+                               pattern: re(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source, [identifier]),
+                               lookbehind: true,
+                               inside: typeInside
+                       },
+                       {
+                               // Using alias (type)
+                               // using Project = PC.MyCompany.Project;
+                               pattern: re(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source, [name, typeExpression]),
+                               lookbehind: true,
+                               inside: typeInside
+                       },
+                       {
+                               // Using alias (alias)
+                               // using Project = PC.MyCompany.Project;
+                               pattern: re(/(\busing\s+)<<0>>(?=\s*=)/.source, [name]),
+                               lookbehind: true
+                       },
+                       {
+                               // Type declarations
+                               // class Foo<A, B>
+                               // interface Foo<out A, B>
+                               pattern: re(/(\b<<0>>\s+)<<1>>/.source, [typeDeclarationKeywords, genericName]),
+                               lookbehind: true,
+                               inside: typeInside
+                       },
+                       {
+                               // Single catch exception declaration
+                               // catch(Foo)
+                               // (things like catch(Foo e) is covered by variable declaration)
+                               pattern: re(/(\bcatch\s*\(\s*)<<0>>/.source, [identifier]),
+                               lookbehind: true,
+                               inside: typeInside
+                       },
+                       {
+                               // Name of the type parameter of generic constraints
+                               // where Foo : class
+                               pattern: re(/(\bwhere\s+)<<0>>/.source, [name]),
+                               lookbehind: true
+                       },
+                       {
+                               // Casts and checks via as and is.
+                               // as Foo<A>, is Bar<B>
+                               // (things like if(a is Foo b) is covered by variable declaration)
+                               pattern: re(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source, [typeExpressionWithoutTuple]),
+                               lookbehind: true,
+                               inside: typeInside
+                       },
+                       {
+                               // Variable, field and parameter declaration
+                               // (Foo bar, Bar baz, Foo[,,] bay, Foo<Bar, FooBar<Bar>> bax)
+                               pattern: re(/\b<<0>>(?=\s+(?!<<1>>)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source, [typeExpression, nonContextualKeywords, name]),
+                               inside: typeInside
+                       }
+               ],
+               'keyword': keywords,
+               // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#literals
+               'number': /(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:ul|lu|[dflmu])?\b/i,
+               'operator': />>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,
+               'punctuation': /\?\.?|::|[{}[\];(),.:]/
+       });
+
+       Prism.languages.insertBefore('csharp', 'number', {
+               'range': {
+                       pattern: /\.\./,
+                       alias: 'operator'
+               }
+       });
+
+       Prism.languages.insertBefore('csharp', 'punctuation', {
+               'named-parameter': {
+                       pattern: re(/([(,]\s*)<<0>>(?=\s*:)/.source, [name]),
+                       lookbehind: true,
+                       alias: 'punctuation'
                }
-       ],
-       'class-name': [
-               {
-                       // (Foo bar, Bar baz)
-                       pattern: /\b[A-Z]\w*(?:\.\w+)*\b(?=\s+\w+)/,
+       });
+
+       Prism.languages.insertBefore('csharp', 'class-name', {
+               'namespace': {
+                       // namespace Foo.Bar {}
+                       // using Foo.Bar;
+                       pattern: re(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source, [name]),
+                       lookbehind: true,
                        inside: {
-                               punctuation: /\./
+                               'punctuation': /\./
                        }
                },
-               {
-                       // [Foo]
-                       pattern: /(\[)[A-Z]\w*(?:\.\w+)*\b/,
+               'type-expression': {
+                       // default(Foo), typeof(Foo<Bar>), sizeof(int)
+                       pattern: re(/(\b(?:default|typeof|sizeof)\s*\(\s*)(?:[^()\s]|\s(?!\s*\))|<<0>>)*(?=\s*\))/.source, [nestedRound]),
+                       lookbehind: true,
+                       alias: 'class-name',
+                       inside: typeInside
+               },
+               'return-type': {
+                       // Foo<Bar> ForBar(); Foo IFoo.Bar() => 0
+                       // int this[int index] => 0; T IReadOnlyList<T>.this[int index] => this[index];
+                       // int Foo => 0; int Foo { get; set } = 0;
+                       pattern: re(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source, [typeExpression, identifier]),
+                       inside: typeInside,
+                       alias: 'class-name'
+               },
+               'constructor-invocation': {
+                       // new List<Foo<Bar[]>> { }
+                       pattern: re(/(\bnew\s+)<<0>>(?=\s*[[({])/.source, [typeExpression]),
                        lookbehind: true,
+                       inside: typeInside,
+                       alias: 'class-name'
+               },
+               /*'explicit-implementation': {
+                       // int IFoo<Foo>.Bar => 0; void IFoo<Foo<Foo>>.Foo<T>();
+                       pattern: replace(/\b<<0>>(?=\.<<1>>)/, className, methodOrPropertyDeclaration),
+                       inside: classNameInside,
+                       alias: 'class-name'
+               },*/
+               'generic-method': {
+                       // foo<Bar>()
+                       pattern: re(/<<0>>\s*<<1>>(?=\s*\()/.source, [name, generic]),
                        inside: {
-                               punctuation: /\./
+                               'function': re(/^<<0>>/.source, [name]),
+                               'generic': {
+                                       pattern: RegExp(generic),
+                                       alias: 'class-name',
+                                       inside: typeInside
+                               }
                        }
                },
-               {
-                       // class Foo : Bar
-                       pattern: /(\b(?:class|interface)\s+[A-Z]\w*(?:\.\w+)*\s*:\s*)[A-Z]\w*(?:\.\w+)*\b/,
+               'type-list': {
+                       // The list of types inherited or of generic constraints
+                       // class Foo<F> : Bar, IList<FooBar>
+                       // where F : Bar, IList<int>
+                       pattern: re(
+                               /\b((?:<<0>>\s+<<1>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>)(?:\s*,\s*(?:<<3>>|<<4>>))*(?=\s*(?:where|[{;]|=>|$))/.source,
+                               [typeDeclarationKeywords, genericName, name, typeExpression, keywords.source]
+                       ),
                        lookbehind: true,
                        inside: {
-                               punctuation: /\./
+                               'keyword': keywords,
+                               'class-name': {
+                                       pattern: RegExp(typeExpression),
+                                       greedy: true,
+                                       inside: typeInside
+                               },
+                               'punctuation': /,/
                        }
                },
-               {
-                       // class Foo
-                       pattern: /((?:\b(?:class|interface|new)\s+)|(?:catch\s+\())[A-Z]\w*(?:\.\w+)*\b/,
+               'preprocessor': {
+                       pattern: /(^\s*)#.*/m,
+                       lookbehind: true,
+                       alias: 'property',
+                       inside: {
+                               // highlight preprocessor directives as keywords
+                               'directive': {
+                                       pattern: /(\s*#)\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,
+                                       lookbehind: true,
+                                       alias: 'keyword'
+                               }
+                       }
+               }
+       });
+
+       // attributes
+       var regularStringOrCharacter = regularString + '|' + character;
+       var regularStringCharacterOrComment = replace(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source, [regularStringOrCharacter]);
+       var roundExpression = nested(replace(/[^"'/()]|<<0>>|\(<<self>>*\)/.source, [regularStringCharacterOrComment]), 2);
+
+       // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/#attribute-targets
+       var attrTarget = /\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source;
+       var attr = replace(/<<0>>(?:\s*\(<<1>>*\))?/.source, [identifier, roundExpression]);
+
+       Prism.languages.insertBefore('csharp', 'class-name', {
+               'attribute': {
+                       // Attributes
+                       // [Foo], [Foo(1), Bar(2, Prop = "foo")], [return: Foo(1), Bar(2)], [assembly: Foo(Bar)]
+                       pattern: re(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source, [attrTarget, attr]),
                        lookbehind: true,
+                       greedy: true,
                        inside: {
-                               punctuation: /\./
+                               'target': {
+                                       pattern: re(/^<<0>>(?=\s*:)/.source, [attrTarget]),
+                                       alias: 'keyword'
+                               },
+                               'attribute-arguments': {
+                                       pattern: re(/\(<<0>>*\)/.source, [roundExpression]),
+                                       inside: Prism.languages.csharp
+                               },
+                               'class-name': {
+                                       pattern: RegExp(identifier),
+                                       inside: {
+                                               'punctuation': /\./
+                                       }
+                               },
+                               'punctuation': /[:,]/
                        }
                }
-       ],
-       'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)f?/i,
-       'operator': />>=?|<<=?|[-=]>|([-+&|?])\1|~|[-+*/%&|^!=<>]=?/,
-       'punctuation': /\?\.?|::|[{}[\];(),.:]/
-});
-
-Prism.languages.insertBefore('csharp', 'class-name', {
-       'generic-method': {
-               pattern: /\w+\s*<[^>\r\n]+?>\s*(?=\()/,
-               inside: {
-                       function: /^\w+/,
-                       'class-name': {
-                               pattern: /\b[A-Z]\w*(?:\.\w+)*\b/,
+       });
+
+
+       // string interpolation
+       var formatString = /:[^}\r\n]+/.source;
+       // multi line
+       var mInterpolationRound = nested(replace(/[^"'/()]|<<0>>|\(<<self>>*\)/.source, [regularStringCharacterOrComment]), 2)
+       var mInterpolation = replace(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source, [mInterpolationRound, formatString]);
+       // single line
+       var sInterpolationRound = nested(replace(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<<self>>*\)/.source, [regularStringOrCharacter]), 2)
+       var sInterpolation = replace(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source, [sInterpolationRound, formatString]);
+
+       function createInterpolationInside(interpolation, interpolationRound) {
+               return {
+                       'interpolation': {
+                               pattern: re(/((?:^|[^{])(?:\{\{)*)<<0>>/.source, [interpolation]),
+                               lookbehind: true,
                                inside: {
-                                       punctuation: /\./
+                                       'format-string': {
+                                               pattern: re(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source, [interpolationRound, formatString]),
+                                               lookbehind: true,
+                                               inside: {
+                                                       'punctuation': /^:/
+                                               }
+                                       },
+                                       'punctuation': /^\{|\}$/,
+                                       'expression': {
+                                               pattern: /[\s\S]+/,
+                                               alias: 'language-csharp',
+                                               inside: Prism.languages.csharp
+                                       }
                                }
                        },
-                       keyword: Prism.languages.csharp.keyword,
-                       punctuation: /[<>(),.:]/
-               }
-       },
-       'preprocessor': {
-               pattern: /(^\s*)#.*/m,
-               lookbehind: true,
-               alias: 'property',
-               inside: {
-                       // highlight preprocessor directives as keywords
-                       'directive': {
-                               pattern: /(\s*#)\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,
+                       'string': /[\s\S]+/
+               };
+       }
+
+       Prism.languages.insertBefore('csharp', 'string', {
+               'interpolation-string': [
+                       {
+                               pattern: re(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source, [mInterpolation]),
+                               lookbehind: true,
+                               greedy: true,
+                               inside: createInterpolationInside(mInterpolation, mInterpolationRound),
+                       },
+                       {
+                               pattern: re(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source, [sInterpolation]),
                                lookbehind: true,
-                               alias: 'keyword'
+                               greedy: true,
+                               inside: createInterpolationInside(sInterpolation, sInterpolationRound),
                        }
-               }
-       }
-});
+               ]
+       });
+
+}(Prism));
 
 Prism.languages.dotnet = Prism.languages.cs = Prism.languages.csharp;
 
index 89b78d77b7f0b59d9c910a1c44156e6e681853aa..c9f4d16a73f09459577f9aa20ecb71233e165022 100644 (file)
@@ -12,7 +12,7 @@ define(["prism/prism"], function () {
 
 Prism.languages.csp = {
        'directive':  {
-               pattern: /\b(?:(?:base-uri|form-action|frame-ancestors|plugin-types|referrer|reflected-xss|report-to|report-uri|require-sri-for|sandbox) |(?:block-all-mixed-content|disown-opener|upgrade-insecure-requests)(?: |;)|(?:child|connect|default|font|frame|img|manifest|media|object|script|style|worker)-src )/i,
+               pattern: /\b(?:base-uri|block-all-mixed-content|(?:child|connect|default|font|frame|img|manifest|media|object|script|style|worker)-src|disown-opener|form-action|frame-ancestors|plugin-types|referrer|reflected-xss|report-to|report-uri|require-sri-for|sandbox|upgrade-insecure-requests)\b/i,
                alias: 'keyword'
        },
        'safe': {
index 5a0bbfa505f0f50bdf55030e9cd07bd5a58086eb..8befc522e818bd69283f0b7cbb972f9b76764d43 100644 (file)
 define(["prism/prism","prism/components/prism-css"], function () {
-Prism.languages.css.selector = {
-       pattern: Prism.languages.css.selector,
-       inside: {
-               'pseudo-element': /:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,
-               'pseudo-class': /:[-\w]+/,
-               'class': /\.[-:.\w]+/,
-               'id': /#[-:.\w]+/,
-               'attribute': {
-                       pattern: /\[(?:[^[\]"']|("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1)*\]/,
-                       greedy: true,
-                       inside: {
-                               'punctuation': /^\[|\]$/,
-                               'case-sensitivity': {
-                                       pattern: /(\s)[si]$/i,
-                                       lookbehind: true,
-                                       alias: 'keyword'
-                               },
-                               'namespace': {
-                                       pattern: /^(\s*)[-*\w\xA0-\uFFFF]*\|(?!=)/,
+(function (Prism) {
+
+       var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
+       var selectorInside;
+
+       Prism.languages.css.selector = {
+               pattern: Prism.languages.css.selector,
+               inside: selectorInside = {
+                       'pseudo-element': /:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,
+                       'pseudo-class': /:[-\w]+/,
+                       'class': /\.[-\w]+/,
+                       'id': /#[-\w]+/,
+                       'attribute': {
+                               pattern: RegExp('\\[(?:[^[\\]"\']|' + string.source + ')*\\]'),
+                               greedy: true,
+                               inside: {
+                                       'punctuation': /^\[|\]$/,
+                                       'case-sensitivity': {
+                                               pattern: /(\s)[si]$/i,
+                                               lookbehind: true,
+                                               alias: 'keyword'
+                                       },
+                                       'namespace': {
+                                               pattern: /^(\s*)[-*\w\xA0-\uFFFF]*\|(?!=)/,
+                                               lookbehind: true,
+                                               inside: {
+                                                       'punctuation': /\|$/
+                                               }
+                                       },
+                                       'attr-name': {
+                                               pattern: /^(\s*)[-\w\xA0-\uFFFF]+/,
+                                               lookbehind: true
+                                       },
+                                       'attr-value': [
+                                               string,
+                                               {
+                                                       pattern: /(=\s*)[-\w\xA0-\uFFFF]+(?=\s*$)/,
+                                                       lookbehind: true
+                                               }
+                                       ],
+                                       'operator': /[|~*^$]?=/
+                               }
+                       },
+                       'n-th': [
+                               {
+                                       pattern: /(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,
                                        lookbehind: true,
                                        inside: {
-                                               'punctuation': /\|$/
+                                               'number': /[\dn]+/,
+                                               'operator': /[+-]/
                                        }
                                },
-                               'attribute': {
-                                       pattern: /^(\s*)[-\w\xA0-\uFFFF]+/,
+                               {
+                                       pattern: /(\(\s*)(?:even|odd)(?=\s*\))/i,
                                        lookbehind: true
-                               },
-                               'value': [
-                                       /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
-                                       {
-                                               pattern: /(=\s*)[-\w\xA0-\uFFFF]+(?=\s*$)/,
-                                               lookbehind: true
-                                       }
-                               ],
-                               'operator': /[|~*^$]?=/
-                       }
+                               }
+                       ],
+                       'combinator': />|\+|~|\|\|/,
+
+                       // the `tag` token has been existed and removed.
+                       // because we can't find a perfect tokenize to match it.
+                       // if you want to add it, please read https://github.com/PrismJS/prism/pull/2373 first.
+
+                       'punctuation': /[(),]/,
+               }
+       };
+
+       Prism.languages.css['atrule'].inside['selector-function-argument'].inside = selectorInside;
+
+       Prism.languages.insertBefore('css', 'property', {
+               'variable': {
+                       pattern: /(^|[^-\w\xA0-\uFFFF])--[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*/i,
+                       lookbehind: true
+               }
+       });
+
+       var unit = {
+               pattern: /(\b\d+)(?:%|[a-z]+\b)/,
+               lookbehind: true
+       };
+       // 123 -123 .123 -.123 12.3 -12.3
+       var number = {
+               pattern: /(^|[^\w.-])-?\d*\.?\d+/,
+               lookbehind: true
+       };
+
+       Prism.languages.insertBefore('css', 'function', {
+               'operator': {
+                       pattern: /(\s)[+\-*\/](?=\s)/,
+                       lookbehind: true
                },
-               'n-th': [
+               // CAREFUL!
+               // Previewers and Inline color use hexcode and color.
+               'hexcode': {
+                       pattern: /\B#(?:[\da-f]{1,2}){3,4}\b/i,
+                       alias: 'color'
+               },
+               'color': [
+                       /\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,
                        {
-                               pattern: /(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,
-                               lookbehind: true,
+                               pattern: /\b(?:rgb|hsl)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:rgb|hsl)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,
                                inside: {
-                                       'number': /[\dn]+/,
-                                       'operator': /[+-]/
+                                       'unit': unit,
+                                       'number': number,
+                                       'function': /[\w-]+(?=\()/,
+                                       'punctuation': /[(),]/
                                }
-                       },
-                       {
-                               pattern: /(\(\s*)(?:even|odd)(?=\s*\))/i,
-                               lookbehind: true
                        }
                ],
-               'punctuation': /[()]/
-       }
-};
+               // it's important that there is no boundary assertion after the hex digits
+               'entity': /\\[\da-f]{1,8}/i,
+               'unit': unit,
+               'number': number
+       });
 
-Prism.languages.insertBefore('css', 'property', {
-       'variable': {
-               pattern: /(^|[^-\w\xA0-\uFFFF])--[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*/i,
-               lookbehind: true
-       }
-});
-
-Prism.languages.insertBefore('css', 'function', {
-       'operator': {
-               pattern: /(\s)[+\-*\/](?=\s)/,
-               lookbehind: true
-       },
-       'hexcode': /#[\da-f]{3,8}/i,
-       'entity': /\\[\da-f]{1,8}/i,
-       'unit': {
-               pattern: /(\d)(?:%|[a-z]+)/,
-               lookbehind: true
-       },
-       'number': /-?[\d.]+/
-});
+})(Prism);
 
 return Prism; })
\ No newline at end of file
index aee107620fe28d147aa41229acded7a50b9918bb..45c7d8a0c1a8c9294c2ea7f20cc30056fe386b26 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-markup"], function () {
+define(["prism/prism"], function () {
 (function (Prism) {
 
        var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;
@@ -8,15 +8,30 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                'atrule': {
                        pattern: /@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,
                        inside: {
-                               'rule': /@[\w-]+/
+                               'rule': /^@[\w-]+/,
+                               'selector-function-argument': {
+                                       pattern: /(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,
+                                       lookbehind: true,
+                                       alias: 'selector'
+                               },
+                               'keyword': {
+                                       pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
+                                       lookbehind: true
+                               }
                                // See rest below
                        }
                },
                'url': {
-                       pattern: RegExp('url\\((?:' + string.source + '|[^\n\r()]*)\\)', 'i'),
+                       // https://drafts.csswg.org/css-values-3/#urls
+                       pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
+                       greedy: true,
                        inside: {
                                'function': /^url/i,
-                               'punctuation': /^\(|\)$/
+                               'punctuation': /^\(|\)$/,
+                               'string': {
+                                       pattern: RegExp('^' + string.source + '$'),
+                                       alias: 'url'
+                               }
                        }
                },
                'selector': RegExp('[^{}\\s](?:[^{};"\']|' + string.source + ')*?(?=\\s*\\{)'),
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-cypher.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-cypher.js
new file mode 100644 (file)
index 0000000..dfa112b
--- /dev/null
@@ -0,0 +1,40 @@
+define(["prism/prism"], function () {
+Prism.languages.cypher = {
+       // https://neo4j.com/docs/cypher-manual/current/syntax/comments/
+       'comment': /\/\/.*/,
+       'string': {
+               pattern: /"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/,
+               greedy: true
+       },
+       'class-name': {
+               pattern: /(:\s*)(?:\w+|`(?:[^`\\\r\n])*`)(?=\s*[{):])/,
+               lookbehind: true,
+               greedy: true
+       },
+       'relationship': {
+               pattern: /(-\[\s*(?:\w+\s*|`(?:[^`\\\r\n])*`\s*)?:\s*|\|\s*:\s*)(?:\w+|`(?:[^`\\\r\n])*`)/,
+               lookbehind: true,
+               greedy: true,
+               alias: 'property'
+       },
+       'identifier': {
+               pattern: /`(?:[^`\\\r\n])*`/,
+               greedy: true,
+               alias: 'symbol'
+       },
+
+       'variable': /\$\w+/,
+
+       // https://neo4j.com/docs/cypher-manual/current/syntax/reserved/
+       'keyword': /\b(?:ADD|ALL|AND|AS|ASC|ASCENDING|ASSERT|BY|CALL|CASE|COMMIT|CONSTRAINT|CONTAINS|CREATE|CSV|DELETE|DESC|DESCENDING|DETACH|DISTINCT|DO|DROP|ELSE|END|ENDS|EXISTS|FOR|FOREACH|IN|INDEX|IS|JOIN|KEY|LIMIT|LOAD|MANDATORY|MATCH|MERGE|NODE|NOT|OF|ON|OPTIONAL|OR|ORDER(?=\s+BY)|PERIODIC|REMOVE|REQUIRE|RETURN|SCALAR|SCAN|SET|SKIP|START|STARTS|THEN|UNION|UNIQUE|UNWIND|USING|WHEN|WHERE|WITH|XOR|YIELD)\b/i,
+
+       'function': /\b\w+\b(?=\s*\()/,
+
+       'boolean': /\b(?:true|false|null)\b/i,
+       'number': /\b(?:0x[\da-fA-F]+|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\b/,
+       // https://neo4j.com/docs/cypher-manual/current/syntax/operators/
+       'operator': /:|<--?|--?>?|<>|=~?|[<>]=?|[+*/%^|]|\.\.\.?/,
+       'punctuation': /[()[\]{},;.]/
+};
+
+return Prism; })
\ No newline at end of file
index 1db3a0e897693e6b49715d4caacf273aac8c401c..b9486b33b2ed1b6cbd2b5a66e539fbeb543d0800 100644 (file)
@@ -1,20 +1,55 @@
 define(["prism/prism","prism/components/prism-clike"], function () {
 Prism.languages.d = Prism.languages.extend('clike', {
+       'comment': [
+               {
+                       // Shebang
+                       pattern: /^\s*#!.+/,
+                       greedy: true
+               },
+               {
+                       pattern: RegExp(/(^|[^\\])/.source + '(?:' + [
+                               // /+ comment +/
+                               // Allow one level of nesting
+                               /\/\+(?:\/\+(?:[^+]|\+(?!\/))*\+\/|(?!\/\+)[\s\S])*?\+\//.source,
+                               // // comment
+                               /\/\/.*/.source,
+                               // /* comment */
+                               /\/\*[\s\S]*?\*\//.source
+                       ].join('|') + ')'),
+                       lookbehind: true,
+                       greedy: true
+               }
+       ],
        'string': [
-               // r"", x""
-               /\b[rx]"(?:\\[\s\S]|[^\\"])*"[cwd]?/,
-               // q"[]", q"()", q"<>", q"{}"
-               /\bq"(?:\[[\s\S]*?\]|\([\s\S]*?\)|<[\s\S]*?>|\{[\s\S]*?\})"/,
-               // q"IDENT
-               // ...
-               // IDENT"
-               /\bq"([_a-zA-Z][_a-zA-Z\d]*)(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\1"/,
-               // q"//", q"||", etc.
-               /\bq"(.)[\s\S]*?\1"/,
-               // Characters
-               /'(?:\\'|\\?[^']+)'/,
+               {
+                       pattern: RegExp([
+                               // r"", x""
+                               /\b[rx]"(?:\\[\s\S]|[^\\"])*"[cwd]?/.source,
+
+                               // q"[]", q"()", q"<>", q"{}"
+                               /\bq"(?:\[[\s\S]*?\]|\([\s\S]*?\)|<[\s\S]*?>|\{[\s\S]*?\})"/.source,
+
+                               // q"IDENT
+                               // ...
+                               // IDENT"
+                               /\bq"((?!\d)\w+)$[\s\S]*?^\1"/.source,
+
+                               // q"//", q"||", etc.
+                               /\bq"(.)[\s\S]*?\2"/.source,
+
+                               // Characters
+                               // 'a', '\\', '\n', '\xFF', '\377', '\uFFFF', '\U0010FFFF', '\quot'
+                               /'(?:\\(?:\W|\w+)|[^\\])'/.source,
 
-               /(["`])(?:\\[\s\S]|(?!\1)[^\\])*\1[cwd]?/
+                               /(["`])(?:\\[\s\S]|(?!\3)[^\\])*\3[cwd]?/.source
+                       ].join('|'), 'm'),
+                       greedy: true
+               },
+               {
+                       pattern: /\bq\{(?:\{[^{}]*\}|[^{}])*\}/,
+                       greedy: true,
+                       alias: 'token-string'
+               }
        ],
 
        'number': [
@@ -32,26 +67,6 @@ Prism.languages.d = Prism.languages.extend('clike', {
        'operator': /\|[|=]?|&[&=]?|\+[+=]?|-[-=]?|\.?\.\.|=[>=]?|!(?:i[ns]\b|<>?=?|>=?|=)?|\bi[ns]\b|(?:<[<>]?|>>?>?|\^\^|[*\/%^~])=?/
 });
 
-
-Prism.languages.d.comment = [
-       // Shebang
-       /^\s*#!.+/,
-       // /+ +/
-       {
-               // Allow one level of nesting
-               pattern: /(^|[^\\])\/\+(?:\/\+[\s\S]*?\+\/|[\s\S])*?\+\//,
-               lookbehind: true
-       }
-].concat(Prism.languages.d.comment);
-
-Prism.languages.insertBefore('d', 'comment', {
-       'token-string': {
-               // Allow one level of nesting
-               pattern: /\bq\{(?:\{[^}]*\}|[^}])*\}/,
-               alias: 'string'
-       }
-});
-
 Prism.languages.insertBefore('d', 'keyword', {
        'property': /\B@\w*/
 });
@@ -63,4 +78,5 @@ Prism.languages.insertBefore('d', 'function', {
                alias: 'variable'
        }
 });
+
 return Prism; })
\ No newline at end of file
index ca296f9abc8aac6636ad340d47d5ba14d7f5e0d4..94c70634e73a7015d8ef13b7c3f4b56df31e6241 100644 (file)
@@ -12,7 +12,7 @@ Prism.languages.dart = Prism.languages.extend('clike', {
        ],
        'keyword': [
                /\b(?:async|sync|yield)\*/,
-               /\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|default|deferred|do|dynamic|else|enum|export|external|extends|factory|final|finally|for|get|if|implements|import|in|library|new|null|operator|part|rethrow|return|set|static|super|switch|this|throw|try|typedef|var|void|while|with|yield)\b/
+               /\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|covariant|default|deferred|do|dynamic|else|enum|export|extension|external|extends|factory|final|finally|for|Function|get|hide|if|implements|interface|import|in|library|mixin|new|null|on|operator|part|rethrow|return|set|show|static|super|switch|sync|this|throw|try|typedef|var|void|while|with|yield)\b/
        ],
        'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
 });
@@ -23,4 +23,5 @@ Prism.languages.insertBefore('dart','function',{
                alias: 'symbol'
        }
 });
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-dax.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-dax.js
new file mode 100644 (file)
index 0000000..f12a7ca
--- /dev/null
@@ -0,0 +1,30 @@
+define(["prism/prism"], function () {
+Prism.languages.dax = {
+    'comment': {
+        pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/).*)/,
+        lookbehind: true
+    },
+    'data-field': {
+        pattern: /'(?:[^']|'')*'(?!')(?:\[[ \w\xA0-\uFFFF]+\])?|\w+\[[ \w\xA0-\uFFFF]+\]/,
+        alias: 'symbol'
+    },
+    'measure': {
+        pattern: /\[[ \w\xA0-\uFFFF]+\]/,
+        alias: 'constant'
+    },
+    'string': {
+        pattern: /"(?:[^"]|"")*"(?!")/,
+        greedy: true
+    },    
+    'function': /\b(?:ABS|ACOS|ACOSH|ACOT|ACOTH|ADDCOLUMNS|ADDMISSINGITEMS|ALL|ALLCROSSFILTERED|ALLEXCEPT|ALLNOBLANKROW|ALLSELECTED|AND|APPROXIMATEDISTINCTCOUNT|ASIN|ASINH|ATAN|ATANH|AVERAGE|AVERAGEA|AVERAGEX|BETA\.DIST|BETA\.INV|BLANK|CALCULATE|CALCULATETABLE|CALENDAR|CALENDARAUTO|CEILING|CHISQ\.DIST|CHISQ\.DIST\.RT|CHISQ\.INV|CHISQ\.INV\.RT|CLOSINGBALANCEMONTH|CLOSINGBALANCEQUARTER|CLOSINGBALANCEYEAR|COALESCE|COMBIN|COMBINA|COMBINEVALUES|CONCATENATE|CONCATENATEX|CONFIDENCE\.NORM|CONFIDENCE\.T|CONTAINS|CONTAINSROW|CONTAINSSTRING|CONTAINSSTRINGEXACT|CONVERT|COS|COSH|COT|COTH|COUNT|COUNTA|COUNTAX|COUNTBLANK|COUNTROWS|COUNTX|CROSSFILTER|CROSSJOIN|CURRENCY|CURRENTGROUP|CUSTOMDATA|DATATABLE|DATE|DATEADD|DATEDIFF|DATESBETWEEN|DATESINPERIOD|DATESMTD|DATESQTD|DATESYTD|DATEVALUE|DAY|DEGREES|DETAILROWS|DISTINCT|DISTINCTCOUNT|DISTINCTCOUNTNOBLANK|DIVIDE|EARLIER|EARLIEST|EDATE|ENDOFMONTH|ENDOFQUARTER|ENDOFYEAR|EOMONTH|ERROR|EVEN|EXACT|EXCEPT|EXP|EXPON\.DIST|FACT|FALSE|FILTER|FILTERS|FIND|FIRSTDATE|FIRSTNONBLANK|FIRSTNONBLANKVALUE|FIXED|FLOOR|FORMAT|GCD|GENERATE|GENERATEALL|GENERATESERIES|GEOMEAN|GEOMEANX|GROUPBY|HASONEFILTER|HASONEVALUE|HOUR|IF|IF\.EAGER|IFERROR|IGNORE|INT|INTERSECT|ISBLANK|ISCROSSFILTERED|ISEMPTY|ISERROR|ISEVEN|ISFILTERED|ISINSCOPE|ISLOGICAL|ISNONTEXT|ISNUMBER|ISO\.CEILING|ISODD|ISONORAFTER|ISSELECTEDMEASURE|ISSUBTOTAL|ISTEXT|KEEPFILTERS|KEYWORDMATCH|LASTDATE|LASTNONBLANK|LASTNONBLANKVALUE|LCM|LEFT|LEN|LN|LOG|LOG10|LOOKUPVALUE|LOWER|MAX|MAXA|MAXX|MEDIAN|MEDIANX|MID|MIN|MINA|MINUTE|MINX|MOD|MONTH|MROUND|NATURALINNERJOIN|NATURALLEFTOUTERJOIN|NEXTDAY|NEXTMONTH|NEXTQUARTER|NEXTYEAR|NONVISUAL|NORM\.DIST|NORM\.INV|NORM\.S\.DIST|NORM\.S\.INV|NOT|NOW|ODD|OPENINGBALANCEMONTH|OPENINGBALANCEQUARTER|OPENINGBALANCEYEAR|OR|PARALLELPERIOD|PATH|PATHCONTAINS|PATHITEM|PATHITEMREVERSE|PATHLENGTH|PERCENTILE\.EXC|PERCENTILE\.INC|PERCENTILEX\.EXC|PERCENTILEX\.INC|PERMUT|PI|POISSON\.DIST|POWER|PREVIOUSDAY|PREVIOUSMONTH|PREVIOUSQUARTER|PREVIOUSYEAR|PRODUCT|PRODUCTX|QUARTER|QUOTIENT|RADIANS|RAND|RANDBETWEEN|RANK\.EQ|RANKX|RELATED|RELATEDTABLE|REMOVEFILTERS|REPLACE|REPT|RIGHT|ROLLUP|ROLLUPADDISSUBTOTAL|ROLLUPGROUP|ROLLUPISSUBTOTAL|ROUND|ROUNDDOWN|ROUNDUP|ROW|SAMEPERIODLASTYEAR|SAMPLE|SEARCH|SECOND|SELECTCOLUMNS|SELECTEDMEASURE|SELECTEDMEASUREFORMATSTRING|SELECTEDMEASURENAME|SELECTEDVALUE|SIGN|SIN|SINH|SQRT|SQRTPI|STARTOFMONTH|STARTOFQUARTER|STARTOFYEAR|STDEV\.P|STDEV\.S|STDEVX\.P|STDEVX\.S|SUBSTITUTE|SUBSTITUTEWITHINDEX|SUM|SUMMARIZE|SUMMARIZECOLUMNS|SUMX|SWITCH|T\.DIST|T\.DIST\.2T|T\.DIST\.RT|T\.INV|T\.INV\.2T|TAN|TANH|TIME|TIMEVALUE|TODAY|TOPN|TOPNPERLEVEL|TOPNSKIP|TOTALMTD|TOTALQTD|TOTALYTD|TREATAS|TRIM|TRUE|TRUNC|UNICHAR|UNICODE|UNION|UPPER|USERELATIONSHIP|USERNAME|USEROBJECTID|USERPRINCIPALNAME|UTCNOW|UTCTODAY|VALUE|VALUES|VAR\.P|VAR\.S|VARX\.P|VARX\.S|WEEKDAY|WEEKNUM|XIRR|XNPV|YEAR|YEARFRAC)(?=\s*\()/i,
+    'keyword': /\b(?:DEFINE|MEASURE|EVALUATE|ORDER\s+BY|RETURN|VAR|START\s+AT|ASC|DESC)\b/i,
+    'boolean': {
+        pattern: /\b(?:TRUE|FALSE|NULL)\b/i,
+        alias: 'constant'
+    },
+    'number': /\b\d+\.?\d*|\B\.\d+\b/i,
+    'operator': /:=|[-+*\/=^]|&&?|\|\||<(?:=>?|<|>)?|>[>=]?|\b(?:IN|NOT)\b/i,
+    'punctuation': /[;\[\](){}`,.]/
+};
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-dhall.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-dhall.js
new file mode 100644 (file)
index 0000000..68ae8d0
--- /dev/null
@@ -0,0 +1,72 @@
+define(["prism/prism"], function () {
+// ABNF grammar:
+// https://github.com/dhall-lang/dhall-lang/blob/master/standard/dhall.abnf
+
+Prism.languages.dhall = {
+       // Multi-line comments can be nested. E.g. {- foo {- bar -} -}
+       // The multi-line pattern is essentially this:
+       //   \{-(?:[^-{]|-(?!\})|\{(?!-)|<SELF>)*-\}
+       'comment': /--.*|\{-(?:[^-{]|-(?!\})|\{(?!-)|\{-(?:[^-{]|-(?!\})|\{(?!-))*-\})*-\}/,
+       'string': {
+               pattern: /"(?:[^"\\]|\\.)*"|''(?:[^']|'(?!')|'''|''\$\{)*''(?!'|\$)/,
+               greedy: true,
+               inside: {
+                       'interpolation': {
+                               pattern: /\$\{[^{}]*\}/,
+                               inside: {
+                                       'expression': {
+                                               pattern: /(^\$\{)[\s\S]+(?=\}$)/,
+                                               lookbehind: true,
+                                               alias: 'language-dhall',
+                                               inside: null // see blow
+                                       },
+                                       'punctuation': /\$\{|\}/
+                               }
+                       }
+               }
+       },
+       'label': {
+               pattern: /`[^`]*`/,
+               greedy: true
+       },
+       'url': {
+               // https://github.com/dhall-lang/dhall-lang/blob/5fde8ef1bead6fb4e999d3c1ffe7044cd019d63a/standard/dhall.abnf#L596
+               pattern: /\bhttps?:\/\/[\w.:%!$&'*+;=@~-]+(?:\/[\w.:%!$&'*+;=@~-]*)*(?:\?[/?\w.:%!$&'*+;=@~-]*)?/,
+               greedy: true
+       },
+       'env': {
+               // https://github.com/dhall-lang/dhall-lang/blob/5fde8ef1bead6fb4e999d3c1ffe7044cd019d63a/standard/dhall.abnf#L661
+               pattern: /\benv:(?:(?!\d)\w+|"(?:[^"\\=]|\\.)*")/,
+               greedy: true,
+               inside: {
+                       'function': /^env/,
+                       'operator': /^:/,
+                       'variable': /[\s\S]+/
+               }
+       },
+       'hash': {
+               // https://github.com/dhall-lang/dhall-lang/blob/5fde8ef1bead6fb4e999d3c1ffe7044cd019d63a/standard/dhall.abnf#L725
+               pattern: /\bsha256:[\da-fA-F]{64}\b/,
+               inside: {
+                       'function': /sha256/,
+                       'operator': /:/,
+                       'number': /[\da-fA-F]{64}/
+               }
+       },
+
+       // https://github.com/dhall-lang/dhall-lang/blob/5fde8ef1bead6fb4e999d3c1ffe7044cd019d63a/standard/dhall.abnf#L359
+       'keyword': /\b(?:as|assert|else|forall|if|in|let|merge|missing|then|toMap|using|with)\b|\u2200/,
+       'builtin': /\b(?:Some|None)\b/,
+
+       'boolean': /\b(?:False|True)\b/,
+       'number': /\bNaN\b|-?\bInfinity\b|[+-]?\b(?:0x[\da-fA-F]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b/,
+       'operator': /\/\\|\/\/\\\\|&&|\|\||[!=]=|===|\/\/|->|\+\+|::|[+*#@=:?<>|\\\u2227\u2a53\u2261\u2afd\u03bb\u2192]/,
+       'punctuation': /\.\.|[{}\[\](),./]/,
+
+       // we'll just assume that every capital word left is a type name
+       'class-name': /\b[A-Z]\w*\b/
+};
+
+Prism.languages.dhall.string.inside.interpolation.inside.expression.inside = Prism.languages.dhall;
+
+return Prism; })
\ No newline at end of file
index d997e08ee3083a6ad73a393738880e6b523d5431..fe2548a07aa75094ab92e10a941071bf1cb830bf 100644 (file)
@@ -1,23 +1,67 @@
 define(["prism/prism"], function () {
-Prism.languages.diff = {
-       'coord': [
-               // Match all kinds of coord lines (prefixed by "+++", "---" or "***").
-               /^(?:\*{3}|-{3}|\+{3}).*$/m,
-               // Match "@@ ... @@" coord lines in unified diff.
-               /^@@.*@@$/m,
-               // Match coord lines in normal diff (starts with a number).
-               /^\d+.*$/m
-       ],
-
-       // Match inserted and deleted lines. Support both +/- and >/< styles.
-       'deleted': /^[-<].*$/m,
-       'inserted': /^[+>].*$/m,
-
-       // Match "different" lines (prefixed with "!") in context diff.
-       'diff': {
-               'pattern': /^!(?!!).+$/m,
-               'alias': 'important'
-       }
-};
+(function (Prism) {
+
+       Prism.languages.diff = {
+               'coord': [
+                       // Match all kinds of coord lines (prefixed by "+++", "---" or "***").
+                       /^(?:\*{3}|-{3}|\+{3}).*$/m,
+                       // Match "@@ ... @@" coord lines in unified diff.
+                       /^@@.*@@$/m,
+                       // Match coord lines in normal diff (starts with a number).
+                       /^\d+.*$/m
+               ]
+
+               // deleted, inserted, unchanged, diff
+       };
+
+       /**
+        * A map from the name of a block to its line prefix.
+        *
+        * @type {Object<string, string>}
+        */
+       var PREFIXES = {
+               'deleted-sign': '-',
+               'deleted-arrow': '<',
+               'inserted-sign': '+',
+               'inserted-arrow': '>',
+               'unchanged': ' ',
+               'diff': '!',
+       };
+
+       // add a token for each prefix
+       Object.keys(PREFIXES).forEach(function (name) {
+               var prefix = PREFIXES[name];
+
+               var alias = [];
+               if (!/^\w+$/.test(name)) { // "deleted-sign" -> "deleted"
+                       alias.push(/\w+/.exec(name)[0]);
+               }
+               if (name === "diff") {
+                       alias.push("bold");
+               }
+
+               Prism.languages.diff[name] = {
+                       pattern: RegExp('^(?:[' + prefix + '].*(?:\r\n?|\n|(?![\\s\\S])))+', 'm'),
+                       alias: alias,
+                       inside: {
+                               'line': {
+                                       pattern: /(.)(?=[\s\S]).*(?:\r\n?|\n)?/,
+                                       lookbehind: true
+                               },
+                               'prefix': {
+                                       pattern: /[\s\S]/,
+                                       alias: /\w+/.exec(name)[0]
+                               }
+                       }
+               };
+               
+       });
+
+       // make prefixes available to Diff plugin
+       Object.defineProperty(Prism.languages.diff, 'PREFIXES', {
+               value: PREFIXES
+       });
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-dns-zone-file.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-dns-zone-file.js
new file mode 100644 (file)
index 0000000..338c1f6
--- /dev/null
@@ -0,0 +1,36 @@
+define(["prism/prism"], function () {
+Prism.languages['dns-zone-file'] = {
+       'comment': /;.*/,
+       'string': {
+               pattern: /"(?:\\.|[^"\\\r\n])*"/,
+               greedy: true
+       },
+       'variable': [
+               {
+                       pattern: /(^\$ORIGIN[ \t]+)\S+/m,
+                       lookbehind: true,
+               },
+               {
+                       pattern: /(^|\s)@(?=\s|$)/,
+                       lookbehind: true,
+               }
+       ],
+       'keyword': /^\$(?:ORIGIN|INCLUDE|TTL)(?=\s|$)/m,
+       'class': {
+               // https://tools.ietf.org/html/rfc1035#page-13
+               pattern: /(^|\s)(?:IN|CH|CS|HS)(?=\s|$)/,
+               lookbehind: true,
+               alias: 'keyword'
+       },
+       'type': {
+               // https://en.wikipedia.org/wiki/List_of_DNS_record_types
+               pattern: /(^|\s)(?:A|A6|AAAA|AFSDB|APL|ATMA|CAA|CDNSKEY|CDS|CERT|CNAME|DHCID|DLV|DNAME|DNSKEY|DS|EID|GID|GPOS|HINFO|HIP|IPSECKEY|ISDN|KEY|KX|LOC|MAILA|MAILB|MB|MD|MF|MG|MINFO|MR|MX|NAPTR|NB|NBSTAT|NIMLOC|NINFO|NS|NSAP|NSAP-PTR|NSEC|NSEC3|NSEC3PARAM|NULL|NXT|OPENPGPKEY|PTR|PX|RKEY|RP|RRSIG|RT|SIG|SINK|SMIMEA|SOA|SPF|SRV|SSHFP|TA|TKEY|TLSA|TSIG|TXT|UID|UINFO|UNSPEC|URI|WKS|X25)(?=\s|$)/,
+               lookbehind: true,
+               alias: 'keyword'
+       },
+       'punctuation': /[()]/
+};
+
+Prism.languages['dns-zone'] = Prism.languages['dns-zone-file']
+
+return Prism; })
\ No newline at end of file
index 5e7e7d96b48fccec4c05ce9a344b70854fff21bb..8b0a5fbd058c08e2406540f0136dce687b2077da 100644 (file)
@@ -5,7 +5,10 @@ Prism.languages.docker = {
                lookbehind: true
        },
        'string': /("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,
-       'comment': /#.*/,
+       'comment': {
+               pattern: /#.*/,
+               greedy: true
+       },
        'punctuation': /---|\.\.\.|[:[\]{}\-,|>?]/
 };
 
index 57aecab4871f9a8e3cb76b567e6f5e0a49778098..a7567b60a902940f5dc0da85439372ce9874c703 100644 (file)
@@ -16,7 +16,7 @@ Prism.languages.ebnf = {
                lookbehind: true,
                alias: ['rule', 'keyword']
        },
-       'rule': /[a-z]\w*(?:[ \t]+[a-z]\w*)*/i,
+       'rule': /\b[a-z]\w*(?:[ \t]+[a-z]\w*)*\b/i,
 
        'punctuation': /\([:/]|[:/]\)|[.,;()[\]{}]/,
        'operator': /[-=|*/!]/
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-editorconfig.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-editorconfig.js
new file mode 100644 (file)
index 0000000..13f8f99
--- /dev/null
@@ -0,0 +1,28 @@
+define(["prism/prism"], function () {
+Prism.languages.editorconfig = {
+       // https://editorconfig-specification.readthedocs.io/en/latest/
+       'comment': /[;#].*/,
+       'section': {
+               pattern: /(^[ \t]*)\[.+]/m,
+               lookbehind: true,
+               alias: 'keyword',
+               inside: {
+                       'regex': /\\\\[\[\]{},!?.*]/, // Escape special characters with '\\'
+                       'operator': /[!?]|\.\.|\*{1,2}/,
+                       'punctuation': /[\[\]{},]/
+               }
+       },
+       'property': {
+               pattern: /(^[ \t]*)[^\s=]+(?=[ \t]*=)/m,
+               lookbehind: true
+       },
+       'value': {
+               pattern: /=.*/,
+               alias: 'string',
+               inside: {
+                       'punctuation': /^=/
+               }
+       }
+};
+
+return Prism; })
\ No newline at end of file
index cc2e560712de4ee1de61511954d7d15f42d18eca..b8c6a47600869faa5536305523bbf832aa8f5cbe 100644 (file)
@@ -14,7 +14,7 @@ Prism.languages.eiffel = {
                },
                // Single-line string
                {
-                       pattern: /"(?:%\s+%|%.|[^%"\r\n])*"/,
+                       pattern: /"(?:%\s*\n\s*%|%.|[^%"\r\n])*"/,
                        greedy: true
                }
        ],
@@ -31,7 +31,7 @@ Prism.languages.eiffel = {
                // hexa | octal | bin
                /\b0[xcb][\da-f](?:_*[\da-f])*\b/i,
                // Decimal
-               /(?:\d(?:_*\d)*)?\.(?:(?:\d(?:_*\d)*)?e[+-]?)?\d(?:_*\d)*|\d(?:_*\d)*\.?/i
+               /(?:\b\d(?:_*\d)*)?\.(?:(?:\d(?:_*\d)*)?e[+-]?)?\d(?:_*\d)*\b|\b\d(?:_*\d)*\b\.?/i
        ],
        'punctuation': /:=|<<|>>|\(\||\|\)|->|\.(?=\w)|[{}[\];(),:?]/,
        'operator': /\\\\|\|\.\.\||\.\.|\/[~\/=]?|[><]=?|[-+*^=~]/
index aeb71c4f419e9de6bfc5bd8229461753066cc8d3..dac5f6b2ec03754a43301931bc85d99a388fe926 100644 (file)
@@ -22,6 +22,8 @@ define(["prism/prism","prism/components/prism-javascript","prism/components/pris
                Prism.languages['markup-templating'].tokenizePlaceholders(env, 'ejs');
        });
 
+       Prism.languages.eta = Prism.languages.ejs;
+
 }(Prism));
 
 return Prism; })
\ No newline at end of file
index a38beda6c8c07b65e2598ddf6bc83438e28bd87d..2ebdf3784083589addf0624709d38984a4cad7ae 100644 (file)
@@ -9,7 +9,7 @@ Prism.languages.elixir = {
        'string': [
                {
                        // ~s"""foo""" (multi-line), ~s'''foo''' (multi-line), ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo} (with interpolation care), ~s<foo>
-                       pattern: /~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,
+                       pattern: /~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|#(?!\{)|[^#\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,
                        greedy: true,
                        inside: {
                                // See interpolation below
@@ -38,7 +38,7 @@ Prism.languages.elixir = {
                alias: 'symbol'
        },
        // Look-ahead prevents bad highlighting of the :: operator
-       'attr-name': /\w+:(?!:)/,
+       'attr-name': /\w+\??:(?!:)/,
        'capture': {
                // Look-behind prevents bad highlighting of the && operator
                pattern: /(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/,
index d0360d8c10e8c7fab8f03d9ff7da729fe4012125..d47d7407ff13e73f7569c9f2531a2f6121f9e896 100644 (file)
@@ -20,7 +20,7 @@ Prism.languages.elm = {
                // The imported or hidden names are not included in this import
                // statement. This is because we want to highlight those exactly like
                // we do for the names in the program.
-               pattern: /^\s*import\s+[A-Z]\w*(?:\.[A-Z]\w*)*(?:\s+as\s+([A-Z]\w*)(?:\.[A-Z]\w*)*)?(?:\s+exposing\s+)?/m,
+               pattern: /^\s*import\s+[A-Z]\w*(?:\.[A-Z]\w*)*(?:\s+as\s+(?:[A-Z]\w*)(?:\.[A-Z]\w*)*)?(?:\s+exposing\s+)?/m,
                inside: {
                        keyword: /\b(?:import|as|exposing)\b/
                }
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-etlua.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-etlua.js
new file mode 100644 (file)
index 0000000..da844c8
--- /dev/null
@@ -0,0 +1,26 @@
+define(["prism/prism","prism/components/prism-lua","prism/components/prism-markup-templating"], function () {
+(function (Prism) {
+
+       Prism.languages.etlua = {
+               'delimiter': {
+                       pattern: /^<%[-=]?|-?%>$/,
+                       alias: 'punctuation'
+               },
+               'language-lua': {
+                       pattern: /[\s\S]+/,
+                       inside: Prism.languages.lua
+               }
+       };
+
+       Prism.hooks.add('before-tokenize', function (env) {
+               var pattern = /<%[\s\S]+?%>/g;
+               Prism.languages['markup-templating'].buildPlaceholders(env, 'etlua', pattern);
+       });
+
+       Prism.hooks.add('after-tokenize', function (env) {
+               Prism.languages['markup-templating'].tokenizePlaceholders(env, 'etlua');
+       });
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-excel-formula.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-excel-formula.js
new file mode 100644 (file)
index 0000000..3792b70
--- /dev/null
@@ -0,0 +1,69 @@
+define(["prism/prism"], function () {
+Prism.languages['excel-formula'] = {
+       'comment': {
+               pattern: /(\bN\(\s*)"(?:[^"]|"")*"(?=\s*\))/i,
+               lookbehind: true,
+               greedy: true
+       },
+       'string': {
+               pattern: /"(?:[^"]|"")*"(?!")/,
+               greedy: true
+       },
+       'reference': {
+               // https://www.ablebits.com/office-addins-blog/2015/12/08/excel-reference-another-sheet-workbook/
+
+               // Sales!B2
+               // 'Winter sales'!B2
+               // [Sales.xlsx]Jan!B2:B5
+               // D:\Reports\[Sales.xlsx]Jan!B2:B5
+               // '[Sales.xlsx]Jan sales'!B2:B5
+               // 'D:\Reports\[Sales.xlsx]Jan sales'!B2:B5
+
+               pattern: /(?:'[^']*'|(?:[^\s()[\]{}<>*?"';,$&]*\[[^^\s()[\]{}<>*?"']+\])?\w+)!/,
+               greedy: true,
+               alias: 'string',
+               inside: {
+                       'operator': /!$/,
+                       'punctuation': /'/,
+                       'sheet': {
+                               pattern: /[^[\]]+$/,
+                               alias: 'function'
+                       },
+                       'file': {
+                               pattern: /\[[^[\]]+\]$/,
+                               inside: {
+                                       'punctuation': /[[\]]/
+                               }
+                       },
+                       'path': /[\s\S]+/
+               }
+       },
+       'function-name': {
+               pattern: /\b[A-Z]\w*(?=\()/i,
+               alias: 'keyword'
+       },
+       'range': {
+               pattern: /\$?\b(?:[A-Z]+\$?\d+:\$?[A-Z]+\$?\d+|[A-Z]+:\$?[A-Z]+|\d+:\$?\d+)\b/i,
+               alias: 'property',
+               inside: {
+                       'operator': /:/,
+                       'cell': /\$?[A-Z]+\$?\d+/i,
+                       'column': /\$?[A-Z]+/i,
+                       'row': /\$?\d+/
+               }
+       },
+       'cell': {
+               // Excel is case insensitive, so the string "foo1" could be either a variable or a cell.
+               // To combat this, we match cells case insensitive, if the contain at least one "$", and case sensitive otherwise.
+               pattern: /\b[A-Z]+\d+\b|\$[A-Za-z]+\$?\d+\b|\b[A-Za-z]+\$\d+\b/,
+               alias: 'property'
+       },
+       'number': /(?:\b\d+(?:\.\d+)?|\B\.\d+)(?:e[+-]?\d+)?\b/i,
+       'boolean': /\b(?:TRUE|FALSE)\b/i,
+       'operator': /[-+*/^%=&,]|<[=>]?|>=?/,
+       'punctuation': /[[\]();{}|]/
+};
+
+Prism.languages['xlsx'] = Prism.languages['xls'] = Prism.languages['excel-formula'];
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-factor.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-factor.js
new file mode 100644 (file)
index 0000000..21f53bf
--- /dev/null
@@ -0,0 +1,406 @@
+define(["prism/prism"], function () {
+(function (Prism) {
+
+       var comment_inside = {
+               'function': /\b(?:TODOS?|FIX(?:MES?)?|NOTES?|BUGS?|XX+|HACKS?|WARN(?:ING)?|\?{2,}|!{2,})\b/
+       };
+       var string_inside = {
+               'number': /\\[^\s']|%\w/
+       };
+
+       var factor = {
+               'comment': [
+                       {
+                               // ! single-line exclamation point comments with whitespace after/around the !
+                               pattern: /(^|\s)(?:! .*|!$)/,
+                               lookbehind: true,
+                               inside: comment_inside
+                       },
+
+                       /* from basis/multiline: */
+                       {
+                               // /* comment */, /* comment*/
+                               pattern: /(^|\s)\/\*\s[\s\S]*?\*\/(?=\s|$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               inside: comment_inside
+                       },
+                       {
+                               // ![[ comment ]] , ![===[ comment]===]
+                               pattern: /(^|\s)!\[(={0,6})\[\s[\s\S]*?\]\2\](?=\s|$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               inside: comment_inside
+                       }
+               ],
+
+               'number': [
+                       {
+                               // basic base 10 integers 9, -9
+                               pattern: /(^|\s)[+-]?\d+(?=\s|$)/,
+                               lookbehind: true
+                       },
+                       {
+                               // base prefix integers 0b010 0o70 0xad 0d10 0XAD -0xa9
+                               pattern: /(^|\s)[+-]?0(?:b[01]+|o[0-7]+|d\d+|x[\dA-F]+)(?=\s|$)/i,
+                               lookbehind: true
+                       },
+                       {
+                               // fractional ratios 1/5 -1/5 and the literal float approximations 1/5. -1/5.
+                               pattern: /(^|\s)[+-]?\d+\/\d+\.?(?=\s|$)/,
+                               lookbehind: true
+                       },
+                       {
+                               // positive mixed numbers 23+1/5 +23+1/5
+                               pattern: /(^|\s)\+?\d+\+\d+\/\d+(?=\s|$)/,
+                               lookbehind: true
+                       },
+                       {
+                               // negative mixed numbers -23-1/5
+                               pattern: /(^|\s)-\d+-\d+\/\d+(?=\s|$)/,
+                               lookbehind: true
+                       },
+                       {
+                               // basic decimal floats -0.01 0. .0 .1 -.1 -1. -12.13 +12.13
+                               // and scientific notation with base 10 exponents 3e4 3e-4 .3e-4
+                               pattern: /(^|\s)[+-]?(?:\d*\.\d+|\d+\.\d*|\d+)(?:e[+-]?\d+)?(?=\s|$)/i,
+                               lookbehind: true
+                       },
+                       {
+                               // NAN literal syntax NAN: 80000deadbeef, NAN: a
+                               pattern: /(^|\s)NAN:\s+[\da-fA-F]+(?=\s|$)/,
+                               lookbehind: true
+                       },
+                       {
+                               /*
+                                       base prefix floats 0x1.0p3 (8.0) 0b1.010p2 (5.0) 0x1.p1 0b1.11111111p11111...
+                                       "The normalized hex form ±0x1.MMMMMMMMMMMMM[pP]±EEEE allows any floating-point number to be specified precisely.
+                                       The values of MMMMMMMMMMMMM and EEEE map directly to the mantissa and exponent fields of the binary IEEE 754 representation."
+                                       <https://docs.factorcode.org/content/article-syntax-floats.html>
+                               */
+                               pattern: /(^|\s)[+-]?0(?:b1\.[01]*|o1\.[0-7]*|d1\.\d*|x1\.[\dA-F]*)p\d+(?=\s|$)/i,
+                               lookbehind: true
+                       }
+               ],
+
+               // R/ regexp?\/\\/
+               'regexp': {
+                       pattern: /(^|\s)R\/\s+(?:\\\S|[^\\/])*\/(?:[idmsr]*|[idmsr]+-[idmsr]+)(?=\s|$)/,
+                       lookbehind: true,
+                       alias: 'number',
+                       inside: {
+                               'variable': /\\\S/,
+                               'keyword': /[+?*\[\]^$(){}.|]/,
+                               'operator': {
+                                       pattern: /(\/)[idmsr]+(?:-[idmsr]+)?/,
+                                       lookbehind: true
+                               }
+                       }
+               },
+
+               'boolean': {
+                       pattern: /(^|\s)[tf](?=\s|$)/,
+                       lookbehind: true
+               },
+
+               // SBUF" asd", URL" ://...", P" /etc/"
+               'custom-string': {
+                       pattern: /(^|\s)[A-Z0-9\-]+"\s(?:\\\S|[^"\\])*"/,
+                       lookbehind: true,
+                       greedy: true,
+                       alias: 'string',
+                       inside: {
+                               'number': /\\\S|%\w|\//
+                       }
+               },
+
+               'multiline-string': [
+                       {
+                               // STRING: name \n content \n ; -> CONSTANT: name "content" (symbol)
+                               pattern: /(^|\s)STRING:\s+\S+(?:\n|\r\n).*(?:\n|\r\n)\s*;(?=\s|$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               alias: 'string',
+                               inside: {
+                                       'number': string_inside.number,
+                                       // trailing semicolon on its own line
+                                       'semicolon-or-setlocal': {
+                                               pattern: /((?:\n|\r\n)\s*);(?=\s|$)/,
+                                               lookbehind: true,
+                                               alias: 'function'
+                                       }
+                               }
+                       },
+                       {
+                               // HEREDOC: marker \n content \n marker ; -> "content" (immediate)
+                               pattern: /(^|\s)HEREDOC:\s+\S+(?:\n|\r\n).*(?:\n|\r\n)\s*\S+(?=\s|$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               alias: 'string',
+                               inside: string_inside
+                       },
+                       {
+                               // [[ string ]], [==[ string]==]
+                               pattern: /(^|\s)\[(={0,6})\[\s[\s\S]*?\]\2\](?=\s|$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               alias: 'string',
+                               inside: string_inside
+                       }
+               ],
+
+               'special-using': {
+                       pattern: /(^|\s)USING:(?:\s\S+)*(?=\s+;(?:\s|$))/,
+                       lookbehind: true,
+                       alias: 'function',
+                       inside: {
+                               // this is essentially a regex for vocab names, which i don't want to specify
+                               // but the USING: gets picked up as a vocab name
+                               'string': {
+                                       pattern: /(\s)[^:\s]+/,
+                                       lookbehind: true
+                               }
+                       }
+               },
+
+               /* this description of stack effect literal syntax is not complete and not as specific as theoretically possible
+                       trying to do better is more work and regex-computation-time than it's worth though.
+                       - we'd like to have the "delimiter" parts of the stack effect [ (, --, and ) ] be a different (less-important or comment-like) colour to the stack effect contents
+                       - we'd like if nested stack effects were treated as such rather than just appearing flat (with `inside`)
+                       - we'd like if the following variable name conventions were recognised specifically:
+                               special row variables = ..a b..
+                               type and stack effect annotations end with a colon = ( quot: ( a: ( -- ) -- b ) -- x ), ( x: number -- )
+                               word throws unconditional error = *
+                               any other word-like variable name = a ? q' etc
+
+                       https://docs.factorcode.org/content/article-effects.html
+
+                       these are pretty complicated to highlight properly without a real parser, and therefore out of scope
+                       the old pattern, which may be later useful, was: (^|\s)(?:call|execute|eval)?\((?:\s+[^"\r\n\t ]\S*)*?\s+--(?:\s+[^"\n\t ]\S*)*?\s+\)(?=\s|$)
+               */
+
+               // current solution is not great
+               'stack-effect-delimiter': [
+                       {
+                               // opening parenthesis
+                               pattern: /(^|\s)(?:call|execute|eval)?\((?=\s)/,
+                               lookbehind: true,
+                               alias: 'operator'
+                       },
+                       {
+                               // middle --
+                               pattern: /(\s)--(?=\s)/,
+                               lookbehind: true,
+                               alias: 'operator'
+                       },
+                       {
+                               // closing parenthesis
+                               pattern: /(\s)\)(?=\s|$)/,
+                               lookbehind: true,
+                               alias: 'operator'
+                       }
+               ],
+
+               'combinators': {
+                       pattern: null,
+                       lookbehind: true,
+                       alias: 'keyword'
+               },
+
+               'kernel-builtin': {
+                       pattern: null,
+                       lookbehind: true,
+                       alias: 'variable'
+               },
+
+               'sequences-builtin': {
+                       pattern: null,
+                       lookbehind: true,
+                       alias: 'variable'
+               },
+
+               'math-builtin': {
+                       pattern: null,
+                       lookbehind: true,
+                       alias: 'variable'
+               },
+
+               'constructor-word': {
+                       // <array> but not <=>
+                       pattern: /(^|\s)<(?!=+>|-+>)\S+>(?=\s|$)/,
+                       lookbehind: true,
+                       alias: 'keyword'
+               },
+
+               'other-builtin-syntax': {
+                       pattern: null,
+                       lookbehind: true,
+                       alias: 'operator'
+               },
+
+               /*
+                       full list of supported word naming conventions: (the convention appears outside of the [brackets])
+                               set-[x]
+                               change-[x]
+                               with-[x]
+                               new-[x]
+                               >[string]
+                               [base]>
+                               [string]>[number]
+                               +[symbol]+
+                               [boolean-word]?
+                               ?[of]
+                               [slot-reader]>>
+                               >>[slot-setter]
+                               [slot-writer]<<
+                               ([implementation-detail])
+                               [mutater]!
+                               [variant]*
+                               [prettyprint].
+                               $[help-markup]
+
+                       <constructors>, SYNTAX:, etc are supported by their own patterns.
+
+                       `with` and `new` from `kernel` are their own builtins.
+
+                       see <https://docs.factorcode.org/content/article-conventions.html>
+               */
+               'conventionally-named-word': {
+                       pattern: /(^|\s)(?!")(?:(?:set|change|with|new)-\S+|\$\S+|>[^>\s]+|[^:>\s]+>|[^>\s]+>[^>\s]+|\+[^+\s]+\+|[^?\s]+\?|\?[^?\s]+|[^>\s]+>>|>>[^>\s]+|[^<\s]+<<|\([^()\s]+\)|[^!\s]+!|[^*\s]\S*\*|[^.\s]\S*\.)(?=\s|$)/,
+                       lookbehind: true,
+                       alias: 'keyword'
+               },
+
+               'colon-syntax': {
+                       pattern: /(^|\s)(?:[A-Z0-9\-]+#?)?:{1,2}\s+(?:;\S+|(?!;)\S+)(?=\s|$)/,
+                       lookbehind: true,
+                       greedy: true,
+                       alias: 'function'
+               },
+
+               'semicolon-or-setlocal': {
+                       pattern: /(\s)(?:;|:>)(?=\s|$)/,
+                       lookbehind: true,
+                       alias: 'function'
+               },
+
+               // do not highlight leading } or trailing X{ at the begin/end of the file as it's invalid syntax
+               'curly-brace-literal-delimiter': [
+                       {
+                               // opening
+                               pattern: /(^|\s)[a-z]*\{(?=\s)/i,
+                               lookbehind: true,
+                               alias: 'operator'
+                       },
+                       {
+                               // closing
+                               pattern: /(\s)\}(?=\s|$)/,
+                               lookbehind: true,
+                               alias: 'operator'
+                       },
+
+               ],
+
+               // do not highlight leading ] or trailing [ at the begin/end of the file as it's invalid syntax
+               'quotation-delimiter': [
+                       {
+                               // opening
+                               pattern: /(^|\s)\[(?=\s)/,
+                               lookbehind: true,
+                               alias: 'operator'
+                       },
+                       {
+                               // closing
+                               pattern: /(\s)\](?=\s|$)/,
+                               lookbehind: true,
+                               alias: 'operator'
+                       },
+               ],
+
+               'normal-word': {
+                       pattern: /(^|\s)[^"\s]\S*(?=\s|$)/,
+                       lookbehind: true
+               },
+
+               /*
+                       basic first-class string "a"
+                               with escaped double-quote "a\""
+                               escaped backslash "\\"
+                               and general escapes since Factor has so many "\N"
+
+                       syntax that works in the reference implementation that isn't fully
+                       supported because it's an implementation detail:
+                               "string 1""string 2" -> 2 strings (works anyway)
+                               "string"5 -> string, 5
+                               "string"[ ] -> string, quotation
+                               { "a"} -> array<string>
+
+                       the rest of those examples all properly recognise the string, but not
+                               the other object (number, quotation, etc)
+                       this is fine for a regex-only implementation.
+               */
+               'string': {
+                       pattern: /"(?:\\\S|[^"\\])*"/,
+                       greedy: true,
+                       inside: string_inside
+               }
+       };
+
+       var escape = function (str) {
+               return (str+'').replace(/([.?*+\^$\[\]\\(){}|\-])/g, '\\$1');
+       };
+
+       var arrToWordsRegExp = function (arr) {
+               return new RegExp(
+                       '(^|\\s)(?:' + arr.map(escape).join('|') + ')(?=\\s|$)'
+               );
+       };
+
+       var builtins = {
+               'kernel-builtin': [
+                       'or', '2nipd', '4drop', 'tuck', 'wrapper', 'nip', 'wrapper?', 'callstack>array', 'die', 'dupd', 'callstack', 'callstack?', '3dup', 'hashcode', 'pick', '4nip', 'build', '>boolean', 'nipd', 'clone', '5nip', 'eq?', '?', '=', 'swapd', '2over', 'clear', '2dup', 'get-retainstack', 'not', 'tuple?', 'dup', '3nipd', 'call', '-rotd', 'object', 'drop', 'assert=', 'assert?', '-rot', 'execute', 'boa', 'get-callstack', 'curried?', '3drop', 'pickd', 'overd', 'over', 'roll', '3nip', 'swap', 'and', '2nip', 'rotd', 'throw', '(clone)', 'hashcode*', 'spin', 'reach', '4dup', 'equal?', 'get-datastack', 'assert', '2drop', '<wrapper>', 'boolean?', 'identity-hashcode', 'identity-tuple?', 'null', 'composed?', 'new', '5drop', 'rot', '-roll', 'xor', 'identity-tuple', 'boolean'
+               ],
+               'other-builtin-syntax': [
+                       // syntax
+                       '=======', 'recursive', 'flushable', '>>', '<<<<<<', 'M\\', 'B', 'PRIVATE>', '\\', '======', 'final', 'inline', 'delimiter', 'deprecated', '<PRIVATE', '>>>>>>', '<<<<<<<', 'parse-complex', 'malformed-complex', 'read-only', '>>>>>>>', 'call-next-method', '<<', 'foldable',
+                       // literals
+                       '$', '$[', '${'
+               ],
+               'sequences-builtin': [
+                       'member-eq?', 'mismatch', 'append', 'assert-sequence=', 'longer', 'repetition', 'clone-like', '3sequence', 'assert-sequence?', 'last-index-from', 'reversed', 'index-from', 'cut*', 'pad-tail', 'join-as', 'remove-eq!', 'concat-as', 'but-last', 'snip', 'nths', 'nth', 'sequence', 'longest', 'slice?', '<slice>', 'remove-nth', 'tail-slice', 'empty?', 'tail*', 'member?', 'virtual-sequence?', 'set-length', 'drop-prefix', 'iota', 'unclip', 'bounds-error?', 'unclip-last-slice', 'non-negative-integer-expected', 'non-negative-integer-expected?', 'midpoint@', 'longer?', '?set-nth', '?first', 'rest-slice', 'prepend-as', 'prepend', 'fourth', 'sift', 'subseq-start', 'new-sequence', '?last', 'like', 'first4', '1sequence', 'reverse', 'slice', 'virtual@', 'repetition?', 'set-last', 'index', '4sequence', 'max-length', 'set-second', 'immutable-sequence', 'first2', 'first3', 'supremum', 'unclip-slice', 'suffix!', 'insert-nth', 'tail', '3append', 'short', 'suffix', 'concat', 'flip', 'immutable?', 'reverse!', '2sequence', 'sum', 'delete-all', 'indices', 'snip-slice', '<iota>', 'check-slice', 'sequence?', 'head', 'append-as', 'halves', 'sequence=', 'collapse-slice', '?second', 'slice-error?', 'product', 'bounds-check?', 'bounds-check', 'immutable', 'virtual-exemplar', 'harvest', 'remove', 'pad-head', 'last', 'set-fourth', 'cartesian-product', 'remove-eq', 'shorten', 'shorter', 'reversed?', 'shorter?', 'shortest', 'head-slice', 'pop*', 'tail-slice*', 'but-last-slice', 'iota?', 'append!', 'cut-slice', 'new-resizable', 'head-slice*', 'sequence-hashcode', 'pop', 'set-nth', '?nth', 'second', 'join', 'immutable-sequence?', '<reversed>', '3append-as', 'virtual-sequence', 'subseq?', 'remove-nth!', 'length', 'last-index', 'lengthen', 'assert-sequence', 'copy', 'move', 'third', 'first', 'tail?', 'set-first', 'prefix', 'bounds-error', '<repetition>', 'exchange', 'surround', 'cut', 'min-length', 'set-third', 'push-all', 'head?', 'subseq-start-from', 'delete-slice', 'rest', 'sum-lengths', 'head*', 'infimum', 'remove!', 'glue', 'slice-error', 'subseq', 'push', 'replace-slice', 'subseq-as', 'unclip-last'
+               ],
+               'math-builtin': [
+                       'number=', 'next-power-of-2', '?1+', 'fp-special?', 'imaginary-part', 'float>bits', 'number?', 'fp-infinity?', 'bignum?', 'fp-snan?', 'denominator', 'gcd', '*', '+', 'fp-bitwise=', '-', 'u>=', '/', '>=', 'bitand', 'power-of-2?', 'log2-expects-positive', 'neg?', '<', 'log2', '>', 'integer?', 'number', 'bits>double', '2/', 'zero?', 'bits>float', 'float?', 'shift', 'ratio?', 'rect>', 'even?', 'ratio', 'fp-sign', 'bitnot', '>fixnum', 'complex?', '/i', 'integer>fixnum', '/f', 'sgn', '>bignum', 'next-float', 'u<', 'u>', 'mod', 'recip', 'rational', '>float', '2^', 'integer', 'fixnum?', 'neg', 'fixnum', 'sq', 'bignum', '>rect', 'bit?', 'fp-qnan?', 'simple-gcd', 'complex', '<fp-nan>', 'real', '>fraction', 'double>bits', 'bitor', 'rem', 'fp-nan-payload', 'real-part', 'log2-expects-positive?', 'prev-float', 'align', 'unordered?', 'float', 'fp-nan?', 'abs', 'bitxor', 'integer>fixnum-strict', 'u<=', 'odd?', '<=', '/mod', '>integer', 'real?', 'rational?', 'numerator'
+               ]
+               // that's all for now
+       };
+
+       Object.keys(builtins).forEach(function (k) {
+               factor[k].pattern = arrToWordsRegExp( builtins[k] );
+       });
+
+       var combinators = [
+               // kernel
+               '2bi', 'while', '2tri', 'bi*', '4dip', 'both?', 'same?', 'tri@', 'curry', 'prepose', '3bi', '?if', 'tri*', '2keep', '3keep', 'curried', '2keepd', 'when', '2bi*', '2tri*', '4keep', 'bi@', 'keepdd', 'do', 'unless*', 'tri-curry', 'if*', 'loop', 'bi-curry*', 'when*', '2bi@', '2tri@', 'with', '2with', 'either?', 'bi', 'until', '3dip', '3curry', 'tri-curry*', 'tri-curry@', 'bi-curry', 'keepd', 'compose', '2dip', 'if', '3tri', 'unless', 'tuple', 'keep', '2curry', 'tri', 'most', 'while*', 'dip', 'composed', 'bi-curry@',
+               // sequences
+               'find-last-from', 'trim-head-slice', 'map-as', 'each-from', 'none?', 'trim-tail', 'partition', 'if-empty', 'accumulate*', 'reject!', 'find-from', 'accumulate-as', 'collector-for-as', 'reject', 'map', 'map-sum', 'accumulate!', '2each-from', 'follow', 'supremum-by', 'map!', 'unless-empty', 'collector', 'padding', 'reduce-index', 'replicate-as', 'infimum-by', 'trim-tail-slice', 'count', 'find-index', 'filter', 'accumulate*!', 'reject-as', 'map-integers', 'map-find', 'reduce', 'selector', 'interleave', '2map', 'filter-as', 'binary-reduce', 'map-index-as', 'find', 'produce', 'filter!', 'replicate', 'cartesian-map', 'cartesian-each', 'find-index-from', 'map-find-last', '3map-as', '3map', 'find-last', 'selector-as', '2map-as', '2map-reduce', 'accumulate', 'each', 'each-index', 'accumulate*-as', 'when-empty', 'all?', 'collector-as', 'push-either', 'new-like', 'collector-for', '2selector', 'push-if', '2all?', 'map-reduce', '3each', 'any?', 'trim-slice', '2reduce', 'change-nth', 'produce-as', '2each', 'trim', 'trim-head', 'cartesian-find', 'map-index',
+               // math
+               'if-zero', 'each-integer', 'unless-zero', '(find-integer)', 'when-zero', 'find-last-integer', '(all-integers?)', 'times', '(each-integer)', 'find-integer', 'all-integers?',
+               // math.combinators
+               'unless-negative', 'if-positive', 'when-positive', 'when-negative', 'unless-positive', 'if-negative',
+               // combinators
+               'case', '2cleave', 'cond>quot', 'case>quot', '3cleave', 'wrong-values', 'to-fixed-point', 'alist>quot', 'cond', 'cleave', 'call-effect', 'recursive-hashcode', 'spread', 'deep-spread>quot',
+               // combinators.short-circuit
+               '2||', '0||', 'n||', '0&&', '2&&', '3||', '1||', '1&&', 'n&&', '3&&',
+               // combinators.smart
+               'smart-unless*', 'keep-inputs', 'reduce-outputs', 'smart-when*', 'cleave>array', 'smart-with', 'smart-apply', 'smart-if', 'inputs/outputs', 'output>sequence-n', 'map-outputs', 'map-reduce-outputs', 'dropping', 'output>array', 'smart-map-reduce', 'smart-2map-reduce', 'output>array-n', 'nullary', 'input<sequence', 'append-outputs', 'drop-inputs', 'inputs', 'smart-2reduce', 'drop-outputs', 'smart-reduce', 'preserving', 'smart-when', 'outputs', 'append-outputs-as', 'smart-unless', 'smart-if*', 'sum-outputs', 'input<sequence-unsafe', 'output>sequence',
+               // tafn
+       ];
+
+       factor.combinators.pattern = arrToWordsRegExp(combinators);
+
+       Prism.languages.factor = factor;
+
+})(Prism);
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-firestore-security-rules.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-firestore-security-rules.js
new file mode 100644 (file)
index 0000000..5e1737a
--- /dev/null
@@ -0,0 +1,38 @@
+define(["prism/prism","prism/components/prism-clike"], function () {
+Prism.languages['firestore-security-rules'] = Prism.languages.extend('clike', {
+       'comment': /\/\/.*/,
+       'keyword': /\b(?:allow|function|if|match|null|return|rules_version|service)\b/,
+       'operator': /&&|\|\||[<>!=]=?|[-+*/%=]|\b(?:in|is)\b/,
+});
+
+delete Prism.languages['firestore-security-rules']['class-name'];
+
+Prism.languages.insertBefore('firestore-security-rules', 'keyword', {
+       'path': {
+               pattern: /(^|[\s(),])(?:\/(?:[\w\xA0-\uFFFF]+|\{[\w\xA0-\uFFFF]+(?:=\*\*)?\}|\$\([\w\xA0-\uFFFF.]+\)))+/,
+               lookbehind: true,
+               greedy: true,
+               inside: {
+                       'variable': {
+                               pattern: /\{[\w\xA0-\uFFFF]+(?:=\*\*)?\}|\$\([\w\xA0-\uFFFF.]+\)/,
+                               inside: {
+                                       'operator': /=/,
+                                       'keyword': /\*\*/,
+                                       'punctuation': /[.$(){}]/
+                               }
+                       },
+                       'punctuation': /[/]/
+               }
+       },
+       'method': {
+               // to make the pattern shorter, the actual method names are omitted
+               pattern: /(\ballow\s+)[a-z]+(?:\s*,\s*[a-z]+)*(?=\s*[:;])/,
+               lookbehind: true,
+               alias: 'builtin',
+               inside: {
+                       'punctuation': /,/
+               }
+       },
+});
+
+return Prism; })
\ No newline at end of file
index d233991215fbf3bdec9cf90c3ff1ce8f6b2ccd35..8f45ec1c25b1ca7c11c494c9495618237819f64c 100644 (file)
@@ -11,7 +11,7 @@ Prism.languages.fsharp = Prism.languages.extend('clike', {
                }
        ],
        'string': {
-               pattern: /(?:"""[\s\S]*?"""|@"(?:""|[^"])*"|"(?:\\[\s\S]|[^\\"])*")B?|'(?:[^\\']|\\.)'B?/,
+               pattern: /(?:"""[\s\S]*?"""|@"(?:""|[^"])*"|"(?:\\[\s\S]|[^\\"])*")B?|'(?:[^\\']|\\(?:.|\d{3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}|U[a-fA-F\d]{8}))'B?/,
                greedy: true
        },
        'class-name': {
@@ -22,7 +22,7 @@ Prism.languages.fsharp = Prism.languages.extend('clike', {
                        'punctuation': /\./
                }
        },
-       'keyword': /\b(?:let|return|use|yield)(?:!\B|\b)|\b(abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|match|member|module|mutable|namespace|new|not|null|of|open|or|override|private|public|rec|select|static|struct|then|to|true|try|type|upcast|val|void|when|while|with|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile)\b/,
+       'keyword': /\b(?:let|return|use|yield)(?:!\B|\b)|\b(?:abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|match|member|module|mutable|namespace|new|not|null|of|open|or|override|private|public|rec|select|static|struct|then|to|true|try|type|upcast|val|void|when|while|with|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile)\b/,
        'number': [
                /\b0x[\da-fA-F]+(?:un|lf|LF)?\b/,
                /\b0b[01]+(?:y|uy)?\b/,
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-ftl.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-ftl.js
new file mode 100644 (file)
index 0000000..a9d8b6b
--- /dev/null
@@ -0,0 +1,100 @@
+define(["prism/prism","prism/components/prism-markup-templating"], function () {
+(function (Prism) {
+
+       // https://freemarker.apache.org/docs/dgui_template_exp.html
+
+       // FTL expression with 4 levels of nesting supported
+       var FTL_EXPR = /[^<()"']|\((?:<expr>)*\)|<(?!#--)|<#--(?:[^-]|-(?!->))*-->|"(?:[^\\"]|\\.)*"|'(?:[^\\']|\\.)*'/.source;
+       for (var i = 0; i < 2; i++) {
+               FTL_EXPR = FTL_EXPR.replace(/<expr>/g, function () { return FTL_EXPR; });
+       }
+       FTL_EXPR = FTL_EXPR.replace(/<expr>/g, /[^\s\S]/.source);
+
+       var ftl = {
+               'comment': /<#--[\s\S]*?-->/,
+               'string': [
+                       {
+                               // raw string
+                               pattern: /\br("|')(?:(?!\1)[^\\]|\\.)*\1/,
+                               greedy: true
+                       },
+                       {
+                               pattern: RegExp(/("|')(?:(?!\1|\$\{)[^\\]|\\.|\$\{(?:<expr>)*?\})*\1/.source.replace(/<expr>/g, function () { return FTL_EXPR; })),
+                               greedy: true,
+                               inside: {
+                                       'interpolation': {
+                                               pattern: RegExp(/((?:^|[^\\])(?:\\\\)*)\$\{(?:<expr>)*?\}/.source.replace(/<expr>/g, function () { return FTL_EXPR; })),
+                                               lookbehind: true,
+                                               inside: {
+                                                       'interpolation-punctuation': {
+                                                               pattern: /^\$\{|\}$/,
+                                                               alias: 'punctuation'
+                                                       },
+                                                       rest: null
+                                               }
+                                       }
+                               }
+                       }
+               ],
+               'keyword': /\b(?:as)\b/,
+               'boolean': /\b(?:true|false)\b/,
+               'builtin-function': {
+                       pattern: /((?:^|[^?])\?\s*)\w+/,
+                       lookbehind: true,
+                       alias: 'function'
+               },
+               'function': /\w+(?=\s*\()/,
+               'number': /\d+(?:\.\d+)?/,
+               'operator': /\.\.[<*!]?|->|--|\+\+|&&|\|\||\?{1,2}|[-+*/%!=<>]=?|\b(?:gt|gte|lt|lte)\b/,
+               'punctuation': /[,;.:()[\]{}]/
+       };
+
+       ftl.string[1].inside.interpolation.inside.rest = ftl;
+
+       Prism.languages.ftl = {
+               'ftl-comment': {
+                       // the pattern is shortened to be more efficient
+                       pattern: /^<#--[\s\S]*/,
+                       alias: 'comment'
+               },
+               'ftl-directive': {
+                       pattern: /^<[\s\S]+>$/,
+                       inside: {
+                               'directive': {
+                                       pattern: /(^<\/?)[#@][a-z]\w*/i,
+                                       lookbehind: true,
+                                       alias: 'keyword'
+                               },
+                               'punctuation': /^<\/?|\/?>$/,
+                               'content': {
+                                       pattern: /[\s\S]*\S[\s\S]*/,
+                                       alias: 'ftl',
+                                       inside: ftl
+                               }
+                       }
+               },
+               'ftl-interpolation': {
+                       pattern: /^\$\{[\s\S]*\}$/,
+                       inside: {
+                               'punctuation': /^\$\{|\}$/,
+                               'content': {
+                                       pattern: /[\s\S]*\S[\s\S]*/,
+                                       alias: 'ftl',
+                                       inside: ftl
+                               }
+                       }
+               }
+       };
+
+       Prism.hooks.add('before-tokenize', function (env) {
+               var pattern = RegExp(/<#--[\s\S]*?-->|<\/?[#@][a-zA-Z](?:<expr>)*?>|\$\{(?:<expr>)*?\}/.source.replace(/<expr>/g, function () { return FTL_EXPR; }), 'gi');
+               Prism.languages['markup-templating'].buildPlaceholders(env, 'ftl', pattern);
+       });
+
+       Prism.hooks.add('after-tokenize', function (env) {
+               Prism.languages['markup-templating'].tokenizePlaceholders(env, 'ftl');
+       });
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-gdscript.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-gdscript.js
new file mode 100644 (file)
index 0000000..f1ec4f3
--- /dev/null
@@ -0,0 +1,30 @@
+define(["prism/prism"], function () {
+Prism.languages.gdscript = {
+       'comment': /#.*/,
+       'string': {
+               pattern: /@?(?:("|')(?:(?!\1)[^\n\\]|\\[\s\S])*\1(?!"|')|"""(?:[^\\]|\\[\s\S])*?""")/,
+               greedy: true
+       },
+       'class-name': {
+               // class_name Foo, extends Bar, class InnerClass
+               // export(int) var baz, export(int, 0) var i
+               // as Node
+               // const FOO: int = 9, var bar: bool = true
+               // func add(reference: Item, amount: int) -> Item:
+               pattern: /(^(?:class_name|class|extends)[ \t]+|^export\([ \t]*|\bas[ \t]+|(?:\b(?:const|var)[ \t]|[,(])[ \t]*\w+[ \t]*:[ \t]*|->[ \t]*)[a-zA-Z_]\w*/m,
+               lookbehind: true
+       },
+       'keyword': /\b(?:and|as|assert|break|breakpoint|class|class_name|const|continue|elif|else|enum|export|extends|for|func|if|in|is|master|mastersync|match|not|null|onready|or|pass|preload|puppet|puppetsync|remote|remotesync|return|self|setget|signal|static|tool|var|while|yield)\b/,
+       'function': /[a-z_]\w*(?=[ \t]*\()/i,
+       'variable': /\$\w+/,
+       'number': [
+               /\b0b[01_]+\b|\b0x[\da-fA-F_]+\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.[\d_]+)(?:e[+-]?[\d_]+)?\b/,
+               /\b(?:INF|NAN|PI|TAU)\b/
+       ],
+       'constant': /\b[A-Z][A-Z_\d]*\b/,
+       'boolean': /\b(?:false|true)\b/,
+       'operator': /->|:=|&&|\|\||<<|>>|[-+*/%&|!<>=]=?|[~^]/,
+       'punctuation': /[.:,;()[\]{}]/
+};
+
+return Prism; })
\ No newline at end of file
index d92163cec909755ad79e9bfdd4b9b3b31320e389..6c90c0885b9e6dd9cc0464c58dd175189a987131 100644 (file)
@@ -1,82 +1,88 @@
 define(["prism/prism"], function () {
-Prism.languages.gherkin = {
-       'pystring': {
-               pattern: /("""|''')[\s\S]+?\1/,
-               alias: 'string'
-       },
-       'comment': {
-               pattern: /((?:^|\r?\n|\r)[ \t]*)#.*/,
-               lookbehind: true
-       },
-       'tag': {
-               pattern: /((?:^|\r?\n|\r)[ \t]*)@\S*/,
-               lookbehind: true
-       },
-       'feature': {
-               pattern: /((?:^|\r?\n|\r)[ \t]*)(?:Ability|Ahoy matey!|Arwedd|Aspekt|Besigheid Behoefte|Business Need|Caracteristica|Característica|Egenskab|Egenskap|Eiginleiki|Feature|Fīča|Fitur|Fonctionnalité|Fonksyonalite|Funcionalidade|Funcionalitat|Functionalitate|Funcţionalitate|Funcționalitate|Functionaliteit|Fungsi|Funkcia|Funkcija|Funkcionalitāte|Funkcionalnost|Funkcja|Funksie|Funktionalität|Funktionalitéit|Funzionalità|Hwaet|Hwæt|Jellemző|Karakteristik|laH|Lastnost|Mak|Mogucnost|Mogućnost|Moznosti|Možnosti|OH HAI|Omadus|Ominaisuus|Osobina|Özellik|perbogh|poQbogh malja'|Potrzeba biznesowa|Požadavek|Požiadavka|Pretty much|Qap|Qu'meH 'ut|Savybė|Tính năng|Trajto|Vermoë|Vlastnosť|Właściwość|Značilnost|Δυνατότητα|Λειτουργία|Могућност|Мөмкинлек|Особина|Свойство|Үзенчәлеклелек|Функционал|Функционалност|Функция|Функціонал|תכונה|خاصية|خصوصیت|صلاحیت|کاروبار کی ضرورت|وِیژگی|रूप लेख|ਖਾਸੀਅਤ|ਨਕਸ਼ ਨੁਹਾਰ|ਮੁਹਾਂਦਰਾ|గుణము|ಹೆಚ್ಚಳ|ความต้องการทางธุรกิจ|ความสามารถ|โครงหลัก|기능|フィーチャ|功能|機能):(?:[^:]+(?:\r?\n|\r|$))*/,
-               lookbehind: true,
-               inside: {
-                       'important': {
-                               pattern: /(:)[^\r\n]+/,
-                               lookbehind: true
-                       },
-                       keyword: /[^:\r\n]+:/
-               }
-       },
-       'scenario': {
-               pattern: /((?:^|\r?\n|\r)[ \t]*)(?:Abstract Scenario|Abstrakt Scenario|Achtergrond|Aer|Ær|Agtergrond|All y'all|Antecedentes|Antecedents|Atburðarás|Atburðarásir|Awww, look mate|B4|Background|Baggrund|Bakgrund|Bakgrunn|Bakgrunnur|Beispiele|Beispiller|Bối cảnh|Cefndir|Cenario|Cenário|Cenario de Fundo|Cenário de Fundo|Cenarios|Cenários|Contesto|Context|Contexte|Contexto|Conto|Contoh|Contone|Dæmi|Dasar|Dead men tell no tales|Delineacao do Cenario|Delineação do Cenário|Dis is what went down|Dữ liệu|Dyagram senaryo|Dyagram Senaryo|Egzanp|Ejemplos|Eksempler|Ekzemploj|Enghreifftiau|Esbozo do escenario|Escenari|Escenario|Esempi|Esquema de l'escenari|Esquema del escenario|Esquema do Cenario|Esquema do Cenário|Examples|EXAMPLZ|Exempel|Exemple|Exemples|Exemplos|First off|Fono|Forgatókönyv|Forgatókönyv vázlat|Fundo|Geçmiş|ghantoH|Grundlage|Hannergrond|Háttér|Heave to|Istorik|Juhtumid|Keadaan|Khung kịch bản|Khung tình huống|Kịch bản|Koncept|Konsep skenario|Kontèks|Kontekst|Kontekstas|Konteksts|Kontext|Konturo de la scenaro|Latar Belakang|lut|lut chovnatlh|lutmey|Lýsing Atburðarásar|Lýsing Dæma|Menggariskan Senario|MISHUN|MISHUN SRSLY|mo'|Náčrt Scenára|Náčrt Scénáře|Náčrt Scenáru|Oris scenarija|Örnekler|Osnova|Osnova Scenára|Osnova scénáře|Osnutek|Ozadje|Paraugs|Pavyzdžiai|Példák|Piemēri|Plan du scénario|Plan du Scénario|Plan senaryo|Plan Senaryo|Plang vum Szenario|Pozadí|Pozadie|Pozadina|Príklady|Příklady|Primer|Primeri|Primjeri|Przykłady|Raamstsenaarium|Reckon it's like|Rerefons|Scenár|Scénář|Scenarie|Scenarij|Scenarijai|Scenarijaus šablonas|Scenariji|Scenārijs|Scenārijs pēc parauga|Scenarijus|Scenario|Scénario|Scenario Amlinellol|Scenario Outline|Scenario Template|Scenariomal|Scenariomall|Scenarios|Scenariu|Scenariusz|Scenaro|Schema dello scenario|Se ðe|Se the|Se þe|Senario|Senaryo|Senaryo deskripsyon|Senaryo Deskripsyon|Senaryo taslağı|Shiver me timbers|Situācija|Situai|Situasie|Situasie Uiteensetting|Skenario|Skenario konsep|Skica|Structura scenariu|Structură scenariu|Struktura scenarija|Stsenaarium|Swa|Swa hwaer swa|Swa hwær swa|Szablon scenariusza|Szenario|Szenariogrundriss|Tapaukset|Tapaus|Tapausaihio|Taust|Tausta|Template Keadaan|Template Senario|Template Situai|The thing of it is|Tình huống|Variantai|Voorbeelde|Voorbeelden|Wharrimean is|Yo\-ho\-ho|You'll wanna|Założenia|Παραδείγματα|Περιγραφή Σεναρίου|Σενάρια|Σενάριο|Υπόβαθρο|Кереш|Контекст|Концепт|Мисаллар|Мисоллар|Основа|Передумова|Позадина|Предистория|Предыстория|Приклади|Пример|Примери|Примеры|Рамка на сценарий|Скица|Структура сценарија|Структура сценария|Структура сценарію|Сценарий|Сценарий структураси|Сценарийның төзелеше|Сценарији|Сценарио|Сценарій|Тарих|Үрнәкләр|דוגמאות|רקע|תבנית תרחיש|תרחיש|الخلفية|الگوی سناریو|امثلة|پس منظر|زمینه|سناریو|سيناريو|سيناريو مخطط|مثالیں|منظر نامے کا خاکہ|منظرنامہ|نمونه ها|उदाहरण|परिदृश्य|परिदृश्य रूपरेखा|पृष्ठभूमि|ਉਦਾਹਰਨਾਂ|ਪਟਕਥਾ|ਪਟਕਥਾ ਢਾਂਚਾ|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਿਛੋਕੜ|ఉదాహరణలు|కథనం|నేపథ్యం|సన్నివేశం|ಉದಾಹರಣೆಗಳು|ಕಥಾಸಾರಾಂಶ|ವಿವರಣೆ|ಹಿನ್ನೆಲೆ|โครงสร้างของเหตุการณ์|ชุดของตัวอย่าง|ชุดของเหตุการณ์|แนวคิด|สรุปเหตุการณ์|เหตุการณ์|배경|시나리오|시나리오 개요|예|サンプル|シナリオ|シナリオアウトライン|シナリオテンプレ|シナリオテンプレート|テンプレ|例|例子|剧本|剧本大纲|劇本|劇本大綱|场景|场景大纲|場景|場景大綱|背景):[^:\r\n]*/,
-               lookbehind: true,
-               inside: {
-                       'important': {
-                               pattern: /(:)[^\r\n]*/,
-                               lookbehind: true
-                       },
-                       keyword: /[^:\r\n]+:/
-               }
-       },
-       'table-body': {
-               // Look-behind is used to skip the table head, which has the same format as any table row
-               pattern: /((?:\r?\n|\r)[ \t]*\|.+\|[^\r\n]*)+/,
-               lookbehind: true,
-               inside: {
-                       'outline': {
-                               pattern: /<[^>]+?>/,
-                               alias: 'variable'
-                       },
-                       'td': {
-                               pattern: /\s*[^\s|][^|]*/,
-                               alias: 'string'
-                       },
-                       'punctuation': /\|/
-               }
-       },
-       'table-head': {
-               pattern: /(?:\r?\n|\r)[ \t]*\|.+\|[^\r\n]*/,
-               inside: {
-                       'th': {
-                               pattern: /\s*[^\s|][^|]*/,
-                               alias: 'variable'
-                       },
-                       'punctuation': /\|/
-               }
-       },
-       'atrule': {
-               pattern: /((?:\r?\n|\r)[ \t]+)(?:'ach|'a|'ej|7|a|A také|A taktiež|A tiež|A zároveň|Aber|Ac|Adott|Akkor|Ak|Aleshores|Ale|Ali|Allora|Alors|Als|Ama|Amennyiben|Amikor|Ampak|an|AN|Ananging|And y'all|And|Angenommen|Anrhegedig a|An|Apabila|Atès|Atesa|Atunci|Avast!|Aye|A|awer|Bagi|Banjur|Bet|Biết|Blimey!|Buh|But at the end of the day I reckon|But y'all|But|BUT|Cal|Când|Cando|Cand|Ce|Cuando|Če|Ða ðe|Ða|Dadas|Dada|Dados|Dado|DaH ghu' bejlu'|dann|Dann|Dano|Dan|Dar|Dat fiind|Data|Date fiind|Date|Dati fiind|Dati|Daţi fiind|Dați fiind|Dato|DEN|Den youse gotta|Dengan|De|Diberi|Diyelim ki|Donada|Donat|Donitaĵo|Do|Dun|Duota|Ðurh|Eeldades|Ef|Eğer ki|Entao|Então|Entón|Entonces|En|Epi|E|És|Etant donnée|Etant donné|Et|Étant données|Étant donnée|Étant donné|Etant données|Etant donnés|Étant donnés|Fakat|Gangway!|Gdy|Gegeben seien|Gegeben sei|Gegeven|Gegewe|ghu' noblu'|Gitt|Given y'all|Given|Givet|Givun|Ha|Cho|I CAN HAZ|In|Ir|It's just unbelievable|I|Ja|Jeśli|Jeżeli|Kadar|Kada|Kad|Kai|Kaj|Když|Keď|Kemudian|Ketika|Khi|Kiedy|Ko|Kuid|Kui|Kun|Lan|latlh|Le sa a|Let go and haul|Le|Lè sa a|Lè|Logo|Lorsqu'<|Lorsque|mä|Maar|Mais|Mając|Majd|Maka|Manawa|Mas|Ma|Menawa|Men|Mutta|Nalikaning|Nalika|Nanging|Når|När|Nato|Nhưng|Niin|Njuk|O zaman|Og|Och|Oletetaan|Onda|Ond|Oraz|Pak|Pero|Però|Podano|Pokiaľ|Pokud|Potem|Potom|Privzeto|Pryd|qaSDI'|Quando|Quand|Quan|Så|Sed|Se|Siis|Sipoze ke|Sipoze Ke|Sipoze|Si|Şi|Și|Soit|Stel|Tada|Tad|Takrat|Tak|Tapi|Ter|Tetapi|Tha the|Tha|Then y'all|Then|Thì|Thurh|Toda|Too right|ugeholl|Und|Un|Và|vaj|Vendar|Ve|wann|Wanneer|WEN|Wenn|When y'all|When|Wtedy|Wun|Y'know|Yeah nah|Yna|Youse know like when|Youse know when youse got|Y|Za predpokladu|Za předpokladu|Zadani|Zadano|Zadan|Zadate|Zadato|Zakładając|Zaradi|Zatati|Þa þe|Þa|Þá|Þegar|Þurh|Αλλά|Δεδομένου|Και|Όταν|Τότε|А також|Агар|Але|Али|Аммо|А|Әгәр|Әйтик|Әмма|Бирок|Ва|Вә|Дадено|Дано|Допустим|Если|Задате|Задати|Задато|И|І|К тому же|Када|Кад|Когато|Когда|Коли|Ләкин|Лекин|Нәтиҗәдә|Нехай|Но|Онда|Припустимо, що|Припустимо|Пусть|Также|Та|Тогда|Тоді|То|Унда|Һәм|Якщо|אבל|אזי|אז|בהינתן|וגם|כאשר|آنگاه|اذاً|اگر|اما|اور|با فرض|بالفرض|بفرض|پھر|تب|ثم|جب|عندما|فرض کیا|لكن|لیکن|متى|هنگامی|و|अगर|और|कदा|किन्तु|चूंकि|जब|तथा|तदा|तब|परन्तु|पर|यदि|ਅਤੇ|ਜਦੋਂ|ਜਿਵੇਂ ਕਿ|ਜੇਕਰ|ਤਦ|ਪਰ|అప్పుడు|ఈ పరిస్థితిలో|కాని|చెప్పబడినది|మరియు|ಆದರೆ|ನಂತರ|ನೀಡಿದ|ಮತ್ತು|ಸ್ಥಿತಿಯನ್ನು|กำหนดให้|ดังนั้น|แต่|เมื่อ|และ|그러면<|그리고<|단<|만약<|만일<|먼저<|조건<|하지만<|かつ<|しかし<|ただし<|ならば<|もし<|並且<|但し<|但是<|假如<|假定<|假設<|假设<|前提<|同时<|同時<|并且<|当<|當<|而且<|那么<|那麼<)(?=[ \t]+)/,
-               lookbehind: true
-       },
-       'string': {
-               pattern: /"(?:\\.|[^"\\\r\n])*"|'(?:\\.|[^'\\\r\n])*'/,
-               inside: {
-                       'outline': {
-                               pattern: /<[^>]+?>/,
-                               alias: 'variable'
+(function (Prism) {
+
+       var tableRow = /(?:\r?\n|\r)[ \t]*\|.+\|.*/.source;
+
+       Prism.languages.gherkin = {
+               'pystring': {
+                       pattern: /("""|''')[\s\S]+?\1/,
+                       alias: 'string'
+               },
+               'comment': {
+                       pattern: /(^[ \t]*)#.*/m,
+                       lookbehind: true
+               },
+               'tag': {
+                       pattern: /(^[ \t]*)@\S*/m,
+                       lookbehind: true
+               },
+               'feature': {
+                       pattern: /((?:^|\r?\n|\r)[ \t]*)(?:Ability|Ahoy matey!|Arwedd|Aspekt|Besigheid Behoefte|Business Need|Caracteristica|Característica|Egenskab|Egenskap|Eiginleiki|Feature|Fīča|Fitur|Fonctionnalité|Fonksyonalite|Funcionalidade|Funcionalitat|Functionalitate|Funcţionalitate|Funcționalitate|Functionaliteit|Fungsi|Funkcia|Funkcija|Funkcionalitāte|Funkcionalnost|Funkcja|Funksie|Funktionalität|Funktionalitéit|Funzionalità|Hwaet|Hwæt|Jellemző|Karakteristik|laH|Lastnost|Mak|Mogucnost|Mogućnost|Moznosti|Možnosti|OH HAI|Omadus|Ominaisuus|Osobina|Özellik|perbogh|poQbogh malja'|Potrzeba biznesowa|Požadavek|Požiadavka|Pretty much|Qap|Qu'meH 'ut|Savybė|Tính năng|Trajto|Vermoë|Vlastnosť|Właściwość|Značilnost|Δυνατότητα|Λειτουργία|Могућност|Мөмкинлек|Особина|Свойство|Үзенчәлеклелек|Функционал|Функционалност|Функция|Функціонал|תכונה|خاصية|خصوصیت|صلاحیت|کاروبار کی ضرورت|وِیژگی|रूप लेख|ਖਾਸੀਅਤ|ਨਕਸ਼ ਨੁਹਾਰ|ਮੁਹਾਂਦਰਾ|గుణము|ಹೆಚ್ಚಳ|ความต้องการทางธุรกิจ|ความสามารถ|โครงหลัก|기능|フィーチャ|功能|機能):(?:[^:]+(?:\r?\n|\r|$))*/,
+                       lookbehind: true,
+                       inside: {
+                               'important': {
+                                       pattern: /(:)[^\r\n]+/,
+                                       lookbehind: true
+                               },
+                               'keyword': /[^:\r\n]+:/
                        }
+               },
+               'scenario': {
+                       pattern: /(^[ \t]*)(?:Abstract Scenario|Abstrakt Scenario|Achtergrond|Aer|Ær|Agtergrond|All y'all|Antecedentes|Antecedents|Atburðarás|Atburðarásir|Awww, look mate|B4|Background|Baggrund|Bakgrund|Bakgrunn|Bakgrunnur|Beispiele|Beispiller|Bối cảnh|Cefndir|Cenario|Cenário|Cenario de Fundo|Cenário de Fundo|Cenarios|Cenários|Contesto|Context|Contexte|Contexto|Conto|Contoh|Contone|Dæmi|Dasar|Dead men tell no tales|Delineacao do Cenario|Delineação do Cenário|Dis is what went down|Dữ liệu|Dyagram senaryo|Dyagram Senaryo|Egzanp|Ejemplos|Eksempler|Ekzemploj|Enghreifftiau|Esbozo do escenario|Escenari|Escenario|Esempi|Esquema de l'escenari|Esquema del escenario|Esquema do Cenario|Esquema do Cenário|Examples|EXAMPLZ|Exempel|Exemple|Exemples|Exemplos|First off|Fono|Forgatókönyv|Forgatókönyv vázlat|Fundo|Geçmiş|ghantoH|Grundlage|Hannergrond|Háttér|Heave to|Istorik|Juhtumid|Keadaan|Khung kịch bản|Khung tình huống|Kịch bản|Koncept|Konsep skenario|Kontèks|Kontekst|Kontekstas|Konteksts|Kontext|Konturo de la scenaro|Latar Belakang|lut|lut chovnatlh|lutmey|Lýsing Atburðarásar|Lýsing Dæma|Menggariskan Senario|MISHUN|MISHUN SRSLY|mo'|Náčrt Scenára|Náčrt Scénáře|Náčrt Scenáru|Oris scenarija|Örnekler|Osnova|Osnova Scenára|Osnova scénáře|Osnutek|Ozadje|Paraugs|Pavyzdžiai|Példák|Piemēri|Plan du scénario|Plan du Scénario|Plan senaryo|Plan Senaryo|Plang vum Szenario|Pozadí|Pozadie|Pozadina|Príklady|Příklady|Primer|Primeri|Primjeri|Przykłady|Raamstsenaarium|Reckon it's like|Rerefons|Scenár|Scénář|Scenarie|Scenarij|Scenarijai|Scenarijaus šablonas|Scenariji|Scenārijs|Scenārijs pēc parauga|Scenarijus|Scenario|Scénario|Scenario Amlinellol|Scenario Outline|Scenario Template|Scenariomal|Scenariomall|Scenarios|Scenariu|Scenariusz|Scenaro|Schema dello scenario|Se ðe|Se the|Se þe|Senario|Senaryo|Senaryo deskripsyon|Senaryo Deskripsyon|Senaryo taslağı|Shiver me timbers|Situācija|Situai|Situasie|Situasie Uiteensetting|Skenario|Skenario konsep|Skica|Structura scenariu|Structură scenariu|Struktura scenarija|Stsenaarium|Swa|Swa hwaer swa|Swa hwær swa|Szablon scenariusza|Szenario|Szenariogrundriss|Tapaukset|Tapaus|Tapausaihio|Taust|Tausta|Template Keadaan|Template Senario|Template Situai|The thing of it is|Tình huống|Variantai|Voorbeelde|Voorbeelden|Wharrimean is|Yo\-ho\-ho|You'll wanna|Założenia|Παραδείγματα|Περιγραφή Σεναρίου|Σενάρια|Σενάριο|Υπόβαθρο|Кереш|Контекст|Концепт|Мисаллар|Мисоллар|Основа|Передумова|Позадина|Предистория|Предыстория|Приклади|Пример|Примери|Примеры|Рамка на сценарий|Скица|Структура сценарија|Структура сценария|Структура сценарію|Сценарий|Сценарий структураси|Сценарийның төзелеше|Сценарији|Сценарио|Сценарій|Тарих|Үрнәкләр|דוגמאות|רקע|תבנית תרחיש|תרחיש|الخلفية|الگوی سناریو|امثلة|پس منظر|زمینه|سناریو|سيناريو|سيناريو مخطط|مثالیں|منظر نامے کا خاکہ|منظرنامہ|نمونه ها|उदाहरण|परिदृश्य|परिदृश्य रूपरेखा|पृष्ठभूमि|ਉਦਾਹਰਨਾਂ|ਪਟਕਥਾ|ਪਟਕਥਾ ਢਾਂਚਾ|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਿਛੋਕੜ|ఉదాహరణలు|కథనం|నేపథ్యం|సన్నివేశం|ಉದಾಹರಣೆಗಳು|ಕಥಾಸಾರಾಂಶ|ವಿವರಣೆ|ಹಿನ್ನೆಲೆ|โครงสร้างของเหตุการณ์|ชุดของตัวอย่าง|ชุดของเหตุการณ์|แนวคิด|สรุปเหตุการณ์|เหตุการณ์|배경|시나리오|시나리오 개요|예|サンプル|シナリオ|シナリオアウトライン|シナリオテンプレ|シナリオテンプレート|テンプレ|例|例子|剧本|剧本大纲|劇本|劇本大綱|场景|场景大纲|場景|場景大綱|背景):[^:\r\n]*/m,
+                       lookbehind: true,
+                       inside: {
+                               'important': {
+                                       pattern: /(:)[^\r\n]*/,
+                                       lookbehind: true
+                               },
+                               'keyword': /[^:\r\n]+:/
+                       }
+               },
+               'table-body': {
+                       // Look-behind is used to skip the table head, which has the same format as any table row
+                       pattern: RegExp('(' + tableRow + ')(?:' + tableRow + ')+'),
+                       lookbehind: true,
+                       inside: {
+                               'outline': {
+                                       pattern: /<[^>]+?>/,
+                                       alias: 'variable'
+                               },
+                               'td': {
+                                       pattern: /\s*[^\s|][^|]*/,
+                                       alias: 'string'
+                               },
+                               'punctuation': /\|/
+                       }
+               },
+               'table-head': {
+                       pattern: RegExp(tableRow),
+                       inside: {
+                               'th': {
+                                       pattern: /\s*[^\s|][^|]*/,
+                                       alias: 'variable'
+                               },
+                               'punctuation': /\|/
+                       }
+               },
+               'atrule': {
+                       pattern: /(^[ \t]+)(?:'ach|'a|'ej|7|a|A také|A taktiež|A tiež|A zároveň|Aber|Ac|Adott|Akkor|Ak|Aleshores|Ale|Ali|Allora|Alors|Als|Ama|Amennyiben|Amikor|Ampak|an|AN|Ananging|And y'all|And|Angenommen|Anrhegedig a|An|Apabila|Atès|Atesa|Atunci|Avast!|Aye|A|awer|Bagi|Banjur|Bet|Biết|Blimey!|Buh|But at the end of the day I reckon|But y'all|But|BUT|Cal|Când|Cando|Cand|Ce|Cuando|Če|Ða ðe|Ða|Dadas|Dada|Dados|Dado|DaH ghu' bejlu'|dann|Dann|Dano|Dan|Dar|Dat fiind|Data|Date fiind|Date|Dati fiind|Dati|Daţi fiind|Dați fiind|Dato|DEN|Den youse gotta|Dengan|De|Diberi|Diyelim ki|Donada|Donat|Donitaĵo|Do|Dun|Duota|Ðurh|Eeldades|Ef|Eğer ki|Entao|Então|Entón|Entonces|En|Epi|E|És|Etant donnée|Etant donné|Et|Étant données|Étant donnée|Étant donné|Etant données|Etant donnés|Étant donnés|Fakat|Gangway!|Gdy|Gegeben seien|Gegeben sei|Gegeven|Gegewe|ghu' noblu'|Gitt|Given y'all|Given|Givet|Givun|Ha|Cho|I CAN HAZ|In|Ir|It's just unbelievable|I|Ja|Jeśli|Jeżeli|Kadar|Kada|Kad|Kai|Kaj|Když|Keď|Kemudian|Ketika|Khi|Kiedy|Ko|Kuid|Kui|Kun|Lan|latlh|Le sa a|Let go and haul|Le|Lè sa a|Lè|Logo|Lorsqu'<|Lorsque|mä|Maar|Mais|Mając|Majd|Maka|Manawa|Mas|Ma|Menawa|Men|Mutta|Nalikaning|Nalika|Nanging|Når|När|Nato|Nhưng|Niin|Njuk|O zaman|Og|Och|Oletetaan|Onda|Ond|Oraz|Pak|Pero|Però|Podano|Pokiaľ|Pokud|Potem|Potom|Privzeto|Pryd|qaSDI'|Quando|Quand|Quan|Så|Sed|Se|Siis|Sipoze ke|Sipoze Ke|Sipoze|Si|Şi|Și|Soit|Stel|Tada|Tad|Takrat|Tak|Tapi|Ter|Tetapi|Tha the|Tha|Then y'all|Then|Thì|Thurh|Toda|Too right|ugeholl|Und|Un|Và|vaj|Vendar|Ve|wann|Wanneer|WEN|Wenn|When y'all|When|Wtedy|Wun|Y'know|Yeah nah|Yna|Youse know like when|Youse know when youse got|Y|Za predpokladu|Za předpokladu|Zadani|Zadano|Zadan|Zadate|Zadato|Zakładając|Zaradi|Zatati|Þa þe|Þa|Þá|Þegar|Þurh|Αλλά|Δεδομένου|Και|Όταν|Τότε|А також|Агар|Але|Али|Аммо|А|Әгәр|Әйтик|Әмма|Бирок|Ва|Вә|Дадено|Дано|Допустим|Если|Задате|Задати|Задато|И|І|К тому же|Када|Кад|Когато|Когда|Коли|Ләкин|Лекин|Нәтиҗәдә|Нехай|Но|Онда|Припустимо, що|Припустимо|Пусть|Также|Та|Тогда|Тоді|То|Унда|Һәм|Якщо|אבל|אזי|אז|בהינתן|וגם|כאשר|آنگاه|اذاً|اگر|اما|اور|با فرض|بالفرض|بفرض|پھر|تب|ثم|جب|عندما|فرض کیا|لكن|لیکن|متى|هنگامی|و|अगर|और|कदा|किन्तु|चूंकि|जब|तथा|तदा|तब|परन्तु|पर|यदि|ਅਤੇ|ਜਦੋਂ|ਜਿਵੇਂ ਕਿ|ਜੇਕਰ|ਤਦ|ਪਰ|అప్పుడు|ఈ పరిస్థితిలో|కాని|చెప్పబడినది|మరియు|ಆದರೆ|ನಂತರ|ನೀಡಿದ|ಮತ್ತು|ಸ್ಥಿತಿಯನ್ನು|กำหนดให้|ดังนั้น|แต่|เมื่อ|และ|그러면<|그리고<|단<|만약<|만일<|먼저<|조건<|하지만<|かつ<|しかし<|ただし<|ならば<|もし<|並且<|但し<|但是<|假如<|假定<|假設<|假设<|前提<|同时<|同時<|并且<|当<|當<|而且<|那么<|那麼<)(?=[ \t])/m,
+                       lookbehind: true
+               },
+               'string': {
+                       pattern: /"(?:\\.|[^"\\\r\n])*"|'(?:\\.|[^'\\\r\n])*'/,
+                       inside: {
+                               'outline': {
+                                       pattern: /<[^>]+?>/,
+                                       alias: 'variable'
+                               }
+                       }
+               },
+               'outline': {
+                       pattern: /<[^>]+?>/,
+                       alias: 'variable'
                }
-       },
-       'outline': {
-               pattern: /<[^>]+?>/,
-               alias: 'variable'
-       }
-};
+       };
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
index c4ab498a7a8470fd76e4383bcbae48b1e490f18a..9d1a98c5c33317b5e0f2c26039fe8e91b2a4f7a7 100644 (file)
@@ -1,18 +1,6 @@
-define(["prism/prism","prism/components/prism-clike"], function () {
-Prism.languages.glsl = Prism.languages.extend('clike', {
-       'comment': [
-               /\/\*[\s\S]*?\*\//,
-               /\/\/(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/
-       ],
-       'number': /(?:\b0x[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ulf]*/i,
+define(["prism/prism","prism/components/prism-c"], function () {
+Prism.languages.glsl = Prism.languages.extend('c', {
        'keyword': /\b(?:attribute|const|uniform|varying|buffer|shared|coherent|volatile|restrict|readonly|writeonly|atomic_uint|layout|centroid|flat|smooth|noperspective|patch|sample|break|continue|do|for|while|switch|case|default|if|else|subroutine|in|out|inout|float|double|int|void|bool|true|false|invariant|precise|discard|return|d?mat[234](?:x[234])?|[ibdu]?vec[234]|uint|lowp|mediump|highp|precision|[iu]?sampler[123]D|[iu]?samplerCube|sampler[12]DShadow|samplerCubeShadow|[iu]?sampler[12]DArray|sampler[12]DArrayShadow|[iu]?sampler2DRect|sampler2DRectShadow|[iu]?samplerBuffer|[iu]?sampler2DMS(?:Array)?|[iu]?samplerCubeArray|samplerCubeArrayShadow|[iu]?image[123]D|[iu]?image2DRect|[iu]?imageCube|[iu]?imageBuffer|[iu]?image[12]DArray|[iu]?imageCubeArray|[iu]?image2DMS(?:Array)?|struct|common|partition|active|asm|class|union|enum|typedef|template|this|resource|goto|inline|noinline|public|static|extern|external|interface|long|short|half|fixed|unsigned|superp|input|output|hvec[234]|fvec[234]|sampler3DRect|filter|sizeof|cast|namespace|using)\b/
 });
 
-Prism.languages.insertBefore('glsl', 'comment', {
-       'preprocessor': {
-               pattern: /(^[ \t]*)#(?:(?:define|undef|if|ifdef|ifndef|else|elif|endif|error|pragma|extension|version|line)\b)?/m,
-               lookbehind: true,
-               alias: 'builtin'
-       }
-});
 return Prism; })
\ No newline at end of file
index f41a525dea20fedd287be919a12c52800aea1300..0d18b48b70f0a17371f2e5847aa038b1521c5d4b 100644 (file)
@@ -3,8 +3,8 @@ Prism.languages.gamemakerlanguage = Prism.languages.gml = Prism.languages.extend
        'number': /(?:\b0x[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ulf]*/i,
        'keyword': /\b(?:if|else|switch|case|default|break|for|repeat|while|do|until|continue|exit|return|globalvar|var|enum)\b/,
        'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not|with|at|xor|not)\b/,
-       'constant': /\b(self|other|all|noone|global|local|undefined|pointer_(?:invalid|null)|action_(?:stop|restart|continue|reverse)|pi|GM_build_date|GM_version|timezone_(?:local|utc)|gamespeed_(?:fps|microseconds)|ev_(?:create|destroy|step|alarm|keyboard|mouse|collision|other|draw|draw_(?:begin|end|pre|post)|keypress|keyrelease|trigger|(?:left|right|middle|no)_button|(?:left|right|middle)_press|(?:left|right|middle)_release|mouse_(?:enter|leave|wheel_up|wheel_down)|global_(?:left|right|middle)_button|global_(?:left|right|middle)_press|global_(?:left|right|middle)_release|joystick(?:1|2)_(?:left|right|up|down|button1|button2|button3|button4|button5|button6|button7|button8)|outside|boundary|game_start|game_end|room_start|room_end|no_more_lives|animation_end|end_of_path|no_more_health|user\d|step_(?:normal|begin|end)|gui|gui_begin|gui_end)|vk_(?:nokey|anykey|enter|return|shift|control|alt|escape|space|backspace|tab|pause|printscreen|left|right|up|down|home|end|delete|insert|pageup|pagedown|f\d|numpad\d|divide|multiply|subtract|add|decimal|lshift|lcontrol|lalt|rshift|rcontrol|ralt)|mb_(?:any|none|left|right|middle)|c_(?:aqua|black|blue|dkgray|fuchsia|gray|green|lime|ltgray|maroon|navy|olive|purple|red|silver|teal|white|yellow|orange)|fa_(?:left|center|right|top|middle|bottom|readonly|hidden|sysfile|volumeid|directory|archive)|pr_(?:pointlist|linelist|linestrip|trianglelist|trianglestrip|trianglefan)|bm_(?:complex|normal|add|max|subtract|zero|one|src_colour|inv_src_colour|src_color|inv_src_color|src_alpha|inv_src_alpha|dest_alpha|inv_dest_alpha|dest_colour|inv_dest_colour|dest_color|inv_dest_color|src_alpha_sat)|audio_(?:falloff_(?:none|inverse_distance|inverse_distance_clamped|linear_distance|linear_distance_clamped|exponent_distance|exponent_distance_clamped)|old_system|new_system|mono|stereo|3d)|cr_(?:default|none|arrow|cross|beam|size_nesw|size_ns|size_nwse|size_we|uparrow|hourglass|drag|appstart|handpoint|size_all)|spritespeed_framesper(?:second|gameframe)|asset_(?:object|unknown|sprite|sound|room|path|script|font|timeline|tiles|shader)|ds_type_(?:map|list|stack|queue|grid|priority)|ef_(?:explosion|ring|ellipse|firework|smoke|smokeup|star|spark|flare|cloud|rain|snow)|pt_shape_(?:pixel|disk|square|line|star|circle|ring|sphere|flare|spark|explosion|cloud|smoke|snow)|ps_(?:distr|shape)_(?:linear|gaussian|invgaussian|rectangle|ellipse|diamond|line)|ty_(?:real|string)|dll_(?:cdel|cdecl|stdcall)|matrix_(?:view|projection|world)|os_(?:win32|windows|macosx|ios|android|linux|unknown|winphone|win8native|psvita|ps4|xboxone|ps3|uwp)|browser_(?:not_a_browser|unknown|ie|firefox|chrome|safari|safari_mobile|opera|tizen|windows_store|ie_mobile)|device_ios_(?:unknown|iphone|iphone_retina|ipad|ipad_retina|iphone5|iphone6|iphone6plus)|device_(?:emulator|tablet)|display_(?:landscape|landscape_flipped|portrait|portrait_flipped)|of_challenge_(?:win|lose|tie)|leaderboard_type_(?:number|time_mins_secs)|cmpfunc_(?:never|less|equal|lessequal|greater|notequal|greaterequal|always)|cull_(?:noculling|clockwise|counterclockwise)|lighttype_(?:dir|point)|iap_(?:ev_storeload|ev_product|ev_purchase|ev_consume|ev_restore|storeload_ok|storeload_failed|status_uninitialised|status_unavailable|status_loading|status_available|status_processing|status_restoring|failed|unavailable|available|purchased|canceled|refunded)|fb_login_(?:default|fallback_to_webview|no_fallback_to_webview|forcing_webview|use_system_account|forcing_safari)|phy_joint_(?:anchor_1_x|anchor_1_y|anchor_2_x|anchor_2_y|reaction_force_x|reaction_force_y|reaction_torque|motor_speed|angle|motor_torque|max_motor_torque|translation|speed|motor_force|max_motor_force|length_1|length_2|damping_ratio|frequency|lower_angle_limit|upper_angle_limit|angle_limits|max_length|max_torque|max_force)|phy_debug_render_(?:aabb|collision_pairs|coms|core_shapes|joints|obb|shapes)|phy_particle_flag_(?:water|zombie|wall|spring|elastic|viscous|powder|tensile|colourmixing|colormixing)|phy_particle_group_flag_(?:solid|rigid)|phy_particle_data_flag_(?:typeflags|position|velocity|colour|color|category)|achievement_(?:our_info|friends_info|leaderboard_info|info|filter_(?:all_players|friends_only|favorites_only)|type_challenge|type_score_challenge|pic_loaded|show_(?:ui|profile|leaderboard|achievement|bank|friend_picker|purchase_prompt))|network_(?:socket_(?:tcp|udp|bluetooth)|type_(?:connect|disconnect|data|non_blocking_connect)|config_(?:connect_timeout|use_non_blocking_socket|enable_reliable_udp|disable_reliable_udp))|buffer_(?:fixed|grow|wrap|fast|vbuffer|network|u8|s8|u16|s16|u32|s32|u64|f16|f32|f64|bool|text|string|seek_start|seek_relative|seek_end|generalerror|outofspace|outofbounds|invalidtype)|gp_(?:face\d|shoulderl|shoulderr|shoulderlb|shoulderrb|select|start|stickl|stickr|padu|padd|padl|padr|axislh|axislv|axisrh|axisrv)|ov_(?:friends|community|players|settings|gamegroup|achievements)|lb_sort_(?:none|ascending|descending)|lb_disp_(?:none|numeric|time_sec|time_ms)|ugc_(?:result_success|filetype_(?:community|microtrans)|visibility_(?:public|friends_only|private)|query_RankedBy(?:Vote|PublicationDate|Trend|NumTimesReported|TotalVotesAsc|VotesUp|TextSearch)|query_(?:AcceptedForGameRankedByAcceptanceDate|FavoritedByFriendsRankedByPublicationDate|CreatedByFriendsRankedByPublicationDate|NotYetRated)|sortorder_CreationOrder(?:Desc|Asc)|sortorder_(?:TitleAsc|LastUpdatedDesc|SubscriptionDateDesc|VoteScoreDesc|ForModeration)|list_(?:Published|VotedOn|VotedUp|VotedDown|WillVoteLater|Favorited|Subscribed|UsedOrPlayed|Followed)|match_(?:Items|Items_Mtx|Items_ReadyToUse|Collections|Artwork|Videos|Screenshots|AllGuides|WebGuides|IntegratedGuides|UsableInGame|ControllerBindings))|vertex_usage_(?:position|colour|color|normal|texcoord|textcoord|blendweight|blendindices|psize|tangent|binormal|fog|depth|sample)|vertex_type_(?:float\d|colour|color|ubyte4)|layerelementtype_(?:undefined|background|instance|oldtilemap|sprite|tilemap|particlesystem|tile)|tile_(?:rotate|flip|mirror|index_mask)|input_type|se_(?:chorus|compressor|echo|equalizer|flanger|gargle|none|reverb)|text_type|(obj|scr|spr|rm)\w+)\b/,
-       'variable': /\b(x|y|(?:x|y)(?:previous|start)|(?:h|v)speed|direction|speed|friction|gravity|gravity_direction|path_(?:index|position|positionprevious|speed|scale|orientation|endaction)|object_index|id|solid|persistent|mask_index|instance_(?:count|id)|alarm|timeline_(?:index|position|speed|running|loop)|visible|sprite_(?:index|width|height|xoffset|yoffset)|image_(?:number|index|speed|depth|xscale|yscale|angle|alpha|blend)|bbox_(?:left|right|top|bottom)|layer|phy_(?:rotation|(?:position|linear_velocity|speed|com|collision|col_normal)_(?:x|y)|angular_(?:velocity|damping)|position_(?:x|y)previous|speed|linear_damping|bullet|fixed_rotation|active|mass|inertia|dynamic|kinematic|sleeping|collision_points)|working_directory|webgl_enabled|view_(?:(?:y|x|w|h)view|(?:y|x|w|h)port|(?:v|h)(?:speed|border)|visible|surface_id|object|enabled|current|angle)|undefined|transition_(?:steps|kind|color)|temp_directory|show_(?:score|lives|health)|secure_mode|score|room_(?:width|speed|persistent|last|height|first|caption)|room|pointer_(?:null|invalid)|os_(?:version|type|device|browser)|mouse_(?:y|x|lastbutton|button)|lives|keyboard_(?:string|lastkey|lastchar|key)|iap_data|health|gamemaker_(?:version|registered|pro)|game_(?:save|project|display)_(?:id|name)|fps_real|fps|event_(?:type|object|number|action)|error_(?:occurred|last)|display_aa|delta_time|debug_mode|cursor_sprite|current_(?:year|weekday|time|second|month|minute|hour|day)|caption_(?:score|lives|health)|browser_(?:width|height)|background_(?:yscale|y|xscale|x|width|vtiled|vspeed|visible|showcolour|showcolor|index|htiled|hspeed|height|foreground|colour|color|blend|alpha)|async_load|application_surface|argument(?:_relitive|_count|\d)|argument|global|local|self|other)\b/
+       'constant': /\b(?:self|other|all|noone|global|local|undefined|pointer_(?:invalid|null)|action_(?:stop|restart|continue|reverse)|pi|GM_build_date|GM_version|timezone_(?:local|utc)|gamespeed_(?:fps|microseconds)|ev_(?:create|destroy|step|alarm|keyboard|mouse|collision|other|draw|draw_(?:begin|end|pre|post)|keypress|keyrelease|trigger|(?:left|right|middle|no)_button|(?:left|right|middle)_press|(?:left|right|middle)_release|mouse_(?:enter|leave|wheel_up|wheel_down)|global_(?:left|right|middle)_button|global_(?:left|right|middle)_press|global_(?:left|right|middle)_release|joystick(?:1|2)_(?:left|right|up|down|button1|button2|button3|button4|button5|button6|button7|button8)|outside|boundary|game_start|game_end|room_start|room_end|no_more_lives|animation_end|end_of_path|no_more_health|user\d|step_(?:normal|begin|end)|gui|gui_begin|gui_end)|vk_(?:nokey|anykey|enter|return|shift|control|alt|escape|space|backspace|tab|pause|printscreen|left|right|up|down|home|end|delete|insert|pageup|pagedown|f\d|numpad\d|divide|multiply|subtract|add|decimal|lshift|lcontrol|lalt|rshift|rcontrol|ralt)|mb_(?:any|none|left|right|middle)|c_(?:aqua|black|blue|dkgray|fuchsia|gray|green|lime|ltgray|maroon|navy|olive|purple|red|silver|teal|white|yellow|orange)|fa_(?:left|center|right|top|middle|bottom|readonly|hidden|sysfile|volumeid|directory|archive)|pr_(?:pointlist|linelist|linestrip|trianglelist|trianglestrip|trianglefan)|bm_(?:complex|normal|add|max|subtract|zero|one|src_colour|inv_src_colour|src_color|inv_src_color|src_alpha|inv_src_alpha|dest_alpha|inv_dest_alpha|dest_colour|inv_dest_colour|dest_color|inv_dest_color|src_alpha_sat)|audio_(?:falloff_(?:none|inverse_distance|inverse_distance_clamped|linear_distance|linear_distance_clamped|exponent_distance|exponent_distance_clamped)|old_system|new_system|mono|stereo|3d)|cr_(?:default|none|arrow|cross|beam|size_nesw|size_ns|size_nwse|size_we|uparrow|hourglass|drag|appstart|handpoint|size_all)|spritespeed_framesper(?:second|gameframe)|asset_(?:object|unknown|sprite|sound|room|path|script|font|timeline|tiles|shader)|ds_type_(?:map|list|stack|queue|grid|priority)|ef_(?:explosion|ring|ellipse|firework|smoke|smokeup|star|spark|flare|cloud|rain|snow)|pt_shape_(?:pixel|disk|square|line|star|circle|ring|sphere|flare|spark|explosion|cloud|smoke|snow)|ps_(?:distr|shape)_(?:linear|gaussian|invgaussian|rectangle|ellipse|diamond|line)|ty_(?:real|string)|dll_(?:cdel|cdecl|stdcall)|matrix_(?:view|projection|world)|os_(?:win32|windows|macosx|ios|android|linux|unknown|winphone|win8native|psvita|ps4|xboxone|ps3|uwp)|browser_(?:not_a_browser|unknown|ie|firefox|chrome|safari|safari_mobile|opera|tizen|windows_store|ie_mobile)|device_ios_(?:unknown|iphone|iphone_retina|ipad|ipad_retina|iphone5|iphone6|iphone6plus)|device_(?:emulator|tablet)|display_(?:landscape|landscape_flipped|portrait|portrait_flipped)|of_challenge_(?:win|lose|tie)|leaderboard_type_(?:number|time_mins_secs)|cmpfunc_(?:never|less|equal|lessequal|greater|notequal|greaterequal|always)|cull_(?:noculling|clockwise|counterclockwise)|lighttype_(?:dir|point)|iap_(?:ev_storeload|ev_product|ev_purchase|ev_consume|ev_restore|storeload_ok|storeload_failed|status_uninitialised|status_unavailable|status_loading|status_available|status_processing|status_restoring|failed|unavailable|available|purchased|canceled|refunded)|fb_login_(?:default|fallback_to_webview|no_fallback_to_webview|forcing_webview|use_system_account|forcing_safari)|phy_joint_(?:anchor_1_x|anchor_1_y|anchor_2_x|anchor_2_y|reaction_force_x|reaction_force_y|reaction_torque|motor_speed|angle|motor_torque|max_motor_torque|translation|speed|motor_force|max_motor_force|length_1|length_2|damping_ratio|frequency|lower_angle_limit|upper_angle_limit|angle_limits|max_length|max_torque|max_force)|phy_debug_render_(?:aabb|collision_pairs|coms|core_shapes|joints|obb|shapes)|phy_particle_flag_(?:water|zombie|wall|spring|elastic|viscous|powder|tensile|colourmixing|colormixing)|phy_particle_group_flag_(?:solid|rigid)|phy_particle_data_flag_(?:typeflags|position|velocity|colour|color|category)|achievement_(?:our_info|friends_info|leaderboard_info|info|filter_(?:all_players|friends_only|favorites_only)|type_challenge|type_score_challenge|pic_loaded|show_(?:ui|profile|leaderboard|achievement|bank|friend_picker|purchase_prompt))|network_(?:socket_(?:tcp|udp|bluetooth)|type_(?:connect|disconnect|data|non_blocking_connect)|config_(?:connect_timeout|use_non_blocking_socket|enable_reliable_udp|disable_reliable_udp))|buffer_(?:fixed|grow|wrap|fast|vbuffer|network|u8|s8|u16|s16|u32|s32|u64|f16|f32|f64|bool|text|string|seek_start|seek_relative|seek_end|generalerror|outofspace|outofbounds|invalidtype)|gp_(?:face\d|shoulderl|shoulderr|shoulderlb|shoulderrb|select|start|stickl|stickr|padu|padd|padl|padr|axislh|axislv|axisrh|axisrv)|ov_(?:friends|community|players|settings|gamegroup|achievements)|lb_sort_(?:none|ascending|descending)|lb_disp_(?:none|numeric|time_sec|time_ms)|ugc_(?:result_success|filetype_(?:community|microtrans)|visibility_(?:public|friends_only|private)|query_RankedBy(?:Vote|PublicationDate|Trend|NumTimesReported|TotalVotesAsc|VotesUp|TextSearch)|query_(?:AcceptedForGameRankedByAcceptanceDate|FavoritedByFriendsRankedByPublicationDate|CreatedByFriendsRankedByPublicationDate|NotYetRated)|sortorder_CreationOrder(?:Desc|Asc)|sortorder_(?:TitleAsc|LastUpdatedDesc|SubscriptionDateDesc|VoteScoreDesc|ForModeration)|list_(?:Published|VotedOn|VotedUp|VotedDown|WillVoteLater|Favorited|Subscribed|UsedOrPlayed|Followed)|match_(?:Items|Items_Mtx|Items_ReadyToUse|Collections|Artwork|Videos|Screenshots|AllGuides|WebGuides|IntegratedGuides|UsableInGame|ControllerBindings))|vertex_usage_(?:position|colour|color|normal|texcoord|textcoord|blendweight|blendindices|psize|tangent|binormal|fog|depth|sample)|vertex_type_(?:float\d|colour|color|ubyte4)|layerelementtype_(?:undefined|background|instance|oldtilemap|sprite|tilemap|particlesystem|tile)|tile_(?:rotate|flip|mirror|index_mask)|input_type|se_(?:chorus|compressor|echo|equalizer|flanger|gargle|none|reverb)|text_type|(?:obj|scr|spr|rm)\w+)\b/,
+       'variable': /\b(?:x|y|(?:x|y)(?:previous|start)|(?:h|v)speed|direction|speed|friction|gravity|gravity_direction|path_(?:index|position|positionprevious|speed|scale|orientation|endaction)|object_index|id|solid|persistent|mask_index|instance_(?:count|id)|alarm|timeline_(?:index|position|speed|running|loop)|visible|sprite_(?:index|width|height|xoffset|yoffset)|image_(?:number|index|speed|depth|xscale|yscale|angle|alpha|blend)|bbox_(?:left|right|top|bottom)|layer|phy_(?:rotation|(?:position|linear_velocity|speed|com|collision|col_normal)_(?:x|y)|angular_(?:velocity|damping)|position_(?:x|y)previous|speed|linear_damping|bullet|fixed_rotation|active|mass|inertia|dynamic|kinematic|sleeping|collision_points)|working_directory|webgl_enabled|view_(?:(?:y|x|w|h)view|(?:y|x|w|h)port|(?:v|h)(?:speed|border)|visible|surface_id|object|enabled|current|angle)|undefined|transition_(?:steps|kind|color)|temp_directory|show_(?:score|lives|health)|secure_mode|score|room_(?:width|speed|persistent|last|height|first|caption)|room|pointer_(?:null|invalid)|os_(?:version|type|device|browser)|mouse_(?:y|x|lastbutton|button)|lives|keyboard_(?:string|lastkey|lastchar|key)|iap_data|health|gamemaker_(?:version|registered|pro)|game_(?:save|project|display)_(?:id|name)|fps_real|fps|event_(?:type|object|number|action)|error_(?:occurred|last)|display_aa|delta_time|debug_mode|cursor_sprite|current_(?:year|weekday|time|second|month|minute|hour|day)|caption_(?:score|lives|health)|browser_(?:width|height)|background_(?:yscale|y|xscale|x|width|vtiled|vspeed|visible|showcolour|showcolor|index|htiled|hspeed|height|foreground|colour|color|blend|alpha)|async_load|application_surface|argument(?:_relitive|_count|\d)|argument|global|local|self|other)\b/
 });
 
 return Prism; })
\ No newline at end of file
index d73092341237f907e4b570958c25da2002705e8e..fc484854829824b7be0768f8828f233c06b750b7 100644 (file)
@@ -6,7 +6,7 @@ Prism.languages.go = Prism.languages.extend('clike', {
        'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
        'number': /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
        'string': {
-               pattern: /(["'`])(\\[\s\S]|(?!\1)[^\\])*\1/,
+               pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
                greedy: true
        }
 });
index 3e498c1d479c8b2c453992de0ae4e17dd1b16cc6..6cfee876726b7d8b425b57ea3793d26b22d7140d 100644 (file)
@@ -1,8 +1,20 @@
 define(["prism/prism"], function () {
 Prism.languages.graphql = {
        'comment': /#.*/,
+       'description': {
+               pattern: /(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,
+               greedy: true,
+               alias: 'string',
+               inside: {
+                       'language-markdown': {
+                               pattern: /(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,
+                               lookbehind: true,
+                               inside: Prism.languages.markdown
+                       }
+               }
+       },
        'string': {
-               pattern: /"(?:\\.|[^\\"\r\n])*"/,
+               pattern: /"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,
                greedy: true
        },
        'number': /(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,
@@ -17,7 +29,7 @@ Prism.languages.graphql = {
                greedy: true
        },
        'class-name': {
-               pattern: /(\b(?:enum|implements|interface|on|scalar|type|union)\s+)[a-zA-Z_]\w*/,
+               pattern: /(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*)[a-zA-Z_]\w*/,
                lookbehind: true
        },
        'fragment': {
@@ -25,8 +37,8 @@ Prism.languages.graphql = {
                lookbehind: true,
                alias: 'function'
        },
-       'keyword': /\b(?:enum|fragment|implements|input|interface|mutation|on|query|scalar|schema|type|union)\b/,
-       'operator': /[!=|]|\.{3}/,
+       'keyword': /\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,
+       'operator': /[!=|&]|\.{3}/,
        'punctuation': /[!(){}\[\]:=,]/,
        'constant': /\b(?!ID\b)[A-Z][A-Z_\d]*\b/
 };
index 97bfb6e3a4162e3c81b552a42942cf7bf3e19f25..87ee716850854e9266828fa1e83254032021563d 100644 (file)
@@ -1,22 +1,25 @@
 define(["prism/prism","prism/components/prism-clike"], function () {
 Prism.languages.groovy = Prism.languages.extend('clike', {
-       'keyword': /\b(?:as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,
        'string': [
                {
-                       pattern: /("""|''')[\s\S]*?\1|(?:\$\/)(?:\$\/\$|[\s\S])*?\/\$/,
+                       // https://groovy-lang.org/syntax.html#_dollar_slashy_string
+                       pattern: /("""|''')(?:[^\\]|\\[\s\S])*?\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,
                        greedy: true
                },
                {
-                       pattern: /(["'\/])(?:\\.|(?!\1)[^\\\r\n])*\1/,
+                       // TODO: Slash strings (e.g. /foo/) can contain line breaks but this will cause a lot of trouble with
+                       // simple division (see JS regex), so find a fix maybe?
+                       pattern: /(["'/])(?:\\.|(?!\1)[^\\\r\n])*\1/,
                        greedy: true
                }
        ],
+       'keyword': /\b(?:as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,
        'number': /\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?[\d]+)?)[glidf]?\b/i,
        'operator': {
-               pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.{1,2}(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
+               pattern: /(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,
                lookbehind: true
        },
-       'punctuation': /\.+|[{}[\];(),:$]/
+       'punctuation': /\.+|[{}[\];(),.:$]/
 });
 
 Prism.languages.insertBefore('groovy', 'string', {
@@ -32,9 +35,9 @@ Prism.languages.insertBefore('groovy', 'punctuation', {
 
 Prism.languages.insertBefore('groovy', 'function', {
        'annotation': {
-               alias: 'punctuation',
                pattern: /(^|[^.])@\w+/,
-               lookbehind: true
+               lookbehind: true,
+               alias: 'punctuation'
        }
 });
 
index d1930d9ea780177b08ca01d5cc22ea5af055ae9b..99fc85df10124d6ce3dc9e8a53ca04584e31946e 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css","prism/components/prism-coffeescript","prism/components/prism-erb","prism/components/prism-javascript","prism/components/prism-less","prism/components/prism-markdown","prism/components/prism-ruby","prism/components/prism-scss","prism/components/prism-textile"], function () {
+define(["prism/prism","prism/components/prism-ruby"], function () {
 /* TODO
        Handle multiline code after tag
            %foo= some |
@@ -21,16 +21,12 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
                        {
                                pattern: /((?:^|\r?\n|\r)([\t ]*)(?:[~-]|[&!]?=)).*,[\t ]*(?:(?:\r?\n|\r)\2[\t ]+.*,[\t ]*)*(?:(?:\r?\n|\r)\2[\t ]+.+)/,
                                lookbehind: true,
-                               inside: {
-                                       rest: Prism.languages.ruby
-                               }
+                               inside: Prism.languages.ruby
                        },
                        {
                                pattern: /((?:^|\r?\n|\r)([\t ]*)(?:[~-]|[&!]?=)).*\|[\t ]*(?:(?:\r?\n|\r)\2[\t ]+.*\|[\t ]*)*/,
                                lookbehind: true,
-                               inside: {
-                                       rest: Prism.languages.ruby
-                               }
+                               inside: Prism.languages.ruby
                        }
                ],
 
@@ -49,9 +45,7 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
                'markup': {
                        pattern: /((?:^|\r?\n|\r)[\t ]*)<.+/,
                        lookbehind: true,
-                       inside: {
-                               rest: Prism.languages.markup
-                       }
+                       inside: Prism.languages.markup
                },
                'doctype': {
                        pattern: /((?:^|\r?\n|\r)[\t ]*)!!!(?: .+)?/,
@@ -68,9 +62,7 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
                                                // Allows for one nested group of braces
                                                pattern: /(^|[^#])\{(?:\{[^}]+\}|[^}])+\}/,
                                                lookbehind: true,
-                                               inside: {
-                                                       rest: Prism.languages.ruby
-                                               }
+                                               inside: Prism.languages.ruby
                                        },
                                        {
                                                pattern: /\([^)]+\)/,
@@ -85,9 +77,7 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
                                        },
                                        {
                                                pattern: /\[[^\]]+\]/,
-                                               inside: {
-                                                       rest: Prism.languages.ruby
-                                               }
+                                               inside: Prism.languages.ruby
                                        }
                                ],
                                'punctuation': /[<>]/
@@ -96,9 +86,7 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
                'code': {
                        pattern: /((?:^|\r?\n|\r)[\t ]*(?:[~-]|[&!]?=)).+/,
                        lookbehind: true,
-                       inside: {
-                               rest: Prism.languages.ruby
-                       }
+                       inside: Prism.languages.ruby
                },
                // Interpolations in plain text
                'interpolation': {
@@ -137,7 +125,7 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
                filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
                if (Prism.languages[filter.language]) {
                        all_filters['filter-' + filter.filter] = {
-                               pattern: RegExp(filter_pattern.replace('{{filter_name}}', filter.filter)),
+                               pattern: RegExp(filter_pattern.replace('{{filter_name}}', function () { return filter.filter; })),
                                lookbehind: true,
                                inside: {
                                        'filter-name': {
@@ -153,4 +141,5 @@ define(["prism/prism","prism/components/prism-ruby","prism/components/prism-css"
        Prism.languages.insertBefore('haml', 'filter', all_filters);
 
 }(Prism));
+
 return Prism; })
\ No newline at end of file
index 938232c1bd23ade900f8adcc80862688782fe039..03efb1427d33b2684639d6b36e82b3c8811877d3 100644 (file)
@@ -22,8 +22,8 @@ define(["prism/prism","prism/components/prism-markup-templating"], function () {
                                variable: /[\s\S]+/
                        }
                },
-               'punctuation': /[!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]/,
-               'variable': /[^!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~\s]+/
+               'punctuation': /[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,
+               'variable': /[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/
        };
 
        Prism.hooks.add('before-tokenize', function(env) {
index 83192713d905643f8da19eec64659db6c067124d..41b7840a1149f08b5e8997d0b259e9bcc588240c 100644 (file)
@@ -29,7 +29,7 @@ Prism.languages.haskell = {
        // It may also be a separator between a module name and an identifier => no
        // operator. If it comes together with other special characters it is an
        // operator too.
-       'operator': /\s\.\s|[-!#$%*+=?&@|~.:<>^\\\/]*\.[-!#$%*+=?&@|~.:<>^\\\/]+|[-!#$%*+=?&@|~.:<>^\\\/]+\.[-!#$%*+=?&@|~.:<>^\\\/]*|[-!#$%*+=?&@|~:<>^\\\/]+|`([A-Z][\w']*\.)*[_a-z][\w']*`/,
+       'operator': /\s\.\s|[-!#$%*+=?&@|~.:<>^\\\/]*\.[-!#$%*+=?&@|~.:<>^\\\/]+|[-!#$%*+=?&@|~.:<>^\\\/]+\.[-!#$%*+=?&@|~.:<>^\\\/]*|[-!#$%*+=?&@|~:<>^\\\/]+|`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/,
        // In Haskell, nearly everything is a variable, do not highlight these.
        'hvariable': /\b(?:[A-Z][\w']*\.)*[_a-z][\w']*\b/,
        'constant': /\b(?:[A-Z][\w']*\.)*[A-Z][\w']*\b/,
@@ -37,4 +37,5 @@ Prism.languages.haskell = {
 };
 
 Prism.languages.hs = Prism.languages.haskell;
+
 return Prism; })
\ No newline at end of file
index 3e7ab0a4786ff9862797b858d67fcd044913e111..4412040e0763266c9b557b0933411260dc4b1479 100644 (file)
@@ -27,9 +27,7 @@ Prism.languages.hcl = {
                                }
                        }
                },
-               {
-                       pattern: /[\w-]+(?=\s+{)/
-               }
+               /[\w-]+(?=\s+{)/
        ],
        'property': [
                /[\w-\.]+(?=\s*=(?!=))/,
@@ -54,13 +52,13 @@ Prism.languages.hcl = {
                                                pattern: /"(?:\\[\s\S]|[^\\"])*"/,
                                                greedy: true,
                                        },
-                                       'number': /\b0x[\da-f]+|\d+\.?\d*(?:e[+-]?\d+)?/i,
+                                       'number': /\b0x[\da-f]+\b|\b\d+\.?\d*(?:e[+-]?\d+)?/i,
                                        'punctuation': /[!\$#%&'()*+,.\/;<=>@\[\\\]^`{|}~?:]/,
                                }
                        },
                }
        },
-       'number': /\b0x[\da-f]+|\d+\.?\d*(?:e[+-]?\d+)?/i,
+       'number': /\b0x[\da-f]+\b|\b\d+\.?\d*(?:e[+-]?\d+)?/i,
        'boolean': /\b(?:true|false)\b/i,
        'punctuation': /[=\[\]{}]/,
 };
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-hlsl.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-hlsl.js
new file mode 100644 (file)
index 0000000..91072b0
--- /dev/null
@@ -0,0 +1,23 @@
+define(["prism/prism","prism/components/prism-c"], function () {
+Prism.languages.hlsl = Prism.languages.extend('c', {
+
+       // Regarding keywords and class names:
+       // The list of all keywords was split into 'keyword' and 'class-name' tokens based on whether they are capitalized.
+       // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-keywords
+       // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-reserved-words
+       'class-name': [
+               Prism.languages.c['class-name'],
+               /\b(?:AppendStructuredBuffer|BlendState|Buffer|ByteAddressBuffer|CompileShader|ComputeShader|ConsumeStructuredBuffer|DepthStencilState|DepthStencilView|DomainShader|GeometryShader|Hullshader|InputPatch|LineStream|OutputPatch|PixelShader|PointStream|RasterizerState|RenderTargetView|RWBuffer|RWByteAddressBuffer|RWStructuredBuffer|RWTexture(?:1D|1DArray|2D|2DArray|3D)|SamplerComparisonState|SamplerState|StructuredBuffer|Texture(?:1D|1DArray|2D|2DArray|2DMS|2DMSArray|3D|Cube|CubeArray)|TriangleStream|VertexShader)\b/
+       ],
+       'keyword': [
+               // HLSL keyword
+               /\b(?:asm|asm_fragment|auto|break|case|catch|cbuffer|centroid|char|class|column_major|compile|compile_fragment|const|const_cast|continue|default|delete|discard|do|dynamic_cast|else|enum|explicit|export|extern|for|friend|fxgroup|goto|groupshared|if|in|inline|inout|interface|line|lineadj|linear|long|matrix|mutable|namespace|new|nointerpolation|noperspective|operator|out|packoffset|pass|pixelfragment|point|precise|private|protected|public|register|reinterpret_cast|return|row_major|sample|sampler|shared|short|signed|sizeof|snorm|stateblock|stateblock_state|static|static_cast|string|struct|switch|tbuffer|technique|technique10|technique11|template|texture|this|throw|triangle|triangleadj|try|typedef|typename|uniform|union|unorm|unsigned|using|vector|vertexfragment|virtual|void|volatile|while)\b/,
+               // scalar, vector, and matrix types
+               /\b(?:bool|double|dword|float|half|int|min(?:10float|12int|16(?:float|int|uint))|uint)(?:[1-4](?:x[1-4])?)?\b/
+       ],
+       // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-grammar#floating-point-numbers
+       'number': /(?:(?:\b\d+\.?\d*|\B\.\d+)(?:[eE][+-]?\d+)?|\b0x[\da-fA-F]+)[fFhHlLuU]?\b/,
+       'boolean': /\b(?:false|true)\b/
+});
+
+return Prism; })
\ No newline at end of file
index a1d34f5ae0e18c0fb637a441a114675e7a1551e8..87e21c80a16d2383ed79b04c72c8883fbf37a7c9 100644 (file)
@@ -11,11 +11,11 @@ Prism.languages.hpkp = {
                alias: 'keyword'
        },
        'safe': {
-               pattern: /\d{7,}/,
+               pattern: /\b\d{7,}\b/,
                alias: 'selector'
        },
        'unsafe': {
-               pattern: /\d{1,6}/,
+               pattern: /\b\d{1,6}\b/,
                alias: 'function'
        }
 };
index a10fe382bc382e6ea176b5274e6e0e6f425f9bca..37ddd750c2400a38def5a664a196b517537f3b94 100644 (file)
@@ -11,11 +11,11 @@ Prism.languages.hsts = {
                alias: 'keyword'
        },
        'safe': {
-               pattern: /\d{8,}/,
+               pattern: /\b\d{8,}\b/,
                alias: 'selector'
        },
        'unsafe': {
-               pattern: /\d{1,7}/,
+               pattern: /\b\d{1,7}\b/,
                alias: 'function'
        }
 };
index 8cf72c2219cea6c5c55100b8742687105d0d80c0..991ee38593f49a1113d09d8a87f29ec44be62a3b 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-javascript","prism/components/prism-markup"], function () {
+define(["prism/prism"], function () {
 (function (Prism) {
        Prism.languages.http = {
                'request-line': {
@@ -64,12 +64,10 @@ define(["prism/prism","prism/components/prism-javascript","prism/components/pris
                        options = options || {};
 
                        var pattern = suffixTypes[contentType] ? getSuffixPattern(contentType) : contentType;
-                       options[contentType] = {
+                       options[contentType.replace(/\//g, '-')] = {
                                pattern: RegExp('(content-type:\\s*' + pattern + '[\\s\\S]*?)(?:\\r?\\n|\\r){2}[\\s\\S]*', 'i'),
                                lookbehind: true,
-                               inside: {
-                                       rest: httpLanguages[contentType]
-                               }
+                               inside: httpLanguages[contentType]
                        };
                }
        }
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-iecst.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-iecst.js
new file mode 100644 (file)
index 0000000..92db120
--- /dev/null
@@ -0,0 +1,33 @@
+define(["prism/prism"], function () {
+Prism.languages.iecst = {
+       'comment': [
+               {
+                       pattern: /(^|[^\\])(?:\/\*[\s\S]*?(?:\*\/|$)|\(\*[\s\S]*?(?:\*\)|$)|\{[\s\S]*?(?:\}|$))/,
+                       lookbehind: true,
+               },
+               {
+                       pattern: /(^|[^\\:])\/\/.*/,
+                       lookbehind: true,
+                       greedy: true,
+               },
+       ],
+       'string': {
+               pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
+               greedy: true,
+       },
+       'class-name': /\b(?:END_)?(?:PROGRAM|CONFIGURATION|INTERFACE|FUNCTION_BLOCK|FUNCTION|ACTION|TRANSITION|TYPE|STRUCT|(?:INITIAL_)?STEP|NAMESPACE|LIBRARY|CHANNEL|FOLDER|RESOURCE|VAR_(?:GLOBAL|INPUT|PUTPUT|IN_OUT|ACCESS|TEMP|EXTERNAL|CONFIG)|VAR|METHOD|PROPERTY)\b/i,
+       'keyword': /\b(?:(?:END_)?(?:IF|WHILE|REPEAT|CASE|FOR)|ELSE|FROM|THEN|ELSIF|DO|TO|BY|PRIVATE|PUBLIC|PROTECTED|CONSTANT|RETURN|EXIT|CONTINUE|GOTO|JMP|AT|RETAIN|NON_RETAIN|TASK|WITH|UNTIL|USING|EXTENDS|IMPLEMENTS|GET|SET|__TRY|__CATCH|__FINALLY|__ENDTRY)\b/,
+       'variable': /\b(?:AT|BOOL|BYTE|(?:D|L)?WORD|U?(?:S|D|L)?INT|L?REAL|TIME(?:_OF_DAY)?|TOD|DT|DATE(?:_AND_TIME)?|STRING|ARRAY|ANY|POINTER)\b/,
+       'symbol': /%[IQM][XBWDL][\d.]*|%[IQ][\d.]*/,
+       'number': /\b(?:16#[\da-f]+|2#[01_]+|0x[\da-f]+)\b|\b(?:T|D|DT|TOD)#[\d_shmd:]*|\b[A-Z]*\#[\d.,_]*|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
+       'boolean': /\b(?:TRUE|FALSE|NULL)\b/,
+       'function': /\w+(?=\()/,
+       'operator': /(?:S?R?:?=>?|&&?|\*\*?|<=?|>=?|[-:^/+])|\b(?:OR|AND|MOD|NOT|XOR|LE|GE|EQ|NE|GE|LT)\b/,
+       'punctuation': /[();]/,
+       'type': {
+               'pattern': /#/,
+               'alias': 'selector',
+       },
+};
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-ignore.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-ignore.js
new file mode 100644 (file)
index 0000000..1f269a1
--- /dev/null
@@ -0,0 +1,26 @@
+define(["prism/prism"], function () {
+(function (Prism) {
+       Prism.languages.ignore = {
+               // https://git-scm.com/docs/gitignore
+               'comment': /^#.*/m,
+               'entry': {
+                       pattern: /\S(?:.*(?:(?:\\ )|\S))?/,
+                       alias: 'string',
+                       inside: {
+                               'operator': /^!|\*\*?|\?/,
+                               'regex': {
+                                       pattern: /(^|[^\\])\[[^\[\]]*\]/,
+                                       lookbehind: true
+                               },
+                               'punctuation': /\//
+                       }
+               }
+       };
+
+       Prism.languages.gitignore = Prism.languages.ignore
+       Prism.languages.hgignore = Prism.languages.ignore
+       Prism.languages.npmignore = Prism.languages.ignore
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 08dac3dcff96aff5a2607efffba62b997eae4d3f..e44c44b2573d3b5d0530c6e0cb230085be26a751 100644 (file)
@@ -27,7 +27,7 @@ Prism.languages.io = {
        'builtin':/\b(?:Array|AudioDevice|AudioMixer|Block|Box|Buffer|CFunction|CGI|Color|Curses|DBM|DNSResolver|DOConnection|DOProxy|DOServer|Date|Directory|Duration|DynLib|Error|Exception|FFT|File|Fnmatch|Font|Future|GL|GLE|GLScissor|GLU|GLUCylinder|GLUQuadric|GLUSphere|GLUT|Host|Image|Importer|LinkList|List|Lobby|Locals|MD5|MP3Decoder|MP3Encoder|Map|Message|Movie|Notification|Number|Object|OpenGL|Point|Protos|Regex|SGML|SGMLElement|SGMLParser|SQLite|Server|Sequence|ShowMessage|SleepyCat|SleepyCatCursor|Socket|SocketManager|Sound|Soup|Store|String|Tree|UDPSender|UPDReceiver|URL|User|Warning|WeakLink|Random|BigNum|Sequence)\b/,
        'boolean': /\b(?:true|false|nil)\b/,
        'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e-?\d+)?/i,
-       'operator': /[=!*/%+-^&|]=|>>?=?|<<?=?|:?:?=|\+\+?|--?|\*\*?|\/\/?|%|\|\|?|&&?|(\b(?:return|and|or|not)\b)|@@?|\?\??|\.\./,
+       'operator': /[=!*/%+\-^&|]=|>>?=?|<<?=?|:?:?=|\+\+?|--?|\*\*?|\/\/?|%|\|\|?|&&?|\b(?:return|and|or|not)\b|@@?|\?\??|\.\./,
        'punctuation': /[{}[\];(),.:]/
 };
 
index eda91e099fa3965312e18b0cc7430eda968618ca..648fed07171cdbe47251972c2c502317af8fb20d 100644 (file)
@@ -12,7 +12,7 @@ Prism.languages.j = {
                pattern: /(?!\^:|;\.|[=!][.:])(?:\{(?:\.|::?)?|p(?:\.\.?|:)|[=!\]]|[<>+*\-%$|,#][.:]?|[?^]\.?|[;\[]:?|[~}"i][.:]|[ACeEIjLor]\.|(?:[_\/\\qsux]|_?\d):)/,
                alias: 'keyword'
        },
-       'number': /\b_?(?:(?!\d:)\d+(?:\.\d+)?(?:(?:[ejpx]|ad|ar)_?\d+(?:\.\d+)?)*(?:b_?[\da-z]+(?:\.[\da-z]+)?)?|_(?!\.))/,
+       'number': /\b_?(?:(?!\d:)\d+(?:\.\d+)?(?:(?:[ejpx]|ad|ar)_?\d+(?:\.\d+)?)*(?:b_?[\da-z]+(?:\.[\da-z]+)?)?|_\b(?!\.))/,
        'adverb': {
                pattern: /[~}]|[\/\\]\.?|[bfM]\.|t[.:]/,
                alias: 'builtin'
@@ -24,4 +24,5 @@ Prism.languages.j = {
        },
        'punctuation': /[()]/
 };
+
 return Prism; })
\ No newline at end of file
index f20fad690ed29b19869ce74044f3ab8b5939ce4c..e4cba23f3eadbff0f00c259af8dc05363003f2bf 100644 (file)
@@ -1,7 +1,7 @@
 define(["prism/prism","prism/components/prism-clike"], function () {
 (function (Prism) {
 
-       var keywords = /\b(?:abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|var|null|exports|module|open|opens|provides|requires|to|transitive|uses|with)\b/;
+       var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|null|open|opens|package|private|protected|provides|public|record|requires|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/;
 
        // based on the java naming conventions
        var className = /\b[A-Z](?:\w*[a-z]\w*)?\b/;
@@ -24,11 +24,20 @@ define(["prism/prism","prism/components/prism-clike"], function () {
                ],
                'number': /\b0b[01][01_]*L?\b|\b0x[\da-f_]*\.?[\da-f_p+-]+\b|(?:\b\d[\d_]*\.?[\d_]*|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,
                'operator': {
-                       pattern: /(^|[^.])(?:<<=?|>>>?=?|->|([-+&|])\2|[?:~]|[-+*/%&|^!=<>]=?)/m,
+                       pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,
                        lookbehind: true
                }
        });
 
+       Prism.languages.insertBefore('java', 'string', {
+               'triple-quoted-string': {
+                       // http://openjdk.java.net/jeps/355#Description
+                       pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,
+                       greedy: true,
+                       alias: 'string'
+               }
+       });
+
        Prism.languages.insertBefore('java', 'class-name', {
                'annotation': {
                        alias: 'punctuation',
@@ -36,7 +45,9 @@ define(["prism/prism","prism/components/prism-clike"], function () {
                        lookbehind: true
                },
                'namespace': {
-                       pattern: /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)[a-z]\w*(\.[a-z]\w*)+/,
+                       pattern: RegExp(
+                               /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/
+                                       .source.replace(/<keyword>/g, function () { return keywords.source; })),
                        lookbehind: true,
                        inside: {
                                'punctuation': /\./,
index cfeda2fd51a2bbd7c3a1df029e15f4f327bac124..e3b5965d2936f639cd2e08922e3e32132f81975e 100644 (file)
@@ -1,54 +1,82 @@
-define(["prism/prism","prism/components/prism-markup","prism/components/prism-java","prism/components/prism-javadoclike","prism/components/prism-scala"], function () {
+define(["prism/prism","prism/components/prism-markup","prism/components/prism-java","prism/components/prism-javadoclike"], function () {
 (function (Prism) {
 
-       var codeLines = {
-               'code': {
-                       pattern: /(^(\s*(?:\*\s*)*)).*[^*\s].+$/m,
-                       lookbehind: true,
-                       inside: Prism.languages.java,
-                       alias: 'language-java'
-               }
-       };
+       var codeLinePattern = /(^(?:\s*(?:\*\s*)*)).*[^*\s].*$/m;
+
+       var memberReference = /#\s*\w+(?:\s*\([^()]*\))?/.source;
+       var reference = /(?:[a-zA-Z]\w+\s*\.\s*)*[A-Z]\w*(?:\s*<mem>)?|<mem>/.source.replace(/<mem>/g, function () { return memberReference });
 
        Prism.languages.javadoc = Prism.languages.extend('javadoclike', {});
        Prism.languages.insertBefore('javadoc', 'keyword', {
-               'class-name': [
-                       {
-                               pattern: /(@(?:exception|throws|see|link|linkplain|value)\s+(?:[a-z\d]+\.)*)[A-Z](?:\w*[a-z]\w*)?(?:\.[A-Z](?:\w*[a-z]\w*)?)*/,
-                               lookbehind: true,
-                               inside: {
-                                       'punctuation': /\./
-                               }
-                       },
-                       {
-                               // @param <T> the first generic type parameter
-                               pattern: /(@param\s+)<[A-Z]\w*>/,
-                               lookbehind: true,
-                               inside: {
-                                       'punctuation': /[.<>]/
-                               }
+               'reference': {
+                       pattern: RegExp(/(@(?:exception|throws|see|link|linkplain|value)\s+(?:\*\s*)?)/.source + '(?:' + reference + ')'),
+                       lookbehind: true,
+                       inside: {
+                               'function': {
+                                       pattern: /(#\s*)\w+(?=\s*\()/,
+                                       lookbehind: true
+                               },
+                               'field': {
+                                       pattern: /(#\s*)\w+/,
+                                       lookbehind: true
+                               },
+                               'namespace': {
+                                       pattern: /\b(?:[a-z]\w*\s*\.\s*)+/,
+                                       inside: {
+                                               'punctuation': /\./
+                                       }
+                               },
+                               'class-name': /\b[A-Z]\w*/,
+                               'keyword': Prism.languages.java.keyword,
+                               'punctuation': /[#()[\],.]/
                        }
-               ],
-               'namespace': {
-                       pattern: /(@(?:exception|throws|see|link|linkplain)\s+)(?:[a-z\d]+\.)+/,
+               },
+               'class-name': {
+                       // @param <T> the first generic type parameter
+                       pattern: /(@param\s+)<[A-Z]\w*>/,
                        lookbehind: true,
                        inside: {
-                               'punctuation': /\./
+                               'punctuation': /[.<>]/
                        }
                },
                'code-section': [
                        {
-                               pattern: /(\{@code\s+)(?:[^{}]|\{[^{}]*\})+?(?=\s*\})/,
+                               pattern: /(\{@code\s+)(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\})+?(?=\s*\})/,
                                lookbehind: true,
-                               inside: codeLines
+                               inside: {
+                                       'code': {
+                                               // there can't be any HTML inside of {@code} tags
+                                               pattern: codeLinePattern,
+                                               lookbehind: true,
+                                               inside: Prism.languages.java,
+                                               alias: 'language-java'
+                                       }
+                               }
                        },
                        {
-                               pattern: /(<(code|tt)>\s*)[\s\S]+?(?=\s*<\/\2>)/,
+                               pattern: /(<(code|pre|tt)>(?!<code>)\s*)[\s\S]+?(?=\s*<\/\2>)/,
                                lookbehind: true,
-                               inside: codeLines
+                               inside: {
+                                       'line': {
+                                               pattern: codeLinePattern,
+                                               lookbehind: true,
+                                               inside: {
+                                                       // highlight HTML tags and entities
+                                                       'tag': Prism.languages.markup.tag,
+                                                       'entity': Prism.languages.markup.entity,
+                                                       'code': {
+                                                               // everything else is Java code
+                                                               pattern: /.+/,
+                                                               inside: Prism.languages.java,
+                                                               alias: 'language-java'
+                                                       }
+                                               }
+                                       }
+                               }
                        }
                ],
                'tag': Prism.languages.markup.tag,
+               'entity': Prism.languages.markup.entity,
        });
 
        Prism.languages.javadoclike.addSupport('java', Prism.languages.javadoc);
index 5e46d4d5f3d17fb1afc218759d61af180692804c..385dab04f0a9b199a4a06ccd59c4469c262c993a 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-java","prism/components/prism-javascript","prism/components/prism-php"], function () {
+define(["prism/prism"], function () {
 (function (Prism) {
 
        var javaDocLike = Prism.languages.javadoclike = {
@@ -36,6 +36,7 @@ define(["prism/prism","prism/components/prism-java","prism/components/prism-java
                        var definition = {};
                        definition[tokenName] = {
                                pattern: /(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,
+                               lookbehind: true,
                                alias: 'comment'
                        };
 
index af00d3fc8d7027e2d0ace69f4291cb26c25d4ce6..45ff0f4299306c6e2e7e7cb70d6bccc8a485052f 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-clike","prism/components/prism-markup"], function () {
+define(["prism/prism","prism/components/prism-clike"], function () {
 Prism.languages.javascript = Prism.languages.extend('clike', {
        'class-name': [
                Prism.languages.clike['class-name'],
@@ -13,27 +13,27 @@ Prism.languages.javascript = Prism.languages.extend('clike', {
                        lookbehind: true
                },
                {
-                       pattern: /(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
+                       pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
                        lookbehind: true
                },
        ],
        'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,
        // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
-       'function': /[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
-       'operator': /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/
+       'function': /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
+       'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
 });
 
 Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/;
 
 Prism.languages.insertBefore('javascript', 'keyword', {
        'regex': {
-               pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=\s*($|[\r\n,.;})\]]))/,
+               pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
                lookbehind: true,
                greedy: true
        },
        // This must be declared before keyword because we use "function" inside the look-forward
        'function-variable': {
-               pattern: /[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
+               pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,
                alias: 'function'
        },
        'parameter': [
@@ -52,7 +52,7 @@ Prism.languages.insertBefore('javascript', 'keyword', {
                        inside: Prism.languages.javascript
                },
                {
-                       pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,
+                       pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,
                        lookbehind: true,
                        inside: Prism.languages.javascript
                }
@@ -62,11 +62,16 @@ Prism.languages.insertBefore('javascript', 'keyword', {
 
 Prism.languages.insertBefore('javascript', 'string', {
        'template-string': {
-               pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|[^\\`])*`/,
+               pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,
                greedy: true,
                inside: {
+                       'template-punctuation': {
+                               pattern: /^`|`$/,
+                               alias: 'string'
+                       },
                        'interpolation': {
-                               pattern: /\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
+                               pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,
+                               lookbehind: true,
                                inside: {
                                        'interpolation-punctuation': {
                                                pattern: /^\${|}$/,
index e1e910c7a603037725f7ee6050195e4c5f03f9f5..1cdc70bf3f7f547b33395bd5a0d7576fc3cd2721 100644 (file)
@@ -24,7 +24,7 @@ Prism.languages.insertBefore( 'jolie', 'keyword', {
                pattern: /(\bAggregates\s*:\s*)(?:\w+(?:\s+with\s+\w+)?\s*,\s*)*\w+(?:\s+with\s+\w+)?/,
                lookbehind: true,
                inside: {
-                       'withExtension': {
+                       'with-extension': {
                                pattern: /\bwith\s+\w+/,
                                inside: {
                                        'keyword' : /\bwith\b/
@@ -54,4 +54,5 @@ Prism.languages.insertBefore( 'jolie', 'keyword', {
                }
        }
 });
+
 return Prism; })
\ No newline at end of file
index 92447b5f9c1c346ab1623827672e125c4bd56133..5f672ea448646685c06df04a89922384f19e78b0 100644 (file)
@@ -2,7 +2,7 @@ define(["prism/prism"], function () {
 (function (Prism) {
 
        var interpolation = /\\\((?:[^()]|\([^()]*\))*\)/.source;
-       var string = RegExp(/"(?:[^"\r\n\\]|\\[^\r\n(]|__)*"/.source.replace(/__/g, interpolation));
+       var string = RegExp(/"(?:[^"\r\n\\]|\\[^\r\n(]|__)*"/.source.replace(/__/g, function () { return interpolation; }));
        var stringInterpolation = {
                'interpolation': {
                        pattern: RegExp(/((?:^|[^\\])(?:\\{2})*)/.source + interpolation),
@@ -38,12 +38,12 @@ define(["prism/prism"], function () {
 
                'variable': /\B\$\w+/,
                'property-literal': {
-                       pattern: /[a-z_]\w*(?=\s*:(?!:))/i,
+                       pattern: /\b[a-z_]\w*(?=\s*:(?!:))/i,
                        alias: 'property'
                },
                'keyword': /\b(?:as|break|catch|def|elif|else|end|foreach|if|import|include|label|module|modulemeta|null|reduce|then|try|while)\b/,
                'boolean': /\b(?:true|false)\b/,
-               'number': /(?:\b\d+\.|\B\.)?\d+(?:[eE][+-]?\d+)?\b/,
+               'number': /(?:\b\d+\.|\B\.)?\b\d+(?:[eE][+-]?\d+)?\b/,
 
                'operator': [
                        {
index cb08c4cac024601b55018de965302285598c6a07..0f8571aff34fd929d92267b5627fc2306e855538 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-javascript","prism/components/prism-actionscript","prism/components/prism-coffeescript","prism/components/prism-flow","prism/components/prism-n4js","prism/components/prism-typescript"], function () {
+define(["prism/prism","prism/components/prism-javascript"], function () {
 (function (Prism) {
 
        Prism.languages.insertBefore('javascript', 'function-variable', {
@@ -61,7 +61,7 @@ define(["prism/prism","prism/components/prism-javascript","prism/components/pris
 
        Prism.languages.insertBefore('javascript', 'punctuation', {
                'property-access': {
-                       pattern: /(\.\s*)[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*/,
+                       pattern: /(\.\s*)#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*/,
                        lookbehind: true
                },
                'maybe-class-name': {
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-js-templates.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-js-templates.js
new file mode 100644 (file)
index 0000000..1dc384d
--- /dev/null
@@ -0,0 +1,349 @@
+define(["prism/prism","prism/components/prism-javascript"], function () {
+(function (Prism) {
+
+       var templateString = Prism.languages.javascript['template-string'];
+
+       // see the pattern in prism-javascript.js
+       var templateLiteralPattern = templateString.pattern.source;
+       var interpolationObject = templateString.inside['interpolation'];
+       var interpolationPunctuationObject = interpolationObject.inside['interpolation-punctuation'];
+       var interpolationPattern = interpolationObject.pattern.source;
+
+
+       /**
+        * Creates a new pattern to match a template string with a special tag.
+        *
+        * This will return `undefined` if there is no grammar with the given language id.
+        *
+        * @param {string} language The language id of the embedded language. E.g. `markdown`.
+        * @param {string} tag The regex pattern to match the tag.
+        * @returns {object | undefined}
+        * @example
+        * createTemplate('css', /\bcss/.source);
+        */
+       function createTemplate(language, tag) {
+               if (!Prism.languages[language]) {
+                       return undefined;
+               }
+
+               return {
+                       pattern: RegExp('((?:' + tag + ')\\s*)' + templateLiteralPattern),
+                       lookbehind: true,
+                       greedy: true,
+                       inside: {
+                               'template-punctuation': {
+                                       pattern: /^`|`$/,
+                                       alias: 'string'
+                               },
+                               'embedded-code': {
+                                       pattern: /[\s\S]+/,
+                                       alias: language
+                               }
+                       }
+               };
+       }
+
+
+       Prism.languages.javascript['template-string'] = [
+               // styled-jsx:
+               //   css`a { color: #25F; }`
+               // styled-components:
+               //   styled.h1`color: red;`
+               createTemplate('css', /\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),
+
+               // html`<p></p>`
+               // div.innerHTML = `<p></p>`
+               createTemplate('html', /\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),
+
+               // svg`<path fill="#fff" d="M55.37 ..."/>`
+               createTemplate('svg', /\bsvg/.source),
+
+               // md`# h1`, markdown`## h2`
+               createTemplate('markdown', /\b(?:md|markdown)/.source),
+
+               // gql`...`, graphql`...`, graphql.experimental`...`
+               createTemplate('graphql', /\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),
+
+               // vanilla template string
+               templateString
+       ].filter(Boolean);
+
+
+       /**
+        * Returns a specific placeholder literal for the given language.
+        *
+        * @param {number} counter
+        * @param {string} language
+        * @returns {string}
+        */
+       function getPlaceholder(counter, language) {
+               return '___' + language.toUpperCase() + '_' + counter + '___';
+       }
+
+       /**
+        * Returns the tokens of `Prism.tokenize` but also runs the `before-tokenize` and `after-tokenize` hooks.
+        *
+        * @param {string} code
+        * @param {any} grammar
+        * @param {string} language
+        * @returns {(string|Token)[]}
+        */
+       function tokenizeWithHooks(code, grammar, language) {
+               var env = {
+                       code: code,
+                       grammar: grammar,
+                       language: language
+               };
+               Prism.hooks.run('before-tokenize', env);
+               env.tokens = Prism.tokenize(env.code, env.grammar);
+               Prism.hooks.run('after-tokenize', env);
+               return env.tokens;
+       }
+
+       /**
+        * Returns the token of the given JavaScript interpolation expression.
+        *
+        * @param {string} expression The code of the expression. E.g. `"${42}"`
+        * @returns {Token}
+        */
+       function tokenizeInterpolationExpression(expression) {
+               var tempGrammar = {};
+               tempGrammar['interpolation-punctuation'] = interpolationPunctuationObject;
+
+               /** @type {Array} */
+               var tokens = Prism.tokenize(expression, tempGrammar);
+               if (tokens.length === 3) {
+                       /**
+                        * The token array will look like this
+                        * [
+                        *     ["interpolation-punctuation", "${"]
+                        *     "..." // JavaScript expression of the interpolation
+                        *     ["interpolation-punctuation", "}"]
+                        * ]
+                        */
+
+                       var args = [1, 1];
+                       args.push.apply(args, tokenizeWithHooks(tokens[1], Prism.languages.javascript, 'javascript'));
+
+                       tokens.splice.apply(tokens, args);
+               }
+
+               return new Prism.Token('interpolation', tokens, interpolationObject.alias, expression);
+       }
+
+       /**
+        * Tokenizes the given code with support for JavaScript interpolation expressions mixed in.
+        *
+        * This function has 3 phases:
+        *
+        * 1. Replace all JavaScript interpolation expression with a placeholder.
+        *    The placeholder will have the syntax of a identify of the target language.
+        * 2. Tokenize the code with placeholders.
+        * 3. Tokenize the interpolation expressions and re-insert them into the tokenize code.
+        *    The insertion only works if a placeholder hasn't been "ripped apart" meaning that the placeholder has been
+        *    tokenized as two tokens by the grammar of the embedded language.
+        *
+        * @param {string} code
+        * @param {object} grammar
+        * @param {string} language
+        * @returns {Token}
+        */
+       function tokenizeEmbedded(code, grammar, language) {
+               // 1. First filter out all interpolations
+
+               // because they might be escaped, we need a lookbehind, so we use Prism
+               /** @type {(Token|string)[]} */
+               var _tokens = Prism.tokenize(code, {
+                       'interpolation': {
+                               pattern: RegExp(interpolationPattern),
+                               lookbehind: true
+                       }
+               });
+
+               // replace all interpolations with a placeholder which is not in the code already
+               var placeholderCounter = 0;
+               /** @type {Object<string, string>} */
+               var placeholderMap = {};
+               var embeddedCode = _tokens.map(function (token) {
+                       if (typeof token === 'string') {
+                               return token;
+                       } else {
+                               var interpolationExpression = token.content;
+
+                               var placeholder;
+                               while (code.indexOf(placeholder = getPlaceholder(placeholderCounter++, language)) !== -1) { }
+                               placeholderMap[placeholder] = interpolationExpression;
+                               return placeholder;
+                       }
+               }).join('');
+
+
+               // 2. Tokenize the embedded code
+
+               var embeddedTokens = tokenizeWithHooks(embeddedCode, grammar, language);
+
+
+               // 3. Re-insert the interpolation
+
+               var placeholders = Object.keys(placeholderMap);
+               placeholderCounter = 0;
+
+               /**
+                *
+                * @param {(Token|string)[]} tokens
+                * @returns {void}
+                */
+               function walkTokens(tokens) {
+                       for (var i = 0; i < tokens.length; i++) {
+                               if (placeholderCounter >= placeholders.length) {
+                                       return;
+                               }
+
+                               var token = tokens[i];
+
+                               if (typeof token === 'string' || typeof token.content === 'string') {
+                                       var placeholder = placeholders[placeholderCounter];
+                                       var s = typeof token === 'string' ? token : /** @type {string} */ (token.content);
+
+                                       var index = s.indexOf(placeholder);
+                                       if (index !== -1) {
+                                               ++placeholderCounter;
+
+                                               var before = s.substring(0, index);
+                                               var middle = tokenizeInterpolationExpression(placeholderMap[placeholder]);
+                                               var after = s.substring(index + placeholder.length);
+
+                                               var replacement = [];
+                                               if (before) {
+                                                       replacement.push(before);
+                                               }
+                                               replacement.push(middle);
+                                               if (after) {
+                                                       var afterTokens = [after];
+                                                       walkTokens(afterTokens);
+                                                       replacement.push.apply(replacement, afterTokens);
+                                               }
+
+                                               if (typeof token === 'string') {
+                                                       tokens.splice.apply(tokens, [i, 1].concat(replacement));
+                                                       i += replacement.length - 1;
+                                               } else {
+                                                       token.content = replacement;
+                                               }
+                                       }
+                               } else {
+                                       var content = token.content;
+                                       if (Array.isArray(content)) {
+                                               walkTokens(content);
+                                       } else {
+                                               walkTokens([content]);
+                                       }
+                               }
+                       }
+               }
+               walkTokens(embeddedTokens);
+
+               return new Prism.Token(language, embeddedTokens, 'language-' + language, code);
+       }
+
+       /**
+        * The languages for which JS templating will handle tagged template literals.
+        *
+        * JS templating isn't active for only JavaScript but also related languages like TypeScript, JSX, and TSX.
+        */
+       var supportedLanguages = {
+               'javascript': true,
+               'js': true,
+               'typescript': true,
+               'ts': true,
+               'jsx': true,
+               'tsx': true,
+       };
+       Prism.hooks.add('after-tokenize', function (env) {
+               if (!(env.language in supportedLanguages)) {
+                       return;
+               }
+
+               /**
+                * Finds and tokenizes all template strings with an embedded languages.
+                *
+                * @param {(Token | string)[]} tokens
+                * @returns {void}
+                */
+               function findTemplateStrings(tokens) {
+                       for (var i = 0, l = tokens.length; i < l; i++) {
+                               var token = tokens[i];
+
+                               if (typeof token === 'string') {
+                                       continue;
+                               }
+
+                               var content = token.content;
+                               if (!Array.isArray(content)) {
+                                       if (typeof content !== 'string') {
+                                               findTemplateStrings([content]);
+                                       }
+                                       continue;
+                               }
+
+                               if (token.type === 'template-string') {
+                                       /**
+                                        * A JavaScript template-string token will look like this:
+                                        *
+                                        * ["template-string", [
+                                        *     ["template-punctuation", "`"],
+                                        *     (
+                                        *         An array of "string" and "interpolation" tokens. This is the simple string case.
+                                        *         or
+                                        *         ["embedded-code", "..."] This is the token containing the embedded code.
+                                        *                                  It also has an alias which is the language of the embedded code.
+                                        *     ),
+                                        *     ["template-punctuation", "`"]
+                                        * ]]
+                                        */
+
+                                       var embedded = content[1];
+                                       if (content.length === 3 && typeof embedded !== 'string' && embedded.type === 'embedded-code') {
+                                               // get string content
+                                               var code = stringContent(embedded);
+
+                                               var alias = embedded.alias;
+                                               var language = Array.isArray(alias) ? alias[0] : alias;
+
+                                               var grammar = Prism.languages[language];
+                                               if (!grammar) {
+                                                       // the embedded language isn't registered.
+                                                       continue;
+                                               }
+
+                                               content[1] = tokenizeEmbedded(code, grammar, language);
+                                       }
+                               } else {
+                                       findTemplateStrings(content);
+                               }
+                       }
+               }
+
+               findTemplateStrings(env.tokens);
+       });
+
+
+       /**
+        * Returns the string content of a token or token stream.
+        *
+        * @param {string | Token | (string | Token)[]} value
+        * @returns {string}
+        */
+       function stringContent(value) {
+               if (typeof value === 'string') {
+                       return value;
+               } else if (Array.isArray(value)) {
+                       return value.map(stringContent).join('');
+               } else {
+                       return stringContent(value.content);
+               }
+       }
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 79865ce4ce3924991e88dd8f51dc6df547d82af0..f9ba19c0f0dba9157d0ea8fa2db9ca649f73e9d7 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-javascript","prism/components/prism-javadoclike","prism/components/prism-actionscript","prism/components/prism-coffeescript"], function () {
+define(["prism/prism","prism/components/prism-javascript","prism/components/prism-javadoclike","prism/components/prism-typescript"], function () {
 (function (Prism) {
 
        var javascript = Prism.languages.javascript;
@@ -41,17 +41,22 @@ define(["prism/prism","prism/components/prism-javascript","prism/components/pris
                },
                'class-name': [
                        {
-                               pattern: RegExp('(@[a-z]+\\s+)' + type),
+                               pattern: RegExp(/(@(?:augments|extends|class|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g, function () { return type; })),
                                lookbehind: true,
                                inside: {
-                                       'punctuation': /[.,:?=<>|{}()[\]]/
+                                       'punctuation': /\./
                                }
                        },
                        {
-                               pattern: /(@(?:augments|extends|class|interface|memberof!?|this)\s+)[A-Z]\w*(?:\.[A-Z]\w*)*/,
+                               pattern: RegExp('(@[a-z]+\\s+)' + type),
                                lookbehind: true,
                                inside: {
-                                       'punctuation': /\./
+                                       'string': javascript.string,
+                                       'number': javascript.number,
+                                       'boolean': javascript.boolean,
+                                       'keyword': Prism.languages.typescript.keyword,
+                                       'operator': /=>|\.\.\.|[&|?:*]/,
+                                       'punctuation': /[.,;=<>{}()[\]]/
                                }
                        }
                ],
index c2ce8f9e1564532a3d4010b6dd1b5c22b023d8ac..b69577de30ce06cdb3be730e45f5aec36c2d496d 100644 (file)
@@ -1,4 +1,5 @@
 define(["prism/prism"], function () {
+// https://www.json.org/json-en.html
 Prism.languages.json = {
        'property': {
                pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
@@ -8,8 +9,11 @@ Prism.languages.json = {
                pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
                greedy: true
        },
-       'comment': /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
-       'number': /-?\d+\.?\d*(e[+-]?\d+)?/i,
+       'comment': {
+               pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
+               greedy: true
+       },
+       'number': /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,
        'punctuation': /[{}[\],]/,
        'operator': /:/,
        'boolean': /\b(?:true|false)\b/,
@@ -19,4 +23,6 @@ Prism.languages.json = {
        }
 };
 
+Prism.languages.webmanifest = Prism.languages.json;
+
 return Prism; })
\ No newline at end of file
index 8e88becf905206d345c43539eff0959d763bc2c8..7931d486fe2dc72e0a36cbb1a06f1be9903c8d21 100644 (file)
@@ -18,7 +18,7 @@ define(["prism/prism","prism/components/prism-json"], function () {
                        pattern: string,
                        greedy: true
                },
-               'number': /[+-]?(?:NaN|Infinity|0x[a-fA-F\d]+|(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/
+               'number': /[+-]?\b(?:NaN|Infinity|0x[a-fA-F\d]+)\b|[+-]?(?:\b\d+\.?\d*|\B\.\d+)(?:[eE][+-]?\d+\b)?/
        });
 
 }(Prism));
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-jsstacktrace.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-jsstacktrace.js
new file mode 100644 (file)
index 0000000..362a136
--- /dev/null
@@ -0,0 +1,51 @@
+define(["prism/prism"], function () {
+Prism.languages.jsstacktrace = {
+       'error-message': {
+               pattern: /^\S.*/m,
+               alias: 'string'
+       },
+       
+       'stack-frame': {
+               pattern: /^[ \t]+at[ \t]+.*/m,
+               inside: {
+                       'not-my-code': {
+                               pattern: /[ \t]+at[ \t]+(?:node\.js|\<unknown\>|.*(?:node_modules|\(\<anonymous\>\)|\(\<unknown\>|\<anonymous\>$|\(internal\/|\(node\.js)).*/m,
+                               alias: 'comment'
+                       },
+                       
+                       'filename': {
+                               pattern: /(\bat\s+|\()(?:[a-zA-Z]:)?[^():]+(?=:)/,
+                               lookbehind: true,
+                               alias: 'url'
+                       },
+                       
+                       'function': {
+                               pattern: /(at\s+(?:new\s+)?)[_$a-zA-Z\xA0-\uFFFF<][.$\w\xA0-\uFFFF<>]*/,
+                               lookbehind: true,
+                               inside: {
+                                       'punctuation': /\./
+                               }
+                       },
+                       
+                       'punctuation': /[()]/,
+                       
+                       'keyword': /\b(?:at|new)\b/,
+                       
+                       'alias': {
+                               pattern: /\[(?:as\s+)?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\]/,
+                               alias: 'variable'
+                       },
+                       
+                       'line-number': {
+                               pattern: /:[0-9]+(?::[0-9]+)?\b/,
+                               alias: 'number',
+                               inside: {
+                                       'punctuation': /:/
+                               }
+                       },
+                       
+               }
+       }
+}
+
+return Prism; })
\ No newline at end of file
index cd8281d7267b44012bbd21512e812581a709726c..2c5b9134fe3702f33deed69c4dc5d7f02464f143 100644 (file)
@@ -1,10 +1,10 @@
-define(["prism/prism","prism/components/prism-markup","prism/components/prism-javascript","prism/components/prism-jsdoc","prism/components/prism-js-extras"], function () {
+define(["prism/prism","prism/components/prism-markup","prism/components/prism-javascript"], function () {
 (function(Prism) {
 
 var javascript = Prism.util.clone(Prism.languages.javascript);
 
 Prism.languages.jsx = Prism.languages.extend('markup', javascript);
-Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{(?:\{[^}]*\}|[^{}])*\}|[^{}])+\}))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?)?>/i;
+Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:$-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}))?|\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}))*\s*\/?)?>/i;
 
 Prism.languages.jsx.tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i;
 Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i;
@@ -12,7 +12,7 @@ Prism.languages.jsx.tag.inside['tag'].inside['class-name'] = /^[A-Z]\w*(?:\.[A-Z
 
 Prism.languages.insertBefore('inside', 'attr-name', {
        'spread': {
-               pattern: /\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}/,
+               pattern: /\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}/,
                inside: {
                        'punctuation': /\.{3}|[{}.]/,
                        'attr-value': /\w+/
@@ -23,7 +23,7 @@ Prism.languages.insertBefore('inside', 'attr-name', {
 Prism.languages.insertBefore('inside', 'attr-value',{
        'script': {
                // Allow for two levels of nesting
-               pattern: /=(\{(?:\{(?:\{[^}]*\}|[^}])*\}|[^}])+\})/i,
+               pattern: /=(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\})/i,
                inside: {
                        'script-punctuation': {
                                pattern: /^=(?={)/,
index 8ca2a73414f055223536671dd91f9acb3a199ead..d0d68985c06bd933674b8774a814853a16d4b0ec 100644 (file)
@@ -1,16 +1,34 @@
 define(["prism/prism"], function () {
-Prism.languages.julia= {
+Prism.languages.julia = {
        'comment': {
-               pattern: /(^|[^\\])#.*/,
+               // support one level of nested comments
+               // https://github.com/JuliaLang/julia/pull/6128
+               pattern: /(^|[^\\])(?:#=(?:[^#=]|=(?!#)|#(?!=)|#=(?:[^#=]|=(?!#)|#(?!=))*=#)*=#|#.*)/,
                lookbehind: true
        },
-       'string': /("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2/,
-       'keyword' : /\b(?:abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|in|let|local|macro|module|print|println|quote|return|struct|try|type|typealias|using|while)\b/,
-       'boolean' : /\b(?:true|false)\b/,
-       'number' : /(?:\b(?=\d)|\B(?=\.))(?:0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:[efp][+-]?\d+)?j?/i,
-       'operator': /[-+*^%÷&$\\]=?|\/[\/=]?|!=?=?|\|[=>]?|<(?:<=?|[=:])?|>(?:=|>>?=?)?|==?=?|[~≠≤≥]/,
-       'punctuation' : /[{}[\];(),.:]/,
-       'constant': /\b(?:(?:NaN|Inf)(?:16|32|64)?)\b/
+       'regex': {
+               // https://docs.julialang.org/en/v1/manual/strings/#Regular-Expressions-1
+               pattern: /r"(?:\\.|[^"\\\r\n])*"[imsx]{0,4}/,
+               greedy: true
+       },
+       'string': {
+               // https://docs.julialang.org/en/v1/manual/strings/#man-characters-1
+               // https://docs.julialang.org/en/v1/manual/strings/#String-Basics-1
+               // https://docs.julialang.org/en/v1/manual/strings/#non-standard-string-literals-1
+               // https://docs.julialang.org/en/v1/manual/running-external-programs/#Running-External-Programs-1
+               pattern: /"""[\s\S]+?"""|\w*"(?:\\.|[^"\\\r\n])*"|(^|[^\w'])'(?:\\[^\r\n][^'\r\n]*|[^\\\r\n])'|`(?:[^\\`\r\n]|\\.)*`/,
+               lookbehind: true,
+               greedy: true
+       },
+       'keyword': /\b(?:abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|in|let|local|macro|module|print|println|quote|return|struct|try|type|typealias|using|while)\b/,
+       'boolean': /\b(?:true|false)\b/,
+       'number': /(?:\b(?=\d)|\B(?=\.))(?:0[box])?(?:[\da-f]+(?:_[\da-f]+)*\.?(?:\d+(?:_\d+)*)?|\.\d+(?:_\d+)*)(?:[efp][+-]?\d+(?:_\d+)*)?j?/i,
+       // https://docs.julialang.org/en/v1/manual/mathematical-operations/
+       // https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity-1
+       'operator': /&&|\|\||[-+*^%÷⊻&$\\]=?|\/[\/=]?|!=?=?|\|[=>]?|<(?:<=?|[=:|])?|>(?:=|>>?=?)?|==?=?|[~≠≤≥'√∛]/,
+       'punctuation': /::?|[{}[\]();,.?]/,
+       // https://docs.julialang.org/en/v1/base/numbers/#Base.im
+       'constant': /\b(?:(?:NaN|Inf)(?:16|32|64)?|im|pi|e|catalan|eulergamma|golden)\b|[πℯγφ]/
 };
 
 return Prism; })
\ No newline at end of file
index cf5fc48a095d0041b09e9e18570c1531d2ee4c6a..24d8835801391fc23fda99da6c2eec899f0d455a 100644 (file)
@@ -43,7 +43,7 @@ define(["prism/prism","prism/components/prism-clike"], function () {
                {
                        pattern: /\$\{[^}]+\}/,
                        inside: {
-                               delimiter: {
+                               'delimiter': {
                                        pattern: /^\$\{|\}$/,
                                        alias: 'variable'
                                },
@@ -60,6 +60,8 @@ define(["prism/prism","prism/components/prism-clike"], function () {
                interpolation: interpolation
        };
 
+       Prism.languages.kt = Prism.languages.kotlin;
+       Prism.languages.kts = Prism.languages.kotlin;
 }(Prism));
 
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-latte.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-latte.js
new file mode 100644 (file)
index 0000000..528f204
--- /dev/null
@@ -0,0 +1,72 @@
+define(["prism/prism","prism/components/prism-clike","prism/components/prism-markup-templating","prism/components/prism-php"], function () {
+(function (Prism) {
+       Prism.languages.latte = {
+               'comment': /^\{\*[\s\S]*/,
+               'ld': {
+                       pattern: /^\{(?:[=_]|\/?(?!\d|\w+\()\w+|)/,
+                       inside: {
+                               'punctuation': /^\{\/?/,
+                               'tag': {
+                                       pattern: /.+/,
+                                       alias: 'important'
+                               }
+                       }
+               },
+               'rd': {
+                       pattern: /\}$/,
+                       inside: {
+                               'punctuation': /.+/
+                       }
+               },
+               'php': {
+                       pattern: /\S(?:[\s\S]*\S)?/,
+                       alias: 'language-php',
+                       inside: Prism.languages.php
+               }
+       };
+
+       var markupLatte = Prism.languages.extend('markup', {});
+       Prism.languages.insertBefore('inside', 'attr-value', {
+               'n-attr': {
+                       pattern: /n:[\w-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+))?/,
+                       inside: {
+                               'attr-name': {
+                                       pattern: /^[^\s=]+/,
+                                       alias: 'important'
+                               },
+                               'attr-value': {
+                                       pattern: /=[\s\S]+/,
+                                       inside: {
+                                               'punctuation': [
+                                                       /^=/,
+                                                       {
+                                                               pattern: /^(\s*)["']|["']$/,
+                                                               lookbehind: true
+                                                       }
+                                               ],
+                                               'php': {
+                                                       pattern: /\S(?:[\s\S]*\S)?/,
+                                                       inside: Prism.languages.php
+                                               }
+                                       }
+                               },
+                       }
+               },
+       }, markupLatte.tag);
+
+       Prism.hooks.add('before-tokenize', function(env) {
+               if (env.language !== 'latte') {
+                       return;
+               }
+               var lattePattern = /\{\*[\s\S]*?\*\}|\{[^'"\s{}*](?:[^"'/{}]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|\/\*[\s\S]*?\*\/)*?\}/g;
+               Prism.languages['markup-templating'].buildPlaceholders(env, 'latte', lattePattern);
+               env.grammar = markupLatte;
+       });
+
+       Prism.hooks.add('after-tokenize', function(env) {
+               Prism.languages['markup-templating'].tokenizePlaceholders(env, 'latte');
+       });
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 9e88c659d35ddb714cf6d651ab0c22d07789fe83..3b52f29197126baa011b6034a93fb6d5bcb0940d 100644 (file)
@@ -16,14 +16,14 @@ Prism.languages.less = Prism.languages.extend('css', {
                }
        ],
        'atrule': {
-               pattern: /@[\w-]+?(?:\([^{}]+\)|[^(){};])*?(?=\s*\{)/i,
+               pattern: /@[\w-]+?(?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};])*?(?=\s*\{)/,
                inside: {
                        'punctuation': /[:()]/
                }
        },
        // selectors and mixins are considered the same
        'selector': {
-               pattern: /(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\([^{}]*\)|[^{};@])*?(?=\s*\{)/,
+               pattern: /(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@])*?(?=\s*\{)/,
                inside: {
                        // mixin parameters
                        'variable': /@+[\w-]+/
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-lilypond.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-lilypond.js
new file mode 100644 (file)
index 0000000..abaadff
--- /dev/null
@@ -0,0 +1,72 @@
+define(["prism/prism","prism/components/prism-scheme"], function () {
+(function (Prism) {
+
+       var schemeExpression = /\((?:[^();"#\\]|\\[\s\S]|;.*(?!.)|"(?:[^"\\]|\\.)*"|#(?:\{(?:(?!#\})[\s\S])*#\}|[^{])|<expr>)*\)/.source;
+       // allow for up to pow(2, recursivenessLog2) many levels of recursive brace expressions
+       // For some reason, this can't be 4
+       var recursivenessLog2 = 5;
+       for (var i = 0; i < recursivenessLog2; i++) {
+               schemeExpression = schemeExpression.replace(/<expr>/g, function () { return schemeExpression; });
+       }
+       schemeExpression = schemeExpression.replace(/<expr>/g, /[^\s\S]/.source);
+
+
+       var lilypond = Prism.languages.lilypond = {
+               'comment': /%(?:(?!\{).*|\{[\s\S]*?%\})/,
+               'embedded-scheme': {
+                       pattern: RegExp(/(^|[=\s])#(?:"(?:[^"\\]|\\.)*"|[^\s()"]*(?:[^\s()]|<expr>))/.source.replace(/<expr>/g, function () { return schemeExpression; }), 'm'),
+                       lookbehind: true,
+                       greedy: true,
+                       inside: {
+                               'scheme': {
+                                       pattern: /^(#)[\s\S]+$/,
+                                       lookbehind: true,
+                                       alias: 'language-scheme',
+                                       inside: {
+                                               'embedded-lilypond': {
+                                                       pattern: /#\{[\s\S]*?#\}/,
+                                                       greedy: true,
+                                                       inside: {
+                                                               'punctuation': /^#\{|#\}$/,
+                                                               'lilypond': {
+                                                                       pattern: /[\s\S]+/,
+                                                                       alias: 'language-lilypond',
+                                                                       inside: null // see below
+                                                               }
+                                                       }
+                                               },
+                                               rest: Prism.languages.scheme
+                                       }
+                               },
+                               'punctuation': /#/
+                       }
+               },
+               'string': {
+                       pattern: /"(?:[^"\\]|\\.)*"/,
+                       greedy: true
+               },
+               'class-name': {
+                       pattern: /(\\new\s+)[\w-]+/,
+                       lookbehind: true
+               },
+               'keyword': {
+                       pattern: /\\[a-z][-\w]*/i,
+                       inside: {
+                               'punctuation': /^\\/
+                       }
+               },
+               'operator': /[=|]|<<|>>/,
+               'punctuation': {
+                       pattern: /(^|[a-z\d])(?:'+|,+|[_^]?-[_^]?(?:[-+^!>._]|(?=\d))|[_^]\.?|[.!])|[{}()[\]<>^~]|\\[()[\]<>\\!]|--|__/,
+                       lookbehind: true
+               },
+               'number': /\b\d+(?:\/\d+)?\b/
+       };
+
+       lilypond['embedded-scheme'].inside['scheme'].inside['embedded-lilypond'].inside['lilypond'].inside = lilypond;
+
+       Prism.languages.ly = lilypond;
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 1b178ea3fc799458db52d5621fc386aebefa9535..482e12b9c7769d03d31bb433b633f7923bac478b 100644 (file)
@@ -131,7 +131,7 @@ define(["prism/prism"], function () {
                },
                punctuation: [
                        // open paren, brackets, and close paren
-                       /(['`,]?\(|[)\[\]])/,
+                       /(?:['`,]?\(|[)\[\]])/,
                        // cons
                        {
                                pattern: /(\s)\.(?=\s)/,
index cf8995826eee17a6023f4745ba6b63cf453344f5..bc9f5c8a00f22d582867555d90a1fc03d3465ded 100644 (file)
@@ -48,7 +48,7 @@ Prism.languages.livescript = {
        ],
        'regex': [
                {
-                       pattern: /\/\/(\[.+?]|\\.|(?!\/\/)[^\\])+\/\/[gimyu]{0,5}/,
+                       pattern: /\/\/(?:\[[^\r\n\]]*\]|\\.|(?!\/\/)[^\\\[])+\/\/[gimyu]{0,5}/,
                        greedy: true,
                        inside: {
                                'comment': {
@@ -58,7 +58,7 @@ Prism.languages.livescript = {
                        }
                },
                {
-                       pattern: /\/(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}/,
+                       pattern: /\/(?:\[[^\r\n\]]*\]|\\.|[^/\\\r\n\[])+\/[gimyu]{0,5}/,
                        greedy: true
                }
        ],
@@ -118,4 +118,5 @@ Prism.languages.livescript = {
 };
 
 Prism.languages.livescript['interpolated-string'].inside['interpolation'].inside.rest = Prism.languages.livescript;
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-llvm.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-llvm.js
new file mode 100644 (file)
index 0000000..8581628
--- /dev/null
@@ -0,0 +1,22 @@
+define(["prism/prism"], function () {
+(function(Prism) {
+       Prism.languages.llvm = {
+               'comment': /;.*/,
+               'string': {
+                       pattern: /"[^"]*"/,
+                       greedy: true,
+               },
+               'boolean': /\b(?:true|false)\b/,
+               'variable': /[%@!#](?:(?!\d)(?:[-$.\w]|\\[a-f\d]{2})+|\d+)/i,
+               'label': /(?!\d)(?:[-$.\w]|\\[a-f\d]{2})+:/i,
+               'type': {
+                       pattern: /\b(?:double|float|fp128|half|i[1-9]\d*|label|metadata|ppc_fp128|token|void|x86_fp80|x86_mmx)\b/,
+                       alias: 'class-name',
+               },
+               'keyword': /\b[a-z_][a-z_0-9]*\b/,
+               'number': /[+-]?\b\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b|\b0x[\dA-Fa-f]+\b|\b0xK[\dA-Fa-f]{20}\b|\b0x[ML][\dA-Fa-f]{32}\b|\b0xH[\dA-Fa-f]{4}\b/,
+               'punctuation': /[{}[\];(),.!*=<>]/,
+       };
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index e746fcccabd2e012269e2adcd271c29c152be879..a211a8fe8871bb24da74165688b8f74bd107d36c 100644 (file)
@@ -5,7 +5,7 @@ Prism.languages.lolcode = {
                /\bBTW.+/
        ],
        'string': {
-               pattern: /"(?::.|[^"])*"/,
+               pattern: /"(?::.|[^":])*"/,
                inside: {
                        'variable': /:\{[^}]+\}/,
                        'symbol': [
@@ -54,4 +54,5 @@ Prism.languages.lolcode = {
        },
        'punctuation': /\.{3}|…|,|!/
 };
+
 return Prism; })
\ No newline at end of file
index 1781a3686fb7bc73b822446b3c03e3708bbe3a6b..05474769cc0043f3d57bb61a483f7e3d3450c2d8 100644 (file)
@@ -2,7 +2,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
 (function (Prism) {
 
        // Allow only one line break
-       var inner = /\\.|[^\\\n\r_]|(?:\r?\n|\r)(?!\r?\n|\r)/.source;
+       var inner = /(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?!\n|\r\n?))/.source;
 
        /**
         * This function is intended for the creation of the bold or italic pattern.
@@ -12,18 +12,19 @@ define(["prism/prism","prism/components/prism-markup"], function () {
         * _Note:_ Keep in mind that this adds a capturing group.
         *
         * @param {string} pattern
-        * @param {boolean} starAlternative Whether to also add an alternative where all `_`s are replaced with `*`s.
         * @returns {RegExp}
         */
-       function createInline(pattern, starAlternative) {
-               pattern = pattern.replace(/<inner>/g, inner);
-               if (starAlternative) {
-                       pattern = pattern + '|' + pattern.replace(/_/g, '\\*');
-               }
+       function createInline(pattern) {
+               pattern = pattern.replace(/<inner>/g, function () { return inner; });
                return RegExp(/((?:^|[^\\])(?:\\{2})*)/.source + '(?:' + pattern + ')');
        }
 
 
+       var tableCell = /(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source;
+       var tableRow = /\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|$)/.source.replace(/__/g, function () { return tableCell; });
+       var tableLine = /\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;
+
+
        Prism.languages.markdown = Prism.languages.extend('markup', {});
        Prism.languages.insertBefore('markdown', 'prolog', {
                'blockquote': {
@@ -31,16 +32,51 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                        pattern: /^>(?:[\t ]*>)*/m,
                        alias: 'punctuation'
                },
+               'table': {
+                       pattern: RegExp('^' + tableRow + tableLine + '(?:' + tableRow + ')*', 'm'),
+                       inside: {
+                               'table-data-rows': {
+                                       pattern: RegExp('^(' + tableRow + tableLine + ')(?:' + tableRow + ')*$'),
+                                       lookbehind: true,
+                                       inside: {
+                                               'table-data': {
+                                                       pattern: RegExp(tableCell),
+                                                       inside: Prism.languages.markdown
+                                               },
+                                               'punctuation': /\|/
+                                       }
+                               },
+                               'table-line': {
+                                       pattern: RegExp('^(' + tableRow + ')' + tableLine + '$'),
+                                       lookbehind: true,
+                                       inside: {
+                                               'punctuation': /\||:?-{3,}:?/
+                                       }
+                               },
+                               'table-header-row': {
+                                       pattern: RegExp('^' + tableRow + '$'),
+                                       inside: {
+                                               'table-header': {
+                                                       pattern: RegExp(tableCell),
+                                                       alias: 'important',
+                                                       inside: Prism.languages.markdown
+                                               },
+                                               'punctuation': /\|/
+                                       }
+                               }
+                       }
+               },
                'code': [
                        {
-                               // Prefixed by 4 spaces or 1 tab
-                               pattern: /^(?: {4}|\t).+/m,
+                               // Prefixed by 4 spaces or 1 tab and preceded by an empty line
+                               pattern: /((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,
+                               lookbehind: true,
                                alias: 'keyword'
                        },
                        {
                                // `code`
                                // ``code``
-                               pattern: /``.+?``|`[^`\n]+`/,
+                               pattern: /``.+?``|`[^`\r\n]+`/,
                                alias: 'keyword'
                        },
                        {
@@ -51,7 +87,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                                greedy: true,
                                inside: {
                                        'code-block': {
-                                               pattern: /^(```.*(?:\r?\n|\r))[\s\S]+?(?=(?:\r?\n|\r)^```$)/m,
+                                               pattern: /^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,
                                                lookbehind: true
                                        },
                                        'code-language': {
@@ -69,7 +105,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
 
                                // title 2
                                // -------
-                               pattern: /\S.*(?:\r?\n|\r)(?:==+|--+)/,
+                               pattern: /\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,
                                alias: 'important',
                                inside: {
                                        punctuation: /==+$|--+$/
@@ -125,7 +161,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                        // __strong__
 
                        // allow one nested instance of italic text using the same delimiter
-                       pattern: createInline(/__(?:<inner>|_(?:<inner>)+_)+__/.source, true),
+                       pattern: createInline(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),
                        lookbehind: true,
                        greedy: true,
                        inside: {
@@ -142,7 +178,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                        // _em_
 
                        // allow one nested instance of bold text using the same delimiter
-                       pattern: createInline(/_(?:<inner>|__(?:<inner>)+__)+_/.source, true),
+                       pattern: createInline(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),
                        lookbehind: true,
                        greedy: true,
                        inside: {
@@ -157,9 +193,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                'strike': {
                        // ~~strike through~~
                        // ~strike~
-
-                       // extra _ is because the inner pattern intentionally doesn't include it because of bold and italic
-                       pattern: createInline(/(~~?)(?:<inner>|_)+?\2/.source, false),
+                       pattern: createInline(/(~~?)(?:(?!~)<inner>)+?\2/.source),
                        lookbehind: true,
                        greedy: true,
                        inside: {
@@ -173,13 +207,21 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                },
                'url': {
                        // [example](http://example.com "Optional title")
+                       // [example][id]
                        // [example] [id]
-                       pattern: /!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,
+                       pattern: createInline(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[(?:(?!\])<inner>)+\])/.source),
+                       lookbehind: true,
+                       greedy: true,
                        inside: {
                                'variable': {
-                                       pattern: /(!?\[)[^\]]+(?=\]$)/,
+                                       pattern: /(\[)[^\]]+(?=\]$)/,
                                        lookbehind: true
                                },
+                               'content': {
+                                       pattern: /(^!?\[)[^\]]+(?=\])/,
+                                       lookbehind: true,
+                                       inside: {} // see below
+                               },
                                'string': {
                                        pattern: /"(?:\\.|[^"\\])*"(?=\)$)/
                                }
@@ -187,7 +229,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                }
        });
 
-       ['bold', 'italic', 'strike'].forEach(function (token) {
+       ['url', 'bold', 'italic', 'strike'].forEach(function (token) {
                ['url', 'bold', 'italic', 'strike'].forEach(function (inside) {
                        if (token !== inside) {
                                Prism.languages.markdown[token].inside.content.inside[inside] = Prism.languages.markdown[inside];
@@ -235,7 +277,12 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                                        typeof codeLang.content === 'string') {
 
                                        // this might be a language that Prism does not support
-                                       var alias = 'language-' + codeLang.content.trim().split(/\s+/)[0].toLowerCase();
+
+                                       // do some replacements to support C++, C#, and F#
+                                       var lang = codeLang.content.replace(/\b#/g, 'sharp').replace(/\b\+\+/g, 'pp')
+                                       // only use the first word
+                                       lang = (/[a-z][\w-]*/i.exec(lang) || [''])[0].toLowerCase();
+                                       var alias = 'language-' + lang;
 
                                        // add alias
                                        if (!codeBlock.alias) {
@@ -270,13 +317,23 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                var grammar = Prism.languages[codeLang];
 
                if (!grammar) {
-                       return;
-               }
+                       if (codeLang && codeLang !== 'none' && Prism.plugins.autoloader) {
+                               var id = 'md-' + new Date().valueOf() + '-' + Math.floor(Math.random() * 1e16);
+                               env.attributes['id'] = id;
 
-               // reverse Prism.util.encode
-               var code = env.content.replace(/&lt;/g, '<').replace(/&amp;/g, '&');
+                               Prism.plugins.autoloader.loadLanguages(codeLang, function () {
+                                       var ele = document.getElementById(id);
+                                       if (ele) {
+                                               ele.innerHTML = Prism.highlight(ele.textContent, Prism.languages[codeLang], codeLang);
+                                       }
+                               });
+                       }
+               } else {
+                       // reverse Prism.util.encode
+                       var code = env.content.replace(/&lt;/g, '<').replace(/&amp;/g, '&');
 
-               env.content = Prism.highlight(code, grammar, codeLang);
+                       env.content = Prism.highlight(code, grammar, codeLang);
+               }
        });
 
        Prism.languages.md = Prism.languages.markdown;
index 3469a88a19df0074c31968e0e55a60441e0ff531..ee720120d2f036dd4a3968afbdf04d5e501beda5 100644 (file)
@@ -2,28 +2,47 @@ define(["prism/prism"], function () {
 Prism.languages.markup = {
        'comment': /<!--[\s\S]*?-->/,
        'prolog': /<\?[\s\S]+?\?>/,
-       'doctype': /<!DOCTYPE[\s\S]+?>/i,
+       'doctype': {
+               // https://www.w3.org/TR/xml/#NT-doctypedecl
+               pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
+               greedy: true,
+               inside: {
+                       'internal-subset': {
+                               pattern: /(\[)[\s\S]+(?=\]>$)/,
+                               lookbehind: true,
+                               greedy: true,
+                               inside: null // see below
+                       },
+                       'string': {
+                               pattern: /"[^"]*"|'[^']*'/,
+                               greedy: true
+                       },
+                       'punctuation': /^<!|>$|[[\]]/,
+                       'doctype-tag': /^DOCTYPE/,
+                       'name': /[^\s<>'"]+/
+               }
+       },
        'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
        'tag': {
-               pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,
+               pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
                greedy: true,
                inside: {
                        'tag': {
-                               pattern: /^<\/?[^\s>\/]+/i,
+                               pattern: /^<\/?[^\s>\/]+/,
                                inside: {
                                        'punctuation': /^<\/?/,
                                        'namespace': /^[^\s>\/:]+:/
                                }
                        },
                        'attr-value': {
-                               pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,
+                               pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
                                inside: {
                                        'punctuation': [
-                                               /^=/,
                                                {
-                                                       pattern: /^(\s*)["']|["']$/,
-                                                       lookbehind: true
-                                               }
+                                                       pattern: /^=/,
+                                                       alias: 'attr-equals'
+                                               },
+                                               /"|'/
                                        ]
                                }
                        },
@@ -37,14 +56,21 @@ Prism.languages.markup = {
 
                }
        },
-       'entity': /&#?[\da-z]{1,8};/i
+       'entity': [
+               {
+                       pattern: /&[\da-z]{1,8};/i,
+                       alias: 'named-entity'
+               },
+               /&#x?[\da-f]{1,8};/i
+       ]
 };
 
 Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
        Prism.languages.markup['entity'];
+Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
 
 // Plugin to make entity title show the real entity, idea by Roman Komarov
-Prism.hooks.add('wrap', function(env) {
+Prism.hooks.add('wrap', function (env) {
 
        if (env.type === 'entity') {
                env.attributes['title'] = env.content.replace(/&amp;/, '&');
@@ -85,7 +111,7 @@ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
 
                var def = {};
                def[tagName] = {
-                       pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[[\s\S]*?\]\]>\s*|[\s\S])*?(?=<\/__>)/.source.replace(/__/g, tagName), 'i'),
+                       pattern: RegExp(/(<__[\s\S]*?>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
                        lookbehind: true,
                        greedy: true,
                        inside: inside
@@ -95,9 +121,13 @@ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
        }
 });
 
-Prism.languages.xml = Prism.languages.extend('markup', {});
 Prism.languages.html = Prism.languages.markup;
 Prism.languages.mathml = Prism.languages.markup;
 Prism.languages.svg = Prism.languages.markup;
 
+Prism.languages.xml = Prism.languages.extend('markup', {});
+Prism.languages.ssml = Prism.languages.xml;
+Prism.languages.atom = Prism.languages.xml;
+Prism.languages.rss = Prism.languages.xml;
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-moonscript.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-moonscript.js
new file mode 100644 (file)
index 0000000..64c9d0a
--- /dev/null
@@ -0,0 +1,60 @@
+define(["prism/prism"], function () {
+Prism.languages.moonscript = {
+       'comment': /--.*/,
+       'string': [
+               {
+                       pattern: /'[^']*'|\[(=*)\[[\s\S]*?\]\1\]/,
+                       greedy: true
+               },
+               {
+                       pattern: /"[^"]*"/,
+                       greedy: true,
+                       inside: {
+                               'interpolation': {
+                                       pattern: /#\{[^{}]*\}/,
+                                       inside: {
+                                               'moonscript': {
+                                                       pattern: /(^#\{)[\s\S]+(?=\})/,
+                                                       lookbehind: true,
+                                                       inside: null // see beow
+                                               },
+                                               'interpolation-punctuation': {
+                                                       pattern: /#\{|\}/,
+                                                       alias: 'punctuation'
+                                               }
+                                       }
+                               }
+                       }
+               }
+       ],
+       'class-name': [
+               {
+                       pattern: /(\b(?:class|extends)[ \t]+)\w+/,
+                       lookbehind: true
+               },
+               // class-like names start with a capital letter
+               /\b[A-Z]\w*/
+       ],
+       'keyword': /\b(?:class|continue|do|else|elseif|export|extends|for|from|if|import|in|local|nil|return|self|super|switch|then|unless|using|when|while|with)\b/,
+       'variable': /@@?\w*/,
+       'property': {
+               pattern: /\b(?!\d)\w+(?=:)|(:)(?!\d)\w+/,
+               lookbehind: true
+       },
+       'function': {
+               pattern: /\b(?:_G|_VERSION|assert|collectgarbage|coroutine\.(?:running|create|resume|status|wrap|yield)|debug\.(?:debug|gethook|getinfo|getlocal|getupvalue|setlocal|setupvalue|sethook|traceback|getfenv|getmetatable|getregistry|setfenv|setmetatable)|dofile|error|getfenv|getmetatable|io\.(?:stdin|stdout|stderr|close|flush|input|lines|open|output|popen|read|tmpfile|type|write)|ipairs|load|loadfile|loadstring|math\.(?:abs|acos|asin|atan|atan2|ceil|sin|cos|tan|deg|exp|floor|log|log10|max|min|fmod|modf|cosh|sinh|tanh|pow|rad|sqrt|frexp|ldexp|random|randomseed|pi)|module|next|os\.(?:clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)|package\.(?:cpath|loaded|loadlib|path|preload|seeall)|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|string\.(?:byte|char|dump|find|len|lower|rep|sub|upper|format|gsub|gmatch|match|reverse)|table\.(?:maxn|concat|sort|insert|remove)|tonumber|tostring|type|unpack|xpcall)\b/,
+               inside: {
+                       'punctuation': /\./
+               }
+       },
+       'boolean': /\b(?:false|true)\b/,
+       'number': /(?:\B\.\d+|\b\d+\.\d+|\b\d+(?=[eE]))(?:[eE][-+]?\d+)?\b|\b(?:0x[a-fA-F\d]+|\d+)(?:U?LL)?\b/,
+       'operator': /\.{3}|[-=]>|~=|(?:[-+*/%<>!=]|\.\.)=?|[:#^]|\b(?:and|or)\b=?|\b(?:not)\b/,
+       'punctuation': /[.,()[\]{}\\]/
+};
+
+Prism.languages.moonscript.string[1].inside.interpolation.inside.moonscript.inside = Prism.languages.moonscript;
+
+Prism.languages.moon = Prism.languages.moonscript;
+
+return Prism; })
\ No newline at end of file
index f5b1c7f71a09259bca982cc08563bfccde95faf4..1d6b902e6869a41f201700c44f7c2bb961041057 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-javascript","prism/components/prism-jsdoc"], function () {
+define(["prism/prism","prism/components/prism-javascript"], function () {
 Prism.languages.n4js = Prism.languages.extend('javascript', {
        // Keywords from N4JS language spec: https://numberfour.github.io/n4js/spec/N4JSSpec.html
        'keyword': /\b(?:any|Array|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-neon.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-neon.js
new file mode 100644 (file)
index 0000000..7603bf0
--- /dev/null
@@ -0,0 +1,44 @@
+define(["prism/prism"], function () {
+Prism.languages.neon = {
+       'comment': {
+               pattern: /#.*/,
+               greedy: true
+       },
+       'datetime': {
+               pattern: /(^|[[{(=:,\s])\d\d\d\d-\d\d?-\d\d?(?:(?:[Tt]| +)\d\d?:\d\d:\d\d(?:\.\d*)? *(?:Z|[-+]\d\d?(?::?\d\d)?)?)?(?=$|[\]}),\s])/,
+               lookbehind: true,
+               alias: 'number'
+       },
+       'key': {
+               pattern: /(^|[[{(,\s])[^,:=[\]{}()'"\s]+(?=\s*:(?:$|[\]}),\s])|\s*=)/,
+               lookbehind: true,
+               alias: 'atrule'
+       },
+       'number': {
+               pattern: /(^|[[{(=:,\s])[+-]?(?:0x[\da-fA-F]+|0o[0-7]+|0b[01]+|(?:\d+\.?\d*|\.?\d+)(?:[eE][+-]?\d+)?)(?=$|[\]}),:=\s])/,
+               lookbehind: true
+       },
+       'boolean': {
+               pattern: /(^|[[{(=:,\s])(?:true|false|yes|no)(?=$|[\]}),:=\s])/i,
+               lookbehind: true
+       },
+       'null': {
+               pattern: /(^|[[{(=:,\s])(?:null)(?=$|[\]}),:=\s])/i,
+               lookbehind: true,
+               alias: 'keyword'
+       },
+       'string': {
+               pattern: /(^|[[{(=:,\s])(?:('''|""")\r?\n(?:(?:[^\r\n]|\r?\n(?![\t ]*\2))*\r?\n)?[\t ]*\2|'[^'\r\n]*'|"(?:\\.|[^\\"\r\n])*")/,
+               lookbehind: true,
+               greedy: true
+       },
+       'literal': {
+               pattern: /(^|[[{(=:,\s])(?:[^#"\',:=[\]{}()\s`-]|[:-][^"\',=[\]{}()\s])(?:[^,:=\]})(\s]+|:(?![\s,\]})]|$)|[ \t]+[^#,:=\]})(\s])*/,
+               lookbehind: true,
+               alias: 'string',
+       },
+       'punctuation': /[,:=[\]{}()-]/,
+};
+
+
+return Prism; })
\ No newline at end of file
index efcd88be912392f18afec6d86ad477178a09752f..3b0d930ef734c435244ff492b019a354a0b880e8 100644 (file)
@@ -6,7 +6,7 @@ define(["prism/prism"], function () {
  */
  Prism.languages.nsis = {
        'comment': {
-               pattern: /(^|[^\\])(\/\*[\s\S]*?\*\/|[#;].*)/,
+               pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|[#;].*)/,
                lookbehind: true
        },
        'string': {
@@ -17,7 +17,7 @@ define(["prism/prism"], function () {
                pattern: /(^\s*)(?:Abort|Add(?:BrandingImage|Size)|AdvSplash|Allow(?:RootDirInstall|SkipFiles)|AutoCloseWindow|Banner|BG(?:Font|Gradient|Image)|BrandingText|BringToFront|Call(?:InstDLL)?|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|Create(?:Directory|Font|ShortCut)|Delete(?:INISec|INIStr|RegKey|RegValue)?|Detail(?:Print|sButtonText)|Dialer|Dir(?:Text|Var|Verify)|EnableWindow|Enum(?:RegKey|RegValue)|Exch|Exec(?:Shell(?:Wait)?|Wait)?|ExpandEnvStrings|File(?:BufSize|Close|ErrorText|Open|Read|ReadByte|ReadUTF16LE|ReadWord|WriteUTF16LE|Seek|Write|WriteByte|WriteWord)?|Find(?:Close|First|Next|Window)|FlushINI|Get(?:CurInstType|CurrentAddress|DlgItem|DLLVersion(?:Local)?|ErrorLevel|FileTime(?:Local)?|FullPathName|Function(?:Address|End)?|InstDirError|LabelAddress|TempFileName)|Goto|HideWindow|Icon|If(?:Abort|Errors|FileExists|RebootFlag|Silent)|InitPluginsDir|Install(?:ButtonText|Colors|Dir(?:RegKey)?)|InstProgressFlags|Inst(?:Type(?:GetText|SetText)?)|Int(?:64|Ptr)?CmpU?|Int(?:64)?Fmt|Int(?:Ptr)?Op|IsWindow|Lang(?:DLL|String)|License(?:BkColor|Data|ForceSelection|LangString|Text)|LoadLanguageFile|LockWindow|Log(?:Set|Text)|Manifest(?:DPIAware|SupportedOS)|Math|MessageBox|MiscButtonText|Name|Nop|ns(?:Dialogs|Exec)|NSISdl|OutFile|Page(?:Callbacks)?|PE(?:DllCharacteristics|SubsysVer)|Pop|Push|Quit|Read(?:EnvStr|INIStr|RegDWORD|RegStr)|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|Section(?:End|GetFlags|GetInstTypes|GetSize|GetText|Group|In|SetFlags|SetInstTypes|SetSize|SetText)?|SendMessage|Set(?:AutoClose|BrandingImage|Compress|Compressor(?:DictSize)?|CtlColors|CurInstType|DatablockOptimize|DateSave|Details(?:Print|View)|ErrorLevel|Errors|FileAttributes|Font|OutPath|Overwrite|PluginUnload|RebootFlag|RegView|ShellVarContext|Silent)|Show(?:InstDetails|UninstDetails|Window)|Silent(?:Install|UnInstall)|Sleep|SpaceTexts|Splash|StartMenu|Str(?:CmpS?|Cpy|Len)|SubCaption|System|Unicode|Uninstall(?:ButtonText|Caption|Icon|SubCaption|Text)|UninstPage|UnRegDLL|UserInfo|Var|VI(?:AddVersionKey|FileVersion|ProductVersion)|VPatch|WindowIcon|Write(?:INIStr|Reg(?:Bin|DWORD|ExpandStr|MultiStr|None|Str)|Uninstaller)|XPStyle)\b/m,
                lookbehind: true
        },
-       'property': /\b(?:admin|all|auto|both|colored|false|force|hide|highest|lastused|leave|listonly|none|normal|notset|off|on|open|print|show|silent|silentlog|smooth|textonly|true|user|ARCHIVE|FILE_(ATTRIBUTE_ARCHIVE|ATTRIBUTE_NORMAL|ATTRIBUTE_OFFLINE|ATTRIBUTE_READONLY|ATTRIBUTE_SYSTEM|ATTRIBUTE_TEMPORARY)|HK((CR|CU|LM)(32|64)?|DD|PD|U)|HKEY_(CLASSES_ROOT|CURRENT_CONFIG|CURRENT_USER|DYN_DATA|LOCAL_MACHINE|PERFORMANCE_DATA|USERS)|ID(ABORT|CANCEL|IGNORE|NO|OK|RETRY|YES)|MB_(ABORTRETRYIGNORE|DEFBUTTON1|DEFBUTTON2|DEFBUTTON3|DEFBUTTON4|ICONEXCLAMATION|ICONINFORMATION|ICONQUESTION|ICONSTOP|OK|OKCANCEL|RETRYCANCEL|RIGHT|RTLREADING|SETFOREGROUND|TOPMOST|USERICON|YESNO)|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)\b/,
+        'property': /\b(?:admin|all|auto|both|colored|false|force|hide|highest|lastused|leave|listonly|none|normal|notset|off|on|open|print|show|silent|silentlog|smooth|textonly|true|user|ARCHIVE|FILE_(?:ATTRIBUTE_ARCHIVE|ATTRIBUTE_NORMAL|ATTRIBUTE_OFFLINE|ATTRIBUTE_READONLY|ATTRIBUTE_SYSTEM|ATTRIBUTE_TEMPORARY)|HK(?:(?:CR|CU|LM)(?:32|64)?|DD|PD|U)|HKEY_(?:CLASSES_ROOT|CURRENT_CONFIG|CURRENT_USER|DYN_DATA|LOCAL_MACHINE|PERFORMANCE_DATA|USERS)|ID(?:ABORT|CANCEL|IGNORE|NO|OK|RETRY|YES)|MB_(?:ABORTRETRYIGNORE|DEFBUTTON1|DEFBUTTON2|DEFBUTTON3|DEFBUTTON4|ICONEXCLAMATION|ICONINFORMATION|ICONQUESTION|ICONSTOP|OK|OKCANCEL|RETRYCANCEL|RIGHT|RTLREADING|SETFOREGROUND|TOPMOST|USERICON|YESNO)|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)\b/,
        'constant': /\${[\w\.:\^-]+}|\$\([\w\.:\^-]+\)/i,
        'variable': /\$\w+/i,
        'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,
index 5e7110022cbff2c9b0cb08edc4403453068be7c2..1ea46e28fcd8eaf9cb58fdedb59303c14af7f070 100644 (file)
@@ -7,4 +7,5 @@ Prism.languages.objectivec = Prism.languages.extend('c', {
 
 delete Prism.languages.objectivec['class-name'];
 
+Prism.languages.objc = Prism.languages.objectivec;
 return Prism; })
\ No newline at end of file
index 7a3913e8e20c66da2b722cd52bff2270b942c3ca..af62b0b81ed017d12f3437e3ee1590680f4b032c 100644 (file)
@@ -12,18 +12,33 @@ Prism.languages.ocaml = {
                }
        ],
        'number': /\b(?:0x[\da-f][\da-f_]+|(?:0[bo])?\d[\d_]*\.?[\d_]*(?:e[+-]?[\d_]+)?)/i,
-       'type': {
-               pattern: /\B['`]\w*/,
-               alias: 'variable'
-       },
        'directive': {
                pattern: /\B#\w+/,
+               alias: 'important'
+       },
+       'label': {
+               pattern: /\B~\w+/,
+               alias: 'function'
+       },
+       'type_variable': {
+               pattern: /\B'\w+/,
                alias: 'function'
        },
-       'keyword': /\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|object|of|open|prefix|private|rec|then|sig|struct|to|try|type|val|value|virtual|where|while|with)\b/,
+       'variant': {
+               pattern: /`\w+/,
+               alias: 'variable'
+       },
+       'module': {
+               pattern: /\b[A-Z]\w+/,
+               alias: 'variable'
+       },
+       // For the list of keywords and operators,
+       // see: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#sec84
+       'keyword': /\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,
        'boolean': /\b(?:false|true)\b/,
        // Custom operators are allowed
-       'operator': /:=|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lxor|lsl|lsr|mod|nor|or)\b/,
-       'punctuation': /[(){}\[\]|_.,:;]/
+       'operator': /:=|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,
+       'punctuation': /[(){}\[\]|.,:;]|\b_\b/
 };
+
 return Prism; })
\ No newline at end of file
index f31901cc4434b0c7d1bb957fef00468657a2a1a0..311f09212e90e140c9eb9aa17712fe610da018fb 100644 (file)
@@ -1,19 +1,20 @@
-define(["prism/prism","prism/components/prism-cpp","prism/components/prism-c","prism/components/prism-cpp"], function () {
+define(["prism/prism","prism/components/prism-c"], function () {
 (function (Prism) {
        /* OpenCL kernel language */
        Prism.languages.opencl = Prism.languages.extend('c', {
                // Extracted from the official specs (2.0) and http://streamcomputing.eu/downloads/?opencl.lang (opencl-keywords, opencl-types) and http://sourceforge.net/tracker/?func=detail&aid=2957794&group_id=95717&atid=612384 (Words2, partly Words3)
+               // https://www.khronos.org/registry/OpenCL/sdk/2.1/docs/man/xhtml/scalarDataTypes.html
+               // https://www.khronos.org/registry/OpenCL/sdk/2.1/docs/man/xhtml/otherDataTypes.html
                'keyword': /\b(?:__attribute__|(?:__)?(?:constant|global|kernel|local|private|read_only|read_write|write_only)|_cl_(?:command_queue|context|device_id|event|kernel|mem|platform_id|program|sampler)|auto|break|case|cl_(?:image_format|mem_fence_flags)|clk_event_t|complex|const|continue|default|do|(?:float|double)(?:16(?:x(?:1|16|2|4|8))?|1x(?:1|16|2|4|8)|2(?:x(?:1|16|2|4|8))?|3|4(?:x(?:1|16|2|4|8))?|8(?:x(?:1|16|2|4|8))?)?|else|enum|event_t|extern|for|goto|(?:u?(?:char|short|int|long)|half|quad|bool)(?:2|3|4|8|16)?|if|image(?:1d_(?:array_|buffer_)?t|2d_(?:array_(?:depth_|msaa_depth_|msaa_)?|depth_|msaa_depth_|msaa_)?t|3d_t)|imaginary|inline|intptr_t|ndrange_t|packed|pipe|ptrdiff_t|queue_t|register|reserve_id_t|restrict|return|sampler_t|signed|size_t|sizeof|static|struct|switch|typedef|uintptr_t|uniform|union|unsigned|void|volatile|while)\b/,
-               // Extracted from http://streamcomputing.eu/downloads/?opencl.lang (global-vars, opencl-dev)
-               'function-opencl-kernel': {
-                       pattern: /\b(?:abs(?:_diff)?|a?(?:cos|sin)(?:h|pi)?|add_sat|aligned|all|and|any|async(?:_work_group_copy|_work_group_strided_copy)?|atan(?:2?(?:pi)?|h)?|atom_(?:add|and|cmpxchg|dec|inc|max|min|or|sub|xchg|xor)|barrier|bitselect|cbrt|ceil|clamp|clz|copies|copysign|cross|degrees|distance|dot|endian|erf|erfc|exp(?:2|10)?|expm1|fabs|fast_(?:distance|length|normalize)|fdim|floor|fma|fmax|fmin|fract|frexp|fro|from|get_(?:global_(?:id|offset|size)|group_id|image_(?:channel_data_type|channel_order|depth|dim|height|width)|local(?:_id|_size)|num_groups|work_dim)|hadd|(?:half|native)_(?:cos|divide|exp(?:2|10)?|log(?:2|10)?|powr|recip|r?sqrt|sin|tan)|hypot|ilogb|is(?:equal|finite|greater(?:equal)?|inf|less(?:equal|greater)?|nan|normal|notequal|(?:un)?ordered)|ldexp|length|lgamma|lgamma_r|log(?:b|1p|2|10)?|mad(?:24|_hi|_sat)?|max|mem(?:_fence)?|min|mix|modf|mul24|mul_hi|nan|nextafter|normalize|pow[nr]?|prefetch|radians|read_(?:image)(?:f|h|u?i)|read_mem_fence|remainder|remquo|reqd_work_group_size|rhadd|rint|rootn|rotate|round|rsqrt|select|shuffle2?|sign|signbit|sincos|smoothstep|sqrt|step|sub_sat|tan|tanh|tanpi|tgamma|to|trunc|upsample|vec_(?:step|type_hint)|v(?:load|store)(?:_half)?(?:2|3|4|8|16)?|v(?:loada_half|storea?(?:_half)?)(?:2|3|4|8|16)?(?:_(?:rte|rtn|rtp|rtz))?|wait_group_events|work_group_size_hint|write_image(?:f|h|u?i)|write_mem_fence)\b/,
-                       alias: 'function'
-               },
                // Extracted from http://streamcomputing.eu/downloads/?opencl.lang (opencl-const)
+               // Math Constants: https://www.khronos.org/registry/OpenCL/sdk/2.1/docs/man/xhtml/mathConstants.html
+               // Macros and Limits: https://www.khronos.org/registry/OpenCL/sdk/2.1/docs/man/xhtml/macroLimits.html
                'constant-opencl-kernel': {
-                       pattern: /\b(?:CHAR_(?:BIT|MAX|MIN)|CLK_(?:ADDRESS_(?:CLAMP(?:_TO_EDGE)?|NONE|REPEAT)|FILTER_(?:LINEAR|NEAREST)|(?:LOCAL|GLOBAL)_MEM_FENCE|NORMALIZED_COORDS_(?:FALSE|TRUE))|CL_(?:BGRA|(?:HALF_)?FLOAT|INTENSITY|LUMINANCE|A?R?G?B?[Ax]?|(?:(?:UN)?SIGNED|[US]NORM)_(?:INT(?:8|16|32))|UNORM_(?:INT_101010|SHORT_(?:555|565)))|(?:DBL|FLT)_(?:DIG|EPSILON|MANT_DIG|(?:MIN|MAX)(?:(?:_10)?_EXP)?)|FLT_RADIX|HUGE_VALF|INFINITY|(?:INT|LONG|SCHAR|SHRT|UCHAR|UINT|ULONG)_(?:MAX|MIN)|MAXFLOAT|M_(?:[12]_PI|2_SQRTPI|E|LN(?:2|10)|LOG(?:10|2)E?|PI[24]?|SQRT(?:1_2|2))|NAN)\b/,
+                       pattern: /\b(?:CHAR_(?:BIT|MAX|MIN)|CLK_(?:ADDRESS_(?:CLAMP(?:_TO_EDGE)?|NONE|REPEAT)|FILTER_(?:LINEAR|NEAREST)|(?:LOCAL|GLOBAL)_MEM_FENCE|NORMALIZED_COORDS_(?:FALSE|TRUE))|CL_(?:BGRA|(?:HALF_)?FLOAT|INTENSITY|LUMINANCE|A?R?G?B?[Ax]?|(?:(?:UN)?SIGNED|[US]NORM)_(?:INT(?:8|16|32))|UNORM_(?:INT_101010|SHORT_(?:555|565)))|(?:DBL|FLT|HALF)_(?:DIG|EPSILON|MANT_DIG|(?:MIN|MAX)(?:(?:_10)?_EXP)?)|FLT_RADIX|HUGE_VALF?|INFINITY|(?:INT|LONG|SCHAR|SHRT)_(?:MAX|MIN)|(?:UCHAR|USHRT|UINT|ULONG)_MAX|MAXFLOAT|M_(?:[12]_PI|2_SQRTPI|E|LN(?:2|10)|LOG(?:10|2)E?|PI(?:_[24])?|SQRT(?:1_2|2))(?:_F|_H)?|NAN)\b/,
                        alias: 'constant'
-               }
+               },
+               'boolean': /\b(?:false|true)\b/,
+               'number': /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[fuhl]*/i
        });
 
        var attributes = {
@@ -40,13 +41,17 @@ define(["prism/prism","prism/components/prism-cpp","prism/components/prism-c","p
 
        /* OpenCL host API */
        Prism.languages.insertBefore('c', 'keyword', attributes);
-       // Extracted from doxygen class list http://github.khronos.org/OpenCL-CLHPP/annotated.html
-       attributes['type-opencl-host-c++'] = {
-               pattern: /\b(?:Buffer|BufferGL|BufferRenderGL|CommandQueue|Context|Device|DeviceCommandQueue|EnqueueArgs|Event|Image|Image1D|Image1DArray|Image1DBuffer|Image2D|Image2DArray|Image2DGL|Image3D|Image3DGL|ImageFormat|ImageGL|Kernel|KernelFunctor|LocalSpaceArg|Memory|NDRange|Pipe|Platform|Program|Sampler|SVMAllocator|SVMTraitAtomic|SVMTraitCoarse|SVMTraitFine|SVMTraitReadOnly|SVMTraitReadWrite|SVMTraitWriteOnly|UserEvent)\b/,
-               alias: 'keyword'
-       };
+
        // C++ includes everything from the OpenCL C host API plus the classes defined in cl2.h
-       Prism.languages.insertBefore('cpp', 'keyword', attributes);
+       if (Prism.languages.cpp) {
+               // Extracted from doxygen class list http://github.khronos.org/OpenCL-CLHPP/annotated.html
+               attributes['type-opencl-host-cpp'] = {
+                       pattern: /\b(?:Buffer|BufferGL|BufferRenderGL|CommandQueue|Context|Device|DeviceCommandQueue|EnqueueArgs|Event|Image|Image1D|Image1DArray|Image1DBuffer|Image2D|Image2DArray|Image2DGL|Image3D|Image3DGL|ImageFormat|ImageGL|Kernel|KernelFunctor|LocalSpaceArg|Memory|NDRange|Pipe|Platform|Program|Sampler|SVMAllocator|SVMTraitAtomic|SVMTraitCoarse|SVMTraitFine|SVMTraitReadOnly|SVMTraitReadWrite|SVMTraitWriteOnly|UserEvent)\b/,
+                       alias: 'keyword'
+               };
+
+               Prism.languages.insertBefore('cpp', 'keyword', attributes);
+       }
 }(Prism));
 
 return Prism; })
\ No newline at end of file
index 734a15bcf272fe96cc228e7928f904c205dd818d..b0ef2306436c3f22f1b2f4f63cc064ec300199f2 100644 (file)
@@ -10,18 +10,19 @@ Prism.languages.oz = {
                greedy: true,
                alias: 'builtin'
        },
-       'keyword': /[$_]|\[\]|\b(?:at|attr|case|catch|choice|class|cond|declare|define|dis|else(?:case|if)?|end|export|fail|false|feat|finally|from|fun|functor|if|import|in|local|lock|meth|nil|not|of|or|prepare|proc|prop|raise|require|self|skip|then|thread|true|try|unit)\b/,
+       'keyword': /\$|\[\]|\b(?:_|at|attr|case|catch|choice|class|cond|declare|define|dis|else(?:case|if)?|end|export|fail|false|feat|finally|from|fun|functor|if|import|in|local|lock|meth|nil|not|of|or|prepare|proc|prop|raise|require|self|skip|then|thread|true|try|unit)\b/,
        'function': [
-               /[a-z][A-Za-z\d]*(?=\()/,
+               /\b[a-z][A-Za-z\d]*(?=\()/,
                {
-                       pattern: /(\{)[A-Z][A-Za-z\d]*/,
+                       pattern: /(\{)[A-Z][A-Za-z\d]*\b/,
                        lookbehind: true
                }
        ],
-       'number': /\b(?:0[bx][\da-f]+|\d+\.?\d*(?:e~?\d+)?\b)|&(?:[^\\]|\\(?:\d{3}|.))/i,
+       'number': /\b(?:0[bx][\da-f]+|\d+\.?\d*(?:e~?\d+)?)\b|&(?:[^\\]|\\(?:\d{3}|.))/i,
        'variable': /\b[A-Z][A-Za-z\d]*|`(?:[^`\\]|\\.)+`/,
        'attr-name': /\w+(?=:)/,
        'operator': /:(?:=|::?)|<[-:=]?|=(?:=|<?:?)|>=?:?|\\=:?|!!?|[|#+\-*\/,~^@]|\b(?:andthen|div|mod|orelse)\b/,
        'punctuation': /[\[\](){}.:;?]/
 };
+
 return Prism; })
\ No newline at end of file
index 9d55b63c1aef1c582262a848cd9d3b3d991d7fb8..766d45054d75f088eb477e31c5f67638ce1dc11f 100644 (file)
@@ -23,10 +23,11 @@ Prism.languages.parigp = {
        'function': /\w[\w ]*?(?= *\()/,
        'number': {
                // The lookbehind and the negative lookahead prevent from breaking the .. operator
-               pattern: /((?:\. *\. *)?)(?:\d(?: *\d)*(?: *(?!\. *\.)\.(?: *\d)*)?|\. *\d(?: *\d)*)(?: *e *[+-]? *\d(?: *\d)*)?/i,
+               pattern: /((?:\. *\. *)?)(?:\b\d(?: *\d)*(?: *(?!\. *\.)\.(?: *\d)*)?|\. *\d(?: *\d)*)(?: *e *[+-]? *\d(?: *\d)*)?/i,
                lookbehind: true
        },
        'operator': /\. *\.|[*\/!](?: *=)?|%(?: *=|(?: *#)?(?: *')*)?|\+(?: *[+=])?|-(?: *[-=>])?|<(?:(?: *<)?(?: *=)?| *>)?|>(?: *>)?(?: *=)?|=(?: *=){0,2}|\\(?: *\/)?(?: *=)?|&(?: *&)?|\| *\||['#~^]/,
        'punctuation': /[\[\]{}().,:;|]/
 };
+
 return Prism; })
\ No newline at end of file
index a9988e66c68e59dc214c79198d556991dffa28cb..1c8cf75e8be0ab0888cbdea91948220abb619505 100644 (file)
@@ -12,7 +12,7 @@ Prism.languages.pascal = {
                /\/\/.*/
        ],
        'string': {
-               pattern: /(?:'(?:''|[^'\r\n])*'|#[&$%]?[a-f\d]+)+|\^[a-z]/i,
+               pattern: /(?:'(?:''|[^'\r\n])*'(?!')|#[&$%]?[a-f\d]+)+|\^[a-z]/i,
                greedy: true
        },
        'keyword': [
@@ -54,4 +54,5 @@ Prism.languages.pascal = {
 };
 
 Prism.languages.objectpascal = Prism.languages.pascal;
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-pascaligo.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-pascaligo.js
new file mode 100644 (file)
index 0000000..3431b6f
--- /dev/null
@@ -0,0 +1,65 @@
+define(["prism/prism"], function () {
+(function (Prism) {
+
+       // Pascaligo is a layer 2 smart contract language for the tezos blockchain
+
+       var braces = /\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\)/.source;
+       var type = /(?:\w+(?:<braces>)?|<braces>)/.source.replace(/<braces>/g, function () { return braces; });
+
+       var pascaligo = Prism.languages.pascaligo = {
+               'comment': /\(\*[\s\S]+?\*\)|\/\/.*/,
+               'string': {
+                       pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1|\^[a-z]/i,
+                       greedy: true
+               },
+               'class-name': [
+                       {
+                               pattern: RegExp(/(\btype\s+\w+\s+is\s+)<type>/.source.replace(/<type>/g, function () { return type; }), 'i'),
+                               lookbehind: true,
+                               inside: null // see below
+                       },
+                       {
+                               pattern: RegExp(/<type>(?=\s+is\b)/.source.replace(/<type>/g, function () { return type; }), 'i'),
+                               inside: null // see below
+                       },
+                       {
+                               pattern: RegExp(/(:\s*)<type>/.source.replace(/<type>/g, function () { return type; })),
+                               lookbehind: true,
+                               inside: null // see below
+                       }
+               ],
+               'keyword': {
+                       pattern: /(^|[^&])\b(?:begin|block|case|const|else|end|fail|for|from|function|if|is|nil|of|remove|return|skip|then|type|var|while|with)\b/i,
+                       lookbehind: true
+               },
+               'boolean': {
+                       pattern: /(^|[^&])\b(?:True|False)\b/i,
+                       lookbehind: true
+               },
+               'builtin': {
+                       pattern: /(^|[^&])\b(?:bool|int|list|map|nat|record|string|unit)\b/i,
+                       lookbehind: true
+               },
+               'function': /\w+(?=\s*\()/i,
+               'number': [
+                       // Hexadecimal, octal and binary
+                       /%[01]+|&[0-7]+|\$[a-f\d]+/i,
+                       // Decimal
+                       /\b\d+(?:\.\d+)?(?:e[+-]?\d+)?(?:mtz|n)?/i
+               ],
+               'operator': /->|=\/=|\.\.|\*\*|:=|<[<=>]?|>[>=]?|[+\-*\/]=?|[@^=|]|\b(?:and|mod|or)\b/,
+               'punctuation': /\(\.|\.\)|[()\[\]:;,.{}]/
+       };
+
+       var classNameInside = ['comment', 'keyword', 'builtin', 'operator', 'punctuation'].reduce(function (accum, key) {
+               accum[key] = pascaligo[key];
+               return accum;
+       }, {});
+
+       pascaligo["class-name"].forEach(function (p) {
+               p.inside = classNameInside;
+       });
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-pcaxis.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-pcaxis.js
new file mode 100644 (file)
index 0000000..bf79a1e
--- /dev/null
@@ -0,0 +1,56 @@
+define(["prism/prism"], function () {
+Prism.languages.pcaxis = {
+       'string': /"[^"]*"/,
+       'keyword': {
+               pattern: /((?:^|;)\s*)[-A-Z\d]+(?:\s*\[[-\w]+\])?(?:\s*\("[^"]*"(?:,\s*"[^"]*")*\))?(?=\s*=)/,
+               lookbehind: true,
+               greedy: true,
+               inside: {
+                       'keyword': /^[-A-Z\d]+/,
+                       'language': {
+                               pattern: /^(\s*)\[[-\w]+\]/,
+                               lookbehind: true,
+                               inside: {
+                                       'punctuation': /^\[|\]$/,
+                                       'property': /[-\w]+/
+                               }
+                       },
+                       'sub-key': {
+                               pattern: /^(\s*)[\s\S]+/,
+                               lookbehind: true,
+                               inside: {
+                                       'parameter': {
+                                               pattern: /"[^"]*"/,
+                                               alias: 'property'
+                                       },
+                                       'punctuation': /^\(|\)$|,/
+                               }
+                       }
+               }
+       },
+       'operator': /=/,
+       'tlist': {
+               pattern: /TLIST\s*\(\s*\w+(?:(?:\s*,\s*"[^"]*")+|\s*,\s*"[^"]*"-"[^"]*")?\s*\)/,
+               greedy: true,
+               inside: {
+                       'function': /^TLIST/,
+                       'property': {
+                               pattern: /^(\s*\(\s*)\w+/,
+                               lookbehind: true
+                       },
+                       'string': /"[^"]*"/,
+                       'punctuation': /[(),]/,
+                       'operator': /-/
+               }
+       },
+       'punctuation': /[;,]/,
+       'number': {
+               pattern: /(^|\s)\d+(?:\.\d+)?(?!\S)/,
+               lookbehind: true
+       },
+       'boolean': /YES|NO/,
+};
+
+Prism.languages.px = Prism.languages.pcaxis;
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-peoplecode.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-peoplecode.js
new file mode 100644 (file)
index 0000000..88ee086
--- /dev/null
@@ -0,0 +1,45 @@
+define(["prism/prism"], function () {
+Prism.languages.peoplecode = {
+       'comment': RegExp([
+               // C-style multiline comments
+               /\/\*[\s\S]*?\*\//.source,
+               // REM comments
+               /\bREM[^;]*;/.source,
+               // Nested <* *> comments
+               /<\*(?:[^<*]|\*(?!>)|<(?!\*)|<\*(?:(?!\*>)[\s\S])*\*>)*\*>/.source,
+               // /+ +/ comments
+               /\/\+[\s\S]*?\+\//.source,
+       ].join("|")),
+       'string': {
+               pattern: /'(?:''|[^'\r\n])*'(?!')|"(?:""|[^"\r\n])*"(?!")/,
+               greedy: true
+       },
+       'variable': /%\w+/,
+       'function-definition': {
+               pattern: /((?:^|[^\w-])(?:function|method)\s+)\w+/i,
+               lookbehind: true,
+               alias: 'function'
+       },
+       'class-name': {
+               pattern: /((?:^|[^-\w])(?:as|catch|class|component|create|extends|global|implements|instance|local|of|property|returns)\s+)\w+(?::\w+)*/i,
+               lookbehind: true,
+               inside: {
+                       'punctuation': /:/
+               }
+       },
+       'keyword': /\b(?:abstract|alias|as|catch|class|component|constant|create|declare|else|end-(?:class|evaluate|for|function|get|if|method|set|try|while)|evaluate|extends|for|function|get|global|implements|import|instance|if|library|local|method|null|of|out|peopleCode|private|program|property|protected|readonly|ref|repeat|returns?|set|step|then|throw|to|try|until|value|when(?:-other)?|while)\b/i,
+       'operator-keyword': {
+               pattern: /\b(?:and|not|or)\b/i,
+               alias: 'operator'
+       },
+       'function': /[_a-z]\w*(?=\s*\()/i,
+
+       'boolean': /\b(?:false|true)\b/i,
+       'number': /\b\d+(?:\.\d+)?\b/,
+       'operator': /<>|[<>]=?|!=|\*\*|[-+*/|=@]/,
+       'punctuation': /[:.;,()[\]]/
+};
+
+Prism.languages.pcode = Prism.languages.peoplecode;
+
+return Prism; })
\ No newline at end of file
index 30c8e8d914b1e49812034702454f7c2b1838b19a..afa8d51893ac0905c8e1c11dd69419b58f5e2137 100644 (file)
@@ -18,31 +18,31 @@ Prism.languages.perl = {
                        pattern: /\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
                        greedy: true
                },
-       
+
                // q a...a
                {
                        pattern: /\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
                        greedy: true
                },
-       
+
                // q(...)
                {
                        pattern: /\b(?:q|qq|qx|qw)\s*\((?:[^()\\]|\\[\s\S])*\)/,
                        greedy: true
                },
-       
+
                // q{...}
                {
                        pattern: /\b(?:q|qq|qx|qw)\s*\{(?:[^{}\\]|\\[\s\S])*\}/,
                        greedy: true
                },
-       
+
                // q[...]
                {
                        pattern: /\b(?:q|qq|qx|qw)\s*\[(?:[^[\]\\]|\\[\s\S])*\]/,
                        greedy: true
                },
-       
+
                // q<...>
                {
                        pattern: /\b(?:q|qq|qx|qw)\s*<(?:[^<>\\]|\\[\s\S])*>/,
@@ -68,31 +68,31 @@ Prism.languages.perl = {
                        pattern: /\b(?:m|qr)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
                        greedy: true
                },
-       
+
                // m a...a
                {
                        pattern: /\b(?:m|qr)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
                        greedy: true
                },
-       
+
                // m(...)
                {
                        pattern: /\b(?:m|qr)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngc]*/,
                        greedy: true
                },
-       
+
                // m{...}
                {
                        pattern: /\b(?:m|qr)\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngc]*/,
                        greedy: true
                },
-       
+
                // m[...]
                {
                        pattern: /\b(?:m|qr)\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngc]*/,
                        greedy: true
                },
-       
+
                // m<...>
                {
                        pattern: /\b(?:m|qr)\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngc]*/,
@@ -107,48 +107,48 @@ Prism.languages.perl = {
                        lookbehind: true,
                        greedy: true
                },
-       
+
                // s a...a...a
                {
                        pattern: /(^|[^-]\b)(?:s|tr|y)\s+([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
                        lookbehind: true,
                        greedy: true
                },
-       
+
                // s(...)(...)
                {
                        pattern: /(^|[^-]\b)(?:s|tr|y)\s*\((?:[^()\\]|\\[\s\S])*\)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngcer]*/,
                        lookbehind: true,
                        greedy: true
                },
-       
+
                // s{...}{...}
                {
                        pattern: /(^|[^-]\b)(?:s|tr|y)\s*\{(?:[^{}\\]|\\[\s\S])*\}\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngcer]*/,
                        lookbehind: true,
                        greedy: true
                },
-       
+
                // s[...][...]
                {
                        pattern: /(^|[^-]\b)(?:s|tr|y)\s*\[(?:[^[\]\\]|\\[\s\S])*\]\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngcer]*/,
                        lookbehind: true,
                        greedy: true
                },
-       
+
                // s<...><...>
                {
                        pattern: /(^|[^-]\b)(?:s|tr|y)\s*<(?:[^<>\\]|\\[\s\S])*>\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngcer]*/,
                        lookbehind: true,
                        greedy: true
                },
-       
+
                // /.../
                // The look-ahead tries to prevent two divisions on
                // the same line from being highlighted as regex.
                // This does not support multi-line regex.
                {
-                       pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/,
+                       pattern: /\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/,
                        greedy: true
                }
        ],
index 2f5a9f54826d22c699609ced21e3ed0f5c429114..ab4210b1628aed64054c74167ae3dd58854cb9c0 100644 (file)
@@ -63,16 +63,14 @@ define(["prism/prism","prism/components/prism-clike","prism/components/prism-mar
        });
 
        var string_interpolation = {
-               pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,
+               pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)*)/,
                lookbehind: true,
-               inside: {
-                       rest: Prism.languages.php
-               }
+               inside: Prism.languages.php
        };
 
        Prism.languages.insertBefore('php', 'string', {
                'nowdoc-string': {
-                       pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/,
+                       pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,
                        greedy: true,
                        alias: 'string',
                        inside: {
@@ -86,7 +84,7 @@ define(["prism/prism","prism/components/prism-clike","prism/components/prism-mar
                        }
                },
                'heredoc-string': {
-                       pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i,
+                       pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,
                        greedy: true,
                        alias: 'string',
                        inside: {
@@ -122,7 +120,7 @@ define(["prism/prism","prism/components/prism-clike","prism/components/prism-mar
                        return;
                }
 
-               var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig;
+               var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig;
                Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
        });
 
index db908791b61e7bf5a3f4ffe70c72291c95a61af0..056a39f7a8aa0f49cd8cce3d6df7e22c96b65aaf 100644 (file)
@@ -1,7 +1,7 @@
 define(["prism/prism","prism/components/prism-php","prism/components/prism-javadoclike"], function () {
 (function (Prism) {
 
-       var typeExpression = /(?:[a-zA-Z]\w*|[|\\[\]])+/.source;
+       var typeExpression = /(?:\b[a-zA-Z]\w*|[|\\[\]])+/.source;
 
        Prism.languages.phpdoc = Prism.languages.extend('javadoclike', {
                'parameter': {
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-powerquery.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-powerquery.js
new file mode 100644 (file)
index 0000000..c894c24
--- /dev/null
@@ -0,0 +1,57 @@
+define(["prism/prism"], function () {
+// https://docs.microsoft.com/en-us/powerquery-m/power-query-m-language-specification
+
+Prism.languages.powerquery = {
+    'comment': {
+        pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:\/\/).*)/,
+        lookbehind: true
+    },
+    'quoted-identifier': {
+        pattern: /#"(?:[^"\r\n]|"")*"(?!")/,
+        greedy: true,
+        alias: 'variable'
+    },
+    'string': {
+        pattern: /"(?:[^"\r\n]|"")*"(?!")/,
+        greedy: true
+    },
+    'constant': [
+        /\bDay\.(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)\b/,
+        /\bTraceLevel\.(?:Critical|Error|Information|Verbose|Warning)\b/,
+        /\bOccurrence\.(?:First|Last|All)\b/,
+        /\bOrder\.(?:Ascending|Descending)\b/,
+        /\bRoundingMode\.(?:AwayFromZero|Down|ToEven|TowardZero|Up)\b/,
+        /\bMissingField\.(?:Error|Ignore|UseNull)\b/,
+        /\bQuoteStyle\.(?:Csv|None)\b/,
+        /\bJoinKind\.(?:Inner|LeftOuter|RightOuter|FullOuter|LeftAnti|RightAnti)\b/,
+        /\bGroupKind\.(?:Global|Local)\b/,
+        /\bExtraValues\.(?:List|Ignore|Error)\b/,
+        /\bJoinAlgorithm\.(?:Dynamic|PairwiseHash|SortMerge|LeftHash|RightHash|LeftIndex|RightIndex)\b/,
+        /\bJoinSide\.(?:Left|Right)\b/,
+        /\bPrecision\.(?:Double|Decimal)\b/,
+        /\bRelativePosition\.From(?:End|Start)\b/,
+        /\bTextEncoding\.(?:Ascii|BigEndianUnicode|Unicode|Utf8|Utf16|Windows)\b/,
+        /\b(?:Any|Binary|Date|DateTime|DateTimeZone|Duration|Int8|Int16|Int32|Int64|Function|List|Logical|None|Number|Record|Table|Text|Time)\.Type\b/,
+        /\bnull\b/
+    ],
+    'boolean': /\b(?:true|false)\b/,
+    'keyword': /\b(?:and|as|each|else|error|if|in|is|let|meta|not|nullable|optional|or|otherwise|section|shared|then|try|type)\b|#(?:binary|date|datetime|datetimezone|duration|infinity|nan|sections|shared|table|time)\b/,
+    'function': {
+        pattern: /(^|[^#\w.])(?!\d)[\w.]+(?=\s*\()/,
+        lookbehind: true
+    },
+    'data-type': {
+        pattern: /\b(?:any|anynonnull|binary|date|datetime|datetimezone|duration|function|list|logical|none|number|record|table|text|time|type)\b/,
+        alias: 'variable'
+    },
+    'number': {
+        pattern: /\b0x[\da-f]+\b|(?:[+-]?(?:\b\d+\.)?\b\d+|[+-]\.\d+|(^|[^.])\B\.\d+)(?:e[+-]?\d+)?\b/i,
+        lookbehind: true
+    },
+    'operator': /[-+*\/&?@^]|<(?:=>?|>)?|>=?|=>?|\.\.\.?/,
+    'punctuation': /[,;\[\](){}]/
+};
+
+Prism.languages.pq = Prism.languages['powerquery'];
+Prism.languages.mscript = Prism.languages['powerquery']
+return Prism; })
\ No newline at end of file
index 386e109756525205be046f040a2fc245d8b52e45..5571e0a529f9ad464b23faa4143d2e94641403e0 100644 (file)
@@ -19,7 +19,7 @@ define(["prism/prism"], function () {
                                inside: {
                                        'function': {
                                                // Allow for one level of nesting
-                                               pattern: /(^|[^`])\$\((?:\$\(.*?\)|(?!\$\()[^\r\n)])*\)/,
+                                               pattern: /(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,
                                                lookbehind: true,
                                                // Populated at end of file
                                                inside: {}
@@ -35,18 +35,18 @@ define(["prism/prism"], function () {
                // Supports two levels of nested brackets (e.g. `[OutputType([System.Collections.Generic.List[int]])]`)
                'namespace': /\[[a-z](?:\[(?:\[[^\]]*]|[^\[\]])*]|[^\[\]])*]/i,
                'boolean': /\$(?:true|false)\b/i,
-               'variable': /\$\w+\b/i,
+               'variable': /\$\w+\b/,
                // Cmdlets and aliases. Aliases should come last, otherwise "write" gets preferred over "write-host" for example
                // Get-Command | ?{ $_.ModuleName -match "Microsoft.PowerShell.(Util|Core|Management)" }
                // Get-Alias | ?{ $_.ReferencedCommand.Module.Name -match "Microsoft.PowerShell.(Util|Core|Management)" }
                'function': [
-                       /\b(?:Add-(?:Computer|Content|History|Member|PSSnapin|Type)|Checkpoint-Computer|Clear-(?:Content|EventLog|History|Item|ItemProperty|Variable)|Compare-Object|Complete-Transaction|Connect-PSSession|ConvertFrom-(?:Csv|Json|StringData)|Convert-Path|ConvertTo-(?:Csv|Html|Json|Xml)|Copy-(?:Item|ItemProperty)|Debug-Process|Disable-(?:ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Disconnect-PSSession|Enable-(?:ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Enter-PSSession|Exit-PSSession|Export-(?:Alias|Clixml|Console|Csv|FormatData|ModuleMember|PSSession)|ForEach-Object|Format-(?:Custom|List|Table|Wide)|Get-(?:Alias|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Culture|Date|Event|EventLog|EventSubscriber|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job|Location|Member|Module|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|WmiObject)|Group-Object|Import-(?:Alias|Clixml|Csv|LocalizedData|Module|PSSession)|Invoke-(?:Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)|Join-Path|Limit-EventLog|Measure-(?:Command|Object)|Move-(?:Item|ItemProperty)|New-(?:Alias|Event|EventLog|Item|ItemProperty|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy)|Out-(?:Default|File|GridView|Host|Null|Printer|String)|Pop-Location|Push-Location|Read-Host|Receive-(?:Job|PSSession)|Register-(?:EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)|Remove-(?:Computer|Event|EventLog|Item|ItemProperty|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)|Rename-(?:Computer|Item|ItemProperty)|Reset-ComputerMachinePassword|Resolve-Path|Restart-(?:Computer|Service)|Restore-Computer|Resume-(?:Job|Service)|Save-Help|Select-(?:Object|String|Xml)|Send-MailMessage|Set-(?:Alias|Content|Date|Item|ItemProperty|Location|PSBreakpoint|PSDebug|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)|Show-(?:Command|ControlPanelItem|EventLog)|Sort-Object|Split-Path|Start-(?:Job|Process|Service|Sleep|Transaction)|Stop-(?:Computer|Job|Process|Service)|Suspend-(?:Job|Service)|Tee-Object|Test-(?:ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)|Trace-Command|Unblock-File|Undo-Transaction|Unregister-(?:Event|PSSessionConfiguration)|Update-(?:FormatData|Help|List|TypeData)|Use-Transaction|Wait-(?:Event|Job|Process)|Where-Object|Write-(?:Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning))\b/i,
+                       /\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,
                        /\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i
                ],
                // per http://technet.microsoft.com/en-us/library/hh847744.aspx
                'keyword': /\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,
                'operator': {
-                       pattern: /(\W?)(?:!|-(eq|ne|gt|ge|lt|le|sh[lr]|not|b?(?:and|x?or)|(?:Not)?(?:Like|Match|Contains|In)|Replace|Join|is(?:Not)?|as)\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,
+                       pattern: /(\W?)(?:!|-(?:eq|ne|gt|ge|lt|le|sh[lr]|not|b?(?:and|x?or)|(?:Not)?(?:Like|Match|Contains|In)|Replace|Join|is(?:Not)?|as)\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,
                        lookbehind: true
                },
                'punctuation': /[|{}[\];(),.]/
index df410431d84c6de405d0ea2c4da9bb0ae2c29e30..1ee47268885156a62a34ca13ec62c9d3ff28776c 100644 (file)
@@ -1,11 +1,46 @@
 define(["prism/prism","prism/components/prism-clike"], function () {
-Prism.languages.protobuf = Prism.languages.extend('clike', {
-       keyword: /\b(?:package|import|message|enum)\b/,
-       builtin: /\b(?:required|repeated|optional|reserved)\b/,
-       primitive: {
-               pattern: /\b(?:double|float|int32|int64|uint32|uint64|sint32|sint64|fixed32|fixed64|sfixed32|sfixed64|bool|string|bytes)\b/,
-               alias: 'symbol'
-       }
-});
+(function (Prism) {
+
+       var builtinTypes = /\b(?:double|float|[su]?int(?:32|64)|s?fixed(?:32|64)|bool|string|bytes)\b/;
+
+       Prism.languages.protobuf = Prism.languages.extend('clike', {
+               'class-name': [
+                       {
+                               pattern: /(\b(?:enum|extend|message|service)\s+)[A-Za-z_]\w*(?=\s*\{)/,
+                               lookbehind: true
+                       },
+                       {
+                               pattern: /(\b(?:rpc\s+\w+|returns)\s*\(\s*(?:stream\s+)?)\.?[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*(?=\s*\))/,
+                               lookbehind: true
+                       }
+               ],
+               'keyword': /\b(?:enum|extend|extensions|import|message|oneof|option|optional|package|public|repeated|required|reserved|returns|rpc(?=\s+\w)|service|stream|syntax|to)\b(?!\s*=\s*\d)/,
+               'function': /[a-z_]\w*(?=\s*\()/i
+       });
+
+       Prism.languages.insertBefore('protobuf', 'operator', {
+               'map': {
+                       pattern: /\bmap<\s*[\w.]+\s*,\s*[\w.]+\s*>(?=\s+[a-z_]\w*\s*[=;])/i,
+                       alias: 'class-name',
+                       inside: {
+                               'punctuation': /[<>.,]/,
+                               'builtin': builtinTypes
+                       }
+               },
+               'builtin': builtinTypes,
+               'positional-class-name': {
+                       pattern: /(?:\b|\B\.)[a-z_]\w*(?:\.[a-z_]\w*)*(?=\s+[a-z_]\w*\s*[=;])/i,
+                       alias: 'class-name',
+                       inside: {
+                               'punctuation': /\./
+                       }
+               },
+               'annotation': {
+                       pattern: /(\[\s*)[a-z_]\w*(?=\s*=)/i,
+                       lookbehind: true
+               }
+       });
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
index 83af1893feb30c279b89d62b95f5cb8f6f5e5c08..da580262fb4d8ae0fe7f2ad4cd7033439ba3b8c5 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-markup","prism/components/prism-javascript","prism/components/prism-coffeescript","prism/components/prism-ejs","prism/components/prism-handlebars","prism/components/prism-less","prism/components/prism-livescript","prism/components/prism-markdown","prism/components/prism-scss","prism/components/prism-stylus","prism/components/prism-twig"], function () {
+define(["prism/prism","prism/components/prism-markup","prism/components/prism-javascript"], function () {
 (function(Prism) {
        // TODO:
        // - Add CSS highlighting inside <style> tags
@@ -23,9 +23,7 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-ja
                'multiline-script': {
                        pattern: /(^([\t ]*)script\b.*\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
                        lookbehind: true,
-                       inside: {
-                               rest: Prism.languages.javascript
-                       }
+                       inside: Prism.languages.javascript
                },
 
                // See at the end of the file for known filters
@@ -47,9 +45,7 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-ja
                'markup': {
                        pattern: /(^[\t ]*)<.+/m,
                        lookbehind: true,
-                       inside: {
-                               rest: Prism.languages.markup
-                       }
+                       inside: Prism.languages.markup
                },
                'doctype': {
                        pattern: /((?:^|\n)[\t ]*)doctype(?: .+)?/,
@@ -99,16 +95,14 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-ja
                                                pattern: /^\+\w+/,
                                                alias: 'function'
                                        },
-                                       'rest': Prism.languages.javascript
+                                       rest: Prism.languages.javascript
                                }
                        }
                ],
                'script': {
                        pattern: /(^[\t ]*script(?:(?:&[^(]+)?\([^)]+\))*[\t ]+).+/m,
                        lookbehind: true,
-                       inside: {
-                               rest: Prism.languages.javascript
-                       }
+                       inside: Prism.languages.javascript
                },
 
                'plain-text': {
@@ -122,9 +116,7 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-ja
                                'attributes': [
                                        {
                                                pattern: /&[^(]+\([^)]+\)/,
-                                               inside: {
-                                                       rest: Prism.languages.javascript
-                                               }
+                                               inside: Prism.languages.javascript
                                        },
                                        {
                                                pattern: /\([^)]+\)/,
@@ -132,25 +124,23 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-ja
                                                        'attr-value': {
                                                                pattern: /(=\s*)(?:\{[^}]*\}|[^,)\r\n]+)/,
                                                                lookbehind: true,
-                                                               inside: {
-                                                                       rest: Prism.languages.javascript
-                                                               }
+                                                               inside: Prism.languages.javascript
                                                        },
                                                        'attr-name': /[\w-]+(?=\s*!?=|\s*[,)])/,
                                                        'punctuation': /[!=(),]+/
                                                }
                                        }
                                ],
-                               'punctuation': /:/
+                               'punctuation': /:/,
+                               'attr-id': /#[\w\-]+/,
+                               'attr-class': /\.[\w\-]+/
                        }
                },
                'code': [
                        {
                                pattern: /(^[\t ]*(?:-|!?=)).+/m,
                                lookbehind: true,
-                               inside: {
-                                       rest: Prism.languages.javascript
-                               }
+                               inside: Prism.languages.javascript
                        }
                ],
                'punctuation': /[.\-!=|]+/
@@ -176,7 +166,7 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-ja
                filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
                if (Prism.languages[filter.language]) {
                        all_filters['filter-' + filter.filter] = {
-                               pattern: RegExp(filter_pattern.replace('{{filter_name}}', filter.filter), 'm'),
+                               pattern: RegExp(filter_pattern.replace('{{filter_name}}', function () { return filter.filter; }), 'm'),
                                lookbehind: true,
                                inside: {
                                        'filter-name': {
index 0372d2ee86b2c655688dd207588f986757283467..40d5cb06d75045fe73f8a500381c307642a0a75a 100644 (file)
@@ -1,5 +1,7 @@
-define(["prism/prism","prism/components/prism-c","prism/components/prism-cpp","prism/components/prism-fortran"], function () {
+define(["prism/prism"], function () {
 (function (Prism) {
+       // https://agraef.github.io/pure-docs/pure.html#lexical-matters
+
        Prism.languages.pure = {
                'comment': [
                        {
@@ -43,7 +45,7 @@ define(["prism/prism","prism/components/prism-c","prism/components/prism-cpp","p
                        alias: 'builtin'
                },
                // Any combination of operator chars can be an operator
-               'operator': /(?=\b_|[^_])[!"#$%&'*+,\-.\/:<=>?@\\^_`|~\u00a1-\u00bf\u00d7-\u00f7\u20d0-\u2bff]+|\b(?:and|div|mod|not|or)\b/,
+               'operator': /(?:[!"#$%&'*+,\-.\/:<=>?@\\^`|~\u00a1-\u00bf\u00d7-\u00f7\u20d0-\u2bff]|\b_+\b)+|\b(?:and|div|mod|not|or)\b/,
                // FIXME: How can we prevent | and , to be highlighted as operator when they are used alone?
                'punctuation': /[(){}\[\];,|]/
        };
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-purebasic.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-purebasic.js
new file mode 100644 (file)
index 0000000..a77fa0e
--- /dev/null
@@ -0,0 +1,73 @@
+define(["prism/prism","prism/components/prism-clike"], function () {
+/*
+Original Code by Bas Groothedde
+!!MANY THANKS!! I never would have made this, regex and me will never be best friends ;)
+==> https://codepen.io/ImagineProgramming/details/JYydBy/
+slightly changed to pass all tests
+*/
+
+
+// PureBasic support, steal stuff from ansi-c
+Prism.languages.purebasic = Prism.languages.extend('clike', {
+       'comment': /;.*/,
+       'keyword': /\b(?:declarecdll|declaredll|compilerselect|compilercase|compilerdefault|compilerendselect|compilererror|enableexplicit|disableexplicit|not|and|or|xor|calldebugger|debuglevel|enabledebugger|disabledebugger|restore|read|includepath|includebinary|threaded|runtime|with|endwith|structureunion|endstructureunion|align|newlist|newmap|interface|endinterface|extends|enumeration|endenumeration|swap|foreach|continue|fakereturn|goto|gosub|return|break|module|endmodule|declaremodule|enddeclaremodule|declare|declarec|prototype|prototypec|enableasm|disableasm|dim|redim|data|datasection|enddatasection|to|procedurereturn|debug|default|case|select|endselect|as|import|endimport|importc|compilerif|compilerelse|compilerendif|compilerelseif|end|structure|endstructure|while|wend|for|next|step|if|else|elseif|endif|repeat|until|procedure|proceduredll|procedurec|procedurecdll|endprocedure|protected|shared|static|global|define|includefile|xincludefile|macro|endmacro)\b/i,
+       'function': /\b\w+(?:\.\w+)?\s*(?=\()/,
+       'number': /(?:\$[\da-f]+|\b-?\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
+       'operator': /(?:@\*?|\?|\*)\w+|-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*/@]/
+});
+
+Prism.languages.insertBefore('purebasic', 'keyword', {
+       'tag': /#\w+/,
+       'asm': {
+               pattern: /(^\s*)!.*/m,
+               lookbehind: true,
+               alias: 'tag',
+               inside: {
+                       'comment': /;.*/,
+                       'string': {
+                               pattern: /(["'`])(?:\\.|(?!\1)[^\\\r\n])*\1/,
+                               greedy: true
+                       },
+                       // Anonymous label references, i.e.: jmp @b
+                       'label-reference-anonymous': {
+                               pattern: /(\s*!\s*j[a-z]+\s+)@[fb]/i,
+                               lookbehind: true,
+                               alias: 'fasm-label'
+                       },
+                       // Named label reference, i.e.: jne label1
+                       'label-reference-addressed': {
+                               pattern: /(\s*!\s*j[a-z]+\s+)[A-Z._?$@][\w.?$@~#]*/i,
+                               lookbehind: true,
+                               alias: 'fasm-label'
+                       },
+                       'function': {
+                               pattern: /^(\s*!\s*)[\da-z]+(?=\s|$)/im,
+                               lookbehind: true
+                       },
+                       'function-inline': {
+                               pattern: /(\s*:\s*)[\da-z]+(?=\s)/i,
+                               lookbehind: true,
+                               alias: 'function'
+                       },
+                       'label': {
+                               pattern: /^(\s*!\s*)[A-Za-z._?$@][\w.?$@~#]*(?=:)/m,
+                               lookbehind: true,
+                               alias: 'fasm-label'
+                       },
+                       'keyword': [
+                               /(?:extern|extern|global)[^;\r\n]*/i,
+                               /(?:CPU|FLOAT|DEFAULT).*/
+                       ],
+                       'register': /\b(?:st\d|[xyz]mm\d\d?|[cdt]r\d|r\d\d?[bwd]?|[er]?[abcd]x|[abcd][hl]|[er]?(?:bp|sp|si|di)|[cdefgs]s|mm\d+)\b/i,
+                       'number': /(?:\b|-|(?=\$))(?:0[hx][\da-f]*\.?[\da-f]+(?:p[+-]?\d+)?|\d[\da-f]+[hx]|\$\d[\da-f]*|0[oq][0-7]+|[0-7]+[oq]|0[by][01]+|[01]+[by]|0[dt]\d+|\d*\.?\d+(?:\.?e[+-]?\d+)?[dt]?)\b/i,
+                       'operator': /[\[\]*+\-/%<>=&|$!,.:]/
+               }
+       }
+});
+
+delete Prism.languages.purebasic['class-name'];
+delete Prism.languages.purebasic['boolean'];
+
+Prism.languages.pbfasm = Prism.languages['purebasic'];
+
+return Prism; })
\ No newline at end of file
index 6ae2113c158239ca2c3caa67c5126aa9c2d564d9..1f2edbe3e1804135f58dd1f3e5d4fbccf0cab196 100644 (file)
@@ -5,7 +5,7 @@ Prism.languages.python = {
                lookbehind: true
        },
        'string-interpolation': {
-               pattern: /(?:f|rf|fr)(?:("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
+               pattern: /(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
                greedy: true,
                inside: {
                        'interpolation': {
@@ -28,7 +28,7 @@ Prism.languages.python = {
                }
        },
        'triple-quoted-string': {
-               pattern: /(?:[rub]|rb|br)?("""|''')[\s\S]+?\1/i,
+               pattern: /(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i,
                greedy: true,
                alias: 'string'
        },
@@ -45,7 +45,7 @@ Prism.languages.python = {
                lookbehind: true
        },
        'decorator': {
-               pattern: /(^\s*)@\w+(?:\.\w+)*/i,
+               pattern: /(^\s*)@\w+(?:\.\w+)*/im,
                lookbehind: true,
                alias: ['annotation', 'punctuation'],
                inside: {
@@ -63,4 +63,5 @@ Prism.languages.python = {
 Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python;
 
 Prism.languages.py = Prism.languages.python;
+
 return Prism; })
\ No newline at end of file
index 7bde86726264eac45d0585a8cdad7fa663cd8d81..1bb2151ca89f31a64bf878bd8c5d4c2283d0860e 100644 (file)
@@ -45,9 +45,10 @@ Prism.languages.q = {
                alias: 'function'
        },
        'verb': {
-               pattern: /(?:\B\.\B|\b[01]:|<[=>]?|>=?|[:+\-*%,!?_~=|$&#@^]):?/,
+               pattern: /(?:\B\.\B|\b[01]:|<[=>]?|>=?|[:+\-*%,!?~=|$&#@^]):?|\b_\b:?/,
                alias: 'operator'
        },
        'punctuation': /[(){}\[\];.]/
 };
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-qml.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-qml.js
new file mode 100644 (file)
index 0000000..41ea1cf
--- /dev/null
@@ -0,0 +1,61 @@
+define(["prism/prism","prism/components/prism-javascript"], function () {
+(function (Prism) {
+
+       var jsString = /"(?:\\.|[^\\"\r\n])*"|'(?:\\.|[^\\'\r\n])*'/.source;
+       var jsComment = /\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))*\*\//.source;
+
+       var jsExpr = /(?:[^\\()[\]{}"'/]|<string>|\/(?![*/])|<comment>|\(<expr>*\)|\[<expr>*\]|\{<expr>*\}|\\[\s\S])/
+               .source.replace(/<string>/g, function () { return jsString; }).replace(/<comment>/g, function () { return jsComment; });
+
+       // the pattern will blow up, so only a few iterations
+       for (var i = 0; i < 2; i++) {
+               jsExpr = jsExpr.replace(/<expr>/g, function () { return jsExpr; });
+       }
+       jsExpr = jsExpr.replace(/<expr>/g, '[^\\s\\S]');
+
+
+       Prism.languages.qml = {
+               'comment': {
+                       pattern: /\/\/.*|\/\*[\s\S]*?\*\//,
+                       greedy: true
+               },
+               'javascript-function': {
+                       pattern: RegExp(/((?:^|;)[ \t]*)function\s+[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*\(<js>*\)\s*\{<js>*\}/.source.replace(/<js>/g, function () { return jsExpr; }), 'm'),
+                       lookbehind: true,
+                       greedy: true,
+                       alias: 'language-javascript',
+                       inside: Prism.languages.javascript
+               },
+               'class-name': {
+                       pattern: /((?:^|[:;])[ \t]*)(?!\d)\w+(?=[ \t]*\{|[ \t]+on\b)/m,
+                       lookbehind: true
+               },
+               'property': [
+                       {
+                               pattern: /((?:^|[;{])[ \t]*)(?!\d)\w+(?:\.\w+)*(?=[ \t]*:)/m,
+                               lookbehind: true
+                       },
+                       {
+                               pattern: /((?:^|[;{])[ \t]*)property[ \t]+(?!\d)\w+(?:\.\w+)*[ \t]+(?!\d)\w+(?:\.\w+)*(?=[ \t]*:)/m,
+                               lookbehind: true,
+                               inside: {
+                                       'keyword': /^property/,
+                                       'property': /\w+(?:\.\w+)*/
+                               }
+                       }
+               ],
+               'javascript-expression': {
+                       pattern: RegExp(/(:[ \t]*)(?![\s;}[])(?:(?!$|[;}])<js>)+/.source.replace(/<js>/g, function () { return jsExpr; }), 'm'),
+                       lookbehind: true,
+                       greedy: true,
+                       alias: 'language-javascript',
+                       inside: Prism.languages.javascript
+               },
+               'string': /"(?:\\.|[^\\"\r\n])*"/,
+               'keyword': /\b(?:as|import|on)\b/,
+               'punctuation': /[{}[\]:;,]/
+       };
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 9056a44634d2be97491f5fd8b25d5ca676769795..8735bcadffeed9b060e6ac1b75956d0078ec887f 100644 (file)
@@ -6,7 +6,7 @@ Prism.languages.qore = Prism.languages.extend('clike', {
        },
        // Overridden to allow unescaped multi-line strings
        'string': {
-               pattern: /("|')(\\[\s\S]|(?!\1)[^\\])*\1/,
+               pattern: /("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/,
                greedy: true
        },
        'variable': /\$(?!\d)\w+\b/,
@@ -19,4 +19,5 @@ Prism.languages.qore = Prism.languages.extend('clike', {
        },
        'function': /\$?\b(?!\d)\w+(?=\()/
 });
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-racket.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-racket.js
new file mode 100644 (file)
index 0000000..28d97fc
--- /dev/null
@@ -0,0 +1,68 @@
+define(["prism/prism","prism/components/prism-scheme"], function () {
+Prism.languages.racket = Prism.languages.extend('scheme', {
+       'lambda-parameter': {
+               // the racket lambda syntax is a lot more complex, so we won't even attempt to capture it.
+               // this will just prevent false positives of the `function` pattern
+               pattern: /(\(lambda\s+\()[^()'\s]+/,
+               lookbehind: true
+       }
+});
+
+// Add brackets to racket
+// The basic idea here is to go through all pattens of Scheme and replace all occurrences of "(" with the union of "("
+// and "["; Similar for ")". This is a bit tricky because "(" can be escaped or inside a character set. Both cases
+// have to be handled differently and, of course, we don't want to destroy groups, so we can only replace literal "("
+// and ")".
+// To do this, we use a regular expression which will parse any JS regular expression. It works because regexes are
+// matches from left to right and already matched text cannot be matched again. We use this to first capture all
+// escaped characters (not really, we don't get escape sequences but we don't need them). Because we already captured
+// all escaped characters, we know that any "[" character is the start of a character set, so we match that character
+// set whole.
+// With the regex parsed, we only have to replace all escaped "(" (they cannot be unescaped outside of character sets)
+// with /[([]/ and replace all "(" inside character sets.
+// Note: This method does not work for "(" that are escaped like this /\x28/ or this /\u0028/.
+Prism.languages.DFS(Prism.languages.racket, function (key, value) {
+       if (Prism.util.type(value) === 'RegExp') {
+               var source = value.source.replace(/\\(.)|\[\^?((?:\\.|[^\\\]])*)\]/g, function (m, g1, g2) {
+                       if (g1) {
+                               if (g1 === '(') {
+                                       // replace all '(' characters outside character sets
+                                       return '[([]';
+                               }
+                               if (g1 === ')') {
+                                       // replace all ')' characters outside character sets
+                                       return '[)\\]]';
+                               }
+                       }
+                       if (g2) {
+                               var prefix = m[1] === '^' ? '[^' : '[';
+                               return prefix + g2.replace(/\\(.)|[()]/g, function (m, g1) {
+                                       if (m === '(' || g1 === '(') {
+                                               // replace all '(' characters inside character sets
+                                               return '([';
+                                       }
+                                       if (m === ')' || g1 === ')') {
+                                               // replace all ')' characters inside character sets
+                                               return ')\\]';
+                                       }
+                                       return m;
+                               }) + ']';
+                       }
+                       return m;
+               });
+
+               this[key] = RegExp(source, value.flags);
+       }
+});
+
+Prism.languages.insertBefore('racket', 'string', {
+       'lang': {
+               pattern: /^#lang.+/m,
+               greedy: true,
+               alias: 'keyword'
+       }
+});
+
+Prism.languages.rkt = Prism.languages.racket;
+
+return Prism; })
\ No newline at end of file
index 604f558d85fb1df0382f035f5dab665d4157fdcd..d35385d5c60aa2105cd462238ee8b43fe76b954d 100644 (file)
@@ -1,9 +1,5 @@
 define(["prism/prism","prism/components/prism-clike"], function () {
 Prism.languages.reason = Prism.languages.extend('clike', {
-       'comment': {
-               pattern: /(^|[^\\])\/\*[\s\S]*?\*\//,
-               lookbehind: true
-       },
        'string': {
                pattern: /"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,
                greedy: true
@@ -31,4 +27,5 @@ Prism.languages.insertBefore('reason', 'class-name', {
 
 // We can't match functions property, so let's not even try.
 delete Prism.languages.reason.function;
+
 return Prism; })
\ No newline at end of file
index 623a67b47f9abb7d2ac79b50263971331708d4f8..5316baf6f42cecda4a248f1b056155d0708be450 100644 (file)
@@ -1,12 +1,19 @@
-define(["prism/prism","prism/components/prism-actionscript","prism/components/prism-coffeescript","prism/components/prism-flow","prism/components/prism-javascript","prism/components/prism-typescript","prism/components/prism-vala"], function () {
+define(["prism/prism"], function () {
 (function (Prism) {
 
        var specialEscape = {
                pattern: /\\[\\(){}[\]^$+*?|.]/,
                alias: 'escape'
        };
-       var escape = /\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|c[a-zA-Z]|0[0-7]{0,2}|[123][0-7]{2}|.)/
-       var charClass = /\\[wsd]|\.|\\p{[^{}]+}/i
+       var escape = /\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|c[a-zA-Z]|0[0-7]{0,2}|[123][0-7]{2}|.)/;
+       var charClass = {
+               pattern: /\.|\\[wsd]|\\p{[^{}]+}/i,
+               alias: 'class-name'
+       };
+       var charClassWithoutDot = {
+               pattern: /\\[wsd]|\\p{[^{}]+}/i,
+               alias: 'class-name'
+       };
 
        var rangeChar = '(?:[^\\\\-]|' + escape.source + ')';
        var range = RegExp(rangeChar + '-' + rangeChar);
@@ -18,16 +25,6 @@ define(["prism/prism","prism/components/prism-actionscript","prism/components/pr
                alias: 'variable'
        };
 
-       var backreference = [
-               /\\(?![123][0-7]{2})[1-9]/, // a backreference which is not an octal escape
-               {
-                       pattern: /\\k<[^<>']+>/,
-                       inside: {
-                               'group-name': groupName
-                       }
-               }
-       ];
-
        Prism.languages.regex = {
                'charset': {
                        pattern: /((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,
@@ -36,25 +33,47 @@ define(["prism/prism","prism/components/prism-actionscript","prism/components/pr
                                'charset-negation': {
                                        pattern: /(^\[)\^/,
                                        lookbehind: true,
+                                       alias: 'operator'
+                               },
+                               'charset-punctuation': {
+                                       pattern: /^\[|\]$/,
+                                       alias: 'punctuation'
                                },
-                               'charset-punctuation': /^\[|\]$/,
                                'range': {
                                        pattern: range,
                                        inside: {
                                                'escape': escape,
-                                               'range-punctuation': /-/
+                                               'range-punctuation': {
+                                                       pattern: /-/,
+                                                       alias: 'operator'
+                                               }
                                        }
                                },
                                'special-escape': specialEscape,
-                               'charclass': charClass,
-                               'backreference': backreference,
+                               'charclass': charClassWithoutDot,
                                'escape': escape
                        }
                },
                'special-escape': specialEscape,
                'charclass': charClass,
-               'backreference': backreference,
-               'anchor': /[$^]|\\[ABbGZz]/,
+               'backreference': [
+                       {
+                               // a backreference which is not an octal escape
+                               pattern: /\\(?![123][0-7]{2})[1-9]/,
+                               alias: 'keyword'
+                       },
+                       {
+                               pattern: /\\k<[^<>']+>/,
+                               alias: 'keyword',
+                               inside: {
+                                       'group-name': groupName
+                               }
+                       }
+               ],
+               'anchor': {
+                       pattern: /[$^]|\\[ABbGZz]/,
+                       alias: 'function'
+               },
                'escape': escape,
                'group': [
                        {
@@ -63,14 +82,24 @@ define(["prism/prism","prism/components/prism-actionscript","prism/components/pr
 
                                // (), (?<name>), (?'name'), (?>), (?:), (?=), (?!), (?<=), (?<!), (?is-m), (?i-m:)
                                pattern: /\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,
+                               alias: 'punctuation',
                                inside: {
                                        'group-name': groupName
                                }
                        },
-                       /\)/
+                       {
+                               pattern: /\)/,
+                               alias: 'punctuation'
+                       }
                ],
-               'quantifier': /[+*?]|\{(?:\d+,?\d*)\}/,
-               'alternation': /\|/
+               'quantifier': {
+                       pattern: /(?:[+*?]|\{(?:\d+,?\d*)\})[?+]?/,
+                       alias: 'number'
+               },
+               'alternation': {
+                       pattern: /\|/,
+                       alias: 'keyword'
+               }
        };
 
 
@@ -85,12 +114,13 @@ define(["prism/prism","prism/components/prism-actionscript","prism/components/pr
                var grammar = Prism.languages[lang];
                if (grammar) {
                        grammar['regex'].inside = {
-                               'regex-flags': /[a-z]+$/,
-                               'regex-delimiter': /^\/|\/$/,
                                'language-regex': {
-                                       pattern: /[\s\S]+/,
+                                       pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/i,
+                                       lookbehind: true,
                                        inside: Prism.languages.regex
-                               }
+                               },
+                               'regex-flags': /[a-z]+$/i,
+                               'regex-delimiter': /^\/|\/$/,
                        };
                }
        });
index fb64a4888920114b7e18ef8124fe58d0ed98a04d..fde4717d8e948879a73fd0396f052b985175bc22 100644 (file)
@@ -29,4 +29,6 @@ Prism.languages.renpy= {
        'punctuation' : /[{}[\];(),.:]/
 };
 
+Prism.languages.rpy = Prism.languages.renpy;
+
 return Prism; })
\ No newline at end of file
index 6139d3985bd7daa01456325c3f65c1f1ed185381..c6fb0b8f56d6b37b33a0347e1bcfb139f965dfee 100644 (file)
@@ -187,7 +187,7 @@ Prism.languages.rest = {
                        }
                },
                {
-                       pattern: /(?:\b[a-z\d](?:[_.:+]?[a-z\d]+)*_?_|`[^`]+`_?_|_`[^`]+`)(?=[\s\-.,:;!?\\\/'")\]}]|$)/i,
+                       pattern: /(?:\b[a-z\d]+(?:[_.:+][a-z\d]+)*_?_|`[^`]+`_?_|_`[^`]+`)(?=[\s\-.,:;!?\\\/'")\]}]|$)/i,
                        alias: 'string',
                        inside: {
                                'punctuation': /^_?`|`$|`?_?_$/
@@ -204,4 +204,5 @@ Prism.languages.rest = {
                lookbehind: true
        }
 };
+
 return Prism; })
\ No newline at end of file
index 294950ce398efe2055043077a7c33f6d35a381ce..3294dbfbf2bef3596dab8b26d8be32aedf9a0a2b 100644 (file)
@@ -15,7 +15,7 @@ Prism.languages.rip = {
        'character': /\B`[^\s`'",.:;#\/\\()<>\[\]{}]\b/,
 
        'regex': {
-               pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/(?=\s*($|[\r\n,.;})]))/,
+               pattern: /(^|[^/])\/(?!\/)(?:\[[^\n\r\]]*\]|\\.|[^/\\\r\n\[])+\/(?=\s*(?:$|[\r\n,.;})]))/,
                lookbehind: true,
                greedy: true
        },
@@ -25,7 +25,7 @@ Prism.languages.rip = {
                pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
                greedy: true
        },
-       'number': /[+-]?(?:(?:\d+\.\d+)|(?:\d+))/,
+       'number': /[+-]?\b(?:\d+\.\d+|\d+)\b/,
 
        'punctuation': /(?:\.{2,3})|[`,.:;=\/\\()<>\[\]{}]/,
 
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-robotframework.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-robotframework.js
new file mode 100644 (file)
index 0000000..99828dc
--- /dev/null
@@ -0,0 +1,107 @@
+define(["prism/prism"], function () {
+(function (Prism) {
+
+       var comment = {
+               pattern: /(^[ \t]*| {2}|\t)#.*/m,
+               lookbehind: true,
+               greedy: true
+       };
+
+       var variable = {
+               pattern: /((?:^|[^\\])(?:\\{2})*)[$@&%]\{(?:[^{}\r\n]|\{[^{}\r\n]*\})*\}/,
+               lookbehind: true,
+               inside: {
+                       'punctuation': /^[$@&%]\{|\}$/
+               }
+       };
+
+       function createSection(name, inside) {
+               var extendecInside = {};
+
+               extendecInside['section-header'] = {
+                       pattern: /^ ?\*{3}.+?\*{3}/,
+                       alias: 'keyword'
+               };
+
+               // copy inside tokens
+               for (var token in inside) {
+                       extendecInside[token] = inside[token];
+               }
+
+               extendecInside['tag'] = {
+                       pattern: /([\r\n](?:  |\t)[ \t]*)\[[-\w]+\]/,
+                       lookbehind: true,
+                       inside: {
+                               'punctuation': /\[|\]/
+                       }
+               };
+               extendecInside['variable'] = variable;
+               extendecInside['comment'] = comment;
+
+               return {
+                       pattern: RegExp(/^ ?\*{3}[ \t]*<name>[ \t]*\*{3}(?:.|[\r\n](?!\*{3}))*/.source.replace(/<name>/g, function () { return name; }), 'im'),
+                       alias: 'section',
+                       inside: extendecInside
+               };
+       }
+
+
+       var docTag = {
+               pattern: /(\[Documentation\](?:  |\t)[ \t]*)(?![ \t]|#)(?:.|(?:\r\n?|\n)[ \t]*\.{3})+/,
+               lookbehind: true,
+               alias: 'string'
+       };
+
+       var testNameLike = {
+               pattern: /([\r\n] ?)(?!#)(?:\S(?:[ \t]\S)*)+/,
+               lookbehind: true,
+               alias: 'function',
+               inside: {
+                       'variable': variable
+               }
+       };
+
+       var testPropertyLike = {
+               pattern: /([\r\n](?:  |\t)[ \t]*)(?!\[|\.{3}|#)(?:\S(?:[ \t]\S)*)+/,
+               lookbehind: true,
+               inside: {
+                       'variable': variable
+               }
+       };
+
+       Prism.languages['robotframework'] = {
+               'settings': createSection('Settings', {
+                       'documentation': {
+                               pattern: /([\r\n] ?Documentation(?:  |\t)[ \t]*)(?![ \t]|#)(?:.|(?:\r\n?|\n)[ \t]*\.{3})+/,
+                               lookbehind: true,
+                               alias: 'string'
+                       },
+                       'property': {
+                               pattern: /([\r\n] ?)(?!\.{3}|#)(?:\S(?:[ \t]\S)*)+/,
+                               lookbehind: true
+                       }
+               }),
+               'variables': createSection('Variables'),
+               'test-cases': createSection('Test Cases', {
+                       'test-name': testNameLike,
+                       'documentation': docTag,
+                       'property': testPropertyLike
+               }),
+               'keywords': createSection('Keywords', {
+                       'keyword-name': testNameLike,
+                       'documentation': docTag,
+                       'property': testPropertyLike
+               }),
+               'tasks': createSection('Tasks', {
+                       'task-name': testNameLike,
+                       'documentation': docTag,
+                       'property': testPropertyLike
+               }),
+               'comment': comment
+       };
+
+       Prism.languages.robot = Prism.languages['robotframework'];
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 226515058154b219e4f71cd76c576da8da5bbec6..b9072c0a739e57679d25657e91787167053caff4 100644 (file)
@@ -3,9 +3,9 @@ define(["prism/prism","prism/components/prism-clike"], function () {
  * Original by Samuel Flores
  *
  * Adds the following new token classes:
- *             constant, builtin, variable, symbol, regex
+ *     constant, builtin, variable, symbol, regex
  */
-(function(Prism) {
+(function (Prism) {
        Prism.languages.ruby = Prism.languages.extend('clike', {
                'comment': [
                        /#.*/,
@@ -14,7 +14,14 @@ define(["prism/prism","prism/components/prism-clike"], function () {
                                greedy: true
                        }
                ],
-               'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
+               'class-name': {
+                       pattern: /(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,
+                       lookbehind: true,
+                       inside: {
+                               'punctuation': /[.\\]/
+                       }
+               },
+               'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/
        });
 
        var interpolation = {
@@ -33,43 +40,21 @@ define(["prism/prism","prism/components/prism-clike"], function () {
        Prism.languages.insertBefore('ruby', 'keyword', {
                'regex': [
                        {
-                               pattern: /%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,
-                               greedy: true,
-                               inside: {
-                                       'interpolation': interpolation
-                               }
-                       },
-                       {
-                               pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,
-                               greedy: true,
-                               inside: {
-                                       'interpolation': interpolation
-                               }
-                       },
-                       {
-                               // Here we need to specifically allow interpolation
-                               pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,
-                               greedy: true,
-                               inside: {
-                                       'interpolation': interpolation
-                               }
-                       },
-                       {
-                               pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,
-                               greedy: true,
-                               inside: {
-                                       'interpolation': interpolation
-                               }
-                       },
-                       {
-                               pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,
+                               pattern: RegExp(/%r/.source + '(?:' + [
+                                       /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/.source,
+                                       /\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/.source,
+                                       // Here we need to specifically allow interpolation
+                                       /\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/.source,
+                                       /\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/.source,
+                                       /<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/.source
+                               ].join('|') + ')'),
                                greedy: true,
                                inside: {
                                        'interpolation': interpolation
                                }
                        },
                        {
-                               pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
+                               pattern: /(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/,
                                lookbehind: true,
                                greedy: true
                        }
@@ -96,36 +81,14 @@ define(["prism/prism","prism/components/prism-clike"], function () {
 
        Prism.languages.ruby.string = [
                {
-                       pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
-                       greedy: true,
-                       inside: {
-                               'interpolation': interpolation
-                       }
-               },
-               {
-                       pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,
-                       greedy: true,
-                       inside: {
-                               'interpolation': interpolation
-                       }
-               },
-               {
-                       // Here we need to specifically allow interpolation
-                       pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,
-                       greedy: true,
-                       inside: {
-                               'interpolation': interpolation
-                       }
-               },
-               {
-                       pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,
-                       greedy: true,
-                       inside: {
-                               'interpolation': interpolation
-                       }
-               },
-               {
-                       pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,
+                       pattern: RegExp(/%[qQiIwWxs]?/.source + '(?:' + [
+                               /([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
+                               /\((?:[^()\\]|\\[\s\S])*\)/.source,
+                               // Here we need to specifically allow interpolation
+                               /\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/.source,
+                               /\[(?:[^\[\]\\]|\\[\s\S])*\]/.source,
+                               /<(?:[^<>\\]|\\[\s\S])*>/.source
+                       ].join('|') + ')'),
                        greedy: true,
                        inside: {
                                'interpolation': interpolation
index b22cd96c280bd6bb58f9766c5b89c0efecaf7865..c4238f3b861f9182d082bcca0ec99b5104839e01 100644 (file)
 define(["prism/prism"], function () {
-/* TODO
-       Add support for Markdown notation inside doc comments
-       Add support for nested block comments...
-       Match closure params even when not followed by dash or brace
-       Add better support for macro definition
-*/
+(function (Prism) {
 
-Prism.languages.rust = {
-       'comment': [
-               {
-                       pattern: /(^|[^\\])\/\*[\s\S]*?\*\//,
-                       lookbehind: true
-               },
-               {
-                       pattern: /(^|[^\\:])\/\/.*/,
-                       lookbehind: true
-               }
-       ],
-       'string': [
-               {
-                       pattern: /b?r(#*)"(?:\\.|(?!"\1)[^\\\r\n])*"\1/,
+       var multilineComment = /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source;
+       for (var i = 0; i < 2; i++) {
+               // support 4 levels of nested comments
+               multilineComment = multilineComment.replace(/<self>/g, function () { return multilineComment; });
+       }
+       multilineComment = multilineComment.replace(/<self>/g, function () { return /[^\s\S]/.source; });
+
+
+       Prism.languages.rust = {
+               'comment': [
+                       {
+                               pattern: RegExp(/(^|[^\\])/.source + multilineComment),
+                               lookbehind: true,
+                               greedy: true
+                       },
+                       {
+                               pattern: /(^|[^\\:])\/\/.*/,
+                               lookbehind: true,
+                               greedy: true
+                       }
+               ],
+               'string': {
+                       pattern: /b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,
                        greedy: true
                },
-               {
-                       pattern: /b?"(?:\\.|[^\\\r\n"])*"/,
-                       greedy: true
-               }
-       ],
-       'char': {
-               pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,
-               alias: 'string'
-       },
-       'lifetime-annotation': {
-               pattern: /'[^\s>']+/,
-               alias: 'symbol'
-       },
-       'keyword': /\b(?:abstract|alignof|as|async|await|be|box|break|const|continue|crate|do|dyn|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|Self|struct|super|true|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,
+               'char': {
+                       pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,
+                       greedy: true,
+                       alias: 'string'
+               },
+               'attribute': {
+                       pattern: /#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,
+                       greedy: true,
+                       alias: 'attr-name',
+                       inside: {
+                               'string': null // see below
+                       }
+               },
+
+               // Closure params should not be confused with bitwise OR |
+               'closure-params': {
+                       pattern: /([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,
+                       lookbehind: true,
+                       greedy: true,
+                       inside: {
+                               'closure-punctuation': {
+                                       pattern: /^\||\|$/,
+                                       alias: 'punctuation'
+                               },
+                               rest: null // see below
+                       }
+               },
+
+               'lifetime-annotation': {
+                       pattern: /'\w+/,
+                       alias: 'symbol'
+               },
+
+               'fragment-specifier': {
+                       pattern: /(\$\w+:)[a-z]+/,
+                       lookbehind: true,
+                       alias: 'punctuation'
+               },
+               'variable': /\$\w+/,
 
-       'attribute': {
-               pattern: /#!?\[.+?\]/,
-               greedy: true,
-               alias: 'attr-name'
-       },
+               'function-definition': {
+                       pattern: /(\bfn\s+)\w+/,
+                       lookbehind: true,
+                       alias: 'function'
+               },
+               'type-definition': {
+                       pattern: /(\b(?:enum|struct|union)\s+)\w+/,
+                       lookbehind: true,
+                       alias: 'class-name'
+               },
+               'module-declaration': [
+                       {
+                               pattern: /(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,
+                               lookbehind: true,
+                               alias: 'namespace'
+                       },
+                       {
+                               pattern: /(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,
+                               lookbehind: true,
+                               alias: 'namespace',
+                               inside: {
+                                       'punctuation': /::/
+                               }
+                       }
+               ],
+               'keyword': [
+                       // https://github.com/rust-lang/reference/blob/master/src/keywords.md
+                       /\b(?:abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|Self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,
+                       // primitives and str
+                       // https://doc.rust-lang.org/stable/rust-by-example/primitives.html
+                       /\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char|str)\b/
+               ],
+
+               // functions can technically start with an upper-case letter, but this will introduce a lot of false positives
+               // and Rust's naming conventions recommend snake_case anyway.
+               // https://doc.rust-lang.org/1.0.0/style/style/naming/README.html
+               'function': /\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,
+               'macro': {
+                       pattern: /\w+!/,
+                       alias: 'property'
+               },
+               'constant': /\b[A-Z_][A-Z_\d]+\b/,
+               'class-name': /\b[A-Z]\w*\b/,
+
+               'namespace': {
+                       pattern: /(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,
+                       inside: {
+                               'punctuation': /::/
+                       }
+               },
 
-       'function': [
-               /\w+(?=\s*\()/,
-               // Macros can use parens or brackets
-               /\w+!(?=\s*\(|\[)/
-       ],
-       'macro-rules': {
-               pattern: /\w+!/,
-               alias: 'function'
-       },
+               // Hex, oct, bin, dec numbers with visual separators and type suffix
+               'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64|size)?|f32|f64))?\b/,
+               'boolean': /\b(?:false|true)\b/,
+               'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,
+               'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/
+       };
 
-       // Hex, oct, bin, dec numbers with visual separators and type suffix
-       'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/,
+       Prism.languages.rust['closure-params'].inside.rest = Prism.languages.rust;
+       Prism.languages.rust['attribute'].inside['string'] = Prism.languages.rust['string'];
 
-       // Closure params should not be confused with bitwise OR |
-       'closure-params': {
-               pattern: /\|[^|]*\|(?=\s*[{-])/,
-               inside: {
-                       'punctuation': /[|:,]/,
-                       'operator': /[&*]/
-               }
-       },
-       'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,
-       'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/
-};
+}(Prism));
 
 return Prism; })
\ No newline at end of file
index 41fff13525c8dbe64f5f8ab80a4f2e432e5c0fc4..426346a7bcd4085e8ca20c2693bb16e6a51d84dc 100644 (file)
 define(["prism/prism"], function () {
-Prism.languages.sas = {
-       'datalines': {
-               pattern: /^\s*(?:(?:data)?lines|cards);[\s\S]+?(?:\r?\n|\r);/im,
-               alias: 'string',
+(function (Prism) {
+
+       var stringPattern = /(?:"(?:""|[^"])*"(?!")|'(?:''|[^'])*'(?!'))/.source;
+
+       var number = /\b(?:\d[\da-f]*x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b/i;
+       var numericConstant = {
+               pattern: RegExp(stringPattern + '[bx]'),
+               alias: 'number'
+       };
+
+       var macroVariable = {
+               pattern: /&[a-z_][a-z_0-9]*/i
+       };
+
+       var macroKeyword = {
+               pattern: /((?:^|\s|=|\())%(?:ABORT|BY|CMS|COPY|DISPLAY|DO|ELSE|END|EVAL|GLOBAL|GO|GOTO|IF|INC|INCLUDE|INDEX|INPUT|KTRIM|LENGTH|LET|LIST|LOCAL|PUT|QKTRIM|QSCAN|QSUBSTR|QSYSFUNC|QUPCASE|RETURN|RUN|SCAN|SUBSTR|SUPERQ|SYMDEL|SYMGLOBL|SYMLOCAL|SYMEXIST|SYSCALL|SYSEVALF|SYSEXEC|SYSFUNC|SYSGET|SYSRPUT|THEN|TO|TSO|UNQUOTE|UNTIL|UPCASE|WHILE|WINDOW)\b/i,
+               lookbehind: true,
+               alias: 'keyword'
+       };
+
+       var step = {
+               pattern: /(^|\s+)(?:proc\s+\w+|quit|run|data(?!\=))\b/i,
+               alias: 'keyword',
+               lookbehind: true
+       };
+
+       var comment = [
+               /\/\*[\s\S]*?\*\//,
+               {
+                       pattern: /(^\s*|;\s*)\*[^;]*;/m,
+                       lookbehind: true
+               }
+       ];
+
+       var string = {
+               pattern: RegExp(stringPattern),
+               greedy: true
+       };
+
+       var punctuation = /[$%@.(){}\[\];,\\]/;
+
+       var func = {
+               pattern: /%?\w+(?=\()/,
+               alias: 'keyword'
+       };
+
+       var args = {
+               'function': func,
+               'arg-value': {
+                       pattern: /(\s*=\s*)[A-Z\.]+/i,
+                       lookbehind: true
+               },
+               'operator': /=/,
+               'macro-variable': macroVariable,
+               'arg': {
+                       pattern: /[A-Z]+/i,
+                       alias: 'keyword'
+               },
+               'number': number,
+               'numeric-constant': numericConstant,
+               'punctuation': punctuation,
+               'string': string
+       };
+
+       var format = {
+               pattern: /\b(?:format|put)\b=?[\w'$.]+/im,
                inside: {
-                       'keyword': {
-                               pattern: /^(\s*)(?:(?:data)?lines|cards)/i,
-                               lookbehind: true
+                       'keyword': /^(?:format|put)(?=\=)/i,
+                       'equals': /=/,
+                       'format': {
+                               pattern: /(?:\w|\$\d)+\.\d?/i,
+                               alias: 'number'
+                       }
+               }
+       };
+
+       var altformat = {
+               pattern: /\b(?:format|put)\s+[\w']+(?:\s+[$.\w]+)+(?=;)/i,
+               inside: {
+                       'keyword': /^(?:format|put)/i,
+                       'format': {
+                               pattern: /[\w$]+\.\d?/,
+                               alias: 'number'
+                       }
+               }
+       };
+
+       var globalStatements = {
+               pattern: /((?:^|[\s])=?)(?:catname|checkpoint execute_always|dm|endsas|filename|footnote|%include|libname|%list|lock|missing|options|page|resetline|%run|sasfile|skip|sysecho|title\d?)\b/i,
+               lookbehind: true,
+               alias: 'keyword'
+       };
+
+       var submitStatement = {
+               pattern: /(^|\s)(?:submit(?:\s+(?:load|parseonly|norun))?|endsubmit)\b/i,
+               lookbehind: true,
+               alias: 'keyword'
+       };
+
+       var actionSets = /accessControl|cdm|aggregation|aStore|ruleMining|audio|autotune|bayesianNetClassifier|bioMedImage|boolRule|builtins|cardinality|sccasl|clustering|copula|countreg|dataDiscovery|dataPreprocess|dataSciencePilot|dataStep|decisionTree|deepLearn|deepNeural|varReduce|simSystem|ds2|deduplication|ecm|entityRes|espCluster|explainModel|factmac|fastKnn|fcmpact|fedSql|freqTab|gam|gleam|graphSemiSupLearn|gVarCluster|hiddenMarkovModel|hyperGroup|image|iml|ica|kernalPca|langModel|ldaTopic|sparseML|mlTools|mixed|modelPublishing|mbc|network|optNetwork|neuralNet|nonlinear|nmf|nonParametricBayes|optimization|panel|pls|percentile|pca|phreg|qkb|qlim|quantreg|recommend|tsReconcile|deepRnn|regression|reinforcementLearn|robustPca|sampling|sparkEmbeddedProcess|search(?:Analytics)?|sentimentAnalysis|sequence|configuration|session(?:Prop)?|severity|simple|smartData|sandwich|spatialreg|stabilityMonitoring|spc|loadStreams|svDataDescription|svm|table|conditionalRandomFields|text(?:Rule(?:Develop|Score)|Mining|Parse|Topic|Util|Filters|Frequency)|tsInfo|timeData|transpose|uniTimeSeries/.source;
+
+       var casActions = {
+               pattern: RegExp(/(^|\s)(?:action\s+)?(?:<act>)\.[a-z]+\b[^;]+/.source.replace(/<act>/g, function () { return actionSets; }), 'i'),
+               lookbehind: true,
+               inside: {
+                       'keyword': RegExp(/(?:<act>)\.[a-z]+\b/.source.replace(/<act>/g, function () { return actionSets; }), 'i'),
+                       'action': {
+                               pattern: /(?:action)/i,
+                               alias: 'keyword'
                        },
-                       'punctuation': /;/
+                       'comment': comment,
+                       'function': func,
+                       'arg-value': args['arg-value'],
+                       'operator': args.operator,
+                       'argument': args.arg,
+                       'number': number,
+                       'numeric-constant': numericConstant,
+                       'punctuation': punctuation,
+                       'string': string
                }
-       },
-       'comment': [
-               {
-                       pattern: /(^\s*|;\s*)\*.*;/m,
-                       lookbehind: true
+       };
+
+       var keywords = {
+               pattern: /((?:^|\s)=?)(?:after|analysis|and|array|barchart|barwidth|begingraph|by|call|cas|cbarline|cfill|class(?:lev)?|close|column|computed?|contains|continue|data(?=\=)|define|delete|describe|document|do\s+over|do|dol|drop|dul|end(?:source|comp)?|entryTitle|else|eval(?:uate)?|exec(?:ute)?|exit|fill(?:attrs)?|file(?:name)?|flist|fnc|function(?:list)?|goto|global|group(?:by)?|headline|headskip|histogram|if|infile|keep|keylabel|keyword|label|layout|leave|legendlabel|length|libname|loadactionset|merge|midpoints|name|noobs|nowd|_?null_|ods|options|or|otherwise|out(?:put)?|over(?:lay)?|plot|put|print|raise|ranexp|rannor|rbreak|retain|return|select|set|session|sessref|source|statgraph|sum|summarize|table|temp|terminate|then\s+do|then|title\d?|to|var|when|where|xaxisopts|yaxisopts|y2axisopts)\b/i,
+               lookbehind: true,
+       };
+
+       Prism.languages.sas = {
+               'datalines': {
+                       pattern: /^(\s*)(?:(?:data)?lines|cards);[\s\S]+?^\s*;/im,
+                       lookbehind: true,
+                       alias: 'string',
+                       inside: {
+                               'keyword': {
+                                       pattern: /^(?:(?:data)?lines|cards)/i
+                               },
+                               'punctuation': /;/
+                       }
                },
-               /\/\*[\s\S]+?\*\//
-       ],
-       'datetime': {
-               // '1jan2013'd, '9:25:19pm't, '18jan2003:9:27:05am'dt
-               pattern: /'[^']+'(?:dt?|t)\b/i,
-               alias: 'number'
-       },
-       'string': {
-               pattern: /(["'])(?:\1\1|(?!\1)[\s\S])*\1/,
-               greedy: true
-       },
-       'keyword': /\b(?:data|else|format|if|input|proc\s\w+|quit|run|then|libname|set|output|options)\b/i,
-       // Decimal (1.2e23), hexadecimal (0c1x)
-       'number': /\b(?:[\da-f]+x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,
-       'operator': /\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?|\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,
-       'punctuation': /[$%@.(){}\[\];,\\]/
-};
+
+               'proc-sql': {
+                       pattern: /(^proc\s+(?:fed)?sql(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,
+                       lookbehind: true,
+                       inside: {
+                               'sql': {
+                                       pattern: RegExp(/^[ \t]*(?:select|alter\s+table|(?:create|describe|drop)\s+(?:index|table(?:\s+constraints)?|view)|create\s+unique\s+index|insert\s+into|update)(?:<str>|[^;"'])+;/.source.replace(/<str>/g, function () { return stringPattern; }), 'im'),
+                                       alias: 'language-sql',
+                                       inside: Prism.languages.sql
+                               },
+                               'global-statements': globalStatements,
+                               'sql-statements': {
+                                       pattern: /(^|\s)(?:disconnect\s+from|exec(?:ute)?|begin|commit|rollback|reset|validate)\b/i,
+                                       lookbehind: true,
+                                       alias: 'keyword'
+                               },
+                               'number': number,
+                               'numeric-constant': numericConstant,
+                               'punctuation': punctuation,
+                               'string': string
+                       }
+               },
+
+               'proc-groovy': {
+                       pattern: /(^proc\s+groovy(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,
+                       lookbehind: true,
+                       inside: {
+                               'comment': comment,
+                               'groovy': {
+                                       pattern: RegExp(/(^[ \t]*submit(?:\s+(?:load|parseonly|norun))?)(?:<str>|[^"'])+?(?=endsubmit;)/.source.replace(/<str>/g, function () { return stringPattern; }), 'im'),
+                                       lookbehind: true,
+                                       alias: 'language-groovy',
+                                       inside: Prism.languages.groovy
+                               },
+                               'keyword': keywords,
+                               'submit-statement': submitStatement,
+                               'global-statements': globalStatements,
+                               'number': number,
+                               'numeric-constant': numericConstant,
+                               'punctuation': punctuation,
+                               'string': string
+                       }
+               },
+
+               'proc-lua': {
+                       pattern: /(^proc\s+lua(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|run|data);|(?![\s\S]))/im,
+                       lookbehind: true,
+                       inside: {
+                               'comment': comment,
+                               'lua': {
+                                       pattern: RegExp(/(^[ \t]*submit(?:\s+(?:load|parseonly|norun))?)(?:<str>|[^"'])+?(?=endsubmit;)/.source.replace(/<str>/g, function () { return stringPattern; }), 'im'),
+                                       lookbehind: true,
+                                       alias: 'language-lua',
+                                       inside: Prism.languages.lua
+                               },
+                               'keyword': keywords,
+                               'submit-statement': submitStatement,
+                               'global-statements': globalStatements,
+                               'number': number,
+                               'numeric-constant': numericConstant,
+                               'punctuation': punctuation,
+                               'string': string
+                       }
+               },
+
+               'proc-cas': {
+                       pattern: /(^proc\s+cas(?:\s+[\w|=]+)?;)[\s\S]+?(?=^(?:proc\s+\w+|quit|data);|(?![\s\S]))/im,
+                       lookbehind: true,
+                       inside: {
+                               'comment': comment,
+                               'statement-var': {
+                                       pattern: /((?:^|\s)=?)saveresult\s+[^;]+/im,
+                                       lookbehind: true,
+                                       inside: {
+                                               'statement': {
+                                                       pattern: /^saveresult\s+\S+/i,
+                                                       inside: {
+                                                               keyword: /^(?:saveresult)/i
+                                                       }
+                                               },
+                                               rest: args
+                                       }
+                               },
+                               'cas-actions': casActions,
+                               'statement': {
+                                       pattern: /((?:^|\s)=?)(?:default|(?:un)?set|on|output|upload)[^;]+/im,
+                                       lookbehind: true,
+                                       inside: args
+                               },
+                               'step': step,
+                               'keyword': keywords,
+                               'function': func,
+                               'format': format,
+                               'altformat': altformat,
+                               'global-statements': globalStatements,
+                               'number': number,
+                               'numeric-constant': numericConstant,
+                               'punctuation': punctuation,
+                               'string': string
+                       }
+               },
+
+               'proc-args': {
+                       pattern: RegExp(/(^proc\s+\w+\s+)(?!\s)(?:[^;"']|<str>)+;/.source.replace(/<str>/g, function () { return stringPattern; }), 'im'),
+                       lookbehind: true,
+                       inside: args
+               },
+               /*Special keywords within macros*/
+               'macro-keyword': macroKeyword,
+               'macro-variable': macroVariable,
+               'macro-string-functions': {
+                       pattern: /((?:^|\s|=))%(?:NRBQUOTE|NRQUOTE|NRSTR|BQUOTE|QUOTE|STR)\(.*?(?:[^%]\))/i,
+                       lookbehind: true,
+                       inside: {
+                               'function': {
+                                       pattern: /%(?:NRBQUOTE|NRQUOTE|NRSTR|BQUOTE|QUOTE|STR)/i,
+                                       alias: 'keyword'
+                               },
+                               'macro-keyword': macroKeyword,
+                               'macro-variable': macroVariable,
+                               'escaped-char': {
+                                       pattern: /%['"()<>=¬^~;,#]/i,
+                               },
+                               'punctuation': punctuation
+                       }
+               },
+               'macro-declaration': {
+                       pattern: /^%macro[^;]+(?=;)/im,
+                       inside: {
+                               'keyword': /%macro/i,
+                       }
+               },
+               'macro-end': {
+                       pattern: /^%mend[^;]+(?=;)/im,
+                       inside: {
+                               'keyword': /%mend/i,
+                       }
+               },
+               /*%_zscore(headcir, _lhc, _mhc, _shc, headcz, headcpct, _Fheadcz); */
+               'macro': {
+                       pattern: /%_\w+(?=\()/,
+                       alias: 'keyword'
+               },
+               'input': {
+                       pattern: /\binput\s+[-\w\s/*.$&]+;/i,
+                       inside: {
+                               'input': {
+                                       alias: 'keyword',
+                                       pattern: /^input/i,
+                               },
+                               'comment': comment,
+                               'number': number,
+                               'numeric-constant': numericConstant
+                       }
+               },
+               'options-args': {
+                       pattern: /(^options)[-'"|/\\<>*+=:()\w\s]*(?=;)/im,
+                       lookbehind: true,
+                       inside: args
+               },
+               'cas-actions': casActions,
+               'comment': comment,
+               'function': func,
+               'format': format,
+               'altformat': altformat,
+               'numeric-constant': numericConstant,
+               'datetime': {
+                       // '1jan2013'd, '9:25:19pm't, '18jan2003:9:27:05am'dt
+                       pattern: RegExp(stringPattern + '(?:dt?|t)'),
+                       alias: 'number'
+               },
+               'string': string,
+               'step': step,
+               'keyword': keywords,
+               // In SAS Studio syntax highlighting, these operators are styled like keywords
+               'operator-keyword': {
+                       pattern: /\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,
+                       alias: 'operator'
+               },
+               // Decimal (1.2e23), hexadecimal (0c1x)
+               'number': number,
+               'operator': /\*\*?|\|\|?|!!?|¦¦?|<[>=]?|>[<=]?|[-+\/=&]|[~¬^]=?/i,
+               'punctuation': punctuation
+       };
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
index 50feab186fce4867a83dde822dd5e186e98b0a33..c1d0baabd0c35e320f473e229de5681cfbdfd151 100644 (file)
@@ -1,16 +1,15 @@
 define(["prism/prism","prism/components/prism-java"], function () {
 Prism.languages.scala = Prism.languages.extend('java', {
        'keyword': /<-|=>|\b(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|null|object|override|package|private|protected|return|sealed|self|super|this|throw|trait|try|type|val|var|while|with|yield)\b/,
-       'string': [
-               {
-                       pattern: /"""[\s\S]*?"""/,
-                       greedy: true
-               },
-               {
-                       pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
-                       greedy: true
-               }
-       ],
+       'triple-quoted-string': {
+               pattern: /"""[\s\S]*?"""/,
+               greedy: true,
+               alias: 'string'
+       },
+       'string': {
+               pattern: /("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
+               greedy: true
+       },
        'builtin': /\b(?:String|Int|Long|Short|Byte|Boolean|Double|Float|Char|Any|AnyRef|AnyVal|Unit|Nothing)\b/,
        'number': /\b0x[\da-f]*\.?[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e\d+)?[dfl]?/i,
        'symbol': /'[^\d\s\\]\w*/
index 02cd468b64e12d2bbdd5c6704ef0dd1bb0ac52e1..acfbfaba603a64f0834cb87aa31460830539fc52 100644 (file)
@@ -2,32 +2,66 @@ define(["prism/prism"], function () {
 Prism.languages.scheme = {
        'comment': /;.*/,
        'string': {
-               pattern: /"(?:[^"\\]|\\.)*"|'[^()#'\s]+/,
+               pattern: /"(?:[^"\\]|\\.)*"/,
+               greedy: true
+       },
+       'symbol': {
+               pattern: /'[^()#'\s]+/,
                greedy: true
        },
        'character': {
-               pattern: /#\\(?:[ux][a-fA-F\d]+|[a-zA-Z]+|\S)/,
+               pattern: /#\\(?:[ux][a-fA-F\d]+|[-a-zA-Z]+|\S)/,
+               greedy: true,
                alias: 'string'
        },
+       'lambda-parameter': [
+               // https://www.cs.cmu.edu/Groups/AI/html/r4rs/r4rs_6.html#SEC30
+               {
+                       pattern: /(\(lambda\s+)[^()'\s]+/,
+                       lookbehind: true
+               },
+               {
+                       pattern: /(\(lambda\s+\()[^()']+/,
+                       lookbehind: true
+               }
+       ],
        'keyword': {
-               pattern: /(\()(?:define(?:-syntax|-library|-values)?|(?:case-)?lambda|let(?:\*|rec)?(?:-values)?|else|if|cond|begin|delay(?:-force)?|parameterize|guard|set!|(?:quasi-)?quote|syntax-rules)(?=[()\s])/,
+               pattern: /(\()(?:define(?:-library|-macro|-syntax|-values)?|defmacro|(?:case-)?lambda|let(?:(?:\*|rec)?(?:-values)?|-syntax|rec-syntax)|else|if|cond|begin|delay(?:-force)?|parameterize|guard|set!|(?:quasi-)?quote|syntax-(?:case|rules))(?=[()\s]|$)/,
                lookbehind: true
        },
        'builtin': {
-               pattern: /(\()(?:(?:cons|car|cdr|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?)(?=[()\s])/,
+               pattern: /(\()(?:(?:cons|car|cdr|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?)(?=[()\s]|$)/,
                lookbehind: true
        },
        'number': {
-               pattern: /([\s()])[-+]?\d*\.?\d+(?:\s*[-+]\s*\d*\.?\d+i)?\b/,
+               // This pattern (apart from the lookarounds) works like this:
+               //
+               // Decimal numbers
+               // <dec real>       := \d*\.?\d+(?:[eE][+-]?\d+)?|\d+\/\d+
+               // <dec complex>    := <dec real>(?:[+-]<dec real>i)?|<dec real>i
+               // <dec prefix>     := (?:#d(?:#[ei])?|#[ei](?:#d)?)?
+               // <dec number>     := <dec prefix>[+-]?<complex>
+               //
+               // Binary, octal, and hexadecimal numbers
+               // <b.o.x. real>    := [\da-fA-F]+(?:\/[\da-fA-F]+)?
+               // <b.o.x. complex> := <b.o.x. real>(?:[+-]<b.o.x. real>i)?|<b.o.x. real>i
+               // <b.o.x. prefix>  := #[box](?:#[ei])?|#[ei](?:#[box])?
+               // <b.o.x. number>  := <b.o.x. prefix>[+-]?<b.o.x. complex>
+               //
+               // <number>         := <dec number>|<b.o.x. number>
+               pattern: /(^|[\s()])(?:(?:#d(?:#[ei])?|#[ei](?:#d)?)?[+-]?(?:(?:\d*\.?\d+(?:[eE][+-]?\d+)?|\d+\/\d+)(?:[+-](?:\d*\.?\d+(?:[eE][+-]?\d+)?|\d+\/\d+)i)?|(?:\d*\.?\d+(?:[eE][+-]?\d+)?|\d+\/\d+)i)|(?:#[box](?:#[ei])?|#[ei](?:#[box])?)[+-]?(?:[\da-fA-F]+(?:\/[\da-fA-F]+)?(?:[+-][\da-fA-F]+(?:\/[\da-fA-F]+)?i)?|[\da-fA-F]+(?:\/[\da-fA-F]+)?i))(?=[()\s]|$)/,
+               lookbehind: true
+       },
+       'boolean': {
+               pattern: /(^|[\s()])#[ft](?=[()\s]|$)/,
                lookbehind: true
        },
-       'boolean': /#[tf]/,
        'operator': {
-               pattern: /(\()(?:[-+*%\/]|[<>]=?|=>?)(?=\s|$)/,
+               pattern: /(\()(?:[-+*%\/]|[<>]=?|=>?)(?=[()\s]|$)/,
                lookbehind: true
        },
        'function': {
-               pattern: /(\()[^()'\s]+(?=[()\s)]|$)/,
+               pattern: /(\()[^()'\s]+(?=[()\s]|$)/,
                lookbehind: true
        },
        'punctuation': /[()']/
index e912ab93b1cf8bf60158bdc639338985ee35a834..23222acc40aa28f60fcdcbb837f340eeff3039df 100644 (file)
@@ -1,24 +1,57 @@
 define(["prism/prism","prism/components/prism-bash"], function () {
-Prism.languages['shell-session'] = {
-       'command': {
-               pattern: /\$(?:[^\r\n'"<]|(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1|((?:^|[^<])<<\s*)["']?(\w+?)["']?\s*(?:\r\n?|\n)(?:[\s\S])*?(?:\r\n?|\n)\3)+/,
-               inside: {
-                       'bash': {
-                               pattern: /(\$\s*)[\s\S]+/,
-                               lookbehind: true,
-                               alias: 'language-bash',
-                               inside: Prism.languages.bash
-                       },
-                       'sh': {
-                               pattern: /^\$/,
-                               alias: 'important'
+(function (Prism) {
+
+       // CAREFUL!
+       // The following patterns are concatenated, so the group referenced by a back reference is non-obvious!
+
+       var strings = [
+               // normal string
+               // 1 capturing group
+               /(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/.source,
+
+               // here doc
+               // 1 capturing group
+               /<<-?\s*(\w+?)[ \t]*(?!.)[\s\S]*?[\r\n]\2/.source,
+
+               // here doc quoted
+               // 2 capturing group
+               /<<-?\s*(["'])(\w+)\3[ \t]*(?!.)[\s\S]*?[\r\n]\4/.source
+       ].join('|');
+
+       Prism.languages['shell-session'] = {
+               'info': {
+                       // foo@bar:~/files$ exit
+                       // foo@bar$ exit
+                       pattern: /^[^\r\n$#*!]+(?=[$#])/m,
+                       alias: 'punctuation',
+                       inside: {
+                               'path': {
+                                       pattern: /(:)[\s\S]+/,
+                                       lookbehind: true
+                               },
+                               'user': /^[^\s@:$#*!/\\]+@[^\s@:$#*!/\\]+(?=:|$)/,
+                               'punctuation': /:/
+                       }
+               },
+               'command': {
+                       pattern: RegExp(/[$#](?:[^\\\r\n'"<]|\\.|<<str>>)+/.source.replace(/<<str>>/g, function () { return strings; })),
+                       greedy: true,
+                       inside: {
+                               'bash': {
+                                       pattern: /(^[$#]\s*)[\s\S]+/,
+                                       lookbehind: true,
+                                       alias: 'language-bash',
+                                       inside: Prism.languages.bash
+                               },
+                               'shell-symbol': {
+                                       pattern: /^[$#]/,
+                                       alias: 'important'
+                               }
                        }
-               }
-       },
-       'output': {
-               pattern: /.(?:.*(?:\r\n?|\n|.$))*/
-               // output highlighting?
-       }
-}
+               },
+               'output': /.(?:.*(?:[\r\n]|.$))*/
+       };
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-smali.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-smali.js
new file mode 100644 (file)
index 0000000..ee6de21
--- /dev/null
@@ -0,0 +1,89 @@
+define(["prism/prism"], function () {
+// Test files for the parser itself:
+// https://github.com/JesusFreke/smali/tree/master/smali/src/test/resources/LexerTest
+
+Prism.languages.smali = {
+       'comment': /#.*/,
+       'string': {
+               pattern: /"(?:[^\r\n\\"]|\\.)*"|'(?:[^\r\n\\']|\\(?:.|u[\da-fA-F]{4}))'/,
+               greedy: true
+       },
+
+       'class-name': {
+               pattern: /L(?:(?:\w+|`[^`\r\n]*`)\/)*(?:[\w$]+|`[^`\r\n]*`)(?=\s*;)/,
+               inside: {
+                       'class-name': {
+                               pattern: /(^L|\/)(?:[\w$]+|`[^`\r\n]*`)$/,
+                               lookbehind: true
+                       },
+                       'namespace': {
+                               pattern: /^(L)(?:(?:\w+|`[^`\r\n]*`)\/)+/,
+                               lookbehind: true,
+                               inside: {
+                                       'punctuation': /\//
+                               }
+                       },
+                       'builtin': /^L/
+               }
+       },
+       'builtin': [
+               {
+                       // Reference: https://github.com/JesusFreke/smali/wiki/TypesMethodsAndFields#types
+                       pattern: /([();\[])[BCDFIJSVZ]+/,
+                       lookbehind: true
+               },
+               {
+                       // e.g. .field mWifiOnUid:I
+                       pattern: /([\w$>]:)[BCDFIJSVZ]/,
+                       lookbehind: true
+               }
+       ],
+       'keyword': [
+               {
+                       pattern: /(\.end\s+)[\w-]+/,
+                       lookbehind: true
+               },
+               {
+                       pattern: /(^|[^\w.-])\.(?!\d)[\w-]+/,
+                       lookbehind: true
+               },
+               {
+                       pattern: /(^|[^\w.-])(?:abstract|annotation|bridge|constructor|enum|final|interface|private|protected|public|runtime|static|synthetic|system|transient)(?![\w.-])/,
+                       lookbehind: true
+               }
+       ],
+       'function': {
+               pattern: /(^|[^\w.-])(?:\w+|<[\w$-]+>)(?=\()/,
+               lookbehind: true
+       },
+
+       'field': {
+               pattern: /[\w$]+(?=:)/,
+               alias: 'variable'
+       },
+       'register': {
+               pattern: /(^|[^\w.-])[vp]\d(?![\w.-])/,
+               lookbehind: true,
+               alias: 'variable'
+       },
+
+       'boolean': {
+               pattern: /(^|[^\w.-])(?:true|false)(?![\w.-])/,
+               lookbehind: true
+       },
+       'number': {
+               pattern: /(^|[^/\w.-])-?(?:NAN|INFINITY|0x(?:[\dA-F]+(?:\.[\dA-F]*)?|\.[\dA-F]+)(?:p[+-]?[\dA-F]+)?|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)[dflst]?(?![\w.-])/i,
+               lookbehind: true
+       },
+
+       'label': {
+               pattern: /(:)\w+/,
+               lookbehind: true,
+               alias: 'property'
+       },
+
+       'operator': /->|\.\.|[\[=]/,
+       'punctuation': /[{}(),;:]/
+};
+
+return Prism; })
\ No newline at end of file
index a7c15d1f987b9a54e5ceb041ff9262339d511b40..01ae7d5e30bb53c2f3cb773bc973730b0a841baf 100644 (file)
@@ -1,6 +1,10 @@
 define(["prism/prism"], function () {
 Prism.languages.smalltalk = {
        'comment': /"(?:""|[^"])*"/,
+       'character': {
+               pattern: /\$./,
+               alias: 'string'
+       },
        'string': /'(?:''|[^'])*'/,
        'symbol': /#[\da-z]+|#(?:-|([+\/\\*~<>=@%|&?!])\1?)|#(?=\()/i,
        'block-arguments': {
@@ -19,10 +23,6 @@ Prism.languages.smalltalk = {
                }
        },
        'keyword': /\b(?:nil|true|false|self|super|new)\b/,
-       'character': {
-               pattern: /\$./,
-               alias: 'string'
-       },
        'number': [
                /\d+r-?[\dA-Z]+(?:\.[\dA-Z]+)?(?:e-?\d+)?/,
                /\b\d+(?:\.\d+)?(?:e-?\d+)?/
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-solidity.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-solidity.js
new file mode 100644 (file)
index 0000000..e35af92
--- /dev/null
@@ -0,0 +1,25 @@
+define(["prism/prism","prism/components/prism-clike"], function () {
+Prism.languages.solidity = Prism.languages.extend('clike', {
+       'class-name': {
+               pattern: /(\b(?:contract|enum|interface|library|new|struct|using)\s+)(?!\d)[\w$]+/,
+               lookbehind: true
+       },
+       'keyword': /\b(?:_|anonymous|as|assembly|assert|break|calldata|case|constant|constructor|continue|contract|default|delete|do|else|emit|enum|event|external|for|from|function|if|import|indexed|inherited|interface|internal|is|let|library|mapping|memory|modifier|new|payable|pragma|private|public|pure|require|returns?|revert|selfdestruct|solidity|storage|struct|suicide|switch|this|throw|using|var|view|while)\b/,
+       'operator': /=>|->|:=|=:|\*\*|\+\+|--|\|\||&&|<<=?|>>=?|[-+*/%^&|<>!=]=?|[~?]/
+});
+
+Prism.languages.insertBefore('solidity', 'keyword', {
+       'builtin': /\b(?:address|bool|string|u?int(?:8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|byte|bytes(?:[1-9]|[12]\d|3[0-2])?)\b/
+});
+
+Prism.languages.insertBefore('solidity', 'number', {
+       'version': {
+               pattern: /([<>]=?|\^)\d+\.\d+\.\d+\b/,
+               lookbehind: true,
+               alias: 'number',
+       }
+});
+
+Prism.languages.sol = Prism.languages.solidity;
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-solution-file.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-solution-file.js
new file mode 100644 (file)
index 0000000..7ee32a4
--- /dev/null
@@ -0,0 +1,54 @@
+define(["prism/prism"], function () {
+(function (Prism){
+
+       var guid = {
+               // https://en.wikipedia.org/wiki/Universally_unique_identifier#Format
+               pattern: /\{[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\}/i,
+               alias: 'constant',
+               inside: {
+                       'punctuation': /[{}]/
+               }
+       };
+
+       Prism.languages['solution-file'] = {
+               'comment': {
+                       pattern: /#.*/,
+                       greedy: true
+               },
+               'string': {
+                       pattern: /"[^"\r\n]*"|'[^'\r\n]*'/,
+                       greedy: true,
+                       inside: {
+                               'guid': guid
+                       }
+               },
+               'object': {
+                       // Foo
+                       //   Bar("abs") = 9
+                       //   EndBar
+                       //   Prop = TRUE
+                       // EndFoo
+                       pattern: /^([ \t]*)(?:([A-Z]\w*)\b(?=.*(?:\r\n?|\n)(?:\1[ \t].*(?:\r\n?|\n))*\1End\2(?=[ \t]*$))|End[A-Z]\w*(?=[ \t]*$))/m,
+                       lookbehind: true,
+                       greedy: true,
+                       alias: 'keyword'
+               },
+               'property': {
+                       pattern: /^([ \t]*)[^\r\n"#=()]*[^\s"#=()](?=\s*=)/m,
+                       lookbehind: true,
+                       inside: {
+                               'guid': guid
+                       }
+               },
+               'guid': guid,
+               'number': /\b\d+(?:\.\d+)*\b/,
+               'boolean': /\b(?:FALSE|TRUE)\b/,
+               'operator': /=/,
+               'punctuation': /[(),]/
+       };
+
+       Prism.languages['sln'] = Prism.languages['solution-file'];
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-sparql.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-sparql.js
new file mode 100644 (file)
index 0000000..9b0fc93
--- /dev/null
@@ -0,0 +1,21 @@
+define(["prism/prism","prism/components/prism-turtle"], function () {
+Prism.languages.sparql = Prism.languages.extend('turtle', {
+               'variable': {
+                       pattern: /[?$]\w+/,
+                       greedy: true
+               },
+               'boolean': /\b(?:true|false)\b/i,
+       }
+);
+
+Prism.languages.insertBefore('sparql', 'punctuation', {
+       'keyword': [
+               /\b(?:A|ADD|ALL|AS|ASC|ASK|BNODE|BY|CLEAR|CONSTRUCT|COPY|CREATE|DATA|DEFAULT|DELETE|DESC|DESCRIBE|DISTINCT|DROP|EXISTS|FILTER|FROM|GROUP|HAVING|INSERT|INTO|LIMIT|LOAD|MINUS|MOVE|NAMED|NOT|NOW|OFFSET|OPTIONAL|ORDER|RAND|REDUCED|SELECT|SEPARATOR|SERVICE|SILENT|STRUUID|UNION|USING|UUID|VALUES|WHERE)\b/i,
+               /\b(?:ABS|AVG|BIND|BOUND|CEIL|COALESCE|CONCAT|CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|FLOOR|GROUP_CONCAT|HOURS|IF|IRI|isBLANK|isIRI|isLITERAL|isNUMERIC|isURI|LANG|LANGMATCHES|LCASE|MAX|MD5|MIN|MINUTES|MONTH|ROUND|REGEX|REPLACE|sameTerm|SAMPLE|SECONDS|SHA1|SHA256|SHA384|SHA512|STR|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|SUM|TIMEZONE|TZ|UCASE|URI|YEAR)\b(?=\s*\()/i,
+               /\b(?:GRAPH|BASE|PREFIX)\b/i
+       ]
+});
+
+Prism.languages.rq = Prism.languages.sparql;
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-splunk-spl.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-splunk-spl.js
new file mode 100644 (file)
index 0000000..3d45a9f
--- /dev/null
@@ -0,0 +1,27 @@
+define(["prism/prism"], function () {
+Prism.languages['splunk-spl'] = {
+       'comment': /`comment\("(?:\\.|[^\\"])*"\)`/,
+       'string': {
+               pattern: /"(?:\\.|[^\\"])*"/,
+               greedy: true
+       },
+       // https://docs.splunk.com/Documentation/Splunk/7.3.0/SearchReference/ListOfSearchCommands
+       'keyword': /\b(?:abstract|accum|addcoltotals|addinfo|addtotals|analyzefields|anomalies|anomalousvalue|anomalydetection|append|appendcols|appendcsv|appendlookup|appendpipe|arules|associate|audit|autoregress|bin|bucket|bucketdir|chart|cluster|cofilter|collect|concurrency|contingency|convert|correlate|datamodel|dbinspect|dedup|delete|delta|diff|erex|eval|eventcount|eventstats|extract|fieldformat|fields|fieldsummary|filldown|fillnull|findtypes|folderize|foreach|format|from|gauge|gentimes|geom|geomfilter|geostats|head|highlight|history|iconify|input|inputcsv|inputlookup|iplocation|join|kmeans|kv|kvform|loadjob|localize|localop|lookup|makecontinuous|makemv|makeresults|map|mcollect|metadata|metasearch|meventcollect|mstats|multikv|multisearch|mvcombine|mvexpand|nomv|outlier|outputcsv|outputlookup|outputtext|overlap|pivot|predict|rangemap|rare|regex|relevancy|reltime|rename|replace|rest|return|reverse|rex|rtorder|run|savedsearch|script|scrub|search|searchtxn|selfjoin|sendemail|set|setfields|sichart|sirare|sistats|sitimechart|sitop|sort|spath|stats|strcat|streamstats|table|tags|tail|timechart|timewrap|top|transaction|transpose|trendline|tscollect|tstats|typeahead|typelearner|typer|union|uniq|untable|where|x11|xmlkv|xmlunescape|xpath|xyseries)\b/i,
+       'operator-word': {
+               pattern: /\b(?:and|as|by|not|or|xor)\b/i,
+               alias: 'operator'
+       },
+       'function': /\w+(?=\s*\()/,
+       'property': /\w+(?=\s*=(?!=))/,
+       'date': {
+               // MM/DD/YYYY(:HH:MM:SS)?
+               pattern: /\b\d{1,2}\/\d{1,2}\/\d{1,4}(?:(?::\d{1,2}){3})?\b/,
+               alias: 'number'
+       },
+       'number': /\b\d+(?:\.\d+)?\b/,
+       'boolean': /\b(?:f|false|t|true)\b/i,
+       'operator': /[<>=]=?|[-+*/%|]/,
+       'punctuation': /[()[\],]/
+}
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-sqf.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-sqf.js
new file mode 100644 (file)
index 0000000..8051726
--- /dev/null
@@ -0,0 +1,37 @@
+define(["prism/prism","prism/components/prism-clike"], function () {
+Prism.languages.sqf = Prism.languages.extend('clike', {
+       'string': {
+               pattern: /"(?:(?:"")?[^"])*"(?!")|'(?:[^'])*'/,
+               greedy: true
+       },
+       'keyword': /\b(?:breakOut|breakTo|call|case|catch|default|do|echo|else|execVM|execFSM|exitWith|for|forEach|forEachMember|forEachMemberAgent|forEachMemberTeam|from|goto|if|nil|preprocessFile|preprocessFileLineNumbers|private|scopeName|spawn|step|switch|then|throw|to|try|while|with)\b/i,
+       'magic-variable': {
+               pattern: /\b(?:_exception|_fnc_scriptName|_fnc_scriptNameParent|_forEachIndex|_this|_thisEventHandler|_thisFSM|_thisScript|_x|this|thisList|thisTrigger)\b/i,
+               alias: 'keyword'
+       },
+       'boolean': /\b(?:true|false)\b/i,
+       'function': /\b(?:abs|accTime|acos|action|actionIDs|actionKeys|actionKeysImages|actionKeysNames|actionKeysNamesArray|actionName|actionParams|activateAddons|activatedAddons|activateKey|add3DENConnection|add3DENEventHandler|add3DENLayer|addAction|addBackpack|addBackpackCargo|addBackpackCargoGlobal|addBackpackGlobal|addCamShake|addCuratorAddons|addCuratorCameraArea|addCuratorEditableObjects|addCuratorEditingArea|addCuratorPoints|addEditorObject|addEventHandler|addForce|addForceGeneratorRTD|addGoggles|addGroupIcon|addHandgunItem|addHeadgear|addItem|addItemCargo|addItemCargoGlobal|addItemPool|addItemToBackpack|addItemToUniform|addItemToVest|addLiveStats|addMagazine|addMagazineAmmoCargo|addMagazineCargo|addMagazineCargoGlobal|addMagazineGlobal|addMagazinePool|addMagazines|addMagazineTurret|addMenu|addMenuItem|addMissionEventHandler|addMPEventHandler|addMusicEventHandler|addOwnedMine|addPlayerScores|addPrimaryWeaponItem|addPublicVariableEventHandler|addRating|addResources|addScore|addScoreSide|addSecondaryWeaponItem|addSwitchableUnit|addTeamMember|addToRemainsCollector|addTorque|addUniform|addVehicle|addVest|addWaypoint|addWeapon|addWeaponCargo|addWeaponCargoGlobal|addWeaponGlobal|addWeaponItem|addWeaponPool|addWeaponTurret|admin|agent|agents|AGLToASL|aimedAtTarget|aimPos|airDensityCurveRTD|airDensityRTD|airplaneThrottle|airportSide|AISFinishHeal|alive|all3DENEntities|allAirports|allControls|allCurators|allCutLayers|allDead|allDeadMen|allDisplays|allGroups|allMapMarkers|allMines|allMissionObjects|allow3DMode|allowCrewInImmobile|allowCuratorLogicIgnoreAreas|allowDamage|allowDammage|allowFileOperations|allowFleeing|allowGetIn|allowSprint|allPlayers|allSimpleObjects|allSites|allTurrets|allUnits|allUnitsUAV|allVariables|ammo|ammoOnPylon|animate|animateBay|animateDoor|animatePylon|animateSource|animationNames|animationPhase|animationSourcePhase|animationState|append|apply|armoryPoints|arrayIntersect|asin|ASLToAGL|ASLToATL|assert|assignAsCargo|assignAsCargoIndex|assignAsCommander|assignAsDriver|assignAsGunner|assignAsTurret|assignCurator|assignedCargo|assignedCommander|assignedDriver|assignedGunner|assignedItems|assignedTarget|assignedTeam|assignedVehicle|assignedVehicleRole|assignItem|assignTeam|assignToAirport|atan|atan2|atg|ATLToASL|attachedObject|attachedObjects|attachedTo|attachObject|attachTo|attackEnabled|backpack|backpackCargo|backpackContainer|backpackItems|backpackMagazines|backpackSpaceFor|behaviour|benchmark|binocular|blufor|boundingBox|boundingBoxReal|boundingCenter|briefingName|buildingExit|buildingPos|buldozer_EnableRoadDiag|buldozer_IsEnabledRoadDiag|buldozer_LoadNewRoads|buldozer_reloadOperMap|buttonAction|buttonSetAction|cadetMode|callExtension|camCommand|camCommit|camCommitPrepared|camCommitted|camConstuctionSetParams|camCreate|camDestroy|cameraEffect|cameraEffectEnableHUD|cameraInterest|cameraOn|cameraView|campaignConfigFile|camPreload|camPreloaded|camPrepareBank|camPrepareDir|camPrepareDive|camPrepareFocus|camPrepareFov|camPrepareFovRange|camPreparePos|camPrepareRelPos|camPrepareTarget|camSetBank|camSetDir|camSetDive|camSetFocus|camSetFov|camSetFovRange|camSetPos|camSetRelPos|camSetTarget|camTarget|camUseNVG|canAdd|canAddItemToBackpack|canAddItemToUniform|canAddItemToVest|cancelSimpleTaskDestination|canFire|canMove|canSlingLoad|canStand|canSuspend|canTriggerDynamicSimulation|canUnloadInCombat|canVehicleCargo|captive|captiveNum|cbChecked|cbSetChecked|ceil|channelEnabled|cheatsEnabled|checkAIFeature|checkVisibility|civilian|className|clear3DENAttribute|clear3DENInventory|clearAllItemsFromBackpack|clearBackpackCargo|clearBackpackCargoGlobal|clearForcesRTD|clearGroupIcons|clearItemCargo|clearItemCargoGlobal|clearItemPool|clearMagazineCargo|clearMagazineCargoGlobal|clearMagazinePool|clearOverlay|clearRadio|clearVehicleInit|clearWeaponCargo|clearWeaponCargoGlobal|clearWeaponPool|clientOwner|closeDialog|closeDisplay|closeOverlay|collapseObjectTree|collect3DENHistory|collectiveRTD|combatMode|commandArtilleryFire|commandChat|commander|commandFire|commandFollow|commandFSM|commandGetOut|commandingMenu|commandMove|commandRadio|commandStop|commandSuppressiveFire|commandTarget|commandWatch|comment|commitOverlay|compile|compileFinal|completedFSM|composeText|configClasses|configFile|configHierarchy|configName|configNull|configProperties|configSourceAddonList|configSourceMod|configSourceModList|confirmSensorTarget|connectTerminalToUAV|controlNull|controlsGroupCtrl|copyFromClipboard|copyToClipboard|copyWaypoints|cos|count|countEnemy|countFriendly|countSide|countType|countUnknown|create3DENComposition|create3DENEntity|createAgent|createCenter|createDialog|createDiaryLink|createDiaryRecord|createDiarySubject|createDisplay|createGearDialog|createGroup|createGuardedPoint|createLocation|createMarker|createMarkerLocal|createMenu|createMine|createMissionDisplay|createMPCampaignDisplay|createSimpleObject|createSimpleTask|createSite|createSoundSource|createTask|createTeam|createTrigger|createUnit|createVehicle|createVehicleCrew|createVehicleLocal|crew|ctAddHeader|ctAddRow|ctClear|ctCurSel|ctData|ctFindHeaderRows|ctFindRowHeader|ctHeaderControls|ctHeaderCount|ctRemoveHeaders|ctRemoveRows|ctrlActivate|ctrlAddEventHandler|ctrlAngle|ctrlAutoScrollDelay|ctrlAutoScrollRewind|ctrlAutoScrollSpeed|ctrlChecked|ctrlClassName|ctrlCommit|ctrlCommitted|ctrlCreate|ctrlDelete|ctrlEnable|ctrlEnabled|ctrlFade|ctrlHTMLLoaded|ctrlIDC|ctrlIDD|ctrlMapAnimAdd|ctrlMapAnimClear|ctrlMapAnimCommit|ctrlMapAnimDone|ctrlMapCursor|ctrlMapMouseOver|ctrlMapScale|ctrlMapScreenToWorld|ctrlMapWorldToScreen|ctrlModel|ctrlModelDirAndUp|ctrlModelScale|ctrlParent|ctrlParentControlsGroup|ctrlPosition|ctrlRemoveAllEventHandlers|ctrlRemoveEventHandler|ctrlScale|ctrlSetActiveColor|ctrlSetAngle|ctrlSetAutoScrollDelay|ctrlSetAutoScrollRewind|ctrlSetAutoScrollSpeed|ctrlSetBackgroundColor|ctrlSetChecked|ctrlSetDisabledColor|ctrlSetEventHandler|ctrlSetFade|ctrlSetFocus|ctrlSetFont|ctrlSetFontH1|ctrlSetFontH1B|ctrlSetFontH2|ctrlSetFontH2B|ctrlSetFontH3|ctrlSetFontH3B|ctrlSetFontH4|ctrlSetFontH4B|ctrlSetFontH5|ctrlSetFontH5B|ctrlSetFontH6|ctrlSetFontH6B|ctrlSetFontHeight|ctrlSetFontHeightH1|ctrlSetFontHeightH2|ctrlSetFontHeightH3|ctrlSetFontHeightH4|ctrlSetFontHeightH5|ctrlSetFontHeightH6|ctrlSetFontHeightSecondary|ctrlSetFontP|ctrlSetFontPB|ctrlSetFontSecondary|ctrlSetForegroundColor|ctrlSetModel|ctrlSetModelDirAndUp|ctrlSetModelScale|ctrlSetPixelPrecision|ctrlSetPosition|ctrlSetScale|ctrlSetStructuredText|ctrlSetText|ctrlSetTextColor|ctrlSetTextColorSecondary|ctrlSetTextSecondary|ctrlSetTooltip|ctrlSetTooltipColorBox|ctrlSetTooltipColorShade|ctrlSetTooltipColorText|ctrlShow|ctrlShown|ctrlText|ctrlTextHeight|ctrlTextSecondary|ctrlTextWidth|ctrlType|ctrlVisible|ctRowControls|ctRowCount|ctSetCurSel|ctSetData|ctSetHeaderTemplate|ctSetRowTemplate|ctSetValue|ctValue|curatorAddons|curatorCamera|curatorCameraArea|curatorCameraAreaCeiling|curatorCoef|curatorEditableObjects|curatorEditingArea|curatorEditingAreaType|curatorMouseOver|curatorPoints|curatorRegisteredObjects|curatorSelected|curatorWaypointCost|current3DENOperation|currentChannel|currentCommand|currentMagazine|currentMagazineDetail|currentMagazineDetailTurret|currentMagazineTurret|currentMuzzle|currentNamespace|currentTask|currentTasks|currentThrowable|currentVisionMode|currentWaypoint|currentWeapon|currentWeaponMode|currentWeaponTurret|currentZeroing|cursorObject|cursorTarget|customChat|customRadio|cutFadeOut|cutObj|cutRsc|cutText|damage|date|dateToNumber|daytime|deActivateKey|debriefingText|debugFSM|debugLog|deg|delete3DENEntities|deleteAt|deleteCenter|deleteCollection|deleteEditorObject|deleteGroup|deleteGroupWhenEmpty|deleteIdentity|deleteLocation|deleteMarker|deleteMarkerLocal|deleteRange|deleteResources|deleteSite|deleteStatus|deleteTeam|deleteVehicle|deleteVehicleCrew|deleteWaypoint|detach|detectedMines|diag_activeMissionFSMs|diag_activeScripts|diag_activeSQFScripts|diag_activeSQSScripts|diag_captureFrame|diag_captureFrameToFile|diag_captureSlowFrame|diag_codePerformance|diag_drawMode|diag_dynamicSimulationEnd|diag_enable|diag_enabled|diag_fps|diag_fpsMin|diag_frameNo|diag_lightNewLoad|diag_list|diag_log|diag_logSlowFrame|diag_mergeConfigFile|diag_recordTurretLimits|diag_setLightNew|diag_tickTime|diag_toggle|dialog|diarySubjectExists|didJIP|didJIPOwner|difficulty|difficultyEnabled|difficultyEnabledRTD|difficultyOption|direction|directSay|disableAI|disableCollisionWith|disableConversation|disableDebriefingStats|disableMapIndicators|disableNVGEquipment|disableRemoteSensors|disableSerialization|disableTIEquipment|disableUAVConnectability|disableUserInput|displayAddEventHandler|displayCtrl|displayNull|displayParent|displayRemoveAllEventHandlers|displayRemoveEventHandler|displaySetEventHandler|dissolveTeam|distance|distance2D|distanceSqr|distributionRegion|do3DENAction|doArtilleryFire|doFire|doFollow|doFSM|doGetOut|doMove|doorPhase|doStop|doSuppressiveFire|doTarget|doWatch|drawArrow|drawEllipse|drawIcon|drawIcon3D|drawLine|drawLine3D|drawLink|drawLocation|drawPolygon|drawRectangle|drawTriangle|driver|drop|dynamicSimulationDistance|dynamicSimulationDistanceCoef|dynamicSimulationEnabled|dynamicSimulationSystemEnabled|east|edit3DENMissionAttributes|editObject|editorSetEventHandler|effectiveCommander|emptyPositions|enableAI|enableAIFeature|enableAimPrecision|enableAttack|enableAudioFeature|enableAutoStartUpRTD|enableAutoTrimRTD|enableCamShake|enableCaustics|enableChannel|enableCollisionWith|enableCopilot|enableDebriefingStats|enableDiagLegend|enableDynamicSimulation|enableDynamicSimulationSystem|enableEndDialog|enableEngineArtillery|enableEnvironment|enableFatigue|enableGunLights|enableInfoPanelComponent|enableIRLasers|enableMimics|enablePersonTurret|enableRadio|enableReload|enableRopeAttach|enableSatNormalOnDetail|enableSaving|enableSentences|enableSimulation|enableSimulationGlobal|enableStamina|enableStressDamage|enableTeamSwitch|enableTraffic|enableUAVConnectability|enableUAVWaypoints|enableVehicleCargo|enableVehicleSensor|enableWeaponDisassembly|endl|endLoadingScreen|endMission|engineOn|enginesIsOnRTD|enginesPowerRTD|enginesRpmRTD|enginesTorqueRTD|entities|environmentEnabled|estimatedEndServerTime|estimatedTimeLeft|evalObjectArgument|everyBackpack|everyContainer|exec|execEditorScript|exp|expectedDestination|exportJIPMessages|eyeDirection|eyePos|face|faction|fadeMusic|fadeRadio|fadeSound|fadeSpeech|failMission|fillWeaponsFromPool|find|findCover|findDisplay|findEditorObject|findEmptyPosition|findEmptyPositionReady|findIf|findNearestEnemy|finishMissionInit|finite|fire|fireAtTarget|firstBackpack|flag|flagAnimationPhase|flagOwner|flagSide|flagTexture|fleeing|floor|flyInHeight|flyInHeightASL|fog|fogForecast|fogParams|forceAddUniform|forceAtPositionRTD|forcedMap|forceEnd|forceFlagTexture|forceFollowRoad|forceGeneratorRTD|forceMap|forceRespawn|forceSpeed|forceWalk|forceWeaponFire|forceWeatherChange|forgetTarget|format|formation|formationDirection|formationLeader|formationMembers|formationPosition|formationTask|formatText|formLeader|freeLook|fromEditor|fuel|fullCrew|gearIDCAmmoCount|gearSlotAmmoCount|gearSlotData|get3DENActionState|get3DENAttribute|get3DENCamera|get3DENConnections|get3DENEntity|get3DENEntityID|get3DENGrid|get3DENIconsVisible|get3DENLayerEntities|get3DENLinesVisible|get3DENMissionAttribute|get3DENMouseOver|get3DENSelected|getAimingCoef|getAllEnvSoundControllers|getAllHitPointsDamage|getAllOwnedMines|getAllSoundControllers|getAmmoCargo|getAnimAimPrecision|getAnimSpeedCoef|getArray|getArtilleryAmmo|getArtilleryComputerSettings|getArtilleryETA|getAssignedCuratorLogic|getAssignedCuratorUnit|getBackpackCargo|getBleedingRemaining|getBurningValue|getCameraViewDirection|getCargoIndex|getCenterOfMass|getClientState|getClientStateNumber|getCompatiblePylonMagazines|getConnectedUAV|getContainerMaxLoad|getCursorObjectParams|getCustomAimCoef|getDammage|getDescription|getDir|getDirVisual|getDLCAssetsUsage|getDLCAssetsUsageByName|getDLCs|getDLCUsageTime|getEditorCamera|getEditorMode|getEditorObjectScope|getElevationOffset|getEngineTargetRpmRTD|getEnvSoundController|getFatigue|getFieldManualStartPage|getForcedFlagTexture|getFriend|getFSMVariable|getFuelCargo|getGroupIcon|getGroupIconParams|getGroupIcons|getHideFrom|getHit|getHitIndex|getHitPointDamage|getItemCargo|getMagazineCargo|getMarkerColor|getMarkerPos|getMarkerSize|getMarkerType|getMass|getMissionConfig|getMissionConfigValue|getMissionDLCs|getMissionLayerEntities|getMissionLayers|getModelInfo|getMousePosition|getMusicPlayedTime|getNumber|getObjectArgument|getObjectChildren|getObjectDLC|getObjectMaterials|getObjectProxy|getObjectTextures|getObjectType|getObjectViewDistance|getOxygenRemaining|getPersonUsedDLCs|getPilotCameraDirection|getPilotCameraPosition|getPilotCameraRotation|getPilotCameraTarget|getPlateNumber|getPlayerChannel|getPlayerScores|getPlayerUID|getPlayerUIDOld|getPos|getPosASL|getPosASLVisual|getPosASLW|getPosATL|getPosATLVisual|getPosVisual|getPosWorld|getPylonMagazines|getRelDir|getRelPos|getRemoteSensorsDisabled|getRepairCargo|getResolution|getRotorBrakeRTD|getShadowDistance|getShotParents|getSlingLoad|getSoundController|getSoundControllerResult|getSpeed|getStamina|getStatValue|getSuppression|getTerrainGrid|getTerrainHeightASL|getText|getTotalDLCUsageTime|getTrimOffsetRTD|getUnitLoadout|getUnitTrait|getUserMFDText|getUserMFDValue|getVariable|getVehicleCargo|getWeaponCargo|getWeaponSway|getWingsOrientationRTD|getWingsPositionRTD|getWPPos|glanceAt|globalChat|globalRadio|goggles|group|groupChat|groupFromNetId|groupIconSelectable|groupIconsVisible|groupId|groupOwner|groupRadio|groupSelectedUnits|groupSelectUnit|grpNull|gunner|gusts|halt|handgunItems|handgunMagazine|handgunWeapon|handsHit|hasInterface|hasPilotCamera|hasWeapon|hcAllGroups|hcGroupParams|hcLeader|hcRemoveAllGroups|hcRemoveGroup|hcSelected|hcSelectGroup|hcSetGroup|hcShowBar|hcShownBar|headgear|hideBody|hideObject|hideObjectGlobal|hideSelection|hint|hintC|hintCadet|hintSilent|hmd|hostMission|htmlLoad|HUDMovementLevels|humidity|image|importAllGroups|importance|in|inArea|inAreaArray|incapacitatedState|independent|inflame|inflamed|infoPanel|infoPanelComponentEnabled|infoPanelComponents|infoPanels|inGameUISetEventHandler|inheritsFrom|initAmbientLife|inPolygon|inputAction|inRangeOfArtillery|insertEditorObject|intersect|is3DEN|is3DENMultiplayer|isAbleToBreathe|isAgent|isAimPrecisionEnabled|isArray|isAutoHoverOn|isAutonomous|isAutoStartUpEnabledRTD|isAutotest|isAutoTrimOnRTD|isBleeding|isBurning|isClass|isCollisionLightOn|isCopilotEnabled|isDamageAllowed|isDedicated|isDLCAvailable|isEngineOn|isEqualTo|isEqualType|isEqualTypeAll|isEqualTypeAny|isEqualTypeArray|isEqualTypeParams|isFilePatchingEnabled|isFlashlightOn|isFlatEmpty|isForcedWalk|isFormationLeader|isGroupDeletedWhenEmpty|isHidden|isInRemainsCollector|isInstructorFigureEnabled|isIRLaserOn|isKeyActive|isKindOf|isLaserOn|isLightOn|isLocalized|isManualFire|isMarkedForCollection|isMultiplayer|isMultiplayerSolo|isNil|isNull|isNumber|isObjectHidden|isObjectRTD|isOnRoad|isPipEnabled|isPlayer|isRealTime|isRemoteExecuted|isRemoteExecutedJIP|isServer|isShowing3DIcons|isSimpleObject|isSprintAllowed|isStaminaEnabled|isSteamMission|isStreamFriendlyUIEnabled|isStressDamageEnabled|isText|isTouchingGround|isTurnedOut|isTutHintsEnabled|isUAVConnectable|isUAVConnected|isUIContext|isUniformAllowed|isVehicleCargo|isVehicleRadarOn|isVehicleSensorEnabled|isWalking|isWeaponDeployed|isWeaponRested|itemCargo|items|itemsWithMagazines|join|joinAs|joinAsSilent|joinSilent|joinString|kbAddDatabase|kbAddDatabaseTargets|kbAddTopic|kbHasTopic|kbReact|kbRemoveTopic|kbTell|kbWasSaid|keyImage|keyName|knowsAbout|land|landAt|landResult|language|laserTarget|lbAdd|lbClear|lbColor|lbColorRight|lbCurSel|lbData|lbDelete|lbIsSelected|lbPicture|lbPictureRight|lbSelection|lbSetColor|lbSetColorRight|lbSetCurSel|lbSetData|lbSetPicture|lbSetPictureColor|lbSetPictureColorDisabled|lbSetPictureColorSelected|lbSetPictureRight|lbSetPictureRightColor|lbSetPictureRightColorDisabled|lbSetPictureRightColorSelected|lbSetSelectColor|lbSetSelectColorRight|lbSetSelected|lbSetText|lbSetTextRight|lbSetTooltip|lbSetValue|lbSize|lbSort|lbSortByValue|lbText|lbTextRight|lbValue|leader|leaderboardDeInit|leaderboardGetRows|leaderboardInit|leaderboardRequestRowsFriends|leaderboardRequestRowsGlobal|leaderboardRequestRowsGlobalAroundUser|leaderboardsRequestUploadScore|leaderboardsRequestUploadScoreKeepBest|leaderboardState|leaveVehicle|libraryCredits|libraryDisclaimers|lifeState|lightAttachObject|lightDetachObject|lightIsOn|lightnings|limitSpeed|linearConversion|lineBreak|lineIntersects|lineIntersectsObjs|lineIntersectsSurfaces|lineIntersectsWith|linkItem|list|listObjects|listRemoteTargets|listVehicleSensors|ln|lnbAddArray|lnbAddColumn|lnbAddRow|lnbClear|lnbColor|lnbColorRight|lnbCurSelRow|lnbData|lnbDeleteColumn|lnbDeleteRow|lnbGetColumnsPosition|lnbPicture|lnbPictureRight|lnbSetColor|lnbSetColorRight|lnbSetColumnsPos|lnbSetCurSelRow|lnbSetData|lnbSetPicture|lnbSetPictureColor|lnbSetPictureColorRight|lnbSetPictureColorSelected|lnbSetPictureColorSelectedRight|lnbSetPictureRight|lnbSetText|lnbSetTextRight|lnbSetValue|lnbSize|lnbSort|lnbSortByValue|lnbText|lnbTextRight|lnbValue|load|loadAbs|loadBackpack|loadFile|loadGame|loadIdentity|loadMagazine|loadOverlay|loadStatus|loadUniform|loadVest|local|localize|locationNull|locationPosition|lock|lockCameraTo|lockCargo|lockDriver|locked|lockedCargo|lockedDriver|lockedTurret|lockIdentity|lockTurret|lockWP|log|logEntities|logNetwork|logNetworkTerminate|lookAt|lookAtPos|magazineCargo|magazines|magazinesAllTurrets|magazinesAmmo|magazinesAmmoCargo|magazinesAmmoFull|magazinesDetail|magazinesDetailBackpack|magazinesDetailUniform|magazinesDetailVest|magazinesTurret|magazineTurretAmmo|mapAnimAdd|mapAnimClear|mapAnimCommit|mapAnimDone|mapCenterOnCamera|mapGridPosition|markAsFinishedOnSteam|markerAlpha|markerBrush|markerColor|markerDir|markerPos|markerShape|markerSize|markerText|markerType|max|members|menuAction|menuAdd|menuChecked|menuClear|menuCollapse|menuData|menuDelete|menuEnable|menuEnabled|menuExpand|menuHover|menuPicture|menuSetAction|menuSetCheck|menuSetData|menuSetPicture|menuSetValue|menuShortcut|menuShortcutText|menuSize|menuSort|menuText|menuURL|menuValue|min|mineActive|mineDetectedBy|missionConfigFile|missionDifficulty|missionName|missionNamespace|missionStart|missionVersion|modelToWorld|modelToWorldVisual|modelToWorldVisualWorld|modelToWorldWorld|modParams|moonIntensity|moonPhase|morale|move|move3DENCamera|moveInAny|moveInCargo|moveInCommander|moveInDriver|moveInGunner|moveInTurret|moveObjectToEnd|moveOut|moveTime|moveTo|moveToCompleted|moveToFailed|musicVolume|name|nameSound|nearEntities|nearestBuilding|nearestLocation|nearestLocations|nearestLocationWithDubbing|nearestObject|nearestObjects|nearestTerrainObjects|nearObjects|nearObjectsReady|nearRoads|nearSupplies|nearTargets|needReload|netId|netObjNull|newOverlay|nextMenuItemIndex|nextWeatherChange|nMenuItems|numberOfEnginesRTD|numberToDate|objectCurators|objectFromNetId|objectParent|objNull|objStatus|onBriefingGear|onBriefingGroup|onBriefingNotes|onBriefingPlan|onBriefingTeamSwitch|onCommandModeChanged|onDoubleClick|onEachFrame|onGroupIconClick|onGroupIconOverEnter|onGroupIconOverLeave|onHCGroupSelectionChanged|onMapSingleClick|onPlayerConnected|onPlayerDisconnected|onPreloadFinished|onPreloadStarted|onShowNewObject|onTeamSwitch|openCuratorInterface|openDLCPage|openDSInterface|openMap|openSteamApp|openYoutubeVideo|opfor|orderGetIn|overcast|overcastForecast|owner|param|params|parseNumber|parseSimpleArray|parseText|parsingNamespace|particlesQuality|pi|pickWeaponPool|pitch|pixelGrid|pixelGridBase|pixelGridNoUIScale|pixelH|pixelW|playableSlotsNumber|playableUnits|playAction|playActionNow|player|playerRespawnTime|playerSide|playersNumber|playGesture|playMission|playMove|playMoveNow|playMusic|playScriptedMission|playSound|playSound3D|position|positionCameraToWorld|posScreenToWorld|posWorldToScreen|ppEffectAdjust|ppEffectCommit|ppEffectCommitted|ppEffectCreate|ppEffectDestroy|ppEffectEnable|ppEffectEnabled|ppEffectForceInNVG|precision|preloadCamera|preloadObject|preloadSound|preloadTitleObj|preloadTitleRsc|primaryWeapon|primaryWeaponItems|primaryWeaponMagazine|priority|processDiaryLink|processInitCommands|productVersion|profileName|profileNamespace|profileNameSteam|progressLoadingScreen|progressPosition|progressSetPosition|publicVariable|publicVariableClient|publicVariableServer|pushBack|pushBackUnique|putWeaponPool|queryItemsPool|queryMagazinePool|queryWeaponPool|rad|radioChannelAdd|radioChannelCreate|radioChannelRemove|radioChannelSetCallSign|radioChannelSetLabel|radioVolume|rain|rainbow|random|rank|rankId|rating|rectangular|registeredTasks|registerTask|reload|reloadEnabled|remoteControl|remoteExec|remoteExecCall|remoteExecutedOwner|remove3DENConnection|remove3DENEventHandler|remove3DENLayer|removeAction|removeAll3DENEventHandlers|removeAllActions|removeAllAssignedItems|removeAllContainers|removeAllCuratorAddons|removeAllCuratorCameraAreas|removeAllCuratorEditingAreas|removeAllEventHandlers|removeAllHandgunItems|removeAllItems|removeAllItemsWithMagazines|removeAllMissionEventHandlers|removeAllMPEventHandlers|removeAllMusicEventHandlers|removeAllOwnedMines|removeAllPrimaryWeaponItems|removeAllWeapons|removeBackpack|removeBackpackGlobal|removeCuratorAddons|removeCuratorCameraArea|removeCuratorEditableObjects|removeCuratorEditingArea|removeDrawIcon|removeDrawLinks|removeEventHandler|removeFromRemainsCollector|removeGoggles|removeGroupIcon|removeHandgunItem|removeHeadgear|removeItem|removeItemFromBackpack|removeItemFromUniform|removeItemFromVest|removeItems|removeMagazine|removeMagazineGlobal|removeMagazines|removeMagazinesTurret|removeMagazineTurret|removeMenuItem|removeMissionEventHandler|removeMPEventHandler|removeMusicEventHandler|removeOwnedMine|removePrimaryWeaponItem|removeSecondaryWeaponItem|removeSimpleTask|removeSwitchableUnit|removeTeamMember|removeUniform|removeVest|removeWeapon|removeWeaponAttachmentCargo|removeWeaponCargo|removeWeaponGlobal|removeWeaponTurret|reportRemoteTarget|requiredVersion|resetCamShake|resetSubgroupDirection|resistance|resize|resources|respawnVehicle|restartEditorCamera|reveal|revealMine|reverse|reversedMouseY|roadAt|roadsConnectedTo|roleDescription|ropeAttachedObjects|ropeAttachedTo|ropeAttachEnabled|ropeAttachTo|ropeCreate|ropeCut|ropeDestroy|ropeDetach|ropeEndPosition|ropeLength|ropes|ropeUnwind|ropeUnwound|rotorsForcesRTD|rotorsRpmRTD|round|runInitScript|safeZoneH|safeZoneW|safeZoneWAbs|safeZoneX|safeZoneXAbs|safeZoneY|save3DENInventory|saveGame|saveIdentity|saveJoysticks|saveOverlay|saveProfileNamespace|saveStatus|saveVar|savingEnabled|say|say2D|say3D|score|scoreSide|screenshot|screenToWorld|scriptDone|scriptName|scriptNull|scudState|secondaryWeapon|secondaryWeaponItems|secondaryWeaponMagazine|select|selectBestPlaces|selectDiarySubject|selectedEditorObjects|selectEditorObject|selectionNames|selectionPosition|selectLeader|selectMax|selectMin|selectNoPlayer|selectPlayer|selectRandom|selectRandomWeighted|selectWeapon|selectWeaponTurret|sendAUMessage|sendSimpleCommand|sendTask|sendTaskResult|sendUDPMessage|serverCommand|serverCommandAvailable|serverCommandExecutable|serverName|serverTime|set|set3DENAttribute|set3DENAttributes|set3DENGrid|set3DENIconsVisible|set3DENLayer|set3DENLinesVisible|set3DENLogicType|set3DENMissionAttribute|set3DENMissionAttributes|set3DENModelsVisible|set3DENObjectType|set3DENSelected|setAccTime|setActualCollectiveRTD|setAirplaneThrottle|setAirportSide|setAmmo|setAmmoCargo|setAmmoOnPylon|setAnimSpeedCoef|setAperture|setApertureNew|setArmoryPoints|setAttributes|setAutonomous|setBehaviour|setBleedingRemaining|setBrakesRTD|setCameraInterest|setCamShakeDefParams|setCamShakeParams|setCamUseTI|setCaptive|setCenterOfMass|setCollisionLight|setCombatMode|setCompassOscillation|setConvoySeparation|setCuratorCameraAreaCeiling|setCuratorCoef|setCuratorEditingAreaType|setCuratorWaypointCost|setCurrentChannel|setCurrentTask|setCurrentWaypoint|setCustomAimCoef|setCustomWeightRTD|setDamage|setDammage|setDate|setDebriefingText|setDefaultCamera|setDestination|setDetailMapBlendPars|setDir|setDirection|setDrawIcon|setDriveOnPath|setDropInterval|setDynamicSimulationDistance|setDynamicSimulationDistanceCoef|setEditorMode|setEditorObjectScope|setEffectCondition|setEngineRpmRTD|setFace|setFaceAnimation|setFatigue|setFeatureType|setFlagAnimationPhase|setFlagOwner|setFlagSide|setFlagTexture|setFog|setForceGeneratorRTD|setFormation|setFormationTask|setFormDir|setFriend|setFromEditor|setFSMVariable|setFuel|setFuelCargo|setGroupIcon|setGroupIconParams|setGroupIconsSelectable|setGroupIconsVisible|setGroupId|setGroupIdGlobal|setGroupOwner|setGusts|setHideBehind|setHit|setHitIndex|setHitPointDamage|setHorizonParallaxCoef|setHUDMovementLevels|setIdentity|setImportance|setInfoPanel|setLeader|setLightAmbient|setLightAttenuation|setLightBrightness|setLightColor|setLightDayLight|setLightFlareMaxDistance|setLightFlareSize|setLightIntensity|setLightnings|setLightUseFlare|setLocalWindParams|setMagazineTurretAmmo|setMarkerAlpha|setMarkerAlphaLocal|setMarkerBrush|setMarkerBrushLocal|setMarkerColor|setMarkerColorLocal|setMarkerDir|setMarkerDirLocal|setMarkerPos|setMarkerPosLocal|setMarkerShape|setMarkerShapeLocal|setMarkerSize|setMarkerSizeLocal|setMarkerText|setMarkerTextLocal|setMarkerType|setMarkerTypeLocal|setMass|setMimic|setMousePosition|setMusicEffect|setMusicEventHandler|setName|setNameSound|setObjectArguments|setObjectMaterial|setObjectMaterialGlobal|setObjectProxy|setObjectTexture|setObjectTextureGlobal|setObjectViewDistance|setOvercast|setOwner|setOxygenRemaining|setParticleCircle|setParticleClass|setParticleFire|setParticleParams|setParticleRandom|setPilotCameraDirection|setPilotCameraRotation|setPilotCameraTarget|setPilotLight|setPiPEffect|setPitch|setPlateNumber|setPlayable|setPlayerRespawnTime|setPos|setPosASL|setPosASL2|setPosASLW|setPosATL|setPosition|setPosWorld|setPylonLoadOut|setPylonsPriority|setRadioMsg|setRain|setRainbow|setRandomLip|setRank|setRectangular|setRepairCargo|setRotorBrakeRTD|setShadowDistance|setShotParents|setSide|setSimpleTaskAlwaysVisible|setSimpleTaskCustomData|setSimpleTaskDescription|setSimpleTaskDestination|setSimpleTaskTarget|setSimpleTaskType|setSimulWeatherLayers|setSize|setSkill|setSlingLoad|setSoundEffect|setSpeaker|setSpeech|setSpeedMode|setStamina|setStaminaScheme|setStatValue|setSuppression|setSystemOfUnits|setTargetAge|setTaskMarkerOffset|setTaskResult|setTaskState|setTerrainGrid|setText|setTimeMultiplier|setTitleEffect|setToneMapping|setToneMappingParams|setTrafficDensity|setTrafficDistance|setTrafficGap|setTrafficSpeed|setTriggerActivation|setTriggerArea|setTriggerStatements|setTriggerText|setTriggerTimeout|setTriggerType|setType|setUnconscious|setUnitAbility|setUnitLoadout|setUnitPos|setUnitPosWeak|setUnitRank|setUnitRecoilCoefficient|setUnitTrait|setUnloadInCombat|setUserActionText|setUserMFDText|setUserMFDValue|setVariable|setVectorDir|setVectorDirAndUp|setVectorUp|setVehicleAmmo|setVehicleAmmoDef|setVehicleArmor|setVehicleCargo|setVehicleId|setVehicleInit|setVehicleLock|setVehiclePosition|setVehicleRadar|setVehicleReceiveRemoteTargets|setVehicleReportOwnPosition|setVehicleReportRemoteTargets|setVehicleTIPars|setVehicleVarName|setVelocity|setVelocityModelSpace|setVelocityTransformation|setViewDistance|setVisibleIfTreeCollapsed|setWantedRpmRTD|setWaves|setWaypointBehaviour|setWaypointCombatMode|setWaypointCompletionRadius|setWaypointDescription|setWaypointForceBehaviour|setWaypointFormation|setWaypointHousePosition|setWaypointLoiterRadius|setWaypointLoiterType|setWaypointName|setWaypointPosition|setWaypointScript|setWaypointSpeed|setWaypointStatements|setWaypointTimeout|setWaypointType|setWaypointVisible|setWeaponReloadingTime|setWind|setWindDir|setWindForce|setWindStr|setWingForceScaleRTD|setWPPos|show3DIcons|showChat|showCinemaBorder|showCommandingMenu|showCompass|showCuratorCompass|showGPS|showHUD|showLegend|showMap|shownArtilleryComputer|shownChat|shownCompass|shownCuratorCompass|showNewEditorObject|shownGPS|shownHUD|shownMap|shownPad|shownRadio|shownScoretable|shownUAVFeed|shownWarrant|shownWatch|showPad|showRadio|showScoretable|showSubtitles|showUAVFeed|showWarrant|showWatch|showWaypoint|showWaypoints|side|sideAmbientLife|sideChat|sideEmpty|sideEnemy|sideFriendly|sideLogic|sideRadio|sideUnknown|simpleTasks|simulationEnabled|simulCloudDensity|simulCloudOcclusion|simulInClouds|simulWeatherSync|sin|size|sizeOf|skill|skillFinal|skipTime|sleep|sliderPosition|sliderRange|sliderSetPosition|sliderSetRange|sliderSetSpeed|sliderSpeed|slingLoadAssistantShown|soldierMagazines|someAmmo|sort|soundVolume|speaker|speed|speedMode|splitString|sqrt|squadParams|stance|startLoadingScreen|stop|stopEngineRTD|stopped|str|sunOrMoon|supportInfo|suppressFor|surfaceIsWater|surfaceNormal|surfaceType|swimInDepth|switchableUnits|switchAction|switchCamera|switchGesture|switchLight|switchMove|synchronizedObjects|synchronizedTriggers|synchronizedWaypoints|synchronizeObjectsAdd|synchronizeObjectsRemove|synchronizeTrigger|synchronizeWaypoint|systemChat|systemOfUnits|tan|targetKnowledge|targets|targetsAggregate|targetsQuery|taskAlwaysVisible|taskChildren|taskCompleted|taskCustomData|taskDescription|taskDestination|taskHint|taskMarkerOffset|taskNull|taskParent|taskResult|taskState|taskType|teamMember|teamMemberNull|teamName|teams|teamSwitch|teamSwitchEnabled|teamType|terminate|terrainIntersect|terrainIntersectASL|terrainIntersectAtASL|text|textLog|textLogFormat|tg|time|timeMultiplier|titleCut|titleFadeOut|titleObj|titleRsc|titleText|toArray|toFixed|toLower|toString|toUpper|triggerActivated|triggerActivation|triggerArea|triggerAttachedVehicle|triggerAttachObject|triggerAttachVehicle|triggerDynamicSimulation|triggerStatements|triggerText|triggerTimeout|triggerTimeoutCurrent|triggerType|turretLocal|turretOwner|turretUnit|tvAdd|tvClear|tvCollapse|tvCollapseAll|tvCount|tvCurSel|tvData|tvDelete|tvExpand|tvExpandAll|tvPicture|tvPictureRight|tvSetColor|tvSetCurSel|tvSetData|tvSetPicture|tvSetPictureColor|tvSetPictureColorDisabled|tvSetPictureColorSelected|tvSetPictureRight|tvSetPictureRightColor|tvSetPictureRightColorDisabled|tvSetPictureRightColorSelected|tvSetSelectColor|tvSetText|tvSetTooltip|tvSetValue|tvSort|tvSortByValue|tvText|tvTooltip|tvValue|type|typeName|typeOf|UAVControl|uiNamespace|uiSleep|unassignCurator|unassignItem|unassignTeam|unassignVehicle|underwater|uniform|uniformContainer|uniformItems|uniformMagazines|unitAddons|unitAimPosition|unitAimPositionVisual|unitBackpack|unitIsUAV|unitPos|unitReady|unitRecoilCoefficient|units|unitsBelowHeight|unlinkItem|unlockAchievement|unregisterTask|updateDrawIcon|updateMenuItem|updateObjectTree|useAIOperMapObstructionTest|useAISteeringComponent|useAudioTimeForMoves|userInputDisabled|vectorAdd|vectorCos|vectorCrossProduct|vectorDiff|vectorDir|vectorDirVisual|vectorDistance|vectorDistanceSqr|vectorDotProduct|vectorFromTo|vectorMagnitude|vectorMagnitudeSqr|vectorModelToWorld|vectorModelToWorldVisual|vectorMultiply|vectorNormalized|vectorUp|vectorUpVisual|vectorWorldToModel|vectorWorldToModelVisual|vehicle|vehicleCargoEnabled|vehicleChat|vehicleRadio|vehicleReceiveRemoteTargets|vehicleReportOwnPosition|vehicleReportRemoteTargets|vehicles|vehicleVarName|velocity|velocityModelSpace|verifySignature|vest|vestContainer|vestItems|vestMagazines|viewDistance|visibleCompass|visibleGPS|visibleMap|visiblePosition|visiblePositionASL|visibleScoretable|visibleWatch|waitUntil|waves|waypointAttachedObject|waypointAttachedVehicle|waypointAttachObject|waypointAttachVehicle|waypointBehaviour|waypointCombatMode|waypointCompletionRadius|waypointDescription|waypointForceBehaviour|waypointFormation|waypointHousePosition|waypointLoiterRadius|waypointLoiterType|waypointName|waypointPosition|waypoints|waypointScript|waypointsEnabledUAV|waypointShow|waypointSpeed|waypointStatements|waypointTimeout|waypointTimeoutCurrent|waypointType|waypointVisible|weaponAccessories|weaponAccessoriesCargo|weaponCargo|weaponDirection|weaponInertia|weaponLowered|weapons|weaponsItems|weaponsItemsCargo|weaponState|weaponsTurret|weightRTD|west|WFSideText|wind|windDir|windRTD|windStr|wingsForcesRTD|worldName|worldSize|worldToModel|worldToModelVisual|worldToScreen)\b/i,
+       'number': /(?:\$|\b0x)[\da-f]+\b|(?:\B\.\d+|\b\d+(?:\.\d+)?)(?:e[+-]?\d+)?\b/i,
+       'operator': /##|>>|&&|\|\||[!=<>]=?|[-+*/%#^]|\b(?:and|mod|not|or)\b/i,
+       'constant': /\bDIK(?:_[a-z\d]+)+\b/i
+});
+
+Prism.languages.insertBefore('sqf', 'string', {
+       'macro': {
+               pattern: /(^\s*)#[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,
+               lookbehind: true,
+               greedy: true,
+               alias: 'property',
+               inside: {
+                       'directive': {
+                               pattern: /#[a-z]+\b/i,
+                               alias: 'keyword'
+                       },
+                       'comment': Prism.languages.sqf.comment
+               }
+       }
+});
+
+delete Prism.languages.sqf['class-name'];
+
+return Prism; })
\ No newline at end of file
index ea7943e76c79bc90d9a2de208850060846379d8c..0795aeed49d3b5c63d816c3d5164720a0c911708 100644 (file)
@@ -17,7 +17,7 @@ Prism.languages.sql = {
                lookbehind: true
        },
        'function': /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, // Should we highlight user defined functions too?
-       'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,
+       'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,
        'boolean': /\b(?:TRUE|FALSE|NULL)\b/i,
        'number': /\b0x[\da-f]+\b|\b\d+\.?\d*|\B\.\d+\b/i,
        'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,
index fd912f9c86dd8607af05b62e56d6d438e463f217..96fcde562b342e60010943d4058d739f59f4fb95 100644 (file)
@@ -1,7 +1,24 @@
 define(["prism/prism"], function () {
 (function (Prism) {
+       var unit = {
+               pattern: /(\b\d+)(?:%|[a-z]+)/,
+               lookbehind: true
+       };
+       // 123 -123 .123 -.123 12.3 -12.3
+       var number = {
+               pattern: /(^|[^\w.-])-?\d*\.?\d+/,
+               lookbehind: true
+       };
+
        var inside = {
-               'url': /url\((["']?).*?\1\)/i,
+               'comment': {
+                       pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
+                       lookbehind: true
+               },
+               'url': {
+                       pattern: /url\((["']?).*?\1\)/i,
+                       greedy: true
+               },
                'string': {
                        pattern: /("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,
                        greedy: true
@@ -14,13 +31,27 @@ define(["prism/prism"], function () {
                        lookbehind: true
                },
                'hexcode': /#[\da-f]{3,6}/i,
-               'number': /\b\d+(?:\.\d+)?%?/,
+               'color': [
+                       /\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,
+                       {
+                               pattern: /\b(?:rgb|hsl)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:rgb|hsl)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,
+                               inside: {
+                                       'unit': unit,
+                                       'number': number,
+                                       'function': /[\w-]+(?=\()/,
+                                       'punctuation': /[(),]/
+                               }
+                       }
+               ],
+               'entity': /\\[\da-f]{1,8}/i,
+               'unit': unit,
                'boolean': /\b(?:true|false)\b/,
                'operator': [
                        // We want non-word chars around "-" because it is
                        // accepted in property names.
-                       /~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.+|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/
+                       /~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/
                ],
+               'number': number,
                'punctuation': /[{}()\[\];:,]/
        };
 
@@ -44,10 +75,6 @@ define(["prism/prism"], function () {
        };
 
        Prism.languages.stylus = {
-               'comment': {
-                       pattern: /(^|[^\\])(\/\*[\s\S]*?\*\/|\/\/.*)/,
-                       lookbehind: true
-               },
                'atrule-declaration': {
                        pattern: /(^\s*)@.+/m,
                        lookbehind: true,
@@ -69,7 +96,7 @@ define(["prism/prism"], function () {
                        pattern: /(^[ \t]*)(?:if|else|for|return|unless)[ \t]+.+/m,
                        lookbehind: true,
                        inside: {
-                               keyword: /^\S+/,
+                               'keyword': /^\S+/,
                                rest: inside
                        }
                },
@@ -77,7 +104,7 @@ define(["prism/prism"], function () {
                // A property/value pair cannot end with a comma or a brace
                // It cannot have indented content unless it ended with a semicolon
                'property-declaration': {
-                       pattern: /((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)[^{\r\n]*(?:;|[^{\r\n,](?=$)(?!(\r?\n|\r)(?:\{|\2[ \t]+)))/m,
+                       pattern: /((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)[^{\r\n]*(?:;|[^{\r\n,](?=$)(?!(?:\r?\n|\r)(?:\{|\2[ \t]+)))/m,
                        lookbehind: true,
                        inside: {
                                'property': {
@@ -100,14 +127,21 @@ define(["prism/prism"], function () {
                        lookbehind: true,
                        inside: {
                                'interpolation': inside.interpolation,
+                               'comment': inside.comment,
                                'punctuation': /[{},]/
                        }
                },
 
                'func': inside.func,
                'string': inside.string,
+               'comment': {
+                       pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
+                       lookbehind: true,
+                       greedy: true
+               },
                'interpolation': inside.interpolation,
                'punctuation': /[{}()\[\];:.]/
        };
 }(Prism));
+
 return Prism; })
\ No newline at end of file
index ae27609252925cca4f67063ed7816056a18d12d3..d62ed9e2d753db0bec175433e0005aa2f9923864 100644 (file)
@@ -2,7 +2,7 @@ define(["prism/prism","prism/components/prism-clike"], function () {
 // issues: nested multiline comments
 Prism.languages.swift = Prism.languages.extend('clike', {
        'string': {
-               pattern: /("|')(\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
+               pattern: /("|')(?:\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
                greedy: true,
                inside: {
                        'interpolation': {
index f0a16395d31c94fb79aa7a85562e245943da4709..e2f1339b39bf168211e99723eae245d1362606a6 100644 (file)
@@ -1,4 +1,4 @@
-define(["prism/prism","prism/components/prism-t4-templating","prism/components/prism-visual-basic"], function () {
-Prism.languages['t4-vb'] = Prism.languages['t4-templating'].createT4('visual-basic');
+define(["prism/prism","prism/components/prism-t4-templating","prism/components/prism-vbnet"], function () {
+Prism.languages['t4-vb'] = Prism.languages['t4-templating'].createT4('vbnet');
 
 return Prism; })
\ No newline at end of file
index de19433bfa805abd3ce662a96903fe21c64dc2a8..b83e7e4cce96eb74c2ab311f1ea76984345b7f3b 100644 (file)
@@ -1,8 +1,23 @@
-define(["prism/prism","prism/components/prism-markup","prism/components/prism-css"], function () {
+define(["prism/prism","prism/components/prism-markup"], function () {
 (function (Prism) {
        // We don't allow for pipes inside parentheses
        // to not break table pattern |(. foo |). bar |
-       var modifierRegex = /(?:\([^|)]+\)|\[[^\]]+\]|\{[^}]+\})+/.source;
+       var modifierRegex = /\([^|()\n]+\)|\[[^\]\n]+\]|\{[^}\n]+\}/.source;
+       // Opening and closing parentheses which are not a modifier
+       // This pattern is necessary to prevent exponential backtracking
+       var parenthesesRegex = /\)|\((?![^|()\n]+\))/.source;
+       /**
+        * @param {string} source
+        * @param {string} [flags]
+        */
+       function withModifier(source, flags) {
+               return RegExp(
+                       source
+                               .replace(/<MOD>/g, function () { return '(?:' + modifierRegex + ')'; })
+                               .replace(/<PAR>/g, function () { return '(?:' + parenthesesRegex + ')'; }),
+                       flags || '');
+       }
+
        var modifierTokens = {
                'css': {
                        pattern: /\{[^}]+\}/,
@@ -33,10 +48,10 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-cs
 
                                // h1. Header 1
                                'block-tag': {
-                                       pattern: RegExp('^[a-z]\\w*(?:' + modifierRegex + '|[<>=()])*\\.'),
+                                       pattern: withModifier(/^[a-z]\w*(?:<MOD>|<PAR>|[<>=])*\./.source),
                                        inside: {
                                                'modifier': {
-                                                       pattern: RegExp('(^[a-z]\\w*)(?:' + modifierRegex + '|[<>=()])+(?=\\.)'),
+                                                       pattern: withModifier(/(^[a-z]\w*)(?:<MOD>|<PAR>|[<>=])+(?=\.)/.source),
                                                        lookbehind: true,
                                                        inside: modifierTokens
                                                },
@@ -48,10 +63,10 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-cs
                                // # List item
                                // * List item
                                'list': {
-                                       pattern: RegExp('^[*#]+(?:' + modifierRegex + ')?\\s+.+', 'm'),
+                                       pattern: withModifier(/^[*#]+<MOD>*\s+.+/.source, 'm'),
                                        inside: {
                                                'modifier': {
-                                                       pattern: RegExp('(^[*#]+)' + modifierRegex),
+                                                       pattern: withModifier(/(^[*#]+)<MOD>+/.source),
                                                        lookbehind: true,
                                                        inside: modifierTokens
                                                },
@@ -63,12 +78,12 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-cs
                                'table': {
                                        // Modifiers can be applied to the row: {color:red}.|1|2|3|
                                        // or the cell: |{color:red}.1|2|3|
-                                       pattern: RegExp('^(?:(?:' + modifierRegex + '|[<>=()^~])+\\.\\s*)?(?:\\|(?:(?:' + modifierRegex + '|[<>=()^~_]|[\\\\/]\\d+)+\\.)?[^|]*)+\\|', 'm'),
+                                       pattern: withModifier(/^(?:(?:<MOD>|<PAR>|[<>=^~])+\.\s*)?(?:\|(?:(?:<MOD>|<PAR>|[<>=^~_]|[\\/]\d+)+\.)?[^|]*)+\|/.source, 'm'),
                                        inside: {
                                                'modifier': {
                                                        // Modifiers for rows after the first one are
                                                        // preceded by a pipe and a line feed
-                                                       pattern: RegExp('(^|\\|(?:\\r?\\n|\\r)?)(?:' + modifierRegex + '|[<>=()^~_]|[\\\\/]\\d+)+(?=\\.)'),
+                                                       pattern: withModifier(/(^|\|(?:\r?\n|\r)?)(?:<MOD>|<PAR>|[<>=^~_]|[\\/]\d+)+(?=\.)/.source),
                                                        lookbehind: true,
                                                        inside: modifierTokens
                                                },
@@ -77,56 +92,57 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-cs
                                },
 
                                'inline': {
-                                       pattern: RegExp('(\\*\\*|__|\\?\\?|[*_%@+\\-^~])(?:' + modifierRegex + ')?.+?\\1'),
+                                       pattern: withModifier(/(^|[^a-zA-Z\d])(\*\*|__|\?\?|[*_%@+\-^~])<MOD>*.+?\2(?![a-zA-Z\d])/.source),
+                                       lookbehind: true,
                                        inside: {
                                                // Note: superscripts and subscripts are not handled specifically
 
                                                // *bold*, **bold**
                                                'bold': {
-                                                       pattern: RegExp('(^(\\*\\*?)(?:' + modifierRegex + ')?).+?(?=\\2)'),
+                                                       pattern: withModifier(/(^(\*\*?)<MOD>*).+?(?=\2)/.source),
                                                        lookbehind: true
                                                },
 
                                                // _italic_, __italic__
                                                'italic': {
-                                                       pattern: RegExp('(^(__?)(?:' + modifierRegex + ')?).+?(?=\\2)'),
+                                                       pattern: withModifier(/(^(__?)<MOD>*).+?(?=\2)/.source),
                                                        lookbehind: true
                                                },
 
                                                // ??cite??
                                                'cite': {
-                                                       pattern: RegExp('(^\\?\\?(?:' + modifierRegex + ')?).+?(?=\\?\\?)'),
+                                                       pattern: withModifier(/(^\?\?<MOD>*).+?(?=\?\?)/.source),
                                                        lookbehind: true,
                                                        alias: 'string'
                                                },
 
                                                // @code@
                                                'code': {
-                                                       pattern: RegExp('(^@(?:' + modifierRegex + ')?).+?(?=@)'),
+                                                       pattern: withModifier(/(^@<MOD>*).+?(?=@)/.source),
                                                        lookbehind: true,
                                                        alias: 'keyword'
                                                },
 
                                                // +inserted+
                                                'inserted': {
-                                                       pattern: RegExp('(^\\+(?:' + modifierRegex + ')?).+?(?=\\+)'),
+                                                       pattern: withModifier(/(^\+<MOD>*).+?(?=\+)/.source),
                                                        lookbehind: true
                                                },
 
                                                // -deleted-
                                                'deleted': {
-                                                       pattern: RegExp('(^-(?:' + modifierRegex + ')?).+?(?=-)'),
+                                                       pattern: withModifier(/(^-<MOD>*).+?(?=-)/.source),
                                                        lookbehind: true
                                                },
 
                                                // %span%
                                                'span': {
-                                                       pattern: RegExp('(^%(?:' + modifierRegex + ')?).+?(?=%)'),
+                                                       pattern: withModifier(/(^%<MOD>*).+?(?=%)/.source),
                                                        lookbehind: true
                                                },
 
                                                'modifier': {
-                                                       pattern: RegExp('(^\\*\\*|__|\\?\\?|[*_%@+\\-^~])' + modifierRegex),
+                                                       pattern: withModifier(/(^\*\*|__|\?\?|[*_%@+\-^~])<MOD>+/.source),
                                                        lookbehind: true,
                                                        inside: modifierTokens
                                                },
@@ -153,14 +169,14 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-cs
                                // "text":http://example.com
                                // "text":link-ref
                                'link': {
-                                       pattern: RegExp('"(?:' + modifierRegex + ')?[^"]+":.+?(?=[^\\w/]?(?:\\s|$))'),
+                                       pattern: withModifier(/"<MOD>*[^"]+":.+?(?=[^\w/]?(?:\s|$))/.source),
                                        inside: {
                                                'text': {
-                                                       pattern: RegExp('(^"(?:' + modifierRegex + ')?)[^"]+(?=")'),
+                                                       pattern: withModifier(/(^"<MOD>*)[^"]+(?=")/.source),
                                                        lookbehind: true
                                                },
                                                'modifier': {
-                                                       pattern: RegExp('(^")' + modifierRegex),
+                                                       pattern: withModifier(/(^")<MOD>+/.source),
                                                        lookbehind: true,
                                                        inside: modifierTokens
                                                },
@@ -175,15 +191,15 @@ define(["prism/prism","prism/components/prism-markup","prism/components/prism-cs
                                // !image.jpg!
                                // !image.jpg(Title)!:http://example.com
                                'image': {
-                                       pattern: RegExp('!(?:' + modifierRegex + '|[<>=()])*[^!\\s()]+(?:\\([^)]+\\))?!(?::.+?(?=[^\\w/]?(?:\\s|$)))?'),
+                                       pattern: withModifier(/!(?:<MOD>|<PAR>|[<>=])*[^!\s()]+(?:\([^)]+\))?!(?::.+?(?=[^\w/]?(?:\s|$)))?/.source),
                                        inside: {
                                                'source': {
-                                                       pattern: RegExp('(^!(?:' + modifierRegex + '|[<>=()])*)[^!\\s()]+(?:\\([^)]+\\))?(?=!)'),
+                                                       pattern: withModifier(/(^!(?:<MOD>|<PAR>|[<>=])*)[^!\s()]+(?:\([^)]+\))?(?=!)/.source),
                                                        lookbehind: true,
                                                        alias: 'url'
                                                },
                                                'modifier': {
-                                                       pattern: RegExp('(^!)(?:' + modifierRegex + '|[<>=()])+'),
+                                                       pattern: withModifier(/(^!)(?:<MOD>|<PAR>|[<>=])+/.source),
                                                        lookbehind: true,
                                                        inside: modifierTokens
                                                },
index 484cf192b59ebde5d10e93e53d90ffe77bc41a79..b11cc34bcc8abee272b2c4bb0e2dda013af3607d 100644 (file)
@@ -1,8 +1,14 @@
 define(["prism/prism"], function () {
 (function (Prism) {
 
-       // pattern: /(?:[\w-]+|'[^'\n\r]*'|"(?:\.|[^\\"\r\n])*")/
-       var key = "(?:[\\w-]+|'[^'\n\r]*'|\"(?:\\.|[^\\\\\"\r\n])*\")";
+       var key = /(?:[\w-]+|'[^'\n\r]*'|"(?:\\.|[^\\"\r\n])*")/.source;
+
+       /**
+        * @param {string} pattern
+        */
+       function insertKey(pattern) {
+               return pattern.replace(/__/g, function () { return key; });
+       }
 
        Prism.languages.toml = {
                'comment': {
@@ -10,13 +16,13 @@ define(["prism/prism"], function () {
                        greedy: true
                },
                'table': {
-                       pattern: RegExp("(^\\s*\\[\\s*(?:\\[\\s*)?)" + key + "(?:\\s*\\.\\s*" + key + ")*(?=\\s*\\])", "m"),
+                       pattern: RegExp(insertKey(/(^\s*\[\s*(?:\[\s*)?)__(?:\s*\.\s*__)*(?=\s*\])/.source), 'm'),
                        lookbehind: true,
                        greedy: true,
                        alias: 'class-name'
                },
                'key': {
-                       pattern: RegExp("(^\\s*|[{,]\\s*)" + key + "(?:\\s*\\.\\s*" + key + ")*(?=\\s*=)", "m"),
+                       pattern: RegExp(insertKey(/(^\s*|[{,]\s*)__(?:\s*\.\s*__)*(?=\s*=)/.source), 'm'),
                        lookbehind: true,
                        greedy: true,
                        alias: 'property'
@@ -28,16 +34,16 @@ define(["prism/prism"], function () {
                'date': [
                        {
                                // Offset Date-Time, Local Date-Time, Local Date
-                               pattern: /\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?/i,
+                               pattern: /\b\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?\b/i,
                                alias: 'number'
                        },
                        {
                                // Local Time
-                               pattern: /\d{2}:\d{2}:\d{2}(?:\.\d+)?/i,
+                               pattern: /\b\d{2}:\d{2}:\d{2}(?:\.\d+)?\b/,
                                alias: 'number'
                        }
                ],
-               'number': /(?:\b0(?:x[\da-zA-Z]+(?:_[\da-zA-Z]+)*|o[0-7]+(?:_[0-7]+)*|b[10]+(?:_[10]+)*))\b|[-+]?\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?\b|[-+]?(?:inf|nan)\b/,
+               'number': /(?:\b0(?:x[\da-zA-Z]+(?:_[\da-zA-Z]+)*|o[0-7]+(?:_[0-7]+)*|b[10]+(?:_[10]+)*))\b|[-+]?\b\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?\b|[-+]?\b(?:inf|nan)\b/,
                'boolean': /\b(?:true|false)\b/,
                'punctuation': /[.,=[\]{}]/
        };
index 9053ed9910ba36d76460db4ccf3712c8dd905f78..713365dfd358f022a11284f4020ac4bc09591d46 100644 (file)
@@ -10,7 +10,7 @@ define(["prism/prism","prism/components/prism-clike","prism/components/prism-mar
        Prism.languages.insertBefore('tt2', 'number', {
                'operator': /=[>=]?|!=?|<=?|>=?|&&|\|\|?|\b(?:and|or|not)\b/,
                'variable': {
-                       pattern: /[a-z]\w*(?:\s*\.\s*(?:\d+|\$?[a-z]\w*))*/i
+                       pattern: /\b[a-z]\w*(?:\s*\.\s*(?:\d+|\$?[a-z]\w*))*\b/i
                }
        });
 
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-turtle.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-turtle.js
new file mode 100644 (file)
index 0000000..cb830e5
--- /dev/null
@@ -0,0 +1,57 @@
+define(["prism/prism"], function () {
+Prism.languages.turtle = {
+       'comment': {
+               pattern: /#.*/,
+               greedy: true
+       },
+       'multiline-string': {
+               pattern: /"""(?:(?:""?)?(?:[^"\\]|\\.))*"""|'''(?:(?:''?)?(?:[^'\\]|\\.))*'''/,
+               greedy: true,
+               alias: 'string',
+               inside: {
+                       'comment': /#.*/
+               }
+       },
+       'string': {
+               pattern: /"(?:[^\\"\r\n]|\\.)*"|'(?:[^\\'\r\n]|\\.)*'/,
+               greedy: true
+       },
+       'url': {
+               pattern: /<(?:[^\x00-\x20<>"{}|^`\\]|\\(?:u[\da-fA-F]{4}|U[\da-fA-F]{8}))*>/,
+               greedy: true,
+               inside: {
+                       'punctuation': /[<>]/
+               }
+       },
+       'function': {
+               pattern: /(?:(?![-.\d\xB7])[-.\w\xB7\xC0-\uFFFD]+)?:(?:(?![-.])(?:[-.:\w\xC0-\uFFFD]|%[\da-f]{2}|\\.)+)?/i,
+               inside: {
+                       'local-name': {
+                               pattern: /([^:]*:)[\s\S]+/,
+                               lookbehind: true
+                       },
+                       'prefix': {
+                               pattern: /[\s\S]+/,
+                               inside: {
+                                       'punctuation': /:/
+                               }
+                       }
+               }
+       },
+       'number': /[+-]?\b\d+\.?\d*(?:e[+-]?\d+)?/i,
+       'punctuation': /[{}.,;()[\]]|\^\^/,
+       'boolean': /\b(?:true|false)\b/,
+       'keyword': [
+               /(?:\ba|@prefix|@base)\b|=/,
+               /\b(?:graph|base|prefix)\b/i
+       ],
+       'tag': {
+               pattern: /@[a-z]+(?:-[a-z\d]+)*/i,
+               inside: {
+                       'punctuation': /@/
+               }
+       }
+};
+Prism.languages.trig = Prism.languages['turtle'];
+
+return Prism; })
\ No newline at end of file
index 86aa52e57087f0b60c0009d1c9fceb0d628ef6ad..2002ea03a10aeae5990673f8e1717b93aec74088 100644 (file)
@@ -1,10 +1,45 @@
 define(["prism/prism","prism/components/prism-javascript"], function () {
-Prism.languages.typescript = Prism.languages.extend('javascript', {
-       // From JavaScript Prism keyword list and TypeScript language spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#221-reserved-words
-       'keyword': /\b(?:abstract|as|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|var|void|while|with|yield)\b/,
-       'builtin': /\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/,
-});
+(function (Prism) {
 
-Prism.languages.ts = Prism.languages.typescript;
+       Prism.languages.typescript = Prism.languages.extend('javascript', {
+               'class-name': {
+                       pattern: /(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,
+                       lookbehind: true,
+                       greedy: true,
+                       inside: null // see below
+               },
+               // From JavaScript Prism keyword list and TypeScript language spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#221-reserved-words
+               'keyword': /\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/,
+               'builtin': /\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/,
+       });
+
+       // doesn't work with TS because TS is too complex
+       delete Prism.languages.typescript['parameter'];
+
+       // a version of typescript specifically for highlighting types
+       var typeInside = Prism.languages.extend('typescript', {});
+       delete typeInside['class-name'];
+
+       Prism.languages.typescript['class-name'].inside = typeInside;
+
+       Prism.languages.insertBefore('typescript', 'function', {
+               'generic-function': {
+                       // e.g. foo<T extends "bar" | "baz">( ...
+                       pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,
+                       greedy: true,
+                       inside: {
+                               'function': /^#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*/,
+                               'generic': {
+                                       pattern: /<[\s\S]+/, // everything after the first <
+                                       alias: 'class-name',
+                                       inside: typeInside
+                               }
+                       }
+               }
+       });
+
+       Prism.languages.ts = Prism.languages.typescript;
+
+}(Prism));
 
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-unrealscript.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-unrealscript.js
new file mode 100644 (file)
index 0000000..4f3d895
--- /dev/null
@@ -0,0 +1,45 @@
+define(["prism/prism"], function () {
+Prism.languages.unrealscript = {
+       'comment': /\/\/.*|\/\*[\s\S]*?\*\//,
+       'string': {
+               pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
+               greedy: true
+       },
+       'category': {
+               pattern: /(\b(?:(?:autoexpand|hide|show)categories|var)\s*\()[^()]+(?=\))/,
+               lookbehind: true,
+               greedy: true,
+               alias: 'property'
+       },
+       'metadata': {
+               pattern: /(\w\s*)<\s*\w+\s*=[^<>|=\r\n]+(?:\|\s*\w+\s*=[^<>|=\r\n]+)*>/,
+               lookbehind: true,
+               greedy: true,
+               inside: {
+                       'property': /\w+(?=\s*=)/,
+                       'operator': /=/,
+                       'punctuation': /[<>|]/
+               }
+       },
+       'macro': {
+               pattern: /`\w+/,
+               alias: 'property'
+       },
+       'class-name': {
+               pattern: /(\b(?:class|enum|extends|interface|state(?:\(\))?|struct|within)\s+)\w+/,
+               lookbehind: true
+       },
+
+       'keyword': /\b(?:abstract|actor|array|auto|autoexpandcategories|bool|break|byte|case|class|classgroup|client|coerce|collapsecategories|config|const|continue|default|defaultproperties|delegate|dependson|deprecated|do|dontcollapsecategories|editconst|editinlinenew|else|enum|event|exec|export|extends|final|float|for|forcescriptorder|foreach|function|goto|guid|hidecategories|hidedropdown|if|ignores|implements|inherits|input|int|interface|iterator|latent|local|material|name|native|nativereplication|noexport|nontransient|noteditinlinenew|notplaceable|operator|optional|out|pawn|perobjectconfig|perobjectlocalized|placeable|postoperator|preoperator|private|protected|reliable|replication|return|server|showcategories|simulated|singular|state|static|string|struct|structdefault|structdefaultproperties|switch|texture|transient|travel|unreliable|until|var|vector|while|within)\b/,
+       'function': /[a-z_]\w*(?=\s*\()/i,
+
+       'boolean': /\b(?:false|true)\b/,
+       'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
+       // https://docs.unrealengine.com/udk/Three/UnrealScriptExpressions.html
+       'operator': />>|<<|--|\+\+|\*\*|[-+*/~!=<>$@]=?|&&?|\|\|?|\^\^?|[?:%]|\b(?:Cross|Dot|ClockwiseFrom)\b/,
+       'punctuation': /[()[\]{};,.]/
+};
+
+Prism.languages.uc = Prism.languages.uscript = Prism.languages.unrealscript;
+
+return Prism; })
\ No newline at end of file
index e965582144e4c4401959873eee9414413ec2fdc3..9b215650f1accf477541f58e5329315b293d9d7f 100644 (file)
@@ -69,8 +69,9 @@ Prism.languages.insertBefore('vala','string', {
 
 Prism.languages.insertBefore('vala', 'keyword', {
        'regex': {
-               pattern: /\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[imsx]{0,4}(?=\s*($|[\r\n,.;})\]]))/,
+               pattern: /\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[imsx]{0,4}(?=\s*(?:$|[\r\n,.;})\]]))/,
                greedy: true
        }
 });
+
 return Prism; })
\ No newline at end of file
index b6f3195a06909d3de0f5cce5a153e8e90a7b64a5..146b5ca5a8cc29308c1ef905751c511d040a9513 100644 (file)
@@ -56,7 +56,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                        pattern: /(^|[^\\](?:\\\\)*)#@?(?:[a-z][\w-]*|{[a-z][\w-]*})(?:\s*\((?:[^()]|\([^()]*\))*\))?/i,
                        lookbehind: true,
                        inside: {
-                               keyword: {
+                               'keyword': {
                                        pattern: /^#@?(?:[a-z][\w-]*|{[a-z][\w-]*})|\bin\b/,
                                        inside: {
                                                'punctuation': /[{}]/
@@ -71,4 +71,5 @@ define(["prism/prism","prism/components/prism-markup"], function () {
        Prism.languages.velocity['tag'].inside['attr-value'].inside.rest = Prism.languages.velocity;
 
 }(Prism));
+
 return Prism; })
\ No newline at end of file
index 285d87bb000af5bbea5c1d64584ec5e7e36ef057..6f8ce736e34831eac82c456715da53d181e88888 100644 (file)
@@ -1,7 +1,7 @@
 define(["prism/prism"], function () {
 Prism.languages['visual-basic'] = {
        'comment': {
-               pattern: /(?:['‘’]|REM\b).*/i,
+               pattern: /(?:['‘’]|REM\b)(?:[^\r\n_]|_(?:\r\n?|\n)?)*/i,
                inside: {
                        'keyword': /^REM/i
                }
@@ -12,16 +12,16 @@ Prism.languages['visual-basic'] = {
                greedy: true
        },
        'string': {
-               pattern: /["“”](?:["“”]{2}|[^"“”])*["“”]C?/i,
+               pattern: /\$?["“”](?:["“”]{2}|[^"“”])*["“”]C?/i,
                greedy: true
        },
        'date': {
-               pattern: /#[^\S\r\n]*(?:\d+([/-])\d+\1\d+(?:[^\S\r\n]+(?:\d+[^\S\r\n]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[^\S\r\n]*(?:AM|PM))?))?|(?:\d+[^\S\r\n]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[^\S\r\n]*(?:AM|PM))?))[^\S\r\n]*#/i,
+               pattern: /#[^\S\r\n]*(?:\d+([/-])\d+\1\d+(?:[^\S\r\n]+(?:\d+[^\S\r\n]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[^\S\r\n]*(?:AM|PM))?))?|\d+[^\S\r\n]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[^\S\r\n]*(?:AM|PM))?)[^\S\r\n]*#/i,
                alias: 'builtin'
        },
        'number': /(?:(?:\b\d+(?:\.\d+)?|\.\d+)(?:E[+-]?\d+)?|&[HO][\dA-F]+)(?:U?[ILS]|[FRD])?/i,
        'boolean': /\b(?:True|False|Nothing)\b/i,
-       'keyword': /\b(?:AddHandler|AddressOf|Alias|And(?:Also)?|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|C(?:Bool|Byte|Char|Date|Dbl|Dec|Int|Lng|Obj|SByte|Short|Sng|Str|Type|UInt|ULng|UShort)|Char|Class|Const|Continue|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else(?:If)?|End(?:If)?|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get(?:Type|XMLNamespace)?|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|Must(?:Inherit|Override)|My(?:Base|Class)|Namespace|Narrowing|New|Next|Not(?:Inheritable|Overridable)?|Object|Of|On|Operator|Option(?:al)?|Or(?:Else)?|Out|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TryCast|TypeOf|U(?:Integer|Long|Short)|Using|Variant|Wend|When|While|Widening|With(?:Events)?|WriteOnly|Xor)\b/i,
+       'keyword': /\b(?:AddHandler|AddressOf|Alias|And(?:Also)?|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|C(?:Bool|Byte|Char|Date|Dbl|Dec|Int|Lng|Obj|SByte|Short|Sng|Str|Type|UInt|ULng|UShort)|Char|Class|Const|Continue|Currency|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else(?:If)?|End(?:If)?|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get(?:Type|XMLNamespace)?|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|Must(?:Inherit|Override)|My(?:Base|Class)|Namespace|Narrowing|New|Next|Not(?:Inheritable|Overridable)?|Object|Of|On|Operator|Option(?:al)?|Or(?:Else)?|Out|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TryCast|Type|TypeOf|U(?:Integer|Long|Short)|Using|Variant|Wend|When|While|Widening|With(?:Events)?|WriteOnly|Until|Xor)\b/i,
        'operator': [
                /[+\-*/\\^<=>&#@$%!]/,
                {
@@ -33,4 +33,6 @@ Prism.languages['visual-basic'] = {
 };
 
 Prism.languages.vb = Prism.languages['visual-basic'];
+Prism.languages.vba = Prism.languages['visual-basic'];
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-warpscript.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-warpscript.js
new file mode 100644 (file)
index 0000000..3d73649
--- /dev/null
@@ -0,0 +1,24 @@
+define(["prism/prism"], function () {
+Prism.languages.warpscript = {
+       'comment': /#.*|\/\/.*|\/\*[\s\S]*?\*\//,
+       'string': {
+               pattern: /"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'|<'(?:[^\\']|'(?!>)|\\.)*'>/,
+               greedy: true
+       },
+       'variable': /\$\S+/,
+       'macro': {
+               pattern: /@\S+/,
+               alias: 'property'
+       },
+       // WarpScript doesn't have any keywords, these are all functions under the control category
+       // https://www.warp10.io/tags/control
+       'keyword': /\b(?:BREAK|CHECKMACRO|CONTINUE|CUDF|DEFINED|DEFINEDMACRO|EVAL|FAIL|FOR|FOREACH|FORSTEP|IFT|IFTE|MSGFAIL|NRETURN|RETHROW|RETURN|SWITCH|TRY|UDF|UNTIL|WHILE)\b/,
+       'number': /[+-]?\b(?:NaN|Infinity|\d+(?:\.\d*)?(?:[Ee][+-]?\d+)?|0x[\da-fA-F]+|0b[01]+)\b/,
+       'boolean': /\b(?:false|true|F|T)\b/,
+       'punctuation': /<%|%>|[{}[\]()]/,
+       // Some operators from the "operators" category
+       // https://www.warp10.io/tags/operators
+       'operator': /==|&&?|\|\|?|\*\*?|>>>?|<<|==|[<>!~]=?|[-/%^]|\+!?|\b(?:AND|NOT|OR)\b/
+};
+
+return Prism; })
\ No newline at end of file
index 98ab078d7267a9c0369efa09f8dd05489f0b4747..2e56270d10657a8e3fcfadd8f785347474036c78 100644 (file)
@@ -16,9 +16,10 @@ Prism.languages.wiki = Prism.languages.extend('markup', {
                // TODO Multi-line
                pattern: /('{2,5}).+?\1/,
                inside: {
-                       'bold italic': {
+                       'bold-italic': {
                                pattern: /(''''').+?(?=\1)/,
-                               lookbehind: true
+                               lookbehind: true,
+                               alias: ['bold', 'italic']
                        },
                        'bold': {
                                pattern: /(''')[^'](?:.*?[^'])?(?=\1)/,
index 1d5113a21f2fbcb756aa4b63a4ceb686f4b79a42..8de62140b88d4243ff2073c94e9743ca165b172c 100644 (file)
@@ -64,7 +64,7 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                        alias: 'function'
                },
                'directive-block-open': {
-                       pattern: /\$\w+:{|\$\w(?:#\d+\+?)?(?:\[[-\w.]+])?:[-\w.]+:{(![A-Z]+)?/,
+                       pattern: /\$\w+:{|\$\w(?:#\d+\+?)?(?:\[[-\w.]+])?:[-\w.]+:{(?:![A-Z]+)?/,
                        inside: {
                                'punctuation': {
                                        pattern: /\$(?:\w:|C(?:\[|#\d))?|[:{[\]]/,
@@ -113,4 +113,5 @@ define(["prism/prism","prism/components/prism-markup"], function () {
        Prism.languages.xeoracube = Prism.languages.xeora;
 
 }(Prism));
+
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-xml-doc.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-xml-doc.js
new file mode 100644 (file)
index 0000000..09092f3
--- /dev/null
@@ -0,0 +1,43 @@
+define(["prism/prism","prism/components/prism-markup"], function () {
+(function (Prism) {
+
+       /**
+        * If the given language is present, it will insert the given doc comment grammar token into it.
+        *
+        * @param {string} lang
+        * @param {any} docComment
+        */
+       function insertDocComment(lang, docComment) {
+               if (Prism.languages[lang]) {
+                       Prism.languages.insertBefore(lang, 'comment', {
+                               'doc-comment': docComment
+                       });
+               }
+       }
+
+       var tag = Prism.languages.markup.tag;
+
+       var slashDocComment = {
+               pattern: /\/\/\/.*/,
+               greedy: true,
+               alias: 'comment',
+               inside: {
+                       'tag': tag
+               }
+       };
+       var tickDocComment = {
+               pattern: /'''.*/,
+               greedy: true,
+               alias: 'comment',
+               inside: {
+                       'tag': tag
+               }
+       };
+
+       insertDocComment('csharp', slashDocComment);
+       insertDocComment('fsharp', slashDocComment);
+       insertDocComment('vbnet', tickDocComment);
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 8a131416f7a3fb81232128ee51836948139a8f00..241794839b26ef17a21678c6a2fe37b52d83ba0c 100644 (file)
@@ -56,16 +56,14 @@ define(["prism/prism","prism/components/prism-markup"], function () {
                'punctuation': /[[\](){},;:/]/
        });
 
-       Prism.languages.xquery.tag.pattern = /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|{(?!{)(?:{(?:{[^}]*}|[^}])*}|[^}])+}|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i;
-       Prism.languages.xquery['tag'].inside['attr-value'].pattern = /=(?:("|')(?:\\[\s\S]|{(?!{)(?:{(?:{[^}]*}|[^}])*}|[^}])+}|(?!\1)[^\\])*\1|[^\s'">=]+)/i;
+       Prism.languages.xquery.tag.pattern = /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|{(?!{)(?:{(?:{[^{}]*}|[^{}])*}|[^{}])+}|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i;
+       Prism.languages.xquery['tag'].inside['attr-value'].pattern = /=(?:("|')(?:\\[\s\S]|{(?!{)(?:{(?:{[^{}]*}|[^{}])*}|[^{}])+}|(?!\1)[^\\])*\1|[^\s'">=]+)/i;
        Prism.languages.xquery['tag'].inside['attr-value'].inside['punctuation'] = /^="|"$/;
        Prism.languages.xquery['tag'].inside['attr-value'].inside['expression'] = {
                // Allow for two levels of nesting
-               pattern: /{(?!{)(?:{(?:{[^}]*}|[^}])*}|[^}])+}/,
-               inside: {
-                       rest: Prism.languages.xquery
-               },
-               'alias': 'language-xquery'
+               pattern: /{(?!{)(?:{(?:{[^{}]*}|[^{}])*}|[^{}])+}/,
+               inside: Prism.languages.xquery,
+               alias: 'language-xquery'
        };
 
        // The following will handle plain text inside tags
@@ -163,4 +161,5 @@ define(["prism/prism","prism/components/prism-markup"], function () {
        });
 
 }(Prism));
+
 return Prism; })
\ No newline at end of file
index 6276fee71dc505779c8ab63e45b2b775bff8903d..2d7bac78caa34d2694b2ceaaec98eafbdceca24f 100644 (file)
@@ -1,49 +1,79 @@
 define(["prism/prism"], function () {
-Prism.languages.yaml = {
-       'scalar': {
-               pattern: /([\-:]\s*(?:![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,
-               lookbehind: true,
-               alias: 'string'
-       },
-       'comment': /#.*/,
-       'key': {
-               pattern: /(\s*(?:^|[:\-,[{\r\n?])[ \t]*(?:![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/,
-               lookbehind: true,
-               alias: 'atrule'
-       },
-       'directive': {
-               pattern: /(^[ \t]*)%.+/m,
-               lookbehind: true,
-               alias: 'important'
-       },
-       'datetime': {
-               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?)(?=[ \t]*(?:$|,|]|}))/m,
-               lookbehind: true,
-               alias: 'number'
-       },
-       'boolean': {
-               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:true|false)[ \t]*(?=$|,|]|})/im,
-               lookbehind: true,
-               alias: 'important'
-       },
-       'null': {
-               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)(?:null|~)[ \t]*(?=$|,|]|})/im,
-               lookbehind: true,
-               alias: 'important'
-       },
-       'string': {
-               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)("|')(?:(?!\2)[^\\\r\n]|\\.)*\2(?=[ \t]*(?:$|,|]|}|\s*#))/m,
-               lookbehind: true,
-               greedy: true
-       },
-       'number': {
-               pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,
-               lookbehind: true
-       },
-       'tag': /![^\s]+/,
-       'important': /[&*][\w]+/,
-       'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
-};
+(function (Prism) {
+
+       // https://yaml.org/spec/1.2/spec.html#c-ns-anchor-property
+       // https://yaml.org/spec/1.2/spec.html#c-ns-alias-node
+       var anchorOrAlias = /[*&][^\s[\]{},]+/;
+       // https://yaml.org/spec/1.2/spec.html#c-ns-tag-property
+       var tag = /!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/;
+       // https://yaml.org/spec/1.2/spec.html#c-ns-properties(n,c)
+       var properties = '(?:' + tag.source + '(?:[ \t]+' + anchorOrAlias.source + ')?|'
+               + anchorOrAlias.source + '(?:[ \t]+' + tag.source + ')?)';
+
+       /**
+        *
+        * @param {string} value
+        * @param {string} [flags]
+        * @returns {RegExp}
+        */
+       function createValuePattern(value, flags) {
+               flags = (flags || '').replace(/m/g, '') + 'm'; // add m flag
+               var pattern = /([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|]|}|\s*#))/.source
+                       .replace(/<<prop>>/g, function () { return properties; }).replace(/<<value>>/g, function () { return value; });
+               return RegExp(pattern, flags)
+       }
+
+       Prism.languages.yaml = {
+               'scalar': {
+                       pattern: RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/.source
+                               .replace(/<<prop>>/g, function () { return properties; })),
+                       lookbehind: true,
+                       alias: 'string'
+               },
+               'comment': /#.*/,
+               'key': {
+                       pattern: RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)[^\r\n{[\]},#\s]+?(?=\s*:\s)/.source
+                               .replace(/<<prop>>/g, function () { return properties; })),
+                       lookbehind: true,
+                       alias: 'atrule'
+               },
+               'directive': {
+                       pattern: /(^[ \t]*)%.+/m,
+                       lookbehind: true,
+                       alias: 'important'
+               },
+               'datetime': {
+                       pattern: createValuePattern(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),
+                       lookbehind: true,
+                       alias: 'number'
+               },
+               'boolean': {
+                       pattern: createValuePattern(/true|false/.source, 'i'),
+                       lookbehind: true,
+                       alias: 'important'
+               },
+               'null': {
+                       pattern: createValuePattern(/null|~/.source, 'i'),
+                       lookbehind: true,
+                       alias: 'important'
+               },
+               'string': {
+                       // \2 because of the lookbehind group
+                       pattern: createValuePattern(/("|')(?:(?!\2)[^\\\r\n]|\\.)*\2/.source),
+                       lookbehind: true,
+                       greedy: true
+               },
+               'number': {
+                       pattern: createValuePattern(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source, 'i'),
+                       lookbehind: true
+               },
+               'tag': tag,
+               'important': anchorOrAlias,
+               'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
+       };
+
+       Prism.languages.yml = Prism.languages.yaml;
+
+}(Prism));
 
-Prism.languages.yml = Prism.languages.yaml;
 return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-yang.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-yang.js
new file mode 100644 (file)
index 0000000..abd2622
--- /dev/null
@@ -0,0 +1,23 @@
+define(["prism/prism"], function () {
+Prism.languages.yang = {
+       // https://tools.ietf.org/html/rfc6020#page-34
+       // http://www.yang-central.org/twiki/bin/view/Main/YangExamples
+       'comment': /\/\*[\s\S]*?\*\/|\/\/.*/,
+       'string': {
+               pattern: /"(?:[^\\"]|\\.)*"|'[^']*'/,
+               greedy: true
+       },
+       'keyword': {
+               pattern: /(^|[{};\r\n][ \t]*)[a-z_][\w.-]*/i,
+               lookbehind: true
+       },
+       'namespace': {
+               pattern: /(\s)[a-z_][\w.-]*(?=:)/i,
+               lookbehind: true
+       },
+       'boolean': /\b(?:false|true)\b/,
+       'operator': /\+/,
+       'punctuation': /[{};:]/
+};
+
+return Prism; })
\ No newline at end of file
diff --git a/wcfsetup/install/files/js/3rdParty/prism/components/prism-zig.js b/wcfsetup/install/files/js/3rdParty/prism/components/prism-zig.js
new file mode 100644 (file)
index 0000000..cb61f3c
--- /dev/null
@@ -0,0 +1,104 @@
+define(["prism/prism"], function () {
+(function (Prism) {
+
+       function literal(str) {
+               return function () { return str; };
+       }
+
+       var keyword = /\b(?:align|allowzero|and|asm|async|await|break|cancel|catch|comptime|const|continue|defer|else|enum|errdefer|error|export|extern|fn|for|if|inline|linksection|nakedcc|noalias|null|or|orelse|packed|promise|pub|resume|return|stdcallcc|struct|suspend|switch|test|threadlocal|try|undefined|union|unreachable|usingnamespace|var|volatile|while)\b/;
+
+       var IDENTIFIER = '\\b(?!' + keyword.source + ')(?!\\d)\\w+\\b';
+       var ALIGN = /align\s*\((?:[^()]|\([^()]*\))*\)/.source;
+       var PREFIX_TYPE_OP = /(?:\?|\bpromise->|(?:\[[^[\]]*\]|\*(?!\*)|\*\*)(?:\s*<ALIGN>|\s*const\b|\s*volatile\b|\s*allowzero\b)*)/.source.replace(/<ALIGN>/g, literal(ALIGN));
+       var SUFFIX_EXPR = /(?:\bpromise\b|(?:\berror\.)?<ID>(?:\.<ID>)*(?!\s+<ID>))/.source.replace(/<ID>/g, literal(IDENTIFIER));
+       var TYPE = '(?!\\s)(?:!?\\s*(?:' + PREFIX_TYPE_OP + '\\s*)*' + SUFFIX_EXPR + ')+';
+
+       /*
+        * A simplified grammar for Zig compile time type literals:
+        *
+        * TypeExpr = ( "!"? PREFIX_TYPE_OP* SUFFIX_EXPR )+
+        *
+        * SUFFIX_EXPR = ( \b "promise" \b | ( \b "error" "." )? IDENTIFIER ( "." IDENTIFIER )* (?! \s+ IDENTIFIER ) )
+        *
+        * PREFIX_TYPE_OP = "?"
+        *                | \b "promise" "->"
+        *                | ( "[" [^\[\]]* "]" | "*" | "**" ) ( ALIGN | "const" \b | "volatile" \b | "allowzero" \b )*
+        *
+        * ALIGN = "align" "(" ( [^()] | "(" [^()]* ")" )* ")"
+        *
+        * IDENTIFIER = \b (?! KEYWORD ) [a-zA-Z_] \w* \b
+        *
+       */
+
+       Prism.languages.zig = {
+               'comment': [
+                       {
+                               pattern: /\/{3}.*/,
+                               alias: 'doc-comment'
+                       },
+                       /\/{2}.*/
+               ],
+               'string': [
+                       {
+                               // "string" and c"string"
+                               pattern: /(^|[^\\@])c?"(?:[^"\\\r\n]|\\.)*"/,
+                               lookbehind: true,
+                               greedy: true
+                       },
+                       {
+                               // multiline strings and c-strings
+                               pattern: /([\r\n])([ \t]+c?\\{2}).*(?:(?:\r\n?|\n)\2.*)*/,
+                               lookbehind: true,
+                               greedy: true
+                       },
+                       {
+                               // characters 'a', '\n', '\xFF', '\u{10FFFF}'
+                               pattern: /(^|[^\\])'(?:[^'\\\r\n]|\\(?:.|x[a-fA-F\d]{2}|u\{[a-fA-F\d]{1,6}\}))'/,
+                               lookbehind: true,
+                               greedy: true
+                       }
+               ],
+               'builtin': /\B@(?!\d)\w+(?=\s*\()/,
+               'label': {
+                       pattern: /(\b(?:break|continue)\s*:\s*)\w+\b|\b(?!\d)\w+\b(?=\s*:\s*(?:\{|while\b))/,
+                       lookbehind: true
+               },
+               'class-name': [
+                       // const Foo = struct {};
+                       /\b(?!\d)\w+(?=\s*=\s*(?:(?:extern|packed)\s+)?(?:enum|struct|union)\s*[({])/,
+                       {
+                               // const x: i32 = 9;
+                               // var x: Bar;
+                               // fn foo(x: bool, y: f32) void {}
+                               pattern: RegExp(/(:\s*)<TYPE>(?=\s*(?:<ALIGN>\s*)?[=;,)])|<TYPE>(?=\s*(?:<ALIGN>\s*)?\{)/.source.replace(/<TYPE>/g, literal(TYPE)).replace(/<ALIGN>/g, literal(ALIGN))),
+                               lookbehind: true,
+                               inside: null // see below
+                       },
+                       {
+                               // extern fn foo(x: f64) f64; (optional alignment)
+                               pattern: RegExp(/(\)\s*)<TYPE>(?=\s*(?:<ALIGN>\s*)?;)/.source.replace(/<TYPE>/g, literal(TYPE)).replace(/<ALIGN>/g, literal(ALIGN))),
+                               lookbehind: true,
+                               inside: null // see below
+                       }
+               ],
+               'builtin-types': {
+                       pattern: /\b(?:anyerror|bool|c_u?(?:short|int|long|longlong)|c_longdouble|c_void|comptime_(?:float|int)|[iu](?:8|16|32|64|128|size)|f(?:16|32|64|128)|noreturn|type|void)\b/,
+                       alias: 'keyword'
+               },
+               'keyword': keyword,
+               'function': /\b(?!\d)\w+(?=\s*\()/,
+               'number': /\b(?:0b[01]+|0o[0-7]+|0x[a-fA-F\d]+\.?[a-fA-F\d]*(?:[pP][+-]?[a-fA-F\d]+)?|\d+\.?\d*(?:[eE][+-]?\d+)?)\b/,
+               'boolean': /\b(?:false|true)\b/,
+               'operator': /\.[*?]|\.{2,3}|[-=]>|\*\*|\+\+|\|\||(?:<<|>>|[-+*]%|[-+*/%^&|<>!=])=?|[?~]/,
+               'punctuation': /[.:,;(){}[\]]/
+       };
+
+       Prism.languages.zig['class-name'].forEach(function (obj) {
+               if (obj.inside === null) {
+                       obj.inside = Prism.languages.zig;
+               }
+       });
+
+}(Prism));
+
+return Prism; })
\ No newline at end of file
index 84813e5b824fa7a2f9318ea9eb7250c702fbbca6..6284a3543ab5614df9541dd910f2585445dfe811 100644 (file)
@@ -1 +1 @@
-define([],function(){return /*START*/{"markup":{"title":"Markup","file":"markup"},"html":{"title":"HTML","file":"markup"},"xml":{"title":"XML","file":"markup"},"svg":{"title":"SVG","file":"markup"},"mathml":{"title":"MathML","file":"markup"},"css":{"title":"CSS","file":"css"},"clike":{"title":"C-like","file":"clike"},"javascript":{"title":"JavaScript","file":"javascript"},"abap":{"title":"ABAP","file":"abap"},"abnf":{"title":"Augmented Backus–Naur form","file":"abnf"},"actionscript":{"title":"ActionScript","file":"actionscript"},"ada":{"title":"Ada","file":"ada"},"apacheconf":{"title":"Apache Configuration","file":"apacheconf"},"apl":{"title":"APL","file":"apl"},"applescript":{"title":"AppleScript","file":"applescript"},"arduino":{"title":"Arduino","file":"arduino"},"arff":{"title":"ARFF","file":"arff"},"asciidoc":{"title":"AsciiDoc","file":"asciidoc"},"asm6502":{"title":"6502 Assembly","file":"asm6502"},"aspnet":{"title":"ASP.NET (C#)","file":"aspnet"},"autohotkey":{"title":"AutoHotkey","file":"autohotkey"},"autoit":{"title":"AutoIt","file":"autoit"},"bash":{"title":"Bash","file":"bash"},"basic":{"title":"BASIC","file":"basic"},"batch":{"title":"Batch","file":"batch"},"bison":{"title":"Bison","file":"bison"},"bnf":{"title":"Backus–Naur form","file":"bnf"},"brainfuck":{"title":"Brainfuck","file":"brainfuck"},"bro":{"title":"Bro","file":"bro"},"c":{"title":"C","file":"c"},"csharp":{"title":"C#","file":"csharp"},"cpp":{"title":"C++","file":"cpp"},"cil":{"title":"CIL","file":"cil"},"coffeescript":{"title":"CoffeeScript","file":"coffeescript"},"cmake":{"title":"CMake","file":"cmake"},"clojure":{"title":"Clojure","file":"clojure"},"crystal":{"title":"Crystal","file":"crystal"},"csp":{"title":"Content-Security-Policy","file":"csp"},"css-extras":{"title":"CSS Extras","file":"css-extras"},"d":{"title":"D","file":"d"},"dart":{"title":"Dart","file":"dart"},"diff":{"title":"Diff","file":"diff"},"django":{"title":"Django/Jinja2","file":"django"},"docker":{"title":"Docker","file":"docker"},"ebnf":{"title":"Extended Backus–Naur form","file":"ebnf"},"eiffel":{"title":"Eiffel","file":"eiffel"},"ejs":{"title":"EJS","file":"ejs"},"elixir":{"title":"Elixir","file":"elixir"},"elm":{"title":"Elm","file":"elm"},"erb":{"title":"ERB","file":"erb"},"erlang":{"title":"Erlang","file":"erlang"},"fsharp":{"title":"F#","file":"fsharp"},"flow":{"title":"Flow","file":"flow"},"fortran":{"title":"Fortran","file":"fortran"},"gcode":{"title":"G-code","file":"gcode"},"gedcom":{"title":"GEDCOM","file":"gedcom"},"gherkin":{"title":"Gherkin","file":"gherkin"},"git":{"title":"Git","file":"git"},"glsl":{"title":"GLSL","file":"glsl"},"gml":{"title":"GameMaker Language","file":"gml"},"go":{"title":"Go","file":"go"},"graphql":{"title":"GraphQL","file":"graphql"},"groovy":{"title":"Groovy","file":"groovy"},"haml":{"title":"Haml","file":"haml"},"handlebars":{"title":"Handlebars","file":"handlebars"},"haskell":{"title":"Haskell","file":"haskell"},"haxe":{"title":"Haxe","file":"haxe"},"hcl":{"title":"HCL","file":"hcl"},"http":{"title":"HTTP","file":"http"},"hpkp":{"title":"HTTP Public-Key-Pins","file":"hpkp"},"hsts":{"title":"HTTP Strict-Transport-Security","file":"hsts"},"ichigojam":{"title":"IchigoJam","file":"ichigojam"},"icon":{"title":"Icon","file":"icon"},"inform7":{"title":"Inform 7","file":"inform7"},"ini":{"title":"Ini","file":"ini"},"io":{"title":"Io","file":"io"},"j":{"title":"J","file":"j"},"java":{"title":"Java","file":"java"},"javadoc":{"title":"JavaDoc","file":"javadoc"},"javadoclike":{"title":"JavaDoc-like","file":"javadoclike"},"javastacktrace":{"title":"Java stack trace","file":"javastacktrace"},"jolie":{"title":"Jolie","file":"jolie"},"jq":{"title":"JQ","file":"jq"},"jsdoc":{"title":"JSDoc","file":"jsdoc"},"js-extras":{"title":"JS Extras","file":"js-extras"},"json":{"title":"JSON","file":"json"},"jsonp":{"title":"JSONP","file":"jsonp"},"json5":{"title":"JSON5","file":"json5"},"julia":{"title":"Julia","file":"julia"},"keyman":{"title":"Keyman","file":"keyman"},"kotlin":{"title":"Kotlin","file":"kotlin"},"latex":{"title":"LaTeX","file":"latex"},"tex":{"title":"TeX","file":"latex"},"context":{"title":"ConTeXt","file":"latex"},"less":{"title":"Less","file":"less"},"liquid":{"title":"Liquid","file":"liquid"},"lisp":{"title":"Lisp","file":"lisp"},"livescript":{"title":"LiveScript","file":"livescript"},"lolcode":{"title":"LOLCODE","file":"lolcode"},"lua":{"title":"Lua","file":"lua"},"makefile":{"title":"Makefile","file":"makefile"},"markdown":{"title":"Markdown","file":"markdown"},"markup-templating":{"title":"Markup templating","file":"markup-templating"},"matlab":{"title":"MATLAB","file":"matlab"},"mel":{"title":"MEL","file":"mel"},"mizar":{"title":"Mizar","file":"mizar"},"monkey":{"title":"Monkey","file":"monkey"},"n1ql":{"title":"N1QL","file":"n1ql"},"n4js":{"title":"N4JS","file":"n4js"},"nand2tetris-hdl":{"title":"Nand To Tetris HDL","file":"nand2tetris-hdl"},"nasm":{"title":"NASM","file":"nasm"},"nginx":{"title":"nginx","file":"nginx"},"nim":{"title":"Nim","file":"nim"},"nix":{"title":"Nix","file":"nix"},"nsis":{"title":"NSIS","file":"nsis"},"objectivec":{"title":"Objective-C","file":"objectivec"},"ocaml":{"title":"OCaml","file":"ocaml"},"opencl":{"title":"OpenCL","file":"opencl"},"oz":{"title":"Oz","file":"oz"},"parigp":{"title":"PARI/GP","file":"parigp"},"parser":{"title":"Parser","file":"parser"},"pascal":{"title":"Pascal","file":"pascal"},"perl":{"title":"Perl","file":"perl"},"php":{"title":"PHP","file":"php"},"phpdoc":{"title":"PHPDoc","file":"phpdoc"},"php-extras":{"title":"PHP Extras","file":"php-extras"},"plsql":{"title":"PL/SQL","file":"plsql"},"powershell":{"title":"PowerShell","file":"powershell"},"processing":{"title":"Processing","file":"processing"},"prolog":{"title":"Prolog","file":"prolog"},"properties":{"title":".properties","file":"properties"},"protobuf":{"title":"Protocol Buffers","file":"protobuf"},"pug":{"title":"Pug","file":"pug"},"puppet":{"title":"Puppet","file":"puppet"},"pure":{"title":"Pure","file":"pure"},"python":{"title":"Python","file":"python"},"q":{"title":"Q (kdb+ database)","file":"q"},"qore":{"title":"Qore","file":"qore"},"r":{"title":"R","file":"r"},"jsx":{"title":"React JSX","file":"jsx"},"tsx":{"title":"React TSX","file":"tsx"},"renpy":{"title":"Ren'py","file":"renpy"},"reason":{"title":"Reason","file":"reason"},"regex":{"title":"Regex","file":"regex"},"rest":{"title":"reST (reStructuredText)","file":"rest"},"rip":{"title":"Rip","file":"rip"},"roboconf":{"title":"Roboconf","file":"roboconf"},"ruby":{"title":"Ruby","file":"ruby"},"rust":{"title":"Rust","file":"rust"},"sas":{"title":"SAS","file":"sas"},"sass":{"title":"Sass (Sass)","file":"sass"},"scss":{"title":"Sass (Scss)","file":"scss"},"scala":{"title":"Scala","file":"scala"},"scheme":{"title":"Scheme","file":"scheme"},"shell-session":{"title":"Shell session","file":"shell-session"},"smalltalk":{"title":"Smalltalk","file":"smalltalk"},"smarty":{"title":"Smarty","file":"smarty"},"sql":{"title":"SQL","file":"sql"},"soy":{"title":"Soy (Closure Template)","file":"soy"},"stylus":{"title":"Stylus","file":"stylus"},"swift":{"title":"Swift","file":"swift"},"tap":{"title":"TAP","file":"tap"},"tcl":{"title":"Tcl","file":"tcl"},"textile":{"title":"Textile","file":"textile"},"toml":{"title":"TOML","file":"toml"},"tt2":{"title":"Template Toolkit 2","file":"tt2"},"twig":{"title":"Twig","file":"twig"},"typescript":{"title":"TypeScript","file":"typescript"},"t4-cs":{"title":"T4 Text Templates (C#)","file":"t4-cs"},"t4-vb":{"title":"T4 Text Templates (VB)","file":"t4-vb"},"t4-templating":{"title":"T4 templating","file":"t4-templating"},"vala":{"title":"Vala","file":"vala"},"vbnet":{"title":"VB.Net","file":"vbnet"},"velocity":{"title":"Velocity","file":"velocity"},"verilog":{"title":"Verilog","file":"verilog"},"vhdl":{"title":"VHDL","file":"vhdl"},"vim":{"title":"vim","file":"vim"},"visual-basic":{"title":"Visual Basic","file":"visual-basic"},"wasm":{"title":"WebAssembly","file":"wasm"},"wiki":{"title":"Wiki markup","file":"wiki"},"xeora":{"title":"Xeora","file":"xeora"},"xojo":{"title":"Xojo (REALbasic)","file":"xojo"},"xquery":{"title":"XQuery","file":"xquery"},"yaml":{"title":"YAML","file":"yaml"}}/*END*/;});
\ No newline at end of file
+define([],function(){return /*START*/{"markup":{"title":"Markup","file":"markup"},"html":{"title":"HTML","file":"markup"},"xml":{"title":"XML","file":"markup"},"svg":{"title":"SVG","file":"markup"},"mathml":{"title":"MathML","file":"markup"},"ssml":{"title":"SSML","file":"markup"},"atom":{"title":"Atom","file":"markup"},"rss":{"title":"RSS","file":"markup"},"css":{"title":"CSS","file":"css"},"clike":{"title":"C-like","file":"clike"},"javascript":{"title":"JavaScript","file":"javascript"},"abap":{"title":"ABAP","file":"abap"},"abnf":{"title":"ABNF","file":"abnf"},"actionscript":{"title":"ActionScript","file":"actionscript"},"ada":{"title":"Ada","file":"ada"},"agda":{"title":"Agda","file":"agda"},"al":{"title":"AL","file":"al"},"antlr4":{"title":"ANTLR4","file":"antlr4"},"apacheconf":{"title":"Apache Configuration","file":"apacheconf"},"apl":{"title":"APL","file":"apl"},"applescript":{"title":"AppleScript","file":"applescript"},"aql":{"title":"AQL","file":"aql"},"arduino":{"title":"Arduino","file":"arduino"},"arff":{"title":"ARFF","file":"arff"},"asciidoc":{"title":"AsciiDoc","file":"asciidoc"},"aspnet":{"title":"ASP.NET (C#)","file":"aspnet"},"asm6502":{"title":"6502 Assembly","file":"asm6502"},"autohotkey":{"title":"AutoHotkey","file":"autohotkey"},"autoit":{"title":"AutoIt","file":"autoit"},"bash":{"title":"Bash","file":"bash"},"basic":{"title":"BASIC","file":"basic"},"batch":{"title":"Batch","file":"batch"},"bbcode":{"title":"BBcode","file":"bbcode"},"bison":{"title":"Bison","file":"bison"},"bnf":{"title":"BNF","file":"bnf"},"brainfuck":{"title":"Brainfuck","file":"brainfuck"},"brightscript":{"title":"BrightScript","file":"brightscript"},"bro":{"title":"Bro","file":"bro"},"c":{"title":"C","file":"c"},"csharp":{"title":"C#","file":"csharp"},"cpp":{"title":"C++","file":"cpp"},"cil":{"title":"CIL","file":"cil"},"clojure":{"title":"Clojure","file":"clojure"},"cmake":{"title":"CMake","file":"cmake"},"coffeescript":{"title":"CoffeeScript","file":"coffeescript"},"concurnas":{"title":"Concurnas","file":"concurnas"},"csp":{"title":"Content-Security-Policy","file":"csp"},"crystal":{"title":"Crystal","file":"crystal"},"css-extras":{"title":"CSS Extras","file":"css-extras"},"cypher":{"title":"Cypher","file":"cypher"},"d":{"title":"D","file":"d"},"dart":{"title":"Dart","file":"dart"},"dax":{"title":"DAX","file":"dax"},"dhall":{"title":"Dhall","file":"dhall"},"diff":{"title":"Diff","file":"diff"},"django":{"title":"Django/Jinja2","file":"django"},"dns-zone-file":{"title":"DNS zone file","file":"dns-zone-file"},"docker":{"title":"Docker","file":"docker"},"ebnf":{"title":"EBNF","file":"ebnf"},"editorconfig":{"title":"EditorConfig","file":"editorconfig"},"eiffel":{"title":"Eiffel","file":"eiffel"},"ejs":{"title":"EJS","file":"ejs"},"elixir":{"title":"Elixir","file":"elixir"},"elm":{"title":"Elm","file":"elm"},"etlua":{"title":"Embedded Lua templating","file":"etlua"},"erb":{"title":"ERB","file":"erb"},"erlang":{"title":"Erlang","file":"erlang"},"excel-formula":{"title":"Excel Formula","file":"excel-formula"},"fsharp":{"title":"F#","file":"fsharp"},"factor":{"title":"Factor","file":"factor"},"firestore-security-rules":{"title":"Firestore security rules","file":"firestore-security-rules"},"flow":{"title":"Flow","file":"flow"},"fortran":{"title":"Fortran","file":"fortran"},"ftl":{"title":"FreeMarker Template Language","file":"ftl"},"gml":{"title":"GameMaker Language","file":"gml"},"gcode":{"title":"G-code","file":"gcode"},"gdscript":{"title":"GDScript","file":"gdscript"},"gedcom":{"title":"GEDCOM","file":"gedcom"},"gherkin":{"title":"Gherkin","file":"gherkin"},"git":{"title":"Git","file":"git"},"glsl":{"title":"GLSL","file":"glsl"},"go":{"title":"Go","file":"go"},"graphql":{"title":"GraphQL","file":"graphql"},"groovy":{"title":"Groovy","file":"groovy"},"haml":{"title":"Haml","file":"haml"},"handlebars":{"title":"Handlebars","file":"handlebars"},"haskell":{"title":"Haskell","file":"haskell"},"haxe":{"title":"Haxe","file":"haxe"},"hcl":{"title":"HCL","file":"hcl"},"hlsl":{"title":"HLSL","file":"hlsl"},"http":{"title":"HTTP","file":"http"},"hpkp":{"title":"HTTP Public-Key-Pins","file":"hpkp"},"hsts":{"title":"HTTP Strict-Transport-Security","file":"hsts"},"ichigojam":{"title":"IchigoJam","file":"ichigojam"},"icon":{"title":"Icon","file":"icon"},"ignore":{"title":".ignore","file":"ignore"},"gitignore":{"title":".gitignore","file":"ignore"},"hgignore":{"title":".hgignore","file":"ignore"},"npmignore":{"title":".npmignore","file":"ignore"},"inform7":{"title":"Inform 7","file":"inform7"},"ini":{"title":"Ini","file":"ini"},"io":{"title":"Io","file":"io"},"j":{"title":"J","file":"j"},"java":{"title":"Java","file":"java"},"javadoc":{"title":"JavaDoc","file":"javadoc"},"javadoclike":{"title":"JavaDoc-like","file":"javadoclike"},"javastacktrace":{"title":"Java stack trace","file":"javastacktrace"},"jolie":{"title":"Jolie","file":"jolie"},"jq":{"title":"JQ","file":"jq"},"jsdoc":{"title":"JSDoc","file":"jsdoc"},"js-extras":{"title":"JS Extras","file":"js-extras"},"json":{"title":"JSON","file":"json"},"json5":{"title":"JSON5","file":"json5"},"jsonp":{"title":"JSONP","file":"jsonp"},"jsstacktrace":{"title":"JS stack trace","file":"jsstacktrace"},"js-templates":{"title":"JS Templates","file":"js-templates"},"julia":{"title":"Julia","file":"julia"},"keyman":{"title":"Keyman","file":"keyman"},"kotlin":{"title":"Kotlin","file":"kotlin"},"kts":{"title":"Kotlin Script","file":"kotlin"},"latex":{"title":"LaTeX","file":"latex"},"tex":{"title":"TeX","file":"latex"},"context":{"title":"ConTeXt","file":"latex"},"latte":{"title":"Latte","file":"latte"},"less":{"title":"Less","file":"less"},"lilypond":{"title":"LilyPond","file":"lilypond"},"liquid":{"title":"Liquid","file":"liquid"},"lisp":{"title":"Lisp","file":"lisp"},"livescript":{"title":"LiveScript","file":"livescript"},"llvm":{"title":"LLVM IR","file":"llvm"},"lolcode":{"title":"LOLCODE","file":"lolcode"},"lua":{"title":"Lua","file":"lua"},"makefile":{"title":"Makefile","file":"makefile"},"markdown":{"title":"Markdown","file":"markdown"},"markup-templating":{"title":"Markup templating","file":"markup-templating"},"matlab":{"title":"MATLAB","file":"matlab"},"mel":{"title":"MEL","file":"mel"},"mizar":{"title":"Mizar","file":"mizar"},"monkey":{"title":"Monkey","file":"monkey"},"moonscript":{"title":"MoonScript","file":"moonscript"},"n1ql":{"title":"N1QL","file":"n1ql"},"n4js":{"title":"N4JS","file":"n4js"},"nand2tetris-hdl":{"title":"Nand To Tetris HDL","file":"nand2tetris-hdl"},"nasm":{"title":"NASM","file":"nasm"},"neon":{"title":"NEON","file":"neon"},"nginx":{"title":"nginx","file":"nginx"},"nim":{"title":"Nim","file":"nim"},"nix":{"title":"Nix","file":"nix"},"nsis":{"title":"NSIS","file":"nsis"},"objectivec":{"title":"Objective-C","file":"objectivec"},"ocaml":{"title":"OCaml","file":"ocaml"},"opencl":{"title":"OpenCL","file":"opencl"},"oz":{"title":"Oz","file":"oz"},"parigp":{"title":"PARI/GP","file":"parigp"},"parser":{"title":"Parser","file":"parser"},"pascal":{"title":"Pascal","file":"pascal"},"pascaligo":{"title":"Pascaligo","file":"pascaligo"},"pcaxis":{"title":"PC-Axis","file":"pcaxis"},"peoplecode":{"title":"PeopleCode","file":"peoplecode"},"perl":{"title":"Perl","file":"perl"},"php":{"title":"PHP","file":"php"},"phpdoc":{"title":"PHPDoc","file":"phpdoc"},"php-extras":{"title":"PHP Extras","file":"php-extras"},"plsql":{"title":"PL/SQL","file":"plsql"},"powerquery":{"title":"PowerQuery","file":"powerquery"},"powershell":{"title":"PowerShell","file":"powershell"},"processing":{"title":"Processing","file":"processing"},"prolog":{"title":"Prolog","file":"prolog"},"properties":{"title":".properties","file":"properties"},"protobuf":{"title":"Protocol Buffers","file":"protobuf"},"pug":{"title":"Pug","file":"pug"},"puppet":{"title":"Puppet","file":"puppet"},"pure":{"title":"Pure","file":"pure"},"purebasic":{"title":"PureBasic","file":"purebasic"},"python":{"title":"Python","file":"python"},"q":{"title":"Q (kdb+ database)","file":"q"},"qml":{"title":"QML","file":"qml"},"qore":{"title":"Qore","file":"qore"},"r":{"title":"R","file":"r"},"racket":{"title":"Racket","file":"racket"},"jsx":{"title":"React JSX","file":"jsx"},"tsx":{"title":"React TSX","file":"tsx"},"reason":{"title":"Reason","file":"reason"},"regex":{"title":"Regex","file":"regex"},"renpy":{"title":"Ren'py","file":"renpy"},"rest":{"title":"reST (reStructuredText)","file":"rest"},"rip":{"title":"Rip","file":"rip"},"roboconf":{"title":"Roboconf","file":"roboconf"},"robotframework":{"title":"Robot Framework","file":"robotframework"},"ruby":{"title":"Ruby","file":"ruby"},"rust":{"title":"Rust","file":"rust"},"sas":{"title":"SAS","file":"sas"},"sass":{"title":"Sass (Sass)","file":"sass"},"scss":{"title":"Sass (Scss)","file":"scss"},"scala":{"title":"Scala","file":"scala"},"scheme":{"title":"Scheme","file":"scheme"},"shell-session":{"title":"Shell session","file":"shell-session"},"smali":{"title":"Smali","file":"smali"},"smalltalk":{"title":"Smalltalk","file":"smalltalk"},"smarty":{"title":"Smarty","file":"smarty"},"solidity":{"title":"Solidity (Ethereum)","file":"solidity"},"solution-file":{"title":"Solution file","file":"solution-file"},"soy":{"title":"Soy (Closure Template)","file":"soy"},"sparql":{"title":"SPARQL","file":"sparql"},"splunk-spl":{"title":"Splunk SPL","file":"splunk-spl"},"sqf":{"title":"SQF: Status Quo Function (Arma 3)","file":"sqf"},"sql":{"title":"SQL","file":"sql"},"iecst":{"title":"Structured Text (IEC 61131-3)","file":"iecst"},"stylus":{"title":"Stylus","file":"stylus"},"swift":{"title":"Swift","file":"swift"},"t4-templating":{"title":"T4 templating","file":"t4-templating"},"t4-cs":{"title":"T4 Text Templates (C#)","file":"t4-cs"},"t4-vb":{"title":"T4 Text Templates (VB)","file":"t4-vb"},"tap":{"title":"TAP","file":"tap"},"tcl":{"title":"Tcl","file":"tcl"},"tt2":{"title":"Template Toolkit 2","file":"tt2"},"textile":{"title":"Textile","file":"textile"},"toml":{"title":"TOML","file":"toml"},"turtle":{"title":"Turtle","file":"turtle"},"twig":{"title":"Twig","file":"twig"},"typescript":{"title":"TypeScript","file":"typescript"},"unrealscript":{"title":"UnrealScript","file":"unrealscript"},"vala":{"title":"Vala","file":"vala"},"vbnet":{"title":"VB.Net","file":"vbnet"},"velocity":{"title":"Velocity","file":"velocity"},"verilog":{"title":"Verilog","file":"verilog"},"vhdl":{"title":"VHDL","file":"vhdl"},"vim":{"title":"vim","file":"vim"},"visual-basic":{"title":"Visual Basic","file":"visual-basic"},"vba":{"title":"VBA","file":"visual-basic"},"warpscript":{"title":"WarpScript","file":"warpscript"},"wasm":{"title":"WebAssembly","file":"wasm"},"wiki":{"title":"Wiki markup","file":"wiki"},"xeora":{"title":"Xeora","file":"xeora"},"xml-doc":{"title":"XML doc (.net)","file":"xml-doc"},"xojo":{"title":"Xojo (REALbasic)","file":"xojo"},"xquery":{"title":"XQuery","file":"xquery"},"yaml":{"title":"YAML","file":"yaml"},"yang":{"title":"YANG","file":"yang"},"zig":{"title":"Zig","file":"zig"}}/*END*/;});
\ No newline at end of file
index d4e81a35fb63769c6e9d69ac6394a9e9f660fe3f..24c3b77a1c35110ce3e6a93d42c61f4e79230ed5 100644 (file)
@@ -1,3 +1,10 @@
+
+/* **********************************************
+     Begin prism-core.js
+********************************************** */
+
+/// <reference lib="WebWorker"/>
+
 var _self = (typeof window !== 'undefined')
        ? window   // if in browser
        : (
@@ -8,34 +15,90 @@ var _self = (typeof window !== 'undefined')
 
 /**
  * Prism: Lightweight, robust, elegant syntax highlighting
- * MIT license http://www.opensource.org/licenses/mit-license.php/
- * @author Lea Verou http://lea.verou.me
+ *
+ * @license MIT <https://opensource.org/licenses/MIT>
+ * @author Lea Verou <https://lea.verou.me>
+ * @namespace
+ * @public
  */
-
 var Prism = (function (_self){
 
 // Private helper vars
 var lang = /\blang(?:uage)?-([\w-]+)\b/i;
 var uniqueId = 0;
 
+
 var _ = {
+       /**
+        * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
+        * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
+        * additional languages or plugins yourself.
+        *
+        * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
+        *
+        * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
+        * empty Prism object into the global scope before loading the Prism script like this:
+        *
+        * ```js
+        * window.Prism = window.Prism || {};
+        * Prism.manual = true;
+        * // add a new <script> to load Prism's script
+        * ```
+        *
+        * @default false
+        * @type {boolean}
+        * @memberof Prism
+        * @public
+        */
        manual: _self.Prism && _self.Prism.manual,
        disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
+
+       /**
+        * A namespace for utility methods.
+        *
+        * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
+        * change or disappear at any time.
+        *
+        * @namespace
+        * @memberof Prism
+        */
        util: {
-               encode: function (tokens) {
+               encode: function encode(tokens) {
                        if (tokens instanceof Token) {
-                               return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
+                               return new Token(tokens.type, encode(tokens.content), tokens.alias);
                        } else if (Array.isArray(tokens)) {
-                               return tokens.map(_.util.encode);
+                               return tokens.map(encode);
                        } else {
                                return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
                        }
                },
 
+               /**
+                * Returns the name of the type of the given value.
+                *
+                * @param {any} o
+                * @returns {string}
+                * @example
+                * type(null)      === 'Null'
+                * type(undefined) === 'Undefined'
+                * type(123)       === 'Number'
+                * type('foo')     === 'String'
+                * type(true)      === 'Boolean'
+                * type([1, 2])    === 'Array'
+                * type({})        === 'Object'
+                * type(String)    === 'Function'
+                * type(/abc+/)    === 'RegExp'
+                */
                type: function (o) {
                        return Object.prototype.toString.call(o).slice(8, -1);
                },
 
+               /**
+                * Returns a unique number for the given object. Later calls will still return the same number.
+                *
+                * @param {Object} obj
+                * @returns {number}
+                */
                objId: function (obj) {
                        if (!obj['__id']) {
                                Object.defineProperty(obj, '__id', { value: ++uniqueId });
@@ -43,18 +106,27 @@ var _ = {
                        return obj['__id'];
                },
 
-               // Deep clone a language definition (e.g. to extend it)
+               /**
+                * Creates a deep clone of the given object.
+                *
+                * The main intended use of this function is to clone language definitions.
+                *
+                * @param {T} o
+                * @param {Record<number, any>} [visited]
+                * @returns {T}
+                * @template T
+                */
                clone: function deepClone(o, visited) {
-                       var clone, id, type = _.util.type(o);
                        visited = visited || {};
 
-                       switch (type) {
+                       var clone, id;
+                       switch (_.util.type(o)) {
                                case 'Object':
                                        id = _.util.objId(o);
                                        if (visited[id]) {
                                                return visited[id];
                                        }
-                                       clone = {};
+                                       clone = /** @type {Record<string, any>} */ ({});
                                        visited[id] = clone;
 
                                        for (var key in o) {
@@ -63,7 +135,7 @@ var _ = {
                                                }
                                        }
 
-                                       return clone;
+                                       return /** @type {any} */ (clone);
 
                                case 'Array':
                                        id = _.util.objId(o);
@@ -73,19 +145,149 @@ var _ = {
                                        clone = [];
                                        visited[id] = clone;
 
-                                       o.forEach(function (v, i) {
+                                       (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
                                                clone[i] = deepClone(v, visited);
                                        });
 
-                                       return clone;
+                                       return /** @type {any} */ (clone);
 
                                default:
                                        return o;
                        }
+               },
+
+               /**
+                * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
+                *
+                * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
+                *
+                * @param {Element} element
+                * @returns {string}
+                */
+               getLanguage: function (element) {
+                       while (element && !lang.test(element.className)) {
+                               element = element.parentElement;
+                       }
+                       if (element) {
+                               return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
+                       }
+                       return 'none';
+               },
+
+               /**
+                * Returns the script element that is currently executing.
+                *
+                * This does __not__ work for line script element.
+                *
+                * @returns {HTMLScriptElement | null}
+                */
+               currentScript: function () {
+                       if (typeof document === 'undefined') {
+                               return null;
+                       }
+                       if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) {
+                               return /** @type {any} */ (document.currentScript);
+                       }
+
+                       // IE11 workaround
+                       // we'll get the src of the current script by parsing IE11's error stack trace
+                       // this will not work for inline scripts
+
+                       try {
+                               throw new Error();
+                       } catch (err) {
+                               // Get file src url from stack. Specifically works with the format of stack traces in IE.
+                               // A stack will look like this:
+                               //
+                               // Error
+                               //    at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
+                               //    at Global code (http://localhost/components/prism-core.js:606:1)
+
+                               var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
+                               if (src) {
+                                       var scripts = document.getElementsByTagName('script');
+                                       for (var i in scripts) {
+                                               if (scripts[i].src == src) {
+                                                       return scripts[i];
+                                               }
+                                       }
+                               }
+                               return null;
+                       }
+               },
+
+               /**
+                * Returns whether a given class is active for `element`.
+                *
+                * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
+                * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
+                * given class is just the given class with a `no-` prefix.
+                *
+                * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
+                * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
+                * ancestors have the given class or the negated version of it, then the default activation will be returned.
+                *
+                * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
+                * version of it, the class is considered active.
+                *
+                * @param {Element} element
+                * @param {string} className
+                * @param {boolean} [defaultActivation=false]
+                * @returns {boolean}
+                */
+               isActive: function (element, className, defaultActivation) {
+                       var no = 'no-' + className;
+
+                       while (element) {
+                               var classList = element.classList;
+                               if (classList.contains(className)) {
+                                       return true;
+                               }
+                               if (classList.contains(no)) {
+                                       return false;
+                               }
+                               element = element.parentElement;
+                       }
+                       return !!defaultActivation;
                }
        },
 
+       /**
+        * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
+        *
+        * @namespace
+        * @memberof Prism
+        * @public
+        */
        languages: {
+               /**
+                * Creates a deep copy of the language with the given id and appends the given tokens.
+                *
+                * If a token in `redef` also appears in the copied language, then the existing token in the copied language
+                * will be overwritten at its original position.
+                *
+                * ## Best practices
+                *
+                * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
+                * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
+                * understand the language definition because, normally, the order of tokens matters in Prism grammars.
+                *
+                * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
+                * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
+                *
+                * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
+                * @param {Grammar} redef The new tokens to append.
+                * @returns {Grammar} The new language created.
+                * @public
+                * @example
+                * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
+                *     // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
+                *     // at its original position
+                *     'comment': { ... },
+                *     // CSS doesn't have a 'color' token, so this token will be appended
+                *     'color': /\b(?:red|green|blue)\b/
+                * });
+                */
                extend: function (id, redef) {
                        var lang = _.util.clone(_.languages[id]);
 
@@ -97,17 +299,84 @@ var _ = {
                },
 
                /**
-                * Insert a token before another token in a language literal
-                * As this needs to recreate the object (we cannot actually insert before keys in object literals),
-                * we cannot just provide an object, we need an object and a key.
-                * @param inside The key (or language id) of the parent
-                * @param before The key to insert before.
-                * @param insert Object with the key/value pairs to insert
-                * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
+                * Inserts tokens _before_ another token in a language definition or any other grammar.
+                *
+                * ## Usage
+                *
+                * This helper method makes it easy to modify existing languages. For example, the CSS language definition
+                * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
+                * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
+                * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
+                * this:
+                *
+                * ```js
+                * Prism.languages.markup.style = {
+                *     // token
+                * };
+                * ```
+                *
+                * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
+                * before existing tokens. For the CSS example above, you would use it like this:
+                *
+                * ```js
+                * Prism.languages.insertBefore('markup', 'cdata', {
+                *     'style': {
+                *         // token
+                *     }
+                * });
+                * ```
+                *
+                * ## Special cases
+                *
+                * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
+                * will be ignored.
+                *
+                * This behavior can be used to insert tokens after `before`:
+                *
+                * ```js
+                * Prism.languages.insertBefore('markup', 'comment', {
+                *     'comment': Prism.languages.markup.comment,
+                *     // tokens after 'comment'
+                * });
+                * ```
+                *
+                * ## Limitations
+                *
+                * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
+                * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
+                * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
+                * deleting properties which is necessary to insert at arbitrary positions.
+                *
+                * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
+                * Instead, it will create a new object and replace all references to the target object with the new one. This
+                * can be done without temporarily deleting properties, so the iteration order is well-defined.
+                *
+                * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
+                * you hold the target object in a variable, then the value of the variable will not change.
+                *
+                * ```js
+                * var oldMarkup = Prism.languages.markup;
+                * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
+                *
+                * assert(oldMarkup !== Prism.languages.markup);
+                * assert(newMarkup === Prism.languages.markup);
+                * ```
+                *
+                * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
+                * object to be modified.
+                * @param {string} before The key to insert before.
+                * @param {Grammar} insert An object containing the key-value pairs to be inserted.
+                * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
+                * object to be modified.
+                *
+                * Defaults to `Prism.languages`.
+                * @returns {Grammar} The new grammar object.
+                * @public
                 */
                insertBefore: function (inside, before, insert, root) {
-                       root = root || _.languages;
+                       root = root || /** @type {any} */ (_.languages);
                        var grammar = root[inside];
+                       /** @type {Grammar} */
                        var ret = {};
 
                        for (var token in grammar) {
@@ -166,50 +435,94 @@ var _ = {
                        }
                }
        },
+
        plugins: {},
 
+       /**
+        * This is the most high-level function in Prism’s API.
+        * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
+        * each one of them.
+        *
+        * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
+        *
+        * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
+        * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
+        * @memberof Prism
+        * @public
+        */
        highlightAll: function(async, callback) {
                _.highlightAllUnder(document, async, callback);
        },
 
+       /**
+        * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
+        * {@link Prism.highlightElement} on each one of them.
+        *
+        * The following hooks will be run:
+        * 1. `before-highlightall`
+        * 2. All hooks of {@link Prism.highlightElement} for each element.
+        *
+        * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
+        * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
+        * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
+        * @memberof Prism
+        * @public
+        */
        highlightAllUnder: function(container, async, callback) {
                var env = {
                        callback: callback,
+                       container: container,
                        selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
                };
 
-               _.hooks.run("before-highlightall", env);
+               _.hooks.run('before-highlightall', env);
+
+               env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
 
-               var elements = env.elements || container.querySelectorAll(env.selector);
+               _.hooks.run('before-all-elements-highlight', env);
 
-               for (var i=0, element; element = elements[i++];) {
+               for (var i = 0, element; element = env.elements[i++];) {
                        _.highlightElement(element, async === true, env.callback);
                }
        },
 
+       /**
+        * Highlights the code inside a single element.
+        *
+        * The following hooks will be run:
+        * 1. `before-sanity-check`
+        * 2. `before-highlight`
+        * 3. All hooks of {@link Prism.highlight}. These hooks will only be run by the current worker if `async` is `true`.
+        * 4. `before-insert`
+        * 5. `after-highlight`
+        * 6. `complete`
+        *
+        * @param {Element} element The element containing the code.
+        * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
+        * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
+        * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
+        * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
+        *
+        * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
+        * asynchronous highlighting to work. You can build your own bundle on the
+        * [Download page](https://prismjs.com/download.html).
+        * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
+        * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
+        * @memberof Prism
+        * @public
+        */
        highlightElement: function(element, async, callback) {
                // Find language
-               var language = 'none', grammar, parent = element;
-
-               while (parent && !lang.test(parent.className)) {
-                       parent = parent.parentNode;
-               }
-
-               if (parent) {
-                       language = (parent.className.match(lang) || [,'none'])[1].toLowerCase();
-                       grammar = _.languages[language];
-               }
+               var language = _.util.getLanguage(element);
+               var grammar = _.languages[language];
 
                // Set language on the element, if not present
                element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
 
-               if (element.parentNode) {
-                       // Set language on the parent, for styling
-                       parent = element.parentNode;
-
-                       if (/pre/i.test(parent.nodeName)) {
-                               parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
-                       }
+               // Set language on the parent, for styling
+               var parent = element.parentElement;
+               if (parent && parent.nodeName.toLowerCase() === 'pre') {
+                       parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
                }
 
                var code = element.textContent;
@@ -221,7 +534,7 @@ var _ = {
                        code: code
                };
 
-               var insertHighlightedCode = function (highlightedCode) {
+               function insertHighlightedCode(highlightedCode) {
                        env.highlightedCode = highlightedCode;
 
                        _.hooks.run('before-insert', env);
@@ -237,6 +550,7 @@ var _ = {
 
                if (!env.code) {
                        _.hooks.run('complete', env);
+                       callback && callback.call(env.element);
                        return;
                }
 
@@ -265,6 +579,26 @@ var _ = {
                }
        },
 
+       /**
+        * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
+        * and the language definitions to use, and returns a string with the HTML produced.
+        *
+        * The following hooks will be run:
+        * 1. `before-tokenize`
+        * 2. `after-tokenize`
+        * 3. `wrap`: On each {@link Token}.
+        *
+        * @param {string} text A string with the code to be highlighted.
+        * @param {Grammar} grammar An object containing the tokens to use.
+        *
+        * Usually a language definition like `Prism.languages.markup`.
+        * @param {string} language The name of the language definition passed to `grammar`.
+        * @returns {string} The highlighted HTML.
+        * @memberof Prism
+        * @public
+        * @example
+        * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
+        */
        highlight: function (text, grammar, language) {
                var env = {
                        code: text,
@@ -277,137 +611,32 @@ var _ = {
                return Token.stringify(_.util.encode(env.tokens), env.language);
        },
 
-       matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
-               for (var token in grammar) {
-                       if(!grammar.hasOwnProperty(token) || !grammar[token]) {
-                               continue;
-                       }
-
-                       if (token == target) {
-                               return;
-                       }
-
-                       var patterns = grammar[token];
-                       patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
-
-                       for (var j = 0; j < patterns.length; ++j) {
-                               var pattern = patterns[j],
-                                       inside = pattern.inside,
-                                       lookbehind = !!pattern.lookbehind,
-                                       greedy = !!pattern.greedy,
-                                       lookbehindLength = 0,
-                                       alias = pattern.alias;
-
-                               if (greedy && !pattern.pattern.global) {
-                                       // Without the global flag, lastIndex won't work
-                                       var flags = pattern.pattern.toString().match(/[imuy]*$/)[0];
-                                       pattern.pattern = RegExp(pattern.pattern.source, flags + "g");
-                               }
-
-                               pattern = pattern.pattern || pattern;
-
-                               // Don’t cache length as it changes during the loop
-                               for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {
-
-                                       var str = strarr[i];
-
-                                       if (strarr.length > text.length) {
-                                               // Something went terribly wrong, ABORT, ABORT!
-                                               return;
-                                       }
-
-                                       if (str instanceof Token) {
-                                               continue;
-                                       }
-
-                                       if (greedy && i != strarr.length - 1) {
-                                               pattern.lastIndex = pos;
-                                               var match = pattern.exec(text);
-                                               if (!match) {
-                                                       break;
-                                               }
-
-                                               var from = match.index + (lookbehind ? match[1].length : 0),
-                                                   to = match.index + match[0].length,
-                                                   k = i,
-                                                   p = pos;
-
-                                               for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
-                                                       p += strarr[k].length;
-                                                       // Move the index i to the element in strarr that is closest to from
-                                                       if (from >= p) {
-                                                               ++i;
-                                                               pos = p;
-                                                       }
-                                               }
-
-                                               // If strarr[i] is a Token, then the match starts inside another Token, which is invalid
-                                               if (strarr[i] instanceof Token) {
-                                                       continue;
-                                               }
-
-                                               // Number of tokens to delete and replace with the new match
-                                               delNum = k - i;
-                                               str = text.slice(pos, p);
-                                               match.index -= pos;
-                                       } else {
-                                               pattern.lastIndex = 0;
-
-                                               var match = pattern.exec(str),
-                                                       delNum = 1;
-                                       }
-
-                                       if (!match) {
-                                               if (oneshot) {
-                                                       break;
-                                               }
-
-                                               continue;
-                                       }
-
-                                       if(lookbehind) {
-                                               lookbehindLength = match[1] ? match[1].length : 0;
-                                       }
-
-                                       var from = match.index + lookbehindLength,
-                                           match = match[0].slice(lookbehindLength),
-                                           to = from + match.length,
-                                           before = str.slice(0, from),
-                                           after = str.slice(to);
-
-                                       var args = [i, delNum];
-
-                                       if (before) {
-                                               ++i;
-                                               pos += before.length;
-                                               args.push(before);
-                                       }
-
-                                       var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy);
-
-                                       args.push(wrapped);
-
-                                       if (after) {
-                                               args.push(after);
-                                       }
-
-                                       Array.prototype.splice.apply(strarr, args);
-
-                                       if (delNum != 1)
-                                               _.matchGrammar(text, strarr, grammar, i, pos, true, token);
-
-                                       if (oneshot)
-                                               break;
-                               }
-                       }
-               }
-       },
-
+       /**
+        * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
+        * and the language definitions to use, and returns an array with the tokenized code.
+        *
+        * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
+        *
+        * This method could be useful in other contexts as well, as a very crude parser.
+        *
+        * @param {string} text A string with the code to be highlighted.
+        * @param {Grammar} grammar An object containing the tokens to use.
+        *
+        * Usually a language definition like `Prism.languages.markup`.
+        * @returns {TokenStream} An array of strings and tokens, a token stream.
+        * @memberof Prism
+        * @public
+        * @example
+        * let code = `var foo = 0;`;
+        * let tokens = Prism.tokenize(code, Prism.languages.javascript);
+        * tokens.forEach(token => {
+        *     if (token instanceof Prism.Token && token.type === 'number') {
+        *         console.log(`Found numeric literal: ${token.content}`);
+        *     }
+        * });
+        */
        tokenize: function(text, grammar) {
-               var strarr = [text];
-
                var rest = grammar.rest;
-
                if (rest) {
                        for (var token in rest) {
                                grammar[token] = rest[token];
@@ -416,14 +645,34 @@ var _ = {
                        delete grammar.rest;
                }
 
-               _.matchGrammar(text, strarr, grammar, 0, 0, false);
+               var tokenList = new LinkedList();
+               addAfter(tokenList, tokenList.head, text);
+
+               matchGrammar(text, tokenList, grammar, tokenList.head, 0);
 
-               return strarr;
+               return toArray(tokenList);
        },
 
+       /**
+        * @namespace
+        * @memberof Prism
+        * @public
+        */
        hooks: {
                all: {},
 
+               /**
+                * Adds the given callback to the list of callbacks for the given hook.
+                *
+                * The callback will be invoked when the hook it is registered for is run.
+                * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
+                *
+                * One callback function can be registered to multiple hooks and the same hook multiple times.
+                *
+                * @param {string} name The name of the hook.
+                * @param {HookCallback} callback The callback function which is given environment variables.
+                * @public
+                */
                add: function (name, callback) {
                        var hooks = _.hooks.all;
 
@@ -432,6 +681,15 @@ var _ = {
                        hooks[name].push(callback);
                },
 
+               /**
+                * Runs a hook invoking all registered callbacks with the given environment variables.
+                *
+                * Callbacks will be invoked synchronously and in the order in which they were registered.
+                *
+                * @param {string} name The name of the hook.
+                * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
+                * @public
+                */
                run: function (name, env) {
                        var callbacks = _.hooks.all[name];
 
@@ -447,52 +705,364 @@ var _ = {
 
        Token: Token
 };
-
 _self.Prism = _;
 
-function Token(type, content, alias, matchedStr, greedy) {
+
+// Typescript note:
+// The following can be used to import the Token type in JSDoc:
+//
+//   @typedef {InstanceType<import("./prism-core")["Token"]>} Token
+
+/**
+ * Creates a new token.
+ *
+ * @param {string} type See {@link Token#type type}
+ * @param {string | TokenStream} content See {@link Token#content content}
+ * @param {string|string[]} [alias] The alias(es) of the token.
+ * @param {string} [matchedStr=""] A copy of the full string this token was created from.
+ * @class
+ * @global
+ * @public
+ */
+function Token(type, content, alias, matchedStr) {
+       /**
+        * The type of the token.
+        *
+        * This is usually the key of a pattern in a {@link Grammar}.
+        *
+        * @type {string}
+        * @see GrammarToken
+        * @public
+        */
        this.type = type;
+       /**
+        * The strings or tokens contained by this token.
+        *
+        * This will be a token stream if the pattern matched also defined an `inside` grammar.
+        *
+        * @type {string | TokenStream}
+        * @public
+        */
        this.content = content;
+       /**
+        * The alias(es) of the token.
+        *
+        * @type {string|string[]}
+        * @see GrammarToken
+        * @public
+        */
        this.alias = alias;
        // Copy of the full string this token was created from
-       this.length = (matchedStr || "").length|0;
-       this.greedy = !!greedy;
+       this.length = (matchedStr || '').length | 0;
 }
 
-Token.stringify = function(o, language) {
+/**
+ * A token stream is an array of strings and {@link Token Token} objects.
+ *
+ * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
+ * them.
+ *
+ * 1. No adjacent strings.
+ * 2. No empty strings.
+ *
+ *    The only exception here is the token stream that only contains the empty string and nothing else.
+ *
+ * @typedef {Array<string | Token>} TokenStream
+ * @global
+ * @public
+ */
+
+/**
+ * Converts the given token or token stream to an HTML representation.
+ *
+ * The following hooks will be run:
+ * 1. `wrap`: On each {@link Token}.
+ *
+ * @param {string | Token | TokenStream} o The token or token stream to be converted.
+ * @param {string} language The name of current language.
+ * @returns {string} The HTML representation of the token or token stream.
+ * @memberof Token
+ * @static
+ */
+Token.stringify = function stringify(o, language) {
        if (typeof o == 'string') {
                return o;
        }
-
        if (Array.isArray(o)) {
-               return o.map(function(element) {
-                       return Token.stringify(element, language);
-               }).join('');
+               var s = '';
+               o.forEach(function (e) {
+                       s += stringify(e, language);
+               });
+               return s;
        }
 
        var env = {
                type: o.type,
-               content: Token.stringify(o.content, language),
+               content: stringify(o.content, language),
                tag: 'span',
                classes: ['token', o.type],
                attributes: {},
                language: language
        };
 
-       if (o.alias) {
-               var aliases = Array.isArray(o.alias) ? o.alias : [o.alias];
-               Array.prototype.push.apply(env.classes, aliases);
+       var aliases = o.alias;
+       if (aliases) {
+               if (Array.isArray(aliases)) {
+                       Array.prototype.push.apply(env.classes, aliases);
+               } else {
+                       env.classes.push(aliases);
+               }
        }
 
        _.hooks.run('wrap', env);
 
-       var attributes = Object.keys(env.attributes).map(function(name) {
-               return name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
-       }).join(' ');
+       var attributes = '';
+       for (var name in env.attributes) {
+               attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
+       }
 
-       return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + '</' + env.tag + '>';
+       return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
 };
 
+/**
+ * @param {string} text
+ * @param {LinkedList<string | Token>} tokenList
+ * @param {any} grammar
+ * @param {LinkedListNode<string | Token>} startNode
+ * @param {number} startPos
+ * @param {RematchOptions} [rematch]
+ * @returns {void}
+ * @private
+ *
+ * @typedef RematchOptions
+ * @property {string} cause
+ * @property {number} reach
+ */
+function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
+       for (var token in grammar) {
+               if (!grammar.hasOwnProperty(token) || !grammar[token]) {
+                       continue;
+               }
+
+               var patterns = grammar[token];
+               patterns = Array.isArray(patterns) ? patterns : [patterns];
+
+               for (var j = 0; j < patterns.length; ++j) {
+                       if (rematch && rematch.cause == token + ',' + j) {
+                               return;
+                       }
+
+                       var patternObj = patterns[j],
+                               inside = patternObj.inside,
+                               lookbehind = !!patternObj.lookbehind,
+                               greedy = !!patternObj.greedy,
+                               lookbehindLength = 0,
+                               alias = patternObj.alias;
+
+                       if (greedy && !patternObj.pattern.global) {
+                               // Without the global flag, lastIndex won't work
+                               var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
+                               patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
+                       }
+
+                       /** @type {RegExp} */
+                       var pattern = patternObj.pattern || patternObj;
+
+                       for ( // iterate the token list and keep track of the current token/string position
+                               var currentNode = startNode.next, pos = startPos;
+                               currentNode !== tokenList.tail;
+                               pos += currentNode.value.length, currentNode = currentNode.next
+                       ) {
+
+                               if (rematch && pos >= rematch.reach) {
+                                       break;
+                               }
+
+                               var str = currentNode.value;
+
+                               if (tokenList.length > text.length) {
+                                       // Something went terribly wrong, ABORT, ABORT!
+                                       return;
+                               }
+
+                               if (str instanceof Token) {
+                                       continue;
+                               }
+
+                               var removeCount = 1; // this is the to parameter of removeBetween
+
+                               if (greedy && currentNode != tokenList.tail.prev) {
+                                       pattern.lastIndex = pos;
+                                       var match = pattern.exec(text);
+                                       if (!match) {
+                                               break;
+                                       }
+
+                                       var from = match.index + (lookbehind && match[1] ? match[1].length : 0);
+                                       var to = match.index + match[0].length;
+                                       var p = pos;
+
+                                       // find the node that contains the match
+                                       p += currentNode.value.length;
+                                       while (from >= p) {
+                                               currentNode = currentNode.next;
+                                               p += currentNode.value.length;
+                                       }
+                                       // adjust pos (and p)
+                                       p -= currentNode.value.length;
+                                       pos = p;
+
+                                       // the current node is a Token, then the match starts inside another Token, which is invalid
+                                       if (currentNode.value instanceof Token) {
+                                               continue;
+                                       }
+
+                                       // find the last node which is affected by this match
+                                       for (
+                                               var k = currentNode;
+                                               k !== tokenList.tail && (p < to || typeof k.value === 'string');
+                                               k = k.next
+                                       ) {
+                                               removeCount++;
+                                               p += k.value.length;
+                                       }
+                                       removeCount--;
+
+                                       // replace with the new match
+                                       str = text.slice(pos, p);
+                                       match.index -= pos;
+                               } else {
+                                       pattern.lastIndex = 0;
+
+                                       var match = pattern.exec(str);
+                               }
+
+                               if (!match) {
+                                       continue;
+                               }
+
+                               if (lookbehind) {
+                                       lookbehindLength = match[1] ? match[1].length : 0;
+                               }
+
+                               var from = match.index + lookbehindLength,
+                                       matchStr = match[0].slice(lookbehindLength),
+                                       to = from + matchStr.length,
+                                       before = str.slice(0, from),
+                                       after = str.slice(to);
+
+                               var reach = pos + str.length;
+                               if (rematch && reach > rematch.reach) {
+                                       rematch.reach = reach;
+                               }
+
+                               var removeFrom = currentNode.prev;
+
+                               if (before) {
+                                       removeFrom = addAfter(tokenList, removeFrom, before);
+                                       pos += before.length;
+                               }
+
+                               removeRange(tokenList, removeFrom, removeCount);
+
+                               var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
+                               currentNode = addAfter(tokenList, removeFrom, wrapped);
+
+                               if (after) {
+                                       addAfter(tokenList, currentNode, after);
+                               }
+
+                               if (removeCount > 1) {
+                                       // at least one Token object was removed, so we have to do some rematching
+                                       // this can only happen if the current pattern is greedy
+                                       matchGrammar(text, tokenList, grammar, currentNode.prev, pos, {
+                                               cause: token + ',' + j,
+                                               reach: reach
+                                       });
+                               }
+                       }
+               }
+       }
+}
+
+/**
+ * @typedef LinkedListNode
+ * @property {T} value
+ * @property {LinkedListNode<T> | null} prev The previous node.
+ * @property {LinkedListNode<T> | null} next The next node.
+ * @template T
+ * @private
+ */
+
+/**
+ * @template T
+ * @private
+ */
+function LinkedList() {
+       /** @type {LinkedListNode<T>} */
+       var head = { value: null, prev: null, next: null };
+       /** @type {LinkedListNode<T>} */
+       var tail = { value: null, prev: head, next: null };
+       head.next = tail;
+
+       /** @type {LinkedListNode<T>} */
+       this.head = head;
+       /** @type {LinkedListNode<T>} */
+       this.tail = tail;
+       this.length = 0;
+}
+
+/**
+ * Adds a new node with the given value to the list.
+ * @param {LinkedList<T>} list
+ * @param {LinkedListNode<T>} node
+ * @param {T} value
+ * @returns {LinkedListNode<T>} The added node.
+ * @template T
+ */
+function addAfter(list, node, value) {
+       // assumes that node != list.tail && values.length >= 0
+       var next = node.next;
+
+       var newNode = { value: value, prev: node, next: next };
+       node.next = newNode;
+       next.prev = newNode;
+       list.length++;
+
+       return newNode;
+}
+/**
+ * Removes `count` nodes after the given node. The given node will not be removed.
+ * @param {LinkedList<T>} list
+ * @param {LinkedListNode<T>} node
+ * @param {number} count
+ * @template T
+ */
+function removeRange(list, node, count) {
+       var next = node.next;
+       for (var i = 0; i < count && next !== list.tail; i++) {
+               next = next.next;
+       }
+       node.next = next;
+       next.prev = node;
+       list.length -= i;
+}
+/**
+ * @param {LinkedList<T>} list
+ * @returns {T[]}
+ * @template T
+ */
+function toArray(list) {
+       var array = [];
+       var node = list.head.next;
+       while (node !== list.tail) {
+               array.push(node.value);
+               node = node.next;
+       }
+       return array;
+}
+
+
 if (!_self.document) {
        if (!_self.addEventListener) {
                // in Node.js
@@ -517,31 +1087,39 @@ if (!_self.document) {
        return _;
 }
 
-//Get current script and highlight
-var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
+// Get current script and highlight
+var script = _.util.currentScript();
 
 if (script) {
        _.filename = script.src;
 
-       if (!_.manual && !script.hasAttribute('data-manual')) {
-               // WoltLab Start
-               _.highlightAutomaticallyCallback = function () {
-                       if (!_.manual) {
-                               _.highlightAll();
-                       }
-               }
+       if (script.hasAttribute('data-manual')) {
+               _.manual = true;
+       }
+}
 
-               if(document.readyState !== "loading") {
-                       if (window.requestAnimationFrame) {
-                               window.requestAnimationFrame(_.highlightAutomaticallyCallback);
-                       } else {
-                               window.setTimeout(_.highlightAutomaticallyCallback, 16);
-                       }
-               }
-               else {
-                       document.addEventListener('DOMContentLoaded', _.highlightAutomaticallyCallback);
+function highlightAutomaticallyCallback() {
+       if (!_.manual) {
+               _.highlightAll();
+       }
+}
+
+if (!_.manual) {
+       // If the document state is "loading", then we'll use DOMContentLoaded.
+       // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
+       // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
+       // might take longer one animation frame to execute which can create a race condition where only some plugins have
+       // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
+       // See https://github.com/PrismJS/prism/issues/2102
+       var readyState = document.readyState;
+       if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
+               document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
+       } else {
+               if (window.requestAnimationFrame) {
+                       window.requestAnimationFrame(highlightAutomaticallyCallback);
+               } else {
+                       window.setTimeout(highlightAutomaticallyCallback, 16);
                }
-               // WoltLab End
        }
 }
 
@@ -557,3 +1135,52 @@ if (typeof module !== 'undefined' && module.exports) {
 if (typeof global !== 'undefined') {
        global.Prism = Prism;
 }
+
+// some additional documentation/types
+
+/**
+ * The expansion of a simple `RegExp` literal to support additional properties.
+ *
+ * @typedef GrammarToken
+ * @property {RegExp} pattern The regular expression of the token.
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
+ * @property {boolean} [greedy=false] Whether the token is greedy.
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
+ * @property {Grammar} [inside] The nested grammar of this token.
+ *
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
+ *
+ * This can be used to make nested and even recursive language definitions.
+ *
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
+ * each another.
+ * @global
+ * @public
+*/
+
+/**
+ * @typedef Grammar
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
+ * @global
+ * @public
+ */
+
+/**
+ * A function which will invoked after an element was successfully highlighted.
+ *
+ * @callback HighlightCallback
+ * @param {Element} element The element successfully highlighted.
+ * @returns {void}
+ * @global
+ * @public
+*/
+
+/**
+ * @callback HookCallback
+ * @param {Object<string, any>} env The environment variables of the hook.
+ * @returns {void}
+ * @global
+ * @public
+ */
index 3ab169d94be4fa927b28a9fb67bd5d2ff2c4f2b8..15cba9f2f6283d7ac6190f4746ee144f99d88d72 100644 (file)
@@ -83,6 +83,13 @@ $.Redactor.prototype.WoltLabButton = function() {
                                }
                        }
                        
+                       // If both the "Code" and "Inline Code" button exist, then place them next to each other.
+                       var inlineCodeButtonIndex = this.opts.buttons.indexOf('tt');
+                       if (this.opts.buttons.indexOf('code') !== -1 && inlineCodeButtonIndex !== -1) {
+                               this.opts.buttons.splice(inlineCodeButtonIndex, 1);
+                               this.opts.buttons.splice(this.opts.buttons.indexOf('code') + 1, 0, 'tt');
+                       }
+                       
                        // enforce button order as provided with `opts.buttons`
                        var listItem, toolbarButtons = {}, toolbarOrder = [];
                        while (toolbar.childElementCount) {
index 24fe65fabe2f296dca74e57629c8128bde23aca1..ad68c7eebdfd5a06fb5c5d0c7cfd990835dc25fe 100644 (file)
@@ -482,14 +482,18 @@ $.Redactor.prototype.WoltLabCaret = function() {
                
                _handleEditorClick: function (event) {
                        var clientY = event.clientY;
+
+                       // Treat this as a collapsed selection instead, because the iOS Safari
+                       // breaks event delegation and refuses to trigger click-style events
+                       // for non-link/non-input elements. Thanks Apple.
+                       var isIosTouch = _iOS && _touchstartTarget === event.target && this.utils.isBlockTag(_touchstartTarget.nodeName);
+                       
+                       if (clientY === undefined && isIosTouch) {
+                               clientY = event.changedTouches[0].clientY;
+                       }
+                       
                        if (!this.selection.get().isCollapsed) {
-                               if (_isSafari && _iOS && _touchstartTarget === event.target && this.utils.isBlockTag(_touchstartTarget.nodeName)) {
-                                       // Treat this as a collapsed selection instead, because the iOS Safari
-                                       // breaks event delegation and refuses to trigger click-style events
-                                       // for non-link/non-input elements. Thanks Apple.
-                                       clientY = event.changedTouches[0].clientY;
-                               }
-                               else {
+                               if (!isIosTouch || clientY === undefined) {
                                        // ignore text selection
                                        return;
                                }
index beebe1dec7dfe1291df3d8681bd37d0747483440..79dc16c81574437bfdc9aaf19039fd8559884d9b 100644 (file)
@@ -351,7 +351,7 @@ $.Redactor.prototype.WoltLabPaste = function() {
                                if (!data.pre && !data.text) {
                                        elBySelAll('img', div, (function(img) {
                                                var src = img.src;
-                                               if (src.indexOf('data:image') === 0 && src !== transparentGif) {
+                                               if ((src.indexOf('data:image') === 0 || src.indexOf("blob:") === 0) && src !== transparentGif) {
                                                        img.src = transparentGif;
                                                        
                                                        var uuid = WCF.getUUID();
@@ -397,10 +397,24 @@ $.Redactor.prototype.WoltLabPaste = function() {
                                                                        img.parentNode.removeChild(img);
                                                                }
                                                                else {
-                                                                       WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this.$element[0].id, {
-                                                                               blob: this.utils.dataURItoBlob(imgData.src),
-                                                                               replace: img
-                                                                       });
+                                                                       if (imgData.src.indexOf("blob:") === 0) {
+                                                                               window.fetch(imgData.src)
+                                                                                       .then(function (response) {
+                                                                                               return response.blob();
+                                                                                       })
+                                                                                       .then((function (blob) {
+                                                                                               WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this.$element[0].id, {
+                                                                                                       blob: blob,
+                                                                                                       replace: img
+                                                                                               });
+                                                                                       }).bind(this));
+                                                                       }
+                                                                       else {
+                                                                               WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'pasteFromClipboard_' + this.$element[0].id, {
+                                                                                       blob: this.utils.dataURItoBlob(imgData.src),
+                                                                                       replace: img
+                                                                               });
+                                                                       }
                                                                }
                                                        }
                                                }
index 62a6815fb7d781d3d0e30080270763cebe776490..d24ac697d2db752b770e154c862e2e44a734dfb8 100644 (file)
@@ -29,11 +29,29 @@ $.Redactor.prototype.WoltLabSmiley = function() {
                        smiley = elById(id);
                        smiley.removeAttribute('id');
                        
-                       // Safari does not properly update the caret position on insert
-                       this.caret.after(smiley);
+                       // Check if there is a zero-width whitespace after the smiley, Safari does
+                       // not like them that much (caret will be placed inside a character).
+                       var nextSibling = smiley.nextSibling;
+                       if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE && nextSibling.textContent === "\u200B") {
+                               nextSibling.remove();
+                       }
+                       
+                       smiley.parentNode.insertBefore(document.createTextNode(" "), smiley);
+                       
+                       var whitespace = document.createTextNode(" ");
+                       smiley.parentNode.insertBefore(whitespace, smiley.nextSibling);
                        
+                       // Replace the image with itself to forcefully invalidate any references.
                        //noinspection SillyAssignmentJS
                        smiley.outerHTML = smiley.outerHTML;
+
+                       var selection = window.getSelection();
+                       var range = document.createRange();
+                       range.selectNode(whitespace);
+                       range.collapse(false);
+
+                       selection.removeAllRanges();
+                       selection.addRange(range);
                        
                        // force-save the caret position
                        this.WoltLabCaret.forceSelectionSave();
index 9b07098964945629aa1e97d5d14ef96b25388c6f..eab7d7ba3dc1383206f09fa005c3d7c79f54f7da 100644 (file)
@@ -109,11 +109,45 @@ $.Redactor.prototype.WoltLabSource = function() {
                        }).bind(this);
                        
                        WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'validate_' + id, (function (data) {
-                               if (textarea.clientHeight) {
+                               if (this.WoltLabSource.isActive()) {
                                        data.api.throwError(this.$element[0], WCF.Language.get('wcf.editor.source.error.active'));
                                        data.valid = false;
                                }
                        }).bind(this));
+
+                       var box = this.core.box()[0];
+                       var form = box.closest("form");
+                       if (form) {
+                               var dl = box.closest("dl");
+
+                               form.addEventListener("submit", (function (event) {
+                                       var message = '';
+                                       if (this.WoltLabSource.isActive()) {
+                                               event.preventDefault();
+
+                                               message = WCF.Language.get('wcf.editor.source.error.active');
+
+                                               // Enable the submit button again to override the FormGuard's behavior.
+                                               var submitButton = form.querySelector(".formSubmit input[type=submit]");
+                                               if (submitButton) {
+                                                       submitButton.disabled = false;
+                                               }
+
+                                               require(['WoltLabSuite/Core/Ui/TabMenu'], function(UiTabMenu) {
+                                                       UiTabMenu._selectErroneousTabs();
+                                               });
+                                       }
+
+                                       elInnerError(box, message);
+
+                                       if (message) {
+                                               dl.classList.add("formError");
+                                       }
+                                       else {
+                                               dl.classList.remove("formError");
+                                       }
+                               }).bind(this));
+                       }
                },
                
                isActive: function () {
index d8a73cf4816d1c624c00264f0943c9cb47e5305c..290c2409668169c75ebc2e14bcc150c9aafccf69 100644 (file)
 // redactor.combined.min.js -- DO NOT EDIT
 
 // redactor.js
-(function (window, undefined) { !function(t){"use strict";function e(t,i){return new e.prototype.init(t,i)}Function.prototype.bind||(Function.prototype.bind=function(t){var e=this;return function(){return e.apply(t)}});var i=0,r=null;"function"==typeof window.require&&require(["Environment"],function(t){r=t}),t.fn.redactor=function(i){var r=[],n=Array.prototype.slice.call(arguments,1);return"string"==typeof i?this.each(function(){var e,s=t.data(this,"redactor");if("-1"!==i.search(/\./)?(e=i.split("."),void 0!==s[e[0]]&&(e=s[e[0]][e[1]])):e=s[i],void 0!==s&&t.isFunction(e)){var o=e.apply(s,n);void 0!==o&&o!==s&&r.push(o)}else t.error('No such method "'+i+'" for Redactor')}):this.each(function(){t.data(this,"redactor",{}),t.data(this,"redactor",e(this,i))}),0===r.length?this:1===r.length?r[0]:r},t.Redactor=e,t.Redactor.VERSION="2.99",t.Redactor.modules=["air","autosave","block","buffer","build","button","caret","clean","code","core","detect","dropdown","events","file","focus","image","indent","inline","insert","keydown","keyup","lang","line","link","linkify","list","marker","modal","observe","offset","paragraphize","paste","placeholder","progress","selection","shortcuts","storage","toolbar","upload","uploads3","utils","browser"],t.Redactor.settings={},t.Redactor.opts={animation:!1,lang:"en",direction:"ltr",spellcheck:!0,overrideStyles:!0,stylesClass:!1,scrollTarget:document,focus:!1,focusEnd:!1,clickToEdit:!1,structure:!1,tabindex:!1,minHeight:!1,maxHeight:!1,maxWidth:!1,plugins:!1,callbacks:{},placeholder:!1,linkify:!0,enterKey:!0,pastePlainText:!1,pasteImages:!0,pasteLinks:!0,pasteBlockTags:["pre","h1","h2","h3","h4","h5","h6","table","tbody","thead","tfoot","th","tr","td","ul","ol","li","blockquote","p","figure","figcaption"],pasteInlineTags:["br","strong","ins","code","del","span","samp","kbd","sup","sub","mark","var","cite","small","b","u","em","i"],preClass:!1,preSpaces:4,tabAsSpaces:!1,tabKey:!0,autosave:!1,autosaveName:!1,autosaveFields:!1,imageUpload:null,imageUploadParam:"file",imageUploadFields:!1,imageUploadForms:!1,imageTag:"figure",imageEditable:!0,imageCaption:!0,imagePosition:!1,imageResizable:!1,imageFloatMargin:"10px",dragImageUpload:!0,multipleImageUpload:!0,clipboardImageUpload:!0,fileUpload:null,fileUploadParam:"file",fileUploadFields:!1,fileUploadForms:!1,dragFileUpload:!0,s3:!1,linkNewTab:!1,linkTooltip:!0,linkNofollow:!1,linkSize:30,linkValidation:!0,pasteLinkTarget:!1,videoContainerClass:"video-container",toolbar:!0,toolbarFixed:!0,toolbarFixedTarget:document,toolbarFixedTopOffset:0,toolbarExternal:!1,toolbarOverflow:!1,air:!1,airWidth:!1,formatting:["p","blockquote","pre","h1","h2","h3","h4","h5","h6"],formattingAdd:!1,buttons:["format","bold","italic","deleted","lists","image","file","link","horizontalrule"],buttonsTextLabeled:!1,buttonsHide:[],buttonsHideOnMobile:[],script:!0,removeNewlines:!1,removeComments:!0,replaceTags:{b:"strong",i:"em",strike:"del"},keepStyleAttr:[],keepInlineOnEnter:!1,shortcuts:{"ctrl+shift+m, meta+shift+m":{func:"inline.removeFormat"},"ctrl+b, meta+b":{func:"inline.format",params:["bold"]},"ctrl+i, meta+i":{func:"inline.format",params:["italic"]},"ctrl+h, meta+h":{func:"inline.format",params:["superscript"]},"ctrl+l, meta+l":{func:"inline.format",params:["subscript"]},"ctrl+k, meta+k":{func:"link.show"},"ctrl+shift+7":{func:"list.toggle",params:["orderedlist"]},"ctrl+shift+8":{func:"list.toggle",params:["unorderedlist"]}},shortcutsAdd:!1,activeButtons:["deleted","italic","bold"],activeButtonsStates:{b:"bold",strong:"bold",i:"italic",em:"italic",del:"deleted",strike:"deleted"},langs:{en:{format:"Format",image:"Image",file:"File",link:"Link",bold:"Bold",italic:"Italic",deleted:"Strikethrough",underline:"Underline","bold-abbr":"B","italic-abbr":"I","deleted-abbr":"S","underline-abbr":"U",lists:"Lists","link-insert":"Insert link","link-edit":"Edit link","link-in-new-tab":"Open link in new tab",unlink:"Unlink",cancel:"Cancel",close:"Close",insert:"Insert",save:"Save",delete:"Delete",text:"Text",edit:"Edit",title:"Title",paragraph:"Normal text",quote:"Quote",code:"Code",heading1:"Heading 1",heading2:"Heading 2",heading3:"Heading 3",heading4:"Heading 4",heading5:"Heading 5",heading6:"Heading 6",filename:"Name",optional:"optional",unorderedlist:"Unordered List",orderedlist:"Ordered List",outdent:"Outdent",indent:"Indent",horizontalrule:"Line","upload-label":"Drop file here or ",caption:"Caption",bulletslist:"Bullets",numberslist:"Numbers","image-position":"Position",none:"None",left:"Left",right:"Right",center:"Center","accessibility-help-label":"Rich text editor"}},type:"textarea",inline:!1,inlineTags:["a","span","strong","strike","b","u","em","i","code","del","ins","samp","kbd","sup","sub","mark","var","cite","small"],blockTags:["pre","ul","ol","li","p","h1","h2","h3","h4","h5","h6","dl","dt","dd","div","td","blockquote","output","figcaption","figure","address","section","header","footer","aside","article","iframe"],paragraphize:!0,paragraphizeBlocks:["table","div","pre","form","ul","ol","h1","h2","h3","h4","h5","h6","dl","blockquote","figcaption","address","section","header","footer","aside","article","object","style","script","iframe","select","input","textarea","button","option","map","area","math","hr","fieldset","legend","hgroup","nav","figure","details","menu","summary","p"],emptyHtml:"<p>&#x200b;</p>",invisibleSpace:"&#x200b;",emptyHtmlRendered:t("").html("​").html(),imageTypes:["image/png","image/jpeg","image/gif"],userAgent:navigator.userAgent.toLowerCase(),observe:{dropdowns:[]},regexps:{linkyoutube:/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi,linkvimeo:/https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,linkimage:/((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/gi,url:/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi}},e.fn=t.Redactor.prototype={keyCode:{BACKSPACE:8,DELETE:46,UP:38,DOWN:40,ENTER:13,SPACE:32,ESC:27,TAB:9,CTRL:17,META:91,SHIFT:16,ALT:18,RIGHT:39,LEFT:37,LEFT_WIN:91},init:function(e,r){if(this.$element=t(e),this.uuid=i++,this.sBuffer=[],this.sRebuffer=[],this.loadOptions(r),this.loadModules(),this.opts.clickToEdit&&!this.$element.hasClass("redactor-click-to-edit"))return this.loadToEdit(r);this.$element.hasClass("redactor-click-to-edit")&&this.$element.removeClass("redactor-click-to-edit"),this.reIsBlock=new RegExp("^("+this.opts.blockTags.join("|").toUpperCase()+")$","i"),this.reIsInline=new RegExp("^("+this.opts.inlineTags.join("|").toUpperCase()+")$","i"),this.opts.dragImageUpload=null!==this.opts.imageUpload&&this.opts.dragImageUpload,this.opts.dragFileUpload=null!==this.opts.fileUpload&&this.opts.dragFileUpload,this.formatting={},this.lang.load(),t.extend(this.opts.shortcuts,this.opts.shortcutsAdd),this.$editor=this.$element,this.detectType(),this.core.callback("start"),this.core.callback("startToEdit"),this.start=!0,this.build.start()},detectType:function(){this.build.isInline()||this.opts.inline?this.opts.type="inline":this.build.isTag("DIV")?this.opts.type="div":this.build.isTag("PRE")&&(this.opts.type="pre")},loadToEdit:function(e){this.$element.on("click.redactor-click-to-edit",t.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},initToEdit:function(e){t.extend(e.callbacks,{startToEdit:function(){this.insert.node(this.marker.get(),!1)},initToEdit:function(){this.selection.restore(),this.clickToCancelStorage=this.code.get(),t(this.opts.clickToCancel).off(".redactor-click-to-edit"),t(this.opts.clickToCancel).show().on("click.redactor-click-to-edit",t.proxy(function(i){i.preventDefault(),this.core.destroy(),this.events.syncFire=!1,this.$element.html(this.clickToCancelStorage),this.core.callback("cancel",this.clickToCancelStorage),this.events.syncFire=!0,this.clickToCancelStorage="",t(this.opts.clickToCancel).hide(),t(this.opts.clickToSave).hide(),this.$element.on("click.redactor-click-to-edit",t.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},this)),t(this.opts.clickToSave).off(".redactor-click-to-edit"),t(this.opts.clickToSave).show().on("click.redactor-click-to-edit",t.proxy(function(i){i.preventDefault(),this.core.destroy(),this.core.callback("save",this.code.get()),t(this.opts.clickToCancel).hide(),t(this.opts.clickToSave).hide(),this.$element.on("click.redactor-click-to-edit",t.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},this))}}),this.$element.redactor(e),this.$element.off(".redactor-click-to-edit")},loadOptions:function(e){var i={};void 0!==t.Redactor.settings.namespace?this.$element.hasClass(t.Redactor.settings.namespace)&&(i=t.Redactor.settings):i=t.Redactor.settings,this.opts=t.extend({},t.Redactor.opts,this.$element.data(),e),this.opts=t.extend({},this.opts,i)},getModuleMethods:function(t){return Object.getOwnPropertyNames(t).filter(function(e){return"function"==typeof t[e]})},loadModules:function(){for(var e=t.Redactor.modules.length,i=0;i<e;i++)this.bindModuleMethods(t.Redactor.modules[i])},bindModuleMethods:function(t){if(void 0!==this[t]){this[t]=this[t]();for(var e=this.getModuleMethods(this[t]),i=e.length,r=0;r<i;r++)this[t][e[r]]=this[t][e[r]].bind(this)}},air:function(){return{enabled:!1,collapsed:function(){},collapsedEnd:function(){},build:function(){},append:function(){},createContainer:function(){},show:function(){},bindHide:function(){},hide:function(){}}},autosave:function(){return{enabled:!1,html:!1,init:function(){},is:function(){},send:function(){},getHiddenFields:function(){},success:function(){},disable:function(){}}},block:function(){return{format:function(e,i,r,n){if(e="quote"===e?"blockquote":e,this.block.tags=["p","blockquote","pre","h1","h2","h3","h4","h5","h6","div","figure"],-1!==t.inArray(e,this.block.tags))return"p"===e&&void 0===i&&(i="class"),this.buffer.set(),this.utils.isCollapsed()?this.block.formatCollapsed(e,i,r,n):this.block.formatUncollapsed(e,i,r,n)},formatCollapsed:function(e,i,r,n){this.selection.save();var s=this.selection.block(),o=s.tagName.toLowerCase();if(-1===t.inArray(o,this.block.tags))return void this.selection.restore();var a=!1;o===e&&void 0===i&&(e="p",a=!0),a&&(this.block.removeAllClass(),this.block.removeAllAttr());var l;if("blockquote"===o&&this.utils.isEndOfElement(s)){this.marker.remove(),l=document.createElement("p"),l.innerHTML=this.opts.invisibleSpace,t(s).after(l),this.caret.start(l);var c=t(s).children().last();0!==c.length&&"BR"===c[0].tagName&&c.remove()}else l=this.utils.replaceToTag(s,e);if("object"==typeof i){n=r;for(var h in i)l=this.block.setAttr(l,h,i[h],n)}else l=this.block.setAttr(l,i,r,n);return"pre"===e&&1===l.length&&t(l).html(t.trim(t(l).html())),this.selection.restore(),this.block.removeInlineTags(l),l},formatUncollapsed:function(e,i,r,n){this.selection.save();var s=[],o=this.selection.blocks();o[0]&&(t(o[0]).hasClass("redactor-in")||t(o[0]).hasClass("redactor-box"))&&(o=this.core.editor().find(this.opts.blockTags.join(", ")));for(var a=o.length,l=0;l<a;l++){var c=o[l].tagName.toLowerCase();if(-1!==t.inArray(c,this.block.tags)&&"figure"!==c){var h=this.utils.replaceToTag(o[l],e);if("object"==typeof i){n=r;for(var d in i)h=this.block.setAttr(h,d,i[d],n)}else h=this.block.setAttr(h,i,r,n);s.push(h),this.block.removeInlineTags(h)}}if(this.selection.restore(),"pre"===e&&0!==s.length){var u=s[0];t.each(s,function(e,i){0!==e&&(t(u).append("\n"+t.trim(i.html())),t(i).remove())}),s=[],s.push(u)}return s},removeInlineTags:function(e){e=e[0]||e;var i=this.opts.inlineTags,r=["PRE","H1","H2","H3","H4","H5","H6"];if(-1!==t.inArray(e.tagName,r)){if("PRE"!==e.tagName){var n=i.indexOf("a");i.splice(n,1)}t(e).find(i.join(",")).not(".redactor-selection-marker").contents().unwrap()}},setAttr:function(t,e,i,r){if(void 0===e)return t;var n=void 0===r?"replace":r;return t="class"===e?this.block[n+"Class"](i,t):"remove"===n?this.block[n+"Attr"](e,t):"removeAll"===n?this.block[n+"Attr"](e,t):this.block[n+"Attr"](e,i,t)},getBlocks:function(e){if(e=void 0===e?this.selection.blocks():e,t(e).hasClass("redactor-box")){var i=[],r=this.core.editor().children();return t.each(r,t.proxy(function(t,e){this.utils.isBlock(e)&&i.push(e)},this)),i}return e},replaceClass:function(e,i){return t(this.block.getBlocks(i)).removeAttr("class").addClass(e)[0]},toggleClass:function(e,i){return t(this.block.getBlocks(i)).toggleClass(e)[0]},addClass:function(e,i){return t(this.block.getBlocks(i)).addClass(e)[0]},removeClass:function(e,i){return t(this.block.getBlocks(i)).removeClass(e)[0]},removeAllClass:function(e){return t(this.block.getBlocks(e)).removeAttr("class")[0]},replaceAttr:function(e,i,r){return r=this.block.removeAttr(e,r),t(r).attr(e,i)[0]},toggleAttr:function(e,i,r){r=this.block.getBlocks(r);var n=this,s=[];return t.each(r,function(r,o){t(o).attr(e)?s.push(n.block.removeAttr(e,o)):s.push(n.block.addAttr(e,i,o))}),s},addAttr:function(e,i,r){return t(this.block.getBlocks(r)).attr(e,i)[0]},removeAttr:function(e,i){return t(this.block.getBlocks(i)).removeAttr(e)[0]},removeAllAttr:function(e){e=this.block.getBlocks(e);var i=[];return t.each(e,function(t,e){if(void 0!==e.attributes)for(;e.attributes.length;)e.removeAttribute(e.attributes[0].name);i.push(e)}),i}}},buffer:function(){return{set:function(t){void 0===t&&this.buffer.clear(),void 0===t||"undo"===t?this.buffer.setUndo():this.buffer.setRedo()},setUndo:function(){var t=this.selection.saveInstant(),e=this.sBuffer[this.sBuffer.length-1],i=this.core.editor().html();(void 0===e||e[0]!==i)&&this.sBuffer.push([i,t])},setRedo:function(){var t=this.selection.saveInstant();this.sRebuffer.push([this.core.editor().html(),t])},add:function(){this.sBuffer.push([this.core.editor().html(),0])},undo:function(){if(0!==this.sBuffer.length){var t=this.sBuffer.pop();this.buffer.set("redo"),this.core.editor().html(t[0]),this.selection.restoreInstant(t[1]),this.selection.restore(),this.observe.load()}},redo:function(){if(0!==this.sRebuffer.length){var t=this.sRebuffer.pop();this.buffer.set("undo"),this.core.editor().html(t[0]),this.selection.restoreInstant(t[1]),this.selection.restore(),this.observe.load()}},clear:function(){this.sRebuffer=[]}}},build:function(){return{start:function(){if("textarea"!==this.opts.type)throw new Error("Only `<textarea>` types are allowed.");this.build.startTextarea(),this.build.setIn(),this.build.setId(),this.build.enableEditor(),this.build.setOptions(),this.build.callEditor()},createContainerBox:function(){this.$box=t('<div class="redactor-box" role="application" />')},setIn:function(){this.core.editor().addClass("redactor-in")},setId:function(){var t="textarea"===this.opts.type?"redactor-uuid-"+this.uuid:this.$element.attr("id");this.core.editor().attr("id",void 0===t?"redactor-uuid-"+this.uuid:t)},getName:function(){var t=this.$element.attr("name");return void 0===t?"content-"+this.uuid:t},buildTextarea:function(){},loadFromTextarea:function(){this.$editor=t("<div />"),this.$textarea=this.$element,this.$element.attr("name",this.build.getName()),this.$box.insertAfter(this.$element).append(this.$editor).append(this.$element),this.build.setStartAttrs(),this.$editor.addClass("redactor-layer"),this.opts.overrideStyles&&this.$editor.addClass("redactor-styles"),this.$element.hide(),this.$box.prepend('<span class="redactor-voice-label" id="redactor-voice-'+this.uuid+'" aria-hidden="false">'+this.lang.get("accessibility-help-label")+"</span>")},setStartAttrs:function(){this.$editor.attr({"aria-labelledby":"redactor-voice-"+this.uuid,role:"presentation"})},startTextarea:function(){this.build.createContainerBox(),this.build.loadFromTextarea(),this.code.start(this.core.textarea().val()),this.core.textarea().val(this.clean.onSync(this.$editor.html()))},isTag:function(t){return this.$element[0].tagName===t},isInline:function(){return!this.build.isTag("TEXTAREA")&&!this.build.isTag("DIV")&&!this.build.isTag("PRE")},enableEditor:function(){this.core.editor().attr({contenteditable:!0})},setOptions:function(){"inline"===this.opts.type&&(this.opts.enterKey=!1),"inline"!==this.opts.type&&"pre"!==this.opts.type||(this.opts.toolbarMobile=!1,this.opts.toolbar=!1),this.core.editor().attr("spellcheck",this.opts.spellcheck),this.opts.structure&&this.core.editor().addClass("redactor-structure"),this.opts.stylesClass&&this.core.editor().addClass(this.opts.stylesClass),"textarea"===this.opts.type&&(this.core.box().attr("dir",this.opts.direction),this.core.editor().attr("dir",this.opts.direction),this.opts.tabindex&&this.core.editor().attr("tabindex",this.opts.tabindex),this.opts.minHeight?this.core.editor().css("min-height",this.opts.minHeight):this.core.editor().css("min-height","40px"),this.opts.maxHeight&&this.core.editor().css("max-height",this.opts.maxHeight),this.opts.maxWidth&&this.core.editor().css({"max-width":this.opts.maxWidth,margin:"auto"}))},callEditor:function(){this.build.disableBrowsersEditing(),this.events.init(),this.build.setHelpers(),this.toolbarsButtons=this.button.init(),this.toolbar.build(),this.core.editor().on("mouseup.redactor-observe."+this.uuid+" keyup.redactor-observe."+this.uuid+" focus.redactor-observe."+this.uuid+" touchstart.redactor-observe."+this.uuid,t.proxy(this.observe.toolbar,this)),this.core.element().on("blur.callback.redactor",t.proxy(function(){this.button.setInactiveAll()},this)),this.modal.templates(),this.build.plugins(),this.code.html=this.code.cleaned(this.core.editor().html()),this.core.callback("init"),this.core.callback("initToEdit"),this.start=!1},setHelpers:function(){this.opts.focus?setTimeout(this.focus.start,100):this.opts.focusEnd&&setTimeout(this.focus.end,100)},disableBrowsersEditing:function(){try{document.execCommand("enableObjectResizing",!1,!1),document.execCommand("enableInlineTableEditing",!1,!1),document.execCommand("AutoUrlDetect",!1,!1)}catch(t){}},plugins:function(){this.opts.plugins&&t.each(this.opts.plugins,t.proxy(function(i,r){var n="undefined"!=typeof RedactorPlugins&&void 0!==RedactorPlugins[r]?RedactorPlugins:e.fn;if(t.isFunction(n[r])){this[r]=n[r]();for(var s=this.getModuleMethods(this[r]),o=s.length,a=0;a<o;a++)this[r][s[a]]=this[r][s[a]].bind(this);if(void 0!==this[r].langs){var l={};void 0!==this[r].langs[this.opts.lang]?l=this[r].langs[this.opts.lang]:void 0===this[r].langs[this.opts.lang]&&void 0!==this[r].langs.en&&(l=this[r].langs.en);var c=this;t.each(l,function(t,e){void 0===c.opts.curLang[t]&&(c.opts.curLang[t]=e)})}"function"==typeof this[r].init&&this[r].init()}},this))}}},button:function(){return{toolbar:function(){return void 0!==this.button.$toolbar&&this.button.$toolbar?this.button.$toolbar:this.$toolbar},init:function(){return{format:{title:this.lang.get("format"),icon:!0,dropdown:{p:{title:this.lang.get("paragraph"),func:"block.format"},blockquote:{title:this.lang.get("quote"),func:"block.format"},pre:{title:this.lang.get("code"),func:"block.format"},h1:{title:this.lang.get("heading1"),func:"block.format"},h2:{title:this.lang.get("heading2"),func:"block.format"},h3:{title:this.lang.get("heading3"),func:"block.format"},h4:{title:this.lang.get("heading4"),func:"block.format"},h5:{title:this.lang.get("heading5"),func:"block.format"},h6:{title:this.lang.get("heading6"),func:"block.format"}}},bold:{title:this.lang.get("bold-abbr"),icon:!0,label:this.lang.get("bold"),func:"inline.format"},italic:{title:this.lang.get("italic-abbr"),icon:!0,label:this.lang.get("italic"),func:"inline.format"},deleted:{title:this.lang.get("deleted-abbr"),icon:!0,label:this.lang.get("deleted"),func:"inline.format"},underline:{title:this.lang.get("underline-abbr"),icon:!0,label:this.lang.get("underline"),func:"inline.format"},lists:{title:this.lang.get("lists"),icon:!0,dropdown:{unorderedlist:{title:"&bull; "+this.lang.get("unorderedlist"),func:"list.toggle"},orderedlist:{title:"1. "+this.lang.get("orderedlist"),func:"list.toggle"},outdent:{title:"< "+this.lang.get("outdent"),func:"indent.decrease",observe:{element:"li",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},indent:{title:"> "+this.lang.get("indent"),func:"indent.increase",observe:{element:"li",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}}}},ul:{title:"&bull; "+this.lang.get("bulletslist"),icon:!0,func:"list.toggle"},ol:{title:"1. "+this.lang.get("numberslist"),icon:!0,func:"list.toggle"},outdent:{title:this.lang.get("outdent"),icon:!0,func:"indent.decrease"},indent:{title:this.lang.get("indent"),icon:!0,func:"indent.increase"},image:{title:this.lang.get("image"),icon:!0,func:"image.show"},file:{title:this.lang.get("file"),icon:!0,func:"file.show"},link:{title:this.lang.get("link"),icon:!0,dropdown:{link:{title:this.lang.get("link-insert"),func:"link.show",observe:{element:"a",in:{title:this.lang.get("link-edit")},out:{title:this.lang.get("link-insert")}}},unlink:{title:this.lang.get("unlink"),func:"link.unlink",observe:{element:"a",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}}}},horizontalrule:{title:this.lang.get("horizontalrule"),icon:!0,func:"line.insert"}}},setFormatting:function(){for(var t in this.toolbarsButtons.format.dropdown)this.toolbarsButtons.format.dropdown.hasOwnProperty(t)&&-1===this.opts.formatting.indexOf(t)&&delete this.toolbarsButtons.format.dropdown[t]},hideButtons:function(){0!==this.opts.buttonsHide.length&&this.button.hideButtonsSlicer(this.opts.buttonsHide)},hideButtonsOnMobile:function(){this.detect.isMobile()&&0!==this.opts.buttonsHideOnMobile.length&&this.button.hideButtonsSlicer(this.opts.buttonsHideOnMobile)},hideButtonsSlicer:function(e){t.each(e,t.proxy(function(t,e){var i=this.opts.buttons.indexOf(e);-1!==i&&this.opts.buttons.splice(i,1)},this))},load:function(t){this.button.buttons=[],this.opts.buttons.forEach(function(e){if(("image"!==e||this.image.is())&&this.toolbarsButtons.hasOwnProperty(e)){var i=elCreate("li");i.appendChild(this.button.build(e,this.toolbarsButtons[e])[0]),t[0].appendChild(i)}}.bind(this))},buildButtonTooltip:function(){},build:function(e,i){var r=t('<a href="javascript:void(null);" rel="'+e+'" />');if(r.addClass("re-button re-"+e),r.attr({role:"button",tabindex:"-1"}),r.html(i.title),(i.func||i.command||i.dropdown)&&this.button.setEvent(r,e,i),i.dropdown){r.addClass("redactor-toolbar-link-dropdown").attr("aria-haspopup",!0);var n=t('<ul class="dropdownMenu redactor-dropdown-menu redactor-dropdown-menu-'+r[0].rel+'" data-dropdown-allow-flip="horizontal" data-dropdown-ignore-page-scroll="true" />');r.data("dropdown",n),this.dropdown.build(e,n,i.dropdown),this.button.setupDropdown(r[0],n[0])}return this.button.buttons.push(r),r},setupDropdown:function(t,e){require(["Ui/SimpleDropdown"],function(i){i.initFragment(t,e),i.registerCallback(t.id,function(t,e){"close"===e&&this.dropdown.hideOut()}.bind(this)),elData(t,"a11y-mouse-event","mousedown"),elData(t,"aria-expanded",!1),t.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation()})}.bind(this))},getButtons:function(){return this.button.toolbar().find("a.re-button")},getButtonsKeys:function(){return this.button.buttons},setEvent:function(e,i,r){e.on("mousedown",t.proxy(function(t){if(t.preventDefault(),e.hasClass("redactor-button-disabled"))return!1;var n="func",s=r.func;return r.command?(n="command",s=r.command):r.dropdown&&(n="dropdown",s=!1),this.button.toggle(t,i,n,s),!1},this))},toggle:function(t,e,i,r,n){!this.detect.isIe()&&this.detect.isDesktop()||(this.utils.freezeScroll(),t.returnValue=!1),"command"===i?this.inline.format(r):"dropdown"===i?this.dropdown.show(t,e):this.button.clickCallback(t,r,e,n),"dropdown"!==i&&this.dropdown.hideAll(!1),!this.detect.isIe()&&this.detect.isDesktop()||this.utils.unfreezeScroll()},clickCallback:function(e,i,r,n){var s;if(e instanceof Event?e.preventDefault():e&&e.originalEvent&&e.originalEvent.preventDefault(),n=void 0===n?r:n,t.isFunction(i))i.call(this,r);else if("-1"!==i.search(/\./)){if(s=i.split("."),void 0===this[s[0]])return;"object"==typeof n?this[s[0]][s[1]].apply(this,n):this[s[0]][s[1]].call(this,n)}else"object"==typeof n?this[i].apply(this,n):this[i].call(this,n);this.observe.buttons(e,r)},all:function(){return this.button.buttons},get:function(t){if(!1!==this.opts.toolbar)return this.button.toolbar().find("a.re-"+t)},set:function(t,e){if(!1!==this.opts.toolbar){var i=this.button.toolbar().find("a.re-"+t);return i.html(e).attr("aria-label",e),i}},add:function(e,i){if(!0!==this.button.isAdded(e))return t();var r=this.button.build(e,{title:i});return this.button.toolbar().append(t("<li>").append(r)),r},addFirst:function(e,i){if(!0!==this.button.isAdded(e))return t();var r=this.button.build(e,{title:i});return this.button.toolbar().prepend(t("<li>").append(r)),r},addAfter:function(e,i,r){if(!0!==this.button.isAdded(i))return t();var n=this.button.build(i,{title:r}),s=this.button.get(e);return 0!==s.length?s.parent().after(t("<li>").append(n)):this.button.toolbar().append(t("<li>").append(n)),n},addBefore:function(e,i,r){if(!0!==this.button.isAdded(i))return t();var n=this.button.build(i,{title:r}),s=this.button.get(e);return 0!==s.length?s.parent().before(t("<li>").append(n)):this.button.toolbar().append(t("<li>").append(n)),n},isAdded:function(t){var e=this.opts.buttonsHideOnMobile.indexOf(t);return!(!1===this.opts.toolbar||-1!==e&&this.detect.isMobile())},setIcon:function(t,e){this.opts.buttonsTextLabeled||t.html(e).addClass("re-button-icon")},changeIcon:function(t,e){var i=this.button.get(t);0!==i.length&&i.find("i").removeAttr("class").addClass("re-icon-"+e)},addCallback:function(e,i){if(void 0!==e&&!1!==this.opts.toolbar){var r="dropdown"===i?"dropdown":"func",n=e.attr("rel");e.on("mousedown",t.proxy(function(t){if(e.hasClass("redactor-button-disabled"))return!1;this.button.toggle(t,n,r,i)},this))}},addDropdown:function(e,i){if(!1!==this.opts.toolbar){e.addClass("redactor-toolbar-link-dropdown").attr("aria-haspopup",!0);var r=e.attr("rel");this.button.addCallback(e,"dropdown");var n=t('<ul class="dropdownMenu redactor-dropdown-menu redactor-dropdown-menu-'+r+'" data-dropdown-allow-flip="horizontal" data-dropdown-ignore-page-scroll="true" />');return e.data("dropdown",n),i&&(this.dropdown.build(r,n,i),this.button.setupDropdown(e[0],n[0])),n}},setActive:function(t){this.button.get(t).addClass("redactor-act").attr({"aria-pressed":!0,tabindex:0})},setInactive:function(t){this.button.get(t).removeClass("redactor-act").attr({"aria-pressed":!1,tabindex:"html"===t?0:-1})},setInactiveAll:function(t){var e=this.button.toolbar().find("a.re-button");void 0!==t&&(e=e.not(".re-"+t)),e.removeClass("redactor-act").attr({"aria-pressed":!1,tabindex:"html"===t?0:-1})},disable:function(t){this.button.get(t).addClass("redactor-button-disabled").attr("aria-disabled",!0)},enable:function(t){this.button.get(t).removeClass("redactor-button-disabled").attr("aria-disabled",!1)},disableAll:function(t){var e=this.button.toolbar().find("a.re-button");void 0!==t&&(Array.isArray(t)||(t=[t]),t=t.map(function(t){return".re-"+t}),e=e.not(t.join(","))),e.addClass("redactor-button-disabled").attr("aria-disabled",!0)},enableAll:function(){this.button.toolbar().find("a.re-button").removeClass("redactor-button-disabled").attr("aria-disabled",!1)},remove:function(t){this.button.get(t).remove()}}},caret:function(){return{set:function(t,e,i){var r=this.core.editor().scrollTop();this.core.editor().focus(),this.core.editor().scrollTop(r),i=void 0===i?0:1,t=t[0]||t,e=e[0]||e;var n=this.selection.get(),s=this.selection.range(n);try{s.setStart(t,0),s.setEnd(e,i)}catch(t){}this.selection.update(n,s)},prepare:function(t){return this.detect.isFirefox()&&void 0!==this.start&&this.core.editor().focus(),t[0]||t},start:function(e){var i,r;if(e=this.caret.prepare(e)){if("BR"===e.tagName)return this.caret.before(e);var n=t(e).children().first(),s=this.utils.isInlineTag(e.tagName);""===e.innerHTML||s?this.caret.setStartEmptyOrInline(e,s):n&&0!==n.length&&this.utils.isInlineTag(n[0].tagName)&&""===n.text()?this.caret.setStartEmptyOrInline(n[0],!0):(i=window.getSelection(),i.removeAllRanges(),r=document.createRange(),r.selectNodeContents(e),r.collapse(!0),i.addRange(r))}},setStartEmptyOrInline:function(e,i){var r=window.getSelection(),n=document.createRange(),s=document.createTextNode("​");n.setStart(e,0),n.insertNode(s),n.setStartAfter(s),n.collapse(!0),r.removeAllRanges(),r.addRange(n),i||this.core.editor().on("keydown.redactor-remove-textnode",function(){t(s).remove(),t(this).off("keydown.redactor-remove-textnode")})},end:function(e){var i,r;if(e=this.caret.prepare(e)){if("BR"!==e.tagName&&""===e.innerHTML)return this.caret.start(e);if("BR"===e.tagName){var n=document.createElement("span");return n.className="redactor-invisible-space",n.innerHTML="&#x200b;",t(e).after(n),i=window.getSelection(),i.removeAllRanges(),r=document.createRange(),r.setStartBefore(n),r.setEndBefore(n),i.addRange(r),void t(n).replaceWith(function(){return t(this).contents()})}if(e.lastChild&&1===e.lastChild.nodeType)return this.caret.after(e.lastChild);var i=window.getSelection();if(i.getRangeAt||i.rangeCount)try{var r=i.getRangeAt(0);r.selectNodeContents(e),r.collapse(!1),i.removeAllRanges(),i.addRange(r)}catch(t){}}},after:function(e){var i,r;if(e=this.caret.prepare(e)){if("BR"===e.tagName)return this.caret.end(e);if(this.utils.isBlockTag(e.tagName)){var n=this.caret.next(e);return void(void 0===n?this.caret.end(e):("TABLE"===n.tagName?n=t(n).find("th, td").first()[0]:"UL"!==n.tagName&&"OL"!==n.tagName||(n=t(n).find("li").first()[0]),this.caret.start(n)))}var s=document.createTextNode("​");i=window.getSelection(),i.removeAllRanges(),r=document.createRange(),r.setStartAfter(e),r.insertNode(s),r.setStartAfter(s),r.collapse(!0),i.addRange(r)}},before:function(e){var i,r;if(e=this.caret.prepare(e)){if(this.utils.isBlockTag(e.tagName)){var n=this.caret.prev(e);return void(void 0===n?this.caret.start(e):("TABLE"===n.tagName?n=t(n).find("th, td").last()[0]:"UL"!==n.tagName&&"OL"!==n.tagName||(n=t(n).find("li").last()[0]),this.caret.end(n)))}i=window.getSelection(),i.removeAllRanges(),r=document.createRange(),r.setStartBefore(e),r.collapse(!0),i.addRange(r)}},next:function(e){var i=t(e).next();return i.hasClass("redactor-script-tag, redactor-selection-marker")?i.next()[0]:i[0]},prev:function(e){var i=t(e).prev();return i.hasClass("redactor-script-tag, redactor-selection-marker")?i.prev()[0]:i[0]},offset:function(t){return this.offset.get(t)}}},clean:function(){return{onSet:function(e){e=this.clean.savePreCode(e),this.opts.script&&(e=e.replace(/<script(.*?[^>]?)>([\w\W]*?)<\/script>/gi,'<pre class="redactor-script-tag" $1>$2</pre>')),e=e.replace(/\$/g,"&#36;"),e=e.replace(/&amp;/g,"&"),e=e.replace(/<a href="(.*?[^>]?)®(.*?[^>]?)">/gi,'<a href="$1&reg$2">'),e=e.replace(/<span id="selection-marker-1"(.*?[^>]?)>​<\/span>/gi,"###marker1###"),e=e.replace(/<span id="selection-marker-2"(.*?[^>]?)>​<\/span>/gi,"###marker2###");var i=this,r=t("<div/>").html(t.parseHTML(e,document,!0)),n=this.opts.replaceTags;if(n){var s=Object.keys(this.opts.replaceTags);r.find(s.join(",")).each(function(t,e){i.utils.replaceToTag(e,n[e.tagName.toLowerCase()])})}r.find("span, a").attr("data-redactor-span",!0),r.find(this.opts.inlineTags.join(",")).each(function(){var e=t(this);e.attr("style")&&e.attr("data-redactor-style-cache",e.attr("style"))}),e=r.html();var o=["font","html","head","link","body","meta","applet"];return this.opts.script||o.push("script"),e=this.clean.stripTags(e,o),this.opts.removeComments&&(e=e.replace(/<!--[\s\S]*?-->/gi,"")),e=this.paragraphize.load(e),e=e.replace("###marker1###",'<span id="selection-marker-1" class="redactor-selection-marker">​</span>'),e=e.replace("###marker2###",'<span id="selection-marker-2" class="redactor-selection-marker">​</span>'),-1!==e.search(/^(||\s||<br\s?\/?>||&nbsp;)$/i)?this.opts.emptyHtml:e},onGet:function(t){return this.clean.onSync(t)},onSync:function(e){if(e=e.replace(/\u200B/g,""),e=e.replace(/&#x200b;/gi,""),
--1!==e.search(/^<p>(||\s||<br\s?\/?>||&nbsp;)<\/p>$/i))return"";e=e.replace(/<span(.*?)id="redactor-image-box"(.*?[^>])>([\w\W]*?)<img(.*?)><\/span>/gi,"$3<img$4>"),e=e.replace(/<span(.*?)id="redactor-image-resizer"(.*?[^>])>(.*?)<\/span>/gi,""),e=e.replace(/<span(.*?)id="redactor-image-editter"(.*?[^>])>(.*?)<\/span>/gi,""),e=e.replace(/<img(.*?)style="(.*?)opacity: 0\.5;(.*?)"(.*?)>/gi,'<img$1style="$2$3"$4>');var i=t("<div/>").html(t.parseHTML(e,document,!0));i.find('*[style=""]').removeAttr("style"),i.find('*[class=""]').removeAttr("class"),i.find('*[rel=""]').removeAttr("rel"),i.find('*[data-image=""]').removeAttr("data-image"),i.find('*[alt=""]').removeAttr("alt"),i.find('*[title=""]').removeAttr("title"),i.find("*[data-redactor-style-cache]").removeAttr("data-redactor-style-cache"),i.find(".redactor-invisible-space, .redactor-unlink").each(function(){t(this).contents().unwrap()}),i.find("span, a").removeAttr("data-redactor-span data-redactor-style-cache").each(function(){0===this.attributes.length&&t(this).contents().unwrap()}),i.find("img").removeAttr("rel"),i.find(".redactor-selection-marker, #redactor-insert-marker").remove(),e=i.html(),this.opts.script&&(e=e.replace(/<pre class="redactor-script-tag"(.*?[^>]?)>([\w\W]*?)<\/pre>/gi,"<script$1>$2<\/script>")),e=this.clean.restoreFormTags(e),e=e.replace(new RegExp("<br\\s?/?></h","gi"),"</h"),e=e.replace(new RegExp("<br\\s?/?></li>","gi"),"</li>"),e=e.replace(new RegExp("</li><br\\s?/?>","gi"),"</li>"),e=e.replace(/<pre>/gi,"<pre>\n"),this.opts.preClass&&(e=e.replace(/<pre>/gi,'<pre class="'+this.opts.preClass+'">')),this.opts.linkNofollow&&(e=e.replace(/<a(.*?)rel="nofollow"(.*?[^>])>/gi,"<a$1$2>"),e=e.replace(/<a(.*?[^>])>/gi,'<a$1 rel="nofollow">'));var r={"™":"&trade;","©":"&copy;","…":"&hellip;","—":"&mdash;","‐":"&dash;"};return t.each(r,function(t,i){e=e.replace(new RegExp(t,"g"),i)}),e=e.replace(/&amp;/g,"&"),e=e.replace(/\n{2,}/g,"\n"),this.opts.removeNewlines&&(e=e.replace(/\r?\n/g,"")),e},onPaste:function(e,i,r){if(!0!==r){e=e.replace(/<b\sid="internal-source-marker(.*?)">([\w\W]*?)<\/b>/gi,"$2"),e=e.replace(/<b(.*?)id="docs-internal-guid(.*?)">([\w\W]*?)<\/b>/gi,"$3"),e=e.replace(/<span[^>]*(font-style: italic; font-weight: bold|font-weight: bold; font-style: italic)[^>]*>([\w\W]*?)<\/span>/gi,"<b><i>$2</i></b>"),e=e.replace(/<span[^>]*(font-style: italic; font-weight: 700|font-weight: 700; font-style: italic)[^>]*>([\w\W]*?)<\/span>/gi,"<b><i>$2</i></b>"),e=e.replace(/<span[^>]*font-style: italic[^>]*>([\w\W]*?)<\/span>/gi,"<i>$1</i>"),e=e.replace(/<span[^>]*font-weight: bold[^>]*>([\w\W]*?)<\/span>/gi,"<b>$1</b>"),e=e.replace(/<span[^>]*font-weight: 700[^>]*>([\w\W]*?)<\/span>/gi,"<b>$1</b>"),e=e.replace(/<o:p[^>]*>/gi,""),e=e.replace(/<\/o:p>/gi,"");this.clean.isHtmlMsWord(e)&&(e=this.clean.cleanMsWord(e))}return e=t.trim(e),i.pre?this.opts.preSpaces&&(e=e.replace(/\t/g,new Array(this.opts.preSpaces+1).join(" "))):(e=this.clean.replaceBrToNl(e),e=this.clean.removeTagsInsidePre(e)),!0!==r&&(e=this.clean.removeEmptyInlineTags(e),!1===i.encode&&(e=e.replace(/&/g,"&amp;"),e=this.clean.convertTags(e,i),e=this.clean.getPlainText(e),e=this.clean.reconvertTags(e,i))),i.text&&(e=this.clean.replaceNbspToSpaces(e),e=this.clean.getPlainText(e)),i.lists&&(e=e.replace("\n","<br>")),i.encode&&(e=this.clean.encodeHtml(e)),i.paragraphize&&(e=e.replace(/ \n/g," "),e=e.replace(/\n /g," "),e=this.paragraphize.load(e),e=e.replace(/<p><\/p>/g,"")),e=e.replace(/<li><p>/g,"<li>"),e=e.replace(/<\/p><\/li>/g,"</li>")},getCurrentType:function(t,e){var i=this.selection.blocks(),r={text:!1,encode:!1,paragraphize:!0,line:this.clean.isHtmlLine(t),blocks:this.clean.isHtmlBlocked(t),pre:!1,lists:!1,block:!0,inline:!0,links:!0,images:!0};return 1===i.length&&this.utils.isCurrentOrParent(["h1","h2","h3","h4","h5","h6","a","figcaption"])?(r.text=!0,r.paragraphize=!1,r.inline=!1,r.images=!1,r.links=!1,r.line=!0):"inline"===this.opts.type||!1===this.opts.enterKey?(r.paragraphize=!1,r.block=!1,r.line=!0):1===i.length&&this.utils.isCurrentOrParent(["li"])?(r.lists=!0,r.block=!1,r.paragraphize=!1,r.images=!1):1===i.length&&this.utils.isCurrentOrParent(["th","td","blockquote"])?(r.block=!1,r.paragraphize=!1):("pre"===this.opts.type||1===i.length&&this.utils.isCurrentOrParent("pre"))&&(r.inline=!1,r.block=!1,r.encode=!0,r.pre=!0,r.paragraphize=!1,r.images=!1,r.links=!1),!0===r.line&&(r.paragraphize=!1),!0===e&&(r.text=!1),r},isHtmlBlocked:function(t){var e=t.match(new RegExp("</("+this.opts.blockTags.join("|").toUpperCase()+")>","gi")),i=t.match(new RegExp("<hr(.*?[^>])>","gi"));return null!==e||null!==i},isHtmlLine:function(t){if(this.clean.isHtmlBlocked(t))return!1;var e=t.match(/<br\s?\/?>/gi),i=t.match(/\n/gi);return!e&&!i},isHtmlMsWord:function(t){return t.match(/class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i)},removeEmptyInlineTags:function(e){var i=this.opts.inlineTags,r=t("<div/>").html(t.parseHTML(e,document,!0)),n=this,s=r.find("span"),o=r.find(i.join(","));return o.removeAttr("style"),o.each(function(){var e=t(this).html();0===this.attributes.length&&n.utils.isEmpty(e)&&t(this).replaceWith(function(){return t(this).contents()})}),s.each(function(){t(this).html();0===this.attributes.length&&t(this).replaceWith(function(){return t(this).contents()})}),e=r.html(),e=e.replace("\x3c!--?php","<?php"),e=e.replace("\x3c!--?","<?"),e=e.replace("?--\x3e","?>"),r.remove(),e},cleanMsWord:function(e){e=e.replace(/<!--[\s\S]*?-->/g,""),e=e.replace(/<o:p>[\s\S]*?<\/o:p>/gi,""),e=e.replace(/\n/g," "),e=e.replace(/<\/p>/gi,'</p><p><br data-redactor="br"></p>'),e=e.replace(/<\/div>|<\/li>|<\/td>/gi,"\n\n");var i=t("<div/>").html(e);elBySelAll("br",i[0],function(t){if("br"===elData(t,"redactor"))t.removeAttribute("data-redactor");else{var e=t.parentNode;if(e&&"P"===e.nodeName){for(var i=elCreate("p");t.nextSibling;)i.appendChild(t.nextSibling);e.parentNode.insertBefore(i,e.nextSibling),elRemove(t)}}});var r=!1,n=1,s=[];return i.find("p[style]").each(function(){var e=t(this).attr("style").match(/mso\-list\:l([0-9]+)\slevel([0-9]+)/);if(e){var o=parseInt(e[1]),a=parseInt(e[2]),l=t(this).html().match(/^[\w]+\./)?"ol":"ul",c=t("<li/>").html(t(this).html());if(c.html(c.html().replace(/^([\w\.]+)</,"<")),c.find("span:first").remove(),1==a&&-1==t.inArray(o,s)){var h=t("<"+l+"/>").attr({"data-level":a,"data-list":o}).html(c);t(this).replaceWith(h),r=o,s.push(o)}else{if(a>n){for(var d=i.find('[data-level="'+n+'"][data-list="'+r+'"]'),u=d,p=n;p<a;p++)h=t("<"+l+"/>"),h.appendTo(u.find("li").last()),u=h;u.attr({"data-level":a,"data-list":o}).html(c)}else{var d=i.find('[data-level="'+a+'"][data-list="'+o+'"]').last();d.append(c)}n=a,r=o,t(this).remove()}}}),i.find("[data-level][data-list]").removeAttr("data-level data-list"),elBySelAll("ol, ul",i[0],function(t){["nextElementSibling","previousElementSibling"].forEach(function(e){for(var i=t[e];i&&"P"===i.nodeName&&""===i.className&&"<br>"===i.innerHTML;)elRemove(i),i=t[e]})}),e=i.html()},replaceNbspToSpaces:function(t){return t.replace("&nbsp;"," ")},replaceBrToNl:function(t){return t.replace(/<br\s?\/?>/gi,"\n")},replaceNlToBr:function(t){return t.replace(/\n/g,"<br />")},convertTags:function(e,i){var r=t("<div>").html(e);r.find("iframe").remove();var n=r.find("a");if(n.removeAttr("style"),!1!==this.opts.pasteLinkTarget&&n.attr("target",this.opts.pasteLinkTarget),i.links&&this.opts.pasteLinks&&r.find("a").each(function(t,e){if(e.href){for(var i,r='#####[a href="'+e.href+'"',n=0,s=e.attributes.length;n<s;n++)i=e.attributes.item(n),"href"!==i.name&&(r+=" "+i.name+'="'+i.value+'"');e.outerHTML=r+"]#####"+e.innerHTML+"#####[/a]#####"}}),e=r.html(),i.images&&this.opts.pasteImages&&(e=e.replace(/<img(.*?)src="(.*?)"(.*?[^>])>/gi,'#####[img$1src="$2"$3]#####')),this.opts.pastePlainText)return e;var s,o=i.lists?["ul","ol","li"]:this.opts.pasteBlockTags;s=i.block||i.lists?i.inline?o.concat(this.opts.pasteInlineTags):o:i.inline?this.opts.pasteInlineTags:[];for(var a=s.length,l=0;l<a;l++)e=e.replace(new RegExp("</"+s[l]+">","gi"),"###/"+s[l]+"###"),"td"===s[l]||"th"===s[l]?e=e.replace(new RegExp("<"+s[l]+'(.*?[^>])((colspan|rowspan)="(.*?[^>])")?(.*?[^>])>',"gi"),"###"+s[l]+" $2###"):this.utils.isInlineTag(s[l])?(e=e.replace(new RegExp("<"+s[l]+'([^>]*)class="([^>]*)"[^>]*>',"gi"),"###"+s[l]+' class="$2"###'),e=e.replace(new RegExp("<"+s[l]+'([^>]*)data-redactor-style-cache="([^>]*)"[^>]*>',"gi"),"###"+s[l]+' cache="$2"###'),e=e.replace(new RegExp("<"+s[l]+"[^>]*>","gi"),"###"+s[l]+"###")):e=e.replace(new RegExp("<"+s[l]+"[^>]*>","gi"),"###"+s[l]+"###");return e},reconvertTags:function(t,e){if((e.links&&this.opts.pasteLinks||e.images&&this.opts.pasteImages)&&(t=t.replace(new RegExp("#####\\[","gi"),"<"),t=t.replace(new RegExp("\\]#####","gi"),">")),this.opts.pastePlainText)return t;var i,r=e.lists?["ul","ol","li"]:this.opts.pasteBlockTags;i=e.block||e.lists?e.inline?r.concat(this.opts.pasteInlineTags):r:e.inline?this.opts.pasteInlineTags:[];for(var n=i.length,s=0;s<n;s++)t=t.replace(new RegExp("###/"+i[s]+"###","gi"),"</"+i[s]+">");for(var s=0;s<n;s++)t=t.replace(new RegExp("###"+i[s]+"###","gi"),"<"+i[s]+">");for(var s=0;s<n;s++)if("td"===i[s]||"th"===i[s])t=t.replace(new RegExp("###"+i[s]+"s?(.*?[^#])###","gi"),"<"+i[s]+"$1>");else if(this.utils.isInlineTag(i[s])){var o="span"===i[s]?' data-redactor-span="true"':"";t=t.replace(new RegExp("###"+i[s]+' cache="(.*?[^#])"###',"gi"),"<"+i[s]+' style="$1"'+o+' data-redactor-style-cache="$1">'),t=t.replace(new RegExp("###"+i[s]+"s?(.*?[^#])###","gi"),"<"+i[s]+"$1>")}return t},cleanPre:function(e){e=void 0===e?t(this.selection.block()).closest("pre",this.core.editor()[0]):e,t(e).find("br").replaceWith(function(){return document.createTextNode("\n")}),t(e).find("p").replaceWith(function(){return t(this).contents()})},removeTagsInsidePre:function(e){var i=t("<div />").append(e);return i.find("pre").replaceWith(function(){var e=t(this).html();return e=e.replace(/<br\s?\/?>|<\/p>|<\/div>|<\/li>|<\/td>/gi,"\n"),e=e.replace(/(<([^>]+)>)/gi,""),t("<pre />").append(e)}),e=i.html(),i.remove(),e},getPlainText:function(e){e=e.replace(/<!--[\s\S]*?-->/gi,""),e=e.replace(/<style[\s\S]*?style>/gi,""),e=e.replace(/<p><\/p>/g,""),e=e.replace(/<\/div>|<\/li>|<\/td>/gi,"\n"),e=e.replace(/<\/p>/gi,"\n\n"),e=e.replace(/<\/H[1-6]>/gi,"\n\n");var i=document.createElement("div");return i.innerHTML=e,e=i.textContent||i.innerText,t.trim(e)},savePreCode:function(t){return t=this.clean.savePreFormatting(t),t=this.clean.saveCodeFormatting(t),t=this.clean.restoreSelectionMarkers(t)},savePreFormatting:function(e){var i=e.match(/<pre(.*?)>([\w\W]*?)<\/pre>/gi);return null===i?e:(t.each(i,t.proxy(function(t,i){var r,n,s,o=[],a=!1;i.match(/<pre(.*?)>(([\n\r\s]+)?)<code(.*?)>/i)?(o=i.match(/<pre(.*?)>(([\n\r\s]+)?)<code(.*?)>([\w\W]*?)<\/code>(([\n\r\s]+)?)<\/pre>/i),a=!0,r=o[5],n=o[1],s=o[4]):(o=i.match(/<pre(.*?)>([\w\W]*?)<\/pre>/i),r=o[2],n=o[1]),r=r.replace(/<br\s?\/?>/g,"\n"),r=r.replace(/&nbsp;/g," "),this.opts.preSpaces&&(r=r.replace(/\t/g,new Array(this.opts.preSpaces+1).join(" "))),r=this.clean.encodeEntities(r),r=r.replace(/\$/g,"&#36;"),e=a?e.replace(i,"<pre"+n+"><code"+s+">"+r+"</code></pre>"):e.replace(i,"<pre"+n+">"+r+"</pre>")},this)),e)},saveCodeFormatting:function(e){var i=e.match(/<code(.*?)>([\w\W]*?)<\/code>/gi);return null===i?e:(t.each(i,t.proxy(function(t,i){var r=i.match(/<code(.*?)>([\w\W]*?)<\/code>/i);r[2]=r[2].replace(/&nbsp;/g," "),r[2]=this.clean.encodeEntities(r[2]),r[2]=r[2].replace(/\$/g,"&#36;"),e=e.replace(i,"<code"+r[1]+">"+r[2]+"</code>")},this)),e)},restoreSelectionMarkers:function(t){return t=t.replace(/&lt;span id=&quot;selection-marker-([0-9])&quot; class=&quot;redactor-selection-marker&quot;&gt;​&lt;\/span&gt;/g,'<span id="selection-marker-$1" class="redactor-selection-marker">​</span>')},saveFormTags:function(t){return t},restoreFormTags:function(t){return t.replace(/<section(.*?) rel="redactor-form-tag"(.*?)>([\w\W]*?)<\/section>/gi,"<form$1$2>$3</form>")},encodeHtml:function(t){return t=t.replace(/”/g,'"'),t=t.replace(/“/g,'"'),t=t.replace(/‘/g,"'"),t=t.replace(/’/g,"'"),t=this.clean.encodeEntities(t)},encodeEntities:function(t){return t=String(t).replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"'),t=t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},stripTags:function(t,e){if(void 0===e)return t.replace(/(<([^>]+)>)/gi,"");var i=/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi;return t.replace(i,function(t,i){return-1===e.indexOf(i.toLowerCase())?t:""})},removeMarkers:function(t){return t.replace(/<span(.*?[^>]?)class="redactor-selection-marker"(.*?[^>]?)>([\w\W]*?)<\/span>/gi,"")},removeSpaces:function(e){return e=t.trim(e),e=e.replace(/\n/g,""),e=e.replace(/[\t]*/g,""),e=e.replace(/\n\s*\n/g,"\n"),e=e.replace(/^[\s\n]*/g," "),e=e.replace(/[\s\n]*$/g," "),e=e.replace(/>\s{2,}</g,"> <"),e=e.replace(/\n\n/g,"\n"),e=e.replace(/\u200B/g,"")},removeSpacesHard:function(e){return e=t.trim(e),e=e.replace(/\n/g,""),e=e.replace(/[\t]*/g,""),e=e.replace(/\n\s*\n/g,"\n"),e=e.replace(/^[\s\n]*/g,""),e=e.replace(/[\s\n]*$/g,""),e=e.replace(/>\s{2,}</g,"><"),e=e.replace(/\n\n/g,"\n"),e=e.replace(/\u200B/g,"")},normalizeCurrentHeading:function(){var t=this.selection.block();this.utils.isCurrentOrParentHeader()&&t&&t.normalize()}}},code:function(){return{syncFire:!0,html:!1,start:function(e){e=t.trim(e),e=e.replace(/^(<span id="selection-marker-1" class="redactor-selection-marker">​<\/span>)/,""),e=this.clean.onSet(e),e=e.replace(/<p><span id="selection-marker-1" class="redactor-selection-marker">​<\/span><\/p>/,""),this.events.stopDetectChanges(),this.core.editor().html(e),this.observe.load(),this.events.startDetectChanges()},set:function(e,i){e=t.trim(e),i=i||{},i.start&&(this.start=i.start),"textarea"===this.opts.type?e=this.clean.onSet(e):"div"===this.opts.type&&""===e&&(e=this.opts.emptyHtml),this.core.editor().html(e),"textarea"===this.opts.type&&this.code.sync()},get:function(){if("textarea"===this.opts.type)return this.core.textarea().val();var t=this.core.editor().html();return t=this.clean.onGet(t)},sync:function(){if(this.code.syncFire){var e=this.core.editor().html(),i=this.code.cleaned(e);if(!this.code.isSync(i)){if(this.code.html=i,"textarea"!==this.opts.type)return this.core.callback("sync",e),void this.core.callback("change",e);"textarea"===this.opts.type&&setTimeout(t.proxy(function(){this.code.startSync(e)},this),10)}}},startSync:function(t){t=this.core.callback("syncBefore",t),t=this.clean.onSync(t),this.core.textarea().val(t),this.core.callback("sync",t),!1===this.start&&this.core.callback("change",t),this.start=!1},isSync:function(t){var e=!1!==this.code.html&&this.code.html;return!1!==e&&e===t},cleaned:function(t){return t=t.replace(/\u200B/g,""),this.clean.removeMarkers(t)}}},core:function(){return{id:function(){return this.$editor.attr("id")},element:function(){return this.$element},editor:function(){return void 0===this.$editor?t():this.$editor},textarea:function(){return this.$textarea},box:function(){return"textarea"===this.opts.type?this.$box:this.$element},toolbar:function(){return!!this.$toolbar&&this.$toolbar},air:function(){return!!this.$air&&this.$air},object:function(){return t.extend({},this)},structure:function(){this.core.editor().toggleClass("redactor-structure")},addEvent:function(t){this.core.event=t},getEvent:function(){return this.core.event},callback:function(e,i,r){var n=!1,s=t._data(this.core.element()[0],"events");if(void 0!==s&&void 0!==s[e])for(var o=s[e].length,a=0;a<o;a++){var l=s[e][a].namespace;if("callback.redactor"===l){var c=s[e][a].handler,h=void 0===r?[i]:[i,r];n=void 0===h?c.call(this,i):c.call(this,i,h)}}if(n)return n;if(void 0===this.opts.callbacks[e])return void 0===r?i:r;var d=this.opts.callbacks[e];return t.isFunction(d)?void 0===r?d.call(this,i):d.call(this,i,r):void 0===r?i:r},destroy:function(){this.opts.destroyed=!0,this.core.callback("destroy"),t("#redactor-voice-"+this.uuid).remove(),this.core.editor().removeClass("redactor-in redactor-styles redactor-structure redactor-layer-img-edit"),this.core.editor().off("keydown.redactor-remove-textnode"),this.core.editor().off(".redactor-observe."+this.uuid),this.$element.off(".redactor").removeData("redactor"),this.core.editor().off(".redactor"),t(document).off(".redactor-air."+this.uuid),t(document).off("mousedown.redactor-blur."+this.uuid),t(document).off("mousedown.redactor."+this.uuid),t(document).off("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid),t(window).off(".redactor-toolbar."+this.uuid),t(window).off("touchmove.redactor."+this.uuid),t("body").off("scroll.redactor."+this.uuid),t(this.opts.toolbarFixedTarget).off("scroll.redactor."+this.uuid);var e=this;!1!==this.opts.plugins&&t.each(this.opts.plugins,function(i,r){t(window).off(".redactor-plugin-"+r),t(document).off(".redactor-plugin-"+r),t("body").off(".redactor-plugin-"+r),e.core.editor().off(".redactor-plugin-"+r)}),this.$element.off("click.redactor-click-to-edit"),this.$element.removeClass("redactor-click-to-edit"),this.core.editor().removeClass("redactor-layer"),this.core.editor().removeAttr("contenteditable");var i=this.code.get();this.opts.toolbar&&this.$toolbar&&this.$toolbar.find("a").each(function(){var e=t(this);e.data("dropdown")&&(e.data("dropdown").remove(),e.data("dropdown",{}))}),"textarea"===this.opts.type&&(this.$box.after(this.$element),this.$box.remove(),this.$element.val(i).show()),this.opts.toolbar&&this.$toolbar&&this.$toolbar.remove(),this.$modalBox&&this.$modalBox.remove(),this.$modalOverlay&&this.$modalOverlay.remove(),t(".redactor-link-tooltip").remove()}}},detect:function(){return{isWebkit:function(){return/webkit/.test(this.opts.userAgent)},isFirefox:function(){return this.opts.userAgent.indexOf("firefox")>-1},isIe:function(t){if(document.documentMode||/Edge/.test(navigator.userAgent))return"edge";var e;return e=RegExp("msie"+(isNaN(t)?"":"\\s"+t),"i").test(navigator.userAgent),e||(e=!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)),e},isMobile:function(){return/(iPhone|iPod|BlackBerry|Android)/.test(navigator.userAgent)},isDesktop:function(){return!/(iPhone|iPod|iPad|BlackBerry|Android)/.test(navigator.userAgent)},isIpad:function(){return/iPad/.test(navigator.userAgent)}}},dropdown:function(){return{active:!1,button:!1,key:!1,position:[],getDropdown:function(){return this.dropdown.active},build:function(e,i,r){var n,s=document.createDocumentFragment();for(var o in r)if(r.hasOwnProperty(o)){n=r[o];var a=this.dropdown.buildItem(o,n);this.observe.addDropdown(t(a),o,n),s.appendChild(a)}for(var l=!1,c=0,h=s.childNodes.length;c<h;c++)if(s.childNodes[c].nodeType===Node.ELEMENT_NODE){l=!0;break}l&&(i[0].rel=e,i[0].appendChild(s))},buildFormatting:function(){},buildItem:function(e,i){var r=elCreate("li");return void 0!==i.classname&&r.classList.add(i.classname),0===e.toLowerCase().indexOf("divider")?(r.classList.add("redactor-dropdown-divider"),r):(r.innerHTML='<a href="#" class="redactor-dropdown-'+e+'" role="button"><span>'+i.title+"</span></a>",t(r.children[0]).on("mousedown",function(t){t.preventDefault(),this.dropdown.buildClick(t,e,i)}.bind(this)),r)},buildClick:function(e,i,r){if(!t(e.target).hasClass("redactor-dropdown-link-inactive")){var n=this.dropdown.buildCommand(r);void 0!==r.args?this.button.toggle(e,i,n.type,n.callback,r.args):this.button.toggle(e,i,n.type,n.callback)}},buildCommand:function(t){var e={};return e.type="func",e.callback=t.func,t.command?(e.type="command",e.callback=t.command):t.dropdown&&(e.type="dropdown",e.callback=t.dropdown),e},show:function(e,i){this.detect.isDesktop()&&this.core.editor().focus(),this.dropdown.hideAll(!1,i),this.dropdown.key=i,this.dropdown.button=this.button.get(this.dropdown.key),require(["Ui/SimpleDropdown"],function(e){var i=this.dropdown.button[0].id;e.toggleDropdown(i),e.isOpen(i)?(this.dropdown.active=t(e.getDropdownMenu(i)),this.core.callback("dropdownShow",{dropdown:this.dropdown.active,key:this.dropdown.key,button:this.dropdown.button}),this.button.setActive(this.dropdown.key),this.dropdown.button.addClass("dropact").attr("aria-expanded",!0),this.dropdown.enableCallback()):this.dropdown.hide()}.bind(this)),e.preventDefault()},showIsFixedToolbar:function(){},showIsUnFixedToolbar:function(){},enableEvents:function(){},enableCallback:function(){this.core.callback("dropdownShown",{dropdown:this.dropdown.active,key:this.dropdown.key,button:this.dropdown.button})},getButtonPosition:function(){},closeHandler:function(){},hideAll:function(t,e){this.dropdown.hideOut(e)},hide:function(){this.dropdown.hideOut()},hideOut:function(t){if(!1!==this.dropdown.active&&this.dropdown.button[0].rel!==t){this.core.callback("dropdownHide",this.dropdown.active);var e=this.dropdown.button[0].id;require(["Ui/SimpleDropdown"],function(t){t.close(e)}),this.dropdown.button.removeClass("redactor-act dropact").attr("aria-expanded",!1),this.dropdown.button=!1,this.dropdown.key=!1,this.dropdown.active=!1}}}},events:function(){return{focused:!1,blured:!0,dropImage:!1,stopChanges:!1,stopDetectChanges:function(){this.events.stopChanges=!0},startDetectChanges:function(){var t=this;setTimeout(function(){t.events.stopChanges=!1},1)},dragover:function(e){e.preventDefault(),e.stopPropagation(),"IMG"===e.target.tagName&&t(e.target).addClass("redactor-image-dragover")},dragleave:function(t){this.core.editor().find("img").removeClass("redactor-image-dragover")},drop:function(t){return t=t.originalEvent||t,this.core.editor().find("img").removeClass("redactor-image-dragover"),"inline"===this.opts.type||"pre"===this.opts.type?(t.preventDefault(),!1):void 0===window.FormData||!t.dataTransfer||(0===t.dataTransfer.files.length?this.events.onDrop(t):(this.events.onDropUpload(t),void this.core.callback("drop",t)))},click:function(t){var e=this.core.getEvent(),i="click"!==e&&"arrow"!==e&&"click";this.core.addEvent(i),this.utils.disableSelectAll(),this.core.callback("click",t)},focus:function(t){if(!this.rtePaste&&(this.events.isCallback("focus")&&this.core.callback("focus",t),this.events.focused=!0,this.events.blured=!1,!1===this.selection.current())){var e=this.selection.get(),i=this.selection.range(e);i.setStart(this.core.editor()[0],0),i.setEnd(this.core.editor()[0],0),this.selection.update(e,i)}},blur:function(e){this.start||this.rtePaste||0===t(e.target).closest("#"+this.core.id()+", .redactor-toolbar, .redactor-dropdown, #redactor-modal-box").length&&(!this.events.blured&&this.events.isCallback("blur")&&this.core.callback("blur",e),this.events.focused=!1,this.events.blured=!0)},touchImageEditing:function(){var e=-1;this.events.imageEditing=!1,t(window).on("touchmove.redactor."+this.uuid,t.proxy(function(){this.events.imageEditing=!0,-1!==e&&clearTimeout(e),e=setTimeout(t.proxy(function(){this.events.imageEditing=!1},this),500)},this))},init:function(){this.core.editor().on("dragover.redactor dragenter.redactor",t.proxy(this.events.dragover,this)),this.core.editor().on("dragleave.redactor",t.proxy(this.events.dragleave,this)),this.core.editor().on("drop.redactor",t.proxy(this.events.drop,this)),this.core.editor().on("click.redactor",t.proxy(this.events.click,this)),this.core.editor().on("paste.redactor",t.proxy(this.paste.init,this)),this.core.editor().on("keydown.redactor",t.proxy(this.keydown.init,this)),this.core.editor().on("keyup.redactor",t.proxy(this.keyup.init,this)),this.core.editor().on("focus.redactor",t.proxy(this.events.focus,this)),t(document).on("mousedown.redactor-blur."+this.uuid,t.proxy(this.events.blur,this)),this.events.touchImageEditing(),this.events.createObserver(),this.events.setupObserver()},createObserver:function(){var e=this;this.events.observer=new MutationObserver(function(i){i.forEach(t.proxy(e.events.iterateObserver,e))})},iterateObserver:function(t){var e=!1;(("textarea"===this.opts.type||"div"===this.opts.type)&&!this.detect.isFirefox()&&t.target===this.core.editor()[0]||"class"===t.attributeName&&t.target===this.core.editor()[0]||"data-vivaldi-spatnav-clickable"==t.attributeName)&&(e=!0),e||(this.observe.load(),this.events.changeHandler())},setupObserver:function(){this.events.observer.observe(this.core.editor()[0],{attributes:!0,subtree:!0,childList:!0,characterData:!0,characterDataOldValue:!0})},changeHandler:function(){this.events.stopChanges||this.code.sync()},onDropUpload:function(t){if(t.preventDefault(),t.stopPropagation(),(this.opts.dragImageUpload||this.opts.dragFileUpload)&&(null!==this.opts.imageUpload||null!==this.opts.fileUpload)){"IMG"===t.target.tagName&&(this.events.dropImage=t.target);for(var e=t.dataTransfer.files,i=e.length,r=0;r<i;r++)this.upload.directUpload(e[r],t)}},onDrop:function(t){this.core.callback("drop",t)},isCallback:function(e){return void 0!==this.opts.callbacks[e]&&t.isFunction(this.opts.callbacks[e])},stopDetect:function(){this.events.stopDetectChanges()},startDetect:function(){this.events.startDetectChanges()}}},file:function(){return{is:function(){},show:function(){},insert:function(){},release:function(){},text:function(t){}}},focus:function(){return{start:function(){if(this.core.editor().focus(),"inline"!==this.opts.type){var t=this.focus.first();!1!==t&&this.caret.start(t)}},end:function(){this.core.editor().focus();var t=this.opts.inline?this.core.editor():this.focus.last();if(0!==t.length){var e=this.focus.lastChild(t);if(this.detect.isWebkit()||!1===e){var i=this.selection.get(),r=this.selection.range(i);null!==r?(r.selectNodeContents(t[0]),r.collapse(!1),this.selection.update(i,r)):this.caret.end(t)}else this.caret.end(e)}},first:function(){var t=this.core.editor().children().first();return(0!==t.length||0!==t[0].length&&"BR"!==t[0].tagName&&"HR"!==t[0].tagName&&3!==t[0].nodeType)&&("UL"===t[0].tagName||"OL"===t[0].tagName?t.find("li").first():t)},last:function(){return this.core.editor().children().last()},lastChild:function(t){var e=t[0].lastChild;return!(null===e||!this.utils.isInlineTag(e.tagName))&&e},is:function(){return this.core.editor()[0]===document.activeElement}}},image:function(){return{is:function(){return!(!this.opts.imageUpload||!this.opts.imageUpload&&!this.opts.s3)},show:function(){this.modal.load("image",this.lang.get("image"),700),this.upload.init("#redactor-modal-image-droparea",this.opts.imageUpload,this.image.insert),this.modal.show()},insert:function(e,i,r){var n;if(void 0!==e.error)return this.modal.close(),this.events.dropImage=!1,void this.core.callback("imageUploadError",e,r);if(!1!==this.events.dropImage)return n=t(this.events.dropImage),this.core.callback("imageDelete",n[0].src,n),n.attr("src",e.url),this.events.dropImage=!1,void this.core.callback("imageUpload",n,e);var s=t("<"+this.opts.imageTag+">");n=t("<img>"),n.attr("src",e.url);var o=void 0===e.id?"":e.id,a=void 0===e.s3?"image":"s3";n.attr("data-"+a,o),s.append(n);var l=this.utils.isTag(this.selection.current(),"pre");if(i){this.marker.remove();var c=this.insert.nodeToPoint(r,this.marker.get()),h=t(c).next();this.selection.restore(),this.buffer.set(),void 0!==h&&0!==h.length&&"IMG"===h[0].tagName?(this.core.callback("imageDelete",h[0].src,h),h.closest("figure, p",this.core.editor()[0]).replaceWith(s),this.caret.after(s)):(l?t(l).after(s):this.insert.node(s),this.caret.after(s))}else this.modal.close(),this.buffer.set(),l?t(l).after(s):this.insert.node(s),this.caret.after(s);this.events.dropImage=!1;var d=n[0].nextSibling,u=s.next(),p=t(d).text().replace(/\u200B/g,""),f=u.text().replace(/\u200B/g,"");""===p&&t(d).remove(),1===u.length&&"FIGURE"===u[0].tagName&&""===f&&u.remove(),null!==i?this.core.callback("imageUpload",n,e):this.core.callback("imageInserted",n,e)},setEditable:function(e){if(e.on("dragstart",function(t){t.preventDefault()}),this.opts.imageResizable){var i=t.proxy(function(i){this.observe.image=e,this.image.resizer=this.image.loadEditableControls(e),t(document).on("mousedown.redactor-image-resize-hide."+this.uuid,t.proxy(this.image.hideResize,this)),this.image.resizer&&this.image.resizer.on("mousedown.redactor touchstart.redactor",t.proxy(function(t){this.image.setResizable(t,e)},this))},this);e.off("mousedown.redactor").on("mousedown.redactor",t.proxy(this.image.hideResize,this)),e.off("click.redactor touchstart.redactor").on("click.redactor touchstart.redactor",i)}else e.off("click.redactor touchstart.redactor").on("click.redactor touchstart.redactor",t.proxy(function(i){setTimeout(t.proxy(function(){this.image.showEdit(e)},this),200)},this))},setResizable:function(t,e){t.preventDefault(),this.image.resizeHandle={x:t.pageX,y:t.pageY,el:e,ratio:e.width()/e.height(),h:e.height()},t=t.originalEvent||t,t.targetTouches&&(this.image.resizeHandle.x=t.targetTouches[0].pageX,this.image.resizeHandle.y=t.targetTouches[0].pageY),this.image.startResize()},startResize:function(){t(document).on("mousemove.redactor-image-resize touchmove.redactor-image-resize",t.proxy(this.image.moveResize,this)),t(document).on("mouseup.redactor-image-resize touchend.redactor-image-resize",t.proxy(this.image.stopResize,this))},moveResize:function(t){t.preventDefault(),t=t.originalEvent||t;var e=this.image.resizeHandle.h;t.targetTouches?e+=t.targetTouches[0].pageY-this.image.resizeHandle.y:e+=t.pageY-this.image.resizeHandle.y;var i=Math.round(e*this.image.resizeHandle.ratio);e<50||i<100||this.core.editor().width()<=i||(this.image.resizeHandle.el.attr({width:i,height:e}),this.image.resizeHandle.el.width(i),this.image.resizeHandle.el.height(e),this.code.sync())},stopResize:function(){this.handle=!1,t(document).off(".redactor-image-resize"),this.image.hideResize()},hideResize:function(e){if(!e||0===t(e.target).closest("#redactor-image-box",this.$editor[0]).length){if(e&&"IMG"==e.target.tagName){t(e.target)}var i=this.$editor.find("#redactor-image-box");0!==i.length&&(t("#redactor-image-editter").remove(),t("#redactor-image-resizer").remove(),i.find("img").css({marginTop:i[0].style.marginTop,marginBottom:i[0].style.marginBottom,marginLeft:i[0].style.marginLeft,marginRight:i[0].style.marginRight}),i.css("margin",""),i.find("img").css("opacity",""),i.replaceWith(function(){return t(this).contents()}),t(document).off("mousedown.redactor-image-resize-hide."+this.uuid),void 0!==this.image.resizeHandle&&this.image.resizeHandle.el.attr("rel",this.image.resizeHandle.el.attr("style")))}},loadResizableControls:function(e,i){if(this.opts.imageResizable&&!this.detect.isMobile()){var r=t('<span id="redactor-image-resizer" data-redactor="verified"></span>');return this.detect.isDesktop()||r.css({width:"15px",height:"15px"}),r.attr("contenteditable",!1),i.append(r),i.append(e),r}return i.append(e),!1},loadEditableControls:function(e){if(0===t("#redactor-image-box").length){var i=t('<span id="redactor-image-box" data-redactor="verified">');if(i.css("float",e.css("float")).attr("contenteditable",!1),"auto"!=e[0].style.margin?(i.css({marginTop:e[0].style.marginTop,marginBottom:e[0].style.marginBottom,marginLeft:e[0].style.marginLeft,marginRight:e[0].style.marginRight}),e.css("margin","")):i.css({display:"block",margin:"auto"}),e.css("opacity",".5").after(i),this.opts.imageEditable){this.image.editter=t('<span id="redactor-image-editter" data-redactor="verified">'+this.lang.get("edit")+"</span>"),this.image.editter.attr("contenteditable",!1),this.image.editter.on("click",t.proxy(function(){this.image.showEdit(e)},this)),i.append(this.image.editter);var r=this.image.editter.innerWidth();this.image.editter.css("margin-left","-"+r/2+"px")}return this.image.loadResizableControls(e,i)}},showEdit:function(e){if(!this.events.imageEditing){this.observe.image=e;var i=e.closest("a",this.$editor[0]),r=e.closest("figure",this.$editor[0]),n=0!==r.length?r:e;if(this.modal.load("image-edit",this.lang.get("edit"),705),this.image.buttonDelete=this.modal.getDeleteButton().text(this.lang.get("delete")),this.image.buttonSave=this.modal.getActionButton().text(this.lang.get("save")),this.image.buttonDelete.on("click",t.proxy(this.image.remove,this)),
-this.image.buttonSave.on("click",t.proxy(this.image.update,this)),!1===this.opts.imageCaption)t("#redactor-image-caption").val("").hide().prev().hide();else{var s=e.closest(this.opts.imageTag,this.$editor[0]),o=s.find("figcaption");0!==o&&t("#redactor-image-caption").val(o.text()).show()}if(this.opts.imagePosition){var a=0!==r.length?"center"===n.css("text-align"):"block"==n.css("display")&&"none"==n.css("float"),l=a?"center":n.css("float");t("#redactor-image-align").val(l)}else t(".redactor-image-position-option").hide();t("#redactor-image-preview").html(t('<img src="'+e.attr("src")+'" style="max-width: 100%;">')),t("#redactor-image-title").val(e.attr("alt")),0!==i.length&&(t("#redactor-image-link").val(i.attr("href")),"_blank"===i.attr("target")&&t("#redactor-image-link-blank").prop("checked",!0)),t(".redactor-link-tooltip").remove(),this.modal.show(),this.detect.isDesktop()&&t("#redactor-image-title").focus()}},update:function(){var e=this.observe.image,i=e.closest("a",this.core.editor()[0]),r=t("#redactor-image-title").val().replace(/(<([^>]+)>)/gi,"");e.attr("alt",r).attr("title",r),this.image.setFloating(e);var n=t.trim(t("#redactor-image-link").val()).replace(/(<([^>]+)>)/gi,"");if(""!==n){var s="((xn--)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,}",o=new RegExp("^(http|ftp|https)://"+s,"i"),a=new RegExp("^"+s,"i");-1===n.search(o)&&0===n.search(a)&&this.opts.linkProtocol&&(n=this.opts.linkProtocol+"://"+n);var l=!!t("#redactor-image-link-blank").prop("checked");if(0===i.length){var c=t('<a href="'+n+'" id="redactor-img-tmp">'+this.utils.getOuterHtml(e)+"</a>");l&&c.attr("target","_blank"),e=e.replaceWith(c),i=this.core.editor().find("#redactor-img-tmp"),i.removeAttr("id")}else i.attr("href",n),l?i.attr("target","_blank"):i.removeAttr("target")}else 0!==i.length&&i.replaceWith(this.utils.getOuterHtml(e));this.image.addCaption(e,i),this.modal.close(),this.buffer.set()},setFloating:function(e){var i=e.closest("figure",this.$editor[0]),r=0!==i.length?i:e,n=t("#redactor-image-align").val(),s="",o="",a="",l="";switch(n){case"left":s="left",a="0 "+this.opts.imageFloatMargin+" "+this.opts.imageFloatMargin+" 0";break;case"right":s="right",a="0 0 "+this.opts.imageFloatMargin+" "+this.opts.imageFloatMargin;break;case"center":0!==i.length?l="center":(o="block",a="auto")}r.css({float:s,display:o,margin:a,"text-align":l}),r.attr("rel",e.attr("style"))},addCaption:function(e,i){var r=t("#redactor-image-caption").val(),n=0!==i.length?i:e,s=n.next();0!==s.length&&"FIGCAPTION"===s[0].tagName||(s=!1),""!==r?!1===s?(s=t("<figcaption />").text(r),n.after(s)):s.text(r):!1!==s&&s.remove()},remove:function(e,i,r){i=void 0===i?t(this.observe.image):i,"boolean"!=typeof e&&this.buffer.set(),this.events.stopDetectChanges();var n=i.closest("a",this.core.editor()[0]),s=i.closest(this.opts.imageTag,this.core.editor()[0]);i.parent();if(!1===this.core.callback("imageDelete",e,i[0]))return e&&e.preventDefault(),!1;0!==t("#redactor-image-box").length&&t("#redactor-image-box").parent();var o,a;0!==s.length?(a=s.prev(),o=s.next(),s.remove()):0!==n.length?(n.parent(),n.remove()):i.remove(),t("#redactor-image-box").remove(),!1!==e&&(o&&0!==o.length?this.caret.start(o):a&&0!==a.length&&this.caret.end(a)),"boolean"!=typeof e&&this.modal.close(),this.utils.restoreScroll(),this.observe.image=!1,this.events.startDetectChanges(),this.code.sync()}}},indent:function(){return{increase:function(){if(this.list.get()){var e=t(this.selection.current()).closest("li"),i=e.closest("ul, ol",this.core.editor()[0]),r=e.closest("li"),n=r.prev();if(0!==n.length&&"LI"===n[0].tagName)if(this.buffer.set(),this.utils.isCollapsed()){var s=i[0].tagName,o=t("<"+s+" />");this.selection.save();var a=n.find("ol").first();if(1===a.length)a.append(e);else{var s=i[0].tagName,o=t("<"+s+" />");o.append(e),n.append(o)}this.selection.restore()}else document.execCommand("indent"),this.selection.save(),this.indent.removeEmpty(),this.indent.normalize(),this.selection.restore()}},decrease:function(){if(this.list.get()){var e=t(this.selection.current()).closest("li");e.closest("ul, ol",this.core.editor()[0]);this.buffer.set(),document.execCommand("outdent");var i=t(this.selection.current()).closest("li",this.core.editor()[0]);if(this.utils.isCollapsed()&&this.indent.repositionItem(i),0===i.length){document.execCommand("formatblock",!1,"p"),i=t(this.selection.current());var r=i.next();0!==r.length&&"BR"===r[0].tagName&&r.remove()}this.selection.save(),this.indent.removeEmpty(),this.indent.normalize(),this.selection.restore()}},repositionItem:function(t){var e=t.next();0===e.length||"UL"===e[0].tagName&&"OL"===e[0].tagName||t.append(e);var i=t.prev();if(0!==i.length&&"LI"!==i[0].tagName){this.selection.save();t.parents("li",this.core.editor()[0]).after(t),this.selection.restore()}},normalize:function(){this.core.editor().find("li").each(t.proxy(function(e,i){var r=t(i),n="";0!==this.opts.keepStyleAttr.length&&(n=","+this.opts.keepStyleAttr.join(",")),r.find(this.opts.inlineTags.join(",")).not("img"+n).removeAttr("style");var s=r.parent();if(0!==s.length&&"LI"===s[0].tagName)return void s.after(r);var o=r.next();0===o.length||"UL"!==o[0].tagName&&"OL"!==o[0].tagName||r.append(o)},this))},removeEmpty:function(e){var i=this.core.editor().find("ul, ol"),r=this.core.editor().find("li");r.each(t.proxy(function(t,e){this.indent.removeItemEmpty(e)},this)),i.each(t.proxy(function(t,e){this.indent.removeItemEmpty(e)},this)),r.each(t.proxy(function(t,e){this.indent.removeItemEmpty(e)},this))},removeItemEmpty:function(e){var i=e.innerHTML.replace(/[\t\s\n]/g,"");""===(i=i.replace(/<span><\/span>/g,""))&&t(e).remove()}}},inline:function(){return{format:function(t,e,i,r){if(!this.utils.isCurrentOrParent(["PRE","CODE"])){var n=this.inline.getParams(e,i,r);t=this.inline.arrangeTag(t),this.buffer.set(),this.utils.isCollapsed()?this.inline.formatCollapsed(t,n):this.inline.formatUncollapsed(t,n)}},formatCollapsed:function(e,i){var r,n=this.selection.inline();if(n){var s=n.tagName.toLowerCase();if(s===e)if(this.utils.isEmpty(n.innerHTML))this.caret.after(n),t(n).remove();else{var o=this.inline.insertBreakpoint(n,s);this.caret.after(o)}else if(0===t(n).closest(e).length)r=this.inline.insertInline(e),r=this.inline.setParams(r,i);else{var o=this.inline.insertBreakpoint(n,s);this.caret.after(o)}}else r=this.inline.insertInline(e),r=this.inline.setParams(r,i)},formatUncollapsed:function(e,i){this.selection.save();var r=this.inline.getClearedNodes();this.inline.setNodesStriked(r,e,i),this.selection.restore(),document.execCommand("strikethrough"),this.selection.saveInstant();for(var n,s,o=this.core.editor()[0].querySelectorAll('[style*="line-through"]'),a=0,l=o.length;a<l;a++)n=o[0],s=document.createElement("strike"),n.parentNode.insertBefore(s,n),s.appendChild(n),n.style.removeProperty("text-decoration");var c=this;this.core.editor().find("strike").each(function(){var r=c.utils.replaceToTag(this,e);c.inline.setParams(r[0],i);var n=r.find(e),s=r.parent(),o=s.parent();if(0!==o.length&&o[0].tagName.toLowerCase()===e&&o.html()==s[0].outerHTML)return r.replaceWith(function(){return t(this).contents()}),void o.replaceWith(function(){return t(this).contents()});0!==n.length&&c.inline.cleanInsideOrParent(n,i),s.html()==r[0].outerHTML&&c.inline.cleanInsideOrParent(s,i),c.detect.isFirefox()&&c.core.editor().find(e+":empty").remove()}),this.selection.restoreInstant()},cleanInsideOrParent:function(t,e){if(e)for(var i in e.data)this.inline.removeSpecificAttr(t,i,e.data[i])},getClearedNodes:function(){for(var e=this.selection.nodes(),i=[],r=e.length,n=0,s=0;s<r;s++)if(t(e[s]).hasClass("redactor-selection-marker")){n=s+2;break}for(var s=0;s<r;s++)s>=n&&!this.utils.isBlockTag(e[s].tagName)&&i.push(e[s]);return i},isConvertableAttr:function(e,i,r){var n=t(e).attr(i);if(n)if("style"===i){r=t.trim(r).replace(/;$/,"");for(var s=r.split(";"),o=0,a=0;a<s.length;a++){var l=s[a].split(":"),c=t.trim(l[0]),h=t.trim(l[1]);if(-1!==c.search(/color/)){var d=t(e).css(c);!d||d!==h&&this.utils.rgb2hex(d)!==h||o++}else t(e).css(c)===h&&o++}if(o===s.length)return 1}else if(n===r)return 1;return 0},isConvertable:function(t,e,i,r){if(e===i){if(!r)return!0;var n=0;for(var s in r.data)n+=this.inline.isConvertableAttr(t,s,r.data[s]);if(n===Object.keys(r.data).length)return!0}return!1},setNodesStriked:function(e,i,r){for(var n=0;n<e.length;n++){var s=e[n].tagName?e[n].tagName.toLowerCase():void 0,o=e[n].parentNode,a=o&&o.tagName?o.tagName.toLowerCase():void 0,l=this.inline.isConvertable(o,a,i,r);if(l){t(o).replaceWith(function(){return t("<strike>").append(t(this).contents())}).attr("data-redactor-inline-converted")}var l=this.inline.isConvertable(e[n],s,i,r);if(l){t(e[n]).replaceWith(function(){return t("<strike>").append(t(this).contents())})}}},insertBreakpoint:function(e,i){var r=document.createElement("span");r.id="redactor-inline-breakpoint",r=this.insert.node(r);var n=this.utils.isEndOfElement(e),s=this.utils.getOuterHtml(e),o=n?"":"<"+i+">";s=s.replace(/<span id="redactor-inline-breakpoint"><\/span>/i,"</"+i+">"+o);var a=t(s);return t(e).replaceWith(a),""!==o&&this.utils.cloneAttributes(e,a.last()),a.first()},insertInline:function(t){var e=document.createElement(t);return this.insert.node(e),this.caret.start(e),e},arrangeTag:function(t){var e=["b","bold","i","italic","underline","strikethrough","deleted","superscript","subscript"],i=["strong","strong","em","em","u","del","del","sup","sub"];t=t.toLowerCase();for(var r=0;r<e.length;r++)t===e[r]&&(t=i[r]);return t},getStyleParams:function(t){for(var e={},i=t.trim().replace(/;$/,"").split(";"),r=0;r<i.length;r++){var n=i[r].split(":");n&&(e[n[0].trim()]=n[1].trim())}return e},getParams:function(t,e,i){var r=!1,n="toggle";return"object"==typeof t?(r=t,n=void 0!==e?e:n):void 0!==t&&void 0!==e&&(r={},r[t]=e,n=void 0!==i?i:n),!!r&&{func:n,data:r}},setParams:function(e,i){if(i)for(var r in i.data){var n=t(e);"style"===r?(e=this.inline[i.func+"Style"](i.data[r],e),n.attr("data-redactor-style-cache",n.attr("style"))):e="class"===r?this.inline[i.func+"Class"](i.data[r],e):"remove"===i.func?this.inline[i.func+"Attr"](r,e):this.inline[i.func+"Attr"](r,i.data[r],e),"style"===r&&"SPAN"===e.tagName&&n.attr("data-redactor-span",!0)}return e},eachInline:function(t,e){var i,r=void 0===t?this.selection.inlines():[t];if(r)for(var n=0;n<r.length;n++)i=e(r[n])[0];return i},replaceClass:function(e,i){return this.inline.eachInline(i,function(i){return t(i).removeAttr("class").addClass(e)})},toggleClass:function(e,i){return this.inline.eachInline(i,function(i){return t(i).toggleClass(e)})},addClass:function(e,i){return this.inline.eachInline(i,function(i){return t(i).addClass(e)})},removeClass:function(e,i){return this.inline.eachInline(i,function(i){return t(i).removeClass(e)})},removeAllClass:function(e){return this.inline.eachInline(e,function(e){return t(e).removeAttr("class")})},replaceAttr:function(e,i,r){return this.inline.eachInline(r,function(i){return t(i).removeAttr(e).attr(e.value)})},toggleAttr:function(e,i,r){return this.inline.eachInline(r,function(i){return t(i).attr(e)?t(i).removeAttr(e):t(i).attr(e.value)})},addAttr:function(e,i,r){return this.inline.eachInline(r,function(r){return t(r).attr(e,i)})},removeAttr:function(e,i){return this.inline.eachInline(i,function(i){var r=t(i);return r.removeAttr(e),"style"===e&&r.removeAttr("data-redactor-style-cache"),r})},removeAllAttr:function(e){return this.inline.eachInline(e,function(e){for(var i=t(e),r=e.attributes.length,n=0;n<r;n++)i.removeAttr(e.attributes[n].name);return i})},removeSpecificAttr:function(e,i,r){var n=t(e);if("style"===i){var s=r.split(":"),o=s[0].trim();n.css(o,""),this.utils.removeEmptyAttr(e,"style")&&n.removeAttr("data-redactor-style-cache")}else n.removeAttr(i)[0]},hasParentStyle:function(t){var e=t.parent();return 1===e.length&&e[0].tagName===t[0].tagName&&e.html()===t[0].outerHTML&&e},addParentStyle:function(e){var i=this.inline.hasParentStyle(e);if(i){var r=this.inline.getStyleParams(e.attr("style"));i.css(r),i.attr("data-redactor-style-cache",i.attr("style")),e.replaceWith(function(){return t(this).contents()})}else e.attr("data-redactor-style-cache",e.attr("style"));return e},replaceStyle:function(e,i){e=this.inline.getStyleParams(e);var r=this;return this.inline.eachInline(i,function(i){var n=t(i);n.removeAttr("style").css(e);var s=n.attr("style");return s&&n.attr("style",s.replace(/"/g,"'")),n=r.inline.addParentStyle(n)})},toggleStyle:function(e,i){e=this.inline.getStyleParams(e);var r=this;return this.inline.eachInline(i,function(i){var n=t(i);for(var s in e){var o=e[s],a=n.css(s);a=r.utils.isRgb(a)?r.utils.rgb2hex(a):a.replace(/"/g,""),o=r.utils.isRgb(o)?r.utils.rgb2hex(o):o.replace(/"/g,""),a===o?n.css(s,""):n.css(s,o)}var l=n.attr("style");return l&&n.attr("style",l.replace(/"/g,"'")),r.utils.removeEmptyAttr(i,"style")?n.removeAttr("data-redactor-style-cache"):n=r.inline.addParentStyle(n),n})},addStyle:function(e,i){e=this.inline.getStyleParams(e);var r=this;return this.inline.eachInline(i,function(i){var n=t(i);n.css(e);var s=n.attr("style");return s&&n.attr("style",s.replace(/"/g,"'")),n=r.inline.addParentStyle(n)})},removeStyle:function(e,i){e=this.inline.getStyleParams(e);var r=this;return this.inline.eachInline(i,function(i){var n=t(i);for(var s in e)n.css(s,"");return r.utils.removeEmptyAttr(i,"style")?n.removeAttr("data-redactor-style-cache"):n.attr("data-redactor-style-cache",n.attr("style")),n})},removeAllStyle:function(e){return this.inline.eachInline(e,function(e){return t(e).removeAttr("style").removeAttr("data-redactor-style-cache")})},removeStyleRule:function(e){var i=this.selection.parent(),r=this.selection.inlines();this.buffer.set(),i&&"SPAN"===i.tagName&&this.inline.removeStyleRuleAttr(t(i),e);for(var n=0;n<r.length;n++){var s=r[n],o=t(s);-1==t.inArray(s.tagName.toLowerCase(),this.opts.inlineTags)||o.hasClass("redactor-selection-marker")||this.inline.removeStyleRuleAttr(o,e)}},removeStyleRuleAttr:function(t,e){t.css(e,""),this.utils.removeEmptyAttr(t,"style")?t.removeAttr("data-redactor-style-cache"):t.attr("data-redactor-style-cache",t.attr("style"))},update:function(t,e,i,r){t=this.inline.arrangeTag(t);var n=this.inline.getParams(e,i,r),s=this.selection.inlines(),o=[];if(s)for(var a=0;a<s.length;a++){var l=s[a];"*"!==t&&l.tagName.toLowerCase()!==t||o.push(this.inline.setParams(l,n))}return o},removeFormat:function(){this.selection.save();for(var e=this.inline.getClearedNodes(),i=0;i<e.length;i++)1===e[i].nodeType&&t(e[i]).replaceWith(function(){return t(this).contents()});this.selection.restore()}}},insert:function(){return{set:function(t){this.code.set(t),this.focus.end()},html:function(e,i){this.core.editor().focus();var r=this.selection.block(),n=this.selection.inline();void 0===i&&(i=this.clean.getCurrentType(e,!0),e=this.clean.onPaste(e,i,!0)),e=t.parseHTML(e);var s=t(e).last(),o=this.selection.get(),a=this.selection.range(o);if(a.deleteContents(),this.selection.update(o,a),i.lists){var l=t(e);if(0!==l.length&&("UL"===l[0].tagName||"OL"===l[0].tagName))return void this.insert.appendLists(r,l)}if(i.blocks&&r)if(this.utils.isSelectAll())this.core.editor().html(e),this.focus.end();else{var c=this.utils.breakBlockTag();if(!1===c)this.insert.placeHtml(e);else{var h=t(e).children().last();h.append(this.marker.get()),"start"===c.type?c.$block.before(e):c.$block.after(e),this.selection.restore(),this.core.editor().find("p").each(function(){""===t.trim(this.innerHTML)&&t(this).remove()})}}else{if(n){var d=t("<div/>").html(e);d.find(n.tagName.toLowerCase()).each(function(){t(this).contents().unwrap()}),e=d.html(),e=t.parseHTML(e),s=t(e).last()}if(this.utils.isSelectAll()){var u=t(this.opts.emptyHtml);this.core.editor().html("").append(u),u.html(e),this.caret.end(u)}else this.insert.placeHtml(e)}this.utils.disableSelectAll(),i.pre&&this.clean.cleanPre(),this.caret.end(s)},text:function(e){e=e.toString(),e=t.trim(e);var i=document.createElement("div");if(i.innerHTML=e,void 0!==(e=i.textContent||i.innerText)){this.core.editor().focus();var r=this.selection.blocks();if(e=e.replace(/\n/g," "),this.utils.isSelectAll()){var n=t(this.opts.emptyHtml);this.core.editor().html("").append(n),n.html(e),this.caret.end(n)}else{var s=this.selection.get(),o=document.createTextNode(e);if(s.getRangeAt&&s.rangeCount){var a=s.getRangeAt(0);a.deleteContents(),a.insertNode(o),a.setStartAfter(o),a.collapse(!0),this.selection.update(s,a)}r.length>1&&(t(o).wrap("<p>"),this.caret.after(o))}this.utils.disableSelectAll(),this.clean.normalizeCurrentHeading()}},raw:function(t){this.core.editor().focus();var e=this.selection.get(),i=this.selection.range(e);i.deleteContents();var r=document.createElement("div");r.innerHTML=t;for(var n,s,o=document.createDocumentFragment();n=r.firstChild;)s=o.appendChild(n);i.insertNode(o),s&&(i=i.cloneRange(),i.setStartAfter(s),i.collapse(!0),e.removeAllRanges(),e.addRange(i))},node:function(e,i){void 0!==this.start&&this.core.editor().focus(),e=e[0]||e;var r=this.selection.block(),n=this.utils.isBlockTag(e.tagName),s=!0;if(this.utils.isSelectAll())n?this.core.editor().html(e):this.core.editor().html(t("<p>").html(e)),this.code.sync();else if(n&&r){var o=this.utils.breakBlockTag();!1===o?this.insert.placeNode(e,i):("start"===o.type?o.$block.before(e):o.$block.after(e),this.core.editor().find("p:empty").remove())}else s=this.insert.placeNode(e,i);return this.utils.disableSelectAll(),s&&this.caret.end(e),e},appendLists:function(e,i){var r,n=t(e),s=this.utils.isEmpty(e.innerHTML);if(s||this.utils.isEndOfElement(e))r=n,i.find("li").each(function(){r.after(this),r=t(this)}),s&&n.remove();else if(this.utils.isStartOfElement(e))i.find("li").each(function(){n.before(this),r=t(this)});else{var o=this.selection.extractEndOfNode(e);n.after(t("<li>").append(o)),n.append(i),r=i}this.marker.remove(),r&&this.caret.end(r)},placeHtml:function(e){var i=document.createElement("span");i.id="redactor-insert-marker",i=this.insert.node(i),t(i).before(e),this.selection.restore(),this.caret.after(i),t(i).remove()},placeNode:function(t,e){var i=this.selection.get(),r=this.selection.range(i);if(null==r)return!1;!1!==e&&r.deleteContents(),r.insertNode(t),r.collapse(!1),this.selection.update(i,r)},nodeToPoint:function(e,i){if(i=i[0]||i,this.utils.isEmpty())return i=this.utils.isBlock(i)?i:t("<p />").append(i),this.core.editor().html(i),i;var r,n=e.clientX,s=e.clientY;if(document.caretPositionFromPoint){var o=document.caretPositionFromPoint(n,s);r=document.getSelection().getRangeAt(0),r.setStart(o.offsetNode,o.offset),r.collapse(!0),r.insertNode(i)}else if(document.caretRangeFromPoint)r=document.caretRangeFromPoint(n,s),r.insertNode(i);else if(void 0!==document.body.createTextRange){r=document.body.createTextRange(),r.moveToPoint(n,s);var a=r.duplicate();a.moveToPoint(n,s),r.setEndPoint("EndToEnd",a),r.select()}return i},nodeToCaretPositionFromPoint:function(t,e){this.insert.nodeToPoint(t,e)},marker:function(){this.marker.insert()}}},keydown:function(){return{init:function(e){if(!this.rtePaste){var i=e.which,n=i>=37&&i<=40;this.keydown.ctrl=e.ctrlKey||e.metaKey,this.keydown.parent=this.selection.parent(),this.keydown.current=this.selection.current(),this.keydown.block=this.selection.block(),this.keydown.pre=this.utils.isTag(this.keydown.current,"pre"),this.keydown.blockquote=this.utils.isTag(this.keydown.current,"blockquote"),this.keydown.figcaption=this.utils.isTag(this.keydown.current,"figcaption"),this.keydown.figure=this.utils.isTag(this.keydown.current,"figure");if(!1===this.core.callback("keydown",e))return e.preventDefault(),!1;if(this.shortcuts.init(e,i),this.keydown.checkEvents(n,i),this.keydown.setupBuffer(e,i),this.utils.isSelectAll()&&(i===this.keyCode.ENTER||i===this.keyCode.BACKSPACE||i===this.keyCode.DELETE))return e.preventDefault(),this.code.set(this.opts.emptyHtml),void this.events.changeHandler();if(this.keydown.addArrowsEvent(n),this.keydown.setupSelectAll(e,i),!this.opts.enterKey&&i===this.keyCode.ENTER){e.preventDefault();var s=this.selection.get(),o=this.selection.range(s);return void(o.collapsed||o.deleteContents())}if(this.opts.enterKey&&i===this.keyCode.DOWN&&this.keydown.onArrowDown(),this.opts.enterKey&&i===this.keyCode.UP&&this.keydown.onArrowUp(),("textarea"===this.opts.type||"div"===this.opts.type)&&this.keydown.current&&3===this.keydown.current.nodeType&&t(this.keydown.parent).hasClass("redactor-in")&&this.keydown.wrapToParagraph(),!this.keyup.lastShiftKey&&i===this.keyCode.SPACE&&(e.ctrlKey||e.shiftKey))return e.preventDefault(),this.keydown.onShiftSpace();if(i===this.keyCode.ENTER&&(e.ctrlKey||e.shiftKey)&&(null===r||"ios"!==r.platform()))return e.preventDefault(),this.keydown.onShiftEnter(e);if(i===this.keyCode.ENTER&&!e.shiftKey&&!e.ctrlKey&&!e.metaKey)return this.keydown.onEnter(e);if(i===this.keyCode.TAB||e.metaKey&&221===i||e.metaKey&&219===i)return this.keydown.onTab(e,i);if(this.detect.isFirefox()&&i===this.keyCode.BACKSPACE&&this.keydown.block&&"P"===this.keydown.block.tagName&&this.utils.isStartOfElement(this.keydown.block)){var a=t(this.keydown.block).prev();if(0!==a.length)return e.preventDefault(),a.append(this.marker.get()),a.append(t(this.keydown.block).html()),t(this.keydown.block).remove(),void this.selection.restore()}if(i===this.keyCode.BACKSPACE||i===this.keyCode.DELETE){if(this.observe.image&&void 0!==this.observe.image&&0!==t("#redactor-image-box").length){e.preventDefault();var a=this.observe.image.closest("figure, p").prev();return this.image.remove(!1),this.observe.image=!1,void(a&&0!==a.length?this.caret.end(a):this.core.editor().focus())}this.keydown.onBackspaceAndDeleteBefore()}if(i===this.keyCode.DELETE){var l=t(this.keydown.block).next();if(this.utils.isEndOfElement(this.keydown.block)&&0!==l.length&&"FIGURE"===l[0].tagName)return l.remove(),!1;if(!(!this.keydown.block||"LI"!==this.keydown.block.tagName)&&this.keydown.block){var c=t(this.keydown.block).parents("ul, ol").last(),h=c.next();if(this.utils.isRedactorParent(c)&&this.utils.isEndOfElement(c)&&0!==h.length&&("UL"===h[0].tagName||"OL"===h[0].tagName))return e.preventDefault(),c.append(h.contents()),h.remove(),!1}if(this.utils.isEndOfElement(this.keydown.block)&&0!==l.length&&"PRE"===l[0].tagName)return t(this.keydown.block).append(l.text()),l.remove(),!1}if(i===this.keyCode.DELETE&&0!==t("#redactor-image-box").length&&this.image.remove(),i===this.keyCode.BACKSPACE){if(this.detect.isFirefox()&&this.line.removeOnBackspace(e),this.list.combineAfterAndBefore(this.keydown.block))return void e.preventDefault();var d=this.selection.block();if(d&&"LI"===d.tagName&&this.utils.isCollapsed()&&this.utils.isStartOfElement())return this.indent.decrease(),void e.preventDefault();this.keydown.removeInvisibleSpace(),this.keydown.removeEmptyListInTable(e)}i!==this.keyCode.BACKSPACE&&i!==this.keyCode.DELETE||this.keydown.onBackspaceAndDeleteAfter(e)}},onShiftSpace:function(){return this.buffer.set(),this.insert.raw("&nbsp;"),!1},onShiftEnter:function(t){return this.buffer.set(),this.keydown.pre?this.keydown.insertNewLine(t):this.insert.raw("<br>")},onBackspaceAndDeleteBefore:function(){this.utils.saveScroll()},onBackspaceAndDeleteAfter:function(e){setTimeout(t.proxy(function(){this.code.syncFire=!1,this.keydown.removeEmptyLists();var t="";0!==this.opts.keepStyleAttr.length&&(t=","+this.opts.keepStyleAttr.join(",")),this.core.editor().find("*[style]").not("img, figure, iframe, #redactor-image-box, #redactor-image-editter, [data-redactor-style-cache], [data-redactor-span]"+t).removeAttr("style"),this.keydown.formatEmpty(e),this.code.syncFire=!0},this),1)},onEnter:function(e){if(!1===this.core.callback("enter",e))return e.preventDefault(),!1;if(this.keydown.blockquote&&!0===this.keydown.exitFromBlockquote(e))return!1;if(this.keydown.pre)return this.keydown.insertNewLine(e);if(this.keydown.blockquote||this.keydown.figcaption)return this.keydown.insertBreakLine(e);if(this.keydown.figure)setTimeout(t.proxy(function(){this.keydown.replaceToParagraph("FIGURE")},this),1);else if(this.keydown.block){if(setTimeout(t.proxy(function(){this.keydown.replaceToParagraph("DIV")},this),1),"LI"===this.keydown.block.tagName){var i=this.selection.current(),r=t(i).closest("li",this.$editor[0]),n=r.parents("ul,ol",this.$editor[0]).last();if(0!==r.length&&this.utils.isEmpty(r.html())&&0===n.next().length&&this.utils.isEmpty(n.find("li").last().html())){n.find("li").last().remove();var s=t(this.opts.emptyHtml);return n.after(s),this.caret.start(s),!1}}}else if(!this.keydown.block)return this.keydown.insertParagraph(e);if(this.detect.isFirefox()&&this.utils.isInline(this.keydown.parent))return void this.keydown.insertBreakLine(e);this.opts.keepInlineOnEnter||setTimeout(t.proxy(function(){var e=this.selection.inline();if(e&&this.utils.isEmpty(e.innerHTML)){var i=this.selection.block();t(e).remove();var r=document.createRange();r.setStart(i,0);var n=document.createTextNode("​");r.insertNode(n),r.setStartAfter(n),r.collapse(!0);var s=window.getSelection();s.removeAllRanges(),s.addRange(r)}},this),1)},checkEvents:function(t,e){t||"click"!==this.core.getEvent()&&"arrow"!==this.core.getEvent()||(this.core.addEvent(!1),this.keydown.checkKeyEvents(e)&&this.buffer.set())},checkKeyEvents:function(e){var i=this.keyCode,r=[i.BACKSPACE,i.DELETE,i.ENTER,i.ESC,i.TAB,i.CTRL,i.META,i.ALT,i.SHIFT];return-1===t.inArray(e,r)},addArrowsEvent:function(t){if(t)return"click"===this.core.getEvent()||"arrow"===this.core.getEvent()?void this.core.addEvent(!1):void this.core.addEvent("arrow")},setupBuffer:function(t,e){return this.keydown.ctrl&&90===e&&!t.shiftKey&&!t.altKey&&this.sBuffer.length?(t.preventDefault(),void this.buffer.undo()):this.keydown.ctrl&&90===e&&t.shiftKey&&!t.altKey&&0!==this.sRebuffer.length?(t.preventDefault(),void this.buffer.redo()):void(this.keydown.ctrl||e!==this.keyCode.SPACE&&e!==this.keyCode.BACKSPACE&&e!==this.keyCode.DELETE&&(e!==this.keyCode.ENTER||t.ctrlKey||t.shiftKey)||this.buffer.set())},exitFromBlockquote:function(e){if(this.utils.isEndOfElement(this.keydown.blockquote)){if(-1!==this.clean.removeSpacesHard(t(this.keydown.blockquote).html()).search(/(<br\s?\/?>){1}$/i)){e.preventDefault();t(this.keydown.blockquote).children().last().filter("br").remove(),t(this.keydown.blockquote).children().last().filter("span").remove();var i=t(this.opts.emptyHtml);return t(this.keydown.blockquote).after(i),this.caret.start(i),!0}}},onArrowDown:function(){for(var t=[this.keydown.blockquote,this.keydown.pre,this.keydown.figcaption],e=0;e<t.length;e++)if(t[e])return this.keydown.insertAfterLastElement(t[e]),!1},onArrowUp:function(){for(var t=[this.keydown.blockquote,this.keydown.pre,this.keydown.figcaption],e=0;e<t.length;e++)if(t[e])return this.keydown.insertBeforeFirstElement(t[e]),!1},insertAfterLastElement:function(e){if(this.utils.isEndOfElement(e)){var i=this.core.editor().contents().last();if(0===("FIGCAPTION"===e.tagName?t(this.keydown.block).parent().next():t(this.keydown.block).next()).length){if(0===i.length&&i[0]!==e)return void this.caret.start(i);var r=t(this.opts.emptyHtml);"FIGCAPTION"===e.tagName?t(e).parent().after(r):t(e).after(r),this.caret.start(r)}}},insertBeforeFirstElement:function(e){if(this.utils.isStartOfElement()&&!(this.core.editor().contents().length>1&&this.core.editor().contents().first()[0]!==e)){var i=t(this.opts.emptyHtml);t(e).before(i),this.caret.start(i)}},onTab:function(t,e){if(!this.opts.tabKey)return!0;var i=this.keydown.block&&"LI"===this.keydown.block.tagName;if(this.utils.isEmpty(this.code.get())||!i&&!this.keydown.pre&&!1===this.opts.tabAsSpaces)return!0;t.preventDefault(),this.buffer.set();var r,n=i&&this.utils.isStartOfElement(this.keydown.block);return this.keydown.pre&&!t.shiftKey?(r=this.opts.preSpaces?document.createTextNode(Array(this.opts.preSpaces+1).join(" ")):document.createTextNode("\t"),this.insert.node(r)):!1===this.opts.tabAsSpaces||n?t.metaKey&&219===e?this.indent.decrease():t.metaKey&&221===e?this.indent.increase():t.shiftKey?this.indent.decrease():this.indent.increase():(r=document.createTextNode(Array(this.opts.tabAsSpaces+1).join(" ")),this.insert.node(r)),!1},setupSelectAll:function(t,e){this.keydown.ctrl&&65===e?this.utils.enableSelectAll():e===this.keyCode.LEFT_WIN||this.keydown.ctrl||this.utils.disableSelectAll()},insertNewLine:function(t){t.preventDefault();var e=document.createTextNode("\n"),i=this.selection.get(),r=this.selection.range(i);return r.deleteContents(),r.insertNode(e),this.caret.after(e),!1},insertParagraph:function(t){t.preventDefault();var e=document.createElement("p");e.innerHTML="<br>";var i=this.selection.get(),r=this.selection.range(i);return r.deleteContents(),r.insertNode(e),this.caret.start(e),!1},insertBreakLine:function(t){return this.keydown.insertBreakLineProcessing(t)},insertDblBreakLine:function(t){return this.keydown.insertBreakLineProcessing(t,!0)},insertBreakLineProcessing:function(t,e){t.stopPropagation();var i=document.createElement("br");if(this.insert.node(i),!0===e){var r=document.createElement("br");this.insert.node(r),this.caret.after(r)}else this.caret.after(i);return!1},wrapToParagraph:function(){var e=t(this.keydown.current),i=t("<p>").append(e.clone());e.replaceWith(i);var r=t(i).next();void 0!==r[0]&&"BR"===r[0].tagName&&r.remove(),this.caret.end(i)},replaceToParagraph:function(e){var i=this.selection.block(),r=t(i).prev(),n=i.innerHTML.replace(/<br\s?\/?>/gi,"");if(i.tagName===e&&this.utils.isEmpty(n)&&!t(i).hasClass("redactor-in")){var s=document.createElement("p");return t(i).replaceWith(s),this.keydown.setCaretToParagraph(s),!1}if("P"===i.tagName)return t(i).removeAttr("class").removeAttr("style"),this.detect.isIe()&&this.utils.isEmpty(n)&&this.utils.isInline(this.keydown.parent)&&t(i).on("input",t.proxy(function(){var e=this.selection.parent();if(this.utils.isInline(e)){var r=t(e).html();t(i).html(r),this.caret.end(i)}t(i).off("keyup")},this)),!1;if(r.hasClass(this.opts.videoContainerClass)){r.removeAttr("class");var s=document.createElement("p");return r.replaceWith(s),this.keydown.setCaretToParagraph(s),!1}},setCaretToParagraph:function(t){var e=document.createRange();e.setStart(t,0);var i=document.createTextNode("​");e.insertNode(i),e.setStartAfter(i),e.collapse(!0);var r=window.getSelection();r.removeAllRanges(),r.addRange(e)},removeInvisibleSpace:function(){var e=t(this.keydown.current);0===e.text().search(/^\u200B$/g)&&e.remove()},removeEmptyListInTable:function(e){var i=t(this.keydown.current),r=t(this.keydown.parent),n=i.closest("td",this.$editor[0]);if(0!==n.length&&i.closest("li",this.$editor[0])&&1===r.children("li").length){if(!this.utils.isEmpty(i.text()))return;e.preventDefault(),i.remove(),r.remove(),this.caret.start(n)}},removeEmptyLists:function(){var e=function(){""===t.trim(this.innerHTML).replace(/\/t\/n/g,"")&&t(this).remove()};this.core.editor().find("li").each(e),this.core.editor().find("ul, ol").each(e)},formatEmpty:function(e){var i=t.trim(this.core.editor().html());if(this.utils.isEmpty(i)){if(e.preventDefault(),"inline"===this.opts.type||"pre"===this.opts.type)this.core.editor().html(this.marker.html()),this.selection.restore();else{var n=function(){this.core.editor().html(this.opts.emptyHtml),this.focus.start()}.bind(this);null!==r&&"ios"===r.platform()?setTimeout(n,50):n()}return!1}}}},keyup:function(){return{init:function(e){if(!this.rtePaste){var i=e.which;this.keyup.block=this.selection.block(),this.keyup.current=this.selection.current(),this.keyup.parent=this.selection.parent(),this.keyup.lastShiftKey=e.shiftKey;if(!1===this.core.callback("keyup",e))return e.preventDefault(),!1;if(i===this.keyCode.ENTER&&this.keyup.block&&"FIGURE"===this.keyup.block.tagName){var r=t(this.keyup.block).prev();if(0!==r.length&&"FIGURE"===r[0].tagName){var n=this.utils.replaceToTag(r,"p");return void this.caret.start(n)}}if(i===this.keyCode.BACKSPACE||i===this.keyCode.DELETE){if(this.utils.isSelectAll())return void this.focus.start()
-;if(this.keyup.block&&this.keydown.block&&"FIGURE"===this.keyup.block.tagName&&this.utils.isStartOfElement(this.keydown.block)){e.preventDefault(),this.selection.save(),t(this.keyup.block).find("figcaption").remove(),t(this.keyup.block).find("img").first().remove(),this.utils.replaceToTag(this.keyup.block,"p");var s=this.marker.find();return t("html, body").animate({scrollTop:s.position().top+20},500),void this.selection.restore()}if(this.keyup.block&&"P"===this.keyup.block.tagName){var o=t(this.keyup.block).find("img").length;""===t(this.keyup.block).text().replace(/\u200B/g,"")&&0!==o&&this.utils.replaceToTag(this.keyup.block,"figure")}this.keyup.block&&"FIGURE"===this.keyup.block.tagName&&0===t(this.keyup.block).find("img").length&&(this.selection.save(),this.utils.replaceToTag(this.keyup.block,"p"),this.selection.restore())}}}}},lang:function(){return{load:function(){this.opts.curLang=this.opts.langs[this.opts.lang]},get:function(t){return void 0!==this.opts.curLang[t]?this.opts.curLang[t]:""}}},line:function(){return{insert:function(){this.buffer.set(),this.insert.html(this.line.getLineHtml());var t=this.core.editor().find("#redactor-hr-tmp-id");return t.removeAttr("id"),this.core.callback("insertedLine",t),t},getLineHtml:function(){var t='<hr id="redactor-hr-tmp-id" />';return!this.detect.isFirefox()&&this.utils.isEmpty()&&(t+="<p>"+this.opts.emptyHtml+"</p>"),t},removeOnBackspace:function(e){if(this.utils.isCollapsed()){var i=t(this.selection.block());if(0!==i.length&&this.utils.isStartOfElement(i)){var r=i.prev();r&&0!==r.length&&"HR"===r[0].tagName&&(e.preventDefault(),r.remove())}}}}},link:function(){return{get:function(){return t(this.selection.inlines("a"))},is:function(){var e=this.selection.nodes(),i=t(this.selection.current()).closest("a",this.core.editor()[0]);return!(0===i.length||e.length>1)&&i},unlink:function(t){void 0!==t&&t.preventDefault&&t.preventDefault(),this.buffer.set();var e=this.selection.inlines("a");if(0!==e.length){var i=this.link.replaceLinksToText(e);this.observe.closeAllTooltip(),this.core.callback("deletedLink",i)}},insert:function(e,i){var r=this.link.is();if(!0!==i&&!1===(e=this.link.buildLinkFromObject(r,e)))return!1;if(this.buffer.set(),e=this.core.callback("beforeInsertingLink",e),!1===r){r=t("<a />"),r=this.link.update(r,e),r=t(this.insert.node(r));var n=r.parent();!1===this.utils.isRedactorParent(n)&&r.wrap("<p>"),n.hasClass("redactor-unlink")&&n.replaceWith(function(){return t(this).contents()}),this.caret.after(r),this.core.callback("insertedLink",r)}else r=this.link.update(r,e),this.caret.after(r);return r},update:function(t,e){return t.text(e.text),t.attr("href",e.url),this.link.target(t,e.target),t},target:function(t,e){return e?t.attr("target","_blank"):t.removeAttr("target")},show:function(e){void 0!==e&&e.preventDefault&&e.preventDefault(),this.observe.closeAllTooltip();var i=this.link.is();this.link.buildModal(i);var r=this.link.buildLinkFromElement(i);r.url=this.link.removeSelfHostFromUrl(r.url),this.opts.linkNewTab&&!i&&(r.target=!0),this.link.setModalValues(r),this.modal.show(),this.detect.isDesktop()&&t("#redactor-link-url").focus()},setModalValues:function(e){t("#redactor-link-blank").prop("checked",e.target),t("#redactor-link-url").val(e.url),t("#redactor-link-url-text").val(e.text)},buildModal:function(e){this.modal.load("link",this.lang.get(!1===e?"link-insert":"link-edit"),600),this.modal.getActionButton().text(this.lang.get(!1===e?"insert":"save")).on("click",t.proxy(this.link.callback,this))},callback:function(){var t=this.link.buildLinkFromModal();if(!1===t)return!1;this.modal.close(),this.link.insert(t,!0)},cleanUrl:function(e){return void 0===e?"":t.trim(e.replace(/[^\W\w\D\d+&\'@#/%?=~_|!:,.;\(\)]/gi,""))},cleanText:function(e){return void 0===e?"":t.trim(e.replace(/(<([^>]+)>)/gi,""))},getText:function(t){return""===t.text&&""!==t.url?this.link.truncateUrl(t.url.replace(/<|>/g,"")):t.text},isUrl:function(t){return!!new RegExp("^((https?|ftp):\\/\\/)?(([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$","i").test(t)&&t},isMailto:function(t){return-1!==t.search("@")&&!1===/(http|ftp|https):\/\//i.test(t)},isEmpty:function(t){return""===t.url||""===t.text&&""===t.url},truncateUrl:function(t){return t.length>this.opts.linkSize?t.substring(0,this.opts.linkSize)+"...":t},parse:function(t){return this.link.isMailto(t.url)?t.url="mailto:"+t.url.replace("mailto:",""):0!==t.url.search("#")&&this.opts.linkValidation&&(t.url=this.link.isUrl(t.url)?"http://"+t.url.replace(/(ftp|https?):\/\//gi,""):t.url),!this.link.isEmpty(t)&&!1!==t.url&&t},buildLinkFromModal:function(){var e={};return e.url=this.link.cleanUrl(t("#redactor-link-url").val()),e.text=this.link.cleanText(t("#redactor-link-url-text").val()),e.text=this.link.getText(e),e.target=!!t("#redactor-link-blank").prop("checked"),this.link.parse(e)},buildLinkFromObject:function(t,e){return e.url=this.link.cleanUrl(e.url),e.text=void 0===e.text&&this.selection.is()?this.selection.text():this.link.cleanText(e.text),e.text=this.link.getText(e),e.target=!1===t?e.target:this.link.buildTarget(t),this.link.parse(e)},buildLinkFromElement:function(t){var e={url:"",text:this.selection.is()?this.selection.text():"",target:!1};return!1!==t&&(e.url=t.attr("href"),e.text=t.text(),e.target=this.link.buildTarget(t)),e},buildTarget:function(t){return void 0!==t.attr("target")&&"_blank"===t.attr("target")},removeSelfHostFromUrl:function(t){var e=self.location.href.replace("#","").replace(/\/$/i,"");return t.replace(/^\/\#/,"#").replace(e,"").replace("mailto:","")},replaceLinksToText:function(e){var i,r=t.each(e,function(e,r){var n=t(r),s=t('<span class="redactor-unlink" />').append(n.contents());return n.replaceWith(s),0===e&&(i=s),n});return 1===e.length&&this.selection.isCollapsed()&&this.caret.after(i),r}}},linkify:function(){return{isKey:function(){},isLink:function(){},isFiltered:function(){},handler:function(){},format:function(){},convertVideoLinks:function(){},convertImages:function(){},convertLinks:function(){}}},list:function(){return{toggle:function(e){if(!this.utils.inBlocks(["table","td","th","tr"])){e="orderedlist"===e?"ol":e,e="unorderedlist"===e?"ul":e,e=e.toLowerCase(),this.buffer.set(),this.selection.save();var i=this.list._getBlocks(),r=this.selection.block(),n=t(r).parents("ul, ol").last();return 0===i.length&&0!==n.length&&(i=[n.get(0)]),i=this.list._isUnformat(e,i)?this.list._unformat(e,i):this.list._format(e,i),this.selection.restore(),i}},get:function(){var e=this.selection.current(),i=t(e).closest("ul, ol",this.core.editor()[0]);return 0!==i.length&&i},combineAfterAndBefore:function(e){var i=t(e).prev(),r=t(e).next(),n=e&&"P"===e.tagName&&("<br>"===e.innerHTML||""===e.innerHTML),s=1===i.closest("ol, ul",this.core.editor()[0]).length&&1===r.closest("ol, ul",this.core.editor()[0]).length;return!(!n||!s)&&(i.children("li").last().append(this.marker.get()),i.append(r.contents()),this.selection.restore(),!0)},_getBlocks:function(){for(var e=[],i=this.selection.blocks(),r=0;r<i.length;r++){t(i[r]).parent().hasClass("redactor-in")&&e.push(i[r])}return e},_isUnformat:function(t,e){for(var i=0,r=0;r<e.length;r++)if(3!==e[r].nodeType){var n=e[r].tagName.toLowerCase();n!==t&&"figure"!==n||i++}return i===e.length},_uniteBlocks:function(e,i){for(var r=0,n={0:[]},s=!1,o=0;o<e.length;o++){var a=t(e[o]),l=a.closest("th, td");0!==l.length?(l.get(0)!==s&&(r++,n[r]=[]),this.list._isUniteBlock(e[o],i)&&n[r].push(e[o])):this.list._isUniteBlock(e[o],i)?n[r].push(e[o]):(r++,n[r]=[]),s=l.get()}return n},_isUniteBlock:function(t,e){return 3===t.nodeType||-1!==e.indexOf(t.tagName.toLowerCase())},_createList:function(e,i,r){var n=i[i.length-1],s=t(n),o=t("<"+e+">");return s.after(o),o},_createListItem:function(e){var i=t("<li>");if(3===e.nodeType)i.append(e);else{var r=t(e);i.append(r.contents()),r.remove()}return i},_format:function(e,i){var r=["p","div","blockquote","pre","h1","h2","h3","h4","h5","h6","ul","ol"],n=this.list._uniteBlocks(i,r),s=[];for(var o in n){for(var a=n[o],l=this.list._createList(e,n[o]),c=0;c<a.length;c++){var h;3===a[c].nodeType||"UL"!==a[c].tagName&&"OL"!==a[c].tagName?(h=this.list._createListItem(a[c]),l.append(h)):(h=t(a[c]).contents(),l.append(h))}s.push(l.get(0))}return s},_unformat:function(e,i){if(1===i.length){var r=t(i[0]),n=r.find("li"),s=this.selection.blocks(["li"]),o=this.selection.block(),a=t(o).closest("li");if(0===s.length&&0!==a.length&&(s=[a.get(0)]),s.length===n.length)return this.list._unformatEntire(i[0]);var l=this.list._getItemsPosition(n,s);if("Top"===l)return this.list._unformatAtSide("before",s,r);if("Bottom"===l)return s.reverse(),this.list._unformatAtSide("after",s,r);if("Middle"===l){var c=t(s[s.length-1]),h=!1,d=!1,u=t("<"+r.get(0).tagName.toLowerCase()+">");n.each(function(e,i){if(h){var r=t(i);r.children("ul, ol").length;0!==r.closest(".redactor-split-item").length||!1!==d&&0!==r.closest(d).length||r.addClass("redactor-split-item"),d=r}i===c.get(0)&&(h=!0)}),n.filter(".redactor-split-item").each(function(e,i){t(i).removeClass("redactor-split-item"),u.append(i)}),r.after(u),s.reverse();for(var p=0;p<s.length;p++){var f=t(s[p]),g=this.list._createUnformatContainer(f);r.after(g),g.find("ul, ol").remove(),f.remove()}return}}else for(var p=0;p<i.length;p++)3!==i[p].nodeType&&i[p].tagName.toLowerCase()===e&&this.list._unformatEntire(i[p])},_unformatEntire:function(e){var i=t(e);i.find("li").each(function(e,r){var n=t(r),s=this.list._createUnformatContainer(n);n.remove(),i.before(s)}.bind(this)),i.remove()},_unformatAtSide:function(e,i,r){for(var n=0;n<i.length;n++){var s=t(i[n]),o=this.list._createUnformatContainer(s);r[e](o);var a=o.find("ul, ol").first();s.append(a),a.each(function(e,r){var n=t(r),s=n.closest("li");s.get(0)===i[e]&&(n.unwrap(),s.addClass("r-unwrapped"))}),this.utils.isEmpty(s.html())&&s.remove()}r.find(".r-unwrapped").each(function(e){var i=t(e);""===i.html().trim()?i.remove():i.removeClass("r-unwrapped")})},_getItemsPosition:function(t,e){var i="Middle",r=e[0],n=e[e.length-1],s=t.first().get(0),o=t.last().get(0);return s===r&&o!==n?i="Top":s!==r&&o===n&&(i="Bottom"),i},_createUnformatContainer:function(e){var i=t("<p>");return i.append(e.contents()),i}}},marker:function(){return{get:function(t){t=void 0===t?1:t;var e=document.createElement("span");return e.id="selection-marker-"+t,e.className="redactor-selection-marker",e.innerHTML=this.opts.invisibleSpace,e},html:function(t){return this.utils.getOuterHtml(this.marker.get(t))},find:function(t){return t=void 0===t?1:t,this.core.editor().find("span#selection-marker-"+t)},insert:function(){var t=this.selection.get(),e=this.selection.range(t);this.marker.insertNode(e,this.marker.get(1),!0),e&&!1===e.collapsed&&this.marker.insertNode(e,this.marker.get(2),!1)},remove:function(){this.core.editor().find(".redactor-selection-marker").each(this.marker.iterateRemove)},insertNode:function(e,i,r){var n=this.selection.parent();if(null!==e&&0!==t(n).closest(".redactor-in").length){e=e.cloneRange();try{e.collapse(r),e.insertNode(i)}catch(t){this.focus.start()}}},iterateRemove:function(e,i){var r=t(i),n=r.text().replace(/\u200B/g,"");r.parent()[0];""===n?r.remove():r.replaceWith(function(){return t(this).contents()})}}},modal:function(){return{callbacks:{},templates:function(){this.opts.modal={"image-edit":"",image:"",file:"",link:String()+'<div class="redactor-modal-tab" data-title="General"><section><label>URL</label><input type="url" id="redactor-link-url" aria-label="URL" /></section><section><label>'+this.lang.get("text")+'</label><input type="text" id="redactor-link-url-text" aria-label="'+this.lang.get("text")+'" /></section><section><label class="checkbox"><input type="checkbox" id="redactor-link-blank"> '+this.lang.get("link-in-new-tab")+'</label></section><section><button id="redactor-modal-button-action">'+this.lang.get("insert")+'</button><button id="redactor-modal-button-cancel">'+this.lang.get("cancel")+"</button></section></div>"},t.extend(this.opts,this.opts.modal)},addCallback:function(t,e){this.modal.callbacks[t]=e},addTemplate:function(t,e){this.opts.modal[t]=e},getTemplate:function(t){return this.opts.modal[t]},getModal:function(){return this.$modalBody},getActionButton:function(){return this.$modalBody.find("#redactor-modal-button-action")},getCancelButton:function(){return this.$modalBody.find("#redactor-modal-button-cancel")},getDeleteButton:function(){return this.$modalBody.find("#redactor-modal-button-delete")},load:function(){},show:function(){},buildWidth:function(){},buildTabber:function(){},showTab:function(){},setTitle:function(){},setContent:function(){this.$modalBody.html(this.modal.getTemplate(this.modal.templateName)),this.modal.getCancelButton().on("mousedown",t.proxy(this.modal.close,this))},setDraggable:function(){},setEnter:function(){},build:function(){this.modal.buildOverlay(),this.$modalBox=t('<div id="redactor-modal-box"/>').hide(),this.$modal=t('<div id="redactor-modal" role="dialog" />'),this.$modalHeader=t('<div id="redactor-modal-header" />'),this.$modalClose=t('<button type="button" id="redactor-modal-close" aria-label="'+this.lang.get("close")+'" />').html("&times;"),this.$modalBody=t('<div id="redactor-modal-body" />'),this.$modal.append(this.$modalHeader),this.$modal.append(this.$modalBody),this.$modal.append(this.$modalClose),this.$modalBox.append(this.$modal),this.$modalBox.appendTo(document.body)},buildOverlay:function(){this.$modalOverlay=t('<div id="redactor-modal-overlay">').hide(),t("body").prepend(this.$modalOverlay)},enableEvents:function(){},disableEvents:function(){},closeHandler:function(){},close:function(){}}},observe:function(){return{load:function(){void 0===this.opts.destroyed&&(this.observe.links(),this.observe.images())},isCurrent:function(e,i){return void 0===i&&(i=t(this.selection.current())),i.is(e)||i.parents(e).length>0},toolbar:function(){this.observe.buttons(),this.observe.dropdowns()},buttons:function(e,i){var r=this.selection.current(),n=this.selection.parent();if(!1!==e?this.button.setInactiveAll():this.button.setInactiveAll(i),!1===e&&"html"!==i)return void(-1!==t.inArray(i,this.opts.activeButtons)&&this.button.toggleActive(i));this.utils.isRedactorParent(r)&&("none"!==this.core.editor().css("display")&&(this.utils.isCurrentOrParentHeader()||this.utils.isCurrentOrParent(["table","pre","blockquote","li"])?this.button.disable("horizontalrule"):this.button.enable("horizontalrule")),t.each(this.opts.activeButtonsStates,t.proxy(function(e,i){var s=t(n).closest(e,this.$editor[0]),o=t(r).closest(e,this.$editor[0]);(0===s.length||this.utils.isRedactorParent(s))&&this.utils.isRedactorParent(o)&&(0===s.length&&0===o.closest(e,this.$editor[0]).length||this.button.setActive(i))},this)))},dropdowns:function(){var e=t("<div />").html(this.selection.html()).find("a").length,i=t(this.selection.current()),r=this.utils.isRedactorParent(i);t.each(this.opts.observe.dropdowns,t.proxy(function(t,n){var s=n.observe,o=s.element,a=n.item,l=void 0!==s.in&&s.in,c=void 0!==s.out&&s.out;i.closest(o).length>0&&r||"a"===o&&0!==e?this.observe.setDropdownProperties(a,l,c):this.observe.setDropdownProperties(a,c,l)},this))},setDropdownProperties:function(t,e,i){i&&void 0!==i.attr&&this.observe.setDropdownAttr(t,i.attr,!0),void 0!==e.attr&&this.observe.setDropdownAttr(t,e.attr),void 0!==e.title&&t.find("span").text(e.title)},setDropdownAttr:function(e,i,r){t.each(i,function(t,i){"class"===t?r?e.removeClass(i):e.addClass(i):r?e.removeAttr(t):e.attr(t,i)})},addDropdown:function(t,e,i){void 0!==i.observe&&(i.item=t,this.opts.observe.dropdowns.push(i))},images:function(){this.opts.imageEditable&&(this.core.editor().addClass("redactor-layer-img-edit"),this.core.editor().find("img").each(t.proxy(function(e,i){var r=t(i);r.closest("a",this.$editor[0]).on("click",function(t){t.preventDefault()}),this.image.setEditable(r)},this)))},links:function(){this.opts.linkTooltip&&this.core.editor().find("a").each(t.proxy(function(e,i){var r=t(i);!0!==r.data("cached")&&(r.data("cached",!0),r.on("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,t.proxy(this.observe.showTooltip,this)))},this))},getTooltipPosition:function(t){return t.offset()},showTooltip:function(e){var i=t(e.target);if("IMG"!==i[0].tagName&&("A"!==i[0].tagName&&(i=i.closest("a",this.$editor[0])),"A"===i[0].tagName)){var r=i,n=this.observe.getTooltipPosition(r),s=t('<span class="redactor-link-tooltip"></span>'),o=r.attr("href");void 0===o&&(o=""),o.length>24&&(o=o.substring(0,24)+"...");var a=t('<a href="'+r.attr("href")+'" target="_blank" />').html(o).addClass("redactor-link-tooltip-action"),l=t('<a href="#" />').html(this.lang.get("edit")).on("click",t.proxy(this.link.show,this)).addClass("redactor-link-tooltip-action"),c=t('<a href="#" />').html(this.lang.get("unlink")).on("click",t.proxy(this.link.unlink,this)).addClass("redactor-link-tooltip-action");s.append(a).append(" | ").append(l).append(" | ").append(c);var h=parseInt(r.css("line-height"),10),d=Math.ceil((e.pageY-n.top)/h),u=n.top+d*h;s.css({top:u+"px",left:n.left+"px"}),t(".redactor-link-tooltip").remove(),t("body").append(s),this.core.editor().on("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,t.proxy(this.observe.closeTooltip,this)),t(document).on("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,t.proxy(this.observe.closeTooltip,this))}},closeAllTooltip:function(){t(".redactor-link-tooltip").remove()},closeTooltip:function(e){e=e.originalEvent||e;var i=e.target,r=t(i).closest("a",this.$editor[0]);0!==r.length&&"A"===r[0].tagName&&"A"!==i.tagName||"A"===i.tagName&&this.utils.isRedactorParent(i)||t(i).hasClass("redactor-link-tooltip-action")||(this.observe.closeAllTooltip(),this.core.editor().off("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,t.proxy(this.observe.closeTooltip,this)),t(document).off("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,t.proxy(this.observe.closeTooltip,this)))}}},offset:function(){return{get:function(e){var i=this.offset.clone(e);if(!1===i)return 0;var r=document.createElement("div");return r.appendChild(i.cloneContents()),r.innerHTML=r.innerHTML.replace(/<img(.*?[^>])>$/gi,"i"),t.trim(t(r).text()).replace(/[\t\n\r\n]/g,"").replace(/\u200B/g,"").length},clone:function(t){var e=this.selection.get(),i=this.selection.range(e);if(null===i&&void 0===t)return!1;if(!1===(t=void 0===t?this.$editor:t))return!1;t=t[0]||t;var r=i.cloneRange();return r.selectNodeContents(t),r.setEnd(i.endContainer,i.endOffset),r},set:function(t,e){e=void 0===e?t:e,this.focus.is()||this.focus.start();for(var i,r=this.selection.get(),n=this.selection.range(r),s=0,o=document.createTreeWalker(this.$editor[0],NodeFilter.SHOW_TEXT,null,null);null!==(i=o.nextNode());)if(s+=i.nodeValue.length,s>t&&(n.setStart(i,i.nodeValue.length+t-s),t=1/0),s>=e){n.setEnd(i,i.nodeValue.length+e-s);break}n.collapse(!1),this.selection.update(r,n)}}},paragraphize:function(){return{load:function(e){return!1===this.opts.paragraphize||"inline"===this.opts.type||"pre"===this.opts.type?e:""===e||"<p></p>"===e?this.opts.emptyHtml:(e+="\n",this.paragraphize.safes=[],this.paragraphize.z=0,e=e.replace(/(<br\s?\/?>){1,}\n?<\/blockquote>/gi,"</blockquote>"),e=e.replace(/<\/pre>/gi,"</pre>\n\n"),e=e.replace(/<p>\s<br><\/p>/gi,"<p></p>"),e=this.paragraphize.getSafes(e),e=e.replace("<br>","\n"),e=this.paragraphize.convert(e),e=this.paragraphize.clear(e),e=this.paragraphize.restoreSafes(e),e=e.replace(new RegExp("<br\\s?/?>\n?<("+this.opts.paragraphizeBlocks.join("|")+")(.*?[^>])>","gi"),"<p><br /></p>\n<$1$2>"),t.trim(e))},getSafes:function(e){var i=t("<div />").append(e);return i.find("blockquote p").replaceWith(function(){return t(this).append("<br />").contents()}),i.find(this.opts.paragraphizeBlocks.join(", ")).each(t.proxy(function(e,i){return this.paragraphize.z++,this.paragraphize.safes[this.paragraphize.z]=i.outerHTML,t(i).replaceWith("\n#####replace"+this.paragraphize.z+"#####\n\n")},this)),i.find("span.redactor-selection-marker").each(t.proxy(function(e,i){return this.paragraphize.z++,this.paragraphize.safes[this.paragraphize.z]=i.outerHTML,t(i).replaceWith("\n#####replace"+this.paragraphize.z+"#####\n\n")},this)),i.html()},restoreSafes:function(e){return t.each(this.paragraphize.safes,function(t,i){i=void 0!==i?i.replace(/\$/g,"&#36;"):i,e=e.replace("#####replace"+t+"#####",i)}),e},convert:function(e){e=e.replace(/\r\n/g,"xparagraphmarkerz"),e=e.replace(/\n/g,"xparagraphmarkerz"),e=e.replace(/\r/g,"xparagraphmarkerz");var i=/\s+/g;e=e.replace(i," "),e=t.trim(e);var r=/xparagraphmarkerzxparagraphmarkerz/gi;e=e.replace(r,"</p><p>");var n=/xparagraphmarkerz/gi;return e=e.replace(n,"<br>"),e="<p>"+e+"</p>",e=e.replace("<p></p>",""),e=e.replace("\r\n\r\n",""),e=e.replace(/<\/p><p>/g,"</p>\r\n\r\n<p>"),e=e.replace(new RegExp("<br\\s?/?></p>","g"),"</p>"),e=e.replace(new RegExp("<p><br\\s?/?>","g"),"<p>"),e=e.replace(new RegExp("<p><br\\s?/?>","g"),"<p>"),e=e.replace(new RegExp("<br\\s?/?></p>","g"),"</p>"),e=e.replace(/<p>&nbsp;<\/p>/gi,""),e=e.replace(/<p>\s?<br>&nbsp;<\/p>/gi,""),e=e.replace(/<p>\s?<br>/gi,"<p>")},clear:function(t){return t=t.replace(/<p>(.*?)#####replace(.*?)#####\s?<\/p>/gi,"<p>$1</p>#####replace$2#####"),t=t.replace(/(<br\s?\/?>){2,}<\/p>/gi,"</p>"),t=t.replace(new RegExp("</blockquote></p>","gi"),"</blockquote>"),t=t.replace(new RegExp("<p></blockquote>","gi"),"</blockquote>"),t=t.replace(new RegExp("<p><blockquote>","gi"),"<blockquote>"),t=t.replace(new RegExp("<blockquote></p>","gi"),"<blockquote>"),t=t.replace(new RegExp("<p><p ","gi"),"<p "),t=t.replace(new RegExp("<p><p>","gi"),"<p>"),t=t.replace(new RegExp("</p></p>","gi"),"</p>"),t=t.replace(new RegExp("<p>\\s?</p>","gi"),""),t=t.replace(new RegExp("\n</p>","gi"),"</p>"),t=t.replace(new RegExp("<p>\t?\t?\n?<p>","gi"),"<p>"),t=t.replace(new RegExp("<p>\t*</p>","gi"),"")}}},paste:function(){return{init:function(e){this.rtePaste=!0;var i=!("pre"!==this.opts.type&&!this.utils.isCurrentOrParent("pre"));if(this.detect.isDesktop()&&!this.paste.pre&&this.opts.clipboardImageUpload&&this.opts.imageUpload&&this.paste.detectClipboardUpload(e))return void(this.detect.isIe()&&setTimeout(t.proxy(this.paste.clipboardUpload,this),100));this.utils.saveScroll(),this.selection.save(),this.paste.createPasteBox(i),t(window).on("scroll.redactor-freeze",t.proxy(function(){t(window).scrollTop(this.saveBodyScroll)},this)),setTimeout(t.proxy(function(){var e=this.paste.getPasteBoxCode(i);this.buffer.set(),this.selection.restore(),this.utils.restoreScroll();var r=this.clean.getCurrentType(e);e=this.clean.onPaste(e,r);var n=this.core.callback("paste",e);e=void 0===n?e:n,this.paste.insert(e,r),this.rtePaste=!1,i&&this.clean.cleanPre(),t(window).off("scroll.redactor-freeze")},this),1)},getPasteBoxCode:function(t){var e=t?this.$pasteBox.val():this.$pasteBox.html();return this.$pasteBox.remove(),e},createPasteBox:function(e){var i={position:"fixed",width:"1px",top:0,left:"-9999px"};this.$pasteBox=e?t("<textarea>").css(i):t("<div>").attr("contenteditable","true").css(i),this.paste.appendPasteBox(),this.$pasteBox.focus()},appendPasteBox:function(){if(this.detect.isIe())this.core.box().append(this.$pasteBox);else{var e=t(".modal-body:visible");e.length>0?e.append(this.$pasteBox):t("body").prepend(this.$pasteBox)}},detectClipboardUpload:function(e){e=e.originalEvent||e;var i=e.clipboardData;if(this.detect.isIe()||this.detect.isFirefox())return!1;if(-1!==i.types.indexOf("public.tiff"))return e.preventDefault(),!1;if(i.items&&i.items.length){var r=i.items[0].getAsFile();if(null===r)return!1;var n=new FileReader;return n.readAsDataURL(r),n.onload=t.proxy(this.paste.insertFromClipboard,this),!0}},clipboardUpload:function(){var e=this.$editor.find("img");t.each(e,t.proxy(function(e,i){if(-1!==i.src.search(/^data\:image/i)){var r=window.FormData?new FormData:null;if(window.FormData){this.upload.direct=!0,this.upload.type="image",this.upload.url=this.opts.imageUpload,this.upload.callback=t.proxy(function(e){if(this.detect.isIe())t(i).wrap(t("<figure />"));else{var r=t(i).parent();this.utils.replaceToTag(r,"figure")}i.src=e.url,this.core.callback("imageUpload",t(i),e)},this);var n=this.utils.dataURItoBlob(i.src);r.append("clipboard",1),r.append(this.opts.imageUploadParam,n),this.upload.send(r,!1),this.code.sync(),this.rtePaste=!1}}},this))},insertFromClipboard:function(t){var e=window.FormData?new FormData:null;if(window.FormData){this.upload.direct=!0,this.upload.type="image",this.upload.url=this.opts.imageUpload,this.upload.callback=this.image.insert;var i=this.utils.dataURItoBlob(t.target.result);e.append("clipboard",1),e.append(this.opts.imageUploadParam,i),this.upload.send(e,t),this.rtePaste=!1}},insert:function(e,i){i.pre?this.insert.raw(e):i.text?this.insert.text(e):this.insert.html(e,i),this.detect.isFirefox()&&this.opts.imageUpload&&this.opts.clipboardImageUpload&&setTimeout(t.proxy(this.paste.clipboardUpload,this),100)}}},placeholder:function(){return{enable:function(){},show:function(){},update:function(){},hide:function(){},is:function(){},init:function(){},enabled:function(){},enableEvents:function(){},disableEvents:function(){},build:function(){},buildPosition:function(){},getPosition:function(){},isEditorEmpty:function(){},isAttr:function(){},destroy:function(){}}},progress:function(){return{$box:null,$bar:null,target:document.body,show:function(){},hide:function(){},update:function(){},is:function(){},build:function(){},destroy:function(){}}},selection:function(){return{get:function(){return window.getSelection?window.getSelection():document.selection&&"Control"!==document.selection.type?document.selection:null},range:function(t){return void 0===t&&(t=this.selection.get()),t.getRangeAt&&t.rangeCount?t.getRangeAt(0):null},is:function(){return!this.selection.isCollapsed()},isRedactor:function(){var e=this.selection.range();if(null!==e){var i=e.startContainer.parentNode;if(t(i).hasClass("redactor-in")||0!==t(i).parents(".redactor-in").length)return!0}return!1},isCollapsed:function(){var t=this.selection.get();return null!==t&&t.isCollapsed},update:function(t,e){null!==e&&(t.removeAllRanges(),t.addRange(e))},current:function(){var t=this.selection.get();return null!==t&&t.anchorNode},parent:function(){var t=this.selection.current();return null!==t&&t.parentNode},block:function(e){for(e=e||this.selection.current();e;){if(this.utils.isBlockTag(e.tagName))return!t(e).hasClass("redactor-in")&&e;e=e.parentNode}return!1},inline:function(e){for(e=e||this.selection.current();e;){if(this.utils.isInlineTag(e.tagName))return!t(e).hasClass("redactor-in")&&e;e=e.parentNode}return!1},element:function(e){for(e||(e=this.selection.current());e;){if(1===e.nodeType)return!t(e).hasClass("redactor-in")&&e;e=e.parentNode}return!1},prev:function(){return null!==this.selection.current()&&this.selection.current().previousSibling},next:function(){return null!==this.selection.current()&&this.selection.current().nextSibling},blocks:function(e){var i=[],r=this.selection.nodes(e);t.each(r,t.proxy(function(t,e){this.utils.isBlock(e)&&i.push(e)},this));var n=this.selection.block();return 0===i.length&&!1===n?[]:0===i.length&&!1!==n?[n]:i},inlines:function(e){var i=[],r=this.selection.nodes(e);t.each(r,t.proxy(function(t,e){this.utils.isInline(e)&&i.push(e)},this));var n=this.selection.inline();return 0===i.length&&!1===n?[]:0===i.length&&!1!==n?[n]:i},nodes:function(e){var i=void 0===e?[]:t.isArray(e)?e:[e],r=this.selection.get(),n=this.selection.range(r),s=[],o=[];if(this.utils.isCollapsed())s=[this.selection.current()];else{var a=n.startContainer,l=n.endContainer;if(a===l)return[a];for(;a&&a!==l;)s.push(a=this.selection.nextNode(a));for(a=n.startContainer;a&&a!==n.commonAncestorContainer;)s.unshift(a),a=a.parentNode}return t.each(s,function(e,r){if(r){var n=1===r.nodeType&&r.tagName.toLowerCase();if(t(r).hasClass("redactor-script-tag")||t(r).hasClass("redactor-selection-marker"))return;if(n&&0!==i.length&&-1===t.inArray(n,i))return;o.push(r)}}),0===o.length?[]:o},nextNode:function(t){if(t.hasChildNodes())return t.firstChild;for(;t&&!t.nextSibling;)t=t.parentNode;return t?t.nextSibling:null},save:function(){this.marker.insert(),this.savedSel=this.core.editor().html()},restore:function(t){var e=this.marker.find(1),i=this.marker.find(2);this.detect.isFirefox()&&this.core.editor().focus(),0!==e.length&&0!==i.length?this.caret.set(e,i):0!==e.length?this.caret.start(e):this.core.editor().focus(),!1!==t&&(this.marker.remove(),this.savedSel=!1)},saveInstant:function(){var t=this.core.editor()[0],e=t.ownerDocument,i=e.defaultView,r=i.getSelection();if(r.getRangeAt&&r.rangeCount){var n=r.getRangeAt(0),s=n.cloneRange();s.selectNodeContents(t),s.setEnd(n.startContainer,n.startOffset);var o=s.toString().length;return this.saved={start:o,end:o+n.toString().length,node:n.startContainer},this.saved}},restoreInstant:function(t){if(void 0!==t||this.saved){this.saved=void 0!==t?t:this.saved;var e=this.core.editor().find(this.saved.node);if(0===e.length||0!==e.text().trim().replace(/\u200B/g,"").length){var i=this.core.editor()[0],r=i.ownerDocument,n=r.defaultView,s=0,o=r.createRange();o.setStart(i,0),o.collapse(!0);for(var a,l=[i],c=!1,h=!1;!h&&(a=l.pop());)if(3==a.nodeType){var d=s+a.length;!c&&this.saved.start>=s&&this.saved.start<=d&&(o.setStart(a,this.saved.start-s),c=!0),c&&this.saved.end>=s&&this.saved.end<=d&&(o.setEnd(a,this.saved.end-s),h=!0),s=d}else for(var u=a.childNodes.length;u--;)l.push(a.childNodes[u]);var p=n.getSelection();p.removeAllRanges(),p.addRange(o)}else try{var o=document.createRange();o.setStart(e[0],0);var p=window.getSelection();p.removeAllRanges(),p.addRange(o)}catch(t){}}},node:function(e){t(e).prepend(this.marker.get(1)),t(e).append(this.marker.get(2)),this.selection.restore()},all:function(){this.core.editor().focus();var t=this.selection.get(),e=this.selection.range(t);e.selectNodeContents(this.core.editor()[0]),this.selection.update(t,e)},remove:function(){this.selection.get().removeAllRanges()},replace:function(t){this.insert.html(t)},text:function(){return this.selection.get().toString()},html:function(){var t="",e=this.selection.get();if(e.rangeCount){for(var i=document.createElement("div"),r=e.rangeCount,n=0;n<r;++n)i.appendChild(e.getRangeAt(n).cloneContents());t=this.clean.onGet(i.innerHTML)}return t},extractEndOfNode:function(t){var e=this.selection.get(),i=this.selection.range(e),r=i.cloneRange();return r.selectNodeContents(t),r.setStart(i.endContainer,i.endOffset),r.extractContents()},removeMarkers:function(){this.marker.remove()},marker:function(t){return this.marker.get(t)},markerHtml:function(t){return this.marker.html(t)}}},shortcuts:function(){return{hotkeysSpecialKeys:{8:"backspace",9:"tab",10:"return",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},hotkeysShiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"},init:function(e,i){if(!1===this.opts.shortcuts)return!e.ctrlKey&&!e.metaKey||66!==i&&73!==i||e.preventDefault(),!1;t.each(this.opts.shortcuts,t.proxy(function(t,i){this.shortcuts.build(e,t,i)},this))},build:function(e,i,r){for(var n=t.proxy(function(){this.shortcuts.buildHandler(r)},this),s=i.split(","),o=s.length,a=0;a<o;a++)"string"==typeof s[a]&&this.shortcuts.handler(e,t.trim(s[a]),n)},buildHandler:function(t){var e;"-1"!==t.func.search(/\./)?(e=t.func.split("."),
-void 0!==this[e[0]]&&this[e[0]][e[1]].apply(this,t.params)):this[t.func].apply(this,t.params)},handler:function(e,i,r){i=i.toLowerCase().split(" ");var n=this.shortcuts.hotkeysSpecialKeys[e.keyCode],s=String.fromCharCode(e.which).toLowerCase(),o="",a={};t.each(["alt","ctrl","meta","shift"],function(t,i){e[i+"Key"]&&n!==i&&(o+=i+"+")}),n&&(a[o+n]=!0),s&&(a[o+s]=!0,a[o+this.shortcuts.hotkeysShiftNums[s]]=!0,"shift+"===o&&(a[this.shortcuts.hotkeysShiftNums[s]]=!0));for(var l=i.length,c=0;c<l;c++)if(a[i[c]])return e.preventDefault(),r.apply(this,arguments)}}},storage:function(){return{data:[],add:function(){},status:function(){},observe:function(){},changes:function(){}}},toolbar:function(){return{build:function(){this.button.hideButtons(),this.button.hideButtonsOnMobile(),this.$toolbarBox=t('<div class="redactor-toolbar-box" />'),this.$toolbarBox[0].innerHTML='<ul class="redactor-toolbar" id="redactor-toolbar-'+this.uuid+'" role="toolbar"></ul>',this.$toolbar=t(this.$toolbarBox[0].children[0]),this.$box[0].insertBefore(this.$toolbarBox[0],this.$box[0].firstChild),this.button.$toolbar=this.$toolbar,this.button.setFormatting(),this.button.load(this.$toolbar),require(["Core"],function(t){this.$toolbar[0].addEventListener("keydown",this.toolbar.keydown.bind(this,t))}.bind(this))},createContainer:function(){},append:function(){},setOverflow:function(){},setFixed:function(){},setUnfixed:function(){},getBoxTop:function(){},observeScroll:function(){},observeScrollResize:function(){},observeScrollEnable:function(){},observeScrollDisable:function(){},setDropdownsFixed:function(){},unsetDropdownsFixed:function(){},setDropdownPosition:function(){},keydown:function(e,i){var r=document.activeElement;if(r.classList.contains("re-button")){if(-1!==[13,32,35,36,37,39,40].indexOf(i.which)){if(13===i.which||32===i.which)return i.preventDefault(),void require(["Core"],function(t){t.triggerEvent(r,"mousedown")});if(40===i.which){if("true"!==elAttr(r,"aria-haspopup"))return;i.preventDefault(),e.triggerEvent(r,"mousedown");var n=t(r).data("dropdown"),s=elBySel("li",n[0]);return void(s&&s.focus())}i.preventDefault();var o=Array.prototype.slice.call(elBySelAll(".re-button",this.$toolbar[0])),a=null;if(35===i.which)a=o[o.length-1];else if(36===i.which)a=o[0];else{var l=o.indexOf(r);37===i.which?-1===--l&&(l=o.length-1):39===i.which&&++l===o.length&&(l=0),a=o[l]}null!==a&&a.focus()}}}}},upload:function(){return{init:function(){},directUpload:function(){},onDrop:function(){},traverseFile:function(){},setConfig:function(){},getType:function(){},getHiddenFields:function(){},send:function(){},onDrag:function(){},onDragLeave:function(){},clearImageFields:function(){},addImageFields:function(){},removeImageFields:function(){},clearFileFields:function(){},addFileFields:function(){},removeFileFields:function(){}}},uploads3:function(){return{send:function(){},executeOnSignedUrl:function(){},createCORSRequest:function(){},sendToS3:function(){}}},utils:function(){return{isEmpty:function(e){return e=void 0===e?this.core.editor().html():e,e=e.replace(/[\u200B-\u200D\uFEFF]/g,""),e=e.replace(/&nbsp;/gi,""),e=e.replace(/<\/?br\s?\/?>/g,""),e=e.replace(/\s/g,""),e=e.replace(/^<p>[^\W\w\D\d]*?<\/p>$/i,""),e=e.replace(/<iframe(.*?[^>])>$/i,"iframe"),e=e.replace(/<source(.*?[^>])>$/i,"source"),e=e.replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),e=e.replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),""===(e=t.trim(e))},isElement:function(t){try{return t instanceof HTMLElement}catch(e){return"object"==typeof t&&1===t.nodeType&&"object"==typeof t.style&&"object"==typeof t.ownerDocument}},strpos:function(t,e,i){var r=t.indexOf(e,i);return r>=0&&r},dataURItoBlob:function(t){var e;e=t.split(",")[0].indexOf("base64")>=0?atob(t.split(",")[1]):unescape(t.split(",")[1]);for(var i=t.split(",")[0].split(":")[1].split(";")[0],r=new Uint8Array(e.length),n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return new Blob([r],{type:i})},getOuterHtml:function(e){return t("<div>").append(t(e).eq(0).clone()).html()},cloneAttributes:function(e,i){e=e[0]||e,i=t(i);for(var r=e.attributes,n=r.length;n--;){var s=r[n];i.attr(s.name,s.value)}return i},breakBlockTag:function(){var e=this.selection.block();if(!e)return!1;var i=this.utils.isEmpty(e.innerHTML),r=e.tagName.toLowerCase();if("pre"===r||"li"===r||"td"===r||"th"===r)return!1;if(!i&&this.utils.isStartOfElement(e))return{$block:t(e),$next:t(e).next(),type:"start"};if(!i&&this.utils.isEndOfElement(e))return{$block:t(e),$next:t(e).next(),type:"end"};var n=this.selection.extractEndOfNode(e),s=t("<"+r+" />").append(n);return s=this.utils.cloneAttributes(e,s),t(e).after(s),{$block:t(e),$next:s,type:"break"}},inBlocks:function(e){e=t.isArray(e)?e:[e];for(var i=this.selection.blocks(),r=i.length,n=!1,s=0;s<r;s++)if(!1!==i[s]){var o=i[s].tagName.toLowerCase();-1!==t.inArray(o,e)&&(n=!0)}return n},inInlines:function(e){e=t.isArray(e)?e:[e];for(var i=this.selection.inlines(),r=i.length,n=!1,s=0;s<r;s++){var o=i[s].tagName.toLowerCase();-1!==t.inArray(o,e)&&(n=!0)}return n},isTag:function(e,i){var r=t(e).closest(i,this.core.editor()[0]);return 1===r.length&&r[0]},isBlock:function(t){return null!==t&&((t=t[0]||t)&&this.utils.isBlockTag(t.tagName))},isBlockTag:function(t){return void 0!==t&&this.reIsBlock.test(t)},isInline:function(t){return(t=t[0]||t)&&this.utils.isInlineTag(t.tagName)},isInlineTag:function(t){return void 0!==t&&this.reIsInline.test(t)},isRedactorParent:function(e){return!!e&&(0!==t(e).parents(".redactor-in").length&&!t(e).hasClass("redactor-in")&&e)},isCurrentOrParentHeader:function(){return this.utils.isCurrentOrParent(["H1","H2","H3","H4","H5","H6"])},isCurrentOrParent:function(e){var i=this.selection.parent(),r=this.selection.current();if(t.isArray(e)){var n=0;return t.each(e,t.proxy(function(t,e){this.utils.isCurrentOrParentOne(r,i,e)&&n++},this)),0!==n}return this.utils.isCurrentOrParentOne(r,i,e)},isCurrentOrParentOne:function(t,e,i){return i=i.toUpperCase(),e&&e.tagName===i?e:!(!t||t.tagName!==i)&&t},isEditorRelative:function(){var e=this.core.editor().css("position"),i=["absolute","fixed","relative"];return-1!==t.inArray(i,e)},setEditorRelative:function(){this.core.editor().addClass("redactor-relative")},getScrollTarget:function(){var e=t(this.opts.scrollTarget);return 0!==e.length?e:t(document)},freezeScroll:function(){this.freezeScrollTop=this.utils.getScrollTarget().scrollTop(),this.utils.getScrollTarget().scrollTop(this.freezeScrollTop)},unfreezeScroll:function(){void 0!==this.freezeScrollTop&&this.utils.getScrollTarget().scrollTop(this.freezeScrollTop)},saveScroll:function(){this.tmpScrollTop=this.utils.getScrollTarget().scrollTop()},restoreScroll:function(){void 0!==this.tmpScrollTop&&this.utils.getScrollTarget().scrollTop(this.tmpScrollTop)},isStartOfElement:function(t){return!(void 0===t&&!(t=this.selection.block()))&&0===this.offset.get(t)},isEndOfElement:function(e){if(void 0===e&&!(e=this.selection.block()))return!1;var i=t.trim(t(e).text()).replace(/[\t\n\r\n]/g,"").replace(/\u200B/g,"");return this.offset.get(e)===i.length},removeEmptyAttr:function(e,i){var r=t(e);return void 0===r.attr(i)||""===r.attr(i)&&(r.removeAttr(i),!0)},replaceToTag:function(e,i){var r;return t(e).replaceWith(function(){r=t("<"+i+" />").append(t(this).contents());for(var e=0;e<this.attributes.length;e++)r.attr(this.attributes[e].name,this.attributes[e].value);return r}),r},isSelectAll:function(){return this.selectAll},enableSelectAll:function(){this.selectAll=!0},disableSelectAll:function(){this.selectAll=!1},disableBodyScroll:function(){},measureScrollbar:function(){var e=t("body"),i=document.createElement("div");i.className="redactor-scrollbar-measure",e.append(i);var r=i.offsetWidth-i.clientWidth;return e[0].removeChild(i),r},enableBodyScroll:function(){},appendFields:function(e,i){if(!e)return i;if("object"==typeof e)return t.each(e,function(e,r){null!==r&&0===r.toString().indexOf("#")&&(r=t(r).val()),i.append(e,r)}),i;var r=t(e);if(0===r.length)return i;return r.each(function(){i.append(t(this).attr("name"),t(this).val())}),i},appendForms:function(e,i){if(!e)return i;var r=t(e);if(0===r.length)return i;var n=r.serializeArray();return t.each(n,function(t,e){i.append(e.name,e.value)}),i},isRgb:function(t){return 0===t.search(/^rgb/i)},rgb2hex:function(t){return t=t.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i),t&&4===t.length?"#"+("0"+parseInt(t[1],10).toString(16)).slice(-2)+("0"+parseInt(t[2],10).toString(16)).slice(-2)+("0"+parseInt(t[3],10).toString(16)).slice(-2):""},isCollapsed:function(){return this.selection.isCollapsed()},isMobile:function(){return this.detect.isMobile()},isDesktop:function(){return this.detect.isDesktop()},isPad:function(){return this.detect.isIpad()}}},browser:function(){return{webkit:function(){return this.detect.isWebkit()},ff:function(){return this.detect.isFirefox()},ie:function(){return this.detect.isIe()}}}},t(window).on("load.tools.redactor",function(){t('[data-tools="redactor"]').redactor()}),e.prototype.init.prototype=e.prototype}(jQuery),function(t){function e(e,i,r,n){var s={duration:.5,iterate:1,delay:0,prefix:"redactor-",timing:"linear"};this.animation=i,this.slide="slideDown"===this.animation||"slideUp"===this.animation,this.$element=t(e),this.prefixes=["","-moz-","-o-animation-","-webkit-"],this.queue=[],"function"==typeof r?(n=r,this.opts=s):this.opts=t.extend(s,r),this.slide&&this.$element.height(this.$element.height()),this.init(n)}t.fn.redactorAnimation=function(t,i,r){return this.each(function(){new e(this,t,i,r)})},e.prototype={init:function(t){this.queue.push(this.animation),this.clean(),"show"===this.animation?(this.opts.timing="linear",this.$element.removeClass("hide").show(),"function"==typeof t&&t(this)):"hide"===this.animation?(this.opts.timing="linear",this.$element.hide(),"function"==typeof t&&t(this)):this.animate(t)},animate:function(e){this.$element.addClass("redactor-animated").css("display","").removeClass("hide"),this.$element.addClass(this.opts.prefix+this.queue[0]),this.set(this.opts.duration+"s",this.opts.delay+"s",this.opts.iterate,this.opts.timing);var i=this.queue.length>1?null:e;this.complete("AnimationEnd",t.proxy(function(){this.$element.hasClass(this.opts.prefix+this.queue[0])&&(this.clean(),this.queue.shift(),this.queue.length&&this.animate(e))},this),i)},set:function(t,e,i,r){for(var n=this.prefixes.length;n--;)this.$element.css(this.prefixes[n]+"animation-duration",t),this.$element.css(this.prefixes[n]+"animation-delay",e),this.$element.css(this.prefixes[n]+"animation-iteration-count",i),this.$element.css(this.prefixes[n]+"animation-timing-function",r)},clean:function(){this.$element.removeClass("redactor-animated"),this.$element.removeClass(this.opts.prefix+this.queue[0]),this.set("","","","")},complete:function(e,i,r){this.$element.one(e.toLowerCase()+" webkit"+e+" o"+e+" MS"+e,t.proxy(function(){"function"==typeof i&&i(),"function"==typeof r&&r(this);var e=["fadeOut","slideUp","zoomOut","slideOutUp","slideOutRight","slideOutLeft"];-1!==t.inArray(this.animation,e)&&this.$element.css("display","none"),this.slide&&this.$element.css("height","")},this))}}}(jQuery); })(this);
+(function (window, undefined) { !function(m){"use strict";Function.prototype.bind||(Function.prototype.bind=function(t){var e=this;return function(){return e.apply(t)}});var i=0,h=null;function l(t,e){return new l.prototype.init(t,e)}"function"==typeof window.require&&require(["Environment"],function(t){h=t}),m.fn.redactor=function(n){var r=[],s=Array.prototype.slice.call(arguments,1);return"string"==typeof n?this.each(function(){var t,e,i=m.data(this,"redactor");"-1"!==n.search(/\./)?void 0!==i[(t=n.split("."))[0]]&&(t=i[t[0]][t[1]]):t=i[n],void 0!==i&&m.isFunction(t)?void 0!==(e=t.apply(i,s))&&e!==i&&r.push(e):m.error('No such method "'+n+'" for Redactor')}):this.each(function(){m.data(this,"redactor",{}),m.data(this,"redactor",l(this,n))}),0===r.length?this:1===r.length?r[0]:r},m.Redactor=l,m.Redactor.VERSION="2.99",m.Redactor.modules=["air","autosave","block","buffer","build","button","caret","clean","code","core","detect","dropdown","events","file","focus","image","indent","inline","insert","keydown","keyup","lang","line","link","linkify","list","marker","modal","observe","offset","paragraphize","paste","placeholder","progress","selection","shortcuts","storage","toolbar","upload","uploads3","utils","browser"],m.Redactor.settings={},m.Redactor.opts={animation:!1,lang:"en",direction:"ltr",spellcheck:!0,overrideStyles:!0,stylesClass:!1,scrollTarget:document,focus:!1,focusEnd:!1,clickToEdit:!1,structure:!1,tabindex:!1,minHeight:!1,maxHeight:!1,maxWidth:!1,plugins:!1,callbacks:{},placeholder:!1,linkify:!0,enterKey:!0,pastePlainText:!1,pasteImages:!0,pasteLinks:!0,pasteBlockTags:["pre","h1","h2","h3","h4","h5","h6","table","tbody","thead","tfoot","th","tr","td","ul","ol","li","blockquote","p","figure","figcaption"],pasteInlineTags:["br","strong","ins","code","del","span","samp","kbd","sup","sub","mark","var","cite","small","b","u","em","i"],preClass:!1,preSpaces:4,tabAsSpaces:!1,tabKey:!0,autosave:!1,autosaveName:!1,autosaveFields:!1,imageUpload:null,imageUploadParam:"file",imageUploadFields:!1,imageUploadForms:!1,imageTag:"figure",imageEditable:!0,imageCaption:!0,imagePosition:!1,imageResizable:!1,imageFloatMargin:"10px",dragImageUpload:!0,multipleImageUpload:!0,clipboardImageUpload:!0,fileUpload:null,fileUploadParam:"file",fileUploadFields:!1,fileUploadForms:!1,dragFileUpload:!0,s3:!1,linkNewTab:!1,linkTooltip:!0,linkNofollow:!1,linkSize:30,linkValidation:!0,pasteLinkTarget:!1,videoContainerClass:"video-container",toolbar:!0,toolbarFixed:!0,toolbarFixedTarget:document,toolbarFixedTopOffset:0,toolbarExternal:!1,toolbarOverflow:!1,air:!1,airWidth:!1,formatting:["p","blockquote","pre","h1","h2","h3","h4","h5","h6"],formattingAdd:!1,buttons:["format","bold","italic","deleted","lists","image","file","link","horizontalrule"],buttonsTextLabeled:!1,buttonsHide:[],buttonsHideOnMobile:[],script:!0,removeNewlines:!1,removeComments:!0,replaceTags:{b:"strong",i:"em",strike:"del"},keepStyleAttr:[],keepInlineOnEnter:!1,shortcuts:{"ctrl+shift+m, meta+shift+m":{func:"inline.removeFormat"},"ctrl+b, meta+b":{func:"inline.format",params:["bold"]},"ctrl+i, meta+i":{func:"inline.format",params:["italic"]},"ctrl+h, meta+h":{func:"inline.format",params:["superscript"]},"ctrl+l, meta+l":{func:"inline.format",params:["subscript"]},"ctrl+k, meta+k":{func:"link.show"},"ctrl+shift+7":{func:"list.toggle",params:["orderedlist"]},"ctrl+shift+8":{func:"list.toggle",params:["unorderedlist"]}},shortcutsAdd:!1,activeButtons:["deleted","italic","bold"],activeButtonsStates:{b:"bold",strong:"bold",i:"italic",em:"italic",del:"deleted",strike:"deleted"},langs:{en:{format:"Format",image:"Image",file:"File",link:"Link",bold:"Bold",italic:"Italic",deleted:"Strikethrough",underline:"Underline","bold-abbr":"B","italic-abbr":"I","deleted-abbr":"S","underline-abbr":"U",lists:"Lists","link-insert":"Insert link","link-edit":"Edit link","link-in-new-tab":"Open link in new tab",unlink:"Unlink",cancel:"Cancel",close:"Close",insert:"Insert",save:"Save",delete:"Delete",text:"Text",edit:"Edit",title:"Title",paragraph:"Normal text",quote:"Quote",code:"Code",heading1:"Heading 1",heading2:"Heading 2",heading3:"Heading 3",heading4:"Heading 4",heading5:"Heading 5",heading6:"Heading 6",filename:"Name",optional:"optional",unorderedlist:"Unordered List",orderedlist:"Ordered List",outdent:"Outdent",indent:"Indent",horizontalrule:"Line","upload-label":"Drop file here or ",caption:"Caption",bulletslist:"Bullets",numberslist:"Numbers","image-position":"Position",none:"None",left:"Left",right:"Right",center:"Center","accessibility-help-label":"Rich text editor"}},type:"textarea",inline:!1,inlineTags:["a","span","strong","strike","b","u","em","i","code","del","ins","samp","kbd","sup","sub","mark","var","cite","small"],blockTags:["pre","ul","ol","li","p","h1","h2","h3","h4","h5","h6","dl","dt","dd","div","td","blockquote","output","figcaption","figure","address","section","header","footer","aside","article","iframe"],paragraphize:!0,paragraphizeBlocks:["table","div","pre","form","ul","ol","h1","h2","h3","h4","h5","h6","dl","blockquote","figcaption","address","section","header","footer","aside","article","object","style","script","iframe","select","input","textarea","button","option","map","area","math","hr","fieldset","legend","hgroup","nav","figure","details","menu","summary","p"],emptyHtml:"<p>&#x200b;</p>",invisibleSpace:"&#x200b;",emptyHtmlRendered:m("").html("​").html(),imageTypes:["image/png","image/jpeg","image/gif"],userAgent:navigator.userAgent.toLowerCase(),observe:{dropdowns:[]},regexps:{linkyoutube:/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi,linkvimeo:/https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,linkimage:/((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/gi,url:/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi}},l.fn=m.Redactor.prototype={keyCode:{BACKSPACE:8,DELETE:46,UP:38,DOWN:40,ENTER:13,SPACE:32,ESC:27,TAB:9,CTRL:17,META:91,SHIFT:16,ALT:18,RIGHT:39,LEFT:37,LEFT_WIN:91},init:function(t,e){if(this.$element=m(t),this.uuid=i++,this.sBuffer=[],this.sRebuffer=[],this.loadOptions(e),this.loadModules(),this.opts.clickToEdit&&!this.$element.hasClass("redactor-click-to-edit"))return this.loadToEdit(e);this.$element.hasClass("redactor-click-to-edit")&&this.$element.removeClass("redactor-click-to-edit"),this.reIsBlock=new RegExp("^("+this.opts.blockTags.join("|").toUpperCase()+")$","i"),this.reIsInline=new RegExp("^("+this.opts.inlineTags.join("|").toUpperCase()+")$","i"),this.opts.dragImageUpload=null!==this.opts.imageUpload&&this.opts.dragImageUpload,this.opts.dragFileUpload=null!==this.opts.fileUpload&&this.opts.dragFileUpload,this.formatting={},this.lang.load(),m.extend(this.opts.shortcuts,this.opts.shortcutsAdd),this.$editor=this.$element,this.detectType(),this.core.callback("start"),this.core.callback("startToEdit"),this.start=!0,this.build.start()},detectType:function(){this.build.isInline()||this.opts.inline?this.opts.type="inline":this.build.isTag("DIV")?this.opts.type="div":this.build.isTag("PRE")&&(this.opts.type="pre")},loadToEdit:function(t){this.$element.on("click.redactor-click-to-edit",m.proxy(function(){this.initToEdit(t)},this)),this.$element.addClass("redactor-click-to-edit")},initToEdit:function(e){m.extend(e.callbacks,{startToEdit:function(){this.insert.node(this.marker.get(),!1)},initToEdit:function(){this.selection.restore(),this.clickToCancelStorage=this.code.get(),m(this.opts.clickToCancel).off(".redactor-click-to-edit"),m(this.opts.clickToCancel).show().on("click.redactor-click-to-edit",m.proxy(function(t){t.preventDefault(),this.core.destroy(),this.events.syncFire=!1,this.$element.html(this.clickToCancelStorage),this.core.callback("cancel",this.clickToCancelStorage),this.events.syncFire=!0,this.clickToCancelStorage="",m(this.opts.clickToCancel).hide(),m(this.opts.clickToSave).hide(),this.$element.on("click.redactor-click-to-edit",m.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},this)),m(this.opts.clickToSave).off(".redactor-click-to-edit"),m(this.opts.clickToSave).show().on("click.redactor-click-to-edit",m.proxy(function(t){t.preventDefault(),this.core.destroy(),this.core.callback("save",this.code.get()),m(this.opts.clickToCancel).hide(),m(this.opts.clickToSave).hide(),this.$element.on("click.redactor-click-to-edit",m.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},this))}}),this.$element.redactor(e),this.$element.off(".redactor-click-to-edit")},loadOptions:function(t){var e={};void 0!==m.Redactor.settings.namespace&&!this.$element.hasClass(m.Redactor.settings.namespace)||(e=m.Redactor.settings),this.opts=m.extend({},m.Redactor.opts,this.$element.data(),t),this.opts=m.extend({},this.opts,e)},getModuleMethods:function(e){return Object.getOwnPropertyNames(e).filter(function(t){return"function"==typeof e[t]})},loadModules:function(){for(var t=m.Redactor.modules.length,e=0;e<t;e++)this.bindModuleMethods(m.Redactor.modules[e])},bindModuleMethods:function(t){if(void 0!==this[t]){this[t]=this[t]();for(var e=this.getModuleMethods(this[t]),i=e.length,n=0;n<i;n++)this[t][e[n]]=this[t][e[n]].bind(this)}},air:function(){return{enabled:!1,collapsed:function(){},collapsedEnd:function(){},build:function(){},append:function(){},createContainer:function(){},show:function(){},bindHide:function(){},hide:function(){}}},autosave:function(){return{enabled:!1,html:!1,init:function(){},is:function(){},send:function(){},getHiddenFields:function(){},success:function(){},disable:function(){}}},block:function(){return{format:function(t,e,i,n){if(t="quote"===t?"blockquote":t,this.block.tags=["p","blockquote","pre","h1","h2","h3","h4","h5","h6","div","figure"],-1!==m.inArray(t,this.block.tags))return"p"===t&&void 0===e&&(e="class"),this.buffer.set(),this.utils.isCollapsed()?this.block.formatCollapsed(t,e,i,n):this.block.formatUncollapsed(t,e,i,n)},formatCollapsed:function(t,e,i,n){this.selection.save();var r=this.selection.block(),s=r.tagName.toLowerCase();if(-1!==m.inArray(s,this.block.tags)){var o,a,l=!1;if(s===t&&void 0===e&&(t="p",l=!0),l&&(this.block.removeAllClass(),this.block.removeAllAttr()),"blockquote"===s&&this.utils.isEndOfElement(r)?(this.marker.remove(),(o=document.createElement("p")).innerHTML=this.opts.invisibleSpace,m(r).after(o),this.caret.start(o),0!==(a=m(r).children().last()).length&&"BR"===a[0].tagName&&a.remove()):o=this.utils.replaceToTag(r,t),"object"==typeof e)for(var c in n=i,e)o=this.block.setAttr(o,c,e[c],n);else o=this.block.setAttr(o,e,i,n);return"pre"===t&&1===o.length&&m(o).html(m.trim(m(o).html())),this.selection.restore(),this.block.removeInlineTags(o),o}this.selection.restore()},formatUncollapsed:function(t,e,i,n){this.selection.save();var r=[],s=this.selection.blocks();s[0]&&(m(s[0]).hasClass("redactor-in")||m(s[0]).hasClass("redactor-box"))&&(s=this.core.editor().find(this.opts.blockTags.join(", ")));for(var o,a=s.length,l=0;l<a;l++){var c=s[l].tagName.toLowerCase();if(-1!==m.inArray(c,this.block.tags)&&"figure"!==c){var h=this.utils.replaceToTag(s[l],t);if("object"==typeof e)for(var d in n=i,e)h=this.block.setAttr(h,d,e[d],n);else h=this.block.setAttr(h,e,i,n);r.push(h),this.block.removeInlineTags(h)}}return this.selection.restore(),"pre"===t&&0!==r.length&&(o=r[0],m.each(r,function(t,e){0!==t&&(m(o).append("\n"+m.trim(e.html())),m(e).remove())}),(r=[]).push(o)),r},removeInlineTags:function(t){t=t[0]||t;var e,i=this.opts.inlineTags;-1!==m.inArray(t.tagName,["PRE","H1","H2","H3","H4","H5","H6"])&&("PRE"!==t.tagName&&(e=i.indexOf("a"),i.splice(e,1)),m(t).find(i.join(",")).not(".redactor-selection-marker").contents().unwrap())},setAttr:function(t,e,i,n){if(void 0===e)return t;var r=void 0===n?"replace":n;return t="class"===e?this.block[r+"Class"](i,t):"remove"===r||"removeAll"===r?this.block[r+"Attr"](e,t):this.block[r+"Attr"](e,i,t)},getBlocks:function(t){if(t=void 0===t?this.selection.blocks():t,m(t).hasClass("redactor-box")){var i=[],e=this.core.editor().children();return m.each(e,m.proxy(function(t,e){this.utils.isBlock(e)&&i.push(e)},this)),i}return t},replaceClass:function(t,e){return m(this.block.getBlocks(e)).removeAttr("class").addClass(t)[0]},toggleClass:function(t,e){return m(this.block.getBlocks(e)).toggleClass(t)[0]},addClass:function(t,e){return m(this.block.getBlocks(e)).addClass(t)[0]},removeClass:function(t,e){return m(this.block.getBlocks(e)).removeClass(t)[0]},removeAllClass:function(t){return m(this.block.getBlocks(t)).removeAttr("class")[0]},replaceAttr:function(t,e,i){return i=this.block.removeAttr(t,i),m(i).attr(t,e)[0]},toggleAttr:function(i,n,t){t=this.block.getBlocks(t);var r=this,s=[];return m.each(t,function(t,e){m(e).attr(i)?s.push(r.block.removeAttr(i,e)):s.push(r.block.addAttr(i,n,e))}),s},addAttr:function(t,e,i){return m(this.block.getBlocks(i)).attr(t,e)[0]},removeAttr:function(t,e){return m(this.block.getBlocks(e)).removeAttr(t)[0]},removeAllAttr:function(t){t=this.block.getBlocks(t);var i=[];return m.each(t,function(t,e){if(void 0!==e.attributes)for(;e.attributes.length;)e.removeAttribute(e.attributes[0].name);i.push(e)}),i}}},buffer:function(){return{set:function(t){void 0===t&&this.buffer.clear(),void 0===t||"undo"===t?this.buffer.setUndo():this.buffer.setRedo()},setUndo:function(){var t=this.selection.saveInstant(),e=this.sBuffer[this.sBuffer.length-1],i=this.core.editor().html();void 0!==e&&e[0]===i||this.sBuffer.push([i,t])},setRedo:function(){var t=this.selection.saveInstant();this.sRebuffer.push([this.core.editor().html(),t])},add:function(){this.sBuffer.push([this.core.editor().html(),0])},undo:function(){var t;0!==this.sBuffer.length&&(t=this.sBuffer.pop(),this.buffer.set("redo"),this.core.editor().html(t[0]),this.selection.restoreInstant(t[1]),this.selection.restore(),this.observe.load())},redo:function(){var t;0!==this.sRebuffer.length&&(t=this.sRebuffer.pop(),this.buffer.set("undo"),this.core.editor().html(t[0]),this.selection.restoreInstant(t[1]),this.selection.restore(),this.observe.load())},clear:function(){this.sRebuffer=[]}}},build:function(){return{start:function(){if("textarea"!==this.opts.type)throw new Error("Only `<textarea>` types are allowed.");this.build.startTextarea(),this.build.setIn(),this.build.setId(),this.build.enableEditor(),this.build.setOptions(),this.build.callEditor()},createContainerBox:function(){this.$box=m('<div class="redactor-box" role="application" />')},setIn:function(){this.core.editor().addClass("redactor-in")},setId:function(){var t="textarea"===this.opts.type?"redactor-uuid-"+this.uuid:this.$element.attr("id");this.core.editor().attr("id",void 0===t?"redactor-uuid-"+this.uuid:t)},getName:function(){var t=this.$element.attr("name");return void 0===t?"content-"+this.uuid:t},buildTextarea:function(){},loadFromTextarea:function(){this.$editor=m("<div />"),this.$textarea=this.$element,this.$element.attr("name",this.build.getName()),this.$box.insertAfter(this.$element).append(this.$editor).append(this.$element),this.build.setStartAttrs(),this.$editor.addClass("redactor-layer"),this.opts.overrideStyles&&this.$editor.addClass("redactor-styles"),this.$element.hide(),this.$box.prepend('<span class="redactor-voice-label" id="redactor-voice-'+this.uuid+'" aria-hidden="false">'+this.lang.get("accessibility-help-label")+"</span>")},setStartAttrs:function(){this.$editor.attr({"aria-labelledby":"redactor-voice-"+this.uuid,role:"presentation"})},startTextarea:function(){this.build.createContainerBox(),this.build.loadFromTextarea(),this.code.start(this.core.textarea().val()),this.core.textarea().val(this.clean.onSync(this.$editor.html()))},isTag:function(t){return this.$element[0].tagName===t},isInline:function(){return!this.build.isTag("TEXTAREA")&&!this.build.isTag("DIV")&&!this.build.isTag("PRE")},enableEditor:function(){this.core.editor().attr({contenteditable:!0})},setOptions:function(){"inline"===this.opts.type&&(this.opts.enterKey=!1),"inline"!==this.opts.type&&"pre"!==this.opts.type||(this.opts.toolbarMobile=!1,this.opts.toolbar=!1),this.core.editor().attr("spellcheck",this.opts.spellcheck),this.opts.structure&&this.core.editor().addClass("redactor-structure"),this.opts.stylesClass&&this.core.editor().addClass(this.opts.stylesClass),"textarea"===this.opts.type&&(this.core.box().attr("dir",this.opts.direction),this.core.editor().attr("dir",this.opts.direction),this.opts.tabindex&&this.core.editor().attr("tabindex",this.opts.tabindex),this.opts.minHeight?this.core.editor().css("min-height",this.opts.minHeight):this.core.editor().css("min-height","40px"),this.opts.maxHeight&&this.core.editor().css("max-height",this.opts.maxHeight),this.opts.maxWidth&&this.core.editor().css({"max-width":this.opts.maxWidth,margin:"auto"}))},callEditor:function(){this.build.disableBrowsersEditing(),this.events.init(),this.build.setHelpers(),this.toolbarsButtons=this.button.init(),this.toolbar.build(),this.core.editor().on("mouseup.redactor-observe."+this.uuid+" keyup.redactor-observe."+this.uuid+" focus.redactor-observe."+this.uuid+" touchstart.redactor-observe."+this.uuid,m.proxy(this.observe.toolbar,this)),this.core.element().on("blur.callback.redactor",m.proxy(function(){this.button.setInactiveAll()},this)),this.modal.templates(),this.build.plugins(),this.code.html=this.code.cleaned(this.core.editor().html()),this.core.callback("init"),this.core.callback("initToEdit"),this.start=!1},setHelpers:function(){this.opts.focus?setTimeout(this.focus.start,100):this.opts.focusEnd&&setTimeout(this.focus.end,100)},disableBrowsersEditing:function(){try{document.execCommand("enableObjectResizing",!1,!1),document.execCommand("enableInlineTableEditing",!1,!1),document.execCommand("AutoUrlDetect",!1,!1)}catch(t){}},plugins:function(){this.opts.plugins&&m.each(this.opts.plugins,m.proxy(function(t,e){var i="undefined"!=typeof RedactorPlugins&&void 0!==RedactorPlugins[e]?RedactorPlugins:l.fn;if(m.isFunction(i[e])){this[e]=i[e]();for(var n,r,s=this.getModuleMethods(this[e]),o=s.length,a=0;a<o;a++)this[e][s[a]]=this[e][s[a]].bind(this);void 0!==this[e].langs&&(n={},void 0!==this[e].langs[this.opts.lang]?n=this[e].langs[this.opts.lang]:void 0===this[e].langs[this.opts.lang]&&void 0!==this[e].langs.en&&(n=this[e].langs.en),r=this,m.each(n,function(t,e){void 0===r.opts.curLang[t]&&(r.opts.curLang[t]=e)})),"function"==typeof this[e].init&&this[e].init()}},this))}}},button:function(){return{toolbar:function(){return void 0!==this.button.$toolbar&&this.button.$toolbar?this.button.$toolbar:this.$toolbar},init:function(){return{format:{title:this.lang.get("format"),icon:!0,dropdown:{p:{title:this.lang.get("paragraph"),func:"block.format"},blockquote:{title:this.lang.get("quote"),func:"block.format"},pre:{title:this.lang.get("code"),func:"block.format"},h1:{title:this.lang.get("heading1"),func:"block.format"},h2:{title:this.lang.get("heading2"),func:"block.format"},h3:{title:this.lang.get("heading3"),func:"block.format"},h4:{title:this.lang.get("heading4"),func:"block.format"},h5:{title:this.lang.get("heading5"),func:"block.format"},h6:{title:this.lang.get("heading6"),func:"block.format"}}},bold:{title:this.lang.get("bold-abbr"),icon:!0,label:this.lang.get("bold"),func:"inline.format"},italic:{title:this.lang.get("italic-abbr"),icon:!0,label:this.lang.get("italic"),func:"inline.format"},deleted:{title:this.lang.get("deleted-abbr"),icon:!0,label:this.lang.get("deleted"),func:"inline.format"},underline:{title:this.lang.get("underline-abbr"),icon:!0,label:this.lang.get("underline"),func:"inline.format"},lists:{title:this.lang.get("lists"),icon:!0,dropdown:{unorderedlist:{title:"&bull; "+this.lang.get("unorderedlist"),func:"list.toggle"},orderedlist:{title:"1. "+this.lang.get("orderedlist"),func:"list.toggle"},outdent:{title:"< "+this.lang.get("outdent"),func:"indent.decrease",observe:{element:"li",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},indent:{title:"> "+this.lang.get("indent"),func:"indent.increase",observe:{element:"li",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}}}},ul:{title:"&bull; "+this.lang.get("bulletslist"),icon:!0,func:"list.toggle"},ol:{title:"1. "+this.lang.get("numberslist"),icon:!0,func:"list.toggle"},outdent:{title:this.lang.get("outdent"),icon:!0,func:"indent.decrease"},indent:{title:this.lang.get("indent"),icon:!0,func:"indent.increase"},image:{title:this.lang.get("image"),icon:!0,func:"image.show"},file:{title:this.lang.get("file"),icon:!0,func:"file.show"},link:{title:this.lang.get("link"),icon:!0,dropdown:{link:{title:this.lang.get("link-insert"),func:"link.show",observe:{element:"a",in:{title:this.lang.get("link-edit")},out:{title:this.lang.get("link-insert")}}},unlink:{title:this.lang.get("unlink"),func:"link.unlink",observe:{element:"a",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}}}},horizontalrule:{title:this.lang.get("horizontalrule"),icon:!0,func:"line.insert"}}},setFormatting:function(){for(var t in this.toolbarsButtons.format.dropdown)this.toolbarsButtons.format.dropdown.hasOwnProperty(t)&&-1===this.opts.formatting.indexOf(t)&&delete this.toolbarsButtons.format.dropdown[t]},hideButtons:function(){0!==this.opts.buttonsHide.length&&this.button.hideButtonsSlicer(this.opts.buttonsHide)},hideButtonsOnMobile:function(){this.detect.isMobile()&&0!==this.opts.buttonsHideOnMobile.length&&this.button.hideButtonsSlicer(this.opts.buttonsHideOnMobile)},hideButtonsSlicer:function(t){m.each(t,m.proxy(function(t,e){var i=this.opts.buttons.indexOf(e);-1!==i&&this.opts.buttons.splice(i,1)},this))},load:function(i){this.button.buttons=[],this.opts.buttons.forEach(function(t){var e;("image"!==t||this.image.is())&&this.toolbarsButtons.hasOwnProperty(t)&&((e=elCreate("li")).appendChild(this.button.build(t,this.toolbarsButtons[t])[0]),i[0].appendChild(e))}.bind(this))},buildButtonTooltip:function(){},build:function(t,e){var i,n=m('<a href="javascript:void(null);" rel="'+t+'" />');return n.addClass("re-button re-"+t),n.attr({role:"button",tabindex:"-1"}),n.html(e.title),(e.func||e.command||e.dropdown)&&this.button.setEvent(n,t,e),e.dropdown&&(n.addClass("redactor-toolbar-link-dropdown").attr("aria-haspopup",!0),i=m('<ul class="dropdownMenu redactor-dropdown-menu redactor-dropdown-menu-'+n[0].rel+'" data-dropdown-allow-flip="horizontal" data-dropdown-ignore-page-scroll="true" />'),n.data("dropdown",i),this.dropdown.build(t,i,e.dropdown),this.button.setupDropdown(n[0],i[0])),this.button.buttons.push(n),n},setupDropdown:function(e,i){require(["Ui/SimpleDropdown"],function(t){t.initFragment(e,i),t.registerCallback(e.id,function(t,e){"close"===e&&this.dropdown.hideOut()}.bind(this)),elData(e,"a11y-mouse-event","mousedown"),elData(e,"aria-expanded",!1),e.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation()})}.bind(this))},getButtons:function(){return this.button.toolbar().find("a.re-button")},getButtonsKeys:function(){return this.button.buttons},setEvent:function(n,r,s){n.on("mousedown",m.proxy(function(t){if(t.preventDefault(),n.hasClass("redactor-button-disabled"))return!1;var e="func",i=s.func;return s.command?(e="command",i=s.command):s.dropdown&&(i=!(e="dropdown")),this.button.toggle(t,r,e,i),!1},this))},toggle:function(t,e,i,n,r){!this.detect.isIe()&&this.detect.isDesktop()||(this.utils.freezeScroll(),t.returnValue=!1),"command"===i?this.inline.format(n):"dropdown"===i?this.dropdown.show(t,e):this.button.clickCallback(t,n,e,r),"dropdown"!==i&&this.dropdown.hideAll(!1),!this.detect.isIe()&&this.detect.isDesktop()||this.utils.unfreezeScroll()},clickCallback:function(t,e,i,n){var r;if(t instanceof Event?t.preventDefault():t&&t.originalEvent&&t.originalEvent.preventDefault(),n=void 0===n?i:n,m.isFunction(e))e.call(this,i);else if("-1"!==e.search(/\./)){if(void 0===this[(r=e.split("."))[0]])return;"object"==typeof n?this[r[0]][r[1]].apply(this,n):this[r[0]][r[1]].call(this,n)}else"object"==typeof n?this[e].apply(this,n):this[e].call(this,n);this.observe.buttons(t,i)},all:function(){return this.button.buttons},get:function(t){if(!1!==this.opts.toolbar)return this.button.toolbar().find("a.re-"+t)},set:function(t,e){if(!1!==this.opts.toolbar){var i=this.button.toolbar().find("a.re-"+t);return i.html(e).attr("aria-label",e),i}},add:function(t,e){if(!0!==this.button.isAdded(t))return m();var i=this.button.build(t,{title:e});return this.button.toolbar().append(m("<li>").append(i)),i},addFirst:function(t,e){if(!0!==this.button.isAdded(t))return m();var i=this.button.build(t,{title:e});return this.button.toolbar().prepend(m("<li>").append(i)),i},addAfter:function(t,e,i){if(!0!==this.button.isAdded(e))return m();var n=this.button.build(e,{title:i}),r=this.button.get(t);return 0!==r.length?r.parent().after(m("<li>").append(n)):this.button.toolbar().append(m("<li>").append(n)),n},addBefore:function(t,e,i){if(!0!==this.button.isAdded(e))return m();var n=this.button.build(e,{title:i}),r=this.button.get(t);return 0!==r.length?r.parent().before(m("<li>").append(n)):this.button.toolbar().append(m("<li>").append(n)),n},isAdded:function(t){var e=this.opts.buttonsHideOnMobile.indexOf(t);return!(!1===this.opts.toolbar||-1!==e&&this.detect.isMobile())},setIcon:function(t,e){this.opts.buttonsTextLabeled||t.html(e).addClass("re-button-icon")},changeIcon:function(t,e){var i=this.button.get(t);0!==i.length&&i.find("i").removeAttr("class").addClass("re-icon-"+e)},addCallback:function(e,i){var n,r;void 0!==e&&!1!==this.opts.toolbar&&(n="dropdown"===i?"dropdown":"func",r=e.attr("rel"),e.on("mousedown",m.proxy(function(t){return!e.hasClass("redactor-button-disabled")&&void this.button.toggle(t,r,n,i)},this)))},addDropdown:function(t,e){if(!1!==this.opts.toolbar){t.addClass("redactor-toolbar-link-dropdown").attr("aria-haspopup",!0);var i=t.attr("rel");this.button.addCallback(t,"dropdown");var n=m('<ul class="dropdownMenu redactor-dropdown-menu redactor-dropdown-menu-'+i+'" data-dropdown-allow-flip="horizontal" data-dropdown-ignore-page-scroll="true" />');return t.data("dropdown",n),e&&(this.dropdown.build(i,n,e),this.button.setupDropdown(t[0],n[0])),n}},setActive:function(t){this.button.get(t).addClass("redactor-act").attr({"aria-pressed":!0,tabindex:0})},setInactive:function(t){this.button.get(t).removeClass("redactor-act").attr({"aria-pressed":!1,tabindex:"html"===t?0:-1})},setInactiveAll:function(t){var e=this.button.toolbar().find("a.re-button");void 0!==t&&(e=e.not(".re-"+t)),e.removeClass("redactor-act").attr({"aria-pressed":!1,tabindex:"html"===t?0:-1})},disable:function(t){this.button.get(t).addClass("redactor-button-disabled").attr("aria-disabled",!0)},enable:function(t){this.button.get(t).removeClass("redactor-button-disabled").attr("aria-disabled",!1)},disableAll:function(t){var e=this.button.toolbar().find("a.re-button");void 0!==t&&(Array.isArray(t)||(t=[t]),t=t.map(function(t){return".re-"+t}),e=e.not(t.join(","))),e.addClass("redactor-button-disabled").attr("aria-disabled",!0)},enableAll:function(){this.button.toolbar().find("a.re-button").removeClass("redactor-button-disabled").attr("aria-disabled",!1)},remove:function(t){this.button.get(t).remove()}}},caret:function(){return{set:function(t,e,i){var n=this.core.editor().scrollTop();this.core.editor().focus(),this.core.editor().scrollTop(n),i=void 0===i?0:1,t=t[0]||t,e=e[0]||e;var r=this.selection.get(),s=this.selection.range(r);try{s.setStart(t,0),s.setEnd(e,i)}catch(t){}this.selection.update(r,s)},prepare:function(t){return this.detect.isFirefox()&&void 0!==this.start&&this.core.editor().focus(),t[0]||t},start:function(t){var e,i;if(t=this.caret.prepare(t)){if("BR"===t.tagName)return this.caret.before(t);var n=m(t).children().first(),r=this.utils.isInlineTag(t.tagName);""===t.innerHTML||r?this.caret.setStartEmptyOrInline(t,r):n&&0!==n.length&&this.utils.isInlineTag(n[0].tagName)&&""===n.text()?this.caret.setStartEmptyOrInline(n[0],!0):((e=window.getSelection()).removeAllRanges(),(i=document.createRange()).selectNodeContents(t),i.collapse(!0),e.addRange(i))}},setStartEmptyOrInline:function(t,e){var i=window.getSelection(),n=document.createRange(),r=document.createTextNode("​");n.setStart(t,0),n.insertNode(r),n.setStartAfter(r),n.collapse(!0),i.removeAllRanges(),i.addRange(n),e||this.core.editor().on("keydown.redactor-remove-textnode",function(){m(r).remove(),m(this).off("keydown.redactor-remove-textnode")})},end:function(t){var e,i;if(t=this.caret.prepare(t)){if("BR"!==t.tagName&&""===t.innerHTML)return this.caret.start(t);if("BR"===t.tagName){var n=document.createElement("span");return n.className="redactor-invisible-space",n.innerHTML="&#x200b;",m(t).after(n),(e=window.getSelection()).removeAllRanges(),(i=document.createRange()).setStartBefore(n),i.setEndBefore(n),e.addRange(i),void m(n).replaceWith(function(){return m(this).contents()})}if(t.lastChild&&1===t.lastChild.nodeType)return this.caret.after(t.lastChild);if((e=window.getSelection()).getRangeAt||e.rangeCount)try{(i=e.getRangeAt(0)).selectNodeContents(t),i.collapse(!1),e.removeAllRanges(),e.addRange(i)}catch(t){}}},after:function(t){var e,i,n,r;if(t=this.caret.prepare(t)){if("BR"===t.tagName)return this.caret.end(t);this.utils.isBlockTag(t.tagName)?void 0===(i=this.caret.next(t))?this.caret.end(t):("TABLE"===i.tagName?i=m(i).find("th, td").first()[0]:"UL"!==i.tagName&&"OL"!==i.tagName||(i=m(i).find("li").first()[0]),this.caret.start(i)):(n=document.createTextNode("​"),(r=window.getSelection()).removeAllRanges(),(e=document.createRange()).setStartAfter(t),e.insertNode(n),e.setStartAfter(n),e.collapse(!0),r.addRange(e))}},before:function(t){var e,i,n;(t=this.caret.prepare(t))&&(this.utils.isBlockTag(t.tagName)?void 0===(n=this.caret.prev(t))?this.caret.start(t):("TABLE"===n.tagName?n=m(n).find("th, td").last()[0]:"UL"!==n.tagName&&"OL"!==n.tagName||(n=m(n).find("li").last()[0]),this.caret.end(n)):((e=window.getSelection()).removeAllRanges(),(i=document.createRange()).setStartBefore(t),i.collapse(!0),e.addRange(i)))},next:function(t){var e=m(t).next();return e.hasClass("redactor-script-tag, redactor-selection-marker")?e.next()[0]:e[0]},prev:function(t){var e=m(t).prev();return e.hasClass("redactor-script-tag, redactor-selection-marker")?e.prev()[0]:e[0]},offset:function(t){return this.offset.get(t)}}},clean:function(){return{onSet:function(t){t=this.clean.savePreCode(t),this.opts.script&&(t=t.replace(/<script(.*?[^>]?)>([\w\W]*?)<\/script>/gi,'<pre class="redactor-script-tag" $1>$2</pre>')),t=(t=(t=(t=(t=t.replace(/\$/g,"&#36;")).replace(/&amp;/g,"&")).replace(/<a href="(.*?[^>]?)®(.*?[^>]?)">/gi,'<a href="$1&reg$2">')).replace(/<span id="selection-marker-1"(.*?[^>]?)>​<\/span>/gi,"###marker1###")).replace(/<span id="selection-marker-2"(.*?[^>]?)>​<\/span>/gi,"###marker2###");var e,i=this,n=m("<div/>").html(m.parseHTML(t,document,!0)),r=this.opts.replaceTags;r&&(e=Object.keys(this.opts.replaceTags),n.find(e.join(",")).each(function(t,e){i.utils.replaceToTag(e,r[e.tagName.toLowerCase()])})),n.find("span, a").attr("data-redactor-span",!0),n.find(this.opts.inlineTags.join(",")).each(function(){var t=m(this);t.attr("style")&&t.attr("data-redactor-style-cache",t.attr("style"))}),t=n.html();var s=["font","html","head","link","body","meta","applet"];return this.opts.script||s.push("script"),t=this.clean.stripTags(t,s),this.opts.removeComments&&(t=t.replace(/<!--[\s\S]*?-->/gi,"")),-1!==(t=(t=(t=this.paragraphize.load(t)).replace("###marker1###",'<span id="selection-marker-1" class="redactor-selection-marker">​</span>')).replace("###marker2###",'<span id="selection-marker-2" class="redactor-selection-marker">​</span>')).search(/^(||\s||<br\s?\/?>||&nbsp;)$/i)?this.opts.emptyHtml:t},onGet:function(t){return this.clean.onSync(t)},onSync:function(i){if(-1!==(i=(i=i.replace(/\u200B/g,"")).replace(/&#x200b;/gi,"")).search(/^<p>(||\s||<br\s?\/?>||&nbsp;)<\/p>$/i))return"";i=(i=(i=(i=i.replace(/<span(.*?)id="redactor-image-box"(.*?[^>])>([\w\W]*?)<img(.*?)><\/span>/gi,"$3<img$4>")).replace(/<span(.*?)id="redactor-image-resizer"(.*?[^>])>(.*?)<\/span>/gi,"")).replace(/<span(.*?)id="redactor-image-editter"(.*?[^>])>(.*?)<\/span>/gi,"")).replace(/<img(.*?)style="(.*?)opacity: 0\.5;(.*?)"(.*?)>/gi,'<img$1style="$2$3"$4>');var t=m("<div/>").html(m.parseHTML(i,document,!0));t.find('*[style=""]').removeAttr("style"),t.find('*[class=""]').removeAttr("class"),t.find('*[rel=""]').removeAttr("rel"),t.find('*[data-image=""]').removeAttr("data-image"),t.find('*[alt=""]').removeAttr("alt"),t.find('*[title=""]').removeAttr("title"),t.find("*[data-redactor-style-cache]").removeAttr("data-redactor-style-cache"),t.find(".redactor-invisible-space, .redactor-unlink").each(function(){m(this).contents().unwrap()}),t.find("span, a").removeAttr("data-redactor-span data-redactor-style-cache").each(function(){0===this.attributes.length&&m(this).contents().unwrap()}),t.find("img").removeAttr("rel"),t.find(".redactor-selection-marker, #redactor-insert-marker").remove(),i=t.html(),this.opts.script&&(i=i.replace(/<pre class="redactor-script-tag"(.*?[^>]?)>([\w\W]*?)<\/pre>/gi,"<script$1>$2<\/script>")),i=(i=(i=(i=(i=this.clean.restoreFormTags(i)).replace(new RegExp("<br\\s?/?></h","gi"),"</h")).replace(new RegExp("<br\\s?/?></li>","gi"),"</li>")).replace(new RegExp("</li><br\\s?/?>","gi"),"</li>")).replace(/<pre>/gi,"<pre>\n"),this.opts.preClass&&(i=i.replace(/<pre>/gi,'<pre class="'+this.opts.preClass+'">')),this.opts.linkNofollow&&(i=(i=i.replace(/<a(.*?)rel="nofollow"(.*?[^>])>/gi,"<a$1$2>")).replace(/<a(.*?[^>])>/gi,'<a$1 rel="nofollow">'));return m.each({"™":"&trade;","©":"&copy;","…":"&hellip;","—":"&mdash;","‐":"&dash;"},function(t,e){i=i.replace(new RegExp(t,"g"),e)}),i=(i=i.replace(/&amp;/g,"&")).replace(/\n{2,}/g,"\n"),this.opts.removeNewlines&&(i=i.replace(/\r?\n/g,"")),i},onPaste:function(t,e,i){return!0!==i&&(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace(/<b\sid="internal-source-marker(.*?)">([\w\W]*?)<\/b>/gi,"$2")).replace(/<b(.*?)id="docs-internal-guid(.*?)">([\w\W]*?)<\/b>/gi,"$3")).replace(/<span[^>]*(font-style: italic; font-weight: bold|font-weight: bold; font-style: italic)[^>]*>([\w\W]*?)<\/span>/gi,"<b><i>$2</i></b>")).replace(/<span[^>]*(font-style: italic; font-weight: 700|font-weight: 700; font-style: italic)[^>]*>([\w\W]*?)<\/span>/gi,"<b><i>$2</i></b>")).replace(/<span[^>]*font-style: italic[^>]*>([\w\W]*?)<\/span>/gi,"<i>$1</i>")).replace(/<span[^>]*font-weight: bold[^>]*>([\w\W]*?)<\/span>/gi,"<b>$1</b>")).replace(/<span[^>]*font-weight: 700[^>]*>([\w\W]*?)<\/span>/gi,"<b>$1</b>")).replace(/<o:p[^>]*>/gi,"")).replace(/<\/o:p>/gi,""),this.clean.isHtmlMsWord(t)&&(t=this.clean.cleanMsWord(t))),t=m.trim(t),e.pre?this.opts.preSpaces&&(t=t.replace(/\t/g,new Array(this.opts.preSpaces+1).join(" "))):(t=this.clean.replaceBrToNl(t),t=this.clean.removeTagsInsidePre(t)),!0!==i&&(t=this.clean.removeEmptyInlineTags(t),!1===e.encode&&(t=t.replace(/&/g,"&amp;"),t=this.clean.convertTags(t,e),t=this.clean.getPlainText(t),t=this.clean.reconvertTags(t,e))),e.text&&(t=this.clean.replaceNbspToSpaces(t),t=this.clean.getPlainText(t)),e.lists&&(t=t.replace("\n","<br>")),e.encode&&(t=this.clean.encodeHtml(t)),e.paragraphize&&(t=(t=t.replace(/ \n/g," ")).replace(/\n /g," "),t=(t=this.paragraphize.load(t)).replace(/<p><\/p>/g,"")),t=(t=t.replace(/<li><p>/g,"<li>")).replace(/<\/p><\/li>/g,"</li>")},getCurrentType:function(t,e){var i=this.selection.blocks(),n={text:!1,encode:!1,paragraphize:!0,line:this.clean.isHtmlLine(t),blocks:this.clean.isHtmlBlocked(t),pre:!1,lists:!1,block:!0,inline:!0,links:!0,images:!0};return 1===i.length&&this.utils.isCurrentOrParent(["h1","h2","h3","h4","h5","h6","a","figcaption"])?(n.text=!0,n.paragraphize=!1,n.inline=!1,n.images=!1,n.links=!1,n.line=!0):"inline"===this.opts.type||!1===this.opts.enterKey?(n.paragraphize=!1,n.block=!1,n.line=!0):1===i.length&&this.utils.isCurrentOrParent(["li"])?(n.lists=!0,n.block=!1,n.paragraphize=!1,n.images=!1):1===i.length&&this.utils.isCurrentOrParent(["th","td","blockquote"])?(n.block=!1,n.paragraphize=!1):("pre"===this.opts.type||1===i.length&&this.utils.isCurrentOrParent("pre"))&&(n.inline=!1,n.block=!1,n.encode=!0,n.pre=!0,n.paragraphize=!1,n.images=!1,n.links=!1),!0===n.line&&(n.paragraphize=!1),!0===e&&(n.text=!1),n},isHtmlBlocked:function(t){var e=t.match(new RegExp("</("+this.opts.blockTags.join("|").toUpperCase()+")>","gi")),i=t.match(new RegExp("<hr(.*?[^>])>","gi"));return null!==e||null!==i},isHtmlLine:function(t){if(this.clean.isHtmlBlocked(t))return!1;var e=t.match(/<br\s?\/?>/gi),i=t.match(/\n/gi);return!e&&!i},isHtmlMsWord:function(t){return t.match(/class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i)},removeEmptyInlineTags:function(t){var e=this.opts.inlineTags,i=m("<div/>").html(m.parseHTML(t,document,!0)),n=this,r=i.find("span"),s=i.find(e.join(","));return s.removeAttr("style"),s.each(function(){var t=m(this).html();0===this.attributes.length&&n.utils.isEmpty(t)&&m(this).replaceWith(function(){return m(this).contents()})}),r.each(function(){m(this).html();0===this.attributes.length&&m(this).replaceWith(function(){return m(this).contents()})}),t=(t=(t=(t=i.html()).replace("\x3c!--?php","<?php")).replace("\x3c!--?","<?")).replace("?--\x3e","?>"),i.remove(),t},cleanMsWord:function(t){t=(t=(t=(t=(t=t.replace(/<!--[\s\S]*?-->/g,"")).replace(/<o:p>[\s\S]*?<\/o:p>/gi,"")).replace(/\n/g," ")).replace(/<\/p>/gi,'</p><p><br data-redactor="br"></p>')).replace(/<\/div>|<\/li>|<\/td>/gi,"\n\n");var l=m("<div/>").html(t);elBySelAll("br",l[0],function(t){if("br"===elData(t,"redactor"))t.removeAttribute("data-redactor");else{var e=t.parentNode;if(e&&"P"===e.nodeName){for(var i=elCreate("p");t.nextSibling;)i.appendChild(t.nextSibling);e.parentNode.insertBefore(i,e.nextSibling),elRemove(t)}}});var c=!1,h=1,d=[];return l.find("p[style]").each(function(){var t=m(this).attr("style").match(/mso\-list\:l([0-9]+)\slevel([0-9]+)/);if(t){var e=parseInt(t[1]),i=parseInt(t[2]),n=m(this).html().match(/^[\w]+\./)?"ol":"ul",r=m("<li/>").html(m(this).html());if(r.html(r.html().replace(/^([\w\.]+)</,"<")),r.find("span:first").remove(),1==i&&-1==m.inArray(e,d)){var s=m("<"+n+"/>").attr({"data-level":i,"data-list":e}).html(r);m(this).replaceWith(s),c=e,d.push(e)}else{if(h<i){for(var o=l.find('[data-level="'+h+'"][data-list="'+c+'"]'),a=h;a<i;a++)(s=m("<"+n+"/>")).appendTo(o.find("li").last()),o=s;o.attr({"data-level":i,"data-list":e}).html(r)}else{l.find('[data-level="'+i+'"][data-list="'+e+'"]').last().append(r)}h=i,c=e,m(this).remove()}}}),l.find("[data-level][data-list]").removeAttr("data-level data-list"),elBySelAll("ol, ul",l[0],function(i){["nextElementSibling","previousElementSibling"].forEach(function(t){for(var e=i[t];e&&"P"===e.nodeName&&""===e.className&&"<br>"===e.innerHTML;)elRemove(e),e=i[t]})}),t=l.html()},replaceNbspToSpaces:function(t){return t.replace("&nbsp;"," ")},replaceBrToNl:function(t){return t.replace(/<br\s?\/?>/gi,"\n")},replaceNlToBr:function(t){return t.replace(/\n/g,"<br />")},convertTags:function(t,e){var i=m("<div>").html(t);i.find("iframe").remove();var n=i.find("a");if(n.removeAttr("style"),!1!==this.opts.pasteLinkTarget&&n.attr("target",this.opts.pasteLinkTarget),e.links&&this.opts.pasteLinks&&i.find("a").each(function(t,e){if(e.href){for(var i,n='#####[a href="'+e.href+'"',r=0,s=e.attributes.length;r<s;r++)"href"!==(i=e.attributes.item(r)).name&&(n+=" "+i.name+'="'+i.value+'"');e.outerHTML=n+"]#####"+e.innerHTML+"#####[/a]#####"}}),t=i.html(),e.images&&this.opts.pasteImages&&(t=t.replace(/<img(.*?)src="(.*?)"(.*?[^>])>/gi,'#####[img$1src="$2"$3]#####')),this.opts.pastePlainText)return t;for(var r=e.lists?["ul","ol","li"]:this.opts.pasteBlockTags,s=e.block||e.lists?e.inline?r.concat(this.opts.pasteInlineTags):r:e.inline?this.opts.pasteInlineTags:[],o=s.length,a=0;a<o;a++)t=t.replace(new RegExp("</"+s[a]+">","gi"),"###/"+s[a]+"###"),t="td"===s[a]||"th"===s[a]?t.replace(new RegExp("<"+s[a]+'(.*?[^>])((colspan|rowspan)="(.*?[^>])")?(.*?[^>])>',"gi"),"###"+s[a]+" $2###"):this.utils.isInlineTag(s[a])?(t=(t=t.replace(new RegExp("<"+s[a]+'([^>]*)class="([^>]*)"[^>]*>',"gi"),"###"+s[a]+' class="$2"###')).replace(new RegExp("<"+s[a]+'([^>]*)data-redactor-style-cache="([^>]*)"[^>]*>',"gi"),"###"+s[a]+' cache="$2"###')).replace(new RegExp("<"+s[a]+"[^>]*>","gi"),"###"+s[a]+"###"):t.replace(new RegExp("<"+s[a]+"[^>]*>","gi"),"###"+s[a]+"###");return t},reconvertTags:function(t,e){if((e.links&&this.opts.pasteLinks||e.images&&this.opts.pasteImages)&&(t=(t=t.replace(new RegExp("#####\\[","gi"),"<")).replace(new RegExp("\\]#####","gi"),">")),this.opts.pastePlainText)return t;for(var i=e.lists?["ul","ol","li"]:this.opts.pasteBlockTags,n=e.block||e.lists?e.inline?i.concat(this.opts.pasteInlineTags):i:e.inline?this.opts.pasteInlineTags:[],r=n.length,s=0;s<r;s++)t=t.replace(new RegExp("###/"+n[s]+"###","gi"),"</"+n[s]+">");for(s=0;s<r;s++)t=t.replace(new RegExp("###"+n[s]+"###","gi"),"<"+n[s]+">");for(var o,s=0;s<r;s++){"td"===n[s]||"th"===n[s]?t=t.replace(new RegExp("###"+n[s]+"s?(.*?[^#])###","gi"),"<"+n[s]+"$1>"):this.utils.isInlineTag(n[s])&&(o="span"===n[s]?' data-redactor-span="true"':"",t=(t=t.replace(new RegExp("###"+n[s]+' cache="(.*?[^#])"###',"gi"),"<"+n[s]+' style="$1"'+o+' data-redactor-style-cache="$1">')).replace(new RegExp("###"+n[s]+"s?(.*?[^#])###","gi"),"<"+n[s]+"$1>"))}return t},cleanPre:function(t){t=void 0===t?m(this.selection.block()).closest("pre",this.core.editor()[0]):t,m(t).find("br").replaceWith(function(){return document.createTextNode("\n")}),m(t).find("p").replaceWith(function(){return m(this).contents()})},removeTagsInsidePre:function(t){var e=m("<div />").append(t);return e.find("pre").replaceWith(function(){var t=m(this).html();return t=(t=t.replace(/<br\s?\/?>|<\/p>|<\/div>|<\/li>|<\/td>/gi,"\n")).replace(/(<([^>]+)>)/gi,""),m("<pre />").append(t)}),t=e.html(),e.remove(),t},getPlainText:function(t){t=(t=(t=(t=(t=(t=t.replace(/<!--[\s\S]*?-->/gi,"")).replace(/<style[\s\S]*?style>/gi,"")).replace(/<p><\/p>/g,"")).replace(/<\/div>|<\/li>|<\/td>/gi,"\n")).replace(/<\/p>/gi,"\n\n")).replace(/<\/H[1-6]>/gi,"\n\n");var e=document.createElement("div");return e.innerHTML=t,t=e.textContent||e.innerText,m.trim(t)},savePreCode:function(t){return t=this.clean.savePreFormatting(t),t=this.clean.saveCodeFormatting(t),t=this.clean.restoreSelectionMarkers(t)},savePreFormatting:function(a){var t=a.match(/<pre(.*?)>([\w\W]*?)<\/pre>/gi);return null===t||m.each(t,m.proxy(function(t,e){var i,n,r,s=[],o=!1;e.match(/<pre(.*?)>(([\n\r\s]+)?)<code(.*?)>/i)?(o=!0,i=(s=e.match(/<pre(.*?)>(([\n\r\s]+)?)<code(.*?)>([\w\W]*?)<\/code>(([\n\r\s]+)?)<\/pre>/i))[5],n=s[1],r=s[4]):(i=(s=e.match(/<pre(.*?)>([\w\W]*?)<\/pre>/i))[2],n=s[1]),i=(i=i.replace(/<br\s?\/?>/g,"\n")).replace(/&nbsp;/g," "),this.opts.preSpaces&&(i=i.replace(/\t/g,new Array(this.opts.preSpaces+1).join(" "))),i=(i=this.clean.encodeEntities(i)).replace(/\$/g,"&#36;"),a=o?a.replace(e,"<pre"+n+"><code"+r+">"+i+"</code></pre>"):a.replace(e,"<pre"+n+">"+i+"</pre>")},this)),a},saveCodeFormatting:function(n){var t=n.match(/<code(.*?)>([\w\W]*?)<\/code>/gi);return null===t||m.each(t,m.proxy(function(t,e){var i=e.match(/<code(.*?)>([\w\W]*?)<\/code>/i);i[2]=i[2].replace(/&nbsp;/g," "),i[2]=this.clean.encodeEntities(i[2]),i[2]=i[2].replace(/\$/g,"&#36;"),n=n.replace(e,"<code"+i[1]+">"+i[2]+"</code>")},this)),n},restoreSelectionMarkers:function(t){return t=t.replace(/&lt;span id=&quot;selection-marker-([0-9])&quot; class=&quot;redactor-selection-marker&quot;&gt;​&lt;\/span&gt;/g,'<span id="selection-marker-$1" class="redactor-selection-marker">​</span>')},saveFormTags:function(t){return t},restoreFormTags:function(t){return t.replace(/<section(.*?) rel="redactor-form-tag"(.*?)>([\w\W]*?)<\/section>/gi,"<form$1$2>$3</form>")},encodeHtml:function(t){return t=(t=(t=(t=t.replace(/”/g,'"')).replace(/“/g,'"')).replace(/‘/g,"'")).replace(/’/g,"'"),t=this.clean.encodeEntities(t)},encodeEntities:function(t){return t=(t=String(t).replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"')).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},stripTags:function(t,i){if(void 0===i)return t.replace(/(<([^>]+)>)/gi,"");return t.replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,function(t,e){return-1===i.indexOf(e.toLowerCase())?t:""})},removeMarkers:function(t){return t.replace(/<span(.*?[^>]?)class="redactor-selection-marker"(.*?[^>]?)>([\w\W]*?)<\/span>/gi,"")},removeSpaces:function(t){return t=(t=(t=(t=(t=(t=(t=(t=(t=m.trim(t)).replace(/\n/g,"")).replace(/[\t]*/g,"")).replace(/\n\s*\n/g,"\n")).replace(/^[\s\n]*/g," ")).replace(/[\s\n]*$/g," ")).replace(/>\s{2,}</g,"> <")).replace(/\n\n/g,"\n")).replace(/\u200B/g,"")},removeSpacesHard:function(t){return t=(t=(t=(t=(t=(t=(t=(t=(t=m.trim(t)).replace(/\n/g,"")).replace(/[\t]*/g,"")).replace(/\n\s*\n/g,"\n")).replace(/^[\s\n]*/g,"")).replace(/[\s\n]*$/g,"")).replace(/>\s{2,}</g,"><")).replace(/\n\n/g,"\n")).replace(/\u200B/g,"")},normalizeCurrentHeading:function(){var t=this.selection.block();this.utils.isCurrentOrParentHeader()&&t&&t.normalize()}}},code:function(){return{syncFire:!0,html:!1,start:function(t){t=(t=m.trim(t)).replace(/^(<span id="selection-marker-1" class="redactor-selection-marker">​<\/span>)/,""),t=(t=this.clean.onSet(t)).replace(/<p><span id="selection-marker-1" class="redactor-selection-marker">​<\/span><\/p>/,""),this.events.stopDetectChanges(),this.core.editor().html(t),this.observe.load(),this.events.startDetectChanges()},set:function(t,e){t=m.trim(t),(e=e||{}).start&&(this.start=e.start),"textarea"===this.opts.type?t=this.clean.onSet(t):"div"===this.opts.type&&""===t&&(t=this.opts.emptyHtml),this.core.editor().html(t),"textarea"===this.opts.type&&this.code.sync()},get:function(){if("textarea"===this.opts.type)return this.core.textarea().val();var t=this.core.editor().html();return t=this.clean.onGet(t)},sync:function(){if(this.code.syncFire){var t=this.core.editor().html(),e=this.code.cleaned(t);if(!this.code.isSync(e)){if(this.code.html=e,"textarea"!==this.opts.type)return this.core.callback("sync",t),void this.core.callback("change",t);"textarea"===this.opts.type&&setTimeout(m.proxy(function(){this.code.startSync(t)},this),10)}}},startSync:function(t){t=this.core.callback("syncBefore",t),t=this.clean.onSync(t),this.core.textarea().val(t),this.core.callback("sync",t),!1===this.start&&this.core.callback("change",t),this.start=!1},isSync:function(t){var e=!1!==this.code.html&&this.code.html;return!1!==e&&e===t},cleaned:function(t){return t=t.replace(/\u200B/g,""),this.clean.removeMarkers(t)}}},core:function(){return{id:function(){return this.$editor.attr("id")},element:function(){return this.$element},editor:function(){return void 0===this.$editor?m():this.$editor},textarea:function(){return this.$textarea},box:function(){return"textarea"===this.opts.type?this.$box:this.$element},toolbar:function(){return!!this.$toolbar&&this.$toolbar},air:function(){return!!this.$air&&this.$air},object:function(){return m.extend({},this)},structure:function(){this.core.editor().toggleClass("redactor-structure")},addEvent:function(t){this.core.event=t},getEvent:function(){return this.core.event},callback:function(t,e,i){var n=!1,r=m._data(this.core.element()[0],"events");if(void 0!==r&&void 0!==r[t])for(var s,o,a=r[t].length,l=0;l<a;l++){"callback.redactor"===r[t][l].namespace&&(s=r[t][l].handler,n=void 0===(o=void 0===i?[e]:[e,i])?s.call(this,e):s.call(this,e,o))}if(n)return n;if(void 0===this.opts.callbacks[t])return void 0===i?e:i;var c=this.opts.callbacks[t];return m.isFunction(c)?void 0===i?c.call(this,e):c.call(this,e,i):void 0===i?e:i},destroy:function(){this.opts.destroyed=!0,this.core.callback("destroy"),m("#redactor-voice-"+this.uuid).remove(),this.core.editor().removeClass("redactor-in redactor-styles redactor-structure redactor-layer-img-edit"),this.core.editor().off("keydown.redactor-remove-textnode"),this.core.editor().off(".redactor-observe."+this.uuid),this.$element.off(".redactor").removeData("redactor"),this.core.editor().off(".redactor"),m(document).off(".redactor-air."+this.uuid),m(document).off("mousedown.redactor-blur."+this.uuid),m(document).off("mousedown.redactor."+this.uuid),m(document).off("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid),m(window).off(".redactor-toolbar."+this.uuid),m(window).off("touchmove.redactor."+this.uuid),m("body").off("scroll.redactor."+this.uuid),m(this.opts.toolbarFixedTarget).off("scroll.redactor."+this.uuid);var i=this;!1!==this.opts.plugins&&m.each(this.opts.plugins,function(t,e){m(window).off(".redactor-plugin-"+e),m(document).off(".redactor-plugin-"+e),m("body").off(".redactor-plugin-"+e),i.core.editor().off(".redactor-plugin-"+e)}),this.$element.off("click.redactor-click-to-edit"),this.$element.removeClass("redactor-click-to-edit"),this.core.editor().removeClass("redactor-layer"),this.core.editor().removeAttr("contenteditable");var t=this.code.get();this.opts.toolbar&&this.$toolbar&&this.$toolbar.find("a").each(function(){var t=m(this);t.data("dropdown")&&(t.data("dropdown").remove(),t.data("dropdown",{}))}),"textarea"===this.opts.type&&(this.$box.after(this.$element),this.$box.remove(),this.$element.val(t).show()),this.opts.toolbar&&this.$toolbar&&this.$toolbar.remove(),this.$modalBox&&this.$modalBox.remove(),this.$modalOverlay&&this.$modalOverlay.remove(),m(".redactor-link-tooltip").remove()}}},detect:function(){return{isWebkit:function(){return/webkit/.test(this.opts.userAgent)},isFirefox:function(){return-1<this.opts.userAgent.indexOf("firefox")},isIe:function(t){if(document.documentMode||/Edge/.test(navigator.userAgent))return"edge";var e=RegExp("msie"+(isNaN(t)?"":"\\s"+t),"i").test(navigator.userAgent);return e=e||!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)},isMobile:function(){return/(iPhone|iPod|BlackBerry|Android)/.test(navigator.userAgent)},isDesktop:function(){return!/(iPhone|iPod|iPad|BlackBerry|Android)/.test(navigator.userAgent)},isIpad:function(){return/iPad/.test(navigator.userAgent)}}},dropdown:function(){return{active:!1,button:!1,key:!1,position:[],getDropdown:function(){return this.dropdown.active},build:function(t,e,i){var n,r,s=document.createDocumentFragment();for(var o in i){i.hasOwnProperty(o)&&(n=i[o],r=this.dropdown.buildItem(o,n),this.observe.addDropdown(m(r),o,n),s.appendChild(r))}for(var a=!1,l=0,c=s.childNodes.length;l<c;l++)if(s.childNodes[l].nodeType===Node.ELEMENT_NODE){a=!0;break}a&&(e[0].rel=t,e[0].appendChild(s))},buildFormatting:function(){},buildItem:function(e,i){var t=elCreate("li");return void 0!==i.classname&&t.classList.add(i.classname),0===e.toLowerCase().indexOf("divider")?t.classList.add("redactor-dropdown-divider"):(t.innerHTML='<a href="#" class="redactor-dropdown-'+e+'" role="button"><span>'+i.title+"</span></a>",m(t.children[0]).on("mousedown",function(t){t.preventDefault(),this.dropdown.buildClick(t,e,i)}.bind(this))),t},buildClick:function(t,e,i){var n;m(t.target).hasClass("redactor-dropdown-link-inactive")||(n=this.dropdown.buildCommand(i),void 0!==i.args?this.button.toggle(t,e,n.type,n.callback,i.args):this.button.toggle(t,e,n.type,n.callback))},buildCommand:function(t){var e={type:"func"};return e.callback=t.func,t.command?(e.type="command",e.callback=t.command):t.dropdown&&(e.type="dropdown",e.callback=t.dropdown),e},show:function(t,e){this.detect.isDesktop()&&this.core.editor().focus(),this.dropdown.hideAll(!1,e),this.dropdown.key=e,this.dropdown.button=this.button.get(this.dropdown.key),require(["Ui/SimpleDropdown"],function(t){var e=this.dropdown.button[0].id;t.toggleDropdown(e),t.isOpen(e)?(this.dropdown.active=m(t.getDropdownMenu(e)),this.core.callback("dropdownShow",{dropdown:this.dropdown.active,key:this.dropdown.key,button:this.dropdown.button}),this.button.setActive(this.dropdown.key),this.dropdown.button.addClass("dropact").attr("aria-expanded",!0),this.dropdown.enableCallback()):this.dropdown.hide()}.bind(this)),t.preventDefault()},showIsFixedToolbar:function(){},showIsUnFixedToolbar:function(){},enableEvents:function(){},enableCallback:function(){this.core.callback("dropdownShown",{dropdown:this.dropdown.active,key:this.dropdown.key,button:this.dropdown.button})},getButtonPosition:function(){},closeHandler:function(){},hideAll:function(t,e){this.dropdown.hideOut(e)},hide:function(){this.dropdown.hideOut()},hideOut:function(t){var e;!1!==this.dropdown.active&&this.dropdown.button[0].rel!==t&&(this.core.callback("dropdownHide",this.dropdown.active),e=this.dropdown.button[0].id,require(["Ui/SimpleDropdown"],function(t){t.close(e)}),this.dropdown.button.removeClass("redactor-act dropact").attr("aria-expanded",!1),this.dropdown.button=!1,this.dropdown.key=!1,this.dropdown.active=!1)}}},events:function(){return{focused:!1,blured:!0,dropImage:!1,stopChanges:!1,stopDetectChanges:function(){this.events.stopChanges=!0},startDetectChanges:function(){var t=this;setTimeout(function(){t.events.stopChanges=!1},1)},dragover:function(t){t.preventDefault(),"IMG"===t.target.tagName&&m(t.target).addClass("redactor-image-dragover")},dragleave:function(t){this.core.editor().find("img").removeClass("redactor-image-dragover")},drop:function(t){return t=t.originalEvent||t,this.core.editor().find("img").removeClass("redactor-image-dragover"),"inline"===this.opts.type||"pre"===this.opts.type?(t.preventDefault(),!1):void 0===window.FormData||!t.dataTransfer||(0===t.dataTransfer.files.length?this.events.onDrop(t):(this.events.onDropUpload(t),void this.core.callback("drop",t)))},click:function(t){var e=this.core.getEvent(),i="click"!==e&&"arrow"!==e&&"click";this.core.addEvent(i),this.utils.disableSelectAll(),this.core.callback("click",t)},focus:function(t){var e,i;this.rtePaste||(this.events.isCallback("focus")&&this.core.callback("focus",t),this.events.focused=!0,(this.events.blured=!1)===this.selection.current()&&(e=this.selection.get(),(i=this.selection.range(e)).setStart(this.core.editor()[0],0),i.setEnd(this.core.editor()[0],0),this.selection.update(e,i)))},blur:function(t){this.start||this.rtePaste||0===m(t.target).closest("#"+this.core.id()+", .redactor-toolbar, .redactor-dropdown, #redactor-modal-box").length&&(!this.events.blured&&this.events.isCallback("blur")&&this.core.callback("blur",t),this.events.focused=!1,this.events.blured=!0)},touchImageEditing:function(){var t=-1;this.events.imageEditing=!1,m(window).on("touchmove.redactor."+this.uuid,m.proxy(function(){this.events.imageEditing=!0,-1!==t&&clearTimeout(t),t=setTimeout(m.proxy(function(){this.events.imageEditing=!1},this),500)},this))},init:function(){this.core.editor().on("dragover.redactor dragenter.redactor",m.proxy(this.events.dragover,this)),this.core.editor().on("dragleave.redactor",m.proxy(this.events.dragleave,this)),this.core.editor().on("drop.redactor",m.proxy(this.events.drop,this)),this.core.editor().on("click.redactor",m.proxy(this.events.click,this)),this.core.editor().on("paste.redactor",m.proxy(this.paste.init,this)),this.core.editor().on("keydown.redactor",m.proxy(this.keydown.init,this)),this.core.editor().on("keyup.redactor",m.proxy(this.keyup.init,this)),this.core.editor().on("focus.redactor",m.proxy(this.events.focus,this)),m(document).on("mousedown.redactor-blur."+this.uuid,m.proxy(this.events.blur,this)),this.events.touchImageEditing(),this.events.createObserver(),this.events.setupObserver()},createObserver:function(){var e=this;this.events.observer=new MutationObserver(function(t){t.forEach(m.proxy(e.events.iterateObserver,e))})},iterateObserver:function(t){var e=!1;("textarea"!==this.opts.type&&"div"!==this.opts.type||this.detect.isFirefox()||t.target!==this.core.editor()[0])&&("class"!==t.attributeName||t.target!==this.core.editor()[0])&&"data-vivaldi-spatnav-clickable"!=t.attributeName||(e=!0),e||(this.observe.load(),this.events.changeHandler())},setupObserver:function(){this.events.observer.observe(this.core.editor()[0],{attributes:!0,subtree:!0,childList:!0,characterData:!0,characterDataOldValue:!0})},changeHandler:function(){this.events.stopChanges||this.code.sync()},onDropUpload:function(t){if(t.preventDefault(),t.stopPropagation(),(this.opts.dragImageUpload||this.opts.dragFileUpload)&&(null!==this.opts.imageUpload||null!==this.opts.fileUpload)){"IMG"===t.target.tagName&&(this.events.dropImage=t.target);for(var e=t.dataTransfer.files,i=e.length,n=0;n<i;n++)this.upload.directUpload(e[n],t)}},onDrop:function(t){this.core.callback("drop",t)},isCallback:function(t){return void 0!==this.opts.callbacks[t]&&m.isFunction(this.opts.callbacks[t])},stopDetect:function(){this.events.stopDetectChanges()},startDetect:function(){this.events.startDetectChanges()}}},file:function(){return{is:function(){},show:function(){},insert:function(){},release:function(){},text:function(t){}}},focus:function(){return{start:function(){var t;this.core.editor().focus(),"inline"===this.opts.type||!1!==(t=this.focus.first())&&this.caret.start(t)},end:function(){this.core.editor().focus();var t,e,i,n=this.opts.inline?this.core.editor():this.focus.last();0!==n.length&&(t=this.focus.lastChild(n),this.detect.isWebkit()||!1===t?(e=this.selection.get(),null!==(i=this.selection.range(e))?(i.selectNodeContents(n[0]),i.collapse(!1),this.selection.update(e,i)):this.caret.end(n)):this.caret.end(t))},first:function(){var t=this.core.editor().children().first();return(0!==t.length||0!==t[0].length&&"BR"!==t[0].tagName&&"HR"!==t[0].tagName&&3!==t[0].nodeType)&&("UL"===t[0].tagName||"OL"===t[0].tagName?t.find("li").first():t)},last:function(){return this.core.editor().children().last()},lastChild:function(t){var e=t[0].lastChild;return!(null===e||!this.utils.isInlineTag(e.tagName))&&e},is:function(){return this.core.editor()[0]===document.activeElement}}},image:function(){return{is:function(){return!(!this.opts.imageUpload||!this.opts.imageUpload&&!this.opts.s3)},show:function(){this.modal.load("image",this.lang.get("image"),700),this.upload.init("#redactor-modal-image-droparea",this.opts.imageUpload,this.image.insert),this.modal.show()},insert:function(t,e,i){if(void 0!==t.error)return this.modal.close(),this.events.dropImage=!1,void this.core.callback("imageUploadError",t,i);if(!1!==this.events.dropImage)return n=m(this.events.dropImage),this.core.callback("imageDelete",n[0].src,n),n.attr("src",t.url),this.events.dropImage=!1,void this.core.callback("imageUpload",n,t);var n,r=m("<"+this.opts.imageTag+">");(n=m("<img>")).attr("src",t.url);var s=void 0===t.id?"":t.id,o=void 0===t.s3?"image":"s3";n.attr("data-"+o,s),r.append(n);var a,l,c=this.utils.isTag(this.selection.current(),"pre");e?(this.marker.remove(),a=this.insert.nodeToPoint(i,this.marker.get()),l=m(a).next(),this.selection.restore(),this.buffer.set(),void 0!==l&&0!==l.length&&"IMG"===l[0].tagName?(this.core.callback("imageDelete",l[0].src,l),l.closest("figure, p",this.core.editor()[0]).replaceWith(r)):c?m(c).after(r):this.insert.node(r)):(this.modal.close(),this.buffer.set(),c?m(c).after(r):this.insert.node(r)),this.caret.after(r),this.events.dropImage=!1;var h=n[0].nextSibling,d=r.next(),u=m(h).text().replace(/\u200B/g,""),p=d.text().replace(/\u200B/g,"");""===u&&m(h).remove(),1===d.length&&"FIGURE"===d[0].tagName&&""===p&&d.remove(),null!==e?this.core.callback("imageUpload",n,t):this.core.callback("imageInserted",n,t)},setEditable:function(e){var t;e.on("dragstart",function(t){t.preventDefault()}),this.opts.imageResizable?(t=m.proxy(function(t){this.observe.image=e,this.image.resizer=this.image.loadEditableControls(e),m(document).on("mousedown.redactor-image-resize-hide."+this.uuid,m.proxy(this.image.hideResize,this)),this.image.resizer&&this.image.resizer.on("mousedown.redactor touchstart.redactor",m.proxy(function(t){this.image.setResizable(t,e)},this))},this),e.off("mousedown.redactor").on("mousedown.redactor",m.proxy(this.image.hideResize,this)),e.off("click.redactor touchstart.redactor").on("click.redactor touchstart.redactor",t)):e.off("click.redactor touchstart.redactor").on("click.redactor touchstart.redactor",m.proxy(function(t){setTimeout(m.proxy(function(){this.image.showEdit(e)},this),200)},this))},setResizable:function(t,e){t.preventDefault(),this.image.resizeHandle={x:t.pageX,y:t.pageY,el:e,ratio:e.width()/e.height(),h:e.height()},(t=t.originalEvent||t).targetTouches&&(this.image.resizeHandle.x=t.targetTouches[0].pageX,this.image.resizeHandle.y=t.targetTouches[0].pageY),this.image.startResize()},startResize:function(){m(document).on("mousemove.redactor-image-resize touchmove.redactor-image-resize",m.proxy(this.image.moveResize,this)),m(document).on("mouseup.redactor-image-resize touchend.redactor-image-resize",m.proxy(this.image.stopResize,this))},moveResize:function(t){t.preventDefault(),t=t.originalEvent||t;var e=this.image.resizeHandle.h;t.targetTouches?e+=t.targetTouches[0].pageY-this.image.resizeHandle.y:e+=t.pageY-this.image.resizeHandle.y;var i=Math.round(e*this.image.resizeHandle.ratio);e<50||i<100||this.core.editor().width()<=i||(this.image.resizeHandle.el.attr({width:i,height:e}),this.image.resizeHandle.el.width(i),this.image.resizeHandle.el.height(e),this.code.sync())},stopResize:function(){this.handle=!1,m(document).off(".redactor-image-resize"),this.image.hideResize()},hideResize:function(t){var e;t&&0!==m(t.target).closest("#redactor-image-box",this.$editor[0]).length||(t&&"IMG"==t.target.tagName&&m(t.target),0!==(e=this.$editor.find("#redactor-image-box")).length&&(m("#redactor-image-editter").remove(),m("#redactor-image-resizer").remove(),e.find("img").css({marginTop:e[0].style.marginTop,marginBottom:e[0].style.marginBottom,marginLeft:e[0].style.marginLeft,marginRight:e[0].style.marginRight}),e.css("margin",""),e.find("img").css("opacity",""),e.replaceWith(function(){return m(this).contents()}),m(document).off("mousedown.redactor-image-resize-hide."+this.uuid),void 0!==this.image.resizeHandle&&this.image.resizeHandle.el.attr("rel",this.image.resizeHandle.el.attr("style"))))},loadResizableControls:function(t,e){if(!this.opts.imageResizable||this.detect.isMobile())return e.append(t),!1;var i=m('<span id="redactor-image-resizer" data-redactor="verified"></span>');return this.detect.isDesktop()||i.css({width:"15px",height:"15px"}),i.attr("contenteditable",!1),e.append(i),e.append(t),i},loadEditableControls:function(t){if(0===m("#redactor-image-box").length){var e,i=m('<span id="redactor-image-box" data-redactor="verified">');return i.css("float",t.css("float")).attr("contenteditable",!1),"auto"!=t[0].style.margin?(i.css({marginTop:t[0].style.marginTop,marginBottom:t[0].style.marginBottom,marginLeft:t[0].style.marginLeft,marginRight:t[0].style.marginRight}),t.css("margin","")):i.css({display:"block",margin:"auto"}),t.css("opacity",".5").after(i),this.opts.imageEditable&&(this.image.editter=m('<span id="redactor-image-editter" data-redactor="verified">'+this.lang.get("edit")+"</span>"),this.image.editter.attr("contenteditable",!1),this.image.editter.on("click",m.proxy(function(){this.image.showEdit(t)},this)),i.append(this.image.editter),e=this.image.editter.innerWidth(),this.image.editter.css("margin-left","-"+e/2+"px")),this.image.loadResizableControls(t,i)}},showEdit:function(t){var e,i,n,r,s;this.events.imageEditing||(e=(this.observe.image=t).closest("a",this.$editor[0]),n=0!==(i=t.closest("figure",this.$editor[0])).length?i:t,this.modal.load("image-edit",this.lang.get("edit"),705),this.image.buttonDelete=this.modal.getDeleteButton().text(this.lang.get("delete")),this.image.buttonSave=this.modal.getActionButton().text(this.lang.get("save")),this.image.buttonDelete.on("click",m.proxy(this.image.remove,this)),this.image.buttonSave.on("click",m.proxy(this.image.update,this)),!1===this.opts.imageCaption?m("#redactor-image-caption").val("").hide().prev().hide():0!==(r=t.closest(this.opts.imageTag,this.$editor[0]).find("figcaption"))&&m("#redactor-image-caption").val(r.text()).show(),this.opts.imagePosition?(s=(0!==i.length?"center"===n.css("text-align"):"block"==n.css("display")&&"none"==n.css("float"))?"center":n.css("float"),m("#redactor-image-align").val(s)):m(".redactor-image-position-option").hide(),m("#redactor-image-preview").html(m('<img src="'+t.attr("src")+'" style="max-width: 100%;">')),m("#redactor-image-title").val(t.attr("alt")),0!==e.length&&(m("#redactor-image-link").val(e.attr("href")),"_blank"===e.attr("target")&&m("#redactor-image-link-blank").prop("checked",!0)),m(".redactor-link-tooltip").remove(),this.modal.show(),this.detect.isDesktop()&&m("#redactor-image-title").focus())},update:function(){var t=this.observe.image,e=t.closest("a",this.core.editor()[0]),i=m("#redactor-image-title").val().replace(/(<([^>]+)>)/gi,"");t.attr("alt",i).attr("title",i),this.image.setFloating(t);var n,r,s,o,a,l=m.trim(m("#redactor-image-link").val()).replace(/(<([^>]+)>)/gi,"");""!==l?(n="((xn--)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,}",r=new RegExp("^(http|ftp|https)://"+n,"i"),s=new RegExp("^"+n,"i"),-1===l.search(r)&&0===l.search(s)&&this.opts.linkProtocol&&(l=this.opts.linkProtocol+"://"+l),o=!!m("#redactor-image-link-blank").prop("checked"),0===e.length?(a=m('<a href="'+l+'" id="redactor-img-tmp">'+this.utils.getOuterHtml(t)+"</a>"),o&&a.attr("target","_blank"),t=t.replaceWith(a),(e=this.core.editor().find("#redactor-img-tmp")).removeAttr("id")):(e.attr("href",l),o?e.attr("target","_blank"):e.removeAttr("target"))):0!==e.length&&e.replaceWith(this.utils.getOuterHtml(t)),this.image.addCaption(t,e),this.modal.close(),this.buffer.set()},setFloating:function(t){var e=t.closest("figure",this.$editor[0]),i=0!==e.length?e:t,n="",r="",s="",o="";switch(m("#redactor-image-align").val()){case"left":n="left",s="0 "+this.opts.imageFloatMargin+" "+this.opts.imageFloatMargin+" 0";break;case"right":n="right",s="0 0 "+this.opts.imageFloatMargin+" "+this.opts.imageFloatMargin;break;case"center":0!==e.length?o="center":(r="block",s="auto")}i.css({float:n,display:r,margin:s,"text-align":o}),i.attr("rel",t.attr("style"))},addCaption:function(t,e){var i=m("#redactor-image-caption").val(),n=0!==e.length?e:t,r=n.next();0!==r.length&&"FIGCAPTION"===r[0].tagName||(r=!1),""!==i?!1===r?(r=m("<figcaption />").text(i),n.after(r)):r.text(i):!1!==r&&r.remove()},remove:function(t,e,i){e=void 0===e?m(this.observe.image):e,"boolean"!=typeof t&&this.buffer.set(),this.events.stopDetectChanges();var n,r,s=e.closest("a",this.core.editor()[0]),o=e.closest(this.opts.imageTag,this.core.editor()[0]);e.parent();if(!1===this.core.callback("imageDelete",t,e[0]))return t&&t.preventDefault(),!1;0!==m("#redactor-image-box").length&&m("#redactor-image-box").parent(),0!==o.length?(r=o.prev(),n=o.next(),o.remove()):0!==s.length?(s.parent(),s.remove()):e.remove(),m("#redactor-image-box").remove(),!1!==t&&(n&&0!==n.length?this.caret.start(n):r&&0!==r.length&&this.caret.end(r)),"boolean"!=typeof t&&this.modal.close(),this.utils.restoreScroll(),this.observe.image=!1,this.events.startDetectChanges(),this.code.sync()}}},indent:function(){return{increase:function(){var t,e,i,n,r,s;this.list.get()&&(e=(t=m(this.selection.current()).closest("li")).closest("ul, ol",this.core.editor()[0]),0!==(i=t.closest("li").prev()).length&&"LI"===i[0].tagName&&(this.buffer.set(),this.utils.isCollapsed()?(r=e[0].tagName,s=m("<"+r+" />"),this.selection.save(),1===(n=i.find("ol").first()).length?n.append(t):(r=e[0].tagName,(s=m("<"+r+" />")).append(t),i.append(s))):(document.execCommand("indent"),this.selection.save(),this.indent.removeEmpty(),this.indent.normalize()),this.selection.restore()))},decrease:function(){if(this.list.get()){m(this.selection.current()).closest("li").closest("ul, ol",this.core.editor()[0]);this.buffer.set(),document.execCommand("outdent");var t=m(this.selection.current()).closest("li",this.core.editor()[0]);this.utils.isCollapsed()&&this.indent.repositionItem(t);var e=null;if(0===t.length){var i=this.selection.block();if(i&&-1!==i.nodeName.indexOf("-")){for(this.selection.save(),e=elCreate("div");i.childNodes.length;)e.appendChild(i.childNodes[0]);i.appendChild(e),this.selection.restore()}document.execCommand("formatblock",!1,"p");var n=(t=m(this.selection.current())).next();0!==n.length&&"BR"===n[0].tagName&&n.remove()}if(this.selection.save(),null!==e){for(var r=e.parentNode;e.childNodes.length;)r.insertBefore(e.childNodes[0],e);r.removeChild(e)}this.indent.removeEmpty(),this.indent.normalize(),this.selection.restore()}},repositionItem:function(t){var e=t.next();0===e.length||"UL"===e[0].tagName&&"OL"===e[0].tagName||t.append(e);var i=t.prev();0!==i.length&&"LI"!==i[0].tagName&&(this.selection.save(),t.parents("li",this.core.editor()[0]).after(t),this.selection.restore())},normalize:function(){this.core.editor().find("li").each(m.proxy(function(t,e){var i=m(e),n="";0!==this.opts.keepStyleAttr.length&&(n=","+this.opts.keepStyleAttr.join(",")),i.find(this.opts.inlineTags.join(",")).not("img"+n).removeAttr("style");var r,s=i.parent();0===s.length||"LI"!==s[0].tagName?0===(r=i.next()).length||"UL"!==r[0].tagName&&"OL"!==r[0].tagName||i.append(r):s.after(i)},this))},removeEmpty:function(t){var e=this.core.editor().find("ul, ol"),i=this.core.editor().find("li");i.each(m.proxy(function(t,e){this.indent.removeItemEmpty(e)},this)),e.each(m.proxy(function(t,e){this.indent.removeItemEmpty(e)},this)),i.each(m.proxy(function(t,e){this.indent.removeItemEmpty(e)},this))},removeItemEmpty:function(t){""===t.innerHTML.replace(/[\t\s\n]/g,"").replace(/<span><\/span>/g,"")&&m(t).remove()}}},inline:function(){return{format:function(t,e,i,n){var r;this.utils.isCurrentOrParent(["PRE","CODE"])||(r=this.inline.getParams(e,i,n),t=this.inline.arrangeTag(t),this.buffer.set(),this.utils.isCollapsed()?this.inline.formatCollapsed(t,r):this.inline.formatUncollapsed(t,r))},formatCollapsed:function(t,e){var i,n,r,s=this.selection.inline();s?(n=s.tagName.toLowerCase())===t?this.utils.isEmpty(s.innerHTML)?(this.caret.after(s),m(s).remove()):(r=this.inline.insertBreakpoint(s,n),this.caret.after(r)):0===m(s).closest(t).length?(i=this.inline.insertInline(t),i=this.inline.setParams(i,e)):(r=this.inline.insertBreakpoint(s,n),this.caret.after(r)):(i=this.inline.insertInline(t),i=this.inline.setParams(i,e))},formatUncollapsed:function(r,s){var t;this.selection.save();var e=window.getSelection().getRangeAt(0);if(null===e.cloneContents().querySelector(r)){(t=e.startContainer).nodeType===Node.TEXT_NODE&&(t=t.parentElement);var i=t.closest(r);if(null!==i&&this.core.editor()[0].contains(i)){var n=document.createElement(r);i.insertAdjacentElement("beforebegin",n);var o=document.createRange();o.selectNodeContents(i),o.setEnd(e.startContainer,e.startOffset),n.appendChild(o.extractContents());var a=document.createElement(r);i.insertAdjacentElement("afterend",a);var l=document.createRange();l.selectNodeContents(i),l.setStart(e.endContainer,e.endOffset),a.appendChild(l.extractContents());for(var c=i.parentElement;i.childNodes.length;)c.insertBefore(i.childNodes[0],i);return void i.remove()}}var h=this.inline.getClearedNodes();this.inline.setNodesStriked(h,r,s),this.selection.restore(),document.execCommand("strikethrough"),this.selection.saveInstant();for(var d,u=this.core.editor()[0].querySelectorAll('[style*="line-through"]'),p=0,f=u.length;p<f;p++)t=u[0],d=document.createElement("strike"),t.parentNode.insertBefore(d,t),d.appendChild(t),t.style.removeProperty("text-decoration");var g=this;this.core.editor().find("strike").each(function(){var t=g.utils.replaceToTag(this,r);g.inline.setParams(t[0],s);var e=t.find(r),i=t.parent(),n=i.parent();if(0!==n.length&&n[0].tagName.toLowerCase()===r&&n.html()==i[0].outerHTML)return t.replaceWith(function(){return m(this).contents()}),void n.replaceWith(function(){return m(this).contents()});0!==e.length&&g.inline.cleanInsideOrParent(e,s),i.html()==t[0].outerHTML&&g.inline.cleanInsideOrParent(i,s),g.detect.isFirefox()&&g.core.editor().find(r+":empty").remove()}),this.selection.restoreInstant()},cleanInsideOrParent:function(t,e){if(e)for(var i in e.data)this.inline.removeSpecificAttr(t,i,e.data[i])},getClearedNodes:function(){for(var t=this.selection.nodes(),e=[],i=t.length,n=0,r=0;r<i;r++)if(m(t[r]).hasClass("redactor-selection-marker")){n=r+2;break}for(r=0;r<i;r++)n<=r&&!this.utils.isBlockTag(t[r].tagName)&&e.push(t[r]);return e},isConvertableAttr:function(t,e,i){var n=m(t).attr(e);if(n)if("style"===e){for(var r=(i=m.trim(i).replace(/;$/,"")).split(";"),s=0,o=0;o<r.length;o++){var a,l=r[o].split(":"),c=m.trim(l[0]),h=m.trim(l[1]);-1!==c.search(/color/)?!(a=m(t).css(c))||a!==h&&this.utils.rgb2hex(a)!==h||s++:m(t).css(c)===h&&s++}if(s===r.length)return 1}else if(n===i)return 1;return 0},isConvertable:function(t,e,i,n){if(e===i){if(!n)return!0;var r=0;for(var s in n.data)r+=this.inline.isConvertableAttr(t,s,n.data[s]);if(r===Object.keys(n.data).length)return!0}return!1},setNodesStriked:function(t,e,i){for(var n=0;n<t.length;n++){var r=t[n].tagName?t[n].tagName.toLowerCase():void 0,s=t[n].parentNode,o=s&&s.tagName?s.tagName.toLowerCase():void 0;this.inline.isConvertable(s,o,e,i)&&m(s).replaceWith(function(){return m("<strike>").append(m(this).contents())}).attr("data-redactor-inline-converted"),this.inline.isConvertable(t[n],r,e,i)&&m(t[n]).replaceWith(function(){return m("<strike>").append(m(this).contents())})}},insertBreakpoint:function(t,e){var i=document.createElement("span");i.id="redactor-inline-breakpoint",i=this.insert.node(i);var n=this.utils.isEndOfElement(t)?"":"<"+e+">",r=(r=this.utils.getOuterHtml(t)).replace(/<span id="redactor-inline-breakpoint"><\/span>/i,"</"+e+">"+n),s=m(r);return m(t).replaceWith(s),n&&this.utils.cloneAttributes(t,s.last()),s.first()},insertInline:function(t){var e=document.createElement(t);return this.insert.node(e),this.caret.start(e),e},arrangeTag:function(t){var e=["b","bold","i","italic","underline","strikethrough","deleted","superscript","subscript"],i=["strong","strong","em","em","u","del","del","sup","sub"];t=t.toLowerCase();for(var n=0;n<e.length;n++)t===e[n]&&(t=i[n]);return t},getStyleParams:function(t){for(var e={},i=t.trim().replace(/;$/,"").split(";"),n=0;n<i.length;n++){var r=i[n].split(":");r&&(e[r[0].trim()]=r[1].trim())}return e},getParams:function(t,e,i){var n=!1,r="toggle";return"object"==typeof t?(n=t,r=void 0!==e?e:r):void 0!==t&&void 0!==e&&((n={})[t]=e,r=void 0!==i?i:r),!!n&&{func:r,data:n}},setParams:function(t,e){if(e)for(var i in e.data){var n=m(t);"style"===i?(t=this.inline[e.func+"Style"](e.data[i],t),n.attr("data-redactor-style-cache",n.attr("style"))):t="class"===i?this.inline[e.func+"Class"](e.data[i],t):"remove"===e.func?this.inline[e.func+"Attr"](i,t):this.inline[e.func+"Attr"](i,e.data[i],t),"style"===i&&"SPAN"===t.tagName&&n.attr("data-redactor-span",!0)}return t},eachInline:function(t,e){var i,n=void 0===t?this.selection.inlines():[t];if(n)for(var r=0;r<n.length;r++)i=e(n[r])[0];return i},replaceClass:function(e,t){return this.inline.eachInline(t,function(t){return m(t).removeAttr("class").addClass(e)})},toggleClass:function(e,t){return this.inline.eachInline(t,function(t){return m(t).toggleClass(e)})},addClass:function(e,t){return this.inline.eachInline(t,function(t){return m(t).addClass(e)})},removeClass:function(e,t){return this.inline.eachInline(t,function(t){return m(t).removeClass(e)})},removeAllClass:function(t){return this.inline.eachInline(t,function(t){return m(t).removeAttr("class")})},replaceAttr:function(e,t,i){return this.inline.eachInline(i,function(t){return m(t).removeAttr(e).attr(e.value)})},toggleAttr:function(e,t,i){return this.inline.eachInline(i,function(t){return m(t).attr(e)?m(t).removeAttr(e):m(t).attr(e.value)})},addAttr:function(e,i,t){return this.inline.eachInline(t,function(t){return m(t).attr(e,i)})},removeAttr:function(i,t){return this.inline.eachInline(t,function(t){var e=m(t);return e.removeAttr(i),"style"===i&&e.removeAttr("data-redactor-style-cache"),e})},removeAllAttr:function(t){return this.inline.eachInline(t,function(t){for(var e=m(t),i=t.attributes.length,n=0;n<i;n++)e.removeAttr(t.attributes[n].name);return e})},removeSpecificAttr:function(t,e,i){var n,r=m(t);"style"===e?(n=i.split(":")[0].trim(),r.css(n,""),this.utils.removeEmptyAttr(t,"style")&&r.removeAttr("data-redactor-style-cache")):r.removeAttr(e)[0]},hasParentStyle:function(t){var e=t.parent();return 1===e.length&&e[0].tagName===t[0].tagName&&e.html()===t[0].outerHTML&&e},addParentStyle:function(t){var e,i=this.inline.hasParentStyle(t);return i?(e=this.inline.getStyleParams(t.attr("style")),i.css(e),i.attr("data-redactor-style-cache",i.attr("style")),t.replaceWith(function(){return m(this).contents()})):t.attr("data-redactor-style-cache",t.attr("style")),t},replaceStyle:function(n,t){n=this.inline.getStyleParams(n);var r=this;return this.inline.eachInline(t,function(t){var e=m(t);e.removeAttr("style").css(n);var i=e.attr("style");return i&&e.attr("style",i.replace(/"/g,"'")),e=r.inline.addParentStyle(e)})},toggleStyle:function(o,t){o=this.inline.getStyleParams(o);var a=this;return this.inline.eachInline(t,function(t){var e=m(t);for(var i in o){var n=o[i],r=e.css(i);(r=a.utils.isRgb(r)?a.utils.rgb2hex(r):r.replace(/"/g,""))===(n=a.utils.isRgb(n)?a.utils.rgb2hex(n):n.replace(/"/g,""))?e.css(i,""):e.css(i,n)}var s=e.attr("style");return s&&e.attr("style",s.replace(/"/g,"'")),a.utils.removeEmptyAttr(t,"style")?e.removeAttr("data-redactor-style-cache"):e=a.inline.addParentStyle(e),e})},addStyle:function(n,t){n=this.inline.getStyleParams(n);var r=this;return this.inline.eachInline(t,function(t){var e=m(t);e.css(n);var i=e.attr("style");return i&&e.attr("style",i.replace(/"/g,"'")),e=r.inline.addParentStyle(e)})},removeStyle:function(n,t){n=this.inline.getStyleParams(n);var r=this;return this.inline.eachInline(t,function(t){var e=m(t);for(var i in n)e.css(i,"");return r.utils.removeEmptyAttr(t,"style")?e.removeAttr("data-redactor-style-cache"):e.attr("data-redactor-style-cache",e.attr("style")),e})},removeAllStyle:function(t){return this.inline.eachInline(t,function(t){return m(t).removeAttr("style").removeAttr("data-redactor-style-cache")})},removeStyleRule:function(t){var e=this.selection.parent(),i=this.selection.inlines();this.buffer.set(),e&&"SPAN"===e.tagName&&this.inline.removeStyleRuleAttr(m(e),t);for(var n=0;n<i.length;n++){var r=i[n],s=m(r);-1==m.inArray(r.tagName.toLowerCase(),this.opts.inlineTags)||s.hasClass("redactor-selection-marker")||this.inline.removeStyleRuleAttr(s,t)}},removeStyleRuleAttr:function(t,e){t.css(e,""),this.utils.removeEmptyAttr(t,"style")?t.removeAttr("data-redactor-style-cache"):t.attr("data-redactor-style-cache",t.attr("style"))},update:function(t,e,i,n){t=this.inline.arrangeTag(t);var r=this.inline.getParams(e,i,n),s=this.selection.inlines(),o=[];if(s)for(var a=0;a<s.length;a++){var l=s[a];"*"!==t&&l.tagName.toLowerCase()!==t||o.push(this.inline.setParams(l,r))}return o},removeFormat:function(){this.selection.save();for(var t=this.inline.getClearedNodes(),e=0;e<t.length;e++)1===t[e].nodeType&&m(t[e]).replaceWith(function(){return m(this).contents()});this.selection.restore()}}},insert:function(){return{set:function(t){this.code.set(t),this.focus.end()},html:function(t,e){this.core.editor().focus();var i=this.selection.block(),n=this.selection.inline();void 0===e&&(e=this.clean.getCurrentType(t,!0),t=this.clean.onPaste(t,e,!0)),t=m.parseHTML(t);var r,s,o,a=m(t).last(),l=this.selection.get(),c=this.selection.range(l);if(c.deleteContents(),this.selection.update(l,c),e.lists){var h=m(t);if(0!==h.length&&("UL"===h[0].tagName||"OL"===h[0].tagName))return void this.insert.appendLists(i,h)}e.blocks&&i?this.utils.isSelectAll()?(this.core.editor().html(t),this.focus.end()):!1===(r=this.utils.breakBlockTag())?this.insert.placeHtml(t):(m(t).children().last().append(this.marker.get()),"start"===r.type?r.$block.before(t):r.$block.after(t),this.selection.restore(),this.core.editor().find("p").each(function(){""===m.trim(this.innerHTML)&&m(this).remove()})):(n&&((s=m("<div/>").html(t)).find(n.tagName.toLowerCase()).each(function(){m(this).contents().unwrap()}),t=s.html(),t=m.parseHTML(t),a=m(t).last()),this.utils.isSelectAll()?(o=m(this.opts.emptyHtml),this.core.editor().html("").append(o),o.html(t),this.caret.end(o)):this.insert.placeHtml(t)),this.utils.disableSelectAll(),e.pre&&this.clean.cleanPre(),this.caret.end(a)},text:function(t){t=t.toString(),t=m.trim(t);var e,i,n,r,s,o=document.createElement("div");o.innerHTML=t,void 0!==(t=o.textContent||o.innerText)&&(this.core.editor().focus(),e=this.selection.blocks(),t=t.replace(/\n/g," "),this.utils.isSelectAll()?(i=m(this.opts.emptyHtml),this.core.editor().html("").append(i),i.html(t),this.caret.end(i)):(n=this.selection.get(),r=document.createTextNode(t),n.getRangeAt&&n.rangeCount&&((s=n.getRangeAt(0)).deleteContents(),s.insertNode(r),s.setStartAfter(r),s.collapse(!0),this.selection.update(n,s)),1<e.length&&(m(r).wrap("<p>"),this.caret.after(r))),this.utils.disableSelectAll(),this.clean.normalizeCurrentHeading())},raw:function(t){this.core.editor().focus();var e=this.selection.get(),i=this.selection.range(e);i.deleteContents();var n=document.createElement("div");n.innerHTML=t;for(var r,s,o=document.createDocumentFragment();r=n.firstChild;)s=o.appendChild(r);i.insertNode(o),s&&((i=i.cloneRange()).setStartAfter(s),i.collapse(!0),e.removeAllRanges(),e.addRange(i))},node:function(t,e){void 0!==this.start&&this.core.editor().focus(),t=t[0]||t;var i,n=this.selection.block(),r=this.utils.isBlockTag(t.tagName),s=!0;return this.utils.isSelectAll()?(r?this.core.editor().html(t):this.core.editor().html(m("<p>").html(t)),this.code.sync()):r&&n?!1===(i=this.utils.breakBlockTag())?this.insert.placeNode(t,e):("start"===i.type?i.$block.before(t):i.$block.after(t),this.core.editor().find("p:empty").remove()):s=this.insert.placeNode(t,e),this.utils.disableSelectAll(),s&&this.caret.end(t),t},appendLists:function(t,e){var i,n,r=m(t),s=this.utils.isEmpty(t.innerHTML);s||this.utils.isEndOfElement(t)?(i=r,e.find("li").each(function(){i.after(this),i=m(this)}),s&&r.remove()):this.utils.isStartOfElement(t)?e.find("li").each(function(){r.before(this),i=m(this)}):(n=this.selection.extractEndOfNode(t),r.after(m("<li>").append(n)),r.append(e),i=e),this.marker.remove(),i&&this.caret.end(i)},placeHtml:function(t){var e=document.createElement("span");e.id="redactor-insert-marker",e=this.insert.node(e),m(e).before(t),this.selection.restore(),this.caret.after(e),m(e).remove()},placeNode:function(t,e){var i=this.selection.get(),n=this.selection.range(i);if(null==n)return!1;!1!==e&&n.deleteContents(),n.insertNode(t),n.collapse(!1),this.selection.update(i,n)},nodeToPoint:function(t,e){if(e=e[0]||e,this.utils.isEmpty())return e=this.utils.isBlock(e)?e:m("<p />").append(e),this.core.editor().html(e),e;var i,n,r,s=t.clientX,o=t.clientY;return document.caretPositionFromPoint?(i=document.caretPositionFromPoint(s,o),(n=document.getSelection().getRangeAt(0)).setStart(i.offsetNode,i.offset),n.collapse(!0),n.insertNode(e)):document.caretRangeFromPoint?(n=document.caretRangeFromPoint(s,o)).insertNode(e):void 0!==document.body.createTextRange&&((n=document.body.createTextRange()).moveToPoint(s,o),(r=n.duplicate()).moveToPoint(s,o),n.setEndPoint("EndToEnd",r),n.select()),e},nodeToCaretPositionFromPoint:function(t,e){this.insert.nodeToPoint(t,e)},marker:function(){this.marker.insert()}}},keydown:function(){return{init:function(t){if(!this.rtePaste){var e=t.which,i=37<=e&&e<=40;if(this.keydown.ctrl=t.ctrlKey||t.metaKey,this.keydown.parent=this.selection.parent(),this.keydown.current=this.selection.current(),this.keydown.block=this.selection.block(),this.keydown.pre=this.utils.isTag(this.keydown.current,"pre"),this.keydown.blockquote=this.utils.isTag(this.keydown.current,"blockquote"),this.keydown.figcaption=this.utils.isTag(this.keydown.current,"figcaption"),this.keydown.figure=this.utils.isTag(this.keydown.current,"figure"),!1===this.core.callback("keydown",t))return t.preventDefault(),!1;if(this.shortcuts.init(t,e),this.keydown.checkEvents(i,e),this.keydown.setupBuffer(t,e),this.utils.isSelectAll()&&(e===this.keyCode.ENTER||e===this.keyCode.BACKSPACE||e===this.keyCode.DELETE))return t.preventDefault(),this.code.set(this.opts.emptyHtml),void this.events.changeHandler();if(this.keydown.addArrowsEvent(i),this.keydown.setupSelectAll(t,e),this.opts.enterKey||e!==this.keyCode.ENTER){if(this.opts.enterKey&&e===this.keyCode.DOWN&&this.keydown.onArrowDown(),this.opts.enterKey&&e===this.keyCode.UP&&this.keydown.onArrowUp(),("textarea"===this.opts.type||"div"===this.opts.type)&&this.keydown.current&&3===this.keydown.current.nodeType&&m(this.keydown.parent).hasClass("redactor-in")&&this.keydown.wrapToParagraph(),!this.keyup.lastShiftKey&&e===this.keyCode.SPACE&&(t.ctrlKey||t.shiftKey))return t.preventDefault(),this.keydown.onShiftSpace();if(e===this.keyCode.ENTER&&(t.ctrlKey||t.shiftKey)&&(null===h||"ios"!==h.platform()))return t.preventDefault(),this.keydown.onShiftEnter(t);if(e===this.keyCode.ENTER&&!t.shiftKey&&!t.ctrlKey&&!t.metaKey)return this.keydown.onEnter(t);if(e===this.keyCode.TAB||t.metaKey&&221===e||t.metaKey&&219===e)return this.keydown.onTab(t,e);if(this.detect.isFirefox()&&e===this.keyCode.BACKSPACE&&this.keydown.block&&"P"===this.keydown.block.tagName&&this.utils.isStartOfElement(this.keydown.block))if(0!==(n=m(this.keydown.block).prev()).length)return t.preventDefault(),n.append(this.marker.get()),n.append(m(this.keydown.block).html()),m(this.keydown.block).remove(),void this.selection.restore();if(e===this.keyCode.BACKSPACE||e===this.keyCode.DELETE){if(this.observe.image&&void 0!==this.observe.image&&0!==m("#redactor-image-box").length){t.preventDefault();var n=this.observe.image.closest("figure, p").prev();return this.image.remove(!1),this.observe.image=!1,void(n&&0!==n.length?this.caret.end(n):this.core.editor().focus())}this.keydown.onBackspaceAndDeleteBefore()}if(e===this.keyCode.DELETE){var r=m(this.keydown.block).next();if(this.utils.isEndOfElement(this.keydown.block)&&0!==r.length&&"FIGURE"===r[0].tagName)return r.remove(),!1;if(!(!this.keydown.block||"LI"!==this.keydown.block.tagName)&&this.keydown.block){var s=m(this.keydown.block).parents("ul, ol").last(),o=s.next();if(this.utils.isRedactorParent(s)&&this.utils.isEndOfElement(s)&&0!==o.length&&("UL"===o[0].tagName||"OL"===o[0].tagName))return t.preventDefault(),s.append(o.contents()),o.remove(),!1}if(this.utils.isEndOfElement(this.keydown.block)&&0!==r.length&&"PRE"===r[0].tagName)return m(this.keydown.block).append(r.text()),r.remove(),!1}if(e===this.keyCode.DELETE&&0!==m("#redactor-image-box").length&&this.image.remove(),e===this.keyCode.BACKSPACE){if(this.detect.isFirefox()&&this.line.removeOnBackspace(t),this.list.combineAfterAndBefore(this.keydown.block))return void t.preventDefault();var a=this.selection.block();if(a&&"LI"===a.tagName&&this.utils.isCollapsed()&&this.utils.isStartOfElement())return this.indent.decrease(),void t.preventDefault();this.keydown.removeInvisibleSpace(),this.keydown.removeEmptyListInTable(t)}e!==this.keyCode.BACKSPACE&&e!==this.keyCode.DELETE||this.keydown.onBackspaceAndDeleteAfter(t)}else{t.preventDefault();var l=this.selection.get(),c=this.selection.range(l);c.collapsed||c.deleteContents()}}},onShiftSpace:function(){return this.buffer.set(),this.insert.raw("&nbsp;"),!1},onShiftEnter:function(t){return this.buffer.set(),this.keydown.pre?this.keydown.insertNewLine(t):this.insert.raw("<br>")},onBackspaceAndDeleteBefore:function(){this.utils.saveScroll()},onBackspaceAndDeleteAfter:function(e){setTimeout(m.proxy(function(){this.code.syncFire=!1,this.keydown.removeEmptyLists();var t="";0!==this.opts.keepStyleAttr.length&&(t=","+this.opts.keepStyleAttr.join(",")),this.core.editor().find("*[style]").not("img, figure, iframe, #redactor-image-box, #redactor-image-editter, [data-redactor-style-cache], [data-redactor-span]"+t).removeAttr("style"),this.keydown.formatEmpty(e),this.code.syncFire=!0},this),1)},onEnter:function(t){if(!1===this.core.callback("enter",t))return t.preventDefault(),!1;if(this.keydown.blockquote&&!0===this.keydown.exitFromBlockquote(t))return!1;if(this.keydown.pre)return this.keydown.insertNewLine(t);if(this.keydown.blockquote||this.keydown.figcaption)return this.keydown.insertBreakLine(t);if(this.keydown.figure)setTimeout(m.proxy(function(){this.keydown.replaceToParagraph("FIGURE")},this),1);else if(this.keydown.block){if(setTimeout(m.proxy(function(){this.keydown.replaceToParagraph("DIV")},this),1),"LI"===this.keydown.block.tagName){var e=this.selection.current(),i=m(e).closest("li",this.$editor[0]),n=i.parents("ul,ol",this.$editor[0]).last();if(0!==i.length&&this.utils.isEmpty(i.html())&&0===n.next().length&&this.utils.isEmpty(n.find("li").last().html())){n.find("li").last().remove();var r=m(this.opts.emptyHtml);return n.after(r),this.caret.start(r),!1}}}else if(!this.keydown.block)return this.keydown.insertParagraph(t);this.detect.isFirefox()&&this.utils.isInline(this.keydown.parent)?this.keydown.insertBreakLine(t):this.opts.keepInlineOnEnter||setTimeout(m.proxy(function(){var t,e,i,n,r=this.selection.inline();r&&this.utils.isEmpty(r.innerHTML)&&(t=this.selection.block(),m(r).remove(),(e=document.createRange()).setStart(t,0),i=document.createTextNode("​"),e.insertNode(i),e.setStartAfter(i),e.collapse(!0),(n=window.getSelection()).removeAllRanges(),n.addRange(e))},this),1)},checkEvents:function(t,e){t||"click"!==this.core.getEvent()&&"arrow"!==this.core.getEvent()||(this.core.addEvent(!1),this.keydown.checkKeyEvents(e)&&this.buffer.set())},checkKeyEvents:function(t){var e=this.keyCode,i=[e.BACKSPACE,e.DELETE,e.ENTER,e.ESC,e.TAB,e.CTRL,e.META,e.ALT,e.SHIFT];return-1===m.inArray(t,i)},addArrowsEvent:function(t){t&&("click"!==this.core.getEvent()&&"arrow"!==this.core.getEvent()?this.core.addEvent("arrow"):this.core.addEvent(!1))},setupBuffer:function(t,e){return this.keydown.ctrl&&90===e&&!t.shiftKey&&!t.altKey&&this.sBuffer.length?(t.preventDefault(),void this.buffer.undo()):this.keydown.ctrl&&90===e&&t.shiftKey&&!t.altKey&&0!==this.sRebuffer.length?(t.preventDefault(),void this.buffer.redo()):void(this.keydown.ctrl||e!==this.keyCode.SPACE&&e!==this.keyCode.BACKSPACE&&e!==this.keyCode.DELETE&&(e!==this.keyCode.ENTER||t.ctrlKey||t.shiftKey)||this.buffer.set())},exitFromBlockquote:function(t){if(this.utils.isEndOfElement(this.keydown.blockquote)&&-1!==this.clean.removeSpacesHard(m(this.keydown.blockquote).html()).search(/(<br\s?\/?>){1}$/i)){t.preventDefault(),m(this.keydown.blockquote).children().last().filter("br").remove(),m(this.keydown.blockquote).children().last().filter("span").remove();var e=m(this.opts.emptyHtml);return m(this.keydown.blockquote).after(e),this.caret.start(e),!0}},onArrowDown:function(){for(var t=[this.keydown.blockquote,this.keydown.pre,this.keydown.figcaption],e=0;e<t.length;e++)if(t[e])return this.keydown.insertAfterLastElement(t[e]),!1},onArrowUp:function(){for(var t=[this.keydown.blockquote,this.keydown.pre,this.keydown.figcaption],e=0;e<t.length;e++)if(t[e])return this.keydown.insertBeforeFirstElement(t[e]),!1},insertAfterLastElement:function(t){var e,i;this.utils.isEndOfElement(t)&&(e=this.core.editor().contents().last(),0===("FIGCAPTION"===t.tagName?m(this.keydown.block).parent().next():m(this.keydown.block).next()).length&&(0!==e.length||e[0]===t?(i=m(this.opts.emptyHtml),"FIGCAPTION"===t.tagName?m(t).parent().after(i):m(t).after(i),this.caret.start(i)):this.caret.start(e)))},insertBeforeFirstElement:function(t){var e;this.utils.isStartOfElement()&&(1<this.core.editor().contents().length&&this.core.editor().contents().first()[0]!==t||(e=m(this.opts.emptyHtml),m(t).before(e),this.caret.start(e)))},onTab:function(t,e){if(!this.opts.tabKey)return!0;var i=this.keydown.block&&"LI"===this.keydown.block.tagName;if(this.utils.isEmpty(this.code.get())||!i&&!this.keydown.pre&&!1===this.opts.tabAsSpaces)return!0;t.preventDefault(),this.buffer.set();var n,r=i&&this.utils.isStartOfElement(this.keydown.block);return this.keydown.pre&&!t.shiftKey?(n=this.opts.preSpaces?document.createTextNode(Array(this.opts.preSpaces+1).join(" ")):document.createTextNode("\t"),this.insert.node(n)):!1===this.opts.tabAsSpaces||r?t.metaKey&&219===e||(!t.metaKey||221!==e)&&t.shiftKey?this.indent.decrease():this.indent.increase():(n=document.createTextNode(Array(this.opts.tabAsSpaces+1).join(" ")),this.insert.node(n)),!1},setupSelectAll:function(t,e){this.keydown.ctrl&&65===e?this.utils.enableSelectAll():e===this.keyCode.LEFT_WIN||this.keydown.ctrl||this.utils.disableSelectAll()},insertNewLine:function(t){t.preventDefault();var e=document.createTextNode("\n"),i=this.selection.get(),n=this.selection.range(i);return n.deleteContents(),n.insertNode(e),this.caret.after(e),!1},insertParagraph:function(t){t.preventDefault();var e=document.createElement("p");e.innerHTML="<br>";var i=this.selection.get(),n=this.selection.range(i);return n.deleteContents(),n.insertNode(e),this.caret.start(e),!1},insertBreakLine:function(t){return this.keydown.insertBreakLineProcessing(t)},insertDblBreakLine:function(t){return this.keydown.insertBreakLineProcessing(t,!0)},insertBreakLineProcessing:function(t,e){t.stopPropagation();var i,n=document.createElement("br");return this.insert.node(n),!0===e?(i=document.createElement("br"),this.insert.node(i),this.caret.after(i)):this.caret.after(n),!1},wrapToParagraph:function(){var t=m(this.keydown.current),e=m("<p>").append(t.clone());t.replaceWith(e);var i=m(e).next();void 0!==i[0]&&"BR"===i[0].tagName&&i.remove(),this.caret.end(e)},replaceToParagraph:function(t){var i=this.selection.block(),e=m(i).prev(),n=i.innerHTML.replace(/<br\s?\/?>/gi,"");if(i.tagName===t&&this.utils.isEmpty(n)&&!m(i).hasClass("redactor-in")){var r=document.createElement("p");return m(i).replaceWith(r),this.keydown.setCaretToParagraph(r),!1}if("P"===i.tagName)return m(i).removeAttr("class").removeAttr("style"),this.detect.isIe()&&this.utils.isEmpty(n)&&this.utils.isInline(this.keydown.parent)&&m(i).on("input",m.proxy(function(){var t,e=this.selection.parent();this.utils.isInline(e)&&(t=m(e).html(),m(i).html(t),this.caret.end(i)),m(i).off("keyup")},this)),!1;if(e.hasClass(this.opts.videoContainerClass)){e.removeAttr("class");r=document.createElement("p");return e.replaceWith(r),this.keydown.setCaretToParagraph(r),!1}},setCaretToParagraph:function(t){var e=document.createRange();e.setStart(t,0);var i=document.createTextNode("​");e.insertNode(i),e.setStartAfter(i),e.collapse(!0);var n=window.getSelection();n.removeAllRanges(),n.addRange(e)},removeInvisibleSpace:function(){var t=m(this.keydown.current);0===t.text().search(/^\u200B$/g)&&t.remove()},removeEmptyListInTable:function(t){var e=m(this.keydown.current),i=m(this.keydown.parent),n=e.closest("td",this.$editor[0]);if(0!==n.length&&e.closest("li",this.$editor[0])&&1===i.children("li").length){if(!this.utils.isEmpty(e.text()))return;t.preventDefault(),e.remove(),i.remove(),this.caret.start(n)}},removeEmptyLists:function(){function t(){""===m.trim(this.innerHTML).replace(/\/t\/n/g,"")&&m(this).remove()}this.core.editor().find("li").each(t),this.core.editor().find("ul, ol").each(t)},formatEmpty:function(t){var e,i=m.trim(this.core.editor().html());if(this.utils.isEmpty(i))return t.preventDefault(),"inline"===this.opts.type||"pre"===this.opts.type?(this.core.editor().html(this.marker.html()),this.selection.restore()):(e=function(){this.core.editor().html(this.opts.emptyHtml),this.focus.start()}.bind(this),null!==h&&"ios"===h.platform()?setTimeout(e,50):e()),!1}}},keyup:function(){return{init:function(t){if(!this.rtePaste){var e,i=t.which;if(this.keyup.block=this.selection.block(),this.keyup.current=this.selection.current(),this.keyup.parent=this.selection.parent(),this.keyup.lastShiftKey=t.shiftKey,!1===this.core.callback("keyup",t))return t.preventDefault(),!1;if(i===this.keyCode.ENTER&&this.keyup.block&&"FIGURE"===this.keyup.block.tagName){var n=m(this.keyup.block).prev();if(0!==n.length&&"FIGURE"===n[0].tagName){var r=this.utils.replaceToTag(n,"p");return void this.caret.start(r)}}if(i===this.keyCode.BACKSPACE||i===this.keyCode.DELETE){if(this.utils.isSelectAll())return void this.focus.start();if(this.keyup.block&&this.keydown.block&&"FIGURE"===this.keyup.block.tagName&&this.utils.isStartOfElement(this.keydown.block)){t.preventDefault(),this.selection.save(),m(this.keyup.block).find("figcaption").remove(),m(this.keyup.block).find("img").first().remove(),this.utils.replaceToTag(this.keyup.block,"p");var s=this.marker.find();return m("html, body").animate({scrollTop:s.position().top+20},500),void this.selection.restore()}this.keyup.block&&"P"===this.keyup.block.tagName&&(e=m(this.keyup.block).find("img").length,""===m(this.keyup.block).text().replace(/\u200B/g,"")&&0!==e&&this.utils.replaceToTag(this.keyup.block,"figure")),this.keyup.block&&"FIGURE"===this.keyup.block.tagName&&0===m(this.keyup.block).find("img").length&&(this.selection.save(),this.utils.replaceToTag(this.keyup.block,"p"),this.selection.restore())}}}}},lang:function(){return{load:function(){this.opts.curLang=this.opts.langs[this.opts.lang]},get:function(t){return void 0!==this.opts.curLang[t]?this.opts.curLang[t]:""}}},line:function(){return{insert:function(){this.buffer.set(),this.insert.html(this.line.getLineHtml());var t=this.core.editor().find("#redactor-hr-tmp-id");return t.removeAttr("id"),this.core.callback("insertedLine",t),t},getLineHtml:function(){var t='<hr id="redactor-hr-tmp-id" />';return!this.detect.isFirefox()&&this.utils.isEmpty()&&(t+="<p>"+this.opts.emptyHtml+"</p>"),t},removeOnBackspace:function(t){var e,i;this.utils.isCollapsed()&&(0===(e=m(this.selection.block())).length||!this.utils.isStartOfElement(e)||(i=e.prev())&&0!==i.length&&"HR"===i[0].tagName&&(t.preventDefault(),i.remove()))}}},link:function(){return{get:function(){return m(this.selection.inlines("a"))},is:function(){var t=this.selection.nodes(),e=m(this.selection.current()).closest("a",this.core.editor()[0]);return!(0===e.length||1<t.length)&&e},unlink:function(t){void 0!==t&&t.preventDefault&&t.preventDefault(),this.buffer.set();var e,i=this.selection.inlines("a");0!==i.length&&(e=this.link.replaceLinksToText(i),this.observe.closeAllTooltip(),this.core.callback("deletedLink",e))},insert:function(t,e){var i,n=this.link.is();return(!0===e||!1!==(t=this.link.buildLinkFromObject(n,t)))&&(this.buffer.set(),t=this.core.callback("beforeInsertingLink",t),!1===n?(n=m("<a />"),n=this.link.update(n,t),i=(n=m(this.insert.node(n))).parent(),!1===this.utils.isRedactorParent(i)&&n.wrap("<p>"),i.hasClass("redactor-unlink")&&i.replaceWith(function(){return m(this).contents()}),this.caret.after(n),this.core.callback("insertedLink",n)):(n=this.link.update(n,t),this.caret.after(n)),n)},update:function(t,e){return t.text(e.text),t.attr("href",e.url),this.link.target(t,e.target),t},target:function(t,e){return e?t.attr("target","_blank"):t.removeAttr("target")},show:function(t){void 0!==t&&t.preventDefault&&t.preventDefault(),this.observe.closeAllTooltip();var e=this.link.is();this.link.buildModal(e);var i=this.link.buildLinkFromElement(e);i.url=this.link.removeSelfHostFromUrl(i.url),this.opts.linkNewTab&&!e&&(i.target=!0),this.link.setModalValues(i),this.modal.show(),this.detect.isDesktop()&&m("#redactor-link-url").focus()},setModalValues:function(t){m("#redactor-link-blank").prop("checked",t.target),m("#redactor-link-url").val(t.url),m("#redactor-link-url-text").val(t.text)},buildModal:function(t){this.modal.load("link",this.lang.get(!1===t?"link-insert":"link-edit"),600),this.modal.getActionButton().text(this.lang.get(!1===t?"insert":"save")).on("click",m.proxy(this.link.callback,this))},callback:function(){var t=this.link.buildLinkFromModal();if(!1===t)return!1;this.modal.close(),this.link.insert(t,!0)},cleanUrl:function(t){return void 0===t?"":m.trim(t.replace(/[^\W\w\D\d+&\'@#/%?=~_|!:,.;\(\)]/gi,""))},cleanText:function(t){return void 0===t?"":m.trim(t.replace(/(<([^>]+)>)/gi,""))},getText:function(t){return""===t.text&&""!==t.url?this.link.truncateUrl(t.url.replace(/<|>/g,"")):t.text},isUrl:function(t){return!!new RegExp("^((https?|ftp):\\/\\/)?(([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$","i").test(t)&&t},isMailto:function(t){return-1!==t.search("@")&&!1===/(http|ftp|https):\/\//i.test(t)},isEmpty:function(t){return""===t.url||""===t.text&&""===t.url},truncateUrl:function(t){return t.length>this.opts.linkSize?t.substring(0,this.opts.linkSize)+"...":t},parse:function(t){return this.link.isMailto(t.url)?t.url="mailto:"+t.url.replace("mailto:",""):0!==t.url.search("#")&&this.opts.linkValidation&&(t.url=this.link.isUrl(t.url)?"http://"+t.url.replace(/(ftp|https?):\/\//gi,""):t.url),!this.link.isEmpty(t)&&!1!==t.url&&t},buildLinkFromModal:function(){var t={};return t.url=this.link.cleanUrl(m("#redactor-link-url").val()),t.text=this.link.cleanText(m("#redactor-link-url-text").val()),t.text=this.link.getText(t),t.target=!!m("#redactor-link-blank").prop("checked"),this.link.parse(t)},buildLinkFromObject:function(t,e){return e.url=this.link.cleanUrl(e.url),e.text=void 0===e.text&&this.selection.is()?this.selection.text():this.link.cleanText(e.text),e.text=this.link.getText(e),e.target=!1===t?e.target:this.link.buildTarget(t),this.link.parse(e)},buildLinkFromElement:function(t){var e={url:"",text:this.selection.is()?this.selection.text():"",target:!1};return!1!==t&&(e.url=t.attr("href"),e.text=t.text(),e.target=this.link.buildTarget(t)),e},buildTarget:function(t){return void 0!==t.attr("target")&&"_blank"===t.attr("target")},removeSelfHostFromUrl:function(t){var e=self.location.href.replace("#","").replace(/\/$/i,"");return t.replace(/^\/\#/,"#").replace(e,"").replace("mailto:","")},replaceLinksToText:function(t){var r,e=m.each(t,function(t,e){var i=m(e),n=m('<span class="redactor-unlink" />').append(i.contents());return i.replaceWith(n),0===t&&(r=n),i});return 1===t.length&&this.selection.isCollapsed()&&this.caret.after(r),e}}},linkify:function(){return{isKey:function(){},isLink:function(){},isFiltered:function(){},handler:function(){},format:function(){},convertVideoLinks:function(){},convertImages:function(){},convertLinks:function(){}}},list:function(){return{toggle:function(t){if(!this.utils.inBlocks(["table","td","th","tr"])){t=(t="unorderedlist"===(t="orderedlist"===t?"ol":t)?"ul":t).toLowerCase(),this.buffer.set(),this.selection.save();var e=this.list._getBlocks(),i=this.selection.block(),n=m(i).parents("ul, ol").last();return 0===e.length&&0!==n.length&&(e=[n.get(0)]),e=this.list._isUnformat(t,e)?this.list._unformat(t,e):this.list._format(t,e),this.selection.restore(),e}},get:function(){var t=this.selection.current(),e=m(t).closest("ul, ol",this.core.editor()[0]);return 0!==e.length&&e},combineAfterAndBefore:function(t){var e=m(t).prev(),i=m(t).next(),n=t&&"P"===t.tagName&&("<br>"===t.innerHTML||""===t.innerHTML),r=1===e.closest("ol, ul",this.core.editor()[0]).length&&1===i.closest("ol, ul",this.core.editor()[0]).length;return!(!n||!r)&&(e.children("li").last().append(this.marker.get()),e.append(i.contents()),this.selection.restore(),!0)},_getBlocks:function(){for(var t=[],e=this.selection.blocks(),i=0;i<e.length;i++){m(e[i]).parent().hasClass("redactor-in")&&t.push(e[i])}return t},_isUnformat:function(t,e){for(var i,n=0,r=0;r<e.length;r++){3!==e[r].nodeType&&((i=e[r].tagName.toLowerCase())!==t&&"figure"!==i||n++)}return n===e.length},_uniteBlocks:function(t,e){for(var i=0,n={0:[]},r=!1,s=0;s<t.length;s++){var o=m(t[s]).closest("th, td");0!==o.length?(o.get(0)!==r&&(n[++i]=[]),this.list._isUniteBlock(t[s],e)&&n[i].push(t[s])):this.list._isUniteBlock(t[s],e)?n[i].push(t[s]):n[++i]=[],r=o.get()}return n},_isUniteBlock:function(t,e){return 3===t.nodeType||-1!==e.indexOf(t.tagName.toLowerCase())},_createList:function(t,e,i){var n=e[e.length-1],r=m(n),s=m("<"+t+">");return r.after(s),s},_createListItem:function(t){var e,i=m("<li>");return 3===t.nodeType?i.append(t):(e=m(t),i.append(e.contents()),e.remove()),i},_format:function(t,e){var i=this.list._uniteBlocks(e,["p","div","blockquote","pre","h1","h2","h3","h4","h5","h6","ul","ol"]),n=[];for(var r in i){for(var s=i[r],o=this.list._createList(t,i[r]),a=0;a<s.length;a++){var l=3===s[a].nodeType||"UL"!==s[a].tagName&&"OL"!==s[a].tagName?this.list._createListItem(s[a]):m(s[a]).contents();o.append(l)}n.push(o.get(0))}return n},_unformat:function(t,e){if(1===e.length){var i=m(e[0]),n=i.find("li"),r=this.selection.blocks(["li"]),s=this.selection.block(),o=m(s).closest("li");if(0===r.length&&0!==o.length&&(r=[o.get(0)]),r.length===n.length)return this.list._unformatEntire(e[0]);var a=this.list._getItemsPosition(n,r);if("Top"===a)return this.list._unformatAtSide("before",r,i);if("Bottom"===a)return r.reverse(),this.list._unformatAtSide("after",r,i);if("Middle"===a){var l=m(r[r.length-1]),c=!1,h=!1,d=m("<"+i.get(0).tagName.toLowerCase()+">");n.each(function(t,e){var i;c&&((i=m(e)).children("ul, ol").length,0!==i.closest(".redactor-split-item").length||!1!==h&&0!==i.closest(h).length||i.addClass("redactor-split-item"),h=i),e===l.get(0)&&(c=!0)}),n.filter(".redactor-split-item").each(function(t,e){m(e).removeClass("redactor-split-item"),d.append(e)}),i.after(d),r.reverse();for(var u=0;u<r.length;u++){var p=m(r[u]),f=this.list._createUnformatContainer(p);i.after(f),f.find("ul, ol").remove(),p.remove()}return}}else for(u=0;u<e.length;u++)3!==e[u].nodeType&&e[u].tagName.toLowerCase()===t&&this.list._unformatEntire(e[u])},_unformatEntire:function(t){var r=m(t);r.find("li").each(function(t,e){var i=m(e),n=this.list._createUnformatContainer(i);i.remove(),r.before(n)}.bind(this)),r.remove()},_unformatAtSide:function(t,r,e){for(var i=0;i<r.length;i++){var n=m(r[i]),s=this.list._createUnformatContainer(n);e[t](s);var o=s.find("ul, ol").first();n.append(o),o.each(function(t,e){var i=m(e),n=i.closest("li");n.get(0)===r[t]&&(i.unwrap(),n.addClass("r-unwrapped"))}),this.utils.isEmpty(n.html())&&n.remove()}e.find(".r-unwrapped").each(function(t){var e=m(t);""===e.html().trim()?e.remove():e.removeClass("r-unwrapped")})},_getItemsPosition:function(t,e){var i="Middle",n=e[0],r=e[e.length-1],s=t.first().get(0),o=t.last().get(0);return s===n&&o!==r?i="Top":s!==n&&o===r&&(i="Bottom"),i},_createUnformatContainer:function(t){var e=m("<p>");return e.append(t.contents()),e}}},marker:function(){return{get:function(t){t=void 0===t?1:t;var e=document.createElement("span");return e.id="selection-marker-"+t,e.className="redactor-selection-marker",e.innerHTML=this.opts.invisibleSpace,e},html:function(t){return this.utils.getOuterHtml(this.marker.get(t))},find:function(t){return t=void 0===t?1:t,this.core.editor().find("span#selection-marker-"+t)},insert:function(){var t=this.selection.get(),e=this.selection.range(t);this.marker.insertNode(e,this.marker.get(1),!0),e&&!1===e.collapsed&&this.marker.insertNode(e,this.marker.get(2),!1)},remove:function(){this.core.editor().find(".redactor-selection-marker").each(this.marker.iterateRemove)},insertNode:function(t,e,i){var n=this.selection.parent();if(null!==t&&0!==m(n).closest(".redactor-in").length){t=t.cloneRange();try{t.collapse(i),t.insertNode(e)}catch(t){this.focus.start()}}},iterateRemove:function(t,e){var i=m(e),n=i.text().replace(/\u200B/g,"");i.parent()[0];""===n?i.remove():i.replaceWith(function(){return m(this).contents()})}}},modal:function(){return{callbacks:{},templates:function(){this.opts.modal={"image-edit":"",image:"",file:"",link:String()+'<div class="redactor-modal-tab" data-title="General"><section><label>URL</label><input type="url" id="redactor-link-url" aria-label="URL" /></section><section><label>'+this.lang.get("text")+'</label><input type="text" id="redactor-link-url-text" aria-label="'+this.lang.get("text")+'" /></section><section><label class="checkbox"><input type="checkbox" id="redactor-link-blank"> '+this.lang.get("link-in-new-tab")+'</label></section><section><button id="redactor-modal-button-action">'+this.lang.get("insert")+'</button><button id="redactor-modal-button-cancel">'+this.lang.get("cancel")+"</button></section></div>"},m.extend(this.opts,this.opts.modal)},addCallback:function(t,e){this.modal.callbacks[t]=e},addTemplate:function(t,e){this.opts.modal[t]=e},getTemplate:function(t){return this.opts.modal[t]},getModal:function(){return this.$modalBody},getActionButton:function(){return this.$modalBody.find("#redactor-modal-button-action")},getCancelButton:function(){return this.$modalBody.find("#redactor-modal-button-cancel")},getDeleteButton:function(){return this.$modalBody.find("#redactor-modal-button-delete")},load:function(){},show:function(){},buildWidth:function(){},buildTabber:function(){},showTab:function(){},setTitle:function(){},setContent:function(){this.$modalBody.html(this.modal.getTemplate(this.modal.templateName)),this.modal.getCancelButton().on("mousedown",m.proxy(this.modal.close,this))},setDraggable:function(){},setEnter:function(){},build:function(){this.modal.buildOverlay(),this.$modalBox=m('<div id="redactor-modal-box"/>').hide(),this.$modal=m('<div id="redactor-modal" role="dialog" />'),this.$modalHeader=m('<div id="redactor-modal-header" />'),this.$modalClose=m('<button type="button" id="redactor-modal-close" aria-label="'+this.lang.get("close")+'" />').html("&times;"),this.$modalBody=m('<div id="redactor-modal-body" />'),this.$modal.append(this.$modalHeader),this.$modal.append(this.$modalBody),this.$modal.append(this.$modalClose),this.$modalBox.append(this.$modal),this.$modalBox.appendTo(document.body)},buildOverlay:function(){this.$modalOverlay=m('<div id="redactor-modal-overlay">').hide(),m("body").prepend(this.$modalOverlay)},enableEvents:function(){},disableEvents:function(){},closeHandler:function(){},close:function(){}}},observe:function(){return{load:function(){void 0===this.opts.destroyed&&(this.observe.links(),this.observe.images())},isCurrent:function(t,e){return void 0===e&&(e=m(this.selection.current())),e.is(t)||0<e.parents(t).length},toolbar:function(){this.observe.buttons(),this.observe.dropdowns()},buttons:function(t,e){var r=this.selection.current(),s=this.selection.parent();!1!==t?this.button.setInactiveAll():this.button.setInactiveAll(e),!1!==t||"html"===e?this.utils.isRedactorParent(r)&&("none"!==this.core.editor().css("display")&&(this.utils.isCurrentOrParentHeader()||this.utils.isCurrentOrParent(["table","pre","blockquote","li"])?this.button.disable("horizontalrule"):this.button.enable("horizontalrule")),m.each(this.opts.activeButtonsStates,m.proxy(function(t,e){var i=m(s).closest(t,this.$editor[0]),n=m(r).closest(t,this.$editor[0]);(0===i.length||this.utils.isRedactorParent(i))&&this.utils.isRedactorParent(n)&&(0===i.length&&0===n.closest(t,this.$editor[0]).length||this.button.setActive(e))},this))):-1!==m.inArray(e,this.opts.activeButtons)&&this.button.toggleActive(e)},dropdowns:function(){var a=m("<div />").html(this.selection.html()).find("a").length,l=m(this.selection.current()),c=this.utils.isRedactorParent(l);m.each(this.opts.observe.dropdowns,m.proxy(function(t,e){var i=e.observe,n=i.element,r=e.item,s=void 0!==i.in&&i.in,o=void 0!==i.out&&i.out;0<l.closest(n).length&&c||"a"===n&&0!==a?this.observe.setDropdownProperties(r,s,o):this.observe.setDropdownProperties(r,o,s)},this))},setDropdownProperties:function(t,e,i){i&&void 0!==i.attr&&this.observe.setDropdownAttr(t,i.attr,!0),void 0!==e.attr&&this.observe.setDropdownAttr(t,e.attr),void 0!==e.title&&t.find("span").text(e.title)},setDropdownAttr:function(i,t,n){m.each(t,function(t,e){"class"===t?n?i.removeClass(e):i.addClass(e):n?i.removeAttr(t):i.attr(t,e)})},addDropdown:function(t,e,i){void 0!==i.observe&&(i.item=t,this.opts.observe.dropdowns.push(i))},images:function(){this.opts.imageEditable&&(this.core.editor().addClass("redactor-layer-img-edit"),this.core.editor().find("img").each(m.proxy(function(t,e){var i=m(e);i.closest("a",this.$editor[0]).on("click",function(t){t.preventDefault()}),this.image.setEditable(i)},this)))},links:function(){this.opts.linkTooltip&&this.core.editor().find("a").each(m.proxy(function(t,e){var i=m(e);!0!==i.data("cached")&&(i.data("cached",!0),i.on("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,m.proxy(this.observe.showTooltip,this)))},this))},getTooltipPosition:function(t){return t.offset()},showTooltip:function(t){var e,i,n,r,s,o,a,l,c,h,d=m(t.target);"IMG"!==d[0].tagName&&("A"!==d[0].tagName&&(d=d.closest("a",this.$editor[0])),"A"===d[0].tagName&&(e=d,i=this.observe.getTooltipPosition(e),n=m('<span class="redactor-link-tooltip"></span>'),void 0===(r=e.attr("href"))&&(r=""),24<r.length&&(r=r.substring(0,24)+"..."),s=m('<a href="'+e.attr("href")+'" target="_blank" />').html(r).addClass("redactor-link-tooltip-action"),o=m('<a href="#" />').html(this.lang.get("edit")).on("click",m.proxy(this.link.show,this)).addClass("redactor-link-tooltip-action"),a=m('<a href="#" />').html(this.lang.get("unlink")).on("click",m.proxy(this.link.unlink,this)).addClass("redactor-link-tooltip-action"),n.append(s).append(" | ").append(o).append(" | ").append(a),l=parseInt(e.css("line-height"),10),c=Math.ceil((t.pageY-i.top)/l),h=i.top+c*l,n.css({top:h+"px",left:i.left+"px"}),m(".redactor-link-tooltip").remove(),m("body").append(n),this.core.editor().on("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,m.proxy(this.observe.closeTooltip,this)),m(document).on("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,m.proxy(this.observe.closeTooltip,this))))},closeAllTooltip:function(){m(".redactor-link-tooltip").remove()},closeTooltip:function(t){var e=(t=t.originalEvent||t).target,i=m(e).closest("a",this.$editor[0]);0!==i.length&&"A"===i[0].tagName&&"A"!==e.tagName||"A"===e.tagName&&this.utils.isRedactorParent(e)||m(e).hasClass("redactor-link-tooltip-action")||(this.observe.closeAllTooltip(),this.core.editor().off("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,m.proxy(this.observe.closeTooltip,this)),m(document).off("touchstart.redactor."+this.uuid+" click.redactor."+this.uuid,m.proxy(this.observe.closeTooltip,this)))}}},offset:function(){return{get:function(t){var e=this.offset.clone(t);if(!1===e)return 0;var i=document.createElement("div");return i.appendChild(e.cloneContents()),i.innerHTML=i.innerHTML.replace(/<img(.*?[^>])>$/gi,"i"),m.trim(m(i).text()).replace(/[\t\n\r\n]/g,"").replace(/\u200B/g,"").length},clone:function(t){var e=this.selection.get(),i=this.selection.range(e);if(null===i&&void 0===t)return!1;if(!1===(t=void 0===t?this.$editor:t))return!1;t=t[0]||t;var n=i.cloneRange();return n.selectNodeContents(t),n.setEnd(i.endContainer,i.endOffset),n},set:function(t,e){e=void 0===e?t:e,this.focus.is()||this.focus.start();for(var i,n=this.selection.get(),r=this.selection.range(n),s=0,o=document.createTreeWalker(this.$editor[0],NodeFilter.SHOW_TEXT,null,null);null!==(i=o.nextNode());)if(t<(s+=i.nodeValue.length)&&(r.setStart(i,i.nodeValue.length+t-s),t=1/0),e<=s){r.setEnd(i,i.nodeValue.length+e-s);break}r.collapse(!1),this.selection.update(n,r)}}},paragraphize:function(){return{load:function(t){return!1===this.opts.paragraphize||"inline"===this.opts.type||"pre"===this.opts.type?t:""===t||"<p></p>"===t?this.opts.emptyHtml:(t+="\n",this.paragraphize.safes=[],this.paragraphize.z=0,t=(t=(t=t.replace(/(<br\s?\/?>){1,}\n?<\/blockquote>/gi,"</blockquote>")).replace(/<\/pre>/gi,"</pre>\n\n")).replace(/<p>\s<br><\/p>/gi,"<p></p>"),t=(t=this.paragraphize.getSafes(t)).replace("<br>","\n"),t=this.paragraphize.convert(t),t=this.paragraphize.clear(t),t=(t=this.paragraphize.restoreSafes(t)).replace(new RegExp("<br\\s?/?>\n?<("+this.opts.paragraphizeBlocks.join("|")+")(.*?[^>])>","gi"),"<p><br /></p>\n<$1$2>"),m.trim(t))},getSafes:function(t){var e=m("<div />").append(t);return e.find("blockquote p").replaceWith(function(){return m(this).append("<br />").contents()}),e.find(this.opts.paragraphizeBlocks.join(", ")).each(m.proxy(function(t,e){return this.paragraphize.z++,this.paragraphize.safes[this.paragraphize.z]=e.outerHTML,m(e).replaceWith("\n#####replace"+this.paragraphize.z+"#####\n\n")},this)),e.find("span.redactor-selection-marker").each(m.proxy(function(t,e){return this.paragraphize.z++,this.paragraphize.safes[this.paragraphize.z]=e.outerHTML,m(e).replaceWith("\n#####replace"+this.paragraphize.z+"#####\n\n")},this)),e.html()},restoreSafes:function(i){return m.each(this.paragraphize.safes,function(t,e){e=void 0!==e?e.replace(/\$/g,"&#36;"):e,i=i.replace("#####replace"+t+"#####",e)}),i},convert:function(t){t=(t=(t=(t=t.replace(/\r\n/g,"xparagraphmarkerz")).replace(/\n/g,"xparagraphmarkerz")).replace(/\r/g,"xparagraphmarkerz")).replace(/\s+/g," ");return t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t="<p>"+(t=(t=(t=m.trim(t)).replace(/xparagraphmarkerzxparagraphmarkerz/gi,"</p><p>")).replace(/xparagraphmarkerz/gi,"<br>"))+"</p>").replace("<p></p>","")).replace("\r\n\r\n","")).replace(/<\/p><p>/g,"</p>\r\n\r\n<p>")).replace(new RegExp("<br\\s?/?></p>","g"),"</p>")).replace(new RegExp("<p><br\\s?/?>","g"),"<p>")).replace(new RegExp("<p><br\\s?/?>","g"),"<p>")).replace(new RegExp("<br\\s?/?></p>","g"),"</p>")).replace(/<p>&nbsp;<\/p>/gi,"")).replace(/<p>\s?<br>&nbsp;<\/p>/gi,"")).replace(/<p>\s?<br>/gi,"<p>")},clear:function(t){return t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace(/<p>(.*?)#####replace(.*?)#####\s?<\/p>/gi,"<p>$1</p>#####replace$2#####")).replace(/(<br\s?\/?>){2,}<\/p>/gi,"</p>")).replace(new RegExp("</blockquote></p>","gi"),"</blockquote>")).replace(new RegExp("<p></blockquote>","gi"),"</blockquote>")).replace(new RegExp("<p><blockquote>","gi"),"<blockquote>")).replace(new RegExp("<blockquote></p>","gi"),"<blockquote>")).replace(new RegExp("<p><p ","gi"),"<p ")).replace(new RegExp("<p><p>","gi"),"<p>")).replace(new RegExp("</p></p>","gi"),"</p>")).replace(new RegExp("<p>\\s?</p>","gi"),"")).replace(new RegExp("\n</p>","gi"),"</p>")).replace(new RegExp("<p>\t?\t?\n?<p>","gi"),"<p>")).replace(new RegExp("<p>\t*</p>","gi"),"")}}},paste:function(){return{init:function(t){this.rtePaste=!0;var n=!("pre"!==this.opts.type&&!this.utils.isCurrentOrParent("pre"));this.detect.isDesktop()&&!this.paste.pre&&this.opts.clipboardImageUpload&&this.opts.imageUpload&&this.paste.detectClipboardUpload(t)?this.detect.isIe()&&setTimeout(m.proxy(this.paste.clipboardUpload,this),100):(this.utils.saveScroll(),this.selection.save(),this.paste.createPasteBox(n),m(window).on("scroll.redactor-freeze",m.proxy(function(){m(window).scrollTop(this.saveBodyScroll)},this)),setTimeout(m.proxy(function(){var t=this.paste.getPasteBoxCode(n);this.buffer.set(),this.selection.restore(),this.utils.restoreScroll();var e=this.clean.getCurrentType(t),t=this.clean.onPaste(t,e),i=this.core.callback("paste",t);t=void 0===i?t:i,this.paste.insert(t,e),this.rtePaste=!1,n&&this.clean.cleanPre(),m(window).off("scroll.redactor-freeze")},this),1))},getPasteBoxCode:function(t){var e=t?this.$pasteBox.val():this.$pasteBox.html();return this.$pasteBox.remove(),e},createPasteBox:function(t){var e={position:"fixed",width:"1px",top:0,left:"-9999px"};this.$pasteBox=t?m("<textarea>").css(e):m("<div>").attr("contenteditable","true").css(e),this.paste.appendPasteBox(),this.$pasteBox.focus()},appendPasteBox:function(){var t;this.detect.isIe()?this.core.box().append(this.$pasteBox):0<(t=m(".modal-body:visible")).length?t.append(this.$pasteBox):m("body").prepend(this.$pasteBox)},detectClipboardUpload:function(t){var e=(t=t.originalEvent||t).clipboardData;if(this.detect.isIe()||this.detect.isFirefox())return!1;if(-1!==e.types.indexOf("public.tiff"))return t.preventDefault(),!1;if(e.items&&e.items.length){var i=e.items[0].getAsFile();if(null===i)return!1;var n=new FileReader;return n.readAsDataURL(i),n.onload=m.proxy(this.paste.insertFromClipboard,this),!0}},clipboardUpload:function(){var t=this.$editor.find("img");m.each(t,m.proxy(function(t,i){var e,n;-1!==i.src.search(/^data\:image/i)&&(e=window.FormData?new FormData:null,window.FormData&&(this.upload.direct=!0,this.upload.type="image",this.upload.url=this.opts.imageUpload,this.upload.callback=m.proxy(function(t){var e;this.detect.isIe()?m(i).wrap(m("<figure />")):(e=m(i).parent(),this.utils.replaceToTag(e,"figure")),i.src=t.url,this.core.callback("imageUpload",m(i),t)},this),n=this.utils.dataURItoBlob(i.src),e.append("clipboard",1),e.append(this.opts.imageUploadParam,n),this.upload.send(e,!1),this.code.sync(),this.rtePaste=!1))},this))},insertFromClipboard:function(t){var e,i=window.FormData?new FormData:null;window.FormData&&(this.upload.direct=!0,this.upload.type="image",this.upload.url=this.opts.imageUpload,this.upload.callback=this.image.insert,e=this.utils.dataURItoBlob(t.target.result),i.append("clipboard",1),i.append(this.opts.imageUploadParam,e),this.upload.send(i,t),this.rtePaste=!1)},insert:function(t,e){e.pre?this.insert.raw(t):e.text?this.insert.text(t):this.insert.html(t,e),this.detect.isFirefox()&&this.opts.imageUpload&&this.opts.clipboardImageUpload&&setTimeout(m.proxy(this.paste.clipboardUpload,this),100)}}},placeholder:function(){return{enable:function(){},show:function(){},update:function(){},hide:function(){},is:function(){},init:function(){},enabled:function(){},enableEvents:function(){},disableEvents:function(){},build:function(){},buildPosition:function(){},getPosition:function(){},isEditorEmpty:function(){},isAttr:function(){},destroy:function(){}}},progress:function(){return{$box:null,$bar:null,target:document.body,show:function(){},hide:function(){},update:function(){},is:function(){},build:function(){},destroy:function(){}}},selection:function(){return{get:function(){return window.getSelection?window.getSelection():document.selection&&"Control"!==document.selection.type?document.selection:null},range:function(t){return void 0===t&&(t=this.selection.get()),t.getRangeAt&&t.rangeCount?t.getRangeAt(0):null},is:function(){return!this.selection.isCollapsed()},isRedactor:function(){var t=this.selection.range();if(null!==t){var e=t.startContainer.parentNode;if(m(e).hasClass("redactor-in")||0!==m(e).parents(".redactor-in").length)return!0}return!1},isCollapsed:function(){var t=this.selection.get();return null!==t&&t.isCollapsed},update:function(t,e){null!==e&&(t.removeAllRanges(),t.addRange(e))},current:function(){var t=this.selection.get();return null!==t&&t.anchorNode},parent:function(){var t=this.selection.current();return null!==t&&t.parentNode},block:function(t){for(t=t||this.selection.current();t;){if(this.utils.isBlockTag(t.tagName))return!m(t).hasClass("redactor-in")&&t;t=t.parentNode}return!1},inline:function(t){for(t=t||this.selection.current();t;){if(this.utils.isInlineTag(t.tagName))return!m(t).hasClass("redactor-in")&&t;t=t.parentNode}return!1},element:function(t){for(t=t||this.selection.current();t;){if(1===t.nodeType)return!m(t).hasClass("redactor-in")&&t;t=t.parentNode}return!1},prev:function(){return null!==this.selection.current()&&this.selection.current().previousSibling},next:function(){return null!==this.selection.current()&&this.selection.current().nextSibling},blocks:function(t){var i=[],e=this.selection.nodes(t);m.each(e,m.proxy(function(t,e){this.utils.isBlock(e)&&i.push(e)},this));var n=this.selection.block();return 0===i.length&&!1===n?[]:0===i.length&&!1!==n?[n]:i},inlines:function(t){var i=[],e=this.selection.nodes(t);m.each(e,m.proxy(function(t,e){this.utils.isInline(e)&&i.push(e)},this));var n=this.selection.inline();return 0===i.length&&!1===n?[]:0===i.length&&!1!==n?[n]:i},nodes:function(t){var n=void 0===t?[]:m.isArray(t)?t:[t],e=this.selection.get(),i=this.selection.range(e),r=[],s=[];if(this.utils.isCollapsed())r=[this.selection.current()];else{var o=i.startContainer,a=i.endContainer;if(o===a)return[o];for(;o&&o!==a;)r.push(o=this.selection.nextNode(o));for(o=i.startContainer;o&&o!==i.commonAncestorContainer;)r.unshift(o),o=o.parentNode}return m.each(r,function(t,e){if(e){var i=1===e.nodeType&&e.tagName.toLowerCase();if(m(e).hasClass("redactor-script-tag")||m(e).hasClass("redactor-selection-marker"))return;if(i&&0!==n.length&&-1===m.inArray(i,n))return;s.push(e)}}),0===s.length?[]:s},nextNode:function(t){if(t.hasChildNodes())return t.firstChild;for(;t&&!t.nextSibling;)t=t.parentNode;return t?t.nextSibling:null},save:function(){this.marker.insert(),this.savedSel=this.core.editor().html()},restore:function(t){var e=this.marker.find(1),i=this.marker.find(2);this.detect.isFirefox()&&this.core.editor().focus(),0!==e.length&&0!==i.length?this.caret.set(e,i):0!==e.length?this.caret.start(e):this.core.editor().focus(),!1!==t&&(this.marker.remove(),this.savedSel=!1)},saveInstant:function(){var t=this.core.editor()[0],e=t.ownerDocument.defaultView.getSelection();if(e.getRangeAt&&e.rangeCount){var i=e.getRangeAt(0),n=i.cloneRange();n.selectNodeContents(t),n.setEnd(i.startContainer,i.startOffset);var r=n.toString().length;return this.saved={start:r,end:r+i.toString().length,node:i.startContainer},this.saved}},restoreInstant:function(t){if(void 0!==t||this.saved){this.saved=void 0!==t?t:this.saved;var e=this.core.editor().find(this.saved.node);if(0===e.length||0!==e.text().trim().replace(/\u200B/g,"").length){var i,n=this.core.editor()[0],r=n.ownerDocument,s=r.defaultView,o=0;(i=r.createRange()).setStart(n,0),i.collapse(!0);for(var a,l,c=[n],h=!1,d=!1;!d&&(a=c.pop());)if(3==a.nodeType){var u=o+a.length;!h&&this.saved.start>=o&&this.saved.start<=u&&(i.setStart(a,this.saved.start-o),h=!0),h&&this.saved.end>=o&&this.saved.end<=u&&(i.setEnd(a,this.saved.end-o),d=!0),o=u}else for(var p=a.childNodes.length;p--;)c.push(a.childNodes[p]);(l=s.getSelection()).removeAllRanges(),l.addRange(i)}else try{(i=document.createRange()).setStart(e[0],0),(l=window.getSelection()).removeAllRanges(),l.addRange(i)}catch(t){}}},node:function(t){m(t).prepend(this.marker.get(1)),m(t).append(this.marker.get(2)),this.selection.restore()},all:function(){this.core.editor().focus();var t=this.selection.get(),e=this.selection.range(t);e.selectNodeContents(this.core.editor()[0]),this.selection.update(t,e)},remove:function(){this.selection.get().removeAllRanges()},replace:function(t){this.insert.html(t)},text:function(){return this.selection.get().toString()},html:function(){var t="",e=this.selection.get();if(e.rangeCount){for(var i=document.createElement("div"),n=e.rangeCount,r=0;r<n;++r)i.appendChild(e.getRangeAt(r).cloneContents());t=this.clean.onGet(i.innerHTML)}return t},extractEndOfNode:function(t){var e=this.selection.get(),i=this.selection.range(e),n=i.cloneRange();return n.selectNodeContents(t),n.setStart(i.endContainer,i.endOffset),n.extractContents()},removeMarkers:function(){this.marker.remove()},marker:function(t){return this.marker.get(t)},markerHtml:function(t){return this.marker.html(t)}}},shortcuts:function(){return{hotkeysSpecialKeys:{8:"backspace",9:"tab",10:"return",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},hotkeysShiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"},init:function(i,t){if(!1===this.opts.shortcuts)return!i.ctrlKey&&!i.metaKey||66!==t&&73!==t||i.preventDefault(),!1;m.each(this.opts.shortcuts,m.proxy(function(t,e){this.shortcuts.build(i,t,e)},this))},build:function(t,e,i){for(var n=m.proxy(function(){this.shortcuts.buildHandler(i)},this),r=e.split(","),s=r.length,o=0;o<s;o++)"string"==typeof r[o]&&this.shortcuts.handler(t,m.trim(r[o]),n)},buildHandler:function(t){var e;"-1"!==t.func.search(/\./)?void 0!==this[(e=t.func.split("."))[0]]&&this[e[0]][e[1]].apply(this,t.params):this[t.func].apply(this,t.params)},handler:function(i,t,e){t=t.toLowerCase().split(" ");var n=this.shortcuts.hotkeysSpecialKeys[i.keyCode],r=String.fromCharCode(i.which).toLowerCase(),s="",o={};m.each(["alt","ctrl","meta","shift"],function(t,e){i[e+"Key"]&&n!==e&&(s+=e+"+")}),n&&(o[s+n]=!0),r&&(o[s+r]=!0,o[s+this.shortcuts.hotkeysShiftNums[r]]=!0,"shift+"===s&&(o[this.shortcuts.hotkeysShiftNums[r]]=!0));for(var a=t.length,l=0;l<a;l++)if(o[t[l]])return i.preventDefault(),e.apply(this,arguments)}}},storage:function(){return{data:[],add:function(){},status:function(){},observe:function(){},changes:function(){}}},toolbar:function(){return{build:function(){this.button.hideButtons(),this.button.hideButtonsOnMobile(),this.$toolbarBox=m('<div class="redactor-toolbar-box" />'),this.$toolbarBox[0].innerHTML='<ul class="redactor-toolbar" id="redactor-toolbar-'+this.uuid+'" role="toolbar"></ul>',this.$toolbar=m(this.$toolbarBox[0].children[0]),this.$box[0].insertBefore(this.$toolbarBox[0],this.$box[0].firstChild),this.button.$toolbar=this.$toolbar,this.button.setFormatting(),this.button.load(this.$toolbar),require(["Core"],function(t){this.$toolbar[0].addEventListener("keydown",this.toolbar.keydown.bind(this,t))}.bind(this))},createContainer:function(){},append:function(){},setOverflow:function(){},setFixed:function(){},setUnfixed:function(){},getBoxTop:function(){},observeScroll:function(){},observeScrollResize:function(){},observeScrollEnable:function(){},observeScrollDisable:function(){},setDropdownsFixed:function(){},unsetDropdownsFixed:function(){},setDropdownPosition:function(){},keydown:function(t,e){var i=document.activeElement;if(i.classList.contains("re-button")){if(-1!==[13,32,35,36,37,39,40].indexOf(e.which)){if(13===e.which||32===e.which)return e.preventDefault(),void require(["Core"],function(t){t.triggerEvent(i,"mousedown")});if(40!==e.which){e.preventDefault();var n,r=Array.prototype.slice.call(elBySelAll(".re-button",this.$toolbar[0])),s=null;null!==(s=35===e.which?r[r.length-1]:36===e.which?r[0]:(n=r.indexOf(i),37===e.which?-1===--n&&(n=r.length-1):39===e.which&&++n===r.length&&(n=0),r[n]))&&s.focus()}else{if("true"!==elAttr(i,"aria-haspopup"))return;e.preventDefault(),t.triggerEvent(i,"mousedown");var o=m(i).data("dropdown"),a=elBySel("li",o[0]);a&&a.focus()}}}}}},upload:function(){return{init:function(){},directUpload:function(){},onDrop:function(){},traverseFile:function(){},setConfig:function(){},getType:function(){},getHiddenFields:function(){},send:function(){},onDrag:function(){},onDragLeave:function(){},clearImageFields:function(){},addImageFields:function(){},removeImageFields:function(){},clearFileFields:function(){},addFileFields:function(){},removeFileFields:function(){}}},uploads3:function(){return{send:function(){},executeOnSignedUrl:function(){},createCORSRequest:function(){},sendToS3:function(){}}},utils:function(){return{isEmpty:function(t){return t=(t=(t=(t=(t=(t=(t=(t=(t=(t=void 0===t?this.core.editor().html():t).replace(/[\u200B-\u200D\uFEFF]/g,"")).replace(/&nbsp;/gi,"")).replace(/<\/?br\s?\/?>/g,"")).replace(/\s/g,"")).replace(/^<p>[^\W\w\D\d]*?<\/p>$/i,"")).replace(/<iframe(.*?[^>])>$/i,"iframe")).replace(/<source(.*?[^>])>$/i,"source")).replace(/<[^\/>][^>]*><\/[^>]+>/gi,"")).replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),""===(t=m.trim(t))},isElement:function(e){try{return e instanceof HTMLElement}catch(t){return"object"==typeof e&&1===e.nodeType&&"object"==typeof e.style&&"object"==typeof e.ownerDocument}},strpos:function(t,e,i){var n=t.indexOf(e,i);return 0<=n&&n},dataURItoBlob:function(t){for(var e=(0<=t.split(",")[0].indexOf("base64")?atob:unescape)(t.split(",")[1]),i=t.split(",")[0].split(":")[1].split(";")[0],n=new Uint8Array(e.length),r=0;r<e.length;r++)n[r]=e.charCodeAt(r);return new Blob([n],{type:i})},getOuterHtml:function(t){return m("<div>").append(m(t).eq(0).clone()).html()},cloneAttributes:function(t,e){t=t[0]||t,e=m(e);for(var i=t.attributes,n=i.length;n--;){var r=i[n];e.attr(r.name,r.value)}return e},breakBlockTag:function(){var t=this.selection.block();if(!t)return!1;var e=this.utils.isEmpty(t.innerHTML),i=t.tagName.toLowerCase();if("pre"===i||"li"===i||"td"===i||"th"===i)return!1;if(!e&&this.utils.isStartOfElement(t))return{$block:m(t),$next:m(t).next(),type:"start"};if(!e&&this.utils.isEndOfElement(t))return{$block:m(t),$next:m(t).next(),type:"end"};var n=this.selection.extractEndOfNode(t),r=m("<"+i+" />").append(n),r=this.utils.cloneAttributes(t,r);return m(t).after(r),{$block:m(t),$next:r,type:"break"}},inBlocks:function(t){t=m.isArray(t)?t:[t];for(var e,i=this.selection.blocks(),n=i.length,r=!1,s=0;s<n;s++){!1!==i[s]&&(e=i[s].tagName.toLowerCase(),-1!==m.inArray(e,t)&&(r=!0))}return r},inInlines:function(t){t=m.isArray(t)?t:[t];for(var e=this.selection.inlines(),i=e.length,n=!1,r=0;r<i;r++){var s=e[r].tagName.toLowerCase();-1!==m.inArray(s,t)&&(n=!0)}return n},isTag:function(t,e){var i=m(t).closest(e,this.core.editor()[0]);return 1===i.length&&i[0]},isBlock:function(t){return null!==t&&((t=t[0]||t)&&this.utils.isBlockTag(t.tagName))},isBlockTag:function(t){return void 0!==t&&this.reIsBlock.test(t)},isInline:function(t){return(t=t[0]||t)&&this.utils.isInlineTag(t.tagName)},isInlineTag:function(t){return void 0!==t&&this.reIsInline.test(t)},isRedactorParent:function(t){return!!t&&(0!==m(t).parents(".redactor-in").length&&!m(t).hasClass("redactor-in")&&t)},isCurrentOrParentHeader:function(){return this.utils.isCurrentOrParent(["H1","H2","H3","H4","H5","H6"])},isCurrentOrParent:function(t){var i=this.selection.parent(),n=this.selection.current();if(m.isArray(t)){var r=0;return m.each(t,m.proxy(function(t,e){this.utils.isCurrentOrParentOne(n,i,e)&&r++},this)),0!==r}return this.utils.isCurrentOrParentOne(n,i,t)},isCurrentOrParentOne:function(t,e,i){return i=i.toUpperCase(),e&&e.tagName===i?e:!(!t||t.tagName!==i)&&t},isEditorRelative:function(){var t=this.core.editor().css("position");return-1!==m.inArray(["absolute","fixed","relative"],t)},setEditorRelative:function(){this.core.editor().addClass("redactor-relative")},getScrollTarget:function(){var t=m(this.opts.scrollTarget);return 0!==t.length?t:m(document)},freezeScroll:function(){this.freezeScrollTop=this.utils.getScrollTarget().scrollTop(),this.utils.getScrollTarget().scrollTop(this.freezeScrollTop)},unfreezeScroll:function(){void 0!==this.freezeScrollTop&&this.utils.getScrollTarget().scrollTop(this.freezeScrollTop)},saveScroll:function(){this.tmpScrollTop=this.utils.getScrollTarget().scrollTop()},restoreScroll:function(){void 0!==this.tmpScrollTop&&this.utils.getScrollTarget().scrollTop(this.tmpScrollTop)},isStartOfElement:function(t){return!(void 0===t&&!(t=this.selection.block()))&&0===this.offset.get(t)},isEndOfElement:function(t){if(void 0===t&&!(t=this.selection.block()))return!1;var e=m.trim(m(t).text()).replace(/[\t\n\r\n]/g,"").replace(/\u200B/g,"");return this.offset.get(t)===e.length},removeEmptyAttr:function(t,e){var i=m(t);return void 0===i.attr(e)||""===i.attr(e)&&(i.removeAttr(e),!0)},replaceToTag:function(t,e){var i;return m(t).replaceWith(function(){i=m("<"+e+" />").append(m(this).contents());for(var t=0;t<this.attributes.length;t++)i.attr(this.attributes[t].name,this.attributes[t].value);return i}),i},isSelectAll:function(){return this.selectAll},enableSelectAll:function(){this.selectAll=!0},disableSelectAll:function(){this.selectAll=!1},disableBodyScroll:function(){},measureScrollbar:function(){var t=m("body"),e=document.createElement("div");e.className="redactor-scrollbar-measure",t.append(e);var i=e.offsetWidth-e.clientWidth;return t[0].removeChild(e),i},enableBodyScroll:function(){},appendFields:function(t,i){if(!t)return i;if("object"==typeof t)return m.each(t,function(t,e){null!==e&&0===e.toString().indexOf("#")&&(e=m(e).val()),i.append(t,e)}),i;var e=m(t);if(0===e.length)return i;return e.each(function(){i.append(m(this).attr("name"),m(this).val())}),i},appendForms:function(t,i){if(!t)return i;var e=m(t);if(0===e.length)return i;var n=e.serializeArray();return m.each(n,function(t,e){i.append(e.name,e.value)}),i},isRgb:function(t){return 0===t.search(/^rgb/i)},rgb2hex:function(t){return(t=t.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i))&&4===t.length?"#"+("0"+parseInt(t[1],10).toString(16)).slice(-2)+("0"+parseInt(t[2],10).toString(16)).slice(-2)+("0"+parseInt(t[3],10).toString(16)).slice(-2):""},isCollapsed:function(){return this.selection.isCollapsed()},isMobile:function(){return this.detect.isMobile()},isDesktop:function(){return this.detect.isDesktop()},isPad:function(){return this.detect.isIpad()}}},browser:function(){return{webkit:function(){return this.detect.isWebkit()},ff:function(){return this.detect.isFirefox()},ie:function(){return this.detect.isIe()}}}},m(window).on("load.tools.redactor",function(){m('[data-tools="redactor"]').redactor()}),l.prototype.init.prototype=l.prototype}(jQuery),function(s){function n(t,e,i,n){var r={duration:.5,iterate:1,delay:0,prefix:"redactor-",timing:"linear"};this.animation=e,this.slide="slideDown"===this.animation||"slideUp"===this.animation,this.$element=s(t),this.prefixes=["","-moz-","-o-animation-","-webkit-"],this.queue=[],"function"==typeof i?(n=i,this.opts=r):this.opts=s.extend(r,i),this.slide&&this.$element.height(this.$element.height()),this.init(n)}s.fn.redactorAnimation=function(t,e,i){return this.each(function(){new n(this,t,e,i)})},n.prototype={init:function(t){this.queue.push(this.animation),this.clean(),"show"===this.animation?(this.opts.timing="linear",this.$element.removeClass("hide").show(),"function"==typeof t&&t(this)):"hide"===this.animation?(this.opts.timing="linear",this.$element.hide(),"function"==typeof t&&t(this)):this.animate(t)},animate:function(t){this.$element.addClass("redactor-animated").css("display","").removeClass("hide"),this.$element.addClass(this.opts.prefix+this.queue[0]),this.set(this.opts.duration+"s",this.opts.delay+"s",this.opts.iterate,this.opts.timing);var e=1<this.queue.length?null:t;this.complete("AnimationEnd",s.proxy(function(){this.$element.hasClass(this.opts.prefix+this.queue[0])&&(this.clean(),this.queue.shift(),this.queue.length&&this.animate(t))},this),e)},set:function(t,e,i,n){for(var r=this.prefixes.length;r--;)this.$element.css(this.prefixes[r]+"animation-duration",t),this.$element.css(this.prefixes[r]+"animation-delay",e),this.$element.css(this.prefixes[r]+"animation-iteration-count",i),this.$element.css(this.prefixes[r]+"animation-timing-function",n)},clean:function(){this.$element.removeClass("redactor-animated"),this.$element.removeClass(this.opts.prefix+this.queue[0]),this.set("","","","")},complete:function(t,e,i){this.$element.one(t.toLowerCase()+" webkit"+t+" o"+t+" MS"+t,s.proxy(function(){"function"==typeof e&&e(),"function"==typeof i&&i(this);-1!==s.inArray(this.animation,["fadeOut","slideUp","zoomOut","slideOutUp","slideOutRight","slideOutLeft"])&&this.$element.css("display","none"),this.slide&&this.$element.css("height","")},this))}}}(jQuery); })(this);
 
 // plugins/WoltLabArticle.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabArticle=function(){"use strict";return{init:function(){var t=this.button.add("woltlabArticle","");require(["WoltLabSuite/Core/Ui/Redactor/Article"],function(i){new i(this,t[0])}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabArticle=function(){"use strict";return{init:function(){var i=this.button.add("woltlabArticle","");require(["WoltLabSuite/Core/Ui/Redactor/Article"],function(t){new t(this,i[0])}.bind(this))}}}; })(this);
 
 // plugins/WoltLabAttachment.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabAttachment=function(){"use strict";return{init:function(){this.opts.woltlab.attachments&&require(["EventHandler"],function(t){t.add("com.woltlab.wcf.redactor2","insertAttachment_"+this.$element[0].id,this.WoltLabAttachment._insert.bind(this)),t.add("com.woltlab.wcf.redactor2","deleteAttachment_"+this.$element[0].id,this.WoltLabAttachment._delete.bind(this)),t.add("com.woltlab.wcf.redactor2","replaceAttachment_"+this.$element[0].id,this.WoltLabAttachment._replaceAttachment.bind(this))}.bind(this))},_insert:function(t){if(!this.WoltLabSource.isActive()){var e=t.attachmentId;if(this.buffer.set(),t.url){var a="wcfImgAttachment"+this.uuid,n=elById(a);n&&n.removeAttribute("id"),this.insert.html('<img src="'+t.url+'" class="woltlabAttachment" data-attachment-id="'+e+'" id="'+a+'">'),n=elById(a);for(var i=!0,r=n;r=r.nextSibling;)if(r.nodeType!==Node.TEXT_NODE||""!==r.textContent.replace(/\u200B/g,"").trim()){i=!1;break}i?this.caret.after(n.parentNode):window.setTimeout(function(){var t=elById(a);if(t){t.removeAttribute("id");var e=t.nextSibling;e&&e.nodeType===Node.TEXT_NODE&&"​"===e.textContent||(e=document.createTextNode("​"),t.parentNode.insertBefore(e,t.nextSibling));var n=document.createRange();n.selectNode(e),n.collapse(!1);var i=window.getSelection();i.removeAllRanges(),i.addRange(n)}}.bind(this),10)}else this.insert.text("[attach="+e+"][/attach]");this.buffer.set()}},_replaceAttachment:function(t){var e=elCreate("img");e.className="woltlabAttachment",e.src=t.src,elData(e,"attachment-id",t.attachmentId),t.img.parentNode.insertBefore(e,t.img),elRemove(t.img)},_delete:function(t){var e=t.attachmentId,a=this.core.editor()[0];elBySelAll('.woltlabAttachment[data-attachment-id="'+e+'"]',a,function(t){elRemove(t)});var n="[attach="+e+"][/attach]";if(!1!==a.textContent.indexOf(n)){for(var i,r=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,null,!1),c=[];i=r.nextNode();)-1!==i.textContent.indexOf(n)&&c.push(i);for(var o=0,l=c.length;o<l;o++)c[o].textContent=c[o].textContent.replace(new RegExp("\\[attach="+e+"\\]\\[\\/attach\\]","g"),"")}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabAttachment=function(){"use strict";return{init:function(){this.opts.woltlab.attachments&&require(["EventHandler"],function(t){t.add("com.woltlab.wcf.redactor2","insertAttachment_"+this.$element[0].id,this.WoltLabAttachment._insert.bind(this)),t.add("com.woltlab.wcf.redactor2","deleteAttachment_"+this.$element[0].id,this.WoltLabAttachment._delete.bind(this)),t.add("com.woltlab.wcf.redactor2","replaceAttachment_"+this.$element[0].id,this.WoltLabAttachment._replaceAttachment.bind(this))}.bind(this))},_insert:function(t){if(!this.WoltLabSource.isActive()){var e=t.attachmentId;if(this.buffer.set(),t.url){var i="wcfImgAttachment"+this.uuid,a=elById(i);a&&a.removeAttribute("id"),this.insert.html('<img src="'+t.url+'" class="woltlabAttachment" data-attachment-id="'+e+'" id="'+i+'">');for(var n=!0,c=a=elById(i);c=c.nextSibling;)if(c.nodeType!==Node.TEXT_NODE||""!==c.textContent.replace(/\u200B/g,"").trim()){n=!1;break}n?this.caret.after(a.parentNode):window.setTimeout(function(){var t,e,a,n=elById(i);n&&(n.removeAttribute("id"),(t=n.nextSibling)&&t.nodeType===Node.TEXT_NODE&&"​"===t.textContent||(t=document.createTextNode("​"),n.parentNode.insertBefore(t,n.nextSibling)),(e=document.createRange()).selectNode(t),e.collapse(!1),(a=window.getSelection()).removeAllRanges(),a.addRange(e))}.bind(this),10)}else this.insert.text("[attach="+e+"][/attach]");this.buffer.set()}},_replaceAttachment:function(t){var e=elCreate("img");e.className="woltlabAttachment",e.src=t.src,elData(e,"attachment-id",t.attachmentId),t.img.parentNode.insertBefore(e,t.img),elRemove(t.img)},_delete:function(t){var e=t.attachmentId,a=this.core.editor()[0];elBySelAll('.woltlabAttachment[data-attachment-id="'+e+'"]',a,function(t){elRemove(t)});var n="[attach="+e+"][/attach]";if(!1!==a.textContent.indexOf(n)){for(var i,c=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,null,!1),r=[];i=c.nextNode();)-1!==i.textContent.indexOf(n)&&r.push(i);for(var o=0,l=r.length;o<l;o++)r[o].textContent=r[o].textContent.replace(new RegExp("\\[attach="+e+"\\]\\[\\/attach\\]","g"),"")}}}}; })(this);
 
 // plugins/WoltLabAutosave.js
 (function (window, undefined) { $.Redactor.prototype.WoltLabAutosave=function(){"use strict";return{init:function(){this.opts.woltlab.autosave&&(this.opts.woltlab.autosave.watch(this),this.opts.woltlab.autosave.createOverlay(),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","autosaveDestroy_"+this.$element[0].id,this.WoltLabAutosave.destroy.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","autosaveReset_"+this.$element[0].id,this.WoltLabAutosave.reset.bind(this)))},destroy:function(){this.opts.woltlab.autosave&&this.opts.woltlab.autosave.destroy()},reset:function(){this.opts.woltlab.autosave&&this.opts.woltlab.autosave.clear()}}}; })(this);
 
 // plugins/WoltLabBlock.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabBlock=function(){"use strict";return{preserveBlocks:["pre","woltlab-quote","woltlab-spoiler"],init:function(){this.block.tags=["p","blockquote","pre","h1","h2","h3","h4","h5","h6","div","figure"],this.block.format=function(e,t,o,i){if(e="quote"===e?"blockquote":e,-1!==$.inArray(e,this.block.tags))return"p"===e&&void 0===t&&(t="class"),this.placeholder.hide(),this.buffer.set(),this.utils.isCollapsed()?this.block.formatCollapsed(e,t,o,i):this.block.formatUncollapsed(e,t,o,i)}.bind(this);var e=function(e,t){return!(document.activeElement!==e||!1===t||!this.utils.isRedactorParent(t))}.bind(this),t=this.block.formatCollapsed;this.block.formatCollapsed=function(o,i,s,r){var l=this.selection.block();if(!l||"LI"!==l.nodeName&&"TD"!==l.nodeName){var a=this.core.editor()[0];e(a,l)||(this.selection.restore(),document.activeElement!==a&&a.focus()),e(a,l)||(this.focus.end(),this.selection.save());var n=t.call(this,o,i,s,r),h=n.length;if(1===h&&n[0].nodeName.match(/^H[1-6]$/)){var c=n[0];1===c.childElementCount&&"BR"===c.children[0].nodeName&&this.utils.isEmpty(c.innerHTML)&&(c.innerHTML="​")}else for(var d=0;d<h;d++)this.WoltLabBlock._paragraphize(n[d]);return this.caret.end(n),n}}.bind(this),this.block.formatUncollapsed=function(e,t,o,i){var s,r;this.selection.save(),this.selection.blocks().forEach(function(e){if("OL"===e.nodeName||"UL"===e.nodeName){e.parentNode.nodeName.toLowerCase();var t=elCreate("div");e.parentNode.insertBefore(t,e),t.appendChild(e)}}),this.selection.restore(),this.selection.save();var l=[],a=this.selection.blocks();a[0]&&($(a[0]).hasClass("redactor-in")||$(a[0]).hasClass("redactor-box"))&&(a=this.core.editor().find(this.opts.blockTags.join(", ")));var n=a.length;for(r=0;r<n;r++){var h=a[r].tagName.toLowerCase();if(-1!==$.inArray(h,this.block.tags)&&"figure"!==h){if("pre"!==e&&-1!==this.WoltLabBlock.preserveBlocks.indexOf(a[r].nodeName.toLowerCase())?(s=elCreate(e),a[r].parentNode.insertBefore(s,a[r]),s.appendChild(a[r]),s=$(s)):s=this.utils.replaceToTag(a[r],e),"object"==typeof t){i=o;for(var c in t)s=this.block.setAttr(s,c,t[c],i)}else s=this.block.setAttr(s,t,o,i);l.push(s),this.block.removeInlineTags(s)}}if(this.selection.restore(),"pre"===e&&0!==l.length){var d=l[0];$.each(l,function(e,t){0!==e&&($(d).append("\n"+$.trim(t.html())),$(t).remove())}),l=[],l.push(d)}var p,f=null;for(r=0,p=l.length;r<p;r++)if(s=l[r][0]||l[r],this.WoltLabBlock._paragraphize(s),0===r)f=s;else{for(;s.childNodes.length;)f.appendChild(s.childNodes[0]);elRemove(s)}return f&&elBySelAll("br",f,function(e){e.parentNode.insertBefore(document.createTextNode("\n"),e),elRemove(e)}),$(f)}.bind(this),this.block.removeAllAttr=function(e){e=this.block.getBlocks(e);var t=[];return $.each(e,function(e,o){for(void 0===o.attributes&&t.push(o);o.attributes.length;)o.removeAttribute(o.attributes[0].name);t.push(o)}),t}.bind(this),this.block.getBlocks=function(e){if(e=void 0===e?this.selection.blocks():e,$(e).hasClass("redactor-box")||$(e).hasClass("redactor-layer")){var t=[],o=this.core.editor().children();return $.each(o,$.proxy(function(e,o){this.utils.isBlock(o)&&t.push(o)},this)),t}return e}.bind(this)},register:function(e,t){-1===this.block.tags.indexOf(e)&&(this.block.tags.push(e),this.opts.paragraphizeBlocks.push(e),-1===this.opts.blockTags.indexOf(e)&&(this.opts.blockTags.push(e),this.reIsBlock=new RegExp("^("+this.opts.blockTags.join("|").toUpperCase()+")$","i")),t&&this.WoltLabKeydown.register(e))},_paragraphize:function(e){if(-1===["p","pre","h1","h2","h3","h4","h5","h6","div","figure"].indexOf(e.nodeName.toLowerCase())){for(var t,o=!1,i=0,s=e.childNodes.length;i<s;i++){if(t=e.childNodes[i],t.nodeType===Node.TEXT_NODE){o=!0;break}if(t.nodeType===Node.ELEMENT_NODE&&-1===this.block.tags.indexOf(t.nodeName.toLowerCase())){o=!0;break}}if(o)for(var r,l=e.childNodes[0],a=null;l;)r=l.nextSibling,l.nodeType!==Node.ELEMENT_NODE||-1===this.block.tags.indexOf(l.nodeName.toLowerCase())?(null===a&&(a=elCreate("p"),e.insertBefore(a,l)),a.appendChild(l)):null!==a&&(a=null),l=r}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabBlock=function(){"use strict";return{preserveBlocks:["pre","woltlab-quote","woltlab-spoiler"],init:function(){this.block.tags=["p","blockquote","pre","h1","h2","h3","h4","h5","h6","div","figure"],this.block.format=function(e,t,o,i){if(e="quote"===e?"blockquote":e,-1!==$.inArray(e,this.block.tags))return"p"===e&&void 0===t&&(t="class"),this.placeholder.hide(),this.buffer.set(),this.utils.isCollapsed()?this.block.formatCollapsed(e,t,o,i):this.block.formatUncollapsed(e,t,o,i)}.bind(this);var c=function(e,t){return!(document.activeElement!==e||!1===t||!this.utils.isRedactorParent(t))}.bind(this),d=this.block.formatCollapsed;this.block.formatCollapsed=function(e,t,o,i){var s=this.selection.block();if(!s||"LI"!==s.nodeName&&"TD"!==s.nodeName){var r=this.core.editor()[0];c(r,s)||(this.selection.restore(),document.activeElement!==r&&r.focus()),c(r,s)||(this.focus.end(),this.selection.save());var l=d.call(this,e,t,o,i),n=l.length;if(1===n&&l[0].nodeName.match(/^H[1-6]$/)){var a=l[0];1===a.childElementCount&&"BR"===a.children[0].nodeName&&this.utils.isEmpty(a.innerHTML)&&(a.innerHTML="​")}else for(var h=0;h<n;h++)this.WoltLabBlock._paragraphize(l[h]);return this.caret.end(l),l}}.bind(this),this.block.formatUncollapsed=function(e,t,o,i){var s;this.selection.save(),this.selection.blocks().forEach(function(e){var t;"OL"!==e.nodeName&&"UL"!==e.nodeName||(e.parentNode.nodeName.toLowerCase(),t=elCreate("div"),e.parentNode.insertBefore(t,e),t.appendChild(e))}),this.selection.restore(),this.selection.save();var r=[],l=this.selection.blocks();l[0]&&($(l[0]).hasClass("redactor-in")||$(l[0]).hasClass("redactor-box"))&&(l=this.core.editor().find(this.opts.blockTags.join(", ")));for(var n,a=l.length,h=0;h<a;h++){var c=l[h].tagName.toLowerCase();if(-1!==$.inArray(c,this.block.tags)&&"figure"!==c){if(s="pre"!==e&&-1!==this.WoltLabBlock.preserveBlocks.indexOf(l[h].nodeName.toLowerCase())?(s=elCreate(e),l[h].parentNode.insertBefore(s,l[h]),s.appendChild(l[h]),$(s)):this.utils.replaceToTag(l[h],e),"object"==typeof t)for(var d in i=o,t)s=this.block.setAttr(s,d,t[d],i);else s=this.block.setAttr(s,t,o,i);r.push(s),this.block.removeInlineTags(s)}}this.selection.restore(),"pre"===e&&0!==r.length&&(n=r[0],$.each(r,function(e,t){0!==e&&($(n).append("\n"+$.trim(t.html())),$(t).remove())}),(r=[]).push(n));var p,f=null;for(h=0,p=r.length;h<p;h++)if(s=r[h][0]||r[h],this.WoltLabBlock._paragraphize(s),0===h)f=s;else{for(;s.childNodes.length;)f.appendChild(s.childNodes[0]);elRemove(s)}return f&&elBySelAll("br",f,function(e){e.parentNode.insertBefore(document.createTextNode("\n"),e),elRemove(e)}),$(f)}.bind(this),this.block.removeAllAttr=function(e){e=this.block.getBlocks(e);var o=[];return $.each(e,function(e,t){for(void 0===t.attributes&&o.push(t);t.attributes.length;)t.removeAttribute(t.attributes[0].name);o.push(t)}),o}.bind(this),this.block.getBlocks=function(e){if(e=void 0===e?this.selection.blocks():e,$(e).hasClass("redactor-box")||$(e).hasClass("redactor-layer")){var o=[],t=this.core.editor().children();return $.each(t,$.proxy(function(e,t){this.utils.isBlock(t)&&o.push(t)},this)),o}return e}.bind(this)},register:function(e,t){-1===this.block.tags.indexOf(e)&&(this.block.tags.push(e),this.opts.paragraphizeBlocks.push(e),-1===this.opts.blockTags.indexOf(e)&&(this.opts.blockTags.push(e),this.reIsBlock=new RegExp("^("+this.opts.blockTags.join("|").toUpperCase()+")$","i")),t&&this.WoltLabKeydown.register(e))},_paragraphize:function(e){if(-1===["p","pre","h1","h2","h3","h4","h5","h6","div","figure"].indexOf(e.nodeName.toLowerCase())){for(var t,o=!1,i=0,s=e.childNodes.length;i<s;i++){if((t=e.childNodes[i]).nodeType===Node.TEXT_NODE){o=!0;break}if(t.nodeType===Node.ELEMENT_NODE&&-1===this.block.tags.indexOf(t.nodeName.toLowerCase())){o=!0;break}}if(o)for(var r,l=e.childNodes[0],n=null;l;)r=l.nextSibling,l.nodeType!==Node.ELEMENT_NODE||-1===this.block.tags.indexOf(l.nodeName.toLowerCase())?(null===n&&(n=elCreate("p"),e.insertBefore(n,l)),n.appendChild(l)):null!==n&&(n=null),l=r}}}}; })(this);
 
 // plugins/WoltLabButton.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabButton=function(){"use strict";var t;return{init:function(){var t,e,o,n;for(o=0,n=this.opts.woltlab.customButtons.length;o<n;o++)e=this.opts.woltlab.customButtons[o],t=this.button.add(e,""),this.button.addCallback(t,this.WoltLabButton._handleCustomButton);var s,i,a,r=this.core.toolbar()[0];for(o=0,n=this.opts.buttons.length;o<n;o++)if("wcfSeparator"!==(e=this.opts.buttons[o])){if(!this.opts.woltlab.buttons.hasOwnProperty(e))throw new Error("Missing button definition for '"+e+"'.");switch(s=this.opts.woltlab.buttons[e],"underline"===e&&(this.opts.activeButtonsStates.u="underline"),e){case"subscript":case"superscript":t=this.button.addAfter(this.opts.buttons[o-1],e,""),this.button.setEvent(t,e,{func:"inline.format"}),this.opts.activeButtonsStates["subscript"===e?"sub":"sup"]=e;break;case"redo":case"undo":t=this.button.addAfter(this.opts.buttons[o-1],e,""),this.button.addCallback(t,this.buffer[e]);break;default:t=this.button.get(e)}if(i=s.icon,a=!i.match(/^fa-/)&&i.match(/\.(gif|jpe?g|png|svg)$/),this.button.setIcon(t,'<span class="icon icon16 '+(a?"redactorButtonImage":i)+'"'+(a?" style=\"background-image: url('"+WCF_PATH+"icon/"+i+"')\"":"")+"></span>"),!t[0])throw new Error("Missing button element for '"+e+"'.");if(t[0].title=s.title,t[0].classList.add("jsTooltip"),"lists"===e){var l=t.data("dropdown");elBySel(".redactor-dropdown-outdent span",l[0]).textContent=WCF.Language.get("wcf.editor.list.outdent"),elBySel(".redactor-dropdown-indent span",l[0]).textContent=WCF.Language.get("wcf.editor.list.indent")}}for(var d,c={},u=[];r.childElementCount;)d=r.removeChild(r.children[0]),e=elAttr(d.children[0],"rel"),c[e]=d,u.push(e);var h=!1;for(o=0,n=this.opts.buttons.length;o<n;o++)e=this.opts.buttons[o],"wcfSeparator"!==e?(d=c[e],r.appendChild(d),u.splice(u.indexOf(e),1),h&&(d.classList.add("redactor-toolbar-separator"),h=!1)):h=!0;for(o=0,n=r.childElementCount;o<n;o++)d=r.children[o],t=d.children[0],elData(d,"show-on-mobile",-1!==this.opts.woltlab.buttonMobile.indexOf(t.rel));u.forEach(function(t){r.appendChild(c[t])}),WCF.DOMNodeInsertedHandler.execute(),require(["Ui/Screen"],function(t){t.on("screen-xs",{match:this.WoltLabButton._enableToggleButton.bind(this),unmatch:this.WoltLabButton._disableToggleButton.bind(this),setup:this.WoltLabButton._setupToggleButton.bind(this)})}.bind(this)),r.addEventListener("dragstart",function(t){t.preventDefault()}),elAttr(elBySel(".re-html",r),"tabindex",0)},_handleCustomButton:function(t){var e={cancel:!1};if(WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","bbcode_"+t+"_"+this.$element[0].id,e),!0!==e.cancel){this.buffer.set();var o=this.marker.get();o.classList.add("woltlab-bbcode-marker");var n="["+t+"]"+this.selection.html()+o.outerHTML+"[/"+t+"]";this.insert.html(n),this.selection.restore()}window.setTimeout(function(){document.activeElement!==this.$editor[0]&&this.$editor[0].focus()}.bind(this),10)},_enableToggleButton:function(){null===t.parentNode&&this.$toolbar[0].appendChild(t)},_disableToggleButton:function(){t&&null!==t.parentNode&&this.$toolbar[0].removeChild(t)},_setupToggleButton:function(){t=elCreate("li"),t.className="redactorToolbarToggle",t.innerHTML='<a href="#"><span class="icon icon16 fa-caret-down"></span></a>',elData(t,"show-on-mobile",!0);var e=t.children[0].children[0],o=function(t){t instanceof Event&&t.preventDefault(),this.$toolbar[0].classList.toggle("redactorToolbarOverride")&&document.activeElement&&document.activeElement!==this.$editor[0]&&document.activeElement.blur(),e.classList.toggle("fa-caret-down"),e.classList.toggle("fa-caret-up")}.bind(this);t.children[0].addEventListener("mousedown",o),this.$toolbar[0].appendChild(t),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+this.$element[0].id,function(){this.$toolbar[0].classList.contains("redactorToolbarOverride")&&o()}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabButton=function(){"use strict";var o;return{init:function(){for(var t,e,o=0,n=this.opts.woltlab.customButtons.length;o<n;o++)e=this.opts.woltlab.customButtons[o],t=this.button.add(e,""),this.button.addCallback(t,this.WoltLabButton._handleCustomButton);var s,i,a,r,l=this.core.toolbar()[0];for(o=0,n=this.opts.buttons.length;o<n;o++)if("wcfSeparator"!==(e=this.opts.buttons[o])){if(!this.opts.woltlab.buttons.hasOwnProperty(e))throw new Error("Missing button definition for '"+e+"'.");switch(s=this.opts.woltlab.buttons[e],"underline"===e&&(this.opts.activeButtonsStates.u="underline"),e){case"subscript":case"superscript":t=this.button.addAfter(this.opts.buttons[o-1],e,""),this.button.setEvent(t,e,{func:"inline.format"}),this.opts.activeButtonsStates["subscript"===e?"sub":"sup"]=e;break;case"redo":case"undo":t=this.button.addAfter(this.opts.buttons[o-1],e,""),this.button.addCallback(t,this.buffer[e]);break;default:t=this.button.get(e)}if(a=!(i=s.icon).match(/^fa-/)&&i.match(/\.(gif|jpe?g|png|svg)$/),this.button.setIcon(t,'<span class="icon icon16 '+(a?"redactorButtonImage":i)+'"'+(a?" style=\"background-image: url('"+WCF_PATH+"icon/"+i+"')\"":"")+"></span>"),!t[0])throw new Error("Missing button element for '"+e+"'.");t[0].title=s.title,t[0].classList.add("jsTooltip"),"lists"===e&&(r=t.data("dropdown"),elBySel(".redactor-dropdown-outdent span",r[0]).textContent=WCF.Language.get("wcf.editor.list.outdent"),elBySel(".redactor-dropdown-indent span",r[0]).textContent=WCF.Language.get("wcf.editor.list.indent"))}var d=this.opts.buttons.indexOf("tt");-1!==this.opts.buttons.indexOf("code")&&-1!==d&&(this.opts.buttons.splice(d,1),this.opts.buttons.splice(this.opts.buttons.indexOf("code")+1,0,"tt"));for(var c,u={},h=[];l.childElementCount;)c=l.removeChild(l.children[0]),e=elAttr(c.children[0],"rel"),u[e]=c,h.push(e);var b=!1;for(o=0,n=this.opts.buttons.length;o<n;o++)"wcfSeparator"!==(e=this.opts.buttons[o])?(c=u[e],l.appendChild(c),h.splice(h.indexOf(e),1),b&&(c.classList.add("redactor-toolbar-separator"),b=!1)):b=!0;for(o=0,n=l.childElementCount;o<n;o++)t=(c=l.children[o]).children[0],elData(c,"show-on-mobile",-1!==this.opts.woltlab.buttonMobile.indexOf(t.rel));h.forEach(function(t){l.appendChild(u[t])}),WCF.DOMNodeInsertedHandler.execute(),require(["Ui/Screen"],function(t){t.on("screen-xs",{match:this.WoltLabButton._enableToggleButton.bind(this),unmatch:this.WoltLabButton._disableToggleButton.bind(this),setup:this.WoltLabButton._setupToggleButton.bind(this)})}.bind(this)),l.addEventListener("dragstart",function(t){t.preventDefault()}),elAttr(elBySel(".re-html",l),"tabindex",0)},_handleCustomButton:function(t){var e,o,n={cancel:!1};WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","bbcode_"+t+"_"+this.$element[0].id,n),!0!==n.cancel&&(this.buffer.set(),(e=this.marker.get()).classList.add("woltlab-bbcode-marker"),o="["+t+"]"+this.selection.html()+e.outerHTML+"[/"+t+"]",this.insert.html(o),this.selection.restore()),window.setTimeout(function(){document.activeElement!==this.$editor[0]&&this.$editor[0].focus()}.bind(this),10)},_enableToggleButton:function(){null===o.parentNode&&this.$toolbar[0].appendChild(o)},_disableToggleButton:function(){o&&null!==o.parentNode&&this.$toolbar[0].removeChild(o)},_setupToggleButton:function(){(o=elCreate("li")).className="redactorToolbarToggle",o.innerHTML='<a href="#"><span class="icon icon16 fa-caret-down"></span></a>',elData(o,"show-on-mobile",!0);var e=o.children[0].children[0],t=function(t){t instanceof Event&&t.preventDefault(),this.$toolbar[0].classList.toggle("redactorToolbarOverride")&&document.activeElement&&document.activeElement!==this.$editor[0]&&document.activeElement.blur(),e.classList.toggle("fa-caret-down"),e.classList.toggle("fa-caret-up")}.bind(this);o.children[0].addEventListener("mousedown",t),this.$toolbar[0].appendChild(o),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+this.$element[0].id,function(){this.$toolbar[0].classList.contains("redactorToolbarOverride")&&t()}.bind(this))}}}; })(this);
 
 // plugins/WoltLabCaret.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabCaret=function(){"use strict";var e,t=!1,n=!1;return{init:function(){var i=this.caret.after;this.caret.after=function(e){e=this.caret.prepare(e),this.utils.isBlockTag(e.tagName)&&this.WoltLabCaret._addParagraphAfterBlock(e),i.call(this,e)}.bind(this);var r=this.caret.start;this.caret.start=function(e){if(n){if(!(e=this.caret.prepare(e)))return;"P"===e.nodeName&&"​"===e.innerHTML&&(e.innerHTML="<br>")}r.call(this,e)}.bind(this);var o=this.core.editor()[0];require(["Environment"],function(i){t="ios"===i.platform(),(n="safari"===i.browser())&&o.classList.add("jsSafariMarginClickTarget");var r=this.WoltLabCaret._handleEditorClick.bind(this),a=this.WoltLabCaret._handleEditorMouseUp.bind(this);n&&t?(o.addEventListener("touchstart",function(t){e=t.target},{passive:!0}),o.addEventListener("touchend",function(e){r(e),a(e)}.bind(this))):(o.addEventListener(WCF_CLICK_EVENT,function(e){this.WoltLabCaret._detectTripleClick(e),r(e)}.bind(this)),o.addEventListener("mouseup",a))}.bind(this));var a=this.caret.end;this.caret.end=function(e){e=this.caret.prepare(e),"OL"!==e.nodeName&&"UL"!==e.nodeName||null===(e=e.lastElementChild)&&(e=e.parentNode);var n=!1;if(e.nodeType===Node.ELEMENT_NODE&&e.lastChild&&"P"===e.lastChild.nodeName)n=!0;else if(t){var i=this.core.editor()[0];e.parentNode===i&&"<p><br></p>"===i.innerHTML&&(n=!0)}else"P"===e.nodeName&&0===e.childNodes.length&&(e.innerHTML="​",n=!0);if(n){var r=window.getSelection(),o=document.createRange();return o.selectNodeContents(e.lastChild),o.collapse(!1),r.removeAllRanges(),void r.addRange(o)}return"P"===e.nodeName&&1===e.childNodes.length&&"BR"===e.childNodes[0].nodeName?this.caret.before(e.childNodes[0]):a.call(this,e)}.bind(this);var s=this.selection.nodes;this.selection.nodes=function(e){var t=s.call(this,e);if(1===t.length&&t[0]===this.$editor[0]){var n=this.selection.range(this.selection.get());if(n.startContainer===n.endContainer)return[n.startContainer]}return t}.bind(this),this.WoltLabCaret._initInternalRange();var l=this.selection.saveInstant;this.selection.saveInstant=function(){var e=l.call(this);if(e){e.isAtNodeStart=!1;var t=window.getSelection();if(t.rangeCount&&!t.isCollapsed){var n=t.getRangeAt(0);n.startContainer.nodeType===Node.TEXT_NODE&&0===n.startOffset&&(e.isAtNodeStart=!0)}}return e}.bind(this);var d=this.selection.restoreInstant;this.selection.restoreInstant=function(e){if(void 0!==e||this.saved){var t=void 0!==e?e:this.saved;d.call(this,e);var n=window.getSelection();if(n.rangeCount)if(!0===t.isAtNodeStart){if(!n.isCollapsed){var i=n.getRangeAt(0),r=i.startContainer;if(t.node===r)return;for(;null!==r&&"P"!==r.nodeName;)r=r.parentNode;if(null!==r&&null!==(r=r.nextElementSibling)&&"P"===r.nodeName&&0===r.textContent.replace(/\u200B/g,"").length){r=r.nextElementSibling;for(var o=t.node;null!==o&&o!==r;)o=o.parentNode;o===r&&(i=i.cloneRange(),i.setStart(t.node,0),n.removeAllRanges(),n.addRange(i))}}}else if(n.isCollapsed){var a=n.anchorNode,s=this.core.editor()[0];if(a.nodeType===Node.TEXT_NODE&&a.parentNode===s&&n.anchorOffset===a.textContent.length){var l=a.nextElementSibling;l&&"P"===l.nodeName&&this.caret.start(l)}}}}.bind(this),this.selection.nodes=function(e){var t=void 0===e?[]:$.isArray(e)?e:[e],n=this.selection.get(),i=this.selection.range(n),r=[],o=[];if(this.utils.isCollapsed())r=[this.selection.current()];else{var a=i.startContainer,s=i.endContainer;if(a===s)return[a];for(var l=i.commonAncestorContainer;a&&a!==s;)r.push(a=this.selection.nextNode(a,l));for(a=i.startContainer;a&&a!==l;)r.unshift(a),a=a.parentNode}return $.each(r,function(e,n){if(n){var i=1===n.nodeType&&n.tagName.toLowerCase();if($(n).hasClass("redactor-script-tag")||$(n).hasClass("redactor-selection-marker"))return;if(i&&0!==t.length&&-1===$.inArray(i,t))return;o.push(n)}}),0===o.length?[]:o}.bind(this),this.selection.nextNode=function(e,t){if(e.hasChildNodes())return e.firstChild;for(;e&&!e.nextSibling;)if(e=e.parentNode,t&&e===t)return null;return e?e.nextSibling:null}},paragraphAfterBlock:function(e){var t=e.nextElementSibling;t&&"P"!==t.nodeName&&(t=elCreate("p"),"<p><br></p>"===this.opts.emptyHtml?t.innerHTML="<br>":t.textContent="​",e.parentNode.insertBefore(t,e.nextSibling)),this.caret.after(e)},endOfEditor:function(){var e=this.core.editor()[0];document.activeElement!==e&&e.focus();var t=e.lastElementChild;"P"===t.nodeName?this.caret.end(t):this.caret.after(t)},_initInternalRange:function(){var e=this.core.editor()[0],t=null,n=window.getSelection(),i=function(){t=n.rangeCount?n.getRangeAt(0).cloneRange():null};this.WoltLabCaret.forceSelectionSave=i;var r=function(){if(null!==t){if(document.activeElement===e){var i=n.getRangeAt(0);if(0!==i.startOffset)return;for(var r=i.startContainer;r;){if(r.parentNode===e){if(r.previousSibling)return;break}if(r.previousSibling)return;r=r.parentNode}if(!r)return}var o=e.scrollLeft,a=e.scrollTop;e.focus(),e.scrollLeft=o,e.scrollTop=a,n.removeAllRanges(),n.addRange(t),t=null}};e.addEventListener("keyup",i),e.addEventListener("mouseup",function(){n.rangeCount&&i()});var o=this.selection.save;this.selection.save=function(){t=null,o.call(this)}.bind(this);var a=this.selection.restore;this.selection.restore=function(){t&&null===elBySel(".redactor-selection-marker",this.$editor[0])&&(r(),n.rangeCount&&this.utils.isRedactorParent(n.getRangeAt(0).commonAncestorContainer))||a.call(this)}.bind(this);var s=this.buffer.set;this.buffer.set=function(t){if(document.activeElement!==e){var n=window.getSelection();n.rangeCount&&!1!==this.utils.isRedactorParent(n.anchorNode)?e.focus():r()}s.call(this,t),i()}.bind(this);var l=this.insert.html;this.insert.html=function(e,t){var n=elBySel(".redactor-selection-marker",this.$editor[0]);l.call(this,e,t),(n||null===elBySel(".redactor-selection-marker",this.$editor[0]))&&i()}.bind(this),require(["Environment"],function(t){"ios"===t.platform()&&(e.addEventListener("focus",function(){document.addEventListener("selectionchange",i)}),e.addEventListener("blur",function(){document.removeEventListener("selectionchange",i)}))}.bind(this))},_detectTripleClick:function(e){if(!(e.detail<3)){var t=window.getSelection();if(!t.isCollapsed){var n=t.getRangeAt(0);if("TR"===n.commonAncestorContainer.nodeName){var i=elClosest(n.startContainer,"td");n=document.createRange(),n.selectNodeContents(i),t.removeAllRanges(),t.addRange(n)}}}},_handleEditorClick:function(i){var r=i.clientY;if(!this.selection.get().isCollapsed){if(!(n&&t&&e===i.target&&this.utils.isBlockTag(e.nodeName)))return;r=i.changedTouches[0].clientY}var o=this.selection.block();if(!1===o){if(this.selection.current()===this.$editor[0]){var a=this.$editor[0].childNodes[this.selection.get().anchorOffset];a.nodeType===Node.ELEMENT_NODE&&"TABLE"===a.nodeName&&(o=a)}if(!1===o)return}var s=!1;n&&this.utils.isBlockTag(i.target.nodeName)&&r>i.target.getBoundingClientRect().bottom&&(o=i.target,s=!0);for(var l=i.target;l&&!this.utils.isBlockTag(l.nodeName);)l=l.parentNode;if(l&&(s||l!==o)&&("P"!==o.nodeName||(o=o.parentNode)!==this.$editor[0]&&this.utils.isBlockTag(o.nodeName))){if("TD"===o.nodeName)for(;"TABLE"!==o.nodeName;)o=o.parentNode;if(!o.nodeName.match(/^H\d$/)&&!$(o).closest("ol, ul",this.$editor[0]).length){for(var d,c,h=o;h;){if(c=h.getBoundingClientRect(),r<c.top)d=!0,o=h;else{if(!(r>c.bottom))break;d=!1,o=h}if(!h.parentNode||h.parentNode===this.$editor[0])break;h=h.parentNode}if(void 0!==d){var f=o[(d?"previous":"next")+"ElementSibling"];if(f&&"P"===f.nodeName)return void this.caret.end(f);this.buffer.set();var u=elCreate("p");u.textContent="​",o.parentNode.insertBefore(u,d?o:o.nextSibling),this.caret.end(u)}}}},_handleEditorMouseUp:function(i){var r,o,a=window.getSelection();if(a.isCollapsed||n&&t&&e===i.target&&this.utils.isBlockTag(e.nodeName))if(i.target===this.$editor[0])r=a.anchorNode,r.nodeType===Node.TEXT_NODE&&(r=r.parentNode),"KBD"===r.nodeName&&(o=r.previousSibling,null!==o&&"​"===o.textContent||(o=document.createTextNode("​"),r.parentNode.insertBefore(o,r)),this.caret.before(o));else if("KBD"===i.target.nodeName){var s=i.target;if(r=a.anchorNode,r.nodeType===Node.TEXT_NODE){for(o=r;(o=o.nextSibling)&&o.nodeType===Node.TEXT_NODE&&(""===o.textContent||"​"===o.textContent););if(o===s){if(0===s.childNodes.length||"​"!==s.childNodes[0].textContent){var l=document.createTextNode("​");s.insertBefore(l,s.firstChild)}var d=document.createRange();d.setStartAfter(s.childNodes[0]),d.setEndAfter(s.childNodes[0]),a.removeAllRanges(),a.addRange(d)}}}},_addParagraphAfterBlock:function(e){var t=e.nextElementSibling;t&&("P"===t.nodeName||this.utils.isBlockTag(t.nodeName))||(t=elCreate("p"),t.textContent="​",e.parentNode.insertBefore(t,e.nextSibling))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabCaret=function(){"use strict";var u,f=!1,g=!1;return{init:function(){var t=this.caret.after;this.caret.after=function(e){e=this.caret.prepare(e),this.utils.isBlockTag(e.tagName)&&this.WoltLabCaret._addParagraphAfterBlock(e),t.call(this,e)}.bind(this);var n=this.caret.start;this.caret.start=function(e){if(g){if(!(e=this.caret.prepare(e)))return;"P"===e.nodeName&&"​"===e.innerHTML&&(e.innerHTML="<br>")}n.call(this,e)}.bind(this);var i=this.core.editor()[0];require(["Environment"],function(e){f="ios"===e.platform(),(g="safari"===e.browser())&&i.classList.add("jsSafariMarginClickTarget");var t=this.WoltLabCaret._handleEditorClick.bind(this),n=this.WoltLabCaret._handleEditorMouseUp.bind(this);g&&f?(i.addEventListener("touchstart",function(e){u=e.target},{passive:!0}),i.addEventListener("touchend",function(e){t(e),n(e)}.bind(this))):(i.addEventListener(WCF_CLICK_EVENT,function(e){this.WoltLabCaret._detectTripleClick(e),t(e)}.bind(this)),i.addEventListener("mouseup",n))}.bind(this));var o=this.caret.end;this.caret.end=function(e){"OL"!==(e=this.caret.prepare(e)).nodeName&&"UL"!==e.nodeName||null===(e=e.lastElementChild)&&(e=e.parentNode);var t,n=!1;if(e.nodeType===Node.ELEMENT_NODE&&e.lastChild&&"P"===e.lastChild.nodeName?n=!0:f?(t=this.core.editor()[0],e.parentNode===t&&"<p><br></p>"===t.innerHTML&&(n=!0)):"P"===e.nodeName&&0===e.childNodes.length&&(e.innerHTML="​",n=!0),n){var i=window.getSelection(),r=document.createRange();return r.selectNodeContents(e.lastChild),r.collapse(!1),i.removeAllRanges(),void i.addRange(r)}return"P"===e.nodeName&&1===e.childNodes.length&&"BR"===e.childNodes[0].nodeName?this.caret.before(e.childNodes[0]):o.call(this,e)}.bind(this);var r=this.selection.nodes;this.selection.nodes=function(e){var t=r.call(this,e);if(1===t.length&&t[0]===this.$editor[0]){var n=this.selection.range(this.selection.get());if(n.startContainer===n.endContainer)return[n.startContainer]}return t}.bind(this),this.WoltLabCaret._initInternalRange();var a=this.selection.saveInstant;this.selection.saveInstant=function(){var e,t,n=a.call(this);return n&&(n.isAtNodeStart=!1,!(e=window.getSelection()).rangeCount||e.isCollapsed||(t=e.getRangeAt(0)).startContainer.nodeType===Node.TEXT_NODE&&0===t.startOffset&&(n.isAtNodeStart=!0)),n}.bind(this);var d=this.selection.restoreInstant;this.selection.restoreInstant=function(e){if(void 0!==e||this.saved){var t=void 0!==e?e:this.saved;d.call(this,e);var n,i,r,o=window.getSelection();if(o.rangeCount)if(!0===t.isAtNodeStart){if(!o.isCollapsed){var a=o.getRangeAt(0),s=a.startContainer;if(t.node===s)return;for(;null!==s&&"P"!==s.nodeName;)s=s.parentNode;if(null!==s&&null!==(s=s.nextElementSibling)&&"P"===s.nodeName&&0===s.textContent.replace(/\u200B/g,"").length){s=s.nextElementSibling;for(var l=t.node;null!==l&&l!==s;)l=l.parentNode;l===s&&((a=a.cloneRange()).setStart(t.node,0),o.removeAllRanges(),o.addRange(a))}}}else o.isCollapsed&&(n=o.anchorNode,i=this.core.editor()[0],n.nodeType!==Node.TEXT_NODE||n.parentNode!==i||o.anchorOffset!==n.textContent.length||(r=n.nextElementSibling)&&"P"===r.nodeName&&this.caret.start(r))}}.bind(this),this.selection.nodes=function(e){var i=void 0===e?[]:$.isArray(e)?e:[e],t=this.selection.get(),n=this.selection.range(t),r=[],o=[];if(this.utils.isCollapsed())r=[this.selection.current()];else{var a=n.startContainer,s=n.endContainer;if(a===s)return[a];for(var l=n.commonAncestorContainer;a&&a!==s;)r.push(a=this.selection.nextNode(a,l));for(a=n.startContainer;a&&a!==l;)r.unshift(a),a=a.parentNode}return $.each(r,function(e,t){if(t){var n=1===t.nodeType&&t.tagName.toLowerCase();if($(t).hasClass("redactor-script-tag")||$(t).hasClass("redactor-selection-marker"))return;if(n&&0!==i.length&&-1===$.inArray(n,i))return;o.push(t)}}),0===o.length?[]:o}.bind(this),this.selection.nextNode=function(e,t){if(e.hasChildNodes())return e.firstChild;for(;e&&!e.nextSibling;)if(e=e.parentNode,t&&e===t)return null;return e?e.nextSibling:null}},paragraphAfterBlock:function(e){var t=e.nextElementSibling;t&&"P"!==t.nodeName&&(t=elCreate("p"),"<p><br></p>"===this.opts.emptyHtml?t.innerHTML="<br>":t.textContent="​",e.parentNode.insertBefore(t,e.nextSibling)),this.caret.after(e)},endOfEditor:function(){var e=this.core.editor()[0];document.activeElement!==e&&e.focus();var t=e.lastElementChild;"P"===t.nodeName?this.caret.end(t):this.caret.after(t)},_initInternalRange:function(){function i(){o=a.rangeCount?a.getRangeAt(0).cloneRange():null}var r=this.core.editor()[0],o=null,a=window.getSelection();this.WoltLabCaret.forceSelectionSave=i;function n(){if(null!==o){if(document.activeElement===r){var e=a.getRangeAt(0);if(0!==e.startOffset)return;for(var t=e.startContainer;t;){if(t.parentNode===r){if(t.previousSibling)return;break}if(t.previousSibling)return;t=t.parentNode}if(!t)return}var n=r.scrollLeft,i=r.scrollTop;r.focus(),r.scrollLeft=n,r.scrollTop=i,a.removeAllRanges(),a.addRange(o),o=null}}r.addEventListener("keyup",i),r.addEventListener("mouseup",function(){a.rangeCount&&i()});var e=this.selection.save;this.selection.save=function(){o=null,e.call(this)}.bind(this);var t=this.selection.restore;this.selection.restore=function(){o&&null===elBySel(".redactor-selection-marker",this.$editor[0])&&(n(),a.rangeCount&&this.utils.isRedactorParent(a.getRangeAt(0).commonAncestorContainer))||t.call(this)}.bind(this);var s=this.buffer.set;this.buffer.set=function(e){var t;document.activeElement!==r&&((t=window.getSelection()).rangeCount&&!1!==this.utils.isRedactorParent(t.anchorNode)?r.focus():n()),s.call(this,e),i()}.bind(this);var l=this.insert.html;this.insert.html=function(e,t){var n=elBySel(".redactor-selection-marker",this.$editor[0]);l.call(this,e,t),!n&&null!==elBySel(".redactor-selection-marker",this.$editor[0])||i()}.bind(this),require(["Environment"],function(e){"ios"===e.platform()&&(r.addEventListener("focus",function(){document.addEventListener("selectionchange",i)}),r.addEventListener("blur",function(){document.removeEventListener("selectionchange",i)}))}.bind(this))},_detectTripleClick:function(e){var t,n,i;e.detail<3||((t=window.getSelection()).isCollapsed||"TR"===(i=t.getRangeAt(0)).commonAncestorContainer.nodeName&&(n=elClosest(i.startContainer,"td"),(i=document.createRange()).selectNodeContents(n),t.removeAllRanges(),t.addRange(i)))},_handleEditorClick:function(e){var t=e.clientY,n=f&&u===e.target&&this.utils.isBlockTag(u.nodeName);if(void 0===t&&n&&(t=e.changedTouches[0].clientY),this.selection.get().isCollapsed||n&&void 0!==t){var i,r=this.selection.block();if(!1===r)if(this.selection.current()!==this.$editor[0]||(i=this.$editor[0].childNodes[this.selection.get().anchorOffset]).nodeType===Node.ELEMENT_NODE&&"TABLE"===i.nodeName&&(r=i),!1===r)return;var o=!1;g&&this.utils.isBlockTag(e.target.nodeName)&&t>e.target.getBoundingClientRect().bottom&&(r=e.target,o=!0);for(var a=e.target;a&&!this.utils.isBlockTag(a.nodeName);)a=a.parentNode;if(a&&(o||a!==r)&&("P"!==r.nodeName||(r=r.parentNode)!==this.$editor[0]&&this.utils.isBlockTag(r.nodeName))){if("TD"===r.nodeName)for(;"TABLE"!==r.nodeName;)r=r.parentNode;if(!r.nodeName.match(/^H\d$/)&&!$(r).closest("ol, ul",this.$editor[0]).length){for(var s,l,d,c,h=r;h;){if(t<(l=h.getBoundingClientRect()).top)s=!0,r=h;else{if(!(t>l.bottom))break;s=!1,r=h}if(!h.parentNode||h.parentNode===this.$editor[0])break;h=h.parentNode}void 0!==s&&((d=r[(s?"previous":"next")+"ElementSibling"])&&"P"===d.nodeName?this.caret.end(d):(this.buffer.set(),(c=elCreate("p")).textContent="​",r.parentNode.insertBefore(c,s?r:r.nextSibling),this.caret.end(c)))}}}},_handleEditorMouseUp:function(e){var t,n=window.getSelection();if(n.isCollapsed||g&&f&&u===e.target&&this.utils.isBlockTag(u.nodeName))if(e.target===this.$editor[0])(i=n.anchorNode).nodeType===Node.TEXT_NODE&&(i=i.parentNode),"KBD"===i.nodeName&&(null!==(t=i.previousSibling)&&"​"===t.textContent||(t=document.createTextNode("​"),i.parentNode.insertBefore(t,i)),this.caret.before(t));else if("KBD"===e.target.nodeName){var i,r,o,a=e.target;if((i=n.anchorNode).nodeType===Node.TEXT_NODE){for(t=i;(t=t.nextSibling)&&t.nodeType===Node.TEXT_NODE&&(""===t.textContent||"​"===t.textContent););t===a&&(0!==a.childNodes.length&&"​"===a.childNodes[0].textContent||(r=document.createTextNode("​"),a.insertBefore(r,a.firstChild)),(o=document.createRange()).setStartAfter(a.childNodes[0]),o.setEndAfter(a.childNodes[0]),n.removeAllRanges(),n.addRange(o))}}},_addParagraphAfterBlock:function(e){var t=e.nextElementSibling;t&&("P"===t.nodeName||this.utils.isBlockTag(t.nodeName))||((t=elCreate("p")).textContent="​",e.parentNode.insertBefore(t,e.nextSibling))}}}; })(this);
 
 // plugins/WoltLabClean.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabClean=function(){"use strict";return{init:function(){var e=this.clean.onSet;this.clean.onSet=function(t){t=t.replace(/\u200B/g,""),t=t.replace(/&amp;amp;/g,"@@@WCF_LITERAL_AMP@@@"),t=t.replace(/&amp;/g,"&amp;WCF_AMPERSAND&amp;"),t=e.call(this,t),t=t.replace(/&amp;WCF_AMPERSAND&(amp;)?/g,"&amp;"),t=t.replace(/@@@WCF_LITERAL_AMP@@@/g,"&amp;amp;");var n=elCreate("div");return n.innerHTML=t,elBySelAll("*",n,function(e){for(var t,n=[],r=0,l=e.attributes.length;r<l;r++)t=e.attributes[r],0===t.name.indexOf("on")&&n.push(t.name);n.forEach(e.removeAttribute.bind(e))}),elBySelAll("iframe",n,elRemove),elBySelAll("pre",n,function(e){e.classList.contains("redactor-script-tag")&&elRemove(e)}),elBySelAll("td",n,function(e){0===e.childNodes.length&&(e.innerHTML="​")}),elBySelAll("pre, woltlab-quote, woltlab-spoiler",n,function(e){0!==e.childElementCount||0!==e.textContent.length&&!e.textContent.match(/^\r?\n$/)||(e.textContent="​")}),t=n.innerHTML}.bind(this);var t=this.clean.onSync;this.clean.onSync=function(e){var n=elCreate("div");n.innerHTML=e;var r={};return elBySelAll("pre",n,function(e){var t=WCF.getUUID();r[t]=e.textContent,e.textContent=t}),elBySelAll("p",n,function(e){var t=e.lastElementChild;if(t&&"BR"===t.nodeName)if(t.nextSibling){if(t.nextSibling.textContent.replace(/[\r\n\t]/g,"").match(/^\u200B+$/)){var n=elCreate("p");n.innerHTML="<br>",e.parentNode.insertBefore(n,e.nextSibling),e.removeChild(t.nextSibling),e.removeChild(t)}}else(t.previousElementSibling||t.previousSibling&&""!==t.previousSibling.textContent.replace(/\u200B/g,"").trim())&&e.removeChild(t)}),elBySelAll("span",n,function(e){if(e.childNodes.length>0){var t=e.childNodes[e.childNodes.length-1];t.nodeType===Node.TEXT_NODE&&t.textContent.match(/\n$/)&&(t.textContent=t.textContent.replace(/\n+$/,e.parentNode.lastChild===e?"":" "))}}),e=n.innerHTML,e=e.replace(/<p>\u200B<\/p>/g,"<p><br></p>"),e=e.replace(/&amp;/g,"&amp;WCF_AMPERSAND&amp;"),e=t.call(this,e),e=e.replace(/&WCF_AMPERSAND&/g,"&amp;"),n.innerHTML=e,elBySelAll("pre",n,function(e){r.hasOwnProperty(e.textContent)&&(e.textContent=r[e.textContent])}),e=n.innerHTML}.bind(this);var n=this.clean.savePreFormatting;this.clean.savePreFormatting=function(e){var t=this.clean.encodeEntities;return this.clean.encodeEntities=function(e){return WCF.String.escapeHTML(e)},e=n.call(this,e),this.clean.encodeEntities=t,e}.bind(this);var r=this.clean.onPaste;this.clean.onPaste=function(e,t,n){if(t.pre||this.utils.isCurrentOrParent("kbd"))return t.pre&&this.opts.preSpaces&&(e=e.replace(/\t/g,new Array(this.opts.preSpaces+1).join(" "))),WCF.String.escapeHTML(e);this.clean.isHtmlMsWord(e)&&(e=this.clean.cleanMsWord(e));var l=elCreate("div");l.innerHTML=e.replace(/@@@WOLTLAB-P-ALIGN-(?:left|right|center|justify)@@@/g,"");var i,o,a,s=!0;for(o=0,a=l.childElementCount;o<a;o++){if(i=l.children[o],"DIV"!==i.nodeName||0===i.childNodes.length){s=!1;break}if(1===i.childNodes.length&&1===i.childElementCount){var c=i.children[0];if(0===c.childNodes.length&&"BR"!==c.nodeName){s=!1;break}}}if(s){var h=[];for(o=0,a=l.childElementCount;o<a;o++)h.push(l.children[o]);h.forEach(function(e){var t=elCreate("p");for(l.insertBefore(t,e);e.childNodes.length>0;)t.appendChild(e.childNodes[0]);l.removeChild(e)})}var d,p,f,u,m=null!==elBySel(".MsoNormal",l),g=elBySelAll("[style]",l);for(o=0,a=g.length;o<a;o++){i=g[o],p=[];for(var v=0,y=i.style.length;v<y;v++)if(d=i.style[v],-1===this.opts.woltlab.allowedInlineStyles.indexOf(d)){if("font-weight"===d&&"STRONG"!==i.nodeName)u=i.style.getPropertyValue(d),"bold"!==u&&"bolder"!==u||(u=600),(u=~~u)>500&&(f=elCreate("strong"),i.parentNode.insertBefore(f,i),f.appendChild(i));else if(m&&"margin-bottom"===d&&"P"===i.nodeName&&(u=i.style.getPropertyValue(d),u.match(/^12(?:\.0)?pt$/))){var b=elCreate("p");b.innerHTML="<br>",i.parentNode.insertBefore(b,i.nextSibling)}p.push(d)}p.forEach(function(e){i.style.removeProperty(e)})}return elBySelAll("span",l,function(e){if(!e.classList.contains("redactor-selection-marker"))if(e.hasAttribute("style")&&e.style.length)for(var t=e.style.getPropertyValue("color"),n=e.style.getPropertyValue("font-family"),r=e.style.getPropertyValue("font-size"),l=(t?1:0)+(n?1:0)+(r?1:0);l>1;){if(this.opts.pastePlainText)return e.style.removeProperty("color"),e.style.removeProperty("font-family"),void e.style.removeProperty("font-size");var i=elCreate("span");t?(i.style.setProperty("color",t,""),e.style.removeProperty("color"),t="",l--):n?(i.style.setProperty("font-family",n,""),e.style.removeProperty("font-family"),n="",l--):r&&(i.style.setProperty("font-size",r,""),e.style.removeProperty("font-size"),r="",l--),e.parentNode.insertBefore(i,e),i.appendChild(e)}else{for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);elRemove(e)}}.bind(this)),elBySelAll("p",l,function(e){e.classList.contains("MsoNormal")?1===e.childElementCount&&"O:P"===e.children[0].nodeName&&" "===e.textContent&&(e.innerHTML="<br>"):e.className.match(/\btext-(left|right|center|justify)\b/)&&e.insertBefore(document.createTextNode("@@@WOLTLAB-P-ALIGN-"+RegExp.$1+"@@@"),e.firstChild),e.removeAttribute("class"),e.removeAttribute("style")}),elBySelAll("img",l,function(e){e.removeAttribute("style")}),elBySelAll("br",l,function(e){e.parentNode.insertBefore(document.createTextNode("@@@WOLTLAB-BR-MARKER@@@"),e.nextSibling)}),elBySelAll("kbd",l,function(e){for(e.insertBefore(document.createTextNode("[tt]"),e.firstChild),e.appendChild(document.createTextNode("[/tt]"));e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);elRemove(e)}),e=r.call(this,l.innerHTML,t,n),e=e.replace(/\n*@@@WOLTLAB-BR-MARKER@@@\n*/g,"<woltlab-br-marker></woltlab-br-marker>"),e=e.replace(/(<p>)?\s*@@@WOLTLAB-P-ALIGN-(left|right|center|justify)@@@/g,function(e,t,n){return t?'<p class="text-'+n+'">':""}),l.innerHTML=e.replace(/&amp;quot;/g,"&quot;"),elBySelAll("woltlab-br-marker",l,function(e){var t=e.parentNode;if(null!==t){for(var n=!1,r=t;null!==r;)"P"===r.nodeName&&(n=!0),r=r.parentNode;if(n){var l=elCreate("p");l.innerHTML="<br>";var i=!1,o=e.nextSibling;o&&"WOLTLAB-BR-MARKER"===o.nodeName&&(i=!0);for(var a=!i;e.nextSibling;)a&&0!==e.nextSibling.textContent.replace(/\u200B/g,"").trim().length&&(a=!1),l.appendChild(e.nextSibling);a||elRemove(l.firstElementChild);var s=e.previousSibling;s&&"BR"===s.nodeName&&elRemove(s),t.parentNode.insertBefore(l,t.nextSibling),i&&(l=elCreate("p"),l.innerHTML="<br>",t.parentNode.insertBefore(l,t.nextSibling))}else t.insertBefore(elCreate("br"),e);elRemove(e)}}),elBySelAll("p",l,function(e){var t=!1;0===e.childNodes.length?t=!0:""===e.textContent?(t=!0,elBySelAll("*",e,function(e){"SPAN"!==e.nodeName&&(t=!1)})):0===e.textContent.trim().length&&(elBySelAll("span",e,function(e){if(!e.hasAttribute("style")||!e.style.length){for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);elRemove(e)}}),0===e.children.length&&(e.innerHTML="<br>")),t&&elRemove(e)}),l.innerHTML}.bind(this);var l=[],i=function(e,t){for(var n,r,i={},o=0,a=t.length;o<a;o++)n=t[o],r=elAttr(e,n),"style"===n&&0===e.style.length&&0===r.indexOf("font-family")&&(r=r.replace(/&quot;/g,"")),i[n]=r;l.push({element:e,attributes:i})},o=this.clean.convertTags;this.clean.convertTags=function(e,t){var n=elCreate("div");n.innerHTML=e,l=[],WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","convertTags_"+this.$element[0].id,{addToStorage:i,div:n}),elBySelAll("span",n,function(e){i(e,["style"])}),l.forEach(function(e,t){var n=e.element,r=n.parentNode;for(r.insertBefore(document.createTextNode("###custom"+t+"###"),n),r.insertBefore(document.createTextNode("###/custom"+t+"###"),n.nextSibling);n.childNodes.length;)r.insertBefore(n.childNodes[0],n);r.removeChild(n)});var r=!1;t.links&&this.opts.pasteLinks&&(elBySelAll("a",n,function(e){e.href&&(e.outerHTML='#@###[a href="'+e.href+'"]###@#'+e.innerHTML+"#@###[/a]###@#")}),r=!0,t.links=!1);var a=!1;return t.images&&this.opts.pasteImages&&(elBySelAll("img",n,function(e){if(e.src){for(var t,n='#####[img src="'+e.src+'"',r=0,l=e.attributes.length;r<l;r++)t=e.attributes.item(r),"src"!==t.name&&(n+=" "+t.name+'="'+t.value+'"');e.outerHTML=n+"]#####"}}),a=!0,t.images=!1),e=o.call(this,n.innerHTML,t),a&&(t.images=!0),r&&(t.links=!0),e}.bind(this);var a=this.clean.reconvertTags;this.clean.reconvertTags=function(e,t){if(l.length){e=e.replace(/###(\/?)custom(\d+)###/g,'<$1woltlab-custom-tag data-index="$2">');var n=elCreate("div");n.innerHTML=e,elBySelAll("woltlab-custom-tag",n,function(e){var t=~~elData(e,"index");if(l[t]){var n=l[t],r=elCreate(n.element.nodeName);for(var i in n.attributes)n.attributes.hasOwnProperty(i)&&elAttr(r,i,n.attributes[i]);for(e.parentNode.insertBefore(r,e);e.childNodes.length;)r.appendChild(e.childNodes[0])}elRemove(e)}),e=n.innerHTML}return(t.links&&this.opts.pasteLinks||t.images&&this.opts.pasteImages)&&(e=e.replace(new RegExp("#@###\\[","gi"),"<"),e=e.replace(new RegExp("\\]###@#","gi"),">")),a.call(this,e,t)}.bind(this),this.clean.removeSpans=function(e){return e};var s=this.clean.getCurrentType;this.clean.getCurrentType=function(e,t){var n=s.call(this,e,t);return this.utils.isCurrentOrParent(["kbd"])&&(n.inline=!1,n.block=!1,n.encode=!0,n.pre=!0,n.paragraphize=!1,n.images=!1,n.links=!1),n}.bind(this);this.clean.removeEmptyInlineTags;this.clean.removeEmptyInlineTags=function(e){var t=this.opts.inlineTags,n=$("<div/>").html($.parseHTML(e,document,!0)),r=this,l=n.find("span"),i=n.find(t.join(","));return i.filter(":not(span)").removeAttr("style"),i.each(function(){var e=$(this).html();0===this.attributes.length&&r.utils.isEmpty(e)&&$(this).replaceWith(function(){return $(this).contents()})}),l.each(function(){$(this).html();0===this.attributes.length&&$(this).replaceWith(function(){return $(this).contents()})}),e=n.html(),e=e.replace("\x3c!--?php","<?php"),e=e.replace("\x3c!--?","<?"),e=e.replace("?--\x3e","?>"),n.remove(),e}.bind(this)},removeRedundantStyles:function(){var e=[],t=["del","em","strong","sub","sup","u"];if(elBySelAll(t.join(","),this.$editor[0],function(t){elBySelAll(t.nodeName,t,function(t){e.push(t)})}),!this.opts.pastePlainText){elBySelAll("span[style]",this.$editor[0],function(t){["color","font-family","font-size"].forEach(function(n){var r=t.style.getPropertyValue(n);r&&window.getComputedStyle(t.parentNode).getPropertyValue(n)===r&&e.push(t)})});var n;e.forEach(function(e){for(n=e.parentNode;e.childNodes.length;)n.insertBefore(e.childNodes[0],e);n.removeChild(e)})}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabClean=function(){"use strict";return{init:function(){var n=this.clean.onSet;this.clean.onSet=function(e){e=(e=(e=e.replace(/\u200B/g,"")).replace(/&amp;amp;/g,"@@@WCF_LITERAL_AMP@@@")).replace(/&amp;/g,"&amp;WCF_AMPERSAND&amp;"),e=(e=(e=n.call(this,e)).replace(/&amp;WCF_AMPERSAND&(amp;)?/g,"&amp;")).replace(/@@@WCF_LITERAL_AMP@@@/g,"&amp;amp;");var t=elCreate("div");return t.innerHTML=e,elBySelAll("*",t,function(e){for(var t,n=[],r=0,l=e.attributes.length;r<l;r++)0===(t=e.attributes[r]).name.indexOf("on")&&n.push(t.name);n.forEach(e.removeAttribute.bind(e))}),elBySelAll("iframe",t,elRemove),elBySelAll("pre",t,function(e){e.classList.contains("redactor-script-tag")&&elRemove(e)}),elBySelAll("td",t,function(e){0===e.childNodes.length&&(e.innerHTML="​")}),elBySelAll("pre, woltlab-quote, woltlab-spoiler",t,function(e){0!==e.childElementCount||0!==e.textContent.length&&!e.textContent.match(/^\r?\n$/)||(e.textContent="​")}),e=t.innerHTML}.bind(this);var r=this.clean.onSync;this.clean.onSync=function(e){var t=elCreate("div");t.innerHTML=e;var n={};return elBySelAll("pre",t,function(e){var t=WCF.getUUID();n[t]=e.textContent,e.textContent=t}),elBySelAll("p",t,function(e){var t,n=e.lastElementChild;n&&"BR"===n.nodeName&&(n.nextSibling?n.nextSibling.textContent.replace(/[\r\n\t]/g,"").match(/^\u200B+$/)&&((t=elCreate("p")).innerHTML="<br>",e.parentNode.insertBefore(t,e.nextSibling),e.removeChild(n.nextSibling),e.removeChild(n)):(n.previousElementSibling||n.previousSibling&&""!==n.previousSibling.textContent.replace(/\u200B/g,"").trim())&&e.removeChild(n))}),elBySelAll("span",t,function(e){var t;0<e.childNodes.length&&((t=e.childNodes[e.childNodes.length-1]).nodeType===Node.TEXT_NODE&&t.textContent.match(/\n$/)&&(t.textContent=t.textContent.replace(/\n+$/,e.parentNode.lastChild===e?"":" ")))}),e=(e=(e=t.innerHTML).replace(/<p>\u200B<\/p>/g,"<p><br></p>")).replace(/&amp;/g,"&amp;WCF_AMPERSAND&amp;"),e=(e=r.call(this,e)).replace(/&WCF_AMPERSAND&/g,"&amp;"),t.innerHTML=e,elBySelAll("pre",t,function(e){n.hasOwnProperty(e.textContent)&&(e.textContent=n[e.textContent])}),e=t.innerHTML}.bind(this);var l=this.clean.savePreFormatting;this.clean.savePreFormatting=function(e){var t=this.clean.encodeEntities;return this.clean.encodeEntities=function(e){return WCF.String.escapeHTML(e)},e=l.call(this,e),this.clean.encodeEntities=t,e}.bind(this);var b=this.clean.onPaste;this.clean.onPaste=function(e,t,n){if(t.pre||this.utils.isCurrentOrParent("kbd"))return t.pre&&this.opts.preSpaces&&(e=e.replace(/\t/g,new Array(this.opts.preSpaces+1).join(" "))),WCF.String.escapeHTML(e);this.clean.isHtmlMsWord(e)&&(e=this.clean.cleanMsWord(e));var r,l=elCreate("div");l.innerHTML=e.replace(/@@@WOLTLAB-P-ALIGN-(?:left|right|center|justify)@@@/g,"");var i=!0;for(s=0,c=l.childElementCount;s<c;s++){if("DIV"!==(r=l.children[s]).nodeName||0===r.childNodes.length){i=!1;break}if(1===r.childNodes.length&&1===r.childElementCount){var o=r.children[0];if(0===o.childNodes.length&&"BR"!==o.nodeName){i=!1;break}}}if(i){for(var a=[],s=0,c=l.childElementCount;s<c;s++)a.push(l.children[s]);a.forEach(function(e){var t=elCreate("p");for(l.insertBefore(t,e);0<e.childNodes.length;)t.appendChild(e.childNodes[0]);l.removeChild(e)})}var h,d,p=null!==elBySel(".MsoNormal",l),u=elBySelAll("[style]",l);for(s=0,c=u.length;s<c;s++){h=[];for(var f=0,m=(r=u[s]).style.length;f<m;f++){var g,v,y=r.style[f];-1===this.opts.woltlab.allowedInlineStyles.indexOf(y)&&("font-weight"===y&&"STRONG"!==r.nodeName?("bold"!==(v=r.style.getPropertyValue(y))&&"bolder"!==v||(v=600),500<(v=~~v)&&(d=elCreate("strong"),r.parentNode.insertBefore(d,r),d.appendChild(r))):p&&"margin-bottom"===y&&"P"===r.nodeName&&(v=r.style.getPropertyValue(y)).match(/^12(?:\.0)?pt$/)&&((g=elCreate("p")).innerHTML="<br>",r.parentNode.insertBefore(g,r.nextSibling)),h.push(y))}h.forEach(function(e){r.style.removeProperty(e)})}return elBySelAll("span",l,function(e){if(!e.classList.contains("redactor-selection-marker"))if(e.hasAttribute("style")&&e.style.length)for(var t=e.style.getPropertyValue("color"),n=e.style.getPropertyValue("font-family"),r=e.style.getPropertyValue("font-size"),l=(t?1:0)+(n?1:0)+(r?1:0);1<l;){if(this.opts.pastePlainText)return e.style.removeProperty("color"),e.style.removeProperty("font-family"),void e.style.removeProperty("font-size");var i=elCreate("span");t?(i.style.setProperty("color",t,""),e.style.removeProperty("color"),t="",l--):n?(i.style.setProperty("font-family",n,""),e.style.removeProperty("font-family"),n="",l--):r&&(i.style.setProperty("font-size",r,""),e.style.removeProperty("font-size"),r="",l--),e.parentNode.insertBefore(i,e),i.appendChild(e)}else{for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);elRemove(e)}}.bind(this)),elBySelAll("p",l,function(e){e.classList.contains("MsoNormal")?1===e.childElementCount&&"O:P"===e.children[0].nodeName&&" "===e.textContent&&(e.innerHTML="<br>"):e.className.match(/\btext-(left|right|center|justify)\b/)&&e.insertBefore(document.createTextNode("@@@WOLTLAB-P-ALIGN-"+RegExp.$1+"@@@"),e.firstChild),e.removeAttribute("class"),e.removeAttribute("style")}),elBySelAll("img",l,function(e){e.removeAttribute("style")}),elBySelAll("br",l,function(e){e.parentNode.insertBefore(document.createTextNode("@@@WOLTLAB-BR-MARKER@@@"),e.nextSibling)}),elBySelAll("kbd",l,function(e){for(e.insertBefore(document.createTextNode("[tt]"),e.firstChild),e.appendChild(document.createTextNode("[/tt]"));e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);elRemove(e)}),e=(e=(e=b.call(this,l.innerHTML,t,n)).replace(/\n*@@@WOLTLAB-BR-MARKER@@@\n*/g,"<woltlab-br-marker></woltlab-br-marker>")).replace(/(<p>)?\s*@@@WOLTLAB-P-ALIGN-(left|right|center|justify)@@@/g,function(e,t,n){return t?'<p class="text-'+n+'">':""}),l.innerHTML=e.replace(/&amp;quot;/g,"&quot;"),elBySelAll("woltlab-br-marker",l,function(e){var t=e.parentNode;if(null!==t){for(var n=!1,r=t;null!==r;)"P"===r.nodeName&&(n=!0),r=r.parentNode;if(n){var l=elCreate("p"),i=!(l.innerHTML="<br>"),o=e.nextSibling;o&&"WOLTLAB-BR-MARKER"===o.nodeName&&(i=!0);for(var a=!i;e.nextSibling;)a&&0!==e.nextSibling.textContent.replace(/\u200B/g,"").trim().length&&(a=!1),l.appendChild(e.nextSibling);a||elRemove(l.firstElementChild);var s=e.previousSibling;s&&"BR"===s.nodeName&&elRemove(s),t.parentNode.insertBefore(l,t.nextSibling),i&&((l=elCreate("p")).innerHTML="<br>",t.parentNode.insertBefore(l,t.nextSibling))}else t.insertBefore(elCreate("br"),e);elRemove(e)}}),elBySelAll("p",l,function(e){var t=!1;0===e.childNodes.length?t=!0:""===e.textContent?(t=!0,elBySelAll("*",e,function(e){"SPAN"!==e.nodeName&&(t=!1)})):0===e.textContent.trim().length&&(elBySelAll("span",e,function(e){if(!e.hasAttribute("style")||!e.style.length){for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);elRemove(e)}}),0===e.children.length&&(e.innerHTML="<br>")),t&&elRemove(e)}),l.innerHTML}.bind(this);function i(e,t){for(var n,r,l={},i=0,o=t.length;i<o;i++)n=t[i],r=elAttr(e,n),"style"===n&&0===e.style.length&&0===r.indexOf("font-family")&&(r=r.replace(/&quot;/g,"")),l[n]=r;a.push({element:e,attributes:l})}var a=[],o=this.clean.convertTags;this.clean.convertTags=function(e,t){var n=elCreate("div");n.innerHTML=e,a=[],WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","convertTags_"+this.$element[0].id,{addToStorage:i,div:n}),elBySelAll("span",n,function(e){i(e,["style"])}),a.forEach(function(e,t){var n=e.element,r=n.parentNode;for(r.insertBefore(document.createTextNode("###custom"+t+"###"),n),r.insertBefore(document.createTextNode("###/custom"+t+"###"),n.nextSibling);n.childNodes.length;)r.insertBefore(n.childNodes[0],n);r.removeChild(n)});var r=!1;t.links&&this.opts.pasteLinks&&(elBySelAll("a",n,function(e){e.href&&(e.outerHTML='#@###[a href="'+e.href+'"]###@#'+e.innerHTML+"#@###[/a]###@#")}),r=!0,t.links=!1);var l=!1;return t.images&&this.opts.pasteImages&&(elBySelAll("img",n,function(e){if(e.src){for(var t,n='#####[img src="'+e.src+'"',r=0,l=e.attributes.length;r<l;r++)"src"!==(t=e.attributes.item(r)).name&&(n+=" "+t.name+'="'+t.value+'"');e.outerHTML=n+"]#####"}}),l=!0,t.images=!1),e=o.call(this,n.innerHTML,t),l&&(t.images=!0),r&&(t.links=!0),e}.bind(this);var s=this.clean.reconvertTags;this.clean.reconvertTags=function(e,t){var n;return a.length&&(e=e.replace(/###(\/?)custom(\d+)###/g,'<$1woltlab-custom-tag data-index="$2">'),(n=elCreate("div")).innerHTML=e,elBySelAll("woltlab-custom-tag",n,function(e){var t=~~elData(e,"index");if(a[t]){var n=a[t],r=elCreate(n.element.nodeName);for(var l in n.attributes)n.attributes.hasOwnProperty(l)&&elAttr(r,l,n.attributes[l]);for(e.parentNode.insertBefore(r,e);e.childNodes.length;)r.appendChild(e.childNodes[0])}elRemove(e)}),e=n.innerHTML),(t.links&&this.opts.pasteLinks||t.images&&this.opts.pasteImages)&&(e=(e=e.replace(new RegExp("#@###\\[","gi"),"<")).replace(new RegExp("\\]###@#","gi"),">")),s.call(this,e,t)}.bind(this),this.clean.removeSpans=function(e){return e};var c=this.clean.getCurrentType;this.clean.getCurrentType=function(e,t){var n=c.call(this,e,t);return this.utils.isCurrentOrParent(["kbd"])&&(n.inline=!1,n.block=!1,n.encode=!0,n.pre=!0,n.paragraphize=!1,n.images=!1,n.links=!1),n}.bind(this);this.clean.removeEmptyInlineTags;this.clean.removeEmptyInlineTags=function(e){var t=this.opts.inlineTags,n=$("<div/>").html($.parseHTML(e,document,!0)),r=this,l=n.find("span"),i=n.find(t.join(","));return i.filter(":not(span)").removeAttr("style"),i.each(function(){var e=$(this).html();0===this.attributes.length&&r.utils.isEmpty(e)&&$(this).replaceWith(function(){return $(this).contents()})}),l.each(function(){$(this).html();0===this.attributes.length&&$(this).replaceWith(function(){return $(this).contents()})}),e=(e=(e=(e=n.html()).replace("\x3c!--?php","<?php")).replace("\x3c!--?","<?")).replace("?--\x3e","?>"),n.remove(),e}.bind(this)},removeRedundantStyles:function(){var t,r=[];elBySelAll(["del","em","strong","sub","sup","u"].join(","),this.$editor[0],function(e){elBySelAll(e.nodeName,e,function(e){r.push(e)})}),this.opts.pastePlainText||(elBySelAll("span[style]",this.$editor[0],function(n){["color","font-family","font-size"].forEach(function(e){var t=n.style.getPropertyValue(e);t&&window.getComputedStyle(n.parentNode).getPropertyValue(e)===t&&r.push(n)})}),r.forEach(function(e){for(t=e.parentNode;e.childNodes.length;)t.insertBefore(e.childNodes[0],e);t.removeChild(e)}))}}}; })(this);
 
 // plugins/WoltLabCode.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabCode=function(){"use strict";return{init:function(){require(["WoltLabSuite/Core/Ui/Redactor/Code"],function(t){new t(this)}.bind(this));var t=this.code.start;this.code.start=function(e){t.call(this,e),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","codeStart_"+this.$element[0].id),elBySelAll("kbd",this.$editor[0],function(t){var e=t.nextSibling;if(!e||e.nodeType!==Node.TEXT_NODE||"​"!==e.textContent.substr(0,1)){var i=document.createTextNode("​");t.parentNode.insertBefore(i,e)}})}.bind(this);var e=this.code.set;this.code.set=function(t,i){e.call(this,t,i),this.utils.isEmpty()&&this.observe.toolbar()}.bind(this);var i=this.code.get;this.code.get=function(){return this.code.html=!1,this.code.startSync(this.core.editor().html()),i.call(this)}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabCode=function(){"use strict";return{init:function(){require(["WoltLabSuite/Core/Ui/Redactor/Code"],function(t){new t(this)}.bind(this));var e=this.code.start;this.code.start=function(t){e.call(this,t),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","codeStart_"+this.$element[0].id),elBySelAll("kbd",this.$editor[0],function(t){var e,i=t.nextSibling;i&&i.nodeType===Node.TEXT_NODE&&"​"===i.textContent.substr(0,1)||(e=document.createTextNode("​"),t.parentNode.insertBefore(e,i))})}.bind(this);var i=this.code.set;this.code.set=function(t,e){i.call(this,t,e),this.utils.isEmpty()&&this.observe.toolbar()}.bind(this);var t=this.code.get;this.code.get=function(){return this.code.html=!1,this.code.startSync(this.core.editor().html()),t.call(this)}.bind(this)}}}; })(this);
 
 // plugins/WoltLabColor.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabColor=function(){"use strict";var o=["000000","800000","8B4513","2F4F4F","008080","000080","4B0082","696969","B22222","A52A2A","DAA520","006400","40E0D0","0000CD","800080","808080","FF0000","FF8C00","FFD700","008000","00FFFF","0000FF","EE82EE","A9A9A9","FFA07A","FFA500","FFFF00","00FF00","AFEEEE","ADD8E6","DDA0DD","D3D3D3","FFF0F5","FAEBD7","FFFFE0","F0FFF0","F0FFFF","F0F8FF","E6E6FA","FFFFFF"];return{init:function(){for(var t,e=this.WoltLabColor.setColor.bind(this),r={},F=0,i=o.length;F<i;F++)t=o[F],r["color_"+t]={title:"#"+t,func:e};r.removeColor={title:this.lang.get("remove-color"),func:this.WoltLabColor.removeColor.bind(this)};var s=this.button.add("woltlabColor","");this.button.addDropdown(s,r);var l=s.data("dropdown");l.find("a").each(function(o,t){t.className.match(/redactor-dropdown-color_([A-F0-9]{6})/)&&(t.style.setProperty("color","#"+RegExp.$1,""),t.parentNode.classList.add("woltlab-color-selection"))}),$('<li class="dropdownDivider"></li>').insertBefore(l.children("li").last())},setColor:function(o){o=o.replace(/^color_/,""),this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(t){this.buffer.set(),t.format(this.$editor[0],"color","#"+o),this.buffer.set()}.bind(this)),this.selection.restore()},removeColor:function(){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(o){this.buffer.set(),o.removeFormat(this.$editor[0],"color"),this.buffer.set()}.bind(this)),this.selection.restore()}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabColor=function(){"use strict";var l=["000000","800000","8B4513","2F4F4F","008080","000080","4B0082","696969","B22222","A52A2A","DAA520","006400","40E0D0","0000CD","800080","808080","FF0000","FF8C00","FFD700","008000","00FFFF","0000FF","EE82EE","A9A9A9","FFA07A","FFA500","FFFF00","00FF00","AFEEEE","ADD8E6","DDA0DD","D3D3D3","FFF0F5","FAEBD7","FFFFE0","F0FFF0","F0FFFF","F0F8FF","E6E6FA","FFFFFF"];return{init:function(){for(var o,t=this.WoltLabColor.setColor.bind(this),e={},r=0,F=l.length;r<F;r++)e["color_"+(o=l[r])]={title:"#"+o,func:t};e.removeColor={title:this.lang.get("remove-color"),func:this.WoltLabColor.removeColor.bind(this)};var i=this.button.add("woltlabColor","");this.button.addDropdown(i,e);var s=i.data("dropdown");s.find("a").each(function(o,t){t.className.match(/redactor-dropdown-color_([A-F0-9]{6})/)&&(t.style.setProperty("color","#"+RegExp.$1,""),t.parentNode.classList.add("woltlab-color-selection"))}),$('<li class="dropdownDivider"></li>').insertBefore(s.children("li").last())},setColor:function(t){t=t.replace(/^color_/,""),this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(o){this.buffer.set(),o.format(this.$editor[0],"color","#"+t),this.buffer.set()}.bind(this)),this.selection.restore()},removeColor:function(){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(o){this.buffer.set(),o.removeFormat(this.$editor[0],"color"),this.buffer.set()}.bind(this)),this.selection.restore()}}}; })(this);
 
 // plugins/WoltLabDragAndDrop.js
 (function (window, undefined) { $.Redactor.prototype.WoltLabDragAndDrop=function(){"use strict";return{init:function(){(this.opts.woltlab.attachments||this.opts.woltlab.media)&&require(["WoltLabSuite/Core/Ui/Redactor/DragAndDrop"],function(t){t.init(this)}.bind(this))}}}; })(this);
 
 // plugins/WoltLabEvent.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabEvent=function(){"use strict";return{init:function(){this._callbacks=[],this._elementId=this.$element[0].id,elData(this.$editor[0],"element-id",this._elementId),require(["EventHandler"],function(t){this.WoltLabEvent._setEvents(t),t.add("com.woltlab.wcf.redactor2","destroy_"+this._elementId,function(){t.removeAllBySuffix("com.woltlab.wcf.redactor2",this._elementId)}.bind(this))}.bind(this));var t=window.navigator.userAgent.toLowerCase();-1===t.indexOf("windows phone")&&-1===t.indexOf("edge/")&&(this.$editor[0].addEventListener("focus",function(){document.documentElement.classList.add("redactorActive")}),this.$editor[0].addEventListener("focusout",function(){window.setTimeout(function(){document.activeElement&&document.activeElement.classList.contains("redactor-layer")||document.documentElement.classList.remove("redactorActive")},100)})),this.events.iterateObserver=function(t){var e=!1;(("textarea"===this.opts.type||"div"===this.opts.type)&&!this.detect.isFirefox()&&t.target===this.core.editor()[0]&&"childList"===t.type&&!t.addedNodes.length&&!t.removedNodes.length||"class"===t.attributeName&&t.target===this.core.editor()[0]||"data-vivaldi-spatnav-clickable"===t.attributeName||"attributes"===t.type&&null===t.attributeName)&&(e=!0),e||(this.observe.load(),this.events.changeHandler())}.bind(this),this.events.observer.disconnect(),this.events.createObserver(),this.events.setupObserver()},_setEvents:function(t){var e=this.$element[0].id,i=this.observe.load;this.observe.load=function(){i.call(this),t.fire("com.woltlab.wcf.redactor2","observe_load_"+e,{editor:this.$editor[0]})}.bind(this),this.opts.callbacks.keyup=function(i){var n={cancel:!1,event:i};return t.fire("com.woltlab.wcf.redactor","keyup_"+e,n),!1===n.cancel},t.add("com.woltlab.wcf.redactor2","getText_"+e,function(t){t.message=this.code.get()}.bind(this)),t.add("com.woltlab.wcf.redactor2","reset_"+e,function(){this.code.set("")}.bind(this))},register:function(t,e){require(["EventHandler"],function(i){var n=this.uuid;-1===this._callbacks.indexOf(t)&&(this.opts.callbacks[t]=function(e){var s={cancel:!1,event:e,redactor:this};return i.fire("com.woltlab.wcf.redactor2",t+"_"+n+"_"+this.WoltLabEvent._elementId,s),!1===s.cancel}.bind(this),this._callbacks.push(t)),require(["EventHandler"],function(i){i.add("com.woltlab.wcf.redactor2",t+"_"+n+"_"+this.WoltLabEvent._elementId,e)}.bind(this))}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabEvent=function(){"use strict";return{init:function(){this._callbacks=[],this._elementId=this.$element[0].id,elData(this.$editor[0],"element-id",this._elementId),require(["EventHandler"],function(t){this.WoltLabEvent._setEvents(t),t.add("com.woltlab.wcf.redactor2","destroy_"+this._elementId,function(){t.removeAllBySuffix("com.woltlab.wcf.redactor2",this._elementId)}.bind(this))}.bind(this));var t=window.navigator.userAgent.toLowerCase();-1===t.indexOf("windows phone")&&-1===t.indexOf("edge/")&&(this.$editor[0].addEventListener("focus",function(){document.documentElement.classList.add("redactorActive")}),this.$editor[0].addEventListener("focusout",function(){window.setTimeout(function(){document.activeElement&&document.activeElement.classList.contains("redactor-layer")||document.documentElement.classList.remove("redactorActive")},100)})),this.events.iterateObserver=function(t){var e=!1;(!("textarea"!==this.opts.type&&"div"!==this.opts.type||this.detect.isFirefox()||t.target!==this.core.editor()[0]||"childList"!==t.type||t.addedNodes.length||t.removedNodes.length)||"class"===t.attributeName&&t.target===this.core.editor()[0]||"data-vivaldi-spatnav-clickable"===t.attributeName||"attributes"===t.type&&null===t.attributeName)&&(e=!0),e||(this.observe.load(),this.events.changeHandler())}.bind(this),this.events.observer.disconnect(),this.events.createObserver(),this.events.setupObserver()},_setEvents:function(i){var n=this.$element[0].id,t=this.observe.load;this.observe.load=function(){t.call(this),i.fire("com.woltlab.wcf.redactor2","observe_load_"+n,{editor:this.$editor[0]})}.bind(this),this.opts.callbacks.keyup=function(t){var e={cancel:!1,event:t};return i.fire("com.woltlab.wcf.redactor","keyup_"+n,e),!1===e.cancel},i.add("com.woltlab.wcf.redactor2","getText_"+n,function(t){t.message=this.code.get()}.bind(this)),i.add("com.woltlab.wcf.redactor2","reset_"+n,function(){this.code.set("")}.bind(this))},register:function(s,e){require(["EventHandler"],function(i){var n=this.uuid;-1===this._callbacks.indexOf(s)&&(this.opts.callbacks[s]=function(t){var e={cancel:!1,event:t,redactor:this};return i.fire("com.woltlab.wcf.redactor2",s+"_"+n+"_"+this.WoltLabEvent._elementId,e),!1===e.cancel}.bind(this),this._callbacks.push(s)),require(["EventHandler"],function(t){t.add("com.woltlab.wcf.redactor2",s+"_"+n+"_"+this.WoltLabEvent._elementId,e)}.bind(this))}.bind(this))}}}; })(this);
 
 // plugins/WoltLabFont.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabFont=function(){"use strict";return{_fonts:["Arial, Helvetica, sans-serif","Comic Sans MS, Marker Felt, cursive","Consolas, Courier New, Courier, monospace","Georgia, serif","Lucida Sans Unicode, Lucida Grande, sans-serif","Tahoma, Geneva, sans-serif","Times New Roman, Times, serif",'Trebuchet MS", Helvetica, sans-serif',"Verdana, Geneva, sans-serif"],init:function(){var t=this.WoltLabFont.setFont.bind(this),e={};this.WoltLabFont._fonts.forEach(function(o,i){e["fontFamily_"+i]={title:o.split(",")[0].replace(/['"]/g,""),func:t}}),e.removeFont={title:this.lang.get("remove-font"),func:this.WoltLabFont.removeFont.bind(this)};var o=this.button.add("woltlabFont","");this.button.addDropdown(o,e);var i=o.data("dropdown");i.find("a").each(function(t,e){e.className.match(/^redactor-dropdown-fontFamily_(\d+)$/)&&e.style.setProperty("font-family",this.WoltLabFont._fonts[RegExp.$1],"")}.bind(this)),$('<li class="dropdownDivider"></li>').insertBefore(i.children("li").last())},setFont:function(t){t=t.replace(/^fontFamily_/,""),this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(e){this.buffer.set(),e.format(this.$editor[0],"font-family",this.WoltLabFont._fonts[t]),this.buffer.set()}.bind(this)),this.selection.restore()},removeFont:function(){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(t){this.buffer.set(),t.removeFormat(this.$editor[0],"font-family"),this.buffer.set()}.bind(this)),this.selection.restore()}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabFont=function(){"use strict";return{_fonts:["Arial, Helvetica, sans-serif","Comic Sans MS, Marker Felt, cursive","Consolas, Courier New, Courier, monospace","Georgia, serif","Lucida Sans Unicode, Lucida Grande, sans-serif","Tahoma, Geneva, sans-serif","Times New Roman, Times, serif",'Trebuchet MS", Helvetica, sans-serif',"Verdana, Geneva, sans-serif"],init:function(){var o=this.WoltLabFont.setFont.bind(this),i={};this.WoltLabFont._fonts.forEach(function(t,e){i["fontFamily_"+e]={title:t.split(",")[0].replace(/['"]/g,""),func:o}}),i.removeFont={title:this.lang.get("remove-font"),func:this.WoltLabFont.removeFont.bind(this)};var t=this.button.add("woltlabFont","");this.button.addDropdown(t,i);var e=t.data("dropdown");e.find("a").each(function(t,e){e.className.match(/^redactor-dropdown-fontFamily_(\d+)$/)&&e.style.setProperty("font-family",this.WoltLabFont._fonts[RegExp.$1],"")}.bind(this)),$('<li class="dropdownDivider"></li>').insertBefore(e.children("li").last())},setFont:function(e){e=e.replace(/^fontFamily_/,""),this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(t){this.buffer.set(),t.format(this.$editor[0],"font-family",this.WoltLabFont._fonts[e]),this.buffer.set()}.bind(this)),this.selection.restore()},removeFont:function(){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(t){this.buffer.set(),t.removeFormat(this.$editor[0],"font-family"),this.buffer.set()}.bind(this)),this.selection.restore()}}}; })(this);
 
 // plugins/WoltLabFullscreen.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabFullscreen=function(){"use strict";var e,t=!1;return{init:function(){var l=this.button.add("woltlabFullscreen","");this.button.addCallback(l,this.WoltLabFullscreen._toggle.bind(this)),e=l[0],elHide(e.parentNode),require(["Ui/Screen"],function(l){l.on("screen-sm-up",{match:function(){elShow(e.parentNode)},unmatch:function(){elHide(e.parentNode),t&&this.WoltLabFullscreen._toggle()}.bind(this),setup:function(){elShow(e.parentNode)}})}.bind(this))},_toggle:function(){e.children[0].classList.toggle("fa-compress"),e.children[0].classList.toggle("fa-expand");var l=elClosest(this.core.box()[0],".anchorFixedHeader");l&&l.classList.toggle("disableAnchorFixedHeader"),this.core.box()[0].classList.toggle("redactorBoxFullscreen")?(WCF.System.DisableScrolling.disable(),t=!0):(WCF.System.DisableScrolling.enable(),t=!1)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabFullscreen=function(){"use strict";var t,l=!1;return{init:function(){var e=this.button.add("woltlabFullscreen","");this.button.addCallback(e,this.WoltLabFullscreen._toggle.bind(this)),t=e[0],elHide(t.parentNode),require(["Ui/Screen"],function(e){e.on("screen-sm-up",{match:function(){elShow(t.parentNode)},unmatch:function(){elHide(t.parentNode),l&&this.WoltLabFullscreen._toggle()}.bind(this),setup:function(){elShow(t.parentNode)}})}.bind(this))},_toggle:function(){t.children[0].classList.toggle("fa-compress"),t.children[0].classList.toggle("fa-expand");var e=elClosest(this.core.box()[0],".anchorFixedHeader");e&&e.classList.toggle("disableAnchorFixedHeader"),l=this.core.box()[0].classList.toggle("redactorBoxFullscreen")?(WCF.System.DisableScrolling.disable(),!0):(WCF.System.DisableScrolling.enable(),!1)}}}; })(this);
 
 // plugins/WoltLabHtml.js
 (function (window, undefined) { $.Redactor.prototype.WoltLabHtml=function(){"use strict";return{init:function(){require(["WoltLabSuite/Core/Ui/Redactor/Html"],function(t){new t(this)}.bind(this))}}}; })(this);
 
 // plugins/WoltLabImage.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabImage=function(){"use strict";return{init:function(){if(this.opts.woltlab.allowImages){var t=this.button.add("woltlabImage","");this.button.addCallback(t,this.WoltLabImage.add)}var e=this.image.showEdit;this.image.showEdit=function(t){var a=t[0];if(!a.classList.contains("smiley")){e(t),this.modal.setTitle(WCF.Language.get("wcf.editor.image.edit")),this.modal.getActionButton().text(WCF.Language.get("wcf.global.button.save")),this.modal.getDeleteButton().text(WCF.Language.get("wcf.global.button.delete")),elById("redactor-image-source").value=a.src;var i=elById("redactor-image-float");a.classList.contains("messageFloatObjectLeft")?i.value="left":a.classList.contains("messageFloatObjectRight")&&(i.value="right"),a.classList.contains("woltlabAttachment")&&elRemove(elById("redactor-image-source-container"))}}.bind(this);var a=this.image.update;this.image.update=function(){var t=this.observe.image[0],e=elById("redactor-image-source"),i=function(t,e){$('<small class="innerError" />').text(e).insertAfter(t)};if(!t.classList.contains("woltlabAttachment")){var r=e.value.trim();if(""===r)return i(e,WCF.Language.get("wcf.global.form.error.empty"));if(!r.match(this.opts.regexps.url))return i(e,WCF.Language.get("wcf.editor.image.source.error.invalid"));if(this.opts.woltlab.forceSecureImages&&0===r.indexOf("http://"))return i(e,WCF.Language.get("wcf.editor.image.source.error.insecure"));if(!this.WoltLabImage.isValidSource(r))return i(e,WCF.Language.get("wcf.editor.image.source.error.blocked"));t.src=r}t.classList.remove("messageFloatObjectLeft"),t.classList.remove("messageFloatObjectRight");var o=elById("redactor-image-float").value;"left"!==o&&"right"!==o||t.classList.add("messageFloatObject"+WCF.String.ucfirst(o)),a.call(this),t.removeAttribute("alt"),t.removeAttribute("title"),this.caret.after(t)}.bind(this),this.opts.modal["image-edit"]='<div class="section"><dl id="redactor-image-source-container"><dt><label for="redactor-image-source">'+WCF.Language.get("wcf.editor.image.source")+'</label></dt><dd><input type="text" id="redactor-image-source" class="long"></dd></dl><dl><dt><label for="redactor-image-link">'+WCF.Language.get("wcf.editor.image.link")+'</label></dt><dd><input type="text" id="redactor-image-link" class="long"></dd></dl><dl><dt><label for="redactor-image-float">'+WCF.Language.get("wcf.editor.image.float")+'</label></dt><dd><select id="redactor-image-float"><option value="none">'+WCF.Language.get("wcf.global.noSelection")+'</option><option value="left">'+WCF.Language.get("wcf.editor.image.float.left")+'</option><option value="right">'+WCF.Language.get("wcf.editor.image.float.right")+'</option></select></dd></dl><input id="redactor-image-title" style="display: none"><input id="redactor-image-caption" style="display: none"><div class="formSubmit"><button id="redactor-modal-button-action" class="buttonPrimary">Insert</button><button id="redactor-modal-button-delete" class="redactor-modal-button-offset">Delete</button></div></div>'},add:function(){this.modal.load("image-edit",WCF.Language.get("wcf.editor.image.insert")),this.modal.show(),this.modal.getDeleteButton().hide();var t=this.modal.getActionButton()[0];t.addEventListener(WCF_CLICK_EVENT,this.WoltLabImage.insert),t.textContent=WCF.Language.get("wcf.global.button.insert"),this.WoltLabModal.rebuild()},insert:function(t){t.preventDefault(),this.modal.getModal().find(".innerError").remove();var e=elById("redactor-image-source"),a=function(t,e){$('<small class="innerError" />').text(e).insertAfter(t)},i=e.value.trim();if(""===i)return a(e,WCF.Language.get("wcf.global.form.error.empty"));if(!i.match(this.opts.regexps.url))return a(e,WCF.Language.get("wcf.editor.image.source.error.invalid"));if(this.opts.woltlab.forceSecureImages&&0===i.indexOf("http://"))return a(e,WCF.Language.get("wcf.editor.image.source.error.insecure"));if(!this.WoltLabImage.isValidSource(i))return a(e,WCF.Language.get("wcf.editor.image.source.error.blocked"));var r=elById("redactor-image-link"),o=r.value.trim();if(""!==o&&!o.match(this.opts.regexps.url))return a(r,WCF.Language.get("wcf.editor.image.link.error.invalid"));var l=elById("redactor-image-float").value,s="";"left"!==l&&"right"!==l||(s="messageFloatObject"+WCF.String.ucfirst(l));var n,d='<img src="'+WCF.String.escapeHTML(i)+'"'+(s?' class="'+s+'"':"")+">";o&&(n=WCF.getUUID(),d='<a href="'+WCF.String.escapeHTML(o)+'" data-uuid="'+n+'">'+d+"</a>"),this.modal.close(),this.buffer.set(),this.insert.html(d),n&&window.setTimeout(function(){var t=elBySel('a[data-uuid="'+n+'"]',this.core.editor()[0]);t&&(t.removeAttribute("data-uuid"),this.caret.after(t))}.bind(this),1)},isValidSource:function(t){var e=elCreate("a");if(e.href=t,""===e.hostname)return!0;if(this.opts.woltlab.images.secureOnly&&"https:"!==e.protocol)return!1;if(!this.opts.woltlab.images.external){var a=!1,i=[];if(this.opts.woltlab.images.whitelist.forEach(function(t){0===t.indexOf("*.")?i.push(t.replace(/^\*\./,"")):e.hostname===t&&(a=!0)}),a||i.forEach(function(t){e.hostname.substr(-1*t.length)===t&&(a=!0)}),!a)return!1}return!0},validateImages:function(){elBySelAll("img:not(.smiley):not(.woltlabAttachment)",this.core.editor()[0],function(t){this.WoltLabImage.isValidSource(t.src)||t.classList.add("editorImageBlocked")}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabImage=function(){"use strict";return{init:function(){var t;this.opts.woltlab.allowImages&&(t=this.button.add("woltlabImage",""),this.button.addCallback(t,this.WoltLabImage.add));var i=this.image.showEdit;this.image.showEdit=function(t){var e,a=t[0];a.classList.contains("smiley")||(i(t),this.modal.setTitle(WCF.Language.get("wcf.editor.image.edit")),this.modal.getActionButton().text(WCF.Language.get("wcf.global.button.save")),this.modal.getDeleteButton().text(WCF.Language.get("wcf.global.button.delete")),elById("redactor-image-source").value=a.src,e=elById("redactor-image-float"),a.classList.contains("messageFloatObjectLeft")?e.value="left":a.classList.contains("messageFloatObjectRight")&&(e.value="right"),a.classList.contains("woltlabAttachment")&&elRemove(elById("redactor-image-source-container")))}.bind(this);var o=this.image.update;this.image.update=function(){function t(t,e){$('<small class="innerError" />').text(e).insertAfter(t)}var e=this.observe.image[0],a=elById("redactor-image-source");if(!e.classList.contains("woltlabAttachment")){var i=a.value.trim();if(""===i)return t(a,WCF.Language.get("wcf.global.form.error.empty"));if(!i.match(this.opts.regexps.url))return t(a,WCF.Language.get("wcf.editor.image.source.error.invalid"));if(this.opts.woltlab.forceSecureImages&&0===i.indexOf("http://"))return t(a,WCF.Language.get("wcf.editor.image.source.error.insecure"));if(!this.WoltLabImage.isValidSource(i))return t(a,WCF.Language.get("wcf.editor.image.source.error.blocked"));e.src=i}e.classList.remove("messageFloatObjectLeft"),e.classList.remove("messageFloatObjectRight");var r=elById("redactor-image-float").value;"left"!==r&&"right"!==r||e.classList.add("messageFloatObject"+WCF.String.ucfirst(r)),o.call(this),e.removeAttribute("alt"),e.removeAttribute("title"),this.caret.after(e)}.bind(this),this.opts.modal["image-edit"]='<div class="section"><dl id="redactor-image-source-container"><dt><label for="redactor-image-source">'+WCF.Language.get("wcf.editor.image.source")+'</label></dt><dd><input type="text" id="redactor-image-source" class="long"></dd></dl><dl><dt><label for="redactor-image-link">'+WCF.Language.get("wcf.editor.image.link")+'</label></dt><dd><input type="text" id="redactor-image-link" class="long"></dd></dl><dl><dt><label for="redactor-image-float">'+WCF.Language.get("wcf.editor.image.float")+'</label></dt><dd><select id="redactor-image-float"><option value="none">'+WCF.Language.get("wcf.global.noSelection")+'</option><option value="left">'+WCF.Language.get("wcf.editor.image.float.left")+'</option><option value="right">'+WCF.Language.get("wcf.editor.image.float.right")+'</option></select></dd></dl><input id="redactor-image-title" style="display: none"><input id="redactor-image-caption" style="display: none"><div class="formSubmit"><button id="redactor-modal-button-action" class="buttonPrimary">Insert</button><button id="redactor-modal-button-delete" class="redactor-modal-button-offset">Delete</button></div></div>'},add:function(){this.modal.load("image-edit",WCF.Language.get("wcf.editor.image.insert")),this.modal.show(),this.modal.getDeleteButton().hide();var t=this.modal.getActionButton()[0];t.addEventListener(WCF_CLICK_EVENT,this.WoltLabImage.insert),t.textContent=WCF.Language.get("wcf.global.button.insert"),this.WoltLabModal.rebuild()},insert:function(t){t.preventDefault(),this.modal.getModal().find(".innerError").remove();function e(t,e){$('<small class="innerError" />').text(e).insertAfter(t)}var a=elById("redactor-image-source"),i=a.value.trim();if(""===i)return e(a,WCF.Language.get("wcf.global.form.error.empty"));if(!i.match(this.opts.regexps.url))return e(a,WCF.Language.get("wcf.editor.image.source.error.invalid"));if(this.opts.woltlab.forceSecureImages&&0===i.indexOf("http://"))return e(a,WCF.Language.get("wcf.editor.image.source.error.insecure"));if(!this.WoltLabImage.isValidSource(i))return e(a,WCF.Language.get("wcf.editor.image.source.error.blocked"));var r=elById("redactor-image-link"),o=r.value.trim();if(""!==o&&!o.match(this.opts.regexps.url))return e(r,WCF.Language.get("wcf.editor.image.link.error.invalid"));var l=elById("redactor-image-float").value,s="";"left"!==l&&"right"!==l||(s="messageFloatObject"+WCF.String.ucfirst(l));var n,d='<img src="'+WCF.String.escapeHTML(i)+'"'+(s?' class="'+s+'"':"")+">";o&&(n=WCF.getUUID(),d='<a href="'+WCF.String.escapeHTML(o)+'" data-uuid="'+n+'">'+d+"</a>"),this.modal.close(),this.buffer.set(),this.insert.html(d),n&&window.setTimeout(function(){var t=elBySel('a[data-uuid="'+n+'"]',this.core.editor()[0]);t&&(t.removeAttribute("data-uuid"),this.caret.after(t))}.bind(this),1)},isValidSource:function(t){var e=elCreate("a");if(e.href=t,""===e.hostname)return!0;if(this.opts.woltlab.images.secureOnly&&"https:"!==e.protocol)return!1;if(!this.opts.woltlab.images.external){var a=!1,i=[];if(this.opts.woltlab.images.whitelist.forEach(function(t){0===t.indexOf("*.")?i.push(t.replace(/^\*\./,"")):e.hostname===t&&(a=!0)}),a||i.forEach(function(t){e.hostname.substr(-1*t.length)===t&&(a=!0)}),!a)return!1}return!0},validateImages:function(){elBySelAll("img:not(.smiley):not(.woltlabAttachment)",this.core.editor()[0],function(t){this.WoltLabImage.isValidSource(t.src)||t.classList.add("editorImageBlocked")}.bind(this))}}}; })(this);
 
 // plugins/WoltLabIndent.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabIndent=function(){"use strict";return{init:function(){if(this.detect.isFirefox()){var e,t,i=this.indent.decrease;this.indent.decrease=function(){if(this.list.get()){var n=$(this.selection.current()).closest("li",this.core.editor()[0]);if(0===n.closest("ul, ol",this.core.editor()[0]).parent().closest("ul, ol",this.core.editor()[0]).length){var r=n[0];if(null!==elBySel("ul, ol",r)){this.buffer.set(),this.selection.save();var l,o,s=r.previousElementSibling;if(null!==s){for(l=elCreate(r.parentNode.nodeName.toLowerCase());s.nextSibling;)l.appendChild(s.nextSibling);o=s.parentNode,o.parentNode.insertBefore(l,o.nextSibling)}if(null!==r.nextElementSibling){for(l=elCreate(r.parentNode.nodeName.toLowerCase());r.nextSibling;)l.appendChild(r.nextSibling);o=r.parentNode,o.parentNode.insertBefore(l,o.nextSibling)}for(o=r.parentNode;r.childNodes.length;)o.parentNode.insertBefore(r.childNodes[0],o);return elRemove(o),void this.selection.restore()}}else{elBySelAll("woltlab-list-marker",this.core.editor()[0],elRemove),this.selection.save(),e=elCreate("woltlab-list-marker"),n[0].insertBefore(e,n[0].firstChild);var a=n[0].lastElementChild;if("BR"===a.nodeName){for(var d="",s=a;s=s.nextSibling;)d+=s.textContent;""===d.replace(/\u200B/g,"").trim()&&elRemove(a)}t=elCreate("woltlab-list-marker"),n[0].appendChild(t),this.selection.restore()}i.call(this)}}.bind(this);var n=this.indent.removeEmpty;this.indent.removeEmpty=function(){if(e&&e.parentNode){for(var i,r=elCreate("li");(i=e.nextSibling)&&i!==t;)r.appendChild(i);e.parentNode.insertBefore(r,e),elBySelAll("woltlab-list-marker",this.core.editor()[0],elRemove),e=void 0,t=void 0}n.call(this)}.bind(this)}this.indent.repositionItem=function(e){var t=e.next();0===t.length||"UL"===t[0].tagName&&"OL"===t[0].tagName||e.append(t);var i=e.prev();if(0!==i.length&&"LI"!==i[0].tagName){this.selection.save();e.closest("li",this.core.editor()[0]).after(e),this.selection.restore()}}.bind(this),this.indent.normalize=function(){if(this.detect.isFirefox()){var e=this.selection.block();if(e&&"P"===e.nodeName){var t=e.previousElementSibling;t&&"BR"===t.nodeName&&elRemove(t)}}this.core.editor().find("li").each($.proxy(function(e,t){var i=$(t),n="";0!==this.opts.keepStyleAttr.length&&(n=","+this.opts.keepStyleAttr.join(",")),i.find(this.opts.inlineTags.join(",")).not("img"+n).not("span").removeAttr("style");var r=i.parent();if(0!==r.length&&"LI"===r[0].tagName){for(;t.nextSibling;)t.appendChild(t.nextSibling);return void r.after(i)}var l=i.next();0===l.length||"UL"!==l[0].tagName&&"OL"!==l[0].tagName||i.append(l)},this))}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabIndent=function(){"use strict";return{init:function(){var s,a,d,i;this.detect.isFirefox()&&(d=this.indent.decrease,this.indent.decrease=function(){if(this.list.get()){var e=$(this.selection.current()).closest("li",this.core.editor()[0]);if(0===e.closest("ul, ol",this.core.editor()[0]).parent().closest("ul, ol",this.core.editor()[0]).length){var t,i,n=e[0];if(null!==elBySel("ul, ol",n)){if(this.buffer.set(),this.selection.save(),null!==(r=n.previousElementSibling)){for(t=elCreate(n.parentNode.nodeName.toLowerCase());r.nextSibling;)t.appendChild(r.nextSibling);(i=r.parentNode).parentNode.insertBefore(t,i.nextSibling)}if(null!==n.nextElementSibling){for(t=elCreate(n.parentNode.nodeName.toLowerCase());n.nextSibling;)t.appendChild(n.nextSibling);(i=n.parentNode).parentNode.insertBefore(t,i.nextSibling)}for(i=n.parentNode;n.childNodes.length;)i.parentNode.insertBefore(n.childNodes[0],i);return elRemove(i),void this.selection.restore()}}else{elBySelAll("woltlab-list-marker",this.core.editor()[0],elRemove),this.selection.save(),s=elCreate("woltlab-list-marker"),e[0].insertBefore(s,e[0].firstChild);var l=e[0].lastElementChild;if("BR"===l.nodeName){for(var o="",r=l;r=r.nextSibling;)o+=r.textContent;""===o.replace(/\u200B/g,"").trim()&&elRemove(l)}a=elCreate("woltlab-list-marker"),e[0].appendChild(a),this.selection.restore()}d.call(this)}}.bind(this),i=this.indent.removeEmpty,this.indent.removeEmpty=function(){if(s&&s.parentNode){for(var e,t=elCreate("li");(e=s.nextSibling)&&e!==a;)t.appendChild(e);s.parentNode.insertBefore(t,s),elBySelAll("woltlab-list-marker",this.core.editor()[0],elRemove),a=s=void 0}i.call(this)}.bind(this)),this.indent.repositionItem=function(e){var t=e.next();0===t.length||"UL"===t[0].tagName&&"OL"===t[0].tagName||e.append(t);var i=e.prev();0!==i.length&&"LI"!==i[0].tagName&&(this.selection.save(),e.closest("li",this.core.editor()[0]).after(e),this.selection.restore())}.bind(this),this.indent.normalize=function(){var e,t;this.detect.isFirefox()&&(!(e=this.selection.block())||"P"!==e.nodeName||(t=e.previousElementSibling)&&"BR"===t.nodeName&&elRemove(t)),this.core.editor().find("li").each($.proxy(function(e,t){var i=$(t),n="";0!==this.opts.keepStyleAttr.length&&(n=","+this.opts.keepStyleAttr.join(",")),i.find(this.opts.inlineTags.join(",")).not("img"+n).not("span").removeAttr("style");var l=i.parent();if(0===l.length||"LI"!==l[0].tagName){var o=i.next();0===o.length||"UL"!==o[0].tagName&&"OL"!==o[0].tagName||i.append(o)}else{for(;t.nextSibling;)t.appendChild(t.nextSibling);l.after(i)}},this))}.bind(this)}}}; })(this);
 
 // plugins/WoltLabInlineCode.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabInlineCode=function(){"use strict";var e;return{init:function(){this.opts.activeButtonsStates.kbd="tt",require(["Environment","EventHandler"],function(t,o){e=t,o.add("com.woltlab.wcf.redactor2","bbcode_tt_"+this.$element[0].id,this.WoltLabInlineCode._toggle.bind(this))}.bind(this))},_toggle:function(t){var o;t.cancel=!0;var n=window.getSelection();if(n.isCollapsed){o=null;var r=n.anchorNode;r.nodeType===Node.TEXT_NODE&&(r=r.parentNode);var d=!1;if("KBD"===r.nodeName&&""!==r.textContent.replace(/\u200b/g,"")){var i=n.anchorNode,a=n.anchorOffset;i.nodeType===Node.TEXT_NODE&&0===a?o=i:i===r&&(0===a?d=!0:o=r.childNodes[a-1])}if(!1===d&&null!==o)for(var l,c=0,N=r.childNodes.length;c<N;c++){if((l=r.childNodes[c])===o){d=!0;break}if(l.nodeType!==Node.TEXT_NODE||""!==l.textContent.replace(/\u200b/g,""))break}if(d){var f=r.previousSibling;return null!==f&&f.nodeType===Node.TEXT_NODE&&"​"===f.textContent||(f=document.createTextNode("​"),r.parentNode.insertBefore(f,r)),void this.caret.before(r)}}if(this.button.toggle({},"kbd","func","inline.format"),o=n.anchorNode,o.nodeType===Node.TEXT_NODE&&(o=o.parentNode),"KBD"===o.nodeName){var s=o.nextSibling;if("ios"===e.platform()&&"safari"===e.browser())return void(s&&"BR"===s.nodeName&&o.parentNode.insertBefore(document.createTextNode("​"),s));for(;s;){if(s.nodeType!==Node.TEXT_NODE||s.textContent.length)return;s=s.nextSibling}s?s.textContent="​":o.parentNode.appendChild(document.createTextNode("​"))}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabInlineCode=function(){"use strict";var s;return{init:function(){this.opts.activeButtonsStates.kbd="tt",require(["Environment","EventHandler"],function(e,t){s=e,t.add("com.woltlab.wcf.redactor2","bbcode_tt_"+this.$element[0].id,this.WoltLabInlineCode._toggle.bind(this))}.bind(this))},_toggle:function(e){var t;e.cancel=!0;var o=window.getSelection();if(o.isCollapsed){t=null;var n=o.anchorNode;n.nodeType===Node.TEXT_NODE&&(n=n.parentNode);var r,d,i=!1;if("KBD"===n.nodeName&&""!==n.textContent.replace(/\u200b/g,"")&&(r=o.anchorNode,d=o.anchorOffset,r.nodeType===Node.TEXT_NODE&&0===d?t=r:r===n&&(0===d?i=!0:t=n.childNodes[d-1])),!1===i&&null!==t)for(var a,l=0,c=n.childNodes.length;l<c;l++){if((a=n.childNodes[l])===t){i=!0;break}if(a.nodeType!==Node.TEXT_NODE||""!==a.textContent.replace(/\u200b/g,""))break}if(i){var N=n.previousSibling;return null!==N&&N.nodeType===Node.TEXT_NODE&&"​"===N.textContent||(N=document.createTextNode("​"),n.parentNode.insertBefore(N,n)),void this.caret.before(n)}}if(this.button.toggle({},"kbd","func","inline.format"),(t=o.anchorNode).nodeType===Node.TEXT_NODE&&(t=t.parentNode),"KBD"===t.nodeName){var f=t.nextSibling;if("ios"===s.platform()&&"safari"===s.browser())return void(f&&"BR"===f.nodeName&&t.parentNode.insertBefore(document.createTextNode("​"),f));for(;f;){if(f.nodeType!==Node.TEXT_NODE||f.textContent.length)return;f=f.nextSibling}f?f.textContent="​":t.parentNode.appendChild(document.createTextNode("​"))}}}}; })(this);
 
 // plugins/WoltLabInsert.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabInsert=function(){"use strict";return{init:function(){function e(t){var o=t.querySelector("p > p");if(null!==o){for(var r=o.parentElement,i=r.parentElement;r.childNodes.length;)i.insertBefore(r.childNodes[0],r);r.remove(),e(t)}}var t=this.opts.woltlab.placeholderCallback,o=this.insert.html;this.insert.html=function(r,i){t&&(t=t());var n=window.getSelection();if(n.rangeCount&&"IMG"===n.anchorNode.nodeName&&this.caret.after(n.anchorNode),this.placeholder.hide(),this.core.editor().focus(),this.detect.isFirefox()){var s=n.anchorNode.nodeType===Node.TEXT_NODE?n.anchorNode.parentNode:n.anchorNode;null===s.closest(".redactor-layer")&&(this.selection.restore(),s=n.anchorNode.nodeType===Node.TEXT_NODE?n.anchorNode.parentNode:n.anchorNode,null===s.closest(".redactor-layer")&&(this.WoltLabCaret.endOfEditor(),this.selection.save()))}var a=this.selection.block(),c=""===this.$editor[0].innerHTML.replace(/<\/?p>/g,"").replace(/<br>/g,"").replace(/\u200B/g,"").trim();if(o.call(this,r,i),c&&(a=this.$editor[0].firstElementChild),a&&"P"===a.nodeName&&a.nextElementSibling){var l=!1;0===a.childElementCount&&""===a.textContent.replace(/\u200B/g,"").trim()?l=!0:1===a.childElementCount&&"<br>"===a.innerHTML&&(l=!0),l&&elRemove(a)}this.detect.isFirefox()&&(this.selection.save(),e(this.$editor[0]),this.selection.restore()),n.rangeCount&&"IMG"===n.anchorNode.nodeName&&this.caret.after(n.anchorNode)}.bind(this);var r=this.insert.text;this.insert.text=function(e){t&&(t=t()),this.core.editor().focus(),this.selection.restore(),elClosest(window.getSelection().anchorNode,".redactor-layer")!==this.core.editor()[0]&&this.WoltLabCaret.endOfEditor(),r.call(this,e),this.selection.saveInstant()}.bind(this),this.insert.placeHtml=function(e){var t=!1;e.forEach(function(e){e instanceof Element&&e.classList.contains("woltlab-bbcode-marker")&&(t=!0)});var o=document.createElement("span");o.id="redactor-insert-marker",o=this.insert.node(o),$(o).before(e),t||(this.selection.restore(),this.caret.after(o)),$(o).remove()}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabInsert=function(){"use strict";return{init:function(){var s=this.opts.woltlab.placeholderCallback;var a=this.insert.html;this.insert.html=function(e,t){s=s&&s();var o=window.getSelection();o.rangeCount&&"IMG"===o.anchorNode.nodeName&&this.caret.after(o.anchorNode),this.placeholder.hide(),this.core.editor().focus(),!this.detect.isFirefox()||null===(o.anchorNode.nodeType===Node.TEXT_NODE?o.anchorNode.parentNode:o.anchorNode).closest(".redactor-layer")&&(this.selection.restore(),null===(o.anchorNode.nodeType===Node.TEXT_NODE?o.anchorNode.parentNode:o.anchorNode).closest(".redactor-layer")&&(this.WoltLabCaret.endOfEditor(),this.selection.save()));var r,i=this.selection.block(),n=""===this.$editor[0].innerHTML.replace(/<\/?p>/g,"").replace(/<br>/g,"").replace(/\u200B/g,"").trim();a.call(this,e,t),n&&(i=this.$editor[0].firstElementChild),i&&"P"===i.nodeName&&i.nextElementSibling&&(r=!1,(0===i.childElementCount&&""===i.textContent.replace(/\u200B/g,"").trim()||1===i.childElementCount&&"<br>"===i.innerHTML)&&(r=!0),r&&elRemove(i)),this.detect.isFirefox()&&(this.selection.save(),function e(t){var o=t.querySelector("p > p");if(null!==o){for(var r=o.parentElement,i=r.parentElement;r.childNodes.length;)i.insertBefore(r.childNodes[0],r);r.remove(),e(t)}}(this.$editor[0]),this.selection.restore()),o.rangeCount&&"IMG"===o.anchorNode.nodeName&&this.caret.after(o.anchorNode)}.bind(this);var t=this.insert.text;this.insert.text=function(e){s=s&&s(),this.core.editor().focus(),this.selection.restore(),elClosest(window.getSelection().anchorNode,".redactor-layer")!==this.core.editor()[0]&&this.WoltLabCaret.endOfEditor(),t.call(this,e),this.selection.saveInstant()}.bind(this),this.insert.placeHtml=function(e){var t=!1;e.forEach(function(e){e instanceof Element&&e.classList.contains("woltlab-bbcode-marker")&&(t=!0)});var o=document.createElement("span");o.id="redactor-insert-marker",o=this.insert.node(o),$(o).before(e),t||(this.selection.restore(),this.caret.after(o)),$(o).remove()}.bind(this)}}}; })(this);
 
 // plugins/WoltLabKeydown.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabKeydown=function(){"use strict";var e=!1,t=[];return{init:function(){var t=window.getSelection();require(["Environment"],function(t){e="safari"===t.browser()});var i=this.keydown.init;this.keydown.init=function(e){var n;if(this.detect.isFirefox()&&t.isCollapsed&&e.which===this.keyCode.BACKSPACE&&(n=t.anchorNode,n.nodeType===Node.ELEMENT_NODE&&t.anchorOffset>0&&(n=n.childNodes[t.anchorOffset-1]),n.nodeType===Node.TEXT_NODE&&"​"===n.textContent)){for(var o=[],r=n;r=r.previousSibling;){if(r.nodeType===Node.ELEMENT_NODE){"IMG"!==r.nodeName&&(o=[]);break}if(r.nodeType===Node.TEXT_NODE){var l=r.textContent;if(""!==l&&"​"!==l){o=[];break}o.push(r)}}o.length&&o.forEach(elRemove)}if((e.originalEvent.which===this.keyCode.BACKSPACE||e.originalEvent.which===this.keyCode.DELETE)&&t.isCollapsed){var s=this.selection.block();if("P"===s.nodeName){if(this.list.combineAfterAndBefore(s))return void e.originalEvent.preventDefault();if(this.utils.isEmpty(s.innerHTML)&&s.previousElementSibling!==s.nextElementSibling){var a=null,d=null;return e.originalEvent.which===this.keyCode.BACKSPACE?null===s.previousElementSibling?d=s.nextElementSibling:a=s.previousElementSibling:null===s.nextElementSibling?a=s.previousElementSibling:d=s.nextElementSibling,elRemove(s),null===d?("OL"!==a.nodeName&&"UL"!==a.nodeName||(a=a.lastElementChild),this.caret.end(a)):("OL"!==d.nodeName&&"UL"!==d.nodeName||(d=d.firstElementChild),this.caret.start(d)),void e.originalEvent.preventDefault()}}else{if(e.originalEvent.which===this.keyCode.DELETE&&-1!==["H1","H2","H3","H4","H5","H6"].indexOf(s.nodeName)&&this.utils.isEmpty(s.innerHTML)){var h=s.nextElementSibling;return h?h=s.nextElementSibling:(h=elCreate("p"),h.innerHTML=this.opts.invisibleSpace,s.parentNode.appendChild(h)),s.parentNode.removeChild(s),this.caret.start(h),void e.originalEvent.preventDefault()}if(this.detect.isWebkit()&&"LI"===s.nodeName&&e.which===this.keyCode.DELETE){var c=t.anchorNode;if(c.nodeType===Node.TEXT_NODE&&c.textContent.length===t.anchorOffset&&c.parentNode.lastChild===c){var f=s.nextElementSibling;if(f&&"LI"===f.nodeName){for(this.buffer.set(),this.selection.save();f.childNodes.length;)s.appendChild(f.childNodes[0]);return elRemove(f),this.selection.restore(),void e.preventDefault()}}}}}var u=null;if(e.which===this.keyCode.BACKSPACE&&this.detect.isFirefox()){var v=this.selection.block();if(v&&"P"===v.tagName&&this.utils.isStartOfElement(v)){var m=v.previousElementSibling;if(m&&("OL"===m.nodeName||"UL"===m.nodeName)){this.buffer.set(),this.selection.save();for(var p=m.lastElementChild;v.childNodes.length;)p.appendChild(v.childNodes[0]);return elRemove(v),this.selection.restore(),void e.preventDefault()}m&&"P"===m.nodeName&&null!==(u=m.lastElementChild)&&"BR"!==u.nodeName&&(u=null)}}if(!1===i.call(this,e)||e.originalEvent.defaultPrevented){if(null!==u&&this.detect.isFirefox()){var g=t.getRangeAt(0);1===g.startOffset&&g.startContainer.firstElementChild===u&&elRemove(u)}}else if(e=e.originalEvent,!(39!==e.which||e.ctrlKey||e.shiftKey||e.metaKey||e.altKey)){if(!t.isCollapsed)return;var N=t.anchorNode;if(N.nodeType!==Node.TEXT_NODE||t.getRangeAt(0).startOffset!==N.textContent.length)return;var b=N.parentNode;if("KBD"!==b.nodeName)return;var y=!0;for(n=b;n&&n!==this.core.editor()[0];){if(null!==n.nextSibling){for(;n.nextSibling&&n.nextSibling.nodeType===Node.TEXT_NODE&&0===n.nextSibling.textContent.length;)n.parentNode.removeChild(n.nextSibling);if(n.nextSibling&&"BR"!==n.nextSibling.nodeName||null!==n.nextSibling.nextSibling){y=!1;break}}n=n.parentNode}y&&b.parentNode.insertBefore(document.createTextNode("​"),b.nextSibling)}}.bind(this);var n=window.navigator.userAgent.toLowerCase();-1!==n.indexOf("linux")&&-1!==n.indexOf("android")&&-1!==n.indexOf("chrome")&&(this.keydown.checkEvents=function(){this.core.addEvent(!1)}.bind(this)),this.core.editor().off("keydown.redactor"),this.core.editor().on("keydown.redactor",this.keydown.init.bind(this)),this.keydown.onArrowDown=function(){for(var e,t,i=this.WoltLabKeydown._getBlocks(),n=0;n<i.length;n++)if(t=i[n]){if(!this.utils.isEndOfElement(t))continue;if(null!==(e=t.nextElementSibling)&&"P"===e.nodeName)break;return void this.keydown.insertAfterLastElement(t)}}.bind(this),this.keydown.onArrowUp=function(){for(var e,t,i=this.WoltLabKeydown._getBlocks(),n=0;n<i.length;n++)if(t=i[n]){if(!this.utils.isStartOfElement())break;if(null!==(e=t.previousElementSibling)&&"P"!==e.nodeName){var o=$(this.opts.emptyHtml)[0];t.parentNode.insertBefore(o,t),this.caret.end(o);break}return void this.keydown.insertBeforeFirstElement(t)}}.bind(this);var o=function(i){if(!1===this.core.callback("enter",i))return i.preventDefault(),!1;if(this.keydown.blockquote&&!0===this.keydown.exitFromBlockquote(i))return!1;if(this.keydown.pre)return this.keydown.insertNewLine(i);if(this.keydown.blockquote||this.keydown.figcaption)return this.keydown.insertBreakLine(i);if(this.keydown.figure)setTimeout($.proxy(function(){this.keydown.replaceToParagraph("FIGURE")},this),1);else if(this.keydown.block){var n=null;if(this.detect.isFirefox()&&"P"===this.keydown.block.nodeName&&t.isCollapsed){var o=elClosest(t.getRangeAt(0).startContainer,"a");null!==o&&null===elBySel("br",o)&&(n=this.keydown.block)}if(setTimeout($.proxy(function(){if(this.keydown.replaceToParagraph("DIV"),null!==n&&null!==n.previousElementSibling){var e=[];if(elBySelAll("a",n.previousElementSibling,function(t){e.push(t)}),e.length){var t=e[e.length-1],i=elBySel("br",t);null!==i&&elRemove(i)}}},this),1),"LI"===this.keydown.block.tagName){var r=this.selection.current(),l=elClosest(r,"li");if(this.utils.isRedactorParent(l)&&this.utils.isEmpty(l.innerHTML)&&null===l.nextElementSibling&&(l.innerHTML=e?"<br>":"",e)){var s=document.createRange();s.selectNodeContents(l),s.collapse(!1),t.removeAllRanges(),t.addRange(s)}}}else if(!this.keydown.block)return this.keydown.insertParagraph(i);return this.detect.isFirefox()&&this.utils.isInline(this.keydown.parent)?(this.keydown.insertBreakLine(i),void setTimeout(function(){for(var e=this.selection.block(),t=this.selection.inline();t&&t!==e;){if("A"===t.nodeName){var i=!1;if(0===t.childNodes.length?i=!0:""===t.textContent.replace(/\u200B/g,"").trim()&&(i=!0,elBySelAll("*",t,function(e){"SPAN"!==e.nodeName&&(i=!1)})),i){for(;t.childNodes.length;)t.parentNode.insertBefore(t.childNodes[0],t);elRemove(t);break}}t=t.parentNode}}.bind(this),1)):void 0}.bind(this);this.keydown.onEnter=function(e){var t=this.keydown.blockquote;t&&(this.keydown.blockquote=!1);var i=o.call(this,e);return t&&(this.keydown.blockquote=t),i}.bind(this),this.keydown.replaceToParagraph=function(e){var t=this.selection.block(),i=t.innerHTML.replace(/<br\s?\/?>/gi,"");if(t.tagName===e&&this.utils.isEmpty(i)&&!$(t).hasClass("redactor-in")){var n=document.createElement("p");$(t).replaceWith(n);var o=document.createRange();o.setStart(n,0);var r=document.createTextNode("​");o.insertNode(r),o.setStartAfter(r),o.collapse(!0);var l=window.getSelection();return l.removeAllRanges(),l.addRange(o),!1}"P"===t.tagName&&$(t).removeAttr("style")}.bind(this),this.keydown.onShiftEnter=function(e){return this.buffer.set(),this.keydown.pre?this.keydown.insertNewLine(e):this.insert.raw("<br>​")}.bind(this);var r=this.keydown.onTab;this.keydown.onTab=function(e,i){if(!this.keydown.pre){var n=$(this.selection.current()).closest("ul, ol, td",this.core.editor()[0]);if(0===n.length)return!0;if(n=n[0],"TD"===n.nodeName){var o=null;if(e.originalEvent.shiftKey?null===(o=n.previousElementSibling)&&null!==(o=n.parentNode.previousElementSibling)&&(o=o.lastElementChild):null===(o=n.nextElementSibling)&&(o=n.parentNode.nextElementSibling,null===o&&(this.table.addRowBelow(),o=n.parentNode.nextElementSibling),o=o.firstElementChild),null!==o)if(this.utils.isEmpty(o.innerHTML))this.caret.end(o);else{var l=document.createRange();l.selectNodeContents(o),t.removeAllRanges(),t.addRange(l)}return e.originalEvent.preventDefault(),!1}}return r.call(this,e,i)}.bind(this);var l=this.keydown.formatEmpty;this.keydown.formatEmpty=function(e){for(var t,i=this.$editor[0],n=0,o=i.childElementCount;n<o;n++)if(t=i.children[n],"P"!==t.nodeName&&this.utils.isBlockTag(t.nodeName))return;return l.call(this,e)}.bind(this);var s=this.keydown.removeInvisibleSpace;this.keydown.removeInvisibleSpace=function(){this.keydown.current!==this.$editor[0]&&s.call(this)}.bind(this),require(["Core","Environment"],function(e,t){if("desktop"===t.platform()){var i=this.$editor[0].closest("form, .message, .jsOuterEditorContainer");if(null!==i){var n=elBySel(".formSubmit",i);if(null!==n){var o=elBySel('input[type="submit"], button[data-type="save"], button[accesskey="s"]',n);o&&(o.removeAttribute("accesskey"),this.WoltLabEvent.register("keydown",function(t){if(83===t.event.which){var i=!1;window.navigator.platform.match(/^Mac/)?t.event.ctrlKey&&t.event.altKey&&(i=!0):t.event.altKey&&!t.event.ctrlKey&&(i=!0),i&&(t.cancel=!0,"function"==typeof o.click?o.click():e.triggerEvent(o,WCF_CLICK_EVENT))}}.bind(this)))}}}}.bind(this)),this.WoltLabKeydown._handleBackspaceAndDelete()},register:function(e){-1===t.indexOf(e)&&t.push(e)},_getBlocks:function(){for(var e=[this.keydown.blockquote,this.keydown.pre,this.keydown.figcaption],i=0,n=t.length;i<n;i++)e.push(this.utils.isTag(this.keydown.current,t[i]));return e},_handleBackspaceAndDelete:function(){var e=function(e){return null===elBySel("img",e)&&""===e.textContent.replace(/\u200B/g,"").trim()},t=function(t){var i,n=this.selection.block();if(n)if("TD"===n.nodeName){var o=n.innerHTML;"​"===o?t.preventDefault():""===o&&(t.preventDefault(),n.innerHTML="​")}else if(-1!==n.nodeName.indexOf("-")&&e(n))i=n.parentNode,i.insertBefore(this.marker.get(),n.nextSibling),elRemove(n),this.selection.restore();else if((i=n&&"P"===n.nodeName?n.parentNode:null)&&-1!==i.nodeName.indexOf("-")){var r=window.getSelection().getRangeAt(0),l=document.createRange();l.setStartBefore(n),l.setEnd(r.startContainer,r.startOffset);var s=l.cloneContents(),a=elCreate("div");if(a.appendChild(s),e(a)){t.preventDefault();var d=n.previousElementSibling,h=null;if(d)h=e(d);else for(i=n;(i=i.parentNode)&&i!==this.$editor[0];)if(d=i.previousElementSibling){h=!1;break}if(h)elRemove(d);else if(null!==h){var c=n.parentNode;if("P"===d.nodeName){d.appendChild(this.marker.get());for(var f;n.childNodes.length;){if(f=n.childNodes[0],"BR"===f.nodeName){elRemove(f);break}d.appendChild(f)}0===n.childNodes.length&&elRemove(n),this.selection.restore()}else d.appendChild(n),n.insertBefore(this.marker.get(),n.firstChild),this.selection.restore();e(c)&&elRemove(c)}else null===h&&(i=n.parentNode,e(i)&&elRemove(i))}}}.bind(this),i=function(t){var i,n=this.selection.block();if(-1!==n.nodeName.indexOf("-")&&e(n))i=n.parentNode,i.insertBefore(this.marker.get(),n.nextSibling),elRemove(n),this.selection.restore();else if((i=n&&"P"===n.nodeName?n.parentNode:null)&&-1!==i.nodeName.indexOf("-")){var o=window.getSelection().getRangeAt(0),r=document.createRange();r.setStart(o.startContainer,o.startOffset),r.setEndAfter(n);var l=r.cloneContents(),s=elCreate("div");if(s.appendChild(l),e(s)){t.preventDefault();var a=n.nextElementSibling,d=null;if(a)d=e(a);else for(i=n;(i=i.parentNode)&&i!==this.$editor[0];)if(a=i.nextElementSibling){d=!1;break}if(d)elRemove(a);else if(null!==d){var h=a.parentNode;if("P"===a.nodeName){for(;a.childNodes.length;)n.appendChild(a.childNodes[0]);elRemove(a)}else{if(n.appendChild(this.marker.get()),i=n.parentNode,-1!==a.nodeName.indexOf("-")){var c=a.firstElementChild;if(c&&"P"===c.nodeName){for(;c.childNodes.length;)n.appendChild(c.childNodes[0]);a.removeChild(c),e(a)&&elRemove(a)}}else i.insertBefore(a,n.nextSibling);this.selection.restore()}e(h)&&elRemove(h)}else null===d&&(i=n.parentNode,e(i)&&elRemove(i))}}}.bind(this),n=function(){return this.opts.blockTags.filter(function(e){return-1!==e.indexOf("-")}).join(",")}.bind(this),o=[],r=function(){elBySelAll(n(),this.core.editor()[0],function(e){null!==e.parentNode&&-1!==o.indexOf(e)&&["nextElementSibling","previousElementSibling"].forEach(function(t){for(var i,n=e[t];null!==n&&n.nodeName===e.nodeName&&-1===o.indexOf(n);){if("previousElementSibling"===t)for(var r=n.childNodes.length-1;r>=0;r--)e.insertBefore(n.childNodes[r],e.firstChild);else for(;n.childNodes.length>0;)e.appendChild(n.childNodes[0]);i=n[t],elRemove(n),n=i}})})}.bind(this),l=0,s=function(){var e=!1;elBySelAll(n(),this.core.editor()[0],function(t){var i=elData(t,"firefox-duplication-bug");if(""!==i){var n=o[parseInt(i,10)];if(null!==n&&null!==n.parentNode&&t!==n&&n.contains(t)){for(;t.childNodes.length;)t.parentNode.insertBefore(t.childNodes[0],t);return t.parentNode.removeChild(t),void(e=!0)}t.removeAttribute("data-firefox-duplication-bug")}}),e&&elBySelAll("h1,h2,h3,h4,h5,h6",this.core.editor()[0],function(e){elBySelAll("p",e,function(e){for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);e.parentNode.removeChild(e)})}),l=0}.bind(this);this.keydown.onBackspaceAndDeleteAfter=function(e){this.detect.isFirefox()&&(this.selection.isCollapsed()?e.which===this.keyCode.BACKSPACE?t(e):e.which===this.keyCode.DELETE&&i(e):e.which!==this.keyCode.BACKSPACE&&e.which!==this.keyCode.DELETE||elBySelAll(n(),this.core.editor()[0],function(e){o.push(e),elData(e,"firefox-duplication-bug",l++)}));var a=!1;if(e.which===this.keyCode.BACKSPACE&&this.selection.isCollapsed()&&this.detect.isWebkit()){var d=this.selection.block();!1!==d&&"PRE"===d.nodeName&&(a=!0)}setTimeout($.proxy(function(){var t;if(o.length>0&&(this.selection.save(),r(),s(),this.selection.restore(),o=[]),a){var i=this.selection.block();if((!1===i||"PRE"!==i.nodeName)&&(t=this.selection.current(),t.nodeType===Node.TEXT_NODE&&t.nextSibling&&"SPAN"===t.nextSibling.nodeName)){var n=t.nextSibling;if(-1!==n.style.getPropertyValue("font-family").indexOf("monospace")&&"pre-wrap"===n.style.getPropertyValue("white-space")){for(;n.childNodes.length;)n.parentNode.insertBefore(n.childNodes[0],n);elRemove(n)}}}this.code.syncFire=!1,this.keydown.removeEmptyLists();var l="";0!==this.opts.keepStyleAttr.length&&(l=","+this.opts.keepStyleAttr.join(",")),this.core.editor().find("*[style]").not("span, img, figure, iframe, #redactor-image-box, #redactor-image-editter, [data-redactor-style-cache], [data-redactor-span]"+l).removeAttr("style"),this.keydown.formatEmpty(e),t=this.selection.current(),"KBD"===t.nodeName&&0===t.innerHTML.length&&elRemove(t),this.code.syncFire=!0},this),1)}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabKeydown=function(){"use strict";var s=!1,n=[];return{init:function(){var b=window.getSelection();require(["Environment"],function(e){s="safari"===e.browser()});var y=this.keydown.init;this.keydown.init=function(e){if(this.detect.isFirefox()&&b.isCollapsed&&e.which===this.keyCode.BACKSPACE&&((N=b.anchorNode).nodeType===Node.ELEMENT_NODE&&0<b.anchorOffset&&(N=N.childNodes[b.anchorOffset-1]),N.nodeType===Node.TEXT_NODE&&"​"===N.textContent)){for(var t=[],i=N;i=i.previousSibling;){if(i.nodeType===Node.ELEMENT_NODE){"IMG"!==i.nodeName&&(t=[]);break}if(i.nodeType===Node.TEXT_NODE){var n=i.textContent;if(""!==n&&"​"!==n){t=[];break}t.push(i)}}t.length&&t.forEach(elRemove)}if((e.originalEvent.which===this.keyCode.BACKSPACE||e.originalEvent.which===this.keyCode.DELETE)&&b.isCollapsed){var o=this.selection.block();if("P"===o.nodeName){if(this.list.combineAfterAndBefore(o))return void e.originalEvent.preventDefault();if(this.utils.isEmpty(o.innerHTML)&&o.previousElementSibling!==o.nextElementSibling){var r=null,l=null;return e.originalEvent.which===this.keyCode.BACKSPACE?null===o.previousElementSibling?l=o.nextElementSibling:r=o.previousElementSibling:null===o.nextElementSibling?r=o.previousElementSibling:l=o.nextElementSibling,elRemove(o),null===l?("OL"!==r.nodeName&&"UL"!==r.nodeName||(r=r.lastElementChild),this.caret.end(r)):("OL"!==l.nodeName&&"UL"!==l.nodeName||(l=l.firstElementChild),this.caret.start(l)),void e.originalEvent.preventDefault()}}else{if(e.originalEvent.which===this.keyCode.DELETE&&-1!==["H1","H2","H3","H4","H5","H6"].indexOf(o.nodeName)&&this.utils.isEmpty(o.innerHTML)){var s=o.nextElementSibling;return s?s=o.nextElementSibling:((s=elCreate("p")).innerHTML=this.opts.invisibleSpace,o.parentNode.appendChild(s)),o.parentNode.removeChild(o),this.caret.start(s),void e.originalEvent.preventDefault()}if(this.detect.isWebkit()&&"LI"===o.nodeName&&e.which===this.keyCode.DELETE){var a=b.anchorNode;if(a.nodeType===Node.TEXT_NODE&&a.textContent.length===b.anchorOffset&&a.parentNode.lastChild===a){var d=o.nextElementSibling;if(d&&"LI"===d.nodeName){for(this.buffer.set(),this.selection.save();d.childNodes.length;)o.appendChild(d.childNodes[0]);return elRemove(d),this.selection.restore(),void e.preventDefault()}}}}}var h,c=null;if(e.which===this.keyCode.BACKSPACE&&this.detect.isFirefox()){var f=this.selection.block();if(f&&"P"===f.tagName&&this.utils.isStartOfElement(f)){var u=f.previousElementSibling;if(u&&("OL"===u.nodeName||"UL"===u.nodeName)){this.buffer.set(),this.selection.save();for(var m=u.lastElementChild;f.childNodes.length;)m.appendChild(f.childNodes[0]);return elRemove(f),this.selection.restore(),void e.preventDefault()}u&&"P"===u.nodeName&&null!==(c=u.lastElementChild)&&"BR"!==c.nodeName&&(c=null)}}if(!1===y.call(this,e)||e.originalEvent.defaultPrevented)null===c||!this.detect.isFirefox()||1===(h=b.getRangeAt(0)).startOffset&&h.startContainer.firstElementChild===c&&elRemove(c);else if(!(39!==(e=e.originalEvent).which||e.ctrlKey||e.shiftKey||e.metaKey||e.altKey)){if(!b.isCollapsed)return;var v=b.anchorNode;if(v.nodeType!==Node.TEXT_NODE||b.getRangeAt(0).startOffset!==v.textContent.length)return;var p=v.parentNode;if("KBD"!==p.nodeName)return;for(var g=!0,N=p;N&&N!==this.core.editor()[0];){if(null!==N.nextSibling){for(;N.nextSibling&&N.nextSibling.nodeType===Node.TEXT_NODE&&0===N.nextSibling.textContent.length;)N.parentNode.removeChild(N.nextSibling);if(N.nextSibling&&"BR"!==N.nextSibling.nodeName||null!==N.nextSibling.nextSibling){g=!1;break}}N=N.parentNode}g&&p.parentNode.insertBefore(document.createTextNode("​"),p.nextSibling)}}.bind(this);var e=window.navigator.userAgent.toLowerCase();-1!==e.indexOf("linux")&&-1!==e.indexOf("android")&&-1!==e.indexOf("chrome")&&(this.keydown.checkEvents=function(){this.core.addEvent(!1)}.bind(this)),this.core.editor().off("keydown.redactor"),this.core.editor().on("keydown.redactor",this.keydown.init.bind(this)),this.keydown.onArrowDown=function(){for(var e,t,i=this.WoltLabKeydown._getBlocks(),n=0;n<i.length;n++)if(t=i[n]){if(!this.utils.isEndOfElement(t))continue;if(null!==(e=t.nextElementSibling)&&"P"===e.nodeName)break;return void this.keydown.insertAfterLastElement(t)}}.bind(this),this.keydown.onArrowUp=function(){for(var e,t,i=this.WoltLabKeydown._getBlocks(),n=0;n<i.length;n++)if(t=i[n]){if(!this.utils.isStartOfElement())break;if(null===(e=t.previousElementSibling)||"P"===e.nodeName)return void this.keydown.insertBeforeFirstElement(t);var o=$(this.opts.emptyHtml)[0];t.parentNode.insertBefore(o,t),this.caret.end(o);break}}.bind(this);var n=function(e){if(!1===this.core.callback("enter",e))return e.preventDefault(),!1;if(this.keydown.blockquote&&!0===this.keydown.exitFromBlockquote(e))return!1;if(this.keydown.pre)return this.keydown.insertNewLine(e);if(this.keydown.blockquote||this.keydown.figcaption)return this.keydown.insertBreakLine(e);if(this.keydown.figure)setTimeout($.proxy(function(){this.keydown.replaceToParagraph("FIGURE")},this),1);else if(this.keydown.block){var t,i,n,o,r=null;this.detect.isFirefox()&&"P"===this.keydown.block.nodeName&&b.isCollapsed&&(null!==(t=elClosest(b.getRangeAt(0).startContainer,"a"))&&null===elBySel("br",t)&&(r=this.keydown.block)),setTimeout($.proxy(function(){var t,e,i;this.keydown.replaceToParagraph("DIV"),null!==r&&null!==r.previousElementSibling&&(t=[],elBySelAll("a",r.previousElementSibling,function(e){t.push(e)}),t.length&&(e=t[t.length-1],null!==(i=elBySel("br",e))&&elRemove(i)))},this),1),"LI"===this.keydown.block.tagName&&(i=this.selection.current(),n=elClosest(i,"li"),this.utils.isRedactorParent(n)&&this.utils.isEmpty(n.innerHTML)&&null===n.nextElementSibling&&(n.innerHTML=s?"<br>":"",s&&((o=document.createRange()).selectNodeContents(n),o.collapse(!1),b.removeAllRanges(),b.addRange(o))))}else if(!this.keydown.block)return this.keydown.insertParagraph(e);return this.detect.isFirefox()&&this.utils.isInline(this.keydown.parent)?(this.keydown.insertBreakLine(e),void setTimeout(function(){for(var e=this.selection.block(),t=this.selection.inline();t&&t!==e;){if("A"===t.nodeName){var i=!1;if(0===t.childNodes.length?i=!0:""===t.textContent.replace(/\u200B/g,"").trim()&&(i=!0,elBySelAll("*",t,function(e){"SPAN"!==e.nodeName&&(i=!1)})),i){for(;t.childNodes.length;)t.parentNode.insertBefore(t.childNodes[0],t);elRemove(t);break}}t=t.parentNode}}.bind(this),1)):void 0}.bind(this);this.keydown.onEnter=function(e){var t=this.keydown.blockquote;t&&(this.keydown.blockquote=!1);var i=n.call(this,e);return t&&(this.keydown.blockquote=t),i}.bind(this),this.keydown.replaceToParagraph=function(e){var t=this.selection.block(),i=t.innerHTML.replace(/<br\s?\/?>/gi,"");if(t.tagName===e&&this.utils.isEmpty(i)&&!$(t).hasClass("redactor-in")){var n=document.createElement("p");$(t).replaceWith(n);var o=document.createRange();o.setStart(n,0);var r=document.createTextNode("​");o.insertNode(r),o.setStartAfter(r),o.collapse(!0);var l=window.getSelection();return l.removeAllRanges(),l.addRange(o),!1}"P"===t.tagName&&$(t).removeAttr("style")}.bind(this),this.keydown.onShiftEnter=function(e){return this.buffer.set(),this.keydown.pre?this.keydown.insertNewLine(e):this.insert.raw("<br>​")}.bind(this);var r=this.keydown.onTab;this.keydown.onTab=function(e,t){if(!this.keydown.pre){var i=$(this.selection.current()).closest("ul, ol, td",this.core.editor()[0]);if(0===i.length)return!0;if("TD"===(i=i[0]).nodeName){var n,o=null;return e.originalEvent.shiftKey?null===(o=i.previousElementSibling)&&null!==(o=i.parentNode.previousElementSibling)&&(o=o.lastElementChild):null===(o=i.nextElementSibling)&&(null===(o=i.parentNode.nextElementSibling)&&(this.table.addRowBelow(),o=i.parentNode.nextElementSibling),o=o.firstElementChild),null!==o&&(this.utils.isEmpty(o.innerHTML)?this.caret.end(o):((n=document.createRange()).selectNodeContents(o),b.removeAllRanges(),b.addRange(n))),e.originalEvent.preventDefault(),!1}}return r.call(this,e,t)}.bind(this);var l=this.keydown.formatEmpty;this.keydown.formatEmpty=function(e){for(var t,i=this.$editor[0],n=0,o=i.childElementCount;n<o;n++)if("P"!==(t=i.children[n]).nodeName&&this.utils.isBlockTag(t.nodeName))return;return l.call(this,e)}.bind(this);var t=this.keydown.removeInvisibleSpace;this.keydown.removeInvisibleSpace=function(){this.keydown.current!==this.$editor[0]&&t.call(this)}.bind(this),require(["Core","Environment"],function(i,e){var t,n,o;"desktop"!==e.platform()||null!==(t=this.$editor[0].closest("form, .message, .jsOuterEditorContainer"))&&(null===(n=elBySel(".formSubmit",t))||(o=elBySel('input[type="submit"], button[data-type="save"], button[accesskey="s"]',n))&&(o.removeAttribute("accesskey"),this.WoltLabEvent.register("keydown",function(e){var t;83===e.event.which&&(t=!1,window.navigator.platform.match(/^Mac/)?e.event.ctrlKey&&e.event.altKey&&(t=!0):e.event.altKey&&!e.event.ctrlKey&&(t=!0),t&&(e.cancel=!0,"function"==typeof o.click?o.click():i.triggerEvent(o,WCF_CLICK_EVENT)))}.bind(this))))}.bind(this)),this.WoltLabKeydown._handleBackspaceAndDelete()},register:function(e){-1===n.indexOf(e)&&n.push(e)},_getBlocks:function(){for(var e=[this.keydown.blockquote,this.keydown.pre,this.keydown.figcaption],t=0,i=n.length;t<i;t++)e.push(this.utils.isTag(this.keydown.current,n[t]));return e},_handleBackspaceAndDelete:function(){function f(e){return null===elBySel("img",e)&&""===e.textContent.replace(/\u200B/g,"").trim()}var t=function(e){var t,i=this.selection.block();if(i)if("TD"===i.nodeName){var n=i.innerHTML;"​"===n?e.preventDefault():""===n&&(e.preventDefault(),i.innerHTML="​")}else if(-1!==i.nodeName.indexOf("-")&&f(i))(t=i.parentNode).insertBefore(this.marker.get(),i.nextSibling),elRemove(i),this.selection.restore();else if((t=i&&"P"===i.nodeName?i.parentNode:null)&&-1!==t.nodeName.indexOf("-")){var o=window.getSelection().getRangeAt(0),r=document.createRange();r.setStartBefore(i),r.setEnd(o.startContainer,o.startOffset);var l=r.cloneContents(),s=elCreate("div");if(s.appendChild(l),f(s)){e.preventDefault();var a=i.previousElementSibling,d=null;if(a)d=f(a);else for(t=i;(t=t.parentNode)&&t!==this.$editor[0];)if(a=t.previousElementSibling){d=!1;break}if(d)elRemove(a);else if(null!==d){var h,c=i.parentNode;if("P"===a.nodeName){for(a.appendChild(this.marker.get());i.childNodes.length;){if("BR"===(h=i.childNodes[0]).nodeName){elRemove(h);break}a.appendChild(h)}0===i.childNodes.length&&elRemove(i),this.selection.restore()}else a.appendChild(i),i.insertBefore(this.marker.get(),i.firstChild),this.selection.restore();f(c)&&elRemove(c)}else null===d&&(t=i.parentNode,f(t)&&elRemove(t))}}}.bind(this),i=function(e){var t,i=this.selection.block();if(-1!==i.nodeName.indexOf("-")&&f(i))(t=i.parentNode).insertBefore(this.marker.get(),i.nextSibling),elRemove(i),this.selection.restore();else if((t=i&&"P"===i.nodeName?i.parentNode:null)&&-1!==t.nodeName.indexOf("-")){var n=window.getSelection().getRangeAt(0),o=document.createRange();o.setStart(n.startContainer,n.startOffset),o.setEndAfter(i);var r=o.cloneContents(),l=elCreate("div");if(l.appendChild(r),f(l)){e.preventDefault();var s=i.nextElementSibling,a=null;if(s)a=f(s);else for(t=i;(t=t.parentNode)&&t!==this.$editor[0];)if(s=t.nextElementSibling){a=!1;break}if(a)elRemove(s);else if(null!==a){var d=s.parentNode;if("P"===s.nodeName){for(;s.childNodes.length;)i.appendChild(s.childNodes[0]);elRemove(s)}else{if(i.appendChild(this.marker.get()),t=i.parentNode,-1!==s.nodeName.indexOf("-")){var h=s.firstElementChild;if(h&&"P"===h.nodeName){for(;h.childNodes.length;)i.appendChild(h.childNodes[0]);s.removeChild(h),f(s)&&elRemove(s)}}else t.insertBefore(s,i.nextSibling);this.selection.restore()}f(d)&&elRemove(d)}else null===a&&(t=i.parentNode,f(t)&&elRemove(t))}}}.bind(this),l=function(){return this.opts.blockTags.filter(function(e){return-1!==e.indexOf("-")}).join(",")}.bind(this),s=[],a=function(){elBySelAll(l(),this.core.editor()[0],function(o){null!==o.parentNode&&-1!==s.indexOf(o)&&["nextElementSibling","previousElementSibling"].forEach(function(e){for(var t,i=o[e];null!==i&&i.nodeName===o.nodeName&&-1===s.indexOf(i);){if("previousElementSibling"===e)for(var n=i.childNodes.length-1;0<=n;n--)o.insertBefore(i.childNodes[n],o.firstChild);else for(;0<i.childNodes.length;)o.appendChild(i.childNodes[0]);t=i[e],elRemove(i),i=t}})})}.bind(this),d=0,h=function(){var n=!1;elBySelAll(l(),this.core.editor()[0],function(e){var t=elData(e,"firefox-duplication-bug");if(""!==t){var i=s[parseInt(t,10)];if(null!==i&&null!==i.parentNode&&e!==i&&i.contains(e)){for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);return e.parentNode.removeChild(e),void(n=!0)}e.removeAttribute("data-firefox-duplication-bug")}}),n&&elBySelAll("h1,h2,h3,h4,h5,h6",this.core.editor()[0],function(e){elBySelAll("p",e,function(e){for(;e.childNodes.length;)e.parentNode.insertBefore(e.childNodes[0],e);e.parentNode.removeChild(e)})}),d=0}.bind(this);this.keydown.onBackspaceAndDeleteAfter=function(o){this.detect.isFirefox()&&(this.selection.isCollapsed()?o.which===this.keyCode.BACKSPACE?t(o):o.which===this.keyCode.DELETE&&i(o):o.which!==this.keyCode.BACKSPACE&&o.which!==this.keyCode.DELETE||elBySelAll(l(),this.core.editor()[0],function(e){s.push(e),elData(e,"firefox-duplication-bug",d++)}));var e,r=!1;o.which===this.keyCode.BACKSPACE&&this.selection.isCollapsed()&&this.detect.isWebkit()&&(!1!==(e=this.selection.block())&&"PRE"===e.nodeName&&(r=!0)),setTimeout($.proxy(function(){var e;if(0<s.length&&(this.selection.save(),a(),h(),this.selection.restore(),s=[]),r){var t=this.selection.block();if((!1===t||"PRE"!==t.nodeName)&&(e=this.selection.current()).nodeType===Node.TEXT_NODE&&e.nextSibling&&"SPAN"===e.nextSibling.nodeName){var i=e.nextSibling;if(-1!==i.style.getPropertyValue("font-family").indexOf("monospace")&&"pre-wrap"===i.style.getPropertyValue("white-space")){for(;i.childNodes.length;)i.parentNode.insertBefore(i.childNodes[0],i);elRemove(i)}}}this.code.syncFire=!1,this.keydown.removeEmptyLists();var n="";0!==this.opts.keepStyleAttr.length&&(n=","+this.opts.keepStyleAttr.join(",")),this.core.editor().find("*[style]").not("span, img, figure, iframe, #redactor-image-box, #redactor-image-editter, [data-redactor-style-cache], [data-redactor-span]"+n).removeAttr("style"),this.keydown.formatEmpty(o),"KBD"===(e=this.selection.current()).nodeName&&0===e.innerHTML.length&&elRemove(e),this.code.syncFire=!0},this),1)}.bind(this)}}}; })(this);
 
 // plugins/WoltLabKeyup.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabKeyup=function(){"use strict";return{init:function(){this.WoltLabEvent.register("keyup",function(e){e.event.originalEvent.which===this.keyCode.ENTER&&this.WoltLabKeyup._keyupEnter()}.bind(this))},_keyupEnter:function(){var e=this.$editor[0],n=window.getSelection(),t=null;if(this.detect.isFirefox()){var r=n.anchorNode;if(r.nodeType===Node.TEXT_NODE&&0===n.anchorOffset&&(t=r.parentNode,t.childNodes[0]===r&&(r=r.parentNode)),"LI"===r.nodeName){var i=r.parentNode;if(t=i.parentNode,"LI"===t.nodeName&&null===i.previousSibling)return t.insertBefore(this.marker.get(),i),t.insertBefore(elCreate("br"),i),void this.selection.restore()}}var o=elClosest(n.anchorNode,"li");if(null!==o&&e.contains(o)){var a=o.previousElementSibling;null===a||"OL"!==a.nodeName&&"UL"!==a.nodeName||a.previousElementSibling.appendChild(a)}for(var l=n.anchorNode;l.parentNode;){if(l.parentNode===e){t=l;break}l=l.parentNode}null!==t&&"P"===t.nodeName&&(this.WoltLabKeyup._rebuildEmptyParagraph(t,!1),null!==(t=t.previousElementSibling)&&"P"===t.nodeName&&this.WoltLabKeyup._rebuildEmptyParagraph(t,!0))},_rebuildEmptyParagraph:function(e,n){if(!(e.textContent.replace(/\u200B/g,"").trim().length>0)){for(var t=e;t.nodeType===Node.ELEMENT_NODE&&0!==t.childNodes.length;){if(t.children.length>1)return;t=1===t.children.length?t.children[0]:t.childNodes[0]}if(t.nodeType===Node.TEXT_NODE){var r=elCreate("br");t.parentNode.appendChild(r),n&&elRemove(t)}}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabKeyup=function(){"use strict";return{init:function(){this.WoltLabEvent.register("keyup",function(e){e.event.originalEvent.which===this.keyCode.ENTER&&this.WoltLabKeyup._keyupEnter()}.bind(this))},_keyupEnter:function(){var e=this.$editor[0],n=window.getSelection(),t=null;if(this.detect.isFirefox()){var r=n.anchorNode;if(r.nodeType===Node.TEXT_NODE&&0===n.anchorOffset&&(t=r.parentNode).childNodes[0]===r&&(r=r.parentNode),"LI"===r.nodeName){var i=r.parentNode;if("LI"===(t=i.parentNode).nodeName&&null===i.previousSibling)return t.insertBefore(this.marker.get(),i),t.insertBefore(elCreate("br"),i),void this.selection.restore()}}var o,l=elClosest(n.anchorNode,"li");null!==l&&e.contains(l)&&(null===(o=l.previousElementSibling)||"OL"!==o.nodeName&&"UL"!==o.nodeName||o.previousElementSibling.appendChild(o));for(var a=n.anchorNode;a.parentNode;){if(a.parentNode===e){t=a;break}a=a.parentNode}null!==t&&"P"===t.nodeName&&(this.WoltLabKeyup._rebuildEmptyParagraph(t,!1),null!==(t=t.previousElementSibling)&&"P"===t.nodeName&&this.WoltLabKeyup._rebuildEmptyParagraph(t,!0))},_rebuildEmptyParagraph:function(e,n){if(!(0<e.textContent.replace(/\u200B/g,"").trim().length)){for(var t,r=e;r.nodeType===Node.ELEMENT_NODE&&0!==r.childNodes.length;){if(1<r.children.length)return;r=1===r.children.length?r.children[0]:r.childNodes[0]}r.nodeType===Node.TEXT_NODE&&(t=elCreate("br"),r.parentNode.appendChild(t),n&&elRemove(r))}}}}; })(this);
 
 // plugins/WoltLabLine.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabLine=function(){"use strict";return{init:function(){this.line.removeOnBackspace=function(){if(this.utils.isCollapsed()){var t=$(this.selection.block());if(0!==t.length&&this.utils.isStartOfElement(t)){var i=t.prev();i.length&&"HR"===i[0].tagName&&(e.preventDefault(),i.remove())}}}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabLine=function(){"use strict";return{init:function(){this.line.removeOnBackspace=function(){var t,i;this.utils.isCollapsed()&&(0===(t=$(this.selection.block())).length||!this.utils.isStartOfElement(t)||(i=t.prev()).length&&"HR"===i[0].tagName&&(e.preventDefault(),i.remove()))}.bind(this)}}}; })(this);
 
 // plugins/WoltLabLink.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabLink=function(){"use strict";var i=null;return{init:function(){this.link.isUrl=function(i){var t="((xn--)?[\\W\\w\\D\\d]+(-(?!-[\\W\\w\\D\\d])+)*\\.)+[\\W\\w]{2,}",e=new RegExp("^(http|ftp|https|steam|ts3server)://"+t,"i"),s=new RegExp("^"+t,"i"),r=new RegExp(".(html|php)$","i"),l=new RegExp("^/","i"),n=new RegExp("^tel:(.*?)","i");return-1===i.search(e)&&-1!==i.search(s)&&-1===i.search(r)&&"/"!==i.substring(0,1)&&(i="http://"+i),(-1!==i.search(e)||-1!==i.search(r)||-1!==i.search(l)||-1!==i.search(n))&&i}.bind(this),this.link.show=this.WoltLabLink.show.bind(this),this.link.parse=function(i){if(this.link.isMailto(i.url))i.url="mailto:"+i.url.replace("mailto:","");else if(0!==i.url.search("#")&&this.opts.linkValidation){var t=this.link.isUrl(i.url);!1===t&&(t="http://"+i.url),i.url=t}return!this.link.isEmpty(i)&&!1!==i.url&&i}.bind(this),require(["WoltLabSuite/Core/Ui/Redactor/Link"],function(t){i=t})},show:function(t){void 0!==t&&t.preventDefault&&t.preventDefault();var e=this.selection.is();this.selection.save(),this.observe.closeAllTooltip();var s=this.link.is();e&&this.selection.restore();var r=this.link.buildLinkFromElement(s);e&&this.selection.save(),i.showDialog({insert:!1===s,submitCallback:function(){var i=this.link.buildLinkFromModal();return!1!==i&&(this.selection.restore(),this.link.insert(i,!0),!0)}.bind(this)}),r.url=this.link.removeSelfHostFromUrl(r.url),this.link.setModalValues(r),this.detect.isDesktop()&&$("#redactor-link-url").focus()}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabLink=function(){"use strict";var r=null;return{init:function(){this.link.isUrl=function(i){var t="((xn--)?[\\W\\w\\D\\d]+(-(?!-[\\W\\w\\D\\d])+)*\\.)+[\\W\\w]{2,}",e=new RegExp("^(http|ftp|https|steam|ts3server)://"+t,"i"),s=new RegExp("^"+t,"i"),r=new RegExp(".(html|php)$","i"),l=new RegExp("^/","i"),n=new RegExp("^tel:(.*?)","i");return-1===i.search(e)&&-1!==i.search(s)&&-1===i.search(r)&&"/"!==i.substring(0,1)&&(i="http://"+i),(-1!==i.search(e)||-1!==i.search(r)||-1!==i.search(l)||-1!==i.search(n))&&i}.bind(this),this.link.show=this.WoltLabLink.show.bind(this),this.link.parse=function(i){var t;return this.link.isMailto(i.url)?i.url="mailto:"+i.url.replace("mailto:",""):0!==i.url.search("#")&&this.opts.linkValidation&&(!1===(t=this.link.isUrl(i.url))&&(t="http://"+i.url),i.url=t),!this.link.isEmpty(i)&&!1!==i.url&&i}.bind(this),require(["WoltLabSuite/Core/Ui/Redactor/Link"],function(i){r=i})},show:function(i){void 0!==i&&i.preventDefault&&i.preventDefault();var t=this.selection.is();this.selection.save(),this.observe.closeAllTooltip();var e=this.link.is();t&&this.selection.restore();var s=this.link.buildLinkFromElement(e);t&&this.selection.save(),r.showDialog({insert:!1===e,submitCallback:function(){var i=this.link.buildLinkFromModal();return!1!==i&&(this.selection.restore(),this.link.insert(i,!0),!0)}.bind(this)}),s.url=this.link.removeSelfHostFromUrl(s.url),this.link.setModalValues(s),this.detect.isDesktop()&&$("#redactor-link-url").focus()}}}; })(this);
 
 // plugins/WoltLabList.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabList=function(){"use strict";return{parentsQualifiedForLists:["woltlab-quote","woltlab-spoiler"],init:function(){this.list.combineAfterAndBefore=function(t){var e=$(t).prev(),i=$(t).next(),s=t&&"P"===t.tagName&&("<br>"===t.innerHTML||""===t.innerHTML),n=1===e.closest("ol, ul",this.core.editor()[0]).length&&1===i.closest("ol, ul",this.core.editor()[0]).length,o=!1;if(n&&!s&&0===t.textContent.replace(/\u200b/g,"").trim().length){var r=["A","B","BR","EM","I","STRONG","U"],l=!0;elBySelAll("*",t,function(t){-1===r.indexOf(t.nodeName)&&("SPAN"===t.nodeName&&""===t.className.trim()||(l=!1))}),l&&(o=!0,s=!0)}if(s&&n){if("LI"===t.nodeName&&o)return e.append(this.marker.get()),elRemove(t),this.selection.restore(),!0;e.children("li").last().append(this.marker.get()),e.append(i.contents());var a=t.nextElementSibling;return"OL"!==a.nodeName&&"UL"!==a.nodeName||0!==a.childElementCount||elRemove(a),o&&elRemove(t),this.selection.restore(),!0}return!1}.bind(this),this.list.toggle=function(t){if(!this.utils.inBlocks(["table","td","th","tr"])){t="orderedlist"===t?"ol":t,t="unorderedlist"===t?"ul":t,t=t.toLowerCase(),this.buffer.set(),this.selection.save();var e=this.list._getBlocks(),i=this.selection.block(),s=$(i).parent().closest("ol, ul",this.core.editor()[0]);return 0===e.length&&0!==s.length&&(e=[s.get(0)]),e=this.list._isUnformat(t,e)?this.list._unformat(t,e):this.list._format(t,e),this.selection.restore(),e}}.bind(this),this.list._getBlocks=function(){return this.selection.blocks().filter(function(t){var e=t.parentNode;return!!e.classList.contains("redactor-in")||-1!==this.WoltLabList.parentsQualifiedForLists.indexOf(e.nodeName.toLowerCase())}.bind(this))}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabList=function(){"use strict";return{parentsQualifiedForLists:["woltlab-quote","woltlab-spoiler"],init:function(){this.list.combineAfterAndBefore=function(t){var e,i,s=$(t).prev(),n=$(t).next(),o=t&&"P"===t.tagName&&("<br>"===t.innerHTML||""===t.innerHTML),r=1===s.closest("ol, ul",this.core.editor()[0]).length&&1===n.closest("ol, ul",this.core.editor()[0]).length,l=!1;if(r&&!o&&0===t.textContent.replace(/\u200b/g,"").trim().length&&(e=["A","B","BR","EM","I","STRONG","U"],i=!0,elBySelAll("*",t,function(t){-1===e.indexOf(t.nodeName)&&("SPAN"===t.nodeName&&""===t.className.trim()||(i=!1))}),i&&(o=l=!0)),o&&r){if("LI"===t.nodeName&&l)return s.append(this.marker.get()),elRemove(t),this.selection.restore(),!0;s.children("li").last().append(this.marker.get()),s.append(n.contents());var a=t.nextElementSibling;return"OL"!==a.nodeName&&"UL"!==a.nodeName||0!==a.childElementCount||elRemove(a),l&&elRemove(t),this.selection.restore(),!0}return!1}.bind(this),this.list.toggle=function(t){if(!this.utils.inBlocks(["table","td","th","tr"])){t=(t="unorderedlist"===(t="orderedlist"===t?"ol":t)?"ul":t).toLowerCase(),this.buffer.set(),this.selection.save();var e=this.list._getBlocks(),i=this.selection.block(),s=$(i).parent().closest("ol, ul",this.core.editor()[0]);return 0===e.length&&0!==s.length&&(e=[s.get(0)]),e=this.list._isUnformat(t,e)?this.list._unformat(t,e):this.list._format(t,e),this.selection.restore(),e}}.bind(this),this.list._getBlocks=function(){return this.selection.blocks().filter(function(t){var e=t.parentNode;return!!e.classList.contains("redactor-in")||-1!==this.WoltLabList.parentsQualifiedForLists.indexOf(e.nodeName.toLowerCase())}.bind(this))}.bind(this)}}}; })(this);
 
 // plugins/WoltLabMedia.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabMedia=function(){"use strict";return{init:function(){var t=this.button.add("woltlabMedia","");$(t).addClass("jsMediaEditorButton");var e=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","metacode_wsm_"+this.$element[0].id,function(t){if(1!==t.attributes.length){var e="";3===t.attributes.length&&("left"===t.attributes[2]?e=" messageFloatObjectLeft":"right"===t.attributes[2]&&(e=" messageFloatObjectRight"));var a=elCreate("img");a.className="woltlabSuiteMedia"+e,a.src=this.opts.woltlab.mediaUrl.replace(/&amp;/,"&").replace("-123456789",t.attributes[0]).replace("thumbnail=void",function(){return t.attributes[1]?"thumbnail="+t.attributes[1]:""}),elData(a,"media-id",t.attributes[0]),elData(a,"media-size",t.attributes[1]);var i=t.metacode;i.parentNode.insertBefore(a,i),elRemove(i),t.cancel=!0}}.bind(this));WCF.System.Event.addListener("com.woltlab.wcf.redactor2","destroy_"+this.$element[0].id,function(){WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","metacode_wsm_"+this.$element[0].id,e)}.bind(this)),require(["WoltLabSuite/Core/Media/Manager/Editor"],function(t){new t({editor:this})}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabMedia=function(){"use strict";return{init:function(){var t=this.button.add("woltlabMedia","");$(t).addClass("jsMediaEditorButton");var e=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","metacode_wsm_"+this.$element[0].id,function(t){var e,a,i;1!==t.attributes.length&&(e="",3===t.attributes.length&&("left"===t.attributes[2]?e=" messageFloatObjectLeft":"right"===t.attributes[2]&&(e=" messageFloatObjectRight")),(a=elCreate("img")).className="woltlabSuiteMedia"+e,a.src=this.opts.woltlab.mediaUrl.replace(/&amp;/,"&").replace("-123456789",t.attributes[0]).replace("thumbnail=void",function(){return t.attributes[1]?"thumbnail="+t.attributes[1]:""}),elData(a,"media-id",t.attributes[0]),elData(a,"media-size",t.attributes[1]),(i=t.metacode).parentNode.insertBefore(a,i),elRemove(i),t.cancel=!0)}.bind(this));WCF.System.Event.addListener("com.woltlab.wcf.redactor2","destroy_"+this.$element[0].id,function(){WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","metacode_wsm_"+this.$element[0].id,e)}.bind(this)),require(["WoltLabSuite/Core/Media/Manager/Editor"],function(t){new t({editor:this})}.bind(this))}}}; })(this);
 
 // plugins/WoltLabMention.js
 (function (window, undefined) { $.Redactor.prototype.WoltLabMention=function(){"use strict";return{init:function(){require(["WoltLabSuite/Core/Ui/Redactor/Mention"],function(t){new t(this)}.bind(this))}}}; })(this);
 
 // plugins/WoltLabModal.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabModal=function(){"use strict";var t=null,i="",e=null,o={close:function(){this.selection.restore(),e.getDialog("redactorOverlay-"+this.uuid)&&e.close("redactorOverlay-"+this.uuid)},load:function(e,o){t.innerHTML=this.modal.getTemplate(e),i=o},setTitle:function(t){e.setTitle(this,t)},show:function(){this.selection.save(),e.open(this),e.setTitle(this,i)}};return{init:function(){t=elCreate("div"),t.className="redactorModalWrapper",t.id="redactorOverlay-"+this.uuid,elHide(t),document.body.appendChild(t),this.$modalBody=$(t),require(["Ui/Dialog"],function(t){e=t;for(var i in o)o.hasOwnProperty(i)&&(this.modal[i]=o[i].bind(this))}.bind(this)),this._dialogSetup=function(){return{id:"redactorOverlay-"+this.uuid,options:{onClose:function(t){var i=e.getDialog(t);elBySelAll("[id]",i.content,function(t){t.removeAttribute("id")})}}}}},rebuild:function(){e&&e.rebuild("redactorOverlay-"+this.uuid)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabModal=function(){"use strict";var e=null,o="",n=null,r={close:function(){this.selection.restore(),n.getDialog("redactorOverlay-"+this.uuid)&&n.close("redactorOverlay-"+this.uuid)},load:function(t,i){e.innerHTML=this.modal.getTemplate(t),o=i},setTitle:function(t){n.setTitle(this,t)},show:function(){this.selection.save(),n.open(this),n.setTitle(this,o)}};return{init:function(){(e=elCreate("div")).className="redactorModalWrapper",e.id="redactorOverlay-"+this.uuid,elHide(e),document.body.appendChild(e),this.$modalBody=$(e),require(["Ui/Dialog"],function(t){for(var i in n=t,r)r.hasOwnProperty(i)&&(this.modal[i]=r[i].bind(this))}.bind(this)),this._dialogSetup=function(){return{id:"redactorOverlay-"+this.uuid,options:{onClose:function(t){var i=n.getDialog(t);elBySelAll("[id]",i.content,function(t){t.removeAttribute("id")})}}}}},rebuild:function(){n&&n.rebuild("redactorOverlay-"+this.uuid)}}}; })(this);
 
 // plugins/WoltLabObserve.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabObserve=function(){"use strict";return{init:function(){var t=elByClass("re-button",this.button.toolbar()[0]);this.button.setInactiveAll=function(e){for(var s,o=0,i=t.length;o<i;o++)s=t[o],s.classList.contains("re-"+e)||(s.classList.remove("redactor-act"),"html"!==s.rel&&elAttr(s,"tabindex",-1),elAttr(s,"aria-pressed",!1))}.bind(this),this.observe.buttons=function(t,e){var s=this.selection.current();if(!1!==t?this.button.setInactiveAll():this.button.setInactiveAll(e),!1===t&&"html"!==e)return void(-1!==$.inArray(e,this.opts.activeButtons)&&this.button.toggleActive(e));if(this.utils.isRedactorParent(s)){var o=this.WoltLabSource.isActive();this.utils.isCurrentOrParentHeader()||this.utils.isCurrentOrParent(["table","pre","blockquote","li"])?this.button.disable("horizontalrule"):o||this.button.enable("horizontalrule"),this.utils.isCurrentOrParent(["table","li"])?(this.button.disable("code"),this.button.disable("spoiler"),this.button.disable("woltlabHtml"),this.button.disable("woltlabQuote")):o||(this.button.enable("code"),this.button.enable("spoiler"),this.button.enable("woltlabHtml"),this.button.enable("woltlabQuote")),o&&this.button.setActive("html"),this.core.box()[0].classList.contains("redactorBoxFullscreen")&&this.button.setActive("woltlabFullscreen");var i=this.$editor[0];if(s.nodeType!==Node.ELEMENT_NODE&&(s=s.parentNode),s.closest(".redactor-layer")===i)for(var r,n,l=[];s!==i;)n=s.nodeName.toLowerCase(),-1===l.indexOf(n)&&(r=n,"pre"===n&&s.classList.contains("woltlabHtml")&&(r="woltlab-html"),this.opts.activeButtonsStates.hasOwnProperty(r)&&this.button.setActive(this.opts.activeButtonsStates[r]),"pre"!==n&&l.push(n)),s=s.parentNode}}.bind(this),this.observe.dropdowns=function(){var t=this.selection.current();t&&t.nodeType!==Node.ELEMENT_NODE&&(t=t.parentNode);var e,s=this.$editor[0],o=t&&t.closest(".redactor-layer")===s,i=[];if(o)for(;t!==s;)e=t.nodeName.toLowerCase(),-1===i.indexOf(e)&&i.push(e),t=t.parentNode;for(var r,n=null,l=0,a=this.opts.observe.dropdowns.length;l<a;l++){r=this.opts.observe.dropdowns[l];var b=r.observe,h=b.element,u=r.item,c=!!b.in&&b.in,d=!!b.out&&b.out;"a"===h&&null===n&&(n=$("<div />").html(this.selection.html()).find("a").length),-1!==i.indexOf(h)&&o||"a"===h&&0!==n?this.observe.setDropdownProperties(u,c,d):this.observe.setDropdownProperties(u,d,c)}}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabObserve=function(){"use strict";return{init:function(){var i=elByClass("re-button",this.button.toolbar()[0]);this.button.setInactiveAll=function(t){for(var e,s=0,o=i.length;s<o;s++)(e=i[s]).classList.contains("re-"+t)||(e.classList.remove("redactor-act"),"html"!==e.rel&&elAttr(e,"tabindex",-1),elAttr(e,"aria-pressed",!1))}.bind(this),this.observe.buttons=function(t,e){var s=this.selection.current();if(!1!==t?this.button.setInactiveAll():this.button.setInactiveAll(e),!1!==t||"html"===e){if(this.utils.isRedactorParent(s)){var o=this.WoltLabSource.isActive();this.utils.isCurrentOrParentHeader()||this.utils.isCurrentOrParent(["table","pre","blockquote","li"])?this.button.disable("horizontalrule"):o||this.button.enable("horizontalrule"),this.utils.isCurrentOrParent(["table","li"])?(this.button.disable("code"),this.button.disable("spoiler"),this.button.disable("woltlabHtml"),this.button.disable("woltlabQuote")):o||(this.button.enable("code"),this.button.enable("spoiler"),this.button.enable("woltlabHtml"),this.button.enable("woltlabQuote")),o&&this.button.setActive("html"),this.core.box()[0].classList.contains("redactorBoxFullscreen")&&this.button.setActive("woltlabFullscreen");var i=this.$editor[0];if(s.nodeType!==Node.ELEMENT_NODE&&(s=s.parentNode),s.closest(".redactor-layer")===i)for(var r,n,l=[];s!==i;)n=s.nodeName.toLowerCase(),-1===l.indexOf(n)&&("pre"===(r=n)&&s.classList.contains("woltlabHtml")&&(r="woltlab-html"),this.opts.activeButtonsStates.hasOwnProperty(r)&&this.button.setActive(this.opts.activeButtonsStates[r]),"pre"!==n&&l.push(n)),s=s.parentNode}}else-1!==$.inArray(e,this.opts.activeButtons)&&this.button.toggleActive(e)}.bind(this),this.observe.dropdowns=function(){var t=this.selection.current();t&&t.nodeType!==Node.ELEMENT_NODE&&(t=t.parentNode);var e,s=this.$editor[0],o=t&&t.closest(".redactor-layer")===s,i=[];if(o)for(;t!==s;)e=t.nodeName.toLowerCase(),-1===i.indexOf(e)&&i.push(e),t=t.parentNode;for(var r,n=null,l=0,a=this.opts.observe.dropdowns.length;l<a;l++){var b=(r=this.opts.observe.dropdowns[l]).observe,h=b.element,u=r.item,c=!!b.in&&b.in,d=!!b.out&&b.out;"a"===h&&null===n&&(n=$("<div />").html(this.selection.html()).find("a").length),-1!==i.indexOf(h)&&o||"a"===h&&0!==n?this.observe.setDropdownProperties(u,c,d):this.observe.setDropdownProperties(u,d,c)}}.bind(this)}}}; })(this);
 
 // plugins/WoltLabPage.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabPage=function(){"use strict";return{init:function(){var t=this.button.add("woltlabPage","");require(["WoltLabSuite/Core/Ui/Redactor/Page"],function(e){new e(this,t[0])}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabPage=function(){"use strict";return{init:function(){var e=this.button.add("woltlabPage","");require(["WoltLabSuite/Core/Ui/Redactor/Page"],function(t){new t(this,e[0])}.bind(this))}}}; })(this);
 
 // plugins/WoltLabPaste.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabPaste=function(){"use strict";var t=null;return{init:function(){var e=null,i=!1,r=document.documentMode&&"object"==typeof window.clipboardData,n=null,a=null,s=function(t){this.rtePaste=!0;var e=!("pre"!==this.opts.type&&!this.utils.isCurrentOrParent("pre"));e&&t.preventDefault(),this.utils.saveScroll(),this.selection.save(),this.paste.createPasteBox(e);var i=this.paste.getPasteBoxCode(e);this.buffer.set(),this.selection.restore(),this.utils.restoreScroll();var r=this.clean.getCurrentType(i);i=this.clean.onPaste(i,r);var n=this.core.callback("paste",i);i=void 0===n?i:n,this.paste.insert(i,r),this.rtePaste=!1,e&&this.clean.cleanPre()}.bind(this),l=this.paste.init;this.paste.init=function(o){a=n=null;var d="pre"===this.opts.type||this.utils.isCurrentOrParent("pre");if(i=!d&&this.utils.isCurrentOrParent("kbd"),d||i){e=r?window.clipboardData.getData("Text"):o.originalEvent.clipboardData.getData("text/plain");var h=this.clean.encodeEntities;this.clean.encodeEntities=function(t){return this.clean.encodeEntities=h,WCF.String.escapeHTML(t)}.bind(this)}else if(!r){var c=o.originalEvent.clipboardData.types,p=!1;if(-1!==c.indexOf("text/html")&&(n=o.originalEvent.clipboardData.getData("text/html"),n.trim().match(/^<html[^>]*>[\s\S]*?<body[^>]*>([\s\S]+)<\/body>[\s\S]*?<\/html>$/)&&(n=RegExp.$1.replace(/^\s*(?:<!--StartFragment-->)(.+)(?:<!--EndFragment-->)?\s*$/,"$1")),p=0!==n.trim().length),!p&&-1!==c.indexOf("text/plain")){var f=WCF.String.escapeHTML(o.originalEvent.clipboardData.getData("text/plain"));a="";var u=f.split("\n");1===u.length?a=f:u.forEach(function(t){t=t.trim(),""===t&&(t="<br>"),a+="<p>"+t+"</p>"})}}null===a&&null===n||o.preventDefault(),"android"===t.platform()&&"chrome"===t.browser()?s(o):l.call(this,o)}.bind(this),require(["Environment"],function(e){if(t=e,"ios"===t.platform()){var i=this.paste.appendPasteBox;this.paste.appendPasteBox=function(){this.$pasteBox.css({fontSize:"16px",height:"1px",left:"1px",overflow:"hidden",position:"absolute",top:~~(window.innerHeight/4)+window.pageYOffset+"px",width:"1px"}),i.call(this)}.bind(this)}}.bind(this));var o=this.paste.createPasteBox;this.paste.createPasteBox=function(t){null===n&&null===a&&o.call(this,t)}.bind(this);var d=this.paste.getPasteBoxCode;this.paste.getPasteBoxCode=function(t){if(null!==n||null!==a)return this.tmpScrollTop=void 0,n||a;var s=d.call(this,t);return i?e:!t||s&&!r?s:e}.bind(this),this.core.editor().off("paste.redactor").on("paste.redactor",this.paste.init.bind(this)),this.paste.detectClipboardUpload=function(t){t=t.originalEvent||t;var e=null;if(r){if(!window.clipboardData.files.length)return!1;e=window.clipboardData.files.item(0)}else{if(this.detect.isFirefox())return!1;var i=t.clipboardData,n=i.types;if(Array.isArray(n)&&-1!==n.indexOf("public.tiff")){if(0===i.files.length)return;if(1!==i.files.length)return t.preventDefault(),!1;e=i.files[0],h=!0,null!==e&&t.preventDefault()}if(null===e){if(!i.items||!i.items.length)return;if(this.detect.isWebkit()){for(var a,s=!1,l=!1,o=0,d=i.items.length;o<d;o++)a=i.items[o],"string"===a.kind&&"text/html"===a.type?l=!0:"file"===a.kind&&(s=!0);if(s&&l)return!1}var h=!1;if(null===(e=i.items[0].getAsFile())){if(this.detect.isWebkit()&&i.items.length>1&&(e=i.items[1].getAsFile(),h=!0,null!==e&&t.preventDefault()),null===e)return!1}else this.detect.isWebkit()&&1===i.items.length&&t.preventDefault()}}var c=new FileReader;return c.readAsDataURL(e),c.onload=this.paste.insertFromClipboard.bind(this),!1===h}.bind(this),this.paste.insertFromClipboard=function(t){window.FormData&&(this.buffer.set(),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this.$element[0].id,{blob:this.utils.dataURItoBlob(t.target.result)}),this.rtePaste=!1)}.bind(this);var h="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",c=this.paste.insert;this.paste.insert=function(t,e){if(i&&(e.pre=!0),this.utils.isCurrentOrParent("kbd")){c.call(this,t,e);var n=this.selection.current();n.nodeType===Node.TEXT_NODE&&(n=n.parentNode);for(var a=n.closest("kbd"),s=elByTag("p",a);s.length;)s[0].outerHTML=s[0].innerHTML;var l=a.innerHTML.split(/<br\s*\/?>/);if(l.length>1){for(var o=this.selection.block(),d=1,p=l.length;d<p;d++){var f=elCreate(o.nodeName);f.innerHTML="<kbd>"+l[d]+(d===p-1?this.marker.html():"")+"</kbd>",o.parentNode.insertBefore(f,o.nextSibling),o=f}a.innerHTML=l[0],this.selection.restore()}}else{if(e.pre)return c.call(this,t,e);var u=elCreate("div");if(u.innerHTML=t,1===u.childElementCount&&"A"===u.children[0].nodeName){var b=u.children[0];if(u.firstChild===b&&u.lastChild===b&&b.href===b.textContent){for(;b.childNodes.length;)u.insertBefore(b.childNodes[0],b);u.removeChild(b)}}var v=[];e.pre||e.text||elBySelAll("img",u,function(t){var e=t.src;if(0===e.indexOf("data:image")&&e!==h){t.src=h;var i=WCF.getUUID();elData(t,"uuid",i),v.push({src:e,uuid:i}),elHide(t)}}.bind(this)),elBySelAll("pre",u,function(t){elBySelAll("br",t,function(t){var e=t.parentNode;e.insertBefore(document.createTextNode("\n"),t),e.removeChild(t)})}),c.call(this,u.innerHTML,e);var m=window.getSelection();m.rangeCount&&"A"===m.anchorNode.nodeName&&m.anchorOffset===m.anchorNode.childNodes.length&&this.caret.after(m.anchorNode),v.length&&window.setTimeout(function(){for(var t,e,i=0,n=v.length;i<n;i++)t=v[i],(e=elBySel('img[data-uuid="'+t.uuid+'"]',this.$editor[0]))&&(r?e.parentNode.removeChild(e):WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this.$element[0].id,{blob:this.utils.dataURItoBlob(t.src),replace:e}))}.bind(this),50);var g,A=[],x=this.core.editor()[0];for(d=0,p=x.childNodes.length;d<p;d++)g=x.childNodes[d],g.nodeType===Node.TEXT_NODE&&"​"===g.textContent&&A.push(g);A.forEach(elRemove),this.WoltLabClean.removeRedundantStyles(),this.rtePaste=!1}}.bind(this),this.paste.clipboardUpload=function(){}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabPaste=function(){"use strict";var p=null;return{init:function(){var l=null,v=!1,g=document.documentMode&&"object"==typeof window.clipboardData,o=null,d=null,h=function(t){this.rtePaste=!0;var e=!("pre"!==this.opts.type&&!this.utils.isCurrentOrParent("pre"));e&&t.preventDefault(),this.utils.saveScroll(),this.selection.save(),this.paste.createPasteBox(e);var i=this.paste.getPasteBoxCode(e);this.buffer.set(),this.selection.restore(),this.utils.restoreScroll();var n=this.clean.getCurrentType(i),i=this.clean.onPaste(i,n),r=this.core.callback("paste",i);i=void 0===r?i:r,this.paste.insert(i,n),this.rtePaste=!1,e&&this.clean.cleanPre()}.bind(this),c=this.paste.init;this.paste.init=function(t){d=o=null;var e,i,n,r,s,a="pre"===this.opts.type||this.utils.isCurrentOrParent("pre");v=!a&&this.utils.isCurrentOrParent("kbd"),a||v?(l=g?window.clipboardData.getData("Text"):t.originalEvent.clipboardData.getData("text/plain"),e=this.clean.encodeEntities,this.clean.encodeEntities=function(t){return this.clean.encodeEntities=e,WCF.String.escapeHTML(t)}.bind(this)):g||(n=!1,-1!==(i=t.originalEvent.clipboardData.types).indexOf("text/html")&&((o=t.originalEvent.clipboardData.getData("text/html")).trim().match(/^<html[^>]*>[\s\S]*?<body[^>]*>([\s\S]+)<\/body>[\s\S]*?<\/html>$/)&&(o=RegExp.$1.replace(/^\s*(?:<!--StartFragment-->)(.+)(?:<!--EndFragment-->)?\s*$/,"$1")),n=0!==o.trim().length),n||-1===i.indexOf("text/plain")||(r=WCF.String.escapeHTML(t.originalEvent.clipboardData.getData("text/plain")),d="",1===(s=r.split("\n")).length?d=r:s.forEach(function(t){""===(t=t.trim())&&(t="<br>"),d+="<p>"+t+"</p>"}))),null===d&&null===o||t.preventDefault(),"android"===p.platform()&&"chrome"===p.browser()?h(t):c.call(this,t)}.bind(this),require(["Environment"],function(t){var e;"ios"===(p=t).platform()&&(e=this.paste.appendPasteBox,this.paste.appendPasteBox=function(){this.$pasteBox.css({fontSize:"16px",height:"1px",left:"1px",overflow:"hidden",position:"absolute",top:~~(window.innerHeight/4)+window.pageYOffset+"px",width:"1px"}),e.call(this)}.bind(this))}.bind(this));var e=this.paste.createPasteBox;this.paste.createPasteBox=function(t){null===o&&null===d&&e.call(this,t)}.bind(this);var i=this.paste.getPasteBoxCode;this.paste.getPasteBoxCode=function(t){if(null!==o||null!==d)return this.tmpScrollTop=void 0,o||d;var e=i.call(this,t);return!v&&(!t||e&&!g)?e:l}.bind(this),this.core.editor().off("paste.redactor").on("paste.redactor",this.paste.init.bind(this)),this.paste.detectClipboardUpload=function(t){t=t.originalEvent||t;var e=null;if(g){if(!window.clipboardData.files.length)return!1;e=window.clipboardData.files.item(0)}else{if(this.detect.isFirefox())return!1;var i=t.clipboardData,n=i.types;if(Array.isArray(n)&&-1!==n.indexOf("public.tiff")){if(0===i.files.length)return;if(1!==i.files.length)return t.preventDefault(),!1;d=!0,null!==(e=i.files[0])&&t.preventDefault()}if(null===e){if(!i.items||!i.items.length)return;if(this.detect.isWebkit()){for(var r,s=!1,a=!1,l=0,o=i.items.length;l<o;l++)"string"===(r=i.items[l]).kind&&"text/html"===r.type?a=!0:"file"===r.kind&&(s=!0);if(s&&a)return!1}var d=!1;if(null===(e=i.items[0].getAsFile())){if(this.detect.isWebkit()&&1<i.items.length&&(d=!0,null!==(e=i.items[1].getAsFile())&&t.preventDefault()),null===e)return!1}else this.detect.isWebkit()&&1===i.items.length&&t.preventDefault()}}var h=new FileReader;return h.readAsDataURL(e),h.onload=this.paste.insertFromClipboard.bind(this),!1===d}.bind(this),this.paste.insertFromClipboard=function(t){window.FormData&&(this.buffer.set(),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this.$element[0].id,{blob:this.utils.dataURItoBlob(t.target.result)}),this.rtePaste=!1)}.bind(this);var A="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",x=this.paste.insert;this.paste.insert=function(t,e){if(v&&(e.pre=!0),this.utils.isCurrentOrParent("kbd")){x.call(this,t,e);var i=this.selection.current();i.nodeType===Node.TEXT_NODE&&(i=i.parentNode);for(var n=i.closest("kbd"),r=elByTag("p",n);r.length;)r[0].outerHTML=r[0].innerHTML;var s=n.innerHTML.split(/<br\s*\/?>/);if(1<s.length){for(var a=this.selection.block(),l=1,o=s.length;l<o;l++){var d=elCreate(a.nodeName);d.innerHTML="<kbd>"+s[l]+(l===o-1?this.marker.html():"")+"</kbd>",a.parentNode.insertBefore(d,a.nextSibling),a=d}n.innerHTML=s[0],this.selection.restore()}}else{if(e.pre)return x.call(this,t,e);var h=elCreate("div");if(h.innerHTML=t,1===h.childElementCount&&"A"===h.children[0].nodeName){var c=h.children[0];if(h.firstChild===c&&h.lastChild===c&&c.href===c.textContent){for(;c.childNodes.length;)h.insertBefore(c.childNodes[0],c);h.removeChild(c)}}var p=[];e.pre||e.text||elBySelAll("img",h,function(t){var e,i=t.src;0!==i.indexOf("data:image")&&0!==i.indexOf("blob:")||i===A||(t.src=A,e=WCF.getUUID(),elData(t,"uuid",e),p.push({src:i,uuid:e}),elHide(t))}.bind(this)),elBySelAll("pre",h,function(t){elBySelAll("br",t,function(t){var e=t.parentNode;e.insertBefore(document.createTextNode("\n"),t),e.removeChild(t)})}),x.call(this,h.innerHTML,e);var f=window.getSelection();f.rangeCount&&"A"===f.anchorNode.nodeName&&f.anchorOffset===f.anchorNode.childNodes.length&&this.caret.after(f.anchorNode),p.length&&window.setTimeout(function(){for(var t,e,i=0,n=p.length;i<n;i++)t=p[i],(e=elBySel('img[data-uuid="'+t.uuid+'"]',this.$editor[0]))&&(g?e.parentNode.removeChild(e):0===t.src.indexOf("blob:")?window.fetch(t.src).then(function(t){return t.blob()}).then(function(t){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this.$element[0].id,{blob:t,replace:e})}.bind(this)):WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this.$element[0].id,{blob:this.utils.dataURItoBlob(t.src),replace:e}))}.bind(this),50);for(var u,b=[],m=this.core.editor()[0],l=0,o=m.childNodes.length;l<o;l++)(u=m.childNodes[l]).nodeType===Node.TEXT_NODE&&"​"===u.textContent&&b.push(u);b.forEach(elRemove),this.WoltLabClean.removeRedundantStyles(),this.rtePaste=!1}}.bind(this),this.paste.clipboardUpload=function(){}}}}; })(this);
 
 // plugins/WoltLabQuote.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabQuote=function(){"use strict";return{init:function(){var t=this.button.add("woltlabQuote","");this.WoltLabBlock.register("woltlab-quote",!0),this.opts.replaceTags.blockquote="woltlab-quote",this.opts.activeButtonsStates["woltlab-quote"]="woltlabQuote",require(["WoltLabSuite/Core/Ui/Redactor/Quote"],function(o){new o(this,t)}.bind(this))}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabQuote=function(){"use strict";return{init:function(){var o=this.button.add("woltlabQuote","");this.WoltLabBlock.register("woltlab-quote",!0),this.opts.replaceTags.blockquote="woltlab-quote",this.opts.activeButtonsStates["woltlab-quote"]="woltlabQuote",require(["WoltLabSuite/Core/Ui/Redactor/Quote"],function(t){new t(this,o)}.bind(this))}}}; })(this);
 
 // plugins/WoltLabReply.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabReply=function(){"use strict";var t=null,e=null,s=null;return{init:function(){var i=this.$editor[0].closest(".messageContent"),o=elById("messageQuickReply");i&&i.classList.contains("messageQuickReplyContent")&&o&&o.classList.contains("messageQuickReplyCollapsed")&&(t=this.WoltLabReply._click.bind(this),e=i,s=o,WCF.System.Event.addListener("com.woltlab.wcf.redactor2","showEditor",this.WoltLabReply.showEditor.bind(this)),e.addEventListener(WCF_CLICK_EVENT,t))},showEditor:function(){if(!s)return void this.WoltLabCaret.endOfEditor();s.classList.contains("messageQuickReplyCollapsed")&&(s.classList.remove("messageQuickReplyCollapsed"),e.removeEventListener(WCF_CLICK_EVENT,t),this.WoltLabCaret.endOfEditor())},_click:function(t){t.preventDefault(),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","showEditor")}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabReply=function(){"use strict";var s=null,i=null,o=null;return{init:function(){var t=this.$editor[0].closest(".messageContent"),e=elById("messageQuickReply");t&&t.classList.contains("messageQuickReplyContent")&&e&&e.classList.contains("messageQuickReplyCollapsed")&&(s=this.WoltLabReply._click.bind(this),i=t,o=e,WCF.System.Event.addListener("com.woltlab.wcf.redactor2","showEditor",this.WoltLabReply.showEditor.bind(this)),i.addEventListener(WCF_CLICK_EVENT,s))},showEditor:function(){o?o.classList.contains("messageQuickReplyCollapsed")&&(o.classList.remove("messageQuickReplyCollapsed"),i.removeEventListener(WCF_CLICK_EVENT,s),this.WoltLabCaret.endOfEditor()):this.WoltLabCaret.endOfEditor()},_click:function(t){t.preventDefault(),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","showEditor")}}}; })(this);
 
 // plugins/WoltLabSize.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabSize=function(){"use strict";return{init:function(){for(var e,t=[8,10,12,14,18,24,36],i=this.WoltLabSize.setSize.bind(this),o={},s=0,r=t.length;s<r;s++)e=t[s],o["size_"+e]={title:e,func:i};o.removeSize={title:this.lang.get("remove-size"),func:this.WoltLabSize.removeSize.bind(this)};var n=this.button.add("woltlabSize","");this.button.addDropdown(n,o);var a=n.data("dropdown");a.find("a").each(function(e,t){t.className.match(/redactor-dropdown-size_(\d{1,2})/)&&(t.style.setProperty("font-size",RegExp.$1+"pt",""),t.parentNode.classList.add("woltlab-size-selection"))}),$('<li class="dropdownDivider"></li>').insertBefore(a.children("li").last())},setSize:function(e){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(t){this.buffer.set(),t.format(this.$editor[0],"font-size",e.replace(/^size_/,"")+"pt"),this.buffer.set()}.bind(this)),this.selection.restore()},removeSize:function(){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(e){this.buffer.set(),e.removeFormat(this.$editor[0],"font-size"),this.buffer.set()}.bind(this)),this.selection.restore()}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabSize=function(){"use strict";return{init:function(){for(var e,t=[8,10,12,14,18,24,36],i=this.WoltLabSize.setSize.bind(this),o={},s=0,r=t.length;s<r;s++)o["size_"+(e=t[s])]={title:e,func:i};o.removeSize={title:this.lang.get("remove-size"),func:this.WoltLabSize.removeSize.bind(this)};var n=this.button.add("woltlabSize","");this.button.addDropdown(n,o);var a=n.data("dropdown");a.find("a").each(function(e,t){t.className.match(/redactor-dropdown-size_(\d{1,2})/)&&(t.style.setProperty("font-size",RegExp.$1+"pt",""),t.parentNode.classList.add("woltlab-size-selection"))}),$('<li class="dropdownDivider"></li>').insertBefore(a.children("li").last())},setSize:function(t){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(e){this.buffer.set(),e.format(this.$editor[0],"font-size",t.replace(/^size_/,"")+"pt"),this.buffer.set()}.bind(this)),this.selection.restore()},removeSize:function(){this.selection.save(),require(["WoltLabSuite/Core/Ui/Redactor/Format"],function(e){this.buffer.set(),e.removeFormat(this.$editor[0],"font-size"),this.buffer.set()}.bind(this)),this.selection.restore()}}}; })(this);
 
 // plugins/WoltLabSmiley.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabSmiley=function(){"use strict";var t=0;return{init:function(){require(["EventHandler"],function(t){t.add("com.woltlab.wcf.redactor2","insertSmiley_"+this.$element[0].id,this.WoltLabSmiley._insert.bind(this))}.bind(this))},_insert:function(e){if(!this.WoltLabSource.isActive()){this.buffer.set();var i="wscSmiley_"+this.uuid+"_"+t++,r=e.img.cloneNode();r.id=i,this.insert.html(r.outerHTML),r=elById(i),r.removeAttribute("id"),this.caret.after(r),r.outerHTML=r.outerHTML,this.WoltLabCaret.forceSelectionSave()}}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabSmiley=function(){"use strict";var c=0;return{init:function(){require(["EventHandler"],function(e){e.add("com.woltlab.wcf.redactor2","insertSmiley_"+this.$element[0].id,this.WoltLabSmiley._insert.bind(this))}.bind(this))},_insert:function(e){var t,i,o,n,r,d;this.WoltLabSource.isActive()||(this.buffer.set(),t="wscSmiley_"+this.uuid+"_"+c++,(i=e.img.cloneNode()).id=t,this.insert.html(i.outerHTML),(i=elById(t)).removeAttribute("id"),(o=i.nextSibling)&&o.nodeType===Node.TEXT_NODE&&"​"===o.textContent&&o.remove(),i.parentNode.insertBefore(document.createTextNode(" "),i),n=document.createTextNode(" "),i.parentNode.insertBefore(n,i.nextSibling),i.outerHTML=i.outerHTML,r=window.getSelection(),(d=document.createRange()).selectNode(n),d.collapse(!1),r.removeAllRanges(),r.addRange(d),this.WoltLabCaret.forceSelectionSave())}}}; })(this);
 
 // plugins/WoltLabSource.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabSource=function(){"use strict";return{init:function(){function e(e){elBySelAll(".icon, .fa",e,function(e){var t=e.className.split(" ");t=t.filter(function(e){return"fa"!==e&&"icon"!==e&&(!e.match(/^icon\d{2}$/)&&!e.match(/^fa-[a-z\-]+$/))}),e.className=t.join(" "),""===e.className.trim()&&""===e.innerHTML&&elRemove(e)})}var t=this.$element[0].id,n=function(e){elBySelAll("woltlab-quote",e,function(e){if(2===e.childElementCount&&"P"===e.children[0].nodeName&&"P"===e.children[1].nodeName){var t=e.children[0];if(""===t.innerHTML.trim()){"<br>"===e.children[1].innerHTML.trim()&&e.removeChild(t)}}})},i=function(e){elBySelAll("pre, woltlab-quote, woltlab-spoiler",e,function(e){e.removeAttribute("data-title")}),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","source_stripIntermediateCode_"+t,{div:e})},r=this.source.hide;this.source.hide=function(){var t=$("<div />").html(this.source.$textarea.val());e(t[0]),this.source.$textarea.val(t[0].innerHTML),r.call(this),setTimeout(function(){this.focus.end(),n(this.core.editor()[0])}.bind(this),100),this.placeholder.enable()}.bind(this);var o=this.source.$textarea[0];this.$element[0].parentNode.insertBefore(o,this.$element[0]);var l=this.source.show;this.source.show=function(){var e=this.$editor[0].offsetHeight,t=this.code.get();l.call(this),this.source.$textarea.val(t.replace(/&nbsp;/g," ")),o.style.setProperty("height",Math.ceil(e)+"px",""),o.style.setProperty("display","block","");var r=elCreate("div");r.innerHTML=o.value,n(r),i(r),o.value=this.WoltLabSource.format(r.innerHTML),o.selectionStart=o.selectionEnd=o.value.length}.bind(this),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","validate_"+t,function(e){o.clientHeight&&(e.api.throwError(this.$element[0],WCF.Language.get("wcf.editor.source.error.active")),e.valid=!1)}.bind(this))},isActive:function(){return"none"===this.$editor[0].style.getPropertyValue("display")},format:function(e){var t=["ul","ol","li","table","tbody","thead","tr","td","th"];this.block.tags.forEach(function(e){t.push(e)}),t=t.join("|").toLowerCase();var n=["p","li","td","th"],i="[^'\">]*(?:(?:\"[^\"]*\"|'[^']*')[^'\">]*)*",r=[];e=e.replace(new RegExp("<pre"+i+">[\\s\\S]*?</pre>","g"),function(e){return r.push(e),"@@@WCF_PRE_BACKUP_"+(r.length-1)+"@@@"}),e=e.replace(new RegExp("\\s*</("+t+")>\\s*","g"),function(e,t){return(-1===n.indexOf(t)?"\n":"")+"</"+t+">"}),e=e.replace(new RegExp("\\s*<("+t+")("+i+")>\\s*","g"),function(e,t,i){return"\n<"+t+i+">"+(-1===n.indexOf(t)?"\n":"")}),e=e.replace(new RegExp("(<(?:"+t+")(?:"+i+")>\n)\n+(?=<(?:"+t+")(?:"+i+")>)","g"),"$1"),e=e.replace(/<woltlab-quote([^>]*)>\n\t*\n(\t*)<p/,"<woltlab-quote$1>\n$2<p"),e=e.replace(new RegExp("<(ol|ul)("+i+")>\\s*","g"),"<$1$2>\n"),e=e.replace(/(<\/[ou]l>)<\/li>/g,"$1\n</li>");var o,l,a,c=e.split(/\n/),s=0,h=new RegExp("^<("+t+")"),u=new RegExp("^</("+t+")>$"),d=!1;for(o=0,l=c.length;o<l;o++){if(a=c[o],d=!1,a.match(h)?-1===n.indexOf(RegExp.$1)&&(d=!0):a.match(u)&&-1===n.indexOf(RegExp.$1)&&s--,s>0){var p=s;for(c[o]="";p--;)c[o]+="\t";c[o]+=a}d&&s++}for(e=c.join("\n"),o=0,l=r.length;o<l;o++)e=e.replace("@@@WCF_PRE_BACKUP_"+o+"@@@",r[o]);return e=e.replace(/\r?\n<\/pre>/g,"</pre>"),e.trim()}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabSource=function(){"use strict";return{init:function(){function n(e){elBySelAll("woltlab-quote",e,function(e){var t;2!==e.childElementCount||"P"!==e.children[0].nodeName||"P"!==e.children[1].nodeName||""===(t=e.children[0]).innerHTML.trim()&&"<br>"===e.children[1].innerHTML.trim()&&e.removeChild(t)})}var o=this.$element[0].id;var r=this.source.hide;this.source.hide=function(){var e,t=$("<div />").html(this.source.$textarea.val());e=t[0],elBySelAll(".icon, .fa",e,function(e){var t=(t=e.className.split(" ")).filter(function(e){return"fa"!==e&&"icon"!==e&&(!e.match(/^icon\d{2}$/)&&!e.match(/^fa-[a-z\-]+$/))});e.className=t.join(" "),""===e.className.trim()&&""===e.innerHTML&&elRemove(e)}),this.source.$textarea.val(t[0].innerHTML),r.call(this),setTimeout(function(){this.focus.end(),n(this.core.editor()[0])}.bind(this),100),this.placeholder.enable()}.bind(this);var l=this.source.$textarea[0];this.$element[0].parentNode.insertBefore(l,this.$element[0]);var a=this.source.show;this.source.show=function(){var e=this.$editor[0].offsetHeight,t=this.code.get();a.call(this),this.source.$textarea.val(t.replace(/&nbsp;/g," ")),l.style.setProperty("height",Math.ceil(e)+"px",""),l.style.setProperty("display","block","");var r,i=elCreate("div");i.innerHTML=l.value,n(i),r=i,elBySelAll("pre, woltlab-quote, woltlab-spoiler",r,function(e){e.removeAttribute("data-title")}),WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","source_stripIntermediateCode_"+o,{div:r}),l.value=this.WoltLabSource.format(i.innerHTML),l.selectionStart=l.selectionEnd=l.value.length}.bind(this),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","validate_"+o,function(e){this.WoltLabSource.isActive()&&(e.api.throwError(this.$element[0],WCF.Language.get("wcf.editor.source.error.active")),e.valid=!1)}.bind(this));var i,s=this.core.box()[0],c=s.closest("form");c&&(i=s.closest("dl"),c.addEventListener("submit",function(e){var t,r="";this.WoltLabSource.isActive()&&(e.preventDefault(),r=WCF.Language.get("wcf.editor.source.error.active"),(t=c.querySelector(".formSubmit input[type=submit]"))&&(t.disabled=!1),require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e._selectErroneousTabs()})),elInnerError(s,r),r?i.classList.add("formError"):i.classList.remove("formError")}.bind(this)))},isActive:function(){return"none"===this.$editor[0].style.getPropertyValue("display")},format:function(e){var t=["ul","ol","li","table","tbody","thead","tr","td","th"];this.block.tags.forEach(function(e){t.push(e)}),t=t.join("|").toLowerCase();for(var r,i=["p","li","td","th"],n="[^'\">]*(?:(?:\"[^\"]*\"|'[^']*')[^'\">]*)*",o=[],l=(e=(e=(e=(e=(e=(e=(e=e.replace(new RegExp("<pre"+n+">[\\s\\S]*?</pre>","g"),function(e){return o.push(e),"@@@WCF_PRE_BACKUP_"+(o.length-1)+"@@@"})).replace(new RegExp("\\s*</("+t+")>\\s*","g"),function(e,t){return(-1===i.indexOf(t)?"\n":"")+"</"+t+">"})).replace(new RegExp("\\s*<("+t+")("+n+")>\\s*","g"),function(e,t,r){return"\n<"+t+r+">"+(-1===i.indexOf(t)?"\n":"")})).replace(new RegExp("(<(?:"+t+")(?:"+n+")>\n)\n+(?=<(?:"+t+")(?:"+n+")>)","g"),"$1")).replace(/<woltlab-quote([^>]*)>\n\t*\n(\t*)<p/,"<woltlab-quote$1>\n$2<p")).replace(new RegExp("<(ol|ul)("+n+")>\\s*","g"),"<$1$2>\n")).replace(/(<\/[ou]l>)<\/li>/g,"$1\n</li>")).split(/\n/),a=0,s=new RegExp("^<("+t+")"),c=new RegExp("^</("+t+")>$"),u=!1,h=0,d=l.length;h<d;h++){if(u=!1,(r=l[h]).match(s)?-1===i.indexOf(RegExp.$1)&&(u=!0):r.match(c)&&-1===i.indexOf(RegExp.$1)&&a--,0<a){var f=a;for(l[h]="";f--;)l[h]+="\t";l[h]+=r}u&&a++}for(e=l.join("\n"),h=0,d=o.length;h<d;h++)e=e.replace("@@@WCF_PRE_BACKUP_"+h+"@@@",o[h]);return(e=e.replace(/\r?\n<\/pre>/g,"</pre>")).trim()}}}; })(this);
 
 // plugins/WoltLabSpoiler.js
 (function (window, undefined) { $.Redactor.prototype.WoltLabSpoiler=function(){"use strict";return{init:function(){this.WoltLabBlock.register("woltlab-spoiler",!0),this.opts.activeButtonsStates["woltlab-spoiler"]="woltlabSpoiler",require(["WoltLabSuite/Core/Ui/Redactor/Spoiler"],function(t){new t(this)}.bind(this))}}}; })(this);
 
 // plugins/WoltLabTable.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabTable=function(){"use strict";var e=null;return{init:function(){this.WoltLabEvent.register("insertedTable",function(){window.setTimeout(function(){var e=this.selection.block()||this.selection.current();if(e===this.$editor[0]){var t=window.getSelection();t.isCollapsed&&t.anchorNode===this.$editor[0]&&t.anchorOffset>0&&(e=t.anchorNode.childNodes[t.anchorOffset-1])}if("TBODY"===e.nodeName&&(e=e.parentNode),"TABLE"===e.nodeName){for(var i,o=[],r=0,s=e.childNodes.length;r<s;r++)i=e.childNodes[r],i.nodeType===Node.TEXT_NODE&&i.textContent.length>0&&o.push(i);o.forEach(elRemove);var l=elBySel("td",e);l&&this.caret.end(l)}}.bind(this),10)}.bind(this));var t=this.button.get("table").data("dropdown"),i=t.find(".redactor-dropdown-insert_table");i.off("mousedown"),i[0].addEventListener("mousedown",this.WoltLabTable._promptTableSize.bind(this)),require(["WoltLabSuite/Core/Ui/Redactor/Table"],function(t){e=t})},_promptTableSize:function(t){t.preventDefault(),this.table.getTable()||(this.selection.save(),e.showDialog({submitCallback:function(){this.WoltLabTable._insertTable(~~elById("redactor-table-rows").value,~~elById("redactor-table-cols").value)}.bind(this)}))},_insertTable:function(e,t){this.placeholder.hide();var i,o="<tr>";for(i=0;i<t;i++)o+="<td>"+this.opts.invisibleSpace+"</td>";o+="</tr>";var r="<table>";for(i=0;i<e;i++)r+=0===i?o.replace(new RegExp("^(<tr><td>"+this.opts.invisibleSpace+")"),"$1"+this.marker.html()):o;r+="</table>",this.selection.restore(),this.buffer.set();var s=this.selection.current();0!==$(s).closest("li",this.core.editor()[0]).length?$(s).closest("ul, ol").first().after(r):this.insert.html(r),this.selection.restore(),this.core.callback("insertedTable",void 0)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabTable=function(){"use strict";var t=null;return{init:function(){this.WoltLabEvent.register("insertedTable",function(){window.setTimeout(function(){var e,t=this.selection.block()||this.selection.current();if(t!==this.$editor[0]||(e=window.getSelection()).isCollapsed&&e.anchorNode===this.$editor[0]&&0<e.anchorOffset&&(t=e.anchorNode.childNodes[e.anchorOffset-1]),"TBODY"===t.nodeName&&(t=t.parentNode),"TABLE"===t.nodeName){for(var i,o=[],r=0,s=t.childNodes.length;r<s;r++)(i=t.childNodes[r]).nodeType===Node.TEXT_NODE&&0<i.textContent.length&&o.push(i);o.forEach(elRemove);var l=elBySel("td",t);l&&this.caret.end(l)}}.bind(this),10)}.bind(this));var e=this.button.get("table").data("dropdown").find(".redactor-dropdown-insert_table");e.off("mousedown"),e[0].addEventListener("mousedown",this.WoltLabTable._promptTableSize.bind(this)),require(["WoltLabSuite/Core/Ui/Redactor/Table"],function(e){t=e})},_promptTableSize:function(e){e.preventDefault(),this.table.getTable()||(this.selection.save(),t.showDialog({submitCallback:function(){this.WoltLabTable._insertTable(~~elById("redactor-table-rows").value,~~elById("redactor-table-cols").value)}.bind(this)}))},_insertTable:function(e,t){this.placeholder.hide();for(var i="<tr>",o=0;o<t;o++)i+="<td>"+this.opts.invisibleSpace+"</td>";i+="</tr>";var r="<table>";for(o=0;o<e;o++)r+=0===o?i.replace(new RegExp("^(<tr><td>"+this.opts.invisibleSpace+")"),"$1"+this.marker.html()):i;r+="</table>",this.selection.restore(),this.buffer.set();var s=this.selection.current();0!==$(s).closest("li",this.core.editor()[0]).length?$(s).closest("ul, ol").first().after(r):this.insert.html(r),this.selection.restore(),this.core.callback("insertedTable",void 0)}}}; })(this);
 
 // plugins/WoltLabUtils.js
-(function (window, undefined) { $.Redactor.prototype.WoltLabUtils=function(){"use strict";return{init:function(){var t=this.utils.replaceToTag;this.utils.replaceToTag=function(i,r){return"figure"===r?i:t.call(this,i,r)}.bind(this)}}}; })(this);
+(function (window, undefined) { $.Redactor.prototype.WoltLabUtils=function(){"use strict";return{init:function(){var r=this.utils.replaceToTag;this.utils.replaceToTag=function(t,i){return"figure"===i?t:r.call(this,t,i)}.bind(this)}}}; })(this);
 
 // plugins/alignment.js
-(function (window, undefined) { !function(t){t.Redactor.prototype.alignment=function(){return{langs:{en:{align:"Align","align-left":"Align Left","align-center":"Align Center","align-right":"Align Right","align-justify":"Align Justify"}},init:function(){var t=this,e={};e.left={title:t.lang.get("align-left"),func:t.alignment.setLeft},e.center={title:t.lang.get("align-center"),func:t.alignment.setCenter},e.right={title:t.lang.get("align-right"),func:t.alignment.setRight},e.justify={title:t.lang.get("align-justify"),func:t.alignment.setJustify};var i=this.button.add("alignment",this.lang.get("align"));this.button.setIcon(i,'<i class="re-icon-alignment"></i>'),this.button.addDropdown(i,e)},removeAlign:function(){this.block.removeClass("text-center"),this.block.removeClass("text-right"),this.block.removeClass("text-justify")},setLeft:function(){this.buffer.set(),this.alignment.removeAlign()},setCenter:function(){this.buffer.set(),this.alignment.removeAlign(),this.block.addClass("text-center"),this.core.editor().focus()},setRight:function(){this.buffer.set(),this.alignment.removeAlign(),this.block.addClass("text-right"),this.core.editor().focus()},setJustify:function(){this.buffer.set(),this.alignment.removeAlign(),this.block.addClass("text-justify"),this.core.editor().focus()}}}}(jQuery); })(this);
+(function (window, undefined) { jQuery.Redactor.prototype.alignment=function(){return{langs:{en:{align:"Align","align-left":"Align Left","align-center":"Align Center","align-right":"Align Right","align-justify":"Align Justify"}},init:function(){var t=this,e={};e.left={title:t.lang.get("align-left"),func:t.alignment.setLeft},e.center={title:t.lang.get("align-center"),func:t.alignment.setCenter},e.right={title:t.lang.get("align-right"),func:t.alignment.setRight},e.justify={title:t.lang.get("align-justify"),func:t.alignment.setJustify};var i=this.button.add("alignment",this.lang.get("align"));this.button.setIcon(i,'<i class="re-icon-alignment"></i>'),this.button.addDropdown(i,e)},removeAlign:function(){this.block.removeClass("text-center"),this.block.removeClass("text-right"),this.block.removeClass("text-justify")},setLeft:function(){this.buffer.set(),this.alignment.removeAlign()},setCenter:function(){this.buffer.set(),this.alignment.removeAlign(),this.block.addClass("text-center"),this.core.editor().focus()},setRight:function(){this.buffer.set(),this.alignment.removeAlign(),this.block.addClass("text-right"),this.core.editor().focus()},setJustify:function(){this.buffer.set(),this.alignment.removeAlign(),this.block.addClass("text-justify"),this.core.editor().focus()}}}; })(this);
 
 // plugins/source.js
-(function (window, undefined) { !function(e){e.Redactor.prototype.source=function(){return{init:function(){var t=this.button.addFirst("html","HTML");this.button.addCallback(t,this.source.toggle);var o={width:"100%",margin:"0",background:"#111","box-sizing":"border-box",color:"rgba(255, 255, 255, .8)","font-size":"14px",outline:"none",padding:"16px","line-height":"22px","font-family":'Menlo, Monaco, Consolas, "Courier New", monospace'};this.source.$textarea=e("<textarea />"),this.source.$textarea.css(o).hide(),"textarea"===this.opts.type?this.core.box().append(this.source.$textarea):this.core.box().after(this.source.$textarea),this.core.element().on("destroy.callback.redactor",e.proxy(function(){this.source.$textarea.remove()},this))},toggle:function(){return this.source.$textarea.hasClass("open")?this.source.hide():this.source.show()},setCaretOnShow:function(){},setCaretOnHide:function(e){return e},hide:function(){this.source.$textarea.removeClass("open").hide(),this.source.$textarea.off(".redactor-source");var e=this.source.$textarea.val();e=this.paragraphize.load(e),this.code.start(e),this.button.enableAll(),this.core.editor().show().focus(),this.selection.restore(),this.code.sync()},show:function(){this.selection.save();var t=this.core.editor().innerHeight(),o=this.code.get();o=o.replace(/\n\n\n/g,"\n"),o=o.replace(/\n\n/g,"\n"),this.core.editor().hide(),this.button.disableAll(["html","woltlabFullscreen"]),this.source.$textarea.val(o).height(t).addClass("open").show(),this.source.$textarea.on("keyup.redactor-source",e.proxy(function(){"textarea"===this.opts.type&&this.core.textarea().val(this.source.$textarea.val())},this)),this.marker.remove(),e(window).scrollTop(scroll),this.source.$textarea[0].setSelectionRange&&this.source.$textarea[0].setSelectionRange(this.source.start,this.source.end),this.source.$textarea[0].scrollTop=0,setTimeout(e.proxy(function(){this.source.$textarea.focus(),this.button.setActive("html")},this),0)},enlargeOffset:function(){}}}}(jQuery); })(this);
+(function (window, undefined) { !function(o){o.Redactor.prototype.source=function(){return{init:function(){var e=this.button.addFirst("html","HTML");this.button.addCallback(e,this.source.toggle);this.source.$textarea=o("<textarea />"),this.source.$textarea.css({width:"100%",margin:"0",background:"#111","box-sizing":"border-box",color:"rgba(255, 255, 255, .8)","font-size":"14px",outline:"none",padding:"16px","line-height":"22px","font-family":'Menlo, Monaco, Consolas, "Courier New", monospace'}).hide(),"textarea"===this.opts.type?this.core.box().append(this.source.$textarea):this.core.box().after(this.source.$textarea),this.core.element().on("destroy.callback.redactor",o.proxy(function(){this.source.$textarea.remove()},this))},toggle:function(){return this.source.$textarea.hasClass("open")?this.source.hide():this.source.show()},setCaretOnShow:function(){},setCaretOnHide:function(e){return e},hide:function(){this.source.$textarea.removeClass("open").hide(),this.source.$textarea.off(".redactor-source");var e=this.source.$textarea.val(),e=this.paragraphize.load(e);this.code.start(e),this.button.enableAll(),this.core.editor().show().focus(),this.selection.restore(),this.code.sync()},show:function(){this.selection.save();var e=this.core.editor().innerHeight(),t=this.code.get();t=(t=t.replace(/\n\n\n/g,"\n")).replace(/\n\n/g,"\n"),this.core.editor().hide(),this.button.disableAll(["html","woltlabFullscreen"]),this.source.$textarea.val(t).height(e).addClass("open").show(),this.source.$textarea.on("keyup.redactor-source",o.proxy(function(){"textarea"===this.opts.type&&this.core.textarea().val(this.source.$textarea.val())},this)),this.marker.remove(),o(window).scrollTop(scroll),this.source.$textarea[0].setSelectionRange&&this.source.$textarea[0].setSelectionRange(this.source.start,this.source.end),this.source.$textarea[0].scrollTop=0,setTimeout(o.proxy(function(){this.source.$textarea.focus(),this.button.setActive("html")},this),0)},enlargeOffset:function(){}}}}(jQuery); })(this);
 
 // plugins/table.js
-(function (window, undefined) { !function(e){e.Redactor.prototype.table=function(){return{langs:{en:{table:"Table","insert-table":"Insert table","insert-row-above":"Insert row above","insert-row-below":"Insert row below","insert-column-left":"Insert column left","insert-column-right":"Insert column right","add-head":"Add head","delete-head":"Delete head","delete-column":"Delete column","delete-row":"Delete row","delete-table":"Delete table"}},init:function(){var e={};e.insert_table={title:this.lang.get("insert-table"),func:this.table.insert,observe:{element:"table",in:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_row_above={title:this.lang.get("insert-row-above"),func:this.table.addRowAbove,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_row_below={title:this.lang.get("insert-row-below"),func:this.table.addRowBelow,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_column_left={title:this.lang.get("insert-column-left"),func:this.table.addColumnLeft,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_column_right={title:this.lang.get("insert-column-right"),func:this.table.addColumnRight,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.add_head={title:this.lang.get("add-head"),func:this.table.addHead,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_head={title:this.lang.get("delete-head"),func:this.table.deleteHead,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_column={title:this.lang.get("delete-column"),func:this.table.deleteColumn,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_row={title:this.lang.get("delete-row"),func:this.table.deleteRow,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_table={title:this.lang.get("delete-table"),func:this.table.deleteTable,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}};var t=this.button.addBefore("link","table",this.lang.get("table"));this.button.setIcon(t,'<i class="re-icon-table"></i>'),this.button.addDropdown(t,e)},insert:function(){if(!this.table.getTable()){this.placeholder.hide();for(var t=e("<div>"),a=e("<table />"),i=0;i<2;i++){for(var r=e("<tr>"),l=0;l<3;l++){var n=e("<td>"+this.opts.invisibleSpace+"</td>");0===i&&0===l&&n.append(this.marker.get()),e(r).append(n)}a.append(r)}t.append(a);var s=t.html();this.buffer.set();var o=this.selection.current();0!==e(o).closest("li",this.core.editor()[0]).length?e(o).closest("ul, ol").first().after(s):(this.air.collapsed(),this.insert.html(s)),this.selection.restore(),this.core.callback("insertedTable",a)}},getTable:function(){var t=e(this.selection.current()).closest("table");return!!this.utils.isRedactorParent(t)&&(0!==t.length&&t)},restoreAfterDelete:function(e){this.selection.restore(),e.find("span.redactor-selection-marker").remove()},deleteTable:function(){var e=this.table.getTable();if(e){this.buffer.set();var t=e.next();this.opts.linebreaks||0===t.length?this.caret.after(e):this.caret.start(t),e.remove()}},deleteRow:function(){var t=this.table.getTable();if(t){var a=e(this.selection.current());this.buffer.set();var i=a.closest("tr"),r=i.prev().length?i.prev():i.next();if(r.length){var l=r.children("td, th").first();l.length&&l.prepend(this.marker.get())}i.remove(),this.table.restoreAfterDelete(t)}},deleteColumn:function(){var t=this.table.getTable();if(t){this.buffer.set();var a=e(this.selection.current()),i=a.closest("td, th"),r=i[0].cellIndex;t.find("tr").each(e.proxy(function(t,a){var i=e(a),l=r-1<0?r+1:r-1;0===t&&i.find("td, th").eq(l).prepend(this.marker.get()),i.find("td, th").eq(r).remove()},this)),this.table.restoreAfterDelete(t)}},addHead:function(){var t=this.table.getTable();if(t){if(this.buffer.set(),0!==t.find("thead").length)return void this.table.deleteHead();var a=t.find("tr").first().clone();a.find("td").replaceWith(e.proxy(function(){return e("<th>").html(this.opts.invisibleSpace)},this)),$thead=e("<thead></thead>").append(a),t.prepend($thead)}},deleteHead:function(){var e=this.table.getTable();if(e){var t=e.find("thead");0!==t.length&&(this.buffer.set(),t.remove())}},addRowAbove:function(){this.table.addRow("before")},addRowBelow:function(){this.table.addRow("after")},addColumnLeft:function(){this.table.addColumn("before")},addColumnRight:function(){this.table.addColumn("after")},addRow:function(t){if(this.table.getTable()){this.buffer.set();var a=e(this.selection.current()),i=a.closest("tr"),r=i.clone();r.find("th").replaceWith(function(){var t=e("<td>");return t[0].attributes=this.attributes,t.append(e(this).contents())}),r.find("td").html(this.opts.invisibleSpace),"after"===t?i.after(r):i.before(r)}},addColumn:function(t){var a=this.table.getTable();if(a){var i=0,r=e(this.selection.current());this.buffer.set();var l=r.closest("tr"),n=r.closest("td, th");l.find("td, th").each(e.proxy(function(t,a){e(a)[0]===n[0]&&(i=t)},this)),a.find("tr").each(e.proxy(function(a,r){var l=e(r).find("td, th").eq(i),n=l.clone();n.html(this.opts.invisibleSpace),"after"===t?l.after(n):l.before(n)},this))}}}}}(jQuery); })(this);
+(function (window, undefined) { !function(o){o.Redactor.prototype.table=function(){return{langs:{en:{table:"Table","insert-table":"Insert table","insert-row-above":"Insert row above","insert-row-below":"Insert row below","insert-column-left":"Insert column left","insert-column-right":"Insert column right","add-head":"Add head","delete-head":"Delete head","delete-column":"Delete column","delete-row":"Delete row","delete-table":"Delete table"}},init:function(){var e={};e.insert_table={title:this.lang.get("insert-table"),func:this.table.insert,observe:{element:"table",in:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_row_above={title:this.lang.get("insert-row-above"),func:this.table.addRowAbove,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_row_below={title:this.lang.get("insert-row-below"),func:this.table.addRowBelow,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_column_left={title:this.lang.get("insert-column-left"),func:this.table.addColumnLeft,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.insert_column_right={title:this.lang.get("insert-column-right"),func:this.table.addColumnRight,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.add_head={title:this.lang.get("add-head"),func:this.table.addHead,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_head={title:this.lang.get("delete-head"),func:this.table.deleteHead,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_column={title:this.lang.get("delete-column"),func:this.table.deleteColumn,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_row={title:this.lang.get("delete-row"),func:this.table.deleteRow,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}},e.delete_table={title:this.lang.get("delete-table"),func:this.table.deleteTable,observe:{element:"table",out:{attr:{class:"redactor-dropdown-link-inactive","aria-disabled":!0}}}};var t=this.button.addBefore("link","table",this.lang.get("table"));this.button.setIcon(t,'<i class="re-icon-table"></i>'),this.button.addDropdown(t,e)},insert:function(){if(!this.table.getTable()){this.placeholder.hide();for(var e=o("<div>"),t=o("<table />"),a=0;a<2;a++){for(var i=o("<tr>"),l=0;l<3;l++){var r=o("<td>"+this.opts.invisibleSpace+"</td>");0===a&&0===l&&r.append(this.marker.get()),o(i).append(r)}t.append(i)}e.append(t);var n=e.html();this.buffer.set();var s=this.selection.current();0!==o(s).closest("li",this.core.editor()[0]).length?o(s).closest("ul, ol").first().after(n):(this.air.collapsed(),this.insert.html(n)),this.selection.restore(),this.core.callback("insertedTable",t)}},getTable:function(){var e=o(this.selection.current()).closest("table");return!!this.utils.isRedactorParent(e)&&(0!==e.length&&e)},restoreAfterDelete:function(e){this.selection.restore(),e.find("span.redactor-selection-marker").remove()},deleteTable:function(){var e,t=this.table.getTable();t&&(this.buffer.set(),e=t.next(),this.opts.linebreaks||0===e.length?this.caret.after(t):this.caret.start(e),t.remove())},deleteRow:function(){var e,t,a,i,l=this.table.getTable();l&&(e=o(this.selection.current()),this.buffer.set(),!(a=(t=e.closest("tr")).prev().length?t.prev():t.next()).length||(i=a.children("td, th").first()).length&&i.prepend(this.marker.get()),t.remove(),this.table.restoreAfterDelete(l))},deleteColumn:function(){var l,e=this.table.getTable();e&&(this.buffer.set(),l=o(this.selection.current()).closest("td, th")[0].cellIndex,e.find("tr").each(o.proxy(function(e,t){var a=o(t),i=l-1<0?l+1:l-1;0===e&&a.find("td, th").eq(i).prepend(this.marker.get()),a.find("td, th").eq(l).remove()},this)),this.table.restoreAfterDelete(e))},addHead:function(){var e,t=this.table.getTable();t&&(this.buffer.set(),0===t.find("thead").length?((e=t.find("tr").first().clone()).find("td").replaceWith(o.proxy(function(){return o("<th>").html(this.opts.invisibleSpace)},this)),$thead=o("<thead></thead>").append(e),t.prepend($thead)):this.table.deleteHead())},deleteHead:function(){var e,t=this.table.getTable();!t||0!==(e=t.find("thead")).length&&(this.buffer.set(),e.remove())},addRowAbove:function(){this.table.addRow("before")},addRowBelow:function(){this.table.addRow("after")},addColumnLeft:function(){this.table.addColumn("before")},addColumnRight:function(){this.table.addColumn("after")},addRow:function(e){var t,a;this.table.getTable()&&(this.buffer.set(),(a=(t=o(this.selection.current()).closest("tr")).clone()).find("th").replaceWith(function(){var e=o("<td>");return e[0].attributes=this.attributes,e.append(o(this).contents())}),a.find("td").html(this.opts.invisibleSpace),"after"===e?t.after(a):t.before(a))},addColumn:function(l){var r,e,t,a,i=this.table.getTable();i&&(r=0,e=o(this.selection.current()),this.buffer.set(),t=e.closest("tr"),a=e.closest("td, th"),t.find("td, th").each(o.proxy(function(e,t){o(t)[0]===a[0]&&(r=e)},this)),i.find("tr").each(o.proxy(function(e,t){var a=o(t).find("td, th").eq(r),i=a.clone();i.html(this.opts.invisibleSpace),"after"===l?a.after(i):a.before(i)},this)))}}}}(jQuery); })(this);
 
index d0f82d2539e32f2237326f491c576ddb886ad810..3f9b99569949ff4748313ebd659a71582cd4d57b 100644 (file)
                                },
                                dragover: function (e) {
                                        e.preventDefault();
-                                       e.stopPropagation();
                                        
                                        if (e.target.tagName === 'IMG') {
                                                $(e.target).addClass('redactor-image-dragover');
                                                this.indent.repositionItem($item);
                                        }
                                        
+                                       var tmpWrapper = null;
                                        if ($item.length === 0) {
+                                               // `formatBlock` does not handle custom elements gracefully, always
+                                               // treating them as inline elements, causing these to be chopped up
+                                               // into separate elements. We can mitigate this problem by introducing
+                                               // a temporary intermediate `<div>` which will serve as a block wrapper.
+                                               var block = this.selection.block();
+                                               if (block && block.nodeName.indexOf('-') !== -1) {
+                                                       this.selection.save();
+                                                       
+                                                       tmpWrapper = elCreate('div');
+                                                       while (block.childNodes.length) {
+                                                               tmpWrapper.appendChild(block.childNodes[0]);
+                                                       }
+                                                       block.appendChild(tmpWrapper);
+                                                       
+                                                       this.selection.restore();
+                                               }
+                                               
                                                document.execCommand('formatblock', false, 'p');
                                                $item = $(this.selection.current());
                                                var $next = $item.next();
                                        
                                        // normalize
                                        this.selection.save();
+                                       
+                                       if (tmpWrapper !== null) {
+                                               var parent = tmpWrapper.parentNode;
+                                               while (tmpWrapper.childNodes.length) {
+                                                       parent.insertBefore(tmpWrapper.childNodes[0], tmpWrapper);
+                                               }
+                                               parent.removeChild(tmpWrapper);
+                                       }
+                                       
                                        this.indent.removeEmpty();
                                        this.indent.normalize();
                                        this.selection.restore();
                                        }
                                },
                                formatUncollapsed: function (tag, params) {
+                                       var element;
+                                       
                                        this.selection.save();
+
+                                       var range = window.getSelection().getRangeAt(0);
+                                       var contents = range.cloneContents();
+                                       if (contents.querySelector(tag) === null) {
+                                               element = range.startContainer;
+                                               if (element.nodeType === Node.TEXT_NODE) {
+                                                       element = element.parentElement;
+                                               }
+
+                                               var parentWithTheSameTag = element.closest(tag);
+                                               if (parentWithTheSameTag !== null && this.core.editor()[0].contains(parentWithTheSameTag)) {
+                                                       // We need to split the matching parent element
+                                                       // by moving everything to the left and the right
+                                                       // into separate nodes.
+                                                       var leftElement = document.createElement(tag);
+                                                       parentWithTheSameTag.insertAdjacentElement("beforebegin", leftElement);
+
+                                                       var leftRange = document.createRange();
+                                                       leftRange.selectNodeContents(parentWithTheSameTag);
+                                                       leftRange.setEnd(range.startContainer, range.startOffset);
+                                                       leftElement.appendChild(leftRange.extractContents());
+
+                                                       var rightElement = document.createElement(tag);
+                                                       parentWithTheSameTag.insertAdjacentElement("afterend", rightElement);
+
+                                                       var rightRange = document.createRange();
+                                                       rightRange.selectNodeContents(parentWithTheSameTag);
+                                                       rightRange.setStart(range.endContainer, range.endOffset);
+                                                       rightElement.appendChild(rightRange.extractContents());
+
+                                                       // Finally remove the offending parent element.
+                                                       var parentElement = parentWithTheSameTag.parentElement;
+                                                       while (parentWithTheSameTag.childNodes.length) {
+                                                               parentElement.insertBefore(parentWithTheSameTag.childNodes[0], parentWithTheSameTag);
+                                                       }
+                                                       parentWithTheSameTag.remove();
+                                                       
+                                                       return;
+                                               }
+                                       }
                                        
                                        var nodes = this.inline.getClearedNodes();
                                        this.inline.setNodesStriked(nodes, tag, params);
                                        // WoltLab: Chrome misbehaves in some cases, causing the `<strike>` element for
                                        // contained elements to be stripped. Instead, those children are assigned the
                                        // CSS style `text-decoration-line: line-through`.
-                                       var chromeElements = this.core.editor()[0].querySelectorAll('[style*="line-through"]'), element, strike;
+                                       var chromeElements = this.core.editor()[0].querySelectorAll('[style*="line-through"]'), strike;
                                        for (var i = 0, length = chromeElements.length; i < length; i++) {
                                                element = chromeElements[0];
 
diff --git a/wcfsetup/install/files/js/3rdParty/zxcvbn.js b/wcfsetup/install/files/js/3rdParty/zxcvbn.js
new file mode 100644 (file)
index 0000000..aa0a900
--- /dev/null
@@ -0,0 +1,24 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.zxcvbn = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+var adjacency_graphs;adjacency_graphs={qwerty:{"!":["`~",null,null,"2@","qQ",null],'"':[";:","[{","]}",null,null,"/?"],"#":["2@",null,null,"4$","eE","wW"],$:["3#",null,null,"5%","rR","eE"],"%":["4$",null,null,"6^","tT","rR"],"&":["6^",null,null,"8*","uU","yY"],"'":[";:","[{","]}",null,null,"/?"],"(":["8*",null,null,"0)","oO","iI"],")":["9(",null,null,"-_","pP","oO"],"*":["7&",null,null,"9(","iI","uU"],"+":["-_",null,null,null,"]}","[{"],",":["mM","kK","lL",".>",null,null],"-":["0)",null,null,"=+","[{","pP"],".":[",<","lL",";:","/?",null,null],"/":[".>",";:","'\"",null,null,null],0:["9(",null,null,"-_","pP","oO"],1:["`~",null,null,"2@","qQ",null],2:["1!",null,null,"3#","wW","qQ"],3:["2@",null,null,"4$","eE","wW"],4:["3#",null,null,"5%","rR","eE"],5:["4$",null,null,"6^","tT","rR"],6:["5%",null,null,"7&","yY","tT"],7:["6^",null,null,"8*","uU","yY"],8:["7&",null,null,"9(","iI","uU"],9:["8*",null,null,"0)","oO","iI"],":":["lL","pP","[{","'\"","/?",".>"],";":["lL","pP","[{","'\"","/?",".>"],"<":["mM","kK","lL",".>",null,null],"=":["-_",null,null,null,"]}","[{"],">":[",<","lL",";:","/?",null,null],"?":[".>",";:","'\"",null,null,null],"@":["1!",null,null,"3#","wW","qQ"],A:[null,"qQ","wW","sS","zZ",null],B:["vV","gG","hH","nN",null,null],C:["xX","dD","fF","vV",null,null],D:["sS","eE","rR","fF","cC","xX"],E:["wW","3#","4$","rR","dD","sS"],F:["dD","rR","tT","gG","vV","cC"],G:["fF","tT","yY","hH","bB","vV"],H:["gG","yY","uU","jJ","nN","bB"],I:["uU","8*","9(","oO","kK","jJ"],J:["hH","uU","iI","kK","mM","nN"],K:["jJ","iI","oO","lL",",<","mM"],L:["kK","oO","pP",";:",".>",",<"],M:["nN","jJ","kK",",<",null,null],N:["bB","hH","jJ","mM",null,null],O:["iI","9(","0)","pP","lL","kK"],P:["oO","0)","-_","[{",";:","lL"],Q:[null,"1!","2@","wW","aA",null],R:["eE","4$","5%","tT","fF","dD"],S:["aA","wW","eE","dD","xX","zZ"],T:["rR","5%","6^","yY","gG","fF"],U:["yY","7&","8*","iI","jJ","hH"],V:["cC","fF","gG","bB",null,null],W:["qQ","2@","3#","eE","sS","aA"],X:["zZ","sS","dD","cC",null,null],Y:["tT","6^","7&","uU","hH","gG"],Z:[null,"aA","sS","xX",null,null],"[":["pP","-_","=+","]}","'\"",";:"],"\\":["]}",null,null,null,null,null],"]":["[{","=+",null,"\\|",null,"'\""],"^":["5%",null,null,"7&","yY","tT"],_:["0)",null,null,"=+","[{","pP"],"`":[null,null,null,"1!",null,null],a:[null,"qQ","wW","sS","zZ",null],b:["vV","gG","hH","nN",null,null],c:["xX","dD","fF","vV",null,null],d:["sS","eE","rR","fF","cC","xX"],e:["wW","3#","4$","rR","dD","sS"],f:["dD","rR","tT","gG","vV","cC"],g:["fF","tT","yY","hH","bB","vV"],h:["gG","yY","uU","jJ","nN","bB"],i:["uU","8*","9(","oO","kK","jJ"],j:["hH","uU","iI","kK","mM","nN"],k:["jJ","iI","oO","lL",",<","mM"],l:["kK","oO","pP",";:",".>",",<"],m:["nN","jJ","kK",",<",null,null],n:["bB","hH","jJ","mM",null,null],o:["iI","9(","0)","pP","lL","kK"],p:["oO","0)","-_","[{",";:","lL"],q:[null,"1!","2@","wW","aA",null],r:["eE","4$","5%","tT","fF","dD"],s:["aA","wW","eE","dD","xX","zZ"],t:["rR","5%","6^","yY","gG","fF"],u:["yY","7&","8*","iI","jJ","hH"],v:["cC","fF","gG","bB",null,null],w:["qQ","2@","3#","eE","sS","aA"],x:["zZ","sS","dD","cC",null,null],y:["tT","6^","7&","uU","hH","gG"],z:[null,"aA","sS","xX",null,null],"{":["pP","-_","=+","]}","'\"",";:"],"|":["]}",null,null,null,null,null],"}":["[{","=+",null,"\\|",null,"'\""],"~":[null,null,null,"1!",null,null]},dvorak:{"!":["`~",null,null,"2@","'\"",null],'"':[null,"1!","2@",",<","aA",null],"#":["2@",null,null,"4$",".>",",<"],$:["3#",null,null,"5%","pP",".>"],"%":["4$",null,null,"6^","yY","pP"],"&":["6^",null,null,"8*","gG","fF"],"'":[null,"1!","2@",",<","aA",null],"(":["8*",null,null,"0)","rR","cC"],")":["9(",null,null,"[{","lL","rR"],"*":["7&",null,null,"9(","cC","gG"],"+":["/?","]}",null,"\\|",null,"-_"],",":["'\"","2@","3#",".>","oO","aA"],"-":["sS","/?","=+",null,null,"zZ"],".":[",<","3#","4$","pP","eE","oO"],"/":["lL","[{","]}","=+","-_","sS"],0:["9(",null,null,"[{","lL","rR"],1:["`~",null,null,"2@","'\"",null],2:["1!",null,null,"3#",",<","'\""],3:["2@",null,null,"4$",".>",",<"],4:["3#",null,null,"5%","pP",".>"],5:["4$",null,null,"6^","yY","pP"],6:["5%",null,null,"7&","fF","yY"],7:["6^",null,null,"8*","gG","fF"],8:["7&",null,null,"9(","cC","gG"],9:["8*",null,null,"0)","rR","cC"],":":[null,"aA","oO","qQ",null,null],";":[null,"aA","oO","qQ",null,null],"<":["'\"","2@","3#",".>","oO","aA"],"=":["/?","]}",null,"\\|",null,"-_"],">":[",<","3#","4$","pP","eE","oO"],"?":["lL","[{","]}","=+","-_","sS"],"@":["1!",null,null,"3#",",<","'\""],A:[null,"'\"",",<","oO",";:",null],B:["xX","dD","hH","mM",null,null],C:["gG","8*","9(","rR","tT","hH"],D:["iI","fF","gG","hH","bB","xX"],E:["oO",".>","pP","uU","jJ","qQ"],F:["yY","6^","7&","gG","dD","iI"],G:["fF","7&","8*","cC","hH","dD"],H:["dD","gG","cC","tT","mM","bB"],I:["uU","yY","fF","dD","xX","kK"],J:["qQ","eE","uU","kK",null,null],K:["jJ","uU","iI","xX",null,null],L:["rR","0)","[{","/?","sS","nN"],M:["bB","hH","tT","wW",null,null],N:["tT","rR","lL","sS","vV","wW"],O:["aA",",<",".>","eE","qQ",";:"],P:[".>","4$","5%","yY","uU","eE"],Q:[";:","oO","eE","jJ",null,null],R:["cC","9(","0)","lL","nN","tT"],S:["nN","lL","/?","-_","zZ","vV"],T:["hH","cC","rR","nN","wW","mM"],U:["eE","pP","yY","iI","kK","jJ"],V:["wW","nN","sS","zZ",null,null],W:["mM","tT","nN","vV",null,null],X:["kK","iI","dD","bB",null,null],Y:["pP","5%","6^","fF","iI","uU"],Z:["vV","sS","-_",null,null,null],"[":["0)",null,null,"]}","/?","lL"],"\\":["=+",null,null,null,null,null],"]":["[{",null,null,null,"=+","/?"],"^":["5%",null,null,"7&","fF","yY"],_:["sS","/?","=+",null,null,"zZ"],"`":[null,null,null,"1!",null,null],a:[null,"'\"",",<","oO",";:",null],b:["xX","dD","hH","mM",null,null],c:["gG","8*","9(","rR","tT","hH"],d:["iI","fF","gG","hH","bB","xX"],e:["oO",".>","pP","uU","jJ","qQ"],f:["yY","6^","7&","gG","dD","iI"],g:["fF","7&","8*","cC","hH","dD"],h:["dD","gG","cC","tT","mM","bB"],i:["uU","yY","fF","dD","xX","kK"],j:["qQ","eE","uU","kK",null,null],k:["jJ","uU","iI","xX",null,null],l:["rR","0)","[{","/?","sS","nN"],m:["bB","hH","tT","wW",null,null],n:["tT","rR","lL","sS","vV","wW"],o:["aA",",<",".>","eE","qQ",";:"],p:[".>","4$","5%","yY","uU","eE"],q:[";:","oO","eE","jJ",null,null],r:["cC","9(","0)","lL","nN","tT"],s:["nN","lL","/?","-_","zZ","vV"],t:["hH","cC","rR","nN","wW","mM"],u:["eE","pP","yY","iI","kK","jJ"],v:["wW","nN","sS","zZ",null,null],w:["mM","tT","nN","vV",null,null],x:["kK","iI","dD","bB",null,null],y:["pP","5%","6^","fF","iI","uU"],z:["vV","sS","-_",null,null,null],"{":["0)",null,null,"]}","/?","lL"],"|":["=+",null,null,null,null,null],"}":["[{",null,null,null,"=+","/?"],"~":[null,null,null,"1!",null,null]},keypad:{"*":["/",null,null,null,"-","+","9","8"],"+":["9","*","-",null,null,null,null,"6"],"-":["*",null,null,null,null,null,"+","9"],".":["0","2","3",null,null,null,null,null],"/":[null,null,null,null,"*","9","8","7"],0:[null,"1","2","3",".",null,null,null],1:[null,null,"4","5","2","0",null,null],2:["1","4","5","6","3",".","0",null],3:["2","5","6",null,null,null,".","0"],4:[null,null,"7","8","5","2","1",null],5:["4","7","8","9","6","3","2","1"],6:["5","8","9","+",null,null,"3","2"],7:[null,null,null,"/","8","5","4",null],8:["7",null,"/","*","9","6","5","4"],9:["8","/","*","-","+",null,"6","5"]},mac_keypad:{"*":["/",null,null,null,null,null,"-","9"],"+":["6","9","-",null,null,null,null,"3"],"-":["9","/","*",null,null,null,"+","6"],".":["0","2","3",null,null,null,null,null],"/":["=",null,null,null,"*","-","9","8"],0:[null,"1","2","3",".",null,null,null],1:[null,null,"4","5","2","0",null,null],2:["1","4","5","6","3",".","0",null],3:["2","5","6","+",null,null,".","0"],4:[null,null,"7","8","5","2","1",null],5:["4","7","8","9","6","3","2","1"],6:["5","8","9","-","+",null,"3","2"],7:[null,null,null,"=","8","5","4",null],8:["7",null,"=","/","9","6","5","4"],9:["8","=","/","*","-","+","6","5"],"=":[null,null,null,null,"/","9","8","7"]}},module.exports=adjacency_graphs;
+
+},{}],2:[function(require,module,exports){
+var Feedback,scoring;scoring=require("./scoring"),Feedback=function(){class s{constructor(s={}){var e,a,r,t,n,o;for(this.phrases={},e=0,r=(t=[this.constructor.default_phrases,s]).length;e<r;e++)for(a in n=t[e])o=n[a],this.phrases[a]={...this.phrases[a]||{},...o};this.default_feedback={warning:"",suggestions:[this.phrases.suggestions.use_words_avoid_common_phrases,this.phrases.suggestions.no_need_for_symbols_digits_uppercase]}}from_result(s){return this.get_feedback(s.score,s.sequence)}get_feedback(s,e){var a,r,t,n,o,i,g;if(0===e.length)return this.default_feedback;if(s>2)return{warning:"",suggestions:[]};for(o=e[0],t=0,n=(g=e.slice(1)).length;t<n;t++)(i=g[t]).token.length>o.token.length&&(o=i);return r=this.get_match_feedback(o,1===e.length),a=this.phrases.suggestions.add_word_uncommon_better,null!=r?(r.suggestions.unshift(a),null==r.warning&&(r.warning="")):r={warning:"",suggestions:[a]},r}get_match_feedback(s,e){switch(s.pattern){case"dictionary":return this.get_dictionary_match_feedback(s,e);case"spatial":return s.graph.toUpperCase(),{warning:1===s.turns?this.phrases.warnings.straight_row:this.phrases.warnings.short_keyboard_pattern,suggestions:[this.phrases.suggestions.use_longer_keyboard_pattern]};case"repeat":return{warning:1===s.base_token.length?this.phrases.warnings.repeat_single_char:this.phrases.warnings.repeat,suggestions:[this.phrases.suggestions.avoid_repeat]};case"sequence":return{warning:this.phrases.warnings.sequence,suggestions:[this.phrases.suggestions.avoid_sequence]};case"regex":if("recent_year"===s.regex_name)return{warning:this.phrases.warnings.recent_year,suggestions:[this.phrases.suggestions.avoid_recent_year,this.phrases.suggestions.avoid_associated_year]};break;case"date":return{warning:this.phrases.warnings.date,suggestions:[this.phrases.suggestions.avoid_date]}}}get_dictionary_match_feedback(s,e){var a,r,t,n;return t="passwords"===s.dictionary_name?!e||s.l33t||s.reversed?s.guesses_log10<=4?this.phrases.warnings.common_alike:void 0:s.rank<=10?this.phrases.warnings.top_10:s.rank<=100?this.phrases.warnings.top_100:this.phrases.warnings.common:"english_wikipedia"===s.dictionary_name?e?this.phrases.warnings.sole_word:void 0:"surnames"===(a=s.dictionary_name)||"male_names"===a||"female_names"===a?e?this.phrases.warnings.sole_name:this.phrases.warnings.name:"",r=[],(n=s.token).match(scoring.START_UPPER)?r.push(this.phrases.suggestions.start_upper):n.match(scoring.ALL_UPPER)&&n.toLowerCase()!==n&&r.push(this.phrases.suggestions.all_upper),s.reversed&&s.token.length>=4&&r.push(this.phrases.suggestions.reversed),s.l33t&&r.push(this.phrases.suggestions.l33t),{warning:t,suggestions:r}}}return s.default_phrases={suggestions:{use_words_avoid_common_phrases:"Use a few words, avoid common phrases",no_need_for_symbols_digits_uppercase:"No need for symbols, digits, or uppercase letters",add_word_uncommon_better:"Add another word or two. Uncommon words are better.",use_longer_keyboard_pattern:"Use a longer keyboard pattern with more turns",avoid_repeat:"Avoid repeated words and characters",avoid_sequence:"Avoid sequences",avoid_recent_year:"Avoid recent years",avoid_associated_year:"Avoid years that are associated with you",avoid_date:"Avoid dates and years that are associated with you",start_upper:"Capitalization doesn't help very much",all_upper:"All-uppercase is almost as easy to guess as all-lowercase",reversed:"Reversed words aren't much harder to guess",l33t:"Predictable substitutions like '@' instead of 'a' don't help very much"},warnings:{straight_row:"Straight rows of keys are easy to guess",short_keyboard_pattern:"Short keyboard patterns are easy to guess",repeat_single_char:'Repeats like "aaa" are easy to guess',repeat:'Repeats like "abcabcabc" are only slightly harder to guess than "abc"',sequence:"Sequences like abc or 6543 are easy to guess",recent_year:"Recent years are easy to guess",date:"Dates are often easy to guess",top_10:"This is a top-10 common password",top_100:"This is a top-100 common password",common:"This is a very common password",common_alike:"This is similar to a commonly used password",sole_word:"A word by itself is easy to guess",sole_name:"Names and surnames by themselves are easy to guess",name:"Common names and surnames are easy to guess"}},s}.call(this),module.exports=Feedback;
+
+},{"./scoring":6}],3:[function(require,module,exports){
+var frequency_lists;frequency_lists={passwords:"123456,password,12345678,qwerty,123456789,12345,1234,111111,1234567,dragon,123123,baseball,abc123,football,monkey,letmein,shadow,master,696969,mustang,666666,qwertyuiop,123321,1234567890,pussy,superman,654321,1qaz2wsx,7777777,fuckyou,qazwsx,jordan,123qwe,000000,killer,trustno1,hunter,harley,zxcvbnm,asdfgh,buster,batman,soccer,tigger,charlie,sunshine,iloveyou,fuckme,ranger,hockey,computer,starwars,asshole,pepper,klaster,112233,zxcvbn,freedom,princess,maggie,pass,ginger,11111111,131313,fuck,love,cheese,159753,summer,chelsea,dallas,biteme,matrix,yankees,6969,corvette,austin,access,thunder,merlin,secret,diamond,hello,hammer,fucker,1234qwer,silver,gfhjkm,internet,samantha,golfer,scooter,test,orange,cookie,q1w2e3r4t5,maverick,sparky,phoenix,mickey,bigdog,snoopy,guitar,whatever,chicken,camaro,mercedes,peanut,ferrari,falcon,cowboy,welcome,sexy,samsung,steelers,smokey,dakota,arsenal,boomer,eagles,tigers,marina,nascar,booboo,gateway,yellow,porsche,monster,spider,diablo,hannah,bulldog,junior,london,purple,compaq,lakers,iceman,qwer1234,hardcore,cowboys,money,banana,ncc1701,boston,tennis,q1w2e3r4,coffee,scooby,123654,nikita,yamaha,mother,barney,brandy,chester,fuckoff,oliver,player,forever,rangers,midnight,chicago,bigdaddy,redsox,angel,badboy,fender,jasper,slayer,rabbit,natasha,marine,bigdick,wizard,marlboro,raiders,prince,casper,fishing,flower,jasmine,iwantu,panties,adidas,winter,winner,gandalf,password1,enter,ghbdtn,1q2w3e4r,golden,cocacola,jordan23,winston,madison,angels,panther,blowme,sexsex,bigtits,spanky,bitch,sophie,asdfasdf,horny,thx1138,toyota,tiger,dick,canada,12344321,blowjob,8675309,muffin,liverpoo,apples,qwerty123,passw0rd,abcd1234,pokemon,123abc,slipknot,qazxsw,123456a,scorpion,qwaszx,butter,startrek,rainbow,asdfghjkl,razz,newyork,redskins,gemini,cameron,qazwsxedc,florida,liverpool,turtle,sierra,viking,booger,butthead,doctor,rocket,159357,dolphins,captain,bandit,jaguar,packers,pookie,peaches,789456,asdf,dolphin,helpme,blue,theman,maxwell,qwertyui,shithead,lovers,maddog,giants,nirvana,metallic,hotdog,rosebud,mountain,warrior,stupid,elephant,suckit,success,bond007,jackass,alexis,porn,lucky,scorpio,samson,q1w2e3,azerty,rush2112,driver,freddy,1q2w3e4r5t,sydney,gators,dexter,red123,123456q,12345a,bubba,creative,voodoo,golf,trouble,america,nissan,gunner,garfield,bullshit,asdfghjk,5150,fucking,apollo,1qazxsw2,2112,eminem,legend,airborne,bear,beavis,apple,brooklyn,godzilla,skippy,4815162342,buddy,qwert,kitten,magic,shelby,beaver,phantom,asdasd,xavier,braves,darkness,blink182,copper,platinum,qweqwe,tomcat,01012011,girls,bigboy,102030,animal,police,online,11223344,voyager,lifehack,12qwaszx,fish,sniper,315475,trinity,blazer,heaven,lover,snowball,playboy,loveme,bubbles,hooters,cricket,willow,donkey,topgun,nintendo,saturn,destiny,pakistan,pumpkin,digital,sergey,redwings,explorer,tits,private,runner,therock,guinness,lasvegas,beatles,789456123,fire,cassie,christin,qwerty1,celtic,asdf1234,andrey,broncos,007007,babygirl,eclipse,fluffy,cartman,michigan,carolina,testing,alexande,birdie,pantera,cherry,vampire,mexico,dickhead,buffalo,genius,montana,beer,minecraft,maximus,flyers,lovely,stalker,metallica,doggie,snickers,speedy,bronco,lol123,paradise,yankee,horses,magnum,dreams,147258369,lacrosse,ou812,goober,enigma,qwertyu,scotty,pimpin,bollocks,surfer,cock,poohbear,genesis,star,asd123,qweasdzxc,racing,hello1,hawaii,eagle1,viper,poopoo,einstein,boobies,12345q,bitches,drowssap,simple,badger,alaska,action,jester,drummer,111222,spitfire,forest,maryjane,champion,diesel,svetlana,friday,hotrod,147258,chevy,lucky1,westside,security,google,badass,tester,shorty,thumper,hitman,mozart,zaq12wsx,boobs,reddog,010203,lizard,a123456,123456789a,ruslan,eagle,1232323q,scarface,qwerty12,147852,a12345,buddha,porno,420420,spirit,money1,stargate,qwe123,naruto,mercury,liberty,12345qwert,semperfi,suzuki,popcorn,spooky,marley,scotland,kitty,cherokee,vikings,simpsons,rascal,qweasd,hummer,loveyou,michael1,patches,russia,jupiter,penguin,passion,cumshot,vfhbyf,honda,vladimir,sandman,passport,raider,bastard,123789,infinity,assman,bulldogs,fantasy,sucker,1234554321,horney,domino,budlight,disney,ironman,usuckballz1,softball,brutus,redrum,bigred,mnbvcxz,fktrcfylh,karina,marines,digger,kawasaki,cougar,fireman,oksana,monday,cunt,justice,nigger,super,wildcats,tinker,logitech,dancer,swordfis,avalon,everton,alexandr,motorola,patriots,hentai,madonna,pussy1,ducati,colorado,connor,juventus,galore,smooth,freeuser,warcraft,boogie,titanic,wolverin,elizabet,arizona,valentin,saints,asdfg,accord,test123,password123,christ,yfnfif,stinky,slut,spiderma,naughty,chopper,hello123,ncc1701d,extreme,skyline,poop,zombie,pearljam,123qweasd,froggy,awesome,vision,pirate,fylhtq,dreamer,bullet,predator,empire,123123a,kirill,charlie1,panthers,penis,skipper,nemesis,rasdzv3,peekaboo,rolltide,cardinal,psycho,danger,mookie,happy1,wanker,chevelle,manutd,goblue,9379992,hobbes,vegeta,fyfcnfcbz,852456,picard,159951,windows,loverboy,victory,vfrcbv,bambam,serega,123654789,turkey,tweety,galina,hiphop,rooster,changeme,berlin,taurus,suckme,polina,electric,avatar,134679,maksim,raptor,alpha1,hendrix,newport,bigcock,brazil,spring,a1b2c3,madmax,alpha,britney,sublime,darkside,bigman,wolfpack,classic,hercules,ronaldo,letmein1,1q2w3e,741852963,spiderman,blizzard,123456789q,cheyenne,cjkysirj,tiger1,wombat,bubba1,pandora,zxc123,holiday,wildcat,devils,horse,alabama,147852369,caesar,12312,buddy1,bondage,pussycat,pickle,shaggy,catch22,leather,chronic,a1b2c3d4,admin,qqq111,qaz123,airplane,kodiak,freepass,billybob,sunset,katana,phpbb,chocolat,snowman,angel1,stingray,firebird,wolves,zeppelin,detroit,pontiac,gundam,panzer,vagina,outlaw,redhead,tarheels,greenday,nastya,01011980,hardon,engineer,dragon1,hellfire,serenity,cobra,fireball,lickme,darkstar,1029384756,01011,mustang1,flash,124578,strike,beauty,pavilion,01012000,bobafett,dbrnjhbz,bigmac,bowling,chris1,ytrewq,natali,pyramid,rulez,welcome1,dodgers,apache,swimming,whynot,teens,trooper,fuckit,defender,precious,135790,packard,weasel,popeye,lucifer,cancer,icecream,142536,raven,swordfish,presario,viktor,rockstar,blonde,james1,wutang,spike,pimp,atlanta,airforce,thailand,casino,lennon,mouse,741852,hacker,bluebird,hawkeye,456123,theone,catfish,sailor,goldfish,nfnmzyf,tattoo,pervert,barbie,maxima,nipples,machine,trucks,wrangler,rocks,tornado,lights,cadillac,bubble,pegasus,madman,longhorn,browns,target,666999,eatme,qazwsx123,microsoft,dilbert,christia,baller,lesbian,shooter,xfiles,seattle,qazqaz,cthutq,amateur,prelude,corona,freaky,malibu,123qweasdzxc,assassin,246810,atlantis,integra,pussies,iloveu,lonewolf,dragons,monkey1,unicorn,software,bobcat,stealth,peewee,openup,753951,srinivas,zaqwsx,valentina,shotgun,trigger,veronika,bruins,coyote,babydoll,joker,dollar,lestat,rocky1,hottie,random,butterfly,wordpass,smiley,sweety,snake,chipper,woody,samurai,devildog,gizmo,maddie,soso123aljg,mistress,freedom1,flipper,express,hjvfirf,moose,cessna,piglet,polaris,teacher,montreal,cookies,wolfgang,scully,fatboy,wicked,balls,tickle,bunny,dfvgbh,foobar,transam,pepsi,fetish,oicu812,basketba,toshiba,hotstuff,sunday,booty,gambit,31415926,impala,stephani,jessica1,hooker,lancer,knicks,shamrock,fuckyou2,stinger,314159,redneck,deftones,squirt,siemens,blaster,trucker,subaru,renegade,ibanez,manson,swinger,reaper,blondie,mylove,galaxy,blahblah,enterpri,travel,1234abcd,babylon5,indiana,skeeter,master1,sugar,ficken,smoke,bigone,sweetpea,fucked,trfnthbyf,marino,escort,smitty,bigfoot,babes,larisa,trumpet,spartan,valera,babylon,asdfghj,yankees1,bigboobs,stormy,mister,hamlet,aardvark,butterfl,marathon,paladin,cavalier,manchester,skater,indigo,hornet,buckeyes,01011990,indians,karate,hesoyam,toronto,diamonds,chiefs,buckeye,1qaz2wsx3edc,highland,hotsex,charger,redman,passwor,maiden,drpepper,storm,pornstar,garden,12345678910,pencil,sherlock,timber,thuglife,insane,pizza,jungle,jesus1,aragorn,1a2b3c,hamster,david1,triumph,techno,lollol,pioneer,catdog,321654,fktrctq,morpheus,141627,pascal,shadow1,hobbit,wetpussy,erotic,consumer,blabla,justme,stones,chrissy,spartak,goforit,burger,pitbull,adgjmptw,italia,barcelona,hunting,colors,kissme,virgin,overlord,pebbles,sundance,emerald,doggy,racecar,irina,element,1478963,zipper,alpine,basket,goddess,poison,nipple,sakura,chichi,huskers,13579,pussys,q12345,ultimate,ncc1701e,blackie,nicola,rommel,matthew1,caserta,omega,geronimo,sammy1,trojan,123qwe123,philips,nugget,tarzan,chicks,aleksandr,bassman,trixie,portugal,anakin,dodger,bomber,superfly,madness,q1w2e3r4t5y6,loser,123asd,fatcat,ybrbnf,soldier,warlock,wrinkle1,desire,sexual,babe,seminole,alejandr,951753,11235813,westham,andrei,concrete,access14,weed,letmein2,ladybug,naked,christop,trombone,tintin,bluesky,rhbcnbyf,qazxswedc,onelove,cdtnkfyf,whore,vfvjxrf,titans,stallion,truck,hansolo,blue22,smiles,beagle,panama,kingkong,flatron,inferno,mongoose,connect,poiuyt,snatch,qawsed,juice,blessed,rocker,snakes,turbo,bluemoon,sex4me,finger,jamaica,a1234567,mulder,beetle,fuckyou1,passat,immortal,plastic,123454321,anthony1,whiskey,dietcoke,suck,spunky,magic1,monitor,cactus,exigen,planet,ripper,teen,spyder,apple1,nolimit,hollywoo,sluts,sticky,trunks,1234321,14789632,pickles,sailing,bonehead,ghbdtnbr,delta,charlott,rubber,911911,112358,molly1,yomama,hongkong,jumper,william1,ilovesex,faster,unreal,cumming,memphis,1123581321,nylons,legion,sebastia,shalom,pentium,geheim,werewolf,funtime,ferret,orion,curious,555666,niners,cantona,sprite,philly,pirates,abgrtyu,lollipop,eternity,boeing,super123,sweets,cooldude,tottenha,green1,jackoff,stocking,7895123,moomoo,martini,biscuit,drizzt,colt45,fossil,makaveli,snapper,satan666,maniac,salmon,patriot,verbatim,nasty,shasta,asdzxc,shaved,blackcat,raistlin,qwerty12345,punkrock,cjkywt,01012010,4128,waterloo,crimson,twister,oxford,musicman,seinfeld,biggie,condor,ravens,megadeth,wolfman,cosmos,sharks,banshee,keeper,foxtrot,gn56gn56,skywalke,velvet,black1,sesame,dogs,squirrel,privet,sunrise,wolverine,sucks,legolas,grendel,ghost,cats,carrot,frosty,lvbnhbq,blades,stardust,frog,qazwsxed,121314,coolio,brownie,groovy,twilight,daytona,vanhalen,pikachu,peanuts,licker,hershey,jericho,intrepid,ninja,1234567a,zaq123,lobster,goblin,punisher,strider,shogun,kansas,amadeus,seven7,jason1,neptune,showtime,muscle,oldman,ekaterina,rfrfirf,getsome,showme,111222333,obiwan,skittles,danni,tanker,maestro,tarheel,anubis,hannibal,anal,newlife,gothic,shark,fighter,blue123,blues,123456z,princes,slick,chaos,thunder1,sabine,1q2w3e4r5t6y,python,test1,mirage,devil,clover,tequila,chelsea1,surfing,delete,potato,chubby,panasonic,sandiego,portland,baggins,fusion,sooners,blackdog,buttons,californ,moscow,playtime,mature,1a2b3c4d,dagger,dima,stimpy,asdf123,gangster,warriors,iverson,chargers,byteme,swallow,liquid,lucky7,dingdong,nymets,cracker,mushroom,456852,crusader,bigguy,miami,dkflbvbh,bugger,nimrod,tazman,stranger,newpass,doodle,powder,gotcha,guardian,dublin,slapshot,septembe,147896325,pepsi1,milano,grizzly,woody1,knights,photos,2468,nookie,charly,rammstein,brasil,123321123,scruffy,munchkin,poopie,123098,kittycat,latino,walnut,1701,thegame,viper1,1passwor,kolobok,picasso,robert1,barcelon,bananas,trance,auburn,coltrane,eatshit,goodluck,starcraft,wheels,parrot,postal,blade,wisdom,pink,gorilla,katerina,pass123,andrew1,shaney14,dumbass,osiris,fuck_inside,oakland,discover,ranger1,spanking,lonestar,bingo,meridian,ping,heather1,dookie,stonecol,megaman,192837465,rjntyjr,ledzep,lowrider,25802580,richard1,firefly,griffey,racerx,paradox,ghjcnj,gangsta,zaq1xsw2,tacobell,weezer,sirius,halflife,buffett,shiloh,123698745,vertigo,sergei,aliens,sobaka,keyboard,kangaroo,sinner,soccer1,0.0.000,bonjour,socrates,chucky,hotboy,sprint,0007,sarah1,scarlet,celica,shazam,formula1,sommer,trebor,qwerasdf,jeep,mailcreated5240,bollox,asshole1,fuckface,honda1,rebels,vacation,lexmark,penguins,12369874,ragnarok,formula,258456,tempest,vfhecz,tacoma,qwertz,colombia,flames,rockon,duck,prodigy,wookie,dodgeram,mustangs,123qaz,sithlord,smoker,server,bang,incubus,scoobydo,oblivion,molson,kitkat,titleist,rescue,zxcv1234,carpet,1122,bigballs,tardis,jimbob,xanadu,blueeyes,shaman,mersedes,pooper,pussy69,golfing,hearts,mallard,12312312,kenwood,patrick1,dogg,cowboys1,oracle,123zxc,nuttertools,102938,topper,1122334455,shemale,sleepy,gremlin,yourmom,123987,gateway1,printer,monkeys,peterpan,mikey,kingston,cooler,analsex,jimbo,pa55word,asterix,freckles,birdman,frank1,defiant,aussie,stud,blondes,tatyana,445566,aspirine,mariners,jackal,deadhead,katrin,anime,rootbeer,frogger,polo,scooter1,hallo,noodles,thomas1,parola,shaolin,celine,11112222,plymouth,creampie,justdoit,ohyeah,fatass,assfuck,amazon,1234567q,kisses,magnus,camel,nopass,bosco,987456,6751520,harley1,putter,champs,massive,spidey,lightnin,camelot,letsgo,gizmodo,aezakmi,bones,caliente,12121,goodtime,thankyou,raiders1,brucelee,redalert,aquarius,456654,catherin,smokin,pooh,mypass,astros,roller,porkchop,sapphire,qwert123,kevin1,a1s2d3f4,beckham,atomic,rusty1,vanilla,qazwsxedcrfv,hunter1,kaktus,cxfcnmt,blacky,753159,elvis1,aggies,blackjac,bangkok,scream,123321q,iforgot,power1,kasper,abc12,buster1,slappy,shitty,veritas,chevrole,amber1,01012001,vader,amsterdam,jammer,primus,spectrum,eduard,granny,horny1,sasha1,clancy,usa123,satan,diamond1,hitler,avenger,1221,spankme,123456qwerty,simba,smudge,scrappy,labrador,john316,syracuse,front242,falcons,husker,candyman,commando,gator,pacman,delta1,pancho,krishna,fatman,clitoris,pineappl,lesbians,8j4ye3uz,barkley,vulcan,punkin,boner,celtics,monopoly,flyboy,romashka,hamburg,123456aa,lick,gangbang,223344,area51,spartans,aaa111,tricky,snuggles,drago,homerun,vectra,homer1,hermes,topcat,cuddles,infiniti,1234567890q,cosworth,goose,phoenix1,killer1,ivanov,bossman,qawsedrf,peugeot,exigent,doberman,durango,brandon1,plumber,telefon,horndog,laguna,rbhbkk,dawg,webmaster,breeze,beast,porsche9,beefcake,leopard,redbull,oscar1,topdog,godsmack,theking,pics,omega1,speaker,viktoria,fuckers,bowler,starbuck,gjkbyf,valhalla,anarchy,blacks,herbie,kingpin,starfish,nokia,loveit,achilles,906090,labtec,ncc1701a,fitness,jordan1,brando,arsenal1,bull,kicker,napass,desert,sailboat,bohica,tractor,hidden,muppet,jackson1,jimmy1,terminator,phillies,pa55w0rd,terror,farside,swingers,legacy,frontier,butthole,doughboy,jrcfyf,tuesday,sabbath,daniel1,nebraska,homers,qwertyuio,azamat,fallen,agent007,striker,camels,iguana,looker,pinkfloy,moloko,qwerty123456,dannyboy,luckydog,789654,pistol,whocares,charmed,skiing,select,franky,puppy,daniil,vladik,vette,vfrcbvrf,ihateyou,nevada,moneys,vkontakte,mandingo,puppies,666777,mystic,zidane,kotenok,dilligaf,budman,bunghole,zvezda,123457,triton,golfball,technics,trojans,panda,laptop,rookie,01011991,15426378,aberdeen,gustav,jethro,enterprise,igor,stripper,filter,hurrican,rfnthbyf,lespaul,gizmo1,butch,132435,dthjybrf,1366613,excalibu,963852,nofear,momoney,possum,cutter,oilers,moocow,cupcake,gbpltw,batman1,splash,svetik,super1,soleil,bogdan,melissa1,vipers,babyboy,tdutybq,lancelot,ccbill,keystone,passwort,flamingo,firefox,dogman,vortex,rebel,noodle,raven1,zaphod,killme,pokemon1,coolman,danila,designer,skinny,kamikaze,deadman,gopher,doobie,warhammer,deeznuts,freaks,engage,chevy1,steve1,apollo13,poncho,hammers,azsxdc,dracula,000007,sassy,bitch1,boots,deskjet,12332,macdaddy,mighty,rangers1,manchest,sterlin,casey1,meatball,mailman,sinatra,cthulhu,summer1,bubbas,cartoon,bicycle,eatpussy,truelove,sentinel,tolkien,breast,capone,lickit,summit,123456k,peter1,daisy1,kitty1,123456789z,crazy1,jamesbon,texas1,sexygirl,362436,sonic,billyboy,redhot,microsof,microlab,daddy1,rockets,iloveyo,fernand,gordon24,danie,cutlass,polska,star69,titties,pantyhos,01011985,thekid,aikido,gofish,mayday,1234qwe,coke,anfield,sony,lansing,smut,scotch,sexx,catman,73501505,hustler,saun,dfkthbz,passwor1,jenny1,azsxdcfv,cheers,irish1,gabrie,tinman,orioles,1225,charlton,fortuna,01011970,airbus,rustam,xtreme,bigmoney,zxcasd,retard,grumpy,huskies,boxing,4runner,kelly1,ultima,warlord,fordf150,oranges,rotten,asdfjkl,superstar,denali,sultan,bikini,saratoga,thor,figaro,sixers,wildfire,vladislav,128500,sparta,mayhem,greenbay,chewie,music1,number1,cancun,fabie,mellon,poiuytrewq,cloud9,crunch,bigtime,chicken1,piccolo,bigbird,321654987,billy1,mojo,01011981,maradona,sandro,chester1,bizkit,rjirfrgbde,789123,rightnow,jasmine1,hyperion,treasure,meatloaf,armani,rovers,jarhead,01011986,cruise,coconut,dragoon,utopia,davids,cosmo,rfhbyf,reebok,1066,charli,giorgi,sticks,sayang,pass1234,exodus,anaconda,zaqxsw,illini,woofwoof,emily1,sandy1,packer,poontang,govols,jedi,tomato,beaner,cooter,creamy,lionking,happy123,albatros,poodle,kenworth,dinosaur,greens,goku,happyday,eeyore,tsunami,cabbage,holyshit,turkey50,memorex,chaser,bogart,orgasm,tommy1,volley,whisper,knopka,ericsson,walleye,321123,pepper1,katie1,chickens,tyler1,corrado,twisted,100000,zorro,clemson,zxcasdqwe,tootsie,milana,zenith,fktrcfylhf,shania,frisco,polniypizdec0211,crazybab,junebug,fugazi,rereirf,vfvekz,1001,sausage,vfczyz,koshka,clapton,justin1,anhyeuem,condom,fubar,hardrock,skywalker,tundra,cocks,gringo,150781,canon,vitalik,aspire,stocks,samsung1,applepie,abc12345,arjay,gandalf1,boob,pillow,sparkle,gmoney,rockhard,lucky13,samiam,everest,hellyeah,bigsexy,skorpion,rfrnec,hedgehog,australi,candle,slacker,dicks,voyeur,jazzman,america1,bobby1,br0d3r,wolfie,vfksirf,1qa2ws3ed,13243546,fright,yosemite,temp,karolina,fart,barsik,surf,cheetah,baddog,deniska,starship,bootie,milena,hithere,kume,greatone,dildo,50cent,0.0.0.000,albion,amanda1,midget,lion,maxell,football1,cyclone,freeporn,nikola,bonsai,kenshin,slider,balloon,roadkill,killbill,222333,jerkoff,78945612,dinamo,tekken,rambler,goliath,cinnamon,malaka,backdoor,fiesta,packers1,rastaman,fletch,sojdlg123aljg,stefano,artemis,calico,nyjets,damnit,robotech,duchess,rctybz,hooter,keywest,18436572,hal9000,mechanic,pingpong,operator,presto,sword,rasputin,spank,bristol,faggot,shado,963852741,amsterda,321456,wibble,carrera,alibaba,majestic,ramses,duster,route66,trident,clipper,steeler,wrestlin,divine,kipper,gotohell,kingfish,snake1,passwords,buttman,pompey,viagra,zxcvbnm1,spurs,332211,slutty,lineage2,oleg,macross,pooter,brian1,qwert1,charles1,slave,jokers,yzerman,swimmer,ne1469,nwo4life,solnce,seamus,lolipop,pupsik,moose1,ivanova,secret1,matador,love69,420247,ktyjxrf,subway,cinder,vermont,pussie,chico,florian,magick,guiness,allsop,ghetto,flash1,a123456789,typhoon,dfkthf,depeche,skydive,dammit,seeker,fuckthis,crysis,kcj9wx5n,umbrella,r2d2c3po,123123q,snoopdog,critter,theboss,ding,162534,splinter,kinky,cyclops,jayhawk,456321,caramel,qwer123,underdog,caveman,onlyme,grapes,feather,hotshot,fuckher,renault,george1,sex123,pippen,000001,789987,floppy,cunts,megapass,1000,pornos,usmc,kickass,great1,quattro,135246,wassup,helloo,p0015123,nicole1,chivas,shannon1,bullseye,java,fishes,blackhaw,jamesbond,tunafish,juggalo,dkflbckfd,123789456,dallas1,translator,122333,beanie,alucard,gfhjkm123,supersta,magicman,ashley1,cohiba,xbox360,caligula,12131415,facial,7753191,dfktynbyf,cobra1,cigars,fang,klingon,bob123,safari,looser,10203,deepthroat,malina,200000,tazmania,gonzo,goalie,jacob1,monaco,cruiser,misfit,vh5150,tommyboy,marino13,yousuck,sharky,vfhufhbnf,horizon,absolut,brighton,123456r,death1,kungfu,maxx,forfun,mamapapa,enter1,budweise,banker,getmoney,kostya,qazwsx12,bigbear,vector,fallout,nudist,gunners,royals,chainsaw,scania,trader,blueboy,walrus,eastside,kahuna,qwerty1234,love123,steph,01011989,cypress,champ,undertaker,ybrjkfq,europa,snowboar,sabres,moneyman,chrisbln,minime,nipper,groucho,whitey,viewsonic,penthous,wolf359,fabric,flounder,coolguy,whitesox,passme,smegma,skidoo,thanatos,fucku2,snapple,dalejr,mondeo,thesims,mybaby,panasoni,sinbad,thecat,topher,frodo,sneakers,q123456,z1x2c3,alfa,chicago1,taylor1,ghjcnjnfr,cat123,olivier,cyber,titanium,0420,madison1,jabroni,dang,hambone,intruder,holly1,gargoyle,sadie1,static,poseidon,studly,newcastl,sexxxx,poppy,johannes,danzig,beastie,musica,buckshot,sunnyday,adonis,bluedog,bonkers,2128506,chrono,compute,spawn,01011988,turbo1,smelly,wapbbs,goldstar,ferrari1,778899,quantum,pisces,boomboom,gunnar,1024,test1234,florida1,nike,superman1,multiplelo,custom,motherlode,1qwerty,westwood,usnavy,apple123,daewoo,korn,stereo,sasuke,sunflowe,watcher,dharma,555777,mouse1,assholes,babyblue,123qwerty,marius,walmart,snoop,starfire,tigger1,paintbal,knickers,aaliyah,lokomotiv,theend,winston1,sapper,rover,erotica,scanner,racer,zeus,sexy69,doogie,bayern,joshua1,newbie,scott1,losers,droopy,outkast,martin1,dodge1,wasser,ufkbyf,rjycnfynby,thirteen,12345z,112211,hotred,deejay,hotpussy,192837,jessic,philippe,scout,panther1,cubbies,havefun,magpie,fghtkm,avalanch,newyork1,pudding,leonid,harry1,cbr600,audia4,bimmer,fucku,01011984,idontknow,vfvfgfgf,1357,aleksey,builder,01011987,zerocool,godfather,mylife,donuts,allmine,redfish,777888,sascha,nitram,bounce,333666,smokes,1x2zkg8w,rodman,stunner,zxasqw12,hoosier,hairy,beretta,insert,123456s,rtyuehe,francesc,tights,cheese1,micron,quartz,hockey1,gegcbr,searay,jewels,bogey,paintball,celeron,padres,bing,syncmaster,ziggy,simon1,beaches,prissy,diehard,orange1,mittens,aleksandra,queens,02071986,biggles,thongs,southpark,artur,twinkle,gretzky,rabota,cambiami,monalisa,gollum,chuckles,spike1,gladiator,whisky,spongebob,sexy1,03082006,mazafaka,meathead,4121,ou8122,barefoot,12345678q,cfitymrf,bigass,a1s2d3,kosmos,blessing,titty,clevelan,terrapin,ginger1,johnboy,maggot,clarinet,deeznutz,336699,stumpy,stoney,footbal,traveler,volvo,bucket,snapon,pianoman,hawkeyes,futbol,casanova,tango,goodboy,scuba,honey1,sexyman,warthog,mustard,abc1234,nickel,10203040,meowmeow,1012,boricua,prophet,sauron,12qwas,reefer,andromeda,crystal1,joker1,90210,goofy,loco,lovesex,triangle,whatsup,mellow,bengals,monster1,maste,01011910,lover1,love1,123aaa,sunshin,smeghead,hokies,sting,welder,rambo,cerberus,bunny1,rockford,monke,1q2w3e4r5,goldwing,gabriell,buzzard,crjhgbjy,james007,rainman,groove,tiberius,purdue,nokia6300,hayabusa,shou,jagger,diver,zigzag,poochie,usarmy,phish,redwood,redwing,12345679,salamander,silver1,abcd123,sputnik,boobie,ripple,eternal,12qw34er,thegreat,allstar,slinky,gesperrt,mishka,whiskers,pinhead,overkill,sweet1,rhfcjnrf,montgom240,sersolution,jamie1,starman,proxy,swords,nikolay,bacardi,rasta,badgirl,rebecca1,wildman,penny1,spaceman,1007,10101,logan1,hacked,bulldog1,helmet,windsor,buffy1,runescape,trapper,123451,banane,dbrnjh,ripken,12345qwe,frisky,shun,fester,oasis,lightning,ib6ub9,cicero,kool,pony,thedog,784512,01011992,megatron,illusion,edward1,napster,11223,squash,roadking,woohoo,19411945,hoosiers,01091989,tracker,bagira,midway,leavemealone,br549,14725836,235689,menace,rachel1,feng,laser,stoned,realmadrid,787898,balloons,tinkerbell,5551212,maria1,pobeda,heineken,sonics,moonlight,optimus,comet,orchid,02071982,jaybird,kashmir,12345678a,chuang,chunky,peach,mortgage,rulezzz,saleen,chuckie,zippy,fishing1,gsxr750,doghouse,maxim,reader,shai,buddah,benfica,chou,salomon,meister,eraser,blackbir,bigmike,starter,pissing,angus,deluxe,eagles1,hardcock,135792468,mian,seahawks,godfathe,bookworm,gregor,intel,talisman,blackjack,babyface,hawaiian,dogfood,zhong,01011975,sancho,ludmila,medusa,mortimer,123456654321,roadrunn,just4me,stalin,01011993,handyman,alphabet,pizzas,calgary,clouds,password2,cgfhnfr,f**k,cubswin,gong,lexus,max123,xxx123,digital1,gfhjkm1,7779311,missy1,michae,beautifu,gator1,1005,pacers,buddie,chinook,heckfy,dutchess,sally1,breasts,beowulf,darkman,jenn,tiffany1,zhei,quan,qazwsx1,satana,shang,idontkno,smiths,puddin,nasty1,teddybea,valkyrie,passwd,chao,boxster,killers,yoda,cheater,inuyasha,beast1,wareagle,foryou,dragonball,mermaid,bhbirf,teddy1,dolphin1,misty1,delphi,gromit,sponge,qazzaq,fytxrf,gameover,diao,sergi,beamer,beemer,kittykat,rancid,manowar,adam12,diggler,assword,austin1,wishbone,gonavy,sparky1,fisting,thedude,sinister,1213,venera,novell,salsero,jayden,fuckoff1,linda1,vedder,02021987,1pussy,redline,lust,jktymrf,02011985,dfcbkbq,dragon12,chrome,gamecube,titten,cong,bella1,leng,02081988,eureka,bitchass,147369,banner,lakota,123321a,mustafa,preacher,hotbox,02041986,z1x2c3v4,playstation,01011977,claymore,electra,checkers,zheng,qing,armagedon,02051986,wrestle,svoboda,bulls,nimbus,alenka,madina,newpass6,onetime,aa123456,bartman,02091987,silverad,electron,12345t,devil666,oliver1,skylar,rhtdtlrj,gobucks,johann,12011987,milkman,02101985,camper,thunderb,bigbutt,jammin,davide,cheeks,goaway,lighter,claudi,thumbs,pissoff,ghostrider,cocaine,teng,squall,lotus,hootie,blackout,doitnow,subzero,02031986,marine1,02021988,pothead,123456qw,skate,1369,peng,antoni,neng,miao,bcfields,1492,marika,794613,musashi,tulips,nong,piao,chai,ruan,southpar,02061985,nude,mandarin,654123,ninjas,cannabis,jetski,xerxes,zhuang,kleopatra,dickie,bilbo,pinky,morgan1,1020,1017,dieter,baseball1,tottenham,quest,yfnfkmz,dirtbike,1234567890a,mango,jackson5,ipswich,iamgod,02011987,tdutybz,modena,qiao,slippery,qweasd123,bluefish,samtron,toon,111333,iscool,02091986,petrov,fuzzy,zhou,1357924680,mollydog,deng,02021986,1236987,pheonix,zhun,ghblehjr,othello,starcraf,000111,sanfran,a11111,cameltoe,badman,vasilisa,jiang,1qaz2ws,luan,sveta,12qw12,akira,chuai,369963,cheech,beatle,pickup,paloma,01011983,caravan,elizaveta,gawker,banzai,pussey,mullet,seng,bingo1,bearcat,flexible,farscape,borussia,zhuai,templar,guitar1,toolman,yfcntymrf,chloe1,xiang,slave1,guai,nuggets,02081984,mantis,slim,scorpio1,fyutkbyf,thedoors,02081987,02061986,123qq123,zappa,fergie,7ugd5hip2j,huai,asdfzxcv,sunflower,pussyman,deadpool,bigtit,01011982,love12,lassie,skyler,gatorade,carpedie,jockey,mancity,spectre,02021984,cameron1,artemka,reng,02031984,iomega,jing,moritz,spice,rhino,spinner,heater,zhai,hover,talon,grease,qiong,corleone,ltybcrf,tian,cowboy1,hippie,chimera,ting,alex123,02021985,mickey1,corsair,sonoma,aaron1,xxxpass,bacchus,webmaste,chuo,xyz123,chrysler,spurs1,artem,shei,cosmic,01020304,deutsch,gabriel1,123455,oceans,987456321,binladen,latinas,a12345678,speedo,buttercu,02081989,21031988,merlot,millwall,ceng,kotaku,jiong,dragonba,2580,stonecold,snuffy,01011999,02011986,hellos,blaze,maggie1,slapper,istanbul,bonjovi,babylove,mazda,bullfrog,phoeni,meng,porsche1,nomore,02061989,bobdylan,capslock,orion1,zaraza,teddybear,ntktajy,myname,rong,wraith,mets,niao,02041984,smokie,chevrolet,dialog,gfhjkmgfhjkm,dotcom,vadim,monarch,athlon,mikey1,hamish,pian,liang,coolness,chui,thoma,ramones,ciccio,chippy,eddie1,house1,ning,marker,cougars,jackpot,barbados,reds,pdtplf,knockers,cobalt,amateurs,dipshit,napoli,kilroy,pulsar,jayhawks,daemon,alexey,weng,shuang,9293709b13,shiner,eldorado,soulmate,mclaren,golfer1,andromed,duan,50spanks,sexyboy,dogshit,02021983,shuo,kakashka,syzygy,111111a,yeahbaby,qiang,netscape,fulham,120676,gooner,zhui,rainbow6,laurent,dog123,halifax,freeway,carlitos,147963,eastwood,microphone,monkey12,1123,persik,coldbeer,geng,nuan,danny1,fgtkmcby,entropy,gadget,just4fun,sophi,baggio,carlito,1234567891,02021989,02041983,specialk,piramida,suan,bigblue,salasana,hopeful,mephisto,bailey1,hack,annie1,generic,violetta,spencer1,arcadia,02051983,hondas,9562876,trainer,jones1,smashing,liao,159632,iceberg,rebel1,snooker,temp123,zang,matteo,fastball,q2w3e4r5,bamboo,fuckyo,shutup,astro,buddyboy,nikitos,redbird,maxxxx,shitface,02031987,kuai,kissmyass,sahara,radiohea,1234asdf,wildcard,maxwell1,patric,plasma,heynow,bruno1,shao,bigfish,misfits,sassy1,sheng,02011988,02081986,testpass,nanook,cygnus,licking,slavik,pringles,xing,1022,ninja1,submit,dundee,tiburon,pinkfloyd,yummy,shuai,guang,chopin,obelix,insomnia,stroker,1a2s3d4f,1223,playboy1,lazarus,jorda,spider1,homerj,sleeper,02041982,darklord,cang,02041988,02041987,tripod,magician,jelly,telephon,15975,vsjasnel12,pasword,iverson3,pavlov,homeboy,gamecock,amigo,brodie,budapest,yjdsqgfhjkm,reckless,02011980,pang,tiger123,2469,mason1,orient,01011979,zong,cdtnbr,maksimka,1011,bushido,taxman,giorgio,sphinx,kazantip,02101984,concorde,verizon,lovebug,georg,sam123,seadoo,qazwsxedc123,jiao,jezebel,pharmacy,abnormal,jellybea,maxime,puffy,islander,bunnies,jiggaman,drakon,010180,pluto,zhjckfd,12365,classics,crusher,mordor,hooligan,strawberry,02081985,scrabble,hawaii50,1224,wg8e3wjf,cthtuf,premium,arrow,123456qwe,mazda626,ramrod,tootie,rhjrjlbk,ghost1,1211,bounty,niang,02071984,goat,killer12,sweetnes,porno1,masamune,426hemi,corolla,mariposa,hjccbz,doomsday,bummer,blue12,zhao,bird33,excalibur,samsun,kirsty,buttfuck,kfhbcf,zhuo,marcello,ozzy,02021982,dynamite,655321,master12,123465,lollypop,stepan,1qa2ws,spiker,goirish,callum,michael2,moonbeam,attila,henry1,lindros,andrea1,sporty,lantern,12365478,nextel,violin,volcom,998877,water1,imation,inspiron,dynamo,citadel,placebo,clowns,tiao,02061988,tripper,dabears,haggis,merlin1,02031985,anthrax,amerika,iloveme,vsegda,burrito,bombers,snowboard,forsaken,katarina,a1a2a3,woofer,tigger2,fullmoon,tiger2,spock,hannah1,snoopy1,sexxxy,sausages,stanislav,cobain,robotics,exotic,green123,mobydick,senators,pumpkins,fergus,asddsa,147741,258852,windsurf,reddevil,vfitymrf,nevermind,nang,woodland,4417,mick,shui,q1q2q3,wingman,69696,superb,zuan,ganesh,pecker,zephyr,anastasiya,icu812,larry1,02081982,broker,zalupa,mihail,vfibyf,dogger,7007,paddle,varvara,schalke,1z2x3c,presiden,yankees2,tuning,poopy,02051982,concord,vanguard,stiffy,rjhjktdf,felix1,wrench,firewall,boxer,bubba69,popper,02011984,temppass,gobears,cuan,tipper,fuckme1,kamila,thong,puss,bigcat,drummer1,02031982,sowhat,digimon,tigers1,rang,jingle,bian,uranus,soprano,mandy1,dusty1,fandango,aloha,pumpkin1,postman,02061980,dogcat,bombay,pussy123,onetwo,highheel,pippo,julie1,laura1,pepito,beng,smokey1,stylus,stratus,reload,duckie,karen1,jimbo1,225588,369258,krusty,snappy,asdf12,electro,111qqq,kuang,fishin,clit,abstr,christma,qqqqq1,1234560,carnage,guyver,boxers,kittens,zeng,1000000,qwerty11,toaster,cramps,yugioh,02061987,icehouse,zxcvbnm123,pineapple,namaste,harrypotter,mygirl,falcon1,earnhard,fender1,spikes,nutmeg,01081989,dogboy,02091983,369852,softail,mypassword,prowler,bigboss,1112,harvest,heng,jubilee,killjoy,basset,keng,zaqxswcde,redsox1,biao,titan,misfit99,robot,wifey,kidrock,02101987,gameboy,enrico,1z2x3c4v,broncos1,arrows,havana,banger,cookie1,chriss,123qw,platypus,cindy1,lumber,pinball,foxy,london1,1023,05051987,02041985,password12,superma,longbow,radiohead,nigga,12051988,spongebo,qwert12345,abrakadabra,dodgers1,02101989,chillin,niceguy,pistons,hookup,santafe,bigben,jets,1013,vikings1,mankind,viktoriya,beardog,hammer1,02071980,reddwarf,magelan,longjohn,jennife,gilles,carmex2,02071987,stasik,bumper,doofus,slamdunk,pixies,garion,steffi,alessandro,beerman,niceass,warrior1,honolulu,134679852,visa,johndeer,mother1,windmill,boozer,oatmeal,aptiva,busty,delight,tasty,slick1,bergkamp,badgers,guitars,puffin,02091981,nikki1,irishman,miller1,zildjian,123000,airwolf,magnet,anai,install,02041981,02061983,astra,romans,megan1,mudvayne,freebird,muscles,dogbert,02091980,02091984,snowflak,01011900,mang,joseph1,nygiants,playstat,junior1,vjcrdf,qwer12,webhompas,giraffe,pelican,jefferso,comanche,bruiser,monkeybo,kjkszpj,123456l,micro,albany,02051987,angel123,epsilon,aladin,death666,hounddog,josephin,altima,chilly,02071988,78945,ultra,02041979,gasman,thisisit,pavel,idunno,kimmie,05051985,paulie,ballin,medion,moondog,manolo,pallmall,climber,fishbone,genesis1,153624,toffee,tbone,clippers,krypton,jerry1,picturs,compass,111111q,02051988,1121,02081977,sairam,getout,333777,cobras,22041987,bigblock,severin,booster,norwich,whiteout,ctrhtn,123456m,02061984,hewlett,shocker,fuckinside,02031981,chase1,white1,versace,123456789s,basebal,iloveyou2,bluebell,08031986,anthon,stubby,foreve,undertak,werder,saiyan,mama123,medic,chipmunk,mike123,mazdarx7,qwe123qwe,bowwow,kjrjvjnbd,celeb,choochoo,demo,lovelife,02051984,colnago,lithium,02051989,15051981,zzzxxx,welcom,anastasi,fidelio,franc,26061987,roadster,stone55,drifter,hookem,hellboy,1234qw,cbr900rr,sinned,good123654,storm1,gypsy,zebra,zachary1,toejam,buceta,02021979,testing1,redfox,lineage,mike1,highbury,koroleva,nathan1,washingt,02061982,02091985,vintage,redbaron,dalshe,mykids,11051987,macbeth,julien,james123,krasotka,111000,10011986,987123,pipeline,tatarin,sensei,codered,komodo,frogman,7894561230,nascar24,juicy,01031988,redrose,mydick,pigeon,tkbpfdtnf,smirnoff,1215,spam,winner1,flyfish,moskva,81fukkc,21031987,olesya,starligh,summer99,13041988,fishhead,freesex,super12,06061986,azazel,scoobydoo,02021981,cabron,yogibear,sheba1,konstantin,tranny,chilli,terminat,ghbywtccf,slowhand,soccer12,cricket1,fuckhead,1002,seagull,achtung,blam,bigbob,bdsm,nostromo,survivor,cnfybckfd,lemonade,boomer1,rainbow1,rober,irinka,cocksuck,peaches1,itsme,sugar1,zodiac,upyours,dinara,135791,sunny1,chiara,johnson1,02041989,solitude,habibi,sushi,markiz,smoke1,rockies,catwoman,johnny1,qwerty7,bearcats,username,01011978,wanderer,ohshit,02101986,sigma,stephen1,paradigm,02011989,flanker,sanity,jsbach,spotty,bologna,fantasia,chevys,borabora,cocker,74108520,123ewq,12021988,01061990,gtnhjdbx,02071981,01011960,sundevil,3000gt,mustang6,gagging,maggi,armstron,yfnfkb,13041987,revolver,02021976,trouble1,madcat,jeremy1,jackass1,volkswag,30051985,corndog,pool6123,marines1,03041991,pizza1,piggy,sissy,02031979,sunfire,angelus,undead,24061986,14061991,wildbill,shinobi,45m2do5bs,123qwer,21011989,cleopatr,lasvega,hornets,amorcit,11081989,coventry,nirvana1,destin,sidekick,20061988,02081983,gbhfvblf,sneaky,bmw325,22021989,nfytxrf,sekret,kalina,zanzibar,hotone,qazws,wasabi,heidi1,highlander,blues1,hitachi,paolo,23041987,slayer1,simba1,02011981,tinkerbe,kieran,01121986,172839,boiler,1125,bluesman,waffle,asdfgh01,threesom,conan,1102,reflex,18011987,nautilus,everlast,fatty,vader1,01071986,cyborg,ghbdtn123,birddog,rubble,02071983,suckers,02021973,skyhawk,12qw12qw,dakota1,joebob,nokia6233,woodie,longdong,lamer,troll,ghjcnjgfhjkm,420000,boating,nitro,armada,messiah,1031,penguin1,02091989,americ,02071989,redeye,asdqwe123,07071987,monty1,goten,spikey,sonata,635241,tokiohotel,sonyericsson,citroen,compaq1,1812,umpire,belmont,jonny,pantera1,nudes,palmtree,14111986,fenway,bighead,razor,gryphon,andyod22,aaaaa1,taco,10031988,enterme,malachi,dogface,reptile,01041985,dindom,handball,marseille,candy1,19101987,torino,tigge,matthias,viewsoni,13031987,stinker,evangelion,24011985,123456123,rampage,sandrine,02081980,thecrow,astral,28041987,sprinter,private1,seabee,shibby,02101988,25081988,fearless,junkie,01091987,aramis,antelope,draven,fuck1,mazda6,eggman,02021990,barselona,buddy123,19061987,fyfnjkbq,nancy1,12121990,10071987,sluggo,kille,hotties,irishka,zxcasdqwe123,shamus,fairlane,honeybee,soccer10,13061986,fantomas,17051988,10051987,20111986,gladiato,karachi,gambler,gordo,01011995,biatch,matthe,25800852,papito,excite,buffalo1,bobdole,cheshire,player1,28021992,thewho,10101986,pinky1,mentor,tomahawk,brown1,03041986,bismillah,bigpoppa,ijrjkfl,01121988,runaway,08121986,skibum,studman,helper,squeak,holycow,manfred,harlem,glock,gideon,987321,14021985,yellow1,wizard1,margarit,success1,medved,sf49ers,lambda,pasadena,johngalt,quasar,1776,02031980,coldplay,amand,playa,bigpimp,04041991,capricorn,elefant,sweetness,bruce1,luca,dominik,10011990,biker,09051945,datsun,elcamino,trinitro,malice,audi,voyager1,02101983,joe123,carpente,spartan1,mario1,glamour,diaper,12121985,22011988,winter1,asimov,callisto,nikolai,pebble,02101981,vendetta,david123,boytoy,11061985,02031989,iloveyou1,stupid1,cayman,casper1,zippo,yamahar1,wildwood,foxylady,calibra,02041980,27061988,dungeon,leedsutd,30041986,11051990,bestbuy,antares,dominion,24680,01061986,skillet,enforcer,derparol,01041988,196969,29071983,f00tball,purple1,mingus,25031987,21031990,remingto,giggles,klaste,3x7pxr,01011994,coolcat,29051989,megane,20031987,02051980,04041988,synergy,0000007,macman,iforget,adgjmp,vjqgfhjkm,28011987,rfvfcenhf,16051989,25121987,16051987,rogue,mamamia,08051990,20091991,1210,carnival,bolitas,paris1,dmitriy,dimas,05051989,papillon,knuckles,29011985,hola,tophat,28021990,100500,cutiepie,devo,415263,ducks,ghjuhfvvf,asdqwe,22021986,freefall,parol,02011983,zarina,buste,vitamin,warez,bigones,17061988,baritone,jamess,twiggy,mischief,bitchy,hetfield,1003,dontknow,grinch,sasha_007,18061990,12031985,12031987,calimero,224466,letmei,15011987,acmilan,alexandre,02031977,08081988,whiteboy,21051991,barney1,02071978,money123,18091985,bigdawg,02031988,cygnusx1,zoloto,31011987,firefigh,blowfish,screamer,lfybbk,20051988,chelse,11121986,01031989,harddick,sexylady,30031988,02041974,auditt,pizdec,kojak,kfgjxrf,20091988,123456ru,wp2003wp,1204,15051990,slugger,kordell1,03031986,swinging,01011974,02071979,rockie,dimples,1234123,1dragon,trucking,rusty2,roger1,marijuana,kerouac,02051978,08031985,paco,thecure,keepout,kernel,noname123,13121985,francisc,bozo,02011982,22071986,02101979,obsidian,12345qw,spud,tabasco,02051985,jaguars,dfktynby,kokomo,popova,notused,sevens,4200,magneto,02051976,roswell,15101986,21101986,lakeside,bigbang,aspen,little1,14021986,loki,suckmydick,strawber,carlos1,nokian73,dirty1,joshu,25091987,16121987,02041975,advent,17011987,slimshady,whistler,10101990,stryker,22031984,15021985,01031985,blueball,26031988,ksusha,bahamut,robocop,w_pass,chris123,impreza,prozac,bookie,bricks,13021990,alice1,cassandr,11111q,john123,4ever,korova,02051973,142857,25041988,paramedi,eclipse1,salope,07091990,1124,darkangel,23021986,999666,nomad,02051981,smackdow,01021990,yoyoma,argentin,moonligh,57chevy,bootys,hardone,capricor,galant,spanker,dkflbr,24111989,magpies,krolik,21051988,cevthrb,cheddar,22041988,bigbooty,scuba1,qwedsa,duffman,bukkake,acura,johncena,sexxy,p@ssw0rd,258369,cherries,12345s,asgard,leopold,fuck123,mopar,lalakers,dogpound,matrix1,crusty,spanner,kestrel,fenris,universa,peachy,assasin,lemmein,eggplant,hejsan,canucks,wendy1,doggy1,aikman,tupac,turnip,godlike,fussball,golden1,19283746,april1,django,petrova,captain1,vincent1,ratman,taekwondo,chocha,serpent,perfect1,capetown,vampir,amore,gymnast,timeout,nbvjatq,blue32,ksenia,k.lvbkf,nazgul,budweiser,clutch,mariya,sylveste,02051972,beaker,cartman1,q11111,sexxx,forever1,loser1,marseill,magellan,vehpbr,sexgod,jktxrf,hallo123,132456,liverpool1,southpaw,seneca,camden,357159,camero,tenchi,johndoe,145236,roofer,741963,vlad,02041978,fktyrf,zxcv123,wingnut,wolfpac,notebook,pufunga7782,brandy1,biteme1,goodgirl,redhat,02031978,challeng,millenium,hoops,maveric,noname,angus1,gaell,onion,olympus,sabrina1,ricard,sixpack,gratis,gagged,camaross,hotgirls,flasher,02051977,bubba123,goldfing,moonshin,gerrard,volkov,sonyfuck,mandrake,258963,tracer,lakers1,asians,susan1,money12,helmut,boater,diablo2,1234zxcv,dogwood,bubbles1,happy2,randy1,aries,beach1,marcius2,navigator,goodie,hellokitty,fkbyjxrf,earthlink,lookout,jumbo,opendoor,stanley1,marie1,12345m,07071977,ashle,wormix,murzik,02081976,lakewood,bluejays,loveya,commande,gateway2,peppe,01011976,7896321,goth,oreo,slammer,rasmus,faith1,knight1,stone1,redskin,ironmaiden,gotmilk,destiny1,dejavu,1master,midnite,timosha,espresso,delfin,toriamos,oberon,ceasar,markie,1a2s3d,ghhh47hj7649,vjkjrj,daddyo,dougie,disco,auggie,lekker,therock1,ou8123,start1,noway,p4ssw0rd,shadow12,333444,saigon,2fast4u,capecod,23skidoo,qazxcv,beater,bremen,aaasss,roadrunner,peace1,12345qwer,02071975,platon,bordeaux,vbkfirf,135798642,test12,supernov,beatles1,qwert40,optimist,vanessa1,prince1,ilovegod,nightwish,natasha1,alchemy,bimbo,blue99,patches1,gsxr1000,richar,hattrick,hott,solaris,proton,nevets,enternow,beavis1,amigos,159357a,ambers,lenochka,147896,suckdick,shag,intercourse,blue1234,spiral,02061977,tosser,ilove,02031975,cowgirl,canuck,q2w3e4,munch,spoons,waterboy,123567,evgeniy,savior,zasada,redcar,mamacita,terefon,globus,doggies,htubcnhfwbz,1008,cuervo,suslik,azertyui,limewire,houston1,stratfor,steaua,coors,tennis1,12345qwerty,stigmata,derf,klondike,patrici,marijuan,hardball,odyssey,nineinch,boston1,pass1,beezer,sandr,charon,power123,a1234,vauxhall,875421,awesome1,reggae,boulder,funstuff,iriska,krokodil,rfntymrf,sterva,champ1,bball,peeper,m123456,toolbox,cabernet,sheepdog,magic32,pigpen,02041977,holein1,lhfrjy,banan,dabomb,natalie1,jennaj,montana1,joecool,funky,steven1,ringo,junio,sammy123,qqqwww,baltimor,footjob,geezer,357951,mash4077,cashmone,pancake,monic,grandam,bongo,yessir,gocubs,nastia,vancouve,barley,dragon69,watford,ilikepie,02071976,laddie,123456789m,hairball,toonarmy,pimpdadd,cvthnm,hunte,davinci,lback,sophie1,firenze,q1234567,admin1,bonanza,elway7,daman,strap,azert,wxcvbn,afrika,theforce,123456t,idefix,wolfen,houdini,scheisse,default,beech,maserati,02061976,sigmachi,dylan1,bigdicks,eskimo,mizzou,02101976,riccardo,egghead,111777,kronos,ghbrjk,chaos1,jomama,rfhnjirf,rodeo,dolemite,cafc91,nittany,pathfind,mikael,password9,vqsablpzla,purpl,gabber,modelsne,myxworld,hellsing,punker,rocknrol,fishon,fuck69,02041976,lolol,twinkie,tripleh,cirrus,redbone,killer123,biggun,allegro,gthcbr,smith1,wanking,bootsy,barry1,mohawk,koolaid,5329,futurama,samoht,klizma,996633,lobo,honeys,peanut1,556677,zxasqw,joemama,javelin,samm,223322,sandra1,flicks,montag,nataly,3006,tasha1,1235789,dogbone,poker1,p0o9i8u7,goodday,smoothie,toocool,max333,metroid,archange,vagabond,billabon,22061941,tyson1,02031973,darkange,skateboard,evolutio,morrowind,wizards,frodo1,rockin,cumslut,plastics,zaqwsxcde,5201314,doit,outback,bumble,dominiqu,persona,nevermore,alinka,02021971,forgetit,sexo,all4one,c2h5oh,petunia,sheeba,kenny1,elisabet,aolsucks,woodstoc,pumper,02011975,fabio,granada,scrapper,123459,minimoni,q123456789,breaker,1004,02091976,ncc74656,slimshad,friendster,austin31,wiseguy,donner,dilbert1,132465,blackbird,buffet,jellybean,barfly,behappy,01011971,carebear,fireblad,02051975,boxcar,cheeky,kiteboy,hello12,panda1,elvisp,opennow,doktor,alex12,02101977,pornking,flamengo,02091975,snowbird,lonesome,robin1,11111a,weed420,baracuda,bleach,12345abc,nokia1,metall,singapor,mariner,herewego,dingo,tycoon,cubs,blunts,proview,123456789d,kamasutra,lagnaf,vipergts,navyseal,starwar,masterbate,wildone,peterbil,cucumber,butkus,123qwert,climax,deniro,gotribe,cement,scooby1,summer69,harrier,shodan,newyear,02091977,starwars1,romeo1,sedona,harald,doubled,sasha123,bigguns,salami,awnyce,kiwi,homemade,pimping,azzer,bradley1,warhamme,linkin,dudeman,qwe321,pinnacle,maxdog,flipflop,lfitymrf,fucker1,acidburn,esquire,sperma,fellatio,jeepster,thedon,sexybitch,pookey,spliff,widget,vfntvfnbrf,trinity1,mutant,samuel1,meliss,gohome,1q2q3q,mercede,comein,grin,cartoons,paragon,henrik,rainyday,pacino,senna,bigdog1,alleycat,12345qaz,narnia,mustang2,tanya1,gianni,apollo11,wetter,clovis,escalade,rainbows,freddy1,smart1,daisydog,s123456,cocksucker,pushkin,lefty,sambo,fyutkjxtr,hiziad,boyz,whiplash,orchard,newark,adrenalin,1598753,bootsie,chelle,trustme,chewy,golfgti,tuscl,ambrosia,5wr2i7h8,penetration,shonuf,jughead,payday,stickman,gotham,kolokol,johnny5,kolbasa,stang,puppydog,charisma,gators1,mone,jakarta,draco,nightmar,01011973,inlove,laetitia,02091973,tarpon,nautica,meadow,0192837465,luckyone,14881488,chessie,goldeney,tarakan,69camaro,bungle,wordup,interne,fuckme2,515000,dragonfl,sprout,02081974,gerbil,bandit1,02071971,melanie1,phialpha,camber,kathy1,adriano,gonzo1,10293847,bigjohn,bismarck,7777777a,scamper,12348765,rabbits,222777,bynthytn,dima123,alexander1,mallorca,dragster,favorite6,beethove,burner,cooper1,fosters,hello2,normandy,777999,sebring,1michael,lauren1,blake1,killa,02091971,nounours,trumpet1,thumper1,playball,xantia,rugby1,rocknroll,guillaum,angela1,strelok,prosper,buttercup,masterp,dbnfkbr,cambridg,venom,treefrog,lumina,1234566,supra,sexybabe,freee,shen,frogs,driller,pavement,grace1,dicky,checker,smackdown,pandas,cannibal,asdffdsa,blue42,zyjxrf,nthvbyfnjh,melrose,neon,jabber,gamma,369258147,aprilia,atticus,benessere,catcher,skipper1,azertyuiop,sixty9,thierry,treetop,jello,melons,123456789qwe,tantra,buzzer,catnip,bouncer,computer1,sexyone,ananas,young1,olenka,sexman,mooses,kittys,sephiroth,contra,hallowee,skylark,sparkles,777333,1qazxsw23edc,lucas1,q1w2e3r,gofast,hannes,amethyst,ploppy,flower2,hotass,amatory,volleyba,dixie1,bettyboo,ticklish,02061974,frenchy,phish1,murphy1,trustno,02061972,leinad,mynameis,spooge,jupiter1,hyundai,frosch,junkmail,abacab,marbles,32167,casio,sunshine1,wayne1,longhair,caster,snicker,02101973,gannibal,skinhead,hansol,gatsby,segblue2,montecar,plato,gumby,kaboom,matty,bosco1,888999,jazzy,panter,jesus123,charlie2,giulia,candyass,sex69,travis1,farmboy,special1,02041973,letsdoit,password01,allison1,abcdefg1,notredam,ilikeit,789654123,liberty1,rugger,uptown,alcatraz,123456w,airman,007bond,navajo,kenobi,terrier,stayout,grisha,frankie1,fluff,1qazzaq1,1234561,virginie,1234568,tango1,werdna,octopus,fitter,dfcbkbcf,blacklab,115599,montrose,allen1,supernova,frederik,ilovepussy,justice1,radeon,playboy2,blubber,sliver,swoosh,motocros,lockdown,pearls,thebear,istheman,pinetree,biit,1234rewq,rustydog,tampabay,titts,babycake,jehovah,vampire1,streaming,collie,camil,fidelity,calvin1,stitch,gatit,restart,puppy1,budgie,grunt,capitals,hiking,dreamcas,zorro1,321678,riffraff,makaka,playmate,napalm,rollin,amstel,zxcvb123,samanth,rumble,fuckme69,jimmys,951357,pizzaman,1234567899,tralala,delpiero,alexi,yamato,itisme,1million,vfndtq,kahlua,londo,wonderboy,carrots,tazz,ratboy,rfgecnf,02081973,nico,fujitsu,tujhrf,sergbest,blobby,02051970,sonic1,1357911,smirnov,video1,panhead,bucky,02031974,44332211,duffer,cashmoney,left4dead,bagpuss,salman,01011972,titfuck,66613666,england1,malish,dresden,lemans,darina,zapper,123456as,123456qqq,met2002,02041972,redstar,blue23,1234509876,pajero,booyah,please1,tetsuo,semper,finder,hanuman,sunlight,123456n,02061971,treble,cupoi,password99,dimitri,3ip76k2,popcorn1,lol12345,stellar,nympho,shark1,keith1,saskia,bigtruck,revoluti,rambo1,asd222,feelgood,phat,gogators,bismark,cola,puck,furball,burnout,slonik,bowtie,mommy1,icecube,fabienn,mouser,papamama,rolex,giants1,blue11,trooper1,momdad,iklo,morten,rhubarb,gareth,123456d,blitz,canada1,r2d2,brest,tigercat,usmarine,lilbit,benny1,azrael,lebowski,12345r,madagaskar,begemot,loverman,dragonballz,italiano,mazda3,naughty1,onions,diver1,cyrano,capcom,asdfg123,forlife,fisherman,weare138,requiem,mufasa,alpha123,piercing,hellas,abracadabra,duckman,caracas,macintos,02011971,jordan2,crescent,fduecn,hogtied,eatmenow,ramjet,18121812,kicksass,whatthe,discus,rfhfvtkmrf,rufus1,sqdwfe,mantle,vegitto,trek,dan123,paladin1,rudeboy,liliya,lunchbox,riversid,acapulco,libero,dnsadm,maison,toomuch,boobear,hemlock,sextoy,pugsley,misiek,athome,migue,altoids,marcin,123450,rhfcfdbwf,jeter2,rhinos,rjhjkm,mercury1,ronaldinho,shampoo,makayla,kamilla,masterbating,tennesse,holger,john1,matchbox,hores,poptart,parlament,goodyear,asdfgh1,02081970,hardwood,alain,erection,hfytnrb,highlife,implants,benjami,dipper,jeeper,bendover,supersonic,babybear,laserjet,gotenks,bama,natedogg,aol123,pokemo,rabbit1,raduga,sopranos,cashflow,menthol,pharao,hacking,334455,ghjcnbnenrf,lizzy,muffin1,pooky,penis1,flyer,gramma,dipset,becca,ireland1,diana1,donjuan,pong,ziggy1,alterego,simple1,cbr900,logger,111555,claudia1,cantona7,matisse,ljxtymrf,victori,harle,mamas,encore,mangos,iceman1,diamon,alexxx,tiamat,5000,desktop,mafia,smurf,princesa,shojou,blueberr,welkom,maximka,123890,123q123,tammy1,bobmarley,clips,demon666,ismail,termite,laser1,missie,altair,donna1,bauhaus,trinitron,mogwai,flyers88,juniper,nokia5800,boroda,jingles,qwerasdfzxcv,shakur,777666,legos,mallrats,1qazxsw,goldeneye,tamerlan,julia1,backbone,spleen,49ers,shady,darkone,medic1,justi,giggle,cloudy,aisan,douche,parkour,bluejay,huskers1,redwine,1qw23er4,satchmo,1231234,nineball,stewart1,ballsack,probes,kappa,amiga,flipper1,dortmund,963258,trigun,1237895,homepage,blinky,screwy,gizzmo,belkin,chemist,coolhand,chachi,braves1,thebest,greedisgood,pro100,banana1,101091m,123456g,wonderfu,barefeet,8inches,1111qqqq,kcchiefs,qweasdzxc123,metal1,jennifer1,xian,asdasd123,pollux,cheerleaers,fruity,mustang5,turbos,shopper,photon,espana,hillbill,oyster,macaroni,gigabyte,jesper,motown,tuxedo,buster12,triplex,cyclones,estrell,mortis,holla,456987,fiddle,sapphic,jurassic,thebeast,ghjcnjq,baura,spock1,metallica1,karaoke,nemrac58,love1234,02031970,flvbybcnhfnjh,frisbee,diva,ajax,feathers,flower1,soccer11,allday,mierda,pearl1,amature,marauder,333555,redheads,womans,egorka,godbless,159263,nimitz,aaaa1111,sashka,madcow,socce,greywolf,baboon,pimpdaddy,123456789r,reloaded,lancia,rfhfylfi,dicker,placid,grimace,22446688,olemiss,whores,culinary,wannabe,maxi,1234567aa,amelie,riley1,trample,phantom1,baberuth,bramble,asdfqwer,vides,4you,abc123456,taichi,aztnm,smother,outsider,hakr,blackhawk,bigblack,girlie,spook,valeriya,gianluca,freedo,1q2q3q4q,handbag,lavalamp,cumm,pertinant,whatup,nokia123,redlight,patrik,111aaa,poppy1,dfytxrf,aviator,sweeps,kristin1,cypher,elway,yinyang,access1,poophead,tucson,noles1,monterey,waterfal,dank,dougal,918273,suede,minnesot,legman,bukowski,ganja,mammoth,riverrat,asswipe,daredevi,lian,arizona1,kamikadze,alex1234,smile1,angel2,55bgates,bellagio,0001,wanrltw,stiletto,lipton,arsena,biohazard,bbking,chappy,tetris,as123456,darthvad,lilwayne,nopassword,7412369,123456789987654321,natchez,glitter,14785236,mytime,rubicon,moto,pyon,wazzup,tbird,shane1,nightowl,getoff,beckham7,trueblue,hotgirl,nevermin,deathnote,13131,taffy,bigal,copenhag,apricot,gallaries,dtkjcbgtl,totoro,onlyone,civicsi,jesse1,baby123,sierra1,festus,abacus,sickboy,fishtank,fungus,charle,golfpro,teensex,mario66,seaside,aleksei,rosewood,blackberry,1020304050,bedlam,schumi,deerhunt,contour,darkelf,surveyor,deltas,pitchers,741258963,dipstick,funny1,lizzard,112233445566,jupiter2,softtail,titman,greenman,z1x2c3v4b5,smartass,12345677,notnow,myworld,nascar1,chewbacc,nosferatu,downhill,dallas22,kuan,blazers,whales,soldat,craving,powerman,yfcntyf,hotrats,cfvceyu,qweasdzx,princess1,feline,qqwwee,chitown,1234qaz,mastermind,114477,dingbat,care1839,standby,kismet,atreides,dogmeat,icarus,monkeyboy,alex1,mouses,nicetits,sealteam,chopper1,crispy,winter99,rrpass1,myporn,myspace1,corazo,topolino,ass123,lawman,muffy,orgy,1love,passord,hooyah,ekmzyf,pretzel,amonra,nestle,01011950,jimbeam,happyman,z12345,stonewal,helios,manunited,harcore,dick1,gaymen,2hot4u,light1,qwerty13,kakashi,pjkjnj,alcatel,taylo,allah,buddydog,ltkmaby,mongo,blonds,start123,audia6,123456v,civilwar,bellaco,turtles,mustan,deadspin,aaa123,fynjirf,lucky123,tortoise,amor,summe,waterski,zulu,drag0n,dtxyjcnm,gizmos,strife,interacial,pusyy,goose1,bear1,equinox,matri,jaguar1,tobydog,sammys,nachos,traktor,bryan1,morgoth,444555,dasani,miami1,mashka,xxxxxx1,ownage,nightwin,hotlips,passmast,cool123,skolko,eldiablo,manu,1357908642,screwyou,badabing,foreplay,hydro,kubrick,seductive,demon1,comeon,galileo,aladdin,metoo,happines,902100,mizuno,caddy,bizzare,girls1,redone,ohmygod,sable,bonovox,girlies,hamper,opus,gizmodo1,aaabbb,pizzahut,999888,rocky2,anton1,kikimora,peavey,ocelot,a1a2a3a4,2wsx3edc,jackie1,solace,sprocket,galary,chuck1,volvo1,shurik,poop123,locutus,virago,wdtnjxtr,tequier,bisexual,doodles,makeitso,fishy,789632145,nothing1,fishcake,sentry,libertad,oaktree,fivestar,adidas1,vegitta,mississi,spiffy,carme,neutron,vantage,agassi,boners,123456789v,hilltop,taipan,barrage,kenneth1,fister,martian,willem,lfybkf,bluestar,moonman,ntktdbpjh,paperino,bikers,daffy,benji,quake,dragonfly,suckcock,danilka,lapochka,belinea,calypso,asshol,camero1,abraxas,mike1234,womam,q1q2q3q4q5,youknow,maxpower,pic's,audi80,sonora,raymond1,tickler,tadpole,belair,crazyman,finalfantasy,999000,jonatha,paisley,kissmyas,morgana,monste,mantra,spunk,magic123,jonesy,mark1,alessand,741258,baddest,ghbdtnrfrltkf,zxccxz,tictac,augustin,racers,7grout,foxfire,99762000,openit,nathanie,1z2x3c4v5b,seadog,gangbanged,lovehate,hondacbr,harpoon,mamochka,fisherma,bismilla,locust,wally1,spiderman1,saffron,utjhubq,123456987,20spanks,safeway,pisser,bdfyjd,kristen1,bigdick1,magenta,vfhujif,anfisa,friday13,qaz123wsx,0987654321q,tyrant,guan,meggie,kontol,nurlan,ayanami,rocket1,yaroslav,websol76,mutley,hugoboss,websolutions,elpaso,gagarin,badboys,sephirot,918273645,newuser,qian,edcrfv,booger1,852258,lockout,timoxa94,mazda323,firedog,sokolova,skydiver,jesus777,1234567890z,soulfly,canary,malinka,guillerm,hookers,dogfart,surfer1,osprey,india123,rhjkbr,stoppedby,nokia5530,123456789o,blue1,werter,divers,3000,123456f,alpina,cali,whoknows,godspeed,986532,foreskin,fuzzy1,heyyou,didier,slapnuts,fresno,rosebud1,sandman1,bears1,blade1,honeybun,queen1,baronn,pakista,philipp,9111961,topsecret,sniper1,214365,slipper,letsfuck,pippen33,godawgs,mousey,qw123456,scrotum,loveis,lighthou,bp2002,nancy123,jeffrey1,susieq,buddy2,ralphie,trout1,willi,antonov,sluttey,rehbwf,marty1,darian,losangeles,letme1n,12345d,pusssy,godiva,ender,golfnut,leonidas,a1b2c3d4e5,puffer,general1,wizzard,lehjxrf,racer1,bigbucks,cool12,buddys,zinger,esprit,vbienrf,josep,tickling,froggie,987654321a,895623,daddys,crumbs,gucci,mikkel,opiate,tracy1,christophe,came11,777555,petrovich,humbug,dirtydog,allstate,horatio,wachtwoord,creepers,squirts,rotary,bigd,georgia1,fujifilm,2sweet,dasha,yorkie,slimjim,wiccan,kenzie,system1,skunk,b12345,getit,pommes,daredevil,sugars,bucker,piston,lionheart,1bitch,515051,catfight,recon,icecold,fantom,vodafone,kontakt,boris1,vfcnth,canine,01011961,valleywa,faraon,chickenwing101,qq123456,livewire,livelife,roosters,jeepers,ilya1234,coochie,pavlik,dewalt,dfhdfhf,architec,blackops,1qaz2wsx3edc4rfv,rhfcjnf,wsxedc,teaser,sebora,25252,rhino1,ankara,swifty,decimal,redleg,shanno,nermal,candies,smirnova,dragon01,photo1,ranetki,a1s2d3f4g5,axio,wertzu,maurizio,6uldv8,zxcvasdf,punkass,flowe,graywolf,peddler,3rjs1la7qe,mpegs,seawolf,ladyboy,pianos,piggies,vixen,alexus,orpheus,gdtrfb,z123456,macgyver,hugetits,ralph1,flathead,maurici,mailru,goofball,nissan1,nikon,stopit,odin,big1,smooch,reboot,famil,bullit,anthony7,gerhard,methos,124038,morena,eagle2,jessica2,zebras,getlost,gfynthf,123581321,sarajevo,indon,comets,tatjana,rfgbnjirf,joystick,batman12,123456c,sabre,beerme,victory1,kitties,1475369,badboy1,booboo1,comcast,slava,squid,saxophon,lionhear,qaywsx,bustle,nastena,roadway,loader,hillside,starlight,24681012,niggers,access99,bazooka,molly123,blackice,bandi,cocacol,nfhfrfy,timur,muschi,horse1,quant4307s,squerting,oscars,mygirls,flashman,tangerin,goofy1,p0o9i8,housewifes,newness,monkey69,escorpio,password11,hippo,warcraft3,qazxsw123,qpalzm,ribbit,ghbdtndctv,bogota,star123,258000,lincoln1,bigjim,lacoste,firestorm,legenda,indain,ludacris,milamber,1009,evangeli,letmesee,a111111,hooters1,bigred1,shaker,husky,a4tech,cnfkrth,argyle,rjhjdf,nataha,0o9i8u7y,gibson1,sooners1,glendale,archery,hoochie,stooge,aaaaaa1,scorpions,school1,vegas1,rapier,mike23,bassoon,groupd2013,macaco,baker1,labia,freewill,santiag,silverado,butch1,vflfufcrfh,monica1,rugrat,cornhole,aerosmit,bionicle,gfgfvfvf,daniel12,virgo,fmale,favorite2,detroit1,pokey,shredder,baggies,wednesda,cosmo1,mimosa,sparhawk,firehawk,romario,911turbo,funtimes,fhntvrf,nexus6,159753456,timothy1,bajingan,terry1,frenchie,raiden,1mustang,babemagnet,74123698,nadejda,truffles,rapture,douglas1,lamborghini,motocross,rjcvjc,748596,skeeter1,dante1,angel666,telecom,carsten,pietro,bmw318,astro1,carpediem,samir,orang,helium,scirocco,fuzzball,rushmore,rebelz,hotspur,lacrimosa,chevys10,madonna1,domenico,yfnfirf,jachin,shelby1,bloke,dawgs,dunhill,atlanta1,service1,mikado,devilman,angelit,reznor,euphoria,lesbain,checkmat,browndog,phreak,blaze1,crash1,farida,mutter,luckyme,horsemen,vgirl,jediknig,asdas,cesare,allnight,rockey,starlite,truck1,passfan,close-up,samue,cazzo,wrinkles,homely,eatme1,sexpot,snapshot,dima1995,asthma,thetruth,ducky,blender,priyanka,gaucho,dutchman,sizzle,kakarot,651550,passcode,justinbieber,666333,elodie,sanjay,110442,alex01,lotus1,2300mj,lakshmi,zoomer,quake3,12349876,teapot,12345687,ramada,pennywis,striper,pilot1,chingon,optima,nudity,ethan1,euclid,beeline,loyola,biguns,zaq12345,bravo1,disney1,buffa,assmunch,vivid,6661313,wellingt,aqwzsx,madala11,9874123,sigmar,pictere,tiptop,bettyboop,dinero,tahiti,gregory1,bionic,speed1,fubar1,lexus1,denis1,hawthorn,saxman,suntzu,bernhard,dominika,camaro1,hunter12,balboa,bmw2002,seville,diablo1,vfhbyjxrf,1234abc,carling,lockerroom,punani,darth,baron1,vaness,1password,libido,picher,232425,karamba,futyn007,daydream,11001001,dragon123,friends1,bopper,rocky123,chooch,asslover,shimmer,riddler,openme,tugboat,sexy123,midori,gulnara,christo,swatch,laker,offroad,puddles,hackers,mannheim,manager1,horseman,roman1,dancer1,komputer,pictuers,nokia5130,ejaculation,lioness,123456y,evilone,nastenka,pushok,javie,lilman,3141592,mjolnir,toulouse,pussy2,bigworm,smoke420,fullback,extensa,dreamcast,belize,delboy,willie1,casablanca,csyjxtr,ricky1,bonghit,salvator,basher,pussylover,rosie1,963258741,vivitron,cobra427,meonly,armageddon,myfriend,zardoz,qwedsazxc,kraken,fzappa,starfox,333999,illmatic,capoeira,weenie,ramzes,freedom2,toasty,pupkin,shinigami,fhvfutljy,nocturne,churchil,thumbnils,tailgate,neworder,sexymama,goarmy,cerebus,michelle1,vbifyz,surfsup,earthlin,dabulls,basketbal,aligator,mojojojo,saibaba,welcome2,wifes,wdtnjr,12345w,slasher,papabear,terran,footman,hocke,153759,texans,tom123,sfgiants,billabong,aassdd,monolith,xxx777,l3tm31n,ticktock,newone,hellno,japanees,contortionist,admin123,scout1,alabama1,divx1,rochard,privat,radar1,bigdad,fhctybq,tortuga,citrus,avanti,fantasy1,woodstock,s12345,fireman1,embalmer,woodwork,bonzai,konyor,newstart,jigga,panorama,goats,smithy,rugrats,hotmama,daedalus,nonstop,fruitbat,lisenok,quaker,violator,12345123,my3sons,cajun,fraggle,gayboy,oldfart,vulva,knickerless,orgasms,undertow,binky,litle,kfcnjxrf,masturbation,bunnie,alexis1,planner,transexual,sparty,leeloo,monies,fozzie,stinger1,landrove,anakonda,scoobie,yamaha1,henti,star12,rfhlbyfk,beyonce,catfood,cjytxrf,zealots,strat,fordtruc,archangel,silvi,sativa,boogers,miles1,bigjoe,tulip,petite,greentea,shitter,jonboy,voltron,morticia,evanescence,3edc4rfv,longshot,windows1,serge,aabbcc,starbucks,sinful,drywall,prelude1,www123,camel1,homebrew,marlins,123412,letmeinn,domini,swampy,plokij,fordf350,webcam,michele1,bolivi,27731828,wingzero,qawsedrftg,shinji,sverige,jasper1,piper1,cummer,iiyama,gocats,amour,alfarome,jumanji,mike69,fantasti,1monkey,w00t88,shawn1,lorien,1a2s3d4f5g,koleso,murph,natascha,sunkist,kennwort,emine,grinder,m12345,q1q2q3q4,cheeba,money2,qazwsxedc1,diamante,prosto,pdiddy,stinky1,gabby1,luckys,franci,pornographic,moochie,gfhjdjp,samdog,empire1,comicbookdb,emili,motdepasse,iphone,braveheart,reeses,nebula,sanjose,bubba2,kickflip,arcangel,superbow,porsche911,xyzzy,nigger1,dagobert,devil1,alatam,monkey2,barbara1,12345v,vfpfafrf,alessio,babemagn,aceman,arrakis,kavkaz,987789,jasons,berserk,sublime1,rogue1,myspace,buckwhea,csyekz,pussy4me,vette1,boots1,boingo,arnaud,budlite,redstorm,paramore,becky1,imtheman,chango,marley1,milkyway,666555,giveme,mahalo,lux2000,lucian,paddy,praxis,shimano,bigpenis,creeper,newproject2004,rammstei,j3qq4h7h2v,hfljcnm,lambchop,anthony2,bugman,gfhjkm12,dreamer1,stooges,cybersex,diamant,cowboyup,maximus1,sentra,615243,goethe,manhatta,fastcar,selmer,1213141516,yfnfitymrf,denni,chewey,yankee1,elektra,123456789p,trousers,fishface,topspin,orwell,vorona,sodapop,motherfu,ibilltes,forall,kookie,ronald1,balrog,maximilian,mypasswo,sonny1,zzxxcc,tkfkdg,magoo,mdogg,heeled,gitara,lesbos,marajade,tippy,morozova,enter123,lesbean,pounded,asd456,fialka,scarab,sharpie,spanky1,gstring,sachin,12345asd,princeto,hellohel,ursitesux,billows,1234kekc,kombat,cashew,duracell,kseniya,sevenof9,kostik,arthur1,corvet07,rdfhnbhf,songoku,tiberian,needforspeed,1qwert,dropkick,kevin123,panache,libra,a123456a,kjiflm,vfhnsirf,cntgfy,iamcool,narut,buffer,sk8ordie,urlaub,fireblade,blanked,marishka,gemini1,altec,gorillaz,chief1,revival47,ironman1,space1,ramstein,doorknob,devilmaycry,nemesis1,sosiska,pennstat,monday1,pioner,shevchenko,detectiv,evildead,blessed1,aggie,coffees,tical,scotts,bullwink,marsel,krypto,adrock,rjitxrf,asmodeus,rapunzel,theboys,hotdogs,deepthro,maxpayne,veronic,fyyeirf,otter,cheste,abbey1,thanos,bedrock,bartok,google1,xxxzzz,rodent,montecarlo,hernande,mikayla,123456789l,bravehea,12locked,ltymub,pegasus1,ameteur,saltydog,faisal,milfnew,momsuck,everques,ytngfhjkz,m0nkey,businessbabe,cooki,custard,123456ab,lbvjxrf,outlaws,753357,qwerty78,udacha,insider,chees,fuckmehard,shotokan,katya,seahorse,vtldtlm,turtle1,mike12,beebop,heathe,everton1,darknes,barnie,rbcekz,alisher,toohot,theduke,555222,reddog1,breezy,bulldawg,monkeyman,baylee,losangel,mastermi,apollo1,aurelie,zxcvb12345,cayenne,bastet,wsxzaq,geibcnbr,yello,fucmy69,redwall,ladybird,bitchs,cccccc1,rktjgfnhf,ghjdthrf,quest1,oedipus,linus,impalass,fartman,12345k,fokker,159753a,optiplex,bbbbbb1,realtor,slipkno,santacru,rowdy,jelena,smeller,3984240,ddddd1,sexyme,janet1,3698741,eatme69,cazzone,today1,poobear,ignatius,master123,newpass1,heather2,snoopdogg,blondinka,pass12,honeydew,fuckthat,890098890,lovem,goldrush,gecko,biker1,llama,pendejo,avalanche,fremont,snowman1,gandolf,chowder,1a2b3c4d5e,flyguy,magadan,1fuck,pingvin,nokia5230,ab1234,lothar,lasers,bignuts,renee1,royboy,skynet,12340987,1122334,dragrace,lovely1,22334455,booter,12345612,corvett,123456qq,capital1,videoes,funtik,wyvern,flange,sammydog,hulkster,13245768,not4you,vorlon,omegared,l58jkdjp!,filippo,123mudar,samadams,petrus,chris12,charlie123,123456789123,icetea,sunderla,adrian1,123qweas,kazanova,aslan,monkey123,fktyeirf,goodsex,123ab,lbtest,banaan,bluenose,837519,asd12345,waffenss,whateve,1a2a3a4a,trailers,vfhbirf,bhbcrf,klaatu,turk182,monsoon,beachbum,sunbeam,succes,clyde1,viking1,rawhide,bubblegum,princ,mackenzi,hershey1,222555,dima55,niggaz,manatee,aquila,anechka,pamel,bugsbunn,lovel,sestra,newport1,althor,hornyman,wakeup,zzz111,phishy,cerber,torrent,thething,solnishko,babel,buckeye1,peanu,ethernet,uncencored,baraka,665544,chris2,rb26dett,willy1,choppers,texaco,biggirl,123456b,anna2614,sukebe,caralho,callofduty,rt6ytere,jesus7,angel12,1money,timelord,allblack,pavlova,romanov,tequiero,yitbos,lookup,bulls23,snowflake,dickweed,barks,lever,irisha,firestar,fred1234,ghjnjnbg,danman,gatito,betty1,milhouse,kbctyjr,masterbaiting,delsol,papit,doggys,123698741,bdfyjdf,invictus,bloods,kayla1,yourmama,apple2,angelok,bigboy1,pontiac1,verygood,yeshua,twins2,porn4me,141516,rasta69,james2,bosshog,candys,adventur,stripe,djkjlz,dokken,austin316,skins,hogwarts,vbhevbh,navigato,desperado,xxx666,cneltyn,vasiliy,hazmat,daytek,eightbal,fred1,four20,74227422,fabia,aerosmith,manue,wingchun,boohoo,hombre,sanity72,goatboy,fuckm,partizan,avrora,utahjazz,submarin,pussyeat,heinlein,control1,costaric,smarty,chuan,triplets,snowy,snafu,teacher1,vangogh,vandal,evergree,cochise,qwerty99,pyramid1,saab900,sniffer,qaz741,lebron23,mark123,wolvie,blackbelt,yoshi,feeder,janeway,nutella,fuking,asscock,deepak,poppie,bigshow,housewife,grils,tonto,cynthia1,temptress,irakli,belle1,russell1,manders,frank123,seabass,gforce,songbird,zippy1,naught,brenda1,chewy1,hotshit,topaz,43046721,girfriend,marinka,jakester,thatsme,planeta,falstaff,patrizia,reborn,riptide,cherry1,shuan,nogard,chino,oasis1,qwaszx12,goodlife,davis1,1911a1,harrys,shitfuck,12345678900,russian7,007700,bulls1,porshe,danil,dolphi,river1,sabaka,gobigred,deborah1,volkswagen,miamo,alkaline,muffdive,1letmein,fkbyrf,goodguy,hallo1,nirvan,ozzie,cannonda,cvbhyjdf,marmite,germany1,joeblow,radio1,love11,raindrop,159852,jacko,newday,fathead,elvis123,caspe,citibank,sports1,deuce,boxter,fakepass,golfman,snowdog,birthday4,nonmembe,niklas,parsifal,krasota,theshit,1235813,maganda,nikita1,omicron,cassie1,columbo,buick,sigma1,thistle,bassin,rickster,apteka,sienna,skulls,miamor,coolgirl,gravis,1qazxc,virgini,hunter2,akasha,batma,motorcyc,bambino,tenerife,fordf250,zhuan,iloveporn,markiza,hotbabes,becool,fynjybyf,wapapapa,forme,mamont,pizda,dragonz,sharon1,scrooge,mrbill,pfloyd,leeroy,natedog,ishmael,777111,tecumseh,carajo,nfy.irf,0000000000o,blackcock,fedorov,antigone,feanor,novikova,bobert,peregrin,spartan117,pumkin,rayman,manuals,tooltime,555333,bonethug,marina1,bonnie1,tonyhawk,laracroft,mahalkita,18273645,terriers,gamer,hoser,littlema,molotok,glennwei,lemon1,caboose,tater,12345654321,brians,fritz1,mistral,jigsaw,fuckshit,hornyguy,southside,edthom,antonio1,bobmarle,pitures,ilikesex,crafty,nexus,boarder,fulcrum,astonvil,yanks1,yngwie,account1,zooropa,hotlegs,sammi,gumbo,rover1,perkele,maurolarastefy,lampard,357753,barracud,dmband,abcxyz,pathfinder,335577,yuliya,micky,jayman,asdfg12345,1596321,halcyon,rerfhtre,feniks,zaxscd,gotyoass,jaycee,samson1,jamesb,vibrate,grandpri,camino,colossus,davidb,mamo4ka,nicky1,homer123,pinguin,watermelon,shadow01,lasttime,glider,823762,helen1,pyramids,tulane,osama,rostov,john12,scoote,bhbyrf,gohan,galeries,joyful,bigpussy,tonka,mowgli,astalavista,zzz123,leafs,dalejr8,unicorn1,777000,primal,bigmama,okmijn,killzone,qaz12345,snookie,zxcvvcxz,davidc,epson,rockman,ceaser,beanbag,katten,3151020,duckhunt,segreto,matros,ragnar,699669,sexsexse,123123z,fuckyeah,bigbutts,gbcmrf,element1,marketin,saratov,elbereth,blaster1,yamahar6,grime,masha,juneau,1230123,pappy,lindsay1,mooner,seattle1,katzen,lucent,polly1,lagwagon,pixie,misiaczek,666666a,smokedog,lakers24,eyeball,ironhors,ametuer,volkodav,vepsrf,kimmy,gumby1,poi098,ovation,1q2w3,drinker,penetrating,summertime,1dallas,prima,modles,takamine,hardwork,macintosh,tahoe,passthie,chiks,sundown,flowers1,boromir,music123,phaedrus,albert1,joung,malakas,gulliver,parker1,balder,sonne,jessie1,domainlock2005,express1,vfkbyf,youandme,raketa,koala,dhjnvytyjub,nhfrnjh,testibil,ybrbnjc,987654321q,axeman,pintail,pokemon123,dogggg,shandy,thesaint,11122233,x72jhhu3z,theclash,raptors,zappa1,djdjxrf,hell666,friday1,vivaldi,pluto1,lance1,guesswho,jeadmi,corgan,skillz,skippy1,mango1,gymnastic,satori,362514,theedge,cxfcnkbdfz,sparkey,deicide,bagels,lololol,lemmings,r4e3w2q1,silve,staind,schnuffi,dazzle,basebal1,leroy1,bilbo1,luckie,qwerty2,goodfell,hermione,peaceout,davidoff,yesterda,killah,flippy,chrisb,zelda1,headless,muttley,fuckof,tittys,catdaddy,photog,beeker,reaver,ram1500,yorktown,bolero,tryagain,arman,chicco,learjet,alexei,jenna1,go2hell,12s3t4p55,momsanaladventure,mustang9,protoss,rooter,ginola,dingo1,mojave,erica1,1qazse4,marvin1,redwolf,sunbird,dangerou,maciek,girsl,hawks1,packard1,excellen,dashka,soleda,toonces,acetate,nacked,jbond007,alligator,debbie1,wellhung,monkeyma,supers,rigger,larsson,vaseline,rjnzhf,maripos,123456asd,cbr600rr,doggydog,cronic,jason123,trekker,flipmode,druid,sonyvaio,dodges,mayfair,mystuff,fun4me,samanta,sofiya,magics,1ranger,arcane,sixtynin,222444,omerta,luscious,gbyudby,bobcats,envision,chance1,seaweed,holdem,tomate,mensch,slicer,acura1,goochi,qweewq,punter,repoman,tomboy,never1,cortina,gomets,147896321,369852147,dogma,bhjxrf,loglatin,eragon,strato,gazelle,growler,885522,klaudia,payton34,fuckem,butchie,scorpi,lugano,123456789k,nichola,chipper1,spide,uhbujhbq,rsalinas,vfylfhby,longhorns,bugatti,everquest,!qaz2wsx,blackass,999111,snakeman,p455w0rd,fanatic,family1,pfqxbr,777vlad,mysecret,marat,phoenix2,october1,genghis,panties1,cooker,citron,ace123,1234569,gramps,blackcoc,kodiak1,hickory,ivanhoe,blackboy,escher,sincity,beaks,meandyou,spaniel,canon1,timmy1,lancaste,polaroid,edinburg,fuckedup,hotman,cueball,golfclub,gopack,bookcase,worldcup,dkflbvbhjdbx,twostep,17171717aa,letsplay,zolushka,stella1,pfkegf,kingtut,67camaro,barracuda,wiggles,gjhjkm,prancer,patata,kjifhf,theman1,romanova,sexyass,copper1,dobber,sokolov,pomidor,algernon,cadman,amoremio,william2,silly1,bobbys,hercule,hd764nw5d7e1vb1,defcon,deutschland,robinhood,alfalfa,machoman,lesbens,pandora1,easypay,tomservo,nadezhda,goonies,saab9000,jordyn,f15eagle,dbrecz,12qwerty,greatsex,thrawn,blunted,baywatch,doggystyle,loloxx,chevy2,january1,kodak,bushel,78963214,ub6ib9,zz8807zpl,briefs,hawker,224488,first1,bonzo,brent1,erasure,69213124,sidewind,soccer13,622521,mentos,kolibri,onepiece,united1,ponyboy,keksa12,wayer,mypussy,andrej,mischa,mille,bruno123,garter,bigpun,talgat,familia,jazzy1,mustang8,newjob,747400,bobber,blackbel,hatteras,ginge,asdfjkl;,camelot1,blue44,rebbyt34,ebony1,vegas123,myboys,aleksander,ijrjkflrf,lopata,pilsner,lotus123,m0nk3y,andreev,freiheit,balls1,drjynfrnt,mazda1,waterpolo,shibumi,852963,123bbb,cezer121,blondie1,volkova,rattler,kleenex,ben123,sanane,happydog,satellit,qazplm,qazwsxedcrfvtgb,meowmix,badguy,facefuck,spice1,blondy,major1,25000,anna123,654321a,sober1,deathrow,patterso,china1,naruto1,hawkeye1,waldo1,butchy,crayon,5tgb6yhn,klopik,crocodil,mothra,imhorny,pookie1,splatter,slippy,lizard1,router,buratino,yahweh,123698,dragon11,123qwe456,peepers,trucker1,ganjaman,1hxboqg2,cheyanne,storys,sebastie,zztop,maddison,4rfv3edc,darthvader,jeffro,iloveit,victor1,hotty,delphin,lifeisgood,gooseman,shifty,insertions,dude123,abrupt,123masha,boogaloo,chronos,stamford,pimpster,kthjxrf,getmein,amidala,flubber,fettish,grapeape,dantes,oralsex,jack1,foxcg33,winchest,francis1,getin,archon,cliffy,blueman,1basebal,sport1,emmitt22,porn123,bignasty,morga,123hfjdk147,ferrar,juanito,fabiol,caseydog,steveo,peternorth,paroll,kimchi,bootleg,gaijin,secre,acacia,eatme2,amarillo,monkey11,rfhfgep,tylers,a1a2a3a4a5,sweetass,blower,rodina,babushka,camilo,cimbom,tiffan,vfnbkmlf,ohbaby,gotigers,lindsey1,dragon13,romulus,qazxsw12,zxcvbn1,dropdead,hitman47,snuggle,eleven11,bloopers,357mag,avangard,bmw320,ginscoot,dshade,masterkey,voodoo1,rootedit,caramba,leahcim,hannover,8phrowz622,tim123,cassius,000000a,angelito,zzzzz1,badkarma,star1,malaga,glenwood,footlove,golf1,summer12,helpme1,fastcars,titan1,police1,polinka,k.jdm,marusya,augusto,shiraz,pantyhose,donald1,blaise,arabella,brigada,c3por2d2,peter01,marco1,hellow,dillweed,uzumymw,geraldin,loveyou2,toyota1,088011,gophers,indy500,slainte,5hsu75kpot,teejay,renat,racoon,sabrin,angie1,shiznit,harpua,sexyred,latex,tucker1,alexandru,wahoo,teamwork,deepblue,goodison,rundmc,r2d2c3p0,puppys,samba,ayrton,boobed,999777,topsecre,blowme1,123321z,loudog,random1,pantie,drevil,mandolin,121212q,hottub,brother1,failsafe,spade1,matvey,open1234,carmen1,priscill,schatzi,kajak,gooddog,trojans1,gordon1,kayak,calamity,argent,ufhvjybz,seviyi,penfold,assface,dildos,hawkwind,crowbar,yanks,ruffles,rastus,luv2epus,open123,aquafina,dawns,jared1,teufel,12345c,vwgolf,pepsi123,amores,passwerd,01478520,boliva,smutty,headshot,password3,davidd,zydfhm,gbgbcmrf,pornpass,insertion,ceckbr,test2,car123,checkit,dbnfkbq,niggas,nyyankee,muskrat,nbuhtyjr,gunner1,ocean1,fabienne,chrissy1,wendys,loveme89,batgirl,cerveza,igorek,steel1,ragman,boris123,novifarm,sexy12,qwerty777,mike01,giveitup,123456abc,fuckall,crevice,hackerz,gspot,eight8,assassins,texass,swallows,123458,baldur,moonshine,labatt,modem,sydney1,voland,dbnfkz,hotchick,jacker,princessa,dawgs1,holiday1,booper,reliant,miranda1,jamaica1,andre1,badnaamhere,barnaby,tiger7,david12,margaux,corsica,085tzzqi,universi,thewall,nevermor,martin6,qwerty77,cipher,apples1,0102030405,seraphim,black123,imzadi,gandon,ducati99,1shadow,dkflbvbhjdyf,44magnum,bigbad,feedme,samantha1,ultraman,redneck1,jackdog,usmc0311,fresh1,monique1,tigre,alphaman,cool1,greyhoun,indycar,crunchy,55chevy,carefree,willow1,063dyjuy,xrated,assclown,federica,hilfiger,trivia,bronco1,mamita,100200300,simcity,lexingky,akatsuki,retsam,johndeere,abudfv,raster,elgato,businka,satanas,mattingl,redwing1,shamil,patate,mannn,moonstar,evil666,b123456,bowl300,tanechka,34523452,carthage,babygir,santino,bondarenko,jesuss,chico1,numlock,shyguy,sound1,kirby1,needit,mostwanted,427900,funky1,steve123,passions,anduril,kermit1,prospero,lusty,barakuda,dream1,broodwar,porky,christy1,mahal,yyyyyy1,allan1,1sexy,flintsto,capri,cumeater,heretic,robert2,hippos,blindax,marykay,collecti,kasumi,1qaz!qaz,112233q,123258,chemistr,coolboy,0o9i8u,kabuki,righton,tigress,nessie,sergej,andrew12,yfafyz,ytrhjvfyn,angel7,victo,mobbdeep,lemming,transfor,1725782,myhouse,aeynbr,muskie,leno4ka,westham1,cvbhyjd,daffodil,pussylicker,pamela1,stuffer,warehous,tinker1,2w3e4r,pluton,louise1,polarbea,253634,prime1,anatoliy,januar,wysiwyg,cobraya,ralphy,whaler,xterra,cableguy,112233a,porn69,jamesd,aqualung,jimmy123,lumpy,luckyman,kingsize,golfing1,alpha7,leeds1,marigold,lol1234,teabag,alex11,10sne1,saopaulo,shanny,roland1,basser,3216732167,carol1,year2005,morozov,saturn1,joseluis,bushed,redrock,memnoch,lalaland,indiana1,lovegod,gulnaz,buffalos,loveyou1,anteater,pattaya,jaydee,redshift,bartek,summerti,coffee1,ricochet,incest,schastie,rakkaus,h2opolo,suikoden,perro,dance1,loveme1,whoopass,vladvlad,boober,flyers1,alessia,gfcgjhn,pipers,papaya,gunsling,coolone,blackie1,gonads,gfhjkzytn,foxhound,qwert12,gangrel,ghjvtntq,bluedevi,mywife,summer01,hangman,licorice,patter,vfr750,thorsten,515253,ninguna,dakine,strange1,mexic,vergeten,12345432,8phrowz624,stampede,floyd1,sailfish,raziel,ananda,giacomo,freeme,crfprf,74185296,allstars,master01,solrac,gfnhbjn,bayliner,bmw525,3465xxx,catter,single1,michael3,pentium4,nitrox,mapet123456,halibut,killroy,xxxxx1,phillip1,poopsie,arsenalfc,buffys,kosova,all4me,32165498,arslan,opensesame,brutis,charles2,pochta,nadegda,backspac,mustang0,invis,gogeta,654321q,adam25,niceday,truckin,gfdkbr,biceps,sceptre,bigdave,lauras,user345,sandys,shabba,ratdog,cristiano,natha,march13,gumball,getsdown,wasdwasd,redhead1,dddddd1,longlegs,13572468,starsky,ducksoup,bunnys,omsairam,whoami,fred123,danmark,flapper,swanky,lakings,yfhenj,asterios,rainier,searcher,dapper,ltdjxrf,horsey,seahawk,shroom,tkfkdgo,aquaman,tashkent,number9,messi10,1asshole,milenium,illumina,vegita,jodeci,buster01,bareback,goldfinger,fire1,33rjhjds,sabian,thinkpad,smooth1,sully,bonghits,sushi1,magnavox,colombi,voiture,limpone,oldone,aruba,rooster1,zhenya,nomar5,touchdow,limpbizkit,rhfcfdxbr,baphomet,afrodita,bball1,madiso,ladles,lovefeet,matthew2,theworld,thunderbird,dolly1,123rrr,forklift,alfons,berkut,speedy1,saphire,oilman,creatine,pussylov,bastard1,456258,wicked1,filimon,skyline1,fucing,yfnfkbz,hot123,abdulla,nippon,nolimits,billiard,booty1,buttplug,westlife,coolbean,aloha1,lopas,asasin,1212121,october2,whodat,good4u,d12345,kostas,ilya1992,regal,pioneer1,volodya,focus1,bastos,nbvjif,fenix,anita1,vadimka,nickle,jesusc,123321456,teste,christ1,essendon,evgenii,celticfc,adam1,forumwp,lovesme,26exkp,chillout,burly,thelast1,marcus1,metalgear,test11,ronaldo7,socrate,world1,franki,mommie,vicecity,postov1000,charlie3,oldschool,333221,legoland,antoshka,counterstrike,buggy,mustang3,123454,qwertzui,toons,chesty,bigtoe,tigger12,limpopo,rerehepf,diddle,nokia3250,solidsnake,conan1,rockroll,963369,titanic1,qwezxc,cloggy,prashant,katharin,maxfli,takashi,cumonme,michael9,mymother,pennstate,khalid,48151623,fightclub,showboat,mateusz,elrond,teenie,arrow1,mammamia,dustydog,dominator,erasmus,zxcvb1,1a2a3a,bones1,dennis1,galaxie,pleaseme,whatever1,junkyard,galadriel,charlies,2wsxzaq1,crimson1,behemoth,teres,master11,fairway,shady1,pass99,1batman,joshua12,baraban,apelsin,mousepad,melon,twodogs,123321qwe,metalica,ryjgrf,pipiska,rerfhfxf,lugnut,cretin,iloveu2,powerade,aaaaaaa1,omanko,kovalenko,isabe,chobits,151nxjmt,shadow11,zcxfcnkbdf,gy3yt2rgls,vfhbyrf,159753123,bladerunner,goodone,wonton,doodie,333666999,fuckyou123,kitty123,chisox,orlando1,skateboa,red12345,destroye,snoogans,satan1,juancarlo,goheels,jetson,scottt,fuckup,aleksa,gfhfljrc,passfind,oscar123,derrick1,hateme,viper123,pieman,audi100,tuffy,andover,shooter1,10000,makarov,grant1,nighthaw,13576479,browneye,batigol,nfvfhf,chocolate1,7hrdnw23,petter,bantam,morlii,jediknight,brenden,argonaut,goodstuf,wisconsi,315920,abigail1,dirtbag,splurge,k123456,lucky777,valdepen,gsxr600,322223,ghjnjrjk,zaq1xsw2cde3,schwanz,walter1,letmein22,nomads,124356,codeblue,nokian70,fucke,footbal1,agyvorc,aztecs,passw0r,smuggles,femmes,ballgag,krasnodar,tamuna,schule,sixtynine,empires,erfolg,dvader,ladygaga,elite1,venezuel,nitrous,kochamcie,olivia1,trustn01,arioch,sting1,131415,tristar,555000,maroon,135799,marsik,555556,fomoco,natalka,cwoui,tartan,davecole,nosferat,hotsauce,dmitry,horus,dimasik,skazka,boss302,bluebear,vesper,ultras,tarantul,asd123asd,azteca,theflash,8ball,1footbal,titlover,lucas123,number6,sampson1,789852,party1,dragon99,adonai,carwash,metropol,psychnau,vthctltc,hounds,firework,blink18,145632,wildcat1,satchel,rice80,ghtktcnm,sailor1,cubano,anderso,rocks1,mike11,famili,dfghjc,besiktas,roygbiv,nikko,bethan,minotaur,rakesh,orange12,hfleuf,jackel,myangel,favorite7,1478520,asssss,agnieszka,haley1,raisin,htubyf,1buster,cfiekz,derevo,1a2a3a4a5a,baltika,raffles,scruffy1,clitlick,louis1,buddha1,fy.nrf,walker1,makoto,shadow2,redbeard,vfvfvskfhfve,mycock,sandydog,lineman,network1,favorite8,longdick,mustangg,mavericks,indica,1killer,cisco1,angelofwar,blue69,brianna1,bubbaa,slayer666,level42,baldrick,brutus1,lowdown,haribo,lovesexy,500000,thissuck,picker,stephy,1fuckme,characte,telecast,1bigdog,repytwjdf,thematrix,hammerhe,chucha,ganesha,gunsmoke,georgi,sheltie,1harley,knulla,sallas,westie,dragon7,conker,crappie,margosha,lisboa,3e2w1q,shrike,grifter,ghjcnjghjcnj,asdfg1,mnbvcxz1,myszka,posture,boggie,rocketman,flhtyfkby,twiztid,vostok,pi314159,force1,televizor,gtkmvtym,samhain,imcool,jadzia,dreamers,strannik,k2trix,steelhea,nikitin,commodor,brian123,chocobo,whopper,ibilljpf,megafon,ararat,thomas12,ghbrjkbcn,q1234567890,hibernia,kings1,jim123,redfive,68camaro,iawgk2,xavier1,1234567u,d123456,ndirish,airborn,halfmoon,fluffy1,ranchero,sneaker,soccer2,passion1,cowman,birthday1,johnn,razzle,glock17,wsxqaz,nubian,lucky2,jelly1,henderso,eric1,123123e,boscoe01,fuck0ff,simpson1,sassie,rjyjgkz,nascar3,watashi,loredana,janus,wilso,conman,david2,mothe,iloveher,snikers,davidj,fkmnthyfnbdf,mettss,ratfink,123456h,lostsoul,sweet16,brabus,wobble,petra1,fuckfest,otters,sable1,svetka,spartacu,bigstick,milashka,1lover,pasport,champagn,papichul,hrvatska,hondacivic,kevins,tacit,moneybag,gohogs,rasta1,246813579,ytyfdbcnm,gubber,darkmoon,vitaliy,233223,playboys,tristan1,joyce1,oriflame,mugwump,access2,autocad,thematri,qweqwe123,lolwut,ibill01,multisyn,1233211,pelikan,rob123,chacal,1234432,griffon,pooch,dagestan,geisha,satriani,anjali,rocketma,gixxer,pendrago,vincen,hellokit,killyou,ruger,doodah,bumblebe,badlands,galactic,emachines,foghorn,jackso,jerem,avgust,frontera,123369,daisymae,hornyboy,welcome123,tigger01,diabl,angel13,interex,iwantsex,rockydog,kukolka,sawdust,online1,3234412,bigpapa,jewboy,3263827,dave123,riches,333222,tony1,toggle,farter,124816,tities,balle,brasilia,southsid,micke,ghbdtn12,patit,ctdfcnjgjkm,olds442,zzzzzz1,nelso,gremlins,gypsy1,carter1,slut69,farcry,7415963,michael8,birdie1,charl,123456789abc,100001,aztec,sinjin,bigpimpi,closeup,atlas1,nvidia,doggone,classic1,manana,malcolm1,rfkbyf,hotbabe,rajesh,dimebag,ganjubas,rodion,jagr68,seren,syrinx,funnyman,karapuz,123456789n,bloomin,admin18533362,biggdogg,ocarina,poopy1,hellome,internet1,booties,blowjobs,matt1,donkey1,swede,1jennife,evgeniya,lfhbyf,coach1,444777,green12,patryk,pinewood,justin12,271828,89600506779,notredame,tuborg,lemond,sk8ter,million1,wowser,pablo1,st0n3,jeeves,funhouse,hiroshi,gobucs,angeleye,bereza,winter12,catalin,qazedc,andros,ramazan,vampyre,sweethea,imperium,murat,jamest,flossy,sandeep,morgen,salamandra,bigdogg,stroller,njdevils,nutsack,vittorio,%%passwo,playful,rjyatnrf,tookie,ubnfhf,michi,777444,shadow13,devils1,radiance,toshiba1,beluga,amormi,dandfa,trust1,killemall,smallville,polgara,billyb,landscap,steves,exploite,zamboni,damage11,dzxtckfd,trader12,pokey1,kobe08,damager,egorov,dragon88,ckfdbr,lisa69,blade2,audis4,nelson1,nibbles,23176djivanfros,mutabor,artofwar,matvei,metal666,hrfzlz,schwinn,poohbea,seven77,thinker,123456789qwerty,sobriety,jakers,karamelka,vbkfyf,volodin,iddqd,dale03,roberto1,lizaveta,qqqqqq1,cathy1,08154711,davidm,quixote,bluenote,tazdevil,katrina1,bigfoot1,bublik,marma,olechka,fatpussy,marduk,arina,nonrev67,qqqq1111,camill,wtpfhm,truffle,fairview,mashina,voltaire,qazxswedcvfr,dickface,grassy,lapdance,bosstone,crazy8,yackwin,mobil,danielit,mounta1n,player69,bluegill,mewtwo,reverb,cnthdf,pablito,a123321,elena1,warcraft1,orland,ilovemyself,rfntyjr,joyride,schoo,dthjxrf,thetachi,goodtimes,blacksun,humpty,chewbacca,guyute,123xyz,lexicon,blue45,qwe789,galatasaray,centrino,hendrix1,deimos,saturn5,craig1,vlad1996,sarah123,tupelo,ljrnjh,hotwife,bingos,1231231,nicholas1,flamer,pusher,1233210,heart1,hun999,jiggy,giddyup,oktober,123456zxc,budda,galahad,glamur,samwise,oneton,bugsbunny,dominic1,scooby2,freetime,internat,159753852,sc00ter,wantit,mazinger,inflames,laracrof,greedo,014789,godofwar,repytwjd,water123,fishnet,venus1,wallace1,tenpin,paula1,1475963,mania,novikov,qwertyasdfgh,goldmine,homies,777888999,8balls,holeinon,paper1,samael,013579,mansur,nikit,ak1234,blueline,polska1,hotcock,laredo,windstar,vbkbwbz,raider1,newworld,lfybkrf,catfish1,shorty1,piranha,treacle,royale,2234562,smurfs,minion,cadence,flapjack,123456p,sydne,135531,robinhoo,nasdaq,decatur,cyberonline,newage,gemstone,jabba,touchme,hooch,pigdog,indahous,fonzie,zebra1,juggle,patrick2,nihongo,hitomi,oldnavy,qwerfdsa,ukraina,shakti,allure,kingrich,diane1,canad,piramide,hottie1,clarion,college1,5641110,connect1,therion,clubber,velcro,dave1,astra1,13579-,astroboy,skittle,isgreat,photoes,cvzefh1gkc,001100,2cool4u,7555545,ginger12,2wsxcde3,camaro69,invader,domenow,asd1234,colgate,qwertasdfg,jack123,pass01,maxman,bronte,whkzyc,peter123,bogie,yecgaa,abc321,1qay2wsx,enfield,camaroz2,trashman,bonefish,system32,azsxdcfvgb,peterose,iwantyou,dick69,temp1234,blastoff,capa200,connie1,blazin,12233445,sexybaby,123456j,brentfor,pheasant,hommer,jerryg,thunders,august1,lager,kapusta,boobs1,nokia5300,rocco1,xytfu7,stars1,tugger,123sas,blingbling,1bubba,0wnsyo0,1george,baile,richard2,habana,1diamond,sensatio,1golfer,maverick1,1chris,clinton1,michael7,dragons1,sunrise1,pissant,fatim,mopar1,levani,rostik,pizzapie,987412365,oceans11,748159263,cum4me,palmetto,4r3e2w1q,paige1,muncher,arsehole,kratos,gaffer,banderas,billys,prakash,crabby,bungie,silver12,caddis,spawn1,xboxlive,sylvania,littlebi,524645,futura,valdemar,isacs155,prettygirl,big123,555444,slimer,chicke,newstyle,skypilot,sailormoon,fatluvr69,jetaime,sitruc,jesuschrist,sameer,bear12,hellion,yendor,country1,etnies,conejo,jedimast,darkknight,toobad,yxcvbn,snooks,porn4life,calvary,alfaromeo,ghostman,yannick,fnkfynblf,vatoloco,homebase,5550666,barret,1111111111zz,odysseus,edwardss,favre4,jerrys,crybaby,xsw21qaz,firestor,spanks,indians1,squish,kingair,babycakes,haters,sarahs,212223,teddyb,xfactor,cumload,rhapsody,death123,three3,raccoon,thomas2,slayer66,1q2q3q4q5q,thebes,mysterio,thirdeye,orkiox.,nodoubt,bugsy,schweiz,dima1996,angels1,darkwing,jeronimo,moonpie,ronaldo9,peaches2,mack10,manish,denise1,fellowes,carioca,taylor12,epaulson,makemoney,oc247ngucz,kochanie,3edcvfr4,vulture,1qw23e,1234567z,munchie,picard1,xthtgfirf,sportste,psycho1,tahoe1,creativ,perils,slurred,hermit,scoob,diesel1,cards1,wipeout,weeble,integra1,out3xf,powerpc,chrism,kalle,ariadne,kailua,phatty,dexter1,fordman,bungalow,paul123,compa,train1,thejoker,jys6wz,pussyeater,eatmee,sludge,dominus,denisa,tagheuer,yxcvbnm,bill1,ghfdlf,300zx,nikita123,carcass,semaj,ramone,muenchen,animal1,greeny,annemari,dbrf134,jeepcj7,mollys,garten,sashok,ironmaid,coyotes,astoria,george12,westcoast,primetim,123456o,panchito,rafae,japan1,framer,auralo,tooshort,egorova,qwerty22,callme,medicina,warhawk,w1w2w3w4,cristia,merli,alex22,kawaii,chatte,wargames,utvols,muaddib,trinket,andreas1,jjjjj1,cleric,scooters,cuntlick,gggggg1,slipknot1,235711,handcuff,stussy,guess1,leiceste,ppppp1,passe,lovegun,chevyman,hugecock,driver1,buttsex,psychnaut1,cyber1,black2,alpha12,melbourn,man123,metalman,yjdsqujl,blondi,bungee,freak1,stomper,caitlin1,nikitina,flyaway,prikol,begood,desperad,aurelius,john1234,whosyourdaddy,slimed123,bretagne,den123,hotwheel,king123,roodypoo,izzicam,save13tx,warpten,nokia3310,samolet,ready1,coopers,scott123,bonito,1aaaaa,yomomma,dawg1,rache,itworks,asecret,fencer,451236,polka,olivetti,sysadmin,zepplin,sanjuan,479373,lickem,hondacrx,pulamea,future1,naked1,sexyguy,w4g8at,lollol1,declan,runner1,rumple,daddy123,4snz9g,grandprix,calcio,whatthefuck,nagrom,asslick,pennst,negrit,squiggy,1223334444,police22,giovann,toronto1,tweet,yardbird,seagate,truckers,554455,scimitar,pescator,slydog,gaysex,dogfish,fuck777,12332112,qazxswed,morkovka,daniela1,imback,horny69,789123456,123456789w,jimmy2,bagger,ilove69,nikolaus,atdhfkm,rebirth,1111aaaa,pervasive,gjgeufq,dte4uw,gfhnbpfy,skeletor,whitney1,walkman,delorean,disco1,555888,as1234,ishikawa,fuck12,reaper1,dmitrii,bigshot,morrisse,purgen,qwer4321,itachi,willys,123123qwe,kisska,roma123,trafford,sk84life,326159487,pedros,idiom,plover,bebop,159875321,jailbird,arrowhea,qwaszx123,zaxscdvf,catlover,bakers,13579246,bones69,vermont1,helloyou,simeon,chevyz71,funguy,stargaze,parolparol,steph1,bubby,apathy,poppet,laxman,kelly123,goodnews,741236,boner1,gaetano,astonvilla,virtua,luckyboy,rocheste,hello2u,elohim,trigger1,cstrike,pepsicola,miroslav,96385274,fistfuck,cheval,magyar,svetlanka,lbfyjxrf,mamedov,123123123q,ronaldo1,scotty1,1nicole,pittbull,fredd,bbbbb1,dagwood,gfhkfvtyn,ghblehrb,logan5,1jordan,sexbomb,omega2,montauk,258741,dtythf,gibbon,winamp,thebomb,millerli,852654,gemin,baldy,halflife2,dragon22,mulberry,morrigan,hotel6,zorglub,surfin,951159,excell,arhangel,emachine,moses1,968574,reklama,bulldog2,cuties,barca,twingo,saber,elite11,redtruck,casablan,ashish,moneyy,pepper12,cnhtktw,rjcnbr,arschloch,phenix,cachorro,sunita,madoka,joselui,adams1,mymoney,hemicuda,fyutkjr,jake12,chicas,eeeee1,sonnyboy,smarties,birdy,kitten1,cnfcbr,island1,kurosaki,taekwond,konfetka,bennett1,omega3,jackson2,fresca,minako,octavian,kban667,feyenoord,muaythai,jakedog,fktrcfylhjdyf,1357911q,phuket,sexslave,fktrcfylhjdbx,asdfjk,89015173454,qwerty00,kindbud,eltoro,sex6969,nyknicks,12344321q,caballo,evenflow,hoddle,love22,metro1,mahalko,lawdog,tightass,manitou,buckie,whiskey1,anton123,335533,password4,primo,ramair,timbo,brayden,stewie,pedro1,yorkshir,ganster,hellothe,tippy1,direwolf,genesi,rodrig,enkeli,vaz21099,sorcerer,winky,oneshot,boggle,serebro,badger1,japanes,comicbook,kamehame,alcat,denis123,echo45,sexboy,gr8ful,hondo,voetbal,blue33,2112rush,geneviev,danni1,moosey,polkmn,matthew7,ironhead,hot2trot,ashley12,sweeper,imogen,blue21,retep,stealth1,guitarra,bernard1,tatian,frankfur,vfnhbwf,slacking,haha123,963741,asdasdas,katenok,airforce1,123456789qaz,shotgun1,12qwasz,reggie1,sharo,976431,pacifica,dhip6a,neptun,kardon,spooky1,beaut,555555a,toosweet,tiedup,11121314,startac,lover69,rediska,pirata,vfhrbp,1234qwerty,energize,hansolo1,playbo,larry123,oemdlg,cnjvfnjkju,a123123,alexan,gohawks,antonius,fcbayern,mambo,yummy1,kremlin,ellen1,tremere,vfiekz,bellevue,charlie9,izabella,malishka,fermat,rotterda,dawggy,becket,chasey,kramer1,21125150,lolit,cabrio,schlong,arisha,verity,3some,favorit,maricon,travelle,hotpants,red1234,garrett1,home123,knarf,seven777,figment,asdewq,canseco,good2go,warhol,thomas01,pionee,al9agd,panacea,chevy454,brazzers,oriole,azerty123,finalfan,patricio,northsta,rebelde,bulldo,stallone,boogie1,7uftyx,cfhfnjd,compusa,cornholi,config,deere,hoopster,sepultura,grasshop,babygurl,lesbo,diceman,proverbs,reddragon,nurbek,tigerwoo,superdup,buzzsaw,kakaroto,golgo13,edwar,123qaz123,butter1,sssss1,texas2,respekt,ou812ic,123456qaz,55555a,doctor1,mcgwire,maria123,aol999,cinders,aa1234,joness,ghbrjkmyj,makemone,sammyboy,567765,380zliki,theraven,testme,mylene,elvira26,indiglo,tiramisu,shannara,baby1,123666,gfhreh,papercut,johnmish,orange8,bogey1,mustang7,bagpipes,dimarik,vsijyjr,4637324,ravage,cogito,seven11,natashka,warzone,hr3ytm,4free,bigdee,000006,243462536,bigboi,123333,trouts,sandy123,szevasz,monica2,guderian,newlife1,ratchet,r12345,razorbac,12345i,piazza31,oddjob,beauty1,fffff1,anklet,nodrog,pepit,olivi,puravida,robert12,transam1,portman,bubbadog,steelers1,wilson1,eightball,mexico1,superboy,4rfv5tgb,mzepab,samurai1,fuckslut,colleen1,girdle,vfrcbvec,q1w2e3r4t,soldier1,19844891,alyssa1,a12345a,fidelis,skelter,nolove,mickeymouse,frehley,password69,watermel,aliska,soccer15,12345e,ladybug1,abulafia,adagio,tigerlil,takehana,hecate,bootneck,junfan,arigato,wonkette,bobby123,trustnoone,phantasm,132465798,brianjo,w12345,t34vfrc1991,deadeye,1robert,1daddy,adida,check1,grimlock,muffi,airwalk,prizrak,onclick,longbeac,ernie1,eadgbe,moore1,geniu,shadow123,bugaga,jonathan1,cjrjkjdf,orlova,buldog,talon1,westport,aenima,541233432442,barsuk,chicago2,kellys,hellbent,toughguy,iskander,skoal,whatisit,jake123,scooter2,fgjrfkbgcbc,ghandi,love13,adelphia,vjhrjdrf,adrenali,niunia,jemoeder,rainbo,all4u8,anime1,freedom7,seraph,789321,tommys,antman,firetruc,neogeo,natas,bmwm3,froggy1,paul1,mamit,bayview,gateways,kusanagi,ihateu,frederi,rock1,centurion,grizli,biggin,fish1,stalker1,3girls,ilovepor,klootzak,lollo,redsox04,kirill123,jake1,pampers,vasya,hammers1,teacup,towing,celtic1,ishtar,yingyang,4904s677075,dahc1,patriot1,patrick9,redbirds,doremi,rebecc,yoohoo,makarova,epiphone,rfgbnfy,milesd,blister,chelseafc,katana1,blackrose,1james,primrose,shock5,hard1,scooby12,c6h12o6,dustoff,boing,chisel,kamil,1william,defiant1,tyvugq,mp8o6d,aaa340,nafets,sonnet,flyhigh,242526,crewcom,love23,strike1,stairway,katusha,salamand,cupcake1,password0,007james,sunnie,multisync,harley01,tequila1,fred12,driver8,q8zo8wzq,hunter01,mozzer,temporar,eatmeraw,mrbrownxx,kailey,sycamore,flogger,tincup,rahasia,ganymede,bandera,slinger,1111122222,vander,woodys,1cowboy,khaled,jamies,london12,babyboo,tzpvaw,diogenes,budice,mavrick,135797531,cheeta,macros,squonk,blackber,topfuel,apache1,falcon16,darkjedi,cheeze,vfhvtkfl,sparco,change1,gfhfif,freestyl,kukuruza,loveme2,12345f,kozlov,sherpa,marbella,44445555,bocephus,1winner,alvar,hollydog,gonefish,iwantin,barman,godislove,amanda18,rfpfynbg,eugen,abcdef1,redhawk,thelema,spoonman,baller1,harry123,475869,tigerman,cdtnjxrf,marillio,scribble,elnino,carguy,hardhead,l2g7k3,troopers,selen,dragon76,antigua,ewtosi,ulysse,astana,paroli,cristo,carmex,marjan,bassfish,letitbe,kasparov,jay123,19933991,blue13,eyecandy,scribe,mylord,ukflbjkec,ellie1,beaver1,destro,neuken,halfpint,ameli,lilly1,satanic,xngwoj,12345trewq,asdf1,bulldogg,asakura,jesucrist,flipside,packers4,biggy,kadett,biteme69,bobdog,silverfo,saint1,bobbo,packman,knowledg,foolio,fussbal,12345g,kozerog,westcoas,minidisc,nbvcxw,martini1,alastair,rasengan,superbee,memento,porker,lena123,florenc,kakadu,bmw123,getalife,bigsky,monkee,people1,schlampe,red321,memyself,0147896325,12345678900987654321,soccer14,realdeal,gfgjxrf,bella123,juggs,doritos,celtics1,peterbilt,ghbdtnbrb,gnusmas,xcountry,ghbdtn1,batman99,deusex,gtnhjdf,blablabl,juster,marimba,love2,rerjkrf,alhambra,micros,siemens1,assmaste,moonie,dashadasha,atybrc,eeeeee1,wildrose,blue55,davidl,xrp23q,skyblue,leo123,ggggg1,bestfriend,franny,1234rmvb,fun123,rules1,sebastien,chester2,hakeem,winston2,fartripper,atlant,07831505,iluvsex,q1a2z3,larrys,009900,ghjkju,capitan,rider1,qazxsw21,belochka,andy123,hellya,chicca,maximal,juergen,password1234,howard1,quetzal,daniel123,qpwoeiruty,123555,bharat,ferrari3,numbnuts,savant,ladydog,phipsi,lovepussy,etoile,power2,mitten,britneys,chilidog,08522580,2fchbg,kinky1,bluerose,loulo,ricardo1,doqvq3,kswbdu,013cpfza,timoha,ghbdtnghbdtn,3stooges,gearhead,browns1,g00ber,super7,greenbud,kitty2,pootie,toolshed,gamers,coffe,ibill123,freelove,anasazi,sister1,jigger,natash,stacy1,weronika,luzern,soccer7,hoopla,dmoney,valerie1,canes,razdvatri,washere,greenwoo,rfhjkbyf,anselm,pkxe62,maribe,daniel2,maxim1,faceoff,carbine,xtkjdtr,buddy12,stratos,jumpman,buttocks,aqswdefr,pepsis,sonechka,steeler1,lanman,nietzsch,ballz,biscuit1,wrxsti,goodfood,juventu,federic,mattman,vika123,strelec,jledfyxbr,sideshow,4life,fredderf,bigwilly,12347890,12345671,sharik,bmw325i,fylhtqrf,dannon4,marky,mrhappy,drdoom,maddog1,pompier,cerbera,goobers,howler,jenny69,evely,letitrid,cthuttdyf,felip,shizzle,golf12,t123456,yamah,bluearmy,squishy,roxan,10inches,dollface,babygirl1,blacksta,kaneda,lexingto,canadien,222888,kukushka,sistema,224422,shadow69,ppspankp,mellons,barbie1,free4all,alfa156,lostone,2w3e4r5t,painkiller,robbie1,binger,8dihc6,jaspe,rellik,quark,sogood,hoopstar,number2,snowy1,dad2ownu,cresta,qwe123asd,hjvfyjdf,gibsonsg,qbg26i,dockers,grunge,duckling,lfiekz,cuntsoup,kasia1,1tigger,woaini,reksio,tmoney,firefighter,neuron,audia3,woogie,powerboo,powermac,fatcock,12345666,upnfmc,lustful,porn1,gotlove,amylee,kbytqrf,11924704,25251325,sarasota,sexme,ozzie1,berliner,nigga1,guatemal,seagulls,iloveyou!,chicken2,qwerty21,010203040506,1pillow,libby1,vodoley,backlash,piglets,teiubesc,019283,vonnegut,perico,thunde,buckey,gtxtymrf,manunite,iiiii1,lost4815162342,madonn,270873_,britney1,kevlar,piano1,boondock,colt1911,salamat,doma77ns,anuradha,cnhjqrf,rottweil,newmoon,topgun1,mauser,fightclu,birthday21,reviewpa,herons,aassddff,lakers32,melissa2,vredina,jiujitsu,mgoblue,shakey,moss84,12345zxcvb,funsex,benji1,garci,113322,chipie,windex,nokia5310,pwxd5x,bluemax,cosita,chalupa,trotsky,new123,g3ujwg,newguy,canabis,gnaget,happydays,felixx,1patrick,cumface,sparkie,kozlova,123234,newports,broncos7,golf18,recycle,hahah,harrypot,cachondo,open4me,miria,guessit,pepsione,knocker,usmc1775,countach,playe,wiking,landrover,cracksevi,drumline,a7777777,smile123,manzana,panty,liberta,pimp69,dolfan,quality1,schnee,superson,elaine22,webhompass,mrbrownx,deepsea,4wheel,mamasita,rockport,rollie,myhome,jordan12,kfvgjxrf,hockey12,seagrave,ford1,chelsea2,samsara,marissa1,lamesa,mobil1,piotrek,tommygun,yyyyy1,wesley1,billy123,homersim,julies,amanda12,shaka,maldini,suzenet,springst,iiiiii1,yakuza,111111aa,westwind,helpdesk,annamari,bringit,hopefull,hhhhhhh1,saywhat,mazdarx8,bulova,jennife1,baikal,gfhjkmxbr,victoria1,gizmo123,alex99,defjam,2girls,sandrock,positivo,shingo,syncmast,opensesa,silicone,fuckina,senna1,karlos,duffbeer,montagne,gehrig,thetick,pepino,hamburge,paramedic,scamp,smokeweed,fabregas,phantoms,venom121293,2583458,badone,porno69,manwhore,vfvf123,notagain,vbktyf,rfnthbyrf,wildblue,kelly001,dragon66,camell,curtis1,frolova,1212123,dothedew,tyler123,reddrago,planetx,promethe,gigolo,1001001,thisone,eugeni,blackshe,cruzazul,incognito,puller,joonas,quick1,spirit1,gazza,zealot,gordito,hotrod1,mitch1,pollito,hellcat,mythos,duluth,383pdjvl,easy123,hermos,binkie,its420,lovecraf,darien,romina,doraemon,19877891,syclone,hadoken,transpor,ichiro,intell,gargamel,dragon2,wavpzt,557744,rjw7x4,jennys,kickit,rjynfrn,likeit,555111,corvus,nec3520,133113,mookie1,bochum,samsung2,locoman0,154ugeiu,vfvfbgfgf,135792,[start],tenni,20001,vestax,hufmqw,neveragain,wizkid,kjgfnf,nokia6303,tristen,saltanat,louie1,gandalf2,sinfonia,alpha3,tolstoy,ford150,f00bar,1hello,alici,lol12,riker1,hellou,333888,1hunter,qw1234,vibrator,mets86,43211234,gonzale,cookies1,sissy1,john11,bubber,blue01,cup2006,gtkmvtyb,nazareth,heybaby,suresh,teddie,mozilla,rodeo1,madhouse,gamera,123123321,naresh,dominos,foxtrot1,taras,powerup,kipling,jasonb,fidget,galena,meatman,alpacino,bookmark,farting,humper,titsnass,gorgon,castaway,dianka,anutka,gecko1,fucklove,connery,wings1,erika1,peoria,moneymaker,ichabod,heaven1,paperboy,phaser,breakers,nurse1,westbrom,alex13,brendan1,123asd123,almera,grubber,clarkie,thisisme,welkom01,51051051051,crypto,freenet,pflybwf,black12,testme2,changeit,autobahn,attica,chaoss,denver1,tercel,gnasher23,master2,vasilii,sherman1,gomer,bigbuck,derek1,qwerzxcv,jumble,dragon23,art131313,numark,beasty,cxfcnmttcnm,updown,starion,glist,sxhq65,ranger99,monkey7,shifter,wolves1,4r5t6y,phone1,favorite5,skytommy,abracada,1martin,102030405060,gatech,giulio,blacktop,cheer1,africa1,grizzly1,inkjet,shemales,durango1,booner,11223344q,supergirl,vanyarespekt,dickless,srilanka,weaponx,6string,nashvill,spicey,boxer1,fabien,2sexy2ho,bowhunt,jerrylee,acrobat,tawnee,ulisse,nolimit8,l8g3bkde,pershing,gordo1,allover,gobrowns,123432,123444,321456987,spoon1,hhhhh1,sailing1,gardenia,teache,sexmachine,tratata,pirate1,niceone,jimbos,314159265,qsdfgh,bobbyy,ccccc1,carla1,vjkjltw,savana,biotech,frigid,123456789g,dragon10,yesiam,alpha06,oakwood,tooter,winsto,radioman,vavilon,asnaeb,google123,nariman,kellyb,dthyjcnm,password6,parol1,golf72,skate1,lthtdj,1234567890s,kennet,rossia,lindas,nataliya,perfecto,eminem1,kitana,aragorn1,rexona,arsenalf,planot,coope,testing123,timex,blackbox,bullhead,barbarian,dreamon,polaris1,cfvjktn,frdfhbev,gametime,slipknot666,nomad1,hfgcjlbz,happy69,fiddler,brazil1,joeboy,indianali,113355,obelisk,telemark,ghostrid,preston1,anonim,wellcome,verizon1,sayangku,censor,timeport,dummies,adult1,nbnfybr,donger,thales,iamgay,sexy1234,deadlift,pidaras,doroga,123qwe321,portuga,asdfgh12,happys,cadr14nu,pi3141,maksik,dribble,cortland,darken,stepanova,bommel,tropic,sochi2014,bluegras,shahid,merhaba,nacho,2580456,orange44,kongen,3cudjz,78girl,my3kids,marcopol,deadmeat,gabbie,saruman,jeepman,freddie1,katie123,master99,ronal,ballbag,centauri,killer7,xqgann,pinecone,jdeere,geirby,aceshigh,55832811,pepsimax,rayden,razor1,tallyho,ewelina,coldfire,florid,glotest,999333,sevenup,bluefin,limaperu,apostol,bobbins,charmed1,michelin,sundin,centaur,alphaone,christof,trial1,lions1,45645,just4you,starflee,vicki1,cougar1,green2,jellyfis,batman69,games1,hihje863,crazyzil,w0rm1,oklick,dogbite,yssup,sunstar,paprika,postov10,124578963,x24ik3,kanada,buckster,iloveamy,bear123,smiler,nx74205,ohiostat,spacey,bigbill,doudo,nikolaeva,hcleeb,sex666,mindy1,buster11,deacons,boness,njkcnsq,candy2,cracker1,turkey1,qwertyu1,gogreen,tazzzz,edgewise,ranger01,qwerty6,blazer1,arian,letmeinnow,cigar1,jjjjjj1,grigio,frien,tenchu,f9lmwd,imissyou,filipp,heathers,coolie,salem1,woodduck,scubadiv,123kat,raffaele,nikolaev,dapzu455,skooter,9inches,lthgfhjkm,gr8one,ffffff1,zujlrf,amanda69,gldmeo,m5wkqf,rfrltkf,televisi,bonjou,paleale,stuff1,cumalot,fuckmenow,climb7,mark1234,t26gn4,oneeye,george2,utyyflbq,hunting1,tracy71,ready2go,hotguy,accessno,charger1,rudedog,kmfdm,goober1,sweetie1,wtpmjgda,dimensio,ollie1,pickles1,hellraiser,mustdie,123zzz,99887766,stepanov,verdun,tokenbad,anatol,bartende,cidkid86,onkelz,timmie,mooseman,patch1,12345678c,marta1,dummy1,bethany1,myfamily,history1,178500,lsutiger,phydeaux,moren,dbrnjhjdbx,gnbxrf,uniden,drummers,abpbrf,godboy,daisy123,hogan1,ratpack,irland,tangerine,greddy,flore,sqrunch,billyjoe,q55555,clemson1,98745632,marios,ishot,angelin,access12,naruto12,lolly,scxakv,austin12,sallad,cool99,rockit,mongo1,mark22,ghbynth,ariadna,senha,docto,tyler2,mobius,hammarby,192168,anna12,claire1,pxx3eftp,secreto,greeneye,stjabn,baguvix,satana666,rhbcnbyjxrf,dallastx,garfiel,michaelj,1summer,montan,1234ab,filbert,squids,fastback,lyudmila,chucho,eagleone,kimberle,ar3yuk3,jake01,nokids,soccer22,1066ad,ballon,cheeto,review69,madeira,taylor2,sunny123,chubbs,lakeland,striker1,porche,qwertyu8,digiview,go1234,ferari,lovetits,aditya,minnow,green3,matman,cellphon,fortytwo,minni,pucara,69a20a,roman123,fuente,12e3e456,paul12,jacky,demian,littleman,jadakiss,vlad1997,franca,282860,midian,nunzio,xaccess2,colibri,jessica0,revilo,654456,harvey1,wolf1,macarena,corey1,husky1,arsen,milleniu,852147,crowes,redcat,combat123654,hugger,psalms,quixtar,ilovemom,toyot,ballss,ilovekim,serdar,james23,avenger1,serendip,malamute,nalgas,teflon,shagger,letmein6,vyjujnjxbt,assa1234,student1,dixiedog,gznybwf13,fuckass,aq1sw2de3,robroy,hosehead,sosa21,123345,ias100,teddy123,poppin,dgl70460,zanoza,farhan,quicksilver,1701d,tajmahal,depechemode,paulchen,angler,tommy2,recoil,megamanx,scarecro,nicole2,152535,rfvtgb,skunky,fatty1,saturno,wormwood,milwauke,udbwsk,sexlover,stefa,7bgiqk,gfnhbr,omar10,bratan,lbyfvj,slyfox,forest1,jambo,william3,tempus,solitari,lucydog,murzilka,qweasdzxc1,vehpbkrf,12312345,fixit,woobie,andre123,123456789x,lifter,zinaida,soccer17,andone,foxbat,torsten,apple12,teleport,123456i,leglover,bigcocks,vologda,dodger1,martyn,d6o8pm,naciona,eagleeye,maria6,rimshot,bentley1,octagon,barbos,masaki,gremio,siemen,s1107d,mujeres,bigtits1,cherr,saints1,mrpink,simran,ghzybr,ferrari2,secret12,tornado1,kocham,picolo,deneme,onelove1,rolan,fenster,1fuckyou,cabbie,pegaso,nastyboy,password5,aidana,mine2306,mike13,wetone,tigger69,ytreza,bondage1,myass,golova,tolik,happyboy,poilkj,nimda2k,rammer,rubies,hardcore1,jetset,hoops1,jlaudio,misskitt,1charlie,google12,theone1,phred,porsch,aalborg,luft4,charlie5,password7,gnosis,djgabbab,1daniel,vinny,borris,cumulus,member1,trogdor,darthmau,andrew2,ktjybl,relisys,kriste,rasta220,chgobndg,weener,qwerty66,fritter,followme,freeman1,ballen,blood1,peache,mariso,trevor1,biotch,gtfullam,chamonix,friendste,alligato,misha1,1soccer,18821221,venkat,superd,molotov,bongos,mpower,acun3t1x,dfcmrf,h4x3d,rfhfufylf,tigran,booyaa,plastic1,monstr,rfnhby,lookatme,anabolic,tiesto,simon123,soulman,canes1,skyking,tomcat1,madona,bassline,dasha123,tarheel1,dutch1,xsw23edc,qwerty123456789,imperator,slaveboy,bateau,paypal,house123,pentax,wolf666,drgonzo,perros,digger1,juninho,hellomoto,bladerun,zzzzzzz1,keebler,take8422,fffffff1,ginuwine,israe,caesar1,crack1,precious1,garand,magda1,zigazaga,321ewq,johnpaul,mama1234,iceman69,sanjeev,treeman,elric,rebell,1thunder,cochon,deamon,zoltan,straycat,uhbyuj,luvfur,mugsy,primer,wonder1,teetime,candycan,pfchfytw,fromage,gitler,salvatio,piggy1,23049307,zafira,chicky,sergeev,katze,bangers,andriy,jailbait,vaz2107,ghbhjlf,dbjktnnf,aqswde,zaratustra,asroma,1pepper,alyss,kkkkk1,ryan1,radish,cozumel,waterpol,pentium1,rosebowl,farmall,steinway,dbrekz,baranov,jkmuf,another1,chinacat,qqqqqqq1,hadrian,devilmaycry4,ratbag,teddy2,love21,pullings,packrat,robyn1,boobo,qw12er34,tribe1,rosey,celestia,nikkie,fortune12,olga123,danthema,gameon,vfrfhjys,dilshod,henry14,jenova,redblue,chimaera,pennywise,sokrates,danimal,qqaazz,fuaqz4,killer2,198200,tbone1,kolyan,wabbit,lewis1,maxtor,egoist,asdfas,spyglass,omegas,jack12,nikitka,esperanz,doozer,matematika,wwwww1,ssssss1,poiu0987,suchka,courtney1,gungho,alpha2,fktyjxrf,summer06,bud420,devildriver,heavyd,saracen,foucault,choclate,rjdfktyrj,goblue1,monaro,jmoney,dcpugh,efbcapa201,qqh92r,pepsicol,bbb747,ch5nmk,honeyb,beszoptad,tweeter,intheass,iseedeadpeople,123dan,89231243658s,farside1,findme,smiley1,55556666,sartre,ytcnjh,kacper,costarica,134679258,mikeys,nolimit9,vova123,withyou,5rxypn,love143,freebie,rescue1,203040,michael6,12monkey,redgreen,steff,itstime,naveen,good12345,acidrain,1dawg,miramar,playas,daddio,orion2,852741,studmuff,kobe24,senha123,stephe,mehmet,allalone,scarface1,helloworld,smith123,blueyes,vitali,memphis1,mybitch,colin1,159874,1dick,podaria,d6wnro,brahms,f3gh65,dfcbkmtd,xxxman,corran,ugejvp,qcfmtz,marusia,totem,arachnid,matrix2,antonell,fgntrf,zemfira,christos,surfing1,naruto123,plato1,56qhxs,madzia,vanille,043aaa,asq321,mutton,ohiostate,golde,cdznjckfd,rhfcysq,green5,elephan,superdog,jacqueli,bollock,lolitas,nick12,1orange,maplelea,july23,argento,waldorf,wolfer,pokemon12,zxcvbnmm,flicka,drexel,outlawz,harrie,atrain,juice2,falcons1,charlie6,19391945,tower1,dragon21,hotdamn,dirtyboy,love4ever,1ginger,thunder2,virgo1,alien1,bubblegu,4wwvte,123456789qqq,realtime,studio54,passss,vasilek,awsome,giorgia,bigbass,2002tii,sunghile,mosdef,simbas,count0,uwrl7c,summer05,lhepmz,ranger21,sugarbea,principe,5550123,tatanka,9638v,cheerios,majere,nomercy,jamesbond007,bh90210,7550055,jobber,karaganda,pongo,trickle,defamer,6chid8,1q2a3z,tuscan,nick123,.adgjm,loveyo,hobbes1,note1234,shootme,171819,loveporn,9788960,monty123,fabrice,macduff,monkey13,shadowfa,tweeker,hanna1,madball,telnet,loveu2,qwedcxzas,thatsit,vfhcbr,ptfe3xxp,gblfhfcs,ddddddd1,hakkinen,liverune,deathsta,misty123,suka123,recon1,inferno1,232629,polecat,sanibel,grouch,hitech,hamradio,rkfdbfnehf,vandam,nadin,fastlane,shlong,iddqdidkfa,ledzeppelin,sexyfeet,098123,stacey1,negras,roofing,lucifer1,ikarus,tgbyhn,melnik,barbaria,montego,twisted1,bigal1,jiggle,darkwolf,acerview,silvio,treetops,bishop1,iwanna,pornsite,happyme,gfccdjhl,114411,veritech,batterse,casey123,yhntgb,mailto,milli,guster,q12345678,coronet,sleuth,fuckmeha,armadill,kroshka,geordie,lastochka,pynchon,killall,tommy123,sasha1996,godslove,hikaru,clticic,cornbrea,vfkmdbyf,passmaster,123123123a,souris,nailer,diabolo,skipjack,martin12,hinata,mof6681,brookie,dogfight,johnso,karpov,326598,rfvbrflpt,travesti,caballer,galaxy1,wotan,antoha,art123,xakep1234,ricflair,pervert1,p00kie,ambulanc,santosh,berserker,larry33,bitch123,a987654321,dogstar,angel22,cjcbcrf,redhouse,toodles,gold123,hotspot,kennedy1,glock21,chosen1,schneide,mainman,taffy1,3ki42x,4zqauf,ranger2,4meonly,year2000,121212a,kfylsi,netzwerk,diese,picasso1,rerecz,225522,dastan,swimmer1,brooke1,blackbea,oneway,ruslana,dont4get,phidelt,chrisp,gjyxbr,xwing,kickme,shimmy,kimmy1,4815162342lost,qwerty5,fcporto,jazzbo,mierd,252627,basses,sr20det,00133,florin,howdy1,kryten,goshen,koufax,cichlid,imhotep,andyman,wrest666,saveme,dutchy,anonymou,semprini,siempre,mocha1,forest11,wildroid,aspen1,sesam,kfgekz,cbhbec,a55555,sigmanu,slash1,giggs11,vatech,marias,candy123,jericho1,kingme,123a123,drakula,cdjkjxm,mercur,oneman,hoseman,plumper,ilovehim,lancers,sergey1,takeshi,goodtogo,cranberr,ghjcnj123,harvick,qazxs,1972chev,horsesho,freedom3,letmein7,saitek,anguss,vfvfgfgfz,300000,elektro,toonporn,999111999q,mamuka,q9umoz,edelweis,subwoofer,bayside,disturbe,volition,lucky3,12345678z,3mpz4r,march1,atlantida,strekoza,seagrams,090909t,yy5rbfsc,jack1234,sammy12,sampras,mark12,eintrach,chaucer,lllll1,nochance,whitepower,197000,lbvekz,passer,torana,12345as,pallas,koolio,12qw34,nokia8800,findout,1thomas,mmmmm1,654987,mihaela,chinaman,superduper,donnas,ringo1,jeroen,gfdkjdf,professo,cdtnrf,tranmere,tanstaaf,himera,ukflbfnjh,667788,alex32,joschi,w123456,okidoki,flatline,papercli,super8,doris1,2good4u,4z34l0ts,pedigree,freeride,gsxr1100,wulfgar,benjie,ferdinan,king1,charlie7,djdxbr,fhntvbq,ripcurl,2wsx1qaz,kingsx,desade,sn00py,loveboat,rottie,evgesha,4money,dolittle,adgjmpt,buzzers,brett1,makita,123123qweqwe,rusalka,sluts1,123456e,jameson1,bigbaby,1z2z3z,ckjybr,love4u,fucker69,erhfbyf,jeanluc,farhad,fishfood,merkin,giant1,golf69,rfnfcnhjaf,camera1,stromb,smoothy,774411,nylon,juice1,rfn.irf,newyor,123456789t,marmot,star11,jennyff,jester1,hisashi,kumquat,alex777,helicopt,merkur,dehpye,cummin,zsmj2v,kristjan,april12,englan,honeypot,badgirls,uzumaki,keines,p12345,guita,quake1,duncan1,juicer,milkbone,hurtme,123456789b,qq123456789,schwein,p3wqaw,54132442,qwertyytrewq,andreeva,ruffryde,punkie,abfkrf,kristinka,anna1987,ooooo1,335533aa,umberto,amber123,456123789,456789123,beelch,manta,peeker,1112131415,3141592654,gipper,wrinkle5,katies,asd123456,james11,78n3s5af,michael0,daboss,jimmyb,hotdog1,david69,852123,blazed,sickan,eljefe,2n6wvq,gobills,rfhfcm,squeaker,cabowabo,luebri,karups,test01,melkor,angel777,smallvil,modano,olorin,4rkpkt,leslie1,koffie,shadows1,littleon,amiga1,topeka,summer20,asterix1,pitstop,aloysius,k12345,magazin,joker69,panocha,pass1word,1233214,ironpony,368ejhih,88keys,pizza123,sonali,57np39,quake2,1234567890qw,1020304,sword1,fynjif,abcde123,dfktyjr,rockys,grendel1,harley12,kokakola,super2,azathoth,lisa123,shelley1,girlss,ibragim,seven1,jeff24,1bigdick,dragan,autobot,t4nvp7,omega123,900000,hecnfv,889988,nitro1,doggie1,fatjoe,811pahc,tommyt,savage1,pallino,smitty1,jg3h4hfn,jamielee,1qazwsx,zx123456,machine1,asdfgh123,guinnes,789520,sharkman,jochen,legend1,sonic2,extreme1,dima12,photoman,123459876,nokian95,775533,vaz2109,april10,becks,repmvf,pooker,qwer12345,themaster,nabeel,monkey10,gogetit,hockey99,bbbbbbb1,zinedine,dolphin2,anelka,1superma,winter01,muggsy,horny2,669966,kuleshov,jesusis,calavera,bullet1,87t5hdf,sleepers,winkie,vespa,lightsab,carine,magister,1spider,shitbird,salavat,becca1,wc18c2,shirak,galactus,zaskar,barkley1,reshma,dogbreat,fullsail,asasa,boeder,12345ta,zxcvbnm12,lepton,elfquest,tony123,vkaxcs,savatage,sevilia1,badkitty,munkey,pebbles1,diciembr,qapmoc,gabriel2,1qa2ws3e,cbcmrb,welldone,nfyufh,kaizen,jack11,manisha,grommit,g12345,maverik,chessman,heythere,mixail,jjjjjjj1,sylvia1,fairmont,harve,skully,global1,youwish,pikachu1,badcat,zombie1,49527843,ultra1,redrider,offsprin,lovebird,153426,stymie,aq1sw2,sorrento,0000001,r3ady41t,webster1,95175,adam123,coonass,159487,slut1,gerasim,monkey99,slutwife,159963,1pass1page,hobiecat,bigtymer,all4you,maggie2,olamide,comcast1,infinit,bailee,vasileva,.ktxrf,asdfghjkl1,12345678912,setter,fuckyou7,nnagqx,lifesuck,draken,austi,feb2000,cable1,1234qwerasdf,hax0red,zxcv12,vlad7788,nosaj,lenovo,underpar,huskies1,lovegirl,feynman,suerte,babaloo,alskdjfhg,oldsmobi,bomber1,redrover,pupuce,methodman,phenom,cutegirl,countyli,gretsch,godisgood,bysunsu,hardhat,mironova,123qwe456rty,rusty123,salut,187211,555666777,11111z,mahesh,rjntyjxtr,br00klyn,dunce1,timebomb,bovine,makelove,littlee,shaven,rizwan,patrick7,42042042,bobbijo,rustem,buttmunc,dongle,tiger69,bluecat,blackhol,shirin,peaces,cherub,cubase,longwood,lotus7,gwju3g,bruin,pzaiu8,green11,uyxnyd,seventee,dragon5,tinkerbel,bluess,bomba,fedorova,joshua2,bodyshop,peluche,gbpacker,shelly1,d1i2m3a4,ghtpbltyn,talons,sergeevna,misato,chrisc,sexmeup,brend,olddog,davros,hazelnut,bridget1,hzze929b,readme,brethart,wild1,ghbdtnbr1,nortel,kinger,royal1,bucky1,allah1,drakkar,emyeuanh,gallaghe,hardtime,jocker,tanman,flavio,abcdef123,leviatha,squid1,skeet,sexse,123456x,mom4u4mm,lilred,djljktq,ocean11,cadaver,baxter1,808state,fighton,primavera,1andrew,moogle,limabean,goddess1,vitalya,blue56,258025,bullride,cicci,1234567d,connor1,gsxr11,oliveoil,leonard1,legsex,gavrik,rjnjgtc,mexicano,2bad4u,goodfellas,ornw6d,mancheste,hawkmoon,zlzfrh,schorsch,g9zns4,bashful,rossi46,stephie,rfhfntkm,sellout,123fuck,stewar1,solnze,00007,thor5200,compaq12,didit,bigdeal,hjlbyf,zebulon,wpf8eu,kamran,emanuele,197500,carvin,ozlq6qwm,3syqo15hil,pennys,epvjb6,asdfghjkl123,198000,nfbcbz,jazzer,asfnhg66,zoloft,albundy,aeiou,getlaid,planet1,gjkbyjxrf,alex2000,brianb,moveon,maggie11,eieio,vcradq,shaggy1,novartis,cocoloco,dunamis,554uzpad,sundrop,1qwertyu,alfie,feliks,briand,123www,red456,addams,fhntv1998,goodhead,theway,javaman,angel01,stratoca,lonsdale,15987532,bigpimpin,skater1,issue43,muffie,yasmina,slowride,crm114,sanity729,himmel,carolcox,bustanut,parabola,masterlo,computador,crackhea,dynastar,rockbott,doggysty,wantsome,bigten,gaelle,juicy1,alaska1,etower,sixnine,suntan,froggies,nokia7610,hunter11,njnets,alicante,buttons1,diosesamo,elizabeth1,chiron,trustnoo,amatuers,tinytim,mechta,sammy2,cthulu,trs8f7,poonam,m6cjy69u35,cookie12,blue25,jordans,santa1,kalinka,mikey123,lebedeva,12345689,kissss,queenbee,vjybnjh,ghostdog,cuckold,bearshare,rjcntyrj,alinochka,ghjcnjrdfibyj,aggie1,teens1,3qvqod,dauren,tonino,hpk2qc,iqzzt580,bears85,nascar88,theboy,njqcw4,masyanya,pn5jvw,intranet,lollone,shadow99,00096462,techie,cvtifhbrb,redeemed,gocanes,62717315,topman,intj3a,cobrajet,antivirus,whyme,berserke,ikilz083,airedale,brandon2,hopkig,johanna1,danil8098,gojira,arthu,vision1,pendragon,milen,chrissie,vampiro,mudder,chris22,blowme69,omega7,surfers,goterps,italy1,baseba11,diego1,gnatsum,birdies,semenov,joker123,zenit2011,wojtek,cab4ma99,watchmen,damia,forgotte,fdm7ed,strummer,freelanc,cingular,orange77,mcdonalds,vjhjpjdf,kariya,tombston,starlet,hawaii1,dantheman,megabyte,nbvjirf,anjing,ybrjkftdbx,hotmom,kazbek,pacific1,sashimi,asd12,coorslig,yvtte545,kitte,elysium,klimenko,cobblers,kamehameha,only4me,redriver,triforce,sidorov,vittoria,fredi,dank420,m1234567,fallout2,989244342a,crazy123,crapola,servus,volvos,1scooter,griffin1,autopass,ownzyou,deviant,george01,2kgwai,boeing74,simhrq,hermosa,hardcor,griffy,rolex1,hackme,cuddles1,master3,bujhtr,aaron123,popolo,blader,1sexyred,gerry1,cronos,ffvdj474,yeehaw,bob1234,carlos2,mike77,buckwheat,ramesh,acls2h,monster2,montess,11qq22ww,lazer,zx123456789,chimpy,masterch,sargon,lochness,archana,1234qwert,hbxfhl,sarahb,altoid,zxcvbn12,dakot,caterham,dolomite,chazz,r29hqq,longone,pericles,grand1,sherbert,eagle3,pudge,irontree,synapse,boome,nogood,summer2,pooki,gangsta1,mahalkit,elenka,lbhtrnjh,dukedog,19922991,hopkins1,evgenia,domino1,x123456,manny1,tabbycat,drake1,jerico,drahcir,kelly2,708090a,facesit,11c645df,mac123,boodog,kalani,hiphop1,critters,hellothere,tbirds,valerka,551scasi,love777,paloalto,mrbrown,duke3d,killa1,arcturus,spider12,dizzy1,smudger,goddog,75395,spammy,1357997531,78678,datalife,zxcvbn123,1122112211,london22,23dp4x,rxmtkp,biggirls,ownsu,lzbs2twz,sharps,geryfe,237081a,golakers,nemesi,sasha1995,pretty1,mittens1,d1lakiss,speedrac,gfhjkmm,sabbat,hellrais,159753258,qwertyuiop123,playgirl,crippler,salma,strat1,celest,hello5,omega5,cheese12,ndeyl5,edward12,soccer3,cheerio,davido,vfrcbr,gjhjctyjr,boscoe,inessa,shithole,ibill,qwepoi,201jedlz,asdlkj,davidk,spawn2,ariel1,michael4,jamie123,romantik,micro1,pittsbur,canibus,katja,muhtar,thomas123,studboy,masahiro,rebrov,patrick8,hotboys,sarge1,1hammer,nnnnn1,eistee,datalore,jackdani,sasha2010,mwq6qlzo,cmfnpu,klausi,cnhjbntkm,andrzej,ilovejen,lindaa,hunter123,vvvvv1,novembe,hamster1,x35v8l,lacey1,1silver,iluvporn,valter,herson,alexsandr,cojones,backhoe,womens,777angel,beatit,klingon1,ta8g4w,luisito,benedikt,maxwel,inspecto,zaq12ws,wladimir,bobbyd,peterj,asdfg12,hellspawn,bitch69,nick1234,golfer23,sony123,jello1,killie,chubby1,kodaira52,yanochka,buckfast,morris1,roaddogg,snakeeye,sex1234,mike22,mmouse,fucker11,dantist,brittan,vfrfhjdf,doc123,plokijuh,emerald1,batman01,serafim,elementa,soccer9,footlong,cthuttdbx,hapkido,eagle123,getsmart,getiton,batman2,masons,mastiff,098890,cfvfhf,james7,azalea,sherif,saun24865709,123red,cnhtrjpf,martina1,pupper,michael5,alan12,shakir,devin1,ha8fyp,palom,mamulya,trippy,deerhunter,happyone,monkey77,3mta3,123456789f,crownvic,teodor,natusik,0137485,vovchik,strutter,triumph1,cvetok,moremone,sonnen,screwbal,akira1,sexnow,pernille,independ,poopies,samapi,kbcbxrf,master22,swetlana,urchin,viper2,magica,slurpee,postit,gilgames,kissarmy,clubpenguin,limpbizk,timber1,celin,lilkim,fuckhard,lonely1,mom123,goodwood,extasy,sdsadee23,foxglove,malibog,clark1,casey2,shell1,odense,balefire,dcunited,cubbie,pierr,solei,161718,bowling1,areyukesc,batboy,r123456,1pionee,marmelad,maynard1,cn42qj,cfvehfq,heathrow,qazxcvbn,connecti,secret123,newfie,xzsawq21,tubitzen,nikusha,enigma1,yfcnz123,1austin,michaelc,splunge,wanger,phantom2,jason2,pain4me,primetime21,babes1,liberte,sugarray,undergro,zonker,labatts,djhjyf,watch1,eagle5,madison2,cntgfirf,sasha2,masterca,fiction7,slick50,bruins1,sagitari,12481632,peniss,insuranc,2b8riedt,12346789,mrclean,ssptx452,tissot,q1w2e3r4t5y6u7,avatar1,comet1,spacer,vbrjkf,pass11,wanker1,14vbqk9p,noshit,money4me,sayana,fish1234,seaways,pipper,romeo123,karens,wardog,ab123456,gorilla1,andrey123,lifesucks,jamesr,4wcqjn,bearman,glock22,matt11,dflbvrf,barbi,maine1,dima1997,sunnyboy,6bjvpe,bangkok1,666666q,rafiki,letmein0,0raziel0,dalla,london99,wildthin,patrycja,skydog,qcactw,tmjxn151,yqlgr667,jimmyd,stripclub,deadwood,863abgsg,horses1,qn632o,scatman,sonia1,subrosa,woland,kolya,charlie4,moleman,j12345,summer11,angel11,blasen,sandal,mynewpas,retlaw,cambria,mustang4,nohack04,kimber45,fatdog,maiden1,bigload,necron,dupont24,ghost123,turbo2,.ktymrf,radagast,balzac,vsevolod,pankaj,argentum,2bigtits,mamabear,bumblebee,mercury7,maddie1,chomper,jq24nc,snooky,pussylic,1lovers,taltos,warchild,diablo66,jojo12,sumerki,aventura,gagger,annelies,drumset,cumshots,azimut,123580,clambake,bmw540,birthday54,psswrd,paganini,wildwest,filibert,teaseme,1test,scampi,thunder5,antosha,purple12,supersex,hhhhhh1,brujah,111222333a,13579a,bvgthfnjh,4506802a,killians,choco,qqqwwweee,raygun,1grand,koetsu13,sharp1,mimi92139,fastfood,idontcare,bluered,chochoz,4z3al0ts,target1,sheffiel,labrat,stalingrad,147123,cubfan,corvett1,holden1,snapper1,4071505,amadeo,pollo,desperados,lovestory,marcopolo,mumbles,familyguy,kimchee,marcio,support1,tekila,shygirl1,trekkie,submissi,ilaria,salam,loveu,wildstar,master69,sales1,netware,homer2,arseniy,gerrity1,raspberr,atreyu,stick1,aldric,tennis12,matahari,alohomora,dicanio,michae1,michaeld,666111,luvbug,boyscout,esmerald,mjordan,admiral1,steamboa,616913,ybhdfyf,557711,555999,sunray,apokalipsis,theroc,bmw330,buzzy,chicos,lenusik,shadowma,eagles05,444222,peartree,qqq123,sandmann,spring1,430799,phatass,andi03,binky1,arsch,bamba,kenny123,fabolous,loser123,poop12,maman,phobos,tecate,myxworld4,metros,cocorico,nokia6120,johnny69,hater,spanked,313233,markos,love2011,mozart1,viktoriy,reccos,331234,hornyone,vitesse,1um83z,55555q,proline,v12345,skaven,alizee,bimini,fenerbahce,543216,zaqqaz,poi123,stabilo,brownie1,1qwerty1,dinesh,baggins1,1234567t,davidkin,friend1,lietuva,octopuss,spooks,12345qq,myshit,buttface,paradoxx,pop123,golfin,sweet69,rfghbp,sambuca,kayak1,bogus1,girlz,dallas12,millers,123456zx,operatio,pravda,eternal1,chase123,moroni,proust,blueduck,harris1,redbarch,996699,1010101,mouche,millenni,1123456,score1,1234565,1234576,eae21157,dave12,pussyy,gfif1991,1598741,hoppy,darrian,snoogins,fartface,ichbins,vfkbyrf,rusrap,2741001,fyfrjylf,aprils,favre,thisis,bannana,serval,wiggum,satsuma,matt123,ivan123,gulmira,123zxc123,oscar2,acces,annie2,dragon0,emiliano,allthat,pajaro,amandine,rawiswar,sinead,tassie,karma1,piggys,nokias,orions,origami,type40,mondo,ferrets,monker,biteme2,gauntlet,arkham,ascona,ingram01,klem1,quicksil,bingo123,blue66,plazma,onfire,shortie,spjfet,123963,thered,fire777,lobito,vball,1chicken,moosehea,elefante,babe23,jesus12,parallax,elfstone,number5,shrooms,freya,hacker1,roxette,snoops,number7,fellini,dtlmvf,chigger,mission1,mitsubis,kannan,whitedog,james01,ghjgecr,rfnfgekmnf,everythi,getnaked,prettybo,sylvan,chiller,carrera4,cowbo,biochem,azbuka,qwertyuiop1,midnight1,informat,audio1,alfred1,0range,sucker1,scott2,russland,1eagle,torben,djkrjlfd,rocky6,maddy1,bonobo,portos,chrissi,xjznq5,dexte,vdlxuc,teardrop,pktmxr,iamtheone,danijela,eyphed,suzuki1,etvww4,redtail,ranger11,mowerman,asshole2,coolkid,adriana1,bootcamp,longcut,evets,npyxr5,bighurt,bassman1,stryder,giblet,nastja,blackadd,topflite,wizar,cumnow,technolo,bassboat,bullitt,kugm7b,maksimus,wankers,mine12,sunfish,pimpin1,shearer9,user1,vjzgjxnf,tycobb,80070633pc,stanly,vitaly,shirley1,cinzia,carolyn1,angeliqu,teamo,qdarcv,aa123321,ragdoll,bonit,ladyluck,wiggly,vitara,jetbalance,12345600,ozzman,dima12345,mybuddy,shilo,satan66,erebus,warrio,090808qwe,stupi,bigdan,paul1234,chiapet,brooks1,philly1,dually,gowest,farmer1,1qa2ws3ed4rf,alberto1,beachboy,barne,aa12345,aliyah,radman,benson1,dfkthbq,highball,bonou2,i81u812,workit,darter,redhook,csfbr5yy,buttlove,episode1,ewyuza,porthos,lalal,abcd12,papero,toosexy,keeper1,silver7,jujitsu,corset,pilot123,simonsay,pinggolf,katerinka,kender,drunk1,fylhjvtlf,rashmi,nighthawk,maggy,juggernaut,larryb,cabibble,fyabcf,247365,gangstar,jaybee,verycool,123456789qw,forbidde,prufrock,12345zxc,malaika,blackbur,docker,filipe,koshechka,gemma1,djamaal,dfcbkmtdf,gangst,9988aa,ducks1,pthrfkj,puertorico,muppets,griffins,whippet,sauber,timofey,larinso,123456789zxc,quicken,qsefth,liteon,headcase,bigdadd,zxc321,maniak,jamesc,bassmast,bigdogs,1girls,123xxx,trajan,lerochka,noggin,mtndew,04975756,domin,wer123,fumanchu,lambada,thankgod,june22,kayaking,patchy,summer10,timepass,poiu1234,kondor,kakka,lament,zidane10,686xqxfg,l8v53x,caveman1,nfvthkfy,holymoly,pepita,alex1996,mifune,fighter1,asslicker,jack22,abc123abc,zaxxon,midnigh,winni,psalm23,punky,monkey22,password13,mymusic,justyna,annushka,lucky5,briann,495rus19,withlove,almaz,supergir,miata,bingbong,bradpitt,kamasutr,yfgjktjy,vanman,pegleg,amsterdam1,123a321,letmein9,shivan,korona,bmw520,annette1,scotsman,gandal,welcome12,sc00by,qpwoei,fred69,m1sf1t,hamburg1,1access,dfkmrbhbz,excalibe,boobies1,fuckhole,karamel,starfuck,star99,breakfas,georgiy,ywvxpz,smasher,fatcat1,allanon,12345n,coondog,whacko,avalon1,scythe,saab93,timon,khorne,atlast,nemisis,brady12,blenheim,52678677,mick7278,9skw5g,fleetwoo,ruger1,kissass,pussy7,scruff,12345l,bigfun,vpmfsz,yxkck878,evgeny,55667788,lickher,foothill,alesis,poppies,77777778,californi,mannie,bartjek,qhxbij,thehulk,xirt2k,angelo4ek,rfkmrekznjh,tinhorse,1david,sparky12,night1,luojianhua,bobble,nederland,rosemari,travi,minou,ciscokid,beehive,565hlgqo,alpine1,samsung123,trainman,xpress,logistic,vw198m2n,hanter,zaqwsx123,qwasz,mariachi,paska,kmg365,kaulitz,sasha12,north1,polarbear,mighty1,makeksa11,123456781,one4all,gladston,notoriou,polniypizdec110211,gosia,grandad,xholes,timofei,invalidp,speaker1,zaharov,maggiema,loislane,gonoles,br5499,discgolf,kaskad,snooper,newman1,belial,demigod,vicky1,pridurok,alex1990,tardis1,cruzer,hornie,sacramen,babycat,burunduk,mark69,oakland1,me1234,gmctruck,extacy,sexdog,putang,poppen,billyd,1qaz2w,loveable,gimlet,azwebitalia,ragtop,198500,qweas,mirela,rock123,11bravo,sprewell,tigrenok,jaredleto,vfhbif,blue2,rimjob,catwalk,sigsauer,loqse,doromich,jack01,lasombra,jonny5,newpassword,profesor,garcia1,123as123,croucher,demeter,4_life,rfhfvtkm,superman2,rogues,assword1,russia1,jeff1,mydream,z123456789,rascal1,darre,kimberl,pickle1,ztmfcq,ponchik,lovesporn,hikari,gsgba368,pornoman,chbjun,choppy,diggity,nightwolf,viktori,camar,vfhecmrf,alisa1,minstrel,wishmaster,mulder1,aleks,gogirl,gracelan,8womys,highwind,solstice,dbrnjhjdyf,nightman,pimmel,beertje,ms6nud,wwfwcw,fx3tuo,poopface,asshat,dirtyd,jiminy,luv2fuck,ptybnxtvgbjy,dragnet,pornogra,10inch,scarlet1,guido1,raintree,v123456,1aaaaaaa,maxim1935,hotwater,gadzooks,playaz,harri,brando1,defcon1,ivanna,123654a,arsenal2,candela,nt5d27,jaime1,duke1,burton1,allstar1,dragos,newpoint,albacore,1236987z,verygoodbot,1wildcat,fishy1,ptktysq,chris11,puschel,itdxtyrj,7kbe9d,serpico,jazzie,1zzzzz,kindbuds,wenef45313,1compute,tatung,sardor,gfyfcjybr,test99,toucan,meteora,lysander,asscrack,jowgnx,hevnm4,suckthis,masha123,karinka,marit,oqglh565,dragon00,vvvbbb,cheburashka,vfrfrf,downlow,unforgiven,p3e85tr,kim123,sillyboy,gold1,golfvr6,quicksan,irochka,froglegs,shortsto,caleb1,tishka,bigtitts,smurfy,bosto,dropzone,nocode,jazzbass,digdug,green7,saltlake,therat,dmitriev,lunita,deaddog,summer0,1212qq,bobbyg,mty3rh,isaac1,gusher,helloman,sugarbear,corvair,extrem,teatime,tujazopi,titanik,efyreg,jo9k2jw2,counchac,tivoli,utjvtnhbz,bebit,jacob6,clayton1,incubus1,flash123,squirter,dima2010,cock1,rawks,komatsu,forty2,98741236,cajun1,madelein,mudhoney,magomed,q111111,qaswed,consense,12345b,bakayaro,silencer,zoinks,bigdic,werwolf,pinkpuss,96321478,alfie1,ali123,sarit,minette,musics,chato,iaapptfcor,cobaka,strumpf,datnigga,sonic123,yfnecbr,vjzctvmz,pasta1,tribbles,crasher,htlbcrf,1tiger,shock123,bearshar,syphon,a654321,cubbies1,jlhanes,eyespy,fucktheworld,carrie1,bmw325is,suzuk,mander,dorina,mithril,hondo1,vfhnbyb,sachem,newton1,12345x,7777755102q,230857z,xxxsex,scubapro,hayastan,spankit,delasoul,searock6,fallout3,nilrem,24681357,pashka,voluntee,pharoh,willo,india1,badboy69,roflmao,gunslinger,lovergir,mama12,melange,640xwfkv,chaton,darkknig,bigman1,aabbccdd,harleyd,birdhouse,giggsy,hiawatha,tiberium,joker7,hello1234,sloopy,tm371855,greendog,solar1,bignose,djohn11,espanol,oswego,iridium,kavitha,pavell,mirjam,cyjdsvujljv,alpha5,deluge,hamme,luntik,turismo,stasya,kjkbnf,caeser,schnecke,tweety1,tralfaz,lambrett,prodigy1,trstno1,pimpshit,werty1,karman,bigboob,pastel,blackmen,matthew8,moomin,q1w2e,gilly,primaver,jimmyg,house2,elviss,15975321,1jessica,monaliza,salt55,vfylfhbyrf,harley11,tickleme,murder1,nurgle,kickass1,theresa1,fordtruck,pargolf,managua,inkognito,sherry1,gotit,friedric,metro2033,slk230,freeport,cigarett,492529,vfhctkm,thebeach,twocats,bakugan,yzerman1,charlieb,motoko,skiman,1234567w,pussy3,love77,asenna,buffie,260zntpc,kinkos,access20,mallard1,fuckyou69,monami,rrrrr1,bigdog69,mikola,1boomer,godzila,ginger2,dima2000,skorpion39,dima1234,hawkdog79,warrior2,ltleirf,supra1,jerusale,monkey01,333z333,666888,kelsey1,w8gkz2x1,fdfnfh,msnxbi,qwe123rty,mach1,monkey3,123456789qq,c123456,nezabudka,barclays,nisse,dasha1,12345678987654321,dima1993,oldspice,frank2,rabbitt,prettyboy,ov3ajy,iamthema,kawasak,banjo1,gtivr6,collants,gondor,hibees,cowboys2,codfish,buster2,purzel,rubyred,kayaker,bikerboy,qguvyt,masher,sseexx,kenshiro,moonglow,semenova,rosari,eduard1,deltaforce,grouper,bongo1,tempgod,1taylor,goldsink,qazxsw1,1jesus,m69fg2w,maximili,marysia,husker1,kokanee,sideout,googl,south1,plumber1,trillian,00001,1357900,farkle,1xxxxx,pascha,emanuela,bagheera,hound1,mylov,newjersey,swampfox,sakic19,torey,geforce,wu4etd,conrail,pigman,martin2,ber02,nascar2,angel69,barty,kitsune,cornet,yes90125,goomba,daking,anthea,sivart,weather1,ndaswf,scoubidou,masterchief,rectum,3364068,oranges1,copter,1samanth,eddies,mimoza,ahfywbz,celtic88,86mets,applemac,amanda11,taliesin,1angel,imhere,london11,bandit12,killer666,beer1,06225930,psylocke,james69,schumach,24pnz6kc,endymion,wookie1,poiu123,birdland,smoochie,lastone,rclaki,olive1,pirat,thunder7,chris69,rocko,151617,djg4bb4b,lapper,ajcuivd289,colole57,shadow7,dallas21,ajtdmw,executiv,dickies,omegaman,jason12,newhaven,aaaaaas,pmdmscts,s456123789,beatri,applesauce,levelone,strapon,benladen,creaven,ttttt1,saab95,f123456,pitbul,54321a,sex12345,robert3,atilla,mevefalkcakk,1johnny,veedub,lilleke,nitsuj,5t6y7u8i,teddys,bluefox,nascar20,vwjetta,buffy123,playstation3,loverr,qweasd12,lover2,telekom,benjamin1,alemania,neutrino,rockz,valjean,testicle,trinity3,realty,firestarter,794613852,ardvark,guadalup,philmont,arnold1,holas,zw6syj,birthday299,dover1,sexxy1,gojets,741236985,cance,blue77,xzibit,qwerty88,komarova,qweszxc,footer,rainger,silverst,ghjcnb,catmando,tatooine,31217221027711,amalgam,69dude,qwerty321,roscoe1,74185,cubby,alfa147,perry1,darock,katmandu,darknight,knicks1,freestuff,45454,kidman,4tlved,axlrose,cutie1,quantum1,joseph10,ichigo,pentium3,rfhectkm,rowdy1,woodsink,justforfun,sveta123,pornografia,mrbean,bigpig,tujheirf,delta9,portsmou,hotbod,kartal,10111213,fkbyf001,pavel1,pistons1,necromancer,verga,c7lrwu,doober,thegame1,hatesyou,sexisfun,1melissa,tuczno18,bowhunte,gobama,scorch,campeon,bruce2,fudge1,herpderp,bacon1,redsky,blackeye,19966991,19992000,ripken8,masturba,34524815,primax,paulina1,vp6y38,427cobra,4dwvjj,dracon,fkg7h4f3v6,longview,arakis,panama1,honda2,lkjhgfdsaz,razors,steels,fqkw5m,dionysus,mariajos,soroka,enriqu,nissa,barolo,king1234,hshfd4n279,holland1,flyer1,tbones,343104ky,modems,tk421,ybrbnrf,pikapp,sureshot,wooddoor,florida2,mrbungle,vecmrf,catsdogs,axolotl,nowayout,francoi,chris21,toenail,hartland,asdjkl,nikkii,onlyyou,buckskin,fnord,flutie,holen1,rincewind,lefty1,ducky1,199000,fvthbrf,redskin1,ryno23,lostlove,19mtpgam19,abercrom,benhur,jordan11,roflcopter,ranma,phillesh,avondale,igromania,p4ssword,jenny123,tttttt1,spycams,cardigan,2112yyz,sleepy1,paris123,mopars,lakers34,hustler1,james99,matrix3,popimp,12pack,eggbert,medvedev,testit,performa,logitec,marija,sexybeast,supermanboy,iwantit,rjktcj,jeffer,svarog,halo123,whdbtp,nokia3230,heyjoe,marilyn1,speeder,ibxnsm,prostock,bennyboy,charmin,codydog,parol999,ford9402,jimmer,crayola,159357258,alex77,joey1,cayuga,phish420,poligon,specops,tarasova,caramelo,draconis,dimon,cyzkhw,june29,getbent,1guitar,jimjam,dictiona,shammy,flotsam,0okm9ijn,crapper,technic,fwsadn,rhfdxtyrj,zaq11qaz,anfield1,159753q,curious1,hip-hop,1iiiii,gfhjkm2,cocteau,liveevil,friskie,crackhead,b1afra,elektrik,lancer1,b0ll0cks,jasond,z1234567,tempest1,alakazam,asdfasd,duffy1,oneday,dinkle,qazedctgb,kasimir,happy7,salama,hondaciv,nadezda,andretti,cannondale,sparticu,znbvjd,blueice,money01,finster,eldar,moosie,pappa,delta123,neruda,bmw330ci,jeanpaul,malibu1,alevtina,sobeit,travolta,fullmetal,enamorad,mausi,boston12,greggy,smurf1,ratrace,ichiban,ilovepus,davidg,wolf69,villa1,cocopuff,football12,starfury,zxc12345,forfree,fairfiel,dreams1,tayson,mike2,dogday,hej123,oldtimer,sanpedro,clicker,mollycat,roadstar,golfe,lvbnhbq1,topdevice,a1b2c,sevastopol,calli,milosc,fire911,pink123,team3x,nolimit5,snickers1,annies,09877890,jewel1,steve69,justin11,autechre,killerbe,browncow,slava1,christer,fantomen,redcloud,elenberg,beautiful1,passw0rd1,nazira,advantag,cockring,chaka,rjpzdrf,99941,az123456,biohazar,energie,bubble1,bmw323,tellme,printer1,glavine,1starwar,coolbeans,april17,carly1,quagmire,admin2,djkujuhfl,pontoon,texmex,carlos12,thermo,vaz2106,nougat,bob666,1hockey,1john,cricke,qwerty10,twinz,totalwar,underwoo,tijger,lildevil,123q321,germania,freddd,1scott,beefy,5t4r3e2w1q,fishbait,nobby,hogger,dnstuff,jimmyc,redknapp,flame1,tinfloor,balla,nfnfhby,yukon1,vixens,batata,danny123,1zxcvbnm,gaetan,homewood,greats,tester1,green99,1fucker,sc0tland,starss,glori,arnhem,goatman,1234asd,supertra,bill123,elguapo,sexylegs,jackryan,usmc69,innow,roaddog,alukard,winter11,crawler,gogiants,rvd420,alessandr,homegrow,gobbler,esteba,valeriy,happy12,1joshua,hawking,sicnarf,waynes,iamhappy,bayadera,august2,sashas,gotti,dragonfire,pencil1,halogen,borisov,bassingw,15975346,zachar,sweetp,soccer99,sky123,flipyou,spots3,xakepy,cyclops1,dragon77,rattolo58,motorhea,piligrim,helloween,dmb2010,supermen,shad0w,eatcum,sandokan,pinga,ufkfrnbrf,roksana,amista,pusser,sony1234,azerty1,1qasw2,ghbdt,q1w2e3r4t5y6u7i8,ktutylf,brehznev,zaebali,shitass,creosote,gjrtvjy,14938685,naughtyboy,pedro123,21crack,maurice1,joesakic,nicolas1,matthew9,lbyfhf,elocin,hfcgbplzq,pepper123,tiktak,mycroft,ryan11,firefly1,arriva,cyecvevhbr,loreal,peedee,jessica8,lisa01,anamari,pionex,ipanema,airbag,frfltvbz,123456789aa,epwr49,casper12,sweethear,sanandreas,wuschel,cocodog,france1,119911,redroses,erevan,xtvgbjy,bigfella,geneve,volvo850,evermore,amy123,moxie,celebs,geeman,underwor,haslo1,joy123,hallow,chelsea0,12435687,abarth,12332145,tazman1,roshan,yummie,genius1,chrisd,ilovelife,seventy7,qaz1wsx2,rocket88,gaurav,bobbyboy,tauchen,roberts1,locksmit,masterof,www111,d9ungl,volvos40,asdasd1,golfers,jillian1,7xm5rq,arwpls4u,gbhcf2,elloco,football2,muerte,bob101,sabbath1,strider1,killer66,notyou,lawnboy,de7mdf,johnnyb,voodoo2,sashaa,homedepo,bravos,nihao123,braindea,weedhead,rajeev,artem1,camille1,rockss,bobbyb,aniston,frnhbcf,oakridge,biscayne,cxfcnm,dressage,jesus3,kellyann,king69,juillet,holliste,h00ters,ripoff,123645,1999ar,eric12,123777,tommi,dick12,bilder,chris99,rulezz,getpaid,chicubs,ender1,byajhvfnbrf,milkshak,sk8board,freakshow,antonella,monolit,shelb,hannah01,masters1,pitbull1,1matthew,luvpussy,agbdlcid,panther2,alphas,euskadi,8318131,ronnie1,7558795,sweetgirl,cookie59,sequoia,5552555,ktyxbr,4500455,money7,severus,shinobu,dbityrf,phisig,rogue2,fractal,redfred,sebastian1,nelli,b00mer,cyberman,zqjphsyf6ctifgu,oldsmobile,redeemer,pimpi,lovehurts,1slayer,black13,rtynfdh,airmax,g00gle,1panther,artemon,nopasswo,fuck1234,luke1,trinit,666000,ziadma,oscardog,davex,hazel1,isgood,demond,james5,construc,555551,january2,m1911a1,flameboy,merda,nathan12,nicklaus,dukester,hello99,scorpio7,leviathan,dfcbktr,pourquoi,vfrcbv123,shlomo,rfcgth,rocky3,ignatz,ajhneyf,roger123,squeek,4815162342a,biskit,mossimo,soccer21,gridlock,lunker,popstar,ghhh47hj764,chutney,nitehawk,vortec,gamma1,codeman,dragula,kappasig,rainbow2,milehigh,blueballs,ou8124me,rulesyou,collingw,mystere,aster,astrovan,firetruck,fische,crawfish,hornydog,morebeer,tigerpaw,radost,144000,1chance,1234567890qwe,gracie1,myopia,oxnard,seminoles,evgeni,edvard,partytim,domani,tuffy1,jaimatadi,blackmag,kzueirf,peternor,mathew1,maggie12,henrys,k1234567,fasted,pozitiv,cfdtkbq,jessica7,goleafs,bandito,girl78,sharingan,skyhigh,bigrob,zorros,poopers,oldschoo,pentium2,gripper,norcal,kimba,artiller,moneymak,00197400,272829,shadow1212,thebull,handbags,all4u2c,bigman2,civics,godisgoo,section8,bandaid,suzanne1,zorba,159123,racecars,i62gbq,rambo123,ironroad,johnson2,knobby,twinboys,sausage1,kelly69,enter2,rhjirf,yessss,james12,anguilla,boutit,iggypop,vovochka,06060,budwiser,romuald,meditate,good1,sandrin,herkules,lakers8,honeybea,11111111a,miche,rangers9,lobster1,seiko,belova,midcon,mackdadd,bigdaddy1,daddie,sepultur,freddy12,damon1,stormy1,hockey2,bailey12,hedimaptfcor,dcowboys,sadiedog,thuggin,horny123,josie1,nikki2,beaver69,peewee1,mateus,viktorija,barrys,cubswin1,matt1234,timoxa,rileydog,sicilia,luckycat,candybar,julian1,abc456,pussylip,phase1,acadia,catty,246800,evertonf,bojangle,qzwxec,nikolaj,fabrizi,kagome,noncapa0,marle,popol,hahaha1,cossie,carla10,diggers,spankey,sangeeta,cucciolo,breezer,starwar1,cornholio,rastafari,spring99,yyyyyyy1,webstar,72d5tn,sasha1234,inhouse,gobuffs,civic1,redstone,234523,minnie1,rivaldo,angel5,sti2000,xenocide,11qq11,1phoenix,herman1,holly123,tallguy,sharks1,madri,superbad,ronin,jalal123,hardbody,1234567r,assman1,vivahate,buddylee,38972091,bonds25,40028922,qrhmis,wp2005,ceejay,pepper01,51842543,redrum1,renton,varadero,tvxtjk7r,vetteman,djhvbrc,curly1,fruitcak,jessicas,maduro,popmart,acuari,dirkpitt,buick1,bergerac,golfcart,pdtpljxrf,hooch1,dudelove,d9ebk7,123452000,afdjhbn,greener,123455432,parachut,mookie12,123456780,jeepcj5,potatoe,sanya,qwerty2010,waqw3p,gotika,freaky1,chihuahu,buccanee,ecstacy,crazyboy,slickric,blue88,fktdnbyf,2004rj,delta4,333222111,calient,ptbdhw,1bailey,blitz1,sheila1,master23,hoagie,pyf8ah,orbita,daveyboy,prono1,delta2,heman,1horny,tyrik123,ostrov,md2020,herve,rockfish,el546218,rfhbyjxrf,chessmaster,redmoon,lenny1,215487,tomat,guppy,amekpass,amoeba,my3girls,nottingh,kavita,natalia1,puccini,fabiana,8letters,romeos,netgear,casper2,taters,gowings,iforgot1,pokesmot,pollit,lawrun,petey1,rosebuds,007jr,gthtcnhjqrf,k9dls02a,neener,azertyu,duke11,manyak,tiger01,petros,supermar,mangas,twisty,spotter,takagi,dlanod,qcmfd454,tusymo,zz123456,chach,navyblue,gilbert1,2kash6zq,avemaria,1hxboqg2s,viviane,lhbjkjubz2957704,nowwowtg,1a2b3c4,m0rn3,kqigb7,superpuper,juehtw,gethigh,theclown,makeme,pradeep,sergik,deion21,nurik,devo2706,nbvibt,roman222,kalima,nevaeh,martin7,anathema,florian1,tamwsn3sja,dinmamma,133159,123654q,slicks,pnp0c08,yojimbo,skipp,kiran,pussyfuck,teengirl,apples12,myballs,angeli,1234a,125678,opelastra,blind1,armagedd,fish123,pitufo,chelseaf,thedevil,nugget1,cunt69,beetle1,carter15,apolon,collant,password00,fishboy,djkrjdf,deftone,celti,three11,cyrus1,lefthand,skoal1,ferndale,aries1,fred01,roberta1,chucks,cornbread,lloyd1,icecrea,cisco123,newjerse,vfhrbpf,passio,volcom1,rikimaru,yeah11,djembe,facile,a1l2e3x4,batman7,nurbol,lorenzo1,monica69,blowjob1,998899,spank1,233391,n123456,1bear,bellsout,999998,celtic67,sabre1,putas,y9enkj,alfabeta,heatwave,honey123,hard4u,insane1,xthysq,magnum1,lightsaber,123qweqwe,fisher1,pixie1,precios,benfic,thegirls,bootsman,4321rewq,nabokov,hightime,djghjc,1chelsea,junglist,august16,t3fkvkmj,1232123,lsdlsd12,chuckie1,pescado,granit,toogood,cathouse,natedawg,bmw530,123kid,hajime,198400,engine1,wessonnn,kingdom1,novembre,1rocks,kingfisher,qwerty89,jordan22,zasranec,megat,sucess,installutil,fetish01,yanshi1982,1313666,1314520,clemence,wargod,time1,newzealand,snaker,13324124,cfrehf,hepcat,mazahaka,bigjay,denisov,eastwest,1yellow,mistydog,cheetos,1596357,ginger11,mavrik,bubby1,bhbyf,pyramide,giusepp,luthien,honda250,andrewjackie,kentavr,lampoon,zaq123wsx,sonicx,davidh,1ccccc,gorodok,windsong,programm,blunt420,vlad1995,zxcvfdsa,tarasov,mrskin,sachas,mercedes1,koteczek,rawdog,honeybear,stuart1,kaktys,richard7,55555n,azalia,hockey10,scouter,francy,1xxxxxx,julie456,tequilla,penis123,schmoe,tigerwoods,1ferrari,popov,snowdrop,matthieu,smolensk,cornflak,jordan01,love2000,23wesdxc,kswiss,anna2000,geniusnet,baby2000,33ds5x,waverly,onlyone4,networkingpe,raven123,blesse,gocards,wow123,pjflkork,juicey,poorboy,freeee,billybo,shaheen,zxcvbnm.,berlit,truth1,gepard,ludovic,gunther1,bobby2,bob12345,sunmoon,septembr,bigmac1,bcnjhbz,seaking,all4u,12qw34er56ty,bassie,nokia5228,7355608,sylwia,charvel,billgate,davion,chablis,catsmeow,kjiflrf,amylynn,rfvbkkf,mizredhe,handjob,jasper12,erbol,solara,bagpipe,biffer,notime,erlan,8543852,sugaree,oshkosh,fedora,bangbus,5lyedn,longball,teresa1,bootyman,aleksand,qazwsxedc12,nujbhc,tifosi,zpxvwy,lights1,slowpoke,tiger12,kstate,password10,alex69,collins1,9632147,doglover,baseball2,security1,grunts,orange2,godloves,213qwe879,julieb,1qazxsw23edcvfr4,noidea,8uiazp,betsy1,junior2,parol123,123456zz,piehonkii,kanker,bunky,hingis,reese1,qaz123456,sidewinder,tonedup,footsie,blackpoo,jalapeno,mummy1,always1,josh1,rockyboy,plucky,chicag,nadroj,blarney,blood123,wheaties,packer1,ravens1,mrjones,gfhjkm007,anna2010,awatar,guitar12,hashish,scale1,tomwaits,amrita,fantasma,rfpfym,pass2,tigris,bigair,slicker,sylvi,shilpa,cindylou,archie1,bitches1,poppys,ontime,horney1,camaroz28,alladin,bujhm,cq2kph,alina1,wvj5np,1211123a,tetons,scorelan,concordi,morgan2,awacs,shanty,tomcat14,andrew123,bear69,vitae,fred99,chingy,octane,belgario,fatdaddy,rhodan,password23,sexxes,boomtown,joshua01,war3demo,my2kids,buck1,hot4you,monamour,12345aa,yumiko,parool,carlton1,neverland,rose12,right1,sociald,grouse,brandon0,cat222,alex00,civicex,bintang,malkav,arschloc,dodgeviper,qwerty666,goduke,dante123,boss1,ontheroc,corpsman,love14,uiegu451,hardtail,irondoor,ghjrehfnehf,36460341,konijn,h2slca,kondom25,123456ss,cfytxrf,btnjey,nando,freemail,comander,natas666,siouxsie,hummer1,biomed,dimsum,yankees0,diablo666,lesbian1,pot420,jasonm,glock23,jennyb,itsmine,lena2010,whattheh,beandip,abaddon,kishore,signup,apogee,biteme12,suzieq,vgfun4,iseeyou,rifleman,qwerta,4pussy,hawkman,guest1,june17,dicksuck,bootay,cash12,bassale,ktybyuhfl,leetch,nescafe,7ovtgimc,clapton1,auror,boonie,tracker1,john69,bellas,cabinboy,yonkers,silky1,ladyffesta,drache,kamil1,davidp,bad123,snoopy12,sanche,werthvfy,achille,nefertiti,gerald1,slage33,warszawa,macsan26,mason123,kotopes,welcome8,nascar99,kiril,77778888,hairy1,monito,comicsans,81726354,killabee,arclight,yuo67,feelme,86753099,nnssnn,monday12,88351132,88889999,websters,subito,asdf12345,vaz2108,zvbxrpl,159753456852,rezeda,multimed,noaccess,henrique,tascam,captiva,zadrot,hateyou,sophie12,123123456,snoop1,charlie8,birmingh,hardline,libert,azsxdcf,89172735872,rjpthju,bondar,philips1,olegnaruto,myword,yakman,stardog,banana12,1234567890w,farout,annick,duke01,rfj422,billard,glock19,shaolin1,master10,cinderel,deltaone,manning1,biggreen,sidney1,patty1,goforit1,766rglqy,sevendus,aristotl,armagedo,blumen,gfhfyjz,kazakov,lekbyxxx,accord1,idiota,soccer16,texas123,victoire,ololo,chris01,bobbbb,299792458,eeeeeee1,confiden,07070,clarks,techno1,kayley,stang1,wwwwww1,uuuuu1,neverdie,jasonr,cavscout,481516234,mylove1,shaitan,1qazxcvb,barbaros,123456782000,123wer,thissucks,7seven,227722,faerie,hayduke,dbacks,snorkel,zmxncbv,tiger99,unknown1,melmac,polo1234,sssssss1,1fire,369147,bandung,bluejean,nivram,stanle,ctcnhf,soccer20,blingbli,dirtball,alex2112,183461,skylin,boobman,geronto,brittany1,yyz2112,gizmo69,ktrcec,dakota12,chiken,sexy11,vg08k714,bernadet,1bulldog,beachs,hollyb,maryjoy,margo1,danielle1,chakra,alexand,hullcity,matrix12,sarenna,pablos,antler,supercar,chomsky,german1,airjordan,545ettvy,camaron,flight1,netvideo,tootall,valheru,481516,1234as,skimmer,redcross,inuyash,uthvfy,1012nw,edoardo,bjhgfi,golf11,9379992a,lagarto,socball,boopie,krazy,.adgjmptw,gaydar,kovalev,geddylee,firstone,turbodog,loveee,135711,badbo,trapdoor,opopop11,danny2,max2000,526452,kerry1,leapfrog,daisy2,134kzbip,1andrea,playa1,peekab00,heskey,pirrello,gsewfmck,dimon4ik,puppie,chelios,554433,hypnodanny,fantik,yhwnqc,ghbdtngjrf,anchorag,buffett1,fanta,sappho,024680,vialli,chiva,lucylu,hashem,exbntkm,thema,23jordan,jake11,wildside,smartie,emerica,2wj2k9oj,ventrue,timoth,lamers,baerchen,suspende,boobis,denman85,1adam12,otello,king12,dzakuni,qsawbbs,isgay,porno123,jam123,daytona1,tazzie,bunny123,amaterasu,jeffre,crocus,mastercard,bitchedup,chicago7,aynrand,intel1,tamila,alianza,mulch,merlin12,rose123,alcapone,mircea,loveher,joseph12,chelsea6,dorothy1,wolfgar,unlimite,arturik,qwerty3,paddy1,piramid,linda123,cooool,millie1,warlock1,forgotit,tort02,ilikeyou,avensis,loveislife,dumbass1,clint1,2110se,drlove,olesia,kalinina,sergey123,123423,alicia1,markova,tri5a3,media1,willia1,xxxxxxx1,beercan,smk7366,jesusislord,motherfuck,smacker,birthday5,jbaby,harley2,hyper1,a9387670a,honey2,corvet,gjmptw,rjhjkmbien,apollon,madhuri,3a5irt,cessna17,saluki,digweed,tamia1,yja3vo,cfvlehfr,1111111q,martyna,stimpy1,anjana,yankeemp,jupiler,idkfa,1blue,fromv,afric,3xbobobo,liverp00l,nikon1,amadeus1,acer123,napoleo,david7,vbhjckfdf,mojo69,percy1,pirates1,grunt1,alenushka,finbar,zsxdcf,mandy123,1fred,timewarp,747bbb,druids,julia123,123321qq,spacebar,dreads,fcbarcelona,angela12,anima,christopher1,stargazer,123123s,hockey11,brewski,marlbor,blinker,motorhead,damngood,werthrf,letmein3,moremoney,killer99,anneke,eatit,pilatus,andrew01,fiona1,maitai,blucher,zxgdqn,e5pftu,nagual,panic1,andron,openwide,alphabeta,alison1,chelsea8,fende,mmm666,1shot2,a19l1980,123456@,1black,m1chael,vagner,realgood,maxxx,vekmnbr,stifler,2509mmh,tarkan,sherzod,1234567b,gunners1,artem2010,shooby,sammie1,p123456,piggie,abcde12345,nokia6230,moldir,piter,1qaz3edc,frequenc,acuransx,1star,nikeair,alex21,dapimp,ranjan,ilovegirls,anastasiy,berbatov,manso,21436587,leafs1,106666,angelochek,ingodwetrust,123456aaa,deano,korsar,pipetka,thunder9,minka,himura,installdevic,1qqqqq,digitalprodu,suckmeoff,plonker,headers,vlasov,ktr1996,windsor1,mishanya,garfield1,korvin,littlebit,azaz09,vandamme,scripto,s4114d,passward,britt1,r1chard,ferrari5,running1,7xswzaq,falcon2,pepper76,trademan,ea53g5,graham1,volvos80,reanimator,micasa,1234554321q,kairat,escorpion,sanek94,karolina1,kolovrat,karen2,1qaz@wsx,racing1,splooge,sarah2,deadman1,creed1,nooner,minicoop,oceane,room112,charme,12345ab,summer00,wetcunt,drewman,nastyman,redfire,appels,merlin69,dolfin,bornfree,diskette,ohwell,12345678qwe,jasont,madcap,cobra2,dolemit1,whatthehell,juanit,voldemar,rocke,bianc,elendil,vtufgjkbc,hotwheels,spanis,sukram,pokerface,k1ller,freakout,dontae,realmadri,drumss,gorams,258789,snakey,jasonn,whitewolf,befree,johnny99,pooka,theghost,kennys,vfvektxrf,toby1,jumpman23,deadlock,barbwire,stellina,alexa1,dalamar,mustanggt,northwes,tesoro,chameleo,sigtau,satoshi,george11,hotcum,cornell1,golfer12,geek01d,trololo,kellym,megapolis,pepsi2,hea666,monkfish,blue52,sarajane,bowler1,skeets,ddgirls,hfccbz,bailey01,isabella1,dreday,moose123,baobab,crushme,000009,veryhot,roadie,meanone,mike18,henriett,dohcvtec,moulin,gulnur,adastra,angel9,western1,natura,sweetpe,dtnfkm,marsbar,daisys,frogger1,virus1,redwood1,streetball,fridolin,d78unhxq,midas,michelob,cantik,sk2000,kikker,macanudo,rambone,fizzle,20000,peanuts1,cowpie,stone32,astaroth,dakota01,redso,mustard1,sexylove,giantess,teaparty,bobbin,beerbong,monet1,charles3,anniedog,anna1988,cameleon,longbeach,tamere,qpful542,mesquite,waldemar,12345zx,iamhere,lowboy,canard,granp,daisymay,love33,moosejaw,nivek,ninjaman,shrike01,aaa777,88002000600,vodolei,bambush,falcor,harley69,alphaomega,severine,grappler,bosox,twogirls,gatorman,vettes,buttmunch,chyna,excelsio,crayfish,birillo,megumi,lsia9dnb9y,littlebo,stevek,hiroyuki,firehous,master5,briley2,gangste,chrisk,camaleon,bulle,troyboy,froinlaven,mybutt,sandhya,rapala,jagged,crazycat,lucky12,jetman,wavmanuk,1heather,beegee,negril,mario123,funtime1,conehead,abigai,mhorgan,patagoni,travel1,backspace,frenchfr,mudcat,dashenka,baseball3,rustys,741852kk,dickme,baller23,griffey1,suckmycock,fuhrfzgc,jenny2,spuds,berlin1,justfun,icewind,bumerang,pavlusha,minecraft123,shasta1,ranger12,123400,twisters,buthead,miked,finance1,dignity7,hello9,lvjdp383,jgthfnjh,dalmatio,paparoach,miller31,2bornot2b,fathe,monterre,theblues,satans,schaap,jasmine2,sibelius,manon,heslo,jcnhjd,shane123,natasha2,pierrot,bluecar,iloveass,harriso,red12,london20,job314,beholder,reddawg,fuckyou!,pussylick,bologna1,austintx,ole4ka,blotto,onering,jearly,balbes,lightbul,bighorn,crossfir,lee123,prapor,1ashley,gfhjkm22,wwe123,09090,sexsite,marina123,jagua,witch1,schmoo,parkview,dragon3,chilango,ultimo,abramova,nautique,2bornot2,duende,1arthur,nightwing,surfboar,quant4307,15s9pu03,karina1,shitball,walleye1,wildman1,whytesha,1morgan,my2girls,polic,baranova,berezuckiy,kkkkkk1,forzima,fornow,qwerty02,gokart,suckit69,davidlee,whatnow,edgard,tits1,bayshore,36987412,ghbphfr,daddyy,explore1,zoidberg,5qnzjx,morgane,danilov,blacksex,mickey12,balsam,83y6pv,sarahc,slaye,all4u2,slayer69,nadia1,rlzwp503,4cranker,kaylie,numberon,teremok,wolf12,deeppurple,goodbeer,aaa555,66669999,whatif,harmony1,ue8fpw,3tmnej,254xtpss,dusty197,wcksdypk,zerkalo,dfnheirf,motorol,digita,whoareyou,darksoul,manics,rounders,killer11,d2000lb,cegthgfhjkm,catdog1,beograd,pepsico,julius1,123654987,softbal,killer23,weasel1,lifeson,q123456q,444555666,bunches,andy1,darby1,service01,bear11,jordan123,amega,duncan21,yensid,lerxst,rassvet,bronco2,fortis,pornlove,paiste,198900,asdflkjh,1236547890,futur,eugene1,winnipeg261,fk8bhydb,seanjohn,brimston,matthe1,bitchedu,crisco,302731,roxydog,woodlawn,volgograd,ace1210,boy4u2ownnyc,laura123,pronger,parker12,z123456z,andrew13,longlife,sarang,drogba,gobruins,soccer4,holida,espace,almira,murmansk,green22,safina,wm00022,1chevy,schlumpf,doroth,ulises,golf99,hellyes,detlef,mydog,erkina,bastardo,mashenka,sucram,wehttam,generic1,195000,spaceboy,lopas123,scammer,skynyrd,daddy2,titani,ficker,cr250r,kbnthfnehf,takedown,sticky1,davidruiz,desant,nremtp,painter1,bogies,agamemno,kansas1,smallfry,archi,2b4dnvsx,1player,saddie,peapod,6458zn7a,qvw6n2,gfxqx686,twice2,sh4d0w3d,mayfly,375125,phitau,yqmbevgk,89211375759,kumar1,pfhfpf,toyboy,way2go,7pvn4t,pass69,chipster,spoony,buddycat,diamond3,rincewin,hobie,david01,billbo,hxp4life,matild,pokemon2,dimochka,clown1,148888,jenmt3,cuxldv,cqnwhy,cde34rfv,simone1,verynice,toobig,pasha123,mike00,maria2,lolpop,firewire,dragon9,martesana,a1234567890,birthday3,providen,kiska,pitbulls,556655,misawa,damned69,martin11,goldorak,gunship,glory1,winxclub,sixgun,splodge,agent1,splitter,dome69,ifghjb,eliza1,snaiper,wutang36,phoenix7,666425,arshavin,paulaner,namron,m69fg1w,qwert1234,terrys,zesyrmvu,joeman,scoots,dwml9f,625vrobg,sally123,gostoso,symow8,pelota,c43qpul5rz,majinbuu,lithium1,bigstuff,horndog1,kipelov,kringle,1beavis,loshara,octobe,jmzacf,12342000,qw12qw,runescape1,chargers1,krokus,piknik,jessy,778811,gjvbljh,474jdvff,pleaser,misskitty,breaker1,7f4df451,dayan,twinky,yakumo,chippers,matia,tanith,len2ski1,manni,nichol1,f00b4r,nokia3110,standart,123456789i,shami,steffie,larrywn,chucker,john99,chamois,jjjkkk,penmouse,ktnj2010,gooners,hemmelig,rodney1,merlin01,bearcat1,1yyyyy,159753z,1fffff,1ddddd,thomas11,gjkbyrf,ivanka,f1f2f3,petrovna,phunky,conair,brian2,creative1,klipsch,vbitymrf,freek,breitlin,cecili,westwing,gohabsgo,tippmann,1steve,quattro6,fatbob,sp00ky,rastas,1123581,redsea,rfnmrf,jerky1,1aaaaaa,spk666,simba123,qwert54321,123abcd,beavis69,fyfyfc,starr1,1236547,peanutbutter,sintra,12345abcde,1357246,abcde1,climbon,755dfx,mermaids,monte1,serkan,geilesau,777win,jasonc,parkside,imagine1,rockhead,producti,playhard,principa,spammer,gagher,escada,tsv1860,dbyjuhfl,cruiser1,kennyg,montgome,2481632,pompano,cum123,angel6,sooty,bear01,april6,bodyhamm,pugsly,getrich,mikes,pelusa,fosgate,jasonp,rostislav,kimberly1,128mo,dallas11,gooner1,manuel1,cocacola1,imesh,5782790,password8,daboys,1jones,intheend,e3w2q1,whisper1,madone,pjcgujrat,1p2o3i,jamesp,felicida,nemrac,phikap,firecat,jrcfyjxrf,matt12,bigfan,doedel,005500,jasonx,1234567k,badfish,goosey,utjuhfabz,wilco,artem123,igor123,spike123,jor23dan,dga9la,v2jmsz,morgan12,avery1,dogstyle,natasa,221195ws,twopac,oktober7,karthik,poop1,mightymo,davidr,zermatt,jehova,aezakmi1,dimwit,monkey5,serega123,qwerty111,blabl,casey22,boy123,1clutch,asdfjkl1,hariom,bruce10,jeep95,1smith,sm9934,karishma,bazzzz,aristo,669e53e1,nesterov,kill666,fihdfv,1abc2,anna1,silver11,mojoman,telefono,goeagles,sd3lpgdr,rfhfynby,melinda1,llcoolj,idteul,bigchief,rocky13,timberwo,ballers,gatekeep,kashif,hardass,anastasija,max777,vfuyjkbz,riesling,agent99,kappas,dalglish,tincan,orange3,turtoise,abkbvjy,mike24,hugedick,alabala,geolog,aziza,devilboy,habanero,waheguru,funboy,freedom5,natwest,seashore,impaler,qwaszx1,pastas,bmw535,tecktonik,mika00,jobsearc,pinche,puntang,aw96b6,1corvett,skorpio,foundati,zzr1100,gembird,vfnhjcrby,soccer18,vaz2110,peterp,archer1,cross1,samedi,dima1992,hunter99,lipper,hotbody,zhjckfdf,ducati1,trailer1,04325956,cheryl1,benetton,kononenko,sloneczko,rfgtkmrf,nashua,balalaika,ampere,eliston,dorsai,digge,flyrod,oxymoron,minolta,ironmike,majortom,karimov,fortun,putaria,an83546921an13,blade123,franchis,mxaigtg5,dynxyu,devlt4,brasi,terces,wqmfuh,nqdgxz,dale88,minchia,seeyou,housepen,1apple,1buddy,mariusz,bighouse,tango2,flimflam,nicola1,qwertyasd,tomek1,shumaher,kartoshka,bassss,canaries,redman1,123456789as,preciosa,allblacks,navidad,tommaso,beaudog,forrest1,green23,ryjgjxrf,go4it,ironman2,badnews,butterba,1grizzly,isaeva,rembrand,toront,1richard,bigjon,yfltymrf,1kitty,4ng62t,littlejo,wolfdog,ctvtyjd,spain1,megryan,tatertot,raven69,4809594q,tapout,stuntman,a131313,lagers,hotstuf,lfdbl11,stanley2,advokat,boloto,7894561,dooker,adxel187,cleodog,4play,0p9o8i,masterb,bimota,charlee,toystory,6820055,6666667,crevette,6031769,corsa,bingoo,dima1990,tennis11,samuri,avocado,melissa6,unicor,habari,metart,needsex,cockman,hernan,3891576,3334444,amigo1,gobuffs2,mike21,allianz,2835493,179355,midgard,joey123,oneluv,ellis1,towncar,shonuff,scouse,tool69,thomas19,chorizo,jblaze,lisa1,dima1999,sophia1,anna1989,vfvekbxrf,krasavica,redlegs,jason25,tbontb,katrine,eumesmo,vfhufhbnrf,1654321,asdfghj1,motdepas,booga,doogle,1453145,byron1,158272,kardinal,tanne,fallen1,abcd12345,ufyljy,n12345,kucing,burberry,bodger,1234578,februar,1234512,nekkid,prober,harrison1,idlewild,rfnz90,foiegras,pussy21,bigstud,denzel,tiffany2,bigwill,1234567890zzz,hello69,compute1,viper9,hellspaw,trythis,gococks,dogballs,delfi,lupine,millenia,newdelhi,charlest,basspro,1mike,joeblack,975310,1rosebud,batman11,misterio,fucknut,charlie0,august11,juancho,ilonka,jigei743ks,adam1234,889900,goonie,alicat,ggggggg1,1zzzzzzz,sexywife,northstar,chris23,888111,containe,trojan1,jason5,graikos,1ggggg,1eeeee,tigers01,indigo1,hotmale,jacob123,mishima,richard3,cjxb2014,coco123,meagain,thaman,wallst,edgewood,bundas,1power,matilda1,maradon,hookedup,jemima,r3vi3wpass,2004-10-,mudman,taz123,xswzaq,emerson1,anna21,warlord1,toering,pelle,tgwdvu,masterb8,wallstre,moppel,priora,ghjcnjrdfif,yoland,12332100,1j9e7f6f,jazzzz,yesman,brianm,42qwerty42,12345698,darkmanx,nirmal,john31,bb123456,neuspeed,billgates,moguls,fj1200,hbhlair,shaun1,ghbdfn,305pwzlr,nbu3cd,susanb,pimpdad,mangust6403,joedog,dawidek,gigante,708090,703751,700007,ikalcr,tbivbn,697769,marvi,iyaayas,karen123,jimmyboy,dozer1,e6z8jh,bigtime1,getdown,kevin12,brookly,zjduc3,nolan1,cobber,yr8wdxcq,liebe,m1garand,blah123,616879,action1,600000,sumitomo,albcaz,asian1,557799,dave69,556699,sasa123,streaker,michel1,karate1,buddy7,daulet,koks888,roadtrip,wapiti,oldguy,illini1,1234qq,mrspock,kwiatek,buterfly,august31,jibxhq,jackin,taxicab,tristram,talisker,446655,444666,chrisa,freespace,vfhbfyyf,chevell,444333,notyours,442244,christian1,seemore,sniper12,marlin1,joker666,multik,devilish,crf450,cdfoli,eastern1,asshead,duhast,voyager2,cyberia,1wizard,cybernet,iloveme1,veterok,karandash,392781,looksee,diddy,diabolic,foofight,missey,herbert1,bmw318i,premier1,zsfmpv,eric1234,dun6sm,fuck11,345543,spudman,lurker,bitem,lizzy1,ironsink,minami,339311,s7fhs127,sterne,332233,plankton,galax,azuywe,changepa,august25,mouse123,sikici,killer69,xswqaz,quovadis,gnomik,033028pw,777777a,barrakuda,spawn666,goodgod,slurp,morbius,yelnats,cujo31,norman1,fastone,earwig,aureli,wordlife,bnfkbz,yasmi,austin123,timberla,missy2,legalize,netcom,liljon,takeit,georgin,987654321z,warbird,vitalina,all4u3,mmmmmm1,bichon,ellobo,wahoos,fcazmj,aksarben,lodoss,satnam,vasili,197800,maarten,sam138989,0u812,ankita,walte,prince12,anvils,bestia,hoschi,198300,univer,jack10,ktyecbr,gr00vy,hokie,wolfman1,fuckwit,geyser,emmanue,ybrjkftd,qwerty33,karat,dblock,avocat,bobbym,womersle,1please,nostra,dayana,billyray,alternat,iloveu1,qwerty69,rammstein1,mystikal,winne,drawde,executor,craxxxs,ghjcnjnf,999888777,welshman,access123,963214785,951753852,babe69,fvcnthlfv,****me,666999666,testing2,199200,nintendo64,oscarr,guido8,zhanna,gumshoe,jbird,159357456,pasca,123452345,satan6,mithrand,fhbirf,aa1111aa,viggen,ficktjuv,radial9,davids1,rainbow7,futuro,hipho,platin,poppy123,rhenjq,fulle,rosit,chicano,scrumpy,lumpy1,seifer,uvmrysez,autumn1,xenon,susie1,7u8i9o0p,gamer1,sirene,muffy1,monkeys1,kalinin,olcrackmaster,hotmove,uconn,gshock,merson,lthtdyz,pizzaboy,peggy1,pistache,pinto1,fishka,ladydi,pandor,baileys,hungwell,redboy,rookie1,amanda01,passwrd,clean1,matty1,tarkus,jabba1,bobster,beer30,solomon1,moneymon,sesamo,fred11,sunnysid,jasmine5,thebears,putamadre,workhard,flashbac,counter1,liefde,magnat,corky1,green6,abramov,lordik,univers,shortys,david3,vip123,gnarly,1234567s,billy2,honkey,deathstar,grimmy,govinda,direktor,12345678s,linus1,shoppin,rekbrjdf,santeria,prett,berty75,mohican,daftpunk,uekmyfhf,chupa,strats,ironbird,giants56,salisbur,koldun,summer04,pondscum,jimmyj,miata1,george3,redshoes,weezie,bartman1,0p9o8i7u,s1lver,dorkus,125478,omega9,sexisgood,mancow,patric1,jetta1,074401,ghjuhtcc,gfhjk,bibble,terry2,123213,medicin,rebel2,hen3ry,4freedom,aldrin,lovesyou,browny,renwod,winnie1,belladon,1house,tyghbn,blessme,rfhfrfnbwf,haylee,deepdive,booya,phantasy,gansta,cock69,4mnveh,gazza1,redapple,structur,anakin1,manolito,steve01,poolman,chloe123,vlad1998,qazwsxe,pushit,random123,ontherocks,o236nq,brain1,dimedrol,agape,rovnogod,1balls,knigh,alliso,love01,wolf01,flintstone,beernuts,tuffguy,isengard,highfive,alex23,casper99,rubina,getreal,chinita,italian1,airsoft,qwerty23,muffdiver,willi1,grace123,orioles1,redbull1,chino1,ziggy123,breadman,estefan,ljcneg,gotoit,logan123,wideglid,mancity1,treess,qwe123456,kazumi,qweasdqwe,oddworld,naveed,protos,towson,a801016,godislov,at_asp,bambam1,soccer5,dark123,67vette,carlos123,hoser1,scouser,wesdxc,pelus,dragon25,pflhjn,abdula,1freedom,policema,tarkin,eduardo1,mackdad,gfhjkm11,lfplhfgthvf,adilet,zzzzxxxx,childre,samarkand,cegthgegth,shama,fresher,silvestr,greaser,allout,plmokn,sexdrive,nintendo1,fantasy7,oleander,fe126fd,crumpet,pingzing,dionis,hipster,yfcnz,requin,calliope,jerome1,housecat,abc123456789,doghot,snake123,augus,brillig,chronic1,gfhjkbot,expediti,noisette,master7,caliban,whitetai,favorite3,lisamari,educatio,ghjhjr,saber1,zcegth,1958proman,vtkrbq,milkdud,imajica,thehip,bailey10,hockey19,dkflbdjcnjr,j123456,bernar,aeiouy,gamlet,deltachi,endzone,conni,bcgfybz,brandi1,auckland2010,7653ajl1,mardigra,testuser,bunko18,camaro67,36936,greenie,454dfmcq,6xe8j2z4,mrgreen,ranger5,headhunt,banshee1,moonunit,zyltrc,hello3,pussyboy,stoopid,tigger11,yellow12,drums1,blue02,kils123,junkman,banyan,jimmyjam,tbbucs,sportster,badass1,joshie,braves10,lajolla,1amanda,antani,78787,antero,19216801,chich,rhett32,sarahm,beloit,sucker69,corkey,nicosnn,rccola,caracol,daffyduc,bunny2,mantas,monkies,hedonist,cacapipi,ashton1,sid123,19899891,patche,greekgod,cbr1000,leader1,19977991,ettore,chongo,113311,picass,cfif123,rhtfnbd,frances1,andy12,minnette,bigboy12,green69,alices,babcia,partyboy,javabean,freehand,qawsed123,xxx111,harold1,passwo,jonny1,kappa1,w2dlww3v5p,1merlin,222999,tomjones,jakeman,franken,markhegarty,john01,carole1,daveman,caseys,apeman,mookey,moon123,claret,titans1,residentevil,campari,curitiba,dovetail,aerostar,jackdaniels,basenji,zaq12w,glencoe,biglove,goober12,ncc170,far7766,monkey21,eclipse9,1234567v,vanechka,aristote,grumble,belgorod,abhishek,neworleans,pazzword,dummie,sashadog,diablo11,mst3000,koala1,maureen1,jake99,isaiah1,funkster,gillian1,ekaterina20,chibears,astra123,4me2no,winte,skippe,necro,windows9,vinograd,demolay,vika2010,quiksilver,19371ayj,dollar1,shecky,qzwxecrv,butterfly1,merrill1,scoreland,1crazy,megastar,mandragora,track1,dedhed,jacob2,newhope,qawsedrftgyh,shack1,samvel,gatita,shyster,clara1,telstar,office1,crickett,truls,nirmala,joselito,chrisl,lesnik,aaaabbbb,austin01,leto2010,bubbie,aaa12345,widder,234432,salinger,mrsmith,qazsedcft,newshoes,skunks,yt1300,bmw316,arbeit,smoove,123321qweewq,123qazwsx,22221111,seesaw,0987654321a,peach1,1029384756q,sereda,gerrard8,shit123,batcave,energy1,peterb,mytruck,peter12,alesya,tomato1,spirou,laputaxx,magoo1,omgkremidia,knight12,norton1,vladislava,shaddy,austin11,jlbyjxrf,kbdthgekm,punheta,fetish69,exploiter,roger2,manstein,gtnhjd,32615948worms,dogbreath,ujkjdjkjvrf,vodka1,ripcord,fatrat,kotek1,tiziana,larrybir,thunder3,nbvfnb,9kyq6fge,remembe,likemike,gavin1,shinigam,yfcnfcmz,13245678,jabbar,vampyr,ane4ka,lollipo,ashwin,scuderia,limpdick,deagle,3247562,vishenka,fdhjhf,alex02,volvov70,mandys,bioshock,caraca,tombraider,matrix69,jeff123,13579135,parazit,black3,noway1,diablos,hitmen,garden1,aminor,decembe,august12,b00ger,006900,452073t,schach,hitman1,mariner1,vbnmrf,paint1,742617000027,bitchboy,pfqxjyjr,5681392,marryher,sinnet,malik1,muffin12,aninha,piolin,lady12,traffic1,cbvjyf,6345789,june21,ivan2010,ryan123,honda99,gunny,coorslight,asd321,hunter69,7224763,sonofgod,dolphins1,1dolphin,pavlenko,woodwind,lovelov,pinkpant,gblfhfcbyf,hotel1,justinbiebe,vinter,jeff1234,mydogs,1pizza,boats1,parrothe,shawshan,brooklyn1,cbrown,1rocky,hemi426,dragon64,redwings1,porsches,ghostly,hubbahub,buttnut,b929ezzh,sorokina,flashg,fritos,b7mguk,metatron,treehous,vorpal,8902792,marcu,free123,labamba,chiefs1,zxc123zxc,keli_14,hotti,1steeler,money4,rakker,foxwoods,free1,ahjkjd,sidorova,snowwhit,neptune1,mrlover,trader1,nudelamb,baloo,power7,deltasig,bills1,trevo,7gorwell,nokia6630,nokia5320,madhatte,1cowboys,manga1,namtab,sanjar,fanny1,birdman1,adv12775,carlo1,dude1998,babyhuey,nicole11,madmike,ubvyfpbz,qawsedr,lifetec,skyhook,stalker123,toolong,robertso,ripazha,zippy123,1111111a,manol,dirtyman,analslut,jason3,dutches,minhasenha,cerise,fenrir,jayjay1,flatbush,franka,bhbyjxrf,26429vadim,lawntrax,198700,fritzy,nikhil,ripper1,harami,truckman,nemvxyheqdd5oqxyxyzi,gkfytnf,bugaboo,cableman,hairpie,xplorer,movado,hotsex69,mordred,ohyeah1,patrick3,frolov,katieh,4311111q,mochaj,presari,bigdo,753951852,freedom4,kapitan,tomas1,135795,sweet123,pokers,shagme,tane4ka,sentinal,ufgyndmv,jonnyb,skate123,123456798,123456788,very1,gerrit,damocles,dollarbi,caroline1,lloyds,pizdets,flatland,92702689,dave13,meoff,ajnjuhfabz,achmed,madison9,744744z,amonte,avrillavigne,elaine1,norma1,asseater,everlong,buddy23,cmgang1,trash1,mitsu,flyman,ulugbek,june27,magistr,fittan,sebora64,dingos,sleipnir,caterpil,cindys,212121qaz,partys,dialer,gjytltkmybr,qweqaz,janvier,rocawear,lostboy,aileron,sweety1,everest1,pornman,boombox,potter1,blackdic,44448888,eric123,112233aa,2502557i,novass,nanotech,yourname,x12345,indian1,15975300,1234567l,carla51,chicago0,coleta,cxzdsaewq,qqwweerr,marwan,deltic,hollys,qwerasd,pon32029,rainmake,nathan0,matveeva,legioner,kevink,riven,tombraid,blitzen,a54321,jackyl,chinese1,shalimar,oleg1995,beaches1,tommylee,eknock,berli,monkey23,badbob,pugwash,likewhoa,jesus2,yujyd360,belmar,shadow22,utfp5e,angelo1,minimax,pooder,cocoa1,moresex,tortue,lesbia,panthe,snoopy2,drumnbass,alway,gmcz71,6jhwmqku,leppard,dinsdale,blair1,boriqua,money111,virtuagirl,267605,rattlesn,1sunshin,monica12,veritas1,newmexic,millertime,turandot,rfvxfnrf,jaydog,kakawka,bowhunter,booboo12,deerpark,erreway,taylorma,rfkbybyf,wooglin,weegee,rexdog,iamhorny,cazzo1,vhou812,bacardi1,dctktyyfz,godpasi,peanut12,bertha1,fuckyoubitch,ghosty,altavista,jertoot,smokeit,ghjcnbvtyz,fhnehxbr,rolsen,qazxcdews,maddmaxx,redrocke,qazokm,spencer2,thekiller,asdf11,123sex,tupac1,p1234567,dbrown,1biteme,tgo4466,316769,sunghi,shakespe,frosty1,gucci1,arcana,bandit01,lyubov,poochy,dartmout,magpies1,sunnyd,mouseman,summer07,chester7,shalini,danbury,pigboy,dave99,deniss,harryb,ashley11,pppppp1,01081988m,balloon1,tkachenko,bucks1,master77,pussyca,tricky1,zzxxccvv,zoulou,doomer,mukesh,iluv69,supermax,todays,thefox,don123,dontask,diplom,piglett,shiney,fahbrf,qaz12wsx,temitope,reggin,project1,buffy2,inside1,lbpfqyth,vanilla1,lovecock,u4slpwra,fylh.irf,123211,7ertu3ds,necroman,chalky,artist1,simpso,4x7wjr,chaos666,lazyacres,harley99,ch33s3,marusa,eagle7,dilligas,computadora,lucky69,denwer,nissan350z,unforgiv,oddball,schalke0,aztec1,borisova,branden1,parkave,marie123,germa,lafayett,878kckxy,405060,cheeseca,bigwave,fred22,andreea,poulet,mercutio,psycholo,andrew88,o4izdmxu,sanctuar,newhome,milion,suckmydi,rjvgm.nth,warior,goodgame,1qwertyuiop,6339cndh,scorpio2,macker,southbay,crabcake,toadie,paperclip,fatkid,maddo,cliff1,rastafar,maries,twins1,geujdrf,anjela,wc4fun,dolina,mpetroff,rollout,zydeco,shadow3,pumpki,steeda,volvo240,terras,blowjo,blue2000,incognit,badmojo,gambit1,zhukov,station1,aaronb,graci,duke123,clipper1,qazxsw2,ledzeppe,kukareku,sexkitte,cinco,007008,lakers12,a1234b,acmilan1,afhfjy,starrr,slutty3,phoneman,kostyan,bonzo1,sintesi07,ersatz,cloud1,nephilim,nascar03,rey619,kairos,123456789e,hardon1,boeing1,juliya,hfccdtn,vgfun8,polizei,456838,keithb,minouche,ariston,savag,213141,clarkken,microwav,london2,santacla,campeo,qr5mx7,464811,mynuts,bombo,1mickey,lucky8,danger1,ironside,carter12,wyatt1,borntorun,iloveyou123,jose1,pancake1,tadmichaels,monsta,jugger,hunnie,triste,heat7777,ilovejesus,queeny,luckycharm,lieben,gordolee85,jtkirk,forever21,jetlag,skylane,taucher,neworlea,holera,000005,anhnhoem,melissa7,mumdad,massimiliano,dima1994,nigel1,madison3,slicky,shokolad,serenit,jmh1978,soccer123,chris3,drwho,rfpzdrf,1qasw23ed,free4me,wonka,sasquatc,sanan,maytag,verochka,bankone,molly12,monopoli,xfqybr,lamborgini,gondolin,candycane,needsome,jb007,scottie1,brigit,0147258369,kalamazo,lololyo123,bill1234,ilovejes,lol123123,popkorn,april13,567rntvm,downunde,charle1,angelbab,guildwars,homeworld,qazxcvbnm,superma1,dupa123,kryptoni,happyy,artyom,stormie,cool11,calvin69,saphir,konovalov,jansport,october8,liebling,druuna,susans,megans,tujhjdf,wmegrfux,jumbo1,ljb4dt7n,012345678910,kolesnik,speculum,at4gftlw,kurgan,93pn75,cahek0980,dallas01,godswill,fhifdby,chelsea4,jump23,barsoom,catinhat,urlacher,angel99,vidadi1,678910,lickme69,topaz1,westend,loveone,c12345,gold12,alex1959,mamon,barney12,1maggie,alex12345,lp2568cskt,s1234567,gjikbdctyf,anthony0,browns99,chips1,sunking,widespre,lalala1,tdutif,fucklife,master00,alino4ka,stakan,blonde1,phoebus,tenore,bvgthbz,brunos,suzjv8,uvdwgt,revenant,1banana,veroniqu,sexfun,sp1der,4g3izhox,isakov,shiva1,scooba,bluefire,wizard12,dimitris,funbags,perseus,hoodoo,keving,malboro,157953,a32tv8ls,latics,animate,mossad,yejntb,karting,qmpq39zr,busdrive,jtuac3my,jkne9y,sr20dett,4gxrzemq,keylargo,741147,rfktylfhm,toast1,skins1,xcalibur,gattone,seether,kameron,glock9mm,julio1,delenn,gameday,tommyd,str8edge,bulls123,66699,carlsberg,woodbird,adnama,45auto,codyman,truck2,1w2w3w4w,pvjegu,method1,luetdi,41d8cd98f00b,bankai,5432112345,94rwpe,reneee,chrisx,melvins,775577,sam2000,scrappy1,rachid,grizzley,margare,morgan01,winstons,gevorg,gonzal,crawdad,gfhfdjp,babilon,noneya,pussy11,barbell,easyride,c00li0,777771,311music,karla1,golions,19866891,peejay,leadfoot,hfvbkm,kr9z40sy,cobra123,isotwe,grizz,sallys,****you,aaa123a,dembel,foxs14,hillcres,webman,mudshark,alfredo1,weeded,lester1,hovepark,ratface,000777fffa,huskie,wildthing,elbarto,waikiki,masami,call911,goose2,regin,dovajb,agricola,cjytxrj,andy11,penny123,family01,a121212,1braves,upupa68,happy100,824655,cjlove,firsttim,kalel,redhair,dfhtymt,sliders,bananna,loverbo,fifa2008,crouton,chevy350,panties2,kolya1,alyona,hagrid,spagetti,q2w3e4r,867530,narkoman,nhfdvfnjkju123,1ccccccc,napolean,0072563,allay,w8sted,wigwam,jamesk,state1,parovoz,beach69,kevinb,rossella,logitech1,celula,gnocca,canucks1,loginova,marlboro1,aaaa1,kalleanka,mester,mishutka,milenko,alibek,jersey1,peterc,1mouse,nedved,blackone,ghfplybr,682regkh,beejay,newburgh,ruffian,clarets,noreaga,xenophon,hummerh2,tenshi,smeagol,soloyo,vfhnby,ereiamjh,ewq321,goomie,sportin,cellphone,sonnie,jetblack,saudan,gblfhfc,matheus,uhfvjnf,alicja,jayman1,devon1,hexagon,bailey2,vtufajy,yankees7,salty1,908070,killemal,gammas,eurocard,sydney12,tuesday1,antietam,wayfarer,beast666,19952009sa,aq12ws,eveli,hockey21,haloreach,dontcare,xxxx1,andrea11,karlmarx,jelszo,tylerb,protools,timberwolf,ruffneck,pololo,1bbbbb,waleed,sasami,twinss,fairlady,illuminati,alex007,sucks1,homerjay,scooter7,tarbaby,barmaley,amistad,vanes,randers,tigers12,dreamer2,goleafsg,googie,bernie1,as12345,godeep,james3,phanto,gwbush,cumlover,2196dc,studioworks,995511,golf56,titova,kaleka,itali,socks1,kurwamac,daisuke,hevonen,woody123,daisie,wouter,henry123,gostosa,guppie,porpoise,iamsexy,276115,paula123,1020315,38gjgeuftd,rjrfrjkf,knotty,idiot1,sasha12345,matrix13,securit,radical1,ag764ks,jsmith,coolguy1,secretar,juanas,sasha1988,itout,00000001,tiger11,1butthea,putain,cavalo,basia1,kobebryant,1232323,12345asdfg,sunsh1ne,cyfqgth,tomkat,dorota,dashit,pelmen,5t6y7u,whipit,smokeone,helloall,bonjour1,snowshoe,nilknarf,x1x2x3,lammas,1234599,lol123456,atombomb,ironchef,noclue,alekseev,gwbush1,silver2,12345678m,yesican,fahjlbnf,chapstic,alex95,open1,tiger200,lisichka,pogiako,cbr929,searchin,tanya123,alex1973,phil413,alex1991,dominati,geckos,freddi,silenthill,egroeg,vorobey,antoxa,dark666,shkola,apple22,rebellio,shamanking,7f8srt,cumsucker,partagas,bill99,22223333,arnster55,fucknuts,proxima,silversi,goblues,parcells,vfrcbvjdf,piloto,avocet,emily2,1597530,miniskir,himitsu,pepper2,juiceman,venom1,bogdana,jujube,quatro,botafogo,mama2010,junior12,derrickh,asdfrewq,miller2,chitarra,silverfox,napol,prestigio,devil123,mm111qm,ara123,max33484,sex2000,primo1,sephan,anyuta,alena2010,viborg,verysexy,hibiscus,terps,josefin,oxcart,spooker,speciali,raffaello,partyon,vfhvtkflrf,strela,a123456z,worksuck,glasss,lomonosov,dusty123,dukeblue,1winter,sergeeva,lala123,john22,cmc09,sobolev,bettylou,dannyb,gjkrjdybr,hagakure,iecnhbr,awsedr,pmdmsctsk,costco,alekseeva,fktrcttd,bazuka,flyingv,garuda,buffy16,gutierre,beer12,stomatolog,ernies,palmeiras,golf123,love269,n.kmgfy,gjkysqgbpltw,youare,joeboo,baksik,lifeguar,111a111,nascar8,mindgame,dude1,neopets,frdfkfyu,june24,phoenix8,penelopa,merlin99,mercenar,badluck,mishel,bookert,deadsexy,power9,chinchil,1234567m,alex10,skunk1,rfhkcjy,sammycat,wright1,randy2,marakesh,temppassword,elmer251,mooki,patrick0,bonoedge,1tits,chiar,kylie1,graffix,milkman1,cornel,mrkitty,nicole12,ticketmaster,beatles4,number20,ffff1,terps1,superfre,yfdbufnjh,jake1234,flblfc,1111qq,zanuda,jmol01,wpoolejr,polopol,nicolett,omega13,cannonba,123456789.,sandy69,ribeye,bo243ns,marilena,bogdan123,milla,redskins1,19733791,alias1,movie1,ducat,marzena,shadowru,56565,coolman1,pornlover,teepee,spiff,nafanya,gateway3,fuckyou0,hasher,34778,booboo69,staticx,hang10,qq12345,garnier,bosco123,1234567qw,carson1,samso,1xrg4kcq,cbr929rr,allan123,motorbik,andrew22,pussy101,miroslava,cytujdbr,camp0017,cobweb,snusmumrik,salmon1,cindy2,aliya,serendipity,co437at,tincouch,timmy123,hunter22,st1100,vvvvvv1,blanka,krondor,sweeti,nenit,kuzmich,gustavo1,bmw320i,alex2010,trees1,kyliem,essayons,april26,kumari,sprin,fajita,appletre,fghbjhb,1green,katieb,steven2,corrado1,satelite,1michell,123456789c,cfkfvfylhf,acurarsx,slut543,inhere,bob2000,pouncer,k123456789,fishie,aliso,audia8,bluetick,soccer69,jordan99,fromhell,mammoth1,fighting54,mike25,pepper11,extra1,worldwid,chaise,vfr800,sordfish,almat,nofate,listopad,hellgate,dctvghbdf,jeremia,qantas,lokiju,honker,sprint1,maral,triniti,compaq3,sixsix6,married1,loveman,juggalo1,repvtyrj,zxcasdqw,123445,whore1,123678,monkey6,west123,warcraf,pwnage,mystery1,creamyou,ant123,rehjgfnrf,corona1,coleman1,steve121,alderaan,barnaul,celeste1,junebug1,bombshel,gretzky9,tankist,targa,cachou,vaz2101,playgolf,boneyard,strateg,romawka,iforgotit,pullup,garbage1,irock,archmage,shaft1,oceano,sadies,alvin1,135135ab,psalm69,lmfao,ranger02,zaharova,33334444,perkman,realman,salguod,cmoney,astonmartin,glock1,greyfox,viper99,helpm,blackdick,46775575,family5,shazbot,dewey1,qwertyas,shivani,black22,mailman1,greenday1,57392632,red007,stanky,sanchez1,tysons,daruma,altosax,krayzie,85852008,1forever,98798798,irock.,123456654,142536789,ford22,brick1,michela,preciou,crazy4u,01telemike01,nolife,concac,safety1,annie123,brunswic,destini,123456qwer,madison0,snowball1,137946,1133557799,jarule,scout2,songohan,thedead,00009999,murphy01,spycam,hirsute,aurinko,associat,1miller,baklan,hermes1,2183rm,martie,kangoo,shweta,yvonne1,westsid,jackpot1,rotciv,maratik,fabrika,claude1,nursultan,noentry,ytnhjufnm,electra1,ghjcnjnfr1,puneet,smokey01,integrit,bugeye,trouble2,14071789,paul01,omgwtf,dmh415,ekilpool,yourmom1,moimeme,sparky11,boludo,ruslan123,kissme1,demetrio,appelsin,asshole3,raiders2,bunns,fynjybj,billygoa,p030710p$e4o,macdonal,248ujnfk,acorns,schmidt1,sparrow1,vinbylrj,weasle,jerom,ycwvrxxh,skywalk,gerlinde,solidus,postal1,poochie1,1charles,rhianna,terorist,rehnrf,omgwtfbbq,assfucke,deadend,zidan,jimboy,vengence,maroon5,7452tr,dalejr88,sombra,anatole,elodi,amazonas,147789,q12345q,gawker1,juanma,kassidy,greek1,bruces,bilbob,mike44,0o9i8u7y6t,kaligula,agentx,familie,anders1,pimpjuice,0128um,birthday10,lawncare,hownow,grandorgue,juggerna,scarfac,kensai,swatteam,123four,motorbike,repytxbr,other1,celicagt,pleomax,gen0303,godisgreat,icepick,lucifer666,heavy1,tea4two,forsure,02020,shortdog,webhead,chris13,palenque,3techsrl,knights1,orenburg,prong,nomarg,wutang1,80637852730,laika,iamfree,12345670,pillow1,12343412,bigears,peterg,stunna,rocky5,12123434,damir,feuerwehr,7418529630,danone,yanina,valenci,andy69,111222q,silvia1,1jjjjj,loveforever,passwo1,stratocaster,8928190a,motorolla,lateralu,ujujkm,chubba,ujkjdf,signon,123456789zx,serdce,stevo,wifey200,ololo123,popeye1,1pass,central1,melena,luxor,nemezida,poker123,ilovemusic,qaz1234,noodles1,lakeshow,amarill,ginseng,billiam,trento,321cba,fatback,soccer33,master13,marie2,newcar,bigtop,dark1,camron,nosgoth,155555,biglou,redbud,jordan7,159789,diversio,actros,dazed,drizzit,hjcnjd,wiktoria,justic,gooses,luzifer,darren1,chynna,tanuki,11335577,icculus,boobss,biggi,firstson,ceisi123,gatewa,hrothgar,jarhead1,happyjoy,felipe1,bebop1,medman,athena1,boneman,keiths,djljgfl,dicklick,russ120,mylady,zxcdsa,rock12,bluesea,kayaks,provista,luckies,smile4me,bootycal,enduro,123123f,heartbre,ern3sto,apple13,bigpappa,fy.njxrf,bigtom,cool69,perrito,quiet1,puszek,cious,cruella,temp1,david26,alemap,aa123123,teddies,tricolor,smokey12,kikiriki,mickey01,robert01,super5,ranman,stevenso,deliciou,money777,degauss,mozar,susanne1,asdasd12,shitbag,mommy123,wrestle1,imfree,fuckyou12,barbaris,florent,ujhijr,f8yruxoj,tefjps,anemone,toltec,2gether,left4dead2,ximen,gfkmvf,dunca,emilys,diana123,16473a,mark01,bigbro,annarbor,nikita2000,11aa11,tigres,llllll1,loser2,fbi11213,jupite,qwaszxqw,macabre,123ert,rev2000,mooooo,klapaucius,bagel1,chiquit,iyaoyas,bear101,irocz28,vfktymrfz,smokey2,love99,rfhnbyf,dracul,keith123,slicko,peacock1,orgasmic,thesnake,solder,wetass,doofer,david5,rhfcyjlfh,swanny,tammys,turkiye,tubaman,estefani,firehose,funnyguy,servo,grace17,pippa1,arbiter,jimmy69,nfymrf,asdf67nm,rjcnzy,demon123,thicknes,sexysex,kristall,michail,encarta,banderos,minty,marchenko,de1987ma,mo5kva,aircav,naomi1,bonni,tatoo,cronaldo,49ers1,mama1963,1truck,telecaster,punksnotdead,erotik,1eagles,1fender,luv269,acdeehan,tanner1,freema,1q3e5t7u,linksys,tiger6,megaman1,neophyte,australia1,mydaddy,1jeffrey,fgdfgdfg,gfgekz,1986irachka,keyman,m0b1l3,dfcz123,mikeyg,playstation2,abc125,slacker1,110491g,lordsoth,bhavani,ssecca,dctvghbdtn,niblick,hondacar,baby01,worldcom,4034407,51094didi,3657549,3630000,3578951,sweetpussy,majick,supercoo,robert11,abacabb,panda123,gfhjkm13,ford4x4,zippo1,lapin,1726354,lovesong,dude11,moebius,paravoz,1357642,matkhau,solnyshko,daniel4,multiplelog,starik,martusia,iamtheman,greentre,jetblue,motorrad,vfrcbvev,redoak,dogma1,gnorman,komlos,tonka1,1010220,666satan,losenord,lateralus,absinthe,command1,jigga1,iiiiiii1,pants1,jungfrau,926337,ufhhbgjnnth,yamakasi,888555,sunny7,gemini69,alone1,zxcvbnmz,cabezon,skyblues,zxc1234,456123a,zero00,caseih,azzurra,legolas1,menudo,murcielago,785612,779977,benidorm,viperman,dima1985,piglet1,hemligt,hotfeet,7elephants,hardup,gamess,a000000,267ksyjf,kaitlynn,sharkie,sisyphus,yellow22,667766,redvette,666420,mets69,ac2zxdty,hxxrvwcy,cdavis,alan1,noddy,579300,druss,eatshit1,555123,appleseed,simpleplan,kazak,526282,fynfyfyfhbde,birthday6,dragon6,1pookie,bluedevils,omg123,hj8z6e,x5dxwp,455445,batman23,termin,chrisbrown,animals1,lucky9,443322,kzktxrf,takayuki,fermer,assembler,zomu9q,sissyboy,sergant,felina,nokia6230i,eminem12,croco,hunt4red,festina,darknigh,cptnz062,ndshnx4s,twizzler,wnmaz7sd,aamaax,gfhfcjkmrf,alabama123,barrynov,happy5,punt0it,durandal,8xuuobe4,cmu9ggzh,bruno12,316497,crazyfrog,vfvfktyf,apple3,kasey1,mackdaddy,anthon1,sunnys,angel3,cribbage,moon1,donal,bryce1,pandabear,mwss474,whitesta,freaker,197100,bitche,p2ssw0rd,turnb,tiktonik,moonlite,ferret1,jackas,ferrum,bearclaw,liberty2,1diablo,caribe,snakeeyes,janbam,azonic,rainmaker,vetalik,bigeasy,baby1234,sureno13,blink1,kluivert,calbears,lavanda,198600,dhtlbyf,medvedeva,fox123,whirling,bonscott,freedom9,october3,manoman,segredo,cerulean,robinso,bsmith,flatus,dannon,password21,rrrrrr1,callista,romai,rainman1,trantor,mickeymo,bulldog7,g123456,pavlin,pass22,snowie,hookah,7ofnine,bubba22,cabible,nicerack,moomoo1,summer98,yoyo123,milan1,lieve27,mustang69,jackster,exocet,nadege,qaz12,bahama,watson1,libras,eclipse2,bahram,bapezm,up9x8rww,ghjcnjz,themaste,deflep27,ghost16,gattaca,fotograf,junior123,gilber,gbjyth,8vjzus,rosco1,begonia,aldebara,flower12,novastar,buzzman,manchild,lopez1,mama11,william7,yfcnz1,blackstar,spurs123,moom4242,1amber,iownyou,tightend,07931505,paquito,1johnson,smokepot,pi31415,snowmass,ayacdc,jessicam,giuliana,5tgbnhy6,harlee,giuli,bigwig,tentacle,scoubidou2,benelli,vasilina,nimda,284655,jaihind,lero4ka,1tommy,reggi,ididit,jlbyjxtcndj,mike26,qbert,wweraw,lukasz,loosee123,palantir,flint1,mapper,baldie,saturne,virgin1,meeeee,elkcit,iloveme2,blue15,themoon,radmir,number3,shyanne,missle,hannelor,jasmina,karin1,lewie622,ghjcnjqgfhjkm,blasters,oiseau,sheela,grinders,panget,rapido,positiv,twink,fltkbyf,kzsfj874,daniel01,enjoyit,nofags,doodad,rustler,squealer,fortunat,peace123,khushi,devils2,7inches,candlebo,topdawg,armen,soundman,zxcqweasd,april7,gazeta,netman,hoppers,bear99,ghbjhbntn,mantle7,bigbo,harpo,jgordon,bullshi,vinny1,krishn,star22,thunderc,galinka,phish123,tintable,nightcrawler,tigerboy,rbhgbx,messi,basilisk,masha1998,nina123,yomamma,kayla123,geemoney,0000000000d,motoman,a3jtni,ser123,owen10,italien,vintelok,12345rewq,nightime,jeepin,ch1tt1ck,mxyzptlk,bandido,ohboy,doctorj,hussar,superted,parfilev,grundle,1jack,livestrong,chrisj,matthew3,access22,moikka,fatone,miguelit,trivium,glenn1,smooches,heiko,dezember,spaghett,stason,molokai,bossdog,guitarma,waderh,boriska,photosho,path13,hfrtnf,audre,junior24,monkey24,silke,vaz21093,bigblue1,trident1,candide,arcanum,klinker,orange99,bengals1,rosebu,mjujuj,nallepuh,mtwapa1a,ranger69,level1,bissjop,leica,1tiffany,rutabega,elvis77,kellie1,sameas,barada,karabas,frank12,queenb,toutoune,surfcity,samanth1,monitor1,littledo,kazakova,fodase,mistral1,april22,carlit,shakal,batman123,fuckoff2,alpha01,5544332211,buddy3,towtruck,kenwood1,vfiekmrf,jkl123,pypsik,ranger75,sitges,toyman,bartek1,ladygirl,booman,boeing77,installsqlst,222666,gosling,bigmack,223311,bogos,kevin2,gomez1,xohzi3g4,kfnju842,klubnika,cubalibr,123456789101,kenpo,0147852369,raptor1,tallulah,boobys,jjones,1q2s3c,moogie,vid2600,almas,wombat1,extra300,xfiles1,green77,sexsex1,heyjude,sammyy,missy123,maiyeuem,nccpl25282,thicluv,sissie,raven3,fldjrfn,buster22,broncos2,laurab,letmein4,harrydog,solovey,fishlips,asdf4321,ford123,superjet,norwegen,movieman,psw333333,intoit,postbank,deepwate,ola123,geolog323,murphys,eshort,a3eilm2s2y,kimota,belous,saurus,123321qaz,i81b4u,aaa12,monkey20,buckwild,byabybnb,mapleleafs,yfcnzyfcnz,baby69,summer03,twista,246890,246824,ltcnhjth,z1z2z3,monika1,sad123,uto29321,bathory,villan,funkey,poptarts,spam967888,705499fh,sebast,porn1234,earn381,1porsche,whatthef,123456789y,polo12,brillo,soreilly,waters1,eudora,allochka,is_a_bot,winter00,bassplay,531879fiz,onemore,bjarne,red911,kot123,artur1,qazxdr,c0rvette,diamond7,matematica,klesko,beaver12,2enter,seashell,panam,chaching,edward2,browni,xenogear,cornfed,aniram,chicco22,darwin1,ancella2,sophie2,vika1998,anneli,shawn41,babie,resolute,pandora2,william8,twoone,coors1,jesusis1,teh012,cheerlea,renfield,tessa1,anna1986,madness1,bkmlfh,19719870,liebherr,ck6znp42,gary123,123654z,alsscan,eyedoc,matrix7,metalgea,chinito,4iter,falcon11,7jokx7b9du,bigfeet,tassadar,retnuh,muscle1,klimova,darion,batistuta,bigsur,1herbier,noonie,ghjrehjh,karimova,faustus,snowwhite,1manager,dasboot,michael12,analfuck,inbed,dwdrums,jaysoncj,maranell,bsheep75,164379,rolodex,166666,rrrrrrr1,almaz666,167943,russel1,negrito,alianz,goodpussy,veronik,1w2q3r4e,efremov,emb377,sdpass,william6,alanfahy,nastya1995,panther5,automag,123qwe12,vfvf2011,fishe,1peanut,speedie,qazwsx1234,pass999,171204j,ketamine,sheena1,energizer,usethis1,123abc123,buster21,thechamp,flvbhfk,frank69,chane,hopeful1,claybird,pander,anusha,bigmaxxx,faktor,housebed,dimidrol,bigball,shashi,derby1,fredy,dervish,bootycall,80988218126,killerb,cheese2,pariss,mymail,dell123,catbert,christa1,chevytru,gjgjdf,00998877,overdriv,ratten,golf01,nyyanks,dinamite,bloembol,gismo,magnus1,march2,twinkles,ryan22,duckey,118a105b,kitcat,brielle,poussin,lanzarot,youngone,ssvegeta,hero63,battle1,kiler,fktrcfylh1,newera,vika1996,dynomite,oooppp,beer4me,foodie,ljhjuf,sonshine,godess,doug1,constanc,thinkbig,steve2,damnyou,autogod,www333,kyle1,ranger7,roller1,harry2,dustin1,hopalong,tkachuk,b00bies,bill2,deep111,stuffit,fire69,redfish1,andrei123,graphix,1fishing,kimbo1,mlesp31,ifufkbyf,gurkan,44556,emily123,busman,and123,8546404,paladine,1world,bulgakov,4294967296,bball23,1wwwww,mycats,elain,delta6,36363,emilyb,color1,6060842,cdtnkfyrf,hedonism,gfgfrfhkj,5551298,scubad,gostate,sillyme,hdbiker,beardown,fishers,sektor,00000007,newbaby,rapid1,braves95,gator2,nigge,anthony3,sammmy,oou812,heffer,phishin,roxanne1,yourass,hornet1,albator,2521659,underwat,tanusha,dianas,3f3fpht7op,dragon20,bilbobag,cheroke,radiatio,dwarf1,majik,33st33,dochka,garibald,robinh,sham69,temp01,wakeboar,violet1,1w2w3w,registr,tonite,maranello,1593570,parolamea,galatasara,loranthos,1472583,asmodean,1362840,scylla,doneit,jokerr,porkypig,kungen,mercator,koolhaas,come2me,debbie69,calbear,liverpoolfc,yankees4,12344321a,kennyb,madma,85200258,dustin23,thomas13,tooling,mikasa,mistic,crfnbyf,112233445,sofia1,heinz57,colts1,price1,snowey,joakim,mark11,963147,cnhfcnm,kzinti,1bbbbbbb,rubberdu,donthate,rupert1,sasha1992,regis1,nbuhbwf,fanboy,sundial,sooner1,wayout,vjnjhjkf,deskpro,arkangel,willie12,mikeyb,celtic1888,luis1,buddy01,duane1,grandma1,aolcom,weeman,172839456,basshead,hornball,magnu,pagedown,molly2,131517,rfvtgbyhn,astonmar,mistery,madalina,cash1,1happy,shenlong,matrix01,nazarova,369874125,800500,webguy,rse2540,ashley2,briank,789551,786110,chunli,j0nathan,greshnik,courtne,suckmyco,mjollnir,789632147,asdfg1234,754321,odelay,ranma12,zebedee,artem777,bmw318is,butt1,rambler1,yankees9,alabam,5w76rnqp,rosies,mafioso,studio1,babyruth,tranzit,magical123,gfhjkm135,12345$,soboleva,709394,ubique,drizzt1,elmers,teamster,pokemons,1472583690,1597532486,shockers,merckx,melanie2,ttocs,clarisse,earth1,dennys,slobber,flagman,farfalla,troika,4fa82hyx,hakan,x4ww5qdr,cumsuck,leather1,forum1,july20,barbel,zodiak,samuel12,ford01,rushfan,bugsy1,invest1,tumadre,screwme,a666666,money5,henry8,tiddles,sailaway,starburs,100years,killer01,comando,hiromi,ranetka,thordog,blackhole,palmeira,verboten,solidsna,q1w1e1,humme,kevinc,gbrfxe,gevaudan,hannah11,peter2,vangar,sharky7,talktome,jesse123,chuchi,pammy,!qazxsw2,siesta,twenty1,wetwilly,477041,natural1,sun123,daniel3,intersta,shithead1,hellyea,bonethugs,solitair,bubbles2,father1,nick01,444000,adidas12,dripik,cameron2,442200,a7nz8546,respublika,fkojn6gb,428054,snoppy,rulez1,haslo,rachael1,purple01,zldej102,ab12cd34,cytuehjxrf,madhu,astroman,preteen,handsoff,mrblonde,biggio,testin,vfdhif,twolves,unclesam,asmara,kpydskcw,lg2wmgvr,grolsch,biarritz,feather1,williamm,s62i93,bone1,penske,337733,336633,taurus1,334433,billet,diamondd,333000,nukem,fishhook,godogs,thehun,lena1982,blue00,smelly1,unb4g9ty,65pjv22,applegat,mikehunt,giancarlo,krillin,felix123,december1,soapy,46doris,nicole23,bigsexy1,justin10,pingu,bambou,falcon12,dgthtl,1surfer,qwerty01,estrellit,nfqcjy,easygo,konica,qazqwe,1234567890m,stingers,nonrev,3e4r5t,champio,bbbbbb99,196400,allen123,seppel,simba2,rockme,zebra3,tekken3,endgame,sandy2,197300,fitte,monkey00,eldritch,littleone,rfyfgkz,1member,66chevy,oohrah,cormac,hpmrbm41,197600,grayfox,elvis69,celebrit,maxwell7,rodders,krist,1camaro,broken1,kendall1,silkcut,katenka,angrick,maruni,17071994a,tktyf,kruemel,snuffles,iro4ka,baby12,alexis01,marryme,vlad1994,forward1,culero,badaboom,malvin,hardtoon,hatelove,molley,knopo4ka,duchess1,mensuck,cba321,kickbutt,zastava,wayner,fuckyou6,eddie123,cjkysir,john33,dragonfi,cody1,jabell,cjhjrf,badseed,sweden1,marihuana,brownlov,elland,nike1234,kwiettie,jonnyboy,togepi,billyk,robert123,bb334,florenci,ssgoku,198910,bristol1,bob007,allister,yjdujhjl,gauloise,198920,bellaboo,9lives,aguilas,wltfg4ta,foxyroxy,rocket69,fifty50,babalu,master21,malinois,kaluga,gogosox,obsessio,yeahrigh,panthers1,capstan,liza2000,leigh1,paintball1,blueskie,cbr600f3,bagdad,jose98,mandreki,shark01,wonderbo,muledeer,xsvnd4b2,hangten,200001,grenden,anaell,apa195,model1,245lufpq,zip100,ghjcgtrn,wert1234,misty2,charro,juanjose,fkbcrf,frostbit,badminto,buddyy,1doctor,vanya,archibal,parviz,spunky1,footboy,dm6tzsgp,legola,samadhi,poopee,ytdxz2ca,hallowboy,dposton,gautie,theworm,guilherme,dopehead,iluvtits,bobbob1,ranger6,worldwar,lowkey,chewbaca,oooooo99,ducttape,dedalus,celular,8i9o0p,borisenko,taylor01,111111z,arlingto,p3nnywiz,rdgpl3ds,boobless,kcmfwesg,blacksab,mother2,markus1,leachim,secret2,s123456789,1derful,espero,russell2,tazzer,marykate,freakme,mollyb,lindros8,james00,gofaster,stokrotka,kilbosik,aquamann,pawel1,shedevil,mousie,slot2009,october6,146969,mm259up,brewcrew,choucho,uliana,sexfiend,fktirf,pantss,vladimi,starz,sheeps,12341234q,bigun,tiggers,crjhjcnm,libtech,pudge1,home12,zircon,klaus1,jerry2,pink1,lingus,monkey66,dumass,polopolo09,feuerweh,rjyatnf,chessy,beefer,shamen,poohbear1,4jjcho,bennevis,fatgirls,ujnbrf,cdexswzaq,9noize9,rich123,nomoney,racecar1,hacke,clahay,acuario,getsum,hondacrv,william0,cheyenn,techdeck,atljhjdf,wtcacq,suger,fallenangel,bammer,tranquil,carla123,relayer,lespaul1,portvale,idontno,bycnbnen,trooper2,gennadiy,pompon,billbob,amazonka,akitas,chinatow,atkbrc,busters,fitness1,cateye,selfok2013,1murphy,fullhous,mucker,bajskorv,nectarin,littlebitch,love24,feyenoor,bigal37,lambo1,pussybitch,icecube1,biged,kyocera,ltybcjdf,boodle,theking1,gotrice,sunset1,abm1224,fromme,sexsells,inheat,kenya1,swinger1,aphrodit,kurtcobain,rhind101,poidog,poiulkjh,kuzmina,beantown,tony88,stuttgar,drumer,joaqui,messenge,motorman,amber2,nicegirl,rachel69,andreia,faith123,studmuffin,jaiden,red111,vtkmybr,gamecocks,gumper,bosshogg,4me2know,tokyo1,kleaner,roadhog,fuckmeno,phoenix3,seeme,buttnutt,boner69,andreyka,myheart,katerin,rugburn,jvtuepip,dc3ubn,chile1,ashley69,happy99,swissair,balls2,fylhttdf,jimboo,55555d,mickey11,voronin,m7hsqstm,stufff,merete,weihnachte,dowjones,baloo1,freeones,bears34,auburn1,beverl,timberland,1elvis,guinness1,bombadil,flatron1,logging7,telefoon,merl1n,masha1,andrei1,cowabung,yousuck1,1matrix,peopl,asd123qwe,sweett,mirror1,torrente,joker12,diamond6,jackaroo,00000a,millerlite,ironhorse,2twins,stryke,gggg1,zzzxxxccc,roosevel,8363eddy,angel21,depeche1,d0ct0r,blue14,areyou,veloce,grendal,frederiksberg,cbcntvf,cb207sl,sasha2000,was.here,fritzz,rosedale,spinoza,cokeisit,gandalf3,skidmark,ashley01,12345j,1234567890qaz,sexxxxxx,beagles,lennart,12345789,pass10,politic,max007,gcheckou,12345611,tiffy,lightman,mushin,velosiped,brucewayne,gauthie,elena123,greenegg,h2oski,clocker,nitemare,123321s,megiddo,cassidy1,david13,boywonde,flori,peggy12,pgszt6md,batterie,redlands,scooter6,bckhere,trueno,bailey11,maxwell2,bandana,timoth1,startnow,ducati74,tiern,maxine1,blackmetal,suzyq,balla007,phatfarm,kirsten1,titmouse,benhogan,culito,forbin,chess1,warren1,panman,mickey7,24lover,dascha,speed2,redlion,andrew10,johnwayn,nike23,chacha1,bendog,bullyboy,goldtree,spookie,tigger99,1cookie,poutine,cyclone1,woodpony,camaleun,bluesky1,dfadan,eagles20,lovergirl,peepshow,mine1,dima1989,rjdfkmxer,11111aaaaa,machina,august17,1hhhhh,0773417k,1monster,freaksho,jazzmin,davidw,kurupt,chumly,huggies,sashenka,ccccccc1,bridge1,giggalo,cincinna,pistol1,hello22,david77,lightfoo,lucky6,jimmy12,261397,lisa12,tabaluga,mysite,belo4ka,greenn,eagle99,punkrawk,salvado,slick123,wichsen,knight99,dummys,fefolico,contrera,kalle1,anna1984,delray,robert99,garena,pretende,racefan,alons,serenada,ludmilla,cnhtkjr,l0swf9gx,hankster,dfktynbyrf,sheep1,john23,cv141ab,kalyani,944turbo,crystal2,blackfly,zrjdktdf,eus1sue1,mario5,riverplate,harddriv,melissa3,elliott1,sexybitc,cnhfyybr,jimdavis,bollix,beta1,amberlee,skywalk1,natala,1blood,brattax,shitty1,gb15kv99,ronjon,rothmans,thedoc,joey21,hotboi,firedawg,bimbo38,jibber,aftermat,nomar,01478963,phishing,domodo,anna13,materia,martha1,budman1,gunblade,exclusiv,sasha1997,anastas,rebecca2,fackyou,kallisti,fuckmyass,norseman,ipswich1,151500,1edward,intelinside,darcy1,bcrich,yjdjcnbf,failte,buzzzz,cream1,tatiana1,7eleven,green8,153351,1a2s3d4f5g6h,154263,milano1,bambi1,bruins77,rugby2,jamal1,bolita,sundaypunch,bubba12,realmadr,vfyxtcnth,iwojima,notlob,black666,valkiria,nexus1,millerti,birthday100,swiss1,appollo,gefest,greeneyes,celebrat,tigerr,slava123,izumrud,bubbabub,legoman,joesmith,katya123,sweetdream,john44,wwwwwww1,oooooo1,socal,lovespor,s5r8ed67s,258147,heidis,cowboy22,wachovia,michaelb,qwe1234567,i12345,255225,goldie1,alfa155,45colt,safeu851,antonova,longtong,1sparky,gfvznm,busen,hjlbjy,whateva,rocky4,cokeman,joshua3,kekskek1,sirocco,jagman,123456qwert,phinupi,thomas10,loller,sakur,vika2011,fullred,mariska,azucar,ncstate,glenn74,halima,aleshka,ilovemylife,verlaat,baggie,scoubidou6,phatboy,jbruton,scoop1,barney11,blindman,def456,maximus2,master55,nestea,11223355,diego123,sexpistols,sniffy,philip1,f12345,prisonbreak,nokia2700,ajnjuhfa,yankees3,colfax,ak470000,mtnman,bdfyeirf,fotball,ichbin,trebla,ilusha,riobravo,beaner1,thoradin,polkaudi,kurosawa,honda123,ladybu,valerik,poltava,saviola,fuckyouguys,754740g0,anallove,microlab1,juris01,ncc1864,garfild,shania1,qagsud,makarenko,cindy69,lebedev,andrew11,johnnybo,groovy1,booster1,sanders1,tommyb,johnson4,kd189nlcih,hondaman,vlasova,chick1,sokada,sevisgur,bear2327,chacho,sexmania,roma1993,hjcnbckfd,valley1,howdie,tuppence,jimandanne,strike3,y4kuz4,nhfnfnf,tsubasa,19955991,scabby,quincunx,dima1998,uuuuuu1,logica,skinner1,pinguino,lisa1234,xpressmusic,getfucked,qqqq1,bbbb1,matulino,ulyana,upsman,johnsmith,123579,co2000,spanner1,todiefor,mangoes,isabel1,123852,negra,snowdon,nikki123,bronx1,booom,ram2500,chuck123,fireboy,creek1,batman13,princesse,az12345,maksat,1knight,28infern,241455,r7112s,muselman,mets1986,katydid,vlad777,playme,kmfdm1,asssex,1prince,iop890,bigbroth,mollymoo,waitron,lizottes,125412,juggler,quinta,0sister0,zanardi,nata123,heckfyxbr,22q04w90e,engine2,nikita95,zamira,hammer22,lutscher,carolina1,zz6319,sanman,vfuflfy,buster99,rossco,kourniko,aggarwal,tattoo1,janice1,finger1,125521,19911992,shdwlnds,rudenko,vfvfgfgf123,galatea,monkeybu,juhani,premiumcash,classact,devilmay,helpme2,knuddel,hardpack,ramil,perrit,basil1,zombie13,stockcar,tos8217,honeypie,nowayman,alphadog,melon1,talula,125689,tiribon12,tornike,haribol,telefone,tiger22,sucka,lfytxrf,chicken123,muggins,a23456,b1234567,lytdybr,otter1,pippa,vasilisk,cooking1,helter,78978,bestboy,viper7,ahmed1,whitewol,mommys,apple5,shazam1,chelsea7,kumiko,masterma,rallye,bushmast,jkz123,entrar,andrew6,nathan01,alaric,tavasz,heimdall,gravy1,jimmy99,cthlwt,powerr,gthtrhtcnjr,canesfan,sasha11,ybrbnf_25,august9,brucie,artichok,arnie1,superdude,tarelka,mickey22,dooper,luners,holeshot,good123,gettysbu,bicho,hammer99,divine5,1zxcvbn,stronzo,q22222,disne,bmw750il,godhead,hallodu,aerith,nastik,differen,cestmoi,amber69,5string,pornosta,dirtygirl,ginger123,formel1,scott12,honda200,hotspurs,johnatha,firstone123,lexmark1,msconfig,karlmasc,l123456,123qweasdzx,baldman,sungod,furka,retsub,9811020,ryder1,tcglyued,astron,lbvfcbr,minddoc,dirt49,baseball12,tbear,simpl,schuey,artimus,bikman,plat1num,quantex,gotyou,hailey1,justin01,ellada,8481068,000002,manimal,dthjybxrf,buck123,dick123,6969696,nospam,strong1,kodeord,bama12,123321w,superman123,gladiolus,nintend,5792076,dreamgirl,spankme1,gautam,arianna1,titti,tetas,cool1234,belladog,importan,4206969,87e5nclizry,teufelo7,doller,yfl.irf,quaresma,3440172,melis,bradle,nnmaster,fast1,iverso,blargh,lucas12,chrisg,iamsam,123321az,tomjerry,kawika,2597174,standrew,billyg,muskan,gizmodo2,rz93qpmq,870621345,sathya,qmezrxg4,januari,marthe,moom4261,cum2me,hkger286,lou1988,suckit1,croaker,klaudia1,753951456,aidan1,fsunoles,romanenko,abbydog,isthebes,akshay,corgi,fuck666,walkman555,ranger98,scorpian,hardwareid,bluedragon,fastman,2305822q,iddqdiddqd,1597532,gopokes,zvfrfcb,w1234567,sputnik1,tr1993,pa$$w0rd,2i5fdruv,havvoc,1357913,1313131,bnm123,cowd00d,flexscan,thesims2,boogiema,bigsexxy,powerstr,ngc4565,joshman,babyboy1,123jlb,funfunfu,qwe456,honor1,puttana,bobbyj,daniel21,pussy12,shmuck,1232580,123578951,maxthedo,hithere1,bond0007,gehenna,nomames,blueone,r1234567,bwana,gatinho,1011111,torrents,cinta,123451234,tiger25,money69,edibey,pointman,mmcm19,wales1,caffreys,phaedra,bloodlus,321ret32,rufuss,tarbit,joanna1,102030405,stickboy,lotrfotr34,jamshid,mclarenf1,ataman,99ford,yarrak,logan2,ironlung,pushistik,dragoon1,unclebob,tigereye,pinokio,tylerj,mermaid1,stevie1,jaylen,888777,ramana,roman777,brandon7,17711771s,thiago,luigi1,edgar1,brucey,videogam,classi,birder,faramir,twiddle,cubalibre,grizzy,fucky,jjvwd4,august15,idinahui,ranita,nikita1998,123342,w1w2w3,78621323,4cancel,789963,(null,vassago,jaydog472,123452,timt42,canada99,123589,rebenok,htyfnf,785001,osipov,maks123,neverwinter,love2010,777222,67390436,eleanor1,bykemo,aquemini,frogg,roboto,thorny,shipmate,logcabin,66005918,nokian,gonzos,louisian,1abcdefg,triathlo,ilovemar,couger,letmeino,supera,runvs,fibonacci,muttly,58565254,5thgbqi,vfnehsv,electr,jose12,artemis1,newlove,thd1shr,hawkey,grigoryan,saisha,tosca,redder,lifesux,temple1,bunnyman,thekids,sabbeth,tarzan1,182838,158uefas,dell50,1super,666222,47ds8x,jackhamm,mineonly,rfnfhbyf,048ro,665259,kristina1,bombero,52545856,secure1,bigloser,peterk,alex2,51525354,anarchy1,superx,teenslut,money23,sigmapi,sanfrancisco,acme34,private5,eclips,qwerttrewq,axelle,kokain,hardguy,peter69,jesuschr,dyanna,dude69,sarah69,toyota91,amberr,45645645,bugmenot,bigted,44556677,556644,wwr8x9pu,alphaome,harley13,kolia123,wejrpfpu,revelati,nairda,sodoff,cityboy,pinkpussy,dkalis,miami305,wow12345,triplet,tannenbau,asdfasdf1,darkhors,527952,retired1,soxfan,nfyz123,37583867,goddes,515069,gxlmxbewym,1warrior,36925814,dmb2011,topten,karpova,89876065093rax,naturals,gateway9,cepseoun,turbot,493949,cock22,italia1,sasafras,gopnik,stalke,1qazxdr5,wm2006,ace1062,alieva,blue28,aracel,sandia,motoguzz,terri1,emmajane,conej,recoba,alex1995,jerkyboy,cowboy12,arenrone,precisio,31415927,scsa316,panzer1,studly1,powerhou,bensam,mashoutq,billee,eeyore1,reape,thebeatl,rul3z,montesa,doodle1,cvzefh1gk,424365,a159753,zimmerma,gumdrop,ashaman,grimreap,icandoit,borodina,branca,dima2009,keywest1,vaders,bubluk,diavolo,assss,goleta,eatass,napster1,382436,369741,5411pimo,lenchik,pikach,gilgamesh,kalimera,singer1,gordon2,rjycnbnewbz,maulwurf,joker13,2much4u,bond00,alice123,robotec,fuckgirl,zgjybz,redhorse,margaret1,brady1,pumpkin2,chinky,fourplay,1booger,roisin,1brandon,sandan,blackheart,cheez,blackfin,cntgfyjdf,mymoney1,09080706,goodboss,sebring1,rose1,kensingt,bigboner,marcus12,ym3cautj,struppi,thestone,lovebugs,stater,silver99,forest99,qazwsx12345,vasile,longboar,mkonji,huligan,rhfcbdfz,airmail,porn11,1ooooo,sofun,snake2,msouthwa,dougla,1iceman,shahrukh,sharona,dragon666,france98,196800,196820,ps253535,zjses9evpa,sniper01,design1,konfeta,jack99,drum66,good4you,station2,brucew,regedit,school12,mvtnr765,pub113,fantas,tiburon1,king99,ghjcnjgbpltw,checkito,308win,1ladybug,corneliu,svetasveta,197430,icicle,imaccess,ou81269,jjjdsl,brandon6,bimbo1,smokee,piccolo1,3611jcmg,children2,cookie2,conor1,darth1,margera,aoi856,paully,ou812345,sklave,eklhigcz,30624700,amazing1,wahooo,seau55,1beer,apples2,chulo,dolphin9,heather6,198206,198207,hergood,miracle1,njhyflj,4real,milka,silverfi,fabfive,spring12,ermine,mammy,jumpjet,adilbek,toscana,caustic,hotlove,sammy69,lolita1,byoung,whipme,barney01,mistys,tree1,buster3,kaylin,gfccgjhn,132333,aishiteru,pangaea,fathead1,smurph,198701,ryslan,gasto,xexeylhf,anisimov,chevyss,saskatoo,brandy12,tweaker,irish123,music2,denny1,palpatin,outlaw1,lovesuck,woman1,mrpibb,diadora,hfnfneq,poulette,harlock,mclaren1,cooper12,newpass3,bobby12,rfgecnfcerf,alskdjfh,mini14,dukers,raffael,199103,cleo123,1234567qwertyu,mossberg,scoopy,dctulf,starline,hjvjxrf,misfits1,rangers2,bilbos,blackhea,pappnase,atwork,purple2,daywalker,summoner,1jjjjjjj,swansong,chris10,laluna,12345qqq,charly1,lionsden,money99,silver33,hoghead,bdaddy,199430,saisg002,nosaints,tirpitz,1gggggg,jason13,kingss,ernest1,0cdh0v99ue,pkunzip,arowana,spiri,deskjet1,armine,lances,magic2,thetaxi,14159265,cacique,14142135,orange10,richard0,backdraf,255ooo,humtum,kohsamui,c43dae874d,wrestling1,cbhtym,sorento,megha,pepsiman,qweqwe12,bliss7,mario64,korolev,balls123,schlange,gordit,optiquest,fatdick,fish99,richy,nottoday,dianne1,armyof1,1234qwerasdfzxcv,bbonds,aekara,lidiya,baddog1,yellow5,funkie,ryan01,greentree,gcheckout,marshal1,liliput,000000z,rfhbyrf,gtogto43,rumpole,tarado,marcelit,aqwzsxedc,kenshin1,sassydog,system12,belly1,zilla,kissfan,tools1,desember,donsdad,nick11,scorpio6,poopoo1,toto99,steph123,dogfuck,rocket21,thx113,dude12,sanek,sommar,smacky,pimpsta,letmego,k1200rs,lytghjgtnhjdcr,abigale,buddog,deles,baseball9,roofus,carlsbad,hamzah,hereiam,genial,schoolgirlie,yfz450,breads,piesek,washear,chimay,apocalyp,nicole18,gfgf1234,gobulls,dnevnik,wonderwall,beer1234,1moose,beer69,maryann1,adpass,mike34,birdcage,hottuna,gigant,penquin,praveen,donna123,123lol123,thesame,fregat,adidas11,selrahc,pandoras,test3,chasmo,111222333000,pecos,daniel11,ingersol,shana1,mama12345,cessna15,myhero,1simpson,nazarenko,cognit,seattle2,irina1,azfpc310,rfycthdf,hardy1,jazmyn,sl1200,hotlanta,jason22,kumar123,sujatha,fsd9shtyu,highjump,changer,entertai,kolding,mrbig,sayuri,eagle21,qwertzu,jorge1,0101dd,bigdong,ou812a,sinatra1,htcnjhfy,oleg123,videoman,pbyfblf,tv612se,bigbird1,kenaidog,gunite,silverma,ardmore,123123qq,hotbot,cascada,cbr600f4,harakiri,chico123,boscos,aaron12,glasgow1,kmn5hc,lanfear,1light,liveoak,fizika,ybrjkftdyf,surfside,intermilan,multipas,redcard,72chevy,balata,coolio1,schroede,kanat,testerer,camion,kierra,hejmeddig,antonio2,tornados,isidor,pinkey,n8skfswa,ginny1,houndog,1bill,chris25,hastur,1marine,greatdan,french1,hatman,123qqq,z1z2z3z4,kicker1,katiedog,usopen,smith22,mrmagoo,1234512i,assa123,7seven7,monster7,june12,bpvtyf,149521,guenter,alex1985,voronina,mbkugegs,zaqwsxcderfv,rusty5,mystic1,master0,abcdef12,jndfkb,r4zpm3,cheesey,skripka,blackwhite,sharon69,dro8smwq,lektor,techman,boognish,deidara,heckfyf,quietkey,authcode,monkey4,jayboy,pinkerto,merengue,chulita,bushwick,turambar,kittykit,joseph2,dad123,kristo,pepote,scheiss,hambone1,bigballa,restaura,tequil,111luzer,euro2000,motox,denhaag,chelsi,flaco1,preeti,lillo,1001sin,passw,august24,beatoff,555555d,willis1,kissthis,qwertyz,rvgmw2gl,iloveboobies,timati,kimbo,msinfo,dewdrop,sdbaker,fcc5nky2,messiah1,catboy,small1,chode,beastie1,star77,hvidovre,short1,xavie,dagobah,alex1987,papageno,dakota2,toonami,fuerte,jesus33,lawina,souppp,dirtybir,chrish,naturist,channel1,peyote,flibble,gutentag,lactate,killem,zucchero,robinho,ditka,grumpy1,avr7000,boxxer,topcop,berry1,mypass1,beverly1,deuce1,9638527410,cthuttdf,kzkmrf,lovethem,band1t,cantona1,purple11,apples123,wonderwo,123a456,fuzzie,lucky99,dancer2,hoddling,rockcity,winner12,spooty,mansfiel,aimee1,287hf71h,rudiger,culebra,god123,agent86,daniel0,bunky1,notmine,9ball,goofus,puffy1,xyh28af4,kulikov,bankshot,vurdf5i2,kevinm,ercole,sexygirls,razvan,october7,goater,lollie,raissa,thefrog,mdmaiwa3,mascha,jesussaves,union1,anthony9,crossroa,brother2,areyuke,rodman91,toonsex,dopeman,gericom,vaz2115,cockgobbler,12356789,12345699,signatur,alexandra1,coolwhip,erwin1,awdrgyjilp,pens66,ghjrjgtyrj,linkinpark,emergenc,psych0,blood666,bootmort,wetworks,piroca,johnd,iamthe1,supermario,homer69,flameon,image1,bebert,fylhtq1,annapoli,apple11,hockey22,10048,indahouse,mykiss,1penguin,markp,misha123,foghat,march11,hank1,santorin,defcon4,tampico,vbnhjafy,robert22,bunkie,athlon64,sex777,nextdoor,koskesh,lolnoob,seemnemaailm,black23,march15,yeehaa,chiqui,teagan,siegheil,monday2,cornhusk,mamusia,chilis,sthgrtst,feldspar,scottm,pugdog,rfghjy,micmac,gtnhjdyf,terminato,1jackson,kakosja,bogomol,123321aa,rkbvtyrj,tresor,tigertig,fuckitall,vbkkbjy,caramon,zxc12,balin,dildo1,soccer09,avata,abby123,cheetah1,marquise,jennyc,hondavfr,tinti,anna1985,dennis2,jorel,mayflowe,icema,hal2000,nikkis,bigmouth,greenery,nurjan,leonov,liberty7,fafnir,larionov,sat321321,byteme1,nausicaa,hjvfynbrf,everto,zebra123,sergio1,titone,wisdom1,kahala,104328q,marcin1,salima,pcitra,1nnnnn,nalini,galvesto,neeraj,rick1,squeeky,agnes1,jitterbu,agshar,maria12,0112358,traxxas,stivone,prophet1,bananza,sommer1,canoneos,hotfun,redsox11,1bigmac,dctdjkjl,legion1,everclea,valenok,black9,danny001,roxie1,1theman,mudslide,july16,lechef,chula,glamis,emilka,canbeef,ioanna,cactus1,rockshox,im2cool,ninja9,thvfrjdf,june28,milo17,missyou,micky1,nbibyf,nokiaa,goldi,mattias,fuckthem,asdzxc123,ironfist,junior01,nesta,crazzy,killswit,hygge,zantac,kazama,melvin1,allston,maandag,hiccup,prototyp,specboot,dwl610,hello6,159456,baldhead,redwhite,calpoly,whitetail,agile1,cousteau,matt01,aust1n,malcolmx,gjlfhjr,semperf1,ferarri,a1b2c3d,vangelis,mkvdari,bettis36,andzia,comand,tazzman,morgaine,pepluv,anna1990,inandout,anetka,anna1997,wallpape,moonrake,huntress,hogtie,cameron7,sammy7,singe11,clownboy,newzeala,wilmar,safrane,rebeld,poopi,granat,hammertime,nermin,11251422,xyzzy1,bogeys,jkmxbr,fktrcfyl,11223311,nfyrbcn,11223300,powerpla,zoedog,ybrbnbyf,zaphod42,tarawa,jxfhjdfirf,dude1234,g5wks9,goobe,czekolada,blackros,amaranth,medical1,thereds,julija,nhecsyfujkjdt,promopas,buddy4,marmalad,weihnachten,tronic,letici,passthief,67mustan,ds7zamnw,morri,w8woord,cheops,pinarell,sonofsam,av473dv,sf161pn,5c92v5h6,purple13,tango123,plant1,1baby,xufrgemw,fitta,1rangers,spawns,kenned,taratata,19944991,11111118,coronas,4ebouux8,roadrash,corvette1,dfyjdf846,marley12,qwaszxerdfcv,68stang,67stang,racin,ellehcim,sofiko,nicetry,seabass1,jazzman1,zaqwsx1,laz2937,uuuuuuu1,vlad123,rafale,j1234567,223366,nnnnnn1,226622,junkfood,asilas,cer980,daddymac,persepho,neelam,00700,shithappens,255555,qwertyy,xbox36,19755791,qweasd1,bearcub,jerryb,a1b1c1,polkaudio,basketball1,456rty,1loveyou,marcus2,mama1961,palace1,transcend,shuriken,sudhakar,teenlove,anabelle,matrix99,pogoda,notme,bartend,jordana,nihaoma,ataris,littlegi,ferraris,redarmy,giallo,fastdraw,accountbloc,peludo,pornostar,pinoyako,cindee,glassjaw,dameon,johnnyd,finnland,saudade,losbravo,slonko,toplay,smalltit,nicksfun,stockhol,penpal,caraj,divedeep,cannibus,poppydog,pass88,viktory,walhalla,arisia,lucozade,goldenbo,tigers11,caball,ownage123,tonna,handy1,johny,capital5,faith2,stillher,brandan,pooky1,antananarivu,hotdick,1justin,lacrimos,goathead,bobrik,cgtwbfkbcn,maywood,kamilek,gbplf123,gulnar,beanhead,vfvjyn,shash,viper69,ttttttt1,hondacr,kanako,muffer,dukies,justin123,agapov58,mushka,bad11bad,muleman,jojo123,andreika,makeit,vanill,boomers,bigals,merlin11,quacker,aurelien,spartak1922,ligeti,diana2,lawnmowe,fortune1,awesom,rockyy,anna1994,oinker,love88,eastbay,ab55484,poker0,ozzy666,papasmurf,antihero,photogra,ktm250,painkill,jegr2d2,p3orion,canman,dextur,qwest123,samboy,yomismo,sierra01,herber,vfrcbvvfrcbv,gloria1,llama1,pie123,bobbyjoe,buzzkill,skidrow,grabber,phili,javier1,9379992q,geroin,oleg1994,sovereig,rollover,zaq12qaz,battery1,killer13,alina123,groucho1,mario12,peter22,butterbean,elise1,lucycat,neo123,ferdi,golfer01,randie,gfhfyjbr,ventura1,chelsea3,pinoy,mtgox,yrrim7,shoeman,mirko,ffggyyo,65mustan,ufdibyjd,john55,suckfuck,greatgoo,fvfnjhb,mmmnnn,love20,1bullshi,sucesso,easy1234,robin123,rockets1,diamondb,wolfee,nothing0,joker777,glasnost,richar1,guille,sayan,koresh,goshawk,alexx,batman21,a123456b,hball,243122,rockandr,coolfool,isaia,mary1,yjdbrjdf,lolopc,cleocat,cimbo,lovehina,8vfhnf,passking,bonapart,diamond2,bigboys,kreator,ctvtyjdf,sassy123,shellac,table54781,nedkelly,philbert,sux2bu,nomis,sparky99,python1,littlebear,numpty,silmaril,sweeet,jamesw,cbufhtnf,peggysue,wodahs,luvsex,wizardry,venom123,love4you,bama1,samat,reviewpass,ned467,cjkjdtq,mamula,gijoe,amersham,devochka,redhill,gisel,preggo,polock,cando,rewster,greenlantern,panasonik,dave1234,mikeee,1carlos,miledi,darkness1,p0o9i8u7y6,kathryn1,happyguy,dcp500,assmaster,sambuka,sailormo,antonio3,logans,18254288,nokiax2,qwertzuiop,zavilov,totti,xenon1,edward11,targa1,something1,tony_t,q1w2e3r4t5y6u7i8o9p0,02551670,vladimir1,monkeybutt,greenda,neel21,craiger,saveliy,dei008,honda450,fylhtq95,spike2,fjnq8915,passwordstandard,vova12345,talonesi,richi,gigemags,pierre1,westin,trevoga,dorothee,bastogne,25563o,brandon3,truegrit,krimml,iamgreat,servis,a112233,paulinka,azimuth,corperfmonsy,358hkyp,homerun1,dogbert1,eatmyass,cottage1,savina,baseball7,bigtex,gimmesum,asdcxz,lennon1,a159357,1bastard,413276191q,pngfilt,pchealth,netsnip,bodiroga,1matt,webtvs,ravers,adapters,siddis,mashamasha,coffee2,myhoney,anna1982,marcia1,fairchil,maniek,iloveluc,batmonh,wildon,bowie1,netnwlnk,fancy1,tom204,olga1976,vfif123,queens1,ajax01,lovess,mockba,icam4usb,triada,odinthor,rstlne,exciter,sundog,anchorat,girls69,nfnmzyrf,soloma,gti16v,shadowman,ottom,rataros,tonchin,vishal,chicken0,pornlo,christiaan,volante,likesit,mariupol,runfast,gbpltw123,missys,villevalo,kbpjxrf,ghibli,calla,cessna172,kinglear,dell11,swift1,walera,1cricket,pussy5,turbo911,tucke,maprchem56458,rosehill,thekiwi1,ygfxbkgt,mandarinka,98xa29,magnit,cjfrf,paswoord,grandam1,shenmue,leedsuni,hatrick,zagadka,angeldog,michaell,dance123,koichi,bballs,29palms,xanth,228822,ppppppp1,1kkkkk,1lllll,mynewbots,spurss,madmax1,224455,city1,mmmmmmm1,nnnnnnn1,biedronka,thebeatles,elessar,f14tomcat,jordan18,bobo123,ayi000,tedbear,86chevyx,user123,bobolink,maktub,elmer1,flyfishi,franco1,gandalf0,traxdata,david21,enlighte,dmitrij,beckys,1giants,flippe,12345678w,jossie,rugbyman,snowcat,rapeme,peanut11,gemeni,udders,techn9ne,armani1,chappie,war123,vakantie,maddawg,sewanee,jake5253,tautt1,anthony5,letterma,jimbo2,kmdtyjr,hextall,jessica6,amiga500,hotcunt,phoenix9,veronda,saqartvelo,scubas,sixer3,williamj,nightfal,shihan,melnikova,kosssss,handily,killer77,jhrl0821,march17,rushman,6gcf636i,metoyou,irina123,mine11,primus1,formatters,matthew5,infotech,gangster1,jordan45,moose69,kompas,motoxxx,greatwhi,cobra12,kirpich,weezer1,hello23,montse,tracy123,connecte,cjymrf,hemingwa,azreal,gundam00,mobila,boxman,slayers1,ravshan,june26,fktrcfylhjd,bermuda1,tylerd,maersk,qazwsx11,eybdthcbntn,ash123,camelo,kat123,backd00r,cheyenne1,1king,jerkin,tnt123,trabant,warhammer40k,rambos,punto,home77,pedrito,1frank,brille,guitarman,george13,rakas,tgbxtcrbq,flute1,bananas1,lovezp1314,thespot,postie,buster69,sexytime,twistys,zacharia,sportage,toccata,denver7,terry123,bogdanova,devil69,higgins1,whatluck,pele10,kkk666,jeffery1,1qayxsw2,riptide1,chevy11,munchy,lazer1,hooker1,ghfgjh,vergesse,playgrou,4077mash,gusev,humpin,oneputt,hydepark,monster9,tiger8,tangsoo,guy123,hesoyam1,uhtqneyu,thanku,lomond,ortezza,kronik,geetha,rabbit66,killas,qazxswe,alabaste,1234567890qwerty,capone1,andrea12,geral,beatbox,slutfuck,booyaka,jasmine7,ostsee,maestro1,beatme,tracey1,buster123,donaldduck,ironfish,happy6,konnichi,gintonic,momoney1,dugan1,today2,enkidu,destiny2,trim7gun,katuha,fractals,morganstanley,polkadot,gotime,prince11,204060,fifa2010,bobbyt,seemee,amanda10,airbrush,bigtitty,heidie,layla1,cotton1,5speed,fyfnjkmtdyf,flynavy,joxury8f,meeko,akuma,dudley1,flyboy1,moondog1,trotters,mariami,signin,chinna,legs11,pussy4,1s1h1e1f1,felici,optimus1,iluvu,marlins1,gavaec,balance1,glock40,london01,kokot,southwes,comfort1,sammy11,rockbottom,brianc,litebeer,homero,chopsuey,greenlan,charit,freecell,hampster,smalldog,viper12,blofeld,1234567890987654321,realsex,romann,cartman2,cjdthitycndj,nelly1,bmw528,zwezda,masterba,jeep99,turtl,america2,sunburst,sanyco,auntjudy,125wm,blue10,qwsazx,cartma,toby12,robbob,red222,ilovecock,losfix16,1explore,helge,vaz2114,whynotme,baba123,mugen,1qazwsxedc,albertjr,0101198,sextime,supras,nicolas2,wantsex,pussy6,checkm8,winam,24gordon,misterme,curlew,gbljhfcs,medtech,franzi,butthea,voivod,blackhat,egoiste,pjkeirf,maddog69,pakalolo,hockey4,igor1234,rouges,snowhite,homefree,sexfreak,acer12,dsmith,blessyou,199410,vfrcbvjd,falco02,belinda1,yaglasph,april21,groundho,jasmin1,nevergiveup,elvir,gborv526,c00kie,emma01,awesome2,larina,mike12345,maximu,anupam,bltynbabrfwbz,tanushka,sukkel,raptor22,josh12,schalke04,cosmodog,fuckyou8,busybee,198800,bijoux,frame1,blackmor,giveit,issmall,bear13,123-123,bladez,littlegirl,ultra123,fletch1,flashnet,loploprock,rkelly,12step,lukas1,littlewhore,cuntfinger,stinkyfinger,laurenc,198020,n7td4bjl,jackie69,camel123,ben1234,1gateway,adelheid,fatmike,thuglove,zzaaqq,chivas1,4815162342q,mamadou,nadano,james22,benwin,andrea99,rjirf,michou,abkbgg,d50gnn,aaazzz,a123654,blankman,booboo11,medicus,bigbone,197200,justine1,bendix,morphius,njhvjp,44mag,zsecyus56,goodbye1,nokiadermo,a333444,waratsea,4rzp8ab7,fevral,brillian,kirbys,minim,erathia,grazia,zxcvb1234,dukey,snaggle,poppi,hymen,1video,dune2000,jpthjdf,cvbn123,zcxfcnkbdfz,astonv,ginnie,316271,engine3,pr1ncess,64chevy,glass1,laotzu,hollyy,comicbooks,assasins,nuaddn9561,scottsda,hfcnfvfy,accobra,7777777z,werty123,metalhead,romanson,redsand,365214,shalo,arsenii,1989cc,sissi,duramax,382563,petera,414243,mamapap,jollymon,field1,fatgirl,janets,trompete,matchbox20,rambo2,nepenthe,441232,qwertyuiop10,bozo123,phezc419hv,romantika,lifestyl,pengui,decembre,demon6,panther6,444888,scanman,ghjcnjabkz,pachanga,buzzword,indianer,spiderman3,tony12,startre,frog1,fyutk,483422,tupacshakur,albert12,1drummer,bmw328i,green17,aerdna,invisibl,summer13,calimer,mustaine,lgnu9d,morefun,hesoyam123,escort1,scrapland,stargat,barabbas,dead13,545645,mexicali,sierr,gfhfpbn,gonchar,moonstafa,searock,counte,foster1,jayhawk1,floren,maremma,nastya2010,softball1,adaptec,halloo,barrabas,zxcasd123,hunny,mariana1,kafedra,freedom0,green420,vlad1234,method7,665566,tooting,hallo12,davinchi,conducto,medias,666444,invernes,madhatter,456asd,12345678i,687887,le33px,spring00,help123,bellybut,billy5,vitalik1,river123,gorila,bendis,power666,747200,footslav,acehigh,qazxswedc123,q1a1z1,richard9,peterburg,tabletop,gavrilov,123qwe1,kolosov,fredrau,run4fun,789056,jkbvgbflf,chitra,87654321q,steve22,wideopen,access88,surfe,tdfyutkbjy,impossib,kevin69,880888,cantina,887766,wxcvb,dontforg,qwer1209,asslicke,mamma123,indig,arkasha,scrapp,morelia,vehxbr,jones2,scratch1,cody11,cassie12,gerbera,dontgotm,underhil,maks2010,hollywood1,hanibal,elena2010,jason11,1010321,stewar,elaman,fireplug,goodby,sacrific,babyphat,bobcat12,bruce123,1233215,tony45,tiburo,love15,bmw750,wallstreet,2h0t4me,1346795,lamerz,munkee,134679q,granvill,1512198,armastus,aiden1,pipeutvj,g1234567,angeleyes,usmc1,102030q,putangina,brandnew,shadowfax,eagles12,1falcon,brianw,lokomoti,2022958,scooper,pegas,jabroni1,2121212,buffal,siffredi,wewiz,twotone,rosebudd,nightwis,carpet1,mickey2,2525252,sleddog,red333,jamesm,2797349,jeff12,onizuka,felixxxx,rf6666,fine1,ohlala,forplay,chicago5,muncho,scooby11,ptichka,johnnn,19851985p,dogphil3650,totenkopf,monitor2,macross7,3816778,dudder,semaj1,bounder,racerx1,5556633,7085506,ofclr278,brody1,7506751,nantucke,hedj2n4q,drew1,aessedai,trekbike,pussykat,samatron,imani,9124852,wiley1,dukenukem,iampurehaha2,9556035,obvious1,mccool24,apache64,kravchenko,justforf,basura,jamese,s0ccer,safado,darksta,surfer69,damian1,gjpbnbd,gunny1,wolley,sananton,zxcvbn123456,odt4p6sv8,sergei1,modem1,mansikka,zzzz1,rifraf,dima777,mary69,looking4,donttell,red100,ninjutsu,uaeuaeman,bigbri,brasco,queenas8151,demetri,angel007,bubbl,kolort,conny,antonia1,avtoritet,kaka22,kailayu,sassy2,wrongway,chevy3,1nascar,patriots1,chrisrey,mike99,sexy22,chkdsk,sd3utre7,padawan,a6pihd,doming,mesohorny,tamada,donatello,emma22,eather,susan69,pinky123,stud69,fatbitch,pilsbury,thc420,lovepuss,1creativ,golf1234,hurryup,1honda,huskerdu,marino1,gowron,girl1,fucktoy,gtnhjpfdjlcr,dkjfghdk,pinkfl,loreli,7777777s,donkeykong,rockytop,staples1,sone4ka,xxxjay,flywheel,toppdogg,bigbubba,aaa123456,2letmein,shavkat,paule,dlanor,adamas,0147852,aassaa,dixon1,bmw328,mother12,ilikepussy,holly2,tsmith,excaliber,fhutynbyf,nicole3,tulipan,emanue,flyvholm,currahee,godsgift,antonioj,torito,dinky1,sanna,yfcnzvjz,june14,anime123,123321456654,hanswurst,bandman,hello101,xxxyyy,chevy69,technica,tagada,arnol,v00d00,lilone,filles,drumandbass,dinamit,a1234a,eatmeat,elway07,inout,james6,dawid1,thewolf,diapason,yodaddy,qscwdv,fuckit1,liljoe,sloeber,simbacat,sascha1,qwe1234,1badger,prisca,angel17,gravedig,jakeyboy,longboard,truskawka,golfer11,pyramid7,highspee,pistola,theriver,hammer69,1packers,dannyd,alfonse,qwertgfdsa,11119999,basket1,ghjtrn,saralee,12inches,paolo1,zse4xdr5,taproot,sophieh6,grizzlie,hockey69,danang,biggums,hotbitch,5alive,beloved1,bluewave,dimon95,koketka,multiscan,littleb,leghorn,poker2,delite,skyfir,bigjake,persona1,amberdog,hannah12,derren,ziffle,1sarah,1assword,sparky01,seymur,tomtom1,123321qw,goskins,soccer19,luvbekki,bumhole,2balls,1muffin,borodin,monkey9,yfeiybrb,1alex,betmen,freder,nigger123,azizbek,gjkzrjdf,lilmike,1bigdadd,1rock,taganrog,snappy1,andrey1,kolonka,bunyan,gomango,vivia,clarkkent,satur,gaudeamus,mantaray,1month,whitehea,fargus,andrew99,ray123,redhawks,liza2009,qw12345,den12345,vfhnsyjdf,147258369a,mazepa,newyorke,1arsenal,hondas2000,demona,fordgt,steve12,birthday2,12457896,dickster,edcwsxqaz,sahalin,pantyman,skinny1,hubertus,cumshot1,chiro,kappaman,mark3434,canada12,lichking,bonkers1,ivan1985,sybase,valmet,doors1,deedlit,kyjelly,bdfysx,ford11,throatfuck,backwood,fylhsq,lalit,boss429,kotova,bricky,steveh,joshua19,kissa,imladris,star1234,lubimka,partyman,crazyd,tobias1,ilike69,imhome,whome,fourstar,scanner1,ujhjl312,anatoli,85bears,jimbo69,5678ytr,potapova,nokia7070,sunday1,kalleank,1996gta,refinnej,july1,molodec,nothanks,enigm,12play,sugardog,nhfkbdfkb,larousse,cannon1,144444,qazxcdew,stimorol,jhereg,spawn7,143000,fearme,hambur,merlin21,dobie,is3yeusc,partner1,dekal,varsha,478jfszk,flavi,hippo1,9hmlpyjd,july21,7imjfstw,lexxus,truelov,nokia5200,carlos6,anais,mudbone,anahit,taylorc,tashas,larkspur,animal2000,nibiru,jan123,miyvarxar,deflep,dolore,communit,ifoptfcor,laura2,anadrol,mamaliga,mitzi1,blue92,april15,matveev,kajlas,wowlook1,1flowers,shadow14,alucard1,1golf,bantha,scotlan,singapur,mark13,manchester1,telus01,superdav,jackoff1,madnes,bullnuts,world123,clitty,palmer1,david10,spider10,sargsyan,rattlers,david4,windows2,sony12,visigoth,qqqaaa,penfloor,cabledog,camilla1,natasha123,eagleman,softcore,bobrov,dietmar,divad,sss123,d1234567,tlbyjhju,1q1q1q1,paraiso,dav123,lfiekmrf,drachen,lzhan16889,tplate,gfghbrf,casio1,123boots1,123test,sys64738,heavymetal,andiamo,meduza,soarer,coco12,negrita,amigas,heavymet,bespin,1asdfghj,wharfrat,wetsex,tight1,janus1,sword123,ladeda,dragon98,austin2,atep1,jungle1,12345abcd,lexus300,pheonix1,alex1974,123qw123,137955,bigtim,shadow88,igor1994,goodjob,arzen,champ123,121ebay,changeme1,brooksie,frogman1,buldozer,morrowin,achim,trish1,lasse,festiva,bubbaman,scottb,kramit,august22,tyson123,passsword,oompah,al123456,fucking1,green45,noodle1,looking1,ashlynn,al1716,stang50,coco11,greese,bob111,brennan1,jasonj,1cherry,1q2345,1xxxxxxx,fifa2011,brondby,zachar1,satyam,easy1,magic7,1rainbow,cheezit,1eeeeeee,ashley123,assass1,amanda123,jerbear,1bbbbbb,azerty12,15975391,654321z,twinturb,onlyone1,denis1988,6846kg3r,jumbos,pennydog,dandelion,haileris,epervier,snoopy69,afrodite,oldpussy,green55,poopypan,verymuch,katyusha,recon7,mine69,tangos,contro,blowme2,jade1,skydive1,fiveiron,dimo4ka,bokser,stargirl,fordfocus,tigers2,platina,baseball11,raque,pimper,jawbreak,buster88,walter34,chucko,penchair,horizon1,thecure1,scc1975,adrianna1,kareta,duke12,krille,dumbfuck,cunt1,aldebaran,laverda,harumi,knopfler,pongo1,pfhbyf,dogman1,rossigno,1hardon,scarlets,nuggets1,ibelieve,akinfeev,xfhkbr,athene,falcon69,happie,billly,nitsua,fiocco,qwerty09,gizmo2,slava2,125690,doggy123,craigs,vader123,silkeborg,124365,peterm,123978,krakatoa,123699,123592,kgvebmqy,pensacol,d1d2d3,snowstor,goldenboy,gfg65h7,ev700,church1,orange11,g0dz1ll4,chester3,acheron,cynthi,hotshot1,jesuschris,motdepass,zymurgy,one2one,fietsbel,harryp,wisper,pookster,nn527hp,dolla,milkmaid,rustyboy,terrell1,epsilon1,lillian1,dale3,crhbgrf,maxsim,selecta,mamada,fatman1,ufkjxrf,shinchan,fuckuall,women1,000008,bossss,greta1,rbhjxrf,mamasboy,purple69,felicidade,sexy21,cathay,hunglow,splatt,kahless,shopping1,1gandalf,themis,delta7,moon69,blue24,parliame,mamma1,miyuki,2500hd,jackmeof,razer,rocker1,juvis123,noremac,boing747,9z5ve9rrcz,icewater,titania,alley1,moparman,christo1,oliver2,vinicius,tigerfan,chevyy,joshua99,doda99,matrixx,ekbnrf,jackfrost,viper01,kasia,cnfhsq,triton1,ssbt8ae2,rugby8,ramman,1lucky,barabash,ghtlfntkm,junaid,apeshit,enfant,kenpo1,shit12,007000,marge1,shadow10,qwerty789,richard8,vbitkm,lostboys,jesus4me,richard4,hifive,kolawole,damilola,prisma,paranoya,prince2,lisaann,happyness,cardss,methodma,supercop,a8kd47v5,gamgee,polly123,irene1,number8,hoyasaxa,1digital,matthew0,dclxvi,lisica,roy123,2468013579,sparda,queball,vaffanculo,pass1wor,repmvbx,999666333,freedom8,botanik,777555333,marcos1,lubimaya,flash2,einstei,08080,123456789j,159951159,159357123,carrot1,alina1995,sanjos,dilara,mustang67,wisteria,jhnjgtl12,98766789,darksun,arxangel,87062134,creativ1,malyshka,fuckthemall,barsic,rocksta,2big4u,5nizza,genesis2,romance1,ofcourse,1horse,latenite,cubana,sactown,789456123a,milliona,61808861,57699434,imperia,bubba11,yellow3,change12,55495746,flappy,jimbo123,19372846,19380018,cutlass1,craig123,klepto,beagle1,solus,51502112,pasha1,19822891,46466452,19855891,petshop,nikolaevna,119966,nokia6131,evenpar,hoosier1,contrasena,jawa350,gonzo123,mouse2,115511,eetfuk,gfhfvgfvgfv,1crystal,sofaking,coyote1,kwiatuszek,fhrflbq,valeria1,anthro,0123654789,alltheway,zoltar,maasikas,wildchil,fredonia,earlgrey,gtnhjczy,matrix123,solid1,slavko,12monkeys,fjdksl,inter1,nokia6500,59382113kevinp,spuddy,cachero,coorslit,password!,kiba1z,karizma,vova1994,chicony,english1,bondra12,1rocket,hunden,jimbob1,zpflhjn1,th0mas,deuce22,meatwad,fatfree,congas,sambora,cooper2,janne,clancy1,stonie,busta,kamaz,speedy2,jasmine3,fahayek,arsenal0,beerss,trixie1,boobs69,luansantana,toadman,control2,ewing33,maxcat,mama1964,diamond4,tabaco,joshua0,piper2,music101,guybrush,reynald,pincher,katiebug,starrs,pimphard,frontosa,alex97,cootie,clockwor,belluno,skyeseth,booty69,chaparra,boochie,green4,bobcat1,havok,saraann,pipeman,aekdb,jumpshot,wintermu,chaika,1chester,rjnjatq,emokid,reset1,regal1,j0shua,134679a,asmodey,sarahh,zapidoo,ciccione,sosexy,beckham23,hornets1,alex1971,delerium,manageme,connor11,1rabbit,sane4ek,caseyboy,cbljhjdf,redsox20,tttttt99,haustool,ander,pantera6,passwd1,journey1,9988776655,blue135,writerspace,xiaoyua123,justice2,niagra,cassis,scorpius,bpgjldsgjldthnf,gamemaster,bloody1,retrac,stabbin,toybox,fight1,ytpyf.,glasha,va2001,taylor11,shameles,ladylove,10078,karmann,rodeos,eintritt,lanesra,tobasco,jnrhjqcz,navyman,pablit,leshka,jessica3,123vika,alena1,platinu,ilford,storm7,undernet,sasha777,1legend,anna2002,kanmax1994,porkpie,thunder0,gundog,pallina,easypass,duck1,supermom,roach1,twincam,14028,tiziano,qwerty32,123654789a,evropa,shampoo1,yfxfkmybr,cubby1,tsunami1,fktrcttdf,yasacrac,17098,happyhap,bullrun,rodder,oaktown,holde,isbest,taylor9,reeper,hammer11,julias,rolltide1,compaq123,fourx4,subzero1,hockey9,7mary3,busines,ybrbnjcbr,wagoneer,danniash,portishead,digitex,alex1981,david11,infidel,1snoopy,free30,jaden,tonto1,redcar27,footie,moskwa,thomas21,hammer12,burzum,cosmo123,50000,burltree,54343,54354,vwpassat,jack5225,cougars1,burlpony,blackhorse,alegna,petert,katemoss,ram123,nels0n,ferrina,angel77,cstock,1christi,dave55,abc123a,alex1975,av626ss,flipoff,folgore,max1998,science1,si711ne,yams7,wifey1,sveiks,cabin1,volodia,ox3ford,cartagen,platini,picture1,sparkle1,tiedomi,service321,wooody,christi1,gnasher,brunob,hammie,iraffert,bot2010,dtcyeirf,1234567890p,cooper11,alcoholi,savchenko,adam01,chelsea5,niewiem,icebear,lllooottt,ilovedick,sweetpus,money8,cookie13,rfnthbyf1988,booboo2,angus123,blockbus,david9,chica1,nazaret,samsung9,smile4u,daystar,skinnass,john10,thegirl,sexybeas,wasdwasd1,sigge1,1qa2ws3ed4rf5tg,czarny,ripley1,chris5,ashley19,anitha,pokerman,prevert,trfnthby,tony69,georgia2,stoppedb,qwertyuiop12345,miniclip,franky1,durdom,cabbages,1234567890o,delta5,liudmila,nhfycajhvths,court1,josiew,abcd1,doghead,diman,masiania,songline,boogle,triston,deepika,sexy4me,grapple,spacebal,ebonee,winter0,smokewee,nargiza,dragonla,sassys,andy2000,menards,yoshio,massive1,suckmy1k,passat99,sexybo,nastya1996,isdead,stratcat,hokuto,infix,pidoras,daffyduck,cumhard,baldeagl,kerberos,yardman,shibainu,guitare,cqub6553,tommyy,bk.irf,bigfoo,hecto,july27,james4,biggus,esbjerg,isgod,1irish,phenmarr,jamaic,roma1990,diamond0,yjdbrjd,girls4me,tampa1,kabuto,vaduz,hanse,spieng,dianochka,csm101,lorna1,ogoshi,plhy6hql,2wsx4rfv,cameron0,adebayo,oleg1996,sharipov,bouboule,hollister1,frogss,yeababy,kablam,adelante,memem,howies,thering,cecilia1,onetwo12,ojp123456,jordan9,msorcloledbr,neveraga,evh5150,redwin,1august,canno,1mercede,moody1,mudbug,chessmas,tiikeri,stickdaddy77,alex15,kvartira,7654321a,lollol123,qwaszxedc,algore,solana,vfhbyfvfhbyf,blue72,misha1111,smoke20,junior13,mogli,threee,shannon2,fuckmylife,kevinh,saransk,karenw,isolde,sekirarr,orion123,thomas0,debra1,laketaho,alondra,curiva,jazz1234,1tigers,jambos,lickme2,suomi,gandalf7,028526,zygote,brett123,br1ttany,supafly,159000,kingrat,luton1,cool-ca,bocman,thomasd,skiller,katter,mama777,chanc,tomass,1rachel,oldno7,rfpfyjdf,bigkev,yelrah,primas,osito,kipper1,msvcr71,bigboy11,thesun,noskcaj,chicc,sonja1,lozinka,mobile1,1vader,ummagumma,waves1,punter12,tubgtn,server1,irina1991,magic69,dak001,pandemonium,dead1,berlingo,cherrypi,1montana,lohotron,chicklet,asdfgh123456,stepside,ikmvw103,icebaby,trillium,1sucks,ukrnet,glock9,ab12345,thepower,robert8,thugstools,hockey13,buffon,livefree,sexpics,dessar,ja0000,rosenrot,james10,1fish,svoloch,mykitty,muffin11,evbukb,shwing,artem1992,andrey1992,sheldon1,passpage,nikita99,fubar123,vannasx,eight888,marial,max2010,express2,violentj,2ykn5ccf,spartan11,brenda69,jackiech,abagail,robin2,grass1,andy76,bell1,taison,superme,vika1995,xtr451,fred20,89032073168,denis1984,2000jeep,weetabix,199020,daxter,tevion,panther8,h9iymxmc,bigrig,kalambur,tsalagi,12213443,racecar02,jeffrey4,nataxa,bigsam,purgator,acuracl,troutbum,potsmoke,jimmyz,manutd1,nytimes,pureevil,bearss,cool22,dragonage,nodnarb,dbrbyu,4seasons,freude,elric1,werule,hockey14,12758698,corkie,yeahright,blademan,tafkap,clave,liziko,hofner,jeffhardy,nurich,runne,stanisla,lucy1,monk3y,forzaroma,eric99,bonaire,blackwoo,fengshui,1qaz0okm,newmoney,pimpin69,07078,anonymer,laptop1,cherry12,ace111,salsa1,wilbur1,doom12,diablo23,jgtxzbhr,under1,honda01,breadfan,megan2,juancarlos,stratus1,ackbar,love5683,happytim,lambert1,cbljhtyrj,komarov,spam69,nfhtkrf,brownn,sarmat,ifiksr,spike69,hoangen,angelz,economia,tanzen,avogadro,1vampire,spanners,mazdarx,queequeg,oriana,hershil,sulaco,joseph11,8seconds,aquariu,cumberla,heather9,anthony8,burton12,crystal0,maria3,qazwsxc,snow123,notgood,198520,raindog,heehaw,consulta,dasein,miller01,cthulhu1,dukenuke,iubire,baytown,hatebree,198505,sistem,lena12,welcome01,maraca,middleto,sindhu,mitsou,phoenix5,vovan,donaldo,dylandog,domovoy,lauren12,byrjuybnj,123llll,stillers,sanchin,tulpan,smallvill,1mmmmm,patti1,folgers,mike31,colts18,123456rrr,njkmrjz,phoenix0,biene,ironcity,kasperok,password22,fitnes,matthew6,spotligh,bujhm123,tommycat,hazel5,guitar11,145678,vfcmrf,compass1,willee,1barney,jack2000,littleminge,shemp,derrek,xxx12345,littlefuck,spuds1,karolinka,camneely,qwertyu123,142500,brandon00,munson15,falcon3,passssap,z3cn2erv,goahead,baggio10,141592,denali1,37kazoo,copernic,123456789asd,orange88,bravada,rush211,197700,pablo123,uptheass,samsam1,demoman,mattylad10,heydude,mister2,werken,13467985,marantz,a22222,f1f2f3f4,fm12mn12,gerasimova,burrito1,sony1,glenny,baldeagle,rmfidd,fenomen,verbati,forgetme,5element,wer138,chanel1,ooicu812,10293847qp,minicooper,chispa,myturn,deisel,vthrehbq,boredboi4u,filatova,anabe,poiuyt1,barmalei,yyyy1,fourkids,naumenko,bangbros,pornclub,okaykk,euclid90,warrior3,kornet,palevo,patatina,gocart,antanta,jed1054,clock1,111111w,dewars,mankind1,peugeot406,liten,tahira,howlin,naumov,rmracing,corone,cunthole,passit,rock69,jaguarxj,bumsen,197101,sweet2,197010,whitecat,sawadee,money100,yfhrjnbrb,andyboy,9085603566,trace1,fagget,robot1,angel20,6yhn7ujm,specialinsta,kareena,newblood,chingada,boobies2,bugger1,squad51,133andre,call06,ashes1,ilovelucy,success2,kotton,cavalla,philou,deebee,theband,nine09,artefact,196100,kkkkkkk1,nikolay9,onelov,basia,emilyann,sadman,fkrjujkbr,teamomuch,david777,padrino,money21,firdaus,orion3,chevy01,albatro,erdfcv,2legit,sarah7,torock,kevinn,holio,soloy,enron714,starfleet,qwer11,neverman,doctorwh,lucy11,dino12,trinity7,seatleon,o123456,pimpman,1asdfgh,snakebit,chancho,prorok,bleacher,ramire,darkseed,warhorse,michael123,1spanky,1hotdog,34erdfcv,n0th1ng,dimanche,repmvbyf,michaeljackson,login1,icequeen,toshiro,sperme,racer2,veget,birthday26,daniel9,lbvekmrf,charlus,bryan123,wspanic,schreibe,1andonly,dgoins,kewell,apollo12,egypt1,fernie,tiger21,aa123456789,blowj,spandau,bisquit,12345678d,deadmau5,fredie,311420,happyface,samant,gruppa,filmstar,andrew17,bakesale,sexy01,justlook,cbarkley,paul11,bloodred,rideme,birdbath,nfkbcvfy,jaxson,sirius1,kristof,virgos,nimrod1,hardc0re,killerbee,1abcdef,pitcher1,justonce,vlada,dakota99,vespucci,wpass,outside1,puertori,rfvbkf,teamlosi,vgfun2,porol777,empire11,20091989q,jasong,webuivalidat,escrima,lakers08,trigger2,addpass,342500,mongini,dfhtybr,horndogg,palermo1,136900,babyblu,alla98,dasha2010,jkelly,kernow,yfnecz,rockhopper,toeman,tlaloc,silver77,dave01,kevinr,1234567887654321,135642,me2you,8096468644q,remmus,spider7,jamesa,jilly,samba1,drongo,770129ji,supercat,juntas,tema1234,esthe,1234567892000,drew11,qazqaz123,beegees,blome,rattrace,howhigh,tallboy,rufus2,sunny2,sou812,miller12,indiana7,irnbru,patch123,letmeon,welcome5,nabisco,9hotpoin,hpvteb,lovinit,stormin,assmonke,trill,atlanti,money1234,cubsfan,mello1,stars2,ueptkm,agate,dannym88,lover123,wordz,worldnet,julemand,chaser1,s12345678,pissword,cinemax,woodchuc,point1,hotchkis,packers2,bananana,kalender,420666,penguin8,awo8rx3wa8t,hoppie,metlife,ilovemyfamily,weihnachtsbau,pudding1,luckystr,scully1,fatboy1,amizade,dedham,jahbless,blaat,surrende,****er,1panties,bigasses,ghjuhfvbcn,asshole123,dfktyrb,likeme,nickers,plastik,hektor,deeman,muchacha,cerebro,santana5,testdrive,dracula1,canalc,l1750sq,savannah1,murena,1inside,pokemon00,1iiiiiii,jordan20,sexual1,mailliw,calipso,014702580369,1zzzzzz,1jjjjjj,break1,15253545,yomama1,katinka,kevin11,1ffffff,martijn,sslazio,daniel5,porno2,nosmas,leolion,jscript,15975312,pundai,kelli1,kkkddd,obafgkm,marmaris,lilmama,london123,rfhfnt,elgordo,talk87,daniel7,thesims3,444111,bishkek,afrika2002,toby22,1speedy,daishi,2children,afroman,qqqqwwww,oldskool,hawai,v55555,syndicat,pukimak,fanatik,tiger5,parker01,bri5kev6,timexx,wartburg,love55,ecosse,yelena03,madinina,highway1,uhfdbwfgf,karuna,buhjvfybz,wallie,46and2,khalif,europ,qaz123wsx456,bobbybob,wolfone,falloutboy,manning18,scuba10,schnuff,ihateyou1,lindam,sara123,popcor,fallengun,divine1,montblanc,qwerty8,rooney10,roadrage,bertie1,latinus,lexusis,rhfvfnjhcr,opelgt,hitme,agatka,1yamaha,dmfxhkju,imaloser,michell1,sb211st,silver22,lockedup,andrew9,monica01,sassycat,dsobwick,tinroof,ctrhtnyj,bultaco,rhfcyjzhcr,aaaassss,14ss88,joanne1,momanddad,ahjkjdf,yelhsa,zipdrive,telescop,500600,1sexsex,facial1,motaro,511647,stoner1,temujin,elephant1,greatman,honey69,kociak,ukqmwhj6,altezza,cumquat,zippos,kontiki,123max,altec1,bibigon,tontos,qazsew,nopasaran,militar,supratt,oglala,kobayash,agathe,yawetag,dogs1,cfiekmrf,megan123,jamesdea,porosenok,tiger23,berger1,hello11,seemann,stunner1,walker2,imissu,jabari,minfd,lollol12,hjvfy,1-oct,stjohns,2278124q,123456789qwer,alex1983,glowworm,chicho,mallards,bluedevil,explorer1,543211,casita,1time,lachesis,alex1982,airborn1,dubesor,changa,lizzie1,captaink,socool,bidule,march23,1861brr,k.ljxrf,watchout,fotze,1brian,keksa2,aaaa1122,matrim,providian,privado,dreame,merry1,aregdone,davidt,nounour,twenty2,play2win,artcast2,zontik,552255,shit1,sluggy,552861,dr8350,brooze,alpha69,thunder6,kamelia2011,caleb123,mmxxmm,jamesh,lfybkjd,125267,125000,124536,bliss1,dddsss,indonesi,bob69,123888,tgkbxfgy,gerar,themack,hijodeputa,good4now,ddd123,clk430,kalash,tolkien1,132forever,blackb,whatis,s1s2s3s4,lolkin09,yamahar,48n25rcc,djtiesto,111222333444555,bigbull,blade55,coolbree,kelse,ichwill,yamaha12,sakic,bebeto,katoom,donke,sahar,wahine,645202,god666,berni,starwood,june15,sonoio,time123,llbean,deadsoul,lazarev,cdtnf,ksyusha,madarchod,technik,jamesy,4speed,tenorsax,legshow,yoshi1,chrisbl,44e3ebda,trafalga,heather7,serafima,favorite4,havefun1,wolve,55555r,james13,nosredna,bodean,jlettier,borracho,mickael,marinus,brutu,sweet666,kiborg,rollrock,jackson6,macross1,ousooner,9085084232,takeme,123qwaszx,firedept,vfrfhjd,jackfros,123456789000,briane,cookie11,baby22,bobby18,gromova,systemofadown,martin01,silver01,pimaou,darthmaul,hijinx,commo,chech,skyman,sunse,2vrd6,vladimirovna,uthvfybz,nicole01,kreker,bobo1,v123456789,erxtgb,meetoo,drakcap,vfvf12,misiek1,butane,network2,flyers99,riogrand,jennyk,e12345,spinne,avalon11,lovejone,studen,maint,porsche2,qwerty100,chamberl,bluedog1,sungam,just4u,andrew23,summer22,ludic,musiclover,aguil,beardog1,libertin,pippo1,joselit,patito,bigberth,digler,sydnee,jockstra,poopo,jas4an,nastya123,profil,fuesse,default1,titan2,mendoz,kpcofgs,anamika,brillo021,bomberman,guitar69,latching,69pussy,blues2,phelge,ninja123,m7n56xo,qwertasd,alex1976,cunningh,estrela,gladbach,marillion,mike2000,258046,bypop,muffinman,kd5396b,zeratul,djkxbwf,john77,sigma2,1linda,selur,reppep,quartz1,teen1,freeclus,spook1,kudos4ever,clitring,sexiness,blumpkin,macbook,tileman,centra,escaflowne,pentable,shant,grappa,zverev,1albert,lommerse,coffee11,777123,polkilo,muppet1,alex74,lkjhgfdsazx,olesica,april14,ba25547,souths,jasmi,arashi,smile2,2401pedro,mybabe,alex111,quintain,pimp1,tdeir8b2,makenna,122333444455555,%e2%82%ac,tootsie1,pass111,zaqxsw123,gkfdfybt,cnfnbcnbrf,usermane,iloveyou12,hard69,osasuna,firegod,arvind,babochka,kiss123,cookie123,julie123,kamakazi,dylan2,223355,tanguy,nbhtqa,tigger13,tubby1,makavel,asdflkj,sambo1,mononoke,mickeys,gayguy,win123,green33,wcrfxtvgbjy,bigsmall,1newlife,clove,babyfac,bigwaves,mama1970,shockwav,1friday,bassey,yarddog,codered1,victory7,bigrick,kracker,gulfstre,chris200,sunbanna,bertuzzi,begemotik,kuolema,pondus,destinee,123456789zz,abiodun,flopsy,amadeusptfcor,geronim,yggdrasi,contex,daniel6,suck1,adonis1,moorea,el345612,f22raptor,moviebuf,raunchy,6043dkf,zxcvbnm123456789,eric11,deadmoin,ratiug,nosliw,fannies,danno,888889,blank1,mikey2,gullit,thor99,mamiya,ollieb,thoth,dagger1,websolutionssu,bonker,prive,1346798520,03038,q1234q,mommy2,contax,zhipo,gwendoli,gothic1,1234562000,lovedick,gibso,digital2,space199,b26354,987654123,golive,serious1,pivkoo,better1,824358553,794613258,nata1980,logout,fishpond,buttss,squidly,good4me,redsox19,jhonny,zse45rdx,matrixxx,honey12,ramina,213546879,motzart,fall99,newspape,killit,gimpy,photowiz,olesja,thebus,marco123,147852963,bedbug,147369258,hellbound,gjgjxrf,123987456,lovehurt,five55,hammer01,1234554321a,alina2011,peppino,ang238,questor,112358132,alina1994,alina1998,money77,bobjones,aigerim,cressida,madalena,420smoke,tinchair,raven13,mooser,mauric,lovebu,adidas69,krypton1,1111112,loveline,divin,voshod,michaelm,cocotte,gbkbuhbv,76689295,kellyj,rhonda1,sweetu70,steamforums,geeque,nothere,124c41,quixotic,steam181,1169900,rfcgthcrbq,rfvbkm,sexstuff,1231230,djctvm,rockstar1,fulhamfc,bhecbr,rfntyf,quiksilv,56836803,jedimaster,pangit,gfhjkm777,tocool,1237654,stella12,55378008,19216811,potte,fender12,mortalkombat,ball1,nudegirl,palace22,rattrap,debeers,lickpussy,jimmy6,not4u2c,wert12,bigjuggs,sadomaso,1357924,312mas,laser123,arminia,branford,coastie,mrmojo,19801982,scott11,banaan123,ingres,300zxtt,hooters6,sweeties,19821983,19831985,19833891,sinnfein,welcome4,winner69,killerman,tachyon,tigre1,nymets1,kangol,martinet,sooty1,19921993,789qwe,harsingh,1597535,thecount,phantom3,36985214,lukas123,117711,pakistan1,madmax11,willow01,19932916,fucker12,flhrci,opelagila,theword,ashley24,tigger3,crazyj,rapide,deadfish,allana,31359092,sasha1993,sanders2,discman,zaq!2wsx,boilerma,mickey69,jamesg,babybo,jackson9,orion7,alina2010,indien,breeze1,atease,warspite,bazongaz,1celtic,asguard,mygal,fitzgera,1secret,duke33,cyklone,dipascuc,potapov,1escobar2,c0l0rad0,kki177hk,1little,macondo,victoriya,peter7,red666,winston6,kl?benhavn,muneca,jackme,jennan,happylife,am4h39d8nh,bodybuil,201980,dutchie,biggame,lapo4ka,rauchen,black10,flaquit,water12,31021364,command2,lainth88,mazdamx5,typhon,colin123,rcfhlfc,qwaszx11,g0away,ramir,diesirae,hacked1,cessna1,woodfish,enigma2,pqnr67w5,odgez8j3,grisou,hiheels,5gtgiaxm,2580258,ohotnik,transits,quackers,serjik,makenzie,mdmgatew,bryana,superman12,melly,lokit,thegod,slickone,fun4all,netpass,penhorse,1cooper,nsync,asdasd22,otherside,honeydog,herbie1,chiphi,proghouse,l0nd0n,shagg,select1,frost1996,casper123,countr,magichat,greatzyo,jyothi,3bears,thefly,nikkita,fgjcnjk,nitros,hornys,san123,lightspe,maslova,kimber1,newyork2,spammm,mikejone,pumpk1n,bruiser1,bacons,prelude9,boodie,dragon4,kenneth2,love98,power5,yodude,pumba,thinline,blue30,sexxybj,2dumb2live,matt21,forsale,1carolin,innova,ilikeporn,rbgtkjd,a1s2d3f,wu9942,ruffus,blackboo,qwerty999,draco1,marcelin,hideki,gendalf,trevon,saraha,cartmen,yjhbkmcr,time2go,fanclub,ladder1,chinni,6942987,united99,lindac,quadra,paolit,mainstre,beano002,lincoln7,bellend,anomie,8520456,bangalor,goodstuff,chernov,stepashka,gulla,mike007,frasse,harley03,omnislash,8538622,maryjan,sasha2011,gineok,8807031,hornier,gopinath,princesit,bdr529,godown,bosslady,hakaone,1qwe2,madman1,joshua11,lovegame,bayamon,jedi01,stupid12,sport123,aaa666,tony44,collect1,charliem,chimaira,cx18ka,trrim777,chuckd,thedream,redsox99,goodmorning,delta88,iloveyou11,newlife2,figvam,chicago3,jasonk,12qwer,9875321,lestat1,satcom,conditio,capri50,sayaka,9933162,trunks1,chinga,snooch,alexand1,findus,poekie,cfdbyf,kevind,mike1969,fire13,leftie,bigtuna,chinnu,silence1,celos1,blackdra,alex24,gfgfif,2boobs,happy8,enolagay,sataniv1993,turner1,dylans,peugeo,sasha1994,hoppel,conno,moonshot,santa234,meister1,008800,hanako,tree123,qweras,gfitymrf,reggie31,august29,supert,joshua10,akademia,gbljhfc,zorro123,nathalia,redsox12,hfpdjl,mishmash,nokiae51,nyyankees,tu190022,strongbo,none1,not4u2no,katie2,popart,harlequi,santan,michal1,1therock,screwu,csyekmrf,olemiss1,tyrese,hoople,sunshin1,cucina,starbase,topshelf,fostex,california1,castle1,symantec,pippolo,babare,turntabl,1angela,moo123,ipvteb,gogolf,alex88,cycle1,maxie1,phase2,selhurst,furnitur,samfox,fromvermine,shaq34,gators96,captain2,delonge,tomatoe,bisous,zxcvbnma,glacius,pineapple1,cannelle,ganibal,mko09ijn,paraklast1974,hobbes12,petty43,artema,junior8,mylover,1234567890d,fatal1ty,prostreet,peruan,10020,nadya,caution1,marocas,chanel5,summer08,metal123,111lox,scrapy,thatguy,eddie666,washingto,yannis,minnesota_hp,lucky4,playboy6,naumova,azzurro,patat,dale33,pa55wd,speedster,zemanova,saraht,newto,tony22,qscesz,arkady,1oliver,death6,vkfwx046,antiflag,stangs,jzf7qf2e,brianp,fozzy,cody123,startrek1,yoda123,murciela,trabajo,lvbnhbtdf,canario,fliper,adroit,henry5,goducks,papirus,alskdj,soccer6,88mike,gogetter,tanelorn,donking,marky1,leedsu,badmofo,al1916,wetdog,akmaral,pallet,april24,killer00,nesterova,rugby123,coffee12,browseui,ralliart,paigow,calgary1,armyman,vtldtltd,frodo2,frxtgb,iambigal,benno,jaytee,2hot4you,askar,bigtee,brentwoo,palladin,eddie2,al1916w,horosho,entrada,ilovetits,venture1,dragon19,jayde,chuvak,jamesl,fzr600,brandon8,vjqvbh,snowbal,snatch1,bg6njokf,pudder,karolin,candoo,pfuflrf,satchel1,manteca,khongbiet,critter1,partridg,skyclad,bigdon,ginger69,brave1,anthony4,spinnake,chinadol,passout,cochino,nipples1,15058,lopesk,sixflags,lloo999,parkhead,breakdance,cia123,fidodido,yuitre12,fooey,artem1995,gayathri,medin,nondriversig,l12345,bravo7,happy13,kazuya,camster,alex1998,luckyy,zipcode,dizzle,boating1,opusone,newpassw,movies23,kamikazi,zapato,bart316,cowboys0,corsair1,kingshit,hotdog12,rolyat,h200svrm,qwerty4,boofer,rhtyltkm,chris999,vaz21074,simferopol,pitboss,love3,britania,tanyshka,brause,123qwerty123,abeille,moscow1,ilkaev,manut,process1,inetcfg,dragon05,fortknox,castill,rynner,mrmike,koalas,jeebus,stockpor,longman,juanpabl,caiman,roleplay,jeremi,26058,prodojo,002200,magical1,black5,bvlgari,doogie1,cbhtqa,mahina,a1s2d3f4g5h6,jblpro,usmc01,bismilah,guitar01,april9,santana1,1234aa,monkey14,sorokin,evan1,doohan,animalsex,pfqxtyjr,dimitry,catchme,chello,silverch,glock45,dogleg,litespee,nirvana9,peyton18,alydar,warhamer,iluvme,sig229,minotavr,lobzik,jack23,bushwack,onlin,football123,joshua5,federov,winter2,bigmax,fufnfrhbcnb,hfpldfnhb,1dakota,f56307,chipmonk,4nick8,praline,vbhjh123,king11,22tango,gemini12,street1,77879,doodlebu,homyak,165432,chuluthu,trixi,karlito,salom,reisen,cdtnkzxjr,pookie11,tremendo,shazaam,welcome0,00000ty,peewee51,pizzle,gilead,bydand,sarvar,upskirt,legends1,freeway1,teenfuck,ranger9,darkfire,dfymrf,hunt0802,justme1,buffy1ma,1harry,671fsa75yt,burrfoot,budster,pa437tu,jimmyp,alina2006,malacon,charlize,elway1,free12,summer02,gadina,manara,gomer1,1cassie,sanja,kisulya,money3,pujols,ford50,midiland,turga,orange6,demetriu,freakboy,orosie1,radio123,open12,vfufpby,mustek,chris33,animes,meiling,nthtvjr,jasmine9,gfdkjd,oligarh,marimar,chicago9,.kzirf,bugssgub,samuraix,jackie01,pimpjuic,macdad,cagiva,vernost,willyboy,fynjyjdf,tabby1,privet123,torres9,retype,blueroom,raven11,q12we3,alex1989,bringiton,ridered,kareltje,ow8jtcs8t,ciccia,goniners,countryb,24688642,covingto,24861793,beyblade,vikin,badboyz,wlafiga,walstib,mirand,needajob,chloes,balaton,kbpfdtnf,freyja,bond9007,gabriel12,stormbri,hollage,love4eve,fenomeno,darknite,dragstar,kyle123,milfhunter,ma123123123,samia,ghislain,enrique1,ferien12,xjy6721,natalie2,reglisse,wilson2,wesker,rosebud7,amazon1,robertr,roykeane,xtcnth,mamatata,crazyc,mikie,savanah,blowjob69,jackie2,forty1,1coffee,fhbyjxrf,bubbah,goteam,hackedit,risky1,logoff,h397pnvr,buck13,robert23,bronc,st123st,godflesh,pornog,iamking,cisco69,septiembr,dale38,zhongguo,tibbar,panther9,buffa1,bigjohn1,mypuppy,vehvfycr,april16,shippo,fire1234,green15,q123123,gungadin,steveg,olivier1,chinaski,magnoli,faithy,storm12,toadfrog,paul99,78791,august20,automati,squirtle,cheezy,positano,burbon,nunya,llebpmac,kimmi,turtle2,alan123,prokuror,violin1,durex,pussygal,visionar,trick1,chicken6,29024,plowboy,rfybreks,imbue,sasha13,wagner1,vitalogy,cfymrf,thepro,26028,gorbunov,dvdcom,letmein5,duder,fastfun,pronin,libra1,conner1,harley20,stinker1,20068,20038,amitech,syoung,dugway,18068,welcome7,jimmypag,anastaci,kafka1,pfhfnecnhf,catsss,campus100,shamal,nacho1,fire12,vikings2,brasil1,rangerover,mohamma,peresvet,14058,cocomo,aliona,14038,qwaser,vikes,cbkmdf,skyblue1,ou81234,goodlove,dfkmltvfh,108888,roamer,pinky2,static1,zxcv4321,barmen,rock22,shelby2,morgans,1junior,pasword1,logjam,fifty5,nhfrnjhbcn,chaddy,philli,nemesis2,ingenier,djkrjd,ranger3,aikman8,knothead,daddy69,love007,vsythb,ford350,tiger00,renrut,owen11,energy12,march14,alena123,robert19,carisma,orange22,murphy11,podarok,prozak,kfgeirf,wolf13,lydia1,shazza,parasha,akimov,tobbie,pilote,heather4,baster,leones,gznfxjr,megama,987654321g,bullgod,boxster1,minkey,wombats,vergil,colegiata,lincol,smoothe,pride1,carwash1,latrell,bowling3,fylhtq123,pickwick,eider,bubblebox,bunnies1,loquit,slipper1,nutsac,purina,xtutdfhf,plokiju,1qazxs,uhjpysq,zxcvbasdfg,enjoy1,1pumpkin,phantom7,mama22,swordsma,wonderbr,dogdays,milker,u23456,silvan,dfkthbr,slagelse,yeahman,twothree,boston11,wolf100,dannyg,troll1,fynjy123,ghbcnfd,bftest,ballsdeep,bobbyorr,alphasig,cccdemo,fire123,norwest,claire2,august10,lth1108,problemas,sapito,alex06,1rusty,maccom,goirish1,ohyes,bxdumb,nabila,boobear1,rabbit69,princip,alexsander,travail,chantal1,dogggy,greenpea,diablo69,alex2009,bergen09,petticoa,classe,ceilidh,vlad2011,kamakiri,lucidity,qaz321,chileno,cexfhf,99ranger,mcitra,estoppel,volvos60,carter80,webpass,temp12,touareg,fcgbhby,bubba8,sunitha,200190ru,bitch2,shadow23,iluvit,nicole0,ruben1,nikki69,butttt,shocker1,souschef,lopotok01,kantot,corsano,cfnfyf,riverat,makalu,swapna,all4u9,cdtnkfy,ntktgepbr,ronaldo99,thomasj,bmw540i,chrisw,boomba,open321,z1x2c3v4b5n6m7,gaviota,iceman44,frosya,chris100,chris24,cosette,clearwat,micael,boogyman,pussy9,camus1,chumpy,heccrbq,konoplya,chester8,scooter5,ghjgfufylf,giotto,koolkat,zero000,bonita1,ckflrbq,j1964,mandog,18n28n24a,renob,head1,shergar,ringo123,tanita,sex4free,johnny12,halberd,reddevils,biolog,dillinge,fatb0y,c00per,hyperlit,wallace2,spears1,vitamine,buheirf,sloboda,alkash,mooman,marion1,arsenal7,sunder,nokia5610,edifier,pippone,fyfnjkmtdbx,fujimo,pepsi12,kulikova,bolat,duetto,daimon,maddog01,timoshka,ezmoney,desdemon,chesters,aiden,hugues,patrick5,aikman08,robert4,roenick,nyranger,writer1,36169544,foxmulder,118801,kutter,shashank,jamjar,118811,119955,aspirina,dinkus,1sailor,nalgene,19891959,snarf,allie1,cracky,resipsa,45678912,kemerovo,19841989,netware1,alhimik,19801984,nicole123,19761977,51501984,malaka1,montella,peachfuz,jethro1,cypress1,henkie,holdon,esmith,55443322,1friend,quique,bandicoot,statistika,great123,death13,ucht36,master4,67899876,bobsmith,nikko1,jr1234,hillary1,78978978,rsturbo,lzlzdfcz,bloodlust,shadow00,skagen,bambina,yummies,88887777,91328378,matthew4,itdoes,98256518,102938475,alina2002,123123789,fubared,dannys,123456321,nikifor,suck69,newmexico,scubaman,rhbcnb,fifnfy,puffdadd,159357852,dtheyxbr,theman22,212009164,prohor,shirle,nji90okm,newmedia,goose5,roma1995,letssee,iceman11,aksana,wirenut,pimpdady,1212312121,tamplier,pelican1,domodedovo,1928374655,fiction6,duckpond,ybrecz,thwack,onetwo34,gunsmith,murphydo,fallout1,spectre1,jabberwo,jgjesq,turbo6,bobo12,redryder,blackpus,elena1971,danilova,antoin,bobo1234,bobob,bobbobbo,dean1,222222a,jesusgod,matt23,musical1,darkmage,loppol,werrew,josepha,rebel12,toshka,gadfly,hawkwood,alina12,dnomyar,sexaddict,dangit,cool23,yocrack,archimed,farouk,nhfkzkz,lindalou,111zzzzz,ghjatccjh,wethepeople,m123456789,wowsers,kbkbxrf,bulldog5,m_roesel,sissinit,yamoon6,123ewqasd,dangel,miruvor79,kaytee,falcon7,bandit11,dotnet,dannii,arsenal9,miatamx5,1trouble,strip4me,dogpile,sexyred1,rjdfktdf,google10,shortman,crystal7,awesome123,cowdog,haruka,birthday28,jitter,diabolik,boomer12,dknight,bluewate,hockey123,crm0624,blueboys,willy123,jumpup,google2,cobra777,llabesab,vicelord,hopper1,gerryber,remmah,j10e5d4,qqqqqqw,agusti,fre_ak8yj,nahlik,redrobin,scott3,epson1,dumpy,bundao,aniolek,hola123,jergens,itsasecret,maxsam,bluelight,mountai1,bongwater,1london,pepper14,freeuse,dereks,qweqw,fordgt40,rfhfdfy,raider12,hunnybun,compac,splicer,megamon,tuffgong,gymnast1,butter11,modaddy,wapbbs_1,dandelio,soccer77,ghjnbdjcnjzybt,123xyi2,fishead,x002tp00,whodaman,555aaa,oussama,brunodog,technici,pmtgjnbl,qcxdw8ry,schweden,redsox3,throbber,collecto,japan10,dbm123dm,hellhoun,tech1,deadzone,kahlan,wolf123,dethklok,xzsawq,bigguy1,cybrthc,chandle,buck01,qq123123,secreta,williams1,c32649135,delta12,flash33,123joker,spacejam,polopo,holycrap,daman1,tummybed,financia,nusrat,euroline,magicone,jimkirk,ameritec,daniel26,sevenn,topazz,kingpins,dima1991,macdog,spencer5,oi812,geoffre,music11,baffle,123569,usagi,cassiope,polla,lilcrowe,thecakeisalie,vbhjndjhtw,vthokies,oldmans,sophie01,ghoster,penny2,129834,locutus1,meesha,magik,jerry69,daddysgirl,irondesk,andrey12,jasmine123,vepsrfyn,likesdick,1accord,jetboat,grafix,tomuch,showit,protozoa,mosias98,taburetka,blaze420,esenin,anal69,zhv84kv,puissant,charles0,aishwarya,babylon6,bitter1,lenina,raleigh1,lechat,access01,kamilka,fynjy,sparkplu,daisy3112,choppe,zootsuit,1234567j,rubyrose,gorilla9,nightshade,alternativa,cghfdjxybr,snuggles1,10121v,vova1992,leonardo1,dave2,matthewd,vfhfnbr,1986mets,nobull,bacall,mexican1,juanjo,mafia1,boomer22,soylent,edwards1,jordan10,blackwid,alex86,gemini13,lunar2,dctvcjcfnm,malaki,plugger,eagles11,snafu2,1shelly,cintaku,hannah22,tbird1,maks5843,irish88,homer22,amarok,fktrcfylhjdf,lincoln2,acess,gre69kik,need4speed,hightech,core2duo,blunt1,ublhjgjybrf,dragon33,1autopas,autopas1,wwww1,15935746,daniel20,2500aa,massim,1ggggggg,96ford,hardcor1,cobra5,blackdragon,vovan_lt,orochimaru,hjlbntkb,qwertyuiop12,tallen,paradoks,frozenfish,ghjuhfvvbcn,gerri1,nuggett,camilit,doright,trans1,serena1,catch2,bkmyeh,fireston,afhvfwtdn,purple3,figure8,fuckya,scamp1,laranja,ontheoutside,louis123,yellow7,moonwalk,mercury2,tolkein,raide,amenra,a13579,dranreb,5150vh,harish,tracksta,sexking,ozzmosis,katiee,alomar,matrix19,headroom,jahlove,ringding,apollo8,132546,132613,12345672000,saretta,135798,136666,thomas7,136913,onetwothree,hockey33,calida,nefertit,bitwise,tailhook,boop4,kfgecbr,bujhmbujhm,metal69,thedark,meteoro,felicia1,house12,tinuviel,istina,vaz2105,pimp13,toolfan,nina1,tuesday2,maxmotives,lgkp500,locksley,treech,darling1,kurama,aminka,ramin,redhed,dazzler,jager1,stpiliot,cardman,rfvtym,cheeser,14314314,paramoun,samcat,plumpy,stiffie,vsajyjr,panatha,qqq777,car12345,098poi,asdzx,keegan1,furelise,kalifornia,vbhjckfd,beast123,zcfvfzkexifz,harry5,1birdie,96328i,escola,extra330,henry12,gfhfyjqz,14u2nv,max1234,templar1,1dave,02588520,catrin,pangolin,marhaba,latin1,amorcito,dave22,escape1,advance1,yasuhiro,grepw,meetme,orange01,ernes,erdna,zsergn,nautica1,justinb,soundwav,miasma,greg78,nadine1,sexmad,lovebaby,promo1,excel1,babys,dragonma,camry1,sonnenschein,farooq,wazzkaprivet,magal,katinas,elvis99,redsox24,rooney1,chiefy,peggys,aliev,pilsung,mudhen,dontdoit,dennis12,supercal,energia,ballsout,funone,claudiu,brown2,amoco,dabl1125,philos,gjdtkbntkm,servette,13571113,whizzer,nollie,13467982,upiter,12string,bluejay1,silkie,william4,kosta1,143333,connor12,sustanon,06068,corporat,ssnake,laurita,king10,tahoes,arsenal123,sapato,charless,jeanmarc,levent,algerie,marine21,jettas,winsome,dctvgbplf,1701ab,xxxp455w0rd5,lllllll1,ooooooo1,monalis,koufax32,anastasya,debugger,sarita2,jason69,ufkxjyjr,gjlcnfdf,1jerry,daniel10,balinor,sexkitten,death2,qwertasdfgzxcvb,s9te949f,vegeta1,sysman,maxxam,dimabilan,mooose,ilovetit,june23,illest,doesit,mamou,abby12,longjump,transalp,moderato,littleguy,magritte,dilnoza,hawaiiguy,winbig,nemiroff,kokaine,admira,myemail,dream2,browneyes,destiny7,dragonss,suckme1,asa123,andranik,suckem,fleshbot,dandie,timmys,scitra,timdog,hasbeen,guesss,smellyfe,arachne,deutschl,harley88,birthday27,nobody1,papasmur,home1,jonass,bunia3,epatb1,embalm,vfvekmrf,apacer,12345656,estreet,weihnachtsbaum,mrwhite,admin12,kristie1,kelebek,yoda69,socken,tima123,bayern1,fktrcfylth,tamiya,99strenght,andy01,denis2011,19delta,stokecit,aotearoa,stalker2,nicnac,conrad1,popey,agusta,bowl36,1bigfish,mossyoak,1stunner,getinnow,jessejames,gkfnjy,drako,1nissan,egor123,hotness,1hawaii,zxc123456,cantstop,1peaches,madlen,west1234,jeter1,markis,judit,attack1,artemi,silver69,153246,crazy2,green9,yoshimi,1vette,chief123,jasper2,1sierra,twentyon,drstrang,aspirant,yannic,jenna123,bongtoke,slurpy,1sugar,civic97,rusty21,shineon,james19,anna12345,wonderwoman,1kevin,karol1,kanabis,wert21,fktif6115,evil1,kakaha,54gv768,826248s,tyrone1,1winston,sugar2,falcon01,adelya,mopar440,zasxcd,leecher,kinkysex,mercede1,travka,11234567,rebon,geekboy".split(","),english_wikipedia:"the,of,and,in,was,is,for,as,on,with,by,he,at,from,his,an,were,are,which,doc,https,also,or,has,had,first,one,their,its,after,new,who,they,two,her,she,been,other,when,time,during,there,into,school,more,may,years,over,only,year,most,would,world,city,some,where,between,later,three,state,such,then,national,used,made,known,under,many,university,united,while,part,season,team,these,american,than,film,second,born,south,became,states,war,through,being,including,both,before,north,high,however,people,family,early,history,album,area,them,series,against,until,since,district,county,name,work,life,group,music,following,number,company,several,four,called,played,released,career,league,game,government,house,each,based,day,same,won,use,station,club,international,town,located,population,general,college,east,found,age,march,end,september,began,home,public,church,line,june,river,member,system,place,century,band,july,york,january,october,song,august,best,former,british,party,named,held,village,show,local,november,took,service,december,built,another,major,within,along,members,five,single,due,although,small,old,left,final,large,include,building,served,president,received,games,death,february,main,third,set,children,own,order,species,park,law,air,published,road,died,book,men,women,army,often,according,education,central,country,division,english,top,included,development,french,community,among,water,play,side,list,times,near,late,form,original,different,center,power,led,students,german,moved,court,six,land,council,island,u.s.,record,million,research,art,established,award,street,military,television,given,region,support,western,production,non,political,point,cup,period,business,title,started,various,election,using,england,role,produced,become,program,works,field,total,office,class,written,association,radio,union,level,championship,director,few,force,created,department,founded,services,married,though,per,n't,site,open,act,short,society,version,royal,present,northern,worked,professional,full,returned,joined,story,france,european,currently,language,social,california,india,days,design,st.,further,round,australia,wrote,san,project,control,southern,railway,board,popular,continued,free,battle,considered,video,common,position,living,half,playing,recorded,red,post,described,average,records,special,modern,appeared,announced,areas,rock,release,elected,others,example,term,opened,similar,formed,route,census,current,schools,originally,lake,developed,race,himself,forces,addition,information,upon,province,match,event,songs,result,events,win,eastern,track,lead,teams,science,human,construction,minister,germany,awards,available,throughout,training,style,body,museum,australian,health,seven,signed,chief,eventually,appointed,sea,centre,debut,tour,points,media,light,range,character,across,features,families,largest,indian,network,less,performance,players,refer,europe,sold,festival,usually,taken,despite,designed,committee,process,return,official,episode,institute,stage,followed,performed,japanese,personal,thus,arts,space,low,months,includes,china,study,middle,magazine,leading,japan,groups,aircraft,featured,federal,civil,rights,model,coach,canadian,books,remained,eight,type,independent,completed,capital,academy,instead,kingdom,organization,countries,studies,competition,sports,size,above,section,finished,gold,involved,reported,management,systems,industry,directed,market,fourth,movement,technology,bank,ground,campaign,base,lower,sent,rather,added,provided,coast,grand,historic,valley,conference,bridge,winning,approximately,films,chinese,awarded,degree,russian,shows,native,female,replaced,municipality,square,studio,medical,data,african,successful,mid,bay,attack,previous,operations,spanish,theatre,student,republic,beginning,provide,ship,primary,owned,writing,tournament,culture,introduced,texas,related,natural,parts,governor,reached,ireland,units,senior,decided,italian,whose,higher,africa,standard,income,professor,placed,regional,los,buildings,championships,active,novel,energy,generally,interest,via,economic,previously,stated,itself,channel,below,operation,leader,traditional,trade,structure,limited,runs,prior,regular,famous,saint,navy,foreign,listed,artist,catholic,airport,results,parliament,collection,unit,officer,goal,attended,command,staff,commission,lived,location,plays,commercial,places,foundation,significant,older,medal,self,scored,companies,highway,activities,programs,wide,musical,notable,library,numerous,paris,towards,individual,allowed,plant,property,annual,contract,whom,highest,initially,required,earlier,assembly,artists,rural,seat,practice,defeated,ended,soviet,length,spent,manager,press,associated,author,issues,additional,characters,lord,zealand,policy,engine,township,noted,historical,complete,financial,religious,mission,contains,nine,recent,represented,pennsylvania,administration,opening,secretary,lines,report,executive,youth,closed,theory,writer,italy,angeles,appearance,feature,queen,launched,legal,terms,entered,issue,edition,singer,greek,majority,background,source,anti,cultural,complex,changes,recording,stadium,islands,operated,particularly,basketball,month,uses,port,castle,mostly,names,fort,selected,increased,status,earth,subsequently,pacific,cover,variety,certain,goals,remains,upper,congress,becoming,studied,irish,nature,particular,loss,caused,chart,dr.,forced,create,era,retired,material,review,rate,singles,referred,larger,individuals,shown,provides,products,speed,democratic,poland,parish,olympics,cities,themselves,temple,wing,genus,households,serving,cost,wales,stations,passed,supported,view,cases,forms,actor,male,matches,males,stars,tracks,females,administrative,median,effect,biography,train,engineering,camp,offered,chairman,houses,mainly,19th,surface,therefore,nearly,score,ancient,subject,prime,seasons,claimed,experience,specific,jewish,failed,overall,believed,plot,troops,greater,spain,consists,broadcast,heavy,increase,raised,separate,campus,1980s,appears,presented,lies,composed,recently,influence,fifth,nations,creek,references,elections,britain,double,cast,meaning,earned,carried,producer,latter,housing,brothers,attempt,article,response,border,remaining,nearby,direct,ships,value,workers,politician,academic,label,1970s,commander,rule,fellow,residents,authority,editor,transport,dutch,projects,responsible,covered,territory,flight,races,defense,tower,emperor,albums,facilities,daily,stories,assistant,managed,primarily,quality,function,proposed,distribution,conditions,prize,journal,code,vice,newspaper,corps,highly,constructed,mayor,critical,secondary,corporation,rugby,regiment,ohio,appearances,serve,allow,nation,multiple,discovered,directly,scene,levels,growth,elements,acquired,1990s,officers,physical,20th,latin,host,jersey,graduated,arrived,issued,literature,metal,estate,vote,immediately,quickly,asian,competed,extended,produce,urban,1960s,promoted,contemporary,global,formerly,appear,industrial,types,opera,ministry,soldiers,commonly,mass,formation,smaller,typically,drama,shortly,density,senate,effects,iran,polish,prominent,naval,settlement,divided,basis,republican,languages,distance,treatment,continue,product,mile,sources,footballer,format,clubs,leadership,initial,offers,operating,avenue,officially,columbia,grade,squadron,fleet,percent,farm,leaders,agreement,likely,equipment,website,mount,grew,method,transferred,intended,renamed,iron,asia,reserve,capacity,politics,widely,activity,advanced,relations,scottish,dedicated,crew,founder,episodes,lack,amount,build,efforts,concept,follows,ordered,leaves,positive,economy,entertainment,affairs,memorial,ability,illinois,communities,color,text,railroad,scientific,focus,comedy,serves,exchange,environment,cars,direction,organized,firm,description,agency,analysis,purpose,destroyed,reception,planned,revealed,infantry,architecture,growing,featuring,household,candidate,removed,situated,models,knowledge,solo,technical,organizations,assigned,conducted,participated,largely,purchased,register,gained,combined,headquarters,adopted,potential,protection,scale,approach,spread,independence,mountains,titled,geography,applied,safety,mixed,accepted,continues,captured,rail,defeat,principal,recognized,lieutenant,mentioned,semi,owner,joint,liberal,actress,traffic,creation,basic,notes,unique,supreme,declared,simply,plants,sales,massachusetts,designated,parties,jazz,compared,becomes,resources,titles,concert,learning,remain,teaching,versions,content,alongside,revolution,sons,block,premier,impact,champions,districts,generation,estimated,volume,image,sites,account,roles,sport,quarter,providing,zone,yard,scoring,classes,presence,performances,representatives,hosted,split,taught,origin,olympic,claims,critics,facility,occurred,suffered,municipal,damage,defined,resulted,respectively,expanded,platform,draft,opposition,expected,educational,ontario,climate,reports,atlantic,surrounding,performing,reduced,ranked,allows,birth,nominated,younger,newly,kong,positions,theater,philadelphia,heritage,finals,disease,sixth,laws,reviews,constitution,tradition,swedish,theme,fiction,rome,medicine,trains,resulting,existing,deputy,environmental,labour,classical,develop,fans,granted,receive,alternative,begins,nuclear,fame,buried,connected,identified,palace,falls,letters,combat,sciences,effort,villages,inspired,regions,towns,conservative,chosen,animals,labor,attacks,materials,yards,steel,representative,orchestra,peak,entitled,officials,returning,reference,northwest,imperial,convention,examples,ocean,publication,painting,subsequent,frequently,religion,brigade,fully,sides,acts,cemetery,relatively,oldest,suggested,succeeded,achieved,application,programme,cells,votes,promotion,graduate,armed,supply,flying,communist,figures,literary,netherlands,korea,worldwide,citizens,1950s,faculty,draw,stock,seats,occupied,methods,unknown,articles,claim,holds,authorities,audience,sweden,interview,obtained,covers,settled,transfer,marked,allowing,funding,challenge,southeast,unlike,crown,rise,portion,transportation,sector,phase,properties,edge,tropical,standards,institutions,philosophy,legislative,hills,brand,fund,conflict,unable,founding,refused,attempts,metres,permanent,starring,applications,creating,effective,aired,extensive,employed,enemy,expansion,billboard,rank,battalion,multi,vehicle,fought,alliance,category,perform,federation,poetry,bronze,bands,entry,vehicles,bureau,maximum,billion,trees,intelligence,greatest,screen,refers,commissioned,gallery,injury,confirmed,setting,treaty,adult,americans,broadcasting,supporting,pilot,mobile,writers,programming,existence,squad,minnesota,copies,korean,provincial,sets,defence,offices,agricultural,internal,core,northeast,retirement,factory,actions,prevent,communications,ending,weekly,containing,functions,attempted,interior,weight,bowl,recognition,incorporated,increasing,ultimately,documentary,derived,attacked,lyrics,mexican,external,churches,centuries,metropolitan,selling,opposed,personnel,mill,visited,presidential,roads,pieces,norwegian,controlled,18th,rear,influenced,wrestling,weapons,launch,composer,locations,developing,circuit,specifically,studios,shared,canal,wisconsin,publishing,approved,domestic,consisted,determined,comic,establishment,exhibition,southwest,fuel,electronic,cape,converted,educated,melbourne,hits,wins,producing,norway,slightly,occur,surname,identity,represent,constituency,funds,proved,links,structures,athletic,birds,contest,users,poet,institution,display,receiving,rare,contained,guns,motion,piano,temperature,publications,passenger,contributed,toward,cathedral,inhabitants,architect,exist,athletics,muslim,courses,abandoned,signal,successfully,disambiguation,tennessee,dynasty,heavily,maryland,jews,representing,budget,weather,missouri,introduction,faced,pair,chapel,reform,height,vietnam,occurs,motor,cambridge,lands,focused,sought,patients,shape,invasion,chemical,importance,communication,selection,regarding,homes,voivodeship,maintained,borough,failure,aged,passing,agriculture,oregon,teachers,flow,philippines,trail,seventh,portuguese,resistance,reaching,negative,fashion,scheduled,downtown,universities,trained,skills,scenes,views,notably,typical,incident,candidates,engines,decades,composition,commune,chain,inc.,austria,sale,values,employees,chamber,regarded,winners,registered,task,investment,colonial,swiss,user,entirely,flag,stores,closely,entrance,laid,journalist,coal,equal,causes,turkish,quebec,techniques,promote,junction,easily,dates,kentucky,singapore,residence,violence,advance,survey,humans,expressed,passes,streets,distinguished,qualified,folk,establish,egypt,artillery,visual,improved,actual,finishing,medium,protein,switzerland,productions,operate,poverty,neighborhood,organisation,consisting,consecutive,sections,partnership,extension,reaction,factor,costs,bodies,device,ethnic,racial,flat,objects,chapter,improve,musicians,courts,controversy,membership,merged,wars,expedition,interests,arab,comics,gain,describes,mining,bachelor,crisis,joining,decade,1930s,distributed,habitat,routes,arena,cycle,divisions,briefly,vocals,directors,degrees,object,recordings,installed,adjacent,demand,voted,causing,businesses,ruled,grounds,starred,drawn,opposite,stands,formal,operates,persons,counties,compete,wave,israeli,ncaa,resigned,brief,greece,combination,demographics,historian,contain,commonwealth,musician,collected,argued,louisiana,session,cabinet,parliamentary,electoral,loan,profit,regularly,conservation,islamic,purchase,17th,charts,residential,earliest,designs,paintings,survived,moth,items,goods,grey,anniversary,criticism,images,discovery,observed,underground,progress,additionally,participate,thousands,reduce,elementary,owners,stating,iraq,resolution,capture,tank,rooms,hollywood,finance,queensland,reign,maintain,iowa,landing,broad,outstanding,circle,path,manufacturing,assistance,sequence,gmina,crossing,leads,universal,shaped,kings,attached,medieval,ages,metro,colony,affected,scholars,oklahoma,coastal,soundtrack,painted,attend,definition,meanwhile,purposes,trophy,require,marketing,popularity,cable,mathematics,mississippi,represents,scheme,appeal,distinct,factors,acid,subjects,roughly,terminal,economics,senator,diocese,prix,contrast,argentina,czech,wings,relief,stages,duties,16th,novels,accused,whilst,equivalent,charged,measure,documents,couples,request,danish,defensive,guide,devices,statistics,credited,tries,passengers,allied,frame,puerto,peninsula,concluded,instruments,wounded,differences,associate,forests,afterwards,replace,requirements,aviation,solution,offensive,ownership,inner,legislation,hungarian,contributions,actors,translated,denmark,steam,depending,aspects,assumed,injured,severe,admitted,determine,shore,technique,arrival,measures,translation,debuted,delivered,returns,rejected,separated,visitors,damaged,storage,accompanied,markets,industries,losses,gulf,charter,strategy,corporate,socialist,somewhat,significantly,physics,mounted,satellite,experienced,constant,relative,pattern,restored,belgium,connecticut,partners,harvard,retained,networks,protected,mode,artistic,parallel,collaboration,debate,involving,journey,linked,salt,authors,components,context,occupation,requires,occasionally,policies,tamil,ottoman,revolutionary,hungary,poem,versus,gardens,amongst,audio,makeup,frequency,meters,orthodox,continuing,suggests,legislature,coalition,guitarist,eighth,classification,practices,soil,tokyo,instance,limit,coverage,considerable,ranking,colleges,cavalry,centers,daughters,twin,equipped,broadway,narrow,hosts,rates,domain,boundary,arranged,12th,whereas,brazilian,forming,rating,strategic,competitions,trading,covering,baltimore,commissioner,infrastructure,origins,replacement,praised,disc,collections,expression,ukraine,driven,edited,austrian,solar,ensure,premiered,successor,wooden,operational,hispanic,concerns,rapid,prisoners,childhood,meets,influential,tunnel,employment,tribe,qualifying,adapted,temporary,celebrated,appearing,increasingly,depression,adults,cinema,entering,laboratory,script,flows,romania,accounts,fictional,pittsburgh,achieve,monastery,franchise,formally,tools,newspapers,revival,sponsored,processes,vienna,springs,missions,classified,13th,annually,branches,lakes,gender,manner,advertising,normally,maintenance,adding,characteristics,integrated,decline,modified,strongly,critic,victims,malaysia,arkansas,nazi,restoration,powered,monument,hundreds,depth,15th,controversial,admiral,criticized,brick,honorary,initiative,output,visiting,birmingham,progressive,existed,carbon,1920s,credits,colour,rising,hence,defeating,superior,filmed,listing,column,surrounded,orleans,principles,territories,struck,participation,indonesia,movements,index,commerce,conduct,constitutional,spiritual,ambassador,vocal,completion,edinburgh,residing,tourism,finland,bears,medals,resident,themes,visible,indigenous,involvement,basin,electrical,ukrainian,concerts,boats,styles,processing,rival,drawing,vessels,experimental,declined,touring,supporters,compilation,coaching,cited,dated,roots,string,explained,transit,traditionally,poems,minimum,representation,14th,releases,effectively,architectural,triple,indicated,greatly,elevation,clinical,printed,10th,proposal,peaked,producers,romanized,rapidly,stream,innings,meetings,counter,householder,honour,lasted,agencies,document,exists,surviving,experiences,honors,landscape,hurricane,harbor,panel,competing,profile,vessel,farmers,lists,revenue,exception,customers,11th,participants,wildlife,utah,bible,gradually,preserved,replacing,symphony,begun,longest,siege,provinces,mechanical,genre,transmission,agents,executed,videos,benefits,funded,rated,instrumental,ninth,similarly,dominated,destruction,passage,technologies,thereafter,outer,facing,affiliated,opportunities,instrument,governments,scholar,evolution,channels,shares,sessions,widespread,occasions,engineers,scientists,signing,battery,competitive,alleged,eliminated,supplies,judges,hampshire,regime,portrayed,penalty,taiwan,denied,submarine,scholarship,substantial,transition,victorian,http,nevertheless,filed,supports,continental,tribes,ratio,doubles,useful,honours,blocks,principle,retail,departure,ranks,patrol,yorkshire,vancouver,inter,extent,afghanistan,strip,railways,component,organ,symbol,categories,encouraged,abroad,civilian,periods,traveled,writes,struggle,immediate,recommended,adaptation,egyptian,graduating,assault,drums,nomination,historically,voting,allies,detailed,achievement,percentage,arabic,assist,frequent,toured,apply,and/or,intersection,maine,touchdown,throne,produces,contribution,emerged,obtain,archbishop,seek,researchers,remainder,populations,clan,finnish,overseas,fifa,licensed,chemistry,festivals,mediterranean,injuries,animated,seeking,publisher,volumes,limits,venue,jerusalem,generated,trials,islam,youngest,ruling,glasgow,germans,songwriter,persian,municipalities,donated,viewed,belgian,cooperation,posted,tech,dual,volunteer,settlers,commanded,claiming,approval,delhi,usage,terminus,partly,electricity,locally,editions,premiere,absence,belief,traditions,statue,indicate,manor,stable,attributed,possession,managing,viewers,chile,overview,seed,regulations,essential,minority,cargo,segment,endemic,forum,deaths,monthly,playoffs,erected,practical,machines,suburb,relation,mrs.,descent,indoor,continuous,characterized,solutions,caribbean,rebuilt,serbian,summary,contested,psychology,pitch,attending,muhammad,tenure,drivers,diameter,assets,venture,punk,airlines,concentration,athletes,volunteers,pages,mines,influences,sculpture,protest,ferry,behalf,drafted,apparent,furthermore,ranging,romanian,democracy,lanka,significance,linear,d.c.,certified,voters,recovered,tours,demolished,boundaries,assisted,identify,grades,elsewhere,mechanism,1940s,reportedly,aimed,conversion,suspended,photography,departments,beijing,locomotives,publicly,dispute,magazines,resort,conventional,platforms,internationally,capita,settlements,dramatic,derby,establishing,involves,statistical,implementation,immigrants,exposed,diverse,layer,vast,ceased,connections,belonged,interstate,uefa,organised,abuse,deployed,cattle,partially,filming,mainstream,reduction,automatic,rarely,subsidiary,decides,merger,comprehensive,displayed,amendment,guinea,exclusively,manhattan,concerning,commons,radical,serbia,baptist,buses,initiated,portrait,harbour,choir,citizen,sole,unsuccessful,manufactured,enforcement,connecting,increases,patterns,sacred,muslims,clothing,hindu,unincorporated,sentenced,advisory,tanks,campaigns,fled,repeated,remote,rebellion,implemented,texts,fitted,tribute,writings,sufficient,ministers,21st,devoted,jurisdiction,coaches,interpretation,pole,businessman,peru,sporting,prices,cuba,relocated,opponent,arrangement,elite,manufacturer,responded,suitable,distinction,calendar,dominant,tourist,earning,prefecture,ties,preparation,anglo,pursue,worship,archaeological,chancellor,bangladesh,scores,traded,lowest,horror,outdoor,biology,commented,specialized,loop,arriving,farming,housed,historians,'the,patent,pupils,christianity,opponents,athens,northwestern,maps,promoting,reveals,flights,exclusive,lions,norfolk,hebrew,extensively,eldest,shops,acquisition,virtual,renowned,margin,ongoing,essentially,iranian,alternate,sailed,reporting,conclusion,originated,temperatures,exposure,secured,landed,rifle,framework,identical,martial,focuses,topics,ballet,fighters,belonging,wealthy,negotiations,evolved,bases,oriented,acres,democrat,heights,restricted,vary,graduation,aftermath,chess,illness,participating,vertical,collective,immigration,demonstrated,leaf,completing,organic,missile,leeds,eligible,grammar,confederate,improvement,congressional,wealth,cincinnati,spaces,indicates,corresponding,reaches,repair,isolated,taxes,congregation,ratings,leagues,diplomatic,submitted,winds,awareness,photographs,maritime,nigeria,accessible,animation,restaurants,philippine,inaugural,dismissed,armenian,illustrated,reservoir,speakers,programmes,resource,genetic,interviews,camps,regulation,computers,preferred,travelled,comparison,distinctive,recreation,requested,southeastern,dependent,brisbane,breeding,playoff,expand,bonus,gauge,departed,qualification,inspiration,shipping,slaves,variations,shield,theories,munich,recognised,emphasis,favour,variable,seeds,undergraduate,territorial,intellectual,qualify,mini,banned,pointed,democrats,assessment,judicial,examination,attempting,objective,partial,characteristic,hardware,pradesh,execution,ottawa,metre,drum,exhibitions,withdrew,attendance,phrase,journalism,logo,measured,error,christians,trio,protestant,theology,respective,atmosphere,buddhist,substitute,curriculum,fundamental,outbreak,rabbi,intermediate,designation,globe,liberation,simultaneously,diseases,experiments,locomotive,difficulties,mainland,nepal,relegated,contributing,database,developments,veteran,carries,ranges,instruction,lodge,protests,obama,newcastle,experiment,physician,describing,challenges,corruption,delaware,adventures,ensemble,succession,renaissance,tenth,altitude,receives,approached,crosses,syria,croatia,warsaw,professionals,improvements,worn,airline,compound,permitted,preservation,reducing,printing,scientist,activist,comprises,sized,societies,enters,ruler,gospel,earthquake,extend,autonomous,croatian,serial,decorated,relevant,ideal,grows,grass,tier,towers,wider,welfare,columns,alumni,descendants,interface,reserves,banking,colonies,manufacturers,magnetic,closure,pitched,vocalist,preserve,enrolled,cancelled,equation,2000s,nickname,bulgaria,heroes,exile,mathematical,demands,input,structural,tube,stem,approaches,argentine,axis,manuscript,inherited,depicted,targets,visits,veterans,regard,removal,efficiency,organisations,concepts,lebanon,manga,petersburg,rally,supplied,amounts,yale,tournaments,broadcasts,signals,pilots,azerbaijan,architects,enzyme,literacy,declaration,placing,batting,incumbent,bulgarian,consistent,poll,defended,landmark,southwestern,raid,resignation,travels,casualties,prestigious,namely,aims,recipient,warfare,readers,collapse,coached,controls,volleyball,coup,lesser,verse,pairs,exhibited,proteins,molecular,abilities,integration,consist,aspect,advocate,administered,governing,hospitals,commenced,coins,lords,variation,resumed,canton,artificial,elevated,palm,difficulty,civic,efficient,northeastern,inducted,radiation,affiliate,boards,stakes,byzantine,consumption,freight,interaction,oblast,numbered,seminary,contracts,extinct,predecessor,bearing,cultures,functional,neighboring,revised,cylinder,grants,narrative,reforms,athlete,tales,reflect,presidency,compositions,specialist,cricketer,founders,sequel,widow,disbanded,associations,backed,thereby,pitcher,commanding,boulevard,singers,crops,militia,reviewed,centres,waves,consequently,fortress,tributary,portions,bombing,excellence,nest,payment,mars,plaza,unity,victories,scotia,farms,nominations,variant,attacking,suspension,installation,graphics,estates,comments,acoustic,destination,venues,surrender,retreat,libraries,quarterback,customs,berkeley,collaborated,gathered,syndrome,dialogue,recruited,shanghai,neighbouring,psychological,saudi,moderate,exhibit,innovation,depot,binding,brunswick,situations,certificate,actively,shakespeare,editorial,presentation,ports,relay,nationalist,methodist,archives,experts,maintains,collegiate,bishops,maintaining,temporarily,embassy,essex,wellington,connects,reformed,bengal,recalled,inches,doctrine,deemed,legendary,reconstruction,statements,palestinian,meter,achievements,riders,interchange,spots,auto,accurate,chorus,dissolved,missionary,thai,operators,e.g.,generations,failing,delayed,cork,nashville,perceived,venezuela,cult,emerging,tomb,abolished,documented,gaining,canyon,episcopal,stored,assists,compiled,kerala,kilometers,mosque,grammy,theorem,unions,segments,glacier,arrives,theatrical,circulation,conferences,chapters,displays,circular,authored,conductor,fewer,dimensional,nationwide,liga,yugoslavia,peer,vietnamese,fellowship,armies,regardless,relating,dynamic,politicians,mixture,serie,somerset,imprisoned,posts,beliefs,beta,layout,independently,electronics,provisions,fastest,logic,headquartered,creates,challenged,beaten,appeals,plains,protocol,graphic,accommodate,iraqi,midfielder,span,commentary,freestyle,reflected,palestine,lighting,burial,virtually,backing,prague,tribal,heir,identification,prototype,criteria,dame,arch,tissue,footage,extending,procedures,predominantly,updated,rhythm,preliminary,cafe,disorder,prevented,suburbs,discontinued,retiring,oral,followers,extends,massacre,journalists,conquest,larvae,pronounced,behaviour,diversity,sustained,addressed,geographic,restrictions,voiced,milwaukee,dialect,quoted,grid,nationally,nearest,roster,twentieth,separation,indies,manages,citing,intervention,guidance,severely,migration,artwork,focusing,rivals,trustees,varied,enabled,committees,centered,skating,slavery,cardinals,forcing,tasks,auckland,youtube,argues,colored,advisor,mumbai,requiring,theological,registration,refugees,nineteenth,survivors,runners,colleagues,priests,contribute,variants,workshop,concentrated,creator,lectures,temples,exploration,requirement,interactive,navigation,companion,perth,allegedly,releasing,citizenship,observation,stationed,ph.d.,sheep,breed,discovers,encourage,kilometres,journals,performers,isle,saskatchewan,hybrid,hotels,lancashire,dubbed,airfield,anchor,suburban,theoretical,sussex,anglican,stockholm,permanently,upcoming,privately,receiver,optical,highways,congo,colours,aggregate,authorized,repeatedly,varies,fluid,innovative,transformed,praise,convoy,demanded,discography,attraction,export,audiences,ordained,enlisted,occasional,westminster,syrian,heavyweight,bosnia,consultant,eventual,improving,aires,wickets,epic,reactions,scandal,i.e.,discrimination,buenos,patron,investors,conjunction,testament,construct,encountered,celebrity,expanding,georgian,brands,retain,underwent,algorithm,foods,provision,orbit,transformation,associates,tactical,compact,varieties,stability,refuge,gathering,moreover,manila,configuration,gameplay,discipline,entity,comprising,composers,skill,monitoring,ruins,museums,sustainable,aerial,altered,codes,voyage,friedrich,conflicts,storyline,travelling,conducting,merit,indicating,referendum,currency,encounter,particles,automobile,workshops,acclaimed,inhabited,doctorate,cuban,phenomenon,dome,enrollment,tobacco,governance,trend,equally,manufacture,hydrogen,grande,compensation,download,pianist,grain,shifted,neutral,evaluation,define,cycling,seized,array,relatives,motors,firms,varying,automatically,restore,nicknamed,findings,governed,investigate,manitoba,administrator,vital,integral,indonesian,confusion,publishers,enable,geographical,inland,naming,civilians,reconnaissance,indianapolis,lecturer,deer,tourists,exterior,rhode,bassist,symbols,scope,ammunition,yuan,poets,punjab,nursing,cent,developers,estimates,presbyterian,nasa,holdings,generate,renewed,computing,cyprus,arabia,duration,compounds,gastropod,permit,valid,touchdowns,facade,interactions,mineral,practiced,allegations,consequence,goalkeeper,baronet,copyright,uprising,carved,targeted,competitors,mentions,sanctuary,fees,pursued,tampa,chronicle,capabilities,specified,specimens,toll,accounting,limestone,staged,upgraded,philosophical,streams,guild,revolt,rainfall,supporter,princeton,terrain,hometown,probability,assembled,paulo,surrey,voltage,developer,destroyer,floors,lineup,curve,prevention,potentially,onwards,trips,imposed,hosting,striking,strict,admission,apartments,solely,utility,proceeded,observations,euro,incidents,vinyl,profession,haven,distant,expelled,rivalry,runway,torpedo,zones,shrine,dimensions,investigations,lithuania,idaho,pursuit,copenhagen,considerably,locality,wireless,decrease,genes,thermal,deposits,hindi,habitats,withdrawn,biblical,monuments,casting,plateau,thesis,managers,flooding,assassination,acknowledged,interim,inscription,guided,pastor,finale,insects,transported,activists,marshal,intensity,airing,cardiff,proposals,lifestyle,prey,herald,capitol,aboriginal,measuring,lasting,interpreted,occurring,desired,drawings,healthcare,panels,elimination,oslo,ghana,blog,sabha,intent,superintendent,governors,bankruptcy,p.m.,equity,disk,layers,slovenia,prussia,quartet,mechanics,graduates,politically,monks,screenplay,nato,absorbed,topped,petition,bold,morocco,exhibits,canterbury,publish,rankings,crater,dominican,enhanced,planes,lutheran,governmental,joins,collecting,brussels,unified,streak,strategies,flagship,surfaces,oval,archive,etymology,imprisonment,instructor,noting,remix,opposing,servant,rotation,width,trans,maker,synthesis,excess,tactics,snail,ltd.,lighthouse,sequences,cornwall,plantation,mythology,performs,foundations,populated,horizontal,speedway,activated,performer,diving,conceived,edmonton,subtropical,environments,prompted,semifinals,caps,bulk,treasury,recreational,telegraph,continent,portraits,relegation,catholics,graph,velocity,rulers,endangered,secular,observer,learns,inquiry,idol,dictionary,certification,estimate,cluster,armenia,observatory,revived,nadu,consumers,hypothesis,manuscripts,contents,arguments,editing,trails,arctic,essays,belfast,acquire,promotional,undertaken,corridor,proceedings,antarctic,millennium,labels,delegates,vegetation,acclaim,directing,substance,outcome,diploma,philosopher,malta,albanian,vicinity,degc,legends,regiments,consent,terrorist,scattered,presidents,gravity,orientation,deployment,duchy,refuses,estonia,crowned,separately,renovation,rises,wilderness,objectives,agreements,empress,slopes,inclusion,equality,decree,ballot,criticised,rochester,recurring,struggled,disabled,henri,poles,prussian,convert,bacteria,poorly,sudan,geological,wyoming,consistently,minimal,withdrawal,interviewed,proximity,repairs,initiatives,pakistani,republicans,propaganda,viii,abstract,commercially,availability,mechanisms,naples,discussions,underlying,lens,proclaimed,advised,spelling,auxiliary,attract,lithuanian,editors,o'brien,accordance,measurement,novelist,ussr,formats,councils,contestants,indie,facebook,parishes,barrier,battalions,sponsor,consulting,terrorism,implement,uganda,crucial,unclear,notion,distinguish,collector,attractions,filipino,ecology,investments,capability,renovated,iceland,albania,accredited,scouts,armor,sculptor,cognitive,errors,gaming,condemned,successive,consolidated,baroque,entries,regulatory,reserved,treasurer,variables,arose,technological,rounded,provider,rhine,agrees,accuracy,genera,decreased,frankfurt,ecuador,edges,particle,rendered,calculated,careers,faction,rifles,americas,gaelic,portsmouth,resides,merchants,fiscal,premises,coin,draws,presenter,acceptance,ceremonies,pollution,consensus,membrane,brigadier,nonetheless,genres,supervision,predicted,magnitude,finite,differ,ancestry,vale,delegation,removing,proceeds,placement,emigrated,siblings,molecules,payments,considers,demonstration,proportion,newer,valve,achieving,confederation,continuously,luxury,notre,introducing,coordinates,charitable,squadrons,disorders,geometry,winnipeg,ulster,loans,longtime,receptor,preceding,belgrade,mandate,wrestler,neighbourhood,factories,buddhism,imported,sectors,protagonist,steep,elaborate,prohibited,artifacts,prizes,pupil,cooperative,sovereign,subspecies,carriers,allmusic,nationals,settings,autobiography,neighborhoods,analog,facilitate,voluntary,jointly,newfoundland,organizing,raids,exercises,nobel,machinery,baltic,crop,granite,dense,websites,mandatory,seeks,surrendered,anthology,comedian,bombs,slot,synopsis,critically,arcade,marking,equations,halls,indo,inaugurated,embarked,speeds,clause,invention,premiership,likewise,presenting,demonstrate,designers,organize,examined,km/h,bavaria,troop,referee,detection,zurich,prairie,rapper,wingspan,eurovision,luxembourg,slovakia,inception,disputed,mammals,entrepreneur,makers,evangelical,yield,clergy,trademark,defunct,allocated,depicting,volcanic,batted,conquered,sculptures,providers,reflects,armoured,locals,walt,herzegovina,contracted,entities,sponsorship,prominence,flowing,ethiopia,marketed,corporations,withdraw,carnegie,induced,investigated,portfolio,flowering,opinions,viewing,classroom,donations,bounded,perception,leicester,fruits,charleston,academics,statute,complaints,smallest,deceased,petroleum,resolved,commanders,algebra,southampton,modes,cultivation,transmitter,spelled,obtaining,sizes,acre,pageant,bats,abbreviated,correspondence,barracks,feast,tackles,raja,derives,geology,disputes,translations,counted,constantinople,seating,macedonia,preventing,accommodation,homeland,explored,invaded,provisional,transform,sphere,unsuccessfully,missionaries,conservatives,highlights,traces,organisms,openly,dancers,fossils,absent,monarchy,combining,lanes,stint,dynamics,chains,missiles,screening,module,tribune,generating,miners,nottingham,seoul,unofficial,owing,linking,rehabilitation,citation,louisville,mollusk,depicts,differential,zimbabwe,kosovo,recommendations,responses,pottery,scorer,aided,exceptions,dialects,telecommunications,defines,elderly,lunar,coupled,flown,25th,espn,formula_1,bordered,fragments,guidelines,gymnasium,valued,complexity,papal,presumably,maternal,challenging,reunited,advancing,comprised,uncertain,favorable,twelfth,correspondent,nobility,livestock,expressway,chilean,tide,researcher,emissions,profits,lengths,accompanying,witnessed,itunes,drainage,slope,reinforced,feminist,sanskrit,develops,physicians,outlets,isbn,coordinator,averaged,termed,occupy,diagnosed,yearly,humanitarian,prospect,spacecraft,stems,enacted,linux,ancestors,karnataka,constitute,immigrant,thriller,ecclesiastical,generals,celebrations,enhance,heating,advocated,evident,advances,bombardment,watershed,shuttle,wicket,twitter,adds,branded,teaches,schemes,pension,advocacy,conservatory,cairo,varsity,freshwater,providence,seemingly,shells,cuisine,specially,peaks,intensive,publishes,trilogy,skilled,nacional,unemployment,destinations,parameters,verses,trafficking,determination,infinite,savings,alignment,linguistic,countryside,dissolution,measurements,advantages,licence,subfamily,highlands,modest,regent,algeria,crest,teachings,knockout,brewery,combine,conventions,descended,chassis,primitive,fiji,explicitly,cumberland,uruguay,laboratories,bypass,elect,informal,preceded,holocaust,tackle,minneapolis,quantity,securities,console,doctoral,religions,commissioners,expertise,unveiled,precise,diplomat,standings,infant,disciplines,sicily,endorsed,systematic,charted,armored,mild,lateral,townships,hurling,prolific,invested,wartime,compatible,galleries,moist,battlefield,decoration,convent,tubes,terrestrial,nominee,requests,delegate,leased,dubai,polar,applying,addresses,munster,sings,commercials,teamed,dances,eleventh,midland,cedar,flee,sandstone,snails,inspection,divide,asset,themed,comparable,paramount,dairy,archaeology,intact,institutes,rectangular,instances,phases,reflecting,substantially,applies,vacant,lacked,copa,coloured,encounters,sponsors,encoded,possess,revenues,ucla,chaired,a.m.,enabling,playwright,stoke,sociology,tibetan,frames,motto,financing,illustrations,gibraltar,chateau,bolivia,transmitted,enclosed,persuaded,urged,folded,suffolk,regulated,bros.,submarines,myth,oriental,malaysian,effectiveness,narrowly,acute,sunk,replied,utilized,tasmania,consortium,quantities,gains,parkway,enlarged,sided,employers,adequate,accordingly,assumption,ballad,mascot,distances,peaking,saxony,projected,affiliation,limitations,metals,guatemala,scots,theaters,kindergarten,verb,employer,differs,discharge,controller,seasonal,marching,guru,campuses,avoided,vatican,maori,excessive,chartered,modifications,caves,monetary,sacramento,mixing,institutional,celebrities,irrigation,shapes,broadcaster,anthem,attributes,demolition,offshore,specification,surveys,yugoslav,contributor,auditorium,lebanese,capturing,airports,classrooms,chennai,paths,tendency,determining,lacking,upgrade,sailors,detected,kingdoms,sovereignty,freely,decorative,momentum,scholarly,georges,gandhi,speculation,transactions,undertook,interact,similarities,cove,teammate,constituted,painters,tends,madagascar,partnerships,afghan,personalities,attained,rebounds,masses,synagogue,reopened,asylum,embedded,imaging,catalogue,defenders,taxonomy,fiber,afterward,appealed,communists,lisbon,rica,judaism,adviser,batsman,ecological,commands,lgbt,cooling,accessed,wards,shiva,employs,thirds,scenic,worcester,tallest,contestant,humanities,economist,textile,constituencies,motorway,tram,percussion,cloth,leisure,1880s,baden,flags,resemble,riots,coined,sitcom,composite,implies,daytime,tanzania,penalties,optional,competitor,excluded,steering,reversed,autonomy,reviewer,breakthrough,professionally,damages,pomeranian,deputies,valleys,ventures,highlighted,electorate,mapping,shortened,executives,tertiary,specimen,launching,bibliography,sank,pursuing,binary,descendant,marched,natives,ideology,turks,adolf,archdiocese,tribunal,exceptional,nigerian,preference,fails,loading,comeback,vacuum,favored,alter,remnants,consecrated,spectators,trends,patriarch,feedback,paved,sentences,councillor,astronomy,advocates,broader,commentator,commissions,identifying,revealing,theatres,incomplete,enables,constituent,reformation,tract,haiti,atmospheric,screened,explosive,czechoslovakia,acids,symbolic,subdivision,liberals,incorporate,challenger,erie,filmmaker,laps,kazakhstan,organizational,evolutionary,chemicals,dedication,riverside,fauna,moths,maharashtra,annexed,gen.,resembles,underwater,garnered,timeline,remake,suited,educator,hectares,automotive,feared,latvia,finalist,narrator,portable,airways,plaque,designing,villagers,licensing,flank,statues,struggles,deutsche,migrated,cellular,jacksonville,wimbledon,defining,highlight,preparatory,planets,cologne,employ,frequencies,detachment,readily,libya,resign,halt,helicopters,reef,landmarks,collaborative,irregular,retaining,helsinki,folklore,weakened,viscount,interred,professors,memorable,mega,repertoire,rowing,dorsal,albeit,progressed,operative,coronation,liner,telugu,domains,philharmonic,detect,bengali,synthetic,tensions,atlas,dramatically,paralympics,xbox,shire,kiev,lengthy,sued,notorious,seas,screenwriter,transfers,aquatic,pioneers,unesco,radius,abundant,tunnels,syndicated,inventor,accreditation,janeiro,exeter,ceremonial,omaha,cadet,predators,resided,prose,slavic,precision,abbot,deity,engaging,cambodia,estonian,compliance,demonstrations,protesters,reactor,commodore,successes,chronicles,mare,extant,listings,minerals,tonnes,parody,cultivated,traders,pioneering,supplement,slovak,preparations,collision,partnered,vocational,atoms,malayalam,welcomed,documentation,curved,functioning,presently,formations,incorporates,nazis,botanical,nucleus,ethical,greeks,metric,automated,whereby,stance,europeans,duet,disability,purchasing,email,telescope,displaced,sodium,comparative,processor,inning,precipitation,aesthetic,import,coordination,feud,alternatively,mobility,tibet,regained,succeeding,hierarchy,apostolic,catalog,reproduction,inscriptions,vicar,clusters,posthumously,rican,loosely,additions,photographic,nowadays,selective,derivative,keyboards,guides,collectively,affecting,combines,operas,networking,decisive,terminated,continuity,finishes,ancestor,consul,heated,simulation,leipzig,incorporating,georgetown,formula_2,circa,forestry,portrayal,councillors,advancement,complained,forewings,confined,transaction,definitions,reduces,televised,1890s,rapids,phenomena,belarus,alps,landscapes,quarterly,specifications,commemorate,continuation,isolation,antenna,downstream,patents,ensuing,tended,saga,lifelong,columnist,labeled,gymnastics,papua,anticipated,demise,encompasses,madras,antarctica,interval,icon,rams,midlands,ingredients,priory,strengthen,rouge,explicit,gaza,aging,securing,anthropology,listeners,adaptations,underway,vista,malay,fortified,lightweight,violations,concerto,financed,jesuit,observers,trustee,descriptions,nordic,resistant,opted,accepts,prohibition,andhra,inflation,negro,wholly,imagery,spur,instructed,gloucester,cycles,middlesex,destroyers,statewide,evacuated,hyderabad,peasants,mice,shipyard,coordinate,pitching,colombian,exploring,numbering,compression,countess,hiatus,exceed,raced,archipelago,traits,soils,o'connor,vowel,android,facto,angola,amino,holders,logistics,circuits,emergence,kuwait,partition,emeritus,outcomes,submission,promotes,barack,negotiated,loaned,stripped,50th,excavations,treatments,fierce,participant,exports,decommissioned,cameo,remarked,residences,fuselage,mound,undergo,quarry,node,midwest,specializing,occupies,etc.,showcase,molecule,offs,modules,salon,exposition,revision,peers,positioned,hunters,competes,algorithms,reside,zagreb,calcium,uranium,silicon,airs,counterpart,outlet,collectors,sufficiently,canberra,inmates,anatomy,ensuring,curves,aviv,firearms,basque,volcano,thrust,sheikh,extensions,installations,aluminum,darker,sacked,emphasized,aligned,asserted,pseudonym,spanning,decorations,eighteenth,orbital,spatial,subdivided,notation,decay,macedonian,amended,declining,cyclist,feat,unusually,commuter,birthplace,latitude,activation,overhead,30th,finalists,whites,encyclopedia,tenor,qatar,survives,complement,concentrations,uncommon,astronomical,bangalore,pius,genome,memoir,recruit,prosecutor,modification,paired,container,basilica,arlington,displacement,germanic,mongolia,proportional,debates,matched,calcutta,rows,tehran,aerospace,prevalent,arise,lowland,24th,spokesman,supervised,advertisements,clash,tunes,revelation,wanderers,quarterfinals,fisheries,steadily,memoirs,pastoral,renewable,confluence,acquiring,strips,slogan,upstream,scouting,analyst,practitioners,turbine,strengthened,heavier,prehistoric,plural,excluding,isles,persecution,turin,rotating,villain,hemisphere,unaware,arabs,corpus,relied,singular,unanimous,schooling,passive,angles,dominance,instituted,aria,outskirts,balanced,beginnings,financially,structured,parachute,viewer,attitudes,subjected,escapes,derbyshire,erosion,addressing,styled,declaring,originating,colts,adjusted,stained,occurrence,fortifications,baghdad,nitrogen,localities,yemen,galway,debris,lodz,victorious,pharmaceutical,substances,unnamed,dwelling,atop,developmental,activism,voter,refugee,forested,relates,overlooking,genocide,kannada,insufficient,oversaw,partisan,dioxide,recipients,factions,mortality,capped,expeditions,receptors,reorganized,prominently,atom,flooded,flute,orchestral,scripts,mathematician,airplay,detached,rebuilding,dwarf,brotherhood,salvation,expressions,arabian,cameroon,poetic,recruiting,bundesliga,inserted,scrapped,disabilities,evacuation,pasha,undefeated,crafts,rituals,aluminium,norm,pools,submerged,occupying,pathway,exams,prosperity,wrestlers,promotions,basal,permits,nationalism,trim,merge,gazette,tributaries,transcription,caste,porto,emerge,modeled,adjoining,counterparts,paraguay,redevelopment,renewal,unreleased,equilibrium,similarity,minorities,soviets,comprise,nodes,tasked,unrelated,expired,johan,precursor,examinations,electrons,socialism,exiled,admiralty,floods,wigan,nonprofit,lacks,brigades,screens,repaired,hanover,fascist,labs,osaka,delays,judged,statutory,colt,col.,offspring,solving,bred,assisting,retains,somalia,grouped,corresponds,tunisia,chaplain,eminent,chord,22nd,spans,viral,innovations,possessions,mikhail,kolkata,icelandic,implications,introduces,racism,workforce,alto,compulsory,admits,censorship,onset,reluctant,inferior,iconic,progression,liability,turnout,satellites,behavioral,coordinated,exploitation,posterior,averaging,fringe,krakow,mountainous,greenwich,para,plantations,reinforcements,offerings,famed,intervals,constraints,individually,nutrition,1870s,taxation,threshold,tomatoes,fungi,contractor,ethiopian,apprentice,diabetes,wool,gujarat,honduras,norse,bucharest,23rd,arguably,accompany,prone,teammates,perennial,vacancy,polytechnic,deficit,okinawa,functionality,reminiscent,tolerance,transferring,myanmar,concludes,neighbours,hydraulic,economically,slower,plots,charities,synod,investor,catholicism,identifies,bronx,interpretations,adverse,judiciary,hereditary,nominal,sensor,symmetry,cubic,triangular,tenants,divisional,outreach,representations,passages,undergoing,cartridge,testified,exceeded,impacts,limiting,railroads,defeats,regain,rendering,humid,retreated,reliability,governorate,antwerp,infamous,implied,packaging,lahore,trades,billed,extinction,ecole,rejoined,recognizes,projection,qualifications,stripes,forts,socially,lexington,accurately,sexuality,westward,wikipedia,pilgrimage,abolition,choral,stuttgart,nests,expressing,strikeouts,assessed,monasteries,reconstructed,humorous,marxist,fertile,consort,urdu,patronage,peruvian,devised,lyric,baba,nassau,communism,extraction,popularly,markings,inability,litigation,accounted,processed,emirates,tempo,cadets,eponymous,contests,broadly,oxide,courtyard,frigate,directory,apex,outline,regency,chiefly,patrols,secretariat,cliffs,residency,privy,armament,australians,dorset,geometric,genetics,scholarships,fundraising,flats,demographic,multimedia,captained,documentaries,updates,canvas,blockade,guerrilla,songwriting,administrators,intake,drought,implementing,fraction,cannes,refusal,inscribed,meditation,announcing,exported,ballots,formula_3,curator,basel,arches,flour,subordinate,confrontation,gravel,simplified,berkshire,patriotic,tuition,employing,servers,castile,posting,combinations,discharged,miniature,mutations,constellation,incarnation,ideals,necessity,granting,ancestral,crowds,pioneered,mormon,methodology,rama,indirect,complexes,bavarian,patrons,uttar,skeleton,bollywood,flemish,viable,bloc,breeds,triggered,sustainability,tailed,referenced,comply,takeover,latvian,homestead,platoon,communal,nationality,excavated,targeting,sundays,posed,physicist,turret,endowment,marginal,dispatched,commentators,renovations,attachment,collaborations,ridges,barriers,obligations,shareholders,prof.,defenses,presided,rite,backgrounds,arbitrary,affordable,gloucestershire,thirteenth,inlet,miniseries,possesses,detained,pressures,subscription,realism,solidarity,proto,postgraduate,noun,burmese,abundance,homage,reasoning,anterior,robust,fencing,shifting,vowels,garde,profitable,loch,anchored,coastline,samoa,terminology,prostitution,magistrate,venezuelan,speculated,regulate,fixture,colonists,digit,induction,manned,expeditionary,computational,centennial,principally,vein,preserving,engineered,numerical,cancellation,conferred,continually,borne,seeded,advertisement,unanimously,treaties,infections,ions,sensors,lowered,amphibious,lava,fourteenth,bahrain,niagara,nicaragua,squares,congregations,26th,periodic,proprietary,1860s,contributors,seller,overs,emission,procession,presumed,illustrator,zinc,gases,tens,applicable,stretches,reproductive,sixteenth,apparatus,accomplishments,canoe,guam,oppose,recruitment,accumulated,limerick,namibia,staging,remixes,ordnance,uncertainty,pedestrian,temperate,treason,deposited,registry,cerambycidae,attracting,lankan,reprinted,shipbuilding,homosexuality,neurons,eliminating,1900s,resume,ministries,beneficial,blackpool,surplus,northampton,licenses,constructing,announcer,standardized,alternatives,taipei,inadequate,failures,yields,medalist,titular,obsolete,torah,burlington,predecessors,lublin,retailers,castles,depiction,issuing,gubernatorial,propulsion,tiles,damascus,discs,alternating,pomerania,peasant,tavern,redesignated,27th,illustration,focal,mans,codex,specialists,productivity,antiquity,controversies,promoter,pits,companions,behaviors,lyrical,prestige,creativity,swansea,dramas,approximate,feudal,tissues,crude,campaigned,unprecedented,chancel,amendments,surroundings,allegiance,exchanges,align,firmly,optimal,commenting,reigning,landings,obscure,1850s,contemporaries,paternal,devi,endurance,communes,incorporation,denominations,exchanged,routing,resorts,amnesty,slender,explores,suppression,heats,pronunciation,centred,coupe,stirling,freelance,treatise,linguistics,laos,informs,discovering,pillars,encourages,halted,robots,definitive,maturity,tuberculosis,venetian,silesian,unchanged,originates,mali,lincolnshire,quotes,seniors,premise,contingent,distribute,danube,gorge,logging,dams,curling,seventeenth,specializes,wetlands,deities,assess,thickness,rigid,culminated,utilities,substrate,insignia,nile,assam,shri,currents,suffrage,canadians,mortar,asteroid,bosnian,discoveries,enzymes,sanctioned,replica,hymn,investigators,tidal,dominate,derivatives,converting,leinster,verbs,honoured,criticisms,dismissal,discrete,masculine,reorganization,unlimited,wurttemberg,sacks,allocation,bahn,jurisdictions,participates,lagoon,famine,communion,culminating,surveyed,shortage,cables,intersects,cassette,foremost,adopting,solicitor,outright,bihar,reissued,farmland,dissertation,turnpike,baton,photographed,christchurch,kyoto,finances,rails,histories,linebacker,kilkenny,accelerated,dispersed,handicap,absorption,rancho,ceramic,captivity,cites,font,weighed,mater,utilize,bravery,extract,validity,slovenian,seminars,discourse,ranged,duel,ironically,warships,sega,temporal,surpassed,prolonged,recruits,northumberland,greenland,contributes,patented,eligibility,unification,discusses,reply,translates,beirut,relies,torque,northward,reviewers,monastic,accession,neural,tramway,heirs,sikh,subscribers,amenities,taliban,audit,rotterdam,wagons,kurdish,favoured,combustion,meanings,persia,browser,diagnostic,niger,formula_4,denomination,dividing,parameter,branding,badminton,leningrad,sparked,hurricanes,beetles,propeller,mozambique,refined,diagram,exhaust,vacated,readings,markers,reconciliation,determines,concurrent,imprint,primera,organism,demonstrating,filmmakers,vanderbilt,affiliates,traction,evaluated,defendants,megachile,investigative,zambia,assassinated,rewarded,probable,staffordshire,foreigners,directorate,nominees,consolidation,commandant,reddish,differing,unrest,drilling,bohemia,resembling,instrumentation,considerations,haute,promptly,variously,dwellings,clans,tablet,enforced,cockpit,semifinal,hussein,prisons,ceylon,emblem,monumental,phrases,correspond,crossover,outlined,characterised,acceleration,caucus,crusade,protested,composing,rajasthan,habsburg,rhythmic,interception,inherent,cooled,ponds,spokesperson,gradual,consultation,kuala,globally,suppressed,builders,avengers,suffix,integer,enforce,fibers,unionist,proclamation,uncovered,infrared,adapt,eisenhower,utilizing,captains,stretched,observing,assumes,prevents,analyses,saxophone,caucasus,notices,villains,dartmouth,mongol,hostilities,stretching,veterinary,lenses,texture,prompting,overthrow,excavation,islanders,masovian,battleship,biographer,replay,degradation,departing,luftwaffe,fleeing,oversight,immigrated,serbs,fishermen,strengthening,respiratory,italians,denotes,radial,escorted,motif,wiltshire,expresses,accessories,reverted,establishments,inequality,protocols,charting,famously,satirical,entirety,trench,friction,atletico,sampling,subset,weekday,upheld,sharply,correlation,incorrect,mughal,travelers,hasan,earnings,offset,evaluate,specialised,recognizing,flexibility,nagar,postseason,algebraic,capitalism,crystals,melodies,polynomial,racecourse,defences,austro,wembley,attracts,anarchist,resurrection,reviewing,decreasing,prefix,ratified,mutation,displaying,separating,restoring,assemblies,ordinance,priesthood,cruisers,appoint,moldova,imports,directive,epidemic,militant,senegal,signaling,restriction,critique,retrospective,nationalists,undertake,sioux,canals,algerian,redesigned,philanthropist,depict,conceptual,turbines,intellectuals,eastward,applicants,contractors,vendors,undergone,namesake,ensured,tones,substituted,hindwings,arrests,tombs,transitional,principality,reelection,taiwanese,cavity,manifesto,broadcasters,spawned,thoroughbred,identities,generators,proposes,hydroelectric,johannesburg,cortex,scandinavian,killings,aggression,boycott,catalyst,physiology,fifteenth,waterfront,chromosome,organist,costly,calculation,cemeteries,flourished,recognise,juniors,merging,disciples,ashore,workplace,enlightenment,diminished,debated,hailed,podium,educate,mandated,distributor,litre,electromagnetic,flotilla,estuary,peterborough,staircase,selections,melodic,confronts,wholesale,integrate,intercepted,catalonia,unite,immense,palatinate,switches,earthquakes,occupational,successors,praising,concluding,faculties,firstly,overhaul,empirical,metacritic,inauguration,evergreen,laden,winged,philosophers,amalgamated,geoff,centimeters,napoleonic,upright,planting,brewing,fined,sensory,migrants,wherein,inactive,headmaster,warwickshire,siberia,terminals,denounced,academia,divinity,bilateral,clive,omitted,peerage,relics,apartheid,syndicate,fearing,fixtures,desirable,dismantled,ethnicity,valves,biodiversity,aquarium,ideological,visibility,creators,analyzed,tenant,balkan,postwar,supplier,smithsonian,risen,morphology,digits,bohemian,wilmington,vishnu,demonstrates,aforementioned,biographical,mapped,khorasan,phosphate,presentations,ecosystem,processors,calculations,mosaic,clashes,penned,recalls,coding,angular,lattice,macau,accountability,extracted,pollen,therapeutic,overlap,violinist,deposed,candidacy,infants,covenant,bacterial,restructuring,dungeons,ordination,conducts,builds,invasive,customary,concurrently,relocation,cello,statutes,borneo,entrepreneurs,sanctions,packet,rockefeller,piedmont,comparisons,waterfall,receptions,glacial,surge,signatures,alterations,advertised,enduring,somali,botanist,100th,canonical,motifs,longitude,circulated,alloy,indirectly,margins,preserves,internally,besieged,shale,peripheral,drained,baseman,reassigned,tobago,soloist,socio,grazing,contexts,roofs,portraying,ottomans,shrewsbury,noteworthy,lamps,supplying,beams,qualifier,portray,greenhouse,stronghold,hitter,rites,cretaceous,urging,derive,nautical,aiming,fortunes,verde,donors,reliance,exceeding,exclusion,exercised,simultaneous,continents,guiding,pillar,gradient,poznan,eruption,clinics,moroccan,indicator,trams,piers,parallels,fragment,teatro,potassium,satire,compressed,businessmen,influx,seine,perspectives,shelters,decreases,mounting,formula_5,confederacy,equestrian,expulsion,mayors,liberia,resisted,affinity,shrub,unexpectedly,stimulus,amtrak,deported,perpendicular,statesman,wharf,storylines,romanesque,weights,surfaced,interceptions,dhaka,crambidae,orchestras,rwanda,conclude,constitutes,subsidiaries,admissions,prospective,shear,bilingual,campaigning,presiding,domination,commemorative,trailing,confiscated,petrol,acquisitions,polymer,onlyinclude,chloride,elevations,resolutions,hurdles,pledged,likelihood,objected,erect,encoding,databases,aristotle,hindus,marshes,bowled,ministerial,grange,acronym,annexation,squads,ambient,pilgrims,botany,sofla,astronomer,planetary,descending,bestowed,ceramics,diplomacy,metabolism,colonization,potomac,africans,engraved,recycling,commitments,resonance,disciplinary,jamaican,narrated,spectral,tipperary,waterford,stationary,arbitration,transparency,threatens,crossroads,slalom,oversee,centenary,incidence,economies,livery,moisture,newsletter,autobiographical,bhutan,propelled,dependence,moderately,adobe,barrels,subdivisions,outlook,labelled,stratford,arising,diaspora,barony,automobiles,ornamental,slated,norms,primetime,generalized,analysts,vectors,libyan,yielded,certificates,rooted,vernacular,belarusian,marketplace,prediction,fairfax,malawi,viruses,wooded,demos,mauritius,prosperous,coincided,liberties,huddersfield,ascent,warnings,hinduism,glucose,pulitzer,unused,filters,illegitimate,acquitted,protestants,canopy,staple,psychedelic,winding,abbas,pathways,cheltenham,lagos,niche,invaders,proponents,barred,conversely,doncaster,recession,embraced,rematch,concession,emigration,upgrades,bowls,tablets,remixed,loops,kensington,shootout,monarchs,organizers,harmful,punjabi,broadband,exempt,neolithic,profiles,portrays,parma,cyrillic,quasi,attested,regimental,revive,torpedoes,heidelberg,rhythms,spherical,denote,hymns,icons,theologian,qaeda,exceptionally,reinstated,comune,playhouse,lobbying,grossing,viceroy,delivers,visually,armistice,utrecht,syllable,vertices,analogous,annex,refurbished,entrants,knighted,disciple,rhetoric,detailing,inactivated,ballads,algae,intensified,favourable,sanitation,receivers,pornography,commemorated,cannons,entrusted,manifold,photographers,pueblo,textiles,steamer,myths,marquess,onward,liturgical,romney,uzbekistan,consistency,denoted,hertfordshire,convex,hearings,sulfur,universidad,podcast,selecting,emperors,arises,justices,1840s,mongolian,exploited,termination,digitally,infectious,sedan,symmetric,penal,illustrate,formulation,attribute,problematic,modular,inverse,berth,searches,rutgers,leicestershire,enthusiasts,lockheed,upwards,transverse,accolades,backward,archaeologists,crusaders,nuremberg,defects,ferries,vogue,containers,openings,transporting,separates,lumpur,purchases,attain,wichita,topology,woodlands,deleted,periodically,syntax,overturned,musicals,corp.,strasbourg,instability,nationale,prevailing,cache,marathi,versailles,unmarried,grains,straits,antagonist,segregation,assistants,d'etat,contention,dictatorship,unpopular,motorcycles,criterion,analytical,salzburg,militants,hanged,worcestershire,emphasize,paralympic,erupted,convinces,offences,oxidation,nouns,populace,atari,spanned,hazardous,educators,playable,births,baha'i,preseason,generates,invites,meteorological,handbook,foothills,enclosure,diffusion,mirza,convergence,geelong,coefficient,connector,formula_6,cylindrical,disasters,pleaded,knoxville,contamination,compose,libertarian,arrondissement,franciscan,intercontinental,susceptible,initiation,malaria,unbeaten,consonants,waived,saloon,popularized,estadio,pseudo,interdisciplinary,transports,transformers,carriages,bombings,revolves,ceded,collaborator,celestial,exemption,colchester,maltese,oceanic,ligue,crete,shareholder,routed,depictions,ridden,advisors,calculate,lending,guangzhou,simplicity,newscast,scheduling,snout,eliot,undertaking,armenians,nottinghamshire,whitish,consulted,deficiency,salle,cinemas,superseded,rigorous,kerman,convened,landowners,modernization,evenings,pitches,conditional,scandinavia,differed,formulated,cyclists,swami,guyana,dunes,electrified,appalachian,abdomen,scenarios,prototypes,sindh,consonant,adaptive,boroughs,wolverhampton,modelling,cylinders,amounted,minimize,ambassadors,lenin,settler,coincide,approximation,grouping,murals,bullying,registers,rumours,engagements,energetic,vertex,annals,bordering,geologic,yellowish,runoff,converts,allegheny,facilitated,saturdays,colliery,monitored,rainforest,interfaces,geographically,impaired,prevalence,joachim,paperback,slowed,shankar,distinguishing,seminal,categorized,authorised,auspices,bandwidth,asserts,rebranded,balkans,supplemented,seldom,weaving,capsule,apostles,populous,monmouth,payload,symphonic,densely,shoreline,managerial,masonry,antioch,averages,textbooks,royalist,coliseum,tandem,brewers,diocesan,posthumous,walled,incorrectly,distributions,ensued,reasonably,graffiti,propagation,automation,harmonic,augmented,middleweight,limbs,elongated,landfall,comparatively,literal,grossed,koppen,wavelength,1830s,cerebral,boasts,congestion,physiological,practitioner,coasts,cartoonist,undisclosed,frontal,launches,burgundy,qualifiers,imposing,stade,flanked,assyrian,raided,multiplayer,montane,chesapeake,pathology,drains,vineyards,intercollegiate,semiconductor,grassland,convey,citations,predominant,rejects,benefited,yahoo,graphs,busiest,encompassing,hamlets,explorers,suppress,minors,graphical,calculus,sediment,intends,diverted,mainline,unopposed,cottages,initiate,alumnus,towed,autism,forums,darlington,modernist,oxfordshire,lectured,capitalist,suppliers,panchayat,actresses,foundry,southbound,commodity,wesleyan,divides,palestinians,luton,caretaker,nobleman,mutiny,organizer,preferences,nomenclature,splits,unwilling,offenders,timor,relying,halftime,semitic,arithmetic,milestone,jesuits,arctiidae,retrieved,consuming,contender,edged,plagued,inclusive,transforming,khmer,federally,insurgents,distributing,amherst,rendition,prosecutors,viaduct,disqualified,kabul,liturgy,prevailed,reelected,instructors,swimmers,aperture,churchyard,interventions,totals,darts,metropolis,fuels,fluent,northbound,correctional,inflicted,barrister,realms,culturally,aristocratic,collaborating,emphasizes,choreographer,inputs,ensembles,humboldt,practised,endowed,strains,infringement,archaeologist,congregational,magna,relativity,efficiently,proliferation,mixtape,abruptly,regeneration,commissioning,yukon,archaic,reluctantly,retailer,northamptonshire,universally,crossings,boilers,nickelodeon,revue,abbreviation,retaliation,scripture,routinely,medicinal,benedictine,kenyan,retention,deteriorated,glaciers,apprenticeship,coupling,researched,topography,entrances,anaheim,pivotal,compensate,arched,modify,reinforce,dusseldorf,journeys,motorsport,conceded,sumatra,spaniards,quantitative,loire,cinematography,discarded,botswana,morale,engined,zionist,philanthropy,sainte,fatalities,cypriot,motorsports,indicators,pricing,institut,bethlehem,implicated,gravitational,differentiation,rotor,thriving,precedent,ambiguous,concessions,forecast,conserved,fremantle,asphalt,landslide,middlesbrough,formula_7,humidity,overseeing,chronological,diaries,multinational,crimean,turnover,improvised,youths,declares,tasmanian,canadiens,fumble,refinery,weekdays,unconstitutional,upward,guardians,brownish,imminent,hamas,endorsement,naturalist,martyrs,caledonia,chords,yeshiva,reptiles,severity,mitsubishi,fairs,installment,substitution,repertory,keyboardist,interpreter,silesia,noticeable,rhineland,transmit,inconsistent,booklet,academies,epithet,pertaining,progressively,aquatics,scrutiny,prefect,toxicity,rugged,consume,o'donnell,evolve,uniquely,cabaret,mediated,landowner,transgender,palazzo,compilations,albuquerque,induce,sinai,remastered,efficacy,underside,analogue,specify,possessing,advocating,compatibility,liberated,greenville,mecklenburg,header,memorials,sewage,rhodesia,1800s,salaries,atoll,coordinating,partisans,repealed,amidst,subjective,optimization,nectar,evolving,exploits,madhya,styling,accumulation,raion,postage,responds,buccaneers,frontman,brunei,choreography,coated,kinetic,sampled,inflammatory,complementary,eclectic,norte,vijay,a.k.a,mainz,casualty,connectivity,laureate,franchises,yiddish,reputed,unpublished,economical,periodicals,vertically,bicycles,brethren,capacities,unitary,archeological,tehsil,domesday,wehrmacht,justification,angered,mysore,fielded,abuses,nutrients,ambitions,taluk,battleships,symbolism,superiority,neglect,attendees,commentaries,collaborators,predictions,yorker,breeders,investing,libretto,informally,coefficients,memorandum,pounder,collingwood,tightly,envisioned,arbor,mistakenly,captures,nesting,conflicting,enhancing,streetcar,manufactures,buckinghamshire,rewards,commemorating,stony,expenditure,tornadoes,semantic,relocate,weimar,iberian,sighted,intending,ensign,beverages,expectation,differentiate,centro,utilizes,saxophonist,catchment,transylvania,ecosystems,shortest,sediments,socialists,ineffective,kapoor,formidable,heroine,guantanamo,prepares,scattering,pamphlet,verified,elector,barons,totaling,shrubs,pyrenees,amalgamation,mutually,longitudinal,comte,negatively,masonic,envoy,sexes,akbar,mythical,tonga,bishopric,assessments,malaya,warns,interiors,reefs,reflections,neutrality,musically,nomadic,waterways,provence,collaborate,scaled,adulthood,emerges,euros,optics,incentives,overland,periodical,liege,awarding,realization,slang,affirmed,schooner,hokkaido,czechoslovak,protectorate,undrafted,disagreed,commencement,electors,spruce,swindon,fueled,equatorial,inventions,suites,slovene,backdrop,adjunct,energies,remnant,inhabit,alliances,simulcast,reactors,mosques,travellers,outfielder,plumage,migratory,benin,experimented,fibre,projecting,drafting,laude,evidenced,northernmost,indicted,directional,replication,croydon,comedies,jailed,organizes,devotees,reservoirs,turrets,originate,economists,songwriters,junta,trenches,mounds,proportions,comedic,apostle,azerbaijani,farmhouse,resembled,disrupted,playback,mixes,diagonal,relevance,govern,programmer,gdansk,maize,soundtracks,tendencies,mastered,impacted,believers,kilometre,intervene,chairperson,aerodrome,sails,subsidies,ensures,aesthetics,congresses,ratios,sardinia,southernmost,functioned,controllers,downward,randomly,distortion,regents,palatine,disruption,spirituality,vidhan,tracts,compiler,ventilation,anchorage,symposium,assert,pistols,excelled,avenues,convoys,moniker,constructions,proponent,phased,spines,organising,schleswig,policing,campeonato,mined,hourly,croix,lucrative,authenticity,haitian,stimulation,burkina,espionage,midfield,manually,staffed,awakening,metabolic,biographies,entrepreneurship,conspicuous,guangdong,preface,subgroup,mythological,adjutant,feminism,vilnius,oversees,honourable,tripoli,stylized,kinase,societe,notoriety,altitudes,configurations,outward,transmissions,announces,auditor,ethanol,clube,nanjing,mecca,haifa,blogs,postmaster,paramilitary,depart,positioning,potent,recognizable,spire,brackets,remembrance,overlapping,turkic,articulated,scientology,operatic,deploy,readiness,biotechnology,restrict,cinematographer,inverted,synonymous,administratively,westphalia,commodities,replaces,downloads,centralized,munitions,preached,sichuan,fashionable,implementations,matrices,hiv/aids,loyalist,luzon,celebrates,hazards,heiress,mercenaries,synonym,creole,ljubljana,technician,auditioned,technicians,viewpoint,wetland,mongols,princely,sharif,coating,dynasties,southward,doubling,formula_8,mayoral,harvesting,conjecture,goaltender,oceania,spokane,welterweight,bracket,gatherings,weighted,newscasts,mussolini,affiliations,disadvantage,vibrant,spheres,sultanate,distributors,disliked,establishes,marches,drastically,yielding,jewellery,yokohama,vascular,airlift,canons,subcommittee,repression,strengths,graded,outspoken,fused,pembroke,filmography,redundant,fatigue,repeal,threads,reissue,pennant,edible,vapor,corrections,stimuli,commemoration,dictator,anand,secession,amassed,orchards,pontifical,experimentation,greeted,bangor,forwards,decomposition,quran,trolley,chesterfield,traverse,sermons,burials,skier,climbs,consultants,petitioned,reproduce,parted,illuminated,kurdistan,reigned,occupants,packaged,geometridae,woven,regulating,protagonists,crafted,affluent,clergyman,consoles,migrant,supremacy,attackers,caliph,defect,convection,rallies,huron,resin,segunda,quota,warship,overseen,criticizing,shrines,glamorgan,lowering,beaux,hampered,invasions,conductors,collects,bluegrass,surrounds,substrates,perpetual,chronology,pulmonary,executions,crimea,compiling,noctuidae,battled,tumors,minsk,novgorod,serviced,yeast,computation,swamps,theodor,baronetcy,salford,uruguayan,shortages,odisha,siberian,novelty,cinematic,invitational,decks,dowager,oppression,bandits,appellate,state-of-the-art,clade,palaces,signalling,galaxies,industrialist,tensor,learnt,incurred,magistrates,binds,orbits,ciudad,willingness,peninsular,basins,biomedical,shafts,marlborough,bournemouth,withstand,fitzroy,dunedin,variance,steamship,integrating,muscular,fines,akron,bulbophyllum,malmo,disclosed,cornerstone,runways,medicines,twenty20,gettysburg,progresses,frigates,bodied,transformations,transforms,helens,modelled,versatile,regulator,pursuits,legitimacy,amplifier,scriptures,voyages,examines,presenters,octagonal,poultry,formula_9,anatolia,computed,migrate,directorial,hybrids,localized,preferring,guggenheim,persisted,grassroots,inflammation,fishery,otago,vigorous,professions,instructional,inexpensive,insurgency,legislators,sequels,surnames,agrarian,stainless,nairobi,minas,forerunner,aristocracy,transitions,sicilian,showcased,doses,hiroshima,summarized,gearbox,emancipation,limitation,nuclei,seismic,abandonment,dominating,appropriations,occupations,electrification,hilly,contracting,exaggerated,entertainer,kazan,oricon,cartridges,characterization,parcel,maharaja,exceeds,aspiring,obituary,flattened,contrasted,narration,replies,oblique,outpost,fronts,arranger,talmud,keynes,doctrines,endured,confesses,fortification,supervisors,kilometer,academie,jammu,bathurst,piracy,prostitutes,navarre,cumulative,cruises,lifeboat,twinned,radicals,interacting,expenditures,wexford,libre,futsal,curated,clockwise,colloquially,procurement,immaculate,lyricist,enhancement,porcelain,alzheimer,highlighting,judah,disagreements,storytelling,sheltered,wroclaw,vaudeville,contrasts,neoclassical,compares,contrasting,deciduous,francaise,descriptive,cyclic,reactive,antiquities,meiji,repeats,creditors,forcibly,newmarket,picturesque,impending,uneven,bison,raceway,solvent,ecumenical,optic,professorship,harvested,waterway,banjo,pharaoh,geologist,scanning,dissent,recycled,unmanned,retreating,gospels,aqueduct,branched,tallinn,groundbreaking,syllables,hangar,designations,procedural,craters,cabins,encryption,anthropologist,montevideo,outgoing,inverness,chattanooga,fascism,calais,chapels,groundwater,downfall,misleading,robotic,tortricidae,pixel,handel,prohibit,crewe,renaming,reprised,kickoff,leftist,spaced,integers,causeway,pines,authorship,organise,ptolemy,accessibility,virtues,lesions,iroquois,qur'an,atheist,synthesized,biennial,confederates,dietary,skaters,stresses,tariff,koreans,intercity,republics,quintet,baroness,naive,amplitude,insistence,tbilisi,residues,grammatical,diversified,egyptians,accompaniment,vibration,repository,mandal,topological,distinctions,coherent,invariant,batters,nuevo,internationals,implements,follower,bahia,widened,independents,cantonese,totaled,guadalajara,wolverines,befriended,muzzle,surveying,hungarians,medici,deportation,rayon,approx,recounts,attends,clerical,hellenic,furnished,alleging,soluble,systemic,gallantry,bolshevik,intervened,hostel,gunpowder,specialising,stimulate,leiden,removes,thematic,floral,bafta,printers,conglomerate,eroded,analytic,successively,lehigh,thessaloniki,kilda,clauses,ascended,nehru,scripted,tokugawa,competence,diplomats,exclude,consecration,freedoms,assaults,revisions,blacksmith,textual,sparse,concacaf,slain,uploaded,enraged,whaling,guise,stadiums,debuting,dormitory,cardiovascular,yunnan,dioceses,consultancy,notions,lordship,archdeacon,collided,medial,airfields,garment,wrestled,adriatic,reversal,refueling,verification,jakob,horseshoe,intricate,veracruz,sarawak,syndication,synthesizer,anthologies,stature,feasibility,guillaume,narratives,publicized,antrim,intermittent,constituents,grimsby,filmmaking,doping,unlawful,nominally,transmitting,documenting,seater,internationale,ejected,steamboat,alsace,boise,ineligible,geared,vassal,mustered,ville,inline,pairing,eurasian,kyrgyzstan,barnsley,reprise,stereotypes,rushes,conform,firefighters,deportivo,revolutionaries,rabbis,concurrency,charters,sustaining,aspirations,algiers,chichester,falkland,morphological,systematically,volcanoes,designate,artworks,reclaimed,jurist,anglia,resurrected,chaotic,feasible,circulating,simulated,environmentally,confinement,adventist,harrisburg,laborers,ostensibly,universiade,pensions,influenza,bratislava,octave,refurbishment,gothenburg,putin,barangay,annapolis,breaststroke,illustrates,distorted,choreographed,promo,emphasizing,stakeholders,descends,exhibiting,intrinsic,invertebrates,evenly,roundabout,salts,formula_10,strata,inhibition,branching,stylistic,rumored,realises,mitochondrial,commuted,adherents,logos,bloomberg,telenovela,guineas,charcoal,engages,winery,reflective,siena,cambridgeshire,ventral,flashback,installing,engraving,grasses,traveller,rotated,proprietor,nationalities,precedence,sourced,trainers,cambodian,reductions,depleted,saharan,classifications,biochemistry,plaintiffs,arboretum,humanist,fictitious,aleppo,climates,bazaar,his/her,homogeneous,multiplication,moines,indexed,linguist,skeletal,foliage,societal,differentiated,informing,mammal,infancy,archival,cafes,malls,graeme,musee,schizophrenia,fargo,pronouns,derivation,descend,ascending,terminating,deviation,recaptured,confessions,weakening,tajikistan,bahadur,pasture,b/hip,donegal,supervising,sikhs,thinkers,euclidean,reinforcement,friars,portage,fuscous,lucknow,synchronized,assertion,choirs,privatization,corrosion,multitude,skyscraper,royalties,ligament,usable,spores,directs,clashed,stockport,fronted,dependency,contiguous,biologist,backstroke,powerhouse,frescoes,phylogenetic,welding,kildare,gabon,conveyed,augsburg,severn,continuum,sahib,lille,injuring,passeriformesfamily,succeeds,translating,unitarian,startup,turbulent,outlying,philanthropic,stanislaw,idols,claremont,conical,haryana,armagh,blended,implicit,conditioned,modulation,rochdale,labourers,coinage,shortstop,potsdam,gears,obesity,bestseller,advisers,bouts,comedians,jozef,lausanne,taxonomic,correlated,columbian,marne,indications,psychologists,libel,edict,beaufort,disadvantages,renal,finalized,racehorse,unconventional,disturbances,falsely,zoology,adorned,redesign,executing,narrower,commended,appliances,stalls,resurgence,saskatoon,miscellaneous,permitting,epoch,formula_11,cumbria,forefront,vedic,eastenders,disposed,supermarkets,rower,inhibitor,magnesium,colourful,yusuf,harrow,formulas,centrally,balancing,ionic,nocturnal,consolidate,ornate,raiding,charismatic,accelerate,nominate,residual,dhabi,commemorates,attribution,uninhabited,mindanao,atrocities,genealogical,romani,applicant,enactment,abstraction,trough,pulpit,minuscule,misconduct,grenades,timely,supplements,messaging,curvature,ceasefire,telangana,susquehanna,braking,redistribution,shreveport,neighbourhoods,gregorian,widowed,khuzestan,empowerment,scholastic,evangelist,peptide,topical,theorist,historia,thence,sudanese,museo,jurisprudence,masurian,frankish,headlined,recounted,netball,petitions,tolerant,hectare,truncated,southend,methane,captives,reigns,massif,subunit,acidic,weightlifting,footballers,sabah,britannia,tunisian,segregated,sawmill,withdrawing,unpaid,weaponry,somme,perceptions,unicode,alcoholism,durban,wrought,waterfalls,jihad,auschwitz,upland,eastbound,adjective,anhalt,evaluating,regimes,guildford,reproduced,pamphlets,hierarchical,maneuvers,hanoi,fabricated,repetition,enriched,arterial,replacements,tides,globalization,adequately,westbound,satisfactory,fleets,phosphorus,lastly,neuroscience,anchors,xinjiang,membranes,improvisation,shipments,orthodoxy,submissions,bolivian,mahmud,ramps,leyte,pastures,outlines,flees,transmitters,fares,sequential,stimulated,novice,alternately,symmetrical,breakaway,layered,baronets,lizards,blackish,edouard,horsepower,penang,principals,mercantile,maldives,overwhelmingly,hawke,rallied,prostate,conscription,juveniles,maccabi,carvings,strikers,sudbury,spurred,improves,lombardy,macquarie,parisian,elastic,distillery,shetland,humane,brentford,wrexham,warehouses,routines,encompassed,introductory,isfahan,instituto,palais,revolutions,sporadic,impoverished,portico,fellowships,speculative,enroll,dormant,adhere,fundamentally,sculpted,meritorious,template,upgrading,reformer,rectory,uncredited,indicative,creeks,galveston,radically,hezbollah,firearm,educating,prohibits,trondheim,locus,refit,headwaters,screenings,lowlands,wasps,coarse,attaining,sedimentary,perished,pitchfork,interned,cerro,stagecoach,aeronautical,liter,transitioned,haydn,inaccurate,legislatures,bromwich,knesset,spectroscopy,butte,asiatic,degraded,concordia,catastrophic,lobes,wellness,pensacola,periphery,hapoel,theta,horizontally,freiburg,liberalism,pleas,durable,warmian,offenses,mesopotamia,shandong,unsuitable,hospitalized,appropriately,phonetic,encompass,conversions,observes,illnesses,breakout,assigns,crowns,inhibitors,nightly,manifestation,fountains,maximize,alphabetical,sloop,expands,newtown,widening,gaddafi,commencing,camouflage,footprint,tyrol,barangays,universite,highlanders,budgets,query,lobbied,westchester,equator,stipulated,pointe,distinguishes,allotted,embankment,advises,storing,loyalists,fourier,rehearsals,starvation,gland,rihanna,tubular,expressive,baccalaureate,intersections,revered,carbonate,eritrea,craftsmen,cosmopolitan,sequencing,corridors,shortlisted,bangladeshi,persians,mimic,parades,repetitive,recommends,flanks,promoters,incompatible,teaming,ammonia,greyhound,solos,improper,legislator,newsweek,recurrent,vitro,cavendish,eireann,crises,prophets,mandir,strategically,guerrillas,formula_12,ghent,contenders,equivalence,drone,sociological,hamid,castes,statehood,aland,clinched,relaunched,tariffs,simulations,williamsburg,rotate,mediation,smallpox,harmonica,lodges,lavish,restrictive,o'sullivan,detainees,polynomials,echoes,intersecting,learners,elects,charlemagne,defiance,epsom,liszt,facilitating,absorbing,revelations,padua,pieter,pious,penultimate,mammalian,montenegrin,supplementary,widows,aromatic,croats,roanoke,trieste,legions,subdistrict,babylonian,grasslands,volga,violently,sparsely,oldies,telecommunication,respondents,quarries,downloadable,commandos,taxpayer,catalytic,malabar,afforded,copying,declines,nawab,junctions,assessing,filtering,classed,disused,compliant,christoph,gottingen,civilizations,hermitage,caledonian,whereupon,ethnically,springsteen,mobilization,terraces,indus,excel,zoological,enrichment,simulate,guitarists,registrar,cappella,invoked,reused,manchu,configured,uppsala,genealogy,mergers,casts,curricular,rebelled,subcontinent,horticultural,parramatta,orchestrated,dockyard,claudius,decca,prohibiting,turkmenistan,brahmin,clandestine,obligatory,elaborated,parasitic,helix,constraint,spearheaded,rotherham,eviction,adapting,albans,rescues,sociologist,guiana,convicts,occurrences,kamen,antennas,asturias,wheeled,sanitary,deterioration,trier,theorists,baseline,announcements,valea,planners,factual,serialized,serials,bilbao,demoted,fission,jamestown,cholera,alleviate,alteration,indefinite,sulfate,paced,climatic,valuation,artisans,proficiency,aegean,regulators,fledgling,sealing,influencing,servicemen,frequented,cancers,tambon,narayan,bankers,clarified,embodied,engraver,reorganisation,dissatisfied,dictated,supplemental,temperance,ratification,puget,nutrient,pretoria,papyrus,uniting,ascribed,cores,coptic,schoolhouse,barrio,1910s,armory,defected,transatlantic,regulates,ported,artefacts,specifies,boasted,scorers,mollusks,emitted,navigable,quakers,projective,dialogues,reunification,exponential,vastly,banners,unsigned,dissipated,halves,coincidentally,leasing,purported,escorting,estimation,foxes,lifespan,inflorescence,assimilation,showdown,staunch,prologue,ligand,superliga,telescopes,northwards,keynote,heaviest,taunton,redeveloped,vocalists,podlaskie,soyuz,rodents,azores,moravian,outset,parentheses,apparel,domestically,authoritative,polymers,monterrey,inhibit,launcher,jordanian,folds,taxis,mandates,singled,liechtenstein,subsistence,marxism,ousted,governorship,servicing,offseason,modernism,prism,devout,translators,islamist,chromosomes,pitted,bedfordshire,fabrication,authoritarian,javanese,leaflets,transient,substantive,predatory,sigismund,assassinate,diagrams,arrays,rediscovered,reclamation,spawning,fjord,peacekeeping,strands,fabrics,highs,regulars,tirana,ultraviolet,athenian,filly,barnet,naacp,nueva,favourites,terminates,showcases,clones,inherently,interpreting,bjorn,finely,lauded,unspecified,chola,pleistocene,insulation,antilles,donetsk,funnel,nutritional,biennale,reactivated,southport,primate,cavaliers,austrians,interspersed,restarted,suriname,amplifiers,wladyslaw,blockbuster,sportsman,minogue,brightness,benches,bridgeport,initiating,israelis,orbiting,newcomers,externally,scaling,transcribed,impairment,luxurious,longevity,impetus,temperament,ceilings,tchaikovsky,spreads,pantheon,bureaucracy,1820s,heraldic,villas,formula_13,galician,meath,avoidance,corresponded,headlining,connacht,seekers,rappers,solids,monograph,scoreless,opole,isotopes,himalayas,parodies,garments,microscopic,republished,havilland,orkney,demonstrators,pathogen,saturated,hellenistic,facilitates,aerodynamic,relocating,indochina,laval,astronomers,bequeathed,administrations,extracts,nagoya,torquay,demography,medicare,ambiguity,renumbered,pursuant,concave,syriac,electrode,dispersal,henan,bialystok,walsall,crystalline,puebla,janata,illumination,tianjin,enslaved,coloration,championed,defamation,grille,johor,rejoin,caspian,fatally,planck,workings,appointing,institutionalized,wessex,modernized,exemplified,regatta,jacobite,parochial,programmers,blending,eruptions,insurrection,regression,indices,sited,dentistry,mobilized,furnishings,levant,primaries,ardent,nagasaki,conqueror,dorchester,opined,heartland,amman,mortally,wellesley,bowlers,outputs,coveted,orthography,immersion,disrepair,disadvantaged,curate,childless,condensed,codice_1,remodeled,resultant,bolsheviks,superfamily,saxons,2010s,contractual,rivalries,malacca,oaxaca,magnate,vertebrae,quezon,olympiad,yucatan,tyres,macro,specialization,commendation,caliphate,gunnery,exiles,excerpts,fraudulent,adjustable,aramaic,interceptor,drumming,standardization,reciprocal,adolescents,federalist,aeronautics,favorably,enforcing,reintroduced,zhejiang,refining,biplane,banknotes,accordion,intersect,illustrating,summits,classmate,militias,biomass,massacres,epidemiology,reworked,wrestlemania,nantes,auditory,taxon,elliptical,chemotherapy,asserting,avoids,proficient,airmen,yellowstone,multicultural,alloys,utilization,seniority,kuyavian,huntsville,orthogonal,bloomington,cultivars,casimir,internment,repulsed,impedance,revolving,fermentation,parana,shutout,partnering,empowered,islamabad,polled,classify,amphibians,greyish,obedience,4x100,projectile,khyber,halfback,relational,d'ivoire,synonyms,endeavour,padma,customized,mastery,defenceman,berber,purge,interestingly,covent,promulgated,restricting,condemnation,hillsborough,walkers,privateer,intra,captaincy,naturalized,huffington,detecting,hinted,migrating,bayou,counterattack,anatomical,foraging,unsafe,swiftly,outdated,paraguayan,attire,masjid,endeavors,jerseys,triassic,quechua,growers,axial,accumulate,wastewater,cognition,fungal,animator,pagoda,kochi,uniformly,antibody,yerevan,hypotheses,combatants,italianate,draining,fragmentation,snowfall,formative,inversion,kitchener,identifier,additive,lucha,selects,ashland,cambrian,racetrack,trapping,congenital,primates,wavelengths,expansions,yeomanry,harcourt,wealthiest,awaited,punta,intervening,aggressively,vichy,piloted,midtown,tailored,heyday,metadata,guadalcanal,inorganic,hadith,pulses,francais,tangent,scandals,erroneously,tractors,pigment,constabulary,jiangsu,landfill,merton,basalt,astor,forbade,debuts,collisions,exchequer,stadion,roofed,flavour,sculptors,conservancy,dissemination,electrically,undeveloped,existent,surpassing,pentecostal,manifested,amend,formula_14,superhuman,barges,tunis,analytics,argyll,liquids,mechanized,domes,mansions,himalayan,indexing,reuters,nonlinear,purification,exiting,timbers,triangles,decommissioning,departmental,causal,fonts,americana,sept.,seasonally,incomes,razavi,sheds,memorabilia,rotational,terre,sutra,protege,yarmouth,grandmaster,annum,looted,imperialism,variability,liquidation,baptised,isotope,showcasing,milling,rationale,hammersmith,austen,streamlined,acknowledging,contentious,qaleh,breadth,turing,referees,feral,toulon,unofficially,identifiable,standout,labeling,dissatisfaction,jurgen,angrily,featherweight,cantons,constrained,dominates,standalone,relinquished,theologians,markedly,italics,downed,nitrate,likened,gules,craftsman,singaporean,pixels,mandela,moray,parity,departement,antigen,academically,burgh,brahma,arranges,wounding,triathlon,nouveau,vanuatu,banded,acknowledges,unearthed,stemming,authentication,byzantines,converge,nepali,commonplace,deteriorating,recalling,palette,mathematicians,greenish,pictorial,ahmedabad,rouen,validation,u.s.a.,'best,malvern,archers,converter,undergoes,fluorescent,logistical,notification,transvaal,illicit,symphonies,stabilization,worsened,fukuoka,decrees,enthusiast,seychelles,blogger,louvre,dignitaries,burundi,wreckage,signage,pinyin,bursts,federer,polarization,urbana,lazio,schism,nietzsche,venerable,administers,seton,kilograms,invariably,kathmandu,farmed,disqualification,earldom,appropriated,fluctuations,kermanshah,deployments,deformation,wheelbase,maratha,psalm,bytes,methyl,engravings,skirmish,fayette,vaccines,ideally,astrology,breweries,botanic,opposes,harmonies,irregularities,contended,gaulle,prowess,constants,aground,filipinos,fresco,ochreous,jaipur,willamette,quercus,eastwards,mortars,champaign,braille,reforming,horned,hunan,spacious,agitation,draught,specialties,flourishing,greensboro,necessitated,swedes,elemental,whorls,hugely,structurally,plurality,synthesizers,embassies,assad,contradictory,inference,discontent,recreated,inspectors,unicef,commuters,embryo,modifying,stints,numerals,communicated,boosted,trumpeter,brightly,adherence,remade,leases,restrained,eucalyptus,dwellers,planar,grooves,gainesville,daimler,anzac,szczecin,cornerback,prized,peking,mauritania,khalifa,motorized,lodging,instrumentalist,fortresses,cervical,formula_15,passerine,sectarian,researches,apprenticed,reliefs,disclose,gliding,repairing,queue,kyushu,literate,canoeing,sacrament,separatist,calabria,parkland,flowed,investigates,statistically,visionary,commits,dragoons,scrolls,premieres,revisited,subdued,censored,patterned,elective,outlawed,orphaned,leyland,richly,fujian,miniatures,heresy,plaques,countered,nonfiction,exponent,moravia,dispersion,marylebone,midwestern,enclave,ithaca,federated,electronically,handheld,microscopy,tolls,arrivals,climbers,continual,cossacks,moselle,deserts,ubiquitous,gables,forecasts,deforestation,vertebrates,flanking,drilled,superstructure,inspected,consultative,bypassed,ballast,subsidy,socioeconomic,relic,grenada,journalistic,administering,accommodated,collapses,appropriation,reclassified,foreword,porte,assimilated,observance,fragmented,arundel,thuringia,gonzaga,shenzhen,shipyards,sectional,ayrshire,sloping,dependencies,promenade,ecuadorian,mangrove,constructs,goalscorer,heroism,iteration,transistor,omnibus,hampstead,cochin,overshadowed,chieftain,scalar,finishers,ghanaian,abnormalities,monoplane,encyclopaedia,characterize,travancore,baronetage,bearers,biking,distributes,paving,christened,inspections,banco,humber,corinth,quadratic,albanians,lineages,majored,roadside,inaccessible,inclination,darmstadt,fianna,epilepsy,propellers,papacy,montagu,bhutto,sugarcane,optimized,pilasters,contend,batsmen,brabant,housemates,sligo,ascot,aquinas,supervisory,accorded,gerais,echoed,nunavut,conservatoire,carniola,quartermaster,gminas,impeachment,aquitaine,reformers,quarterfinal,karlsruhe,accelerator,coeducational,archduke,gelechiidae,seaplane,dissident,frenchman,palau,depots,hardcover,aachen,darreh,denominational,groningen,parcels,reluctance,drafts,elliptic,counters,decreed,airship,devotional,contradiction,formula_16,undergraduates,qualitative,guatemalan,slavs,southland,blackhawks,detrimental,abolish,chechen,manifestations,arthritis,perch,fated,hebei,peshawar,palin,immensely,havre,totalling,rampant,ferns,concourse,triples,elites,olympian,larva,herds,lipid,karabakh,distal,monotypic,vojvodina,batavia,multiplied,spacing,spellings,pedestrians,parchment,glossy,industrialization,dehydrogenase,patriotism,abolitionist,mentoring,elizabethan,figurative,dysfunction,abyss,constantin,middletown,stigma,mondays,gambia,gaius,israelites,renounced,nepalese,overcoming,buren,sulphur,divergence,predation,looting,iberia,futuristic,shelved,anthropological,innsbruck,escalated,clermont,entrepreneurial,benchmark,mechanically,detachments,populist,apocalyptic,exited,embryonic,stanza,readership,chiba,landlords,expansive,boniface,therapies,perpetrators,whitehall,kassel,masts,carriageway,clinch,pathogens,mazandaran,undesirable,teutonic,miocene,nagpur,juris,cantata,compile,diffuse,dynastic,reopening,comptroller,o'neal,flourish,electing,scientifically,departs,welded,modal,cosmology,fukushima,libertadores,chang'an,asean,generalization,localization,afrikaans,cricketers,accompanies,emigrants,esoteric,southwards,shutdown,prequel,fittings,innate,wrongly,equitable,dictionaries,senatorial,bipolar,flashbacks,semitism,walkway,lyrically,legality,sorbonne,vigorously,durga,samoan,karel,interchanges,patna,decider,registering,electrodes,anarchists,excursion,overthrown,gilan,recited,michelangelo,advertiser,kinship,taboo,cessation,formula_17,premiers,traversed,madurai,poorest,torneo,exerted,replicate,spelt,sporadically,horde,landscaping,razed,hindered,esperanto,manchuria,propellant,jalan,baha'is,sikkim,linguists,pandit,racially,ligands,dowry,francophone,escarpment,behest,magdeburg,mainstay,villiers,yangtze,grupo,conspirators,martyrdom,noticeably,lexical,kazakh,unrestricted,utilised,sired,inhabits,proofs,joseon,pliny,minted,buddhists,cultivate,interconnected,reuse,viability,australasian,derelict,resolving,overlooks,menon,stewardship,playwrights,thwarted,filmfare,disarmament,protections,bundles,sidelined,hypothesized,singer/songwriter,forage,netted,chancery,townshend,restructured,quotation,hyperbolic,succumbed,parliaments,shenandoah,apical,kibbutz,storeys,pastors,lettering,ukrainians,hardships,chihuahua,avail,aisles,taluka,antisemitism,assent,ventured,banksia,seamen,hospice,faroe,fearful,woreda,outfield,chlorine,transformer,tatar,panoramic,pendulum,haarlem,styria,cornice,importing,catalyzes,subunits,enamel,bakersfield,realignment,sorties,subordinates,deanery,townland,gunmen,tutelage,evaluations,allahabad,thrace,veneto,mennonite,sharia,subgenus,satisfies,puritan,unequal,gastrointestinal,ordinances,bacterium,horticulture,argonauts,adjectives,arable,duets,visualization,woolwich,revamped,euroleague,thorax,completes,originality,vasco,freighter,sardar,oratory,sects,extremes,signatories,exporting,arisen,exacerbated,departures,saipan,furlongs,d'italia,goring,dakar,conquests,docked,offshoot,okrug,referencing,disperse,netting,summed,rewritten,articulation,humanoid,spindle,competitiveness,preventive,facades,westinghouse,wycombe,synthase,emulate,fostering,abdel,hexagonal,myriad,caters,arjun,dismay,axiom,psychotherapy,colloquial,complemented,martinique,fractures,culmination,erstwhile,atrium,electronica,anarchism,nadal,montpellier,algebras,submitting,adopts,stemmed,overcame,internacional,asymmetric,gallipoli,gliders,flushing,extermination,hartlepool,tesla,interwar,patriarchal,hitherto,ganges,combatant,marred,philology,glastonbury,reversible,isthmus,undermined,southwark,gateshead,andalusia,remedies,hastily,optimum,smartphone,evade,patrolled,beheaded,dopamine,waivers,ugandan,gujarati,densities,predicting,intestinal,tentative,interstellar,kolonia,soloists,penetrated,rebellions,qeshlaq,prospered,colegio,deficits,konigsberg,deficient,accessing,relays,kurds,politburo,codified,incarnations,occupancy,cossack,metaphysical,deprivation,chopra,piccadilly,formula_18,makeshift,protestantism,alaskan,frontiers,faiths,tendon,dunkirk,durability,autobots,bonuses,coinciding,emails,gunboat,stucco,magma,neutrons,vizier,subscriptions,visuals,envisaged,carpets,smoky,schema,parliamentarian,immersed,domesticated,parishioners,flinders,diminutive,mahabharata,ballarat,falmouth,vacancies,gilded,twigs,mastering,clerics,dalmatia,islington,slogans,compressor,iconography,congolese,sanction,blends,bulgarians,moderator,outflow,textures,safeguard,trafalgar,tramways,skopje,colonialism,chimneys,jazeera,organisers,denoting,motivations,ganga,longstanding,deficiencies,gwynedd,palladium,holistic,fascia,preachers,embargo,sidings,busan,ignited,artificially,clearwater,cemented,northerly,salim,equivalents,crustaceans,oberliga,quadrangle,historiography,romanians,vaults,fiercely,incidental,peacetime,tonal,bhopal,oskar,radha,pesticides,timeslot,westerly,cathedrals,roadways,aldershot,connectors,brahmins,paler,aqueous,gustave,chromatic,linkage,lothian,specialises,aggregation,tributes,insurgent,enact,hampden,ghulam,federations,instigated,lyceum,fredrik,chairmanship,floated,consequent,antagonists,intimidation,patriarchate,warbler,heraldry,entrenched,expectancy,habitation,partitions,widest,launchers,nascent,ethos,wurzburg,lycee,chittagong,mahatma,merseyside,asteroids,yokosuka,cooperatives,quorum,redistricting,bureaucratic,yachts,deploying,rustic,phonology,chorale,cellist,stochastic,crucifixion,surmounted,confucian,portfolios,geothermal,crested,calibre,tropics,deferred,nasir,iqbal,persistence,essayist,chengdu,aborigines,fayetteville,bastion,interchangeable,burlesque,kilmarnock,specificity,tankers,colonels,fijian,quotations,enquiry,quito,palmerston,delle,multidisciplinary,polynesian,iodine,antennae,emphasised,manganese,baptists,galilee,jutland,latent,excursions,skepticism,tectonic,precursors,negligible,musique,misuse,vitoria,expressly,veneration,sulawesi,footed,mubarak,chongqing,chemically,midday,ravaged,facets,varma,yeovil,ethnographic,discounted,physicists,attache,disbanding,essen,shogunate,cooperated,waikato,realising,motherwell,pharmacology,sulfide,inward,expatriate,devoid,cultivar,monde,andean,groupings,goran,unaffected,moldovan,postdoctoral,coleophora,delegated,pronoun,conductivity,coleridge,disapproval,reappeared,microbial,campground,olsztyn,fostered,vaccination,rabbinical,champlain,milestones,viewership,caterpillar,effected,eupithecia,financier,inferred,uzbek,bundled,bandar,balochistan,mysticism,biosphere,holotype,symbolizes,lovecraft,photons,abkhazia,swaziland,subgroups,measurable,falkirk,valparaiso,ashok,discriminatory,rarity,tabernacle,flyweight,jalisco,westernmost,antiquarian,extracellular,margrave,colspan=9,midsummer,digestive,reversing,burgeoning,substitutes,medallist,khrushchev,guerre,folio,detonated,partido,plentiful,aggregator,medallion,infiltration,shaded,santander,fared,auctioned,permian,ramakrishna,andorra,mentors,diffraction,bukit,potentials,translucent,feminists,tiers,protracted,coburg,wreath,guelph,adventurer,he/she,vertebrate,pipelines,celsius,outbreaks,australasia,deccan,garibaldi,unionists,buildup,biochemical,reconstruct,boulders,stringent,barbed,wording,furnaces,pests,befriends,organises,popes,rizal,tentacles,cadre,tallahassee,punishments,occidental,formatted,mitigation,rulings,rubens,cascades,inducing,choctaw,volta,synagogues,movable,altarpiece,mitigate,practise,intermittently,encountering,memberships,earns,signify,retractable,amounting,pragmatic,wilfrid,dissenting,divergent,kanji,reconstituted,devonian,constitutions,levied,hendrik,starch,costal,honduran,ditches,polygon,eindhoven,superstars,salient,argus,punitive,purana,alluvial,flaps,inefficient,retracted,advantageous,quang,andersson,danville,binghamton,symbolize,conclave,shaanxi,silica,interpersonal,adept,frans,pavilions,lubbock,equip,sunken,limburg,activates,prosecutions,corinthian,venerated,shootings,retreats,parapet,orissa,riviere,animations,parodied,offline,metaphysics,bluffs,plume,piety,fruition,subsidized,steeplechase,shanxi,eurasia,angled,forecasting,suffragan,ashram,larval,labyrinth,chronicler,summaries,trailed,merges,thunderstorms,filtered,formula_19,advertisers,alpes,informatics,parti,constituting,undisputed,certifications,javascript,molten,sclerosis,rumoured,boulogne,hmong,lewes,breslau,notts,bantu,ducal,messengers,radars,nightclubs,bantamweight,carnatic,kaunas,fraternal,triggering,controversially,londonderry,visas,scarcity,offaly,uprisings,repelled,corinthians,pretext,kuomintang,kielce,empties,matriculated,pneumatic,expos,agile,treatises,midpoint,prehistory,oncology,subsets,hydra,hypertension,axioms,wabash,reiterated,swapped,achieves,premio,ageing,overture,curricula,challengers,subic,selangor,liners,frontline,shutter,validated,normalized,entertainers,molluscs,maharaj,allegation,youngstown,synth,thoroughfare,regionally,pillai,transcontinental,pedagogical,riemann,colonia,easternmost,tentatively,profiled,herefordshire,nativity,meuse,nucleotide,inhibits,huntingdon,throughput,recorders,conceding,domed,homeowners,centric,gabled,canoes,fringes,breeder,subtitled,fluoride,haplogroup,zionism,izmir,phylogeny,kharkiv,romanticism,adhesion,usaaf,delegations,lorestan,whalers,biathlon,vaulted,mathematically,pesos,skirmishes,heisman,kalamazoo,gesellschaft,launceston,interacts,quadruple,kowloon,psychoanalysis,toothed,ideologies,navigational,valence,induces,lesotho,frieze,rigging,undercarriage,explorations,spoof,eucharist,profitability,virtuoso,recitals,subterranean,sizeable,herodotus,subscriber,huxley,pivot,forewing,warring,boleslaw,bharatiya,suffixes,trois,percussionist,downturn,garrisons,philosophies,chants,mersin,mentored,dramatist,guilds,frameworks,thermodynamic,venomous,mehmed,assembling,rabbinic,hegemony,replicas,enlargement,claimant,retitled,utica,dumfries,metis,deter,assortment,tubing,afflicted,weavers,rupture,ornamentation,transept,salvaged,upkeep,callsign,rajput,stevenage,trimmed,intracellular,synchronization,consular,unfavorable,royalists,goldwyn,fasting,hussars,doppler,obscurity,currencies,amiens,acorn,tagore,townsville,gaussian,migrations,porta,anjou,graphite,seaport,monographs,gladiators,metrics,calligraphy,sculptural,swietokrzyskie,tolombeh,eredivisie,shoals,queries,carts,exempted,fiberglass,mirrored,bazar,progeny,formalized,mukherjee,professed,amazon.com,cathode,moreton,removable,mountaineers,nagano,transplantation,augustinian,steeply,epilogue,adapter,decisively,accelerating,mediaeval,substituting,tasman,devonshire,litres,enhancements,himmler,nephews,bypassing,imperfect,argentinian,reims,integrates,sochi,ascii,licences,niches,surgeries,fables,versatility,indra,footpath,afonso,crore,evaporation,encodes,shelling,conformity,simplify,updating,quotient,overt,firmware,umpires,architectures,eocene,conservatism,secretion,embroidery,f.c..,tuvalu,mosaics,shipwreck,prefectural,cohort,grievances,garnering,centerpiece,apoptosis,djibouti,bethesda,formula_20,shonen,richland,justinian,dormitories,meteorite,reliably,obtains,pedagogy,hardness,cupola,manifolds,amplification,steamers,familial,dumbarton,jerzy,genital,maidstone,salinity,grumman,signifies,presbytery,meteorology,procured,aegis,streamed,deletion,nuestra,mountaineering,accords,neuronal,khanate,grenoble,axles,dispatches,tokens,turku,auctions,propositions,planters,proclaiming,recommissioned,stravinsky,obverse,bombarded,waged,saviour,massacred,reformist,purportedly,resettlement,ravenna,embroiled,minden,revitalization,hikers,bridging,torpedoed,depletion,nizam,affectionately,latitudes,lubeck,spore,polymerase,aarhus,nazism,101st,buyout,galerie,diets,overflow,motivational,renown,brevet,deriving,melee,goddesses,demolish,amplified,tamworth,retake,brokerage,beneficiaries,henceforth,reorganised,silhouette,browsers,pollutants,peron,lichfield,encircled,defends,bulge,dubbing,flamenco,coimbatore,refinement,enshrined,grizzlies,capacitor,usefulness,evansville,interscholastic,rhodesian,bulletins,diamondbacks,rockers,platted,medalists,formosa,transporter,slabs,guadeloupe,disparate,concertos,violins,regaining,mandible,untitled,agnostic,issuance,hamiltonian,brampton,srpska,homology,downgraded,florentine,epitaph,kanye,rallying,analysed,grandstand,infinitely,antitrust,plundered,modernity,colspan=3|total,amphitheatre,doric,motorists,yemeni,carnivorous,probabilities,prelate,struts,scrapping,bydgoszcz,pancreatic,signings,predicts,compendium,ombudsman,apertura,appoints,rebbe,stereotypical,valladolid,clustered,touted,plywood,inertial,kettering,curving,d'honneur,housewives,grenadier,vandals,barbarossa,necked,waltham,reputedly,jharkhand,cistercian,pursues,viscosity,organiser,cloister,islet,stardom,moorish,himachal,strives,scripps,staggered,blasts,westwards,millimeters,angolan,hubei,agility,admirals,mordellistena,coincides,platte,vehicular,cordillera,riffs,schoolteacher,canaan,acoustics,tinged,reinforcing,concentrates,daleks,monza,selectively,musik,polynesia,exporter,reviving,macclesfield,bunkers,ballets,manors,caudal,microbiology,primes,unbroken,outcry,flocks,pakhtunkhwa,abelian,toowoomba,luminous,mould,appraisal,leuven,experimentally,interoperability,hideout,perak,specifying,knighthood,vasily,excerpt,computerized,niels,networked,byzantium,reaffirmed,geographer,obscured,fraternities,mixtures,allusion,accra,lengthened,inquest,panhandle,pigments,revolts,bluetooth,conjugate,overtaken,foray,coils,breech,streaks,impressionist,mendelssohn,intermediary,panned,suggestive,nevis,upazila,rotunda,mersey,linnaeus,anecdotes,gorbachev,viennese,exhaustive,moldavia,arcades,irrespective,orator,diminishing,predictive,cohesion,polarized,montage,avian,alienation,conus,jaffna,urbanization,seawater,extremity,editorials,scrolling,dreyfus,traverses,topographic,gunboats,extratropical,normans,correspondents,recognises,millennia,filtration,ammonium,voicing,complied,prefixes,diplomas,figurines,weakly,gated,oscillator,lucerne,embroidered,outpatient,airframe,fractional,disobedience,quarterbacks,formula_21,shinto,chiapas,epistle,leakage,pacifist,avignon,penrith,renders,mantua,screenplays,gustaf,tesco,alphabetically,rations,discharges,headland,tapestry,manipur,boolean,mediator,ebenezer,subchannel,fable,bestselling,ateneo,trademarks,recurrence,dwarfs,britannica,signifying,vikram,mediate,condensation,censuses,verbandsgemeinde,cartesian,sprang,surat,britons,chelmsford,courtenay,statistic,retina,abortions,liabilities,closures,mississauga,skyscrapers,saginaw,compounded,aristocrat,msnbc,stavanger,septa,interpretive,hinder,visibly,seeding,shutouts,irregularly,quebecois,footbridge,hydroxide,implicitly,lieutenants,simplex,persuades,midshipman,heterogeneous,officiated,crackdown,lends,tartu,altars,fractions,dissidents,tapered,modernisation,scripting,blazon,aquaculture,thermodynamics,sistan,hasidic,bellator,pavia,propagated,theorized,bedouin,transnational,mekong,chronicled,declarations,kickstarter,quotas,runtime,duquesne,broadened,clarendon,brownsville,saturation,tatars,electorates,malayan,replicated,observable,amphitheater,endorsements,referral,allentown,mormons,pantomime,eliminates,typeface,allegorical,varna,conduction,evoke,interviewer,subordinated,uyghur,landscaped,conventionally,ascend,edifice,postulated,hanja,whitewater,embarking,musicologist,tagalog,frontage,paratroopers,hydrocarbons,transliterated,nicolae,viewpoints,surrealist,asheville,falklands,hacienda,glide,opting,zimbabwean,discal,mortgages,nicaraguan,yadav,ghosh,abstracted,castilian,compositional,cartilage,intergovernmental,forfeited,importation,rapping,artes,republika,narayana,condominium,frisian,bradman,duality,marche,extremist,phosphorylation,genomes,allusions,valencian,habeas,ironworks,multiplex,harpsichord,emigrate,alternated,breda,waffen,smartphones,familiarity,regionalliga,herbaceous,piping,dilapidated,carboniferous,xviii,critiques,carcinoma,sagar,chippewa,postmodern,neapolitan,excludes,notoriously,distillation,tungsten,richness,installments,monoxide,chand,privatisation,molded,maths,projectiles,luoyang,epirus,lemma,concentric,incline,erroneous,sideline,gazetted,leopards,fibres,renovate,corrugated,unilateral,repatriation,orchestration,saeed,rockingham,loughborough,formula_22,bandleader,appellation,openness,nanotechnology,massively,tonnage,dunfermline,exposes,moored,ridership,motte,eurobasket,majoring,feats,silla,laterally,playlist,downwards,methodologies,eastbourne,daimyo,cellulose,leyton,norwalk,oblong,hibernian,opaque,insular,allegory,camogie,inactivation,favoring,masterpieces,rinpoche,serotonin,portrayals,waverley,airliner,longford,minimalist,outsourcing,excise,meyrick,qasim,organisational,synaptic,farmington,gorges,scunthorpe,zoned,tohoku,librarians,davao,decor,theatrically,brentwood,pomona,acquires,planter,capacitors,synchronous,skateboarding,coatings,turbocharged,ephraim,capitulation,scoreboard,hebrides,ensues,cereals,ailing,counterpoint,duplication,antisemitic,clique,aichi,oppressive,transcendental,incursions,rename,renumbering,powys,vestry,bitterly,neurology,supplanted,affine,susceptibility,orbiter,activating,overlaps,ecoregion,raman,canoer,darfur,microorganisms,precipitated,protruding,torun,anthropologists,rennes,kangaroos,parliamentarians,edits,littoral,archived,begum,rensselaer,microphones,ypres,empower,etruscan,wisden,montfort,calibration,isomorphic,rioting,kingship,verbally,smyrna,cohesive,canyons,fredericksburg,rahul,relativistic,micropolitan,maroons,industrialized,henchmen,uplift,earthworks,mahdi,disparity,cultured,transliteration,spiny,fragmentary,extinguished,atypical,inventors,biosynthesis,heralded,curacao,anomalies,aeroplane,surya,mangalore,maastricht,ashkenazi,fusiliers,hangzhou,emitting,monmouthshire,schwarzenegger,ramayana,peptides,thiruvananthapuram,alkali,coimbra,budding,reasoned,epithelial,harbors,rudimentary,classically,parque,ealing,crusades,rotations,riparian,pygmy,inertia,revolted,microprocessor,calendars,solvents,kriegsmarine,accademia,cheshmeh,yoruba,ardabil,mitra,genomic,notables,propagate,narrates,univision,outposts,polio,birkenhead,urinary,crocodiles,pectoral,barrymore,deadliest,rupees,chaim,protons,comical,astrophysics,unifying,formula_23,vassals,cortical,audubon,pedals,tenders,resorted,geophysical,lenders,recognising,tackling,lanarkshire,doctrinal,annan,combating,guangxi,estimating,selectors,tribunals,chambered,inhabiting,exemptions,curtailed,abbasid,kandahar,boron,bissau,150th,codenamed,wearer,whorl,adhered,subversive,famer,smelting,inserting,mogadishu,zoologist,mosul,stumps,almanac,olympiacos,stamens,participatory,cults,honeycomb,geologists,dividend,recursive,skiers,reprint,pandemic,liber,percentages,adversely,stoppage,chieftains,tubingen,southerly,overcrowding,unorganized,hangars,fulfil,hails,cantilever,woodbridge,pinus,wiesbaden,fertilization,fluorescence,enhances,plenary,troublesome,episodic,thrissur,kickboxing,allele,staffing,garda,televisions,philatelic,spacetime,bullpen,oxides,leninist,enrolling,inventive,truro,compatriot,ruskin,normative,assay,gotha,murad,illawarra,gendarmerie,strasse,mazraeh,rebounded,fanfare,liaoning,rembrandt,iranians,emirate,governs,latency,waterfowl,chairmen,katowice,aristocrats,eclipsed,sentient,sonatas,interplay,sacking,decepticons,dynamical,arbitrarily,resonant,petar,velocities,alludes,wastes,prefectures,belleville,sensibility,salvadoran,consolidating,medicaid,trainees,vivekananda,molar,porous,upload,youngster,infused,doctorates,wuhan,annihilation,enthusiastically,gamespot,kanpur,accumulating,monorail,operetta,tiling,sapporo,finns,calvinist,hydrocarbon,sparrows,orienteering,cornelis,minster,vuelta,plebiscite,embraces,panchayats,focussed,remediation,brahman,olfactory,reestablished,uniqueness,northumbria,rwandan,predominately,abode,ghats,balances,californian,uptake,bruges,inert,westerns,reprints,cairn,yarra,resurfaced,audible,rossini,regensburg,italiana,fleshy,irrigated,alerts,yahya,varanasi,marginalized,expatriates,cantonment,normandie,sahitya,directives,rounder,hulls,fictionalized,constables,inserts,hipped,potosi,navies,biologists,canteen,husbandry,augment,fortnight,assamese,kampala,o'keefe,paleolithic,bluish,promontory,consecutively,striving,niall,reuniting,dipole,friendlies,disapproved,thrived,netflix,liberian,dielectric,medway,strategist,sankt,pickups,hitters,encode,rerouted,claimants,anglesey,partitioned,cavan,flutes,reared,repainted,armaments,bowed,thoracic,balliol,piero,chaplains,dehestan,sender,junkers,sindhi,sickle,dividends,metallurgy,honorific,berths,namco,springboard,resettled,gansu,copyrighted,criticizes,utopian,bendigo,ovarian,binomial,spaceflight,oratorio,proprietors,supergroup,duplicated,foreground,strongholds,revolved,optimize,layouts,westland,hurler,anthropomorphic,excelsior,merchandising,reeds,vetoed,cryptography,hollyoaks,monash,flooring,ionian,resilience,johnstown,resolves,lawmakers,alegre,wildcards,intolerance,subculture,selector,slums,formulate,bayonet,istvan,restitution,interchangeably,awakens,rostock,serpentine,oscillation,reichstag,phenotype,recessed,piotr,annotated,preparedness,consultations,clausura,preferential,euthanasia,genoese,outcrops,freemasonry,geometrical,genesee,islets,prometheus,panamanian,thunderbolt,terraced,stara,shipwrecks,futebol,faroese,sharqi,aldermen,zeitung,unify,formula_24,humanism,syntactic,earthen,blyth,taxed,rescinded,suleiman,cymru,dwindled,vitality,superieure,resupply,adolphe,ardennes,rajiv,profiling,olympique,gestation,interfaith,milosevic,tagline,funerary,druze,silvery,plough,shrubland,relaunch,disband,nunatak,minimizing,excessively,waned,attaching,luminosity,bugle,encampment,electrostatic,minesweeper,dubrovnik,rufous,greenock,hochschule,assyrians,extracting,malnutrition,priya,attainment,anhui,connotations,predicate,seabirds,deduced,pseudonyms,gopal,plovdiv,refineries,imitated,kwazulu,terracotta,tenets,discourses,brandeis,whigs,dominions,pulmonate,landslides,tutors,determinant,richelieu,farmstead,tubercles,technicolor,hegel,redundancy,greenpeace,shortening,mules,distilled,xxiii,fundamentalist,acrylic,outbuildings,lighted,corals,signaled,transistors,cavite,austerity,76ers,exposures,dionysius,outlining,commutative,permissible,knowledgeable,howrah,assemblage,inhibited,crewmen,mbit/s,pyramidal,aberdeenshire,bering,rotates,atheism,howitzer,saone,lancet,fermented,contradicted,materiel,ofsted,numeric,uniformity,josephus,nazarene,kuwaiti,noblemen,pediment,emergent,campaigner,akademi,murcia,perugia,gallen,allsvenskan,finned,cavities,matriculation,rosters,twickenham,signatory,propel,readable,contends,artisan,flamboyant,reggio,italo,fumbles,widescreen,rectangle,centimetres,collaborates,envoys,rijeka,phonological,thinly,refractive,civilisation,reductase,cognate,dalhousie,monticello,lighthouses,jitsu,luneburg,socialite,fermi,collectible,optioned,marquee,jokingly,architecturally,kabir,concubine,nationalisation,watercolor,wicklow,acharya,pooja,leibniz,rajendra,nationalized,stalemate,bloggers,glutamate,uplands,shivaji,carolingian,bucuresti,dasht,reappears,muscat,functionally,formulations,hinged,hainan,catechism,autosomal,incremental,asahi,coeur,diversification,multilateral,fewest,recombination,finisher,harrogate,hangul,feasts,photovoltaic,paget,liquidity,alluded,incubation,applauded,choruses,malagasy,hispanics,bequest,underparts,cassava,kazimierz,gastric,eradication,mowtowr,tyrosine,archbishopric,e9e9e9,unproductive,uxbridge,hydrolysis,harbours,officio,deterministic,devonport,kanagawa,breaches,freetown,rhinoceros,chandigarh,janos,sanatorium,liberator,inequalities,agonist,hydrophobic,constructors,nagorno,snowboarding,welcomes,subscribed,iloilo,resuming,catalysts,stallions,jawaharlal,harriers,definitively,roughriders,hertford,inhibiting,elgar,randomized,incumbents,episcopate,rainforests,yangon,improperly,kemal,interpreters,diverged,uttarakhand,umayyad,phnom,panathinaikos,shabbat,diode,jiangxi,forbidding,nozzle,artistry,licensee,processions,staffs,decimated,expressionism,shingle,palsy,ontology,mahayana,maribor,sunil,hostels,edwardian,jetty,freehold,overthrew,eukaryotic,schuylkill,rawalpindi,sheath,recessive,ferenc,mandibles,berlusconi,confessor,convergent,ababa,slugging,rentals,sephardic,equivalently,collagen,markov,dynamically,hailing,depressions,sprawling,fairgrounds,indistinguishable,plutarch,pressurized,banff,coldest,braunschweig,mackintosh,sociedad,wittgenstein,tromso,airbase,lecturers,subtitle,attaches,purified,contemplated,dreamworks,telephony,prophetic,rockland,aylesbury,biscay,coherence,aleksandar,judoka,pageants,theses,homelessness,luthor,sitcoms,hinterland,fifths,derwent,privateers,enigmatic,nationalistic,instructs,superimposed,conformation,tricycle,dusan,attributable,unbeknownst,laptops,etching,archbishops,ayatollah,cranial,gharbi,interprets,lackawanna,abingdon,saltwater,tories,lender,minaj,ancillary,ranching,pembrokeshire,topographical,plagiarism,murong,marque,chameleon,assertions,infiltrated,guildhall,reverence,schenectady,formula_25,kollam,notary,mexicana,initiates,abdication,basra,theorems,ionization,dismantling,eared,censors,budgetary,numeral,verlag,excommunicated,distinguishable,quarried,cagliari,hindustan,symbolizing,watertown,descartes,relayed,enclosures,militarily,sault,devolved,dalian,djokovic,filaments,staunton,tumour,curia,villainous,decentralized,galapagos,moncton,quartets,onscreen,necropolis,brasileiro,multipurpose,alamos,comarca,jorgen,concise,mercia,saitama,billiards,entomologist,montserrat,lindbergh,commuting,lethbridge,phoenician,deviations,anaerobic,denouncing,redoubt,fachhochschule,principalities,negros,announcers,seconded,parrots,konami,revivals,approving,devotee,riyadh,overtook,morecambe,lichen,expressionist,waterline,silverstone,geffen,sternites,aspiration,behavioural,grenville,tripura,mediums,genders,pyotr,charlottesville,sacraments,programmable,ps100,shackleton,garonne,sumerian,surpass,authorizing,interlocking,lagoons,voiceless,advert,steeple,boycotted,alouettes,yosef,oxidative,sassanid,benefiting,sayyid,nauru,predetermined,idealism,maxillary,polymerization,semesters,munchen,conor,outfitted,clapham,progenitor,gheorghe,observational,recognitions,numerically,colonized,hazrat,indore,contaminants,fatality,eradicate,assyria,convocation,cameos,skillful,skoda,corfu,confucius,overtly,ramadan,wollongong,placements,d.c..,permutation,contemporaneous,voltages,elegans,universitat,samar,plunder,dwindling,neuter,antonin,sinhala,campania,solidified,stanzas,fibrous,marburg,modernize,sorcery,deutscher,florets,thakur,disruptive,infielder,disintegration,internazionale,vicariate,effigy,tripartite,corrective,klamath,environs,leavenworth,sandhurst,workmen,compagnie,hoseynabad,strabo,palisades,ordovician,sigurd,grandsons,defection,viacom,sinhalese,innovator,uncontrolled,slavonic,indexes,refrigeration,aircrew,superbike,resumption,neustadt,confrontations,arras,hindenburg,ripon,embedding,isomorphism,dwarves,matchup,unison,lofty,argos,louth,constitutionally,transitive,newington,facelift,degeneration,perceptual,aviators,enclosing,igneous,symbolically,academician,constitutionality,iso/iec,sacrificial,maturation,apprentices,enzymology,naturalistic,hajji,arthropods,abbess,vistula,scuttled,gradients,pentathlon,etudes,freedmen,melaleuca,thrice,conductive,sackville,franciscans,stricter,golds,kites,worshiped,monsignor,trios,orally,tiered,primacy,bodywork,castleford,epidemics,alveolar,chapelle,chemists,hillsboro,soulful,warlords,ngati,huguenot,diurnal,remarking,luger,motorways,gauss,jahan,cutoff,proximal,bandai,catchphrase,jonubi,ossetia,codename,codice_2,throated,itinerant,chechnya,riverfront,leela,evoked,entailed,zamboanga,rejoining,circuitry,haymarket,khartoum,feuds,braced,miyazaki,mirren,lubusz,caricature,buttresses,attrition,characterizes,widnes,evanston,materialism,contradictions,marist,midrash,gainsborough,ulithi,turkmen,vidya,escuela,patrician,inspirations,reagent,premierships,humanistic,euphrates,transitioning,belfry,zedong,adaption,kaliningrad,lobos,epics,waiver,coniferous,polydor,inductee,refitted,moraine,unsatisfactory,worsening,polygamy,rajya,nested,subgenre,broadside,stampeders,lingua,incheon,pretender,peloton,persuading,excitation,multan,predates,tonne,brackish,autoimmune,insulated,podcasts,iraqis,bodybuilding,condominiums,midlothian,delft,debtor,asymmetrical,lycaenidae,forcefully,pathogenic,tamaulipas,andaman,intravenous,advancements,senegalese,chronologically,realigned,inquirer,eusebius,dekalb,additives,shortlist,goldwater,hindustani,auditing,caterpillars,pesticide,nakhon,ingestion,lansdowne,traditionalist,northland,thunderbirds,josip,nominating,locale,ventricular,animators,verandah,epistles,surveyors,anthems,dredd,upheaval,passaic,anatolian,svalbard,associative,floodplain,taranaki,estuaries,irreducible,beginners,hammerstein,allocate,coursework,secreted,counteract,handwritten,foundational,passover,discoverer,decoding,wares,bourgeoisie,playgrounds,nazionale,abbreviations,seanad,golan,mishra,godavari,rebranding,attendances,backstory,interrupts,lettered,hasbro,ultralight,hormozgan,armee,moderne,subdue,disuse,improvisational,enrolment,persists,moderated,carinthia,hatchback,inhibitory,capitalized,anatoly,abstracts,albemarle,bergamo,insolvency,sentai,cellars,walloon,joked,kashmiri,dirac,materialized,renomination,homologous,gusts,eighteens,centrifugal,storied,baluchestan,formula_26,poincare,vettel,infuriated,gauges,streetcars,vedanta,stately,liquidated,goguryeo,swifts,accountancy,levee,acadian,hydropower,eustace,comintern,allotment,designating,torsion,molding,irritation,aerobic,halen,concerted,plantings,garrisoned,gramophone,cytoplasm,onslaught,requisitioned,relieving,genitive,centrist,jeong,espanola,dissolving,chatterjee,sparking,connaught,varese,arjuna,carpathian,empowering,meteorologist,decathlon,opioid,hohenzollern,fenced,ibiza,avionics,footscray,scrum,discounts,filament,directories,a.f.c,stiffness,quaternary,adventurers,transmits,harmonious,taizong,radiating,germantown,ejection,projectors,gaseous,nahuatl,vidyalaya,nightlife,redefined,refuted,destitute,arista,potters,disseminated,distanced,jamboree,kaohsiung,tilted,lakeshore,grained,inflicting,kreis,novelists,descendents,mezzanine,recast,fatah,deregulation,ac/dc,australis,kohgiluyeh,boreal,goths,authoring,intoxicated,nonpartisan,theodosius,pyongyang,shree,boyhood,sanfl,plenipotentiary,photosynthesis,presidium,sinaloa,honshu,texan,avenida,transmembrane,malays,acropolis,catalunya,vases,inconsistencies,methodists,quell,suisse,banat,simcoe,cercle,zealanders,discredited,equine,sages,parthian,fascists,interpolation,classifying,spinoff,yehuda,cruised,gypsum,foaled,wallachia,saraswati,imperialist,seabed,footnotes,nakajima,locales,schoolmaster,drosophila,bridgehead,immanuel,courtier,bookseller,niccolo,stylistically,portmanteau,superleague,konkani,millimetres,arboreal,thanjavur,emulation,sounders,decompression,commoners,infusion,methodological,osage,rococo,anchoring,bayreuth,formula_27,abstracting,symbolized,bayonne,electrolyte,rowed,corvettes,traversing,editorship,sampler,presidio,curzon,adirondack,swahili,rearing,bladed,lemur,pashtun,behaviours,bottling,zaire,recognisable,systematics,leeward,formulae,subdistricts,smithfield,vijaya,buoyancy,boosting,cantonal,rishi,airflow,kamakura,adana,emblems,aquifer,clustering,husayn,woolly,wineries,montessori,turntable,exponentially,caverns,espoused,pianists,vorpommern,vicenza,latterly,o'rourke,williamstown,generale,kosice,duisburg,poirot,marshy,mismanagement,mandalay,dagenham,universes,chiral,radiated,stewards,vegan,crankshaft,kyrgyz,amphibian,cymbals,infrequently,offenbach,environmentalist,repatriated,permutations,midshipmen,loudoun,refereed,bamberg,ornamented,nitric,selim,translational,dorsum,annunciation,gippsland,reflector,informational,regia,reactionary,ahmet,weathering,erlewine,legalized,berne,occupant,divas,manifests,analyzes,disproportionate,mitochondria,totalitarian,paulista,interscope,anarcho,correlate,brookfield,elongate,brunel,ordinal,precincts,volatility,equaliser,hittite,somaliland,ticketing,monochrome,ubuntu,chhattisgarh,titleholder,ranches,referendums,blooms,accommodates,merthyr,religiously,ryukyu,tumultuous,checkpoints,anode,mi'kmaq,cannonball,punctuation,remodelled,assassinations,criminology,alternates,yonge,pixar,namibian,piraeus,trondelag,hautes,lifeboats,shoal,atelier,vehemently,sadat,postcode,jainism,lycoming,undisturbed,lutherans,genomics,popmatters,tabriz,isthmian,notched,autistic,horsham,mites,conseil,bloomsbury,seung,cybertron,idris,overhauled,disbandment,idealized,goldfields,worshippers,lobbyist,ailments,paganism,herbarium,athenians,messerschmitt,faraday,entangled,'olya,untreated,criticising,howitzers,parvati,lobed,debussy,atonement,tadeusz,permeability,mueang,sepals,degli,optionally,fuelled,follies,asterisk,pristina,lewiston,congested,overpass,affixed,pleads,telecasts,stanislaus,cryptographic,friesland,hamstring,selkirk,antisubmarine,inundated,overlay,aggregates,fleur,trolleybus,sagan,ibsen,inductees,beltway,tiled,ladders,cadbury,laplace,ascetic,micronesia,conveying,bellingham,cleft,batches,usaid,conjugation,macedon,assisi,reappointed,brine,jinnah,prairies,screenwriting,oxidized,despatches,linearly,fertilizers,brazilians,absorbs,wagga,modernised,scorsese,ashraf,charlestown,esque,habitable,nizhny,lettres,tuscaloosa,esplanade,coalitions,carbohydrates,legate,vermilion,standardised,galleria,psychoanalytic,rearrangement,substation,competency,nationalised,reshuffle,reconstructions,mehdi,bougainville,receivership,contraception,enlistment,conducive,aberystwyth,solicitors,dismisses,fibrosis,montclair,homeowner,surrealism,s.h.i.e.l.d,peregrine,compilers,1790s,parentage,palmas,rzeszow,worldview,eased,svenska,housemate,bundestag,originator,enlisting,outwards,reciprocity,formula_28,carbohydrate,democratically,firefighting,romagna,acknowledgement,khomeini,carbide,quests,vedas,characteristically,guwahati,brixton,unintended,brothels,parietal,namur,sherbrooke,moldavian,baruch,milieu,undulating,laurier,entre,dijon,ethylene,abilene,heracles,paralleling,ceres,dundalk,falun,auspicious,chisinau,polarity,foreclosure,templates,ojibwe,punic,eriksson,biden,bachchan,glaciation,spitfires,norsk,nonviolent,heidegger,algonquin,capacitance,cassettes,balconies,alleles,airdate,conveys,replays,classifies,infrequent,amine,cuttings,rarer,woking,olomouc,amritsar,rockabilly,illyrian,maoist,poignant,tempore,stalinist,segmented,bandmate,mollusc,muhammed,totalled,byrds,tendered,endogenous,kottayam,aisne,oxidase,overhears,illustrators,verve,commercialization,purplish,directv,moulded,lyttelton,baptismal,captors,saracens,georgios,shorten,polity,grids,fitzwilliam,sculls,impurities,confederations,akhtar,intangible,oscillations,parabolic,harlequin,maulana,ovate,tanzanian,singularity,confiscation,qazvin,speyer,phonemes,overgrown,vicarage,gurion,undocumented,niigata,thrones,preamble,stave,interment,liiga,ataturk,aphrodite,groupe,indentured,habsburgs,caption,utilitarian,ozark,slovenes,reproductions,plasticity,serbo,dulwich,castel,barbuda,salons,feuding,lenape,wikileaks,swamy,breuning,shedding,afield,superficially,operationally,lamented,okanagan,hamadan,accolade,furthering,adolphus,fyodor,abridged,cartoonists,pinkish,suharto,cytochrome,methylation,debit,colspan=9|,refine,taoist,signalled,herding,leaved,bayan,fatherland,rampart,sequenced,negation,storyteller,occupiers,barnabas,pelicans,nadir,conscripted,railcars,prerequisite,furthered,columba,carolinas,markup,gwalior,franche,chaco,eglinton,ramparts,rangoon,metabolites,pollination,croat,televisa,holyoke,testimonial,setlist,safavid,sendai,georgians,shakespearean,galleys,regenerative,krzysztof,overtones,estado,barbary,cherbourg,obispo,sayings,composites,sainsbury,deliberation,cosmological,mahalleh,embellished,ascap,biala,pancras,calumet,grands,canvases,antigens,marianas,defenseman,approximated,seedlings,soren,stele,nuncio,immunology,testimonies,glossary,recollections,suitability,tampere,venous,cohomology,methanol,echoing,ivanovich,warmly,sterilization,imran,multiplying,whitechapel,undersea,xuanzong,tacitus,bayesian,roundhouse,correlations,rioters,molds,fiorentina,bandmates,mezzo,thani,guerilla,200th,premiums,tamils,deepwater,chimpanzees,tribesmen,selwyn,globo,turnovers,punctuated,erode,nouvelle,banbury,exponents,abolishing,helical,maimonides,endothelial,goteborg,infield,encroachment,cottonwood,mazowiecki,parable,saarbrucken,reliever,epistemology,artistes,enrich,rationing,formula_29,palmyra,subfamilies,kauai,zoran,fieldwork,arousal,creditor,friuli,celts,comoros,equated,escalation,negev,tallied,inductive,anion,netanyahu,mesoamerican,lepidoptera,aspirated,remit,westmorland,italic,crosse,vaclav,fuego,owain,balmain,venetians,ethnicities,deflected,ticino,apulia,austere,flycatcher,reprising,repressive,hauptbahnhof,subtype,ophthalmology,summarizes,eniwetok,colonisation,subspace,nymphalidae,earmarked,tempe,burnet,crests,abbots,norwegians,enlarge,ashoka,frankfort,livorno,malware,renters,singly,iliad,moresby,rookies,gustavus,affirming,alleges,legume,chekhov,studded,abdicated,suzhou,isidore,townsite,repayment,quintus,yankovic,amorphous,constructor,narrowing,industrialists,tanganyika,capitalization,connective,mughals,rarities,aerodynamics,worthing,antalya,diagnostics,shaftesbury,thracian,obstetrics,benghazi,multiplier,orbitals,livonia,roscommon,intensify,ravel,oaths,overseer,locomotion,necessities,chickasaw,strathclyde,treviso,erfurt,aortic,contemplation,accrington,markazi,predeceased,hippocampus,whitecaps,assemblyman,incursion,ethnography,extraliga,reproducing,directorship,benzene,byway,stupa,taxable,scottsdale,onondaga,favourably,countermeasures,lithuanians,thatched,deflection,tarsus,consuls,annuity,paralleled,contextual,anglian,klang,hoisted,multilingual,enacting,samaj,taoiseach,carthaginian,apologised,hydrology,entrant,seamless,inflorescences,mugabe,westerners,seminaries,wintering,penzance,mitre,sergeants,unoccupied,delimitation,discriminate,upriver,abortive,nihon,bessarabia,calcareous,buffaloes,patil,daegu,streamline,berks,chaparral,laity,conceptions,typified,kiribati,threaded,mattel,eccentricity,signified,patagonia,slavonia,certifying,adnan,astley,sedition,minimally,enumerated,nikos,goalless,walid,narendra,causa,missoula,coolant,dalek,outcrop,hybridization,schoolchildren,peasantry,afghans,confucianism,shahr,gallic,tajik,kierkegaard,sauvignon,commissar,patriarchs,tuskegee,prussians,laois,ricans,talmudic,officiating,aesthetically,baloch,antiochus,separatists,suzerainty,arafat,shading,u.s.c,chancellors,inc..,toolkit,nepenthes,erebidae,solicited,pratap,kabbalah,alchemist,caltech,darjeeling,biopic,spillway,kaiserslautern,nijmegen,bolstered,neath,pahlavi,eugenics,bureaus,retook,northfield,instantaneous,deerfield,humankind,selectivity,putative,boarders,cornhuskers,marathas,raikkonen,aliabad,mangroves,garages,gulch,karzai,poitiers,chernobyl,thane,alexios,belgrano,scion,solubility,urbanized,executable,guizhou,nucleic,tripled,equalled,harare,houseguests,potency,ghazi,repeater,overarching,regrouped,broward,ragtime,d'art,nandi,regalia,campsites,mamluk,plating,wirral,presumption,zenit,archivist,emmerdale,decepticon,carabidae,kagoshima,franconia,guarani,formalism,diagonally,submarginal,denys,walkways,punts,metrolink,hydrographic,droplets,upperside,martyred,hummingbird,antebellum,curiously,mufti,friary,chabad,czechs,shaykh,reactivity,berklee,turbonilla,tongan,sultans,woodville,unlicensed,enmity,dominicans,operculum,quarrying,watercolour,catalyzed,gatwick,'what,mesozoic,auditors,shizuoka,footballing,haldane,telemundo,appended,deducted,disseminate,o'shea,pskov,abrasive,entente,gauteng,calicut,lemurs,elasticity,suffused,scopula,staining,upholding,excesses,shostakovich,loanwords,naidu,championnat,chromatography,boasting,goaltenders,engulfed,salah,kilogram,morristown,shingles,shi'a,labourer,renditions,frantisek,jekyll,zonal,nanda,sheriffs,eigenvalues,divisione,endorsing,ushered,auvergne,cadres,repentance,freemasons,utilising,laureates,diocletian,semiconductors,o'grady,vladivostok,sarkozy,trackage,masculinity,hydroxyl,mervyn,muskets,speculations,gridiron,opportunistic,mascots,aleutian,fillies,sewerage,excommunication,borrowers,capillary,trending,sydenham,synthpop,rajah,cagayan,deportes,kedah,faure,extremism,michoacan,levski,culminates,occitan,bioinformatics,unknowingly,inciting,emulated,footpaths,piacenza,dreadnought,viceroyalty,oceanographic,scouted,combinatorial,ornithologist,cannibalism,mujahideen,independiente,cilicia,hindwing,minimized,odeon,gyorgy,rubles,purchaser,collieries,kickers,interurban,coiled,lynchburg,respondent,plzen,detractors,etchings,centering,intensification,tomography,ranjit,warblers,retelling,reinstatement,cauchy,modulus,redirected,evaluates,beginner,kalateh,perforated,manoeuvre,scrimmage,internships,megawatts,mottled,haakon,tunbridge,kalyan,summarised,sukarno,quetta,canonized,henryk,agglomeration,coahuila,diluted,chiropractic,yogyakarta,talladega,sheik,cation,halting,reprisals,sulfuric,musharraf,sympathizers,publicised,arles,lectionary,fracturing,startups,sangha,latrobe,rideau,ligaments,blockading,cremona,lichens,fabaceae,modulated,evocative,embodies,battersea,indistinct,altai,subsystem,acidity,somatic,formula_30,tariq,rationality,sortie,ashlar,pokal,cytoplasmic,valour,bangla,displacing,hijacking,spectrometry,westmeath,weill,charing,goias,revolvers,individualized,tenured,nawaz,piquet,chanted,discard,bernd,phalanx,reworking,unilaterally,subclass,yitzhak,piloting,circumvent,disregarded,semicircular,viscous,tibetans,endeavours,retaliated,cretan,vienne,workhouse,sufficiency,aurangzeb,legalization,lipids,expanse,eintracht,sanjak,megas,125th,bahraini,yakima,eukaryotes,thwart,affirmation,peloponnese,retailing,carbonyl,chairwoman,macedonians,dentate,rockaway,correctness,wealthier,metamorphic,aragonese,fermanagh,pituitary,schrodinger,evokes,spoiler,chariots,akita,genitalia,combe,confectionery,desegregation,experiential,commodores,persepolis,viejo,restorations,virtualization,hispania,printmaking,stipend,yisrael,theravada,expended,radium,tweeted,polygonal,lippe,charente,leveraged,cutaneous,fallacy,fragrant,bypasses,elaborately,rigidity,majid,majorca,kongo,plasmodium,skits,audiovisual,eerste,staircases,prompts,coulthard,northwestward,riverdale,beatrix,copyrights,prudential,communicates,mated,obscenity,asynchronous,analyse,hansa,searchlight,farnborough,patras,asquith,qarah,contours,fumbled,pasteur,redistributed,almeria,sanctuaries,jewry,israelite,clinicians,koblenz,bookshop,affective,goulburn,panelist,sikorsky,cobham,mimics,ringed,portraiture,probabilistic,girolamo,intelligible,andalusian,jalal,athenaeum,eritrean,auxiliaries,pittsburg,devolution,sangam,isolating,anglers,cronulla,annihilated,kidderminster,synthesize,popularised,theophilus,bandstand,innumerable,chagrin,retroactively,weser,multiples,birdlife,goryeo,pawnee,grosser,grappling,tactile,ahmadinejad,turboprop,erdogan,matchday,proletarian,adhering,complements,austronesian,adverts,luminaries,archeology,impressionism,conifer,sodomy,interracial,platoons,lessen,postings,pejorative,registrations,cookery,persecutions,microbes,audits,idiosyncratic,subsp,suspensions,restricts,colouring,ratify,instrumentals,nucleotides,sulla,posits,bibliotheque,diameters,oceanography,instigation,subsumed,submachine,acceptor,legation,borrows,sedge,discriminated,loaves,insurers,highgate,detectable,abandons,kilns,sportscaster,harwich,iterations,preakness,arduous,tensile,prabhu,shortwave,philologist,shareholding,vegetative,complexities,councilors,distinctively,revitalize,automaton,amassing,montreux,khanh,surabaya,nurnberg,pernambuco,cuisines,charterhouse,firsts,tercera,inhabitant,homophobia,naturalism,einar,powerplant,coruna,entertainments,whedon,rajputs,raton,democracies,arunachal,oeuvre,wallonia,jeddah,trolleybuses,evangelism,vosges,kiowa,minimise,encirclement,undertakes,emigrant,beacons,deepened,grammars,publius,preeminent,seyyed,repechage,crafting,headingley,osteopathic,lithography,hotly,bligh,inshore,betrothed,olympians,formula_31,dissociation,trivandrum,arran,petrovic,stettin,disembarked,simplification,bronzes,philo,acrobatic,jonsson,conjectured,supercharged,kanto,detects,cheeses,correlates,harmonics,lifecycle,sudamericana,reservists,decayed,elitserien,parametric,113th,dusky,hogarth,modulo,symbiotic,monopolies,discontinuation,converges,southerners,tucuman,eclipses,enclaves,emits,famicom,caricatures,artistically,levelled,mussels,erecting,mouthparts,cunard,octaves,crucible,guardia,unusable,lagrangian,droughts,ephemeral,pashto,canis,tapering,sasebo,silurian,metallurgical,outscored,evolves,reissues,sedentary,homotopy,greyhawk,reagents,inheriting,onshore,tilting,rebuffed,reusable,naturalists,basingstoke,insofar,offensives,dravidian,curators,planks,rajan,isoforms,flagstaff,preside,globular,egalitarian,linkages,biographers,goalscorers,molybdenum,centralised,nordland,jurists,ellesmere,rosberg,hideyoshi,restructure,biases,borrower,scathing,redress,tunnelling,workflow,magnates,mahendra,dissenters,plethora,transcriptions,handicrafts,keyword,xi'an,petrograd,unser,prokofiev,90deg,madan,bataan,maronite,kearny,carmarthen,termini,consulates,disallowed,rockville,bowery,fanzine,docklands,bests,prohibitions,yeltsin,selassie,naturalization,realisation,dispensary,tribeca,abdulaziz,pocahontas,stagnation,pamplona,cuneiform,propagating,subsurface,christgau,epithelium,schwerin,lynching,routledge,hanseatic,upanishad,glebe,yugoslavian,complicity,endowments,girona,mynetworktv,entomology,plinth,ba'ath,supercup,torus,akkadian,salted,englewood,commandery,belgaum,prefixed,colorless,dartford,enthroned,caesarea,nominative,sandown,safeguards,hulled,formula_32,leamington,dieppe,spearhead,generalizations,demarcation,llanelli,masque,brickwork,recounting,sufism,strikingly,petrochemical,onslow,monologues,emigrating,anderlecht,sturt,hossein,sakhalin,subduction,novices,deptford,zanjan,airstrikes,coalfield,reintroduction,timbaland,hornby,messianic,stinging,universalist,situational,radiocarbon,strongman,rowling,saloons,traffickers,overran,fribourg,cambrai,gravesend,discretionary,finitely,archetype,assessor,pilipinas,exhumed,invocation,interacted,digitized,timisoara,smelter,teton,sexism,precepts,srinagar,pilsudski,carmelite,hanau,scoreline,hernando,trekking,blogging,fanbase,wielded,vesicles,nationalization,banja,rafts,motoring,luang,takeda,girder,stimulates,histone,sunda,nanoparticles,attains,jumpers,catalogued,alluding,pontus,ancients,examiners,shinkansen,ribbentrop,reimbursement,pharmacological,ramat,stringed,imposes,cheaply,transplanted,taiping,mizoram,looms,wallabies,sideman,kootenay,encased,sportsnet,revolutionized,tangier,benthic,runic,pakistanis,heatseekers,shyam,mishnah,presbyterians,stadt,sutras,straddles,zoroastrian,infer,fueling,gymnasts,ofcom,gunfight,journeyman,tracklist,oshawa,ps500,pa'in,mackinac,xiongnu,mississippian,breckinridge,freemason,bight,autoroute,liberalization,distantly,thrillers,solomons,presumptive,romanization,anecdotal,bohemians,unpaved,milder,concurred,spinners,alphabets,strenuous,rivieres,kerrang,mistreatment,dismounted,intensively,carlist,dancehall,shunting,pluralism,trafficked,brokered,bonaventure,bromide,neckar,designates,malian,reverses,sotheby,sorghum,serine,environmentalists,languedoc,consulship,metering,bankstown,handlers,militiamen,conforming,regularity,pondicherry,armin,capsized,consejo,capitalists,drogheda,granular,purged,acadians,endocrine,intramural,elicit,terns,orientations,miklos,omitting,apocryphal,slapstick,brecon,pliocene,affords,typography,emigre,tsarist,tomasz,beset,nishi,necessitating,encyclical,roleplaying,journeyed,inflow,sprints,progressives,novosibirsk,cameroonian,ephesus,speckled,kinshasa,freiherr,burnaby,dalmatian,torrential,rigor,renegades,bhakti,nurburgring,cosimo,convincingly,reverting,visayas,lewisham,charlottetown,charadriiformesfamily,transferable,jodhpur,converters,deepening,camshaft,underdeveloped,protease,polonia,uterine,quantify,tobruk,dealerships,narasimha,fortran,inactivity,1780s,victors,categorised,naxos,workstation,skink,sardinian,chalice,precede,dammed,sondheim,phineas,tutored,sourcing,uncompromising,placer,tyneside,courtiers,proclaims,pharmacies,hyogo,booksellers,sengoku,kursk,spectrometer,countywide,wielkopolski,bobsleigh,shetty,llywelyn,consistory,heretics,guinean,cliches,individualism,monolithic,imams,usability,bursa,deliberations,railings,torchwood,inconsistency,balearic,stabilizer,demonstrator,facet,radioactivity,outboard,educates,d'oyly,heretical,handover,jurisdictional,shockwave,hispaniola,conceptually,routers,unaffiliated,trentino,formula_33,cypriots,intervenes,neuchatel,formulating,maggiore,delisted,alcohols,thessaly,potable,estimator,suborder,fluency,mimicry,clergymen,infrastructures,rivals.com,baroda,subplot,majlis,plano,clinching,connotation,carinae,savile,intercultural,transcriptional,sandstones,ailerons,annotations,impresario,heinkel,scriptural,intermodal,astrological,ribbed,northeastward,posited,boers,utilise,kalmar,phylum,breakwater,skype,textured,guideline,azeri,rimini,massed,subsidence,anomalous,wolfsburg,polyphonic,accrediting,vodacom,kirov,captaining,kelantan,logie,fervent,eamon,taper,bundeswehr,disproportionately,divination,slobodan,pundits,hispano,kinetics,reunites,makati,ceasing,statistician,amending,chiltern,eparchy,riverine,melanoma,narragansett,pagans,raged,toppled,breaching,zadar,holby,dacian,ochre,velodrome,disparities,amphoe,sedans,webpage,williamsport,lachlan,groton,baring,swastika,heliport,unwillingness,razorbacks,exhibitors,foodstuffs,impacting,tithe,appendages,dermot,subtypes,nurseries,balinese,simulating,stary,remakes,mundi,chautauqua,geologically,stockade,hakka,dilute,kalimantan,pahang,overlapped,fredericton,baha'u'llah,jahangir,damping,benefactors,shomali,triumphal,cieszyn,paradigms,shielded,reggaeton,maharishi,zambian,shearing,golestan,mirroring,partitioning,flyover,songbook,incandescent,merrimack,huguenots,sangeet,vulnerabilities,trademarked,drydock,tantric,honoris,queenstown,labelling,iterative,enlists,statesmen,anglicans,herge,qinghai,burgundian,islami,delineated,zhuge,aggregated,banknote,qatari,suitably,tapestries,asymptotic,charleroi,majorities,pyramidellidae,leanings,climactic,tahir,ramsar,suppressor,revisionist,trawler,ernakulam,penicillium,categorization,slits,entitlement,collegium,earths,benefice,pinochet,puritans,loudspeaker,stockhausen,eurocup,roskilde,alois,jaroslav,rhondda,boutiques,vigor,neurotransmitter,ansar,malden,ferdinando,sported,relented,intercession,camberwell,wettest,thunderbolts,positional,oriel,cloverleaf,penalized,shoshone,rajkumar,completeness,sharjah,chromosomal,belgians,woolen,ultrasonic,sequentially,boleyn,mordella,microsystems,initiator,elachista,mineralogy,rhododendron,integrals,compostela,hamza,sawmills,stadio,berlioz,maidens,stonework,yachting,tappeh,myocardial,laborer,workstations,costumed,nicaea,lanark,roundtable,mashhad,nablus,algonquian,stuyvesant,sarkar,heroines,diwan,laments,intonation,intrigues,almaty,feuded,grandes,algarve,rehabilitate,macrophages,cruciate,dismayed,heuristic,eliezer,kozhikode,covalent,finalised,dimorphism,yaroslavl,overtaking,leverkusen,middlebury,feeders,brookings,speculates,insoluble,lodgings,jozsef,cysteine,shenyang,habilitation,spurious,brainchild,mtdna,comique,albedo,recife,partick,broadening,shahi,orientated,himalaya,swabia,palme,mennonites,spokeswoman,conscripts,sepulchre,chartres,eurozone,scaffold,invertebrate,parishad,bagan,heian,watercolors,basse,supercomputer,commences,tarragona,plainfield,arthurian,functor,identically,murex,chronicling,pressings,burrowing,histoire,guayaquil,goalkeeping,differentiable,warburg,machining,aeneas,kanawha,holocene,ramesses,reprisal,qingdao,avatars,turkestan,cantatas,besieging,repudiated,teamsters,equipping,hydride,ahmadiyya,euston,bottleneck,computations,terengganu,kalinga,stela,rediscovery,'this,azhar,stylised,karelia,polyethylene,kansai,motorised,lounges,normalization,calculators,1700s,goalkeepers,unfolded,commissary,cubism,vignettes,multiverse,heaters,briton,sparingly,childcare,thorium,plock,riksdag,eunuchs,catalysis,limassol,perce,uncensored,whitlam,ulmus,unites,mesopotamian,refraction,biodiesel,forza,fulda,unseated,mountbatten,shahrak,selenium,osijek,mimicking,antimicrobial,axons,simulcasting,donizetti,swabian,sportsmen,hafiz,neared,heraclius,locates,evaded,subcarpathian,bhubaneswar,negeri,jagannath,thaksin,aydin,oromo,lateran,goldsmiths,multiculturalism,cilia,mihai,evangelists,lorient,qajar,polygons,vinod,mechanised,anglophone,prefabricated,mosses,supervillain,airliners,biofuels,iodide,innovators,valais,wilberforce,logarithm,intelligentsia,dissipation,sanctioning,duchies,aymara,porches,simulators,mostar,telepathic,coaxial,caithness,burghs,fourths,stratification,joaquim,scribes,meteorites,monarchist,germination,vries,desiring,replenishment,istria,winemaking,tammany,troupes,hetman,lanceolate,pelagic,triptych,primeira,scant,outbound,hyphae,denser,bentham,basie,normale,executes,ladislaus,kontinental,herat,cruiserweight,activision,customization,manoeuvres,inglewood,northwood,waveform,investiture,inpatient,alignments,kiryat,rabat,archimedes,ustad,monsanto,archetypal,kirkby,sikhism,correspondingly,catskill,overlaid,petrels,widowers,unicameral,federalists,metalcore,gamerankings,mussel,formula_34,lymphocytes,cystic,southgate,vestiges,immortals,kalam,strove,amazons,pocono,sociologists,sopwith,adheres,laurens,caregivers,inspecting,transylvanian,rebroadcast,rhenish,miserables,pyrams,blois,newtonian,carapace,redshirt,gotland,nazir,unilever,distortions,linebackers,federalism,mombasa,lumen,bernoulli,favouring,aligarh,denounce,steamboats,dnieper,stratigraphic,synths,bernese,umass,icebreaker,guanajuato,heisenberg,boldly,diodes,ladakh,dogmatic,scriptwriter,maritimes,battlestar,symposia,adaptable,toluca,bhavan,nanking,ieyasu,picardy,soybean,adalbert,brompton,deutsches,brezhnev,glandular,laotian,hispanicized,ibadan,personification,dalit,yamuna,regio,dispensed,yamagata,zweibrucken,revising,fandom,stances,participle,flavours,khitan,vertebral,crores,mayaguez,dispensation,guntur,undefined,harpercollins,unionism,meena,leveling,philippa,refractory,telstra,judea,attenuation,pylons,elaboration,elegy,edging,gracillariidae,residencies,absentia,reflexive,deportations,dichotomy,stoves,sanremo,shimon,menachem,corneal,conifers,mordellidae,facsimile,diagnoses,cowper,citta,viticulture,divisive,riverview,foals,mystics,polyhedron,plazas,airspeed,redgrave,motherland,impede,multiplicity,barrichello,airships,pharmacists,harvester,clays,payloads,differentiating,popularize,caesars,tunneling,stagnant,circadian,indemnity,sensibilities,musicology,prefects,serfs,metra,lillehammer,carmarthenshire,kiosks,welland,barbican,alkyl,tillandsia,gatherers,asociacion,showings,bharati,brandywine,subversion,scalable,pfizer,dawla,barium,dardanelles,nsdap,konig,ayutthaya,hodgkin,sedimentation,completions,purchasers,sponsorships,maximizing,banked,taoism,minot,enrolls,fructose,aspired,capuchin,outages,artois,carrollton,totality,osceola,pawtucket,fontainebleau,converged,queretaro,competencies,botha,allotments,sheaf,shastri,obliquely,banding,catharines,outwardly,monchengladbach,driest,contemplative,cassini,ranga,pundit,kenilworth,tiananmen,disulfide,formula_35,townlands,codice_3,looping,caravans,rachmaninoff,segmentation,fluorine,anglicised,gnostic,dessau,discern,reconfigured,altrincham,rebounding,battlecruiser,ramblers,1770s,convective,triomphe,miyagi,mourners,instagram,aloft,breastfeeding,courtyards,folkestone,changsha,kumamoto,saarland,grayish,provisionally,appomattox,uncial,classicism,mahindra,elapsed,supremes,monophyletic,cautioned,formula_36,noblewoman,kernels,sucre,swaps,bengaluru,grenfell,epicenter,rockhampton,worshipful,licentiate,metaphorical,malankara,amputated,wattle,palawan,tankobon,nobunaga,polyhedra,transduction,jilin,syrians,affinities,fluently,emanating,anglicized,sportscar,botanists,altona,dravida,chorley,allocations,kunming,luanda,premiering,outlived,mesoamerica,lingual,dissipating,impairments,attenborough,balustrade,emulator,bakhsh,cladding,increments,ascents,workington,qal'eh,winless,categorical,petrel,emphasise,dormer,toros,hijackers,telescopic,solidly,jankovic,cession,gurus,madoff,newry,subsystems,northside,talib,englishmen,farnese,holographic,electives,argonne,scrivener,predated,brugge,nauvoo,catalyses,soared,siddeley,graphically,powerlifting,funicular,sungai,coercive,fusing,uncertainties,locos,acetic,diverge,wedgwood,dressings,tiebreaker,didactic,vyacheslav,acreage,interplanetary,battlecruisers,sunbury,alkaloids,hairpin,automata,wielkie,interdiction,plugins,monkees,nudibranch,esporte,approximations,disabling,powering,characterisation,ecologically,martinsville,termen,perpetuated,lufthansa,ascendancy,motherboard,bolshoi,athanasius,prunus,dilution,invests,nonzero,mendocino,charan,banque,shaheed,counterculture,unita,voivode,hospitalization,vapour,supermarine,resistor,steppes,osnabruck,intermediates,benzodiazepines,sunnyside,privatized,geopolitical,ponta,beersheba,kievan,embody,theoretic,sangh,cartographer,blige,rotors,thruway,battlefields,discernible,demobilized,broodmare,colouration,sagas,policymakers,serialization,augmentation,hoare,frankfurter,transnistria,kinases,detachable,generational,converging,antiaircraft,khaki,bimonthly,coadjutor,arkhangelsk,kannur,buffers,livonian,northwich,enveloped,cysts,yokozuna,herne,beeching,enron,virginian,woollen,excepting,competitively,outtakes,recombinant,hillcrest,clearances,pathe,cumbersome,brasov,u.s.a,likud,christiania,cruciform,hierarchies,wandsworth,lupin,resins,voiceover,sitar,electrochemical,mediacorp,typhus,grenadiers,hepatic,pompeii,weightlifter,bosniak,oxidoreductase,undersecretary,rescuers,ranji,seleucid,analysing,exegesis,tenancy,toure,kristiansand,110th,carillon,minesweepers,poitou,acceded,palladian,redevelop,naismith,rifled,proletariat,shojo,hackensack,harvests,endpoint,kuban,rosenborg,stonehenge,authorisation,jacobean,revocation,compatriots,colliding,undetermined,okayama,acknowledgment,angelou,fresnel,chahar,ethereal,mg/kg,emmet,mobilised,unfavourable,cultura,characterizing,parsonage,skeptics,expressways,rabaul,medea,guardsmen,visakhapatnam,caddo,homophobic,elmwood,encircling,coexistence,contending,seljuk,mycologist,infertility,moliere,insolvent,covenants,underpass,holme,landesliga,workplaces,delinquency,methamphetamine,contrived,tableau,tithes,overlying,usurped,contingents,spares,oligocene,molde,beatification,mordechai,balloting,pampanga,navigators,flowered,debutant,codec,orogeny,newsletters,solon,ambivalent,ubisoft,archdeaconry,harpers,kirkus,jabal,castings,kazhagam,sylhet,yuwen,barnstaple,amidships,causative,isuzu,watchtower,granules,canaveral,remuneration,insurer,payout,horizonte,integrative,attributing,kiwis,skanderbeg,asymmetry,gannett,urbanism,disassembled,unaltered,precluded,melodifestivalen,ascends,plugin,gurkha,bisons,stakeholder,industrialisation,abbotsford,sextet,bustling,uptempo,slavia,choreographers,midwives,haram,javed,gazetteer,subsection,natively,weighting,lysine,meera,redbridge,muchmusic,abruzzo,adjoins,unsustainable,foresters,kbit/s,cosmopterigidae,secularism,poetics,causality,phonograph,estudiantes,ceausescu,universitario,adjoint,applicability,gastropods,nagaland,kentish,mechelen,atalanta,woodpeckers,lombards,gatineau,romansh,avraham,acetylcholine,perturbation,galois,wenceslaus,fuzhou,meandering,dendritic,sacristy,accented,katha,therapeutics,perceives,unskilled,greenhouses,analogues,chaldean,timbre,sloped,volodymyr,sadiq,maghreb,monogram,rearguard,caucuses,mures,metabolite,uyezd,determinism,theosophical,corbet,gaels,disruptions,bicameral,ribosomal,wolseley,clarksville,watersheds,tarsi,radon,milanese,discontinuous,aristotelian,whistleblower,representational,hashim,modestly,localised,atrial,hazara,ravana,troyes,appointees,rubus,morningside,amity,aberdare,ganglia,wests,zbigniew,aerobatic,depopulated,corsican,introspective,twinning,hardtop,shallower,cataract,mesolithic,emblematic,graced,lubrication,republicanism,voronezh,bastions,meissen,irkutsk,oboes,hokkien,sprites,tenet,individualist,capitulated,oakville,dysentery,orientalist,hillsides,keywords,elicited,incised,lagging,apoel,lengthening,attractiveness,marauders,sportswriter,decentralization,boltzmann,contradicts,draftsman,precipitate,solihull,norske,consorts,hauptmann,riflemen,adventists,syndromes,demolishing,customize,continuo,peripherals,seamlessly,linguistically,bhushan,orphanages,paraul,lessened,devanagari,quarto,responders,patronymic,riemannian,altoona,canonization,honouring,geodetic,exemplifies,republica,enzymatic,porters,fairmount,pampa,sufferers,kamchatka,conjugated,coachella,uthman,repositories,copious,headteacher,awami,phoneme,homomorphism,franconian,moorland,davos,quantified,kamloops,quarks,mayoralty,weald,peacekeepers,valerian,particulate,insiders,perthshire,caches,guimaraes,piped,grenadines,kosciuszko,trombonist,artemisia,covariance,intertidal,soybeans,beatified,ellipse,fruiting,deafness,dnipropetrovsk,accrued,zealous,mandala,causation,junius,kilowatt,bakeries,montpelier,airdrie,rectified,bungalows,toleration,debian,pylon,trotskyist,posteriorly,two-and-a-half,herbivorous,islamists,poetical,donne,wodehouse,frome,allium,assimilate,phonemic,minaret,unprofitable,darpa,untenable,leaflet,bitcoin,zahir,thresholds,argentino,jacopo,bespoke,stratified,wellbeing,shiite,basaltic,timberwolves,secrete,taunts,marathons,isomers,carre,consecrators,penobscot,pitcairn,sakha,crosstown,inclusions,impassable,fenders,indre,uscgc,jordi,retinue,logarithmic,pilgrimages,railcar,cashel,blackrock,macroscopic,aligning,tabla,trestle,certify,ronson,palps,dissolves,thickened,silicate,taman,walsingham,hausa,lowestoft,rondo,oleksandr,cuyahoga,retardation,countering,cricketing,holborn,identifiers,hells,geophysics,infighting,sculpting,balaji,webbed,irradiation,runestone,trusses,oriya,sojourn,forfeiture,colonize,exclaimed,eucharistic,lackluster,glazing,northridge,gutenberg,stipulates,macroeconomic,priori,outermost,annular,udinese,insulating,headliner,godel,polytope,megalithic,salix,sharapova,derided,muskegon,braintree,plateaus,confers,autocratic,isomer,interstitial,stamping,omits,kirtland,hatchery,evidences,intifada,111th,podgorica,capua,motivating,nuneaton,jakub,korsakov,amitabh,mundial,monrovia,gluten,predictor,marshalling,d'orleans,levers,touchscreen,brantford,fricative,banishment,descendent,antagonism,ludovico,loudspeakers,formula_37,livelihoods,manassas,steamships,dewsbury,uppermost,humayun,lures,pinnacles,dependents,lecce,clumps,observatories,paleozoic,dedicating,samiti,draughtsman,gauls,incite,infringing,nepean,pythagorean,convents,triumvirate,seigneur,gaiman,vagrant,fossa,byproduct,serrated,renfrewshire,sheltering,achaemenid,dukedom,catchers,sampdoria,platelet,bielefeld,fluctuating,phenomenology,strikeout,ethnology,prospectors,woodworking,tatra,wildfires,meditations,agrippa,fortescue,qureshi,wojciech,methyltransferase,accusative,saatchi,amerindian,volcanism,zeeland,toyama,vladimirovich,allege,polygram,redox,budgeted,advisories,nematode,chipset,starscream,tonbridge,hardening,shales,accompanist,paraded,phonographic,whitefish,sportive,audiobook,kalisz,hibernation,latif,duels,ps200,coxeter,nayak,safeguarding,cantabria,minesweeping,zeiss,dunams,catholicos,sawtooth,ontological,nicobar,bridgend,unclassified,intrinsically,hanoverian,rabbitohs,kenseth,alcalde,northumbrian,raritan,septuagint,presse,sevres,origen,dandenong,peachtree,intersected,impeded,usages,hippodrome,novara,trajectories,customarily,yardage,inflected,yanow,kalan,taverns,liguria,librettist,intermarriage,1760s,courant,gambier,infanta,ptolemaic,ukulele,haganah,sceptical,manchukuo,plexus,implantation,hilal,intersex,efficiencies,arbroath,hagerstown,adelphi,diario,marais,matti,lifes,coining,modalities,divya,bletchley,conserving,ivorian,mithridates,generative,strikeforce,laymen,toponymy,pogrom,satya,meticulously,agios,dufferin,yaakov,fortnightly,cargoes,deterrence,prefrontal,przemysl,mitterrand,commemorations,chatsworth,gurdwara,abuja,chakraborty,badajoz,geometries,artiste,diatonic,ganglion,presides,marymount,nanak,cytokines,feudalism,storks,rowers,widens,politico,evangelicals,assailants,pittsfield,allowable,bijapur,telenovelas,dichomeris,glenelg,herbivores,keita,inked,radom,fundraisers,constantius,boheme,portability,komnenos,crystallography,derrida,moderates,tavistock,fateh,spacex,disjoint,bristles,commercialized,interwoven,empirically,regius,bulacan,newsday,showa,radicalism,yarrow,pleura,sayed,structuring,cotes,reminiscences,acetyl,edicts,escalators,aomori,encapsulated,legacies,bunbury,placings,fearsome,postscript,powerfully,keighley,hildesheim,amicus,crevices,deserters,benelux,aurangabad,freeware,ioannis,carpathians,chirac,seceded,prepaid,landlocked,naturalised,yanukovych,soundscan,blotch,phenotypic,determinants,twente,dictatorial,giessen,composes,recherche,pathophysiology,inventories,ayurveda,elevating,gravestone,degeneres,vilayet,popularizing,spartanburg,bloemfontein,previewed,renunciation,genotype,ogilvy,tracery,blacklisted,emissaries,diploid,disclosures,tupolev,shinjuku,antecedents,pennine,braganza,bhattacharya,countable,spectroscopic,ingolstadt,theseus,corroborated,compounding,thrombosis,extremadura,medallions,hasanabad,lambton,perpetuity,glycol,besancon,palaiologos,pandey,caicos,antecedent,stratum,laserdisc,novitiate,crowdfunding,palatal,sorceress,dassault,toughness,celle,cezanne,vientiane,tioga,hander,crossbar,gisborne,cursor,inspectorate,serif,praia,sphingidae,nameplate,psalter,ivanovic,sitka,equalised,mutineers,sergius,outgrowth,creationism,haredi,rhizomes,predominate,undertakings,vulgate,hydrothermal,abbeville,geodesic,kampung,physiotherapy,unauthorised,asteraceae,conservationist,minoan,supersport,mohammadabad,cranbrook,mentorship,legitimately,marshland,datuk,louvain,potawatomi,carnivores,levies,lyell,hymnal,regionals,tinto,shikoku,conformal,wanganui,beira,lleida,standstill,deloitte,formula_40,corbusier,chancellery,mixtapes,airtime,muhlenberg,formula_39,bracts,thrashers,prodigious,gironde,chickamauga,uyghurs,substitutions,pescara,batangas,gregarious,gijon,paleo,mathura,pumas,proportionally,hawkesbury,yucca,kristiania,funimation,fluted,eloquence,mohun,aftermarket,chroniclers,futurist,nonconformist,branko,mannerisms,lesnar,opengl,altos,retainers,ashfield,shelbourne,sulaiman,divisie,gwent,locarno,lieder,minkowski,bivalve,redeployed,cartography,seaway,bookings,decays,ostend,antiquaries,pathogenesis,formula_38,chrysalis,esperance,valli,motogp,homelands,bridged,bloor,ghazal,vulgaris,baekje,prospector,calculates,debtors,hesperiidae,titian,returner,landgrave,frontenac,kelowna,pregame,castelo,caius,canoeist,watercolours,winterthur,superintendents,dissonance,dubstep,adorn,matic,salih,hillel,swordsman,flavoured,emitter,assays,monongahela,deeded,brazzaville,sufferings,babylonia,fecal,umbria,astrologer,gentrification,frescos,phasing,zielona,ecozone,candido,manoj,quadrilateral,gyula,falsetto,prewar,puntland,infinitive,contraceptive,bakhtiari,ohrid,socialization,tailplane,evoking,havelock,macapagal,plundering,104th,keynesian,templars,phrasing,morphologically,czestochowa,humorously,catawba,burgas,chiswick,ellipsoid,kodansha,inwards,gautama,katanga,orthopaedic,heilongjiang,sieges,outsourced,subterminal,vijayawada,hares,oration,leitrim,ravines,manawatu,cryogenic,tracklisting,about.com,ambedkar,degenerated,hastened,venturing,lobbyists,shekhar,typefaces,northcote,rugen,'good,ornithology,asexual,hemispheres,unsupported,glyphs,spoleto,epigenetic,musicianship,donington,diogo,kangxi,bisected,polymorphism,megawatt,salta,embossed,cheetahs,cruzeiro,unhcr,aristide,rayleigh,maturing,indonesians,noire,llano,ffffff,camus,purges,annales,convair,apostasy,algol,phage,apaches,marketers,aldehyde,pompidou,kharkov,forgeries,praetorian,divested,retrospectively,gornji,scutellum,bitumen,pausanias,magnification,imitations,nyasaland,geographers,floodlights,athlone,hippolyte,expositions,clarinetist,razak,neutrinos,rotax,sheykh,plush,interconnect,andalus,cladogram,rudyard,resonator,granby,blackfriars,placido,windscreen,sahel,minamoto,haida,cations,emden,blackheath,thematically,blacklist,pawel,disseminating,academical,undamaged,raytheon,harsher,powhatan,ramachandran,saddles,paderborn,capping,zahra,prospecting,glycine,chromatin,profane,banska,helmand,okinawan,dislocation,oscillators,insectivorous,foyle,gilgit,autonomic,tuareg,sluice,pollinated,multiplexed,granary,narcissus,ranchi,staines,nitra,goalscoring,midwifery,pensioners,algorithmic,meetinghouse,biblioteca,besar,narva,angkor,predate,lohan,cyclical,detainee,occipital,eventing,faisalabad,dartmoor,kublai,courtly,resigns,radii,megachilidae,cartels,shortfall,xhosa,unregistered,benchmarks,dystopian,bulkhead,ponsonby,jovanovic,accumulates,papuan,bhutanese,intuitively,gotaland,headliners,recursion,dejan,novellas,diphthongs,imbued,withstood,analgesic,amplify,powertrain,programing,maidan,alstom,affirms,eradicated,summerslam,videogame,molla,severing,foundered,gallium,atmospheres,desalination,shmuel,howmeh,catolica,bossier,reconstructing,isolates,lyase,tweets,unconnected,tidewater,divisible,cohorts,orebro,presov,furnishing,folklorist,simplifying,centrale,notations,factorization,monarchies,deepen,macomb,facilitation,hennepin,declassified,redrawn,microprocessors,preliminaries,enlarging,timeframe,deutschen,shipbuilders,patiala,ferrous,aquariums,genealogies,vieux,unrecognized,bridgwater,tetrahedral,thule,resignations,gondwana,registries,agder,dataset,felled,parva,analyzer,worsen,coleraine,columella,blockaded,polytechnique,reassembled,reentry,narvik,greys,nigra,knockouts,bofors,gniezno,slotted,hamasaki,ferrers,conferring,thirdly,domestication,photojournalist,universality,preclude,ponting,halved,thereupon,photosynthetic,ostrava,mismatch,pangasinan,intermediaries,abolitionists,transited,headings,ustase,radiological,interconnection,dabrowa,invariants,honorius,preferentially,chantilly,marysville,dialectical,antioquia,abstained,gogol,dirichlet,muricidae,symmetries,reproduces,brazos,fatwa,bacillus,ketone,paribas,chowk,multiplicative,dermatitis,mamluks,devotes,adenosine,newbery,meditative,minefields,inflection,oxfam,conwy,bystrica,imprints,pandavas,infinitesimal,conurbation,amphetamine,reestablish,furth,edessa,injustices,frankston,serjeant,4x200,khazar,sihanouk,longchamp,stags,pogroms,coups,upperparts,endpoints,infringed,nuanced,summing,humorist,pacification,ciaran,jamaat,anteriorly,roddick,springboks,faceted,hypoxia,rigorously,cleves,fatimid,ayurvedic,tabled,ratna,senhora,maricopa,seibu,gauguin,holomorphic,campgrounds,amboy,coordinators,ponderosa,casemates,ouachita,nanaimo,mindoro,zealander,rimsky,cluny,tomaszow,meghalaya,caetano,tilak,roussillon,landtag,gravitation,dystrophy,cephalopods,trombones,glens,killarney,denominated,anthropogenic,pssas,roubaix,carcasses,montmorency,neotropical,communicative,rabindranath,ordinated,separable,overriding,surged,sagebrush,conciliation,codice_4,durrani,phosphatase,qadir,votive,revitalized,taiyuan,tyrannosaurus,graze,slovaks,nematodes,environmentalism,blockhouse,illiteracy,schengen,ecotourism,alternation,conic,wields,hounslow,blackfoot,kwame,ambulatory,volhynia,hordaland,croton,piedras,rohit,drava,conceptualized,birla,illustrative,gurgaon,barisal,tutsi,dezong,nasional,polje,chanson,clarinets,krasnoyarsk,aleksandrovich,cosmonaut,d'este,palliative,midseason,silencing,wardens,durer,girders,salamanders,torrington,supersonics,lauda,farid,circumnavigation,embankments,funnels,bajnoksag,lorries,cappadocia,jains,warringah,retirees,burgesses,equalization,cusco,ganesan,algal,amazonian,lineups,allocating,conquerors,usurper,mnemonic,predating,brahmaputra,ahmadabad,maidenhead,numismatic,subregion,encamped,reciprocating,freebsd,irgun,tortoises,governorates,zionists,airfoil,collated,ajmer,fiennes,etymological,polemic,chadian,clerestory,nordiques,fluctuated,calvados,oxidizing,trailhead,massena,quarrels,dordogne,tirunelveli,pyruvate,pulsed,athabasca,sylar,appointee,serer,japonica,andronikos,conferencing,nicolaus,chemin,ascertained,incited,woodbine,helices,hospitalised,emplacements,to/from,orchestre,tyrannical,pannonia,methodism,pop/rock,shibuya,berbers,despot,seaward,westpac,separator,perpignan,alamein,judeo,publicize,quantization,ethniki,gracilis,menlo,offside,oscillating,unregulated,succumbing,finnmark,metrical,suleyman,raith,sovereigns,bundesstrasse,kartli,fiduciary,darshan,foramen,curler,concubines,calvinism,larouche,bukhara,sophomores,mohanlal,lutheranism,monomer,eamonn,'black,uncontested,immersive,tutorials,beachhead,bindings,permeable,postulates,comite,transformative,indiscriminate,hofstra,associacao,amarna,dermatology,lapland,aosta,babur,unambiguous,formatting,schoolboys,gwangju,superconducting,replayed,adherent,aureus,compressors,forcible,spitsbergen,boulevards,budgeting,nossa,annandale,perumal,interregnum,sassoon,kwajalein,greenbrier,caldas,triangulation,flavius,increment,shakhtar,nullified,pinfall,nomen,microfinance,depreciation,cubist,steeper,splendour,gruppe,everyman,chasers,campaigners,bridle,modality,percussive,darkly,capes,velar,picton,triennial,factional,padang,toponym,betterment,norepinephrine,112th,estuarine,diemen,warehousing,morphism,ideologically,pairings,immunization,crassus,exporters,sefer,flocked,bulbous,deseret,booms,calcite,bohol,elven,groot,pulau,citigroup,wyeth,modernizing,layering,pastiche,complies,printmaker,condenser,theropod,cassino,oxyrhynchus,akademie,trainings,lowercase,coxae,parte,chetniks,pentagonal,keselowski,monocoque,morsi,reticulum,meiosis,clapboard,recoveries,tinge,an/fps,revista,sidon,livre,epidermis,conglomerates,kampong,congruent,harlequins,tergum,simplifies,epidemiological,underwriting,tcp/ip,exclusivity,multidimensional,mysql,columbine,ecologist,hayat,sicilies,levees,handset,aesop,usenet,pacquiao,archiving,alexandrian,compensatory,broadsheet,annotation,bahamian,d'affaires,interludes,phraya,shamans,marmara,customizable,immortalized,ambushes,chlorophyll,diesels,emulsion,rheumatoid,voluminous,screenwriters,tailoring,sedis,runcorn,democratization,bushehr,anacostia,constanta,antiquary,sixtus,radiate,advaita,antimony,acumen,barristers,reichsbahn,ronstadt,symbolist,pasig,cursive,secessionist,afrikaner,munnetra,inversely,adsorption,syllabic,moltke,idioms,midline,olimpico,diphosphate,cautions,radziwill,mobilisation,copelatus,trawlers,unicron,bhaskar,financiers,minimalism,derailment,marxists,oireachtas,abdicate,eigenvalue,zafar,vytautas,ganguly,chelyabinsk,telluride,subordination,ferried,dived,vendee,pictish,dimitrov,expiry,carnation,cayley,magnitudes,lismore,gretna,sandwiched,unmasked,sandomierz,swarthmore,tetra,nanyang,pevsner,dehradun,mormonism,rashi,complying,seaplanes,ningbo,cooperates,strathcona,mornington,mestizo,yulia,edgbaston,palisade,ethno,polytopes,espirito,tymoshenko,pronunciations,paradoxical,taichung,chipmunks,erhard,maximise,accretion,kanda,`abdu'l,narrowest,umpiring,mycenaean,divisor,geneticist,ceredigion,barque,hobbyists,equates,auxerre,spinose,cheil,sweetwater,guano,carboxylic,archiv,tannery,cormorant,agonists,fundacion,anbar,tunku,hindrance,meerut,concordat,secunderabad,kachin,achievable,murfreesboro,comprehensively,forges,broadest,synchronised,speciation,scapa,aliyev,conmebol,tirelessly,subjugated,pillaged,udaipur,defensively,lakhs,stateless,haasan,headlamps,patterning,podiums,polyphony,mcmurdo,mujer,vocally,storeyed,mucosa,multivariate,scopus,minimizes,formalised,certiorari,bourges,populate,overhanging,gaiety,unreserved,borromeo,woolworths,isotopic,bashar,purify,vertebra,medan,juxtaposition,earthwork,elongation,chaudhary,schematic,piast,steeped,nanotubes,fouls,achaea,legionnaires,abdur,qmjhl,embraer,hardback,centerville,ilocos,slovan,whitehorse,mauritian,moulding,mapuche,donned,provisioning,gazprom,jonesboro,audley,lightest,calyx,coldwater,trigonometric,petroglyphs,psychoanalyst,congregate,zambezi,fissure,supervises,bexley,etobicoke,wairarapa,tectonics,emphasises,formula_41,debugging,linfield,spatially,ionizing,ungulates,orinoco,clades,erlangen,news/talk,vols.,ceara,yakovlev,finsbury,entanglement,fieldhouse,graphene,intensifying,grigory,keyong,zacatecas,ninian,allgemeine,keswick,societa,snorri,femininity,najib,monoclonal,guyanese,postulate,huntly,abbeys,machinist,yunus,emphasising,ishaq,urmia,bremerton,pretenders,lumiere,thoroughfares,chikara,dramatized,metathorax,taiko,transcendence,wycliffe,retrieves,umpired,steuben,racehorses,taylors,kuznetsov,montezuma,precambrian,canopies,gaozong,propodeum,disestablished,retroactive,shoreham,rhizome,doubleheader,clinician,diwali,quartzite,shabaab,agassiz,despatched,stormwater,luxemburg,callao,universidade,courland,skane,glyph,dormers,witwatersrand,curacy,qualcomm,nansen,entablature,lauper,hausdorff,lusaka,ruthenian,360deg,cityscape,douai,vaishnava,spars,vaulting,rationalist,gygax,sequestration,typology,pollinates,accelerators,leben,colonials,cenotaph,imparted,carthaginians,equaled,rostrum,gobind,bodhisattva,oberst,bicycling,arabi,sangre,biophysics,hainaut,vernal,lunenburg,apportioned,finches,lajos,nenad,repackaged,zayed,nikephoros,r.e.m,swaminarayan,gestalt,unplaced,crags,grohl,sialkot,unsaturated,gwinnett,linemen,forays,palakkad,writs,instrumentalists,aircrews,badged,terrapins,180deg,oneness,commissariat,changi,pupation,circumscribed,contador,isotropic,administrated,fiefs,nimes,intrusions,minoru,geschichte,nadph,tainan,changchun,carbondale,frisia,swapo,evesham,hawai'i,encyclopedic,transporters,dysplasia,formula_42,onsite,jindal,guetta,judgements,narbonne,permissions,paleogene,rationalism,vilna,isometric,subtracted,chattahoochee,lamina,missa,greville,pervez,lattices,persistently,crystallization,timbered,hawaiians,fouling,interrelated,masood,ripening,stasi,gamal,visigothic,warlike,cybernetics,tanjung,forfar,cybernetic,karelian,brooklands,belfort,greifswald,campeche,inexplicably,refereeing,understory,uninterested,prius,collegiately,sefid,sarsfield,categorize,biannual,elsevier,eisteddfod,declension,autonoma,procuring,misrepresentation,novelization,bibliographic,shamanism,vestments,potash,eastleigh,ionized,turan,lavishly,scilly,balanchine,importers,parlance,'that,kanyakumari,synods,mieszko,crossovers,serfdom,conformational,legislated,exclave,heathland,sadar,differentiates,propositional,konstantinos,photoshop,manche,vellore,appalachia,orestes,taiga,exchanger,grozny,invalidated,baffin,spezia,staunchly,eisenach,robustness,virtuosity,ciphers,inlets,bolagh,understandings,bosniaks,parser,typhoons,sinan,luzerne,webcomic,subtraction,jhelum,businessweek,ceske,refrained,firebox,mitigated,helmholtz,dilip,eslamabad,metalwork,lucan,apportionment,provident,gdynia,schooners,casement,danse,hajjiabad,benazir,buttress,anthracite,newsreel,wollaston,dispatching,cadastral,riverboat,provincetown,nantwich,missal,irreverent,juxtaposed,darya,ennobled,electropop,stereoscopic,maneuverability,laban,luhansk,udine,collectibles,haulage,holyrood,materially,supercharger,gorizia,shkoder,townhouses,pilate,layoffs,folkloric,dialectic,exuberant,matures,malla,ceuta,citizenry,crewed,couplet,stopover,transposition,tradesmen,antioxidant,amines,utterance,grahame,landless,isere,diction,appellant,satirist,urbino,intertoto,subiaco,antonescu,nehemiah,ubiquitin,emcee,stourbridge,fencers,103rd,wranglers,monteverdi,watertight,expounded,xiamen,manmohan,pirie,threefold,antidepressant,sheboygan,grieg,cancerous,diverging,bernini,polychrome,fundamentalism,bihari,critiqued,cholas,villers,tendulkar,dafydd,vastra,fringed,evangelization,episcopalian,maliki,sana'a,ashburton,trianon,allegany,heptathlon,insufficiently,panelists,pharrell,hexham,amharic,fertilized,plumes,cistern,stratigraphy,akershus,catalans,karoo,rupee,minuteman,quantification,wigmore,leutnant,metanotum,weeknights,iridescent,extrasolar,brechin,deuterium,kuching,lyricism,astrakhan,brookhaven,euphorbia,hradec,bhagat,vardar,aylmer,positron,amygdala,speculators,unaccompanied,debrecen,slurry,windhoek,disaffected,rapporteur,mellitus,blockers,fronds,yatra,sportsperson,precession,physiologist,weeknight,pidgin,pharma,condemns,standardize,zetian,tibor,glycoprotein,emporia,cormorants,amalie,accesses,leonhard,denbighshire,roald,116th,will.i.am,symbiosis,privatised,meanders,chemnitz,jabalpur,shing,secede,ludvig,krajina,homegrown,snippets,sasanian,euripides,peder,cimarron,streaked,graubunden,kilimanjaro,mbeki,middleware,flensburg,bukovina,lindwall,marsalis,profited,abkhaz,polis,camouflaged,amyloid,morgantown,ovoid,bodleian,morte,quashed,gamelan,juventud,natchitoches,storyboard,freeview,enumeration,cielo,preludes,bulawayo,1600s,olympiads,multicast,faunal,asura,reinforces,puranas,ziegfeld,handicraft,seamount,kheil,noche,hallmarks,dermal,colorectal,encircle,hessen,umbilicus,sunnis,leste,unwin,disclosing,superfund,montmartre,refuelling,subprime,kolhapur,etiology,bismuth,laissez,vibrational,mazar,alcoa,rumsfeld,recurve,ticonderoga,lionsgate,onlookers,homesteads,filesystem,barometric,kingswood,biofuel,belleza,moshav,occidentalis,asymptomatic,northeasterly,leveson,huygens,numan,kingsway,primogeniture,toyotomi,yazoo,limpets,greenbelt,booed,concurrence,dihedral,ventrites,raipur,sibiu,plotters,kitab,109th,trackbed,skilful,berthed,effendi,fairing,sephardi,mikhailovich,lockyer,wadham,invertible,paperbacks,alphabetic,deuteronomy,constitutive,leathery,greyhounds,estoril,beechcraft,poblacion,cossidae,excreted,flamingos,singha,olmec,neurotransmitters,ascoli,nkrumah,forerunners,dualism,disenchanted,benefitted,centrum,undesignated,noida,o'donoghue,collages,egrets,egmont,wuppertal,cleave,montgomerie,pseudomonas,srinivasa,lymphatic,stadia,resold,minima,evacuees,consumerism,ronde,biochemist,automorphism,hollows,smuts,improvisations,vespasian,bream,pimlico,eglin,colne,melancholic,berhad,ousting,saale,notaulices,ouest,hunslet,tiberias,abdomina,ramsgate,stanislas,donbass,pontefract,sucrose,halts,drammen,chelm,l'arc,taming,trolleys,konin,incertae,licensees,scythian,giorgos,dative,tanglewood,farmlands,o'keeffe,caesium,romsdal,amstrad,corte,oglethorpe,huntingdonshire,magnetization,adapts,zamosc,shooto,cuttack,centrepiece,storehouse,winehouse,morbidity,woodcuts,ryazan,buddleja,buoyant,bodmin,estero,austral,verifiable,periyar,christendom,curtail,shura,kaifeng,cotswold,invariance,seafaring,gorica,androgen,usman,seabird,forecourt,pekka,juridical,audacious,yasser,cacti,qianlong,polemical,d'amore,espanyol,distrito,cartographers,pacifism,serpents,backa,nucleophilic,overturning,duplicates,marksman,oriente,vuitton,oberleutnant,gielgud,gesta,swinburne,transfiguration,1750s,retaken,celje,fredrikstad,asuka,cropping,mansard,donates,blacksmiths,vijayanagara,anuradhapura,germinate,betis,foreshore,jalandhar,bayonets,devaluation,frazione,ablaze,abidjan,approvals,homeostasis,corollary,auden,superfast,redcliffe,luxembourgish,datum,geraldton,printings,ludhiana,honoree,synchrotron,invercargill,hurriedly,108th,three-and-a-half,colonist,bexar,limousin,bessemer,ossetian,nunataks,buddhas,rebuked,thais,tilburg,verdicts,interleukin,unproven,dordrecht,solent,acclamation,muammar,dahomey,operettas,4x400,arrears,negotiators,whitehaven,apparitions,armoury,psychoactive,worshipers,sculptured,elphinstone,airshow,kjell,o'callaghan,shrank,professorships,predominance,subhash,coulomb,sekolah,retrofitted,samos,overthrowing,vibrato,resistors,palearctic,datasets,doordarshan,subcutaneous,compiles,immorality,patchwork,trinidadian,glycogen,pronged,zohar,visigoths,freres,akram,justo,agora,intakes,craiova,playwriting,bukhari,militarism,iwate,petitioners,harun,wisla,inefficiency,vendome,ledges,schopenhauer,kashi,entombed,assesses,tenn.,noumea,baguio,carex,o'donovan,filings,hillsdale,conjectures,blotches,annuals,lindisfarne,negated,vivek,angouleme,trincomalee,cofactor,verkhovna,backfield,twofold,automaker,rudra,freighters,darul,gharana,busway,formula_43,plattsburgh,portuguesa,showrunner,roadmap,valenciennes,erdos,biafra,spiritualism,transactional,modifies,carne,107th,cocos,gcses,tiverton,radiotherapy,meadowlands,gunma,srebrenica,foxtel,authenticated,enslavement,classicist,klaipeda,minstrels,searchable,infantrymen,incitement,shiga,nadp+,urals,guilders,banquets,exteriors,counterattacks,visualized,diacritics,patrimony,svensson,transepts,prizren,telegraphy,najaf,emblazoned,coupes,effluent,ragam,omani,greensburg,taino,flintshire,cd/dvd,lobbies,narrating,cacao,seafarers,bicolor,collaboratively,suraj,floodlit,sacral,puppetry,tlingit,malwa,login,motionless,thien,overseers,vihar,golem,specializations,bathhouse,priming,overdubs,winningest,archetypes,uniao,acland,creamery,slovakian,lithographs,maryborough,confidently,excavating,stillborn,ramallah,audiencia,alava,ternary,hermits,rostam,bauxite,gawain,lothair,captions,gulfstream,timelines,receded,mediating,petain,bastia,rudbar,bidders,disclaimer,shrews,tailings,trilobites,yuriy,jamil,demotion,gynecology,rajinikanth,madrigals,ghazni,flycatchers,vitebsk,bizet,computationally,kashgar,refinements,frankford,heralds,europe/africa,levante,disordered,sandringham,queues,ransacked,trebizond,verdes,comedie,primitives,figurine,organists,culminate,gosport,coagulation,ferrying,hoyas,polyurethane,prohibitive,midfielders,ligase,progesterone,defectors,sweetened,backcountry,diodorus,waterside,nieuport,khwaja,jurong,decried,gorkha,ismaili,300th,octahedral,kindergartens,paseo,codification,notifications,disregarding,risque,reconquista,shortland,atolls,texarkana,perceval,d'etudes,kanal,herbicides,tikva,nuova,gatherer,dissented,soweto,dexterity,enver,bacharach,placekicker,carnivals,automate,maynooth,symplectic,chetnik,militaire,upanishads,distributive,strafing,championing,moiety,miliband,blackadder,enforceable,maung,dimer,stadtbahn,diverges,obstructions,coleophoridae,disposals,shamrocks,aural,banca,bahru,coxed,grierson,vanadium,watermill,radiative,ecoregions,berets,hariri,bicarbonate,evacuations,mallee,nairn,rushden,loggia,slupsk,satisfactorily,milliseconds,cariboo,reine,cyclo,pigmentation,postmodernism,aqueducts,vasari,bourgogne,dilemmas,liquefied,fluminense,alloa,ibaraki,tenements,kumasi,humerus,raghu,labours,putsch,soundcloud,bodybuilder,rakyat,domitian,pesaro,translocation,sembilan,homeric,enforcers,tombstones,lectureship,rotorua,salamis,nikolaos,inferences,superfortress,lithgow,surmised,undercard,tarnow,barisan,stingrays,federacion,coldstream,haverford,ornithological,heerenveen,eleazar,jyoti,murali,bamako,riverbed,subsidised,theban,conspicuously,vistas,conservatorium,madrasa,kingfishers,arnulf,credential,syndicalist,sheathed,discontinuity,prisms,tsushima,coastlines,escapees,vitis,optimizing,megapixel,overground,embattled,halide,sprinters,buoys,mpumalanga,peculiarities,106th,roamed,menezes,macao,prelates,papyri,freemen,dissertations,irishmen,pooled,sverre,reconquest,conveyance,subjectivity,asturian,circassian,formula_45,comdr,thickets,unstressed,monro,passively,harmonium,moveable,dinar,carlsson,elysees,chairing,b'nai,confusingly,kaoru,convolution,godolphin,facilitator,saxophones,eelam,jebel,copulation,anions,livres,licensure,pontypridd,arakan,controllable,alessandria,propelling,stellenbosch,tiber,wolka,liberators,yarns,d'azur,tsinghua,semnan,amhara,ablation,melies,tonality,historique,beeston,kahne,intricately,sonoran,robespierre,gyrus,boycotts,defaulted,infill,maranhao,emigres,framingham,paraiba,wilhelmshaven,tritium,skyway,labial,supplementation,possessor,underserved,motets,maldivian,marrakech,quays,wikimedia,turbojet,demobilization,petrarch,encroaching,sloops,masted,karbala,corvallis,agribusiness,seaford,stenosis,hieronymus,irani,superdraft,baronies,cortisol,notability,veena,pontic,cyclin,archeologists,newham,culled,concurring,aeolian,manorial,shouldered,fords,philanthropists,105th,siddharth,gotthard,halim,rajshahi,jurchen,detritus,practicable,earthenware,discarding,travelogue,neuromuscular,elkhart,raeder,zygmunt,metastasis,internees,102nd,vigour,upmarket,summarizing,subjunctive,offsets,elizabethtown,udupi,pardubice,repeaters,instituting,archaea,substandard,technische,linga,anatomist,flourishes,velika,tenochtitlan,evangelistic,fitchburg,springbok,cascading,hydrostatic,avars,occasioned,filipina,perceiving,shimbun,africanus,consternation,tsing,optically,beitar,45deg,abutments,roseville,monomers,huelva,lotteries,hypothalamus,internationalist,electromechanical,hummingbirds,fibreglass,salaried,dramatists,uncovers,invokes,earners,excretion,gelding,ancien,aeronautica,haverhill,stour,ittihad,abramoff,yakov,ayodhya,accelerates,industrially,aeroplanes,deleterious,dwelt,belvoir,harpalus,atpase,maluku,alasdair,proportionality,taran,epistemological,interferometer,polypeptide,adjudged,villager,metastatic,marshalls,madhavan,archduchess,weizmann,kalgoorlie,balan,predefined,sessile,sagaing,brevity,insecticide,psychosocial,africana,steelworks,aether,aquifers,belem,mineiro,almagro,radiators,cenozoic,solute,turbocharger,invicta,guested,buccaneer,idolatry,unmatched,paducah,sinestro,dispossessed,conforms,responsiveness,cyanobacteria,flautist,procurator,complementing,semifinalist,rechargeable,permafrost,cytokine,refuges,boomed,gelderland,franchised,jinan,burnie,doubtless,randomness,colspan=12,angra,ginebra,famers,nuestro,declarative,roughness,lauenburg,motile,rekha,issuer,piney,interceptors,napoca,gipsy,formulaic,formula_44,viswanathan,ebrahim,thessalonica,galeria,muskogee,unsold,html5,taito,mobutu,icann,carnarvon,fairtrade,morphisms,upsilon,nozzles,fabius,meander,murugan,strontium,episcopacy,sandinista,parasol,attenuated,bhima,primeval,panay,ordinator,negara,osteoporosis,glossop,ebook,paradoxically,grevillea,modoc,equating,phonetically,legumes,covariant,dorje,quatre,bruxelles,pyroclastic,shipbuilder,zhaozong,obscuring,sveriges,tremolo,extensible,barrack,multnomah,hakon,chaharmahal,parsing,volumetric,astrophysical,glottal,combinatorics,freestanding,encoder,paralysed,cavalrymen,taboos,heilbronn,orientalis,lockport,marvels,ozawa,dispositions,waders,incurring,saltire,modulate,papilio,phenol,intermedia,rappahannock,plasmid,fortify,phenotypes,transiting,correspondences,leaguer,larnaca,incompatibility,mcenroe,deeming,endeavoured,aboriginals,helmed,salar,arginine,werke,ferrand,expropriated,delimited,couplets,phoenicians,petioles,ouster,anschluss,protectionist,plessis,urchins,orquesta,castleton,juniata,bittorrent,fulani,donji,mykola,rosemont,chandos,scepticism,signer,chalukya,wicketkeeper,coquitlam,programmatic,o'brian,carteret,urology,steelhead,paleocene,konkan,bettered,venkatesh,surfacing,longitudinally,centurions,popularization,yazid,douro,widths,premios,leonards,gristmill,fallujah,arezzo,leftists,ecliptic,glycerol,inaction,disenfranchised,acrimonious,depositing,parashah,cockatoo,marechal,bolzano,chios,cablevision,impartiality,pouches,thickly,equities,bentinck,emotive,boson,ashdown,conquistadors,parsi,conservationists,reductive,newlands,centerline,ornithologists,waveguide,nicene,philological,hemel,setanta,masala,aphids,convening,casco,matrilineal,chalcedon,orthographic,hythe,replete,damming,bolivarian,admixture,embarks,borderlands,conformed,nagarjuna,blenny,chaitanya,suwon,shigeru,tatarstan,lingayen,rejoins,grodno,merovingian,hardwicke,puducherry,prototyping,laxmi,upheavals,headquarter,pollinators,bromine,transom,plantagenet,arbuthnot,chidambaram,woburn,osamu,panelling,coauthored,zhongshu,hyaline,omissions,aspergillus,offensively,electrolytic,woodcut,sodom,intensities,clydebank,piotrkow,supplementing,quipped,focke,harbinger,positivism,parklands,wolfenbuttel,cauca,tryptophan,taunus,curragh,tsonga,remand,obscura,ashikaga,eltham,forelimbs,analogs,trnava,observances,kailash,antithesis,ayumi,abyssinia,dorsally,tralee,pursuers,misadventures,padova,perot,mahadev,tarim,granth,licenced,compania,patuxent,baronial,korda,cochabamba,codices,karna,memorialized,semaphore,playlists,mandibular,halal,sivaji,scherzinger,stralsund,foundries,ribosome,mindfulness,nikolayevich,paraphyletic,newsreader,catalyze,ioannina,thalamus,gbit/s,paymaster,sarab,500th,replenished,gamepro,cracow,formula_46,gascony,reburied,lessing,easement,transposed,meurthe,satires,proviso,balthasar,unbound,cuckoos,durbar,louisbourg,cowes,wholesalers,manet,narita,xiaoping,mohamad,illusory,cathal,reuptake,alkaloid,tahrir,mmorpg,underlies,anglicanism,repton,aharon,exogenous,buchenwald,indigent,odostomia,milled,santorum,toungoo,nevsky,steyr,urbanisation,darkseid,subsonic,canaanite,akiva,eglise,dentition,mediators,cirencester,peloponnesian,malmesbury,durres,oerlikon,tabulated,saens,canaria,ischemic,esterhazy,ringling,centralization,walthamstow,nalanda,lignite,takht,leninism,expiring,circe,phytoplankton,promulgation,integrable,breeches,aalto,menominee,borgo,scythians,skrull,galleon,reinvestment,raglan,reachable,liberec,airframes,electrolysis,geospatial,rubiaceae,interdependence,symmetrically,simulcasts,keenly,mauna,adipose,zaidi,fairport,vestibular,actuators,monochromatic,literatures,congestive,sacramental,atholl,skytrain,tycho,tunings,jamia,catharina,modifier,methuen,tapings,infiltrating,colima,grafting,tauranga,halides,pontificate,phonetics,koper,hafez,grooved,kintetsu,extrajudicial,linkoping,cyberpunk,repetitions,laurentian,parnu,bretton,darko,sverdlovsk,foreshadowed,akhenaten,rehnquist,gosford,coverts,pragmatism,broadleaf,ethiopians,instated,mediates,sodra,opulent,descriptor,enugu,shimla,leesburg,officership,giffard,refectory,lusitania,cybermen,fiume,corus,tydfil,lawrenceville,ocala,leviticus,burghers,ataxia,richthofen,amicably,acoustical,watling,inquired,tiempo,multiracial,parallelism,trenchard,tokyopop,germanium,usisl,philharmonia,shapur,jacobites,latinized,sophocles,remittances,o'farrell,adder,dimitrios,peshwa,dimitar,orlov,outstretched,musume,satish,dimensionless,serialised,baptisms,pagasa,antiviral,1740s,quine,arapaho,bombardments,stratosphere,ophthalmic,injunctions,carbonated,nonviolence,asante,creoles,sybra,boilermakers,abington,bipartite,permissive,cardinality,anheuser,carcinogenic,hohenlohe,surinam,szeged,infanticide,generically,floorball,'white,automakers,cerebellar,homozygous,remoteness,effortlessly,allude,'great,headmasters,minting,manchurian,kinabalu,wemyss,seditious,widgets,marbled,almshouses,bards,subgenres,tetsuya,faulting,kickboxer,gaulish,hoseyn,malton,fluvial,questionnaires,mondale,downplayed,traditionalists,vercelli,sumatran,landfills,gamesradar,exerts,franciszek,unlawfully,huesca,diderot,libertarians,professorial,laane,piecemeal,conidae,taiji,curatorial,perturbations,abstractions,szlachta,watercraft,mullah,zoroastrianism,segmental,khabarovsk,rectors,affordability,scuola,diffused,stena,cyclonic,workpiece,romford,'little,jhansi,stalag,zhongshan,skipton,maracaibo,bernadotte,thanet,groening,waterville,encloses,sahrawi,nuffield,moorings,chantry,annenberg,islay,marchers,tenses,wahid,siegen,furstenberg,basques,resuscitation,seminarians,tympanum,gentiles,vegetarianism,tufted,venkata,fantastical,pterophoridae,machined,superposition,glabrous,kaveri,chicane,executors,phyllonorycter,bidirectional,jasta,undertones,touristic,majapahit,navratilova,unpopularity,barbadian,tinian,webcast,hurdler,rigidly,jarrah,staphylococcus,igniting,irrawaddy,stabilised,airstrike,ragas,wakayama,energetically,ekstraklasa,minibus,largemouth,cultivators,leveraging,waitangi,carnaval,weaves,turntables,heydrich,sextus,excavate,govind,ignaz,pedagogue,uriah,borrowings,gemstones,infractions,mycobacterium,batavian,massing,praetor,subalpine,massoud,passers,geostationary,jalil,trainsets,barbus,impair,budejovice,denbigh,pertain,historicity,fortaleza,nederlandse,lamenting,masterchef,doubs,gemara,conductance,ploiesti,cetaceans,courthouses,bhagavad,mihailovic,occlusion,bremerhaven,bulwark,morava,kaine,drapery,maputo,conquistador,kaduna,famagusta,first-past-the-post,erudite,galton,undated,tangential,filho,dismembered,dashes,criterium,darwen,metabolized,blurring,everard,randwick,mohave,impurity,acuity,ansbach,chievo,surcharge,plantain,algoma,porosity,zirconium,selva,sevenoaks,venizelos,gwynne,golgi,imparting,separatism,courtesan,idiopathic,gravestones,hydroelectricity,babar,orford,purposeful,acutely,shard,ridgewood,viterbo,manohar,expropriation,placenames,brevis,cosine,unranked,richfield,newnham,recoverable,flightless,dispersing,clearfield,abu'l,stranraer,kempe,streamlining,goswami,epidermal,pieta,conciliatory,distilleries,electrophoresis,bonne,tiago,curiosities,candidature,picnicking,perihelion,lintel,povoa,gullies,configure,excision,facies,signers,1730s,insufficiency,semiotics,streatham,deactivation,entomological,skippers,albacete,parodying,escherichia,honorees,singaporeans,counterterrorism,tiruchirappalli,omnivorous,metropole,globalisation,athol,unbounded,codice_5,landforms,classifier,farmhouses,reaffirming,reparation,yomiuri,technologists,mitte,medica,viewable,steampunk,konya,kshatriya,repelling,edgewater,lamiinae,devas,potteries,llandaff,engendered,submits,virulence,uplifted,educationist,metropolitans,frontrunner,dunstable,forecastle,frets,methodius,exmouth,linnean,bouchet,repulsion,computable,equalling,liceo,tephritidae,agave,hydrological,azarenka,fairground,l'homme,enforces,xinhua,cinematographers,cooperstown,sa'id,paiute,christianization,tempos,chippenham,insulator,kotor,stereotyped,dello,cours,hisham,d'souza,eliminations,supercars,passau,rebrand,natures,coote,persephone,rededicated,cleaved,plenum,blistering,indiscriminately,cleese,safed,recursively,compacted,revues,hydration,shillong,echelons,garhwal,pedimented,grower,zwolle,wildflower,annexing,methionine,petah,valens,famitsu,petiole,specialities,nestorian,shahin,tokaido,shearwater,barberini,kinsmen,experimenter,alumnae,cloisters,alumina,pritzker,hardiness,soundgarden,julich,ps300,watercourse,cementing,wordplay,olivet,demesne,chasseurs,amide,zapotec,gaozu,porphyry,absorbers,indium,analogies,devotions,engravers,limestones,catapulted,surry,brickworks,gotra,rodham,landline,paleontologists,shankara,islip,raucous,trollope,arpad,embarkation,morphemes,recites,picardie,nakhchivan,tolerances,formula_47,khorramabad,nichiren,adrianople,kirkuk,assemblages,collider,bikaner,bushfires,roofline,coverings,reredos,bibliotheca,mantras,accentuated,commedia,rashtriya,fluctuation,serhiy,referential,fittipaldi,vesicle,geeta,iraklis,immediacy,chulalongkorn,hunsruck,bingen,dreadnoughts,stonemason,meenakshi,lebesgue,undergrowth,baltistan,paradoxes,parlement,articled,tiflis,dixieland,meriden,tejano,underdogs,barnstable,exemplify,venter,tropes,wielka,kankakee,iskandar,zilina,pharyngeal,spotify,materialised,picts,atlantique,theodoric,prepositions,paramilitaries,pinellas,attlee,actuated,piedmontese,grayling,thucydides,multifaceted,unedited,autonomously,universelle,utricularia,mooted,preto,incubated,underlie,brasenose,nootka,bushland,sensu,benzodiazepine,esteghlal,seagoing,amenhotep,azusa,sappers,culpeper,smokeless,thoroughbreds,dargah,gorda,alumna,mankato,zdroj,deleting,culvert,formula_49,punting,wushu,hindering,immunoglobulin,standardisation,birger,oilfield,quadrangular,ulama,recruiters,netanya,1630s,communaute,istituto,maciej,pathan,meher,vikas,characterizations,playmaker,interagency,intercepts,assembles,horthy,introspection,narada,matra,testes,radnicki,estonians,csiro,instar,mitford,adrenergic,crewmembers,haaretz,wasatch,lisburn,rangefinder,ordre,condensate,reforestation,corregidor,spvgg,modulator,mannerist,faulted,aspires,maktoum,squarepants,aethelred,piezoelectric,mulatto,dacre,progressions,jagiellonian,norge,samaria,sukhoi,effingham,coxless,hermetic,humanists,centrality,litters,stirlingshire,beaconsfield,sundanese,geometrically,caretakers,habitually,bandra,pashtuns,bradenton,arequipa,laminar,brickyard,hitchin,sustains,shipboard,ploughing,trechus,wheelers,bracketed,ilyushin,subotica,d'hondt,reappearance,bridgestone,intermarried,fulfilment,aphasia,birkbeck,transformational,strathmore,hornbill,millstone,lacan,voids,solothurn,gymnasiums,laconia,viaducts,peduncle,teachta,edgware,shinty,supernovae,wilfried,exclaim,parthia,mithun,flashpoint,moksha,cumbia,metternich,avalanches,militancy,motorist,rivadavia,chancellorsville,federals,gendered,bounding,footy,gauri,caliphs,lingam,watchmaker,unrecorded,riverina,unmodified,seafloor,droit,pfalz,chrysostom,gigabit,overlordship,besiege,espn2,oswestry,anachronistic,ballymena,reactivation,duchovny,ghani,abacetus,duller,legio,watercourses,nord-pas-de-calais,leiber,optometry,swarms,installer,sancti,adverbs,iheartmedia,meiningen,zeljko,kakheti,notional,circuses,patrilineal,acrobatics,infrastructural,sheva,oregonian,adjudication,aamir,wloclawek,overfishing,obstructive,subtracting,aurobindo,archeologist,newgate,'cause,secularization,tehsils,abscess,fingal,janacek,elkhorn,trims,kraftwerk,mandating,irregulars,faintly,congregationalist,sveti,kasai,mishaps,kennebec,provincially,durkheim,scotties,aicte,rapperswil,imphal,surrenders,morphs,nineveh,hoxha,cotabato,thuringian,metalworking,retold,shogakukan,anthers,proteasome,tippeligaen,disengagement,mockumentary,palatial,erupts,flume,corrientes,masthead,jaroslaw,rereleased,bharti,labors,distilling,tusks,varzim,refounded,enniskillen,melkite,semifinalists,vadodara,bermudian,capstone,grasse,origination,populus,alesi,arrondissements,semigroup,verein,opossum,messrs.,portadown,bulbul,tirupati,mulhouse,tetrahedron,roethlisberger,nonverbal,connexion,warangal,deprecated,gneiss,octet,vukovar,hesketh,chambre,despatch,claes,kargil,hideo,gravelly,tyndale,aquileia,tuners,defensible,tutte,theotokos,constructivist,ouvrage,dukla,polisario,monasticism,proscribed,commutation,testers,nipissing,codon,mesto,olivine,concomitant,exoskeleton,purports,coromandel,eyalet,dissension,hippocrates,purebred,yaounde,composting,oecophoridae,procopius,o'day,angiogenesis,sheerness,intelligencer,articular,felixstowe,aegon,endocrinology,trabzon,licinius,pagodas,zooplankton,hooghly,satie,drifters,sarthe,mercian,neuilly,tumours,canal+,scheldt,inclinations,counteroffensive,roadrunners,tuzla,shoreditch,surigao,predicates,carnot,algeciras,militaries,generalize,bulkheads,gawler,pollutant,celta,rundgren,microrna,gewog,olimpija,placental,lubelski,roxburgh,discerned,verano,kikuchi,musicale,l'enfant,ferocity,dimorphic,antigonus,erzurum,prebendary,recitative,discworld,cyrenaica,stigmella,totnes,sutta,pachuca,ulsan,downton,landshut,castellan,pleural,siedlce,siecle,catamaran,cottbus,utilises,trophic,freeholders,holyhead,u.s.s,chansons,responder,waziristan,suzuka,birding,shogi,asker,acetone,beautification,cytotoxic,dixit,hunterdon,cobblestone,formula_48,kossuth,devizes,sokoto,interlaced,shuttered,kilowatts,assiniboine,isaak,salto,alderney,sugarloaf,franchising,aggressiveness,toponyms,plaintext,antimatter,henin,equidistant,salivary,bilingualism,mountings,obligate,extirpated,irenaeus,misused,pastoralists,aftab,immigrating,warping,tyrolean,seaforth,teesside,soundwave,oligarchy,stelae,pairwise,iupac,tezuka,posht,orchestrations,landmass,ironstone,gallia,hjalmar,carmelites,strafford,elmhurst,palladio,fragility,teleplay,gruffudd,karoly,yerba,potok,espoo,inductance,macaque,nonprofits,pareto,rock'n'roll,spiritualist,shadowed,skateboarder,utterances,generality,congruence,prostrate,deterred,yellowknife,albarn,maldon,battlements,mohsen,insecticides,khulna,avellino,menstruation,glutathione,springdale,parlophone,confraternity,korps,countrywide,bosphorus,preexisting,damodar,astride,alexandrovich,sprinting,crystallized,botev,leaching,interstates,veers,angevin,undaunted,yevgeni,nishapur,northerners,alkmaar,bethnal,grocers,sepia,tornus,exemplar,trobe,charcot,gyeonggi,larne,tournai,lorain,voided,genji,enactments,maxilla,adiabatic,eifel,nazim,transducer,thelonious,pyrite,deportiva,dialectal,bengt,rosettes,labem,sergeyevich,synoptic,conservator,statuette,biweekly,adhesives,bifurcation,rajapaksa,mammootty,republique,yusef,waseda,marshfield,yekaterinburg,minnelli,fundy,fenian,matchups,dungannon,supremacist,panelled,drenthe,iyengar,fibula,narmada,homeport,oceanside,precept,antibacterial,altarpieces,swath,ospreys,lillooet,legnica,lossless,formula_50,galvatron,iorga,stormont,rsfsr,loggers,kutno,phenomenological,medallists,cuatro,soissons,homeopathy,bituminous,injures,syndicates,typesetting,displacements,dethroned,makassar,lucchese,abergavenny,targu,alborz,akb48,boldface,gastronomy,sacra,amenity,accumulator,myrtaceae,cornices,mourinho,denunciation,oxbow,diddley,aargau,arbitrage,bedchamber,gruffydd,zamindar,klagenfurt,caernarfon,slowdown,stansted,abrasion,tamaki,suetonius,dukakis,individualistic,ventrally,hotham,perestroika,ketones,fertilisation,sobriquet,couplings,renderings,misidentified,rundfunk,sarcastically,braniff,concours,dismissals,elegantly,modifiers,crediting,combos,crucially,seafront,lieut,ischemia,manchus,derivations,proteases,aristophanes,adenauer,porting,hezekiah,sante,trulli,hornblower,foreshadowing,ypsilanti,dharwad,khani,hohenstaufen,distillers,cosmodrome,intracranial,turki,salesian,gorzow,jihlava,yushchenko,leichhardt,venables,cassia,eurogamer,airtel,curative,bestsellers,timeform,sortied,grandview,massillon,ceding,pilbara,chillicothe,heredity,elblag,rogaland,ronne,millennial,batley,overuse,bharata,fille,campbelltown,abeyance,counterclockwise,250cc,neurodegenerative,consigned,electromagnetism,sunnah,saheb,exons,coxswain,gleaned,bassoons,worksop,prismatic,immigrate,pickets,takeo,bobsledder,stosur,fujimori,merchantmen,stiftung,forli,endorses,taskforce,thermally,atman,gurps,floodplains,enthalpy,extrinsic,setubal,kennesaw,grandis,scalability,durations,showrooms,prithvi,outro,overruns,andalucia,amanita,abitur,hipper,mozambican,sustainment,arsene,chesham,palaeolithic,reportage,criminality,knowsley,haploid,atacama,shueisha,ridgefield,astern,getafe,lineal,timorese,restyled,hollies,agincourt,unter,justly,tannins,mataram,industrialised,tarnovo,mumtaz,mustapha,stretton,synthetase,condita,allround,putra,stjepan,troughs,aechmea,specialisation,wearable,kadokawa,uralic,aeros,messiaen,existentialism,jeweller,effigies,gametes,fjordane,cochlear,interdependent,demonstrative,unstructured,emplacement,famines,spindles,amplitudes,actuator,tantalum,psilocybe,apnea,monogatari,expulsions,seleucus,tsuen,hospitaller,kronstadt,eclipsing,olympiakos,clann,canadensis,inverter,helio,egyptologist,squamous,resonate,munir,histology,torbay,khans,jcpenney,veterinarians,aintree,microscopes,colonised,reflectors,phosphorylated,pristimantis,tulare,corvinus,multiplexing,midweek,demosthenes,transjordan,ecija,tengku,vlachs,anamorphic,counterweight,radnor,trinitarian,armidale,maugham,njsiaa,futurism,stairways,avicenna,montebello,bridgetown,wenatchee,lyonnais,amass,surinamese,streptococcus,m*a*s*h,hydrogenation,frazioni,proscenium,kalat,pennsylvanian,huracan,tallying,kralove,nucleolar,phrygian,seaports,hyacinthe,ignace,donning,instalment,regnal,fonds,prawn,carell,folktales,goaltending,bracknell,vmware,patriarchy,mitsui,kragujevac,pythagoras,soult,thapa,disproved,suwalki,secures,somoza,l'ecole,divizia,chroma,herders,technologist,deduces,maasai,rampur,paraphrase,raimi,imaged,magsaysay,ivano,turmeric,formula_51,subcommittees,axillary,ionosphere,organically,indented,refurbishing,pequot,violinists,bearn,colle,contralto,silverton,mechanization,etruscans,wittelsbach,pasir,redshirted,marrakesh,scarp,plein,wafers,qareh,teotihuacan,frobenius,sinensis,rehoboth,bundaberg,newbridge,hydrodynamic,traore,abubakar,adjusts,storytellers,dynamos,verbandsliga,concertmaster,exxonmobil,appreciable,sieradz,marchioness,chaplaincy,rechristened,cunxu,overpopulation,apolitical,sequencer,beaked,nemanja,binaries,intendant,absorber,filamentous,indebtedness,nusra,nashik,reprises,psychedelia,abwehr,ligurian,isoform,resistive,pillaging,mahathir,reformatory,lusatia,allerton,ajaccio,tepals,maturin,njcaa,abyssinian,objector,fissures,sinuous,ecclesiastic,dalits,caching,deckers,phosphates,wurlitzer,navigated,trofeo,berea,purefoods,solway,unlockable,grammys,kostroma,vocalizations,basilan,rebuke,abbasi,douala,helsingborg,ambon,bakar,runestones,cenel,tomislav,pigmented,northgate,excised,seconda,kirke,determinations,dedicates,vilas,pueblos,reversion,unexploded,overprinted,ekiti,deauville,masato,anaesthesia,endoplasmic,transponders,aguascalientes,hindley,celluloid,affording,bayeux,piaget,rickshaws,eishockey,camarines,zamalek,undersides,hardwoods,hermitian,mutinied,monotone,blackmails,affixes,jpmorgan,habermas,mitrovica,paleontological,polystyrene,thana,manas,conformist,turbofan,decomposes,logano,castration,metamorphoses,patroness,herbicide,mikolaj,rapprochement,macroeconomics,barranquilla,matsudaira,lintels,femina,hijab,spotsylvania,morpheme,bitola,baluchistan,kurukshetra,otway,extrusion,waukesha,menswear,helder,trung,bingley,protester,boars,overhang,differentials,exarchate,hejaz,kumara,unjustified,timings,sharpness,nuovo,taisho,sundar,etc..,jehan,unquestionably,muscovy,daltrey,canute,paneled,amedeo,metroplex,elaborates,telus,tetrapods,dragonflies,epithets,saffir,parthenon,lucrezia,refitting,pentateuch,hanshin,montparnasse,lumberjacks,sanhedrin,erectile,odors,greenstone,resurgent,leszek,amory,substituents,prototypical,viewfinder,monck,universiteit,joffre,revives,chatillon,seedling,scherzo,manukau,ashdod,gympie,homolog,stalwarts,ruinous,weibo,tochigi,wallenberg,gayatri,munda,satyagraha,storefronts,heterogeneity,tollway,sportswriters,binocular,gendarmes,ladysmith,tikal,ortsgemeinde,ja'far,osmotic,linlithgow,bramley,telecoms,pugin,repose,rupaul,sieur,meniscus,garmisch,reintroduce,400th,shoten,poniatowski,drome,kazakhstani,changeover,astronautics,husserl,herzl,hypertext,katakana,polybius,antananarivo,seong,breguet,reliquary,utada,aggregating,liangshan,sivan,tonawanda,audiobooks,shankill,coulee,phenolic,brockton,bookmakers,handsets,boaters,wylde,commonality,mappings,silhouettes,pennines,maurya,pratchett,singularities,eschewed,pretensions,vitreous,ibero,totalitarianism,poulenc,lingered,directx,seasoning,deputation,interdict,illyria,feedstock,counterbalance,muzik,buganda,parachuted,violist,homogeneity,comix,fjords,corsairs,punted,verandahs,equilateral,laoghaire,magyars,117th,alesund,televoting,mayotte,eateries,refurbish,nswrl,yukio,caragiale,zetas,dispel,codecs,inoperable,outperformed,rejuvenation,elstree,modernise,contributory,pictou,tewkesbury,chechens,ashina,psionic,refutation,medico,overdubbed,nebulae,sandefjord,personages,eccellenza,businessperson,placename,abenaki,perryville,threshing,reshaped,arecibo,burslem,colspan=3|turnout,rebadged,lumia,erinsborough,interactivity,bitmap,indefatigable,theosophy,excitatory,gleizes,edsel,bermondsey,korce,saarinen,wazir,diyarbakir,cofounder,liberalisation,onsen,nighthawks,siting,retirements,semyon,d'histoire,114th,redditch,venetia,praha,'round,valdosta,hieroglyphic,postmedial,edirne,miscellany,savona,cockpits,minimization,coupler,jacksonian,appeasement,argentines,saurashtra,arkwright,hesiod,folios,fitzalan,publica,rivaled,civitas,beermen,constructivism,ribeira,zeitschrift,solanum,todos,deformities,chilliwack,verdean,meagre,bishoprics,gujrat,yangzhou,reentered,inboard,mythologies,virtus,unsurprisingly,rusticated,museu,symbolise,proportionate,thesaban,symbian,aeneid,mitotic,veliki,compressive,cisterns,abies,winemaker,massenet,bertolt,ahmednagar,triplemania,armorial,administracion,tenures,smokehouse,hashtag,fuerza,regattas,gennady,kanazawa,mahmudabad,crustal,asaph,valentinian,ilaiyaraaja,honeyeater,trapezoidal,cooperatively,unambiguously,mastodon,inhospitable,harnesses,riverton,renewables,djurgardens,haitians,airings,humanoids,boatswain,shijiazhuang,faints,veera,punjabis,steepest,narain,karlovy,serre,sulcus,collectives,1500m,arion,subarctic,liberally,apollonius,ostia,droplet,headstones,norra,robusta,maquis,veronese,imola,primers,luminance,escadrille,mizuki,irreconcilable,stalybridge,temur,paraffin,stuccoed,parthians,counsels,fundamentalists,vivendi,polymath,sugababes,mikko,yonne,fermions,vestfold,pastoralist,kigali,unseeded,glarus,cusps,amasya,northwesterly,minorca,astragalus,verney,trevelyan,antipathy,wollstonecraft,bivalves,boulez,royle,divisao,quranic,bareilly,coronal,deviates,lulea,erectus,petronas,chandan,proxies,aeroflot,postsynaptic,memoriam,moyne,gounod,kuznetsova,pallava,ordinating,reigate,'first,lewisburg,exploitative,danby,academica,bailiwick,brahe,injective,stipulations,aeschylus,computes,gulden,hydroxylase,liveries,somalis,underpinnings,muscovite,kongsberg,domus,overlain,shareware,variegated,jalalabad,agence,ciphertext,insectivores,dengeki,menuhin,cladistic,baerum,betrothal,tokushima,wavelet,expansionist,pottsville,siyuan,prerequisites,carpi,nemzeti,nazar,trialled,eliminator,irrorated,homeward,redwoods,undeterred,strayed,lutyens,multicellular,aurelian,notated,lordships,alsatian,idents,foggia,garros,chalukyas,lillestrom,podlaski,pessimism,hsien,demilitarized,whitewashed,willesden,kirkcaldy,sanctorum,lamia,relaying,escondido,paediatric,contemplates,demarcated,bluestone,betula,penarol,capitalise,kreuznach,kenora,115th,hold'em,reichswehr,vaucluse,m.i.a,windings,boys/girls,cajon,hisar,predictably,flemington,ysgol,mimicked,clivina,grahamstown,ionia,glyndebourne,patrese,aquaria,sleaford,dayal,sportscenter,malappuram,m.b.a.,manoa,carbines,solvable,designator,ramanujan,linearity,academicians,sayid,lancastrian,factorial,strindberg,vashem,delos,comyn,condensing,superdome,merited,kabaddi,intransitive,bideford,neuroimaging,duopoly,scorecards,ziggler,heriot,boyars,virology,marblehead,microtubules,westphalian,anticipates,hingham,searchers,harpist,rapides,morricone,convalescent,mises,nitride,metrorail,matterhorn,bicol,drivetrain,marketer,snippet,winemakers,muban,scavengers,halberstadt,herkimer,peten,laborious,stora,montgomeryshire,booklist,shamir,herault,eurostar,anhydrous,spacewalk,ecclesia,calliostoma,highschool,d'oro,suffusion,imparts,overlords,tagus,rectifier,counterinsurgency,ministered,eilean,milecastle,contre,micromollusk,okhotsk,bartoli,matroid,hasidim,thirunal,terme,tarlac,lashkar,presque,thameslink,flyby,troopship,renouncing,fatih,messrs,vexillum,bagration,magnetite,bornholm,androgynous,vehement,tourette,philosophic,gianfranco,tuileries,codice_6,radially,flexion,hants,reprocessing,setae,burne,palaeographically,infantryman,shorebirds,tamarind,moderna,threading,militaristic,crohn,norrkoping,125cc,stadtholder,troms,klezmer,alphanumeric,brome,emmanuelle,tiwari,alchemical,formula_52,onassis,bleriot,bipedal,colourless,hermeneutics,hosni,precipitating,turnstiles,hallucinogenic,panhellenic,wyandotte,elucidated,chita,ehime,generalised,hydrophilic,biota,niobium,rnzaf,gandhara,longueuil,logics,sheeting,bielsko,cuvier,kagyu,trefoil,docent,pancrase,stalinism,postures,encephalopathy,monckton,imbalances,epochs,leaguers,anzio,diminishes,pataki,nitrite,amuro,nabil,maybach,l'aquila,babbler,bacolod,thutmose,evora,gaudi,breakage,recur,preservative,60deg,mendip,functionaries,columnar,maccabiah,chert,verden,bromsgrove,clijsters,dengue,pastorate,phuoc,principia,viareggio,kharagpur,scharnhorst,anyang,bosons,l'art,criticises,ennio,semarang,brownian,mirabilis,asperger,calibers,typographical,cartooning,minos,disembark,supranational,undescribed,etymologically,alappuzha,vilhelm,lanao,pakenham,bhagavata,rakoczi,clearings,astrologers,manitowoc,bunuel,acetylene,scheduler,defamatory,trabzonspor,leaded,scioto,pentathlete,abrahamic,minigames,aldehydes,peerages,legionary,1640s,masterworks,loudness,bryansk,likeable,genocidal,vegetated,towpath,declination,pyrrhus,divinely,vocations,rosebery,associazione,loaders,biswas,oeste,tilings,xianzong,bhojpuri,annuities,relatedness,idolator,psers,constriction,chuvash,choristers,hanafi,fielders,grammarian,orpheum,asylums,millbrook,gyatso,geldof,stabilise,tableaux,diarist,kalahari,panini,cowdenbeath,melanin,4x100m,resonances,pinar,atherosclerosis,sheringham,castlereagh,aoyama,larks,pantograph,protrude,natak,gustafsson,moribund,cerevisiae,cleanly,polymeric,holkar,cosmonauts,underpinning,lithosphere,firuzabad,languished,mingled,citrate,spadina,lavas,daejeon,fibrillation,porgy,pineville,ps1000,cobbled,emamzadeh,mukhtar,dampers,indelible,salonika,nanoscale,treblinka,eilat,purporting,fluctuate,mesic,hagiography,cutscenes,fondation,barrens,comically,accrue,ibrox,makerere,defections,'there,hollandia,skene,grosseto,reddit,objectors,inoculation,rowdies,playfair,calligrapher,namor,sibenik,abbottabad,propellants,hydraulically,chloroplasts,tablelands,tecnico,schist,klasse,shirvan,bashkortostan,bullfighting,north/south,polski,hanns,woodblock,kilmore,ejecta,ignacy,nanchang,danubian,commendations,snohomish,samaritans,argumentation,vasconcelos,hedgehogs,vajrayana,barents,kulkarni,kumbakonam,identifications,hillingdon,weirs,nayanar,beauvoir,messe,divisors,atlantiques,broods,affluence,tegucigalpa,unsuited,autodesk,akash,princeps,culprits,kingstown,unassuming,goole,visayan,asceticism,blagojevich,irises,paphos,unsound,maurier,pontchartrain,desertification,sinfonietta,latins,especial,limpet,valerenga,glial,brainstem,mitral,parables,sauropod,judean,iskcon,sarcoma,venlo,justifications,zhuhai,blavatsky,alleviated,usafe,steppenwolf,inversions,janko,chagall,secretory,basildon,saguenay,pergamon,hemispherical,harmonized,reloading,franjo,domaine,extravagance,relativism,metamorphosed,labuan,baloncesto,gmail,byproducts,calvinists,counterattacked,vitus,bubonic,120th,strachey,ritually,brookwood,selectable,savinja,incontinence,meltwater,jinja,1720s,brahmi,morgenthau,sheaves,sleeved,stratovolcano,wielki,utilisation,avoca,fluxus,panzergrenadier,philately,deflation,podlaska,prerogatives,kuroda,theophile,zhongzong,gascoyne,magus,takao,arundell,fylde,merdeka,prithviraj,venkateswara,liepaja,daigo,dreamland,reflux,sunnyvale,coalfields,seacrest,soldering,flexor,structuralism,alnwick,outweighed,unaired,mangeshkar,batons,glaad,banshees,irradiated,organelles,biathlete,cabling,chairlift,lollapalooza,newsnight,capacitive,succumbs,flatly,miramichi,burwood,comedienne,charteris,biotic,workspace,aficionados,sokolka,chatelet,o'shaughnessy,prosthesis,neoliberal,refloated,oppland,hatchlings,econometrics,loess,thieu,androids,appalachians,jenin,pterostichinae,downsized,foils,chipsets,stencil,danza,narrate,maginot,yemenite,bisects,crustacean,prescriptive,melodious,alleviation,empowers,hansson,autodromo,obasanjo,osmosis,daugava,rheumatism,moraes,leucine,etymologies,chepstow,delaunay,bramall,bajaj,flavoring,approximates,marsupials,incisive,microcomputer,tactically,waals,wilno,fisichella,ursus,hindmarsh,mazarin,lomza,xenophobia,lawlessness,annecy,wingers,gornja,gnaeus,superieur,tlaxcala,clasps,symbolises,slats,rightist,effector,blighted,permanence,divan,progenitors,kunsthalle,anointing,excelling,coenzyme,indoctrination,dnipro,landholdings,adriaan,liturgies,cartan,ethmia,attributions,sanctus,trichy,chronicon,tancred,affinis,kampuchea,gantry,pontypool,membered,distrusted,fissile,dairies,hyposmocoma,craigie,adarsh,martinsburg,taxiway,30deg,geraint,vellum,bencher,khatami,formula_53,zemun,teruel,endeavored,palmares,pavements,u.s..,internationalization,satirized,carers,attainable,wraparound,muang,parkersburg,extinctions,birkenfeld,wildstorm,payers,cohabitation,unitas,culloden,capitalizing,clwyd,daoist,campinas,emmylou,orchidaceae,halakha,orientales,fealty,domnall,chiefdom,nigerians,ladislav,dniester,avowed,ergonomics,newsmagazine,kitsch,cantilevered,benchmarking,remarriage,alekhine,coldfield,taupo,almirante,substations,apprenticeships,seljuq,levelling,eponym,symbolising,salyut,opioids,underscore,ethnologue,mohegan,marikina,libro,bassano,parse,semantically,disjointed,dugdale,padraig,tulsi,modulating,xfinity,headlands,mstislav,earthworms,bourchier,lgbtq,embellishments,pennants,rowntree,betel,motet,mulla,catenary,washoe,mordaunt,dorking,colmar,girardeau,glentoran,grammatically,samad,recreations,technion,staccato,mikoyan,spoilers,lyndhurst,victimization,chertsey,belafonte,tondo,tonsberg,narrators,subcultures,malformations,edina,augmenting,attests,euphemia,cabriolet,disguising,1650s,navarrese,demoralized,cardiomyopathy,welwyn,wallachian,smoothness,planktonic,voles,issuers,sardasht,survivability,cuauhtemoc,thetis,extruded,signet,raghavan,lombok,eliyahu,crankcase,dissonant,stolberg,trencin,desktops,bursary,collectivization,charlottenburg,triathlete,curvilinear,involuntarily,mired,wausau,invades,sundaram,deletions,bootstrap,abellio,axiomatic,noguchi,setups,malawian,visalia,materialist,kartuzy,wenzong,plotline,yeshivas,parganas,tunica,citric,conspecific,idlib,superlative,reoccupied,blagoevgrad,masterton,immunological,hatta,courbet,vortices,swallowtail,delves,haridwar,diptera,boneh,bahawalpur,angering,mardin,equipments,deployable,guanine,normality,rimmed,artisanal,boxset,chandrasekhar,jools,chenar,tanakh,carcassonne,belatedly,millville,anorthosis,reintegration,velde,surfactant,kanaan,busoni,glyphipterix,personas,fullness,rheims,tisza,stabilizers,bharathi,joost,spinola,mouldings,perching,esztergom,afzal,apostate,lustre,s.league,motorboat,monotheistic,armature,barat,asistencia,bloomsburg,hippocampal,fictionalised,defaults,broch,hexadecimal,lusignan,ryanair,boccaccio,breisgau,southbank,bskyb,adjoined,neurobiology,aforesaid,sadhu,langue,headship,wozniacki,hangings,regulus,prioritized,dynamism,allier,hannity,shimin,antoninus,gymnopilus,caledon,preponderance,melayu,electrodynamics,syncopated,ibises,krosno,mechanistic,morpeth,harbored,albini,monotheism,'real,hyperactivity,haveli,writer/director,minato,nimoy,caerphilly,chitral,amirabad,fanshawe,l'oreal,lorde,mukti,authoritarianism,valuing,spyware,hanbury,restarting,stato,embed,suiza,empiricism,stabilisation,stari,castlemaine,orbis,manufactory,mauritanian,shoji,taoyuan,prokaryotes,oromia,ambiguities,embodying,slims,frente,innovate,ojibwa,powdery,gaeltacht,argentinos,quatermass,detergents,fijians,adaptor,tokai,chileans,bulgars,oxidoreductases,bezirksliga,conceicao,myosin,nellore,500cc,supercomputers,approximating,glyndwr,polypropylene,haugesund,cockerell,tudman,ashbourne,hindemith,bloodlines,rigveda,etruria,romanos,steyn,oradea,deceleration,manhunter,laryngeal,fraudulently,janez,wendover,haplotype,janaki,naoki,belizean,mellencamp,cartographic,sadhana,tricolour,pseudoscience,satara,bytow,s.p.a.,jagdgeschwader,arcot,omagh,sverdrup,masterplan,surtees,apocrypha,ahvaz,d'amato,socratic,leumit,unnumbered,nandini,witold,marsupial,coalesced,interpolated,gimnasia,karadzic,keratin,mamoru,aldeburgh,speculator,escapement,irfan,kashyap,satyajit,haddington,solver,rothko,ashkelon,kickapoo,yeomen,superbly,bloodiest,greenlandic,lithic,autofocus,yardbirds,poona,keble,javan,sufis,expandable,tumblr,ursuline,swimwear,winwood,counsellors,aberrations,marginalised,befriending,workouts,predestination,varietal,siddhartha,dunkeld,judaic,esquimalt,shabab,ajith,telefonica,stargard,hoysala,radhakrishnan,sinusoidal,strada,hiragana,cebuano,monoid,independencia,floodwaters,mildura,mudflats,ottokar,translit,radix,wigner,philosophically,tephritid,synthesizing,castletown,installs,stirner,resettle,bushfire,choirmaster,kabbalistic,shirazi,lightship,rebus,colonizers,centrifuge,leonean,kristofferson,thymus,clackamas,ratnam,rothesay,municipally,centralia,thurrock,gulfport,bilinear,desirability,merite,psoriasis,macaw,erigeron,consignment,mudstone,distorting,karlheinz,ramen,tailwheel,vitor,reinsurance,edifices,superannuation,dormancy,contagion,cobden,rendezvoused,prokaryotic,deliberative,patricians,feigned,degrades,starlings,sopot,viticultural,beaverton,overflowed,convener,garlands,michiel,ternopil,naturelle,biplanes,bagot,gamespy,ventspils,disembodied,flattening,profesional,londoners,arusha,scapular,forestall,pyridine,ulema,eurodance,aruna,callus,periodontal,coetzee,immobilized,o'meara,maharani,katipunan,reactants,zainab,microgravity,saintes,britpop,carrefour,constrain,adversarial,firebirds,brahmo,kashima,simca,surety,surpluses,superconductivity,gipuzkoa,cumans,tocantins,obtainable,humberside,roosting,'king,formula_54,minelayer,bessel,sulayman,cycled,biomarkers,annealing,shusha,barda,cassation,djing,polemics,tuple,directorates,indomitable,obsolescence,wilhelmine,pembina,bojan,tambo,dioecious,pensioner,magnificat,1660s,estrellas,southeasterly,immunodeficiency,railhead,surreptitiously,codeine,encores,religiosity,tempera,camberley,efendi,boardings,malleable,hagia,input/output,lucasfilm,ujjain,polymorphisms,creationist,berners,mickiewicz,irvington,linkedin,endures,kinect,munition,apologetics,fairlie,predicated,reprinting,ethnographer,variances,levantine,mariinsky,jadid,jarrow,asia/oceania,trinamool,waveforms,bisexuality,preselection,pupae,buckethead,hieroglyph,lyricists,marionette,dunbartonshire,restorer,monarchical,pazar,kickoffs,cabildo,savannas,gliese,dench,spoonbills,novelette,diliman,hypersensitivity,authorising,montefiore,mladen,qu'appelle,theistic,maruti,laterite,conestoga,saare,californica,proboscis,carrickfergus,imprecise,hadassah,baghdadi,jolgeh,deshmukh,amusements,heliopolis,berle,adaptability,partenkirchen,separations,baikonur,cardamom,southeastward,southfield,muzaffar,adequacy,metropolitana,rajkot,kiyoshi,metrobus,evictions,reconciles,librarianship,upsurge,knightley,badakhshan,proliferated,spirituals,burghley,electroacoustic,professing,featurette,reformists,skylab,descriptors,oddity,greyfriars,injects,salmond,lanzhou,dauntless,subgenera,underpowered,transpose,mahinda,gatos,aerobatics,seaworld,blocs,waratahs,joris,giggs,perfusion,koszalin,mieczyslaw,ayyubid,ecologists,modernists,sant'angelo,quicktime,him/her,staves,sanyo,melaka,acrocercops,qigong,iterated,generalizes,recuperation,vihara,circassians,psychical,chavo,memoires,infiltrates,notaries,pelecaniformesfamily,strident,chivalric,pierrepont,alleviating,broadsides,centipede,b.tech,reinterpreted,sudetenland,hussite,covenanters,radhika,ironclads,gainsbourg,testis,penarth,plantar,azadegan,beano,espn.com,leominster,autobiographies,nbcuniversal,eliade,khamenei,montferrat,undistinguished,ethnological,wenlock,fricatives,polymorphic,biome,joule,sheaths,astrophysicist,salve,neoclassicism,lovat,downwind,belisarius,forma,usurpation,freie,depopulation,backbench,ascenso,'high,aagpbl,gdanski,zalman,mouvement,encapsulation,bolshevism,statny,voyageurs,hywel,vizcaya,mazra'eh,narthex,azerbaijanis,cerebrospinal,mauretania,fantail,clearinghouse,bolingbroke,pequeno,ansett,remixing,microtubule,wrens,jawahar,palembang,gambian,hillsong,fingerboard,repurposed,sundry,incipient,veolia,theologically,ulaanbaatar,atsushi,foundling,resistivity,myeloma,factbook,mazowiecka,diacritic,urumqi,clontarf,provokes,intelsat,professes,materialise,portobello,benedictines,panionios,introverted,reacquired,bridport,mammary,kripke,oratorios,vlore,stoning,woredas,unreported,antti,togolese,fanzines,heuristics,conservatories,carburetors,clitheroe,cofounded,formula_57,erupting,quinnipiac,bootle,ghostface,sittings,aspinall,sealift,transferase,boldklub,siskiyou,predominated,francophonie,ferruginous,castrum,neogene,sakya,madama,precipitous,'love,posix,bithynia,uttara,avestan,thrushes,seiji,memorably,septimius,libri,cibernetico,hyperinflation,dissuaded,cuddalore,peculiarity,vaslui,grojec,albumin,thurles,casks,fasteners,fluidity,buble,casals,terek,gnosticism,cognates,ulnar,radwanska,babylonians,majuro,oxidizer,excavators,rhythmically,liffey,gorakhpur,eurydice,underscored,arborea,lumumba,tuber,catholique,grama,galilei,scrope,centreville,jacobin,bequests,ardeche,polygamous,montauban,terai,weatherboard,readability,attainder,acraea,transversely,rivets,winterbottom,reassures,bacteriology,vriesea,chera,andesite,dedications,homogenous,reconquered,bandon,forrestal,ukiyo,gurdjieff,tethys,sparc,muscogee,grebes,belchatow,mansa,blantyre,palliser,sokolow,fibroblasts,exmoor,misaki,soundscapes,housatonic,middelburg,convenor,leyla,antipope,histidine,okeechobee,alkenes,sombre,alkene,rubik,macaques,calabar,trophee,pinchot,'free,frusciante,chemins,falaise,vasteras,gripped,schwarzenberg,cumann,kanchipuram,acoustically,silverbacks,fangio,inset,plympton,kuril,vaccinations,recep,theropods,axils,stavropol,encroached,apoptotic,papandreou,wailers,moonstone,assizes,micrometers,hornchurch,truncation,annapurna,egyptologists,rheumatic,promiscuity,satiric,fleche,caloptilia,anisotropy,quaternions,gruppo,viscounts,awardees,aftershocks,sigint,concordance,oblasts,gaumont,stent,commissars,kesteven,hydroxy,vijayanagar,belorussian,fabricius,watermark,tearfully,mamet,leukaemia,sorkh,milepost,tattooing,vosta,abbasids,uncompleted,hedong,woodwinds,extinguishing,malus,multiplexes,francoist,pathet,responsa,bassists,'most,postsecondary,ossory,grampian,saakashvili,alito,strasberg,impressionistic,volador,gelatinous,vignette,underwing,campanian,abbasabad,albertville,hopefuls,nieuwe,taxiways,reconvened,recumbent,pathologists,unionized,faversham,asymptotically,romulo,culling,donja,constricted,annesley,duomo,enschede,lovech,sharpshooter,lansky,dhamma,papillae,alanine,mowat,delius,wrest,mcluhan,podkarpackie,imitators,bilaspur,stunting,pommel,casemate,handicaps,nagas,testaments,hemings,necessitate,rearward,locative,cilla,klitschko,lindau,merion,consequential,antic,soong,copula,berthing,chevrons,rostral,sympathizer,budokan,ranulf,beria,stilt,replying,conflated,alcibiades,painstaking,yamanashi,calif.,arvid,ctesiphon,xizong,rajas,caxton,downbeat,resurfacing,rudders,miscegenation,deathmatch,foregoing,arthropod,attestation,karts,reapportionment,harnessing,eastlake,schola,dosing,postcolonial,imtiaz,formula_55,insulators,gunung,accumulations,pampas,llewelyn,bahnhof,cytosol,grosjean,teaneck,briarcliff,arsenio,canara,elaborating,passchendaele,searchlights,holywell,mohandas,preventable,gehry,mestizos,ustinov,cliched,'national,heidfeld,tertullian,jihadist,tourer,miletus,semicircle,outclassed,bouillon,cardinalate,clarifies,dakshina,bilayer,pandyan,unrwa,chandragupta,formula_56,portola,sukumaran,lactation,islamia,heikki,couplers,misappropriation,catshark,montt,ploughs,carib,stator,leaderboard,kenrick,dendrites,scape,tillamook,molesworth,mussorgsky,melanesia,restated,troon,glycoside,truckee,headwater,mashup,sectoral,gangwon,docudrama,skirting,psychopathology,dramatised,ostroleka,infestations,thabo,depolarization,wideroe,eisenbahn,thomond,kumaon,upendra,foreland,acronyms,yaqui,retaking,raphaelite,specie,dupage,villars,lucasarts,chloroplast,werribee,balsa,ascribe,havant,flava,khawaja,tyumen,subtract,interrogators,reshaping,buzzcocks,eesti,campanile,potemkin,apertures,snowboarder,registrars,handbooks,boyar,contaminant,depositors,proximate,jeunesse,zagora,pronouncements,mists,nihilism,deified,margraviate,pietersen,moderators,amalfi,adjectival,copepods,magnetosphere,pallets,clemenceau,castra,perforation,granitic,troilus,grzegorz,luthier,dockyards,antofagasta,ffestiniog,subroutine,afterword,waterwheel,druce,nitin,undifferentiated,emacs,readmitted,barneveld,tapers,hittites,infomercials,infirm,braathens,heligoland,carpark,geomagnetic,musculoskeletal,nigerien,machinima,harmonize,repealing,indecency,muskoka,verite,steubenville,suffixed,cytoskeleton,surpasses,harmonia,imereti,ventricles,heterozygous,envisions,otsego,ecoles,warrnambool,burgenland,seria,rawat,capistrano,welby,kirin,enrollments,caricom,dragonlance,schaffhausen,expanses,photojournalism,brienne,etude,referent,jamtland,schemas,xianbei,cleburne,bicester,maritima,shorelines,diagonals,bjelke,nonpublic,aliasing,m.f.a,ovals,maitreya,skirmishing,grothendieck,sukhothai,angiotensin,bridlington,durgapur,contras,gakuen,skagit,rabbinate,tsunamis,haphazard,tyldesley,microcontroller,discourages,hialeah,compressing,septimus,larvik,condoleezza,psilocybin,protectionism,songbirds,clandestinely,selectmen,wargame,cinemascope,khazars,agronomy,melzer,latifah,cherokees,recesses,assemblymen,basescu,banaras,bioavailability,subchannels,adenine,o'kelly,prabhakar,leonese,dimethyl,testimonials,geoffroy,oxidant,universiti,gheorghiu,bohdan,reversals,zamorin,herbivore,jarre,sebastiao,infanterie,dolmen,teddington,radomsko,spaceships,cuzco,recapitulation,mahoning,bainimarama,myelin,aykroyd,decals,tokelau,nalgonda,rajasthani,121st,quelled,tambov,illyrians,homilies,illuminations,hypertrophy,grodzisk,inundation,incapacity,equilibria,combats,elihu,steinitz,berengar,gowda,canwest,khosrau,maculata,houten,kandinsky,onside,leatherhead,heritable,belvidere,federative,chukchi,serling,eruptive,patan,entitlements,suffragette,evolutions,migrates,demobilisation,athleticism,trope,sarpsborg,kensal,translink,squamish,concertgebouw,energon,timestamp,competences,zalgiris,serviceman,codice_7,spoofing,assange,mahadevan,skien,suceava,augustan,revisionism,unconvincing,hollande,drina,gottlob,lippi,broglie,darkening,tilapia,eagerness,nacht,kolmogorov,photometric,leeuwarden,jrotc,haemorrhage,almanack,cavalli,repudiation,galactose,zwickau,cetinje,houbraken,heavyweights,gabonese,ordinals,noticias,museveni,steric,charaxes,amjad,resection,joinville,leczyca,anastasius,purbeck,subtribe,dalles,leadoff,monoamine,jettisoned,kaori,anthologized,alfreton,indic,bayezid,tottori,colonizing,assassinating,unchanging,eusebian,d'estaing,tsingtao,toshio,transferases,peronist,metrology,equus,mirpur,libertarianism,kovil,indole,'green,abstention,quantitatively,icebreakers,tribals,mainstays,dryandra,eyewear,nilgiri,chrysanthemum,inositol,frenetic,merchantman,hesar,physiotherapist,transceiver,dancefloor,rankine,neisse,marginalization,lengthen,unaided,rework,pageantry,savio,striated,funen,witton,illuminates,frass,hydrolases,akali,bistrita,copywriter,firings,handballer,tachinidae,dmytro,coalesce,neretva,menem,moraines,coatbridge,crossrail,spoofed,drosera,ripen,protour,kikuyu,boleslav,edwardes,troubadours,haplogroups,wrasse,educationalist,sroda,khaneh,dagbladet,apennines,neuroscientist,deplored,terje,maccabees,daventry,spaceport,lessening,ducats,singer/guitarist,chambersburg,yeong,configurable,ceremonially,unrelenting,caffe,graaf,denizens,kingsport,ingush,panhard,synthesised,tumulus,homeschooled,bozorg,idiomatic,thanhouser,queensway,radek,hippolytus,inking,banovina,peacocks,piaui,handsworth,pantomimes,abalone,thera,kurzweil,bandura,augustinians,bocelli,ferrol,jiroft,quadrature,contravention,saussure,rectification,agrippina,angelis,matanzas,nidaros,palestrina,latium,coriolis,clostridium,ordain,uttering,lanchester,proteolytic,ayacucho,merseburg,holbein,sambalpur,algebraically,inchon,ostfold,savoia,calatrava,lahiri,judgeship,ammonite,masaryk,meyerbeer,hemorrhagic,superspeedway,ningxia,panicles,encircles,khmelnytsky,profusion,esher,babol,inflationary,anhydride,gaspe,mossy,periodicity,nacion,meteorologists,mahjong,interventional,sarin,moult,enderby,modell,palgrave,warners,montcalm,siddha,functionalism,rilke,politicized,broadmoor,kunste,orden,brasileira,araneta,eroticism,colquhoun,mamba,blacktown,tubercle,seagrass,manoel,camphor,neoregelia,llandudno,annexe,enplanements,kamien,plovers,statisticians,iturbide,madrasah,nontrivial,publican,landholders,manama,uninhabitable,revivalist,trunkline,friendliness,gurudwara,rocketry,unido,tripos,besant,braque,evolutionarily,abkhazian,staffel,ratzinger,brockville,bohemond,intercut,djurgarden,utilitarianism,deploys,sastri,absolutism,subhas,asghar,fictions,sepinwall,proportionately,titleholders,thereon,foursquare,machinegun,knightsbridge,siauliai,aqaba,gearboxes,castaways,weakens,phallic,strzelce,buoyed,ruthenia,pharynx,intractable,neptunes,koine,leakey,netherlandish,preempted,vinay,terracing,instigating,alluvium,prosthetics,vorarlberg,politiques,joinery,reduplication,nebuchadnezzar,lenticular,banka,seaborne,pattinson,helpline,aleph,beckenham,californians,namgyal,franziska,aphid,branagh,transcribe,appropriateness,surakarta,takings,propagates,juraj,b0d3fb,brera,arrayed,tailback,falsehood,hazleton,prosody,egyptology,pinnate,tableware,ratan,camperdown,ethnologist,tabari,classifiers,biogas,126th,kabila,arbitron,apuestas,membranous,kincardine,oceana,glories,natick,populism,synonymy,ghalib,mobiles,motherboards,stationers,germinal,patronised,formula_58,gaborone,torts,jeezy,interleague,novaya,batticaloa,offshoots,wilbraham,filename,nswrfl,'well,trilobite,pythons,optimally,scientologists,rhesus,pilsen,backdrops,batang,unionville,hermanos,shrikes,fareham,outlawing,discontinuing,boisterous,shamokin,scanty,southwestward,exchangers,unexpired,mewar,h.m.s,saldanha,pawan,condorcet,turbidity,donau,indulgences,coincident,cliques,weeklies,bardhaman,violators,kenai,caspase,xperia,kunal,fistula,epistemic,cammell,nephi,disestablishment,rotator,germaniawerft,pyaar,chequered,jigme,perlis,anisotropic,popstars,kapil,appendices,berat,defecting,shacks,wrangel,panchayath,gorna,suckling,aerosols,sponheim,talal,borehole,encodings,enlai,subduing,agong,nadar,kitsap,syrmia,majumdar,pichilemu,charleville,embryology,booting,literati,abutting,basalts,jussi,repubblica,hertogenbosch,digitization,relents,hillfort,wiesenthal,kirche,bhagwan,bactrian,oases,phyla,neutralizing,helsing,ebooks,spearheading,margarine,'golden,phosphor,picea,stimulants,outliers,timescale,gynaecology,integrator,skyrocketed,bridgnorth,senecio,ramachandra,suffragist,arrowheads,aswan,inadvertent,microelectronics,118th,sofer,kubica,melanesian,tuanku,balkh,vyborg,crystallographic,initiators,metamorphism,ginzburg,looters,unimproved,finistere,newburyport,norges,immunities,franchisees,asterism,kortrijk,camorra,komsomol,fleurs,draughts,patagonian,voracious,artin,collaborationist,revolucion,revitalizing,xaver,purifying,antipsychotic,disjunct,pompeius,dreamwave,juvenal,beinn,adiyaman,antitank,allama,boletus,melanogaster,dumitru,caproni,aligns,athabaskan,stobart,phallus,veikkausliiga,hornsey,buffering,bourbons,dobruja,marga,borax,electrics,gangnam,motorcyclist,whidbey,draconian,lodger,galilean,sanctification,imitates,boldness,underboss,wheatland,cantabrian,terceira,maumee,redefining,uppercase,ostroda,characterise,universalism,equalized,syndicalism,haringey,masovia,deleuze,funkadelic,conceals,thuan,minsky,pluralistic,ludendorff,beekeeping,bonfires,endoscopic,abuts,prebend,jonkoping,amami,tribunes,yup'ik,awadh,gasification,pforzheim,reforma,antiwar,vaishnavism,maryville,inextricably,margrethe,empresa,neutrophils,sanctified,ponca,elachistidae,curiae,quartier,mannar,hyperplasia,wimax,busing,neologism,florins,underrepresented,digitised,nieuw,cooch,howards,frege,hughie,plied,swale,kapellmeister,vajpayee,quadrupled,aeronautique,dushanbe,custos,saltillo,kisan,tigray,manaus,epigrams,shamanic,peppered,frosts,promotion/relegation,concedes,zwingli,charentes,whangarei,hyung,spring/summer,sobre,eretz,initialization,sawai,ephemera,grandfathered,arnaldo,customised,permeated,parapets,growths,visegrad,estudios,altamont,provincia,apologises,stoppard,carburettor,rifts,kinematic,zhengzhou,eschatology,prakrit,folate,yvelines,scapula,stupas,rishon,reconfiguration,flutist,1680s,apostolate,proudhon,lakshman,articulating,stortford,faithfull,bitterns,upwelling,qur'anic,lidar,interferometry,waterlogged,koirala,ditton,wavefunction,fazal,babbage,antioxidants,lemberg,deadlocked,tolled,ramapo,mathematica,leiria,topologies,khali,photonic,balti,1080p,corrects,recommenced,polyglot,friezes,tiebreak,copacabana,cholmondeley,armband,abolishment,sheamus,buttes,glycolysis,cataloged,warrenton,sassari,kishan,foodservice,cryptanalysis,holmenkollen,cosplay,machi,yousuf,mangal,allying,fertiliser,otomi,charlevoix,metallurg,parisians,bottlenose,oakleigh,debug,cidade,accede,ligation,madhava,pillboxes,gatefold,aveyron,sorin,thirsk,immemorial,menelik,mehra,domingos,underpinned,fleshed,harshness,diphthong,crestwood,miskolc,dupri,pyrausta,muskingum,tuoba,prodi,incidences,waynesboro,marquesas,heydar,artesian,calinescu,nucleation,funders,covalently,compaction,derbies,seaters,sodor,tabular,amadou,peckinpah,o'halloran,zechariah,libyans,kartik,daihatsu,chandran,erzhu,heresies,superheated,yarder,dorde,tanjore,abusers,xuanwu,juniperus,moesia,trusteeship,birdwatching,beatz,moorcock,harbhajan,sanga,choreographic,photonics,boylston,amalgamate,prawns,electrifying,sarath,inaccurately,exclaims,powerpoint,chaining,cpusa,adulterous,saccharomyces,glogow,vfl/afl,syncretic,simla,persisting,functors,allosteric,euphorbiaceae,juryo,mlada,moana,gabala,thornycroft,kumanovo,ostrovsky,sitio,tutankhamun,sauropods,kardzhali,reinterpretation,sulpice,rosyth,originators,halesowen,delineation,asesoria,abatement,gardai,elytra,taillights,overlays,monsoons,sandpipers,ingmar,henrico,inaccuracy,irwell,arenabowl,elche,pressburg,signalman,interviewees,sinkhole,pendle,ecommerce,cellos,nebria,organometallic,surrealistic,propagandist,interlaken,canandaigua,aerials,coutinho,pascagoula,tonopah,letterkenny,gropius,carbons,hammocks,childe,polities,hosiery,donitz,suppresses,diaghilev,stroudsburg,bagram,pistoia,regenerating,unitarians,takeaway,offstage,vidin,glorification,bakunin,yavapai,lutzow,sabercats,witney,abrogated,gorlitz,validating,dodecahedron,stubbornly,telenor,glaxosmithkline,solapur,undesired,jellicoe,dramatization,four-and-a-half,seawall,waterpark,artaxerxes,vocalization,typographic,byung,sachsenhausen,shepparton,kissimmee,konnan,belsen,dhawan,khurd,mutagenesis,vejle,perrot,estradiol,formula_60,saros,chiloe,misiones,lamprey,terrains,speke,miasto,eigenvectors,haydock,reservist,corticosteroids,savitri,shinawatra,developmentally,yehudi,berates,janissaries,recapturing,rancheria,subplots,gresley,nikkatsu,oryol,cosmas,boavista,formula_59,playfully,subsections,commentated,kathakali,dorid,vilaine,seepage,hylidae,keiji,kazakhs,triphosphate,1620s,supersede,monarchists,falla,miyako,notching,bhumibol,polarizing,secularized,shingled,bronislaw,lockerbie,soleyman,bundesbahn,latakia,redoubts,boult,inwardly,invents,ondrej,minangkabau,newquay,permanente,alhaji,madhav,malini,ellice,bookmaker,mankiewicz,etihad,o'dea,interrogative,mikawa,wallsend,canisius,bluesy,vitruvius,noord,ratifying,mixtec,gujranwala,subprefecture,keelung,goiania,nyssa,shi'ite,semitone,ch'uan,computerised,pertuan,catapults,nepomuk,shruti,millstones,buskerud,acolytes,tredegar,sarum,armia,dell'arte,devises,custodians,upturned,gallaudet,disembarking,thrashed,sagrada,myeon,undeclared,qumran,gaiden,tepco,janesville,showground,condense,chalon,unstaffed,pasay,undemocratic,hauts,viridis,uninjured,escutcheon,gymkhana,petaling,hammam,dislocations,tallaght,rerum,shias,indios,guaranty,simplicial,benares,benediction,tajiri,prolifically,huawei,onerous,grantee,ferencvaros,otranto,carbonates,conceit,digipak,qadri,masterclasses,swamiji,cradock,plunket,helmsman,119th,salutes,tippecanoe,murshidabad,intelligibility,mittal,diversifying,bidar,asansol,crowdsourcing,rovere,karakoram,grindcore,skylights,tulagi,furrows,ligne,stuka,sumer,subgraph,amata,regionalist,bulkeley,teletext,glorify,readied,lexicographer,sabadell,predictability,quilmes,phenylalanine,bandaranaike,pyrmont,marksmen,quisling,viscountess,sociopolitical,afoul,pediments,swazi,martyrology,nullify,panagiotis,superconductors,veldenz,jujuy,l'isle,hematopoietic,shafi,subsea,hattiesburg,jyvaskyla,kebir,myeloid,landmine,derecho,amerindians,birkenau,scriabin,milhaud,mucosal,nikaya,freikorps,theoretician,proconsul,o'hanlon,clerked,bactria,houma,macular,topologically,shrubby,aryeh,ghazali,afferent,magalhaes,moduli,ashtabula,vidarbha,securitate,ludwigsburg,adoor,varun,shuja,khatun,chengde,bushels,lascelles,professionnelle,elfman,rangpur,unpowered,citytv,chojnice,quaternion,stokowski,aschaffenburg,commutes,subramaniam,methylene,satrap,gharb,namesakes,rathore,helier,gestational,heraklion,colliers,giannis,pastureland,evocation,krefeld,mahadeva,churchmen,egret,yilmaz,galeazzo,pudukkottai,artigas,generalitat,mudslides,frescoed,enfeoffed,aphorisms,melilla,montaigne,gauliga,parkdale,mauboy,linings,prema,sapir,xylophone,kushan,rockne,sequoyah,vasyl,rectilinear,vidyasagar,microcosm,san'a,carcinogen,thicknesses,aleut,farcical,moderating,detested,hegemonic,instalments,vauban,verwaltungsgemeinschaft,picayune,razorback,magellanic,moluccas,pankhurst,exportation,waldegrave,sufferer,bayswater,1up.com,rearmament,orangutans,varazdin,b.o.b,elucidate,harlingen,erudition,brankovic,lapis,slipway,urraca,shinde,unwell,elwes,euboea,colwyn,srivijaya,grandstands,hortons,generalleutnant,fluxes,peterhead,gandhian,reals,alauddin,maximized,fairhaven,endow,ciechanow,perforations,darters,panellist,manmade,litigants,exhibitor,tirol,caracalla,conformance,hotelier,stabaek,hearths,borac,frisians,ident,veliko,emulators,schoharie,uzbeks,samarra,prestwick,wadia,universita,tanah,bucculatrix,predominates,genotypes,denounces,roadsides,ganassi,keokuk,philatelist,tomic,ingots,conduits,samplers,abdus,johar,allegories,timaru,wolfpacks,secunda,smeaton,sportivo,inverting,contraindications,whisperer,moradabad,calamities,bakufu,soundscape,smallholders,nadeem,crossroad,xenophobic,zakir,nationalliga,glazes,retroflex,schwyz,moroder,rubra,quraysh,theodoros,endemol,infidels,km/hr,repositioned,portraitist,lluis,answerable,arges,mindedness,coarser,eyewall,teleported,scolds,uppland,vibraphone,ricoh,isenburg,bricklayer,cuttlefish,abstentions,communicable,cephalopod,stockyards,balto,kinston,armbar,bandini,elphaba,maxims,bedouins,sachsen,friedkin,tractate,pamir,ivanovo,mohini,kovalainen,nambiar,melvyn,orthonormal,matsuyama,cuernavaca,veloso,overstated,streamer,dravid,informers,analyte,sympathized,streetscape,gosta,thomasville,grigore,futuna,depleting,whelks,kiedis,armadale,earner,wynyard,dothan,animating,tridentine,sabri,immovable,rivoli,ariege,parley,clinker,circulates,junagadh,fraunhofer,congregants,180th,buducnost,formula_62,olmert,dedekind,karnak,bayernliga,mazes,sandpiper,ecclestone,yuvan,smallmouth,decolonization,lemmy,adjudicated,retiro,legia,benue,posit,acidification,wahab,taconic,floatplane,perchlorate,atria,wisbech,divestment,dallara,phrygia,palustris,cybersecurity,rebates,facie,mineralogical,substituent,proteges,fowey,mayenne,smoothbore,cherwell,schwarzschild,junin,murrumbidgee,smalltalk,d'orsay,emirati,calaveras,titusville,theremin,vikramaditya,wampanoag,burra,plaines,onegin,emboldened,whampoa,langa,soderbergh,arnaz,sowerby,arendal,godunov,pathanamthitta,damselfly,bestowing,eurosport,iconoclasm,outfitters,acquiesced,badawi,hypotension,ebbsfleet,annulus,sohrab,thenceforth,chagatai,necessitates,aulus,oddities,toynbee,uniontown,innervation,populaire,indivisible,rossellini,minuet,cyrene,gyeongju,chania,cichlids,harrods,1690s,plunges,abdullahi,gurkhas,homebuilt,sortable,bangui,rediff,incrementally,demetrios,medaille,sportif,svend,guttenberg,tubules,carthusian,pleiades,torii,hoppus,phenyl,hanno,conyngham,teschen,cronenberg,wordless,melatonin,distinctiveness,autos,freising,xuanzang,dunwich,satanism,sweyn,predrag,contractually,pavlovic,malaysians,micrometres,expertly,pannonian,abstaining,capensis,southwesterly,catchphrases,commercialize,frankivsk,normanton,hibernate,verso,deportees,dubliners,codice_8,condors,zagros,glosses,leadville,conscript,morrisons,usury,ossian,oulton,vaccinium,civet,ayman,codrington,hadron,nanometers,geochemistry,extractor,grigori,tyrrhenian,neocollyris,drooping,falsification,werft,courtauld,brigantine,orhan,chapultepec,supercopa,federalized,praga,havering,encampments,infallibility,sardis,pawar,undirected,reconstructionist,ardrossan,varuna,pastimes,archdiocesan,fledging,shenhua,molise,secondarily,stagnated,replicates,ciencias,duryodhana,marauding,ruislip,ilyich,intermixed,ravenswood,shimazu,mycorrhizal,icosahedral,consents,dunblane,follicular,pekin,suffield,muromachi,kinsale,gauche,businesspeople,thereto,watauga,exaltation,chelmno,gorse,proliferate,drainages,burdwan,kangra,transducers,inductor,duvalier,maguindanao,moslem,uncaf,givenchy,plantarum,liturgics,telegraphs,lukashenko,chenango,andante,novae,ironwood,faubourg,torme,chinensis,ambala,pietermaritzburg,virginians,landform,bottlenecks,o'driscoll,darbhanga,baptistery,ameer,needlework,naperville,auditoriums,mullingar,starrer,animatronic,topsoil,madura,cannock,vernet,santurce,catocala,ozeki,pontevedra,multichannel,sundsvall,strategists,medio,135th,halil,afridi,trelawny,caloric,ghraib,allendale,hameed,ludwigshafen,spurned,pavlo,palmar,strafed,catamarca,aveiro,harmonization,surah,predictors,solvay,mande,omnipresent,parenthesis,echolocation,equaling,experimenters,acyclic,lithographic,sepoys,katarzyna,sridevi,impoundment,khosrow,caesarean,nacogdoches,rockdale,lawmaker,caucasians,bahman,miyan,rubric,exuberance,bombastic,ductile,snowdonia,inlays,pinyon,anemones,hurries,hospitallers,tayyip,pulleys,treme,photovoltaics,testbed,polonium,ryszard,osgoode,profiting,ironwork,unsurpassed,nepticulidae,makai,lumbini,preclassic,clarksburg,egremont,videography,rehabilitating,ponty,sardonic,geotechnical,khurasan,solzhenitsyn,henna,phoenicia,rhyolite,chateaux,retorted,tomar,deflections,repressions,harborough,renan,brumbies,vandross,storia,vodou,clerkenwell,decking,universo,salon.com,imprisoning,sudwest,ghaziabad,subscribing,pisgah,sukhumi,econometric,clearest,pindar,yildirim,iulia,atlases,cements,remaster,dugouts,collapsible,resurrecting,batik,unreliability,thiers,conjunctions,colophon,marcher,placeholder,flagella,wolds,kibaki,viviparous,twelver,screenshots,aroostook,khadr,iconographic,itasca,jaume,basti,propounded,varro,be'er,jeevan,exacted,shrublands,creditable,brocade,boras,bittern,oneonta,attentional,herzliya,comprehensible,lakeville,discards,caxias,frankland,camerata,satoru,matlab,commutator,interprovincial,yorkville,benefices,nizami,edwardsville,amigaos,cannabinoid,indianola,amateurliga,pernicious,ubiquity,anarchic,novelties,precondition,zardari,symington,sargodha,headphone,thermopylae,mashonaland,zindagi,thalberg,loewe,surfactants,dobro,crocodilians,samhita,diatoms,haileybury,berwickshire,supercritical,sofie,snorna,slatina,intramolecular,agung,osteoarthritis,obstetric,teochew,vakhtang,connemara,deformations,diadem,ferruccio,mainichi,qualitatively,refrigerant,rerecorded,methylated,karmapa,krasinski,restatement,rouvas,cubitt,seacoast,schwarzkopf,homonymous,shipowner,thiamine,approachable,xiahou,160th,ecumenism,polistes,internazionali,fouad,berar,biogeography,texting,inadequately,'when,4kids,hymenoptera,emplaced,cognomen,bellefonte,supplant,michaelmas,uriel,tafsir,morazan,schweinfurt,chorister,ps400,nscaa,petipa,resolutely,ouagadougou,mascarene,supercell,konstanz,bagrat,harmonix,bergson,shrimps,resonators,veneta,camas,mynydd,rumford,generalmajor,khayyam,web.com,pappus,halfdan,tanana,suomen,yutaka,bibliographical,traian,silat,noailles,contrapuntal,agaricus,'special,minibuses,1670s,obadiah,deepa,rorschach,malolos,lymington,valuations,imperials,caballeros,ambroise,judicature,elegiac,sedaka,shewa,checksum,gosforth,legionaries,corneille,microregion,friedrichshafen,antonis,surnamed,mycelium,cantus,educations,topmost,outfitting,ivica,nankai,gouda,anthemic,iosif,supercontinent,antifungal,belarusians,mudaliar,mohawks,caversham,glaciated,basemen,stevan,clonmel,loughton,deventer,positivist,manipuri,tensors,panipat,changeup,impermeable,dubbo,elfsborg,maritimo,regimens,bikram,bromeliad,substratum,norodom,gaultier,queanbeyan,pompeo,redacted,eurocopter,mothballed,centaurs,borno,copra,bemidji,'home,sopron,neuquen,passo,cineplex,alexandrov,wysokie,mammoths,yossi,sarcophagi,congreve,petkovic,extraneous,waterbirds,slurs,indias,phaeton,discontented,prefaced,abhay,prescot,interoperable,nordisk,bicyclists,validly,sejong,litovsk,zanesville,kapitanleutnant,kerch,changeable,mcclatchy,celebi,attesting,maccoll,sepahan,wayans,veined,gaudens,markt,dansk,soane,quantized,petersham,forebears,nayarit,frenzied,queuing,bygone,viggo,ludwik,tanka,hanssen,brythonic,cornhill,primorsky,stockpiles,conceptualization,lampeter,hinsdale,mesoderm,bielsk,rosenheim,ultron,joffrey,stanwyck,khagan,tiraspol,pavelic,ascendant,empoli,metatarsal,descentralizado,masada,ligier,huseyin,ramadi,waratah,tampines,ruthenium,statoil,mladost,liger,grecian,multiparty,digraph,maglev,reconsideration,radiography,cartilaginous,taizu,wintered,anabaptist,peterhouse,shoghi,assessors,numerator,paulet,painstakingly,halakhic,rocroi,motorcycling,gimel,kryptonian,emmeline,cheeked,drawdown,lelouch,dacians,brahmana,reminiscence,disinfection,optimizations,golders,extensor,tsugaru,tolling,liman,gulzar,unconvinced,crataegus,oppositional,dvina,pyrolysis,mandan,alexius,prion,stressors,loomed,moated,dhivehi,recyclable,relict,nestlings,sarandon,kosovar,solvers,czeslaw,kenta,maneuverable,middens,berkhamsted,comilla,folkways,loxton,beziers,batumi,petrochemicals,optimised,sirjan,rabindra,musicality,rationalisation,drillers,subspaces,'live,bbwaa,outfielders,tsung,danske,vandalised,norristown,striae,kanata,gastroenterology,steadfastly,equalising,bootlegging,mannerheim,notodontidae,lagoa,commentating,peninsulas,chishti,seismology,modigliani,preceptor,canonically,awardee,boyaca,hsinchu,stiffened,nacelle,bogor,dryness,unobstructed,yaqub,scindia,peeters,irritant,ammonites,ferromagnetic,speechwriter,oxygenated,walesa,millais,canarian,faience,calvinistic,discriminant,rasht,inker,annexes,howth,allocates,conditionally,roused,regionalism,regionalbahn,functionary,nitrates,bicentenary,recreates,saboteurs,koshi,plasmids,thinned,124th,plainview,kardashian,neuville,victorians,radiates,127th,vieques,schoolmates,petru,tokusatsu,keying,sunaina,flamethrower,'bout,demersal,hosokawa,corelli,omniscient,o'doherty,niksic,reflectivity,transdev,cavour,metronome,temporally,gabba,nsaids,geert,mayport,hematite,boeotia,vaudreuil,torshavn,sailplane,mineralogist,eskisehir,practises,gallifrey,takumi,unease,slipstream,hedmark,paulinus,ailsa,wielkopolska,filmworks,adamantly,vinaya,facelifted,franchisee,augustana,toppling,velvety,crispa,stonington,histological,genealogist,tactician,tebow,betjeman,nyingma,overwinter,oberoi,rampal,overwinters,petaluma,lactarius,stanmore,balikpapan,vasant,inclines,laminate,munshi,sociedade,rabbah,septal,boyband,ingrained,faltering,inhumans,nhtsa,affix,l'ordre,kazuki,rossendale,mysims,latvians,slaveholders,basilicata,neuburg,assize,manzanillo,scrobipalpa,formula_61,belgique,pterosaurs,privateering,vaasa,veria,northport,pressurised,hobbyist,austerlitz,sahih,bhadra,siliguri,bistrica,bursaries,wynton,corot,lepidus,lully,libor,libera,olusegun,choline,mannerism,lymphocyte,chagos,duxbury,parasitism,ecowas,morotai,cancion,coniston,aggrieved,sputnikmusic,parle,ammonian,civilisations,malformation,cattaraugus,skyhawks,d'arc,demerara,bronfman,midwinter,piscataway,jogaila,threonine,matins,kohlberg,hubli,pentatonic,camillus,nigam,potro,unchained,chauvel,orangeville,cistercians,redeployment,xanthi,manju,carabinieri,pakeha,nikolaevich,kantakouzenos,sesquicentennial,gunships,symbolised,teramo,ballo,crusading,l'oeil,bharatpur,lazier,gabrovo,hysteresis,rothbard,chaumont,roundel,ma'mun,sudhir,queried,newts,shimane,presynaptic,playfield,taxonomists,sensitivities,freleng,burkinabe,orfeo,autovia,proselytizing,bhangra,pasok,jujutsu,heung,pivoting,hominid,commending,formula_64,epworth,christianized,oresund,hantuchova,rajputana,hilversum,masoretic,dayak,bakri,assen,magog,macromolecules,waheed,qaida,spassky,rumped,protrudes,preminger,misogyny,glencairn,salafi,lacunae,grilles,racemes,areva,alighieri,inari,epitomized,photoshoot,one-of-a-kind,tring,muralist,tincture,backwaters,weaned,yeasts,analytically,smaland,caltrans,vysocina,jamuna,mauthausen,175th,nouvelles,censoring,reggina,christology,gilad,amplifying,mehmood,johnsons,redirects,eastgate,sacrum,meteoric,riverbanks,guidebooks,ascribes,scoparia,iconoclastic,telegraphic,chine,merah,mistico,lectern,sheung,aethelstan,capablanca,anant,uspto,albatrosses,mymensingh,antiretroviral,clonal,coorg,vaillant,liquidator,gigas,yokai,eradicating,motorcyclists,waitakere,tandon,nears,montenegrins,250th,tatsuya,yassin,atheistic,syncretism,nahum,berisha,transcended,owensboro,lakshmana,abteilung,unadorned,nyack,overflows,harrisonburg,complainant,uematsu,frictional,worsens,sangguniang,abutment,bulwer,sarma,apollinaire,shippers,lycia,alentejo,porpoises,optus,trawling,augustow,blackwall,workbench,westmount,leaped,sikandar,conveniences,stornoway,culverts,zoroastrians,hristo,ansgar,assistive,reassert,fanned,compasses,delgada,maisons,arima,plonsk,verlaine,starstruck,rakhine,befell,spirally,wyclef,expend,colloquium,formula_63,albertus,bellarmine,handedness,holon,introns,movimiento,profitably,lohengrin,discoverers,awash,erste,pharisees,dwarka,oghuz,hashing,heterodox,uloom,vladikavkaz,linesman,rehired,nucleophile,germanicus,gulshan,songz,bayerische,paralympian,crumlin,enjoined,khanum,prahran,penitent,amersfoort,saranac,semisimple,vagrants,compositing,tualatin,oxalate,lavra,ironi,ilkeston,umpqua,calum,stretford,zakat,guelders,hydrazine,birkin,spurring,modularity,aspartate,sodermanland,hopital,bellary,legazpi,clasico,cadfael,hypersonic,volleys,pharmacokinetics,carotene,orientale,pausini,bataille,lunga,retailed,m.phil,mazowieckie,vijayan,rawal,sublimation,promissory,estimators,ploughed,conflagration,penda,segregationist,otley,amputee,coauthor,sopra,pellew,wreckers,tollywood,circumscription,permittivity,strabane,landward,articulates,beaverbrook,rutherglen,coterminous,whistleblowers,colloidal,surbiton,atlante,oswiecim,bhasa,lampooned,chanter,saarc,landkreis,tribulation,tolerates,daiichi,hatun,cowries,dyschirius,abercromby,attock,aldwych,inflows,absolutist,l'histoire,committeeman,vanbrugh,headstock,westbourne,appenzell,hoxton,oculus,westfalen,roundabouts,nickelback,trovatore,quenching,summarises,conservators,transmutation,talleyrand,barzani,unwillingly,axonal,'blue,opining,enveloping,fidesz,rafah,colborne,flickr,lozenge,dulcimer,ndebele,swaraj,oxidize,gonville,resonated,gilani,superiore,endeared,janakpur,shepperton,solidifying,memoranda,sochaux,kurnool,rewari,emirs,kooning,bruford,unavailability,kayseri,judicious,negating,pterosaur,cytosolic,chernihiv,variational,sabretooth,seawolves,devalued,nanded,adverb,volunteerism,sealers,nemours,smederevo,kashubian,bartin,animax,vicomte,polotsk,polder,archiepiscopal,acceptability,quidditch,tussock,seminaire,immolation,belge,coves,wellingborough,khaganate,mckellen,nayaka,brega,kabhi,pontoons,bascule,newsreels,injectors,cobol,weblog,diplo,biggar,wheatbelt,erythrocytes,pedra,showgrounds,bogdanovich,eclecticism,toluene,elegies,formalize,andromedae,airworthiness,springville,mainframes,overexpression,magadha,bijelo,emlyn,glutamine,accenture,uhuru,metairie,arabidopsis,patanjali,peruvians,berezovsky,accion,astrolabe,jayanti,earnestly,sausalito,recurved,1500s,ramla,incineration,galleons,laplacian,shiki,smethwick,isomerase,dordevic,janow,jeffersonville,internationalism,penciled,styrene,ashur,nucleoside,peristome,horsemanship,sedges,bachata,medes,kristallnacht,schneerson,reflectance,invalided,strutt,draupadi,destino,partridges,tejas,quadrennial,aurel,halych,ethnomusicology,autonomist,radyo,rifting,shi'ar,crvena,telefilm,zawahiri,plana,sultanates,theodorus,subcontractors,pavle,seneschal,teleports,chernivtsi,buccal,brattleboro,stankovic,safar,dunhuang,electrocution,chastised,ergonomic,midsomer,130th,zomba,nongovernmental,escapist,localize,xuzhou,kyrie,carinthian,karlovac,nisan,kramnik,pilipino,digitisation,khasi,andronicus,highwayman,maior,misspelling,sebastopol,socon,rhaetian,archimandrite,partway,positivity,otaku,dingoes,tarski,geopolitics,disciplinarian,zulfikar,kenzo,globose,electrophilic,modele,storekeeper,pohang,wheldon,washers,interconnecting,digraphs,intrastate,campy,helvetic,frontispiece,ferrocarril,anambra,petraeus,midrib,endometrial,dwarfism,mauryan,endocytosis,brigs,percussionists,furtherance,synergistic,apocynaceae,krona,berthier,circumvented,casal,siltstone,precast,ethnikos,realists,geodesy,zarzuela,greenback,tripathi,persevered,interments,neutralization,olbermann,departements,supercomputing,demobilised,cassavetes,dunder,ministering,veszprem,barbarism,'world,pieve,apologist,frentzen,sulfides,firewalls,pronotum,staatsoper,hachette,makhachkala,oberland,phonon,yoshihiro,instars,purnima,winslet,mutsu,ergative,sajid,nizamuddin,paraphrased,ardeidae,kodagu,monooxygenase,skirmishers,sportiva,o'byrne,mykolaiv,ophir,prieta,gyllenhaal,kantian,leche,copan,herero,ps250,gelsenkirchen,shalit,sammarinese,chetwynd,wftda,travertine,warta,sigmaringen,concerti,namespace,ostergotland,biomarker,universals,collegio,embarcadero,wimborne,fiddlers,likening,ransomed,stifled,unabated,kalakaua,khanty,gongs,goodrem,countermeasure,publicizing,geomorphology,swedenborg,undefended,catastrophes,diverts,storyboards,amesbury,contactless,placentia,festivity,authorise,terrane,thallium,stradivarius,antonine,consortia,estimations,consecrate,supergiant,belichick,pendants,butyl,groza,univac,afire,kavala,studi,teletoon,paucity,gonbad,koninklijke,128th,stoichiometric,multimodal,facundo,anatomic,melamine,creuse,altan,brigands,mcguinty,blomfield,tsvangirai,protrusion,lurgan,warminster,tenzin,russellville,discursive,definable,scotrail,lignin,reincorporated,o'dell,outperform,redland,multicolored,evaporates,dimitrie,limbic,patapsco,interlingua,surrogacy,cutty,potrero,masud,cahiers,jintao,ardashir,centaurus,plagiarized,minehead,musings,statuettes,logarithms,seaview,prohibitively,downforce,rivington,tomorrowland,microbiologist,ferric,morag,capsid,kucinich,clairvaux,demotic,seamanship,cicada,painterly,cromarty,carbonic,tupou,oconee,tehuantepec,typecast,anstruther,internalized,underwriters,tetrahedra,flagrant,quakes,pathologies,ulrik,nahal,tarquini,dongguan,parnassus,ryoko,senussi,seleucia,airasia,einer,sashes,d'amico,matriculating,arabesque,honved,biophysical,hardinge,kherson,mommsen,diels,icbms,reshape,brasiliensis,palmach,netaji,oblate,functionalities,grigor,blacksburg,recoilless,melanchthon,reales,astrodome,handcrafted,memes,theorizes,isma'il,aarti,pirin,maatschappij,stabilizes,honiara,ashbury,copts,rootes,defensed,queiroz,mantegna,galesburg,coraciiformesfamily,cabrillo,tokio,antipsychotics,kanon,173rd,apollonia,finial,lydian,hadamard,rangi,dowlatabad,monolingual,platformer,subclasses,chiranjeevi,mirabeau,newsgroup,idmanyurdu,kambojas,walkover,zamoyski,generalist,khedive,flanges,knowle,bande,157th,alleyn,reaffirm,pininfarina,zuckerberg,hakodate,131st,aditi,bellinzona,vaulter,planking,boscombe,colombians,lysis,toppers,metered,nahyan,queensryche,minho,nagercoil,firebrand,foundress,bycatch,mendota,freeform,antena,capitalisation,martinus,overijssel,purists,interventionist,zgierz,burgundians,hippolyta,trompe,umatilla,moroccans,dictionnaire,hydrography,changers,chota,rimouski,aniline,bylaw,grandnephew,neamt,lemnos,connoisseurs,tractive,rearrangements,fetishism,finnic,apalachicola,landowning,calligraphic,circumpolar,mansfeld,legible,orientalism,tannhauser,blamey,maximization,noinclude,blackbirds,angara,ostersund,pancreatitis,glabra,acleris,juried,jungian,triumphantly,singlet,plasmas,synesthesia,yellowhead,unleashes,choiseul,quanzhong,brookville,kaskaskia,igcse,skatepark,jatin,jewellers,scaritinae,techcrunch,tellurium,lachaise,azuma,codeshare,dimensionality,unidirectional,scolaire,macdill,camshafts,unassisted,verband,kahlo,eliya,prelature,chiefdoms,saddleback,sockers,iommi,coloratura,llangollen,biosciences,harshest,maithili,k'iche,plical,multifunctional,andreu,tuskers,confounding,sambre,quarterdeck,ascetics,berdych,transversal,tuolumne,sagami,petrobras,brecker,menxia,instilling,stipulating,korra,oscillate,deadpan,v/line,pyrotechnic,stoneware,prelims,intracoastal,retraining,ilija,berwyn,encrypt,achievers,zulfiqar,glycoproteins,khatib,farmsteads,occultist,saman,fionn,derulo,khilji,obrenovic,argosy,toowong,dementieva,sociocultural,iconostasis,craigslist,festschrift,taifa,intercalated,tanjong,penticton,sharad,marxian,extrapolation,guises,wettin,prabang,exclaiming,kosta,famas,conakry,wanderings,'aliabad,macleay,exoplanet,bancorp,besiegers,surmounting,checkerboard,rajab,vliet,tarek,operable,wargaming,haldimand,fukuyama,uesugi,aggregations,erbil,brachiopods,tokyu,anglais,unfavorably,ujpest,escorial,armagnac,nagara,funafuti,ridgeline,cocking,o'gorman,compactness,retardant,krajowa,barua,coking,bestows,thampi,chicagoland,variably,o'loughlin,minnows,schwa,shaukat,polycarbonate,chlorinated,godalming,gramercy,delved,banqueting,enlil,sarada,prasanna,domhnall,decadal,regressive,lipoprotein,collectable,surendra,zaporizhia,cycliste,suchet,offsetting,formula_65,pudong,d'arte,blyton,quonset,osmania,tientsin,manorama,proteomics,bille,jalpaiguri,pertwee,barnegat,inventiveness,gollancz,euthanized,henricus,shortfalls,wuxia,chlorides,cerrado,polyvinyl,folktale,straddled,bioengineering,eschewing,greendale,recharged,olave,ceylonese,autocephalous,peacebuilding,wrights,guyed,rosamund,abitibi,bannockburn,gerontology,scutari,souness,seagram,codice_9,'open,xhtml,taguig,purposed,darbar,orthopedics,unpopulated,kisumu,tarrytown,feodor,polyhedral,monadnock,gottorp,priam,redesigning,gasworks,elfin,urquiza,homologation,filipovic,bohun,manningham,gornik,soundness,shorea,lanus,gelder,darke,sandgate,criticality,paranaense,153rd,vieja,lithograph,trapezoid,tiebreakers,convalescence,yan'an,actuaries,balad,altimeter,thermoelectric,trailblazer,previn,tenryu,ancaster,endoscopy,nicolet,discloses,fracking,plaine,salado,americanism,placards,absurdist,propylene,breccia,jirga,documenta,ismailis,161st,brentano,dallas/fort,embellishment,calipers,subscribes,mahavidyalaya,wednesbury,barnstormers,miwok,schembechler,minigame,unterberger,dopaminergic,inacio,nizamabad,overridden,monotype,cavernous,stichting,sassafras,sotho,argentinean,myrrh,rapidity,flatts,gowrie,dejected,kasaragod,cyprinidae,interlinked,arcseconds,degeneracy,infamously,incubate,substructure,trigeminal,sectarianism,marshlands,hooliganism,hurlers,isolationist,urania,burrard,switchover,lecco,wilts,interrogator,strived,ballooning,volterra,raciborz,relegating,gilding,cybele,dolomites,parachutist,lochaber,orators,raeburn,backend,benaud,rallycross,facings,banga,nuclides,defencemen,futurity,emitters,yadkin,eudonia,zambales,manasseh,sirte,meshes,peculiarly,mcminnville,roundly,boban,decrypt,icelanders,sanam,chelan,jovian,grudgingly,penalised,subscript,gambrinus,poaceae,infringements,maleficent,runciman,148th,supersymmetry,granites,liskeard,eliciting,involution,hallstatt,kitzbuhel,shankly,sandhills,inefficiencies,yishuv,psychotropic,nightjars,wavell,sangamon,vaikundar,choshu,retrospectives,pitesti,gigantea,hashemi,bosna,gakuin,siochana,arrangers,baronetcies,narayani,temecula,creston,koscierzyna,autochthonous,wyandot,anniston,igreja,mobilise,buzau,dunster,musselburgh,wenzhou,khattak,detoxification,decarboxylase,manlius,campbells,coleoptera,copyist,sympathisers,suisun,eminescu,defensor,transshipment,thurgau,somerton,fluctuates,ambika,weierstrass,lukow,giambattista,volcanics,romanticized,innovated,matabeleland,scotiabank,garwolin,purine,d'auvergne,borderland,maozhen,pricewaterhousecoopers,testator,pallium,scout.com,mv/pi,nazca,curacies,upjohn,sarasvati,monegasque,ketrzyn,malory,spikelets,biomechanics,haciendas,rapped,dwarfed,stews,nijinsky,subjection,matsu,perceptible,schwarzburg,midsection,entertains,circuitous,epiphytic,wonsan,alpini,bluefield,sloths,transportable,braunfels,dictum,szczecinek,jukka,wielun,wejherowo,hucknall,grameen,duodenum,ribose,deshpande,shahar,nexstar,injurious,dereham,lithographer,dhoni,structuralist,progreso,deschutes,christus,pulteney,quoins,yitzchak,gyeongsang,breviary,makkah,chiyoda,jutting,vineland,angiosperms,necrotic,novelisation,redistribute,tirumala,140th,featureless,mafic,rivaling,toyline,2/1st,martius,saalfeld,monthan,texian,kathak,melodramas,mithila,regierungsbezirk,509th,fermenting,schoolmate,virtuosic,briain,kokoda,heliocentric,handpicked,kilwinning,sonically,dinars,kasim,parkways,bogdanov,luxembourgian,halland,avesta,bardic,daugavpils,excavator,qwest,frustrate,physiographic,majoris,'ndrangheta,unrestrained,firmness,montalban,abundances,preservationists,adare,executioners,guardsman,bonnaroo,neglects,nazrul,pro12,hoorn,abercorn,refuting,kabud,cationic,parapsychology,troposphere,venezuelans,malignancy,khoja,unhindered,accordionist,medak,visby,ejercito,laparoscopic,dinas,umayyads,valmiki,o'dowd,saplings,stranding,incisions,illusionist,avocets,buccleuch,amazonia,fourfold,turboprops,roosts,priscus,turnstile,areal,certifies,pocklington,spoofs,viseu,commonalities,dabrowka,annam,homesteaders,daredevils,mondrian,negotiates,fiestas,perennials,maximizes,lubavitch,ravindra,scrapers,finials,kintyre,violas,snoqualmie,wilders,openbsd,mlawa,peritoneal,devarajan,congke,leszno,mercurial,fakir,joannes,bognor,overloading,unbuilt,gurung,scuttle,temperaments,bautzen,jardim,tradesman,visitations,barbet,sagamore,graaff,forecasters,wilsons,assis,l'air,shariah,sochaczew,russa,dirge,biliary,neuve,heartbreakers,strathearn,jacobian,overgrazing,edrich,anticline,parathyroid,petula,lepanto,decius,channelled,parvathi,puppeteers,communicators,francorchamps,kahane,longus,panjang,intron,traite,xxvii,matsuri,amrit,katyn,disheartened,cacak,omonia,alexandrine,partaking,wrangling,adjuvant,haskovo,tendrils,greensand,lammermoor,otherworld,volusia,stabling,one-and-a-half,bresson,zapatista,eotvos,ps150,webisodes,stepchildren,microarray,braganca,quanta,dolne,superoxide,bellona,delineate,ratha,lindenwood,bruhl,cingulate,tallies,bickerton,helgi,bevin,takoma,tsukuba,statuses,changeling,alister,bytom,dibrugarh,magnesia,duplicating,outlier,abated,goncalo,strelitz,shikai,mardan,musculature,ascomycota,springhill,tumuli,gabaa,odenwald,reformatted,autocracy,theresienstadt,suplex,chattopadhyay,mencken,congratulatory,weatherfield,systema,solemnity,projekt,quanzhou,kreuzberg,postbellum,nobuo,mediaworks,finisterre,matchplay,bangladeshis,kothen,oocyte,hovered,aromas,afshar,browed,teases,chorlton,arshad,cesaro,backbencher,iquique,vulcans,padmini,unabridged,cyclase,despotic,kirilenko,achaean,queensberry,debre,octahedron,iphigenia,curbing,karimnagar,sagarmatha,smelters,surrealists,sanada,shrestha,turridae,leasehold,jiedushi,eurythmics,appropriating,correze,thimphu,amery,musicomh,cyborgs,sandwell,pushcart,retorts,ameliorate,deteriorates,stojanovic,spline,entrenchments,bourse,chancellorship,pasolini,lendl,personage,reformulated,pubescens,loiret,metalurh,reinvention,nonhuman,eilema,tarsal,complutense,magne,broadview,metrodome,outtake,stouffville,seinen,bataillon,phosphoric,ostensible,opatow,aristides,beefheart,glorifying,banten,romsey,seamounts,fushimi,prophylaxis,sibylla,ranjith,goslar,balustrades,georgiev,caird,lafitte,peano,canso,bankura,halfpenny,segregate,caisson,bizerte,jamshedpur,euromaidan,philosophie,ridged,cheerfully,reclassification,aemilius,visionaries,samoans,wokingham,chemung,wolof,unbranched,cinerea,bhosle,ourense,immortalised,cornerstones,sourcebook,khufu,archimedean,universitatea,intermolecular,fiscally,suffices,metacomet,adjudicator,stablemate,specks,glace,inowroclaw,patristic,muharram,agitating,ashot,neurologic,didcot,gamla,ilves,putouts,siraj,laski,coaling,diarmuid,ratnagiri,rotulorum,liquefaction,morbihan,harel,aftershock,gruiformesfamily,bonnier,falconiformesfamily,adorns,wikis,maastrichtian,stauffenberg,bishopsgate,fakhr,sevenfold,ponders,quantifying,castiel,opacity,depredations,lenten,gravitated,o'mahony,modulates,inuktitut,paston,kayfabe,vagus,legalised,balked,arianism,tendering,sivas,birthdate,awlaki,khvajeh,shahab,samtgemeinde,bridgeton,amalgamations,biogenesis,recharging,tsukasa,mythbusters,chamfered,enthronement,freelancers,maharana,constantia,sutil,messines,monkton,okanogan,reinvigorated,apoplexy,tanahashi,neues,valiants,harappan,russes,carding,volkoff,funchal,statehouse,imitative,intrepidity,mellotron,samaras,turkana,besting,longitudes,exarch,diarrhoea,transcending,zvonareva,darna,ramblin,disconnection,137th,refocused,diarmait,agricole,ba'athist,turenne,contrabass,communis,daviess,fatimids,frosinone,fittingly,polyphyletic,qanat,theocratic,preclinical,abacha,toorak,marketplaces,conidia,seiya,contraindicated,retford,bundesautobahn,rebuilds,climatology,seaworthy,starfighter,qamar,categoria,malai,hellinsia,newstead,airworthy,catenin,avonmouth,arrhythmias,ayyavazhi,downgrade,ashburnham,ejector,kinematics,petworth,rspca,filmation,accipitridae,chhatrapati,g/mol,bacau,agama,ringtone,yudhoyono,orchestrator,arbitrators,138th,powerplants,cumbernauld,alderley,misamis,hawai`i,cuando,meistriliiga,jermyn,alans,pedigrees,ottavio,approbation,omnium,purulia,prioress,rheinland,lymphoid,lutsk,oscilloscope,ballina,iliac,motorbikes,modernising,uffizi,phylloxera,kalevala,bengalis,amravati,syntheses,interviewers,inflectional,outflank,maryhill,unhurt,profiler,nacelles,heseltine,personalised,guarda,herpetologist,airpark,pigot,margaretha,dinos,peleliu,breakbeat,kastamonu,shaivism,delamere,kingsville,epigram,khlong,phospholipids,journeying,lietuvos,congregated,deviance,celebes,subsoil,stroma,kvitova,lubricating,layoff,alagoas,olafur,doron,interuniversity,raycom,agonopterix,uzice,nanna,springvale,raimundo,wrested,pupal,talat,skinheads,vestige,unpainted,handan,odawara,ammar,attendee,lapped,myotis,gusty,ciconiiformesfamily,traversal,subfield,vitaphone,prensa,hasidism,inwood,carstairs,kropotkin,turgenev,dobra,remittance,purim,tannin,adige,tabulation,lethality,pacha,micronesian,dhruva,defensemen,tibeto,siculus,radioisotope,sodertalje,phitsanulok,euphonium,oxytocin,overhangs,skinks,fabrica,reinterred,emulates,bioscience,paragliding,raekwon,perigee,plausibility,frolunda,erroll,aznar,vyasa,albinus,trevally,confederacion,terse,sixtieth,1530s,kendriya,skateboarders,frontieres,muawiyah,easements,shehu,conservatively,keystones,kasem,brutalist,peekskill,cowry,orcas,syllabary,paltz,elisabetta,denticles,hampering,dolni,eidos,aarau,lermontov,yankton,shahbaz,barrages,kongsvinger,reestablishment,acetyltransferase,zulia,mrnas,slingsby,eucalypt,efficacious,weybridge,gradation,cinematheque,malthus,bampton,coexisted,cisse,hamdi,cupertino,saumarez,chionodes,libertine,formers,sakharov,pseudonymous,vol.1,mcduck,gopalakrishnan,amberley,jorhat,grandmasters,rudiments,dwindle,param,bukidnon,menander,americanus,multipliers,pulawy,homoerotic,pillbox,cd+dvd,epigraph,aleksandrow,extrapolated,horseshoes,contemporain,angiography,hasselt,shawinigan,memorization,legitimized,cyclades,outsold,rodolphe,kelis,powerball,dijkstra,analyzers,incompressible,sambar,orangeburg,osten,reauthorization,adamawa,sphagnum,hypermarket,millipedes,zoroaster,madea,ossuary,murrayfield,pronominal,gautham,resellers,ethers,quarrelled,dolna,stragglers,asami,tangut,passos,educacion,sharaf,texel,berio,bethpage,bezalel,marfa,noronha,36ers,genteel,avram,shilton,compensates,sweetener,reinstalled,disables,noether,1590s,balakrishnan,kotaro,northallerton,cataclysm,gholam,cancellara,schiphol,commends,longinus,albinism,gemayel,hamamatsu,volos,islamism,sidereal,pecuniary,diggings,townsquare,neosho,lushan,chittoor,akhil,disputation,desiccation,cambodians,thwarting,deliberated,ellipsis,bahini,susumu,separators,kohneh,plebeians,kultur,ogaden,pissarro,trypeta,latur,liaodong,vetting,datong,sohail,alchemists,lengthwise,unevenly,masterly,microcontrollers,occupier,deviating,farringdon,baccalaureat,theocracy,chebyshev,archivists,jayaram,ineffectiveness,scandinavians,jacobins,encomienda,nambu,g/cm3,catesby,paavo,heeded,rhodium,idealised,10deg,infective,mecyclothorax,halevy,sheared,minbari,audax,lusatian,rebuffs,hitfix,fastener,subjugate,tarun,binet,compuserve,synthesiser,keisuke,amalric,ligatures,tadashi,ignazio,abramovich,groundnut,otomo,maeve,mortlake,ostrogoths,antillean,todor,recto,millimetre,espousing,inaugurate,paracetamol,galvanic,harpalinae,jedrzejow,reassessment,langlands,civita,mikan,stikine,bijar,imamate,istana,kaiserliche,erastus,federale,cytosine,expansionism,hommes,norrland,smriti,snapdragon,gulab,taleb,lossy,khattab,urbanised,sesto,rekord,diffuser,desam,morganatic,silting,pacts,extender,beauharnais,purley,bouches,halfpipe,discontinuities,houthi,farmville,animism,horni,saadi,interpretative,blockades,symeon,biogeographic,transcaucasian,jetties,landrieu,astrocytes,conjunto,stumpings,weevils,geysers,redux,arching,romanus,tazeh,marcellinus,casein,opava,misrata,anare,sattar,declarer,dreux,oporto,venta,vallis,icosahedron,cortona,lachine,mohammedan,sandnes,zynga,clarin,diomedes,tsuyoshi,pribram,gulbarga,chartist,superettan,boscawen,altus,subang,gating,epistolary,vizianagaram,ogdensburg,panna,thyssen,tarkovsky,dzogchen,biograph,seremban,unscientific,nightjar,legco,deism,n.w.a,sudha,siskel,sassou,flintlock,jovial,montbeliard,pallida,formula_66,tranquillity,nisei,adornment,'people,yamhill,hockeyallsvenskan,adopters,appian,lowicz,haplotypes,succinctly,starogard,presidencies,kheyrabad,sobibor,kinesiology,cowichan,militum,cromwellian,leiningen,ps1.5,concourses,dalarna,goldfield,brzeg,faeces,aquarii,matchless,harvesters,181st,numismatics,korfball,sectioned,transpires,facultative,brandishing,kieron,forages,menai,glutinous,debarge,heathfield,1580s,malang,photoelectric,froome,semiotic,alwar,grammophon,chiaroscuro,mentalist,maramures,flacco,liquors,aleutians,marvell,sutlej,patnaik,qassam,flintoff,bayfield,haeckel,sueno,avicii,exoplanets,hoshi,annibale,vojislav,honeycombs,celebrant,rendsburg,veblen,quails,141st,carronades,savar,narrations,jeeva,ontologies,hedonistic,marinette,godot,munna,bessarabian,outrigger,thame,gravels,hoshino,falsifying,stereochemistry,nacionalista,medially,radula,ejecting,conservatorio,odile,ceiba,jaina,essonne,isometry,allophones,recidivism,iveco,ganda,grammarians,jagan,signposted,uncompressed,facilitators,constancy,ditko,propulsive,impaling,interbank,botolph,amlaib,intergroup,sorbus,cheka,debye,praca,adorning,presbyteries,dormition,strategos,qarase,pentecostals,beehives,hashemite,goldust,euronext,egress,arpanet,soames,jurchens,slovenska,copse,kazim,appraisals,marischal,mineola,sharada,caricaturist,sturluson,galba,faizabad,overwintering,grete,uyezds,didsbury,libreville,ablett,microstructure,anadolu,belenenses,elocution,cloaks,timeslots,halden,rashidun,displaces,sympatric,germanus,tuples,ceska,equalize,disassembly,krautrock,babangida,memel,deild,gopala,hematology,underclass,sangli,wawrinka,assur,toshack,refrains,nicotinic,bhagalpur,badami,racetracks,pocatello,walgreens,nazarbayev,occultation,spinnaker,geneon,josias,hydrolyzed,dzong,corregimiento,waistcoat,thermoplastic,soldered,anticancer,lactobacillus,shafi'i,carabus,adjournment,schlumberger,triceratops,despotate,mendicant,krishnamurti,bahasa,earthworm,lavoisier,noetherian,kalki,fervently,bhawan,saanich,coquille,gannet,motagua,kennels,mineralization,fitzherbert,svein,bifurcated,hairdressing,felis,abounded,dimers,fervour,hebdo,bluffton,aetna,corydon,clevedon,carneiro,subjectively,deutz,gastropoda,overshot,concatenation,varman,carolla,maharshi,mujib,inelastic,riverhead,initialized,safavids,rohini,caguas,bulges,fotbollforbund,hefei,spithead,westville,maronites,lytham,americo,gediminas,stephanus,chalcolithic,hijra,gnu/linux,predilection,rulership,sterility,haidar,scarlatti,saprissa,sviatoslav,pointedly,sunroof,guarantor,thevar,airstrips,pultusk,sture,129th,divinities,daizong,dolichoderus,cobourg,maoists,swordsmanship,uprated,bohme,tashi,largs,chandi,bluebeard,householders,richardsonian,drepanidae,antigonish,elbasan,occultism,marca,hypergeometric,oirat,stiglitz,ignites,dzungar,miquelon,pritam,d'automne,ulidiid,niamey,vallecano,fondo,billiton,incumbencies,raceme,chambery,cadell,barenaked,kagame,summerside,haussmann,hatshepsut,apothecaries,criollo,feint,nasals,timurid,feltham,plotinus,oxygenation,marginata,officinalis,salat,participations,ising,downe,izumo,unguided,pretence,coursed,haruna,viscountcy,mainstage,justicia,powiat,takara,capitoline,implacable,farben,stopford,cosmopterix,tuberous,kronecker,galatians,kweli,dogmas,exhorted,trebinje,skanda,newlyn,ablative,basidia,bhiwani,encroachments,stranglers,regrouping,tubal,shoestring,wawel,anionic,mesenchymal,creationists,pyrophosphate,moshi,despotism,powerbook,fatehpur,rupiah,segre,ternate,jessore,b.i.g,shevardnadze,abounds,gliwice,densest,memoria,suborbital,vietcong,ratepayers,karunanidhi,toolbar,descents,rhymney,exhortation,zahedan,carcinomas,hyperbaric,botvinnik,billets,neuropsychological,tigranes,hoards,chater,biennially,thistles,scotus,wataru,flotillas,hungama,monopolistic,payouts,vetch,generalissimo,caries,naumburg,piran,blizzards,escalates,reactant,shinya,theorize,rizzoli,transitway,ecclesiae,streptomyces,cantal,nisibis,superconductor,unworkable,thallus,roehampton,scheckter,viceroys,makuuchi,ilkley,superseding,takuya,klodzko,borbon,raspberries,operand,w.a.k.o,sarabande,factionalism,egalitarianism,temasek,torbat,unscripted,jorma,westerner,perfective,vrije,underlain,goldfrapp,blaenau,jomon,barthes,drivetime,bassa,bannock,umaga,fengxiang,zulus,sreenivasan,farces,codice_10,freeholder,poddebice,imperialists,deregulated,wingtip,o'hagan,pillared,overtone,hofstadter,149th,kitano,saybrook,standardizing,aldgate,staveley,o'flaherty,hundredths,steerable,soltan,empted,cruyff,intramuros,taluks,cotonou,marae,karur,figueres,barwon,lucullus,niobe,zemlya,lathes,homeported,chaux,amyotrophic,opines,exemplars,bhamo,homomorphisms,gauleiter,ladin,mafiosi,airdrieonians,b/soul,decal,transcaucasia,solti,defecation,deaconess,numidia,sampradaya,normalised,wingless,schwaben,alnus,cinerama,yakutsk,ketchikan,orvieto,unearned,monferrato,rotem,aacsb,loong,decoders,skerries,cardiothoracic,repositioning,pimpernel,yohannan,tenebrionoidea,nargis,nouvel,costliest,interdenominational,noize,redirecting,zither,morcha,radiometric,frequenting,irtysh,gbagbo,chakri,litvinenko,infotainment,ravensbruck,harith,corbels,maegashira,jousting,natan,novus,falcao,minis,railed,decile,rauma,ramaswamy,cavitation,paranaque,berchtesgaden,reanimated,schomberg,polysaccharides,exclusionary,cleon,anurag,ravaging,dhanush,mitchells,granule,contemptuous,keisei,rolleston,atlantean,yorkist,daraa,wapping,micrometer,keeneland,comparably,baranja,oranje,schlafli,yogic,dinajpur,unimpressive,masashi,recreativo,alemannic,petersfield,naoko,vasudeva,autosport,rajat,marella,busko,wethersfield,ssris,soulcalibur,kobani,wildland,rookery,hoffenheim,kauri,aliphatic,balaclava,ferrite,publicise,victorias,theism,quimper,chapbook,functionalist,roadbed,ulyanovsk,cupen,purpurea,calthorpe,teofilo,mousavi,cochlea,linotype,detmold,ellerslie,gakkai,telkom,southsea,subcontractor,inguinal,philatelists,zeebrugge,piave,trochidae,dempo,spoilt,saharanpur,mihrab,parasympathetic,barbarous,chartering,antiqua,katsina,bugis,categorizes,altstadt,kandyan,pambansa,overpasses,miters,assimilating,finlandia,uneconomic,am/fm,harpsichordist,dresdner,luminescence,authentically,overpowers,magmatic,cliftonville,oilfields,skirted,berthe,cuman,oakham,frelimo,glockenspiel,confection,saxophonists,piaseczno,multilevel,antipater,levying,maltreatment,velho,opoczno,harburg,pedophilia,unfunded,palettes,plasterwork,breve,dharmendra,auchinleck,nonesuch,blackmun,libretti,rabbani,145th,hasselbeck,kinnock,malate,vanden,cloverdale,ashgabat,nares,radians,steelworkers,sabor,possums,catterick,hemispheric,ostra,outpaced,dungeness,almshouse,penryn,texians,1000m,franchitti,incumbency,texcoco,newar,tramcars,toroidal,meitetsu,spellbound,agronomist,vinifera,riata,bunko,pinas,ba'al,github,vasilyevich,obsolescent,geodesics,ancestries,tujue,capitalised,unassigned,throng,unpaired,psychometric,skegness,exothermic,buffered,kristiansund,tongued,berenger,basho,alitalia,prolongation,archaeologically,fractionation,cyprinid,echinoderms,agriculturally,justiciar,sonam,ilium,baits,danceable,grazer,ardahan,grassed,preemption,glassworks,hasina,ugric,umbra,wahhabi,vannes,tinnitus,capitaine,tikrit,lisieux,scree,hormuz,despenser,jagiellon,maisonneuve,gandaki,santarem,basilicas,lancing,landskrona,weilburg,fireside,elysian,isleworth,krishnamurthy,filton,cynon,tecmo,subcostal,scalars,triglycerides,hyperplane,farmingdale,unione,meydan,pilings,mercosur,reactivate,akiba,fecundity,jatra,natsume,zarqawi,preta,masao,presbyter,oakenfold,rhodri,ferran,ruizong,cloyne,nelvana,epiphanius,borde,scutes,strictures,troughton,whitestone,sholom,toyah,shingon,kutuzov,abelard,passant,lipno,cafeterias,residuals,anabaptists,paratransit,criollos,pleven,radiata,destabilizing,hadiths,bazaars,mannose,taiyo,crookes,welbeck,baoding,archelaus,nguesso,alberni,wingtips,herts,viasat,lankans,evreux,wigram,fassbinder,ryuichi,storting,reducible,olesnica,znojmo,hyannis,theophanes,flatiron,mustering,rajahmundry,kadir,wayang,prome,lethargy,zubin,illegality,conall,dramedy,beerbohm,hipparchus,ziarat,ryuji,shugo,glenorchy,microarchitecture,morne,lewinsky,cauvery,battenberg,hyksos,wayanad,hamilcar,buhari,brazo,bratianu,solms,aksaray,elamite,chilcotin,bloodstock,sagara,dolny,reunified,umlaut,proteaceae,camborne,calabrian,dhanbad,vaxjo,cookware,potez,rediffusion,semitones,lamentations,allgau,guernica,suntory,pleated,stationing,urgell,gannets,bertelsmann,entryway,raphitomidae,acetaldehyde,nephrology,categorizing,beiyang,permeate,tourney,geosciences,khana,masayuki,crucis,universitaria,slaskie,khaimah,finno,advani,astonishingly,tubulin,vampiric,jeolla,sociale,cleethorpes,badri,muridae,suzong,debater,decimation,kenyans,mutualism,pontifex,middlemen,insee,halevi,lamentation,psychopathy,brassey,wenders,kavya,parabellum,prolactin,inescapable,apses,malignancies,rinzai,stigmatized,menahem,comox,ateliers,welshpool,setif,centimetre,truthfulness,downfield,drusus,woden,glycosylation,emanated,agulhas,dalkeith,jazira,nucky,unifil,jobim,operon,oryzomys,heroically,seances,supernumerary,backhouse,hashanah,tatler,imago,invert,hayato,clockmaker,kingsmill,swiecie,analogously,golconda,poste,tacitly,decentralised,ge'ez,diplomatically,fossiliferous,linseed,mahavira,pedestals,archpriest,byelection,domiciled,jeffersonian,bombus,winegrowing,waukegan,uncultivated,haverfordwest,saumur,communally,disbursed,cleeve,zeljeznicar,speciosa,vacationers,sigur,vaishali,zlatko,iftikhar,cropland,transkei,incompleteness,bohra,subantarctic,slieve,physiologic,similis,klerk,replanted,'right,chafee,reproducible,bayburt,regicide,muzaffarpur,plurals,hanyu,orthologs,diouf,assailed,kamui,tarik,dodecanese,gorne,on/off,179th,shimoga,granaries,carlists,valar,tripolitania,sherds,simmern,dissociated,isambard,polytechnical,yuvraj,brabazon,antisense,pubmed,glans,minutely,masaaki,raghavendra,savoury,podcasting,tachi,bienville,gongsun,ridgely,deform,yuichi,binders,canna,carcetti,llobregat,implored,berri,njegos,intermingled,offload,athenry,motherhouse,corpora,kakinada,dannebrog,imperio,prefaces,musicologists,aerospatiale,shirai,nagapattinam,servius,cristoforo,pomfret,reviled,entebbe,stane,east/west,thermometers,matriarchal,siglo,bodil,legionnaire,ze'ev,theorizing,sangeetha,horticulturist,uncountable,lookalike,anoxic,ionospheric,genealogists,chicopee,imprinting,popish,crematoria,diamondback,cyathea,hanzhong,cameramen,halogaland,naklo,waclaw,storehouses,flexed,comuni,frits,glauca,nilgiris,compresses,nainital,continuations,albay,hypoxic,samajwadi,dunkerque,nanticoke,sarwar,interchanged,jubal,corba,jalgaon,derleth,deathstroke,magny,vinnytsia,hyphenated,rimfire,sawan,boehner,disrepute,normalize,aromanian,dualistic,approximant,chama,karimabad,barnacles,sanok,stipends,dyfed,rijksmuseum,reverberation,suncorp,fungicides,reverie,spectrograph,stereophonic,niazi,ordos,alcan,karaite,lautrec,tableland,lamellar,rieti,langmuir,russula,webern,tweaks,hawick,southerner,morphy,naturalisation,enantiomer,michinoku,barbettes,relieves,carburettors,redruth,oblates,vocabularies,mogilev,bagmati,galium,reasserted,extolled,symon,eurosceptic,inflections,tirtha,recompense,oruro,roping,gouverneur,pared,yayoi,watermills,retooled,leukocytes,jubilant,mazhar,nicolau,manheim,touraine,bedser,hambledon,kohat,powerhouses,tlemcen,reuven,sympathetically,afrikaners,interes,handcrafts,etcher,baddeley,wodonga,amaury,155th,vulgarity,pompadour,automorphisms,1540s,oppositions,prekmurje,deryni,fortifying,arcuate,mahila,bocage,uther,nozze,slashes,atlantica,hadid,rhizomatous,azeris,'with,osmena,lewisville,innervated,bandmaster,outcropping,parallelogram,dominicana,twang,ingushetia,extensional,ladino,sastry,zinoviev,relatable,nobilis,cbeebies,hitless,eulima,sporangia,synge,longlisted,criminalized,penitential,weyden,tubule,volyn,priestesses,glenbrook,kibbutzim,windshaft,canadair,falange,zsolt,bonheur,meine,archangels,safeguarded,jamaicans,malarial,teasers,badging,merseyrail,operands,pulsars,gauchos,biotin,bambara,necaxa,egmond,tillage,coppi,anxiolytic,preah,mausoleums,plautus,feroz,debunked,187th,belediyespor,mujibur,wantage,carboxyl,chettiar,murnau,vagueness,racemic,backstretch,courtland,municipio,palpatine,dezful,hyperbola,sreekumar,chalons,altay,arapahoe,tudors,sapieha,quilon,burdensome,kanya,xxviii,recension,generis,siphuncle,repressor,bitrate,mandals,midhurst,dioxin,democratique,upholds,rodez,cinematographic,epoque,jinping,rabelais,zhytomyr,glenview,rebooted,khalidi,reticulata,122nd,monnaie,passersby,ghazals,europaea,lippmann,earthbound,tadic,andorran,artvin,angelicum,banksy,epicentre,resemblances,shuttled,rathaus,bernt,stonemasons,balochi,siang,tynemouth,cygni,biosynthetic,precipitates,sharecroppers,d'annunzio,softbank,shiji,apeldoorn,polycyclic,wenceslas,wuchang,samnites,tamarack,silmarillion,madinah,palaeontology,kirchberg,sculpin,rohtak,aquabats,oviparous,thynne,caney,blimps,minimalistic,whatcom,palatalization,bardstown,direct3d,paramagnetic,kamboja,khash,globemaster,lengua,matej,chernigov,swanage,arsenals,cascadia,cundinamarca,tusculum,leavers,organics,warplanes,'three,exertions,arminius,gandharva,inquires,comercio,kuopio,chabahar,plotlines,mersenne,anquetil,paralytic,buckminster,ambit,acrolophus,quantifiers,clacton,ciliary,ansaldo,fergana,egoism,thracians,chicoutimi,northbrook,analgesia,brotherhoods,hunza,adriaen,fluoridation,snowfalls,soundboard,fangoria,cannibalistic,orthogonius,chukotka,dindigul,manzoni,chainz,macromedia,beltline,muruga,schistura,provable,litex,initio,pneumoniae,infosys,cerium,boonton,cannonballs,d'une,solvency,mandurah,houthis,dolmens,apologists,radioisotopes,blaxploitation,poroshenko,stawell,coosa,maximilien,tempelhof,espouse,declaratory,hambro,xalapa,outmoded,mihiel,benefitting,desirous,archeparchy,repopulated,telescoping,captor,mackaye,disparaged,ramanathan,crowne,tumbled,technetium,silted,chedi,nievre,hyeon,cartoonish,interlock,infocom,rediff.com,dioramas,timekeeping,concertina,kutaisi,cesky,lubomirski,unapologetic,epigraphic,stalactites,sneha,biofilm,falconry,miraflores,catena,'outstanding,prospekt,apotheosis,o'odham,pacemakers,arabica,gandhinagar,reminisces,iroquoian,ornette,tilling,neoliberalism,chameleons,pandava,prefontaine,haiyan,gneisenau,utama,bando,reconstitution,azaria,canola,paratroops,ayckbourn,manistee,stourton,manifestos,lympne,denouement,tractatus,rakim,bellflower,nanometer,sassanids,turlough,presbyterianism,varmland,20deg,phool,nyerere,almohad,manipal,vlaanderen,quickness,removals,makow,circumflex,eatery,morane,fondazione,alkylation,unenforceable,galliano,silkworm,junior/senior,abducts,phlox,konskie,lofoten,buuren,glyphosate,faired,naturae,cobbles,taher,skrulls,dostoevsky,walkout,wagnerian,orbited,methodically,denzil,sarat,extraterritorial,kohima,d'armor,brinsley,rostropovich,fengtian,comitatus,aravind,moche,wrangell,giscard,vantaa,viljandi,hakoah,seabees,muscatine,ballade,camanachd,sothern,mullioned,durad,margraves,maven,arete,chandni,garifuna,142nd,reading/literature,thickest,intensifies,trygve,khaldun,perinatal,asana,powerline,acetylation,nureyev,omiya,montesquieu,riverwalk,marly,correlating,intermountain,bulgar,hammerheads,underscores,wiretapping,quatrain,ruisseau,newsagent,tuticorin,polygyny,hemsworth,partisanship,banna,istrian,evaporator".split(","),female_names:"mary,patricia,linda,barbara,elizabeth,jennifer,maria,susan,margaret,dorothy,lisa,nancy,karen,betty,helen,sandra,donna,carol,ruth,sharon,michelle,laura,sarah,kimberly,deborah,jessica,shirley,cynthia,angela,melissa,brenda,amy,anna,rebecca,virginia,kathleen,pamela,martha,debra,amanda,stephanie,carolyn,christine,marie,janet,catherine,frances,ann,joyce,diane,alice,julie,heather,teresa,doris,gloria,evelyn,jean,cheryl,mildred,katherine,joan,ashley,judith,rose,janice,kelly,nicole,judy,christina,kathy,theresa,beverly,denise,tammy,irene,jane,lori,rachel,marilyn,andrea,kathryn,louise,sara,anne,jacqueline,wanda,bonnie,julia,ruby,lois,tina,phyllis,norma,paula,diana,annie,lillian,emily,robin,peggy,crystal,gladys,rita,dawn,connie,florence,tracy,edna,tiffany,carmen,rosa,cindy,grace,wendy,victoria,edith,kim,sherry,sylvia,josephine,thelma,shannon,sheila,ethel,ellen,elaine,marjorie,carrie,charlotte,monica,esther,pauline,emma,juanita,anita,rhonda,hazel,amber,eva,debbie,april,leslie,clara,lucille,jamie,joanne,eleanor,valerie,danielle,megan,alicia,suzanne,michele,gail,bertha,darlene,veronica,jill,erin,geraldine,lauren,cathy,joann,lorraine,lynn,sally,regina,erica,beatrice,dolores,bernice,audrey,yvonne,annette,marion,dana,stacy,ana,renee,ida,vivian,roberta,holly,brittany,melanie,loretta,yolanda,jeanette,laurie,katie,kristen,vanessa,alma,sue,elsie,beth,jeanne,vicki,carla,tara,rosemary,eileen,terri,gertrude,lucy,tonya,ella,stacey,wilma,gina,kristin,jessie,natalie,agnes,vera,charlene,bessie,delores,melinda,pearl,arlene,maureen,colleen,allison,tamara,joy,georgia,constance,lillie,claudia,jackie,marcia,tanya,nellie,minnie,marlene,heidi,glenda,lydia,viola,courtney,marian,stella,caroline,dora,vickie,mattie,maxine,irma,mabel,marsha,myrtle,lena,christy,deanna,patsy,hilda,gwendolyn,jennie,nora,margie,nina,cassandra,leah,penny,kay,priscilla,naomi,carole,olga,billie,dianne,tracey,leona,jenny,felicia,sonia,miriam,velma,becky,bobbie,violet,kristina,toni,misty,mae,shelly,daisy,ramona,sherri,erika,katrina,claire,lindsey,lindsay,geneva,guadalupe,belinda,margarita,sheryl,cora,faye,ada,sabrina,isabel,marguerite,hattie,harriet,molly,cecilia,kristi,brandi,blanche,sandy,rosie,joanna,iris,eunice,angie,inez,lynda,madeline,amelia,alberta,genevieve,monique,jodi,janie,kayla,sonya,jan,kristine,candace,fannie,maryann,opal,alison,yvette,melody,luz,susie,olivia,flora,shelley,kristy,mamie,lula,lola,verna,beulah,antoinette,candice,juana,jeannette,pam,kelli,whitney,bridget,karla,celia,latoya,patty,shelia,gayle,della,vicky,lynne,sheri,marianne,kara,jacquelyn,erma,blanca,myra,leticia,pat,krista,roxanne,angelica,robyn,adrienne,rosalie,alexandra,brooke,bethany,sadie,bernadette,traci,jody,kendra,nichole,rachael,mable,ernestine,muriel,marcella,elena,krystal,angelina,nadine,kari,estelle,dianna,paulette,lora,mona,doreen,rosemarie,desiree,antonia,janis,betsy,christie,freda,meredith,lynette,teri,cristina,eula,leigh,meghan,sophia,eloise,rochelle,gretchen,cecelia,raquel,henrietta,alyssa,jana,gwen,jenna,tricia,laverne,olive,tasha,silvia,elvira,delia,kate,patti,lorena,kellie,sonja,lila,lana,darla,mindy,essie,mandy,lorene,elsa,josefina,jeannie,miranda,dixie,lucia,marta,faith,lela,johanna,shari,camille,tami,shawna,elisa,ebony,melba,ora,nettie,tabitha,ollie,winifred,kristie,alisha,aimee,rena,myrna,marla,tammie,latasha,bonita,patrice,ronda,sherrie,addie,francine,deloris,stacie,adriana,cheri,abigail,celeste,jewel,cara,adele,rebekah,lucinda,dorthy,effie,trina,reba,sallie,aurora,lenora,etta,lottie,kerri,trisha,nikki,estella,francisca,josie,tracie,marissa,karin,brittney,janelle,lourdes,laurel,helene,fern,elva,corinne,kelsey,ina,bettie,elisabeth,aida,caitlin,ingrid,iva,eugenia,christa,goldie,maude,jenifer,therese,dena,lorna,janette,latonya,candy,consuelo,tamika,rosetta,debora,cherie,polly,dina,jewell,fay,jillian,dorothea,nell,trudy,esperanza,patrica,kimberley,shanna,helena,cleo,stefanie,rosario,ola,janine,mollie,lupe,alisa,lou,maribel,susanne,bette,susana,elise,cecile,isabelle,lesley,jocelyn,paige,joni,rachelle,leola,daphne,alta,ester,petra,graciela,imogene,jolene,keisha,lacey,glenna,gabriela,keri,ursula,lizzie,kirsten,shana,adeline,mayra,jayne,jaclyn,gracie,sondra,carmela,marisa,rosalind,charity,tonia,beatriz,marisol,clarice,jeanine,sheena,angeline,frieda,lily,shauna,millie,claudette,cathleen,angelia,gabrielle,autumn,katharine,jodie,staci,lea,christi,justine,elma,luella,margret,dominique,socorro,martina,margo,mavis,callie,bobbi,maritza,lucile,leanne,jeannine,deana,aileen,lorie,ladonna,willa,manuela,gale,selma,dolly,sybil,abby,ivy,dee,winnie,marcy,luisa,jeri,magdalena,ofelia,meagan,audra,matilda,leila,cornelia,bianca,simone,bettye,randi,virgie,latisha,barbra,georgina,eliza,leann,bridgette,rhoda,haley,adela,nola,bernadine,flossie,ila,greta,ruthie,nelda,minerva,lilly,terrie,letha,hilary,estela,valarie,brianna,rosalyn,earline,catalina,ava,mia,clarissa,lidia,corrine,alexandria,concepcion,tia,sharron,rae,dona,ericka,jami,elnora,chandra,lenore,neva,marylou,melisa,tabatha,serena,avis,allie,sofia,jeanie,odessa,nannie,harriett,loraine,penelope,milagros,emilia,benita,allyson,ashlee,tania,esmeralda,eve,pearlie,zelma,malinda,noreen,tameka,saundra,hillary,amie,althea,rosalinda,lilia,alana,clare,alejandra,elinor,lorrie,jerri,darcy,earnestine,carmella,noemi,marcie,liza,annabelle,louisa,earlene,mallory,carlene,nita,selena,tanisha,katy,julianne,lakisha,edwina,maricela,margery,kenya,dollie,roxie,roslyn,kathrine,nanette,charmaine,lavonne,ilene,tammi,suzette,corine,kaye,chrystal,lina,deanne,lilian,juliana,aline,luann,kasey,maryanne,evangeline,colette,melva,lawanda,yesenia,nadia,madge,kathie,ophelia,valeria,nona,mitzi,mari,georgette,claudine,fran,alissa,roseann,lakeisha,susanna,reva,deidre,chasity,sheree,elvia,alyce,deirdre,gena,briana,araceli,katelyn,rosanne,wendi,tessa,berta,marva,imelda,marietta,marci,leonor,arline,sasha,madelyn,janna,juliette,deena,aurelia,josefa,augusta,liliana,lessie,amalia,savannah,anastasia,vilma,natalia,rosella,lynnette,corina,alfreda,leanna,amparo,coleen,tamra,aisha,wilda,karyn,maura,mai,evangelina,rosanna,hallie,erna,enid,mariana,lacy,juliet,jacklyn,freida,madeleine,mara,cathryn,lelia,casandra,bridgett,angelita,jannie,dionne,annmarie,katina,beryl,millicent,katheryn,diann,carissa,maryellen,liz,lauri,helga,gilda,rhea,marquita,hollie,tisha,tamera,angelique,francesca,kaitlin,lolita,florine,rowena,reyna,twila,fanny,janell,ines,concetta,bertie,alba,brigitte,alyson,vonda,pansy,elba,noelle,letitia,deann,brandie,louella,leta,felecia,sharlene,lesa,beverley,isabella,herminia,terra,celina,tori,octavia,jade,denice,germaine,michell,cortney,nelly,doretha,deidra,monika,lashonda,judi,chelsey,antionette,margot,adelaide,leeann,elisha,dessie,libby,kathi,gayla,latanya,mina,mellisa,kimberlee,jasmin,renae,zelda,elda,justina,gussie,emilie,camilla,abbie,rocio,kaitlyn,edythe,ashleigh,selina,lakesha,geri,allene,pamala,michaela,dayna,caryn,rosalia,jacquline,rebeca,marybeth,krystle,iola,dottie,belle,griselda,ernestina,elida,adrianne,demetria,delma,jaqueline,arleen,virgina,retha,fatima,tillie,eleanore,cari,treva,wilhelmina,rosalee,maurine,latrice,jena,taryn,elia,debby,maudie,jeanna,delilah,catrina,shonda,hortencia,theodora,teresita,robbin,danette,delphine,brianne,nilda,danna,cindi,bess,iona,winona,vida,rosita,marianna,racheal,guillermina,eloisa,celestine,caren,malissa,lona,chantel,shellie,marisela,leora,agatha,soledad,migdalia,ivette,christen,athena,janel,veda,pattie,tessie,tera,marilynn,lucretia,karrie,dinah,daniela,alecia,adelina,vernice,shiela,portia,merry,lashawn,dara,tawana,verda,alene,zella,sandi,rafaela,maya,kira,candida,alvina,suzan,shayla,lettie,samatha,oralia,matilde,larissa,vesta,renita,delois,shanda,phillis,lorri,erlinda,cathrine,barb,isabell,ione,gisela,roxanna,mayme,kisha,ellie,mellissa,dorris,dalia,bella,annetta,zoila,reta,reina,lauretta,kylie,christal,pilar,charla,elissa,tiffani,tana,paulina,leota,breanna,jayme,carmel,vernell,tomasa,mandi,dominga,santa,melodie,lura,alexa,tamela,mirna,kerrie,venus,felicita,cristy,carmelita,berniece,annemarie,tiara,roseanne,missy,cori,roxana,pricilla,kristal,jung,elyse,haydee,aletha,bettina,marge,gillian,filomena,zenaida,harriette,caridad,vada,aretha,pearline,marjory,marcela,flor,evette,elouise,alina,damaris,catharine,belva,nakia,marlena,luanne,lorine,karon,dorene,danita,brenna,tatiana,louann,julianna,andria,philomena,lucila,leonora,dovie,romona,mimi,jacquelin,gaye,tonja,misti,chastity,stacia,roxann,micaela,velda,marlys,johnna,aura,ivonne,hayley,nicki,majorie,herlinda,yadira,perla,gregoria,antonette,shelli,mozelle,mariah,joelle,cordelia,josette,chiquita,trista,laquita,georgiana,candi,shanon,hildegard,stephany,magda,karol,gabriella,tiana,roma,richelle,oleta,jacque,idella,alaina,suzanna,jovita,tosha,nereida,marlyn,kyla,delfina,tena,stephenie,sabina,nathalie,marcelle,gertie,darleen,thea,sharonda,shantel,belen,venessa,rosalina,genoveva,clementine,rosalba,renate,renata,georgianna,floy,dorcas,ariana,tyra,theda,mariam,juli,jesica,vikki,verla,roselyn,melvina,jannette,ginny,debrah,corrie,violeta,myrtis,latricia,collette,charleen,anissa,viviana,twyla,nedra,latonia,hellen,fabiola,annamarie,adell,sharyn,chantal,niki,maud,lizette,lindy,kesha,jeana,danelle,charline,chanel,valorie,dortha,cristal,sunny,leone,leilani,gerri,debi,andra,keshia,eulalia,easter,dulce,natividad,linnie,kami,georgie,catina,brook,alda,winnifred,sharla,ruthann,meaghan,magdalene,lissette,adelaida,venita,trena,shirlene,shameka,elizebeth,dian,shanta,latosha,carlotta,windy,rosina,mariann,leisa,jonnie,dawna,cathie,astrid,laureen,janeen,holli,fawn,vickey,teressa,shante,rubye,marcelina,chanda,terese,scarlett,marnie,lulu,lisette,jeniffer,elenor,dorinda,donita,carman,bernita,altagracia,aleta,adrianna,zoraida,lyndsey,janina,starla,phylis,phuong,kyra,charisse,blanch,sanjuanita,rona,nanci,marilee,maranda,brigette,sanjuana,marita,kassandra,joycelyn,felipa,chelsie,bonny,mireya,lorenza,kyong,ileana,candelaria,sherie,lucie,leatrice,lakeshia,gerda,edie,bambi,marylin,lavon,hortense,garnet,evie,tressa,shayna,lavina,kyung,jeanetta,sherrill,shara,phyliss,mittie,anabel,alesia,thuy,tawanda,joanie,tiffanie,lashanda,karissa,enriqueta,daria,daniella,corinna,alanna,abbey,roxane,roseanna,magnolia,lida,joellen,coral,carleen,tresa,peggie,novella,nila,maybelle,jenelle,carina,nova,melina,marquerite,margarette,josephina,evonne,cinthia,albina,toya,tawnya,sherita,myriam,lizabeth,lise,keely,jenni,giselle,cheryle,ardith,ardis,alesha,adriane,shaina,linnea,karolyn,felisha,dori,darci,artie,armida,zola,xiomara,vergie,shamika,nena,nannette,maxie,lovie,jeane,jaimie,inge,farrah,elaina,caitlyn,felicitas,cherly,caryl,yolonda,yasmin,teena,prudence,pennie,nydia,mackenzie,orpha,marvel,lizbeth,laurette,jerrie,hermelinda,carolee,tierra,mirian,meta,melony,kori,jennette,jamila,yoshiko,susannah,salina,rhiannon,joleen,cristine,ashton,aracely,tomeka,shalonda,marti,lacie,kala,jada,ilse,hailey,brittani,zona,syble,sherryl,nidia,marlo,kandice,kandi,alycia,ronna,norene,mercy,ingeborg,giovanna,gemma,christel,audry,zora,vita,trish,stephaine,shirlee,shanika,melonie,mazie,jazmin,inga,hettie,geralyn,fonda,estrella,adella,sarita,rina,milissa,maribeth,golda,evon,ethelyn,enedina,cherise,chana,velva,tawanna,sade,mirta,karie,jacinta,elna,davina,cierra,ashlie,albertha,tanesha,nelle,mindi,lorinda,larue,florene,demetra,dedra,ciara,chantelle,ashly,suzy,rosalva,noelia,lyda,leatha,krystyna,kristan,karri,darline,darcie,cinda,cherrie,awilda,almeda,rolanda,lanette,jerilyn,gisele,evalyn,cyndi,cleta,carin,zina,zena,velia,tanika,charissa,talia,margarete,lavonda,kaylee,kathlene,jonna,irena,ilona,idalia,candis,candance,brandee,anitra,alida,sigrid,nicolette,maryjo,linette,hedwig,christiana,alexia,tressie,modesta,lupita,lita,gladis,evelia,davida,cherri,cecily,ashely,annabel,agustina,wanita,shirly,rosaura,hulda,yetta,verona,thomasina,sibyl,shannan,mechelle,leandra,lani,kylee,kandy,jolynn,ferne,eboni,corene,alysia,zula,nada,moira,lyndsay,lorretta,jammie,hortensia,gaynell,adria,vina,vicenta,tangela,stephine,norine,nella,liana,leslee,kimberely,iliana,glory,felica,emogene,elfriede,eden,eartha,carma,ocie,lennie,kiara,jacalyn,carlota,arielle,otilia,kirstin,kacey,johnetta,joetta,jeraldine,jaunita,elana,dorthea,cami,amada,adelia,vernita,tamar,siobhan,renea,rashida,ouida,nilsa,meryl,kristyn,julieta,danica,breanne,aurea,anglea,sherron,odette,malia,lorelei,leesa,kenna,kathlyn,fiona,charlette,suzie,shantell,sabra,racquel,myong,mira,martine,lucienne,lavada,juliann,elvera,delphia,christiane,charolette,carri,asha,angella,paola,ninfa,leda,stefani,shanell,palma,machelle,lissa,kecia,kathryne,karlene,julissa,jettie,jenniffer,corrina,carolann,alena,rosaria,myrtice,marylee,liane,kenyatta,judie,janey,elmira,eldora,denna,cristi,cathi,zaida,vonnie,viva,vernie,rosaline,mariela,luciana,lesli,karan,felice,deneen,adina,wynona,tarsha,sheron,shanita,shani,shandra,randa,pinkie,nelida,marilou,lyla,laurene,laci,janene,dorotha,daniele,dani,carolynn,carlyn,berenice,ayesha,anneliese,alethea,thersa,tamiko,rufina,oliva,mozell,marylyn,kristian,kathyrn,kasandra,kandace,janae,domenica,debbra,dannielle,chun,arcelia,zenobia,sharen,sharee,lavinia,kacie,jackeline,huong,felisa,emelia,eleanora,cythia,cristin,claribel,anastacia,zulma,zandra,yoko,tenisha,susann,sherilyn,shay,shawanda,romana,mathilda,linsey,keiko,joana,isela,gretta,georgetta,eugenie,desirae,delora,corazon,antonina,anika,willene,tracee,tamatha,nichelle,mickie,maegan,luana,lanita,kelsie,edelmira,bree,afton,teodora,tamie,shena,linh,keli,kaci,danyelle,arlette,albertine,adelle,tiffiny,simona,nicolasa,nichol,nakisha,maira,loreen,kizzy,fallon,christene,bobbye,ying,vincenza,tanja,rubie,roni,queenie,margarett,kimberli,irmgard,idell,hilma,evelina,esta,emilee,dennise,dania,carie,risa,rikki,particia,masako,luvenia,loree,loni,lien,gigi,florencia,denita,billye,tomika,sharita,rana,nikole,neoma,margarite,madalyn,lucina,laila,kali,jenette,gabriele,evelyne,elenora,clementina,alejandrina,zulema,violette,vannessa,thresa,retta,patience,noella,nickie,jonell,chaya,camelia,bethel,anya,suzann,mila,lilla,laverna,keesha,kattie,georgene,eveline,estell,elizbeth,vivienne,vallie,trudie,stephane,magaly,madie,kenyetta,karren,janetta,hermine,drucilla,debbi,celestina,candie,britni,beckie,amina,zita,yolande,vivien,vernetta,trudi,pearle,patrina,ossie,nicolle,loyce,letty,katharina,joselyn,jonelle,jenell,iesha,heide,florinda,florentina,elodia,dorine,brunilda,brigid,ashli,ardella,twana,tarah,shavon,serina,rayna,ramonita,margurite,lucrecia,kourtney,kati,jesenia,crista,ayana,alica,alia,vinnie,suellen,romelia,rachell,olympia,michiko,kathaleen,jolie,jessi,janessa,hana,elease,carletta,britany,shona,salome,rosamond,regena,raina,ngoc,nelia,louvenia,lesia,latrina,laticia,larhonda,jina,jacki,emmy,deeann,coretta,arnetta,thalia,shanice,neta,mikki,micki,lonna,leana,lashunda,kiley,joye,jacqulyn,ignacia,hyun,hiroko,henriette,elayne,delinda,dahlia,coreen,consuela,conchita,babette,ayanna,anette,albertina,shawnee,shaneka,quiana,pamelia,merri,merlene,margit,kiesha,kiera,kaylene,jodee,jenise,erlene,emmie,dalila,daisey,casie,belia,babara,versie,vanesa,shelba,shawnda,nikia,naoma,marna,margeret,madaline,lawana,kindra,jutta,jazmine,janett,hannelore,glendora,gertrud,garnett,freeda,frederica,florance,flavia,carline,beverlee,anjanette,valda,tamala,shonna,sarina,oneida,merilyn,marleen,lurline,lenna,katherin,jeni,gracia,glady,farah,enola,dominque,devona,delana,cecila,caprice,alysha,alethia,vena,theresia,tawny,shakira,samara,sachiko,rachele,pamella,marni,mariel,maren,malisa,ligia,lera,latoria,larae,kimber,kathern,karey,jennefer,janeth,halina,fredia,delisa,debroah,ciera,angelika,andree,altha,vivan,terresa,tanna,sudie,signe,salena,ronni,rebbecca,myrtie,malika,maida,leonarda,kayleigh,ethyl,ellyn,dayle,cammie,brittni,birgit,avelina,asuncion,arianna,akiko,venice,tyesha,tonie,tiesha,takisha,steffanie,sindy,meghann,manda,macie,kellye,kellee,joslyn,inger,indira,glinda,glennis,fernanda,faustina,eneida,elicia,digna,dell,arletta,willia,tammara,tabetha,sherrell,sari,rebbeca,pauletta,natosha,nakita,mammie,kenisha,kazuko,kassie,earlean,daphine,corliss,clotilde,carolyne,bernetta,augustina,audrea,annis,annabell,tennille,tamica,selene,rosana,regenia,qiana,markita,macy,leeanne,laurine,jessenia,janita,georgine,genie,emiko,elvie,deandra,dagmar,corie,collen,cherish,romaine,porsha,pearlene,micheline,merna,margorie,margaretta,lore,jenine,hermina,fredericka,elke,drusilla,dorathy,dione,celena,brigida,allegra,tamekia,synthia,sook,slyvia,rosann,reatha,raye,marquetta,margart,ling,layla,kymberly,kiana,kayleen,katlyn,karmen,joella,emelda,eleni,detra,clemmie,cheryll,chantell,cathey,arnita,arla,angle,angelic,alyse,zofia,thomasine,tennie,sherly,sherley,sharyl,remedios,petrina,nickole,myung,myrle,mozella,louanne,lisha,latia,krysta,julienne,jeanene,jacqualine,isaura,gwenda,earleen,cleopatra,carlie,audie,antonietta,alise,verdell,tomoko,thao,talisha,shemika,savanna,santina,rosia,raeann,odilia,nana,minna,magan,lynelle,karma,joeann,ivana,inell,ilana,gudrun,dreama,crissy,chante,carmelina,arvilla,annamae,alvera,aleida,yanira,vanda,tianna,stefania,shira,nicol,nancie,monserrate,melynda,melany,lovella,laure,kacy,jacquelynn,hyon,gertha,eliana,christena,christeen,charise,caterina,carley,candyce,arlena,ammie,willette,vanita,tuyet,syreeta,penney,nyla,maryam,marya,magen,ludie,loma,livia,lanell,kimberlie,julee,donetta,diedra,denisha,deane,dawne,clarine,cherryl,bronwyn,alla,valery,tonda,sueann,soraya,shoshana,shela,sharleen,shanelle,nerissa,meridith,mellie,maye,maple,magaret,lili,leonila,leonie,leeanna,lavonia,lavera,kristel,kathey,kathe,jann,ilda,hildred,hildegarde,genia,fumiko,evelin,ermelinda,elly,dung,doloris,dionna,danae,berneice,annice,alix,verena,verdie,shawnna,shawana,shaunna,rozella,randee,ranae,milagro,lynell,luise,loida,lisbeth,karleen,junita,jona,isis,hyacinth,hedy,gwenn,ethelene,erline,donya,domonique,delicia,dannette,cicely,branda,blythe,bethann,ashlyn,annalee,alline,yuko,vella,trang,towanda,tesha,sherlyn,narcisa,miguelina,meri,maybell,marlana,marguerita,madlyn,lory,loriann,leonore,leighann,laurice,latesha,laronda,katrice,kasie,kaley,jadwiga,glennie,gearldine,francina,epifania,dyan,dorie,diedre,denese,demetrice,delena,cristie,cleora,catarina,carisa,barbera,almeta,trula,tereasa,solange,sheilah,shavonne,sanora,rochell,mathilde,margareta,maia,lynsey,lawanna,launa,kena,keena,katia,glynda,gaylene,elvina,elanor,danuta,danika,cristen,cordie,coletta,clarita,carmon,brynn,azucena,aundrea,angele,verlie,verlene,tamesha,silvana,sebrina,samira,reda,raylene,penni,norah,noma,mireille,melissia,maryalice,laraine,kimbery,karyl,karine,jolanda,johana,jesusa,jaleesa,jacquelyne,iluminada,hilaria,hanh,gennie,francie,floretta,exie,edda,drema,delpha,barbar,assunta,ardell,annalisa,alisia,yukiko,yolando,wonda,waltraud,veta,temeka,tameika,shirleen,shenita,piedad,ozella,mirtha,marilu,kimiko,juliane,jenice,janay,jacquiline,hilde,elois,echo,devorah,chau,brinda,betsey,arminda,aracelis,apryl,annett,alishia,veola,usha,toshiko,theola,tashia,talitha,shery,renetta,reiko,rasheeda,obdulia,mika,melaine,meggan,marlen,marget,marceline,mana,magdalen,librada,lezlie,latashia,lasandra,kelle,isidra,inocencia,gwyn,francoise,erminia,erinn,dimple,devora,criselda,armanda,arie,ariane,angelena,aliza,adriene,adaline,xochitl,twanna,tomiko,tamisha,taisha,susy,rutha,rhona,noriko,natashia,merrie,marinda,mariko,margert,loris,lizzette,leisha,kaila,joannie,jerrica,jene,jannet,janee,jacinda,herta,elenore,doretta,delaine,daniell,claudie,britta,apolonia,amberly,alease,yuri,waneta,tomi,sharri,sandie,roselle,reynalda,raguel,phylicia,patria,olimpia,odelia,mitzie,minda,mignon,mica,mendy,marivel,maile,lynetta,lavette,lauryn,latrisha,lakiesha,kiersten,kary,josphine,jolyn,jetta,janise,jacquie,ivelisse,glynis,gianna,gaynelle,danyell,danille,dacia,coralee,cher,ceola,arianne,aleshia,yung,williemae,trinh,thora,sherika,shemeka,shaunda,roseline,ricki,melda,mallie,lavonna,latina,laquanda,lala,lachelle,klara,kandis,johna,jeanmarie,jaye,grayce,gertude,emerita,ebonie,clorinda,ching,chery,carola,breann,blossom,bernardine,becki,arletha,argelia,alita,yulanda,yessenia,tobi,tasia,sylvie,shirl,shirely,shella,shantelle,sacha,rebecka,providencia,paulene,misha,miki,marline,marica,lorita,latoyia,lasonya,kerstin,kenda,keitha,kathrin,jaymie,gricelda,ginette,eryn,elina,elfrieda,danyel,cheree,chanelle,barrie,aurore,annamaria,alleen,ailene,aide,yasmine,vashti,treasa,tiffaney,sheryll,sharie,shanae,raisa,neda,mitsuko,mirella,milda,maryanna,maragret,mabelle,luetta,lorina,letisha,latarsha,lanelle,lajuana,krissy,karly,karena,jessika,jerica,jeanelle,jalisa,jacelyn,izola,euna,etha,domitila,dominica,daina,creola,carli,camie,brittny,ashanti,anisha,aleen,adah,yasuko,valrie,tona,tinisha,terisa,taneka,simonne,shalanda,serita,ressie,refugia,olene,margherita,mandie,maire,lyndia,luci,lorriane,loreta,leonia,lavona,lashawnda,lakia,kyoko,krystina,krysten,kenia,kelsi,jeanice,isobel,georgiann,genny,felicidad,eilene,deloise,deedee,conception,clora,cherilyn,calandra,armandina,anisa,tiera,theressa,stephania,sima,shyla,shonta,shera,shaquita,shala,rossana,nohemi,nery,moriah,melita,melida,melani,marylynn,marisha,mariette,malorie,madelene,ludivina,loria,lorette,loralee,lianne,lavenia,laurinda,lashon,kimi,keila,katelynn,jone,joane,jayna,janella,hertha,francene,elinore,despina,delsie,deedra,clemencia,carolin,bulah,brittanie,blondell,bibi,beaulah,beata,annita,agripina,virgen,valene,twanda,tommye,tarra,tari,tammera,shakia,sadye,ruthanne,rochel,rivka,pura,nenita,natisha,ming,merrilee,melodee,marvis,lucilla,leena,laveta,larita,lanie,keren,ileen,georgeann,genna,frida,eufemia,emely,edyth,deonna,deadra,darlena,chanell,cathern,cassondra,cassaundra,bernarda,berna,arlinda,anamaria,vertie,valeri,torri,stasia,sherise,sherill,sanda,ruthe,rosy,robbi,ranee,quyen,pearly,palmira,onita,nisha,niesha,nida,merlyn,mayola,marylouise,marth,margene,madelaine,londa,leontine,leoma,leia,lauralee,lanora,lakita,kiyoko,keturah,katelin,kareen,jonie,johnette,jenee,jeanett,izetta,hiedi,heike,hassie,giuseppina,georgann,fidela,fernande,elwanda,ellamae,eliz,dusti,dotty,cyndy,coralie,celesta,alverta,xenia,wava,vanetta,torrie,tashina,tandy,tambra,tama,stepanie,shila,shaunta,sharan,shaniqua,shae,setsuko,serafina,sandee,rosamaria,priscila,olinda,nadene,muoi,michelina,mercedez,maryrose,marcene,magali,mafalda,lannie,kayce,karoline,kamilah,kamala,justa,joline,jennine,jacquetta,iraida,georgeanna,franchesca,emeline,elane,ehtel,earlie,dulcie,dalene,classie,chere,charis,caroyln,carmina,carita,bethanie,ayako,arica,alysa,alessandra,akilah,adrien,zetta,youlanda,yelena,yahaira,xuan,wendolyn,tijuana,terina,teresia,suzi,sherell,shavonda,shaunte,sharda,shakita,sena,ryann,rubi,riva,reginia,rachal,parthenia,pamula,monnie,monet,michaele,melia,malka,maisha,lisandra,lekisha,lean,lakendra,krystin,kortney,kizzie,kittie,kera,kendal,kemberly,kanisha,julene,jule,johanne,jamee,halley,gidget,fredricka,fleta,fatimah,eusebia,elza,eleonore,dorthey,doria,donella,dinorah,delorse,claretha,christinia,charlyn,bong,belkis,azzie,andera,aiko,adena,yajaira,vania,ulrike,toshia,tifany,stefany,shizue,shenika,shawanna,sharolyn,sharilyn,shaquana,shantay,rozanne,roselee,remona,reanna,raelene,phung,petronila,natacha,nancey,myrl,miyoko,miesha,merideth,marvella,marquitta,marhta,marchelle,lizeth,libbie,lahoma,ladawn,kina,katheleen,katharyn,karisa,kaleigh,junie,julieann,johnsie,janean,jaimee,jackqueline,hisako,herma,helaine,gwyneth,gita,eustolia,emelina,elin,edris,donnette,donnetta,dierdre,denae,darcel,clarisa,cinderella,chia,charlesetta,charita,celsa,cassy,cassi,carlee,bruna,brittaney,brande,billi,antonetta,angla,angelyn,analisa,alane,wenona,wendie,veronique,vannesa,tobie,tempie,sumiko,sulema,somer,sheba,sharice,shanel,shalon,rosio,roselia,renay,rema,reena,ozie,oretha,oralee,ngan,nakesha,milly,marybelle,margrett,maragaret,manie,lurlene,lillia,lieselotte,lavelle,lashaunda,lakeesha,kaycee,kalyn,joya,joette,jenae,janiece,illa,grisel,glayds,genevie,gala,fredda,eleonor,debera,deandrea,corrinne,cordia,contessa,colene,cleotilde,chantay,cecille,beatris,azalee,arlean,ardath,anjelica,anja,alfredia,aleisha,zada,yuonne,xiao,willodean,vennie,vanna,tyisha,tova,torie,tonisha,tilda,tien,sirena,sherril,shanti,shan,senaida,samella,robbyn,renda,reita,phebe,paulita,nobuko,nguyet,neomi,mikaela,melania,maximina,marg,maisie,lynna,lilli,lashaun,lakenya,lael,kirstie,kathline,kasha,karlyn,karima,jovan,josefine,jennell,jacqui,jackelyn,hien,grazyna,florrie,floria,eleonora,dwana,dorla,delmy,deja,dede,dann,crysta,clelia,claris,chieko,cherlyn,cherelle,charmain,chara,cammy,arnette,ardelle,annika,amiee,amee,allena,yvone,yuki,yoshie,yevette,yael,willetta,voncile,venetta,tula,tonette,timika,temika,telma,teisha,taren,stacee,shawnta,saturnina,ricarda,pasty,onie,nubia,marielle,mariella,marianela,mardell,luanna,loise,lisabeth,lindsy,lilliana,lilliam,lelah,leigha,leanora,kristeen,khalilah,keeley,kandra,junko,joaquina,jerlene,jani,jamika,hsiu,hermila,genevive,evia,eugena,emmaline,elfreda,elene,donette,delcie,deeanna,darcey,clarinda,cira,chae,celinda,catheryn,casimira,carmelia,camellia,breana,bobette,bernardina,bebe,basilia,arlyne,amal,alayna,zonia,zenia,yuriko,yaeko,wynell,willena,vernia,tora,terrilyn,terica,tenesha,tawna,tajuana,taina,stephnie,sona,sina,shondra,shizuko,sherlene,sherice,sharika,rossie,rosena,rima,rheba,renna,natalya,nancee,melodi,meda,matha,marketta,maricruz,marcelene,malvina,luba,louetta,leida,lecia,lauran,lashawna,laine,khadijah,katerine,kasi,kallie,julietta,jesusita,jestine,jessia,jeffie,janyce,isadora,georgianne,fidelia,evita,eura,eulah,estefana,elsy,eladia,dodie,denisse,deloras,delila,daysi,crystle,concha,claretta,charlsie,charlena,carylon,bettyann,asley,ashlea,amira,agueda,agnus,yuette,vinita,victorina,tynisha,treena,toccara,tish,thomasena,tegan,soila,shenna,sharmaine,shantae,shandi,saran,sarai,sana,rosette,rolande,regine,otelia,olevia,nicholle,necole,naida,myrta,myesha,mitsue,minta,mertie,margy,mahalia,madalene,loura,lorean,lesha,leonida,lenita,lavone,lashell,lashandra,lamonica,kimbra,katherina,karry,kanesha,jong,jeneva,jaquelyn,gilma,ghislaine,gertrudis,fransisca,fermina,ettie,etsuko,ellan,elidia,edra,dorethea,doreatha,denyse,deetta,daine,cyrstal,corrin,cayla,carlita,camila,burma,bula,buena,barabara,avril,alaine,zana,wilhemina,wanetta,verline,vasiliki,tonita,tisa,teofila,tayna,taunya,tandra,takako,sunni,suanne,sixta,sharell,seema,rosenda,robena,raymonde,pamila,ozell,neida,mistie,micha,merissa,maurita,maryln,maryetta,marcell,malena,makeda,lovetta,lourie,lorrine,lorilee,laurena,lashay,larraine,laree,lacresha,kristle,keva,keira,karole,joie,jinny,jeannetta,jama,heidy,gilberte,gema,faviola,evelynn,enda,elli,ellena,divina,dagny,collene,codi,cindie,chassidy,chasidy,catrice,catherina,cassey,caroll,carlena,candra,calista,bryanna,britteny,beula,bari,audrie,audria,ardelia,annelle,angila,alona,allyn".split(","),surnames:"smith,johnson,williams,jones,brown,davis,miller,wilson,moore,taylor,anderson,jackson,white,harris,martin,thompson,garcia,martinez,robinson,clark,rodriguez,lewis,lee,walker,hall,allen,young,hernandez,king,wright,lopez,hill,green,adams,baker,gonzalez,nelson,carter,mitchell,perez,roberts,turner,phillips,campbell,parker,evans,edwards,collins,stewart,sanchez,morris,rogers,reed,cook,morgan,bell,murphy,bailey,rivera,cooper,richardson,cox,howard,ward,torres,peterson,gray,ramirez,watson,brooks,sanders,price,bennett,wood,barnes,ross,henderson,coleman,jenkins,perry,powell,long,patterson,hughes,flores,washington,butler,simmons,foster,gonzales,bryant,alexander,griffin,diaz,hayes,myers,ford,hamilton,graham,sullivan,wallace,woods,cole,west,owens,reynolds,fisher,ellis,harrison,gibson,mcdonald,cruz,marshall,ortiz,gomez,murray,freeman,wells,webb,simpson,stevens,tucker,porter,hicks,crawford,boyd,mason,morales,kennedy,warren,dixon,ramos,reyes,burns,gordon,shaw,holmes,rice,robertson,hunt,black,daniels,palmer,mills,nichols,grant,knight,ferguson,stone,hawkins,dunn,perkins,hudson,spencer,gardner,stephens,payne,pierce,berry,matthews,arnold,wagner,willis,watkins,olson,carroll,duncan,snyder,hart,cunningham,lane,andrews,ruiz,harper,fox,riley,armstrong,carpenter,weaver,greene,elliott,chavez,sims,peters,kelley,franklin,lawson,fields,gutierrez,schmidt,carr,vasquez,castillo,wheeler,chapman,montgomery,richards,williamson,johnston,banks,meyer,bishop,mccoy,howell,alvarez,morrison,hansen,fernandez,garza,harvey,burton,nguyen,jacobs,reid,fuller,lynch,garrett,romero,welch,larson,frazier,burke,hanson,mendoza,moreno,bowman,medina,fowler,brewer,hoffman,carlson,silva,pearson,holland,fleming,jensen,vargas,byrd,davidson,hopkins,herrera,wade,soto,walters,neal,caldwell,lowe,jennings,barnett,graves,jimenez,horton,shelton,barrett,obrien,castro,sutton,mckinney,lucas,miles,rodriquez,chambers,holt,lambert,fletcher,watts,bates,hale,rhodes,pena,beck,newman,haynes,mcdaniel,mendez,bush,vaughn,parks,dawson,santiago,norris,hardy,steele,curry,powers,schultz,barker,guzman,page,munoz,ball,keller,chandler,weber,walsh,lyons,ramsey,wolfe,schneider,mullins,benson,sharp,bowen,barber,cummings,hines,baldwin,griffith,valdez,hubbard,salazar,reeves,warner,stevenson,burgess,santos,tate,cross,garner,mann,mack,moss,thornton,mcgee,farmer,delgado,aguilar,vega,glover,manning,cohen,harmon,rodgers,robbins,newton,blair,higgins,ingram,reese,cannon,strickland,townsend,potter,goodwin,walton,rowe,hampton,ortega,patton,swanson,goodman,maldonado,yates,becker,erickson,hodges,rios,conner,adkins,webster,malone,hammond,flowers,cobb,moody,quinn,pope,osborne,mccarthy,guerrero,estrada,sandoval,gibbs,gross,fitzgerald,stokes,doyle,saunders,wise,colon,gill,alvarado,greer,padilla,waters,nunez,ballard,schwartz,mcbride,houston,christensen,klein,pratt,briggs,parsons,mclaughlin,zimmerman,buchanan,moran,copeland,pittman,brady,mccormick,holloway,brock,poole,logan,bass,marsh,drake,wong,jefferson,morton,abbott,sparks,norton,huff,massey,figueroa,carson,bowers,roberson,barton,tran,lamb,harrington,boone,cortez,clarke,mathis,singleton,wilkins,cain,underwood,hogan,mckenzie,collier,luna,phelps,mcguire,bridges,wilkerson,nash,summers,atkins,wilcox,pitts,conley,marquez,burnett,cochran,chase,davenport,hood,gates,ayala,sawyer,vazquez,dickerson,hodge,acosta,flynn,espinoza,nicholson,monroe,wolf,morrow,whitaker,oconnor,skinner,ware,molina,kirby,huffman,gilmore,dominguez,oneal,lang,combs,kramer,hancock,gallagher,gaines,shaffer,wiggins,mathews,mcclain,fischer,wall,melton,hensley,bond,dyer,grimes,contreras,wyatt,baxter,snow,mosley,shepherd,larsen,hoover,beasley,petersen,whitehead,meyers,garrison,shields,horn,savage,olsen,schroeder,hartman,woodard,mueller,kemp,deleon,booth,patel,calhoun,wiley,eaton,cline,navarro,harrell,humphrey,parrish,duran,hutchinson,hess,dorsey,bullock,robles,beard,dalton,avila,rich,blackwell,johns,blankenship,trevino,salinas,campos,pruitt,callahan,montoya,hardin,guerra,mcdowell,stafford,gallegos,henson,wilkinson,booker,merritt,atkinson,orr,decker,hobbs,tanner,knox,pacheco,stephenson,glass,rojas,serrano,marks,hickman,sweeney,strong,mcclure,conway,roth,maynard,farrell,lowery,hurst,nixon,weiss,trujillo,ellison,sloan,juarez,winters,mclean,boyer,villarreal,mccall,gentry,carrillo,ayers,lara,sexton,pace,hull,leblanc,browning,velasquez,leach,chang,sellers,herring,noble,foley,bartlett,mercado,landry,durham,walls,barr,mckee,bauer,rivers,bradshaw,pugh,velez,rush,estes,dodson,morse,sheppard,weeks,camacho,bean,barron,livingston,middleton,spears,branch,blevins,chen,kerr,mcconnell,hatfield,harding,solis,frost,giles,blackburn,pennington,woodward,finley,mcintosh,koch,mccullough,blanchard,rivas,brennan,mejia,kane,benton,buckley,valentine,maddox,russo,mcknight,buck,moon,mcmillan,crosby,berg,dotson,mays,roach,chan,richmond,meadows,faulkner,oneill,knapp,kline,ochoa,jacobson,gay,hendricks,horne,shepard,hebert,cardenas,mcintyre,waller,holman,donaldson,cantu,morin,gillespie,fuentes,tillman,bentley,peck,key,salas,rollins,gamble,dickson,santana,cabrera,cervantes,howe,hinton,hurley,spence,zamora,yang,mcneil,suarez,petty,gould,mcfarland,sampson,carver,bray,macdonald,stout,hester,melendez,dillon,farley,hopper,galloway,potts,joyner,stein,aguirre,osborn,mercer,bender,franco,rowland,sykes,pickett,sears,mayo,dunlap,hayden,wilder,mckay,coffey,mccarty,ewing,cooley,vaughan,bonner,cotton,holder,stark,ferrell,cantrell,fulton,lott,calderon,pollard,hooper,burch,mullen,fry,riddle,levy,duke,odonnell,britt,daugherty,berger,dillard,alston,frye,riggs,chaney,odom,duffy,fitzpatrick,valenzuela,mayer,alford,mcpherson,acevedo,barrera,cote,reilly,compton,mooney,mcgowan,craft,clemons,wynn,nielsen,baird,stanton,snider,rosales,bright,witt,hays,holden,rutledge,kinney,clements,castaneda,slater,hahn,burks,delaney,pate,lancaster,sharpe,whitfield,talley,macias,burris,ratliff,mccray,madden,kaufman,beach,goff,cash,bolton,mcfadden,levine,byers,kirkland,kidd,workman,carney,mcleod,holcomb,finch,sosa,haney,franks,sargent,nieves,downs,rasmussen,bird,hewitt,foreman,valencia,oneil,delacruz,vinson,dejesus,hyde,forbes,gilliam,guthrie,wooten,huber,barlow,boyle,mcmahon,buckner,rocha,puckett,langley,knowles,cooke,velazquez,whitley,vang,shea,rouse,hartley,mayfield,elder,rankin,hanna,cowan,lucero,arroyo,slaughter,haas,oconnell,minor,boucher,archer,boggs,dougherty,andersen,newell,crowe,wang,friedman,bland,swain,holley,pearce,childs,yarbrough,galvan,proctor,meeks,lozano,mora,rangel,bacon,villanueva,schaefer,rosado,helms,boyce,goss,stinson,ibarra,hutchins,covington,crowley,hatcher,mackey,bunch,womack,polk,dodd,childress,childers,villa,springer,mahoney,dailey,belcher,lockhart,griggs,costa,brandt,walden,moser,tatum,mccann,akers,lutz,pryor,orozco,mcallister,lugo,davies,shoemaker,rutherford,newsome,magee,chamberlain,blanton,simms,godfrey,flanagan,crum,cordova,escobar,downing,sinclair,donahue,krueger,mcginnis,gore,farris,webber,corbett,andrade,starr,lyon,yoder,hastings,mcgrath,spivey,krause,harden,crabtree,kirkpatrick,arrington,ritter,mcghee,bolden,maloney,gagnon,dunbar,ponce,pike,mayes,beatty,mobley,kimball,butts,montes,eldridge,braun,hamm,gibbons,moyer,manley,herron,plummer,elmore,cramer,rucker,pierson,fontenot,rubio,goldstein,elkins,wills,novak,hickey,worley,gorman,katz,dickinson,broussard,woodruff,crow,britton,nance,lehman,bingham,zuniga,whaley,shafer,coffman,steward,delarosa,neely,mata,davila,mccabe,kessler,hinkle,welsh,pagan,goldberg,goins,crouch,cuevas,quinones,mcdermott,hendrickson,samuels,denton,bergeron,ivey,locke,haines,snell,hoskins,byrne,arias,corbin,beltran,chappell,downey,dooley,tuttle,couch,payton,mcelroy,crockett,groves,cartwright,dickey,mcgill,dubois,muniz,tolbert,dempsey,cisneros,sewell,latham,vigil,tapia,rainey,norwood,stroud,meade,tipton,kuhn,hilliard,bonilla,teague,gunn,greenwood,correa,reece,pineda,phipps,frey,kaiser,ames,gunter,schmitt,milligan,espinosa,bowden,vickers,lowry,pritchard,costello,piper,mcclellan,lovell,sheehan,hatch,dobson,singh,jeffries,hollingsworth,sorensen,meza,fink,donnelly,burrell,tomlinson,colbert,billings,ritchie,helton,sutherland,peoples,mcqueen,thomason,givens,crocker,vogel,robison,dunham,coker,swartz,keys,ladner,richter,hargrove,edmonds,brantley,albright,murdock,boswell,muller,quintero,padgett,kenney,daly,connolly,inman,quintana,lund,barnard,villegas,simons,huggins,tidwell,sanderson,bullard,mcclendon,duarte,draper,marrero,dwyer,abrams,stover,goode,fraser,crews,bernal,godwin,conklin,mcneal,baca,esparza,crowder,bower,brewster,mcneill,rodrigues,leal,coates,raines,mccain,mccord,miner,holbrook,swift,dukes,carlisle,aldridge,ackerman,starks,ricks,holliday,ferris,hairston,sheffield,lange,fountain,doss,betts,kaplan,carmichael,bloom,ruffin,penn,kern,bowles,sizemore,larkin,dupree,seals,metcalf,hutchison,henley,farr,mccauley,hankins,gustafson,curran,waddell,ramey,cates,pollock,cummins,messer,heller,funk,cornett,palacios,galindo,cano,hathaway,pham,enriquez,salgado,pelletier,painter,wiseman,blount,feliciano,houser,doherty,mead,mcgraw,swan,capps,blanco,blackmon,thomson,mcmanus,burkett,gleason,dickens,cormier,voss,rushing,rosenberg,hurd,dumas,benitez,arellano,marin,caudill,bragg,jaramillo,huerta,gipson,colvin,biggs,vela,platt,cassidy,tompkins,mccollum,dolan,daley,crump,sneed,kilgore,grove,grimm,davison,brunson,prater,marcum,devine,dodge,stratton,rosas,choi,tripp,ledbetter,hightower,feldman,epps,yeager,posey,scruggs,cope,stubbs,richey,overton,trotter,sprague,cordero,butcher,stiles,burgos,woodson,horner,bassett,purcell,haskins,akins,ziegler,spaulding,hadley,grubbs,sumner,murillo,zavala,shook,lockwood,driscoll,dahl,thorpe,redmond,putnam,mcwilliams,mcrae,romano,joiner,sadler,hedrick,hager,hagen,fitch,coulter,thacker,mansfield,langston,guidry,ferreira,corley,conn,rossi,lackey,baez,saenz,mcnamara,mcmullen,mckenna,mcdonough,link,engel,browne,roper,peacock,eubanks,drummond,stringer,pritchett,parham,mims,landers,grayson,schafer,egan,timmons,ohara,keen,hamlin,finn,cortes,mcnair,nadeau,moseley,michaud,rosen,oakes,kurtz,jeffers,calloway,beal,bautista,winn,suggs,stern,stapleton,lyles,laird,montano,dawkins,hagan,goldman,bryson,barajas,lovett,segura,metz,lockett,langford,hinson,eastman,hooks,smallwood,shapiro,crowell,whalen,triplett,chatman,aldrich,cahill,youngblood,ybarra,stallings,sheets,reeder,connelly,bateman,abernathy,winkler,wilkes,masters,hackett,granger,gillis,schmitz,sapp,napier,souza,lanier,gomes,weir,otero,ledford,burroughs,babcock,ventura,siegel,dugan,bledsoe,atwood,wray,varner,spangler,anaya,staley,kraft,fournier,belanger,wolff,thorne,bynum,burnette,boykin,swenson,purvis,pina,khan,duvall,darby,xiong,kauffman,healy,engle,benoit,valle,steiner,spicer,shaver,randle,lundy,chin,calvert,staton,neff,kearney,darden,oakley,medeiros,mccracken,crenshaw,perdue,dill,whittaker,tobin,washburn,hogue,goodrich,easley,bravo,dennison,shipley,kerns,jorgensen,crain,villalobos,maurer,longoria,keene,coon,witherspoon,staples,pettit,kincaid,eason,madrid,echols,lusk,stahl,currie,thayer,shultz,mcnally,seay,maher,gagne,barrow,nava,moreland,honeycutt,hearn,diggs,caron,whitten,westbrook,stovall,ragland,munson,meier,looney,kimble,jolly,hobson,goddard,culver,burr,presley,negron,connell,tovar,huddleston,ashby,salter,root,pendleton,oleary,nickerson,myrick,judd,jacobsen,bain,adair,starnes,matos,busby,herndon,hanley,bellamy,doty,bartley,yazzie,rowell,parson,gifford,cullen,christiansen,benavides,barnhart,talbot,mock,crandall,connors,bonds,whitt,gage,bergman,arredondo,addison,lujan,dowdy,jernigan,huynh,bouchard,dutton,rhoades,ouellette,kiser,herrington,hare,blackman,babb,allred,rudd,paulson,ogden,koenig,geiger,begay,parra,lassiter,hawk,esposito,waldron,ransom,prather,chacon,vick,sands,roark,parr,mayberry,greenberg,coley,bruner,whitman,skaggs,shipman,leary,hutton,romo,medrano,ladd,kruse,askew,schulz,alfaro,tabor,mohr,gallo,bermudez,pereira,bliss,reaves,flint,comer,woodall,naquin,guevara,delong,carrier,pickens,tilley,schaffer,knutson,fenton,doran,vogt,vann,prescott,mclain,landis,corcoran,zapata,hyatt,hemphill,faulk,dove,boudreaux,aragon,whitlock,trejo,tackett,shearer,saldana,hanks,mckinnon,koehler,bourgeois,keyes,goodson,foote,lunsford,goldsmith,flood,winslow,sams,reagan,mccloud,hough,esquivel,naylor,loomis,coronado,ludwig,braswell,bearden,huang,fagan,ezell,edmondson,cronin,nunn,lemon,guillory,grier,dubose,traylor,ryder,dobbins,coyle,aponte,whitmore,smalls,rowan,malloy,cardona,braxton,borden,humphries,carrasco,ruff,metzger,huntley,hinojosa,finney,madsen,ernst,dozier,burkhart,bowser,peralta,daigle,whittington,sorenson,saucedo,roche,redding,fugate,avalos,waite,lind,huston,hawthorne,hamby,boyles,boles,regan,faust,crook,beam,barger,hinds,gallardo,willoughby,willingham,eckert,busch,zepeda,worthington,tinsley,hoff,hawley,carmona,varela,rector,newcomb,kinsey,dube,whatley,ragsdale,bernstein,becerra,yost,mattson,felder,cheek,handy,grossman,gauthier,escobedo,braden,beckman,mott,hillman,flaherty,dykes,stockton,stearns,lofton,coats,cavazos,beavers,barrios,tang,mosher,cardwell,coles,burnham,weller,lemons,beebe,aguilera,parnell,harman,couture,alley,schumacher,redd,dobbs,blum,blalock,merchant,ennis,denson,cottrell,brannon,bagley,aviles,watt,sousa,rosenthal,rooney,dietz,blank,paquette,mcclelland,duff,velasco,lentz,grubb,burrows,barbour,ulrich,shockley,rader,beyer,mixon,layton,altman,weathers,stoner,squires,shipp,priest,lipscomb,cutler,caballero,zimmer,willett,thurston,storey,medley,epperson,shah,mcmillian,baggett,torrez,hirsch,dent,poirier,peachey,farrar,creech,barth,trimble,dupre,albrecht,sample,lawler,crisp,conroy,wetzel,nesbitt,murry,jameson,wilhelm,patten,minton,matson,kimbrough,guinn,croft,toth,pulliam,nugent,newby,littlejohn,dias,canales,bernier,baron,singletary,renteria,pruett,mchugh,mabry,landrum,brower,stoddard,cagle,stjohn,scales,kohler,kellogg,hopson,gant,tharp,gann,zeigler,pringle,hammons,fairchild,deaton,chavis,carnes,rowley,matlock,kearns,irizarry,carrington,starkey,lopes,jarrell,craven,baum,littlefield,linn,humphreys,etheridge,cuellar,chastain,bundy,speer,skelton,quiroz,pyle,portillo,ponder,moulton,machado,killian,hutson,hitchcock,dowling,cloud,burdick,spann,pedersen,levin,leggett,hayward,dietrich,beaulieu,barksdale,wakefield,snowden,briscoe,bowie,berman,ogle,mcgregor,laughlin,helm,burden,wheatley,schreiber,pressley,parris,alaniz,agee,swann,snodgrass,schuster,radford,monk,mattingly,harp,girard,cheney,yancey,wagoner,ridley,lombardo,hudgins,gaskins,duckworth,coburn,willey,prado,newberry,magana,hammonds,elam,whipple,slade,serna,ojeda,liles,dorman,diehl,upton,reardon,michaels,goetz,eller,bauman,baer,layne,hummel,brenner,amaya,adamson,ornelas,dowell,cloutier,castellanos,wellman,saylor,orourke,moya,montalvo,kilpatrick,durbin,shell,oldham,kang,garvin,foss,branham,bartholomew,templeton,maguire,holton,rider,monahan,mccormack,beaty,anders,streeter,nieto,nielson,moffett,lankford,keating,heck,gatlin,delatorre,callaway,adcock,worrell,unger,robinette,nowak,jeter,brunner,steen,parrott,overstreet,nobles,montanez,clevenger,brinkley,trahan,quarles,pickering,pederson,jansen,grantham,gilchrist,crespo,aiken,schell,schaeffer,lorenz,leyva,harms,dyson,wallis,pease,leavitt,cheng,cavanaugh,batts,warden,seaman,rockwell,quezada,paxton,linder,houck,fontaine,durant,caruso,adler,pimentel,mize,lytle,cleary,cason,acker,switzer,isaacs,higginbotham,waterman,vandyke,stamper,sisk,shuler,riddick,mcmahan,levesque,hatton,bronson,bollinger,arnett,okeefe,gerber,gannon,farnsworth,baughman,silverman,satterfield,mccrary,kowalski,grigsby,greco,cabral,trout,rinehart,mahon,linton,gooden,curley,baugh,wyman,weiner,schwab,schuler,morrissey,mahan,bunn,thrasher,spear,waggoner,qualls,purdy,mcwhorter,mauldin,gilman,perryman,newsom,menard,martino,graf,billingsley,artis,simpkins,salisbury,quintanilla,gilliland,fraley,foust,crouse,scarborough,grissom,fultz,marlow,markham,madrigal,lawton,barfield,whiting,varney,schwarz,gooch,arce,wheat,truong,poulin,hurtado,selby,gaither,fortner,culpepper,coughlin,brinson,boudreau,bales,stepp,holm,schilling,morrell,kahn,heaton,gamez,causey,turpin,shanks,schrader,meek,isom,hardison,carranza,yanez,scroggins,schofield,runyon,ratcliff,murrell,moeller,irby,currier,butterfield,ralston,pullen,pinson,estep,carbone,hawks,ellington,casillas,spurlock,sikes,motley,mccartney,kruger,isbell,houle,burk,tomlin,quigley,neumann,lovelace,fennell,cheatham,bustamante,skidmore,hidalgo,forman,culp,bowens,betancourt,aquino,robb,milner,martel,gresham,wiles,ricketts,dowd,collazo,bostic,blakely,sherrod,kenyon,gandy,ebert,deloach,allard,sauer,robins,olivares,gillette,chestnut,bourque,paine,hite,hauser,devore,crawley,chapa,talbert,poindexter,meador,mcduffie,mattox,kraus,harkins,choate,wren,sledge,sanborn,kinder,geary,cornwell,barclay,abney,seward,rhoads,howland,fortier,benner,vines,tubbs,troutman,rapp,mccurdy,deluca,westmoreland,havens,guajardo,clary,seal,meehan,herzog,guillen,ashcraft,waugh,renner,milam,elrod,churchill,breaux,bolin,asher,windham,tirado,pemberton,nolen,noland,knott,emmons,cornish,christenson,brownlee,barbee,waldrop,pitt,olvera,lombardi,gruber,gaffney,eggleston,banda,archuleta,slone,prewitt,pfeiffer,nettles,mena,mcadams,henning,gardiner,cromwell,chisholm,burleson,vest,oglesby,mccarter,lumpkin,wofford,vanhorn,thorn,teel,swafford,stclair,stanfield,ocampo,herrmann,hannon,arsenault,roush,mcalister,hiatt,gunderson,forsythe,duggan,delvalle,cintron,wilks,weinstein,uribe,rizzo,noyes,mclendon,gurley,bethea,winstead,maples,guyton,giordano,alderman,valdes,polanco,pappas,lively,grogan,griffiths,bobo,arevalo,whitson,sowell,rendon,fernandes,farrow,benavidez,ayres,alicea,stump,smalley,seitz,schulte,gilley,gallant,canfield,wolford,omalley,mcnutt,mcnulty,mcgovern,hardman,harbin,cowart,chavarria,brink,beckett,bagwell,armstead,anglin,abreu,reynoso,krebs,jett,hoffmann,greenfield,forte,burney,broome,sisson,trammell,partridge,mace,lomax,lemieux,gossett,frantz,fogle,cooney,broughton,pence,paulsen,muncy,mcarthur,hollins,beauchamp,withers,osorio,mulligan,hoyle,dockery,cockrell,begley,amador,roby,rains,lindquist,gentile,everhart,bohannon,wylie,sommers,purnell,fortin,dunning,breeden,vail,phelan,phan,marx,cosby,colburn,boling,biddle,ledesma,gaddis,denney,chow,bueno,berrios,wicker,tolliver,thibodeaux,nagle,lavoie,fisk,crist,barbosa,reedy,locklear,kolb,himes,behrens,beckwith,weems,wahl,shorter,shackelford,rees,muse,cerda,valadez,thibodeau,saavedra,ridgeway,reiter,mchenry,majors,lachance,keaton,ferrara,clemens,blocker,applegate,needham,mojica,kuykendall,hamel,escamilla,doughty,burchett,ainsworth,vidal,upchurch,thigpen,strauss,spruill,sowers,riggins,ricker,mccombs,harlow,buffington,sotelo,olivas,negrete,morey,macon,logsdon,lapointe,bigelow,bello,westfall,stubblefield,lindley,hein,hawes,farrington,breen,birch,wilde,steed,sepulveda,reinhardt,proffitt,minter,messina,mcnabb,maier,keeler,gamboa,donohue,basham,shinn,crooks,cota,borders,bills,bachman,tisdale,tavares,schmid,pickard,gulley,fonseca,delossantos,condon,batista,wicks,wadsworth,martell,littleton,ison,haag,folsom,brumfield,broyles,brito,mireles,mcdonnell,leclair,hamblin,gough,fanning,binder,winfield,whitworth,soriano,palumbo,newkirk,mangum,hutcherson,comstock,carlin,beall,bair,wendt,watters,walling,putman,otoole,morley,mares,lemus,keener,hundley,dial,damico,billups,strother,mcfarlane,lamm,eaves,crutcher,caraballo,canty,atwell,taft,siler,rust,rawls,rawlings,prieto,mcneely,mcafee,hulsey,hackney,galvez,escalante,delagarza,crider,bandy,wilbanks,stowe,steinberg,renfro,masterson,massie,lanham,haskell,hamrick,dehart,burdette,branson,bourne,babin,aleman,worthy,tibbs,smoot,slack,paradis,mull,luce,houghton,gantt,furman,danner,christianson,burge,ashford,arndt,almeida,stallworth,shade,searcy,sager,noonan,mclemore,mcintire,maxey,lavigne,jobe,ferrer,falk,coffin,byrnes,aranda,apodaca,stamps,rounds,peek,olmstead,lewandowski,kaminski,dunaway,bruns,brackett,amato,reich,mcclung,lacroix,koontz,herrick,hardesty,flanders,cousins,cato,cade,vickery,shank,nagel,dupuis,croteau,cotter,stuckey,stine,porterfield,pauley,moffitt,knudsen,hardwick,goforth,dupont,blunt,barrows,barnhill,shull,rash,loftis,lemay,kitchens,horvath,grenier,fuchs,fairbanks,culbertson,calkins,burnside,beattie,ashworth,albertson,wertz,vaught,vallejo,turk,tuck,tijerina,sage,peterman,marroquin,marr,lantz,hoang,demarco,cone,berube,barnette,wharton,stinnett,slocum,scanlon,sander,pinto,mancuso,lima,headley,epstein,counts,clarkson,carnahan,boren,arteaga,adame,zook,whittle,whitehurst,wenzel,saxton,reddick,puente,handley,haggerty,earley,devlin,chaffin,cady,acuna,solano,sigler,pollack,pendergrass,ostrander,janes,francois,crutchfield,chamberlin,brubaker,baptiste,willson,reis,neeley,mullin,mercier,lira,layman,keeling,higdon,espinal,chapin,warfield,toledo,pulido,peebles,nagy,montague,mello,lear,jaeger,hogg,graff,furr,soliz,poore,mendenhall,mclaurin,maestas,gable,barraza,tillery,snead,pond,neill,mcculloch,mccorkle,lightfoot,hutchings,holloman,harness,dorn,bock,zielinski,turley,treadwell,stpierre,starling,somers,oswald,merrick,easterling,bivens,truitt,poston,parry,ontiveros,olivarez,moreau,medlin,lenz,knowlton,fairley,cobbs,chisolm,bannister,woodworth,toler,ocasio,noriega,neuman,moye,milburn,mcclanahan,lilley,hanes,flannery,dellinger,danielson,conti,blodgett,beers,weatherford,strain,karr,hitt,denham,custer,coble,clough,casteel,bolduc,batchelor,ammons,whitlow,tierney,staten,sibley,seifert,schubert,salcedo,mattison,laney,haggard,grooms,dees,cromer,cooks,colson,caswell,zarate,swisher,shin,ragan,pridgen,mcvey,matheny,lafleur,franz,ferraro,dugger,whiteside,rigsby,mcmurray,lehmann,jacoby,hildebrand,hendrick,headrick,goad,fincher,drury,borges,archibald,albers,woodcock,trapp,soares,seaton,monson,luckett,lindberg,kopp,keeton,healey,garvey,gaddy,fain,burchfield,wentworth,strand,stack,spooner,saucier,ricci,plunkett,pannell,ness,leger,freitas,fong,elizondo,duval,beaudoin,urbina,rickard,partin,mcgrew,mcclintock,ledoux,forsyth,faison,devries,bertrand,wasson,tilton,scarbrough,leung,irvine,garber,denning,corral,colley,castleberry,bowlin,bogan,beale,baines,trice,rayburn,parkinson,nunes,mcmillen,leahy,kimmel,higgs,fulmer,carden,bedford,taggart,spearman,prichard,morrill,koonce,heinz,hedges,guenther,grice,findley,dover,creighton,boothe,bayer,arreola,vitale,valles,raney,osgood,hanlon,burley,bounds,worden,weatherly,vetter,tanaka,stiltner,nevarez,mosby,montero,melancon,harter,hamer,goble,gladden,gist,ginn,akin,zaragoza,tarver,sammons,royster,oreilly,muir,morehead,luster,kingsley,kelso,grisham,glynn,baumann,alves,yount,tamayo,paterson,oates,menendez,longo,hargis,gillen,desantis,conover,breedlove,sumpter,scherer,rupp,reichert,heredia,creel,cohn,clemmons,casas,bickford,belton,bach,williford,whitcomb,tennant,sutter,stull,mccallum,langlois,keel,keegan,dangelo,dancy,damron,clapp,clanton,bankston,oliveira,mintz,mcinnis,martens,mabe,laster,jolley,hildreth,hefner,glaser,duckett,demers,brockman,blais,alcorn,agnew,toliver,tice,seeley,najera,musser,mcfall,laplante,galvin,fajardo,doan,coyne,copley,clawson,cheung,barone,wynne,woodley,tremblay,stoll,sparrow,sparkman,schweitzer,sasser,samples,roney,legg,heim,farias,colwell,christman,bratcher,winchester,upshaw,southerland,sorrell,sells,mccloskey,martindale,luttrell,loveless,lovejoy,linares,latimer,embry,coombs,bratton,bostick,venable,tuggle,toro,staggs,sandlin,jefferies,heckman,griffis,crayton,clem,browder,thorton,sturgill,sprouse,royer,rousseau,ridenour,pogue,perales,peeples,metzler,mesa,mccutcheon,mcbee,hornsby,heffner,corrigan,armijo,plante,peyton,paredes,macklin,hussey,hodgson,granados,frias,becnel,batten,almanza,turney,teal,sturgeon,meeker,mcdaniels,limon,keeney,hutto,holguin,gorham,fishman,fierro,blanchette,rodrigue,reddy,osburn,oden,lerma,kirkwood,keefer,haugen,hammett,chalmers,brinkman,baumgartner,zhang,valerio,tellez,steffen,shumate,sauls,ripley,kemper,guffey,evers,craddock,carvalho,blaylock,banuelos,balderas,wheaton,turnbull,shuman,pointer,mosier,mccue,ligon,kozlowski,johansen,ingle,herr,briones,snipes,rickman,pipkin,pantoja,orosco,moniz,lawless,kunkel,hibbard,galarza,enos,bussey,schott,salcido,perreault,mcdougal,mccool,haight,garris,easton,conyers,atherton,wimberly,utley,spellman,smithson,slagle,ritchey,rand,petit,osullivan,oaks,nutt,mcvay,mccreary,mayhew,knoll,jewett,harwood,cardoza,ashe,arriaga,zeller,wirth,whitmire,stauffer,rountree,redden,mccaffrey,martz,larose,langdon,humes,gaskin,faber,devito,cass,almond,wingfield,wingate,villareal,tyner,smothers,severson,reno,pennell,maupin,leighton,janssen,hassell,hallman,halcomb,folse,fitzsimmons,fahey,cranford,bolen,battles,battaglia,wooldridge,trask,rosser,regalado,mcewen,keefe,fuqua,echevarria,caro,boynton,andrus,viera,vanmeter,taber,spradlin,seibert,provost,prentice,oliphant,laporte,hwang,hatchett,hass,greiner,freedman,covert,chilton,byars,wiese,venegas,swank,shrader,roberge,mullis,mortensen,mccune,marlowe,kirchner,keck,isaacson,hostetler,halverson,gunther,griswold,fenner,durden,blackwood,ahrens,sawyers,savoy,nabors,mcswain,mackay,lavender,lash,labbe,jessup,fullerton,cruse,crittenden,correia,centeno,caudle,canady,callender,alarcon,ahern,winfrey,tribble,salley,roden,musgrove,minnick,fortenberry,carrion,bunting,batiste,whited,underhill,stillwell,rauch,pippin,perrin,messenger,mancini,lister,kinard,hartmann,fleck,wilt,treadway,thornhill,spalding,rafferty,pitre,patino,ordonez,linkous,kelleher,homan,galbraith,feeney,curtin,coward,camarillo,buss,bunnell,bolt,beeler,autry,alcala,witte,wentz,stidham,shively,nunley,meacham,martins,lemke,lefebvre,hynes,horowitz,hoppe,holcombe,dunne,derr,cochrane,brittain,bedard,beauregard,torrence,strunk,soria,simonson,shumaker,scoggins,oconner,moriarty,kuntz,ives,hutcheson,horan,hales,garmon,fitts,bohn,atchison,wisniewski,vanwinkle,sturm,sallee,prosser,moen,lundberg,kunz,kohl,keane,jorgenson,jaynes,funderburk,freed,durr,creamer,cosgrove,batson,vanhoose,thomsen,teeter,smyth,redmon,orellana,maness,heflin,goulet,frick,forney,bunker,asbury,aguiar,talbott,southard,mowery,mears,lemmon,krieger,hickson,elston,duong,delgadillo,dayton,dasilva,conaway,catron,bruton,bradbury,bordelon,bivins,bittner,bergstrom,beals,abell,whelan,tejada,pulley,pino,norfleet,nealy,maes,loper,gatewood,frierson,freund,finnegan,cupp,covey,catalano,boehm,bader,yoon,walston,tenney,sipes,rawlins,medlock,mccaskill,mccallister,marcotte,maclean,hughey,henke,harwell,gladney,gilson,chism,caskey,brandenburg,baylor,villasenor,veal,thatcher,stegall,petrie,nowlin,navarrete,lombard,loftin,lemaster,kroll,kovach,kimbrell,kidwell,hershberger,fulcher,cantwell,bustos,boland,bobbitt,binkley,wester,weis,verdin,tong,tiller,sisco,sharkey,seymore,rosenbaum,rohr,quinonez,pinkston,malley,logue,lessard,lerner,lebron,krauss,klinger,halstead,haller,getz,burrow,alger,shores,pfeifer,perron,nelms,munn,mcmaster,mckenney,manns,knudson,hutchens,huskey,goebel,flagg,cushman,click,castellano,carder,bumgarner,wampler,spinks,robson,neel,mcreynolds,mathias,maas,loera,jenson,florez,coons,buckingham,brogan,berryman,wilmoth,wilhite,thrash,shephard,seidel,schulze,roldan,pettis,obryan,maki,mackie,hatley,frazer,fiore,chesser,bottoms,bisson,benefield,allman,wilke,trudeau,timm,shifflett,mundy,milliken,mayers,leake,kohn,huntington,horsley,hermann,guerin,fryer,frizzell,foret,flemming,fife,criswell,carbajal,bozeman,boisvert,angulo,wallen,tapp,silvers,ramsay,oshea,orta,moll,mckeever,mcgehee,linville,kiefer,ketchum,howerton,groce,gass,fusco,corbitt,betz,bartels,amaral,aiello,weddle,sperry,seiler,runyan,raley,overby,osteen,olds,mckeown,matney,lauer,lattimore,hindman,hartwell,fredrickson,fredericks,espino,clegg,carswell,cambell,burkholder,woodbury,welker,totten,thornburg,theriault,stitt,stamm,stackhouse,scholl,saxon,rife,razo,quinlan,pinkerton,olivo,nesmith,nall,mattos,lafferty,justus,giron,geer,fielder,drayton,dortch,conners,conger,boatwright,billiot,barden,armenta,tibbetts,steadman,slattery,rinaldi,raynor,pinckney,pettigrew,milne,matteson,halsey,gonsalves,fellows,durand,desimone,cowley,cowles,brill,barham,barela,barba,ashmore,withrow,valenti,tejeda,spriggs,sayre,salerno,peltier,peel,merriman,matheson,lowman,lindstrom,hyland,giroux,earls,dugas,dabney,collado,briseno,baxley,whyte,wenger,vanover,vanburen,thiel,schindler,schiller,rigby,pomeroy,passmore,marble,manzo,mahaffey,lindgren,laflamme,greathouse,fite,calabrese,bayne,yamamoto,wick,townes,thames,reinhart,peeler,naranjo,montez,mcdade,mast,markley,marchand,leeper,kellum,hudgens,hennessey,hadden,gainey,coppola,borrego,bolling,beane,ault,slaton,pape,null,mulkey,lightner,langer,hillard,ethridge,enright,derosa,baskin,weinberg,turman,somerville,pardo,noll,lashley,ingraham,hiller,hendon,glaze,cothran,cooksey,conte,carrico,abner,wooley,swope,summerlin,sturgis,sturdivant,stott,spurgeon,spillman,speight,roussel,popp,nutter,mckeon,mazza,magnuson,lanning,kozak,jankowski,heyward,forster,corwin,callaghan,bays,wortham,usher,theriot,sayers,sabo,poling,loya,lieberman,laroche,labelle,howes,harr,garay,fogarty,everson,durkin,dominquez,chaves,chambliss,witcher,vieira,vandiver,terrill,stoker,schreiner,moorman,liddell,lawhorn,krug,irons,hylton,hollenbeck,herrin,hembree,goolsby,goodin,gilmer,foltz,dinkins,daughtry,caban,brim,briley,bilodeau,wyant,vergara,tallent,swearingen,stroup,scribner,quillen,pitman,mccants,maxfield,martinson,holtz,flournoy,brookins,brody,baumgardner,straub,sills,roybal,roundtree,oswalt,mcgriff,mcdougall,mccleary,maggard,gragg,gooding,godinez,doolittle,donato,cowell,cassell,bracken,appel,zambrano,reuter,perea,nakamura,monaghan,mickens,mcclinton,mcclary,marler,kish,judkins,gilbreath,freese,flanigan,felts,erdmann,dodds,chew,brownell,boatright,barreto,slayton,sandberg,saldivar,pettway,odum,narvaez,moultrie,montemayor,merrell,lees,keyser,hoke,hardaway,hannan,gilbertson,fogg,dumont,deberry,coggins,buxton,bucher,broadnax,beeson,araujo,appleton,amundson,aguayo,ackley,yocum,worsham,shivers,sanches,sacco,robey,rhoden,pender,ochs,mccurry,madera,luong,knotts,jackman,heinrich,hargrave,gault,comeaux,chitwood,caraway,boettcher,bernhardt,barrientos,zink,wickham,whiteman,thorp,stillman,settles,schoonover,roque,riddell,pilcher,phifer,novotny,macleod,hardee,haase,grider,doucette,clausen,bevins,beamon,badillo,tolley,tindall,soule,snook,seale,pinkney,pellegrino,nowell,nemeth,mondragon,mclane,lundgren,ingalls,hudspeth,hixson,gearhart,furlong,downes,dibble,deyoung,cornejo,camara,brookshire,boyette,wolcott,surratt,sellars,segal,salyer,reeve,rausch,labonte,haro,gower,freeland,fawcett,eads,driggers,donley,collett,bromley,boatman,ballinger,baldridge,volz,trombley,stonge,shanahan,rivard,rhyne,pedroza,matias,jamieson,hedgepeth,hartnett,estevez,eskridge,denman,chiu,chinn,catlett,carmack,buie,bechtel,beardsley,bard,ballou,ulmer,skeen,robledo,rincon,reitz,piazza,munger,moten,mcmichael,loftus,ledet,kersey,groff,fowlkes,crumpton,clouse,bettis,villagomez,timmerman,strom,santoro,roddy,penrod,musselman,macpherson,leboeuf,harless,haddad,guido,golding,fulkerson,fannin,dulaney,dowdell,cottle,ceja,cate,bosley,benge,albritton,voigt,trowbridge,soileau,seely,rohde,pearsall,paulk,orth,nason,mota,mcmullin,marquardt,madigan,hoag,gillum,gabbard,fenwick,danforth,cushing,cress,creed,cazares,bettencourt,barringer,baber,stansberry,schramm,rutter,rivero,oquendo,necaise,mouton,montenegro,miley,mcgough,marra,macmillan,lamontagne,jasso,horst,hetrick,heilman,gaytan,gall,fortney,dingle,desjardins,dabbs,burbank,brigham,breland,beaman,arriola,yarborough,wallin,toscano,stowers,reiss,pichardo,orton,michels,mcnamee,mccrory,leatherman,kell,keister,horning,hargett,guay,ferro,deboer,dagostino,carper,blanks,beaudry,towle,tafoya,stricklin,strader,soper,sonnier,sigmon,schenk,saddler,pedigo,mendes,lunn,lohr,lahr,kingsbury,jarman,hume,holliman,hofmann,haworth,harrelson,hambrick,flick,edmunds,dacosta,crossman,colston,chaplin,carrell,budd,weiler,waits,valentino,trantham,tarr,solorio,roebuck,powe,plank,pettus,pagano,mink,luker,leathers,joslin,hartzell,gambrell,cepeda,carty,caputo,brewington,bedell,ballew,applewhite,warnock,walz,urena,tudor,reel,pigg,parton,mickelson,meagher,mclellan,mcculley,mandel,leech,lavallee,kraemer,kling,kipp,kehoe,hochstetler,harriman,gregoire,grabowski,gosselin,gammon,fancher,edens,desai,brannan,armendariz,woolsey,whitehouse,whetstone,ussery,towne,testa,tallman,studer,strait,steinmetz,sorrells,sauceda,rolfe,paddock,mitchem,mcginn,mccrea,lovato,hazen,gilpin,gaynor,fike,devoe,delrio,curiel,burkhardt,bode,backus,zinn,watanabe,wachter,vanpelt,turnage,shaner,schroder,sato,riordan,quimby,portis,natale,mckoy,mccown,kilmer,hotchkiss,hesse,halbert,gwinn,godsey,delisle,chrisman,canter,arbogast,angell,acree,yancy,woolley,wesson,weatherspoon,trainor,stockman,spiller,sipe,rooks,reavis,propst,porras,neilson,mullens,loucks,llewellyn,kumar,koester,klingensmith,kirsch,kester,honaker,hodson,hennessy,helmick,garrity,garibay,drain,casarez,callis,botello,aycock,avant,wingard,wayman,tully,theisen,szymanski,stansbury,segovia,rainwater,preece,pirtle,padron,mincey,mckelvey,mathes,larrabee,kornegay,klug,ingersoll,hecht,germain,eggers,dykstra,deering,decoteau,deason,dearing,cofield,carrigan,bonham,bahr,aucoin,appleby,almonte,yager,womble,wimmer,weimer,vanderpool,stancil,sprinkle,romine,remington,pfaff,peckham,olivera,meraz,maze,lathrop,koehn,hazelton,halvorson,hallock,haddock,ducharme,dehaven,caruthers,brehm,bosworth,bost,bias,beeman,basile,bane,aikens,wold,walther,tabb,suber,strawn,stocker,shirey,schlosser,riedel,rembert,reimer,pyles,peele,merriweather,letourneau,latta,kidder,hixon,hillis,hight,herbst,henriquez,haygood,hamill,gabel,fritts,eubank,dawes,correll,bushey,buchholz,brotherton,botts,barnwell,auger,atchley,westphal,veilleux,ulloa,stutzman,shriver,ryals,pilkington,moyers,marrs,mangrum,maddux,lockard,laing,kuhl,harney,hammock,hamlett,felker,doerr,depriest,carrasquillo,carothers,bogle,bischoff,bergen,albanese,wyckoff,vermillion,vansickle,thibault,tetreault,stickney,shoemake,ruggiero,rawson,racine,philpot,paschal,mcelhaney,mathison,legrand,lapierre,kwan,kremer,jiles,hilbert,geyer,faircloth,ehlers,egbert,desrosiers,dalrymple,cotten,cashman,cadena,boardman,alcaraz,wyrick,therrien,tankersley,strickler,puryear,plourde,pattison,pardue,mcginty,mcevoy,landreth,kuhns,koon,hewett,giddens,emerick,eades,deangelis,cosme,ceballos,birdsong,benham,bemis,armour,anguiano,welborn,tsosie,storms,shoup,sessoms,samaniego,rood,rojo,rhinehart,raby,northcutt,myer,munguia,morehouse,mcdevitt,mallett,lozada,lemoine,kuehn,hallett,grim,gillard,gaylor,garman,gallaher,feaster,faris,darrow,dardar,coney,carreon,braithwaite,boylan,boyett,bixler,bigham,benford,barragan,barnum,zuber,wyche,westcott,vining,stoltzfus,simonds,shupe,sabin,ruble,rittenhouse,richman,perrone,mulholland,millan,lomeli,kite,jemison,hulett,holler,hickerson,herold,hazelwood,griffen,gause,forde,eisenberg,dilworth,charron,chaisson,bristow,breunig,brace,boutwell,bentz,belk,bayless,batchelder,baran,baeza,zimmermann,weathersby,volk,toole,theis,tedesco,searle,schenck,satterwhite,ruelas,rankins,partida,nesbit,morel,menchaca,levasseur,kaylor,johnstone,hulse,hollar,hersey,harrigan,harbison,guyer,gish,giese,gerlach,geller,geisler,falcone,elwell,doucet,deese,darr,corder,chafin,byler,bussell,burdett,brasher,bowe,bellinger,bastian,barner,alleyne,wilborn,weil,wegner,tatro,spitzer,smithers,schoen,resendez,parisi,overman,obrian,mudd,mahler,maggio,lindner,lalonde,lacasse,laboy,killion,kahl,jessen,jamerson,houk,henshaw,gustin,graber,durst,duenas,davey,cundiff,conlon,colunga,coakley,chiles,capers,buell,bricker,bissonnette,bartz,bagby,zayas,volpe,treece,toombs,thom,terrazas,swinney,skiles,silveira,shouse,senn,ramage,moua,langham,kyles,holston,hoagland,herd,feller,denison,carraway,burford,bickel,ambriz,abercrombie,yamada,weidner,waddle,verduzco,thurmond,swindle,schrock,sanabria,rosenberger,probst,peabody,olinger,nazario,mccafferty,mcbroom,mcabee,mazur,matherne,mapes,leverett,killingsworth,heisler,griego,gosnell,frankel,franke,ferrante,fenn,ehrlich,christopherso,chasse,caton,brunelle,bloomfield,babbitt,azevedo,abramson,ables,abeyta,youmans,wozniak,wainwright,stowell,smitherman,samuelson,runge,rothman,rosenfeld,peake,owings,olmos,munro,moreira,leatherwood,larkins,krantz,kovacs,kizer,kindred,karnes,jaffe,hubbell,hosey,hauck,goodell,erdman,dvorak,doane,cureton,cofer,buehler,bierman,berndt,banta,abdullah,warwick,waltz,turcotte,torrey,stith,seger,sachs,quesada,pinder,peppers,pascual,paschall,parkhurst,ozuna,oster,nicholls,lheureux,lavalley,kimura,jablonski,haun,gourley,gilligan,croy,cotto,cargill,burwell,burgett,buckman,booher,adorno,wrenn,whittemore,urias,szabo,sayles,saiz,rutland,rael,pharr,pelkey,ogrady,nickell,musick,moats,mather,massa,kirschner,kieffer,kellar,hendershot,gott,godoy,gadson,furtado,fiedler,erskine,dutcher,dever,daggett,chevalier,brake,ballesteros,amerson,wingo,waldon,trott,silvey,showers,schlegel,ritz,pepin,pelayo,parsley,palermo,moorehead,mchale,lett,kocher,kilburn,iglesias,humble,hulbert,huckaby,hartford,hardiman,gurney,grigg,grasso,goings,fillmore,farber,depew,dandrea,cowen,covarrubias,burrus,bracy,ardoin,thompkins,standley,radcliffe,pohl,persaud,parenteau,pabon,newson,newhouse,napolitano,mulcahy,malave,keim,hooten,hernandes,heffernan,hearne,greenleaf,glick,fuhrman,fetter,faria,dishman,dickenson,crites,criss,clapper,chenault,castor,casto,bugg,bove,bonney,anderton,allgood,alderson,woodman,warrick,toomey,tooley,tarrant,summerville,stebbins,sokol,searles,schutz,schumann,scheer,remillard,raper,proulx,palmore,monroy,messier,melo,melanson,mashburn,manzano,lussier,jenks,huneycutt,hartwig,grimsley,fulk,fielding,fidler,engstrom,eldred,dantzler,crandell,calder,brumley,breton,brann,bramlett,boykins,bianco,bancroft,almaraz,alcantar,whitmer,whitener,welton,vineyard,rahn,paquin,mizell,mcmillin,mckean,marston,maciel,lundquist,liggins,lampkin,kranz,koski,kirkham,jiminez,hazzard,harrod,graziano,grammer,gendron,garrido,fordham,englert,dryden,demoss,deluna,crabb,comeau,brummett,blume,benally,wessel,vanbuskirk,thorson,stumpf,stockwell,reams,radtke,rackley,pelton,niemi,newland,nelsen,morrissette,miramontes,mcginley,mccluskey,marchant,luevano,lampe,lail,jeffcoat,infante,hinman,gaona,eady,desmarais,decosta,dansby,cisco,choe,breckenridge,bostwick,borg,bianchi,alberts,wilkie,whorton,vargo,tait,soucy,schuman,ousley,mumford,lippert,leath,lavergne,laliberte,kirksey,kenner,johnsen,izzo,hiles,gullett,greenwell,gaspar,galbreath,gaitan,ericson,delapaz,croom,cottingham,clift,bushnell,bice,beason,arrowood,waring,voorhees,truax,shreve,shockey,schatz,sandifer,rubino,rozier,roseberry,pieper,peden,nester,nave,murphey,malinowski,macgregor,lafrance,kunkle,kirkman,hipp,hasty,haddix,gervais,gerdes,gamache,fouts,fitzwater,dillingham,deming,deanda,cedeno,cannady,burson,bouldin,arceneaux,woodhouse,whitford,wescott,welty,weigel,torgerson,toms,surber,sunderland,sterner,setzer,riojas,pumphrey,puga,metts,mcgarry,mccandless,magill,lupo,loveland,llamas,leclerc,koons,kahler,huss,holbert,heintz,haupt,grimmett,gaskill,ellingson,dorr,dingess,deweese,desilva,crossley,cordeiro,converse,conde,caldera,cairns,burmeister,burkhalter,brawner,bott,youngs,vierra,valladares,shrum,shropshire,sevilla,rusk,rodarte,pedraza,nino,merino,mcminn,markle,mapp,lajoie,koerner,kittrell,kato,hyder,hollifield,heiser,hazlett,greenwald,fant,eldredge,dreher,delafuente,cravens,claypool,beecher,aronson,alanis,worthen,wojcik,winger,whitacre,valverde,valdivia,troupe,thrower,swindell,suttles,stroman,spires,slate,shealy,sarver,sartin,sadowski,rondeau,rolon,rascon,priddy,paulino,nolte,munroe,molloy,mciver,lykins,loggins,lenoir,klotz,kempf,hupp,hollowell,hollander,haynie,harkness,harker,gottlieb,frith,eddins,driskell,doggett,densmore,charette,cassady,byrum,burcham,buggs,benn,whitted,warrington,vandusen,vaillancourt,steger,siebert,scofield,quirk,purser,plumb,orcutt,nordstrom,mosely,michalski,mcphail,mcdavid,mccraw,marchese,mannino,lefevre,largent,lanza,kress,isham,hunsaker,hoch,hildebrandt,guarino,grijalva,graybill,fick,ewell,ewald,cusick,crumley,coston,cathcart,carruthers,bullington,bowes,blain,blackford,barboza,yingling,wert,weiland,varga,silverstein,sievers,shuster,shumway,runnels,rumsey,renfroe,provencher,polley,mohler,middlebrooks,kutz,koster,groth,glidden,fazio,deen,chipman,chenoweth,champlin,cedillo,carrero,carmody,buckles,brien,boutin,bosch,berkowitz,altamirano,wilfong,wiegand,waites,truesdale,toussaint,tobey,tedder,steelman,sirois,schnell,robichaud,richburg,plumley,pizarro,piercy,ortego,oberg,neace,mertz,mcnew,matta,lapp,lair,kibler,howlett,hollister,hofer,hatten,hagler,falgoust,engelhardt,eberle,dombrowski,dinsmore,daye,casares,braud,balch,autrey,wendel,tyndall,strobel,stoltz,spinelli,serrato,reber,rathbone,palomino,nickels,mayle,mathers,mach,loeffler,littrell,levinson,leong,lemire,lejeune,lazo,lasley,koller,kennard,hoelscher,hintz,hagerman,greaves,fore,eudy,engler,corrales,cordes,brunet,bidwell,bennet,tyrrell,tharpe,swinton,stribling,southworth,sisneros,savoie,samons,ruvalcaba,ries,ramer,omara,mosqueda,millar,mcpeak,macomber,luckey,litton,lehr,lavin,hubbs,hoard,hibbs,hagans,futrell,exum,evenson,culler,carbaugh,callen,brashear,bloomer,blakeney,bigler,addington,woodford,unruh,tolentino,sumrall,stgermain,smock,sherer,rayner,pooler,oquinn,nero,mcglothlin,linden,kowal,kerrigan,ibrahim,harvell,hanrahan,goodall,geist,fussell,fung,ferebee,eley,eggert,dorsett,dingman,destefano,colucci,clemmer,burnell,brumbaugh,boddie,berryhill,avelar,alcantara,winder,winchell,vandenberg,trotman,thurber,thibeault,stlouis,stilwell,sperling,shattuck,sarmiento,ruppert,rumph,renaud,randazzo,rademacher,quiles,pearman,palomo,mercurio,lowrey,lindeman,lawlor,larosa,lander,labrecque,hovis,holifield,henninger,hawkes,hartfield,hann,hague,genovese,garrick,fudge,frink,eddings,dinh,cribbs,calvillo,bunton,brodeur,bolding,blanding,agosto,zahn,wiener,trussell,tello,teixeira,speck,sharma,shanklin,sealy,scanlan,santamaria,roundy,robichaux,ringer,rigney,prevost,polson,nord,moxley,medford,mccaslin,mcardle,macarthur,lewin,lasher,ketcham,keiser,heine,hackworth,grose,grizzle,gillman,gartner,frazee,fleury,edson,edmonson,derry,cronk,conant,burress,burgin,broom,brockington,bolick,boger,birchfield,billington,baily,bahena,armbruster,anson,yoho,wilcher,tinney,timberlake,thielen,sutphin,stultz,sikora,serra,schulman,scheffler,santillan,rego,preciado,pinkham,mickle,lomas,lizotte,lent,kellerman,keil,johanson,hernadez,hartsfield,haber,gorski,farkas,eberhardt,duquette,delano,cropper,cozart,cockerham,chamblee,cartagena,cahoon,buzzell,brister,brewton,blackshear,benfield,aston,ashburn,arruda,wetmore,weise,vaccaro,tucci,sudduth,stromberg,stoops,showalter,shears,runion,rowden,rosenblum,riffle,renfrow,peres,obryant,leftwich,lark,landeros,kistler,killough,kerley,kastner,hoggard,hartung,guertin,govan,gatling,gailey,fullmer,fulford,flatt,esquibel,endicott,edmiston,edelstein,dufresne,dressler,dickman,chee,busse,bonnett,berard,yoshida,velarde,veach,vanhouten,vachon,tolson,tolman,tennyson,stites,soler,shutt,ruggles,rhone,pegues,neese,muro,moncrief,mefford,mcphee,mcmorris,mceachern,mcclurg,mansour,mader,leija,lecompte,lafountain,labrie,jaquez,heald,hash,hartle,gainer,frisby,farina,eidson,edgerton,dyke,durrett,duhon,cuomo,cobos,cervantez,bybee,brockway,borowski,binion,beery,arguello,amaro,acton,yuen,winton,wigfall,weekley,vidrine,vannoy,tardiff,shoop,shilling,schick,safford,prendergast,pilgrim,pellerin,osuna,nissen,nalley,moller,messner,messick,merrifield,mcguinness,matherly,marcano,mahone,lemos,lebrun,jara,hoffer,herren,hecker,haws,haug,gwin,gober,gilliard,fredette,favela,echeverria,downer,donofrio,desrochers,crozier,corson,bechtold,argueta,aparicio,zamudio,westover,westerman,utter,troyer,thies,tapley,slavin,shirk,sandler,roop,rimmer,raymer,radcliff,otten,moorer,millet,mckibben,mccutchen,mcavoy,mcadoo,mayorga,mastin,martineau,marek,madore,leflore,kroeger,kennon,jimerson,hostetter,hornback,hendley,hance,guardado,granado,gowen,goodale,flinn,fleetwood,fitz,durkee,duprey,dipietro,dilley,clyburn,brawley,beckley,arana,weatherby,vollmer,vestal,tunnell,trigg,tingle,takahashi,sweatt,storer,snapp,shiver,rooker,rathbun,poisson,perrine,perri,parmer,parke,pare,papa,palmieri,midkiff,mecham,mccomas,mcalpine,lovelady,lillard,lally,knopp,kile,kiger,haile,gupta,goldsberry,gilreath,fulks,friesen,franzen,flack,findlay,ferland,dreyer,dore,dennard,deckard,debose,crim,coulombe,chancey,cantor,branton,bissell,barns,woolard,witham,wasserman,spiegel,shoffner,scholz,ruch,rossman,petry,palacio,paez,neary,mortenson,millsap,miele,menke,mckim,mcanally,martines,lemley,larochelle,klaus,klatt,kaufmann,kapp,helmer,hedge,halloran,glisson,frechette,fontana,eagan,distefano,danley,creekmore,chartier,chaffee,carillo,burg,bolinger,berkley,benz,basso,bash,zelaya,woodring,witkowski,wilmot,wilkens,wieland,verdugo,urquhart,tsai,timms,swiger,swaim,sussman,pires,molnar,mcatee,lowder,loos,linker,landes,kingery,hufford,higa,hendren,hammack,hamann,gillam,gerhardt,edelman,delk,deans,curl,constantine,cleaver,claar,casiano,carruth,carlyle,brophy,bolanos,bibbs,bessette,beggs,baugher,bartel,averill,andresen,amin,adames,valente,turnbow,swink,sublett,stroh,stringfellow,ridgway,pugliese,poteat,ohare,neubauer,murchison,mingo,lemmons,kwon,kellam,kean,jarmon,hyden,hudak,hollinger,henkel,hemingway,hasson,hansel,halter,haire,ginsberg,gillispie,fogel,flory,etter,elledge,eckman,deas,currin,crafton,coomer,colter,claxton,bulter,braddock,bowyer,binns,bellows,baskerville,barros,ansley,woolf,wight,waldman,wadley,tull,trull,tesch,stouffer,stadler,slay,shubert,sedillo,santacruz,reinke,poynter,neri,neale,mowry,moralez,monger,mitchum,merryman,manion,macdougall,litchfield,levitt,lepage,lasalle,khoury,kavanagh,karns,ivie,huebner,hodgkins,halpin,garica,eversole,dutra,dunagan,duffey,dillman,dillion,deville,dearborn,damato,courson,coulson,burdine,bousquet,bonin,bish,atencio,westbrooks,wages,vaca,toner,tillis,swett,struble,stanfill,solorzano,slusher,sipple,silvas,shults,schexnayder,saez,rodas,rager,pulver,penton,paniagua,meneses,mcfarlin,mcauley,matz,maloy,magruder,lohman,landa,lacombe,jaimes,holzer,holst,heil,hackler,grundy,gilkey,farnham,durfee,dunton,dunston,duda,dews,craver,corriveau,conwell,colella,chambless,bremer,boutte,bourassa,blaisdell,backman,babineaux,audette,alleman,towner,taveras,tarango,sullins,suiter,stallard,solberg,schlueter,poulos,pimental,owsley,okelley,moffatt,metcalfe,meekins,medellin,mcglynn,mccowan,marriott,marable,lennox,lamoureux,koss,kerby,karp,isenberg,howze,hockenberry,highsmith,hallmark,gusman,greeley,giddings,gaudet,gallup,fleenor,eicher,edington,dimaggio,dement,demello,decastro,bushman,brundage,brooker,bourg,blackstock,bergmann,beaton,banister,argo,appling,wortman,watterson,villalpando,tillotson,tighe,sundberg,sternberg,stamey,shipe,seeger,scarberry,sattler,sain,rothstein,poteet,plowman,pettiford,penland,partain,pankey,oyler,ogletree,ogburn,moton,merkel,lucier,lakey,kratz,kinser,kershaw,josephson,imhoff,hendry,hammon,frisbie,frawley,fraga,forester,eskew,emmert,drennan,doyon,dandridge,cawley,carvajal,bracey,belisle,batey,ahner,wysocki,weiser,veliz,tincher,sansone,sankey,sandstrom,rohrer,risner,pridemore,pfeffer,persinger,peery,oubre,nowicki,musgrave,murdoch,mullinax,mccary,mathieu,livengood,kyser,klink,kimes,kellner,kavanaugh,kasten,imes,hoey,hinshaw,hake,gurule,grube,grillo,geter,gatto,garver,garretson,farwell,eiland,dunford,decarlo,corso,colman,collard,cleghorn,chasteen,cavender,carlile,calvo,byerly,brogdon,broadwater,breault,bono,bergin,behr,ballenger,amick,tamez,stiffler,steinke,simmon,shankle,schaller,salmons,sackett,saad,rideout,ratcliffe,ranson,plascencia,petterson,olszewski,olney,olguin,nilsson,nevels,morelli,montiel,monge,michaelson,mertens,mcchesney,mcalpin,mathewson,loudermilk,lineberry,liggett,kinlaw,kight,jost,hereford,hardeman,halpern,halliday,hafer,gaul,friel,freitag,forsberg,evangelista,doering,dicarlo,dendy,delp,deguzman,dameron,curtiss,cosper,cauthen,bradberry,bouton,bonnell,bixby,bieber,beveridge,bedwell,barhorst,bannon,baltazar,baier,ayotte,attaway,arenas,abrego,turgeon,tunstall,thaxton,tenorio,stotts,sthilaire,shedd,seabolt,scalf,salyers,ruhl,rowlett,robinett,pfister,perlman,pepe,parkman,nunnally,norvell,napper,modlin,mckellar,mcclean,mascarenas,leibowitz,ledezma,kuhlman,kobayashi,hunley,holmquist,hinkley,hazard,hartsell,gribble,gravely,fifield,eliason,doak,crossland,carleton,bridgeman,bojorquez,boggess,auten,woosley,whiteley,wexler,twomey,tullis,townley,standridge,santoyo,rueda,riendeau,revell,pless,ottinger,nigro,nickles,mulvey,menefee,mcshane,mcloughlin,mckinzie,markey,lockridge,lipsey,knisley,knepper,kitts,kiel,jinks,hathcock,godin,gallego,fikes,fecteau,estabrook,ellinger,dunlop,dudek,countryman,chauvin,chatham,bullins,brownfield,boughton,bloodworth,bibb,baucom,barbieri,aubin,armitage,alessi,absher,abbate,zito,woolery,wiggs,wacker,tynes,tolle,telles,tarter,swarey,strode,stockdale,stalnaker,spina,schiff,saari,risley,rameriz,rakes,pettaway,penner,paulus,palladino,omeara,montelongo,melnick,mehta,mcgary,mccourt,mccollough,marchetti,manzanares,lowther,leiva,lauderdale,lafontaine,kowalczyk,knighton,joubert,jaworski,huth,hurdle,housley,hackman,gulick,gordy,gilstrap,gehrke,gebhart,gaudette,foxworth,endres,dunkle,cimino,caddell,brauer,braley,bodine,blackmore,belden,backer,ayer,andress,wisner,vuong,valliere,twigg,tavarez,strahan,steib,staub,sowder,seiber,schutt,scharf,schade,rodriques,risinger,renshaw,rahman,presnell,piatt,nieman,nevins,mcilwain,mcgaha,mccully,mccomb,massengale,macedo,lesher,kearse,jauregui,husted,hudnall,holmberg,hertel,hardie,glidewell,frausto,fassett,dalessandro,dahlgren,corum,constantino,conlin,colquitt,colombo,claycomb,cardin,buller,boney,bocanegra,biggers,benedetto,araiza,andino,albin,zorn,werth,weisman,walley,vanegas,ulibarri,towe,tedford,teasley,suttle,steffens,stcyr,squire,singley,sifuentes,shuck,schram,sass,rieger,ridenhour,rickert,richerson,rayborn,rabe,raab,pendley,pastore,ordway,moynihan,mellott,mckissick,mcgann,mccready,mauney,marrufo,lenhart,lazar,lafave,keele,kautz,jardine,jahnke,jacobo,hord,hardcastle,hageman,giglio,gehring,fortson,duque,duplessis,dicken,derosier,deitz,dalessio,cram,castleman,candelario,callison,caceres,bozarth,biles,bejarano,bashaw,avina,armentrout,alverez,acord,waterhouse,vereen,vanlandingham,strawser,shotwell,severance,seltzer,schoonmaker,schock,schaub,schaffner,roeder,rodrigez,riffe,rasberry,rancourt,railey,quade,pursley,prouty,perdomo,oxley,osterman,nickens,murphree,mounts,merida,maus,mattern,masse,martinelli,mangan,lutes,ludwick,loney,laureano,lasater,knighten,kissinger,kimsey,kessinger,honea,hollingshead,hockett,heyer,heron,gurrola,gove,glasscock,gillett,galan,featherstone,eckhardt,duron,dunson,dasher,culbreth,cowden,cowans,claypoole,churchwell,chabot,caviness,cater,caston,callan,byington,burkey,boden,beckford,atwater,archambault,alvey,alsup,whisenant,weese,voyles,verret,tsang,tessier,sweitzer,sherwin,shaughnessy,revis,remy,prine,philpott,peavy,paynter,parmenter,ovalle,offutt,nightingale,newlin,nakano,myatt,muth,mohan,mcmillon,mccarley,mccaleb,maxson,marinelli,maley,liston,letendre,kain,huntsman,hirst,hagerty,gulledge,greenway,grajeda,gorton,goines,gittens,frederickson,fanelli,embree,eichelberger,dunkin,dixson,dillow,defelice,chumley,burleigh,borkowski,binette,biggerstaff,berglund,beller,audet,arbuckle,allain,alfano,youngman,wittman,weintraub,vanzant,vaden,twitty,stollings,standifer,sines,shope,scalise,saville,posada,pisano,otte,nolasco,mier,merkle,mendiola,melcher,mejias,mcmurry,mccalla,markowitz,manis,mallette,macfarlane,lough,looper,landin,kittle,kinsella,kinnard,hobart,helman,hellman,hartsock,halford,hage,gordan,glasser,gayton,gattis,gastelum,gaspard,frisch,fitzhugh,eckstein,eberly,dowden,despain,crumpler,crotty,cornelison,chouinard,chamness,catlin,cann,bumgardner,budde,branum,bradfield,braddy,borst,birdwell,bazan,banas,bade,arango,ahearn,addis,zumwalt,wurth,wilk,widener,wagstaff,urrutia,terwilliger,tart,steinman,staats,sloat,rives,riggle,revels,reichard,prickett,poff,pitzer,petro,pell,northrup,nicks,moline,mielke,maynor,mallon,magness,lingle,lindell,lieb,lesko,lebeau,lammers,lafond,kiernan,ketron,jurado,holmgren,hilburn,hayashi,hashimoto,harbaugh,guillot,gard,froehlich,feinberg,falco,dufour,drees,doney,diep,delao,daves,dail,crowson,coss,congdon,carner,camarena,butterworth,burlingame,bouffard,bloch,bilyeu,barta,bakke,baillargeon,avent,aquilar,zeringue,yarber,wolfson,vogler,voelker,truss,troxell,thrift,strouse,spielman,sistrunk,sevigny,schuller,schaaf,ruffner,routh,roseman,ricciardi,peraza,pegram,overturf,olander,odaniel,millner,melchor,maroney,machuca,macaluso,livesay,layfield,laskowski,kwiatkowski,kilby,hovey,heywood,hayman,havard,harville,haigh,hagood,grieco,glassman,gebhardt,fleischer,fann,elson,eccles,cunha,crumb,blakley,bardwell,abshire,woodham,wines,welter,wargo,varnado,tutt,traynor,swaney,stricker,stoffel,stambaugh,sickler,shackleford,selman,seaver,sansom,sanmiguel,royston,rourke,rockett,rioux,puleo,pitchford,nardi,mulvaney,middaugh,malek,leos,lathan,kujawa,kimbro,killebrew,houlihan,hinckley,herod,hepler,hamner,hammel,hallowell,gonsalez,gingerich,gambill,funkhouser,fricke,fewell,falkner,endsley,dulin,drennen,deaver,dambrosio,chadwell,castanon,burkes,brune,brisco,brinker,bowker,boldt,berner,beaumont,beaird,bazemore,barrick,albano,younts,wunderlich,weidman,vanness,toland,theobald,stickler,steiger,stanger,spies,spector,sollars,smedley,seibel,scoville,saito,rummel,rowles,rouleau,roos,rogan,roemer,ream,raya,purkey,priester,perreira,penick,paulin,parkins,overcash,oleson,neves,muldrow,minard,midgett,michalak,melgar,mcentire,mcauliffe,marte,lydon,lindholm,leyba,langevin,lagasse,lafayette,kesler,kelton,kaminsky,jaggers,humbert,huck,howarth,hinrichs,higley,gupton,guimond,gravois,giguere,fretwell,fontes,feeley,faucher,eichhorn,ecker,earp,dole,dinger,derryberry,demars,deel,copenhaver,collinsworth,colangelo,cloyd,claiborne,caulfield,carlsen,calzada,caffey,broadus,brenneman,bouie,bodnar,blaney,blanc,beltz,behling,barahona,yockey,winkle,windom,wimer,villatoro,trexler,teran,taliaferro,sydnor,swinson,snelling,smtih,simonton,simoneaux,simoneau,sherrer,seavey,scheel,rushton,rupe,ruano,rippy,reiner,reiff,rabinowitz,quach,penley,odle,nock,minnich,mckown,mccarver,mcandrew,longley,laux,lamothe,lafreniere,kropp,krick,kates,jepson,huie,howse,howie,henriques,haydon,haught,hatter,hartzog,harkey,grimaldo,goshorn,gormley,gluck,gilroy,gillenwater,giffin,fluker,feder,eyre,eshelman,eakins,detwiler,delrosario,davisson,catalan,canning,calton,brammer,botelho,blakney,bartell,averett,askins,aker,witmer,winkelman,widmer,whittier,weitzel,wardell,wagers,ullman,tupper,tingley,tilghman,talton,simard,seda,scheller,sala,rundell,rost,ribeiro,rabideau,primm,pinon,peart,ostrom,ober,nystrom,nussbaum,naughton,murr,moorhead,monti,monteiro,melson,meissner,mclin,mcgruder,marotta,makowski,majewski,madewell,lunt,lukens,leininger,lebel,lakin,kepler,jaques,hunnicutt,hungerford,hoopes,hertz,heins,halliburton,grosso,gravitt,glasper,gallman,gallaway,funke,fulbright,falgout,eakin,dostie,dorado,dewberry,derose,cutshall,crampton,costanzo,colletti,cloninger,claytor,chiang,campagna,burd,brokaw,broaddus,bretz,brainard,binford,bilbrey,alpert,aitken,ahlers,zajac,woolfolk,witten,windle,wayland,tramel,tittle,talavera,suter,straley,specht,sommerville,soloman,skeens,sigman,sibert,shavers,schuck,schmit,sartain,sabol,rosenblatt,rollo,rashid,rabb,polston,nyberg,northrop,navarra,muldoon,mikesell,mcdougald,mcburney,mariscal,lozier,lingerfelt,legere,latour,lagunas,lacour,kurth,killen,kiely,kayser,kahle,isley,huertas,hower,hinz,haugh,gumm,galicia,fortunato,flake,dunleavy,duggins,doby,digiovanni,devaney,deltoro,cribb,corpuz,coronel,coen,charbonneau,caine,burchette,blakey,blakemore,bergquist,beene,beaudette,bayles,ballance,bakker,bailes,asberry,arwood,zucker,willman,whitesell,wald,walcott,vancleave,trump,strasser,simas,shick,schleicher,schaal,saleh,rotz,resnick,rainer,partee,ollis,oller,oday,noles,munday,mong,millican,merwin,mazzola,mansell,magallanes,llanes,lewellen,lepore,kisner,keesee,jeanlouis,ingham,hornbeck,hawn,hartz,harber,haffner,gutshall,guth,grays,gowan,finlay,finkelstein,eyler,enloe,dungan,diez,dearman,cull,crosson,chronister,cassity,campion,callihan,butz,breazeale,blumenthal,berkey,batty,batton,arvizu,alderete,aldana,albaugh,abernethy,wolter,wille,tweed,tollefson,thomasson,teter,testerman,sproul,spates,southwick,soukup,skelly,senter,sealey,sawicki,sargeant,rossiter,rosemond,repp,pifer,ormsby,nickelson,naumann,morabito,monzon,millsaps,millen,mcelrath,marcoux,mantooth,madson,macneil,mackinnon,louque,leister,lampley,kushner,krouse,kirwan,jessee,janson,jahn,jacquez,islas,hutt,holladay,hillyer,hepburn,hensel,harrold,gingrich,geis,gales,fults,finnell,ferri,featherston,epley,ebersole,eames,dunigan,drye,dismuke,devaughn,delorenzo,damiano,confer,collum,clower,clow,claussen,clack,caylor,cawthon,casias,carreno,bluhm,bingaman,bewley,belew,beckner,auld,amey,wolfenbarger,wilkey,wicklund,waltman,villalba,valero,valdovinos,ullrich,tyus,twyman,trost,tardif,tanguay,stripling,steinbach,shumpert,sasaki,sappington,sandusky,reinhold,reinert,quijano,placencia,pinkard,phinney,perrotta,pernell,parrett,oxendine,owensby,orman,nuno,mori,mcroberts,mcneese,mckamey,mccullum,markel,mardis,maines,lueck,lubin,lefler,leffler,larios,labarbera,kershner,josey,jeanbaptiste,izaguirre,hermosillo,haviland,hartshorn,hafner,ginter,getty,franck,fiske,dufrene,doody,davie,dangerfield,dahlberg,cuthbertson,crone,coffelt,chidester,chesson,cauley,caudell,cantara,campo,caines,bullis,bucci,brochu,bogard,bickerstaff,benning,arzola,antonelli,adkinson,zellers,wulf,worsley,woolridge,whitton,westerfield,walczak,vassar,truett,trueblood,trawick,townsley,topping,tobar,telford,steverson,stagg,sitton,sill,sergent,schoenfeld,sarabia,rutkowski,rubenstein,rigdon,prentiss,pomerleau,plumlee,philbrick,patnode,oloughlin,obregon,nuss,morell,mikell,mele,mcinerney,mcguigan,mcbrayer,lollar,kuehl,kinzer,kamp,joplin,jacobi,howells,holstein,hedden,hassler,harty,halle,greig,gouge,goodrum,gerhart,geier,geddes,gast,forehand,ferree,fendley,feltner,esqueda,encarnacion,eichler,egger,edmundson,eatmon,doud,donohoe,donelson,dilorenzo,digiacomo,diggins,delozier,dejong,danford,crippen,coppage,cogswell,clardy,cioffi,cabe,brunette,bresnahan,blomquist,blackstone,biller,bevis,bevan,bethune,benbow,baty,basinger,balcom,andes,aman,aguero,adkisson,yandell,wilds,whisenhunt,weigand,weeden,voight,villar,trottier,tillett,suazo,setser,scurry,schuh,schreck,schauer,samora,roane,rinker,reimers,ratchford,popovich,parkin,natal,melville,mcbryde,magdaleno,loehr,lockman,lingo,leduc,larocca,lamere,laclair,krall,korte,koger,jalbert,hughs,higbee,henton,heaney,haith,gump,greeson,goodloe,gholston,gasper,gagliardi,fregoso,farthing,fabrizio,ensor,elswick,elgin,eklund,eaddy,drouin,dorton,dizon,derouen,deherrera,davy,dampier,cullum,culley,cowgill,cardoso,cardinale,brodsky,broadbent,brimmer,briceno,branscum,bolyard,boley,bennington,beadle,baur,ballentine,azure,aultman,arciniega,aguila,aceves,yepez,woodrum,wethington,weissman,veloz,trusty,troup,trammel,tarpley,stivers,steck,sprayberry,spraggins,spitler,spiers,sohn,seagraves,schiffman,rudnick,rizo,riccio,rennie,quackenbush,puma,plott,pearcy,parada,paiz,munford,moskowitz,mease,mcnary,mccusker,lozoya,longmire,loesch,lasky,kuhlmann,krieg,koziol,kowalewski,konrad,kindle,jowers,jolin,jaco,horgan,hine,hileman,hepner,heise,heady,hawkinson,hannigan,haberman,guilford,grimaldi,garton,gagliano,fruge,follett,fiscus,ferretti,ebner,easterday,eanes,dirks,dimarco,depalma,deforest,cruce,craighead,christner,candler,cadwell,burchell,buettner,brinton,brazier,brannen,brame,bova,bomar,blakeslee,belknap,bangs,balzer,athey,armes,alvis,alverson,alvardo,yeung,wheelock,westlund,wessels,volkman,threadgill,thelen,tague,symons,swinford,sturtevant,straka,stier,stagner,segarra,seawright,rutan,roux,ringler,riker,ramsdell,quattlebaum,purifoy,poulson,permenter,peloquin,pasley,pagel,osman,obannon,nygaard,newcomer,munos,motta,meadors,mcquiston,mcniel,mcmann,mccrae,mayne,matte,legault,lechner,kucera,krohn,kratzer,koopman,jeske,horrocks,hock,hibbler,hesson,hersh,harvin,halvorsen,griner,grindle,gladstone,garofalo,frampton,forbis,eddington,diorio,dingus,dewar,desalvo,curcio,creasy,cortese,cordoba,connally,cluff,cascio,capuano,canaday,calabro,bussard,brayton,borja,bigley,arnone,arguelles,acuff,zamarripa,wooton,widner,wideman,threatt,thiele,templin,teeters,synder,swint,swick,sturges,stogner,stedman,spratt,siegfried,shetler,scull,savino,sather,rothwell,rook,rone,rhee,quevedo,privett,pouliot,poche,pickel,petrillo,pellegrini,peaslee,partlow,otey,nunnery,morelock,morello,meunier,messinger,mckie,mccubbin,mccarron,lerch,lavine,laverty,lariviere,lamkin,kugler,krol,kissel,keeter,hubble,hickox,hetzel,hayner,hagy,hadlock,groh,gottschalk,goodsell,gassaway,garrard,galligan,firth,fenderson,feinstein,etienne,engleman,emrick,ellender,drews,doiron,degraw,deegan,dart,crissman,corr,cookson,coil,cleaves,charest,chapple,chaparro,castano,carpio,byer,bufford,bridgewater,bridgers,brandes,borrero,bonanno,aube,ancheta,abarca,abad,wooster,wimbush,willhite,willams,wigley,weisberg,wardlaw,vigue,vanhook,unknow,torre,tasker,tarbox,strachan,slover,shamblin,semple,schuyler,schrimsher,sayer,salzman,rubalcava,riles,reneau,reichel,rayfield,rabon,pyatt,prindle,poss,polito,plemmons,pesce,perrault,pereyra,ostrowski,nilsen,niemeyer,munsey,mundell,moncada,miceli,meader,mcmasters,mckeehan,matsumoto,marron,marden,lizarraga,lingenfelter,lewallen,langan,lamanna,kovac,kinsler,kephart,keown,kass,kammerer,jeffreys,hysell,hosmer,hardnett,hanner,guyette,greening,glazer,ginder,fromm,fluellen,finkle,fessler,essary,eisele,duren,dittmer,crochet,cosentino,cogan,coelho,cavin,carrizales,campuzano,brough,bopp,bookman,bobb,blouin,beesley,battista,bascom,bakken,badgett,arneson,anselmo,albino,ahumada,woodyard,wolters,wireman,willison,warman,waldrup,vowell,vantassel,twombly,toomer,tennison,teets,tedeschi,swanner,stutz,stelly,sheehy,schermerhorn,scala,sandidge,salters,salo,saechao,roseboro,rolle,ressler,renz,renn,redford,raposa,rainbolt,pelfrey,orndorff,oney,nolin,nimmons,nardone,myhre,morman,menjivar,mcglone,mccammon,maxon,marciano,manus,lowrance,lorenzen,lonergan,lollis,littles,lindahl,lamas,lach,kuster,krawczyk,knuth,knecht,kirkendall,keitt,keever,kantor,jarboe,hoye,houchens,holter,holsinger,hickok,helwig,helgeson,hassett,harner,hamman,hames,hadfield,goree,goldfarb,gaughan,gaudreau,gantz,gallion,frady,foti,flesher,ferrin,faught,engram,donegan,desouza,degroot,cutright,crowl,criner,coan,clinkscales,chewning,chavira,catchings,carlock,bulger,buenrostro,bramblett,brack,boulware,bookout,bitner,birt,baranowski,baisden,allmon,acklin,yoakum,wilbourn,whisler,weinberger,washer,vasques,vanzandt,vanatta,troxler,tomes,tindle,tims,throckmorton,thach,stpeter,stlaurent,stenson,spry,spitz,songer,snavely,shroyer,shortridge,shenk,sevier,seabrook,scrivner,saltzman,rosenberry,rockwood,robeson,roan,reiser,ramires,raber,posner,popham,piotrowski,pinard,peterkin,pelham,peiffer,peay,nadler,musso,millett,mestas,mcgowen,marques,marasco,manriquez,manos,mair,lipps,leiker,krumm,knorr,kinslow,kessel,kendricks,kelm,irick,ickes,hurlburt,horta,hoekstra,heuer,helmuth,heatherly,hampson,hagar,haga,greenlaw,grau,godbey,gingras,gillies,gibb,gayden,gauvin,garrow,fontanez,florio,finke,fasano,ezzell,ewers,eveland,eckenrode,duclos,drumm,dimmick,delancey,defazio,dashiell,cusack,crowther,crigger,cray,coolidge,coldiron,cleland,chalfant,cassel,camire,cabrales,broomfield,brittingham,brisson,brickey,braziel,brazell,bragdon,boulanger,boman,bohannan,beem,barre,azar,ashbaugh,armistead,almazan,adamski,zendejas,winburn,willaims,wilhoit,westberry,wentzel,wendling,visser,vanscoy,vankirk,vallee,tweedy,thornberry,sweeny,spradling,spano,smelser,shim,sechrist,schall,scaife,rugg,rothrock,roesler,riehl,ridings,render,ransdell,radke,pinero,petree,pendergast,peluso,pecoraro,pascoe,panek,oshiro,navarrette,murguia,moores,moberg,michaelis,mcwhirter,mcsweeney,mcquade,mccay,mauk,mariani,marceau,mandeville,maeda,lunde,ludlow,loeb,lindo,linderman,leveille,leith,larock,lambrecht,kulp,kinsley,kimberlin,kesterson,hoyos,helfrich,hanke,grisby,goyette,gouveia,glazier,gile,gerena,gelinas,gasaway,funches,fujimoto,flynt,fenske,fellers,fehr,eslinger,escalera,enciso,duley,dittman,dineen,diller,devault,collings,clymer,clowers,chavers,charland,castorena,castello,camargo,bunce,bullen,boyes,borchers,borchardt,birnbaum,birdsall,billman,benites,bankhead,ange,ammerman,adkison,winegar,wickman,warr,warnke,villeneuve,veasey,vassallo,vannatta,vadnais,twilley,towery,tomblin,tippett,theiss,talkington,talamantes,swart,swanger,streit,stines,stabler,spurling,sobel,sine,simmers,shippy,shiflett,shearin,sauter,sanderlin,rusch,runkle,ruckman,rorie,roesch,richert,rehm,randel,ragin,quesenberry,puentes,plyler,plotkin,paugh,oshaughnessy,ohalloran,norsworthy,niemann,nader,moorefield,mooneyham,modica,miyamoto,mickel,mebane,mckinnie,mazurek,mancilla,lukas,lovins,loughlin,lotz,lindsley,liddle,levan,lederman,leclaire,lasseter,lapoint,lamoreaux,lafollette,kubiak,kirtley,keffer,kaczmarek,housman,hiers,hibbert,herrod,hegarty,hathorn,greenhaw,grafton,govea,futch,furst,franko,forcier,foran,flickinger,fairfield,eure,emrich,embrey,edgington,ecklund,eckard,durante,deyo,delvecchio,dade,currey,creswell,cottrill,casavant,cartier,cargile,capel,cammack,calfee,burse,burruss,brust,brousseau,bridwell,braaten,borkholder,bloomquist,bjork,bartelt,amburgey,yeary,whitefield,vinyard,vanvalkenburg,twitchell,timmins,tapper,stringham,starcher,spotts,slaugh,simonsen,sheffer,sequeira,rosati,rhymes,quint,pollak,peirce,patillo,parkerson,paiva,nilson,nevin,narcisse,mitton,merriam,merced,meiners,mckain,mcelveen,mcbeth,marsden,marez,manke,mahurin,mabrey,luper,krull,hunsicker,hornbuckle,holtzclaw,hinnant,heston,hering,hemenway,hegwood,hearns,halterman,guiterrez,grote,granillo,grainger,glasco,gilder,garren,garlock,garey,fryar,fredricks,fraizer,foshee,ferrel,felty,everitt,evens,esser,elkin,eberhart,durso,duguay,driskill,doster,dewall,deveau,demps,demaio,delreal,deleo,darrah,cumberbatch,culberson,cranmer,cordle,colgan,chesley,cavallo,castellon,castelli,carreras,carnell,carlucci,bontrager,blumberg,blasingame,becton,artrip,andujar,alkire,alder,zukowski,zuckerman,wroblewski,wrigley,woodside,wigginton,westman,westgate,werts,washam,wardlow,walser,waiters,tadlock,stringfield,stimpson,stickley,standish,spurlin,spindler,speller,spaeth,sotomayor,sluder,shryock,shepardson,shatley,scannell,santistevan,rosner,resto,reinhard,rathburn,prisco,poulsen,pinney,phares,pennock,pastrana,oviedo,ostler,nauman,mulford,moise,moberly,mirabal,metoyer,metheny,mentzer,meldrum,mcinturff,mcelyea,mcdougle,massaro,lumpkins,loveday,lofgren,lirette,lesperance,lefkowitz,ledger,lauzon,lachapelle,klassen,keough,kempton,kaelin,jeffords,hsieh,hoyer,horwitz,hoeft,hennig,haskin,gourdine,golightly,girouard,fulgham,fritsch,freer,frasher,foulk,firestone,fiorentino,fedor,ensley,englehart,eells,dunphy,donahoe,dileo,dibenedetto,dabrowski,crick,coonrod,conder,coddington,chunn,chaput,cerna,carreiro,calahan,braggs,bourdon,bollman,bittle,bauder,barreras,aubuchon,anzalone,adamo,zerbe,willcox,westberg,weikel,waymire,vroman,vinci,vallejos,truesdell,troutt,trotta,tollison,toles,tichenor,symonds,surles,strayer,stgeorge,sroka,sorrentino,solares,snelson,silvestri,sikorski,shawver,schumaker,schorr,schooley,scates,satterlee,satchell,rymer,roselli,robitaille,riegel,regis,reames,provenzano,priestley,plaisance,pettey,palomares,nowakowski,monette,minyard,mclamb,mchone,mccarroll,masson,magoon,maddy,lundin,licata,leonhardt,landwehr,kircher,kinch,karpinski,johannsen,hussain,houghtaling,hoskinson,hollaway,holeman,hobgood,hiebert,goggin,geissler,gadbois,gabaldon,fleshman,flannigan,fairman,eilers,dycus,dunmire,duffield,dowler,deloatch,dehaan,deemer,clayborn,christofferso,chilson,chesney,chatfield,carron,canale,brigman,branstetter,bosse,borton,bonar,biron,barroso,arispe,zacharias,zabel,yaeger,woolford,whetzel,weakley,veatch,vandeusen,tufts,troxel,troche,traver,townsel,talarico,swilley,sterrett,stenger,speakman,sowards,sours,souders,souder,soles,sobers,snoddy,smither,shute,shoaf,shahan,schuetz,scaggs,santini,rosson,rolen,robidoux,rentas,recio,pixley,pawlowski,pawlak,paull,overbey,orear,oliveri,oldenburg,nutting,naugle,mossman,misner,milazzo,michelson,mcentee,mccullar,mccree,mcaleer,mazzone,mandell,manahan,malott,maisonet,mailloux,lumley,lowrie,louviere,lipinski,lindemann,leppert,leasure,labarge,kubik,knisely,knepp,kenworthy,kennelly,kelch,kanter,houchin,hosley,hosler,hollon,holleman,heitman,haggins,gwaltney,goulding,gorden,geraci,gathers,frison,feagin,falconer,espada,erving,erikson,eisenhauer,ebeling,durgin,dowdle,dinwiddie,delcastillo,dedrick,crimmins,covell,cournoyer,coria,cohan,cataldo,carpentier,canas,campa,brode,brashears,blaser,bicknell,bednar,barwick,ascencio,althoff,almodovar,alamo,zirkle,zabala,wolverton,winebrenner,wetherell,westlake,wegener,weddington,tuten,trosclair,tressler,theroux,teske,swinehart,swensen,sundquist,southall,socha,sizer,silverberg,shortt,shimizu,sherrard,shaeffer,scheid,scheetz,saravia,sanner,rubinstein,rozell,romer,rheaume,reisinger,randles,pullum,petrella,payan,nordin,norcross,nicoletti,nicholes,newbold,nakagawa,monteith,milstead,milliner,mellen,mccardle,liptak,leitch,latimore,larrison,landau,laborde,koval,izquierdo,hymel,hoskin,holte,hoefer,hayworth,hausman,harrill,harrel,hardt,gully,groover,grinnell,greenspan,graver,grandberry,gorrell,goldenberg,goguen,gilleland,fuson,feldmann,everly,dyess,dunnigan,downie,dolby,deatherage,cosey,cheever,celaya,caver,cashion,caplinger,cansler,byrge,bruder,breuer,breslin,brazelton,botkin,bonneau,bondurant,bohanan,bogue,bodner,boatner,blatt,bickley,belliveau,beiler,beier,beckstead,bachmann,atkin,altizer,alloway,allaire,albro,abron,zellmer,yetter,yelverton,wiens,whidden,viramontes,vanwormer,tarantino,tanksley,sumlin,strauch,strang,stice,spahn,sosebee,sigala,shrout,seamon,schrum,schneck,schantz,ruddy,romig,roehl,renninger,reding,polak,pohlman,pasillas,oldfield,oldaker,ohanlon,ogilvie,norberg,nolette,neufeld,nellis,mummert,mulvihill,mullaney,monteleone,mendonca,meisner,mcmullan,mccluney,mattis,massengill,manfredi,luedtke,lounsbury,liberatore,lamphere,laforge,jourdan,iorio,iniguez,ikeda,hubler,hodgdon,hocking,heacock,haslam,haralson,hanshaw,hannum,hallam,haden,garnes,garces,gammage,gambino,finkel,faucett,ehrhardt,eggen,dusek,durrant,dubay,dones,depasquale,delucia,degraff,decamp,davalos,cullins,conard,clouser,clontz,cifuentes,chappel,chaffins,celis,carwile,byram,bruggeman,bressler,brathwaite,brasfield,bradburn,boose,bodie,blosser,bertsch,bernardi,bernabe,bengtson,barrette,astorga,alday,albee,abrahamson,yarnell,wiltse,wiebe,waguespack,vasser,upham,turek,traxler,torain,tomaszewski,tinnin,tiner,tindell,styron,stahlman,staab,skiba,sheperd,seidl,secor,schutte,sanfilippo,ruder,rondon,rearick,procter,prochaska,pettengill,pauly,neilsen,nally,mullenax,morano,meads,mcnaughton,mcmurtry,mcmath,mckinsey,matthes,massenburg,marlar,margolis,malin,magallon,mackin,lovette,loughran,loring,longstreet,loiselle,lenihan,kunze,koepke,kerwin,kalinowski,kagan,innis,innes,holtzman,heinemann,harshman,haider,haack,grondin,grissett,greenawalt,goudy,goodlett,goldston,gokey,gardea,galaviz,gafford,gabrielson,furlow,fritch,fordyce,folger,elizalde,ehlert,eckhoff,eccleston,ealey,dubin,diemer,deschamps,delapena,decicco,debolt,cullinan,crittendon,crase,cossey,coppock,coots,colyer,cluck,chamberland,burkhead,bumpus,buchan,borman,birkholz,berardi,benda,behnke,barter,amezquita,wotring,wirtz,wingert,wiesner,whitesides,weyant,wainscott,venezia,varnell,tussey,thurlow,tabares,stiver,stell,starke,stanhope,stanek,sisler,sinnott,siciliano,shehan,selph,seager,scurlock,scranton,santucci,santangelo,saltsman,rogge,rettig,renwick,reidy,reider,redfield,premo,parente,paolucci,palmquist,ohler,netherton,mutchler,morita,mistretta,minnis,middendorf,menzel,mendosa,mendelson,meaux,mcspadden,mcquaid,mcnatt,manigault,maney,mager,lukes,lopresti,liriano,letson,lechuga,lazenby,lauria,larimore,krupp,krupa,kopec,kinchen,kifer,kerney,kerner,kennison,kegley,karcher,justis,johson,jellison,janke,huskins,holzman,hinojos,hefley,hatmaker,harte,halloway,hallenbeck,goodwyn,glaspie,geise,fullwood,fryman,frakes,fraire,farrer,enlow,engen,ellzey,eckles,earles,dunkley,drinkard,dreiling,draeger,dinardo,dills,desroches,desantiago,curlee,crumbley,critchlow,coury,courtright,coffield,cleek,charpentier,cardone,caples,cantin,buntin,bugbee,brinkerhoff,brackin,bourland,blassingame,beacham,banning,auguste,andreasen,amann,almon,alejo,adelman,abston,yerger,wymer,woodberry,windley,whiteaker,westfield,weibel,wanner,waldrep,villani,vanarsdale,utterback,updike,triggs,topete,tolar,tigner,thoms,tauber,tarvin,tally,swiney,sweatman,studebaker,stennett,starrett,stannard,stalvey,sonnenberg,smithey,sieber,sickles,shinault,segars,sanger,salmeron,rothe,rizzi,restrepo,ralls,ragusa,quiroga,papenfuss,oropeza,okane,mudge,mozingo,molinaro,mcvicker,mcgarvey,mcfalls,mccraney,matus,magers,llanos,livermore,linehan,leitner,laymon,lawing,lacourse,kwong,kollar,kneeland,kennett,kellett,kangas,janzen,hutter,huling,hofmeister,hewes,harjo,habib,guice,grullon,greggs,grayer,granier,grable,gowdy,giannini,getchell,gartman,garnica,ganey,gallimore,fetters,fergerson,farlow,fagundes,exley,esteves,enders,edenfield,easterwood,drakeford,dipasquale,desousa,deshields,deeter,dedmon,debord,daughtery,cutts,courtemanche,coursey,copple,coomes,collis,cogburn,clopton,choquette,chaidez,castrejon,calhoon,burbach,bulloch,buchman,bruhn,bohon,blough,baynes,barstow,zeman,zackery,yardley,yamashita,wulff,wilken,wiliams,wickersham,wible,whipkey,wedgeworth,walmsley,walkup,vreeland,verrill,umana,traub,swingle,summey,stroupe,stockstill,steffey,stefanski,statler,stapp,speights,solari,soderberg,shunk,shorey,shewmaker,sheilds,schiffer,schank,schaff,sagers,rochon,riser,rickett,reale,raglin,polen,plata,pitcock,percival,palen,orona,oberle,nocera,navas,nault,mullings,montejano,monreal,minick,middlebrook,meece,mcmillion,mccullen,mauck,marshburn,maillet,mahaney,magner,maclin,lucey,litteral,lippincott,leite,leaks,lamarre,jurgens,jerkins,jager,hurwitz,hughley,hotaling,horstman,hohman,hocker,hively,hipps,hessler,hermanson,hepworth,helland,hedlund,harkless,haigler,gutierez,grindstaff,glantz,giardina,gerken,gadsden,finnerty,farnum,encinas,drakes,dennie,cutlip,curtsinger,couto,cortinas,corby,chiasson,carle,carballo,brindle,borum,bober,blagg,berthiaume,beahm,batres,basnight,backes,axtell,atterberry,alvares,alegria,woodell,wojciechowski,winfree,winbush,wiest,wesner,wamsley,wakeman,verner,truex,trafton,toman,thorsen,theus,tellier,tallant,szeto,strope,stills,simkins,shuey,shaul,servin,serio,serafin,salguero,ryerson,rudder,ruark,rother,rohrbaugh,rohrbach,rohan,rogerson,risher,reeser,pryce,prokop,prins,priebe,prejean,pinheiro,petrone,petri,penson,pearlman,parikh,natoli,murakami,mullikin,mullane,motes,morningstar,mcveigh,mcgrady,mcgaughey,mccurley,marchan,manske,lusby,linde,likens,licon,leroux,lemaire,legette,laskey,laprade,laplant,kolar,kittredge,kinley,kerber,kanagy,jetton,janik,ippolito,inouye,hunsinger,howley,howery,horrell,holthaus,hiner,hilson,hilderbrand,hartzler,harnish,harada,hansford,halligan,hagedorn,gwynn,gudino,greenstein,greear,gracey,goudeau,goodner,ginsburg,gerth,gerner,fujii,frier,frenette,folmar,fleisher,fleischmann,fetzer,eisenman,earhart,dupuy,dunkelberger,drexler,dillinger,dilbeck,dewald,demby,deford,craine,chesnut,casady,carstens,carrick,carino,carignan,canchola,bushong,burman,buono,brownlow,broach,britten,brickhouse,boyden,boulton,borland,bohrer,blubaugh,bever,berggren,benevides,arocho,arends,amezcua,almendarez,zalewski,witzel,winkfield,wilhoite,vangundy,vanfleet,vanetten,vandergriff,urbanski,troiano,thibodaux,straus,stoneking,stjean,stillings,stange,speicher,speegle,smeltzer,slawson,simmonds,shuttleworth,serpa,senger,seidman,schweiger,schloss,schimmel,schechter,sayler,sabatini,ronan,rodiguez,riggleman,richins,reamer,prunty,porath,plunk,piland,philbrook,pettitt,perna,peralez,pascale,padula,oboyle,nivens,nickols,mundt,munden,montijo,mcmanis,mcgrane,mccrimmon,manzi,mangold,malick,mahar,maddock,losey,litten,leedy,leavell,ladue,krahn,kluge,junker,iversen,imler,hurtt,huizar,hubbert,howington,hollomon,holdren,hoisington,heiden,hauge,hartigan,gutirrez,griffie,greenhill,gratton,granata,gottfried,gertz,gautreaux,furry,furey,funderburg,flippen,fitzgibbon,drucker,donoghue,dildy,devers,detweiler,despres,denby,degeorge,cueto,cranston,courville,clukey,cirillo,chivers,caudillo,butera,bulluck,buckmaster,braunstein,bracamonte,bourdeau,bonnette".split(","),us_tv_and_film:"you,i,to,that,it,me,what,this,know,i'm,no,have,my,don't,just,not,do,be,your,we,it's,so,but,all,well,oh,about,right,you're,get,here,out,going,like,yeah,if,can,up,want,think,that's,now,go,him,how,got,did,why,see,come,good,really,look,will,okay,back,can't,mean,tell,i'll,hey,he's,could,didn't,yes,something,because,say,take,way,little,make,need,gonna,never,we're,too,she's,i've,sure,our,sorry,what's,let,thing,maybe,down,man,very,there's,should,anything,said,much,any,even,off,please,doing,thank,give,thought,help,talk,god,still,wait,find,nothing,again,things,let's,doesn't,call,told,great,better,ever,night,away,believe,feel,everything,you've,fine,last,keep,does,put,around,stop,they're,i'd,guy,isn't,always,listen,wanted,guys,huh,those,big,lot,happened,thanks,won't,trying,kind,wrong,talking,guess,care,bad,mom,remember,getting,we'll,together,dad,leave,understand,wouldn't,actually,hear,baby,nice,father,else,stay,done,wasn't,course,might,mind,every,enough,try,hell,came,someone,you'll,whole,yourself,idea,ask,must,coming,looking,woman,room,knew,tonight,real,son,hope,went,hmm,happy,pretty,saw,girl,sir,friend,already,saying,next,job,problem,minute,thinking,haven't,heard,honey,matter,myself,couldn't,exactly,having,probably,happen,we've,hurt,boy,dead,gotta,alone,excuse,start,kill,hard,you'd,today,car,ready,without,wants,hold,wanna,yet,seen,deal,once,gone,morning,supposed,friends,head,stuff,worry,live,truth,face,forget,true,cause,soon,knows,telling,wife,who's,chance,run,move,anyone,person,bye,somebody,heart,miss,making,meet,anyway,phone,reason,damn,lost,looks,bring,case,turn,wish,tomorrow,kids,trust,check,change,anymore,least,aren't,working,makes,taking,means,brother,hate,ago,says,beautiful,gave,fact,crazy,sit,afraid,important,rest,fun,kid,word,watch,glad,everyone,sister,minutes,everybody,bit,couple,whoa,either,mrs,feeling,daughter,wow,gets,asked,break,promise,door,close,hand,easy,question,tried,far,walk,needs,mine,killed,hospital,anybody,alright,wedding,shut,able,die,perfect,stand,comes,hit,waiting,dinner,funny,husband,almost,pay,answer,cool,eyes,news,child,shouldn't,yours,moment,sleep,read,where's,sounds,sonny,pick,sometimes,bed,date,plan,hours,lose,hands,serious,shit,behind,inside,ahead,week,wonderful,fight,past,cut,quite,he'll,sick,it'll,eat,nobody,goes,save,seems,finally,lives,worried,upset,carly,met,brought,seem,sort,safe,weren't,leaving,front,shot,loved,asking,running,clear,figure,hot,felt,parents,drink,absolutely,how's,daddy,sweet,alive,sense,meant,happens,bet,blood,ain't,kidding,lie,meeting,dear,seeing,sound,fault,ten,buy,hour,speak,lady,jen,thinks,christmas,outside,hang,possible,worse,mistake,ooh,handle,spend,totally,giving,here's,marriage,realize,unless,sex,send,needed,scared,picture,talked,ass,hundred,changed,completely,explain,certainly,sign,boys,relationship,loves,hair,lying,choice,anywhere,future,weird,luck,she'll,turned,touch,kiss,crane,questions,obviously,wonder,pain,calling,somewhere,throw,straight,cold,fast,words,food,none,drive,feelings,they'll,marry,drop,cannot,dream,protect,twenty,surprise,sweetheart,poor,looked,mad,except,gun,y'know,dance,takes,appreciate,especially,situation,besides,pull,hasn't,worth,sheridan,amazing,expect,swear,piece,busy,happening,movie,we'd,catch,perhaps,step,fall,watching,kept,darling,dog,honor,moving,till,admit,problems,murder,he'd,evil,definitely,feels,honest,eye,broke,missed,longer,dollars,tired,evening,starting,entire,trip,niles,suppose,calm,imagine,fair,caught,blame,sitting,favor,apartment,terrible,clean,learn,frasier,relax,accident,wake,prove,smart,message,missing,forgot,interested,table,nbsp,mouth,pregnant,ring,careful,shall,dude,ride,figured,wear,shoot,stick,follow,angry,write,stopped,ran,standing,forgive,jail,wearing,ladies,kinda,lunch,cristian,greenlee,gotten,hoping,phoebe,thousand,ridge,paper,tough,tape,count,boyfriend,proud,agree,birthday,they've,share,offer,hurry,feet,wondering,decision,ones,finish,voice,herself,would've,mess,deserve,evidence,cute,dress,interesting,hotel,enjoy,quiet,concerned,staying,beat,sweetie,mention,clothes,fell,neither,mmm,fix,respect,prison,attention,holding,calls,surprised,bar,keeping,gift,hadn't,putting,dark,owe,ice,helping,normal,aunt,lawyer,apart,plans,jax,girlfriend,floor,whether,everything's,box,judge,upstairs,sake,mommy,possibly,worst,acting,accept,blow,strange,saved,conversation,plane,mama,yesterday,lied,quick,lately,stuck,difference,store,she'd,bought,doubt,listening,walking,cops,deep,dangerous,buffy,sleeping,chloe,rafe,join,card,crime,gentlemen,willing,window,walked,guilty,likes,fighting,difficult,soul,joke,favorite,uncle,promised,bother,seriously,cell,knowing,broken,advice,somehow,paid,losing,push,helped,killing,boss,liked,innocent,rules,learned,thirty,risk,letting,speaking,ridiculous,afternoon,apologize,nervous,charge,patient,boat,how'd,hide,detective,planning,huge,breakfast,horrible,awful,pleasure,driving,hanging,picked,sell,quit,apparently,dying,notice,congratulations,visit,could've,c'mon,letter,decide,forward,fool,showed,smell,seemed,spell,memory,pictures,slow,seconds,hungry,hearing,kitchen,ma'am,should've,realized,kick,grab,discuss,fifty,reading,idiot,suddenly,agent,destroy,bucks,shoes,peace,arms,demon,livvie,consider,papers,incredible,witch,drunk,attorney,tells,knock,ways,gives,nose,skye,turns,keeps,jealous,drug,sooner,cares,plenty,extra,outta,weekend,matters,gosh,opportunity,impossible,waste,pretend,jump,eating,proof,slept,arrest,breathe,perfectly,warm,pulled,twice,easier,goin,dating,suit,romantic,drugs,comfortable,finds,checked,divorce,begin,ourselves,closer,ruin,smile,laugh,treat,fear,what'd,otherwise,excited,mail,hiding,stole,pacey,noticed,fired,excellent,bringing,bottom,note,sudden,bathroom,honestly,sing,foot,remind,charges,witness,finding,tree,dare,hardly,that'll,steal,silly,contact,teach,shop,plus,colonel,fresh,trial,invited,roll,reach,dirty,choose,emergency,dropped,butt,credit,obvious,locked,loving,nuts,agreed,prue,goodbye,condition,guard,fuckin,grow,cake,mood,crap,crying,belong,partner,trick,pressure,dressed,taste,neck,nurse,raise,lots,carry,whoever,drinking,they'd,breaking,file,lock,wine,spot,paying,assume,asleep,turning,viki,bedroom,shower,nikolas,camera,fill,reasons,forty,bigger,nope,breath,doctors,pants,freak,movies,folks,cream,wild,truly,desk,convince,client,threw,hurts,spending,answers,shirt,chair,rough,doin,sees,ought,empty,wind,aware,dealing,pack,tight,hurting,guest,arrested,salem,confused,surgery,expecting,deacon,unfortunately,goddamn,bottle,beyond,whenever,pool,opinion,starts,jerk,secrets,falling,necessary,barely,dancing,tests,copy,cousin,ahem,twelve,tess,skin,fifteen,speech,orders,complicated,nowhere,escape,biggest,restaurant,grateful,usual,burn,address,someplace,screw,everywhere,regret,goodness,mistakes,details,responsibility,suspect,corner,hero,dumb,terrific,whoo,hole,memories,o'clock,teeth,ruined,bite,stenbeck,liar,showing,cards,desperate,search,pathetic,spoke,scare,marah,afford,settle,stayed,checking,hired,heads,concern,blew,alcazar,champagne,connection,tickets,happiness,saving,kissing,hated,personally,suggest,prepared,onto,downstairs,ticket,it'd,loose,holy,duty,convinced,throwing,kissed,legs,loud,saturday,babies,where'd,warning,miracle,carrying,blind,ugly,shopping,hates,sight,bride,coat,clearly,celebrate,brilliant,wanting,forrester,lips,custody,screwed,buying,toast,thoughts,reality,lexie,attitude,advantage,grandfather,sami,grandma,someday,roof,marrying,powerful,grown,grandmother,fake,must've,ideas,exciting,familiar,bomb,bout,harmony,schedule,capable,practically,correct,clue,forgotten,appointment,deserves,threat,bloody,lonely,shame,jacket,hook,scary,investigation,invite,shooting,lesson,criminal,victim,funeral,considering,burning,strength,harder,sisters,pushed,shock,pushing,heat,chocolate,miserable,corinthos,nightmare,brings,zander,crash,chances,sending,recognize,healthy,boring,feed,engaged,headed,treated,knife,drag,badly,hire,paint,pardon,behavior,closet,warn,gorgeous,milk,survive,ends,dump,rent,remembered,thanksgiving,rain,revenge,prefer,spare,pray,disappeared,aside,statement,sometime,meat,fantastic,breathing,laughing,stood,affair,ours,depends,protecting,jury,brave,fingers,murdered,explanation,picking,blah,stronger,handsome,unbelievable,anytime,shake,oakdale,wherever,pulling,facts,waited,lousy,circumstances,disappointed,weak,trusted,license,nothin,trash,understanding,slip,sounded,awake,friendship,stomach,weapon,threatened,mystery,vegas,understood,basically,switch,frankly,cheap,lifetime,deny,clock,garbage,why'd,tear,ears,indeed,changing,singing,tiny,decent,avoid,messed,filled,touched,disappear,exact,pills,kicked,harm,fortune,pretending,insurance,fancy,drove,cared,belongs,nights,lorelai,lift,timing,guarantee,chest,woke,burned,watched,heading,selfish,drinks,doll,committed,elevator,freeze,noise,wasting,ceremony,uncomfortable,staring,files,bike,stress,permission,thrown,possibility,borrow,fabulous,doors,screaming,bone,xander,what're,meal,apology,anger,honeymoon,bail,parking,fixed,wash,stolen,sensitive,stealing,photo,chose,lets,comfort,worrying,pocket,mateo,bleeding,shoulder,ignore,talent,tied,garage,dies,demons,dumped,witches,rude,crack,bothering,radar,soft,meantime,gimme,kinds,fate,concentrate,throat,prom,messages,intend,ashamed,somethin,manage,guilt,interrupt,guts,tongue,shoe,basement,sentence,purse,glasses,cabin,universe,repeat,mirror,wound,travers,tall,engagement,therapy,emotional,jeez,decisions,soup,thrilled,stake,chef,moves,extremely,moments,expensive,counting,shots,kidnapped,cleaning,shift,plate,impressed,smells,trapped,aidan,knocked,charming,attractive,argue,puts,whip,embarrassed,package,hitting,bust,stairs,alarm,pure,nail,nerve,incredibly,walks,dirt,stamp,terribly,friendly,damned,jobs,suffering,disgusting,stopping,deliver,riding,helps,disaster,bars,crossed,trap,talks,eggs,chick,threatening,spoken,introduce,confession,embarrassing,bags,impression,gate,reputation,presents,chat,suffer,argument,talkin,crowd,homework,coincidence,cancel,pride,solve,hopefully,pounds,pine,mate,illegal,generous,outfit,maid,bath,punch,freaked,begging,recall,enjoying,prepare,wheel,defend,signs,painful,yourselves,maris,that'd,suspicious,cooking,button,warned,sixty,pity,yelling,awhile,confidence,offering,pleased,panic,hers,gettin,refuse,grandpa,testify,choices,cruel,mental,gentleman,coma,cutting,proteus,guests,expert,benefit,faces,jumped,toilet,sneak,halloween,privacy,smoking,reminds,twins,swing,solid,options,commitment,crush,ambulance,wallet,gang,eleven,option,laundry,assure,stays,skip,fail,discussion,clinic,betrayed,sticking,bored,mansion,soda,sheriff,suite,handled,busted,load,happier,studying,romance,procedure,commit,assignment,suicide,minds,swim,yell,llanview,chasing,proper,believes,humor,hopes,lawyers,giant,latest,escaped,parent,tricks,insist,dropping,cheer,medication,flesh,routine,sandwich,handed,false,beating,warrant,awfully,odds,treating,thin,suggesting,fever,sweat,silent,clever,sweater,mall,sharing,assuming,judgment,goodnight,divorced,surely,steps,confess,math,listened,comin,answered,vulnerable,bless,dreaming,chip,zero,pissed,nate,kills,tears,knees,chill,brains,unusual,packed,dreamed,cure,lookin,grave,cheating,breaks,locker,gifts,awkward,thursday,joking,reasonable,dozen,curse,quartermaine,millions,dessert,rolling,detail,alien,delicious,closing,vampires,wore,tail,secure,salad,murderer,spit,offense,dust,conscience,bread,answering,lame,invitation,grief,smiling,pregnancy,prisoner,delivery,guards,virus,shrink,freezing,wreck,massimo,wire,technically,blown,anxious,cave,holidays,cleared,wishes,caring,candles,bound,charm,pulse,jumping,jokes,boom,occasion,silence,nonsense,frightened,slipped,dimera,blowing,relationships,kidnapping,spin,tool,roxy,packing,blaming,wrap,obsessed,fruit,torture,personality,there'll,fairy,necessarily,seventy,print,motel,underwear,grams,exhausted,believing,freaking,carefully,trace,touching,messing,recovery,intention,consequences,belt,sacrifice,courage,enjoyed,attracted,remove,testimony,intense,heal,defending,unfair,relieved,loyal,slowly,buzz,alcohol,surprises,psychiatrist,plain,attic,who'd,uniform,terrified,cleaned,zach,threaten,fella,enemies,satisfied,imagination,hooked,headache,forgetting,counselor,andie,acted,badge,naturally,frozen,sakes,appropriate,trunk,dunno,costume,sixteen,impressive,kicking,junk,grabbed,understands,describe,clients,owns,affect,witnesses,starving,instincts,happily,discussing,deserved,strangers,surveillance,admire,questioning,dragged,barn,deeply,wrapped,wasted,tense,hoped,fellas,roommate,mortal,fascinating,stops,arrangements,agenda,literally,propose,honesty,underneath,sauce,promises,lecture,eighty,torn,shocked,backup,differently,ninety,deck,biological,pheebs,ease,creep,waitress,telephone,ripped,raising,scratch,rings,prints,thee,arguing,ephram,asks,oops,diner,annoying,taggert,sergeant,blast,towel,clown,habit,creature,bermuda,snap,react,paranoid,handling,eaten,therapist,comment,sink,reporter,nurses,beats,priority,interrupting,warehouse,loyalty,inspector,pleasant,excuses,threats,guessing,tend,praying,motive,unconscious,mysterious,unhappy,tone,switched,rappaport,sookie,neighbor,loaded,swore,piss,balance,toss,misery,thief,squeeze,lobby,goa'uld,geez,exercise,forth,booked,sandburg,poker,eighteen,d'you,bury,everyday,digging,creepy,wondered,liver,hmmm,magical,fits,discussed,moral,helpful,searching,flew,depressed,aisle,cris,amen,vows,neighbors,darn,cents,arrange,annulment,useless,adventure,resist,fourteen,celebrating,inch,debt,violent,sand,teal'c,celebration,reminded,phones,paperwork,emotions,stubborn,pound,tension,stroke,steady,overnight,chips,beef,suits,boxes,cassadine,collect,tragedy,spoil,realm,wipe,surgeon,stretch,stepped,nephew,neat,limo,confident,perspective,climb,punishment,finest,springfield,hint,furniture,blanket,twist,proceed,fries,worries,niece,gloves,soap,signature,disappoint,crawl,convicted,flip,counsel,doubts,crimes,accusing,shaking,remembering,hallway,halfway,bothered,madam,gather,cameras,blackmail,symptoms,rope,ordinary,imagined,cigarette,supportive,explosion,trauma,ouch,furious,cheat,avoiding,whew,thick,oooh,boarding,approve,urgent,shhh,misunderstanding,drawer,phony,interfere,catching,bargain,tragic,respond,punish,penthouse,thou,rach,ohhh,insult,bugs,beside,begged,absolute,strictly,socks,senses,sneaking,reward,polite,checks,tale,physically,instructions,fooled,blows,tabby,bitter,adorable,y'all,tested,suggestion,jewelry,alike,jacks,distracted,shelter,lessons,constable,circus,audition,tune,shoulders,mask,helpless,feeding,explains,sucked,robbery,objection,behave,valuable,shadows,courtroom,confusing,talented,smarter,mistaken,customer,bizarre,scaring,motherfucker,alert,vecchio,reverend,foolish,compliment,bastards,worker,wheelchair,protective,gentle,reverse,picnic,knee,cage,wives,wednesday,voices,toes,stink,scares,pour,cheated,slide,ruining,filling,exit,cottage,upside,proves,parked,diary,complaining,confessed,pipe,merely,massage,chop,spill,prayer,betray,waiter,scam,rats,fraud,brush,tables,sympathy,pill,filthy,seventeen,employee,bracelet,pays,fairly,deeper,arrive,tracking,spite,shed,recommend,oughta,nanny,menu,diet,corn,roses,patch,dime,devastated,subtle,bullets,beans,pile,confirm,strings,parade,borrowed,toys,straighten,steak,premonition,planted,honored,exam,convenient,traveling,laying,insisted,dish,aitoro,kindly,grandson,donor,temper,teenager,proven,mothers,denial,backwards,tent,swell,noon,happiest,drives,thinkin,spirits,potion,holes,fence,whatsoever,rehearsal,overheard,lemme,hostage,bench,tryin,taxi,shove,moron,impress,needle,intelligent,instant,disagree,stinks,rianna,recover,groom,gesture,constantly,bartender,suspects,sealed,legally,hears,dresses,sheet,psychic,teenage,knocking,judging,accidentally,waking,rumor,manners,homeless,hollow,desperately,tapes,referring,item,genoa,gear,majesty,cried,tons,spells,instinct,quote,motorcycle,convincing,fashioned,aids,accomplished,grip,bump,upsetting,needing,invisible,forgiveness,feds,compare,bothers,tooth,inviting,earn,compromise,cocktail,tramp,jabot,intimate,dignity,dealt,souls,informed,gods,dressing,cigarettes,alistair,leak,fond,corky,seduce,liquor,fingerprints,enchantment,butters,stuffed,stavros,emotionally,transplant,tips,oxygen,nicely,lunatic,drill,complain,announcement,unfortunate,slap,prayers,plug,opens,oath,o'neill,mutual,yacht,remembers,fried,extraordinary,bait,warton,sworn,stare,safely,reunion,burst,might've,dive,aboard,expose,buddies,trusting,booze,sweep,sore,scudder,properly,parole,ditch,canceled,speaks,glow,wears,thirsty,skull,ringing,dorm,dining,bend,unexpected,pancakes,harsh,flattered,ahhh,troubles,fights,favourite,eats,rage,undercover,spoiled,sloane,shine,destroying,deliberately,conspiracy,thoughtful,sandwiches,plates,nails,miracles,fridge,drank,contrary,beloved,allergic,washed,stalking,solved,sack,misses,forgiven,bent,maciver,involve,dragging,cooked,pointing,foul,dull,beneath,heels,faking,deaf,stunt,jealousy,hopeless,fears,cuts,scenario,necklace,crashed,accuse,restraining,homicide,helicopter,firing,safer,auction,videotape,tore,reservations,pops,appetite,wounds,vanquish,ironic,fathers,excitement,anyhow,tearing,sends,rape,laughed,belly,dealer,cooperate,accomplish,wakes,spotted,sorts,reservation,ashes,tastes,supposedly,loft,intentions,integrity,wished,towels,suspected,investigating,inappropriate,lipstick,lawn,compassion,cafeteria,scarf,precisely,obsession,loses,lighten,infection,granddaughter,explode,balcony,this'll,spying,publicity,depend,cracked,conscious,ally,absurd,vicious,invented,forbid,directions,defendant,bare,announce,screwing,salesman,robbed,leap,lakeview,insanity,reveal,possibilities,kidnap,gown,chairs,wishing,setup,punished,criminals,regrets,raped,quarters,lamp,dentist,anyways,anonymous,semester,risks,owes,lungs,explaining,delicate,tricked,eager,doomed,adoption,stab,sickness,scum,floating,envelope,vault,sorel,pretended,potatoes,plea,photograph,payback,misunderstood,kiddo,healing,cascade,capeside,stabbed,remarkable,brat,privilege,passionate,nerves,lawsuit,kidney,disturbed,cozy,tire,shirts,oven,ordering,delay,risky,monsters,honorable,grounded,closest,breakdown,bald,abandon,scar,collar,worthless,sucking,enormous,disturbing,disturb,distract,deals,conclusions,vodka,dishes,crawling,briefcase,wiped,whistle,sits,roast,rented,pigs,flirting,deposit,bottles,topic,riot,overreacting,logical,hostile,embarrass,casual,beacon,amusing,altar,claus,survival,skirt,shave,porch,ghosts,favors,drops,dizzy,chili,advise,strikes,rehab,photographer,peaceful,leery,heavens,fortunately,fooling,expectations,cigar,weakness,ranch,practicing,examine,cranes,bribe,sail,prescription,hush,fragile,forensics,expense,drugged,cows,bells,visitor,suitcase,sorta,scan,manticore,insecure,imagining,hardest,clerk,wrist,what'll,starters,silk,pump,pale,nicer,haul,flies,boot,thumb,there'd,how're,elders,quietly,pulls,idiots,erase,denying,ankle,amnesia,accepting,heartbeat,devane,confront,minus,legitimate,fixing,arrogant,tuna,supper,slightest,sins,sayin,recipe,pier,paternity,humiliating,genuine,snack,rational,minded,guessed,weddings,tumor,humiliated,aspirin,spray,picks,eyed,drowning,contacts,ritual,perfume,hiring,hating,docks,creatures,visions,thanking,thankful,sock,nineteen,fork,throws,teenagers,stressed,slice,rolls,plead,ladder,kicks,detectives,assured,tellin,shallow,responsibilities,repay,howdy,girlfriends,deadly,comforting,ceiling,verdict,insensitive,spilled,respected,messy,interrupted,halliwell,blond,bleed,wardrobe,takin,murders,backs,underestimate,justify,harmless,frustrated,fold,enzo,communicate,bugging,arson,whack,salary,rumors,obligation,liking,dearest,congratulate,vengeance,rack,puzzle,fires,courtesy,caller,blamed,tops,quiz,prep,curiosity,circles,barbecue,sunnydale,spinning,psychotic,cough,accusations,resent,laughs,freshman,envy,drown,bartlet,asses,sofa,poster,highness,dock,apologies,theirs,stat,stall,realizes,psych,mmmm,fools,understandable,treats,succeed,stir,relaxed,makin,gratitude,faithful,accent,witter,wandering,locate,inevitable,gretel,deed,crushed,controlling,smelled,robe,gossip,gambling,cosmetics,accidents,surprising,stiff,sincere,rushed,refrigerator,preparing,nightmares,mijo,ignoring,hunch,fireworks,drowned,brass,whispering,sophisticated,luggage,hike,explore,emotion,crashing,contacted,complications,shining,rolled,righteous,reconsider,goody,geek,frightening,ethics,creeps,courthouse,camping,affection,smythe,haircut,essay,baked,apologized,vibe,respects,receipt,mami,hats,destructive,adore,adopt,tracked,shorts,reminding,dough,creations,cabot,barrel,snuck,slight,reporters,pressing,magnificent,madame,lazy,glorious,fiancee,bits,visitation,sane,kindness,shoulda,rescued,mattress,lounge,lifted,importantly,glove,enterprises,disappointment,condo,beings,admitting,yelled,waving,spoon,screech,satisfaction,reads,nailed,worm,tick,resting,marvelous,fuss,cortlandt,chased,pockets,luckily,lilith,filing,conversations,consideration,consciousness,worlds,innocence,forehead,aggressive,trailer,slam,quitting,inform,delighted,daylight,danced,confidential,aunts,washing,tossed,spectra,marrow,lined,implying,hatred,grill,corpse,clues,sober,offended,morgue,infected,humanity,distraction,cart,wired,violation,promising,harassment,glue,d'angelo,cursed,brutal,warlocks,wagon,unpleasant,proving,priorities,mustn't,lease,flame,disappearance,depressing,thrill,sitter,ribs,flush,earrings,deadline,corporal,collapsed,update,snapped,smack,melt,figuring,delusional,coulda,burnt,tender,sperm,realise,pork,popped,interrogation,esteem,choosing,undo,pres,prayed,plague,manipulate,insulting,detention,delightful,coffeehouse,betrayal,apologizing,adjust,wrecked,wont,whipped,rides,reminder,monsieur,faint,bake,distress,correctly,complaint,blocked,tortured,risking,pointless,handing,dumping,cups,alibi,struggling,shiny,risked,mummy,mint,hose,hobby,fortunate,fleischman,fitting,curtain,counseling,rode,puppet,modeling,memo,irresponsible,humiliation,hiya,freakin,felony,choke,blackmailing,appreciated,tabloid,suspicion,recovering,pledge,panicked,nursery,louder,jeans,investigator,homecoming,frustrating,buys,busting,buff,sleeve,irony,dope,declare,autopsy,workin,torch,prick,limb,hysterical,goddamnit,fetch,dimension,crowded,clip,climbing,bonding,woah,trusts,negotiate,lethal,iced,fantasies,deeds,bore,babysitter,questioned,outrageous,kiriakis,insulted,grudge,driveway,deserted,definite,beep,wires,suggestions,searched,owed,lend,drunken,demanding,costanza,conviction,bumped,weigh,touches,tempted,shout,resolve,relate,poisoned,meals,invitations,haunted,bogus,autograph,affects,tolerate,stepping,spontaneous,sleeps,probation,manny,fist,spectacular,hostages,heroin,havin,habits,encouraging,consult,burgers,boyfriends,bailed,baggage,watches,troubled,torturing,teasing,sweetest,qualities,postpone,overwhelmed,malkovich,impulse,classy,charging,amazed,policeman,hypocrite,humiliate,hideous,d'ya,costumes,bluffing,betting,bein,bedtime,alcoholic,vegetable,tray,suspicions,spreading,splendid,shrimp,shouting,pressed,nooo,grieving,gladly,fling,eliminate,cereal,aaah,sonofabitch,paralyzed,lotta,locks,guaranteed,dummy,despise,dental,briefing,bluff,batteries,whatta,sounding,servants,presume,handwriting,fainted,dried,allright,acknowledge,whacked,toxic,reliable,quicker,overwhelming,lining,harassing,fatal,endless,dolls,convict,whatcha,unlikely,shutting,positively,overcome,goddam,essence,dose,diagnosis,cured,bully,ahold,yearbook,tempting,shelf,prosecution,pouring,possessed,greedy,wonders,thorough,spine,rath,psychiatric,meaningless,latte,jammed,ignored,fiance,evidently,contempt,compromised,cans,weekends,urge,theft,suing,shipment,scissors,responding,proposition,noises,matching,hormones,hail,grandchildren,gently,smashed,sexually,sentimental,nicest,manipulated,intern,handcuffs,framed,errands,entertaining,crib,carriage,barge,spends,slipping,seated,rubbing,rely,reject,recommendation,reckon,headaches,float,embrace,corners,whining,sweating,skipped,mountie,motives,listens,cristobel,cleaner,cheerleader,balsom,unnecessary,stunning,scent,quartermaines,pose,montega,loosen,info,hottest,haunt,gracious,forgiving,errand,cakes,blames,abortion,sketch,shifts,plotting,perimeter,pals,mere,mattered,lonigan,interference,eyewitness,enthusiasm,diapers,strongest,shaken,punched,portal,catches,backyard,terrorists,sabotage,organs,needy,cuff,civilization,woof,who'll,prank,obnoxious,mates,hereby,gabby,faked,cellar,whitelighter,void,strangle,sour,muffins,interfering,demonic,clearing,boutique,barrington,terrace,smoked,righty,quack,petey,pact,knot,ketchup,disappearing,cordy,uptight,ticking,terrifying,tease,swamp,secretly,rejection,reflection,realizing,rays,mentally,marone,doubted,deception,congressman,cheesy,toto,stalling,scoop,ribbon,immune,expects,destined,bets,bathing,appreciation,accomplice,wander,shoved,sewer,scroll,retire,lasts,fugitive,freezer,discount,cranky,crank,clearance,bodyguard,anxiety,accountant,whoops,volunteered,talents,stinking,remotely,garlic,decency,cord,beds,altogether,uniforms,tremendous,popping,outa,observe,lung,hangs,feelin,dudes,donation,disguise,curb,bites,antique,toothbrush,realistic,predict,landlord,hourglass,hesitate,consolation,babbling,tipped,stranded,smartest,repeating,puke,psst,paycheck,overreacted,macho,juvenile,grocery,freshen,disposal,cuffs,caffeine,vanished,unfinished,ripping,pinch,flattering,expenses,dinners,colleague,ciao,belthazor,attorneys,woulda,whereabouts,waitin,truce,tripped,tasted,steer,poisoning,manipulative,immature,husbands,heel,granddad,delivering,condoms,addict,trashed,raining,pasta,needles,leaning,detector,coolest,batch,appointments,almighty,vegetables,spark,perfection,pains,momma,mole,meow,hairs,getaway,cracking,compliments,behold,verge,tougher,timer,tapped,taped,specialty,snooping,shoots,rendezvous,pentagon,leverage,jeopardize,janitor,grandparents,forbidden,clueless,bidding,ungrateful,unacceptable,tutor,serum,scuse,pajamas,mouths,lure,irrational,doom,cries,beautifully,arresting,approaching,traitor,sympathetic,smug,smash,rental,prostitute,premonitions,jumps,inventory,darlin,committing,banging,asap,worms,violated,vent,traumatic,traced,sweaty,shaft,overboard,insight,healed,grasp,experiencing,crappy,crab,chunk,awww,stain,shack,reacted,pronounce,poured,moms,marriages,jabez,handful,flipped,fireplace,embarrassment,disappears,concussion,bruises,brakes,twisting,swept,summon,splitting,sloppy,settling,reschedule,notch,hooray,grabbing,exquisite,disrespect,thornhart,straw,slapped,shipped,shattered,ruthless,refill,payroll,numb,mourning,manly,hunk,entertain,drift,dreadful,doorstep,confirmation,chops,appreciates,vague,tires,stressful,stashed,stash,sensed,preoccupied,predictable,noticing,madly,gunshot,dozens,dork,confuse,cleaners,charade,chalk,cappuccino,bouquet,amulet,addiction,who've,warming,unlock,satisfy,sacrificed,relaxing,lone,blocking,blend,blankets,addicted,yuck,hunger,hamburger,greeting,greet,gravy,gram,dreamt,dice,caution,backpack,agreeing,whale,taller,supervisor,sacrifices,phew,ounce,irrelevant,gran,felon,favorites,farther,fade,erased,easiest,convenience,compassionate,cane,backstage,agony,adores,veins,tweek,thieves,surgical,strangely,stetson,recital,proposing,productive,meaningful,immunity,hassle,goddamned,frighten,dearly,cease,ambition,wage,unstable,salvage,richer,refusing,raging,pumping,pressuring,mortals,lowlife,intimidated,intentionally,inspire,forgave,devotion,despicable,deciding,dash,comfy,breach,bark,aaaah,switching,swallowed,stove,screamed,scars,russians,pounding,poof,pipes,pawn,legit,invest,farewell,curtains,civilized,caviar,boost,token,superstition,supernatural,sadness,recorder,psyched,motivated,microwave,hallelujah,fraternity,dryer,cocoa,chewing,acceptable,unbelievably,smiled,smelling,simpler,respectable,remarks,khasinau,indication,gutter,grabs,fulfill,flashlight,ellenor,blooded,blink,blessings,beware,uhhh,turf,swings,slips,shovel,shocking,puff,mirrors,locking,heartless,fras,childish,cardiac,utterly,tuscany,ticked,stunned,statesville,sadly,purely,kiddin,jerks,hitch,flirt,fare,equals,dismiss,christening,casket,c'mere,breakup,biting,antibiotics,accusation,abducted,witchcraft,thread,runnin,punching,paramedics,newest,murdering,masks,lawndale,initials,grampa,choking,charms,careless,bushes,buns,bummed,shred,saves,saddle,rethink,regards,precinct,persuade,meds,manipulating,llanfair,leash,hearted,guarantees,fucks,disgrace,deposition,bookstore,boil,vitals,veil,trespassing,sidewalk,sensible,punishing,overtime,optimistic,obsessing,notify,mornin,jeopardy,jaffa,injection,hilarious,desires,confide,cautious,yada,where're,vindictive,vial,teeny,stroll,sittin,scrub,rebuild,posters,ordeal,nuns,intimacy,inheritance,exploded,donate,distracting,despair,crackers,wildwind,virtue,thoroughly,tails,spicy,sketches,sights,sheer,shaving,seize,scarecrow,refreshing,prosecute,platter,napkin,misplaced,merchandise,loony,jinx,heroic,frankenstein,ambitious,syrup,solitary,resemblance,reacting,premature,lavery,flashes,cheque,awright,acquainted,wrapping,untie,salute,realised,priceless,partying,lightly,lifting,kasnoff,insisting,glowing,generator,explosives,cutie,confronted,buts,blouse,ballistic,antidote,analyze,allowance,adjourned,unto,understatement,tucked,touchy,subconscious,screws,sarge,roommates,rambaldi,offend,nerd,knives,irresistible,incapable,hostility,goddammit,fuse,frat,curfew,blackmailed,walkin,starve,sleigh,sarcastic,recess,rebound,pinned,parlor,outfits,livin,heartache,haired,fundraiser,doorman,discreet,dilucca,cracks,considerate,climbed,catering,apophis,zoey,urine,strung,stitches,sordid,sark,protector,phoned,pets,hostess,flaw,flavor,deveraux,consumed,confidentiality,bourbon,straightened,specials,spaghetti,prettier,powerless,playin,playground,paranoia,instantly,havoc,exaggerating,eavesdropping,doughnuts,diversion,deepest,cutest,comb,bela,behaving,anyplace,accessory,workout,translate,stuffing,speeding,slime,royalty,polls,marital,lurking,lottery,imaginary,greetings,fairwinds,elegant,elbow,credibility,credentials,claws,chopped,bridal,bedside,babysitting,witty,unforgivable,underworld,tempt,tabs,sophomore,selfless,secrecy,restless,okey,movin,metaphor,messes,meltdown,lecter,incoming,gasoline,diefenbaker,buckle,admired,adjustment,warmth,throats,seduced,queer,parenting,noses,luckiest,graveyard,gifted,footsteps,dimeras,cynical,wedded,verbal,unpredictable,tuned,stoop,slides,sinking,rigged,plumbing,lingerie,hankey,greed,everwood,elope,dresser,chauffeur,bulletin,bugged,bouncing,temptation,strangest,slammed,sarcasm,pending,packages,orderly,obsessive,murderers,meteor,inconvenience,glimpse,froze,execute,courageous,consulate,closes,bosses,bees,amends,wuss,wolfram,wacky,unemployed,testifying,syringe,stew,startled,sorrow,sleazy,shaky,screams,rsquo,remark,poke,nutty,mentioning,mend,inspiring,impulsive,housekeeper,foam,fingernails,conditioning,baking,whine,thug,starved,sniffing,sedative,programmed,picket,paged,hound,homosexual,homo,hips,forgets,flipping,flea,flatter,dwell,dumpster,choo,assignments,ants,vile,unreasonable,tossing,thanked,steals,souvenir,scratched,psychopath,outs,obstruction,obey,lump,insists,harass,gloat,filth,edgy,didn,coroner,confessing,bruise,betraying,bailing,appealing,adebisi,wrath,wandered,waist,vain,traps,stepfather,poking,obligated,heavenly,dilemma,crazed,contagious,coaster,cheering,bundle,vomit,thingy,speeches,robbing,raft,pumped,pillows,peep,packs,neglected,m'kay,loneliness,intrude,helluva,gardener,forresters,drooling,betcha,vase,supermarket,squat,spitting,rhyme,relieve,receipts,racket,pictured,pause,overdue,motivation,morgendorffer,kidnapper,insect,horns,feminine,eyeballs,dumps,disappointing,crock,convertible,claw,clamp,canned,cambias,bathtub,avanya,artery,weep,warmer,suspense,summoned,spiders,reiber,raving,pushy,postponed,ohhhh,noooo,mold,laughter,incompetent,hugging,groceries,drip,communicating,auntie,adios,wraps,wiser,willingly,weirdest,timmih,thinner,swelling,swat,steroids,sensitivity,scrape,rehearse,prophecy,ledge,justified,insults,hateful,handles,doorway,chatting,buyer,buckaroo,bedrooms,askin,ammo,tutoring,subpoena,scratching,privileges,pager,mart,intriguing,idiotic,grape,enlighten,corrupt,brunch,bridesmaid,barking,applause,acquaintance,wretched,superficial,soak,smoothly,sensing,restraint,posing,pleading,payoff,oprah,nemo,morals,loaf,jumpy,ignorant,herbal,hangin,germs,generosity,flashing,doughnut,clumsy,chocolates,captive,behaved,apologise,vanity,stumbled,preview,poisonous,perjury,parental,onboard,mugged,minding,linen,knots,interviewing,humour,grind,greasy,goons,drastic,coop,comparing,cocky,clearer,bruised,brag,bind,worthwhile,whoop,vanquishing,tabloids,sprung,spotlight,sentencing,racist,provoke,pining,overly,locket,imply,impatient,hovering,hotter,fest,endure,dots,doren,debts,crawled,chained,brit,breaths,weirdo,warmed,wand,troubling,tok'ra,strapped,soaked,skipping,scrambled,rattle,profound,musta,mocking,misunderstand,limousine,kacl,hustle,forensic,enthusiastic,duct,drawers,devastating,conquer,clarify,chores,cheerleaders,cheaper,callin,blushing,barging,abused,yoga,wrecking,wits,waffles,virginity,vibes,uninvited,unfaithful,teller,strangled,scheming,ropes,rescuing,rave,postcard,o'reily,morphine,lotion,lads,kidneys,judgement,itch,indefinitely,grenade,glamorous,genetically,freud,discretion,delusions,crate,competent,bakery,argh,ahhhh,wedge,wager,unfit,tripping,torment,superhero,stirring,spinal,sorority,seminar,scenery,rabble,pneumonia,perks,override,ooooh,mija,manslaughter,mailed,lime,lettuce,intimidate,guarded,grieve,grad,frustration,doorbell,chinatown,authentic,arraignment,annulled,allergies,wanta,verify,vegetarian,tighter,telegram,stalk,spared,shoo,satisfying,saddam,requesting,pens,overprotective,obstacles,notified,nasedo,grandchild,genuinely,flushed,fluids,floss,escaping,ditched,cramp,corny,bunk,bitten,billions,bankrupt,yikes,wrists,ultrasound,ultimatum,thirst,sniff,shakes,salsa,retrieve,reassuring,pumps,neurotic,negotiating,needn't,monitors,millionaire,lydecker,limp,incriminating,hatchet,gracias,gordie,fills,feeds,doubting,decaf,biopsy,whiz,voluntarily,ventilator,unpack,unload,toad,spooked,snitch,schillinger,reassure,persuasive,mystical,mysteries,matrimony,mails,jock,headline,explanations,dispatch,curly,cupid,condolences,comrade,cassadines,bulb,bragging,awaits,assaulted,ambush,adolescent,abort,yank,whit,vaguely,undermine,tying,swamped,stabbing,slippers,slash,sincerely,sigh,setback,secondly,rotting,precaution,pcpd,melting,liaison,hots,hooking,headlines,haha,ganz,fury,felicity,fangs,encouragement,earring,dreidel,dory,donut,dictate,decorating,cocktails,bumps,blueberry,believable,backfired,backfire,apron,adjusting,vous,vouch,vitamins,ummm,tattoos,slimy,sibling,shhhh,renting,peculiar,parasite,paddington,marries,mailbox,magically,lovebirds,knocks,informant,exits,drazen,distractions,disconnected,dinosaurs,dashwood,crooked,conveniently,wink,warped,underestimated,tacky,shoving,seizure,reset,pushes,opener,mornings,mash,invent,indulge,horribly,hallucinating,festive,eyebrows,enjoys,desperation,dealers,darkest,daph,boragora,belts,bagel,authorization,auditions,agitated,wishful,wimp,vanish,unbearable,tonic,suffice,suction,slaying,safest,rocking,relive,puttin,prettiest,noisy,newlyweds,nauseous,misguided,mildly,midst,liable,judgmental,indy,hunted,givin,fascinated,elephants,dislike,deluded,decorate,crummy,contractions,carve,bottled,bonded,bahamas,unavailable,twenties,trustworthy,surgeons,stupidity,skies,remorse,preferably,pies,nausea,napkins,mule,mourn,melted,mashed,inherit,greatness,golly,excused,dumbo,drifting,delirious,damaging,cubicle,compelled,comm,chooses,checkup,boredom,bandages,alarms,windshield,who're,whaddya,transparent,surprisingly,sunglasses,slit,roar,reade,prognosis,probe,pitiful,persistent,peas,nosy,nagging,morons,masterpiece,martinis,limbo,liars,irritating,inclined,hump,hoynes,fiasco,eatin,cubans,concentrating,colorful,clam,cider,brochure,barto,bargaining,wiggle,welcoming,weighing,vanquished,stains,sooo,snacks,smear,sire,resentment,psychologist,pint,overhear,morality,landingham,kisser,hoot,holling,handshake,grilled,formality,elevators,depths,confirms,boathouse,accidental,westbridge,wacko,ulterior,thugs,thighs,tangled,stirred,snag,sling,sleaze,rumour,ripe,remarried,puddle,pins,perceptive,miraculous,longing,lockup,librarian,impressions,immoral,hypothetically,guarding,gourmet,gabe,faxed,extortion,downright,digest,cranberry,bygones,buzzing,burying,bikes,weary,taping,takeout,sweeping,stepmother,stale,senor,seaborn,pros,pepperoni,newborn,ludicrous,injected,geeks,forged,faults,drue,dire,dief,desi,deceiving,caterer,calmed,budge,ankles,vending,typing,tribbiani,there're,squared,snowing,shades,sexist,rewrite,regretted,raises,picky,orphan,mural,misjudged,miscarriage,memorize,leaking,jitters,invade,interruption,illegally,handicapped,glitch,gittes,finer,distraught,dispose,dishonest,digs,dads,cruelty,circling,canceling,butterflies,belongings,barbrady,amusement,alias,zombies,where've,unborn,swearing,stables,squeezed,sensational,resisting,radioactive,questionable,privileged,portofino,owning,overlook,orson,oddly,interrogate,imperative,impeccable,hurtful,hors,heap,graders,glance,disgust,devious,destruct,crazier,countdown,chump,cheeseburger,burglar,berries,ballroom,assumptions,annoyed,allergy,admirer,admirable,activate,underpants,twit,tack,strokes,stool,sham,scrap,retarded,resourceful,remarkably,refresh,pressured,precautions,pointy,nightclub,mustache,maui,lace,hunh,hubby,flare,dont,dokey,dangerously,crushing,clinging,choked,chem,cheerleading,checkbook,cashmere,calmly,blush,believer,amazingly,alas,what've,toilets,tacos,stairwell,spirited,sewing,rubbed,punches,protects,nuisance,motherfuckers,mingle,kynaston,knack,kinkle,impose,gullible,godmother,funniest,friggin,folding,fashions,eater,dysfunctional,drool,dripping,ditto,cruising,criticize,conceive,clone,cedars,caliber,brighter,blinded,birthdays,banquet,anticipate,annoy,whim,whichever,volatile,veto,vested,shroud,rests,reindeer,quarantine,pleases,painless,orphans,orphanage,offence,obliged,negotiation,narcotics,mistletoe,meddling,manifest,lookit,lilah,intrigued,injustice,homicidal,gigantic,exposing,elves,disturbance,disastrous,depended,demented,correction,cooped,cheerful,buyers,brownies,beverage,basics,arvin,weighs,upsets,unethical,swollen,sweaters,stupidest,sensation,scalpel,props,prescribed,pompous,objections,mushrooms,mulwray,manipulation,lured,internship,insignificant,inmate,incentive,fulfilled,disagreement,crypt,cornered,copied,brightest,beethoven,attendant,amaze,yogurt,wyndemere,vocabulary,tulsa,tactic,stuffy,respirator,pretends,polygraph,pennies,ordinarily,olives,necks,morally,martyr,leftovers,joints,hopping,homey,hints,heartbroken,forge,florist,firsthand,fiend,dandy,crippled,corrected,conniving,conditioner,clears,chemo,bubbly,bladder,beeper,baptism,wiring,wench,weaknesses,volunteering,violating,unlocked,tummy,surrogate,subid,stray,startle,specifics,slowing,scoot,robbers,rightful,richest,qfxmjrie,puffs,pierced,pencils,paralysis,makeover,luncheon,linksynergy,jerky,jacuzzi,hitched,hangover,fracture,flock,firemen,disgusted,darned,clams,borrowing,banged,wildest,weirder,unauthorized,stunts,sleeves,sixties,shush,shalt,retro,quits,pegged,painfully,paging,omelet,memorized,lawfully,jackets,intercept,ingredient,grownup,glued,fulfilling,enchanted,delusion,daring,compelling,carton,bridesmaids,bribed,boiling,bathrooms,bandage,awaiting,assign,arrogance,antiques,ainsley,turkeys,trashing,stockings,stalked,stabilized,skates,sedated,robes,respecting,psyche,presumptuous,prejudice,paragraph,mocha,mints,mating,mantan,lorne,loads,listener,itinerary,hepatitis,heave,guesses,fading,examining,dumbest,dishwasher,deceive,cunning,cripple,convictions,confided,compulsive,compromising,burglary,bumpy,brainwashed,benes,arnie,affirmative,adrenaline,adamant,watchin,waitresses,transgenic,toughest,tainted,surround,stormed,spree,spilling,spectacle,soaking,shreds,sewers,severed,scarce,scamming,scalp,rewind,rehearsing,pretentious,potions,overrated,obstacle,nerds,meems,mcmurphy,maternity,maneuver,loathe,fertility,eloping,ecstatic,ecstasy,divorcing,dignan,costing,clubhouse,clocks,candid,bursting,breather,braces,bending,arsonist,adored,absorb,valiant,uphold,unarmed,topolsky,thrilling,thigh,terminate,sustain,spaceship,snore,sneeze,smuggling,salty,quaint,patronize,patio,morbid,mamma,kettle,joyous,invincible,interpret,insecurities,impulses,illusions,holed,exploit,drivin,defenseless,dedicate,cradle,coupon,countless,conjure,cardboard,booking,backseat,accomplishment,wordsworth,wisely,valet,vaccine,urges,unnatural,unlucky,truths,traumatized,tasting,swears,strawberries,steaks,stats,skank,seducing,secretive,scumbag,screwdriver,schedules,rooting,rightfully,rattled,qualifies,puppets,prospects,pronto,posse,polling,pedestal,palms,muddy,morty,microscope,merci,lecturing,inject,incriminate,hygiene,grapefruit,gazebo,funnier,cuter,bossy,booby,aides,zende,winthrop,warrants,valentines,undressed,underage,truthfully,tampered,suffers,speechless,sparkling,sidelines,shrek,railing,puberty,pesky,outrage,outdoors,motions,moods,lunches,litter,kidnappers,itching,intuition,imitation,humility,hassling,gallons,drugstore,dosage,disrupt,dipping,deranged,debating,cuckoo,cremated,craziness,cooperating,circumstantial,chimney,blinking,biscuits,admiring,weeping,triad,trashy,soothing,slumber,slayers,skirts,siren,shindig,sentiment,rosco,riddance,quaid,purity,proceeding,pretzels,panicking,mckechnie,lovin,leaked,intruding,impersonating,ignorance,hamburgers,footprints,fluke,fleas,festivities,fences,feisty,evacuate,emergencies,deceived,creeping,craziest,corpses,conned,coincidences,bounced,bodyguards,blasted,bitterness,baloney,ashtray,apocalypse,zillion,watergate,wallpaper,telesave,sympathize,sweeter,startin,spades,sodas,snowed,sleepover,signor,seein,retainer,restroom,rested,repercussions,reliving,reconcile,prevail,preaching,overreact,o'neil,noose,moustache,manicure,maids,landlady,hypothetical,hopped,homesick,hives,hesitation,herbs,hectic,heartbreak,haunting,gangs,frown,fingerprint,exhausting,everytime,disregard,cling,chevron,chaperone,blinding,bitty,beads,battling,badgering,anticipation,upstanding,unprofessional,unhealthy,turmoil,truthful,toothpaste,tippin,thoughtless,tagataya,shooters,senseless,rewarding,propane,preposterous,pigeons,pastry,overhearing,obscene,negotiable,loner,jogging,itchy,insinuating,insides,hospitality,hormone,hearst,forthcoming,fists,fifties,etiquette,endings,destroys,despises,deprived,cuddy,crust,cloak,circumstance,chewed,casserole,bidder,bearer,artoo,applaud,appalling,vowed,virgins,vigilante,undone,throttle,testosterone,tailor,symptom,swoop,suitcases,stomp,sticker,stakeout,spoiling,snatched,smoochy,smitten,shameless,restraints,researching,renew,refund,reclaim,raoul,puzzles,purposely,punks,prosecuted,plaid,picturing,pickin,parasites,mysteriously,multiply,mascara,jukebox,interruptions,gunfire,furnace,elbows,duplicate,drapes,deliberate,decoy,cryptic,coupla,condemn,complicate,colossal,clerks,clarity,brushed,banished,argon,alarmed,worships,versa,uncanny,technicality,sundae,stumble,stripping,shuts,schmuck,satin,saliva,robber,relentless,reconnect,recipes,rearrange,rainy,psychiatrists,policemen,plunge,plugged,patched,overload,o'malley,mindless,menus,lullaby,lotte,leavin,killin,karinsky,invalid,hides,grownups,griff,flaws,flashy,flaming,fettes,evicted,dread,degrassi,dealings,dangers,cushion,bowel,barged,abide,abandoning,wonderfully,wait'll,violate,suicidal,stayin,sorted,slamming,sketchy,shoplifting,raiser,quizmaster,prefers,needless,motherhood,momentarily,migraine,lifts,leukemia,leftover,keepin,hinks,hellhole,gowns,goodies,gallon,futures,entertained,eighties,conspiring,cheery,benign,apiece,adjustments,abusive,abduction,wiping,whipping,welles,unspeakable,unidentified,trivial,transcripts,textbook,supervise,superstitious,stricken,stimulating,spielberg,slices,shelves,scratches,sabotaged,retrieval,repressed,rejecting,quickie,ponies,peeking,outraged,o'connell,moping,moaning,mausoleum,licked,kovich,klutz,interrogating,interfered,insulin,infested,incompetence,hyper,horrified,handedly,gekko,fraid,fractured,examiner,eloped,disoriented,dashing,crashdown,courier,cockroach,chipped,brushing,bombed,bolts,baths,baptized,astronaut,assurance,anemia,abuela,abiding,withholding,weave,wearin,weaker,suffocating,straws,straightforward,stench,steamed,starboard,sideways,shrinks,shortcut,scram,roasted,roaming,riviera,respectfully,repulsive,psychiatry,provoked,penitentiary,painkillers,ninotchka,mitzvah,milligrams,midge,marshmallows,looky,lapse,kubelik,intellect,improvise,implant,goa'ulds,giddy,geniuses,fruitcake,footing,fightin,drinkin,doork,detour,cuddle,crashes,combo,colonnade,cheats,cetera,bailiff,auditioning,assed,amused,alienate,aiding,aching,unwanted,topless,tongues,tiniest,superiors,soften,sheldrake,rawley,raisins,presses,plaster,nessa,narrowed,minions,merciful,lawsuits,intimidating,infirmary,inconvenient,imposter,hugged,honoring,holdin,hades,godforsaken,fumes,forgery,foolproof,folder,flattery,fingertips,exterminator,explodes,eccentric,dodging,disguised,crave,constructive,concealed,compartment,chute,chinpokomon,bodily,astronauts,alimony,accustomed,abdominal,wrinkle,wallow,valium,untrue,uncover,trembling,treasures,torched,toenails,timed,termites,telly,taunting,taransky,talker,succubus,smarts,sliding,sighting,semen,seizures,scarred,savvy,sauna,saddest,sacrificing,rubbish,riled,ratted,rationally,provenance,phonse,perky,pedal,overdose,nasal,nanites,mushy,movers,missus,midterm,merits,melodramatic,manure,knitting,invading,interpol,incapacitated,hotline,hauling,gunpoint,grail,ganza,framing,flannel,faded,eavesdrop,desserts,calories,breathtaking,bleak,blacked,batter,aggravated,yanked,wigand,whoah,unwind,undoubtedly,unattractive,twitch,trimester,torrance,timetable,taxpayers,strained,stared,slapping,sincerity,siding,shenanigans,shacking,sappy,samaritan,poorer,politely,paste,oysters,overruled,nightcap,mosquito,millimeter,merrier,manhood,lucked,kilos,ignition,hauled,harmed,goodwill,freshmen,fenmore,fasten,farce,exploding,erratic,drunks,ditching,d'artagnan,cramped,contacting,closets,clientele,chimp,bargained,arranging,anesthesia,amuse,altering,afternoons,accountable,abetting,wolek,waved,uneasy,toddy,tattooed,spauldings,sliced,sirens,schibetta,scatter,rinse,remedy,redemption,pleasures,optimism,oblige,mmmmm,masked,malicious,mailing,kosher,kiddies,judas,isolate,insecurity,incidentally,heals,headlights,growl,grilling,glazed,flunk,floats,fiery,fairness,exercising,excellency,disclosure,cupboard,counterfeit,condescending,conclusive,clicked,cleans,cholesterol,cashed,broccoli,brats,blueprints,blindfold,billing,attach,appalled,alrighty,wynant,unsolved,unreliable,toots,tighten,sweatshirt,steinbrenner,steamy,spouse,sonogram,slots,sleepless,shines,retaliate,rephrase,redeem,rambling,quilt,quarrel,prying,proverbial,priced,prescribe,prepped,pranks,possessive,plaintiff,pediatrics,overlooked,outcast,nightgown,mumbo,mediocre,mademoiselle,lunchtime,lifesaver,leaned,lambs,interns,hounding,hellmouth,hahaha,goner,ghoul,gardening,frenzy,foyer,extras,exaggerate,everlasting,enlightened,dialed,devote,deceitful,d'oeuvres,cosmetic,contaminated,conspired,conning,cavern,carving,butting,boiled,blurry,babysit,ascension,aaaaah,wildly,whoopee,whiny,weiskopf,walkie,vultures,vacations,upfront,unresolved,tampering,stockholders,snaps,sleepwalking,shrunk,sermon,seduction,scams,revolve,phenomenal,patrolling,paranormal,ounces,omigod,nightfall,lashing,innocents,infierno,incision,humming,haunts,gloss,gloating,frannie,fetal,feeny,entrapment,discomfort,detonator,dependable,concede,complication,commotion,commence,chulak,caucasian,casually,brainer,bolie,ballpark,anwar,analyzing,accommodations,youse,wring,wallowing,transgenics,thrive,tedious,stylish,strippers,sterile,squeezing,squeaky,sprained,solemn,snoring,shattering,shabby,seams,scrawny,revoked,residue,reeks,recite,ranting,quoting,predicament,plugs,pinpoint,petrified,pathological,passports,oughtta,nighter,navigate,kippie,intrigue,intentional,insufferable,hunky,how've,horrifying,hearty,hamptons,grazie,funerals,forks,fetched,excruciating,enjoyable,endanger,dumber,drying,diabolical,crossword,corry,comprehend,clipped,classmates,candlelight,brutally,brutality,boarded,bathrobe,authorize,assemble,aerobics,wholesome,whiff,vermin,trophies,trait,tragically,toying,testy,tasteful,stocked,spinach,sipping,sidetracked,scrubbing,scraping,sanctity,robberies,ridin,retribution,refrain,realities,radiant,protesting,projector,plutonium,payin,parting,o'reilly,nooooo,motherfucking,measly,manic,lalita,juggling,jerking,intro,inevitably,hypnosis,huddle,horrendous,hobbies,heartfelt,harlin,hairdresser,gonorrhea,fussing,furtwangler,fleeting,flawless,flashed,fetus,eulogy,distinctly,disrespectful,denies,crossbow,cregg,crabs,cowardly,contraction,contingency,confirming,condone,coffins,cleansing,cheesecake,certainty,cages,c'est,briefed,bravest,bosom,boils,binoculars,bachelorette,appetizer,ambushed,alerted,woozy,withhold,vulgar,utmost,unleashed,unholy,unhappiness,unconditional,typewriter,typed,twists,supermodel,subpoenaed,stringing,skeptical,schoolgirl,romantically,rocked,revoir,reopen,puncture,preach,polished,planetarium,penicillin,peacefully,nurturing,more'n,mmhmm,midgets,marklar,lodged,lifeline,jellyfish,infiltrate,hutch,horseback,heist,gents,frickin,freezes,forfeit,flakes,flair,fathered,eternally,epiphany,disgruntled,discouraged,delinquent,decipher,danvers,cubes,credible,coping,chills,cherished,catastrophe,bombshell,birthright,billionaire,ample,affections,admiration,abbotts,whatnot,watering,vinegar,unthinkable,unseen,unprepared,unorthodox,underhanded,uncool,timeless,thump,thermometer,theoretically,tapping,tagged,swung,stares,spiked,solves,smuggle,scarier,saucer,quitter,prudent,powdered,poked,pointers,peril,penetrate,penance,opium,nudge,nostrils,neurological,mockery,mobster,medically,loudly,insights,implicate,hypocritical,humanly,holiness,healthier,hammered,haldeman,gunman,gloom,freshly,francs,flunked,flawed,emptiness,drugging,dozer,derevko,deprive,deodorant,cryin,crocodile,coloring,colder,cognac,clocked,clippings,charades,chanting,certifiable,caterers,brute,brochures,botched,blinders,bitchin,banter,woken,ulcer,tread,thankfully,swine,swimsuit,swans,stressing,steaming,stamped,stabilize,squirm,snooze,shuffle,shredded,seafood,scratchy,savor,sadistic,rhetorical,revlon,realist,prosecuting,prophecies,polyester,petals,persuasion,paddles,o'leary,nuthin,neighbour,negroes,muster,meningitis,matron,lockers,letterman,legged,indictment,hypnotized,housekeeping,hopelessly,hallucinations,grader,goldilocks,girly,flask,envelopes,downside,doves,dissolve,discourage,disapprove,diabetic,deliveries,decorator,crossfire,criminally,containment,comrades,complimentary,chatter,catchy,cashier,cartel,caribou,cardiologist,brawl,booted,barbershop,aryan,angst,administer,zellie,wreak,whistles,vandalism,vamps,uterus,upstate,unstoppable,understudy,tristin,transcript,tranquilizer,toxins,tonsils,stempel,spotting,spectator,spatula,softer,snotty,slinging,showered,sexiest,sensual,sadder,rimbaud,restrain,resilient,remission,reinstate,rehash,recollection,rabies,popsicle,plausible,pediatric,patronizing,ostrich,ortolani,oooooh,omelette,mistrial,marseilles,loophole,laughin,kevvy,irritated,infidelity,hypothermia,horrific,groupie,grinding,graceful,goodspeed,gestures,frantic,extradition,echelon,disks,dawnie,dared,damsel,curled,collateral,collage,chant,calculating,bumping,bribes,boardwalk,blinds,blindly,bleeds,bickering,beasts,backside,avenge,apprehended,anguish,abusing,youthful,yells,yanking,whomever,when'd,vomiting,vengeful,unpacking,unfamiliar,undying,tumble,trolls,treacherous,tipping,tantrum,tanked,summons,straps,stomped,stinkin,stings,staked,squirrels,sprinkles,speculate,sorting,skinned,sicko,sicker,shootin,shatter,seeya,schnapps,s'posed,ronee,respectful,regroup,regretting,reeling,reckoned,ramifications,puddy,projections,preschool,plissken,platonic,permalash,outdone,outburst,mutants,mugging,misfortune,miserably,miraculously,medications,margaritas,manpower,lovemaking,logically,leeches,latrine,kneel,inflict,impostor,hypocrisy,hippies,heterosexual,heightened,hecuba,healer,gunned,grooming,groin,gooey,gloomy,frying,friendships,fredo,firepower,fathom,exhaustion,evils,endeavor,eggnog,dreaded,d'arcy,crotch,coughing,coronary,cookin,consummate,congrats,companionship,caved,caspar,bulletproof,brilliance,breakin,brash,blasting,aloud,airtight,advising,advertise,adultery,aches,wronged,upbeat,trillion,thingies,tending,tarts,surreal,specs,specialize,spade,shrew,shaping,selves,schoolwork,roomie,recuperating,rabid,quart,provocative,proudly,pretenses,prenatal,pharmaceuticals,pacing,overworked,originals,nicotine,murderous,mileage,mayonnaise,massages,losin,interrogated,injunction,impartial,homing,heartbreaker,hacks,glands,giver,fraizh,flips,flaunt,englishman,electrocuted,dusting,ducking,drifted,donating,cylon,crutches,crates,cowards,comfortably,chummy,chitchat,childbirth,businesswoman,brood,blatant,bethy,barring,bagged,awakened,asbestos,airplanes,worshipped,winnings,why're,visualize,unprotected,unleash,trays,thicker,therapists,takeoff,streisand,storeroom,stethoscope,stacked,spiteful,sneaks,snapping,slaughtered,slashed,simplest,silverware,shits,secluded,scruples,scrubs,scraps,ruptured,roaring,receptionist,recap,raditch,radiator,pushover,plastered,pharmacist,perverse,perpetrator,ornament,ointment,nineties,napping,nannies,mousse,moors,momentary,misunderstandings,manipulator,malfunction,laced,kivar,kickin,infuriating,impressionable,holdup,hires,hesitated,headphones,hammering,groundwork,grotesque,graces,gauze,gangsters,frivolous,freeing,fours,forwarding,ferrars,faulty,fantasizing,extracurricular,empathy,divorces,detonate,depraved,demeaning,deadlines,dalai,cursing,cufflink,crows,coupons,comforted,claustrophobic,casinos,camped,busboy,bluth,bennetts,baskets,attacker,aplastic,angrier,affectionate,zapped,wormhole,weaken,unrealistic,unravel,unimportant,unforgettable,twain,suspend,superbowl,stutter,stewardess,stepson,standin,spandex,souvenirs,sociopath,skeletons,shivering,sexier,selfishness,scrapbook,ritalin,ribbons,reunite,remarry,relaxation,rattling,rapist,psychosis,prepping,poses,pleasing,pisses,piling,persecuted,padded,operatives,negotiator,natty,menopause,mennihan,martimmys,loyalties,laynie,lando,justifies,intimately,inexperienced,impotent,immortality,horrors,hooky,hinges,heartbreaking,handcuffed,gypsies,guacamole,grovel,graziella,goggles,gestapo,fussy,ferragamo,feeble,eyesight,explosions,experimenting,enchanting,doubtful,dizziness,dismantle,detectors,deserving,defective,dangling,dancin,crumble,creamed,cramping,conceal,clockwork,chrissakes,chrissake,chopping,cabinets,brooding,bonfire,blurt,bloated,blackmailer,beforehand,bathed,bathe,barcode,banish,badges,babble,await,attentive,aroused,antibodies,animosity,ya'll,wrinkled,wonderland,willed,whisk,waltzing,waitressing,vigilant,upbringing,unselfish,uncles,trendy,trajectory,striped,stamina,stalled,staking,stacks,spoils,snuff,snooty,snide,shrinking,senora,secretaries,scoundrel,saline,salads,rundown,riddles,relapse,recommending,raspberry,plight,pecan,pantry,overslept,ornaments,niner,negligent,negligence,nailing,mucho,mouthed,monstrous,malpractice,lowly,loitering,logged,lingering,lettin,lattes,kamal,juror,jillefsky,jacked,irritate,intrusion,insatiable,infect,impromptu,icing,hmmmm,hefty,gasket,frightens,flapping,firstborn,faucet,estranged,envious,dopey,doesn,disposition,disposable,disappointments,dipped,dignified,deceit,dealership,deadbeat,curses,coven,counselors,concierge,clutches,casbah,callous,cahoots,brotherly,britches,brides,bethie,beige,autographed,attendants,attaboy,astonishing,appreciative,antibiotic,aneurysm,afterlife,affidavit,zoning,whats,whaddaya,vasectomy,unsuspecting,toula,topanga,tonio,toasted,tiring,terrorized,tenderness,tailing,sweats,suffocated,sucky,subconsciously,starvin,sprouts,spineless,sorrows,snowstorm,smirk,slicery,sledding,slander,simmer,signora,sigmund,seventies,sedate,scented,sandals,rollers,retraction,resigning,recuperate,receptive,racketeering,queasy,provoking,priors,prerogative,premed,pinched,pendant,outsiders,orbing,opportunist,olanov,neurologist,nanobot,mommies,molested,misread,mannered,laundromat,intercom,inspect,insanely,infatuation,indulgent,indiscretion,inconsiderate,hurrah,howling,herpes,hasta,harassed,hanukkah,groveling,groosalug,gander,galactica,futile,fridays,flier,fixes,exploiting,exorcism,evasive,endorse,emptied,dreary,dreamy,downloaded,dodged,doctored,disobeyed,disneyland,disable,dehydrated,contemplating,coconuts,cockroaches,clogged,chilling,chaperon,cameraman,bulbs,bucklands,bribing,brava,bracelets,bowels,bluepoint,appetizers,appendix,antics,anointed,analogy,almonds,yammering,winch,weirdness,wangler,vibrations,vendor,unmarked,unannounced,twerp,trespass,travesty,transfusion,trainee,towelie,tiresome,straightening,staggering,sonar,socializing,sinus,sinners,shambles,serene,scraped,scones,scepter,sarris,saberhagen,ridiculously,ridicule,rents,reconciled,radios,publicist,pubes,prune,prude,precrime,postponing,pluck,perish,peppermint,peeled,overdo,nutshell,nostalgic,mulan,mouthing,mistook,meddle,maybourne,martimmy,lobotomy,livelihood,lippman,likeness,kindest,kaffee,jocks,jerked,jeopardizing,jazzed,insured,inquisition,inhale,ingenious,holier,helmets,heirloom,heinous,haste,harmsway,hardship,hanky,gutters,gruesome,groping,goofing,godson,glare,finesse,figuratively,ferrie,endangerment,dreading,dozed,dorky,dmitri,divert,discredit,dialing,cufflinks,crutch,craps,corrupted,cocoon,cleavage,cannery,bystander,brushes,bruising,bribery,brainstorm,bolted,binge,ballistics,astute,arroway,adventurous,adoptive,addicts,addictive,yadda,whitelighters,wematanye,weeds,wedlock,wallets,vulnerability,vroom,vents,upped,unsettling,unharmed,trippin,trifle,tracing,tormenting,thats,syphilis,subtext,stickin,spices,sores,smacked,slumming,sinks,signore,shitting,shameful,shacked,septic,seedy,righteousness,relish,rectify,ravishing,quickest,phoebs,perverted,peeing,pedicure,pastrami,passionately,ozone,outnumbered,oregano,offender,nukes,nosed,nighty,nifty,mounties,motivate,moons,misinterpreted,mercenary,mentality,marsellus,lupus,lumbar,lovesick,lobsters,leaky,laundering,latch,jafar,instinctively,inspires,indoors,incarcerated,hundredth,handkerchief,gynecologist,guittierez,groundhog,grinning,goodbyes,geese,fullest,eyelashes,eyelash,enquirer,endlessly,elusive,disarm,detest,deluding,dangle,cotillion,corsage,conjugal,confessional,cones,commandment,coded,coals,chuckle,christmastime,cheeseburgers,chardonnay,celery,campfire,calming,burritos,brundle,broflovski,brighten,borderline,blinked,bling,beauties,bauers,battered,articulate,alienated,ahhhhh,agamemnon,accountants,y'see,wrongful,wrapper,workaholic,winnebago,whispered,warts,vacate,unworthy,unanswered,tonane,tolerated,throwin,throbbing,thrills,thorns,thereof,there've,tarot,sunscreen,stretcher,stereotype,soggy,sobbing,sizable,sightings,shucks,shrapnel,sever,senile,seaboard,scorned,saver,rebellious,rained,putty,prenup,pores,pinching,pertinent,peeping,paints,ovulating,opposites,occult,nutcracker,nutcase,newsstand,newfound,mocked,midterms,marshmallow,marbury,maclaren,leans,krudski,knowingly,keycard,junkies,juilliard,jolinar,irritable,invaluable,inuit,intoxicating,instruct,insolent,inexcusable,incubator,illustrious,hunsecker,houseguest,homosexuals,homeroom,hernia,harming,handgun,hallways,hallucination,gunshots,groupies,groggy,goiter,gingerbread,giggling,frigging,fledged,fedex,fairies,exchanging,exaggeration,esteemed,enlist,drags,dispense,disloyal,disconnect,desks,dentists,delacroix,degenerate,daydreaming,cushions,cuddly,corroborate,complexion,compensated,cobbler,closeness,chilled,checkmate,channing,carousel,calms,bylaws,benefactor,ballgame,baiting,backstabbing,artifact,airspace,adversary,actin,accuses,accelerant,abundantly,abstinence,zissou,zandt,yapping,witchy,willows,whadaya,vilandra,veiled,undress,undivided,underestimating,ultimatums,twirl,truckload,tremble,toasting,tingling,tents,tempered,sulking,stunk,sponges,spills,softly,snipers,scourge,rooftop,riana,revolting,revisit,refreshments,redecorating,recapture,raysy,pretense,prejudiced,precogs,pouting,poofs,pimple,piles,pediatrician,padre,packets,paces,orvelle,oblivious,objectivity,nighttime,nervosa,mexicans,meurice,melts,matchmaker,maeby,lugosi,lipnik,leprechaun,kissy,kafka,introductions,intestines,inspirational,insightful,inseparable,injections,inadvertently,hussy,huckabees,hittin,hemorrhaging,headin,haystack,hallowed,grudges,granilith,grandkids,grading,gracefully,godsend,gobbles,fragrance,fliers,finchley,farts,eyewitnesses,expendable,existential,dorms,delaying,degrading,deduction,darlings,danes,cylons,counsellor,contraire,consciously,conjuring,congratulating,cokes,buffay,brooch,bitching,bistro,bijou,bewitched,benevolent,bends,bearings,barren,aptitude,amish,amazes,abomination,worldly,whispers,whadda,wayward,wailing,vanishing,upscale,untouchable,unspoken,uncontrollable,unavoidable,unattended,trite,transvestite,toupee,timid,timers,terrorizing,swana,stumped,strolling,storybook,storming,stomachs,stoked,stationery,springtime,spontaneity,spits,spins,soaps,sentiments,scramble,scone,rooftops,retract,reflexes,rawdon,ragged,quirky,quantico,psychologically,prodigal,pounce,potty,pleasantries,pints,petting,perceive,onstage,notwithstanding,nibble,newmans,neutralize,mutilated,millionaires,mayflower,masquerade,mangy,macreedy,lunatics,lovable,locating,limping,lasagna,kwang,keepers,juvie,jaded,ironing,intuitive,intensely,insure,incantation,hysteria,hypnotize,humping,happenin,griet,grasping,glorified,ganging,g'night,focker,flunking,flimsy,flaunting,fixated,fitzwallace,fainting,eyebrow,exonerated,ether,electrician,egotistical,earthly,dusted,dignify,detonation,debrief,dazzling,dan'l,damnedest,daisies,crushes,crucify,contraband,confronting,collapsing,cocked,clicks,cliche,circled,chandelier,carburetor,callers,broads,breathes,bloodshed,blindsided,blabbing,bialystock,bashing,ballerina,aviva,arteries,anomaly,airstrip,agonizing,adjourn,aaaaa,yearning,wrecker,witnessing,whence,warhead,unsure,unheard,unfreeze,unfold,unbalanced,ugliest,troublemaker,toddler,tiptoe,threesome,thirties,thermostat,swipe,surgically,subtlety,stung,stumbling,stubs,stride,strangling,sprayed,socket,smuggled,showering,shhhhh,sabotaging,rumson,rounding,risotto,repairman,rehearsed,ratty,ragging,radiology,racquetball,racking,quieter,quicksand,prowl,prompt,premeditated,prematurely,prancing,porcupine,plated,pinocchio,peeked,peddle,panting,overweight,overrun,outing,outgrown,obsess,nursed,nodding,negativity,negatives,musketeers,mugger,motorcade,merrily,matured,masquerading,marvellous,maniacs,lovey,louse,linger,lilies,lawful,kudos,knuckle,juices,judgments,itches,intolerable,intermission,inept,incarceration,implication,imaginative,huckleberry,holster,heartburn,gunna,groomed,graciously,fulfillment,fugitives,forsaking,forgives,foreseeable,flavors,flares,fixation,fickle,fantasize,famished,fades,expiration,exclamation,erasing,eiffel,eerie,earful,duped,dulles,dissing,dissect,dispenser,dilated,detergent,desdemona,debriefing,damper,curing,crispina,crackpot,courting,cordial,conflicted,comprehension,commie,cleanup,chiropractor,charmer,chariot,cauldron,catatonic,bullied,buckets,brilliantly,breathed,booths,boardroom,blowout,blindness,blazing,biologically,bibles,biased,beseech,barbaric,balraj,audacity,anticipating,alcoholics,airhead,agendas,admittedly,absolution,youre,yippee,wittlesey,withheld,willful,whammy,weakest,washes,virtuous,videotapes,vials,unplugged,unpacked,unfairly,turbulence,tumbling,tricking,tremendously,traitors,torches,tinga,thyroid,teased,tawdry,taker,sympathies,swiped,sundaes,suave,strut,stepdad,spewing,spasm,socialize,slither,simulator,shutters,shrewd,shocks,semantics,schizophrenic,scans,savages,rya'c,runny,ruckus,royally,roadblocks,rewriting,revoke,repent,redecorate,recovers,recourse,ratched,ramali,racquet,quince,quiche,puppeteer,puking,puffed,problemo,praises,pouch,postcards,pooped,poised,piled,phoney,phobia,patching,parenthood,pardner,oozing,ohhhhh,numbing,nostril,nosey,neatly,nappa,nameless,mortuary,moronic,modesty,midwife,mcclane,matuka,maitre,lumps,lucid,loosened,loins,lawnmower,lamotta,kroehner,jinxy,jessep,jamming,jailhouse,jacking,intruders,inhuman,infatuated,indigestion,implore,implanted,hormonal,hoboken,hillbilly,heartwarming,headway,hatched,hartmans,harping,grapevine,gnome,forties,flyin,flirted,fingernail,exhilarating,enjoyment,embark,dumper,dubious,drell,docking,disillusioned,dishonor,disbarred,dicey,custodial,counterproductive,corned,cords,contemplate,concur,conceivable,cobblepot,chickened,checkout,carpe,cap'n,campers,buyin,bullies,braid,boxed,bouncy,blueberries,blubbering,bloodstream,bigamy,beeped,bearable,autographs,alarming,wretch,wimps,widower,whirlwind,whirl,warms,vandelay,unveiling,undoing,unbecoming,turnaround,touche,togetherness,tickles,ticker,teensy,taunt,sweethearts,stitched,standpoint,staffers,spotless,soothe,smothered,sickening,shouted,shepherds,shawl,seriousness,schooled,schoolboy,s'mores,roped,reminders,raggedy,preemptive,plucked,pheromones,particulars,pardoned,overpriced,overbearing,outrun,ohmigod,nosing,nicked,neanderthal,mosquitoes,mortified,milky,messin,mecha,markinson,marivellas,mannequin,manderley,madder,macready,lookie,locusts,lifetimes,lanna,lakhi,kholi,impersonate,hyperdrive,horrid,hopin,hogging,hearsay,harpy,harboring,hairdo,hafta,grasshopper,gobble,gatehouse,foosball,floozy,fished,firewood,finalize,felons,euphemism,entourage,elitist,elegance,drokken,drier,dredge,dossier,diseased,diarrhea,diagnose,despised,defuse,d'amour,contesting,conserve,conscientious,conjured,collars,clogs,chenille,chatty,chamomile,casing,calculator,brittle,breached,blurted,birthing,bikinis,astounding,assaulting,aroma,appliance,antsy,amnio,alienating,aliases,adolescence,xerox,wrongs,workload,willona,whistling,werewolves,wallaby,unwelcome,unseemly,unplug,undermining,ugliness,tyranny,tuesdays,trumpets,transference,ticks,tangible,tagging,swallowing,superheroes,studs,strep,stowed,stomping,steffy,sprain,spouting,sponsoring,sneezing,smeared,slink,shakin,sewed,seatbelt,scariest,scammed,sanctimonious,roasting,rightly,retinal,rethinking,resented,reruns,remover,racks,purest,progressing,presidente,preeclampsia,postponement,portals,poppa,pliers,pinning,pelvic,pampered,padding,overjoyed,ooooo,one'll,octavius,nonono,nicknames,neurosurgeon,narrows,misled,mislead,mishap,milltown,milking,meticulous,mediocrity,meatballs,machete,lurch,layin,knockin,khruschev,jurors,jumpin,jugular,jeweler,intellectually,inquiries,indulging,indestructible,indebted,imitate,ignores,hyperventilating,hyenas,hurrying,hermano,hellish,heheh,harshly,handout,grunemann,glances,giveaway,getup,gerome,furthest,frosting,frail,forwarded,forceful,flavored,flammable,flaky,fingered,fatherly,ethic,embezzlement,duffel,dotted,distressed,disobey,disappearances,dinky,diminish,diaphragm,deuces,creme,courteous,comforts,coerced,clots,clarification,chunks,chickie,chases,chaperoning,cartons,caper,calves,caged,bustin,bulging,bringin,boomhauer,blowin,blindfolded,biscotti,ballplayer,bagging,auster,assurances,aschen,arraigned,anonymity,alters,albatross,agreeable,adoring,abduct,wolfi,weirded,watchers,washroom,warheads,vincennes,urgency,understandably,uncomplicated,uhhhh,twitching,treadmill,thermos,tenorman,tangle,talkative,swarm,surrendering,summoning,strive,stilts,stickers,squashed,spraying,sparring,soaring,snort,sneezed,slaps,skanky,singin,sidle,shreck,shortness,shorthand,sharper,shamed,sadist,rydell,rusik,roulette,resumes,respiration,recount,reacts,purgatory,princesses,presentable,ponytail,plotted,pinot,pigtails,phillippe,peddling,paroled,orbed,offends,o'hara,moonlit,minefield,metaphors,malignant,mainframe,magicks,maggots,maclaine,loathing,leper,leaps,leaping,lashed,larch,larceny,lapses,ladyship,juncture,jiffy,jakov,invoke,infantile,inadmissible,horoscope,hinting,hideaway,hesitating,heddy,heckles,hairline,gripe,gratifying,governess,goebbels,freddo,foresee,fascination,exemplary,executioner,etcetera,escorts,endearing,eaters,earplugs,draped,disrupting,disagrees,dimes,devastate,detain,depositions,delicacy,darklighter,cynicism,cyanide,cutters,cronus,continuance,conquering,confiding,compartments,combing,cofell,clingy,cleanse,christmases,cheered,cheekbones,buttle,burdened,bruenell,broomstick,brained,bozos,bontecou,bluntman,blazes,blameless,bizarro,bellboy,beaucoup,barkeep,awaken,astray,assailant,appease,aphrodisiac,alleys,yesss,wrecks,woodpecker,wondrous,wimpy,willpower,wheeling,weepy,waxing,waive,videotaped,veritable,untouched,unlisted,unfounded,unforeseen,twinge,triggers,traipsing,toxin,tombstone,thumping,therein,testicles,telephones,tarmac,talby,tackled,swirling,suicides,suckered,subtitles,sturdy,strangler,stockbroker,stitching,steered,standup,squeal,sprinkler,spontaneously,splendor,spiking,spender,snipe,snagged,skimming,siddown,showroom,shovels,shotguns,shoelaces,shitload,shellfish,sharpest,shadowy,seizing,scrounge,scapegoat,sayonara,saddled,rummaging,roomful,renounce,reconsidered,recharge,realistically,radioed,quirks,quadrant,punctual,practising,pours,poolhouse,poltergeist,pocketbook,plainly,picnics,pesto,pawing,passageway,partied,oneself,numero,nostalgia,nitwit,neuro,mixer,meanest,mcbeal,matinee,margate,marce,manipulations,manhunt,manger,magicians,loafers,litvack,lightheaded,lifeguard,lawns,laughingstock,ingested,indignation,inconceivable,imposition,impersonal,imbecile,huddled,housewarming,horizons,homicides,hiccups,hearse,hardened,gushing,gushie,greased,goddamit,freelancer,forging,fondue,flustered,flung,flinch,flicker,fixin,festivus,fertilizer,farted,faggots,exonerate,evict,enormously,encrypted,emdash,embracing,duress,dupres,dowser,doormat,disfigured,disciplined,dibbs,depository,deathbed,dazzled,cuttin,cures,crowding,crepe,crammed,copycat,contradict,confidant,condemning,conceited,commute,comatose,clapping,circumference,chuppah,chore,choksondik,chestnuts,briault,bottomless,bonnet,blokes,berluti,beret,beggars,bankroll,bania,athos,arsenic,apperantly,ahhhhhh,afloat,accents,zipped,zeros,zeroes,zamir,yuppie,youngsters,yorkers,wisest,wipes,wield,whyn't,weirdos,wednesdays,vicksburg,upchuck,untraceable,unsupervised,unpleasantness,unhook,unconscionable,uncalled,trappings,tragedies,townie,thurgood,things'll,thine,tetanus,terrorize,temptations,tanning,tampons,swarming,straitjacket,steroid,startling,starry,squander,speculating,sollozzo,sneaked,slugs,skedaddle,sinker,silky,shortcomings,sellin,seasoned,scrubbed,screwup,scrapes,scarves,sandbox,salesmen,rooming,romances,revere,reproach,reprieve,rearranging,ravine,rationalize,raffle,punchy,psychobabble,provocation,profoundly,prescriptions,preferable,polishing,poached,pledges,pirelli,perverts,oversized,overdressed,outdid,nuptials,nefarious,mouthpiece,motels,mopping,mongrel,missin,metaphorically,mertin,memos,melodrama,melancholy,measles,meaner,mantel,maneuvering,mailroom,luring,listenin,lifeless,licks,levon,legwork,kneecaps,kippur,kiddie,kaput,justifiable,insistent,insidious,innuendo,innit,indecent,imaginable,horseshit,hemorrhoid,hella,healthiest,haywire,hamsters,hairbrush,grouchy,grisly,gratuitous,glutton,glimmer,gibberish,ghastly,gentler,generously,geeky,fuhrer,fronting,foolin,faxes,faceless,extinguisher,expel,etched,endangering,ducked,dodgeball,dives,dislocated,discrepancy,devour,derail,dementia,daycare,cynic,crumbling,cowardice,covet,cornwallis,corkscrew,cookbook,commandments,coincidental,cobwebs,clouded,clogging,clicking,clasp,chopsticks,chefs,chaps,cashing,carat,calmer,brazen,brainwashing,bradys,bowing,boned,bloodsucking,bleachers,bleached,bedpan,bearded,barrenger,bachelors,awwww,assures,assigning,asparagus,apprehend,anecdote,amoral,aggravation,afoot,acquaintances,accommodating,yakking,worshipping,wladek,willya,willies,wigged,whoosh,whisked,watered,warpath,volts,violates,valuables,uphill,unwise,untimely,unsavory,unresponsive,unpunished,unexplained,tubby,trolling,toxicology,tormented,toothache,tingly,timmiihh,thursdays,thoreau,terrifies,temperamental,telegrams,talkie,takers,symbiote,swirl,suffocate,stupider,strapping,steckler,springing,someway,sleepyhead,sledgehammer,slant,slams,showgirl,shoveling,shmoopy,sharkbait,shan't,scrambling,schematics,sandeman,sabbatical,rummy,reykjavik,revert,responsive,rescheduled,requisition,relinquish,rejoice,reckoning,recant,rebadow,reassurance,rattlesnake,ramble,primed,pricey,prance,pothole,pocus,persist,perpetrated,pekar,peeling,pastime,parmesan,pacemaker,overdrive,ominous,observant,nothings,noooooo,nonexistent,nodded,nieces,neglecting,nauseating,mutated,musket,mumbling,mowing,mouthful,mooseport,monologue,mistrust,meetin,masseuse,mantini,mailer,madre,lowlifes,locksmith,livid,liven,limos,liberating,lhasa,leniency,leering,laughable,lashes,lasagne,laceration,korben,katan,kalen,jittery,jammies,irreplaceable,intubate,intolerant,inhaler,inhaled,indifferent,indifference,impound,impolite,humbly,heroics,heigh,guillotine,guesthouse,grounding,grips,gossiping,goatee,gnomes,gellar,frutt,frobisher,freudian,foolishness,flagged,femme,fatso,fatherhood,fantasized,fairest,faintest,eyelids,extravagant,extraterrestrial,extraordinarily,escalator,elevate,drivel,dissed,dismal,disarray,dinnertime,devastation,dermatologist,delicately,defrost,debutante,debacle,damone,dainty,cuvee,culpa,crucified,creeped,crayons,courtship,convene,congresswoman,concocted,compromises,comprende,comma,coleslaw,clothed,clinically,chickenshit,checkin,cesspool,caskets,calzone,brothel,boomerang,bodega,blasphemy,bitsy,bicentennial,berlini,beatin,beards,barbas,barbarians,backpacking,arrhythmia,arousing,arbitrator,antagonize,angling,anesthetic,altercation,aggressor,adversity,acathla,aaahhh,wreaking,workup,wonderin,wither,wielding,what'm,what'cha,waxed,vibrating,veterinarian,venting,vasey,valor,validate,upholstery,untied,unscathed,uninterrupted,unforgiving,undies,uncut,twinkies,tucking,treatable,treasured,tranquility,townspeople,torso,tomei,tipsy,tinsel,tidings,thirtieth,tantrums,tamper,talky,swayed,swapping,suitor,stylist,stirs,standoff,sprinklers,sparkly,snobby,snatcher,smoother,sleepin,shrug,shoebox,sheesh,shackles,setbacks,sedatives,screeching,scorched,scanned,satyr,roadblock,riverbank,ridiculed,resentful,repellent,recreate,reconvene,rebuttal,realmedia,quizzes,questionnaire,punctured,pucker,prolong,professionalism,pleasantly,pigsty,penniless,paychecks,patiently,parading,overactive,ovaries,orderlies,oracles,oiled,offending,nudie,neonatal,neighborly,moops,moonlighting,mobilize,mmmmmm,milkshake,menial,meats,mayan,maxed,mangled,magua,lunacy,luckier,liters,lansbury,kooky,knowin,jeopardized,inkling,inhalation,inflated,infecting,incense,inbound,impractical,impenetrable,idealistic,i'mma,hypocrites,hurtin,humbled,hologram,hokey,hocus,hitchhiking,hemorrhoids,headhunter,hassled,harts,hardworking,haircuts,hacksaw,genitals,gazillion,gammy,gamesphere,fugue,footwear,folly,flashlights,fives,filet,extenuating,estrogen,entails,embezzled,eloquent,egomaniac,ducts,drowsy,drones,doree,donovon,disguises,diggin,deserting,depriving,defying,deductible,decorum,decked,daylights,daybreak,dashboard,damnation,cuddling,crunching,crickets,crazies,councilman,coughed,conundrum,complimented,cohaagen,clutching,clued,clader,cheques,checkpoint,chats,channeling,ceases,carasco,capisce,cantaloupe,cancelling,campsite,burglars,breakfasts,bra'tac,blueprint,bleedin,blabbed,beneficiary,basing,avert,atone,arlyn,approves,apothecary,antiseptic,aleikuum,advisement,zadir,wobbly,withnail,whattaya,whacking,wedged,wanders,vaginal,unimaginable,undeniable,unconditionally,uncharted,unbridled,tweezers,tvmegasite,trumped,triumphant,trimming,treading,tranquilizers,toontown,thunk,suture,suppressing,strays,stonewall,stogie,stepdaughter,stace,squint,spouses,splashed,speakin,sounder,sorrier,sorrel,sombrero,solemnly,softened,snobs,snippy,snare,smoothing,slump,slimeball,slaving,silently,shiller,shakedown,sensations,scrying,scrumptious,screamin,saucy,santoses,roundup,roughed,rosary,robechaux,retrospect,rescind,reprehensible,repel,remodeling,reconsidering,reciprocate,railroaded,psychics,promos,prob'ly,pristine,printout,priestess,prenuptial,precedes,pouty,phoning,peppy,pariah,parched,panes,overloaded,overdoing,nymphs,nother,notebooks,nearing,nearer,monstrosity,milady,mieke,mephesto,medicated,marshals,manilow,mammogram,m'lady,lotsa,loopy,lesion,lenient,learner,laszlo,kross,kinks,jinxed,involuntary,insubordination,ingrate,inflatable,incarnate,inane,hypoglycemia,huntin,humongous,hoodlum,honking,hemorrhage,helpin,hathor,hatching,grotto,grandmama,gorillas,godless,girlish,ghouls,gershwin,frosted,flutter,flagpole,fetching,fatter,faithfully,exert,evasion,escalate,enticing,enchantress,elopement,drills,downtime,downloading,dorks,doorways,divulge,dissociative,disgraceful,disconcerting,deteriorate,destinies,depressive,dented,denim,decruz,decidedly,deactivate,daydreams,curls,culprit,cruelest,crippling,cranberries,corvis,copped,commend,coastguard,cloning,cirque,churning,chock,chivalry,catalogues,cartwheels,carols,canister,buttered,bundt,buljanoff,bubbling,brokers,broaden,brimstone,brainless,bores,badmouthing,autopilot,ascertain,aorta,ampata,allenby,accosted,absolve,aborted,aaagh,aaaaaah,yonder,yellin,wyndham,wrongdoing,woodsboro,wigging,wasteland,warranty,waltzed,walnuts,vividly,veggie,unnecessarily,unloaded,unicorns,understated,unclean,umbrellas,twirling,turpentine,tupperware,triage,treehouse,tidbit,tickled,threes,thousandth,thingie,terminally,teething,tassel,talkies,swoon,switchboard,swerved,suspiciously,subsequentlyne,subscribe,strudel,stroking,strictest,stensland,starin,stannart,squirming,squealing,sorely,softie,snookums,sniveling,smidge,sloth,skulking,simian,sightseeing,siamese,shudder,shoppers,sharpen,shannen,semtex,secondhand,seance,scowl,scorn,safekeeping,russe,rummage,roshman,roomies,roaches,rinds,retrace,retires,resuscitate,rerun,reputations,rekall,refreshment,reenactment,recluse,ravioli,raves,raking,purses,punishable,punchline,puked,prosky,previews,poughkeepsie,poppins,polluted,placenta,pissy,petulant,perseverance,pears,pawns,pastries,partake,panky,palate,overzealous,orchids,obstructing,objectively,obituaries,obedient,nothingness,musty,motherly,mooning,momentous,mistaking,minutemen,milos,microchip,meself,merciless,menelaus,mazel,masturbate,mahogany,lysistrata,lillienfield,likable,liberate,leveled,letdown,larynx,lardass,lainey,lagged,klorel,kidnappings,keyed,karmic,jeebies,irate,invulnerable,intrusive,insemination,inquire,injecting,informative,informants,impure,impasse,imbalance,illiterate,hurled,hunts,hematoma,headstrong,handmade,handiwork,growling,gorky,getcha,gesundheit,gazing,galley,foolishly,fondness,floris,ferocious,feathered,fateful,fancies,fakes,faker,expire,ever'body,essentials,eskimos,enlightening,enchilada,emissary,embolism,elsinore,ecklie,drenched,drazi,doped,dogging,doable,dislikes,dishonesty,disengage,discouraging,derailed,deformed,deflect,defer,deactivated,crips,constellations,congressmen,complimenting,clubbing,clawing,chromium,chimes,chews,cheatin,chaste,cellblock,caving,catered,catacombs,calamari,bucking,brulee,brits,brisk,breezes,bounces,boudoir,binks,better'n,bellied,behrani,behaves,bedding,balmy,badmouth,backers,avenging,aromatherapy,armpit,armoire,anythin,anonymously,anniversaries,aftershave,affliction,adrift,admissible,adieu,acquittal,yucky,yearn,whitter,whirlpool,wendigo,watchdog,wannabes,wakey,vomited,voicemail,valedictorian,uttered,unwed,unrequited,unnoticed,unnerving,unkind,unjust,uniformed,unconfirmed,unadulterated,unaccounted,uglier,turnoff,trampled,tramell,toads,timbuktu,throwback,thimble,tasteless,tarantula,tamale,takeovers,swish,supposing,streaking,stargher,stanzi,stabs,squeamish,splattered,spiritually,spilt,speciality,smacking,skywire,skips,skaara,simpatico,shredding,showin,shortcuts,shite,shielding,shamelessly,serafine,sentimentality,seasick,schemer,scandalous,sainted,riedenschneider,rhyming,revel,retractor,retards,resurrect,remiss,reminiscing,remanded,reiben,regains,refuel,refresher,redoing,redheaded,reassured,rearranged,rapport,qumar,prowling,prejudices,precarious,powwow,pondering,plunger,plunged,pleasantville,playpen,phlegm,perfected,pancreas,paley,ovary,outbursts,oppressed,ooohhh,omoroca,offed,o'toole,nurture,nursemaid,nosebleed,necktie,muttering,munchies,mucking,mogul,mitosis,misdemeanor,miscarried,millionth,migraines,midler,manicurist,mandelbaum,manageable,malfunctioned,magnanimous,loudmouth,longed,lifestyles,liddy,lickety,leprechauns,komako,klute,kennel,justifying,irreversible,inventing,intergalactic,insinuate,inquiring,ingenuity,inconclusive,incessant,improv,impersonation,hyena,humperdinck,hubba,housework,hoffa,hither,hissy,hippy,hijacked,heparin,hellooo,hearth,hassles,hairstyle,hahahaha,hadda,guys'll,gutted,gulls,gritty,grievous,graft,gossamer,gooder,gambled,gadgets,fundamentals,frustrations,frolicking,frock,frilly,foreseen,footloose,fondly,flirtation,flinched,flatten,farthest,exposer,evading,escrow,empathize,embryos,embodiment,ellsberg,ebola,dulcinea,dreamin,drawbacks,doting,doose,doofy,disturbs,disorderly,disgusts,detox,denominator,demeanor,deliriously,decode,debauchery,croissant,cravings,cranked,coworkers,councilor,confuses,confiscate,confines,conduit,compress,combed,clouding,clamps,cinch,chinnery,celebratory,catalogs,carpenters,carnal,canin,bundys,bulldozer,buggers,bueller,brainy,booming,bookstores,bloodbath,bittersweet,bellhop,beeping,beanstalk,beady,baudelaire,bartenders,bargains,averted,armadillo,appreciating,appraised,antlers,aloof,allowances,alleyway,affleck,abject,zilch,youore,xanax,wrenching,wouldn,witted,wicca,whorehouse,whooo,whips,vouchers,victimized,vicodin,untested,unsolicited,unfocused,unfettered,unfeeling,unexplainable,understaffed,underbelly,tutorial,tryst,trampoline,towering,tirade,thieving,thang,swimmin,swayzak,suspecting,superstitions,stubbornness,streamers,strattman,stonewalling,stiffs,stacking,spout,splice,sonrisa,smarmy,slows,slicing,sisterly,shrill,shined,seeming,sedley,seatbelts,scour,scold,schoolyard,scarring,salieri,rustling,roxbury,rewire,revved,retriever,reputable,remodel,reins,reincarnation,rance,rafters,rackets,quail,pumbaa,proclaim,probing,privates,pried,prewedding,premeditation,posturing,posterity,pleasurable,pizzeria,pimps,penmanship,penchant,pelvis,overturn,overstepped,overcoat,ovens,outsmart,outed,ooohh,oncologist,omission,offhand,odour,nyazian,notarized,nobody'll,nightie,navel,nabbed,mystique,mover,mortician,morose,moratorium,mockingbird,mobsters,mingling,methinks,messengered,merde,masochist,martouf,martians,marinara,manray,majorly,magnifying,mackerel,lurid,lugging,lonnegan,loathsome,llantano,liberace,leprosy,latinos,lanterns,lamest,laferette,kraut,intestine,innocencia,inhibitions,ineffectual,indisposed,incurable,inconvenienced,inanimate,improbable,implode,hydrant,hustling,hustled,huevos,how'm,hooey,hoods,honcho,hinge,hijack,heimlich,hamunaptra,haladki,haiku,haggle,gutsy,grunting,grueling,gribbs,greevy,grandstanding,godparents,glows,glistening,gimmick,gaping,fraiser,formalities,foreigner,folders,foggy,fitty,fiends,fe'nos,favours,eyeing,extort,expedite,escalating,epinephrine,entitles,entice,eminence,eights,earthlings,eagerly,dunville,dugout,doublemeat,doling,dispensing,dispatcher,discoloration,diners,diddly,dictates,diazepam,derogatory,delights,defies,decoder,dealio,danson,cutthroat,crumbles,croissants,crematorium,craftsmanship,could'a,cordless,cools,conked,confine,concealing,complicates,communique,cockamamie,coasters,clobbered,clipping,clipboard,clemenza,cleanser,circumcision,chanukah,certainaly,cellmate,cancels,cadmium,buzzed,bumstead,bucko,browsing,broth,braver,boggling,bobbing,blurred,birkhead,benet,belvedere,bellies,begrudge,beckworth,banky,baldness,baggy,babysitters,aversion,astonished,assorted,appetites,angina,amiss,ambulances,alibis,airway,admires,adhesive,yoyou,xxxxxx,wreaked,wracking,woooo,wooing,wised,wilshire,wedgie,waging,violets,vincey,uplifting,untrustworthy,unmitigated,uneventful,undressing,underprivileged,unburden,umbilical,tweaking,turquoise,treachery,tosses,torching,toothpick,toasts,thickens,tereza,tenacious,teldar,taint,swill,sweatin,subtly,subdural,streep,stopwatch,stockholder,stillwater,stalkers,squished,squeegee,splinters,spliced,splat,spied,spackle,sophistication,snapshots,smite,sluggish,slithered,skeeters,sidewalks,sickly,shrugs,shrubbery,shrieking,shitless,settin,sentinels,selfishly,scarcely,sangria,sanctum,sahjhan,rustle,roving,rousing,rosomorf,riddled,responsibly,renoir,remoray,remedial,refundable,redirect,recheck,ravenwood,rationalizing,ramus,ramelle,quivering,pyjamas,psychos,provocations,prouder,protestors,prodded,proctologist,primordial,pricks,prickly,precedents,pentangeli,pathetically,parka,parakeet,panicky,overthruster,outsmarted,orthopedic,oncoming,offing,nutritious,nuthouse,nourishment,nibbling,newlywed,narcissist,mutilation,mundane,mummies,mumble,mowed,morvern,mortem,mopes,molasses,misplace,miscommunication,miney,midlife,menacing,memorizing,massaging,masking,magnets,luxuries,lounging,lothario,liposuction,lidocaine,libbets,levitate,leeway,launcelot,larek,lackeys,kumbaya,kryptonite,knapsack,keyhole,katarangura,juiced,jakey,ironclad,invoice,intertwined,interlude,interferes,injure,infernal,indeedy,incur,incorrigible,incantations,impediment,igloo,hysterectomy,hounded,hollering,hindsight,heebie,havesham,hasenfuss,hankering,hangers,hakuna,gutless,gusto,grubbing,grrrr,grazed,gratification,grandeur,gorak,godammit,gnawing,glanced,frostbite,frees,frazzled,fraulein,fraternizing,fortuneteller,formaldehyde,followup,foggiest,flunky,flickering,firecrackers,figger,fetuses,fates,eyeliner,extremities,extradited,expires,exceedingly,evaporate,erupt,epileptic,entrails,emporium,egregious,eggshells,easing,duwayne,droll,dreyfuss,dovey,doubly,doozy,donkeys,donde,distrust,distressing,disintegrate,discreetly,decapitated,dealin,deader,dashed,darkroom,dares,daddies,dabble,cushy,cupcakes,cuffed,croupier,croak,crapped,coursing,coolers,contaminate,consummated,construed,condos,concoction,compulsion,commish,coercion,clemency,clairvoyant,circulate,chesterton,checkered,charlatan,chaperones,categorically,cataracts,carano,capsules,capitalize,burdon,bullshitting,brewed,breathless,breasted,brainstorming,bossing,borealis,bonsoir,bobka,boast,blimp,bleep,bleeder,blackouts,bisque,billboards,beatings,bayberry,bashed,bamboozled,balding,baklava,baffled,backfires,babak,awkwardness,attest,attachments,apologizes,anyhoo,antiquated,alcante,advisable,aahhh,aaahh,zatarc,yearbooks,wuddya,wringing,womanhood,witless,winging,whatsa,wetting,waterproof,wastin,vogelman,vocation,vindicated,vigilance,vicariously,venza,vacuuming,utensils,uplink,unveil,unloved,unloading,uninhibited,unattached,tweaked,turnips,trinkets,toughen,toting,topside,terrors,terrify,technologically,tarnish,tagliati,szpilman,surly,supple,summation,suckin,stepmom,squeaking,splashmore,souffle,solitaire,solicitation,solarium,smokers,slugged,slobbering,skylight,skimpy,sinuses,silenced,sideburns,shrinkage,shoddy,shhhhhh,shelled,shareef,shangri,seuss,serenade,scuffle,scoff,scanners,sauerkraut,sardines,sarcophagus,salvy,rusted,russells,rowboat,rolfsky,ringside,respectability,reparations,renegotiate,reminisce,reimburse,regimen,raincoat,quibble,puzzled,purposefully,pubic,proofing,prescribing,prelim,poisons,poaching,personalized,personable,peroxide,pentonville,payphone,payoffs,paleontology,overflowing,oompa,oddest,objecting,o'hare,o'daniel,notches,nobody'd,nightstand,neutralized,nervousness,nerdy,needlessly,naquadah,nappy,nantucket,nambla,mountaineer,motherfuckin,morrie,monopolizing,mohel,mistreated,misreading,misbehave,miramax,minivan,milligram,milkshakes,metamorphosis,medics,mattresses,mathesar,matchbook,matata,marys,malucci,magilla,lymphoma,lowers,lordy,linens,lindenmeyer,limelight,leapt,laxative,lather,lapel,lamppost,laguardia,kindling,kegger,kawalsky,juries,jokin,jesminder,interning,innermost,injun,infallible,industrious,indulgence,incinerator,impossibility,impart,illuminate,iguanas,hypnotic,hyped,hospitable,hoses,homemaker,hirschmuller,helpers,headset,guardianship,guapo,grubby,granola,granddaddy,goren,goblet,gluttony,globes,giorno,getter,geritol,gassed,gaggle,foxhole,fouled,foretold,floorboards,flippers,flaked,fireflies,feedings,fashionably,farragut,fallback,facials,exterminate,excites,everything'll,evenin,ethically,ensue,enema,empath,eluded,eloquently,eject,edema,dumpling,droppings,dolled,distasteful,disputing,displeasure,disdain,deterrent,dehydration,defied,decomposing,dawned,dailies,custodian,crusts,crucifix,crowning,crier,crept,craze,crawls,couldn,correcting,corkmaster,copperfield,cooties,contraption,consumes,conspire,consenting,consented,conquers,congeniality,complains,communicator,commendable,collide,coladas,colada,clout,clooney,classifieds,clammy,civility,cirrhosis,chink,catskills,carvers,carpool,carelessness,cardio,carbs,capades,butabi,busmalis,burping,burdens,bunks,buncha,bulldozers,browse,brockovich,breakthroughs,bravado,boogety,blossoms,blooming,bloodsucker,blight,betterton,betrayer,belittle,beeps,bawling,barts,bartending,bankbooks,babish,atropine,assertive,armbrust,anyanka,annoyance,anemic,anago,airwaves,aimlessly,aaargh,aaand,yoghurt,writhing,workable,winking,winded,widen,whooping,whiter,whatya,wazoo,voila,virile,vests,vestibule,versed,vanishes,urkel,uproot,unwarranted,unscheduled,unparalleled,undergrad,tweedle,turtleneck,turban,trickery,transponder,toyed,townhouse,thyself,thunderstorm,thinning,thawed,tether,technicalities,tau'ri,tarnished,taffeta,tacked,systolic,swerve,sweepstakes,swabs,suspenders,superwoman,sunsets,succulent,subpoenas,stumper,stosh,stomachache,stewed,steppin,stepatech,stateside,spicoli,sparing,soulless,sonnets,sockets,snatching,smothering,slush,sloman,slashing,sitters,simpleton,sighs,sidra,sickens,shunned,shrunken,showbiz,shopped,shimmering,shagging,semblance,segue,sedation,scuzzlebutt,scumbags,screwin,scoundrels,scarsdale,scabs,saucers,saintly,saddened,runaways,runaround,rheya,resenting,rehashing,rehabilitated,regrettable,refreshed,redial,reconnecting,ravenous,raping,rafting,quandary,pylea,putrid,puffing,psychopathic,prunes,probate,prayin,pomegranate,plummeting,planing,plagues,pinata,pithy,perversion,personals,perched,peeps,peckish,pavarotti,pajama,packin,pacifier,overstepping,okama,obstetrician,nutso,nuance,normalcy,nonnegotiable,nomak,ninny,nines,nicey,newsflash,neutered,nether,negligee,necrosis,navigating,narcissistic,mylie,muses,momento,moisturizer,moderation,misinformed,misconception,minnifield,mikkos,methodical,mebbe,meager,maybes,matchmaking,masry,markovic,malakai,luzhin,lusting,lumberjack,loopholes,loaning,lightening,leotard,launder,lamaze,kubla,kneeling,kibosh,jumpsuit,joliet,jogger,janover,jakovasaurs,irreparable,innocently,inigo,infomercial,inexplicable,indispensable,impregnated,impossibly,imitating,hunches,hummus,houmfort,hothead,hostiles,hooves,hooligans,homos,homie,hisself,heyyy,hesitant,hangout,handsomest,handouts,hairless,gwennie,guzzling,guinevere,grungy,goading,glaring,gavel,gardino,gangrene,fruitful,friendlier,freckle,freakish,forthright,forearm,footnote,flops,fixer,firecracker,finito,figgered,fezzik,fastened,farfetched,fanciful,familiarize,faire,fahrenheit,extravaganza,exploratory,explanatory,everglades,eunuch,estas,escapade,erasers,emptying,embarassing,dweeb,dutiful,dumplings,dries,drafty,dollhouse,dismissing,disgraced,discrepancies,disbelief,disagreeing,digestion,didnt,deviled,deviated,demerol,delectable,decaying,decadent,dears,dateless,d'algout,cultivating,cryto,crumpled,crumbled,cronies,crease,craves,cozying,corduroy,congratulated,confidante,compressions,complicating,compadre,coerce,classier,chums,chumash,chivalrous,chinpoko,charred,chafing,celibacy,carted,carryin,carpeting,carotid,cannibals,candor,butterscotch,busts,busier,bullcrap,buggin,brookside,brodski,brassiere,brainwash,brainiac,botrelle,bonbon,boatload,blimey,blaring,blackness,bipartisan,bimbos,bigamist,biebe,biding,betrayals,bestow,bellerophon,bedpans,bassinet,basking,barzini,barnyard,barfed,backups,audited,asinine,asalaam,arouse,applejack,annoys,anchovies,ampule,alameida,aggravate,adage,accomplices,yokel,y'ever,wringer,witwer,withdrawals,windward,willfully,whorfin,whimsical,whimpering,weddin,weathered,warmest,wanton,volant,visceral,vindication,veggies,urinate,uproar,unwritten,unwrap,unsung,unsubstantiated,unspeakably,unscrupulous,unraveling,unquote,unqualified,unfulfilled,undetectable,underlined,unattainable,unappreciated,ummmm,ulcers,tylenol,tweak,turnin,tuatha,tropez,trellis,toppings,tootin,toodle,tinkering,thrives,thespis,theatrics,thatherton,tempers,tavington,tartar,tampon,swelled,sutures,sustenance,sunflowers,sublet,stubbins,strutting,strewn,stowaway,stoic,sternin,stabilizing,spiraling,spinster,speedometer,speakeasy,soooo,soiled,sneakin,smithereens,smelt,smacks,slaughterhouse,slacks,skids,sketching,skateboards,sizzling,sixes,sirree,simplistic,shouts,shorted,shoelace,sheeit,shards,shackled,sequestered,selmak,seduces,seclusion,seamstress,seabeas,scoops,scooped,scavenger,satch,s'more,rudeness,romancing,rioja,rifkin,rieper,revise,reunions,repugnant,replicating,repaid,renewing,relaxes,rekindle,regrettably,regenerate,reels,reciting,reappear,readin,ratting,rapes,rancher,rammed,rainstorm,railroading,queers,punxsutawney,punishes,pssst,prudy,proudest,protectors,procrastinating,proactive,priss,postmortem,pompoms,poise,pickings,perfectionist,peretti,people'll,pecking,patrolman,paralegal,paragraphs,paparazzi,pankot,pampering,overstep,overpower,outweigh,omnipotent,odious,nuwanda,nurtured,newsroom,neeson,needlepoint,necklaces,neato,muggers,muffler,mousy,mourned,mosey,mopey,mongolians,moldy,misinterpret,minibar,microfilm,mendola,mended,melissande,masturbating,masbath,manipulates,maimed,mailboxes,magnetism,m'lord,m'honey,lymph,lunge,lovelier,lefferts,leezak,ledgers,larraby,laloosh,kundun,kozinski,knockoff,kissin,kiosk,kennedys,kellman,karlo,kaleidoscope,jeffy,jaywalking,instructing,infraction,informer,infarction,impulsively,impressing,impersonated,impeach,idiocy,hyperbole,hurray,humped,huhuh,hsing,hordes,hoodlums,honky,hitchhiker,hideously,heaving,heathcliff,headgear,headboard,hazing,harem,handprint,hairspray,gutiurrez,goosebumps,gondola,glitches,gasping,frolic,freeways,frayed,fortitude,forgetful,forefathers,fonder,foiled,foaming,flossing,flailing,fitzgeralds,firehouse,finders,fiftieth,fellah,fawning,farquaad,faraway,fancied,extremists,exorcist,exhale,ethros,entrust,ennui,energized,encephalitis,embezzling,elster,elixir,electrolytes,duplex,dryers,drexl,dredging,drawback,don'ts,dobisch,divorcee,disrespected,disprove,disobeying,disinfectant,dingy,digress,dieting,dictating,devoured,devise,detonators,desist,deserter,derriere,deron,deceptive,debilitating,deathwok,daffodils,curtsy,cursory,cuppa,cumin,cronkite,cremation,credence,cranking,coverup,courted,countin,counselling,cornball,contentment,consensual,compost,cluett,cleverly,cleansed,cleanliness,chopec,chomp,chins,chime,cheswick,chessler,cheapest,chatted,cauliflower,catharsis,catchin,caress,camcorder,calorie,cackling,bystanders,buttoned,buttering,butted,buries,burgel,buffoon,brogna,bragged,boutros,bogeyman,blurting,blurb,blowup,bloodhound,blissful,birthmark,bigot,bestest,belted,belligerent,beggin,befall,beeswax,beatnik,beaming,barricade,baggoli,badness,awoke,artsy,artful,aroun,armpits,arming,annihilate,anise,angiogram,anaesthetic,amorous,ambiance,alligators,adoration,admittance,adama,abydos,zonked,zhivago,yorkin,wrongfully,writin,wrappers,worrywart,woops,wonderfalls,womanly,wickedness,whoopie,wholeheartedly,whimper,which'll,wheelchairs,what'ya,warranted,wallop,wading,wacked,virginal,vermouth,vermeil,verger,ventriss,veneer,vampira,utero,ushers,urgently,untoward,unshakable,unsettled,unruly,unlocks,ungodly,undue,uncooperative,uncontrollably,unbeatable,twitchy,tumbler,truest,triumphs,triplicate,tribbey,tortures,tongaree,tightening,thorazine,theres,testifies,teenaged,tearful,taxing,taldor,syllabus,swoops,swingin,suspending,sunburn,stuttering,stupor,strides,strategize,strangulation,stooped,stipulation,stingy,stapled,squeaks,squawking,spoilsport,splicing,spiel,spencers,spasms,spaniard,softener,sodding,soapbox,smoldering,smithbauer,skittish,sifting,sickest,sicilians,shuffling,shrivel,segretti,seeping,securely,scurrying,scrunch,scrote,screwups,schenkman,sawing,savin,satine,sapiens,salvaging,salmonella,sacrilege,rumpus,ruffle,roughing,rotted,rondall,ridding,rickshaw,rialto,rhinestone,restrooms,reroute,requisite,repress,rednecks,redeeming,rayed,ravell,raked,raincheck,raffi,racked,pushin,profess,prodding,procure,presuming,preppy,prednisone,potted,posttraumatic,poorhouse,podiatrist,plowed,pledging,playroom,plait,placate,pinback,picketing,photographing,pharoah,petrak,petal,persecuting,perchance,pellets,peeved,peerless,payable,pauses,pathologist,pagliacci,overwrought,overreaction,overqualified,overheated,outcasts,otherworldly,opinionated,oodles,oftentimes,occured,obstinate,nutritionist,numbness,nubile,nooooooo,nobodies,nepotism,neanderthals,mushu,mucus,mothering,mothballs,monogrammed,molesting,misspoke,misspelled,misconstrued,miscalculated,minimums,mince,mildew,mighta,middleman,mementos,mellowed,mayol,mauled,massaged,marmalade,mardi,makings,lundegaard,lovingly,loudest,lotto,loosing,loompa,looming,longs,loathes,littlest,littering,lifelike,legalities,laundered,lapdog,lacerations,kopalski,knobs,knitted,kittridge,kidnaps,kerosene,karras,jungles,jockeys,iranoff,invoices,invigorating,insolence,insincere,insectopia,inhumane,inhaling,ingrates,infestation,individuality,indeterminate,incomprehensible,inadequacy,impropriety,importer,imaginations,illuminating,ignite,hysterics,hypodermic,hyperventilate,hyperactive,humoring,honeymooning,honed,hoist,hoarding,hitching,hiker,hightail,hemoglobin,hell'd,heinie,growin,grasped,grandparent,granddaughters,gouged,goblins,gleam,glades,gigantor,get'em,geriatric,gatekeeper,gargoyles,gardenias,garcon,garbo,gallows,gabbing,futon,fulla,frightful,freshener,fortuitous,forceps,fogged,fodder,foamy,flogging,flaun,flared,fireplaces,feverish,favell,fattest,fattening,fallow,extraordinaire,evacuating,errant,envied,enchant,enamored,egocentric,dussander,dunwitty,dullest,dropout,dredged,dorsia,doornail,donot,dongs,dogged,dodgy,ditty,dishonorable,discriminating,discontinue,dings,dilly,dictation,dialysis,delly,delightfully,daryll,dandruff,cruddy,croquet,cringe,crimp,credo,crackling,courtside,counteroffer,counterfeiting,corrupting,copping,conveyor,contusions,contusion,conspirator,consoling,connoisseur,confetti,composure,compel,colic,coddle,cocksuckers,coattails,cloned,claustrophobia,clamoring,churn,chugga,chirping,chasin,chapped,chalkboard,centimeter,caymans,catheter,casings,caprica,capelli,cannolis,cannoli,camogli,camembert,butchers,butchered,busboys,bureaucrats,buckled,bubbe,brownstone,bravely,brackley,bouquets,botox,boozing,boosters,bodhi,blunders,blunder,blockage,biocyte,betrays,bested,beryllium,beheading,beggar,begbie,beamed,bastille,barstool,barricades,barbecues,barbecued,bandwagon,backfiring,bacarra,avenged,autopsies,aunties,associating,artichoke,arrowhead,appendage,apostrophe,antacid,ansel,annul,amuses,amped,amicable,amberg,alluring,adversaries,admirers,adlai,acupuncture,abnormality,aaaahhhh,zooming,zippity,zipping,zeroed,yuletide,yoyodyne,yengeese,yeahhh,wrinkly,wracked,withered,winks,windmills,whopping,wendle,weigart,waterworks,waterbed,watchful,wantin,wagging,waaah,vying,ventricle,varnish,vacuumed,unreachable,unprovoked,unmistakable,unfriendly,unfolding,underpaid,uncuff,unappealing,unabomber,typhoid,tuxedos,tushie,turds,tumnus,troubadour,trinium,treaters,treads,transpired,transgression,tought,thready,thins,thinners,techs,teary,tattaglia,tassels,tarzana,tanking,tablecloths,synchronize,symptomatic,sycophant,swimmingly,sweatshop,surfboard,superpowers,sunroom,sunblock,sugarplum,stupidly,strumpet,strapless,stooping,stools,stealthy,stalks,stairmaster,staffer,sshhh,squatting,squatters,spectacularly,sorbet,socked,sociable,snubbed,snorting,sniffles,snazzy,snakebite,smuggler,smorgasbord,smooching,slurping,slouch,slingshot,slaved,skimmed,sisterhood,silliest,sidarthur,sheraton,shebang,sharpening,shanghaied,shakers,sendoff,scurvy,scoliosis,scaredy,scagnetti,sawchuk,saugus,sasquatch,sandbag,saltines,s'pose,roston,rostle,riveting,ristle,rifling,revulsion,reverently,retrograde,restful,resents,reptilian,reorganize,renovating,reiterate,reinvent,reinmar,reibers,reechard,recuse,reconciling,recognizance,reclaiming,recitation,recieved,rebate,reacquainted,rascals,railly,quintuplets,quahog,pygmies,puzzling,punctuality,prosthetic,proms,probie,preys,preserver,preppie,poachers,plummet,plumbers,plannin,pitying,pitfalls,piqued,pinecrest,pinches,pillage,pigheaded,physique,pessimistic,persecute,perjure,percentile,pentothal,pensky,penises,peini,pazzi,pastels,parlour,paperweight,pamper,pained,overwhelm,overalls,outrank,outpouring,outhouse,outage,ouija,obstructed,obsessions,obeying,obese,o'riley,o'higgins,nosebleeds,norad,noooooooo,nononono,nonchalant,nippy,neurosis,nekhorvich,necronomicon,naquada,n'est,mystik,mystified,mumps,muddle,mothership,moped,monumentally,monogamous,mondesi,misogynistic,misinterpreting,mindlock,mending,megaphone,meeny,medicating,meanie,masseur,markstrom,marklars,margueritas,manifesting,maharajah,lukewarm,loveliest,loran,lizardo,liquored,lipped,lingers,limey,lemkin,leisurely,lathe,latched,lapping,ladle,krevlorneswath,kosygin,khakis,kenaru,keats,kaitlan,julliard,jollies,jaundice,jargon,jackals,invisibility,insipid,inflamed,inferiority,inexperience,incinerated,incinerate,incendiary,incan,inbred,implicating,impersonator,hunks,horsing,hooded,hippopotamus,hiked,hetson,hetero,hessian,henslowe,hendler,hellstrom,headstone,hayloft,harbucks,handguns,hallucinate,haldol,haggling,gynaecologist,gulag,guilder,guaranteeing,groundskeeper,grindstone,grimoir,grievance,griddle,gribbit,greystone,graceland,gooders,goeth,gentlemanly,gelatin,gawking,ganged,fukes,fromby,frenchmen,foursome,forsley,forbids,footwork,foothold,floater,flinging,flicking,fittest,fistfight,fireballs,fillings,fiddling,fennyman,felonious,felonies,feces,favoritism,fatten,fanatics,faceman,excusing,excepted,entwined,entree,ensconced,eladio,ehrlichman,easterland,dueling,dribbling,drape,downtrodden,doused,dosed,dorleen,dokie,distort,displeased,disown,dismount,disinherited,disarmed,disapproves,diperna,dined,diligent,dicaprio,depress,decoded,debatable,dealey,darsh,damsels,damning,dad'll,d'oeuvre,curlers,curie,cubed,crikey,crepes,countrymen,cornfield,coppers,copilot,copier,cooing,conspiracies,consigliere,condoning,commoner,commies,combust,comas,colds,clawed,clamped,choosy,chomping,chimps,chigorin,chianti,cheep,checkups,cheaters,celibate,cautiously,cautionary,castell,carpentry,caroling,carjacking,caritas,caregiver,cardiology,candlesticks,canasta,cain't,burro,burnin,bunking,bumming,bullwinkle,brummel,brooms,brews,breathin,braslow,bracing,botulism,boorish,bloodless,blayne,blatantly,blankie,bedbugs,becuase,barmaid,bared,baracus,banal,bakes,backpacks,attentions,atrocious,ativan,athame,asunder,astound,assuring,aspirins,asphyxiation,ashtrays,aryans,arnon,apprehension,applauding,anvil,antiquing,antidepressants,annoyingly,amputate,altruistic,alotta,alerting,afterthought,affront,affirm,actuality,abysmal,absentee,yeller,yakushova,wuzzy,wriggle,worrier,woogyman,womanizer,windpipe,windbag,willin,whisking,whimsy,wendall,weeny,weensy,weasels,watery,watcha,wasteful,waski,washcloth,waaay,vouched,viznick,ventriloquist,vendettas,veils,vayhue,vamanos,vadimus,upstage,uppity,unsaid,unlocking,unintentionally,undetected,undecided,uncaring,unbearably,tween,tryout,trotting,trini,trimmings,trickier,treatin,treadstone,trashcan,transcendent,tramps,townsfolk,torturous,torrid,toothpicks,tolerable,tireless,tiptoeing,timmay,tillinghouse,tidying,tibia,thumbing,thrusters,thrashing,these'll,thatos,testicular,teriyaki,tenors,tenacity,tellers,telemetry,tarragon,switchblade,swicker,swells,sweatshirts,swatches,surging,supremely,sump'n,succumb,subsidize,stumbles,stuffs,stoppin,stipulate,stenographer,steamroll,stasis,stagger,squandered,splint,splendidly,splashy,splashing,specter,sorcerers,somewheres,somber,snuggled,snowmobile,sniffed,snags,smugglers,smudged,smirking,smearing,slings,sleet,sleepovers,sleek,slackers,siree,siphoning,singed,sincerest,sickened,shuffled,shriveled,shorthanded,shittin,shish,shipwrecked,shins,sheetrock,shawshank,shamu,sha're,servitude,sequins,seascape,scrapings,scoured,scorching,sandpaper,saluting,salud,ruffled,roughnecks,rougher,rosslyn,rosses,roost,roomy,romping,revolutionize,reprimanded,refute,refrigerated,reeled,redundancies,rectal,recklessly,receding,reassignment,reapers,readout,ration,raring,ramblings,raccoons,quarantined,purging,punters,psychically,premarital,pregnancies,predisposed,precautionary,pollute,podunk,plums,plaything,pixilated,pitting,piranhas,pieced,piddles,pickled,photogenic,phosphorous,pffft,pestilence,pessimist,perspiration,perps,penticoff,passageways,pardons,panics,pancamo,paleontologist,overwhelms,overstating,overpaid,overdid,outlive,orthodontist,orgies,oreos,ordover,ordinates,ooooooh,oooohhh,omelettes,officiate,obtuse,obits,nymph,novocaine,noooooooooo,nipping,nilly,nightstick,negate,neatness,natured,narcotic,narcissism,namun,nakatomi,murky,muchacho,mouthwash,motzah,morsel,morph,morlocks,mooch,moloch,molest,mohra,modus,modicum,mockolate,misdemeanors,miscalculation,middies,meringue,mercilessly,meditating,mayakovsky,maximillian,marlee,markovski,maniacal,maneuvered,magnificence,maddening,lutze,lunged,lovelies,lorry,loosening,lookee,littered,lilac,lightened,laces,kurzon,kurtzweil,kind've,kimono,kenji,kembu,keanu,kazuo,jonesing,jilted,jiggling,jewelers,jewbilee,jacqnoud,jacksons,ivories,insurmountable,innocuous,innkeeper,infantery,indulged,indescribable,incoherent,impervious,impertinent,imperfections,hunnert,huffy,horsies,horseradish,hollowed,hogwash,hockley,hissing,hiromitsu,hidin,hereafter,helpmann,hehehe,haughty,happenings,hankie,handsomely,halliwells,haklar,haise,gunsights,grossly,grope,grocer,grits,gripping,grabby,glorificus,gizzard,gilardi,gibarian,geminon,gasses,garnish,galloping,gairwyn,futterman,futility,fumigated,fruitless,friendless,freon,foregone,forego,floored,flighty,flapjacks,fizzled,ficus,festering,farbman,fabricate,eyghon,extricate,exalted,eventful,esophagus,enterprising,entail,endor,emphatically,embarrasses,electroshock,easel,duffle,drumsticks,dissection,dissected,disposing,disparaging,disorientation,disintegrated,disarming,devoting,dessaline,deprecating,deplorable,delve,degenerative,deduct,decomposed,deathly,dearie,daunting,dankova,cyclotron,cyberspace,cutbacks,culpable,cuddled,crumpets,cruelly,crouching,cranium,cramming,cowering,couric,cordesh,conversational,conclusively,clung,clotting,cleanest,chipping,chimpanzee,chests,cheapen,chainsaws,censure,catapult,caravaggio,carats,captivating,calrissian,butlers,busybody,bussing,bunion,bulimic,budging,brung,browbeat,brokenhearted,brecher,breakdowns,bracebridge,boning,blowhard,blisters,blackboard,bigotry,bialy,bhamra,bended,begat,battering,baste,basquiat,barricaded,barometer,balled,baited,badenweiler,backhand,ascenscion,argumentative,appendicitis,apparition,anxiously,antagonistic,angora,anacott,amniotic,ambience,alonna,aleck,akashic,ageless,abouts,aawwww,aaaaarrrrrrggghhh,aaaaaa,zendi,yuppies,yodel,y'hear,wrangle,wombosi,wittle,withstanding,wisecracks,wiggling,wierd,whittlesley,whipper,whattya,whatsamatter,whatchamacallit,whassup,whad'ya,weakling,warfarin,waponis,wampum,wadn't,vorash,vizzini,virtucon,viridiana,veracity,ventilated,varicose,varcon,vandalized,vamos,vamoose,vaccinated,vacationing,usted,urinal,uppers,unwittingly,unsealed,unplanned,unhinged,unhand,unfathomable,unequivocally,unbreakable,unadvisedly,udall,tynacorp,tuxes,tussle,turati,tunic,tsavo,trussed,troublemakers,trollop,tremors,transsexual,transfusions,toothbrushes,toned,toddlers,tinted,tightened,thundering,thorpey,this'd,thespian,thaddius,tenuous,tenths,tenement,telethon,teleprompter,teaspoon,taunted,tattle,tardiness,taraka,tappy,tapioca,tapeworm,talcum,tacks,swivel,swaying,superpower,summarize,sumbitch,sultry,suburbia,styrofoam,stylings,strolls,strobe,stockpile,stewardesses,sterilized,sterilize,stealin,stakeouts,squawk,squalor,squabble,sprinkled,sportsmanship,spokes,spiritus,sparklers,spareribs,sowing,sororities,sonovabitch,solicit,softy,softness,softening,snuggling,snatchers,snarling,snarky,snacking,smears,slumped,slowest,slithering,sleazebag,slayed,slaughtering,skidded,skated,sivapathasundaram,sissies,silliness,silences,sidecar,sicced,shylock,shtick,shrugged,shriek,shoves,should'a,shortcake,shockingly,shirking,shaves,shatner,sharpener,shapely,shafted,sexless,septum,selflessness,seabea,scuff,screwball,scoping,scooch,scolding,schnitzel,schemed,scalper,santy,sankara,sanest,salesperson,sakulos,safehouse,sabers,runes,rumblings,rumbling,ruijven,ringers,righto,rhinestones,retrieving,reneging,remodelling,relentlessly,regurgitate,refills,reeking,reclusive,recklessness,recanted,ranchers,rafer,quaking,quacks,prophesied,propensity,profusely,problema,prided,prays,postmark,popsicles,poodles,pollyanna,polaroids,pokes,poconos,pocketful,plunging,plugging,pleeease,platters,pitied,pinetti,piercings,phooey,phonies,pestering,periscope,pentagram,pelts,patronized,paramour,paralyze,parachutes,pales,paella,paducci,owatta,overdone,overcrowded,overcompensating,ostracized,ordinate,optometrist,operandi,omens,okayed,oedipal,nuttier,nuptial,nunheim,noxious,nourish,notepad,nitroglycerin,nibblet,neuroses,nanosecond,nabbit,mythic,munchkins,multimillion,mulroney,mucous,muchas,mountaintop,morlin,mongorians,moneybags,mom'll,molto,mixup,misgivings,mindset,michalchuk,mesmerized,merman,mensa,meaty,mbwun,materialize,materialistic,masterminded,marginally,mapuhe,malfunctioning,magnify,macnamara,macinerney,machinations,macadamia,lysol,lurks,lovelorn,lopsided,locator,litback,litany,linea,limousines,limes,lighters,liebkind,levity,levelheaded,letterhead,lesabre,leron,lepers,lefts,leftenant,laziness,layaway,laughlan,lascivious,laryngitis,lapsed,landok,laminated,kurten,kobol,knucklehead,knowed,knotted,kirkeby,kinsa,karnovsky,jolla,jimson,jettison,jeric,jawed,jankis,janitors,jango,jalopy,jailbreak,jackers,jackasses,invalidate,intercepting,intercede,insinuations,infertile,impetuous,impaled,immerse,immaterial,imbeciles,imagines,idyllic,idolized,icebox,i'd've,hypochondriac,hyphen,hurtling,hurried,hunchback,hullo,horsting,hoooo,homeboys,hollandaise,hoity,hijinks,hesitates,herrero,herndorff,helplessly,heeyy,heathen,hearin,headband,harrassment,harpies,halstrom,hahahahaha,hacer,grumbling,grimlocks,grift,greets,grandmothers,grander,grafts,gordievsky,gondorff,godorsky,glscripts,gaudy,gardeners,gainful,fuses,fukienese,frizzy,freshness,freshening,fraught,frantically,foxbooks,fortieth,forked,foibles,flunkies,fleece,flatbed,fisted,firefight,fingerpaint,filibuster,fhloston,fenceline,femur,fatigues,fanucci,fantastically,familiars,falafel,fabulously,eyesore,expedient,ewwww,eviscerated,erogenous,epidural,enchante,embarassed,embarass,embalming,elude,elspeth,electrocute,eigth,eggshell,echinacea,eases,earpiece,earlobe,dumpsters,dumbshit,dumbasses,duloc,duisberg,drummed,drinkers,dressy,dorma,doily,divvy,diverting,dissuade,disrespecting,displace,disorganized,disgustingly,discord,disapproving,diligence,didja,diced,devouring,detach,destructing,desolate,demerits,delude,delirium,degrade,deevak,deemesa,deductions,deduce,debriefed,deadbeats,dateline,darndest,damnable,dalliance,daiquiri,d'agosta,cussing,cryss,cripes,cretins,crackerjack,cower,coveting,couriers,countermission,cotswolds,convertibles,conversationalist,consorting,consoled,consarn,confides,confidentially,commited,commiserate,comme,comforter,comeuppance,combative,comanches,colosseum,colling,coexist,coaxing,cliffside,chutes,chucked,chokes,childlike,childhoods,chickening,chenowith,charmingly,changin,catsup,captioning,capsize,cappucino,capiche,candlewell,cakewalk,cagey,caddie,buxley,bumbling,bulky,buggered,brussel,brunettes,brumby,brotha,bronck,brisket,bridegroom,braided,bovary,bookkeeper,bluster,bloodline,blissfully,blase,billionaires,bicker,berrisford,bereft,berating,berate,bendy,belive,belated,beikoku,beens,bedspread,bawdy,barreling,baptize,banya,balthazar,balmoral,bakshi,bails,badgered,backstreet,awkwardly,auras,attuned,atheists,astaire,assuredly,arrivederci,appetit,appendectomy,apologetic,antihistamine,anesthesiologist,amulets,albie,alarmist,aiight,adstream,admirably,acquaint,abound,abominable,aaaaaaah,zekes,zatunica,wussy,worded,wooed,woodrell,wiretap,windowsill,windjammer,windfall,whisker,whims,whatiya,whadya,weirdly,weenies,waunt,washout,wanto,waning,victimless,verdad,veranda,vandaley,vancomycin,valise,vaguest,upshot,unzip,unwashed,untrained,unstuck,unprincipled,unmentionables,unjustly,unfolds,unemployable,uneducated,unduly,undercut,uncovering,unconsciousness,unconsciously,tyndareus,turncoat,turlock,tulle,tryouts,trouper,triplette,trepkos,tremor,treeger,trapeze,traipse,tradeoff,trach,torin,tommorow,tollan,toity,timpani,thumbprint,thankless,tell'em,telepathy,telemarketing,telekinesis,teevee,teeming,tarred,tambourine,talentless,swooped,switcheroo,swirly,sweatpants,sunstroke,suitors,sugarcoat,subways,subterfuge,subservient,subletting,stunningly,strongbox,striptease,stravanavitch,stradling,stoolie,stodgy,stocky,stifle,stealer,squeezes,squatter,squarely,sprouted,spool,spindly,speedos,soups,soundly,soulmates,somebody'll,soliciting,solenoid,sobering,snowflakes,snowballs,snores,slung,slimming,skulk,skivvies,skewered,skewer,sizing,sistine,sidebar,sickos,shushing,shunt,shugga,shone,shol'va,sharpened,shapeshifter,shadowing,shadoe,selectman,sefelt,seared,scrounging,scribbling,scooping,scintillating,schmoozing,scallops,sapphires,sanitarium,sanded,safes,rudely,roust,rosebush,rosasharn,rondell,roadhouse,riveted,rewrote,revamp,retaliatory,reprimand,replicators,replaceable,remedied,relinquishing,rejoicing,reincarnated,reimbursed,reevaluate,redid,redefine,recreating,reconnected,rebelling,reassign,rearview,rayne,ravings,ratso,rambunctious,radiologist,quiver,quiero,queef,qualms,pyrotechnics,pulsating,psychosomatic,proverb,promiscuous,profanity,prioritize,preying,predisposition,precocious,precludes,prattling,prankster,povich,potting,postpartum,porridge,polluting,plowing,pistachio,pissin,pickpocket,physicals,peruse,pertains,personified,personalize,perjured,perfecting,pepys,pepperdine,pembry,peering,peels,pedophile,patties,passkey,paratrooper,paraphernalia,paralyzing,pandering,paltry,palpable,pagers,pachyderm,overstay,overestimated,overbite,outwit,outgrow,outbid,ooops,oomph,oohhh,oldie,obliterate,objectionable,nygma,notting,noches,nitty,nighters,newsstands,newborns,neurosurgery,nauseated,nastiest,narcolepsy,mutilate,muscled,murmur,mulva,mulling,mukada,muffled,morgues,moonbeams,monogamy,molester,molestation,molars,moans,misprint,mismatched,mirth,mindful,mimosas,millander,mescaline,menstrual,menage,mellowing,medevac,meddlesome,matey,manicures,malevolent,madmen,macaroons,lydell,lycra,lunchroom,lunching,lozenges,looped,litigious,liquidate,linoleum,lingk,limitless,limber,lilacs,ligature,liftoff,lemmiwinks,leggo,learnin,lazarre,lawyered,lactose,knelt,kenosha,kemosabe,jussy,junky,jordy,jimmies,jeriko,jakovasaur,issacs,isabela,irresponsibility,ironed,intoxication,insinuated,inherits,ingest,ingenue,inflexible,inflame,inevitability,inedible,inducement,indignant,indictments,indefensible,incomparable,incommunicado,improvising,impounded,illogical,ignoramus,hydrochloric,hydrate,hungover,humorless,humiliations,hugest,hoverdrone,hovel,hmmph,hitchhike,hibernating,henchman,helloooo,heirlooms,heartsick,headdress,hatches,harebrained,hapless,hanen,handsomer,hallows,habitual,guten,gummy,guiltier,guidebook,gstaad,gruff,griss,grieved,grata,gorignak,goosed,goofed,glowed,glitz,glimpses,glancing,gilmores,gianelli,geraniums,garroway,gangbusters,gamblers,galls,fuddy,frumpy,frowning,frothy,fro'tak,frere,fragrances,forgettin,follicles,flowery,flophouse,floatin,flirts,flings,flatfoot,fingerprinting,fingerprinted,fingering,finald,fillet,fianc,femoral,federales,fawkes,fascinates,farfel,fambly,falsified,fabricating,exterminators,expectant,excusez,excrement,excercises,evian,etins,esophageal,equivalency,equate,equalizer,entrees,enquire,endearment,empathetic,emailed,eggroll,earmuffs,dyslexic,duper,duesouth,drunker,druggie,dreadfully,dramatics,dragline,downplay,downers,dominatrix,doers,docket,docile,diversify,distracts,disloyalty,disinterested,discharging,disagreeable,dirtier,dinghy,dimwitted,dimoxinil,dimmy,diatribe,devising,deviate,detriment,desertion,depressants,depravity,deniability,delinquents,defiled,deepcore,deductive,decimate,deadbolt,dauthuille,dastardly,daiquiris,daggers,dachau,curiouser,curdled,cucamonga,cruller,cruces,crosswalk,crinkle,crescendo,cremate,counseled,couches,cornea,corday,copernicus,contrition,contemptible,constipated,conjoined,confounded,condescend,concoct,conch,compensating,committment,commandeered,comely,coddled,cockfight,cluttered,clunky,clownfish,cloaked,clenched,cleanin,civilised,circumcised,cimmeria,cilantro,chutzpah,chucking,chiseled,chicka,chattering,cervix,carrey,carpal,carnations,cappuccinos,candied,calluses,calisthenics,bushy,burners,budington,buchanans,brimming,braids,boycotting,bouncers,botticelli,botherin,bookkeeping,bogyman,bogged,bloodthirsty,blintzes,blanky,binturong,billable,bigboote,bewildered,betas,bequeath,behoove,befriend,bedpost,bedded,baudelaires,barreled,barboni,barbeque,bangin,baltus,bailout,backstabber,baccarat,awning,augie,arguillo,archway,apricots,apologising,annyong,anchorman,amenable,amazement,allspice,alannis,airfare,airbags,ahhhhhhhhh,ahhhhhhhh,ahhhhhhh,agitator,adrenal,acidosis,achoo,accessorizing,accentuate,abrasions,abductor,aaaahhh,aaaaaaaa,aaaaaaa,zeroing,zelner,zeldy,yevgeny,yeska,yellows,yeesh,yeahh,yamuri,wouldn't've,workmanship,woodsman,winnin,winked,wildness,whoring,whitewash,whiney,when're,wheezer,wheelman,wheelbarrow,westerburg,weeding,watermelons,washboard,waltzes,wafting,voulez,voluptuous,vitone,vigilantes,videotaping,viciously,vices,veruca,vermeer,verifying,vasculitis,valets,upholstered,unwavering,untold,unsympathetic,unromantic,unrecognizable,unpredictability,unmask,unleashing,unintentional,unglued,unequivocal,underrated,underfoot,unchecked,unbutton,unbind,unbiased,unagi,uhhhhh,tugging,triads,trespasses,treehorn,traviata,trappers,transplants,trannie,tramping,tracheotomy,tourniquet,tooty,toothless,tomarrow,toasters,thruster,thoughtfulness,thornwood,tengo,tenfold,telltale,telephoto,telephoned,telemarketer,tearin,tastic,tastefully,tasking,taser,tamed,tallow,taketh,taillight,tadpoles,tachibana,syringes,sweated,swarthy,swagger,surges,supermodels,superhighway,sunup,sun'll,sulfa,sugarless,sufficed,subside,strolled,stringy,strengthens,straightest,straightens,storefront,stopper,stockpiling,stimulant,stiffed,steyne,sternum,stepladder,stepbrother,steers,steelheads,steakhouse,stathis,stankylecartmankennymr,standoffish,stalwart,squirted,spritz,sprig,sprawl,spousal,sphincter,spenders,spearmint,spatter,spangled,southey,soured,sonuvabitch,somethng,snuffed,sniffs,smokescreen,smilin,slobs,sleepwalker,sleds,slays,slayage,skydiving,sketched,skanks,sixed,siphoned,siphon,simpering,sigfried,sidearm,siddons,sickie,shuteye,shuffleboard,shrubberies,shrouded,showmanship,shouldn't've,shoplift,shiatsu,sentries,sentance,sensuality,seething,secretions,searing,scuttlebutt,sculpt,scowling,scouring,scorecard,schoolers,schmucks,scepters,scaly,scalps,scaffolding,sauces,sartorius,santen,salivating,sainthood,saget,saddens,rygalski,rusting,ruination,rueland,rudabaga,rottweiler,roofies,romantics,rollerblading,roldy,roadshow,rickets,rible,rheza,revisiting,retentive,resurface,restores,respite,resounding,resorting,resists,repulse,repressing,repaying,reneged,refunds,rediscover,redecorated,reconstructive,recommitted,recollect,receptacle,reassess,reanimation,realtors,razinin,rationalization,ratatouille,rashum,rasczak,rancheros,rampler,quizzing,quips,quartered,purring,pummeling,puede,proximo,prospectus,pronouncing,prolonging,procreation,proclamations,principled,prides,preoccupation,prego,precog,prattle,pounced,potshots,potpourri,porque,pomegranates,polenta,plying,pluie,plesac,playmates,plantains,pillowcase,piddle,pickers,photocopied,philistine,perpetuate,perpetually,perilous,pawned,pausing,pauper,parter,parlez,parlay,pally,ovulation,overtake,overstate,overpowering,overpowered,overconfident,overbooked,ovaltine,outweighs,outings,ottos,orrin,orifice,orangutan,oopsy,ooooooooh,oooooo,ooohhhh,ocular,obstruct,obscenely,o'dwyer,nutjob,nunur,notifying,nostrand,nonny,nonfat,noblest,nimble,nikes,nicht,newsworthy,nestled,nearsighted,ne'er,nastier,narco,nakedness,muted,mummified,mudda,mozzarella,moxica,motivator,motility,mothafucka,mortmain,mortgaged,mores,mongers,mobbed,mitigating,mistah,misrepresented,mishke,misfortunes,misdirection,mischievous,mineshaft,millaney,microwaves,metzenbaum,mccovey,masterful,masochistic,marliston,marijawana,manya,mantumbi,malarkey,magnifique,madrona,madox,machida,m'hidi,lullabies,loveliness,lotions,looka,lompoc,litterbug,litigator,lithe,liquorice,linds,limericks,lightbulb,lewises,letch,lemec,layover,lavatory,laurels,lateness,laparotomy,laboring,kuato,kroff,krispy,krauts,knuckleheads,kitschy,kippers,kimbrow,keypad,keepsake,kebab,karloff,junket,judgemental,jointed,jezzie,jetting,jeeze,jeeter,jeesus,jeebs,janeane,jails,jackhammer,ixnay,irritates,irritability,irrevocable,irrefutable,irked,invoking,intricacies,interferon,intents,insubordinate,instructive,instinctive,inquisitive,inlay,injuns,inebriated,indignity,indecisive,incisors,incacha,inalienable,impresses,impregnate,impregnable,implosion,idolizes,hypothyroidism,hypoglycemic,huseni,humvee,huddling,honing,hobnobbing,hobnob,histrionics,histamine,hirohito,hippocratic,hindquarters,hikita,hikes,hightailed,hieroglyphics,heretofore,herbalist,hehey,hedriks,heartstrings,headmistress,headlight,hardheaded,happend,handlebars,hagitha,habla,gyroscope,guys'd,guy'd,guttersnipe,grump,growed,grovelling,groan,greenbacks,gravedigger,grating,grasshoppers,grandiose,grandest,grafted,gooood,goood,gooks,godsakes,goaded,glamorama,giveth,gingham,ghostbusters,germane,georgy,gazzo,gazelles,gargle,garbled,galgenstein,gaffe,g'day,fyarl,furnish,furies,fulfills,frowns,frowned,frighteningly,freebies,freakishly,forewarned,foreclose,forearms,fordson,fonics,flushes,flitting,flemmer,flabby,fishbowl,fidgeting,fevers,feigning,faxing,fatigued,fathoms,fatherless,fancier,fanatical,factored,eyelid,eyeglasses,expresso,expletive,expectin,excruciatingly,evidentiary,ever'thing,eurotrash,eubie,estrangement,erlich,epitome,entrap,enclose,emphysema,embers,emasculating,eighths,eardrum,dyslexia,duplicitous,dumpty,dumbledore,dufus,duddy,duchamp,drunkenness,drumlin,drowns,droid,drinky,drifts,drawbridge,dramamine,douggie,douchebag,dostoyevsky,doodling,don'tcha,domineering,doings,dogcatcher,doctoring,ditzy,dissimilar,dissecting,disparage,disliking,disintegrating,dishwalla,dishonored,dishing,disengaged,disavowed,dippy,diorama,dimmed,dilate,digitalis,diggory,dicing,diagnosing,devola,desolation,dennings,denials,deliverance,deliciously,delicacies,degenerates,degas,deflector,defile,deference,decrepit,deciphered,dawdle,dauphine,daresay,dangles,dampen,damndest,cucumbers,cucaracha,cryogenically,croaks,croaked,criticise,crisper,creepiest,creams,crackle,crackin,covertly,counterintelligence,corrosive,cordially,cops'll,convulsions,convoluted,conversing,conga,confrontational,confab,condolence,condiments,complicit,compiegne,commodus,comings,cometh,collusion,collared,cockeyed,clobber,clemonds,clarithromycin,cienega,christmasy,christmassy,chloroform,chippie,chested,cheeco,checklist,chauvinist,chandlers,chambermaid,chakras,cellophane,caveat,cataloguing,cartmanland,carples,carny,carded,caramels,cappy,caped,canvassing,callback,calibrated,calamine,buttermilk,butterfingers,bunsen,bulimia,bukatari,buildin,budged,brobich,bringer,brendell,brawling,bratty,braised,boyish,boundless,botch,boosh,bookies,bonbons,bodes,bobunk,bluntly,blossoming,bloomers,bloodstains,bloodhounds,blech,biter,biometric,bioethics,bijan,bigoted,bicep,bereaved,bellowing,belching,beholden,beached,batmobile,barcodes,barch,barbecuing,bandanna,backwater,backtrack,backdraft,augustino,atrophy,atrocity,atley,atchoo,asthmatic,assoc,armchair,arachnids,aptly,appetizing,antisocial,antagonizing,anorexia,anini,andersons,anagram,amputation,alleluia,airlock,aimless,agonized,agitate,aggravating,aerosol,acing,accomplishing,accidently,abuser,abstain,abnormally,aberration,aaaaahh,zlotys,zesty,zerzura,zapruder,zantopia,yelburton,yeess,y'knowwhati'msayin,wwhat,wussies,wrenched,would'a,worryin,wormser,wooooo,wookiee,wolchek,wishin,wiseguys,windbreaker,wiggy,wieners,wiedersehen,whoopin,whittled,wherefore,wharvey,welts,wellstone,wedges,wavered,watchit,wastebasket,wango,waken,waitressed,wacquiem,vrykolaka,voula,vitally,visualizing,viciousness,vespers,vertes,verily,vegetarians,vater,vaporize,vannacutt,vallens,ussher,urinating,upping,unwitting,untangle,untamed,unsanitary,unraveled,unopened,unisex,uninvolved,uninteresting,unintelligible,unimaginative,undeserving,undermines,undergarments,unconcerned,tyrants,typist,tykes,tybalt,twosome,twits,tutti,turndown,tularemia,tuberculoma,tsimshian,truffaut,truer,truant,trove,triumphed,tripe,trigonometry,trifled,trifecta,tribulations,tremont,tremoille,transcends,trafficker,touchin,tomfoolery,tinkered,tinfoil,tightrope,thousan,thoracotomy,thesaurus,thawing,thatta,tessio,temps,taxidermist,tator,tachycardia,t'akaya,swelco,sweetbreads,swatting,supercollider,sunbathing,summarily,suffocation,sueleen,succinct,subsided,submissive,subjecting,subbing,subatomic,stupendous,stunted,stubble,stubbed,streetwalker,strategizing,straining,straightaway,stoli,stiffer,stickup,stens,steamroller,steadwell,steadfast,stateroom,stans,sshhhh,squishing,squinting,squealed,sprouting,sprimp,spreadsheets,sprawled,spotlights,spooning,spirals,speedboat,spectacles,speakerphone,southglen,souse,soundproof,soothsayer,sommes,somethings,solidify,soars,snorted,snorkeling,snitches,sniping,snifter,sniffin,snickering,sneer,snarl,smila,slinking,slanted,slanderous,slammin,skimp,skilosh,siteid,sirloin,singe,sighing,sidekicks,sicken,showstopper,shoplifter,shimokawa,sherborne,shavadai,sharpshooters,sharking,shagged,shaddup,senorita,sesterces,sensuous,seahaven,scullery,scorcher,schotzie,schnoz,schmooze,schlep,schizo,scents,scalping,scalped,scallop,scalding,sayeth,saybrooke,sawed,savoring,sardine,sandstorm,sandalwood,salutations,sagman,s'okay,rsvp'd,rousted,rootin,romper,romanovs,rollercoaster,rolfie,robinsons,ritzy,ritualistic,ringwald,rhymed,rheingold,rewrites,revoking,reverts,retrofit,retort,retinas,respirations,reprobate,replaying,repaint,renquist,renege,relapsing,rekindled,rejuvenating,rejuvenated,reinstating,recriminations,rechecked,reassemble,rears,reamed,reacquaint,rayanne,ravish,rathole,raspail,rarest,rapists,rants,racketeer,quittin,quitters,quintessential,queremos,quellek,quelle,quasimodo,pyromaniac,puttanesca,puritanical,purer,puree,pungent,pummel,puedo,psychotherapist,prosecutorial,prosciutto,propositioning,procrastination,probationary,primping,preventative,prevails,preservatives,preachy,praetorians,practicality,powders,potus,postop,positives,poser,portolano,portokalos,poolside,poltergeists,pocketed,poach,plummeted,plucking,plimpton,playthings,plastique,plainclothes,pinpointed,pinkus,pinks,pigskin,piffle,pictionary,piccata,photocopy,phobias,perignon,perfumes,pecks,pecked,patently,passable,parasailing,paramus,papier,paintbrush,pacer,paaiint,overtures,overthink,overstayed,overrule,overestimate,overcooked,outlandish,outgrew,outdoorsy,outdo,orchestrate,oppress,opposable,oooohh,oomupwah,okeydokey,okaaay,ohashi,of'em,obscenities,oakie,o'gar,nurection,nostradamus,norther,norcom,nooch,nonsensical,nipped,nimbala,nervously,neckline,nebbleman,narwhal,nametag,n'n't,mycenae,muzak,muumuu,mumbled,mulvehill,muggings,muffet,mouthy,motivates,motaba,moocher,mongi,moley,moisturize,mohair,mocky,mmkay,mistuh,missis,misdeeds,mincemeat,miggs,miffed,methadone,messieur,menopausal,menagerie,mcgillicuddy,mayflowers,matrimonial,matick,masai,marzipan,maplewood,manzelle,mannequins,manhole,manhandle,malfunctions,madwoman,machiavelli,lynley,lynched,lurconis,lujack,lubricant,looove,loons,loofah,lonelyhearts,lollipops,lineswoman,lifers,lexter,lepner,lemony,leggy,leafy,leadeth,lazerus,lazare,lawford,languishing,lagoda,ladman,kundera,krinkle,krendler,kreigel,kowolski,knockdown,knifed,kneed,kneecap,kids'll,kennie,kenmore,keeled,kazootie,katzenmoyer,kasdan,karak,kapowski,kakistos,julyan,jockstrap,jobless,jiggly,jaunt,jarring,jabbering,irrigate,irrevocably,irrationally,ironies,invitro,intimated,intently,intentioned,intelligently,instill,instigator,instep,inopportune,innuendoes,inflate,infects,infamy,indiscretions,indiscreet,indio,indignities,indict,indecision,inconspicuous,inappropriately,impunity,impudent,impotence,implicates,implausible,imperfection,impatience,immutable,immobilize,idealist,iambic,hysterically,hyperspace,hygienist,hydraulics,hydrated,huzzah,husks,hunched,huffed,hubris,hubbub,hovercraft,houngan,hosed,horoscopes,hopelessness,hoodwinked,honorably,honeysuckle,homegirl,holiest,hippity,hildie,hieroglyphs,hexton,herein,heckle,heaping,healthilizer,headfirst,hatsue,harlot,hardwired,halothane,hairstyles,haagen,haaaaa,gutting,gummi,groundless,groaning,gristle,grills,graynamore,grabbin,goodes,goggle,glittering,glint,gleaming,glassy,girth,gimbal,giblets,gellers,geezers,geeze,garshaw,gargantuan,garfunkel,gangway,gandarium,gamut,galoshes,gallivanting,gainfully,gachnar,fusionlips,fusilli,furiously,frugal,fricking,frederika,freckling,frauds,fountainhead,forthwith,forgo,forgettable,foresight,foresaw,fondling,fondled,fondle,folksy,fluttering,fluffing,floundering,flirtatious,flexing,flatterer,flaring,fixating,finchy,figurehead,fiendish,fertilize,ferment,fending,fellahs,feelers,fascinate,fantabulous,falsify,fallopian,faithless,fairer,fainter,failings,facetious,eyepatch,exxon,extraterrestrials,extradite,extracurriculars,extinguish,expunged,expelling,exorbitant,exhilarated,exertion,exerting,excercise,everbody,evaporated,escargot,escapee,erases,epizootics,epithelials,ephrum,entanglements,enslave,engrossed,emphatic,emeralds,ember,emancipated,elevates,ejaculate,effeminate,eccentricities,easygoing,earshot,dunks,dullness,dulli,dulled,drumstick,dropper,driftwood,dregs,dreck,dreamboat,draggin,downsizing,donowitz,dominoes,diversions,distended,dissipate,disraeli,disqualify,disowned,dishwashing,disciplining,discerning,disappoints,dinged,digested,dicking,detonating,despising,depressor,depose,deport,dents,defused,deflecting,decryption,decoys,decoupage,decompress,decibel,decadence,deafening,dawning,dater,darkened,dappy,dallying,dagon,czechoslovakians,cuticles,cuteness,cupboards,culottes,cruisin,crosshairs,cronyn,criminalistics,creatively,creaming,crapping,cranny,cowed,contradicting,constipation,confining,confidences,conceiving,conceivably,concealment,compulsively,complainin,complacent,compels,communing,commode,comming,commensurate,columnists,colonoscopy,colchicine,coddling,clump,clubbed,clowning,cliffhanger,clang,cissy,choosers,choker,chiffon,channeled,chalet,cellmates,cathartic,caseload,carjack,canvass,canisters,candlestick,candlelit,camry,calzones,calitri,caldy,byline,butterball,bustier,burlap,bureaucrat,buffoons,buenas,brookline,bronzed,broiled,broda,briss,brioche,briar,breathable,brays,brassieres,boysenberry,bowline,boooo,boonies,booklets,bookish,boogeyman,boogey,bogas,boardinghouse,bluuch,blundering,bluer,blowed,blotchy,blossomed,bloodwork,bloodied,blithering,blinks,blathering,blasphemous,blacking,birdson,bings,bfmid,bfast,bettin,berkshires,benjamins,benevolence,benched,benatar,bellybutton,belabor,behooves,beddy,beaujolais,beattle,baxworth,baseless,barfing,bannish,bankrolled,banek,ballsy,ballpoint,baffling,badder,badda,bactine,backgammon,baako,aztreonam,authoritah,auctioning,arachtoids,apropos,aprons,apprised,apprehensive,anythng,antivenin,antichrist,anorexic,anoint,anguished,angioplasty,angio,amply,ampicillin,amphetamines,alternator,alcove,alabaster,airlifted,agrabah,affidavits,admonished,admonish,addled,addendum,accuser,accompli,absurdity,absolved,abrusso,abreast,aboot,abductions,abducting,aback,ababwa,aaahhhh,zorin,zinthar,zinfandel,zillions,zephyrs,zatarcs,zacks,youuu,yokels,yardstick,yammer,y'understand,wynette,wrung,wreaths,wowed,wouldn'ta,worming,wormed,workday,woodsy,woodshed,woodchuck,wojadubakowski,withering,witching,wiseass,wiretaps,wining,willoby,wiccaning,whupped,whoopi,whoomp,wholesaler,whiteness,whiner,whatchya,wharves,wenus,weirdoes,weaning,watusi,waponi,waistband,wackos,vouching,votre,vivica,viveca,vivant,vivacious,visor,visitin,visage,vicrum,vetted,ventriloquism,venison,varnsen,vaporized,vapid,vanstock,uuuuh,ushering,urologist,urination,upstart,uprooted,unsubtitled,unspoiled,unseat,unseasonably,unseal,unsatisfying,unnerve,unlikable,unleaded,uninsured,uninspired,unicycle,unhooked,unfunny,unfreezing,unflattering,unfairness,unexpressed,unending,unencumbered,unearth,undiscovered,undisciplined,understan,undershirt,underlings,underline,undercurrent,uncivilized,uncharacteristic,umpteenth,uglies,tuney,trumps,truckasaurus,trubshaw,trouser,tringle,trifling,trickster,trespassers,trespasser,traumas,trattoria,trashes,transgressions,trampling,tp'ed,toxoplasmosis,tounge,tortillas,topsy,topple,topnotch,tonsil,tions,timmuh,timithious,tilney,tighty,tightness,tightens,tidbits,ticketed,thyme,threepio,thoughtfully,thorkel,thommo,thing'll,thefts,that've,thanksgivings,tetherball,testikov,terraforming,tepid,tendonitis,tenboom,telex,teenybopper,tattered,tattaglias,tanneke,tailspin,tablecloth,swooping,swizzle,swiping,swindled,swilling,swerving,sweatshops,swaddling,swackhammer,svetkoff,supossed,superdad,sumptuous,sugary,sugai,subvert,substantiate,submersible,sublimating,subjugation,stymied,strychnine,streetlights,strassmans,stranglehold,strangeness,straddling,straddle,stowaways,stotch,stockbrokers,stifling,stepford,steerage,steena,statuary,starlets,staggeringly,ssshhh,squaw,spurt,spungeon,spritzer,sprightly,sprays,sportswear,spoonful,splittin,splitsville,speedily,specialise,spastic,sparrin,souvlaki,southie,sourpuss,soupy,soundstage,soothes,somebody'd,softest,sociopathic,socialized,snyders,snowmobiles,snowballed,snatches,smugness,smoothest,smashes,sloshed,sleight,skyrocket,skied,skewed,sixpence,sipowicz,singling,simulates,shyness,shuvanis,showoff,shortsighted,shopkeeper,shoehorn,shithouse,shirtless,shipshape,shifu,shelve,shelbyville,sheepskin,sharpens,shaquille,shanshu,servings,sequined,seizes,seashells,scrambler,scopes,schnauzer,schmo,schizoid,scampered,savagely,saudis,santas,sandovals,sanding,saleswoman,sagging,s'cuse,rutting,ruthlessly,runneth,ruffians,rubes,rosalita,rollerblades,rohypnol,roasts,roadies,ritten,rippling,ripples,rigoletto,richardo,rethought,reshoot,reserving,reseda,rescuer,reread,requisitions,repute,reprogram,replenish,repetitious,reorganizing,reinventing,reinvented,reheat,refrigerators,reenter,recruiter,recliner,rawdy,rashes,rajeski,raison,raisers,rages,quinine,questscape,queller,pygmalion,pushers,pusan,purview,pumpin,pubescent,prudes,provolone,propriety,propped,procrastinate,processional,preyed,pretrial,portent,pooling,poofy,polloi,policia,poacher,pluses,pleasuring,platitudes,plateaued,plaguing,pittance,pinheads,pincushion,pimply,pimped,piggyback,piecing,phillipe,philipse,philby,pharaohs,petyr,petitioner,peshtigo,pesaram,persnickety,perpetrate,percolating,pepto,penne,penell,pemmican,peeks,pedaling,peacemaker,pawnshop,patting,pathologically,patchouli,pasts,pasties,passin,parlors,paltrow,palamon,padlock,paddling,oversleep,overheating,overdosed,overcharge,overblown,outrageously,ornery,opportune,oooooooooh,oohhhh,ohhhhhh,ogres,odorless,obliterated,nyong,nymphomaniac,ntozake,novocain,nough,nonnie,nonissue,nodules,nightmarish,nightline,niceties,newsman,needra,nedry,necking,navour,nauseam,nauls,narim,namath,nagged,naboo,n'sync,myslexia,mutator,mustafi,musketeer,murtaugh,murderess,munching,mumsy,muley,mouseville,mortifying,morgendorffers,moola,montel,mongoloid,molestered,moldings,mocarbies,mo'ss,mixers,misrell,misnomer,misheard,mishandled,miscreant,misconceptions,miniscule,millgate,mettle,metricconverter,meteors,menorah,mengele,melding,meanness,mcgruff,mcarnold,matzoh,matted,mastectomy,massager,marveling,marooned,marmaduke,marick,manhandled,manatees,man'll,maltin,maliciously,malfeasance,malahide,maketh,makeovers,maiming,machismo,lumpectomy,lumbering,lucci,lording,lorca,lookouts,loogie,loners,loathed,lissen,lighthearted,lifer,lickin,lewen,levitation,lestercorp,lessee,lentils,legislate,legalizing,lederhosen,lawmen,lasskopf,lardner,lambeau,lamagra,ladonn,lactic,lacquer,labatier,krabappel,kooks,knickknacks,klutzy,kleynach,klendathu,kinross,kinkaid,kind'a,ketch,kesher,karikos,karenina,kanamits,junshi,jumbled,joust,jotted,jobson,jingling,jigalong,jerries,jellies,jeeps,javna,irresistable,internist,intercranial,inseminated,inquisitor,infuriate,inflating,infidelities,incessantly,incensed,incase,incapacitate,inasmuch,inaccuracies,imploding,impeding,impediments,immaturity,illegible,iditarod,icicles,ibuprofen,i'i'm,hymie,hydrolase,hunker,humps,humons,humidor,humdinger,humbling,huggin,huffing,housecleaning,hothouse,hotcakes,hosty,hootenanny,hootchie,hoosegow,honks,honeymooners,homily,homeopathic,hitchhikers,hissed,hillnigger,hexavalent,hewwo,hershe,hermey,hergott,henny,hennigans,henhouse,hemolytic,helipad,heifer,hebrews,hebbing,heaved,headlock,harrowing,harnessed,hangovers,handi,handbasket,halfrek,hacene,gyges,guys're,gundersons,gumption,gruntmaster,grubs,grossie,groped,grins,greaseball,gravesite,gratuity,granma,grandfathers,grandbaby,gradski,gracing,gossips,gooble,goners,golitsyn,gofer,godsake,goddaughter,gnats,gluing,glares,givers,ginza,gimmie,gimmee,gennero,gemme,gazpacho,gazed,gassy,gargling,gandhiji,galvanized,gallbladder,gaaah,furtive,fumigation,fucka,fronkonsteen,frills,freezin,freewald,freeloader,frailty,forger,foolhardy,fondest,fomin,followin,follicle,flotation,flopping,floodgates,flogged,flicked,flenders,fleabag,fixings,fixable,fistful,firewater,firelight,fingerbang,finalizing,fillin,filipov,fiderer,felling,feldberg,feign,faunia,fatale,farkus,fallible,faithfulness,factoring,eyeful,extramarital,exterminated,exhume,exasperated,eviscerate,estoy,esmerelda,escapades,epoxy,enticed,enthused,entendre,engrossing,endorphins,emptive,emmys,eminently,embezzler,embarressed,embarrassingly,embalmed,eludes,eling,elated,eirie,egotitis,effecting,eerily,eecom,eczema,earthy,earlobes,eally,dyeing,dwells,duvet,duncans,dulcet,droves,droppin,drools,drey'auc,downriver,domesticity,dollop,doesnt,dobler,divulged,diversionary,distancing,dispensers,disorienting,disneyworld,dismissive,disingenuous,disheveled,disfiguring,dinning,dimming,diligently,dilettante,dilation,dickensian,diaphragms,devastatingly,destabilize,desecrate,deposing,deniece,demony,delving,delicates,deigned,defraud,deflower,defibrillator,defiantly,defenceless,defacing,deconstruction,decompose,deciphering,decibels,deceptively,deceptions,decapitation,debutantes,debonair,deadlier,dawdling,davic,darwinism,darnit,darks,danke,danieljackson,dangled,cytoxan,cutout,cutlery,curveball,curfews,cummerbund,crunches,crouched,crisps,cripples,crilly,cribs,crewman,creepin,creeds,credenza,creak,crawly,crawlin,crawlers,crated,crackheads,coworker,couldn't've,corwins,coriander,copiously,convenes,contraceptives,contingencies,contaminating,conniption,condiment,concocting,comprehending,complacency,commendatore,comebacks,com'on,collarbone,colitis,coldly,coiffure,coffers,coeds,codependent,cocksucking,cockney,cockles,clutched,closeted,cloistered,cleve,cleats,clarifying,clapped,cinnabar,chunnel,chumps,cholinesterase,choirboy,chocolatey,chlamydia,chigliak,cheesie,chauvinistic,chasm,chartreuse,charo,charnier,chapil,chalked,chadway,certifiably,cellulite,celled,cavalcade,cataloging,castrated,cassio,cashews,cartouche,carnivore,carcinogens,capulet,captivated,capt'n,cancellations,campin,callate,callar,caffeinated,cadavers,cacophony,cackle,buzzes,buttoning,busload,burglaries,burbs,buona,bunions,bullheaded,buffs,bucyk,buckling,bruschetta,browbeating,broomsticks,broody,bromly,brolin,briefings,brewskies,breathalyzer,breakups,bratwurst,brania,braiding,brags,braggin,bradywood,bottomed,bossa,bordello,bookshelf,boogida,bondsman,bolder,boggles,bludgeoned,blowtorch,blotter,blips,blemish,bleaching,blainetologists,blading,blabbermouth,birdseed,bimmel,biloxi,biggly,bianchinni,betadine,berenson,belus,belloq,begets,befitting,beepers,beelzebub,beefed,bedridden,bedevere,beckons,beaded,baubles,bauble,battleground,bathrobes,basketballs,basements,barroom,barnacle,barkin,barked,baretta,bangles,bangler,banality,bambang,baltar,ballplayers,bagman,baffles,backroom,babysat,baboons,averse,audiotape,auctioneer,atten,atcha,astonishment,arugula,arroz,antihistamines,annoyances,anesthesiology,anatomically,anachronism,amiable,amaretto,allahu,alight,aimin,ailment,afterglow,affronte,advil,adrenals,actualization,acrost,ached,accursed,accoutrements,absconded,aboveboard,abetted,aargh,aaaahh,zuwicky,zolda,ziploc,zakamatak,youve,yippie,yesterdays,yella,yearns,yearnings,yearned,yawning,yalta,yahtzee,y'mean,y'are,wuthering,wreaks,worrisome,workiiing,wooooooo,wonky,womanizing,wolodarsky,wiwith,withdraws,wishy,wisht,wipers,wiper,winos,windthorne,windsurfing,windermere,wiggled,wiggen,whwhat,whodunit,whoaaa,whittling,whitesnake,whereof,wheezing,wheeze,whatd'ya,whataya,whammo,whackin,wellll,weightless,weevil,wedgies,webbing,weasly,wayside,waxes,waturi,washy,washrooms,wandell,waitaminute,waddya,waaaah,vornac,vishnoor,virulent,vindictiveness,vinceres,villier,vigeous,vestigial,ventilate,vented,venereal,veering,veered,veddy,vaslova,valosky,vailsburg,vaginas,vagas,urethra,upstaged,uploading,unwrapping,unwieldy,untapped,unsatisfied,unquenchable,unnerved,unmentionable,unlovable,unknowns,uninformed,unimpressed,unhappily,unguarded,unexplored,undergarment,undeniably,unclench,unclaimed,uncharacteristically,unbuttoned,unblemished,ululd,uhhhm,tweeze,tutsami,tushy,tuscarora,turkle,turghan,turbinium,tubers,trucoat,troxa,tropicana,triquetra,trimmers,triceps,trespassed,traya,traumatizing,transvestites,trainors,tradin,trackers,townies,tourelles,toucha,tossin,tortious,topshop,topes,tonics,tongs,tomsk,tomorrows,toiling,toddle,tizzy,tippers,timmi,thwap,thusly,ththe,thrusts,throwers,throwed,throughway,thickening,thermonuclear,thelwall,thataway,terrifically,tendons,teleportation,telepathically,telekinetic,teetering,teaspoons,tarantulas,tapas,tanned,tangling,tamales,tailors,tahitian,tactful,tachy,tablespoon,syrah,synchronicity,synch,synapses,swooning,switchman,swimsuits,sweltering,sweetly,suvolte,suslov,surfed,supposition,suppertime,supervillains,superfluous,superego,sunspots,sunning,sunless,sundress,suckah,succotash,sublevel,subbasement,studious,striping,strenuously,straights,stonewalled,stillness,stilettos,stevesy,steno,steenwyck,stargates,stammering,staedert,squiggly,squiggle,squashing,squaring,spreadsheet,spramp,spotters,sporto,spooking,splendido,spittin,spirulina,spiky,spate,spartacus,spacerun,soonest,something'll,someth,somepin,someone'll,sofas,soberly,sobered,snowmen,snowbank,snowballing,snivelling,sniffling,snakeskin,snagging,smush,smooter,smidgen,smackers,slumlord,slossum,slimmer,slighted,sleepwalk,sleazeball,skokie,skeptic,sitarides,sistah,sipped,sindell,simpletons,simony,silkwood,silks,silken,sightless,sideboard,shuttles,shrugging,shrouds,showy,shoveled,shouldn'ta,shoplifters,shitstorm,sheeny,shapetype,shaming,shallows,shackle,shabbily,shabbas,seppuku,senility,semite,semiautomatic,selznick,secretarial,sebacio,scuzzy,scummy,scrutinized,scrunchie,scribbled,scotches,scolded,scissor,schlub,scavenging,scarin,scarfing,scallions,scald,savour,savored,saute,sarcoidosis,sandbar,saluted,salish,saith,sailboats,sagittarius,sacre,saccharine,sacamano,rushdie,rumpled,rumba,rulebook,rubbers,roughage,rotisserie,rootie,roofy,roofie,romanticize,rittle,ristorante,rippin,rinsing,ringin,rincess,rickety,reveling,retest,retaliating,restorative,reston,restaurateur,reshoots,resetting,resentments,reprogramming,repossess,repartee,renzo,remore,remitting,remeber,relaxants,rejuvenate,rejections,regenerated,refocus,referrals,reeno,recycles,recrimination,reclining,recanting,reattach,reassigning,razgul,raved,rattlesnakes,rattles,rashly,raquetball,ransack,raisinettes,raheem,radisson,radishes,raban,quoth,qumari,quints,quilts,quilting,quien,quarreled,purty,purblind,punchbowl,publically,psychotics,psychopaths,psychoanalyze,pruning,provasik,protectin,propping,proportioned,prophylactic,proofed,prompter,procreate,proclivities,prioritizing,prinze,pricked,press'll,presets,prescribes,preocupe,prejudicial,prefex,preconceived,precipice,pralines,pragmatist,powerbar,pottie,pottersville,potsie,potholes,posses,posies,portkey,porterhouse,pornographers,poring,poppycock,poppers,pomponi,pokin,poitier,podiatry,pleeze,pleadings,playbook,platelets,plane'arium,placebos,place'll,pistachios,pirated,pinochle,pineapples,pinafore,pimples,piggly,piddling,picon,pickpockets,picchu,physiologically,physic,phobic,philandering,phenomenally,pheasants,pewter,petticoat,petronis,petitioning,perturbed,perpetuating,permutat,perishable,perimeters,perfumed,percocet,per'sus,pepperjack,penalize,pelting,pellet,peignoir,pedicures,peckers,pecans,pawning,paulsson,pattycake,patrolmen,patois,pathos,pasted,parishioner,parcheesi,parachuting,papayas,pantaloons,palpitations,palantine,paintballing,overtired,overstress,oversensitive,overnights,overexcited,overanxious,overachiever,outwitted,outvoted,outnumber,outlast,outlander,out've,orphey,orchestrating,openers,ooooooo,okies,ohhhhhhhhh,ohhhhhhhh,ogling,offbeat,obsessively,obeyed,o'hana,o'bannon,o'bannion,numpce,nummy,nuked,nuances,nourishing,nosedive,norbu,nomlies,nomine,nixed,nihilist,nightshift,newmeat,neglectful,neediness,needin,naphthalene,nanocytes,nanite,naivete,n'yeah,mystifying,myhnegon,mutating,musing,mulled,muggy,muerto,muckraker,muchachos,mountainside,motherless,mosquitos,morphed,mopped,moodoo,moncho,mollem,moisturiser,mohicans,mocks,mistresses,misspent,misinterpretation,miscarry,minuses,mindee,mimes,millisecond,milked,mightn't,mightier,mierzwiak,microchips,meyerling,mesmerizing,mershaw,meecrob,medicate,meddled,mckinnons,mcgewan,mcdunnough,mcats,mbien,matzah,matriarch,masturbated,masselin,martialed,marlboros,marksmanship,marinate,marchin,manicured,malnourished,malign,majorek,magnon,magnificently,macking,machiavellian,macdougal,macchiato,macaws,macanaw,m'self,lydells,lusts,lucite,lubricants,lopper,lopped,loneliest,lonelier,lomez,lojack,loath,liquefy,lippy,limps,likin,lightness,liesl,liebchen,licious,libris,libation,lhamo,leotards,leanin,laxatives,lavished,latka,lanyard,lanky,landmines,lameness,laddies,lacerated,labored,l'amour,kreskin,kovitch,kournikova,kootchy,konoss,knknow,knickety,knackety,kmart,klicks,kiwanis,kissable,kindergartners,kilter,kidnet,kid'll,kicky,kickbacks,kickback,kholokov,kewpie,kendo,katra,kareoke,kafelnikov,kabob,junjun,jumba,julep,jordie,jondy,jolson,jenoff,jawbone,janitorial,janiro,ipecac,invigorated,intruded,intros,intravenously,interruptus,interrogations,interject,interfacing,interestin,insuring,instilled,insensitivity,inscrutable,inroads,innards,inlaid,injector,ingratitude,infuriates,infra,infliction,indelicate,incubators,incrimination,inconveniencing,inconsolable,incestuous,incas,incarcerate,inbreeding,impudence,impressionists,impeached,impassioned,imipenem,idling,idiosyncrasies,icebergs,hypotensive,hydrochloride,hushed,humus,humph,hummm,hulking,hubcaps,hubald,howya,howbout,how'll,housebroken,hotwire,hotspots,hotheaded,horrace,hopsfield,honto,honkin,honeymoons,homewrecker,hombres,hollers,hollerin,hoedown,hoboes,hobbling,hobble,hoarse,hinky,highlighters,hexes,heru'ur,hernias,heppleman,hell're,heighten,heheheheheh,heheheh,hedging,heckling,heckled,heavyset,heatshield,heathens,heartthrob,headpiece,hayseed,haveo,hauls,hasten,harridan,harpoons,hardens,harcesis,harbouring,hangouts,halkein,haleh,halberstam,hairnet,hairdressers,hacky,haaaa,h'yah,gusta,gushy,gurgling,guilted,gruel,grudging,grrrrrr,grosses,groomsmen,griping,gravest,gratified,grated,goulash,goopy,goona,goodly,godliness,godawful,godamn,glycerin,glutes,glowy,globetrotters,glimpsed,glenville,glaucoma,girlscout,giraffes,gilbey,gigglepuss,ghora,gestating,gelato,geishas,gearshift,gayness,gasped,gaslighting,garretts,garba,gablyczyck,g'head,fumigating,fumbling,fudged,fuckwad,fuck're,fuchsia,fretting,freshest,frenchies,freezers,fredrica,fraziers,fraidy,foxholes,fourty,fossilized,forsake,forfeits,foreclosed,foreal,footsies,florists,flopped,floorshow,floorboard,flinching,flecks,flaubert,flatware,flatulence,flatlined,flashdance,flail,flagging,fiver,fitzy,fishsticks,finetti,finelli,finagle,filko,fieldstone,fibber,ferrini,feedin,feasting,favore,fathering,farrouhk,farmin,fairytale,fairservice,factoid,facedown,fabled,eyeballin,extortionist,exquisitely,expedited,exorcise,existentialist,execs,exculpatory,exacerbate,everthing,eventuality,evander,euphoric,euphemisms,estamos,erred,entitle,enquiries,enormity,enfants,endive,encyclopedias,emulating,embittered,effortless,ectopic,ecirc,easely,earphones,earmarks,dweller,durslar,durned,dunois,dunking,dunked,dumdum,dullard,dudleys,druthers,druggist,drossos,drooled,driveways,drippy,dreamless,drawstring,drang,drainpipe,dozing,dotes,dorkface,doorknobs,doohickey,donnatella,doncha,domicile,dokos,dobermans,dizzying,divola,ditsy,distaste,disservice,dislodged,dislodge,disinherit,disinformation,discounting,dinka,dimly,digesting,diello,diddling,dictatorships,dictators,diagnostician,devours,devilishly,detract,detoxing,detours,detente,destructs,desecrated,derris,deplore,deplete,demure,demolitions,demean,delish,delbruck,delaford,degaulle,deftly,deformity,deflate,definatly,defector,decrypted,decontamination,decapitate,decanter,dardis,dampener,damme,daddy'll,dabbling,dabbled,d'etre,d'argent,d'alene,d'agnasti,czechoslovakian,cymbal,cyberdyne,cutoffs,cuticle,curvaceous,curiousity,crowing,crowed,croutons,cropped,criminy,crescentis,crashers,cranwell,coverin,courtrooms,countenance,cosmically,cosign,corroboration,coroners,cornflakes,copperpot,copperhead,copacetic,coordsize,convulsing,consults,conjures,congenial,concealer,compactor,commercialism,cokey,cognizant,clunkers,clumsily,clucking,cloves,cloven,cloths,clothe,clods,clocking,clings,clavicle,classless,clashing,clanking,clanging,clamping,civvies,citywide,circulatory,circuited,chronisters,chromic,choos,chloroformed,chillun,cheesed,chatterbox,chaperoned,channukah,cerebellum,centerpieces,centerfold,ceecee,ccedil,cavorting,cavemen,cauterized,cauldwell,catting,caterine,cassiopeia,carves,cartwheel,carpeted,carob,caressing,carelessly,careening,capricious,capitalistic,capillaries,candidly,camaraderie,callously,calfskin,caddies,buttholes,busywork,busses,burps,burgomeister,bunkhouse,bungchow,bugler,buffets,buffed,brutish,brusque,bronchitis,bromden,brolly,broached,brewskis,brewin,brean,breadwinner,brana,bountiful,bouncin,bosoms,borgnine,bopping,bootlegs,booing,bombosity,bolting,boilerplate,bluey,blowback,blouses,bloodsuckers,bloodstained,bloat,bleeth,blackface,blackest,blackened,blacken,blackballed,blabs,blabbering,birdbrain,bipartisanship,biodegradable,biltmore,bilked,big'uns,bidet,besotted,bernheim,benegas,bendiga,belushi,bellboys,belittling,behinds,begone,bedsheets,beckoning,beaute,beaudine,beastly,beachfront,bathes,batak,baser,baseballs,barbella,bankrolling,bandaged,baerly,backlog,backin,babying,azkaban,awwwww,aviary,authorizes,austero,aunty,attics,atreus,astounded,astonish,artemus,arses,arintero,appraiser,apathetic,anybody'd,anxieties,anticlimactic,antar,anglos,angleman,anesthetist,androscoggin,andolini,andale,amway,amuck,amniocentesis,amnesiac,americano,amara,alvah,altruism,alternapalooza,alphabetize,alpaca,allus,allergist,alexandros,alaikum,akimbo,agoraphobia,agides,aggrhh,aftertaste,adoptions,adjuster,addictions,adamantium,activator,accomplishes,aberrant,aaaaargh,aaaaaaaaaaaaa,a'ight,zzzzzzz,zucchini,zookeeper,zirconia,zippers,zequiel,zellary,zeitgeist,zanuck,zagat,you'n,ylang,yes'm,yenta,yecchh,yecch,yawns,yankin,yahdah,yaaah,y'got,xeroxed,wwooww,wristwatch,wrangled,wouldst,worthiness,worshiping,wormy,wormtail,wormholes,woosh,wollsten,wolfing,woefully,wobbling,wintry,wingding,windstorm,windowtext,wiluna,wilting,wilted,willick,willenholly,wildflowers,wildebeest,whyyy,whoppers,whoaa,whizzing,whizz,whitest,whistled,whist,whinny,wheelies,whazzup,whatwhatwhaaat,whato,whatdya,what'dya,whacks,wewell,wetsuit,welluh,weeps,waylander,wavin,wassail,wasnt,warneford,warbucks,waltons,wallbanger,waiving,waitwait,vowing,voucher,vornoff,vorhees,voldemort,vivre,vittles,vindaloo,videogames,vichyssoise,vicarious,vesuvius,verguenza,ven't,velveteen,velour,velociraptor,vastness,vasectomies,vapors,vanderhof,valmont,validates,valiantly,vacuums,usurp,usernum,us'll,urinals,unyielding,unvarnished,unturned,untouchables,untangled,unsecured,unscramble,unreturned,unremarkable,unpretentious,unnerstand,unmade,unimpeachable,unfashionable,underwrite,underlining,underling,underestimates,underappreciated,uncouth,uncork,uncommonly,unclog,uncircumcised,unchallenged,uncas,unbuttoning,unapproved,unamerican,unafraid,umpteen,umhmm,uhwhy,ughuh,typewriters,twitches,twitched,twirly,twinkling,twinges,twiddling,turners,turnabout,tumblin,tryed,trowel,trousseau,trivialize,trifles,tribianni,trenchcoat,trembled,traumatize,transitory,transients,transfuse,transcribing,tranq,trampy,traipsed,trainin,trachea,traceable,touristy,toughie,toscanini,tortola,tortilla,torreon,toreador,tommorrow,tollbooth,tollans,toidy,togas,tofurkey,toddling,toddies,toasties,toadstool,to've,tingles,timin,timey,timetables,tightest,thuggee,thrusting,thrombus,throes,thrifty,thornharts,thinnest,thicket,thetas,thesulac,tethered,testaburger,tersenadine,terrif,terdlington,tepui,temping,tector,taxidermy,tastebuds,tartlets,tartabull,tar'd,tantamount,tangy,tangles,tamer,tabula,tabletops,tabithia,szechwan,synthedyne,svenjolly,svengali,survivalists,surmise,surfboards,surefire,suprise,supremacists,suppositories,superstore,supercilious,suntac,sunburned,summercliff,sullied,sugared,suckle,subtleties,substantiated,subsides,subliminal,subhuman,strowman,stroked,stroganoff,streetlight,straying,strainer,straighter,straightener,stoplight,stirrups,stewing,stereotyping,stepmommy,stephano,stashing,starshine,stairwells,squatsie,squandering,squalid,squabbling,squab,sprinkling,spreader,spongy,spokesmen,splintered,spittle,spitter,spiced,spews,spendin,spect,spearchucker,spatulas,southtown,soused,soshi,sorter,sorrowful,sooth,some'in,soliloquy,soiree,sodomized,sobriki,soaping,snows,snowcone,snitching,snitched,sneering,snausages,snaking,smoothed,smoochies,smarten,smallish,slushy,slurring,sluman,slithers,slippin,sleuthing,sleeveless,skinless,skillfully,sketchbook,skagnetti,sista,sinning,singularly,sinewy,silverlake,siguto,signorina,sieve,sidearms,shying,shunning,shtud,shrieks,shorting,shortbread,shopkeepers,shmancy,shizzit,shitheads,shitfaced,shipmates,shiftless,shelving,shedlow,shavings,shatters,sharifa,shampoos,shallots,shafter,sha'nauc,sextant,serviceable,sepsis,senores,sendin,semis,semanski,selflessly,seinfelds,seers,seeps,seductress,secaucus,sealant,scuttling,scusa,scrunched,scissorhands,schreber,schmancy,scamps,scalloped,savoir,savagery,sarong,sarnia,santangel,samool,sallow,salino,safecracker,sadism,sacrilegious,sabrini,sabath,s'aright,ruttheimer,rudest,rubbery,rousting,rotarian,roslin,roomed,romari,romanica,rolltop,rolfski,rockettes,roared,ringleader,riffing,ribcage,rewired,retrial,reting,resuscitated,restock,resale,reprogrammed,replicant,repentant,repellant,repays,repainting,renegotiating,rendez,remem,relived,relinquishes,relearn,relaxant,rekindling,rehydrate,refueled,refreshingly,refilling,reexamine,reeseman,redness,redeemable,redcoats,rectangles,recoup,reciprocated,reassessing,realy,realer,reachin,re'kali,rawlston,ravages,rappaports,ramoray,ramming,raindrops,rahesh,radials,racists,rabartu,quiches,quench,quarreling,quaintly,quadrants,putumayo,put'em,purifier,pureed,punitis,pullout,pukin,pudgy,puddings,puckering,pterodactyl,psychodrama,psats,protestations,protectee,prosaic,propositioned,proclivity,probed,printouts,prevision,pressers,preset,preposition,preempt,preemie,preconceptions,prancan,powerpuff,potties,potpie,poseur,porthole,poops,pooping,pomade,polyps,polymerized,politeness,polisher,polack,pocketknife,poatia,plebeian,playgroup,platonically,platitude,plastering,plasmapheresis,plaids,placemats,pizzazz,pintauro,pinstripes,pinpoints,pinkner,pincer,pimento,pileup,pilates,pigmen,pieeee,phrased,photocopies,phoebes,philistines,philanderer,pheromone,phasers,pfeffernuesse,pervs,perspire,personify,perservere,perplexed,perpetrating,perkiness,perjurer,periodontist,perfunctory,perdido,percodan,pentameter,pentacle,pensive,pensione,pennybaker,pennbrooke,penhall,pengin,penetti,penetrates,pegnoir,peeve,peephole,pectorals,peckin,peaky,peaksville,paxcow,paused,patted,parkishoff,parkers,pardoning,paraplegic,paraphrasing,paperers,papered,pangs,paneling,palooza,palmed,palmdale,palatable,pacify,pacified,owwwww,oversexed,overrides,overpaying,overdrawn,overcompensate,overcomes,overcharged,outmaneuver,outfoxed,oughtn't,ostentatious,oshun,orthopedist,or'derves,ophthalmologist,operagirl,oozes,oooooooh,onesie,omnis,omelets,oktoberfest,okeydoke,ofthe,ofher,obstetrical,obeys,obeah,o'henry,nyquil,nyanyanyanyah,nuttin,nutsy,nutball,nurhachi,numbskull,nullifies,nullification,nucking,nubbin,nourished,nonspecific,noing,noinch,nohoho,nobler,nitwits,newsprint,newspaperman,newscaster,neuropathy,netherworld,neediest,navasky,narcissists,napped,nafta,mache,mykonos,mutilating,mutherfucker,mutha,mutates,mutate,musn't,murchy,multitasking,mujeeb,mudslinging,muckraking,mousetrap,mourns,mournful,motherf,mostro,morphing,morphate,moralistic,moochy,mooching,monotonous,monopolize,monocle,molehill,moland,mofet,mockup,mobilizing,mmmmmmm,mitzvahs,mistreating,misstep,misjudge,misinformation,misdirected,miscarriages,miniskirt,mindwarped,minced,milquetoast,miguelito,mightily,midstream,midriff,mideast,microbe,methuselah,mesdames,mescal,men'll,memma,megaton,megara,megalomaniac,meeee,medulla,medivac,meaninglessness,mcnuggets,mccarthyism,maypole,may've,mauve,mateys,marshack,markles,marketable,mansiere,manservant,manse,manhandling,mallomars,malcontent,malaise,majesties,mainsail,mailmen,mahandra,magnolias,magnified,magev,maelstrom,machu,macado,m'boy,m'appelle,lustrous,lureen,lunges,lumped,lumberyard,lulled,luego,lucks,lubricated,loveseat,loused,lounger,loski,lorre,loora,looong,loonies,loincloth,lofts,lodgers,lobbing,loaner,livered,liqueur,ligourin,lifesaving,lifeguards,lifeblood,liaisons,let'em,lesbianism,lence,lemonlyman,legitimize,leadin,lazars,lazarro,lawyering,laugher,laudanum,latrines,lations,laters,lapels,lakefront,lahit,lafortunata,lachrymose,l'italien,kwaini,kruczynski,kramerica,kowtow,kovinsky,korsekov,kopek,knowakowski,knievel,knacks,kiowas,killington,kickball,keyworth,keymaster,kevie,keveral,kenyons,keggers,keepsakes,kechner,keaty,kavorka,karajan,kamerev,kaggs,jujyfruit,jostled,jonestown,jokey,joists,jocko,jimmied,jiggled,jests,jenzen,jenko,jellyman,jedediah,jealitosis,jaunty,jarmel,jankle,jagoff,jagielski,jackrabbits,jabbing,jabberjaw,izzat,irresponsibly,irrepressible,irregularity,irredeemable,inuvik,intuitions,intubated,intimates,interminable,interloper,intercostal,instyle,instigate,instantaneously,ining,ingrown,ingesting,infusing,infringe,infinitum,infact,inequities,indubitably,indisputable,indescribably,indentation,indefinable,incontrovertible,inconsequential,incompletes,incoherently,inclement,incidentals,inarticulate,inadequacies,imprudent,improprieties,imprison,imprinted,impressively,impostors,importante,imperious,impale,immodest,immobile,imbedded,imbecilic,illegals,idn't,hysteric,hypotenuse,hygienic,hyeah,hushpuppies,hunhh,humpback,humored,hummed,humiliates,humidifier,huggy,huggers,huckster,hotbed,hosing,hosers,horsehair,homebody,homebake,holing,holies,hoisting,hogwallop,hocks,hobbits,hoaxes,hmmmmm,hisses,hippest,hillbillies,hilarity,heurh,herniated,hermaphrodite,hennifer,hemlines,hemline,hemery,helplessness,helmsley,hellhound,heheheheh,heeey,hedda,heartbeats,heaped,healers,headstart,headsets,headlong,hawkland,havta,haulin,harvey'll,hanta,hansom,hangnail,handstand,handrail,handoff,hallucinogen,hallor,halitosis,haberdashery,gypped,guy'll,gumbel,guerillas,guava,guardrail,grunther,grunick,groppi,groomer,grodin,gripes,grinds,grifters,gretch,greevey,greasing,graveyards,grandkid,grainy,gouging,gooney,googly,goldmuff,goldenrod,goingo,godly,gobbledygook,gobbledegook,glues,gloriously,glengarry,glassware,glamor,gimmicks,giggly,giambetti,ghoulish,ghettos,ghali,gether,geriatrics,gerbils,geosynchronous,georgio,gente,gendarme,gelbman,gazillionth,gayest,gauging,gastro,gaslight,gasbag,garters,garish,garas,gantu,gangy,gangly,gangland,galling,gadda,furrowed,funnies,funkytown,fugimotto,fudging,fuckeen,frustrates,froufrou,froot,fromberge,frizzies,fritters,frightfully,friendliest,freeloading,freelancing,freakazoid,fraternization,framers,fornication,fornicating,forethought,footstool,foisting,focussing,focking,flurries,fluffed,flintstones,fledermaus,flayed,flawlessly,flatters,flashbang,flapped,fishies,firmer,fireproof,firebug,fingerpainting,finessed,findin,financials,finality,fillets,fiercest,fiefdom,fibbing,fervor,fentanyl,fenelon,fedorchuk,feckless,feathering,faucets,farewells,fantasyland,fanaticism,faltered,faggy,faberge,extorting,extorted,exterminating,exhumation,exhilaration,exhausts,exfoliate,excels,exasperating,exacting,everybody'd,evasions,espressos,esmail,errrr,erratically,eroding,ernswiler,epcot,enthralled,ensenada,enriching,enrage,enhancer,endear,encrusted,encino,empathic,embezzle,emanates,electricians,eking,egomaniacal,egging,effacing,ectoplasm,eavesdropped,dummkopf,dugray,duchaisne,drunkard,drudge,droop,droids,drips,dripped,dribbles,drazens,downy,downsize,downpour,dosages,doppelganger,dopes,doohicky,dontcha,doneghy,divining,divest,diuretics,diuretic,distrustful,disrupts,dismemberment,dismember,disinfect,disillusionment,disheartening,discourteous,discotheque,discolored,dirtiest,diphtheria,dinks,dimpled,didya,dickwad,diatribes,diathesis,diabetics,deviants,detonates,detests,detestable,detaining,despondent,desecration,derision,derailing,deputized,depressors,dependant,dentures,denominators,demur,demonology,delts,dellarte,delacour,deflated,defib,defaced,decorators,deaqon,davola,datin,darwinian,darklighters,dandelions,dampened,damaskinos,dalrimple,d'peshu,d'hoffryn,d'astier,cynics,cutesy,cutaway,curmudgeon,curdle,culpability,cuisinart,cuffing,crypts,cryptid,crunched,crumblers,crudely,crosscheck,croon,crissake,crevasse,creswood,creepo,creases,creased,creaky,cranks,crabgrass,coveralls,couple'a,coughs,coslaw,corporeal,cornucopia,cornering,corks,cordoned,coolly,coolin,cookbooks,contrite,contented,constrictor,confound,confit,confiscating,condoned,conditioners,concussions,comprendo,comers,combustible,combusted,collingswood,coldness,coitus,codicil,coasting,clydesdale,cluttering,clunker,clunk,clumsiness,clotted,clothesline,clinches,clincher,cleverness,clench,clein,cleanses,claymores,clammed,chugging,chronically,christsakes,choque,chompers,chiseling,chirpy,chirp,chinks,chingachgook,chickenpox,chickadee,chewin,chessboard,chargin,chanteuse,chandeliers,chamdo,chagrined,chaff,certs,certainties,cerreno,cerebrum,censured,cemetary,caterwauling,cataclysmic,casitas,cased,carvel,carting,carrear,carolling,carolers,carnie,cardiogram,carbuncle,capulets,canines,candaules,canape,caldecott,calamitous,cadillacs,cachet,cabeza,cabdriver,buzzards,butai,businesswomen,bungled,bumpkins,bummers,bulldoze,buffybot,bubut,bubbies,brrrrr,brownout,brouhaha,bronzing,bronchial,broiler,briskly,briefcases,bricked,breezing,breeher,breakable,breadstick,bravenet,braved,brandies,brainwaves,brainiest,braggart,bradlee,boys're,boys'll,boys'd,boutonniere,bossed,bosomy,borans,boosts,bookshelves,bookends,boneless,bombarding,bollo,boinked,boink,bluest,bluebells,bloodshot,blockhead,blockbusters,blithely,blather,blankly,bladders,blackbeard,bitte,bippy,biogenetics,bilge,bigglesworth,bicuspids,beususe,betaseron,besmirch,bernece,bereavement,bentonville,benchley,benching,bembe,bellyaching,bellhops,belie,beleaguered,behrle,beginnin,begining,beenie,beefs,beechwood,becau,beaverhausen,beakers,bazillion,baudouin,barrytown,barringtons,barneys,barbs,barbers,barbatus,bankrupted,bailiffs,backslide,baby'd,baaad,b'fore,awwwk,aways,awakes,automatics,authenticate,aught,aubyn,attired,attagirl,atrophied,asystole,astroturf,assertiveness,artichokes,arquillians,aright,archenemy,appraise,appeased,antin,anspaugh,anesthetics,anaphylactic,amscray,ambivalence,amalio,alriiight,alphabetized,alpena,alouette,allora,alliteration,allenwood,allegiances,algerians,alcerro,alastor,ahaha,agitators,aforethought,advertises,admonition,adirondacks,adenoids,acupuncturist,acula,actuarial,activators,actionable,achingly,accusers,acclimated,acclimate,absurdly,absorbent,absolvo,absolutes,absences,abdomenizer,aaaaaaaaah,aaaaaaaaaa,a'right".split(","),male_names:"james,john,robert,michael,william,david,richard,charles,joseph,thomas,christopher,daniel,paul,mark,donald,george,kenneth,steven,edward,brian,ronald,anthony,kevin,jason,matthew,gary,timothy,jose,larry,jeffrey,frank,scott,eric,stephen,andrew,raymond,gregory,joshua,jerry,dennis,walter,patrick,peter,harold,douglas,henry,carl,arthur,ryan,roger,joe,juan,jack,albert,jonathan,justin,terry,gerald,keith,samuel,willie,ralph,lawrence,nicholas,roy,benjamin,bruce,brandon,adam,harry,fred,wayne,billy,steve,louis,jeremy,aaron,randy,eugene,carlos,russell,bobby,victor,ernest,phillip,todd,jesse,craig,alan,shawn,clarence,sean,philip,chris,johnny,earl,jimmy,antonio,danny,bryan,tony,luis,mike,stanley,leonard,nathan,dale,manuel,rodney,curtis,norman,marvin,vincent,glenn,jeffery,travis,jeff,chad,jacob,melvin,alfred,kyle,francis,bradley,jesus,herbert,frederick,ray,joel,edwin,don,eddie,ricky,troy,randall,barry,bernard,mario,leroy,francisco,marcus,micheal,theodore,clifford,miguel,oscar,jay,jim,tom,calvin,alex,jon,ronnie,bill,lloyd,tommy,leon,derek,darrell,jerome,floyd,leo,alvin,tim,wesley,dean,greg,jorge,dustin,pedro,derrick,dan,zachary,corey,herman,maurice,vernon,roberto,clyde,glen,hector,shane,ricardo,sam,rick,lester,brent,ramon,tyler,gilbert,gene,marc,reginald,ruben,brett,nathaniel,rafael,edgar,milton,raul,ben,cecil,duane,andre,elmer,brad,gabriel,ron,roland,jared,adrian,karl,cory,claude,erik,darryl,neil,christian,javier,fernando,clinton,ted,mathew,tyrone,darren,lonnie,lance,cody,julio,kurt,allan,clayton,hugh,max,dwayne,dwight,armando,felix,jimmie,everett,ian,ken,bob,jaime,casey,alfredo,alberto,dave,ivan,johnnie,sidney,byron,julian,isaac,clifton,willard,daryl,virgil,andy,salvador,kirk,sergio,seth,kent,terrance,rene,eduardo,terrence,enrique,freddie,stuart,fredrick,arturo,alejandro,joey,nick,luther,wendell,jeremiah,evan,julius,donnie,otis,trevor,luke,homer,gerard,doug,kenny,hubert,angelo,shaun,lyle,matt,alfonso,orlando,rex,carlton,ernesto,pablo,lorenzo,omar,wilbur,blake,horace,roderick,kerry,abraham,rickey,ira,andres,cesar,johnathan,malcolm,rudolph,damon,kelvin,rudy,preston,alton,archie,marco,pete,randolph,garry,geoffrey,jonathon,felipe,bennie,gerardo,dominic,loren,delbert,colin,guillermo,earnest,benny,noel,rodolfo,myron,edmund,salvatore,cedric,lowell,gregg,sherman,devin,sylvester,roosevelt,israel,jermaine,forrest,wilbert,leland,simon,irving,owen,rufus,woodrow,sammy,kristopher,levi,marcos,gustavo,jake,lionel,marty,gilberto,clint,nicolas,laurence,ismael,orville,drew,ervin,dewey,wilfred,josh,hugo,ignacio,caleb,tomas,sheldon,erick,frankie,darrel,rogelio,terence,alonzo,elias,bert,elbert,ramiro,conrad,noah,grady,phil,cornelius,lamar,rolando,clay,percy,bradford,merle,darin,amos,terrell,moses,irvin,saul,roman,darnell,randal,tommie,timmy,darrin,brendan,toby,van,abel,dominick,emilio,elijah,cary,domingo,aubrey,emmett,marlon,emanuel,jerald,edmond,emil,dewayne,otto,teddy,reynaldo,bret,jess,trent,humberto,emmanuel,stephan,louie,vicente,lamont,garland,micah,efrain,heath,rodger,demetrius,ethan,eldon,rocky,pierre,eli,bryce,antoine,robbie,kendall,royce,sterling,grover,elton,cleveland,dylan,chuck,damian,reuben,stan,leonardo,russel,erwin,benito,hans,monte,blaine,ernie,curt,quentin,agustin,jamal,devon,adolfo,tyson,wilfredo,bart,jarrod,vance,denis,damien,joaquin,harlan,desmond,elliot,darwin,gregorio,kermit,roscoe,esteban,anton,solomon,norbert,elvin,nolan,carey,rod,quinton,hal,brain,rob,elwood,kendrick,darius,moises,marlin,fidel,thaddeus,cliff,marcel,ali,raphael,bryon,armand,alvaro,jeffry,dane,joesph,thurman,ned,sammie,rusty,michel,monty,rory,fabian,reggie,kris,isaiah,gus,avery,loyd,diego,adolph,millard,rocco,gonzalo,derick,rodrigo,gerry,rigoberto,alphonso,rickie,noe,vern,elvis,bernardo,mauricio,hiram,donovan,basil,nickolas,scot,vince,quincy,eddy,sebastian,federico,ulysses,heriberto,donnell,denny,gavin,emery,romeo,jayson,dion,dante,clement,coy,odell,jarvis,bruno,issac,dudley,sanford,colby,carmelo,nestor,hollis,stefan,donny,linwood,beau,weldon,galen,isidro,truman,delmar,johnathon,silas,frederic,irwin,merrill,charley,marcelino,carlo,trenton,kurtis,aurelio,winfred,vito,collin,denver,leonel,emory,pasquale,mohammad,mariano,danial,landon,dirk,branden,adan,numbers,clair,buford,bernie,wilmer,emerson,zachery,jacques,errol,josue,edwardo,wilford,theron,raymundo,daren,tristan,robby,lincoln,jame,genaro,octavio,cornell,hung,arron,antony,herschel,alva,giovanni,garth,cyrus,cyril,ronny,stevie,lon,kennith,carmine,augustine,erich,chadwick,wilburn,russ,myles,jonas,mitchel,mervin,zane,jamel,lazaro,alphonse,randell,johnie,jarrett,ariel,abdul,dusty,luciano,seymour,scottie,eugenio,mohammed,arnulfo,lucien,ferdinand,thad,ezra,aldo,rubin,mitch,earle,abe,marquis,lanny,kareem,jamar,boris,isiah,emile,elmo,aron,leopoldo,everette,josef,eloy,dorian,rodrick,reinaldo,lucio,jerrod,weston,hershel,lemuel,lavern,burt,jules,gil,eliseo,ahmad,nigel,efren,antwan,alden,margarito,refugio,dino,osvaldo,les,deandre,normand,kieth,ivory,trey,norberto,napoleon,jerold,fritz,rosendo,milford,sang,deon,christoper,alfonzo,lyman,josiah,brant,wilton,rico,jamaal,dewitt,brenton,yong,olin,faustino,claudio,judson,gino,edgardo,alec,jarred,donn,trinidad,tad,porfirio,odis,lenard,chauncey,tod,mel,marcelo,kory,augustus,keven,hilario,bud,sal,orval,mauro,dannie,zachariah,olen,anibal,milo,jed,thanh,amado,lenny,tory,richie,horacio,brice,mohamed,delmer,dario,mac,jonah,jerrold,robt,hank,sung,rupert,rolland,kenton,damion,chi,antone,waldo,fredric,bradly,kip,burl,tyree,jefferey,ahmed,willy,stanford,oren,moshe,mikel,enoch,brendon,quintin,jamison,florencio,darrick,tobias,minh,hassan,giuseppe,demarcus,cletus,tyrell,lyndon,keenan,werner,theo,geraldo,columbus,chet,bertram,markus,huey,hilton,dwain,donte,tyron,omer,isaias,hipolito,fermin,chung,adalberto,jamey,teodoro,mckinley,maximo,raleigh,lawerence,abram,rashad,emmitt,daron,chong,samual,otha,miquel,eusebio,dong,domenic,darron,wilber,renato,hoyt,haywood,ezekiel,chas,florentino,elroy,clemente,arden,neville,edison,deshawn,carrol,shayne,nathanial,jordon,danilo,claud,sherwood,raymon,rayford,cristobal,ambrose,titus,hyman,felton,ezequiel,erasmo,lonny,milan,lino,jarod,herb,andreas,rhett,jude,douglass,cordell,oswaldo,ellsworth,virgilio,toney,nathanael,benedict,mose,hong,isreal,garret,fausto,arlen,zack,modesto,francesco,manual,gaylord,gaston,filiberto,deangelo,michale,granville,malik,zackary,tuan,nicky,cristopher,antione,malcom,korey,jospeh,colton,waylon,hosea,shad,santo,rudolf,rolf,renaldo,marcellus,lucius,kristofer,harland,arnoldo,rueben,leandro,kraig,jerrell,jeromy,hobert,cedrick,arlie,winford,wally,luigi,keneth,jacinto,graig,franklyn,edmundo,leif,jeramy,willian,vincenzo,shon,michal,lynwood,jere,elden,darell,broderick,alonso".split(",")},module.exports=frequency_lists;
+
+},{}],4:[function(require,module,exports){
+var Feedback,feedbacker,matching,scoring,time,time_estimates,zxcvbn;matching=require("./matching"),scoring=require("./scoring"),time_estimates=require("./time_estimates"),Feedback=require("./feedback"),time=function(){return(new Date).getTime()},feedbacker=new Feedback,(zxcvbn=function(e,t=[]){var i,c,a,n,r,s,m,o,b,u,g;for(u=time(),b=[],a=0,n=t.length;a<n;a++)"string"!=(m=typeof(i=t[a]))&&"number"!==m&&"boolean"!==m||b.push(i.toString().toLowerCase());for(s in matching.set_user_input_dictionary(b),r=matching.omnimatch(e),(o=scoring.most_guessable_match_sequence(e,r)).calc_time=time()-u,c=time_estimates.estimate_attack_times(o.guesses))g=c[s],o[s]=g;return o.feedback=feedbacker.get_feedback(o.score,o.sequence),o}).Feedback=Feedback,module.exports=zxcvbn;
+
+},{"./feedback":2,"./matching":5,"./scoring":6,"./time_estimates":7}],5:[function(require,module,exports){
+var DATE_MAX_YEAR,DATE_MIN_YEAR,DATE_SPLITS,GRAPHS,L33T_TABLE,RANKED_DICTIONARIES,REGEXEN,adjacency_graphs,build_ranked_dict,frequency_lists,lst,matching,name,scoring;for(name in frequency_lists=require("./frequency_lists"),adjacency_graphs=require("./adjacency_graphs"),scoring=require("./scoring"),build_ranked_dict=function(e){var t,n,r,i;for(i={},t=1,r=0,n=e.length;r<n;r++)i[e[r]]=t,t+=1;return i},RANKED_DICTIONARIES={},frequency_lists)lst=frequency_lists[name],RANKED_DICTIONARIES[name]=build_ranked_dict(lst);GRAPHS={qwerty:adjacency_graphs.qwerty,dvorak:adjacency_graphs.dvorak,keypad:adjacency_graphs.keypad,mac_keypad:adjacency_graphs.mac_keypad},L33T_TABLE={a:["4","@"],b:["8"],c:["(","{","[","<"],e:["3"],g:["6","9"],i:["1","!","|"],l:["1","|","7"],o:["0"],s:["$","5"],t:["+","7"],x:["%"],z:["2"]},REGEXEN={recent_year:/19\d\d|200\d|201\d/g},DATE_MAX_YEAR=2050,DATE_MIN_YEAR=1e3,DATE_SPLITS={4:[[1,2],[2,3]],5:[[1,3],[2,3]],6:[[1,2],[2,4],[4,5]],7:[[1,3],[2,3],[4,5],[4,6]],8:[[2,4],[4,6]]},matching={empty:function(e){var t;return 0===function(){var n;for(t in n=[],e)n.push(t);return n}().length},extend:function(e,t){return e.push.apply(e,t)},translate:function(e,t){var n;return function(){var r,i,a,s;for(s=[],i=0,r=(a=e.split("")).length;i<r;i++)n=a[i],s.push(t[n]||n);return s}().join("")},mod:function(e,t){return(e%t+t)%t},sorted:function(e){return e.sort(function(e,t){return e.i-t.i||e.j-t.j})},omnimatch:function(e){var t,n,r,i,a;for(i=[],a=0,t=(r=[this.dictionary_match,this.reverse_dictionary_match,this.l33t_match,this.spatial_match,this.repeat_match,this.sequence_match,this.regex_match,this.date_match]).length;a<t;a++)n=r[a],this.extend(i,n.call(this,e));return this.sorted(i)},dictionary_match:function(e,t=RANKED_DICTIONARIES){var n,r,i,a,s,o,h,c,u,l,_,f,d,p;for(n in s=[],a=e.length,c=e.toLowerCase(),t)for(l=t[n],r=o=0,_=a;0<=_?o<_:o>_;r=0<=_?++o:--o)for(i=h=f=r,d=a;f<=d?h<d:h>d;i=f<=d?++h:--h)c.slice(r,+i+1||9e9)in l&&(u=l[p=c.slice(r,+i+1||9e9)],s.push({pattern:"dictionary",i:r,j:i,token:e.slice(r,+i+1||9e9),matched_word:p,rank:u,dictionary_name:n,reversed:!1,l33t:!1}));return this.sorted(s)},reverse_dictionary_match:function(e,t=RANKED_DICTIONARIES){var n,r,i,a,s;for(s=e.split("").reverse().join(""),a=0,n=(i=this.dictionary_match(s,t)).length;a<n;a++)(r=i[a]).token=r.token.split("").reverse().join(""),r.reversed=!0,[r.i,r.j]=[e.length-1-r.j,e.length-1-r.i];return this.sorted(i)},set_user_input_dictionary:function(e){return RANKED_DICTIONARIES.user_inputs=build_ranked_dict(e.slice())},relevant_l33t_subtable:function(e,t){var n,r,i,a,s,o,h,c,u,l;for(s={},a=0,r=(o=e.split("")).length;a<r;a++)n=o[a],s[n]=!0;for(i in l={},t)u=t[i],(h=function(){var e,t,n;for(n=[],t=0,e=u.length;t<e;t++)(c=u[t])in s&&n.push(c);return n}()).length>0&&(l[i]=h);return l},enumerate_l33t_subs:function(e){var t,n,r,i,a,s,o,h,c,u,l,_,f,d;for(a=function(){var t;for(i in t=[],e)t.push(i);return t}(),d=[[]],n=function(e){var t,n,r,a,s,o,h,c;for(n=[],s={},o=0,a=e.length;o<a;o++)h=e[o],(t=function(){var e,t,n;for(n=[],c=t=0,e=h.length;t<e;c=++t)i=h[c],n.push([i,c]);return n}()).sort(),(r=function(){var e,n,r;for(r=[],c=n=0,e=t.length;n<e;c=++n)i=t[c],r.push(i+","+c);return r}().join("-"))in s||(s[r]=!0,n.push(h));return n},(r=function(t){var i,a,s,o,h,c,u,l,_,f,p,g,m,A,E,y;if(t.length){for(a=t[0],m=t.slice(1),u=[],l=0,h=(p=e[a]).length;l<h;l++)for(o=p[l],_=0,c=d.length;_<c;_++){for(i=-1,s=f=0,g=(A=d[_]).length;0<=g?f<g:f>g;s=0<=g?++f:--f)if(A[s][0]===o){i=s;break}-1===i?(y=A.concat([[o,a]]),u.push(y)):((E=A.slice(0)).splice(i,1),E.push([o,a]),u.push(A),u.push(E))}return d=n(u),r(m)}})(a),f=[],c=0,o=d.length;c<o;c++){for(_={},u=0,h=(l=d[c]).length;u<h;u++)[s,t]=l[u],_[s]=t;f.push(_)}return f},l33t_match:function(e,t=RANKED_DICTIONARIES,n=L33T_TABLE){var r,i,a,s,o,h,c,u,l,_,f,d,p,g,m,A;for(c=[],u=0,a=(_=this.enumerate_l33t_subs(this.relevant_l33t_subtable(e,n))).length;u<a&&(d=_[u],!this.empty(d));u++)for(g=this.translate(e,d),l=0,s=(f=this.dictionary_match(g,t)).length;l<s;l++)if(o=f[l],(m=e.slice(o.i,+o.j+1||9e9)).toLowerCase()!==o.matched_word){for(p in h={},d)r=d[p],-1!==m.indexOf(p)&&(h[p]=r);o.l33t=!0,o.token=m,o.sub=h,o.sub_display=function(){var e;for(i in e=[],h)A=h[i],e.push(`${i} -> ${A}`);return e}().join(", "),c.push(o)}return this.sorted(c.filter(function(e){return e.token.length>1}))},spatial_match:function(e,t=GRAPHS){var n,r,i;for(r in i=[],t)n=t[r],this.extend(i,this.spatial_match_helper(e,n,r));return this.sorted(i)},SHIFTED_RX:/[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?]/,spatial_match_helper:function(e,t,n){var r,i,a,s,o,h,c,u,l,_,f,d,p,g;for(f=[],c=0;c<e.length-1;)for(u=c+1,l=null,g=0,p="qwerty"!==n&&"dvorak"!==n||!this.SHIFTED_RX.exec(e.charAt(c))?0:1;;){if(o=!1,h=-1,s=-1,i=t[e.charAt(u-1)]||[],u<e.length)for(a=e.charAt(u),d=0,_=i.length;d<_;d++)if(s+=1,(r=i[d])&&-1!==r.indexOf(a)){o=!0,h=s,1===r.indexOf(a)&&(p+=1),l!==h&&(g+=1,l=h);break}if(!o){u-c>2&&f.push({pattern:"spatial",i:c,j:u-1,token:e.slice(c,u),graph:n,turns:g,shifted_count:p}),c=u;break}u+=1}return f},repeat_match:function(e){var t,n,r,i,a,s,o,h,c,u,l,_,f,d;for(d=[],a=/(.+)\1+/g,u=/(.+?)\1+/g,l=/^(.+?)\1+$/,c=0;c<e.length&&(a.lastIndex=u.lastIndex=c,s=a.exec(e),_=u.exec(e),null!=s);)s[0].length>_[0].length?(f=s,i=l.exec(f[0])[1]):i=(f=_)[1],[o,h]=[f.index,f.index+f[0].length-1],r=(t=scoring.most_guessable_match_sequence(i,this.omnimatch(i))).sequence,n=t.guesses,d.push({pattern:"repeat",i:o,j:h,token:f[0],base_token:i,base_guesses:n,base_matches:r,repeat_count:f[0].length/i.length}),c=h+1;return d},MAX_DELTA:5,sequence_match:function(e){var t,n,r,i,a,s,o,h,c;if(1===e.length)return[];for(c=((t,n,r)=>{var i,a,s,o;if((n-t>1||1===Math.abs(r))&&0<(i=Math.abs(r))&&i<=this.MAX_DELTA)return o=e.slice(t,+n+1||9e9),/^[a-z]+$/.test(o)?(a="lower",s=26):/^[A-Z]+$/.test(o)?(a="upper",s=26):/^\d+$/.test(o)?(a="digits",s=10):(a="unicode",s=26),h.push({pattern:"sequence",i:t,j:n,token:e.slice(t,+n+1||9e9),sequence_name:a,sequence_space:s,ascending:r>0})}),h=[],n=0,a=null,i=s=1,o=e.length;1<=o?s<o:s>o;i=1<=o?++s:--s)t=e.charCodeAt(i)-e.charCodeAt(i-1),null==a&&(a=t),t!==a&&(c(n,r=i-1,a),n=r,a=t);return c(n,e.length-1,a),h},regex_match:function(e,t=REGEXEN){var n,r,i,a;for(name in n=[],t)for((r=t[name]).lastIndex=0;i=r.exec(e);)a=i[0],n.push({pattern:"regex",token:a,i:i.index,j:i.index+i[0].length-1,regex_name:name,regex_match:i});return this.sorted(n)},date_match:function(e){var t,n,r,i,a,s,o,h,c,u,l,_,f,d,p,g,m,A,E,y,v,I,R,T,D,k,x,j,b,N,S,q;for(_=[],f=/^\d{4,8}$/,d=/^(\d{1,4})([\s\/\\_.-])(\d{1,2})\2(\d{1,4})$/,s=m=0,v=e.length-4;0<=v?m<=v:m>=v;s=0<=v?++m:--m)for(o=A=I=s+3,R=s+7;(I<=R?A<=R:A>=R)&&!(o>=e.length);o=I<=R?++A:--A)if(q=e.slice(s,+o+1||9e9),f.exec(q)){for(r=[],E=0,u=(T=DATE_SPLITS[q.length]).length;E<u;E++)[h,c]=T[E],null!=(a=this.map_ints_to_dmy([parseInt(q.slice(0,h)),parseInt(q.slice(h,c)),parseInt(q.slice(c))]))&&r.push(a);if(r.length>0){for(t=r[0],g=(p=function(e){return Math.abs(e.year-scoring.REFERENCE_YEAR)})(r[0]),y=0,l=(D=r.slice(1)).length;y<l;y++)(i=p(n=D[y]))<g&&([t,g]=[n,i]);_.push({pattern:"date",token:q,i:s,j:o,separator:"",year:t.year,month:t.month,day:t.day})}}for(s=N=0,k=e.length-6;0<=k?N<=k:N>=k;s=0<=k?++N:--N)for(o=S=x=s+5,j=s+9;(x<=j?S<=j:S>=j)&&!(o>=e.length);o=x<=j?++S:--S)q=e.slice(s,+o+1||9e9),null!=(b=d.exec(q))&&null!=(a=this.map_ints_to_dmy([parseInt(b[1]),parseInt(b[3]),parseInt(b[4])]))&&_.push({pattern:"date",token:q,i:s,j:o,separator:b[2],year:a.year,month:a.month,day:a.day});return this.sorted(_.filter(function(e){var t,n,r,i;for(t=!1,i=0,n=_.length;i<n;i++)if(e!==(r=_[i])&&r.i<=e.i&&r.j>=e.j){t=!0;break}return!t}))},map_ints_to_dmy:function(e){var t,n,r,i,a,s,o,h,c,u,l,_,f,d;if(!(e[1]>31||e[1]<=0)){for(o=0,h=0,f=0,s=0,r=e.length;s<r;s++){if(99<(n=e[s])&&n<DATE_MIN_YEAR||n>DATE_MAX_YEAR)return;n>31&&(h+=1),n>12&&(o+=1),n<=0&&(f+=1)}if(!(h>=2||3===o||f>=2)){for(c=0,i=(u=[[e[2],e.slice(0,2)],[e[0],e.slice(1,3)]]).length;c<i;c++)if([d,_]=u[c],DATE_MIN_YEAR<=d&&d<=DATE_MAX_YEAR)return null!=(t=this.map_ints_to_dm(_))?{year:d,month:t.month,day:t.day}:void 0;for(l=0,a=u.length;l<a;l++)if([d,_]=u[l],null!=(t=this.map_ints_to_dm(_)))return{year:d=this.two_to_four_digit_year(d),month:t.month,day:t.day}}}},map_ints_to_dm:function(e){var t,n,r,i,a;for(i=0,n=(a=[e,e.slice().reverse()]).length;i<n;i++)if([t,r]=a[i],1<=t&&t<=31&&1<=r&&r<=12)return{day:t,month:r}},two_to_four_digit_year:function(e){return e>99?e:e>50?e+1900:e+2e3}},module.exports=matching;
+
+},{"./adjacency_graphs":1,"./frequency_lists":3,"./scoring":6}],6:[function(require,module,exports){
+var BRUTEFORCE_CARDINALITY,MIN_GUESSES_BEFORE_GROWING_SEQUENCE,MIN_SUBMATCH_GUESSES_MULTI_CHAR,MIN_SUBMATCH_GUESSES_SINGLE_CHAR,adjacency_graphs,calc_average_degree,k,scoring,v;adjacency_graphs=require("./adjacency_graphs"),calc_average_degree=function(e){var t,r,n,s,a;for(n in t=0,e)a=e[n],t+=function(){var e,t,r;for(r=[],t=0,e=a.length;t<e;t++)(s=a[t])&&r.push(s);return r}().length;return t/=function(){var t;for(r in t=[],e)e[r],t.push(r);return t}().length},BRUTEFORCE_CARDINALITY=10,MIN_GUESSES_BEFORE_GROWING_SEQUENCE=1e4,MIN_SUBMATCH_GUESSES_SINGLE_CHAR=10,MIN_SUBMATCH_GUESSES_MULTI_CHAR=50,scoring={nCk:function(e,t){var r,n,s,a;if(t>e)return 0;if(0===t)return 1;for(s=1,r=n=1,a=t;1<=a?n<=a:n>=a;r=1<=a?++n:--n)s*=e,s/=r,e-=1;return s},log10:function(e){return Math.log(e)/Math.log(10)},log2:function(e){return Math.log(e)/Math.log(2)},factorial:function(e){var t,r,n,s;if(e<2)return 1;for(t=1,r=n=2,s=e;2<=s?n<=s:n>=s;r=2<=s?++n:--n)t*=r;return t},most_guessable_match_sequence:function(e,t,r=!1){var n,s,a,i,u,_,o,h,E,g,c,f,l,A,S,p,R,I,v,M,N,C;for(c=e.length,g=function(){var e,t,r;for(r=[],e=0,t=c;0<=t?e<t:e>t;0<=t?++e:--e)r.push([]);return r}(),f=0,u=t.length;f<u;f++)g[(h=t[f]).j].push(h);for(p=0,_=g.length;p<_;p++)g[p].sort(function(e,t){return e.i-t.i});for(l={m:function(){var e,t,r;for(t=[],r=0,e=c;0<=e?r<e:r>e;0<=e?++r:--r)t.push({});return t}(),pi:function(){var e,t,r;for(t=[],r=0,e=c;0<=e?r<e:r>e;0<=e?++r:--r)t.push({});return t}(),g:function(){var e,t,r;for(t=[],r=0,e=c;0<=e?r<e:r>e;0<=e?++r:--r)t.push({});return t}()},N=((t,n)=>{var s,a,i,u,_,o;for(a in u=t.j,_=this.estimate_guesses(t,e),n>1&&(_*=l.pi[t.i-1][n-1]),i=this.factorial(n)*_,r||(i+=Math.pow(MIN_GUESSES_BEFORE_GROWING_SEQUENCE,n-1)),o=l.g[u])if(s=o[a],!(a>n)&&s<=i)return;return l.g[u][n]=i,l.m[u][n]=t,l.pi[u][n]=_}),n=(e=>{var t,r,n,s,a,i;for(h=E(0,e),N(h,1),a=[],t=i=1,s=e;1<=s?i<=s:i>=s;t=1<=s?++i:--i)h=E(t,e),a.push(function(){var e,s;for(r in s=[],e=l.m[t-1])n=e[r],r=parseInt(r),"bruteforce"!==n.pattern&&s.push(N(h,r+1));return s}());return a}),E=((t,r)=>({pattern:"bruteforce",token:e.slice(t,+r+1||9e9),i:t,j:r})),M=(e=>{var t,r,n,s,a,i,u;for(r in i=[],s=e-1,a=void 0,n=Infinity,u=l.g[s])(t=u[r])<n&&(a=r,n=t);for(;s>=0;)h=l.m[s][a],i.unshift(h),s=h.i-1,a--;return i}),a=v=0,R=c;0<=R?v<R:v>R;a=0<=R?++v:--v){for(C=0,o=(I=g[a]).length;C<o;C++)if((h=I[C]).i>0)for(i in l.m[h.i-1])i=parseInt(i),N(h,i+1);else N(h,1);n(a)}return A=(S=M(c)).length,s=0===e.length?1:l.g[c-1][A],{password:e,guesses:s,guesses_log10:this.log10(s),sequence:S}},estimate_guesses:function(e,t){var r,n;return null!=e.guesses?e.guesses:(n=1,e.token.length<t.length&&(n=1===e.token.length?MIN_SUBMATCH_GUESSES_SINGLE_CHAR:MIN_SUBMATCH_GUESSES_MULTI_CHAR),r={bruteforce:this.bruteforce_guesses,dictionary:this.dictionary_guesses,spatial:this.spatial_guesses,repeat:this.repeat_guesses,sequence:this.sequence_guesses,regex:this.regex_guesses,date:this.date_guesses}[e.pattern].call(this,e),e.guesses=Math.max(r,n),e.guesses_log10=this.log10(e.guesses),e.guesses)},bruteforce_guesses:function(e){var t,r;return(t=Math.pow(BRUTEFORCE_CARDINALITY,e.token.length))===Number.POSITIVE_INFINITY&&(t=Number.MAX_VALUE),r=1===e.token.length?MIN_SUBMATCH_GUESSES_SINGLE_CHAR+1:MIN_SUBMATCH_GUESSES_MULTI_CHAR+1,Math.max(t,r)},repeat_guesses:function(e){return e.base_guesses*e.repeat_count},sequence_guesses:function(e){var t,r;return t="a"===(r=e.token.charAt(0))||"A"===r||"z"===r||"Z"===r||"0"===r||"1"===r||"9"===r?4:r.match(/\d/)?10:26,e.ascending||(t*=2),t*e.token.length},MIN_YEAR_SPACE:20,REFERENCE_YEAR:(new Date).getFullYear(),regex_guesses:function(e){var t,r;if(t={alpha_lower:26,alpha_upper:26,alpha:52,alphanumeric:62,digits:10,symbols:33},e.regex_name in t)return Math.pow(t[e.regex_name],e.token.length);switch(e.regex_name){case"recent_year":return r=Math.abs(parseInt(e.regex_match[0])-this.REFERENCE_YEAR),r=Math.max(r,this.MIN_YEAR_SPACE)}},date_guesses:function(e){var t;return t=365*Math.max(Math.abs(e.year-this.REFERENCE_YEAR),this.MIN_YEAR_SPACE),e.separator&&(t*=4),t},KEYBOARD_AVERAGE_DEGREE:calc_average_degree(adjacency_graphs.qwerty),KEYPAD_AVERAGE_DEGREE:calc_average_degree(adjacency_graphs.keypad),KEYBOARD_STARTING_POSITIONS:function(){var e,t;for(k in t=[],e=adjacency_graphs.qwerty)v=e[k],t.push(k);return t}().length,KEYPAD_STARTING_POSITIONS:function(){var e,t;for(k in t=[],e=adjacency_graphs.keypad)v=e[k],t.push(k);return t}().length,spatial_guesses:function(e){var t,r,n,s,a,i,u,_,o,h,E,g,c,f,l,A,S;for("qwerty"===(h=e.graph)||"dvorak"===h?(f=this.KEYBOARD_STARTING_POSITIONS,s=this.KEYBOARD_AVERAGE_DEGREE):(f=this.KEYPAD_STARTING_POSITIONS,s=this.KEYPAD_AVERAGE_DEGREE),a=0,t=e.token.length,A=e.turns,i=_=2,E=t;2<=E?_<=E:_>=E;i=2<=E?++_:--_)for(u=o=1,g=Math.min(A,i-1);1<=g?o<=g:o>=g;u=1<=g?++o:--o)a+=this.nCk(i-1,u-1)*f*Math.pow(s,u);if(e.shifted_count)if(r=e.shifted_count,n=e.token.length-e.shifted_count,0===r||0===n)a*=2;else{for(l=0,i=S=1,c=Math.min(r,n);1<=c?S<=c:S>=c;i=1<=c?++S:--S)l+=this.nCk(r+n,i);a*=l}return a},dictionary_guesses:function(e){var t;return e.base_guesses=e.rank,e.uppercase_variations=this.uppercase_variations(e),e.l33t_variations=this.l33t_variations(e),t=e.reversed?2:1,e.base_guesses*e.uppercase_variations*e.l33t_variations*t},START_UPPER:/^[A-Z][^A-Z]+$/,END_UPPER:/^[^A-Z]+[A-Z]$/,ALL_UPPER:/^[^a-z]+$/,ALL_LOWER:/^[^A-Z]+$/,uppercase_variations:function(e){var t,r,n,s,a,i,u,_,o,h,E,g;if((g=e.token).match(this.ALL_LOWER)||g.toLowerCase()===g)return 1;for(i=0,a=(_=[this.START_UPPER,this.END_UPPER,this.ALL_UPPER]).length;i<a;i++)if(h=_[i],g.match(h))return 2;for(r=function(){var e,t,r,s;for(s=[],t=0,e=(r=g.split("")).length;t<e;t++)(n=r[t]).match(/[A-Z]/)&&s.push(n);return s}().length,t=function(){var e,t,r,s;for(s=[],t=0,e=(r=g.split("")).length;t<e;t++)(n=r[t]).match(/[a-z]/)&&s.push(n);return s}().length,E=0,s=u=1,o=Math.min(r,t);1<=o?u<=o:u>=o;s=1<=o?++u:--u)E+=this.nCk(r+t,s);return E},l33t_variations:function(e){var t,r,n,s,a,i,u,_,o,h,E,g;if(!e.l33t)return 1;for(h in g=1,_=e.sub)if(E=_[h],s=e.token.toLowerCase().split(""),t=function(){var e,t,r;for(r=[],t=0,e=s.length;t<e;t++)(n=s[t])===h&&r.push(n);return r}().length,r=function(){var e,t,r;for(r=[],t=0,e=s.length;t<e;t++)(n=s[t])===E&&r.push(n);return r}().length,0===t||0===r)g*=2;else{for(u=0,a=i=1,o=Math.min(r,t);1<=o?i<=o:i>=o;a=1<=o?++i:--i)u+=this.nCk(r+t,a);g*=u}return g}},module.exports=scoring;
+
+},{"./adjacency_graphs":1}],7:[function(require,module,exports){
+var time_estimates;time_estimates={estimate_attack_times:function(e){var t,n,s,o;for(s in t={},n={online_throttling_100_per_hour:e/(100/3600),online_no_throttling_10_per_second:e/10,offline_slow_hashing_1e4_per_second:e/1e4,offline_fast_hashing_1e10_per_second:e/1e10})o=n[s],t[s]=this.display_time(o);return{crack_times_seconds:n,crack_times_display:t,score:this.guesses_to_score(e)}},guesses_to_score:function(e){return 5,e<1005?0:e<1e6+5?1:e<1e8+5?2:e<1e10+5?3:4},display_time:function(e){var t,n,s;return 60,3600,86400,2678400,32140800,321408e4,[n,s]=e<1?[null,"less than a second"]:e<60?[t=Math.round(e),`${t} second`]:e<3600?[t=Math.round(e/60),`${t} minute`]:e<86400?[t=Math.round(e/3600),`${t} hour`]:e<2678400?[t=Math.round(e/86400),`${t} day`]:e<32140800?[t=Math.round(e/2678400),`${t} month`]:e<321408e4?[t=Math.round(e/32140800),`${t} year`]:[null,"centuries"],null!=n&&1!==n&&(s+="s"),s}},module.exports=time_estimates;
+
+},{}]},{},[4])(4)
+});
+//# sourceMappingURL=zxcvbn.js.map
index f9262d282564e5abd5c85ebf1e4917ae1d9dd382..8291ac92102ee2c7c1f6efd9d20b997c423e44d7 100644 (file)
@@ -7,7 +7,7 @@
 (function(){var a=false,b=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){};Class.extend=function(c){function g(){if(!a&&this.init)this.init.apply(this,arguments);}var d=this.prototype;a=true;var e=new this;a=false;for(var f in c){e[f]=typeof c[f]=="function"&&typeof d[f]=="function"&&b.test(c[f])?function(a,b){return function(){var c=this._super;this._super=d[a];var e=b.apply(this,arguments);this._super=c;return e;};}(f,c[f]):c[f]}g.prototype=e;g.prototype.constructor=g;g.extend=arguments.callee;return g;};})();
 
 /*! head.load - v1.0.3 */
-(function(n,t){"use strict";function w(){}function u(n,t){if(n){typeof n=="object"&&(n=[].slice.call(n));for(var i=0,r=n.length;i<r;i++)t.call(n,n[i],i)}}function it(n,i){var r=Object.prototype.toString.call(i).slice(8,-1);return i!==t&&i!==null&&r===n}function s(n){return it("Function",n)}function a(n){return it("Array",n)}function et(n){var i=n.split("/"),t=i[i.length-1],r=t.indexOf("?");return r!==-1?t.substring(0,r):t}function f(n){(n=n||w,n._done)||(n(),n._done=1)}function ot(n,t,r,u){var f=typeof n=="object"?n:{test:n,success:!t?!1:a(t)?t:[t],failure:!r?!1:a(r)?r:[r],callback:u||w},e=!!f.test;return e&&!!f.success?(f.success.push(f.callback),i.load.apply(null,f.success)):e||!f.failure?u():(f.failure.push(f.callback),i.load.apply(null,f.failure)),i}function v(n){var t={},i,r;if(typeof n=="object")for(i in n)!n[i]||(t={name:i,url:n[i]});else t={name:et(n),url:n};return(r=c[t.name],r&&r.url===t.url)?r:(c[t.name]=t,t)}function y(n){n=n||c;for(var t in n)if(n.hasOwnProperty(t)&&n[t].state!==l)return!1;return!0}function st(n){n.state=ft;u(n.onpreload,function(n){n.call()})}function ht(n){n.state===t&&(n.state=nt,n.onpreload=[],rt({url:n.url,type:"cache"},function(){st(n)}))}function ct(){var n=arguments,t=n[n.length-1],r=[].slice.call(n,1),f=r[0];return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(f?(u(r,function(n){s(n)||!n||ht(v(n))}),b(v(n[0]),s(f)?f:function(){i.load.apply(null,r)})):b(v(n[0])),i)}function lt(){var n=arguments,t=n[n.length-1],r={};return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(u(n,function(n){n!==t&&(n=v(n),r[n.name]=n)}),u(n,function(n){n!==t&&(n=v(n),b(n,function(){y(r)&&f(t)}))}),i)}function b(n,t){if(t=t||w,n.state===l){t();return}if(n.state===tt){i.ready(n.name,t);return}if(n.state===nt){n.onpreload.push(function(){b(n,t)});return}n.state=tt;rt(n,function(){n.state=l;t();u(h[n.name],function(n){f(n)});o&&y()&&u(h.ALL,function(n){f(n)})})}function at(n){n=n||"";var t=n.split("?")[0].split(".");return t[t.length-1].toLowerCase()}function rt(t,i){function e(t){t=t||n.event;u.onload=u.onreadystatechange=u.onerror=null;i()}function o(f){f=f||n.event;(f.type==="load"||/loaded|complete/.test(u.readyState)&&(!r.documentMode||r.documentMode<9))&&(n.clearTimeout(t.errorTimeout),n.clearTimeout(t.cssTimeout),u.onload=u.onreadystatechange=u.onerror=null,i())}function s(){if(t.state!==l&&t.cssRetries<=20){for(var i=0,f=r.styleSheets.length;i<f;i++)if(r.styleSheets[i].href===u.href){o({type:"load"});return}t.cssRetries++;t.cssTimeout=n.setTimeout(s,250)}}var u,h,f;i=i||w;h=at(t.url);h==="css"?(u=r.createElement("link"),u.type="text/"+(t.type||"css"),u.rel="stylesheet",u.href=t.url,t.cssRetries=0,t.cssTimeout=n.setTimeout(s,500)):(u=r.createElement("script"),u.type="text/"+(t.type||"javascript"),u.src=t.url);u.onload=u.onreadystatechange=o;u.onerror=e;u.async=!1;u.defer=!1;t.errorTimeout=n.setTimeout(function(){e({type:"timeout"})},7e3);f=r.head||r.getElementsByTagName("head")[0];f.insertBefore(u,f.lastChild)}function vt(){for(var t,u=r.getElementsByTagName("script"),n=0,f=u.length;n<f;n++)if(t=u[n].getAttribute("data-headjs-load"),!!t){i.load(t);return}}function yt(n,t){var v,p,e;return n===r?(o?f(t):d.push(t),i):(s(n)&&(t=n,n="ALL"),a(n))?(v={},u(n,function(n){v[n]=c[n];i.ready(n,function(){y(v)&&f(t)})}),i):typeof n!="string"||!s(t)?i:(p=c[n],p&&p.state===l||n==="ALL"&&y()&&o)?(f(t),i):(e=h[n],e?e.push(t):e=h[n]=[t],i)}function e(){if(!r.body){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(e,50);return}o||(o=!0,vt(),u(d,function(n){f(n)}))}function k(){r.addEventListener?(r.removeEventListener("DOMContentLoaded",k,!1),e()):r.readyState==="complete"&&(r.detachEvent("onreadystatechange",k),e())}var r=n.document,d=[],h={},c={},ut="async"in r.createElement("script")||"MozAppearance"in r.documentElement.style||n.opera,o,g=n.head_conf&&n.head_conf.head||"head",i=n[g]=n[g]||function(){i.ready.apply(null,arguments)},nt=1,ft=2,tt=3,l=4,p;if(r.readyState==="complete")e();else if(r.addEventListener)r.addEventListener("DOMContentLoaded",k,!1),n.addEventListener("load",e,!1);else{r.attachEvent("onreadystatechange",k);n.attachEvent("onload",e);p=!1;try{p=!n.frameElement&&r.documentElement}catch(wt){}p&&p.doScroll&&function pt(){if(!o){try{p.doScroll("left")}catch(t){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(pt,50);return}e()}}()}i.load=i.js=ut?lt:ct;i.test=ot;i.ready=yt;i.ready(r,function(){y()&&u(h.ALL,function(n){f(n)});i.feature&&i.feature("domloaded",!0)})})(window);
+(function(n,t){"use strict";function w(){}function u(n,t){if(n){typeof n=="object"&&(n=[].slice.call(n));for(var i=0,r=n.length;i<r;i++)t.call(n,n[i],i)}}function it(n,i){var r=Object.prototype.toString.call(i).slice(8,-1);return i!==t&&i!==null&&r===n}function s(n){return it("Function",n)}function a(n){return it("Array",n)}function et(n){var i=n.split("/"),t=i[i.length-1],r=t.indexOf("?");return r!==-1?t.substring(0,r):t}function f(n){(n=n||w,n._done)||(n(),n._done=1)}function ot(n,t,r,u){var f=typeof n=="object"?n:{test:n,success:!t?!1:a(t)?t:[t],failure:!r?!1:a(r)?r:[r],callback:u||w},e=!!f.test;return e&&!!f.success?(f.success.push(f.callback),i.load.apply(null,f.success)):e||!f.failure?u():(f.failure.push(f.callback),i.load.apply(null,f.failure)),i}function v(n){var t={},i,r;if(typeof n=="object")for(i in n)!n[i]||(t={name:i,url:n[i]});else t={name:et(n),url:n};return(r=c[t.name],r&&r.url===t.url)?r:(c[t.name]=t,t)}function y(n){n=n||c;for(var t in n)if(n.hasOwnProperty(t)&&n[t].state!==l)return!1;return!0}function st(n){n.state=ft;u(n.onpreload,function(n){n.call()})}function ht(n){n.state===t&&(n.state=nt,n.onpreload=[],rt({url:n.url,type:"cache"},function(){st(n)}))}function ct(){var n=arguments,t=n[n.length-1],r=[].slice.call(n,1),f=r[0];return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(f?(u(r,function(n){s(n)||!n||ht(v(n))}),b(v(n[0]),s(f)?f:function(){i.load.apply(null,r)})):b(v(n[0])),i)}function lt(){var n=arguments,t=n[n.length-1],r={};return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(u(n,function(n){n!==t&&(n=v(n),r[n.name]=n)}),u(n,function(n){n!==t&&(n=v(n),b(n,function(){y(r)&&f(t)}))}),i)}function b(n,t){if(t=t||w,n.state===l){t();return}if(n.state===tt){i.ready(n.name,t);return}if(n.state===nt){n.onpreload.push(function(){b(n,t)});return}n.state=tt;rt(n,function(){n.state=l;t();u(h[n.name],function(n){f(n)});o&&y()&&u(h.ALL,function(n){f(n)})})}function at(n){n=n||"";var t=n.split("?")[0].split(".");return t[t.length-1].toLowerCase()}function rt(t,i){function e(t){t=t||n.event;u.onload=u.onreadystatechange=u.onerror=null;i()}function o(f){f=f||n.event;(f.type==="load"||/loaded|complete/.test(u.readyState)&&(!r.documentMode||r.documentMode<9))&&(n.clearTimeout(t.errorTimeout),n.clearTimeout(t.cssTimeout),u.onload=u.onreadystatechange=u.onerror=null,i())}function s(){if(t.state!==l&&t.cssRetries<=20){for(var i=0,f=r.styleSheets.length;i<f;i++)if(r.styleSheets[i].href===u.href){o({type:"load"});return}t.cssRetries++;t.cssTimeout=n.setTimeout(s,250)}}var u,h,f;i=i||w;h=at(t.url);h==="css"?(u=r.createElement("link"),u.type="text/"+(t.type||"css"),u.rel="stylesheet",u.href=t.url,t.cssRetries=0,t.cssTimeout=n.setTimeout(s,500)):(u=r.createElement("script"),u.type="text/"+(t.type||"javascript"),u.src=t.url);u.onload=u.onreadystatechange=o;u.onerror=e;u.async=!1;u.defer=!1;t.errorTimeout=n.setTimeout(function(){e({type:"timeout"})},60e3);f=r.head||r.getElementsByTagName("head")[0];f.insertBefore(u,f.lastChild)}function vt(){for(var t,u=r.getElementsByTagName("script"),n=0,f=u.length;n<f;n++)if(t=u[n].getAttribute("data-headjs-load"),!!t){i.load(t);return}}function yt(n,t){var v,p,e;return n===r?(o?f(t):d.push(t),i):(s(n)&&(t=n,n="ALL"),a(n))?(v={},u(n,function(n){v[n]=c[n];i.ready(n,function(){y(v)&&f(t)})}),i):typeof n!="string"||!s(t)?i:(p=c[n],p&&p.state===l||n==="ALL"&&y()&&o)?(f(t),i):(e=h[n],e?e.push(t):e=h[n]=[t],i)}function e(){if(!r.body){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(e,50);return}o||(o=!0,vt(),u(d,function(n){f(n)}))}function k(){r.addEventListener?(r.removeEventListener("DOMContentLoaded",k,!1),e()):r.readyState==="complete"&&(r.detachEvent("onreadystatechange",k),e())}var r=n.document,d=[],h={},c={},ut="async"in r.createElement("script")||"MozAppearance"in r.documentElement.style||n.opera,o,g=n.head_conf&&n.head_conf.head||"head",i=n[g]=n[g]||function(){i.ready.apply(null,arguments)},nt=1,ft=2,tt=3,l=4,p;if(r.readyState==="complete")e();else if(r.addEventListener)r.addEventListener("DOMContentLoaded",k,!1),n.addEventListener("load",e,!1);else{r.attachEvent("onreadystatechange",k);n.attachEvent("onload",e);p=!1;try{p=!n.frameElement&&r.documentElement}catch(wt){}p&&p.doScroll&&function pt(){if(!o){try{p.doScroll("left")}catch(t){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(pt,50);return}e()}}()}i.load=i.js=ut?lt:ct;i.test=ot;i.ready=yt;i.ready(r,function(){y()&&u(h.ALL,function(n){f(n)});i.feature&&i.feature("domloaded",!0)})})(window);
 
 /*
 * @fileOverview TouchSwipe - jQuery Plugin
index 1f9e31cb4c82e020cad52163925ca7efd629cb7b..34ff910301e24eeb3062ebc3edacb9e14a3fb0bf 100644 (file)
@@ -87,8 +87,7 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                this._fileListSelector.find('.jsButtonAttachmentInsertThumbnail').click($.proxy(this._insert, this));
                this._fileListSelector.find('.jsButtonAttachmentInsertFull').click($.proxy(this._insert, this));
                
-               WCF.DOMNodeRemovedHandler.addCallback('WCF.Attachment.Upload', $.proxy(this._removeLimitError, this));
-               WCF.System.Event.addListener('com.woltlab.wcf.action.delete', 'attachment_' + this._editorId, $.proxy(this._removeLimitError, this));
+               WCF.System.Event.addListener('com.woltlab.wcf.action.delete', 'attachment', this._onDelete.bind(this));
                
                this._makeSortable();
                
@@ -153,6 +152,8 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                                }
                        }).bind(this));
                        
+                       var syncUuid = WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'sync_' + this._tmpHash, this._sync.bind(this));
+                       
                        WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'destroy_' + this._editorId, (function () {
                                WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'submit_' + this._editorId);
                                WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'reset_' + this._editorId);
@@ -162,6 +163,7 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                                WCF.System.Event.removeAllListeners('com.woltlab.wcf.redactor2', 'autosaveMetaData_' + this._editorId);
                                
                                WCF.System.Event.removeListener('com.woltlab.wcf.redactor2', 'metacode_attach_' + this._editorId, metacodeAttachUuid);
+                               WCF.System.Event.removeListener('com.woltlab.wcf.redactor2', 'sync_' + this._tmpHash, syncUuid);
                        }).bind(this));
                }
        },
@@ -172,7 +174,7 @@ WCF.Attachment.Upload = WCF.Upload.extend({
         * @param        object                data
         */
        _editorUpload: function (data) {
-               var $uploadID, replace = null;
+               var replace = null;
                
                // show tab
                this._fileListSelector.closest('.messageTabMenu').messageTabMenu('showTab', 'attachments', true);
@@ -189,10 +191,10 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                }).bind(this);
                
                if (data.file) {
-                       $uploadID = this._upload(undefined, data.file, undefined, callbackUploadId);
+                       this._upload(undefined, data.file, undefined, callbackUploadId);
                }
                else {
-                       $uploadID = this._upload(undefined, undefined, data.blob, callbackUploadId);
+                       this._upload(undefined, undefined, data.blob, callbackUploadId);
                        replace = data.replace || null;
                }
        },
@@ -333,6 +335,13 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                                // As our resizer is based on Pica it will use multiple workers per image if possible.
                                promise = Array.prototype.reduce.call(files, (function (acc, file) {
                                        return acc.then((function (arr) {
+                                               // Ignore anything that is neither PNG nor JPEG. GIFs are not supported
+                                               // due to the support for animations.
+                                               if (['image/png', 'image/jpeg'].indexOf(file.type) === -1) {
+                                                       arr.push(file);
+                                                       return arr;
+                                               }
+                                               
                                                var timeout = new Promise(function (resolve, reject) {
                                                        // We issue one timeout per image, thus multiple timeout
                                                        // handlers will run in parallel
@@ -455,7 +464,7 @@ WCF.Attachment.Upload = WCF.Upload.extend({
         * @see        WCF.Upload._initFile()
         */
        _initFile: function (file) {
-               var $li = $('<li class="box64"><span class="icon icon64 fa-spinner" /><div><div><p>' + file.name + '</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data('filename', file.name);
+               var $li = $('<li class="box64 formAttachmentListItem"><span class="icon icon64 fa-spinner" /><div><div><p>' + file.name + '</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data('filename', file.name);
                this._fileListSelector.append($li);
                this._fileListSelector.show();
                
@@ -481,9 +490,10 @@ WCF.Attachment.Upload = WCF.Upload.extend({
         *
         * @return      {boolean}
         * @protected
+        * @deprecated 5.3
         */
        _useThumbnail: function() {
-               return elDataBool(this._fileListSelector[0], 'enable-thumbnails');
+               return true;
        },
        
        /**
@@ -508,6 +518,8 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                        if (data.returnValues && data.returnValues.attachments[$internalFileID]) {
                                attachmentData = data.returnValues.attachments[$internalFileID];
                                
+                               elData($li[0], 'object-id', attachmentData.attachmentID);
+                               
                                // show thumbnail
                                if (attachmentData.tinyURL) {
                                        $li.children('.fa-spinner').replaceWith($('<img src="' + attachmentData.tinyURL + '" alt="" class="attachmentTinyThumbnail" />'));
@@ -536,27 +548,30 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                                
                                // init buttons
                                var $buttonList = $li.find('ul').addClass('buttonGroup');
-                               var $deleteButton = $('<li><span class="button small jsDeleteButton" data-object-id="' + attachmentData.attachmentID + '" data-confirm-message="' + WCF.Language.get('wcf.attachment.delete.sure') + '" data-event-name="attachment_' + this._editorId + '">' + WCF.Language.get('wcf.global.button.delete') + '</span></li>');
+                               var $deleteButton = $('<li><span class="button small jsDeleteButton" data-object-id="' + attachmentData.attachmentID + '" data-confirm-message="' + WCF.Language.get('wcf.attachment.delete.sure') + '" data-event-name="attachment">' + WCF.Language.get('wcf.global.button.delete') + '</span></li>');
                                $buttonList.append($deleteButton);
                                
                                $li.data('objectID', attachmentData.attachmentID);
                                
                                if (this._editorId) {
-                                       if (attachmentData.tinyURL || (!this._useThumbnail() && attachmentData.isImage)) {
+                                       if (attachmentData.tinyURL) {
                                                if (attachmentData.thumbnailURL) {
-                                                       var $insertThumbnail = $('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.thumbnailURL) + '">' + WCF.Language.get('wcf.attachment.insertThumbnail') + '</span></li>').appendTo($buttonList);
-                                                       $insertThumbnail.children('span.button').click($.proxy(this._insert, this));
+                                                       $('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.thumbnailURL) + '">' + WCF.Language.get('wcf.attachment.insertThumbnail') + '</span></li>').appendTo($buttonList);
                                                }
                                                
-                                               var $insertOriginal = $('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.url) + '">' + WCF.Language.get('wcf.attachment.insertFull') + '</span></li>').appendTo($buttonList);
-                                               $insertOriginal.children('span.button').click($.proxy(this._insert, this));
+                                               $('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="' + attachmentData.attachmentID + '" data-url="' + WCF.String.escapeHTML(attachmentData.url) + '">' + WCF.Language.get('wcf.attachment.insertFull') + '</span></li>').appendTo($buttonList);
                                        }
                                        else {
-                                               var $insertPlain = $('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="' + attachmentData.attachmentID + '">' + WCF.Language.get('wcf.attachment.insert') + '</span></li>');
-                                               $insertPlain.appendTo($buttonList).children('span.button').click($.proxy(this._insert, this));
+                                               $('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="' + attachmentData.attachmentID + '">' + WCF.Language.get('wcf.attachment.insert') + '</span></li>').appendTo($buttonList);
                                        }
                                }
                                
+                               this._triggerSync('new', {
+                                       html: $li[0].outerHTML
+                               });
+                               
+                               this._registerEditorButtons($li[0]);
+                               
                                if (this._replaceOnLoad.hasOwnProperty(uploadID)) {
                                        if (!$li.hasClass('uploadFailed')) {
                                                var img = this._replaceOnLoad[uploadID];
@@ -607,6 +622,10 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                        }
                }
                
+               this._rebuildInterface();
+       },
+       
+       _rebuildInterface: function () {
                this._makeSortable();
                
                if (this._fileListSelector.children('li:not(.uploadFailed)').length) {
@@ -619,6 +638,14 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                WCF.DOMNodeInsertedHandler.execute();
        },
        
+       _registerEditorButtons: function (attachment) {
+               if (this._editorId) {
+                       elBySelAll('.jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain', attachment, (function(button) {
+                               button.addEventListener('click', this._insert.bind(this));
+                       }).bind(this));
+               }
+       },
+       
        /**
         * Inserts an attachment into WYSIWYG editor contents.
         *
@@ -635,15 +662,12 @@ WCF.Attachment.Upload = WCF.Upload.extend({
         * Inserts all attachments at once.
         */
        _insertAll: function () {
-               var attachment, button, preferThumbnail = this._useThumbnail();
+               var attachment, button;
                for (var i = 0, length = this._fileListSelector[0].childNodes.length; i < length; i++) {
                        attachment = this._fileListSelector[0].childNodes[i];
                        if (attachment.nodeName === 'LI' && !attachment.classList.contains('uploadFailed')) {
-                               button = null;
-                               if (preferThumbnail) {
-                                       button = elBySel('.jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain', attachment);
-                               }
-
+                               button = elBySel('.jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain', attachment);
+                               
                                if (button === null) {
                                        button = elBySel('.jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain', attachment);
                                }
@@ -717,5 +741,72 @@ WCF.Attachment.Upload = WCF.Upload.extend({
                                }
                        }).bind(this));
                }
+       },
+       
+       /**
+        * @param {Object} data
+        * @param {jQuery} data.button
+        * @param {jQuery} data.container
+        */
+       _onDelete: function (data) {
+               var objectId = elData(data.button[0], 'object-id');
+               var attachment = elBySel('.formAttachmentListItem[data-object-id="' + objectId + '"]', this._fileListSelector[0]);
+               if (attachment !== null) {
+                       elRemove(attachment);
+               }
+               
+               this._removeLimitError(data);
+       },
+       
+       /**
+        * @param {Object} payload
+        * @param {Object} payload.data
+        * @param {Object} payload.source
+        * @param {string} payload.type
+        */
+       _sync: function (payload) {
+               if (payload.source === this) {
+                       return;
+               }
+               
+               switch (payload.type) {
+                       case 'new':
+                               this._syncNew(payload.data);
+                               break;
+                               
+                       default:
+                               throw new Error("Unexpected type '" + payload.type + "'");
+               }
+       },
+       
+       /**
+        * @param {Object} data
+        */
+       _syncNew: function (data) {
+               require(['Dom/Util'], (function (DomUtil) {
+                       var fragment = DomUtil.createFragmentFromHtml(data.html);
+                       var attachment = elBySel('li', fragment);
+                       attachment.id = '';
+                       
+                       this._registerEditorButtons(attachment);
+                       
+                       this._fileListSelector[0].appendChild(attachment);
+                       
+                       elShow(this._fileListSelector[0]);
+                       
+                       this._rebuildInterface();
+               }).bind(this));
+       },
+       
+       /**
+        * @param {string} type
+        * @param {Object} data
+        */
+       _triggerSync: function (type, data) {
+               WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'sync_' + this._tmpHash, {
+                       source: this,
+                       type: type,
+                       data: data
+               });
        }
 });
index cddf4969be56e3b621c22a3053de9e96d5f10303..e2ba490117db415f12398d9ce75c87f1862ed0a6 100755 (executable)
@@ -1,70 +1,62 @@
 // WCF.Combined.min.js -- DO NOT EDIT
 
 // 3rdParty/jquery.js
-(function (window, undefined) { !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(e,t,n){t=t||ae;var r,i=t.createElement("script");if(i.text=e,n)for(r in be)n[r]&&(i[r]=n[r]);t.head.appendChild(i).parentNode.removeChild(i)}function r(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?pe[de.call(e)]||"object":typeof e}function i(e){var t=!!e&&"length"in e&&e.length,n=r(e);return!me(e)&&!xe(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function o(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}function a(e,t,n){return me(t)?we.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?we.grep(e,function(e){return e===t!==n}):"string"!=typeof t?we.grep(e,function(e){return fe.call(t,e)>-1!==n}):we.filter(t,e,n)}function s(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function u(e){var t={};return we.each(e.match(Le)||[],function(e,n){t[n]=!0}),t}function l(e){return e}function c(e){throw e}function f(e,t,n,r){var i;try{e&&me(i=e.promise)?i.call(e).done(t).fail(n):e&&me(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}function p(){ae.removeEventListener("DOMContentLoaded",p),e.removeEventListener("load",p),we.ready()}function d(e,t){return t.toUpperCase()}function h(e){return e.replace(Me,"ms-").replace(Re,d)}function g(){this.expando=we.expando+g.uid++}function v(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Be.test(e)?JSON.parse(e):e)}function y(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Fe,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=v(n)}catch(e){}$e.set(e,t,n)}else n=void 0;return n}function m(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return we.css(e,t,"")},u=s(),l=n&&n[3]||(we.cssNumber[t]?"":"px"),c=(we.cssNumber[t]||"px"!==l&&+u)&&ze.exec(we.css(e,t));if(c&&c[3]!==l){for(u/=2,l=l||c[3],c=+u||1;a--;)we.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,we.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function x(e){var t,n=e.ownerDocument,r=e.nodeName,i=Ge[r];return i||(t=n.body.appendChild(n.createElement(r)),i=we.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),Ge[r]=i,i)}function b(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)r=e[o],r.style&&(n=r.style.display,t?("none"===n&&(i[o]=We.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&Ue(r)&&(i[o]=x(r))):"none"!==n&&(i[o]="none",We.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}function w(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&o(e,t)?we.merge([e],n):n}function T(e,t){for(var n=0,r=e.length;n<r;n++)We.set(e[n],"globalEval",!t||We.get(t[n],"globalEval"))}function C(e,t,n,i,o){for(var a,s,u,l,c,f,p=t.createDocumentFragment(),d=[],h=0,g=e.length;h<g;h++)if((a=e[h])||0===a)if("object"===r(a))we.merge(d,a.nodeType?[a]:a);else if(Ze.test(a)){for(s=s||p.appendChild(t.createElement("div")),u=(Qe.exec(a)||["",""])[1].toLowerCase(),l=Ke[u]||Ke._default,s.innerHTML=l[1]+we.htmlPrefilter(a)+l[2],f=l[0];f--;)s=s.lastChild;we.merge(d,s.childNodes),s=p.firstChild,s.textContent=""}else d.push(t.createTextNode(a));for(p.textContent="",h=0;a=d[h++];)if(i&&we.inArray(a,i)>-1)o&&o.push(a);else if(c=we.contains(a.ownerDocument,a),s=w(p.appendChild(a),"script"),c&&T(s),n)for(f=0;a=s[f++];)Je.test(a.type||"")&&n.push(a);return p}function E(){return!0}function k(){return!1}function S(){try{return ae.activeElement}catch(e){}}function D(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)D(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=k;else if(!i)return e;return 1===o&&(a=i,i=function(e){return we().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=we.guid++)),e.each(function(){we.event.add(this,t,i,r,n)})}function N(e,t){return o(e,"table")&&o(11!==t.nodeType?t:t.firstChild,"tr")?we(e).children("tbody")[0]||e:e}function A(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function j(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function q(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(We.hasData(e)&&(o=We.access(e),a=We.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)we.event.add(t,i,l[i][n])}$e.hasData(e)&&(s=$e.access(e),u=we.extend({},s),$e.set(t,u))}}function L(e,t){var n=t.nodeName.toLowerCase();"input"===n&&Ye.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function H(e,t,r,i){t=le.apply([],t);var o,a,s,u,l,c,f=0,p=e.length,d=p-1,h=t[0],g=me(h);if(g||p>1&&"string"==typeof h&&!ye.checkClone&&at.test(h))return e.each(function(n){var o=e.eq(n);g&&(t[0]=h.call(this,n,o.html())),H(o,t,r,i)});if(p&&(o=C(t,e[0].ownerDocument,!1,e,i),a=o.firstChild,1===o.childNodes.length&&(o=a),a||i)){for(s=we.map(w(o,"script"),A),u=s.length;f<p;f++)l=o,f!==d&&(l=we.clone(l,!0,!0),u&&we.merge(s,w(l,"script"))),r.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,we.map(s,j),f=0;f<u;f++)l=s[f],Je.test(l.type||"")&&!We.access(l,"globalEval")&&we.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?we._evalUrl&&we._evalUrl(l.src):n(l.textContent.replace(st,""),c,l))}return e}function O(e,t,n){for(var r,i=t?we.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||we.cleanData(w(r)),r.parentNode&&(n&&we.contains(r.ownerDocument,r)&&T(w(r,"script")),r.parentNode.removeChild(r));return e}function P(e,t,n){var r,i,o,a,s=e.style;return n=n||lt(e),n&&(a=n.getPropertyValue(t)||n[t],""!==a||we.contains(e.ownerDocument,e)||(a=we.style(e,t)),!ye.pixelBoxStyles()&&ut.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function M(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function R(e){if(e in vt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=gt.length;n--;)if((e=gt[n]+t)in vt)return e}function I(e){var t=we.cssProps[e];return t||(t=we.cssProps[e]=R(e)||e),t}function W(e,t,n){var r=ze.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function $(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=we.css(e,n+Xe[a],!0,i)),r?("content"===n&&(u-=we.css(e,"padding"+Xe[a],!0,i)),"margin"!==n&&(u-=we.css(e,"border"+Xe[a]+"Width",!0,i))):(u+=we.css(e,"padding"+Xe[a],!0,i),"padding"!==n?u+=we.css(e,"border"+Xe[a]+"Width",!0,i):s+=we.css(e,"border"+Xe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function B(e,t,n){var r=lt(e),i=P(e,t,r),o="border-box"===we.css(e,"boxSizing",!1,r),a=o;if(ut.test(i)){if(!n)return i;i="auto"}return a=a&&(ye.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===we.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+$(e,t,n||(o?"border":"content"),a,r,i)+"px"}function F(e,t,n,r,i){return new F.prototype.init(e,t,n,r,i)}function _(){mt&&(!1===ae.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(_):e.setTimeout(_,we.fx.interval),we.fx.tick())}function z(){return e.setTimeout(function(){yt=void 0}),yt=Date.now()}function X(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)n=Xe[r],i["margin"+n]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function U(e,t,n){for(var r,i=(Y.tweeners[t]||[]).concat(Y.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function V(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&Ue(e),v=We.get(e,"fxshow");n.queue||(a=we._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,we.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],xt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||we.style(e,r)}if((u=!we.isEmptyObject(t))||!we.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],l=v&&v.display,null==l&&(l=We.get(e,"display")),c=we.css(e,"display"),"none"===c&&(l?c=l:(b([e],!0),l=e.style.display||l,c=we.css(e,"display"),b([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===we.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(v?"hidden"in v&&(g=v.hidden):v=We.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&b([e],!0),p.done(function(){g||b([e]),We.remove(e,"fxshow");for(r in d)we.style(e,r,d[r])})),u=U(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}}function G(e,t){var n,r,i,o,a;for(n in e)if(r=h(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=we.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function Y(e,t,n){var r,i,o=0,a=Y.prefilters.length,s=we.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=yt||z(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(u||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:we.extend({},t),opts:we.extend(!0,{specialEasing:{},easing:we.easing._default},n),originalProperties:t,originalOptions:n,startTime:yt||z(),duration:n.duration,tweens:[],createTween:function(t,n){var r=we.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(G(c,l.opts.specialEasing);o<a;o++)if(r=Y.prefilters[o].call(l,e,c,l.opts))return me(r.stop)&&(we._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return we.map(c,U,l),me(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),we.fx.timer(we.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}function Q(e){return(e.match(Le)||[]).join(" ")}function J(e){return e.getAttribute&&e.getAttribute("class")||""}function K(e){return Array.isArray(e)?e:"string"==typeof e?e.match(Le)||[]:[]}function Z(e,t,n,i){var o;if(Array.isArray(t))we.each(t,function(t,r){n||qt.test(e)?i(e,r):Z(e+"["+("object"==typeof r&&null!=r?t:"")+"]",r,n,i)});else if(n||"object"!==r(t))i(e,t);else for(o in t)Z(e+"["+o+"]",t[o],n,i)}function ee(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(Le)||[];if(me(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function te(e,t,n,r){function i(s){var u;return o[s]=!0,we.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===_t;return i(t.dataTypes[0])||!o["*"]&&i("*")}function ne(e,t){var n,r,i=we.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&we.extend(!0,e,r),e}function re(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function ie(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if(s=i.split(" "),s[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}var oe=[],ae=e.document,se=Object.getPrototypeOf,ue=oe.slice,le=oe.concat,ce=oe.push,fe=oe.indexOf,pe={},de=pe.toString,he=pe.hasOwnProperty,ge=he.toString,ve=ge.call(Object),ye={},me=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},xe=function(e){return null!=e&&e===e.window},be={type:!0,src:!0,noModule:!0},we=function(e,t){return new we.fn.init(e,t)},Te=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;we.fn=we.prototype={jquery:"3.3.1",constructor:we,length:0,toArray:function(){return ue.call(this)},get:function(e){return null==e?ue.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=we.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return we.each(this,e)},map:function(e){return this.pushStack(we.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ue.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ce,sort:oe.sort,splice:oe.splice},we.extend=we.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||me(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(we.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&we.isPlainObject(n)?n:{},a[t]=we.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},we.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==de.call(e))&&(!(t=se(e))||"function"==typeof(n=he.call(t,"constructor")&&t.constructor)&&ge.call(n)===ve)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){n(e)},each:function(e,t){var n,r=0;if(i(e))for(n=e.length;r<n&&!1!==t.call(e[r],r,e[r]);r++);else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(Te,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(i(Object(e))?we.merge(n,"string"==typeof e?[e]:e):ce.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:fe.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,o,a=0,s=[];if(i(e))for(r=e.length;a<r;a++)null!=(o=t(e[a],a,n))&&s.push(o);else for(a in e)null!=(o=t(e[a],a,n))&&s.push(o);return le.apply([],s)},guid:1,support:ye}),"function"==typeof Symbol&&(we.fn[Symbol.iterator]=oe[Symbol.iterator]),we.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){pe["[object "+t+"]"]=t.toLowerCase()});var Ce=function(e){function t(e,t,n,r){var i,o,a,s,u,c,p,d=t&&t.ownerDocument,h=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==h&&9!==h&&11!==h)return n;if(!r&&((t?t.ownerDocument||t:W)!==q&&j(t),t=t||q,H)){if(11!==h&&(u=ge.exec(e)))if(i=u[1]){if(9===h){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(d&&(a=d.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(u[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=u[3])&&b.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(b.qsa&&!z[e+" "]&&(!O||!O.test(e))){if(1!==h)d=t,p=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(xe,be):t.setAttribute("id",s=I),c=E(e),o=c.length;o--;)c[o]="#"+s+" "+f(c[o]);p=c.join(","),d=ve.test(e)&&l(t.parentNode)||t}if(p)try{return Q.apply(n,d.querySelectorAll(p)),n}catch(e){}finally{s===I&&t.removeAttribute("id")}}}return S(e.replace(oe,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>w.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[I]=!0,e}function i(e){var t=q.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)w.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&Te(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function u(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function l(e){return e&&void 0!==e.getElementsByTagName&&e}function c(){}function f(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=B++;return t.first?function(t,n,i){for(;t=t[r];)if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[$,s];if(u){for(;t=t[r];)if((1===t.nodeType||a)&&e(t,n,u))return!0}else for(;t=t[r];)if(1===t.nodeType||a)if(f=t[I]||(t[I]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===$&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function d(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function h(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function g(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function v(e,t,n,i,o,a){return i&&!i[I]&&(i=v(i)),o&&!o[I]&&(o=v(o,a)),r(function(r,a,s,u){var l,c,f,p=[],d=[],v=a.length,y=r||h(t||"*",s.nodeType?[s]:s,[]),m=!e||!r&&t?y:g(y,p,e,s,u),x=n?o||(r?e:v||i)?[]:a:m;if(n&&n(m,x,s,u),i)for(l=g(x,d),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[d[c]]=!(m[d[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(m[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?K(r,f):p[c])>-1&&(r[l]=!(a[l]=f))}}else x=g(x===a?x.splice(v,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function y(e){for(var t,n,r,i=e.length,o=w.relative[e[0].type],a=o||w.relative[" "],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return K(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==D)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=w.relative[e[s].type])c=[p(d(c),n)];else{if(n=w.filter[e[s].type].apply(null,e[s].matches),n[I]){for(r=++s;r<i&&!w.relative[e[r].type];r++);return v(s>1&&d(c),s>1&&f(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(oe,"$1"),n,s<r&&y(e.slice(s,r)),r<i&&y(e=e.slice(r)),r<i&&f(e))}c.push(n)}return d(c)}function m(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,p,d=0,h="0",v=r&&[],y=[],m=D,x=r||o&&w.find.TAG("*",l),b=$+=null==m?1:Math.random()||.1,T=x.length;for(l&&(D=a===q||a||l);h!==T&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===q||(j(c),s=!H);p=e[f++];)if(p(c,a||q,s)){u.push(c);break}l&&($=b)}i&&((c=!p&&c)&&d--,r&&v.push(c))}if(d+=h,i&&h!==d){for(f=0;p=n[f++];)p(v,y,a,s);if(r){if(d>0)for(;h--;)v[h]||y[h]||(y[h]=G.call(u));y=g(y)}Q.apply(u,y),l&&!r&&y.length>0&&d+n.length>1&&t.uniqueSort(u)}return l&&($=b,D=m),v};return i?r(a):a}var x,b,w,T,C,E,k,S,D,N,A,j,q,L,H,O,P,M,R,I="sizzle"+1*new Date,W=e.document,$=0,B=0,F=n(),_=n(),z=n(),X=function(e,t){return e===t&&(A=!0),0},U={}.hasOwnProperty,V=[],G=V.pop,Y=V.push,Q=V.push,J=V.slice,K=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},Z="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",ee="[\\x20\\t\\r\\n\\f]",te="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",ne="\\["+ee+"*("+te+")(?:"+ee+"*([*^$|!~]?=)"+ee+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+te+"))|)"+ee+"*\\]",re=":("+te+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+ne+")*)|.*)\\)|)",ie=new RegExp(ee+"+","g"),oe=new RegExp("^"+ee+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ee+"+$","g"),ae=new RegExp("^"+ee+"*,"+ee+"*"),se=new RegExp("^"+ee+"*([>+~]|"+ee+")"+ee+"*"),ue=new RegExp("="+ee+"*([^\\]'\"]*?)"+ee+"*\\]","g"),le=new RegExp(re),ce=new RegExp("^"+te+"$"),fe={ID:new RegExp("^#("+te+")"),CLASS:new RegExp("^\\.("+te+")"),TAG:new RegExp("^("+te+"|[*])"),ATTR:new RegExp("^"+ne),PSEUDO:new RegExp("^"+re),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ee+"*(even|odd|(([+-]|)(\\d*)n|)"+ee+"*(?:([+-]|)"+ee+"*(\\d+)|))"+ee+"*\\)|)","i"),bool:new RegExp("^(?:"+Z+")$","i"),needsContext:new RegExp("^"+ee+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ee+"*((?:-\\d)?\\d*)"+ee+"*\\)|)(?=[^-]|$)","i")},pe=/^(?:input|select|textarea|button)$/i,de=/^h\d$/i,he=/^[^{]+\{\s*\[native \w/,ge=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,ye=new RegExp("\\\\([\\da-f]{1,6}"+ee+"?|("+ee+")|.)","ig"),me=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},xe=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,be=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},we=function(){j()},Te=p(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{Q.apply(V=J.call(W.childNodes),W.childNodes),V[W.childNodes.length].nodeType}catch(e){Q={apply:V.length?function(e,t){Y.apply(e,J.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}b=t.support={},C=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},j=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:W;return r!==q&&9===r.nodeType&&r.documentElement?(q=r,L=q.documentElement,H=!C(q),W!==q&&(n=q.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",we,!1):n.attachEvent&&n.attachEvent("onunload",we)),b.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),b.getElementsByTagName=i(function(e){return e.appendChild(q.createComment("")),!e.getElementsByTagName("*").length}),b.getElementsByClassName=he.test(q.getElementsByClassName),b.getById=i(function(e){return L.appendChild(e).id=I,!q.getElementsByName||!q.getElementsByName(I).length}),b.getById?(w.filter.ID=function(e){var t=e.replace(ye,me);return function(e){return e.getAttribute("id")===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&H){var n=t.getElementById(e);return n?[n]:[]}}):(w.filter.ID=function(e){var t=e.replace(ye,me);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&H){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),w.find.TAG=b.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):b.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},w.find.CLASS=b.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&H)return t.getElementsByClassName(e)},P=[],O=[],(b.qsa=he.test(q.querySelectorAll))&&(i(function(e){L.appendChild(e).innerHTML="<a id='"+I+"'></a><select id='"+I+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&O.push("[*^$]="+ee+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||O.push("\\["+ee+"*(?:value|"+Z+")"),e.querySelectorAll("[id~="+I+"-]").length||O.push("~="),e.querySelectorAll(":checked").length||O.push(":checked"),e.querySelectorAll("a#"+I+"+*").length||O.push(".#.+[+~]")}),i(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=q.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&O.push("name"+ee+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&O.push(":enabled",":disabled"),L.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&O.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),O.push(",.*:")})),(b.matchesSelector=he.test(M=L.matches||L.webkitMatchesSelector||L.mozMatchesSelector||L.oMatchesSelector||L.msMatchesSelector))&&i(function(e){b.disconnectedMatch=M.call(e,"*"),M.call(e,"[s!='']:x"),P.push("!=",re)}),O=O.length&&new RegExp(O.join("|")),P=P.length&&new RegExp(P.join("|")),t=he.test(L.compareDocumentPosition),R=t||he.test(L.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},X=t?function(e,t){if(e===t)return A=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!b.sortDetached&&t.compareDocumentPosition(e)===n?e===q||e.ownerDocument===W&&R(W,e)?-1:t===q||t.ownerDocument===W&&R(W,t)?1:N?K(N,e)-K(N,t):0:4&n?-1:1)}:function(e,t){if(e===t)return A=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===q?-1:t===q?1:i?-1:o?1:N?K(N,e)-K(N,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===W?-1:u[r]===W?1:0},q):q},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==q&&j(e),n=n.replace(ue,"='$1']"),b.matchesSelector&&H&&!z[n+" "]&&(!P||!P.test(n))&&(!O||!O.test(n)))try{var r=M.call(e,n);if(r||b.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,q,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==q&&j(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==q&&j(e);var n=w.attrHandle[t.toLowerCase()],r=n&&U.call(w.attrHandle,t.toLowerCase())?n(e,t,!H):void 0;return void 0!==r?r:b.attributes||!H?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+"").replace(xe,be)},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(A=!b.detectDuplicates,N=!b.sortStable&&e.slice(0),e.sort(X),A){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return N=null,e},T=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=T(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=T(t);return n},w=t.selectors={cacheLength:50,createPseudo:r,match:fe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ye,me),e[3]=(e[3]||e[4]||e[5]||"").replace(ye,me),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return fe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&le.test(n)&&(t=E(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ye,me).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=F[e+" "];return t||(t=new RegExp("(^|"+ee+")"+e+"("+ee+"|$)"))&&F(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ie," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",v=t.parentNode,y=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(v){if(o){for(;g;){for(p=t;p=p[g];)if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?v.firstChild:v.lastChild],a&&m){for(p=v,f=p[I]||(p[I]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],d=l[0]===$&&l[1],x=d&&l[2],p=d&&v.childNodes[d];p=++d&&p&&p[g]||(x=d=0)||h.pop();)if(1===p.nodeType&&++x&&p===t){c[e]=[$,d,x];break}}else if(m&&(p=t,f=p[I]||(p[I]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],d=l[0]===$&&l[1],x=d),!1===x)for(;(p=++d&&p&&p[g]||(x=d=0)||h.pop())&&((s?p.nodeName.toLowerCase()!==y:1!==p.nodeType)||!++x||(m&&(f=p[I]||(p[I]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),c[e]=[$,x]),p!==t)););return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=w.pseudos[e]||w.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[I]?o(n):o.length>1?(i=[e,e,"",n],w.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=K(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(oe,"$1"));return i[I]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(ye,me),function(t){return(t.textContent||t.innerText||T(t)).indexOf(e)>-1}}),lang:r(function(e){return ce.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(ye,me).toLowerCase(),function(t){var n;do{if(n=H?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===L},focus:function(e){return e===q.activeElement&&(!q.hasFocus||q.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:s(!1),disabled:s(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,
-!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!w.pseudos.empty(e)},header:function(e){return de.test(e.nodeName)},input:function(e){return pe.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:u(function(){return[0]}),last:u(function(e,t){return[t-1]}),eq:u(function(e,t,n){return[n<0?n+t:n]}),even:u(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:u(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:u(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:u(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},w.pseudos.nth=w.pseudos.eq;for(x in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})w.pseudos[x]=function(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}(x);for(x in{submit:!0,reset:!0})w.pseudos[x]=function(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}(x);return c.prototype=w.filters=w.pseudos,w.setFilters=new c,E=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=_[e+" "];if(c)return n?0:c.slice(0);for(s=e,u=[],l=w.preFilter;s;){r&&!(i=ae.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=se.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(oe," ")}),s=s.slice(r.length));for(a in w.filter)!(i=fe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):_(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=z[e+" "];if(!o){for(t||(t=E(e)),n=t.length;n--;)o=y(t[n]),o[I]?r.push(o):i.push(o);o=z(e,m(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,c="function"==typeof e&&e,p=!r&&E(e=c.selector||e);if(n=n||[],1===p.length){if(o=p[0]=p[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&H&&w.relative[o[1].type]){if(!(t=(w.find.ID(a.matches[0].replace(ye,me),t)||[])[0]))return n;c&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=fe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!w.relative[s=a.type]);)if((u=w.find[s])&&(r=u(a.matches[0].replace(ye,me),ve.test(o[0].type)&&l(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&f(o)))return Q.apply(n,r),n;break}}return(c||k(e,p))(r,t,!H,n,!t||ve.test(e)&&l(t.parentNode)||t),n},b.sortStable=I.split("").sort(X).join("")===I,b.detectDuplicates=!!A,j(),b.sortDetached=i(function(e){return 1&e.compareDocumentPosition(q.createElement("fieldset"))}),i(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),b.attributes&&i(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(Z,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);we.find=Ce,we.expr=Ce.selectors,we.expr[":"]=we.expr.pseudos,we.uniqueSort=we.unique=Ce.uniqueSort,we.text=Ce.getText,we.isXMLDoc=Ce.isXML,we.contains=Ce.contains,we.escapeSelector=Ce.escape;var Ee=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&we(e).is(n))break;r.push(e)}return r},ke=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Se=we.expr.match.needsContext,De=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;we.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?we.find.matchesSelector(r,e)?[r]:[]:we.find.matches(e,we.grep(t,function(e){return 1===e.nodeType}))},we.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(we(e).filter(function(){for(t=0;t<r;t++)if(we.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)we.find(e,i[t],n);return r>1?we.uniqueSort(n):n},filter:function(e){return this.pushStack(a(this,e||[],!1))},not:function(e){return this.pushStack(a(this,e||[],!0))},is:function(e){return!!a(this,"string"==typeof e&&Se.test(e)?we(e):e||[],!1).length}});var Ne,Ae=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(we.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ne,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:Ae.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof we?t[0]:t,we.merge(this,we.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:ae,!0)),De.test(r[1])&&we.isPlainObject(t))for(r in t)me(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=ae.getElementById(r[2]),i&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):me(e)?void 0!==n.ready?n.ready(e):e(we):we.makeArray(e,this)}).prototype=we.fn,Ne=we(ae);var je=/^(?:parents|prev(?:Until|All))/,qe={children:!0,contents:!0,next:!0,prev:!0};we.fn.extend({has:function(e){var t=we(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(we.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&we(e);if(!Se.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&we.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?we.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?fe.call(we(e),this[0]):fe.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(we.uniqueSort(we.merge(this.get(),we(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),we.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return Ee(e,"parentNode")},parentsUntil:function(e,t,n){return Ee(e,"parentNode",n)},next:function(e){return s(e,"nextSibling")},prev:function(e){return s(e,"previousSibling")},nextAll:function(e){return Ee(e,"nextSibling")},prevAll:function(e){return Ee(e,"previousSibling")},nextUntil:function(e,t,n){return Ee(e,"nextSibling",n)},prevUntil:function(e,t,n){return Ee(e,"previousSibling",n)},siblings:function(e){return ke((e.parentNode||{}).firstChild,e)},children:function(e){return ke(e.firstChild)},contents:function(e){return o(e,"iframe")?e.contentDocument:(o(e,"template")&&(e=e.content||e),we.merge([],e.childNodes))}},function(e,t){we.fn[e]=function(n,r){var i=we.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=we.filter(r,i)),this.length>1&&(qe[e]||we.uniqueSort(i),je.test(e)&&i.reverse()),this.pushStack(i)}});var Le=/[^\x20\t\r\n\f]+/g;we.Callbacks=function(e){e="string"==typeof e?u(e):we.extend({},e);var t,n,i,o,a=[],s=[],l=-1,c=function(){for(o=o||e.once,i=t=!0;s.length;l=-1)for(n=s.shift();++l<a.length;)!1===a[l].apply(n[0],n[1])&&e.stopOnFalse&&(l=a.length,n=!1);e.memory||(n=!1),t=!1,o&&(a=n?[]:"")},f={add:function(){return a&&(n&&!t&&(l=a.length-1,s.push(n)),function t(n){we.each(n,function(n,i){me(i)?e.unique&&f.has(i)||a.push(i):i&&i.length&&"string"!==r(i)&&t(i)})}(arguments),n&&!t&&c()),this},remove:function(){return we.each(arguments,function(e,t){for(var n;(n=we.inArray(t,a,n))>-1;)a.splice(n,1),n<=l&&l--}),this},has:function(e){return e?we.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return o=s=[],a=n="",this},disabled:function(){return!a},lock:function(){return o=s=[],n||t||(a=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!i}};return f},we.extend({Deferred:function(t){var n=[["notify","progress",we.Callbacks("memory"),we.Callbacks("memory"),2],["resolve","done",we.Callbacks("once memory"),we.Callbacks("once memory"),0,"resolved"],["reject","fail",we.Callbacks("once memory"),we.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return we.Deferred(function(t){we.each(n,function(n,r){var i=me(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&me(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){function o(t,n,r,i){return function(){var s=this,u=arguments,f=function(){var e,f;if(!(t<a)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");f=e&&("object"==typeof e||"function"==typeof e)&&e.then,me(f)?i?f.call(e,o(a,n,l,i),o(a,n,c,i)):(a++,f.call(e,o(a,n,l,i),o(a,n,c,i),o(a,n,l,n.notifyWith))):(r!==l&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},p=i?f:function(){try{f()}catch(e){we.Deferred.exceptionHook&&we.Deferred.exceptionHook(e,p.stackTrace),t+1>=a&&(r!==c&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?p():(we.Deferred.getStackHook&&(p.stackTrace=we.Deferred.getStackHook()),e.setTimeout(p))}}var a=0;return we.Deferred(function(e){n[0][3].add(o(0,e,me(i)?i:l,e.notifyWith)),n[1][3].add(o(0,e,me(t)?t:l)),n[2][3].add(o(0,e,me(r)?r:c))}).promise()},promise:function(e){return null!=e?we.extend(e,i):i}},o={};return we.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=ue.call(arguments),o=we.Deferred(),a=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?ue.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(f(e,o.done(a(n)).resolve,o.reject,!t),"pending"===o.state()||me(i[n]&&i[n].then)))return o.then();for(;n--;)f(i[n],a(n),o.reject);return o.promise()}});var He=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;we.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&He.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},we.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=we.Deferred();we.fn.ready=function(e){return Oe.then(e).catch(function(e){we.readyException(e)}),this},we.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--we.readyWait:we.isReady)||(we.isReady=!0,!0!==e&&--we.readyWait>0||Oe.resolveWith(ae,[we]))}}),we.ready.then=Oe.then,"complete"===ae.readyState||"loading"!==ae.readyState&&!ae.documentElement.doScroll?e.setTimeout(we.ready):(ae.addEventListener("DOMContentLoaded",p),e.addEventListener("load",p));var Pe=function(e,t,n,i,o,a,s){var u=0,l=e.length,c=null==n;if("object"===r(n)){o=!0;for(u in n)Pe(e,t,u,n[u],!0,a,s)}else if(void 0!==i&&(o=!0,me(i)||(s=!0),c&&(s?(t.call(e,i),t=null):(c=t,t=function(e,t,n){return c.call(we(e),n)})),t))for(;u<l;u++)t(e[u],n,s?i:i.call(e[u],u,t(e[u],n)));return o?e:c?t.call(e):l?t(e[0],n):a},Me=/^-ms-/,Re=/-([a-z])/g,Ie=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};g.uid=1,g.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Ie(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[h(t)]=n;else for(r in t)i[h(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][h(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){Array.isArray(t)?t=t.map(h):(t=h(t),t=t in r?[t]:t.match(Le)||[]),n=t.length;for(;n--;)delete r[t[n]]}(void 0===t||we.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!we.isEmptyObject(t)}};var We=new g,$e=new g,Be=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Fe=/[A-Z]/g;we.extend({hasData:function(e){return $e.hasData(e)||We.hasData(e)},data:function(e,t,n){return $e.access(e,t,n)},removeData:function(e,t){$e.remove(e,t)},_data:function(e,t,n){return We.access(e,t,n)},_removeData:function(e,t){We.remove(e,t)}}),we.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=$e.get(o),1===o.nodeType&&!We.get(o,"hasDataAttrs"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf("data-")&&(r=h(r.slice(5)),y(o,r,i[r])));We.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){$e.set(this,e)}):Pe(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=$e.get(o,e)))return n;if(void 0!==(n=y(o,e)))return n}else this.each(function(){$e.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){$e.remove(this,e)})}}),we.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=We.get(e,t),n&&(!r||Array.isArray(n)?r=We.access(e,t,we.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=we.queue(e,t),r=n.length,i=n.shift(),o=we._queueHooks(e,t),a=function(){we.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return We.get(e,n)||We.access(e,n,{empty:we.Callbacks("once memory").add(function(){We.remove(e,[t+"queue",n])})})}}),we.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?we.queue(this[0],e):void 0===t?this:this.each(function(){var n=we.queue(this,e,t);we._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&we.dequeue(this,e)})},dequeue:function(e){return this.each(function(){we.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=we.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";a--;)(n=We.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var _e=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ze=new RegExp("^(?:([+-])=|)("+_e+")([a-z%]*)$","i"),Xe=["Top","Right","Bottom","Left"],Ue=function(e,t){return e=t||e,"none"===e.style.display||""===e.style.display&&we.contains(e.ownerDocument,e)&&"none"===we.css(e,"display")},Ve=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},Ge={};we.fn.extend({show:function(){return b(this,!0)},hide:function(){return b(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Ue(this)?we(this).show():we(this).hide()})}});var Ye=/^(?:checkbox|radio)$/i,Qe=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,Je=/^$|^module$|\/(?:java|ecma)script/i,Ke={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};Ke.optgroup=Ke.option,Ke.tbody=Ke.tfoot=Ke.colgroup=Ke.caption=Ke.thead,Ke.th=Ke.td;var Ze=/<|&#?\w+;/;!function(){var e=ae.createDocumentFragment(),t=e.appendChild(ae.createElement("div")),n=ae.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),ye.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="<textarea>x</textarea>",ye.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var et=ae.documentElement,tt=/^key/,nt=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,rt=/^([^.]*)(?:\.(.+)|)/;we.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=We.get(e);if(v)for(n.handler&&(o=n,n=o.handler,i=o.selector),i&&we.find.matchesSelector(et,i),n.guid||(n.guid=we.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(t){return void 0!==we&&we.event.triggered!==t.type?we.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(Le)||[""],l=t.length;l--;)s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d&&(f=we.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=we.event.special[d]||{},c=we.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&we.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||(p=u[d]=[],p.delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),we.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=We.hasData(e)&&We.get(e);if(v&&(u=v.events)){for(t=(t||"").match(Le)||[""],l=t.length;l--;)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){for(f=we.event.special[d]||{},d=(r?f.delegateType:f.bindType)||d,p=u[d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||we.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)we.event.remove(e,d+t[l],n,r,!0);we.isEmptyObject(u)&&We.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=we.event.fix(e),u=new Array(arguments.length),l=(We.get(this,"events")||{})[s.type]||[],c=we.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){for(a=we.event.handlers.call(this,s,l),t=0;(i=a[t++])&&!s.isPropagationStopped();)for(s.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!s.isImmediatePropagationStopped();)s.rnamespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((we.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)r=t[n],i=r.selector+" ",void 0===a[i]&&(a[i]=r.needsContext?we(i,this).index(l)>-1:we.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(we.Event.prototype,e,{enumerable:!0,configurable:!0,get:me(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[we.expando]?e:new we.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==S()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===S()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&o(this,"input"))return this.click(),!1},_default:function(e){return o(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},we.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},we.Event=function(e,t){if(!(this instanceof we.Event))return new we.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?E:k,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&we.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[we.expando]=!0},we.Event.prototype={constructor:we.Event,isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=E,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=E,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=E,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},we.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&tt.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&nt.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},we.event.addProp),we.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){we.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||we.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),we.fn.extend({on:function(e,t,n,r){return D(this,e,t,n,r)},one:function(e,t,n,r){return D(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,we(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=k),this.each(function(){we.event.remove(this,e,n,t)})}});var it=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,ot=/<script|<style|<link/i,at=/checked\s*(?:[^=]|=\s*.checked.)/i,st=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;we.extend({htmlPrefilter:function(e){return e.replace(it,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=we.contains(e.ownerDocument,e);if(!(ye.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||we.isXMLDoc(e)))for(a=w(s),o=w(e),r=0,i=o.length;r<i;r++)L(o[r],a[r]);if(t)if(n)for(o=o||w(e),a=a||w(s),r=0,i=o.length;r<i;r++)q(o[r],a[r]);else q(e,s);return a=w(s,"script"),a.length>0&&T(a,!u&&w(e,"script")),s},cleanData:function(e){for(var t,n,r,i=we.event.special,o=0;void 0!==(n=e[o]);o++)if(Ie(n)){if(t=n[We.expando]){if(t.events)for(r in t.events)i[r]?we.event.remove(n,r):we.removeEvent(n,r,t.handle);n[We.expando]=void 0}n[$e.expando]&&(n[$e.expando]=void 0)}}}),we.fn.extend({detach:function(e){return O(this,e,!0)},remove:function(e){return O(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?we.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return H(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){N(this,e).appendChild(e)}})},prepend:function(){return H(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=N(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return H(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return H(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(we.cleanData(w(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return we.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ot.test(e)&&!Ke[(Qe.exec(e)||["",""])[1].toLowerCase()]){e=we.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(we.cleanData(w(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return H(this,arguments,function(t){var n=this.parentNode;we.inArray(this,e)<0&&(we.cleanData(w(this)),n&&n.replaceChild(t,this))},e)}}),we.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){we.fn[e]=function(e){for(var n,r=[],i=we(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),we(i[a])[t](n),ce.apply(r,n.get());return this.pushStack(r)}});var ut=new RegExp("^("+_e+")(?!px)[a-z%]+$","i"),lt=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},ct=new RegExp(Xe.join("|"),"i");!function(){function t(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",et.appendChild(u).appendChild(l);var t=e.getComputedStyle(l);r="1%"!==t.top,s=12===n(t.marginLeft),l.style.right="60%",a=36===n(t.right),i=36===n(t.width),l.style.position="absolute",o=36===l.offsetWidth||"absolute",et.removeChild(u),l=null}}function n(e){return Math.round(parseFloat(e))}var r,i,o,a,s,u=ae.createElement("div"),l=ae.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",ye.clearCloneStyle="content-box"===l.style.backgroundClip,we.extend(ye,{boxSizingReliable:function(){return t(),i},pixelBoxStyles:function(){return t(),a},pixelPosition:function(){return t(),r},reliableMarginLeft:function(){return t(),s},scrollboxSize:function(){return t(),o}}))}();var ft=/^(none|table(?!-c[ea]).+)/,pt=/^--/,dt={position:"absolute",visibility:"hidden",display:"block"},ht={letterSpacing:"0",fontWeight:"400"},gt=["Webkit","Moz","ms"],vt=ae.createElement("div").style;we.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=P(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=h(t),u=pt.test(t),l=e.style;if(u||(t=I(s)),a=we.cssHooks[t]||we.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];o=typeof n,"string"===o&&(i=ze.exec(n))&&i[1]&&(n=m(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(we.cssNumber[s]?"":"px")),ye.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=h(t);return pt.test(t)||(t=I(s)),a=we.cssHooks[t]||we.cssHooks[s],a&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=P(e,t,r)),"normal"===i&&t in ht&&(i=ht[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),we.each(["height","width"],function(e,t){we.cssHooks[t]={get:function(e,n,r){if(n)return!ft.test(we.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?B(e,t,r):Ve(e,dt,function(){return B(e,t,r)})},set:function(e,n,r){var i,o=lt(e),a="border-box"===we.css(e,"boxSizing",!1,o),s=r&&$(e,t,r,a,o);return a&&ye.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-$(e,t,"border",!1,o)-.5)),s&&(i=ze.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=we.css(e,t)),W(e,n,s)}}}),we.cssHooks.marginLeft=M(ye.reliableMarginLeft,function(e,t){if(t)return(parseFloat(P(e,"marginLeft"))||e.getBoundingClientRect().left-Ve(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),we.each({margin:"",padding:"",border:"Width"},function(e,t){we.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+Xe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(we.cssHooks[e+t].set=W)}),we.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=lt(e),i=t.length;a<i;a++)o[t[a]]=we.css(e,t[a],!1,r);return o}return void 0!==n?we.style(e,t,n):we.css(e,t)},e,t,arguments.length>1)}}),we.Tween=F,F.prototype={constructor:F,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||we.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(we.cssNumber[n]?"":"px")},cur:function(){var e=F.propHooks[this.prop];return e&&e.get?e.get(this):F.propHooks._default.get(this)},run:function(e){var t,n=F.propHooks[this.prop];return this.options.duration?this.pos=t=we.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):F.propHooks._default.set(this),this}},F.prototype.init.prototype=F.prototype,F.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=we.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){we.fx.step[e.prop]?we.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[we.cssProps[e.prop]]&&!we.cssHooks[e.prop]?e.elem[e.prop]=e.now:we.style(e.elem,e.prop,e.now+e.unit)}}},F.propHooks.scrollTop=F.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},we.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},we.fx=F.prototype.init,we.fx.step={};var yt,mt,xt=/^(?:toggle|show|hide)$/,bt=/queueHooks$/;we.Animation=we.extend(Y,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return m(n.elem,e,ze.exec(t),n),n}]},tweener:function(e,t){me(e)?(t=e,e=["*"]):e=e.match(Le);for(var n,r=0,i=e.length;r<i;r++)n=e[r],Y.tweeners[n]=Y.tweeners[n]||[],Y.tweeners[n].unshift(t)},prefilters:[V],prefilter:function(e,t){t?Y.prefilters.unshift(e):Y.prefilters.push(e)}}),we.speed=function(e,t,n){var r=e&&"object"==typeof e?we.extend({},e):{complete:n||!n&&t||me(e)&&e,duration:e,easing:n&&t||t&&!me(t)&&t};return we.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in we.fx.speeds?r.duration=we.fx.speeds[r.duration]:r.duration=we.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){me(r.old)&&r.old.call(this),r.queue&&we.dequeue(this,r.queue)},r},we.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Ue).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=we.isEmptyObject(e),o=we.speed(t,n,r),a=function(){var t=Y(this,we.extend({},e),o);(i||We.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=we.timers,a=We.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&bt.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||we.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),
-this.each(function(){var t,n=We.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=we.timers,a=r?r.length:0;for(n.finish=!0,we.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),we.each(["toggle","show","hide"],function(e,t){var n=we.fn[t];we.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(X(t,!0),e,r,i)}}),we.each({slideDown:X("show"),slideUp:X("hide"),slideToggle:X("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){we.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),we.timers=[],we.fx.tick=function(){var e,t=0,n=we.timers;for(yt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||we.fx.stop(),yt=void 0},we.fx.timer=function(e){we.timers.push(e),we.fx.start()},we.fx.interval=13,we.fx.start=function(){mt||(mt=!0,_())},we.fx.stop=function(){mt=null},we.fx.speeds={slow:600,fast:200,_default:400},we.fn.delay=function(t,n){return t=we.fx?we.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=ae.createElement("input"),t=ae.createElement("select"),n=t.appendChild(ae.createElement("option"));e.type="checkbox",ye.checkOn=""!==e.value,ye.optSelected=n.selected,e=ae.createElement("input"),e.value="t",e.type="radio",ye.radioValue="t"===e.value}();var wt,Tt=we.expr.attrHandle;we.fn.extend({attr:function(e,t){return Pe(this,we.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){we.removeAttr(this,e)})}}),we.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?we.prop(e,t,n):(1===o&&we.isXMLDoc(e)||(i=we.attrHooks[t.toLowerCase()]||(we.expr.match.bool.test(t)?wt:void 0)),void 0!==n?null===n?void we.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=we.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!ye.radioValue&&"radio"===t&&o(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(Le);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),wt={set:function(e,t,n){return!1===t?we.removeAttr(e,n):e.setAttribute(n,n),n}},we.each(we.expr.match.bool.source.match(/\w+/g),function(e,t){var n=Tt[t]||we.find.attr;Tt[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=Tt[a],Tt[a]=i,i=null!=n(e,t,r)?a:null,Tt[a]=o),i}});var Ct=/^(?:input|select|textarea|button)$/i,Et=/^(?:a|area)$/i;we.fn.extend({prop:function(e,t){return Pe(this,we.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[we.propFix[e]||e]})}}),we.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&we.isXMLDoc(e)||(t=we.propFix[t]||t,i=we.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=we.find.attr(e,"tabindex");return t?parseInt(t,10):Ct.test(e.nodeName)||Et.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),ye.optSelected||(we.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),we.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){we.propFix[this.toLowerCase()]=this}),we.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(me(e))return this.each(function(t){we(this).addClass(e.call(this,t,J(this)))});if(t=K(e),t.length)for(;n=this[u++];)if(i=J(n),r=1===n.nodeType&&" "+Q(i)+" "){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");s=Q(r),i!==s&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(me(e))return this.each(function(t){we(this).removeClass(e.call(this,t,J(this)))});if(!arguments.length)return this.attr("class","");if(t=K(e),t.length)for(;n=this[u++];)if(i=J(n),r=1===n.nodeType&&" "+Q(i)+" "){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");s=Q(r),i!==s&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):me(e)?this.each(function(n){we(this).toggleClass(e.call(this,n,J(this),t),t)}):this.each(function(){var t,i,o,a;if(r)for(i=0,o=we(this),a=K(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||(t=J(this),t&&We.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":We.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+Q(J(n))+" ").indexOf(t)>-1)return!0;return!1}});var kt=/\r/g;we.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=me(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,we(this).val()):e,null==i?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=we.map(i,function(e){return null==e?"":e+""})),(t=we.valHooks[this.type]||we.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=we.valHooks[i.type]||we.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"==typeof n?n.replace(kt,""):null==n?"":n)}}}),we.extend({valHooks:{option:{get:function(e){var t=we.find.attr(e,"value");return null!=t?t:Q(we.text(e))}},select:{get:function(e){var t,n,r,i=e.options,a=e.selectedIndex,s="select-one"===e.type,u=s?null:[],l=s?a+1:i.length;for(r=a<0?l:s?a:0;r<l;r++)if(n=i[r],(n.selected||r===a)&&!n.disabled&&(!n.parentNode.disabled||!o(n.parentNode,"optgroup"))){if(t=we(n).val(),s)return t;u.push(t)}return u},set:function(e,t){for(var n,r,i=e.options,o=we.makeArray(t),a=i.length;a--;)r=i[a],(r.selected=we.inArray(we.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),we.each(["radio","checkbox"],function(){we.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=we.inArray(we(e).val(),t)>-1}},ye.checkOn||(we.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),ye.focusin="onfocusin"in e;var St=/^(?:focusinfocus|focusoutblur)$/,Dt=function(e){e.stopPropagation()};we.extend(we.event,{trigger:function(t,n,r,i){var o,a,s,u,l,c,f,p,d=[r||ae],h=he.call(t,"type")?t.type:t,g=he.call(t,"namespace")?t.namespace.split("."):[];if(a=p=s=r=r||ae,3!==r.nodeType&&8!==r.nodeType&&!St.test(h+we.event.triggered)&&(h.indexOf(".")>-1&&(g=h.split("."),h=g.shift(),g.sort()),l=h.indexOf(":")<0&&"on"+h,t=t[we.expando]?t:new we.Event(h,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:we.makeArray(n,[t]),f=we.event.special[h]||{},i||!f.trigger||!1!==f.trigger.apply(r,n))){if(!i&&!f.noBubble&&!xe(r)){for(u=f.delegateType||h,St.test(u+h)||(a=a.parentNode);a;a=a.parentNode)d.push(a),s=a;s===(r.ownerDocument||ae)&&d.push(s.defaultView||s.parentWindow||e)}for(o=0;(a=d[o++])&&!t.isPropagationStopped();)p=a,t.type=o>1?u:f.bindType||h,c=(We.get(a,"events")||{})[t.type]&&We.get(a,"handle"),c&&c.apply(a,n),(c=l&&a[l])&&c.apply&&Ie(a)&&(t.result=c.apply(a,n),!1===t.result&&t.preventDefault());return t.type=h,i||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(d.pop(),n)||!Ie(r)||l&&me(r[h])&&!xe(r)&&(s=r[l],s&&(r[l]=null),we.event.triggered=h,t.isPropagationStopped()&&p.addEventListener(h,Dt),r[h](),t.isPropagationStopped()&&p.removeEventListener(h,Dt),we.event.triggered=void 0,s&&(r[l]=s)),t.result}},simulate:function(e,t,n){var r=we.extend(new we.Event,n,{type:e,isSimulated:!0});we.event.trigger(r,null,t)}}),we.fn.extend({trigger:function(e,t){return this.each(function(){we.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return we.event.trigger(e,t,n,!0)}}),ye.focusin||we.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){we.event.simulate(t,e.target,we.event.fix(e))};we.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=We.access(r,t);i||r.addEventListener(e,n,!0),We.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=We.access(r,t)-1;i?We.access(r,t,i):(r.removeEventListener(e,n,!0),We.remove(r,t))}}});var Nt=e.location,At=Date.now(),jt=/\?/;we.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||we.error("Invalid XML: "+t),n};var qt=/\[\]$/,Lt=/\r?\n/g,Ht=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;we.param=function(e,t){var n,r=[],i=function(e,t){var n=me(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!we.isPlainObject(e))we.each(e,function(){i(this.name,this.value)});else for(n in e)Z(n,e[n],t,i);return r.join("&")},we.fn.extend({serialize:function(){return we.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=we.prop(this,"elements");return e?we.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!we(this).is(":disabled")&&Ot.test(this.nodeName)&&!Ht.test(e)&&(this.checked||!Ye.test(e))}).map(function(e,t){var n=we(this).val();return null==n?null:Array.isArray(n)?we.map(n,function(e){return{name:t.name,value:e.replace(Lt,"\r\n")}}):{name:t.name,value:n.replace(Lt,"\r\n")}}).get()}});var Pt=/%20/g,Mt=/#.*$/,Rt=/([?&])_=[^&]*/,It=/^(.*?):[ \t]*([^\r\n]*)$/gm,Wt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,$t=/^(?:GET|HEAD)$/,Bt=/^\/\//,Ft={},_t={},zt="*/".concat("*"),Xt=ae.createElement("a");Xt.href=Nt.href,we.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Nt.href,type:"GET",isLocal:Wt.test(Nt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":we.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?ne(ne(e,we.ajaxSettings),t):ne(we.ajaxSettings,e)},ajaxPrefilter:ee(Ft),ajaxTransport:ee(_t),ajax:function(t,n){function r(t,n,r,s){var l,p,d,b,w,T=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",C.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=re(h,C,r)),b=ie(h,b,C,l),l?(h.ifModified&&(w=C.getResponseHeader("Last-Modified"),w&&(we.lastModified[o]=w),(w=C.getResponseHeader("etag"))&&(we.etag[o]=w)),204===t||"HEAD"===h.type?T="nocontent":304===t?T="notmodified":(T=b.state,p=b.data,d=b.error,l=!d)):(d=T,!t&&T||(T="error",t<0&&(t=0))),C.status=t,C.statusText=(n||T)+"",l?y.resolveWith(g,[p,T,C]):y.rejectWith(g,[C,T,d]),C.statusCode(x),x=void 0,f&&v.trigger(l?"ajaxSuccess":"ajaxError",[C,h,l?p:d]),m.fireWith(g,[C,T]),f&&(v.trigger("ajaxComplete",[C,h]),--we.active||we.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=we.ajaxSetup({},n),g=h.context||h,v=h.context&&(g.nodeType||g.jquery)?we(g):we.event,y=we.Deferred(),m=we.Callbacks("once memory"),x=h.statusCode||{},b={},w={},T="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=It.exec(a);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)C.always(e[C.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return i&&i.abort(t),r(0,t),this}};if(y.promise(C),h.url=((t||h.url||Nt.href)+"").replace(Bt,Nt.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(Le)||[""],null==h.crossDomain){l=ae.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Xt.protocol+"//"+Xt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=we.param(h.data,h.traditional)),te(Ft,h,n,C),c)return C;f=we.event&&h.global,f&&0==we.active++&&we.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!$t.test(h.type),o=h.url.replace(Mt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Pt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(jt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Rt,"$1"),d=(jt.test(o)?"&":"?")+"_="+At+++d),h.url=o+d),h.ifModified&&(we.lastModified[o]&&C.setRequestHeader("If-Modified-Since",we.lastModified[o]),we.etag[o]&&C.setRequestHeader("If-None-Match",we.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&C.setRequestHeader("Content-Type",h.contentType),C.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+zt+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)C.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,C,h)||c))return C.abort();if(T="abort",m.add(h.complete),C.done(h.success),C.fail(h.error),i=te(_t,h,n,C)){if(C.readyState=1,f&&v.trigger("ajaxSend",[C,h]),c)return C;h.async&&h.timeout>0&&(u=e.setTimeout(function(){C.abort("timeout")},h.timeout));try{c=!1,i.send(b,r)}catch(e){if(c)throw e;r(-1,e)}}else r(-1,"No Transport");return C},getJSON:function(e,t,n){return we.get(e,t,n,"json")},getScript:function(e,t){return we.get(e,void 0,t,"script")}}),we.each(["get","post"],function(e,t){we[t]=function(e,n,r,i){return me(n)&&(i=i||r,r=n,n=void 0),we.ajax(we.extend({url:e,type:t,dataType:i,data:n,success:r},we.isPlainObject(e)&&e))}}),we._evalUrl=function(e){return we.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},we.fn.extend({wrapAll:function(e){var t;return this[0]&&(me(e)&&(e=e.call(this[0])),t=we(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return me(e)?this.each(function(t){we(this).wrapInner(e.call(this,t))}):this.each(function(){var t=we(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=me(e);return this.each(function(n){we(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){we(this).replaceWith(this.childNodes)}),this}}),we.expr.pseudos.hidden=function(e){return!we.expr.pseudos.visible(e)},we.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},we.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Vt=we.ajaxSettings.xhr();ye.cors=!!Vt&&"withCredentials"in Vt,ye.ajax=Vt=!!Vt,we.ajaxTransport(function(t){var n,r;if(ye.cors||Vt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Ut[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),we.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),we.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return we.globalEval(e),e}}}),we.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),we.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=we("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),ae.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;we.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||we.expando+"_"+At++;return this[e]=!0,e}}),we.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Yt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=me(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Yt,"$1"+i):!1!==t.jsonp&&(t.url+=(jt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||we.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?we(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Gt.push(i)),a&&me(o)&&o(a[0]),a=o=void 0}),"script"}),ye.createHTMLDocument=function(){var e=ae.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),we.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var r,i,o;return t||(ye.createHTMLDocument?(t=ae.implementation.createHTMLDocument(""),r=t.createElement("base"),r.href=ae.location.href,t.head.appendChild(r)):t=ae),i=De.exec(e),o=!n&&[],i?[t.createElement(i[1])]:(i=C([e],t,o),o&&o.length&&we(o).remove(),we.merge([],i.childNodes))},we.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=Q(e.slice(s)),e=e.slice(0,s)),me(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&we.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?we("<div>").append(we.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},we.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){we.fn[t]=function(e){return this.on(t,e)}}),we.expr.pseudos.animated=function(e){return we.grep(we.timers,function(t){return e===t.elem}).length},we.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=we.css(e,"position"),f=we(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=we.css(e,"top"),u=we.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),me(t)&&(t=t.call(e,n,we.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},we.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){we.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===we.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===we.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&(i=we(e).offset(),i.top+=we.css(e,"borderTopWidth",!0),i.left+=we.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-we.css(r,"marginTop",!0),left:t.left-i.left-we.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===we.css(e,"position");)e=e.offsetParent;return e||et})}}),we.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;we.fn[e]=function(r){return Pe(this,function(e,r,i){var o;if(xe(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),we.each(["top","left"],function(e,t){we.cssHooks[t]=M(ye.pixelPosition,function(e,n){if(n)return n=P(e,t),ut.test(n)?we(e).position()[t]+"px":n})}),we.each({Height:"height",Width:"width"},function(e,t){we.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){we.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return Pe(this,function(t,n,i){var o;return xe(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?we.css(t,n,s):we.style(t,n,i,s)},t,a?i:void 0,a)}})}),we.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){we.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),we.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),we.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),we.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),me(e))return r=ue.call(arguments,2),i=function(){return e.apply(t||this,r.concat(ue.call(arguments)))},i.guid=e.guid=e.guid||we.guid++,i},we.holdReady=function(e){e?we.readyWait++:we.ready(!0)},we.isArray=Array.isArray,we.parseJSON=JSON.parse,we.nodeName=o,we.isFunction=me,we.isWindow=xe,we.camelCase=h,we.type=r,we.now=Date.now,we.isNumeric=function(e){var t=we.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return we});var Qt=e.jQuery,Jt=e.$;return we.noConflict=function(t){return e.$===we&&(e.$=Jt),t&&e.jQuery===we&&(e.jQuery=Qt),we},t||(e.jQuery=e.$=we),we}); })(this);
+(function (window, undefined) { !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";function g(e){return null!=e&&e===e.window}var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,v=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},x=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,noModule:!0};function b(e,t,n){var r,i=(t=t||E).createElement("script");if(i.text=e,n)for(r in c)n[r]&&(i[r]=n[r]);t.head.appendChild(i).parentNode.removeChild(i)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.3.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!x(e)&&!g(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||x(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(o=i?(i=!1,n&&Array.isArray(n)?n:[]):n&&k.isPlainObject(n)?n:{},a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){b(e)},each:function(e,t){var n,r=0;if(d(e))for(n=e.length;r<n&&!1!==t.call(e[r],r,e[r]);r++);else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!=a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return v.apply([],a)},guid:1,support:m}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){function f(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(65536+r):String.fromCharCode(r>>10|55296,1023&r|56320)}function i(){T()}var e,d,b,o,a,h,p,g,w,u,l,T,C,s,E,v,c,y,m,k="sizzle"+ +new Date,x=n.document,S=0,r=0,D=ae(),N=ae(),A=ae(),j=function(e,t){return e===t&&(l=!0),0},q={}.hasOwnProperty,t=[],L=t.pop,H=t.push,O=t.push,P=t.slice,M=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",$="\\["+I+"*("+W+")(?:"+I+"*([*^$|!~]?=)"+I+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+W+"))|)"+I+"*\\]",B=":("+W+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+$+")*)|.*)\\)|)",F=new RegExp(I+"+","g"),_=new RegExp("^"+I+"+|((?:^|[^\\\\])(?:\\\\.)*)"+I+"+$","g"),z=new RegExp("^"+I+"*,"+I+"*"),X=new RegExp("^"+I+"*([>+~]|"+I+")"+I+"*"),U=new RegExp("="+I+"*([^\\]'\"]*?)"+I+"*\\]","g"),V=new RegExp(B),G=new RegExp("^"+W+"$"),Y={ID:new RegExp("^#("+W+")"),CLASS:new RegExp("^\\.("+W+")"),TAG:new RegExp("^("+W+"|[*])"),ATTR:new RegExp("^"+$),PSEUDO:new RegExp("^"+B),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+I+"*(even|odd|(([+-]|)(\\d*)n|)"+I+"*(?:([+-]|)"+I+"*(\\d+)|))"+I+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+I+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+I+"*((?:-\\d)?\\d*)"+I+"*\\)|)(?=[^-]|$)","i")},Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+I+"?|("+I+")|.)","ig"),ne=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,re=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},ie=ve(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(x.childNodes),x.childNodes),t[x.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){H.apply(e,P.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function oe(e,t,n,r){var i,o,a,s,u,l,c,f=t&&t.ownerDocument,p=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==p&&9!==p&&11!==p)return n;if(!r&&((t?t.ownerDocument||t:x)!==C&&T(t),t=t||C,E)){if(11!==p&&(u=Z.exec(e)))if(i=u[1]){if(9===p){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&m(t,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,t.getElementsByTagName(e)),n;if((i=u[3])&&d.getElementsByClassName&&t.getElementsByClassName)return O.apply(n,t.getElementsByClassName(i)),n}if(d.qsa&&!A[e+" "]&&(!v||!v.test(e))){if(1!==p)f=t,c=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(ne,re):t.setAttribute("id",s=k),o=(l=h(e)).length;o--;)l[o]="#"+s+" "+ge(l[o]);c=l.join(","),f=ee.test(e)&&de(t.parentNode)||t}if(c)try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){}finally{s===k&&t.removeAttribute("id")}}}return g(e.replace(_,"$1"),t,n,r)}function ae(){var n=[];function r(e,t){return n.push(e+" ")>b.cacheLength&&delete r[n.shift()],r[e+" "]=t}return r}function se(e){return e[k]=!0,e}function ue(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),r=n.length;r--;)b.attrHandle[n[r]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ie(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function pe(a){return se(function(o){return o=+o,se(function(e,t){for(var n,r=a([],e.length,o),i=r.length;i--;)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function de(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=oe.support={},a=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},T=oe.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:x;return r!==C&&9===r.nodeType&&r.documentElement&&(s=(C=r).documentElement,E=!a(C),x!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",i,!1):n.attachEvent&&n.attachEvent("onunload",i)),d.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ue(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ue(function(e){return s.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,f);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,f);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[i++];)1===n.nodeType&&r.push(n);return r},b.find.CLASS=d.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},c=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ue(function(e){s.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+I+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+I+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+I+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(y=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ue(function(e){d.disconnectedMatch=y.call(e,"*"),y.call(e,"[s!='']:x"),c.push("!=",B)}),v=v.length&&new RegExp(v.join("|")),c=c.length&&new RegExp(c.join("|")),t=K.test(s.compareDocumentPosition),m=t||K.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===x&&m(x,e)?-1:t===C||t.ownerDocument===x&&m(x,t)?1:u?M(u,e)-M(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?M(u,e)-M(u,t):0;if(i===o)return ce(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ce(a[r],s[r]):a[r]===x?-1:s[r]===x?1:0}),C},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),t=t.replace(U,"='$1']"),d.matchesSelector&&E&&!A[t+" "]&&(!c||!c.test(t))&&(!v||!v.test(t)))try{var n=y.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return 0<oe(t,C,null,[e]).length},oe.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),m(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&q.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},oe.escape=function(e){return(e+"").replace(ne,re)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return u=null,e},o=oe.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=o(t);return n},(b=oe.selectors={cacheLength:50,createPseudo:se,match:Y,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,f),e[3]=(e[3]||e[4]||e[5]||"").replace(te,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=D[e+" "];return t||(t=new RegExp("(^|"+I+")"+e+"("+I+"|$)"))&&D(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=oe.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!=m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){for(;l;){for(a=e;a=a[l];)if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){for(d=(s=(r=(i=(o=(a=c)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1])&&r[2],a=s&&c.childNodes[s];a=++s&&a&&a[l]||(d=s=0)||u.pop();)if(1===a.nodeType&&++d&&a===e){i[h]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1]),!1===d)for(;(a=++s&&a&&a[l]||(d=s=0)||u.pop())&&((x?a.nodeName.toLowerCase()!==f:1!==a.nodeType)||!++d||(p&&((i=(o=a[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,d]),a!==e)););return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,t){for(var n,r=a(e,o),i=r.length;i--;)e[n=M(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:se(function(e){var r=[],i=[],s=p(e.replace(_,"$1"));return s[k]?se(function(e,t,n,r){for(var i,o=s(e,null,r,[]),a=e.length;a--;)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:se(function(t){return function(e){return 0<oe(t,e).length}}),contains:se(function(t){return t=t.replace(te,f),function(e){return-1<(e.textContent||e.innerText||o(e)).indexOf(t)}}),lang:se(function(n){return G.test(n||"")||oe.error("unsupported lang: "+n),n=n.replace(te,f).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===s},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:fe(!1),disabled:fe(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:pe(function(){return[0]}),last:pe(function(e,t){return[t-1]}),eq:pe(function(e,t,n){return[n<0?n+t:n]}),even:pe(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:pe(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:pe(function(e,t,n){for(var r=n<0?n+t:n;0<=--r;)e.push(r);return e}),gt:pe(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=function(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=function(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}(e);function he(){}function ge(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function ve(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){for(;e=e[u];)if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[S,p];if(n){for(;e=e[u];)if((1===e.nodeType||f)&&s(e,t,n))return!0}else for(;e=e[u];)if(1===e.nodeType||f)if(i=(o=e[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function ye(i){return 1<i.length?function(e,t,n){for(var r=i.length;r--;)if(!i[r](e,t,n))return!1;return!0}:i[0]}function me(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function xe(d,h,g,v,y,e){return v&&!v[k]&&(v=xe(v)),y&&!y[k]&&(y=xe(y,e)),se(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:me(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v)for(i=me(p,u),v(i,[],n,r),o=i.length;o--;)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a));if(e){if(y||d){if(y){for(i=[],o=p.length;o--;)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}for(o=p.length;o--;)(a=p[o])&&-1<(i=y?M(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=me(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):O.apply(t,p)})}function be(v,y){function e(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=S+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t===C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){for(a=0,t||o.ownerDocument===C||(T(o),n=!E);s=v[a++];)if(s(o,t||C,n)){r.push(o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){for(a=0;s=y[a++];)s(c,f,t,n);if(e){if(0<u)for(;l--;)c[l]||f[l]||(f[l]=L.call(r));f=me(f)}O.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&oe.uniqueSort(r)}return i&&(S=h,w=p),c}var m=0<y.length,x=0<v.length;return m?se(e):e}return he.prototype=b.filters=b.pseudos,b.setFilters=new he,h=oe.tokenize=function(e,t){var n,r,i,o,a,s,u,l=N[e+" "];if(l)return t?0:l.slice(0);for(a=e,s=[],u=b.preFilter;a;){for(o in n&&!(r=z.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(_," ")}),a=a.slice(n.length)),b.filter)!(r=Y[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?oe.error(e):N(e,s).slice(0)},p=oe.compile=function(e,t){var n,r=[],i=[],o=A[e+" "];if(!o){for(n=(t=t||h(e)).length;n--;)(o=function e(t){for(var i,n,r,o=t.length,a=b.relative[t[0].type],s=a||b.relative[" "],u=a?1:0,l=ve(function(e){return e===i},s,!0),c=ve(function(e){return-1<M(i,e)},s,!0),f=[function(e,t,n){var r=!a&&(n||t!==w)||((i=t).nodeType?l:c)(e,t,n);return i=null,r}];u<o;u++)if(n=b.relative[t[u].type])f=[ve(ye(f),n)];else{if((n=b.filter[t[u].type].apply(null,t[u].matches))[k]){for(r=++u;r<o&&!b.relative[t[r].type];r++);return xe(1<u&&ye(f),1<u&&ge(t.slice(0,u-1).concat({value:" "===t[u-2].type?"*":""})).replace(_,"$1"),n,u<r&&e(t.slice(u,r)),r<o&&e(t=t.slice(r)),r<o&&ge(t))}f.push(n)}return ye(f)}(t[n]))[k]?r.push(o):i.push(o);(o=A(e,be(i,r))).selector=e}return o},g=oe.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,f),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=Y.needsContext.test(e)?0:o.length;i--&&(a=o[i],!b.relative[s=a.type]);)if((u=b.find[s])&&(r=u(a.matches[0].replace(te,f),ee.test(o[0].type)&&de(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&ge(o)))return O.apply(n,r),n;break}}return(l||p(e,c))(r,t,!E,n,!t||ee.test(e)&&de(t.parentNode)||t),n},d.sortStable=k.split("").sort(j).join("")===k,d.detectDuplicates=!!l,T(),d.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(C);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;function T(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r}function S(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}var D=k.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return x(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):x(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),A.test(r[1])&&k.isPlainObject(t))for(r in t)x(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&x(i=e.promise)?i.call(e).done(t).fail(n):e&&x(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(M)||[],function(e,t){n[t]=!0}),n):k.extend({},r);function i(){for(s=s||r.once,a=o=!0;l.length;c=-1)for(t=l.shift();++c<u.length;)!1===u[c].apply(t[0],t[1])&&r.stopOnFalse&&(c=u.length,t=!1);r.memory||(t=!1),o=!1,s&&(u=t?[]:"")}var o,t,a,s,u=[],l=[],c=-1,f={add:function(){return u&&(t&&!o&&(c=u.length-1,l.push(t)),function n(e){k.each(e,function(e,t){x(t)?r.unique&&f.has(t)||u.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!o&&i()),this},remove:function(){return k.each(arguments,function(e,t){for(var n;-1<(n=k.inArray(t,u,n));)u.splice(n,1),n<=c&&c--}),this},has:function(e){return e?-1<k.inArray(e,u):0<u.length},empty:function(){return u=u&&[],this},disable:function(){return s=l=[],u=t="",this},disabled:function(){return!u},lock:function(){return s=l=[],t||o||(u=t=""),this},locked:function(){return!!s},fireWith:function(e,t){return s||(t=[e,(t=t||[]).slice?t.slice():t],l.push(t),o||i()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!a}};return f},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},catch:function(e){return a.then(null,e)},pipe:function(){var i=arguments;return k.Deferred(function(r){k.each(o,function(e,t){var n=x(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&x(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){function e(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,x(t)?s?t.call(e,l(u,o,R,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,I,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}}var n=this,r=arguments,t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,x(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,x(t)?t:R)),o[2][3].add(l(0,e,x(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){function t(t){return function(e){i[t]=this,o[t]=1<arguments.length?s.call(arguments):e,--n||a.resolveWith(i,o)}}var n=arguments.length,r=n,i=Array(r),o=s.call(arguments),a=k.Deferred();if(n<=1&&(W(e,a.done(t(r)).resolve,a.reject,!n),"pending"===a.state()||x(o[r]&&o[r].then)))return a.then();for(;r--;)W(o[r],t(r),a.reject);return a.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var B=k.Deferred();function F(){E.removeEventListener("DOMContentLoaded",F),C.removeEventListener("load",F),k.ready()}k.fn.ready=function(e){return B.then(e).catch(function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||B.resolveWith(E,[k])}}),k.ready.then=B.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.ready):(E.addEventListener("DOMContentLoaded",F),C.addEventListener("load",F));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,x(r)||(a=!0),l&&(t=a?(t.call(e,r),null):(l=t,function(e,t,n){return l.call(k(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,X=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(X,U)}function G(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType}function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(M)||[]).length;for(;n--;)delete r[t[n]]}void 0!==t&&!k.isEmptyObject(r)||(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0!==n)return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;return o&&void 0===e?void 0!==(t=J.get(o,n))||void 0!==(t=ee(o,n))?t:void 0:void this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0);if(this.length&&(i=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){for(t=a.length;t--;)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){function n(){--i||o.resolveWith(a,[a])}var r,i=1,o=k.Deferred(),a=this,s=this.length;for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";s--;)(r=Q.get(a[s],e+"queueHooks"))&&r.empty&&(i++,r.empty.add(n));return n(),o.promise(t)}});function te(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i}var ne=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,re=new RegExp("^(?:([+-])=|)("+ne+")([a-z%]*)$","i"),ie=["Top","Right","Bottom","Left"],oe=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&k.contains(e.ownerDocument,e)&&"none"===k.css(e,"display")};function ae(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=(k.cssNumber[t]||"px"!==l&&+u)&&re.exec(k.css(e,t));if(c&&c[3]!==l){for(u/=2,l=l||c[3],c=+u||1;a--;)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var se={};function ue(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&oe(r)&&(l[c]=(u=s=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=se[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),se[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return ue(this,!0)},hide:function(){return ue(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){oe(this)?k(this).show():k(this).hide()})}});var le=/^(?:checkbox|radio)$/i,ce=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,fe=/^$|^module$|\/(?:java|ecma)script/i,pe={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function de(e,t){var n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&N(e,t)?k.merge([e],n):n}function he(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}pe.optgroup=pe.option,pe.tbody=pe.tfoot=pe.colgroup=pe.caption=pe.thead,pe.th=pe.td;var ge,ve,ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))k.merge(p,o.nodeType?[o]:o);else if(ye.test(o)){for(a=a||f.appendChild(t.createElement("div")),s=(ce.exec(o)||["",""])[1].toLowerCase(),u=pe[s]||pe._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];c--;)a=a.lastChild;k.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));for(f.textContent="",d=0;o=p[d++];)if(r&&-1<k.inArray(o,r))i&&i.push(o);else if(l=k.contains(o.ownerDocument,o),a=de(f.appendChild(o),"script"),l&&he(a),n)for(c=0;o=a[c++];)fe.test(o.type||"")&&n.push(o);return f}ge=E.createDocumentFragment().appendChild(E.createElement("div")),(ve=E.createElement("input")).setAttribute("type","radio"),ve.setAttribute("checked","checked"),ve.setAttribute("name","t"),ge.appendChild(ve),m.checkClone=ge.cloneNode(!0).cloneNode(!0).lastChild.checked,ge.innerHTML="<textarea>x</textarea>",m.noCloneChecked=!!ge.cloneNode(!0).lastChild.defaultValue;var xe=E.documentElement,be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function ke(){try{return E.activeElement}catch(e){}}function Se(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Se(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(xe,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(M)||[""]).length;l--;)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){for(l=(t=(t||"").match(M)||[""]).length;l--;)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){for(f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){for(a=k.event.handlers.call(this,s,l),t=0;(i=a[t++])&&!s.isPropagationStopped();)for(s.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!s.isImmediatePropagationStopped();)s.rnamespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<k(i,this).index(l):k.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(k.Event.prototype,t,{enumerable:!0,configurable:!0,get:x(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ke()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===ke()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Se(this,e,t,n,r)},one:function(e,t,n,r){return Se(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"!=typeof e)return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){k.event.remove(this,e,n,t)});for(i in e)this.off(i,t,e[i]);return this}});var De=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ne=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Pe(n,r,i,o){r=v.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=x(d);if(h||1<f&&"string"==typeof d&&!m.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=me(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(de(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,de(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,He),c=0;c<s;c++)u=a[c],fe.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&k._evalUrl(u.src):b(u.textContent.replace(je,""),l,u))}return n}function Me(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(de(r)),r.parentNode&&(n&&k.contains(r.ownerDocument,r)&&he(de(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(De,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=k.contains(e.ownerDocument,e);if(!(m.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=de(c),r=0,i=(o=de(e)).length;r<i;r++)s=o[r],u=a[r],l=void 0,"input"===(l=u.nodeName.toLowerCase())&&le.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||de(e),a=a||de(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=de(c,"script")).length&&he(a,!f&&de(e,"script")),c},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return Me(this,e,!0)},remove:function(e){return Me(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){var t;1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(t=qe(this,e)).insertBefore(e,t.firstChild)})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(de(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!pe[(ce.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.cleanData(de(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(de(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Re,Ie,We,$e,Be,Fe,_e,ze=new RegExp("^("+ne+")(?!px)[a-z%]+$","i"),Xe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Ue=new RegExp(ie.join("|"),"i");function Ve(){var e;_e&&(Fe.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",_e.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",xe.appendChild(Fe).appendChild(_e),e=C.getComputedStyle(_e),Re="1%"!==e.top,Be=12===Ge(e.marginLeft),_e.style.right="60%",$e=36===Ge(e.right),Ie=36===Ge(e.width),_e.style.position="absolute",We=36===_e.offsetWidth||"absolute",xe.removeChild(Fe),_e=null)}function Ge(e){return Math.round(parseFloat(e))}function Ye(e,t,n){var r,i,o,a,s=e.style;return(n=n||Xe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||k.contains(e.ownerDocument,e)||(a=k.style(e,t)),!m.pixelBoxStyles()&&ze.test(a)&&Ue.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Qe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}Fe=E.createElement("div"),(_e=E.createElement("div")).style&&(_e.style.backgroundClip="content-box",_e.cloneNode(!0).style.backgroundClip="",m.clearCloneStyle="content-box"===_e.style.backgroundClip,k.extend(m,{boxSizingReliable:function(){return Ve(),Ie},pixelBoxStyles:function(){return Ve(),$e},pixelPosition:function(){return Ve(),Re},reliableMarginLeft:function(){return Ve(),Be},scrollboxSize:function(){return Ve(),We}}));var Je=/^(none|table(?!-c[ea]).+)/,Ke=/^--/,Ze={position:"absolute",visibility:"hidden",display:"block"},et={letterSpacing:"0",fontWeight:"400"},tt=["Webkit","Moz","ms"],nt=E.createElement("div").style;function rt(e){return k.cssProps[e]||(k.cssProps[e]=function(e){if(e in nt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=tt.length;n--;)if((e=tt[n]+t)in nt)return e}(e)||e)}function it(e,t,n){var r=re.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function ot(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=k.css(e,n+ie[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+ie[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+ie[a]+"Width",!0,i))):(u+=k.css(e,"padding"+ie[a],!0,i),"padding"!==n?u+=k.css(e,"border"+ie[a]+"Width",!0,i):s+=k.css(e,"border"+ie[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function at(e,t,n){var r=Xe(e),i=Ye(e,t,r),o="border-box"===k.css(e,"boxSizing",!1,r),a=o;if(ze.test(i)){if(!n)return i;i="auto"}return a=a&&(m.boxSizingReliable()||i===e.style[t]),"auto"!==i&&(parseFloat(i)||"inline"!==k.css(e,"display",!1,r))||(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+ot(e,t,n||(o?"border":"content"),a,r,i)+"px"}function st(e,t,n,r,i){return new st.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ye(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Ke.test(t),l=e.style;if(u||(t=rt(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=re.exec(n))&&i[1]&&(n=ae(e,t,i),o="number"),null!=n&&n==n&&("number"===o&&(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),m.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Ke.test(t)||(t=rt(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ye(e,t,r)),"normal"===i&&t in et&&(i=et[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,s){k.cssHooks[s]={get:function(e,t,n){if(t)return!Je.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?at(e,s,n):te(e,Ze,function(){return at(e,s,n)})},set:function(e,t,n){var r,i=Xe(e),o="border-box"===k.css(e,"boxSizing",!1,i),a=n&&ot(e,s,n,o,i);return o&&m.scrollboxSize()===i.position&&(a-=Math.ceil(e["offset"+s[0].toUpperCase()+s.slice(1)]-parseFloat(i[s])-ot(e,s,"border",!1,i)-.5)),a&&(r=re.exec(t))&&"px"!==(r[3]||"px")&&(e.style[s]=t,t=k.css(e,s)),it(0,t,a)}}}),k.cssHooks.marginLeft=Qe(m.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Ye(e,"marginLeft"))||e.getBoundingClientRect().left-te(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ie[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=it)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Xe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),(k.Tween=st).prototype={constructor:st,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=st.propHooks[this.prop];return e&&e.get?e.get(this):st.propHooks._default.get(this)},run:function(e){var t,n=st.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):st.propHooks._default.set(this),this}},st.prototype.init.prototype=st.prototype,st.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[k.cssProps[e.prop]]&&!k.cssHooks[e.prop]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}},st.propHooks.scrollTop=st.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=st.prototype.init,k.fx.step={};var ut,lt,ct,ft,pt=/^(?:toggle|show|hide)$/,dt=/queueHooks$/;function ht(){lt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ht):C.setTimeout(ht,k.fx.interval),k.fx.tick())}function gt(){return C.setTimeout(function(){ut=void 0}),ut=Date.now()}function vt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ie[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function yt(e,t,n){for(var r,i=(mt.tweeners[t]||[]).concat(mt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function mt(o,e,t){var n,a,r=0,i=mt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=ut||gt(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:ut||gt(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=mt.prefilters[r].call(l,o,c,l.opts))return x(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,yt,l),x(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(mt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ae(n.elem,e,re.exec(t),n),n}]},tweener:function(e,t){for(var n,r=0,i=(e=x(e)?(t=e,["*"]):e.match(M)).length;r<i;r++)n=e[r],mt.tweeners[n]=mt.tweeners[n]||[],mt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&oe(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],pt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(ue([e],!0),l=e.style.display||l,c=k.css(e,"display"),ue([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&ue([e],!0),p.done(function(){for(r in g||ue([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=yt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?mt.prefilters.unshift(e):mt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||x(e)&&e,duration:e,easing:n&&t||t&&!x(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){x(r.old)&&r.old.call(this),r.queue&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(oe).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){function i(){var e=mt(this,k.extend({},t),a);(o||Q.get(this,"finish"))&&e.stop(!0)}var o=k.isEmptyObject(t),a=k.speed(e,n,r);return i.finish=i,o||!1===a.queue?this.each(i):this.queue(a.queue,i)},stop:function(i,e,o){function a(e){var t=e.stop;delete e.stop,t(o)}return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&dt.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(vt(r,!0),e,t,n)}}),k.each({slideDown:vt("show"),slideUp:vt("hide"),slideToggle:vt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(ut=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),ut=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){lt||(lt=!0,ht())},k.fx.stop=function(){lt=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},ct=E.createElement("input"),ft=E.createElement("select").appendChild(E.createElement("option")),ct.type="checkbox",m.checkOn=""!==ct.value,m.optSelected=ft.selected,(ct=E.createElement("input")).value="t",ct.type="radio",m.radioValue="t"===ct.value;var xt,bt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?xt:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):!(i&&"get"in i&&null!==(r=i.get(e,t)))&&null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),xt={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=bt[t]||k.find.attr;bt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=bt[o],bt[o]=r,r=null!=a(e,t,n)?o:null,bt[o]=i),r}});var wt=/^(?:input|select|textarea|button)$/i,Tt=/^(?:a|area)$/i;function Ct(e){return(e.match(M)||[]).join(" ")}function Et(e){return e.getAttribute&&e.getAttribute("class")||""}function kt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(M)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):wt.test(e.nodeName)||Tt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(x(t))return this.each(function(e){k(this).addClass(t.call(this,e,Et(this)))});if((e=kt(t)).length)for(;n=this[u++];)if(i=Et(n),r=1===n.nodeType&&" "+Ct(i)+" "){for(a=0;o=e[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=Ct(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(x(t))return this.each(function(e){k(this).removeClass(t.call(this,e,Et(this)))});if(!arguments.length)return this.attr("class","");if((e=kt(t)).length)for(;n=this[u++];)if(i=Et(n),r=1===n.nodeType&&" "+Ct(i)+" "){for(a=0;o=e[a++];)for(;-1<r.indexOf(" "+o+" ");)r=r.replace(" "+o+" "," ");i!==(s=Ct(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"==o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):x(i)?this.each(function(e){k(this).toggleClass(i.call(this,e,Et(this),t),t)}):this.each(function(){var e,t,n,r;if(a)for(t=0,n=k(this),r=kt(i);e=r[t++];)n.hasClass(e)?n.removeClass(e):n.addClass(e);else void 0!==i&&"boolean"!=o||((e=Et(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==i&&Q.get(this,"__className__")||""))})},hasClass:function(e){for(var t,n=0,r=" "+e+" ";t=this[n++];)if(1===t.nodeType&&-1<(" "+Ct(Et(t))+" ").indexOf(r))return!0;return!1}});var St=/\r/g;k.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=x(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(St,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:Ct(k.text(e))}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(((n=r[u]).selected||u===i)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=k(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=k.makeArray(t),a=i.length;a--;)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},m.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),m.focusin="onfocusin"in C;function Dt(e){e.stopPropagation()}var Nt=/^(?:focusinfocus|focusoutblur)$/;k.extend(k.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f=[n||E],p=y.call(e,"type")?e.type:e,d=y.call(e,"namespace")?e.namespace.split("."):[],h=c=o=n=n||E;if(3!==n.nodeType&&8!==n.nodeType&&!Nt.test(p+k.event.triggered)&&(-1<p.indexOf(".")&&(p=(d=p.split(".")).shift(),d.sort()),s=p.indexOf(":")<0&&"on"+p,(e=e[k.expando]?e:new k.Event(p,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=d.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:k.makeArray(t,[e]),l=k.event.special[p]||{},r||!l.trigger||!1!==l.trigger.apply(n,t))){if(!r&&!l.noBubble&&!g(n)){for(a=l.delegateType||p,Nt.test(a+p)||(h=h.parentNode);h;h=h.parentNode)f.push(h),o=h;o===(n.ownerDocument||E)&&f.push(o.defaultView||o.parentWindow||C)}for(i=0;(h=f[i++])&&!e.isPropagationStopped();)c=h,e.type=1<i?a:l.bindType||p,(u=(Q.get(h,"events")||{})[e.type]&&Q.get(h,"handle"))&&u.apply(h,t),(u=s&&h[s])&&u.apply&&G(h)&&(e.result=u.apply(h,t),!1===e.result&&e.preventDefault());return e.type=p,r||e.isDefaultPrevented()||l._default&&!1!==l._default.apply(f.pop(),t)||!G(n)||s&&x(n[p])&&!g(n)&&((o=n[s])&&(n[s]=null),k.event.triggered=p,e.isPropagationStopped()&&c.addEventListener(p,Dt),n[p](),e.isPropagationStopped()&&c.removeEventListener(p,Dt),k.event.triggered=void 0,o&&(n[s]=o)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),m.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){function i(e){k.event.simulate(r,e.target,k.event.fix(e))}k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var At=C.location,jt=Date.now(),qt=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Lt=/\[\]$/,Ht=/\r?\n/g,Ot=/^(?:submit|button|image|reset|file)$/i,Pt=/^(?:input|select|textarea|keygen)/i;k.param=function(e,t){function n(e,t){var n=x(t)?t():t;i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)}var r,i=[];if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){n(this.name,this.value)});else for(r in e)!function n(r,e,i,o){var t;if(Array.isArray(e))k.each(e,function(e,t){i||Lt.test(r)?o(r,t):n(r+"["+("object"==typeof t&&null!=t?e:"")+"]",t,i,o)});else if(i||"object"!==w(e))o(r,e);else for(t in e)n(r+"["+t+"]",e[t],i,o)}(r,e[r],t,n);return i.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&Pt.test(this.nodeName)&&!Ot.test(e)&&(this.checked||!le.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(Ht,"\r\n")}}):{name:t.name,value:n.replace(Ht,"\r\n")}}).get()}});var Mt=/%20/g,Rt=/#.*$/,It=/([?&])_=[^&]*/,Wt=/^(.*?):[ \t]*([^\r\n]*)$/gm,$t=/^(?:GET|HEAD)$/,Bt=/^\/\//,Ft={},_t={},zt="*/".concat("*"),Xt=E.createElement("a");function Ut(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(M)||[];if(x(t))for(;n=i[r++];)"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Vt(t,i,o,a){var s={},u=t===_t;function l(e){var r;return s[e]=!0,k.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Gt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r=r||{})[n]=t[n]);return r&&k.extend(!0,e,r),e}Xt.href=At.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:At.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(At.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Gt(Gt(e,k.ajaxSettings),t):Gt(k.ajaxSettings,e)},ajaxPrefilter:Ut(Ft),ajaxTransport:Ut(_t),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n)for(n={};t=Wt.exec(p);)n[t[1].toLowerCase()]=t[2];t=n[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||At.href)+"").replace(Bt,At.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(M)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Xt.protocol+"//"+Xt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),Vt(Ft,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!$t.test(v.type),f=v.url.replace(Rt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Mt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(qt.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(It,"$1"),o=(qt.test(f)?"&":"?")+"_="+jt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+zt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Vt(_t,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a=a||i}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return x(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(x(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return x(n)?this.each(function(e){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=x(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Yt={0:200,1223:204},Qt=k.ajaxSettings.xhr();m.cors=!!Qt&&"withCredentials"in Qt,m.ajax=Qt=!!Qt,k.ajaxTransport(function(i){var o,a;if(m.cors||Qt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Yt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain)return{send:function(e,t){r=k("<script>").prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=x(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(qt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&x(i)&&i(o[0]),o=i=void 0}),"script"}),m.createHTMLDocument=((Jt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Jt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=A.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=Ct(e.slice(s)),e=e.slice(0,s)),x(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),i=("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,r.left):(a=parseFloat(o)||0,parseFloat(u)||0),x(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||xe})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;return g(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n?r?r[i]:e[t]:void(r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n)},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Qe(m.pixelPosition,function(e,t){if(t)return t=Ye(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return g(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),k.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),x(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=N,k.isFunction=x,k.isWindow=g,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var en=C.jQuery,tn=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=tn),e&&C.jQuery===k&&(C.jQuery=en),k},e||(C.jQuery=C.$=k),k}); })(this);
 
 // 3rdParty/jquery-ui.js
-(function (window, undefined) { !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){t.ui=t.ui||{};var e=(t.ui.version="1.12.1",0),i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,o,n;for(n=0;null!=(o=i[n]);n++)try{s=t._data(o,"events"),s&&s.remove&&t(o).triggerHandler("remove")}catch(t){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var o,n,r,a={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},o=t[h][e],n=t[h][e]=function(t,e){if(!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},t.extend(n,o,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),r=new i,r.options=t.widget.extend({},r.options),t.each(s,function(e,s){if(!t.isFunction(s))return void(a[e]=s);a[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,n=this._superApply;return this._super=t,this._superApply=o,e=s.apply(this,arguments),this._super=i,this._superApply=n,e}}()}),n.prototype=t.widget.extend(r,{widgetEventPrefix:o?r.widgetEventPrefix||e:e},a,{constructor:n,namespace:h,widgetName:e,widgetFullName:l}),o?(t.each(o._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,n,i._proto)}),delete o._childConstructors):i._childConstructors.push(n),t.widget.bridge(e,n),n},t.widget.extend=function(e){for(var s,o,n=i.call(arguments,1),r=0,a=n.length;r<a;r++)for(s in n[r])o=n[r][s],n[r].hasOwnProperty(s)&&void 0!==o&&(t.isPlainObject(o)?e[s]=t.isPlainObject(e[s])?t.widget.extend({},e[s],o):t.widget.extend({},o):e[s]=o);return e},t.widget.bridge=function(e,s){var o=s.prototype.widgetFullName||e;t.fn[e]=function(n){var r="string"==typeof n,a=i.call(arguments,1),h=this;return r?this.length||"instance"!==n?this.each(function(){var i,s=t.data(this,o);return"instance"===n?(h=s,!1):s?t.isFunction(s[n])&&"_"!==n.charAt(0)?(i=s[n].apply(s,a),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; attempted to call method '"+n+"'")}):h=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,o);e?(e.option(n||{}),e._init&&e._init()):t.data(this,o,new s(n,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,o,n,r=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(r={},s=e.split("."),e=s.shift(),s.length){for(o=r[e]=t.widget.extend({},this.options[e]),n=0;n<s.length-1;n++)o[s[n]]=o[s[n]]||{},o=o[s[n]];if(e=s.pop(),1===arguments.length)return void 0===o[e]?null:o[e];o[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];r[e]=i}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,o;for(i in e)o=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&o&&o.length&&(s=t(o.get()),this._removeClass(o,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,n){var r,a;for(a=0;a<i.length;a++)r=o.classesElementLookup[i[a]]||t(),r=t(e.add?t.unique(r.get().concat(e.element.get())):r.not(e.element).get()),o.classesElementLookup[i[a]]=r,s.push(i[a]),n&&e.classes[i[a]]&&s.push(e.classes[i[a]])}var s=[],o=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,o){-1!==t.inArray(e.target,o)&&(i.classesElementLookup[s]=t(o.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var o="string"==typeof t||null===t,n={extra:o?e:i,keys:o?t:e,element:o?this.element:t,add:s};return n.element.toggleClass(this._classes(n),s),this},_on:function(e,i,s){var o,n=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=o=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,o=this.widget()),t.each(s,function(s,r){function a(){if(e||!0!==n.options.disabled&&!t(this).hasClass("ui-state-disabled"))return("string"==typeof r?n[r]:r).apply(n,arguments)}"string"!=typeof r&&(a.guid=r.guid=r.guid||a.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+n.eventNamespace,c=h[2];c?o.on(l,c,a):i.on(l,a)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var o,n,r=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],n=i.originalEvent)for(o in n)o in i||(i[o]=n[o]);return this.element.trigger(i,s),!(t.isFunction(r)&&!1===r.apply(this.element[0],[i].concat(s))||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,o,n){"string"==typeof o&&(o={effect:o});var r,a=o?!0===o||"number"==typeof o?i:o.effect||i:e;o=o||{},"number"==typeof o&&(o={duration:o}),r=!t.isEmptyObject(o),o.complete=n,o.delay&&s.delay(o.delay),r&&t.effects&&t.effects.effect[a]?s[e](o):a!==e&&s[a]?s[a](o.duration,o.easing,n):s.queue(function(i){t(this)[e](),n&&n.call(s[0]),i()})}});t.widget;!function(){function e(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var o,n=Math.max,r=Math.abs,a=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==o)return o;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),n=s.children()[0];return t("body").append(s),e=n.offsetWidth,s.css("overflow","scroll"),i=n.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),o=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),o="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth;return{width:"scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight?t.position.scrollbarWidth():0,height:o?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),o=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:o,offset:s||o?{left:0,top:0}:t(e).offset(),scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(o){if(!o||!o.of)return f.apply(this,arguments);o=t.extend({},o);var p,u,d,g,m,v,_=t(o.of),b=t.position.getWithinInfo(o.within),w=t.position.getScrollInfo(b),y=(o.collision||"flip").split(" "),P={};return v=s(_),_[0].preventDefault&&(o.at="left top"),u=v.width,d=v.height,g=v.offset,m=t.extend({},g),t.each(["my","at"],function(){var t,e,i=(o[this]||"").split(" ");1===i.length&&(i=a.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=a.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),P[this]=[t?t[0]:0,e?e[0]:0],o[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===y.length&&(y[1]=y[0]),"right"===o.at[0]?m.left+=u:"center"===o.at[0]&&(m.left+=u/2),"bottom"===o.at[1]?m.top+=d:"center"===o.at[1]&&(m.top+=d/2),p=e(P.at,u,d),m.left+=p[0],m.top+=p[1],this.each(function(){var s,a,h=t(this),l=h.outerWidth(),c=h.outerHeight(),f=i(this,"marginLeft"),v=i(this,"marginTop"),x=l+f+i(this,"marginRight")+w.width,C=c+v+i(this,"marginBottom")+w.height,z=t.extend({},m),H=e(P.my,h.outerWidth(),h.outerHeight());"right"===o.my[0]?z.left-=l:"center"===o.my[0]&&(z.left-=l/2),"bottom"===o.my[1]?z.top-=c:"center"===o.my[1]&&(z.top-=c/2),z.left+=H[0],z.top+=H[1],s={marginLeft:f,marginTop:v},t.each(["left","top"],function(e,i){t.ui.position[y[e]]&&t.ui.position[y[e]][i](z,{targetWidth:u,targetHeight:d,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:x,collisionHeight:C,offset:[p[0]+H[0],p[1]+H[1]],my:o.my,at:o.at,within:b,elem:h})}),o.using&&(a=function(t){var e=g.left-z.left,i=e+u-l,s=g.top-z.top,a=s+d-c,p={target:{element:_,left:g.left,top:g.top,width:u,height:d},element:{element:h,left:z.left,top:z.top,width:l,height:c},horizontal:i<0?"left":e>0?"right":"center",vertical:a<0?"top":s>0?"bottom":"middle"};u<l&&r(e+i)<u&&(p.horizontal="center"),d<c&&r(s+a)<d&&(p.vertical="middle"),n(r(e),r(i))>n(r(s),r(a))?p.important="horizontal":p.important="vertical",o.using.call(this,t,p)}),h.offset(t.extend(z,{using:a}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollLeft:s.offset.left,r=s.width,a=t.left-e.collisionPosition.marginLeft,h=o-a,l=a+e.collisionWidth-r-o;e.collisionWidth>r?h>0&&l<=0?(i=t.left+h+e.collisionWidth-r-o,t.left+=h-i):t.left=l>0&&h<=0?o:h>l?o+r-e.collisionWidth:o:h>0?t.left+=h:l>0?t.left-=l:t.left=n(t.left-a,t.left)},top:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollTop:s.offset.top,r=e.within.height,a=t.top-e.collisionPosition.marginTop,h=o-a,l=a+e.collisionHeight-r-o;e.collisionHeight>r?h>0&&l<=0?(i=t.top+h+e.collisionHeight-r-o,t.top+=h-i):t.top=l>0&&h<=0?o:h>l?o+r-e.collisionHeight:o:h>0?t.top+=h:l>0?t.top-=l:t.top=n(t.top-a,t.top)}},flip:{left:function(t,e){var i,s,o=e.within,n=o.offset.left+o.scrollLeft,a=o.width,h=o.isWindow?o.scrollLeft:o.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,p=l+e.collisionWidth-a-h,f="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,u="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,d=-2*e.offset[0];c<0?((i=t.left+f+u+d+e.collisionWidth-a-n)<0||i<r(c))&&(t.left+=f+u+d):p>0&&((s=t.left-e.collisionPosition.marginLeft+f+u+d-h)>0||r(s)<p)&&(t.left+=f+u+d)},top:function(t,e){var i,s,o=e.within,n=o.offset.top+o.scrollTop,a=o.height,h=o.isWindow?o.scrollTop:o.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,p=l+e.collisionHeight-a-h,f="top"===e.my[1],u=f?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,d="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];c<0?((s=t.top+u+d+g+e.collisionHeight-a-n)<0||s<r(c))&&(t.top+=u+d+g):p>0&&((i=t.top-e.collisionPosition.marginTop+u+d+g-h)>0||r(i)<p)&&(t.top+=u+d+g)}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}();var s=(t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,o=e?/(auto|scroll|hidden)/:/(auto|scroll)/,n=this.parents().filter(function(){var e=t(this);return(!s||"static"!==e.css("position"))&&o.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&n.length?n:t(this[0].ownerDocument||document)},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),!1);t(document).on("mouseup",function(){s=!1});t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){if(!0===t.data(i.target,e.widgetName+".preventClickEvent"))return t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,o=1===e.which,n=!("string"!=typeof this.options.cancel||!e.target.nodeName)&&t(e.target).closest(this.options.cancel).length;return!(o&&!n&&this._mouseCapture(e))||(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=!1!==this._mouseStart(e),!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0))}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||document.documentMode<9)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,e),this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var o,n=t.ui[e].prototype;for(o in s)n.plugins[o]=n.plugins[o]||[],n.plugins[o].push([i,s[o]])},call:function(t,e,i,s){var o,n=t.plugins[e];if(n&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(o=0;o<n.length;o++)t.options[n[o][0]]&&n[o][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")};t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){if((this.helper||this.element).is(".ui-draggable-dragging"))return void(this.destroyOnClear=!0);this._removeHandleClassName(),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return!(this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0)&&(this.handle=this._getHandle(e),!!this.handle&&(this._blurActiveElement(e),this._blockFrames(!0===i.iframeFix?"iframe":i.iframeFix),!0))},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]);t(e.target).closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),!1===this._trigger("start",e)?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(!1===this._trigger("drag",e,s))return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||!0===this.options.revert||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){!1!==i._trigger("stop",e)&&i._clear()}):!1!==this._trigger("stop",e)&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return!this.options.handle||!!t(e.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),o=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return o.parents("body").length||o.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&o[0]===this.element[0]&&this._setPositionRelative(),o[0]===this.element[0]||/(fixed|absolute)/.test(o.css("position"))||o.css("position","absolute"),o},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,o=this.options,n=this.document[0];return this.relativeContainer=null,o.containment?"window"===o.containment?void(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):"document"===o.containment?void(this.containment=[0,0,t(n).width()-this.helperProportions.width-this.margins.left,(t(n).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):o.containment.constructor===Array?void(this.containment=o.containment):("parent"===o.containment&&(o.containment=this.helper[0].parentNode),i=t(o.containment),void((s=i[0])&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i))):void(this.containment=null)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,o,n,r=this.options,a=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return a&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),r.grid&&(o=r.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/r.grid[1])*r.grid[1]:this.originalPageY,l=i?o-this.offset.click.top>=i[1]||o-this.offset.click.top>i[3]?o:o-this.offset.click.top>=i[1]?o-r.grid[1]:o+r.grid[1]:o,n=r.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/r.grid[0])*r.grid[0]:this.originalPageX,h=i?n-this.offset.click.left>=i[0]||n-this.offset.click.left>i[2]?n:n-this.offset.click.left>=i[0]?n-r.grid[0]:n+r.grid[0]:n),"y"===r.axis&&(h=this.originalPageX),"x"===r.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var o=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,o))})},stop:function(e,i,s){var o=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,o))})},drag:function(e,i,s){t.each(s.sortables,function(){var o=!1,n=this;n.positionAbs=s.positionAbs,n.helperProportions=s.helperProportions,n.offset.click=s.offset.click,n._intersectsWith(n.containerCache)&&(o=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==n&&this._intersectsWith(this.containerCache)&&t.contains(n.element[0],this.element[0])&&(o=!1),o})),o?(n.isOver||(n.isOver=1,s._parent=i.helper.parent(),n.currentItem=i.helper.appendTo(n.element).data("ui-sortable-item",!0),n.options._helper=n.options.helper,n.options.helper=function(){return i.helper[0]},e.target=n.currentItem[0],n._mouseCapture(e,!0),n._mouseStart(e,!0,!0),n.offset.click.top=s.offset.click.top,n.offset.click.left=s.offset.click.left,n.offset.parent.left-=s.offset.parent.left-n.offset.parent.left,
-n.offset.parent.top-=s.offset.parent.top-n.offset.parent.top,s._trigger("toSortable",e),s.dropped=n.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,n.fromOutside=s),n.currentItem&&(n._mouseDrag(e),i.position=n.position)):n.isOver&&(n.isOver=0,n.cancelHelperRemoval=!0,n.options._revert=n.options.revert,n.options.revert=!1,n._trigger("out",e,n._uiHash(n)),n._mouseStop(e,!0),n.options.revert=n.options._revert,n.options.helper=n.options._helper,n.placeholder&&n.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var o=t("body"),n=s.options;o.css("cursor")&&(n._cursor=o.css("cursor")),o.css("cursor",n.cursor)},stop:function(e,i,s){var o=s.options;o._cursor&&t("body").css("cursor",o._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var o=t(i.helper),n=s.options;o.css("opacity")&&(n._opacity=o.css("opacity")),o.css("opacity",n.opacity)},stop:function(e,i,s){var o=s.options;o._opacity&&t(i.helper).css("opacity",o._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var o=s.options,n=!1,r=s.scrollParentNotHidden[0],a=s.document[0];r!==a&&"HTML"!==r.tagName?(o.axis&&"x"===o.axis||(s.overflowOffset.top+r.offsetHeight-e.pageY<o.scrollSensitivity?r.scrollTop=n=r.scrollTop+o.scrollSpeed:e.pageY-s.overflowOffset.top<o.scrollSensitivity&&(r.scrollTop=n=r.scrollTop-o.scrollSpeed)),o.axis&&"y"===o.axis||(s.overflowOffset.left+r.offsetWidth-e.pageX<o.scrollSensitivity?r.scrollLeft=n=r.scrollLeft+o.scrollSpeed:e.pageX-s.overflowOffset.left<o.scrollSensitivity&&(r.scrollLeft=n=r.scrollLeft-o.scrollSpeed))):(o.axis&&"x"===o.axis||(e.pageY-t(a).scrollTop()<o.scrollSensitivity?n=t(a).scrollTop(t(a).scrollTop()-o.scrollSpeed):t(window).height()-(e.pageY-t(a).scrollTop())<o.scrollSensitivity&&(n=t(a).scrollTop(t(a).scrollTop()+o.scrollSpeed))),o.axis&&"y"===o.axis||(e.pageX-t(a).scrollLeft()<o.scrollSensitivity?n=t(a).scrollLeft(t(a).scrollLeft()-o.scrollSpeed):t(window).width()-(e.pageX-t(a).scrollLeft())<o.scrollSensitivity&&(n=t(a).scrollLeft(t(a).scrollLeft()+o.scrollSpeed)))),!1!==n&&t.ui.ddmanager&&!o.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var o=s.options;s.snapElements=[],t(o.snap.constructor!==String?o.snap.items||":data(ui-draggable)":o.snap).each(function(){var e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var o,n,r,a,h,l,c,p,f,u,d=s.options,g=d.snapTolerance,m=i.offset.left,v=m+s.helperProportions.width,_=i.offset.top,b=_+s.helperProportions.height;for(f=s.snapElements.length-1;f>=0;f--)h=s.snapElements[f].left-s.margins.left,l=h+s.snapElements[f].width,c=s.snapElements[f].top-s.margins.top,p=c+s.snapElements[f].height,v<h-g||m>l+g||b<c-g||_>p+g||!t.contains(s.snapElements[f].item.ownerDocument,s.snapElements[f].item)?(s.snapElements[f].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[f].item})),s.snapElements[f].snapping=!1):("inner"!==d.snapMode&&(o=Math.abs(c-b)<=g,n=Math.abs(p-_)<=g,r=Math.abs(h-v)<=g,a=Math.abs(l-m)<=g,o&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),n&&(i.position.top=s._convertPositionTo("relative",{top:p,left:0}).top),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),u=o||n||r||a,"outer"!==d.snapMode&&(o=Math.abs(c-_)<=g,n=Math.abs(p-b)<=g,r=Math.abs(h-m)<=g,a=Math.abs(l-v)<=g,o&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),n&&(i.position.top=s._convertPositionTo("relative",{top:p-s.helperProportions.height,left:0}).top),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[f].snapping&&(o||n||r||a||u)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[f].item})),s.snapElements[f].snapping=o||n||r||a||u)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var o,n=s.options,r=t.makeArray(t(n.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});r.length&&(o=parseInt(t(r[0]).css("zIndex"),10)||0,t(r).each(function(e){t(this).css("zIndex",o+e)}),this.css("zIndex",o+r.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var o=t(i.helper),n=s.options;o.css("zIndex")&&(n._zIndex=o.css("zIndex")),o.css("zIndex",n.zIndex)},stop:function(e,i,s){var o=s.options;o._zIndex&&t(i.helper).css("zIndex",o._zIndex)}});t.ui.draggable;t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){if(!arguments.length)return e||(e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight});e=arguments[0]},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return!(!s||(s.currentItem||s.element)[0]===this.element[0])&&(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");if(i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&o(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e))return n=!0,!1}),!n&&(!!this.accept.call(this.element[0],s.currentItem||s.element)&&(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element)))},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var o=t.ui.intersect=function(){function t(t,e,i){return t>=e&&t<e+i}return function(e,i,s,o){if(!i.offset)return!1;var n=(e.positionAbs||e.position.absolute).left+e.margins.left,r=(e.positionAbs||e.position.absolute).top+e.margins.top,a=n+e.helperProportions.width,h=r+e.helperProportions.height,l=i.offset.left,c=i.offset.top,p=l+i.proportions().width,f=c+i.proportions().height;switch(s){case"fit":return l<=n&&a<=p&&c<=r&&h<=f;case"intersect":return l<n+e.helperProportions.width/2&&a-e.helperProportions.width/2<p&&c<r+e.helperProportions.height/2&&h-e.helperProportions.height/2<f;case"pointer":return t(o.pageY,c,i.proportions().height)&&t(o.pageX,l,i.proportions().width);case"touch":return(r>=c&&r<=f||h>=c&&h<=f||r<c&&h>f)&&(n>=l&&n<=p||a>=l&&a<=p||n<l&&a>p);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{default:[]},prepareOffsets:function(e,i){var s,o,n=t.ui.ddmanager.droppables[e.options.scope]||[],r=i?i.type:null,a=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;s<n.length;s++)if(!(n[s].options.disabled||e&&!n[s].accept.call(n[s].element[0],e.currentItem||e.element))){for(o=0;o<a.length;o++)if(a[o]===n[s].element[0]){n[s].proportions().height=0;continue t}n[s].visible="none"!==n[s].element.css("display"),n[s].visible&&("mousedown"===r&&n[s]._activate.call(n[s],i),n[s].offset=n[s].element.offset(),n[s].proportions({width:n[s].element[0].offsetWidth,height:n[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&o(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,r,a=o(e,this,this.options.tolerance,i),h=!a&&this.isover?"isout":a&&!this.isover?"isover":null;h&&(this.options.greedy&&(n=this.options.scope,r=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),r.length&&(s=t(r[0]).droppable("instance"),s.greedyChild="isover"===h)),s&&"isover"===h&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[h]=!0,this["isout"===h?"isover":"isout"]=!1,this["isover"===h?"_over":"_out"].call(this,i),s&&"isout"===h&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},!1!==t.uiBackCompat&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}});t.ui.droppable;t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",o=!1;return e[s]>0||(e[s]=1,o=e[s]>0,e[s]=0,o)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles()}},_setupHandles:function(){var e,i,s,o,n,r=this.options,a=this;if(this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;i<s.length;i++)e=t.trim(s[i]),o="ui-resizable-"+e,n=t("<div>"),this._addClass(n,"ui-resizable-handle "+o),n.css({zIndex:r.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(n);this._renderAxis=function(e){var i,s,o,n;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:a._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),n=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),o=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(o,n),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,o=!1;for(i in this.handles)((s=t(this.handles[i])[0])===e.target||t.contains(s,e.target))&&(o=!0);return!this.options.disabled&&o},_mouseStart:function(e){var i,s,o,n=this.options,r=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),n.containment&&(i+=t(n.containment).scrollLeft()||0,s+=t(n.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:r.width(),height:r.height()},this.originalSize=this._helper?{width:r.outerWidth(),height:r.outerHeight()}:{width:r.width(),height:r.height()},this.sizeDiff={width:r.outerWidth()-r.width(),height:r.outerHeight()-r.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof n.aspectRatio?n.aspectRatio:this.originalSize.width/this.originalSize.height||1,o=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===o?this.axis+"-resize":o),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,o=this.originalMousePosition,n=this.axis,r=e.pageX-o.left||0,a=e.pageY-o.top||0,h=this._change[n];return this._updatePrevProperties(),!!h&&(i=h.apply(this,[e,r,a]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1)},_mouseStop:function(e){this.resizing=!1;var i,s,o,n,r,a,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,n=s?0:c.sizeDiff.width,r={width:c.helper.width()-n,height:c.helper.height()-o},a=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(r,{top:h,left:a})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,o,n,r=this.options;n={minWidth:this._isNumber(r.minWidth)?r.minWidth:0,maxWidth:this._isNumber(r.maxWidth)?r.maxWidth:1/0,minHeight:this._isNumber(r.minHeight)?r.minHeight:0,maxHeight:this._isNumber(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,s=n.minWidth/this.aspectRatio,i=n.maxHeight*this.aspectRatio,o=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),s>n.minHeight&&(n.minHeight=s),i<n.maxWidth&&(n.maxWidth=i),o<n.maxHeight&&(n.maxHeight=o)),this._vBoundaries=n},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,n=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,r=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return n&&(t.width=e.minWidth),r&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),n&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),r&&c&&(t.top=h-e.minHeight),o&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],o=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(o[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e<this._proportionallyResizeElements.length;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,o=i._proportionallyResizeElements,n=o.length&&/textarea/i.test(o[0].nodeName),r=n&&i._hasScroll(o[0],"left")?0:i.sizeDiff.height,a=n?0:i.sizeDiff.width,h={width:i.size.width-a,height:i.size.height-r},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};o&&o.length&&t(o[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,o,n,r,a,h=t(this).resizable("instance"),l=h.options,c=h.element,p=l.containment,f=p instanceof t?p.get(0):/parent/.test(p)?c.parent().get(0):p;f&&(h.containerElement=t(f),/document/.test(p)||p===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(f),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,o=h.containerSize.height,n=h.containerSize.width,r=h._hasScroll(f,"left")?f.scrollWidth:n,a=h._hasScroll(f)?f.scrollHeight:o,h.parentData={element:f,left:s.left,top:s.top,width:r,height:a}))},resize:function(e){var i,s,o,n,r=t(this).resizable("instance"),a=r.options,h=r.containerOffset,l=r.position,c=r._aspectRatio||e.shiftKey,p={top:0,left:0},f=r.containerElement,u=!0;f[0]!==document&&/static/.test(f.css("position"))&&(p=h),l.left<(r._helper?h.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-h.left:r.position.left-p.left),c&&(r.size.height=r.size.width/r.aspectRatio,u=!1),r.position.left=a.helper?h.left:0),l.top<(r._helper?h.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-h.top:r.position.top),c&&(r.size.width=r.size.height*r.aspectRatio,u=!1),r.position.top=r._helper?h.top:0),o=r.containerElement.get(0)===r.element.parent().get(0),n=/relative|absolute/.test(r.containerElement.css("position")),o&&n?(r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top):(r.offset.left=r.element.offset().left,r.offset.top=r.element.offset().top),i=Math.abs(r.sizeDiff.width+(r._helper?r.offset.left-p.left:r.offset.left-h.left)),s=Math.abs(r.sizeDiff.height+(r._helper?r.offset.top-p.top:r.offset.top-h.top)),i+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-i,c&&(r.size.height=r.size.width/r.aspectRatio,u=!1)),s+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-s,c&&(r.size.width=r.size.height*r.aspectRatio,u=!1)),u||(r.position.left=r.prevPosition.left,r.position.top=r.prevPosition.top,r.size.width=r.prevSize.width,r.size.height=r.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,o=e.containerPosition,n=e.containerElement,r=t(e.helper),a=r.offset(),h=r.outerWidth()-e.sizeDiff.width,l=r.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(n.css("position"))&&t(this).css({left:a.left-o.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(n.css("position"))&&t(this).css({left:a.left-o.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),o=s.options,n=s.originalSize,r=s.originalPosition,a={height:s.size.height-n.height||0,width:s.size.width-n.width||0,top:s.position.top-r.top||0,left:s.position.left-r.left||0};t(o.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),o={},n=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(n,function(t,e){var i=(s[e]||0)+(a[e]||0);i&&i>=0&&(o[e]=i||null)}),e.css(o)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),!1!==t.uiBackCompat&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,o=i.size,n=i.originalSize,r=i.originalPosition,a=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,p=Math.round((o.width-n.width)/l)*l,f=Math.round((o.height-n.height)/c)*c,u=n.width+p,d=n.height+f,g=s.maxWidth&&s.maxWidth<u,m=s.maxHeight&&s.maxHeight<d,v=s.minWidth&&s.minWidth>u,_=s.minHeight&&s.minHeight>d;s.grid=h,v&&(u+=l),_&&(d+=c),g&&(u-=l),m&&(d-=c),/^(se|s|e)$/.test(a)?(i.size.width=u,i.size.height=d):/^(ne)$/.test(a)?(i.size.width=u,i.size.height=d,i.position.top=r.top-f):/^(sw)$/.test(a)?(i.size.width=u,i.size.height=d,i.position.left=r.left-p):((d-c<=0||u-l<=0)&&(e=i._getPaddingPlusBorderDimensions(this)),d-c>0?(i.size.height=d,i.position.top=r.top-f):(d=c-e.height,i.size.height=d,i.position.top=r.top+n.height-d),u-l>0?(i.size.width=u,i.position.left=r.left-p):(u=l-e.width,i.size.width=u,i.position.left=r.left+n.width-u))}});var n=(t.ui.resizable,t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),o={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:o.left,top:o.top,right:o.left+i.outerWidth(),bottom:o.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,o=t.data(this,"selectable-item");if(o)return s=!e.metaKey&&!e.ctrlKey||!o.$element.hasClass("ui-selected"),i._removeClass(o.$element,s?"ui-unselecting":"ui-selected")._addClass(o.$element,s?"ui-selecting":"ui-unselecting"),o.unselecting=!s,o.selecting=s,o.selected=s,s?i._trigger("selecting",e,{selecting:o.element}):i._trigger("unselecting",e,{unselecting:o.element}),!1}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){
-var i,s=this,o=this.options,n=this.opos[0],r=this.opos[1],a=e.pageX,h=e.pageY;return n>a&&(i=a,a=n,n=i),r>h&&(i=h,h=r,r=i),this.helper.css({left:n,top:r,width:a-n,height:h-r}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===o.tolerance?l=!(c.left>a||c.right<n||c.top>h||c.bottom<r):"fit"===o.tolerance&&(l=c.left>n&&c.right<a&&c.top>r&&c.bottom<h),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&t<e+i},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,o=!1,n=this;return!this.reverting&&(!this.options.disabled&&"static"!==this.options.type&&(this._refreshItems(e),t(e.target).parents().each(function(){if(t.data(this,n.widgetName+"-item")===n)return s=t(this),!1}),t.data(e.target,n.widgetName+"-item")===n&&(s=t(e.target)),!!s&&(!(this.options.handle&&!i&&(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(o=!0)}),!o))&&(this.currentItem=s,this._removeCurrentsFromItems(),!0))))},_mouseStart:function(e,i,s){var o,n,r=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,r.cursorAt&&this._adjustOffsetFromHelper(r.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),r.containment&&this._setContainment(),r.cursor&&"auto"!==r.cursor&&(n=this.document.find("body"),this.storedCursor=n.css("cursor"),n.css("cursor",r.cursor),this.storedStylesheet=t("<style>*{ cursor: "+r.cursor+" !important; }</style>").appendTo(n)),r.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",r.opacity)),r.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",r.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(o=this.containers.length-1;o>=0;o--)this.containers[o]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!r.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,o,n,r=this.options,a=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<r.scrollSensitivity?this.scrollParent[0].scrollTop=a=this.scrollParent[0].scrollTop+r.scrollSpeed:e.pageY-this.overflowOffset.top<r.scrollSensitivity&&(this.scrollParent[0].scrollTop=a=this.scrollParent[0].scrollTop-r.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<r.scrollSensitivity?this.scrollParent[0].scrollLeft=a=this.scrollParent[0].scrollLeft+r.scrollSpeed:e.pageX-this.overflowOffset.left<r.scrollSensitivity&&(this.scrollParent[0].scrollLeft=a=this.scrollParent[0].scrollLeft-r.scrollSpeed)):(e.pageY-this.document.scrollTop()<r.scrollSensitivity?a=this.document.scrollTop(this.document.scrollTop()-r.scrollSpeed):this.window.height()-(e.pageY-this.document.scrollTop())<r.scrollSensitivity&&(a=this.document.scrollTop(this.document.scrollTop()+r.scrollSpeed)),e.pageX-this.document.scrollLeft()<r.scrollSensitivity?a=this.document.scrollLeft(this.document.scrollLeft()-r.scrollSpeed):this.window.width()-(e.pageX-this.document.scrollLeft())<r.scrollSensitivity&&(a=this.document.scrollLeft(this.document.scrollLeft()+r.scrollSpeed))),!1!==a&&t.ui.ddmanager&&!r.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],o=s.item[0],(n=this._intersectsWithPointer(s))&&s.instance===this.currentContainer&&!(o===this.currentItem[0]||this.placeholder[1===n?"next":"prev"]()[0]===o||t.contains(this.placeholder[0],o)||"semi-dynamic"===this.options.type&&t.contains(this.element[0],o))){if(this.direction=1===n?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,o=this.placeholder.offset(),n=this.options.axis,r={};n&&"x"!==n||(r.left=o.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),n&&"y"!==n||(r.top=o.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(r,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,o=s+this.helperProportions.height,n=t.left,r=n+t.width,a=t.top,h=a+t.height,l=this.offset.click.top,c=this.offset.click.left,p="x"===this.options.axis||s+l>a&&s+l<h,f="y"===this.options.axis||e+c>n&&e+c<r,u=p&&f;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?u:n<e+this.helperProportions.width/2&&i-this.helperProportions.width/2<r&&a<s+this.helperProportions.height/2&&o-this.helperProportions.height/2<h},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),o="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width);return!(!s||!o)&&(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1))},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&i||"left"===o&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){a.push(this)}var s,o,n,r,a=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(n=t(l[s],this.document[0]),o=n.length-1;o>=0;o--)(r=t.data(n[o],this.widgetFullName))&&r!==this&&!r.options.disabled&&h.push([t.isFunction(r.options.items)?r.options.items.call(r.element):t(r.options.items,r.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),r]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(a)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;i<e.length;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,o,n,r,a,h,l,c=this.items,p=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],f=this._connectWith();if(f&&this.ready)for(i=f.length-1;i>=0;i--)for(o=t(f[i],this.document[0]),s=o.length-1;s>=0;s--)(n=t.data(o[s],this.widgetFullName))&&n!==this&&!n.options.disabled&&(p.push([t.isFunction(n.options.items)?n.options.items.call(n.element[0],e,{item:this.currentItem}):t(n.options.items,n.element),n]),this.containers.push(n));for(i=p.length-1;i>=0;i--)for(r=p[i][1],a=p[i][0],s=0,l=a.length;s<l;s++)h=t(a[s]),h.data(this.widgetName+"-item",r),c.push({item:h,instance:r,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=!!this.items.length&&("x"===this.options.axis||this._isFloating(this.items[0].item)),this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,o,n;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(o=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=o.outerWidth(),s.height=o.outerHeight()),n=o.offset(),s.left=n.left,s.top=n.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)n=this.containers[i].element.offset(),this.containers[i].containerCache.left=n.left,this.containers[i].containerCache.top=n.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),o=t("<"+s+">",e.document[0]);return e._addClass(o,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(o,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("<tr>",e.document[0]).appendTo(o)):"tr"===s?e._createTrPlaceholder(e.currentItem,o):"img"===s&&o.attr("src",e.currentItem.attr("src")),i||o.css("visibility","hidden"),o},update:function(t,o){i&&!s.forcePlaceholderSize||(o.height()||o.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),o.width()||o.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("<td>&#160;</td>",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,o,n,r,a,h,l,c,p,f=null,u=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(f&&t.contains(this.containers[i].element[0],f.element[0]))continue;f=this.containers[i],u=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",e,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(o=1e4,n=null,c=f.floating||this._isFloating(this.currentItem),r=c?"left":"top",a=c?"width":"height",p=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[u].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[r],l=!1,e[p]-h>this.items[s][a]/2&&(l=!0),Math.abs(e[p]-h)<o&&(o=Math.abs(e[p]-h),n=this.items[s],this.direction=l?"up":"down"));if(!n&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[u])return void(this.currentContainer.containerCache.over||(this.containers[u]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1));n?this._rearrange(e,n,null,!0):this._rearrange(e,null,this.containers[u].element,!0),this._trigger("change",e,this._uiHash()),this.containers[u]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[u],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[u]._trigger("over",e,this._uiHash(this)),this.containers[u].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),s[0].style.width&&!i.forceHelperSize||s.width(this.currentItem.width()),s[0].style.height&&!i.forceHelperSize||s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,o=this.options;"parent"===o.containment&&(o.containment=this.helper[0].parentNode),"document"!==o.containment&&"window"!==o.containment||(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===o.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===o.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(o.containment)||(e=t(o.containment)[0],i=t(o.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,o="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,n=/(html|body)/i.test(o[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():n?0:o.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():n?0:o.scrollLeft())*s}},_generatePosition:function(e){var i,s,o=this.options,n=e.pageX,r=e.pageY,a="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(a[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(n=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(r=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(n=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(r=this.containment[3]+this.offset.click.top)),o.grid&&(i=this.originalPageY+Math.round((r-this.originalPageY)/o.grid[1])*o.grid[1],r=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-o.grid[1]:i+o.grid[1]:i,s=this.originalPageX+Math.round((n-this.originalPageX)/o.grid[0])*o.grid[0],n=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-o.grid[0]:s+o.grid[0]:s)),{top:r-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:a.scrollTop()),left:n-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:a.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var o=this.counter;this._delay(function(){o===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,o=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)"auto"!==this._storedCSS[s]&&"static"!==this._storedCSS[s]||(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&o.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||o.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(o.push(function(t){this._trigger("remove",t,this._uiHash())}),o.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),o.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||o.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(o.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;s<o.length;s++)o[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){!1===t.Widget.prototype._trigger.apply(this,arguments)&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),"ui-effects-animated"),r=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=c[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:s.max<t?s.max:t)}function s(e){var i=h(),s=i._rgba=[];return e=e.toLowerCase(),u(a,function(t,o){var n,r=o.re.exec(e),a=r&&o.parse(r),h=o.space||"rgba";if(a)return n=i[h](a),i[l[h].cache]=n[l[h].cache],s=i._rgba=n._rgba,!1}),s.length?("0,0,0,0"===s.join()&&t.extend(s,n.transparent),i):n[e]}function o(t,e,i){return i=(i+1)%1,6*i<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}var n,r=/^([\-+])=\s*(\d+\.?\d*)/,a=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,o){return new t.Color.fn.parse(e,i,s,o)},l={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},c={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},p=h.support={},f=t("<p>")[0],u=t.each;f.style.cssText="background-color:rgba(1,1,1,.5)",p.rgba=f.style.backgroundColor.indexOf("rgba")>-1,u(l,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(e,o,r,a){if(void 0===e)return this._rgba=[null,null,null,null],this;(e.jquery||e.nodeType)&&(e=t(e).css(o),o=void 0);var c=this,p=t.type(e),f=this._rgba=[];return void 0!==o&&(e=[e,o,r,a],p="array"),"string"===p?this.parse(s(e)||n._default):"array"===p?(u(l.rgba.props,function(t,s){f[s.idx]=i(e[s.idx],s)}),this):"object"===p?(e instanceof h?u(l,function(t,i){e[i.cache]&&(c[i.cache]=e[i.cache].slice())}):u(l,function(s,o){var n=o.cache;u(o.props,function(t,s){if(!c[n]&&o.to){if("alpha"===t||null==e[t])return;c[n]=o.to(c._rgba)}c[n][s.idx]=i(e[t],s,!0)}),c[n]&&t.inArray(null,c[n].slice(0,3))<0&&(c[n][3]=1,o.from&&(c._rgba=o.from(c[n])))}),this):void 0},is:function(t){var e=h(t),i=!0,s=this;return u(l,function(t,o){var n,r=e[o.cache];return r&&(n=s[o.cache]||o.to&&o.to(s._rgba)||[],u(o.props,function(t,e){if(null!=r[e.idx])return i=r[e.idx]===n[e.idx]})),i}),i},_space:function(){var t=[],e=this;return u(l,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),o=s._space(),n=l[o],r=0===this.alpha()?h("transparent"):this,a=r[n.cache]||n.to(r._rgba),p=a.slice();return s=s[n.cache],u(n.props,function(t,o){var n=o.idx,r=a[n],h=s[n],l=c[o.type]||{};null!==h&&(null===r?p[n]=h:(l.mod&&(h-r>l.mod/2?r+=l.mod:r-h>l.mod/2&&(r-=l.mod)),p[n]=i((h-r)*e+r,o)))}),this[o](p)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),o=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*o[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&e<3&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,l.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,o=t[1]/255,n=t[2]/255,r=t[3],a=Math.max(s,o,n),h=Math.min(s,o,n),l=a-h,c=a+h,p=.5*c;return e=h===a?0:s===a?60*(o-n)/l+360:o===a?60*(n-s)/l+120:60*(s-o)/l+240,i=0===l?0:p<=.5?l/c:l/(2-c),[Math.round(e)%360,i,p,null==r?1:r]},l.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],n=t[3],r=s<=.5?s*(1+i):s+i-s*i,a=2*s-r;return[Math.round(255*o(a,r,e+1/3)),Math.round(255*o(a,r,e)),Math.round(255*o(a,r,e-1/3)),n]},u(l,function(e,s){var o=s.props,n=s.cache,a=s.to,l=s.from;h.fn[e]=function(e){if(a&&!this[n]&&(this[n]=a(this._rgba)),void 0===e)return this[n].slice();var s,r=t.type(e),c="array"===r||"object"===r?e:arguments,p=this[n].slice();return u(o,function(t,e){var s=c["object"===r?t:e.idx];null==s&&(s=p[e.idx]),p[e.idx]=i(s,e)}),l?(s=h(l(p)),s[n]=p,s):h(p)},u(o,function(i,s){h.fn[i]||(h.fn[i]=function(o){var n,a=t.type(o),h="alpha"===i?this._hsla?"hsla":"rgba":e,l=this[h](),c=l[s.idx];return"undefined"===a?c:("function"===a&&(o=o.call(this,c),a=t.type(o)),null==o&&s.empty?this:("string"===a&&(n=r.exec(o))&&(o=c+parseFloat(n[2])*("+"===n[1]?1:-1)),l[s.idx]=o,this[h](l)))})})}),h.hook=function(e){var i=e.split(" ");u(i,function(e,i){t.cssHooks[i]={set:function(e,o){var n,r,a=""
-;if("transparent"!==o&&("string"!==t.type(o)||(n=s(o)))){if(o=h(n||o),!p.rgba&&1!==o._rgba[3]){for(r="backgroundColor"===i?e.parentNode:e;(""===a||"transparent"===a)&&r&&r.style;)try{a=t.css(r,"backgroundColor"),r=r.parentNode}catch(t){}o=o.blend(a&&"transparent"!==a?a:"_default")}o=o.toRgbaString()}try{e.style[i]=o}catch(t){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor"),t.cssHooks.borderColor={expand:function(t){var e={};return u(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},n=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(r),function(){function e(e){var i,s,o=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,n={};if(o&&o.length&&o[0]&&o[o[0]])for(s=o.length;s--;)i=o[s],"string"==typeof o[i]&&(n[t.camelCase(i)]=o[i]);else for(i in o)"string"==typeof o[i]&&(n[i]=o[i]);return n}function i(e,i){var s,n,r={};for(s in i)n=i[s],e[s]!==n&&(o[s]||!t.fx.step[s]&&isNaN(parseFloat(n))||(r[s]=n));return r}var s=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(r.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(o,n,r,a){var h=t.speed(n,r,a);return this.queue(function(){var n,r=t(this),a=r.attr("class")||"",l=h.children?r.find("*").addBack():r;l=l.map(function(){return{el:t(this),start:e(this)}}),n=function(){t.each(s,function(t,e){o[e]&&r[e+"Class"](o[e])})},n(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),r.attr("class",a),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){n(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(r[0])})})},t.fn.extend({addClass:function(e){return function(i,s,o,n){return s?t.effects.animateClass.call(this,{add:i},s,o,n):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,o,n){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,o,n):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,o,n,r){return"boolean"==typeof s||void 0===s?o?t.effects.animateClass.call(this,s?{add:i}:{remove:i},o,n,r):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,o,n)}}(t.fn.toggleClass),switchClass:function(e,i,s,o,n){return t.effects.animateClass.call(this,{add:i,remove:e},s,o,n)}})}(),function(){function e(e,i,s,o){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(o=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(o=s,s=i,i={}),t.isFunction(s)&&(o=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=o||i.complete,e}function i(e){return!(e&&"number"!=typeof e&&!t.fx.speeds[e])||("string"==typeof e&&!t.effects.effect[e]||(!!t.isFunction(e)||"object"==typeof e&&!e.effect))}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),o=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,n=o.exec(t)||["",0,i,s,0];return{top:parseFloat(n[1])||0,right:"auto"===n[2]?i:parseFloat(n[2]),bottom:"auto"===n[3]?s:parseFloat(n[3]),left:parseFloat(n[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(n)||e(i)}}(t.expr.filters.animated)),!1!==t.uiBackCompat&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;i<s;i++)null!==e[i]&&t.data("ui-effects-"+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,o=e.length;s<o;s++)null!==e[s]&&(i=t.data("ui-effects-"+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),float:e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),o={width:e.width(),height:e.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return e.wrap(s),(e[0]===n||t.contains(e[0],n))&&t(n).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(o),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,o="vertical"!==i?(e||100)/100:1;return{height:t.height()*o,width:t.width()*s,outerHeight:t.outerHeight()*o,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data("ui-effects-style",t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data("ui-effects-style")||"",t.removeData("ui-effects-style")},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),o=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),float:e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data("ui-effects-placeholder",i)),e.css({position:s,left:o.left,top:o.top}),i},removePlaceholder:function(t){var e="ui-effects-placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,o){return o=o||{},t.each(i,function(t,i){var n=e.cssUnit(i);n[0]>0&&(o[i]=n[0]*s+n[1])}),o}}),t.fn.extend({effect:function(){function i(e){function i(){h.removeData(n),t.effects.cleanUp(h),"hide"===s.mode&&h.hide(),a()}function a(){t.isFunction(l)&&l.call(h[0]),t.isFunction(e)&&e()}var h=t(this);s.mode=p.shift(),!1===t.uiBackCompat||r?"none"===s.mode?(h[c](),a()):o.call(h[0],s,i):(h.is(":hidden")?"hide"===c:"show"===c)?(h[c](),a()):o.call(h[0],s,a)}var s=e.apply(this,arguments),o=t.effects.effect[s.effect],r=o.mode,a=s.queue,h=a||"fx",l=s.complete,c=s.mode,p=[],f=function(e){var i=t(this),s=t.effects.mode(i,c)||r;i.data(n,!0),p.push(s),r&&("show"===s||s===r&&"hide"===s)&&i.show(),r&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!o?c?this[c](s.duration,l):this.each(function(){l&&l.call(this)}):!1===a?this.each(f).each(i):this.queue(h,f).queue(h,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var o=e.apply(this,arguments);return o.mode="show",this.effect.call(this,o)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var o=e.apply(this,arguments);return o.mode="hide",this.effect.call(this,o)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var o=e.apply(this,arguments);return o.mode="toggle",this.effect.call(this,o)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),o=t(e.to),n="fixed"===o.css("position"),r=t("body"),a=n?r.scrollTop():0,h=n?r.scrollLeft():0,l=o.offset(),c={top:l.top-a,left:l.left-h,height:o.innerHeight(),width:o.innerWidth()},p=s.offset(),f=t("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(e.className).css({top:p.top-a,left:p.left-h,height:s.innerHeight(),width:s.innerWidth(),position:n?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){f.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return t<.5?i(2*t)/2:1-i(-2*t+2)/2}})}();t.effects,t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},o=t(this),n=e.direction||"up",r=o.cssClip(),a={clip:t.extend({},r)},h=t.effects.createPlaceholder(o);a.clip[s[n][0]]=a.clip[s[n][1]],"show"===e.mode&&(o.cssClip(a.clip),h&&h.css(t.effects.clipToBox(a)),a.clip=r),h&&h.animate(t.effects.clipToBox(a),e.duration,e.easing),o.animate(a,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,o,n,r=t(this),a=e.mode,h="hide"===a,l="show"===a,c=e.direction||"up",p=e.distance,f=e.times||5,u=2*f+(l||h?1:0),d=e.duration/u,g=e.easing,m="up"===c||"down"===c?"top":"left",v="up"===c||"left"===c,_=0,b=r.queue().length;for(t.effects.createPlaceholder(r),n=r.css(m),p||(p=r["top"===m?"outerHeight":"outerWidth"]()/3),l&&(o={opacity:1},o[m]=n,r.css("opacity",0).css(m,v?2*-p:2*p).animate(o,d,g)),h&&(p/=Math.pow(2,f-1)),o={},o[m]=n;_<f;_++)s={},s[m]=(v?"-=":"+=")+p,r.animate(s,d,g).animate(o,d,g),p=h?2*p:p/2;h&&(s={opacity:0},s[m]=(v?"-=":"+=")+p,r.animate(s,d,g)),r.queue(i),t.effects.unshift(r,b,u+1)}),t.effects.define("drop","hide",function(e,i){var s,o=t(this),n=e.mode,r="show"===n,a=e.direction||"left",h="up"===a||"down"===a?"top":"left",l="up"===a||"left"===a?"-=":"+=",c="+="===l?"-=":"+=",p={opacity:0};t.effects.createPlaceholder(o),s=e.distance||o["top"===h?"outerHeight":"outerWidth"](!0)/2,p[h]=l+s,r&&(o.css(p),p[h]=c+s,p.opacity=1),o.animate(p,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),o=e.mode,n="show"===o,r="hide"===o,a=e.size||15,h=/([0-9]+)%/.exec(a),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],p=e.duration/2,f=t.effects.createPlaceholder(s),u=s.cssClip(),d={clip:t.extend({},u)},g={clip:t.extend({},u)},m=[u[c[0]],u[c[1]]],v=s.queue().length;h&&(a=parseInt(h[1],10)/100*m[r?0:1]),d.clip[c[0]]=a,g.clip[c[0]]=a,g.clip[c[1]]=0,n&&(s.cssClip(g.clip),f&&f.css(t.effects.clipToBox(g)),g.clip=u),s.queue(function(i){f&&f.animate(t.effects.clipToBox(d),p,e.easing).animate(t.effects.clipToBox(g),p,e.easing),i()}).animate(d,p,e.easing).animate(g,p,e.easing).queue(i),t.effects.unshift(s,v,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),o={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(o.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(o,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,o,n,r=t(this),a=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,p="effect"!==c,f=e.scale||"both",u=e.origin||["middle","center"],d=r.css("position"),g=r.position(),m=t.effects.scaledDimensions(r),v=e.from||m,_=e.to||t.effects.scaledDimensions(r,0);t.effects.createPlaceholder(r),"show"===c&&(n=v,v=_,_=n),o={from:{y:v.height/m.height,x:v.width/m.width},to:{y:_.height/m.height,x:_.width/m.width}},"box"!==f&&"both"!==f||(o.from.y!==o.to.y&&(v=t.effects.setTransition(r,h,o.from.y,v),_=t.effects.setTransition(r,h,o.to.y,_)),o.from.x!==o.to.x&&(v=t.effects.setTransition(r,l,o.from.x,v),_=t.effects.setTransition(r,l,o.to.x,_))),"content"!==f&&"both"!==f||o.from.y!==o.to.y&&(v=t.effects.setTransition(r,a,o.from.y,v),_=t.effects.setTransition(r,a,o.to.y,_)),u&&(s=t.effects.getBaseline(u,m),v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left,_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left),r.css(v),"content"!==f&&"both"!==f||(h=h.concat(["marginTop","marginBottom"]).concat(a),l=l.concat(["marginLeft","marginRight"]),r.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),n={height:s.height*o.from.y,width:s.width*o.from.x,outerHeight:s.outerHeight*o.from.y,outerWidth:s.outerWidth*o.from.x},r={height:s.height*o.to.y,width:s.width*o.to.x,outerHeight:s.height*o.to.y,outerWidth:s.width*o.to.x};o.from.y!==o.to.y&&(n=t.effects.setTransition(i,h,o.from.y,n),r=t.effects.setTransition(i,h,o.to.y,r)),o.from.x!==o.to.x&&(n=t.effects.setTransition(i,l,o.from.x,n),r=t.effects.setTransition(i,l,o.to.x,r)),p&&t.effects.saveStyle(i),i.css(n),i.animate(r,e.duration,e.easing,function(){p&&t.effects.restoreStyle(i)})})),r.animate(_,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=r.offset();0===_.opacity&&r.css("opacity",v.opacity),p||(r.css("position","static"===d?"relative":d).offset(e),t.effects.saveStyle(r)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),o=e.mode,n=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==o?0:100),r=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,n,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(r.from.opacity=1,r.to.opacity=0),t.effects.effect.size.call(this,r,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),o=e.mode,n="show"===o,r="hide"===o,a=n||r,h=2*(e.times||5)+(a?1:0),l=e.duration/h,c=0,p=1,f=s.queue().length;for(!n&&s.is(":visible")||(s.css("opacity",0).show(),c=1);p<h;p++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,f,h+1)}),t.effects.define("shake",function(e,i){var s=1,o=t(this),n=e.direction||"left",r=e.distance||20,a=e.times||3,h=2*a+1,l=Math.round(e.duration/h),c="up"===n||"down"===n?"top":"left",p="up"===n||"left"===n,f={},u={},d={},g=o.queue().length;for(t.effects.createPlaceholder(o),f[c]=(p?"-=":"+=")+r,u[c]=(p?"+=":"-=")+2*r,d[c]=(p?"-=":"+=")+2*r,o.animate(f,l,e.easing);s<a;s++)o.animate(u,l,e.easing).animate(d,l,e.easing);o.animate(u,l,e.easing).animate(f,l/2,e.easing).queue(i),t.effects.unshift(o,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,o,n=t(this),r={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},a=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,p=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0),f={};t.effects.createPlaceholder(n),s=n.cssClip(),o=n.position()[l],f[l]=(c?-1:1)*p+o,f.clip=n.cssClip(),f.clip[r[h][1]]=f.clip[r[h][0]],"show"===a&&(n.cssClip(f.clip),n.css(l,f[l]),f.clip=s,f[l]=o),n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});!1!==t.uiBackCompat&&t.effects.define("transfer",function(e,i){t(this).transfer(e,i)})}); })(this);
+(function (window, undefined) { !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(P){P.ui=P.ui||{};P.ui.version="1.12.1";var o,i=0,a=Array.prototype.slice;P.cleanData=(o=P.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)try{(e=P._data(i,"events"))&&e.remove&&P(i).triggerHandler("remove")}catch(t){}o(t)}),P.widget=function(t,i,e){var s,o,n,r={},a=t.split(".")[0],h=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=P.Widget),P.isArray(e)&&(e=P.extend.apply(null,[{}].concat(e))),P.expr[":"][h.toLowerCase()]=function(t){return!!P.data(t,h)},P[a]=P[a]||{},s=P[a][t],o=P[a][t]=function(t,e){if(!this._createWidget)return new o(t,e);arguments.length&&this._createWidget(t,e)},P.extend(o,s,{version:e.version,_proto:P.extend({},e),_childConstructors:[]}),(n=new i).options=P.widget.extend({},n.options),P.each(e,function(e,s){function o(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}P.isFunction(s)?r[e]=function(){var t,e=this._super,i=this._superApply;return this._super=o,this._superApply=n,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:r[e]=s}),o.prototype=P.widget.extend(n,{widgetEventPrefix:s&&n.widgetEventPrefix||t},r,{constructor:o,namespace:a,widgetName:t,widgetFullName:h}),s?(P.each(s._childConstructors,function(t,e){var i=e.prototype;P.widget(i.namespace+"."+i.widgetName,o,e._proto)}),delete s._childConstructors):i._childConstructors.push(o),P.widget.bridge(t,o),o},P.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),o=0,n=s.length;o<n;o++)for(e in s[o])i=s[o][e],s[o].hasOwnProperty(e)&&void 0!==i&&(P.isPlainObject(i)?t[e]=P.isPlainObject(t[e])?P.widget.extend({},t[e],i):P.widget.extend({},i):t[e]=i);return t},P.widget.bridge=function(n,e){var r=e.prototype.widgetFullName||n;P.fn[n]=function(i){var t="string"==typeof i,s=a.call(arguments,1),o=this;return t?this.length||"instance"!==i?this.each(function(){var t,e=P.data(this,r);return"instance"===i?(o=e,!1):e?P.isFunction(e[i])&&"_"!==i.charAt(0)?(t=e[i].apply(e,s))!==e&&void 0!==t?(o=t&&t.jquery?o.pushStack(t.get()):t,!1):void 0:P.error("no such method '"+i+"' for "+n+" widget instance"):P.error("cannot call methods on "+n+" prior to initialization; attempted to call method '"+i+"'")}):o=void 0:(s.length&&(i=P.widget.extend.apply(null,[i].concat(s))),this.each(function(){var t=P.data(this,r);t?(t.option(i||{}),t._init&&t._init()):P.data(this,r,new e(i,this))})),o}},P.Widget=function(){},P.Widget._childConstructors=[],P.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=P(e||this.defaultElement||this)[0],this.element=P(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=P(),this.hoverable=P(),this.focusable=P(),this.classesElementLookup={},e!==this&&(P.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=P(e.style?e.ownerDocument:e.document||e),this.window=P(this.document[0].defaultView||this.document[0].parentWindow)),this.options=P.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:P.noop,_create:P.noop,_init:P.noop,destroy:function(){var i=this;this._destroy(),P.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:P.noop,widget:function(){return this.element},option:function(t,e){var i,s,o,n=t;if(0===arguments.length)return P.widget.extend({},this.options);if("string"==typeof t)if(n={},t=(i=t.split(".")).shift(),i.length){for(s=n[t]=P.widget.extend({},this.options[t]),o=0;o<i.length-1;o++)s[i[o]]=s[i[o]]||{},s=s[i[o]];if(t=i.pop(),1===arguments.length)return void 0===s[t]?null:s[t];s[t]=e}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];n[t]=e}return this._setOptions(n),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(t){var e,i,s;for(e in t)s=this.classesElementLookup[e],t[e]!==this.options.classes[e]&&s&&s.length&&(i=P(s.get()),this._removeClass(s,e),i.addClass(this._classes({element:i,keys:e,classes:t,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(o){var n=[],r=this;function t(t,e){for(var i,s=0;s<t.length;s++)i=r.classesElementLookup[t[s]]||P(),i=o.add?P(P.unique(i.get().concat(o.element.get()))):P(i.not(o.element).get()),r.classesElementLookup[t[s]]=i,n.push(t[s]),e&&o.classes[t[s]]&&n.push(o.classes[t[s]])}return o=P.extend({element:this.element,classes:this.options.classes||{}},o),this._on(o.element,{remove:"_untrackClassesElement"}),o.keys&&t(o.keys.match(/\S+/g)||[],!0),o.extra&&t(o.extra.match(/\S+/g)||[]),n.join(" ")},_untrackClassesElement:function(i){var s=this;P.each(s.classesElementLookup,function(t,e){-1!==P.inArray(i.target,e)&&(s.classesElementLookup[t]=P(e.not(i.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var o="string"==typeof t||null===t,n={extra:o?e:i,keys:o?t:e,element:o?this.element:t,add:s};return n.element.toggleClass(this._classes(n),s),this},_on:function(r,a,t){var h,l=this;"boolean"!=typeof r&&(t=a,a=r,r=!1),t?(a=h=P(a),this.bindings=this.bindings.add(a)):(t=a,a=this.element,h=this.widget()),P.each(t,function(t,e){function i(){if(r||!0!==l.options.disabled&&!P(this).hasClass("ui-state-disabled"))return("string"==typeof e?l[e]:e).apply(l,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||P.guid++);var s=t.match(/^([\w:-]*)\s*(.*)$/),o=s[1]+l.eventNamespace,n=s[2];n?h.on(o,n,i):a.on(o,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e).off(e),this.bindings=P(this.bindings.not(t).get()),this.focusable=P(this.focusable.not(t).get()),this.hoverable=P(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(P(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(P(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(P(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(P(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var s,o,n=this.options[t];if(i=i||{},(e=P.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],o=e.originalEvent)for(s in o)s in e||(e[s]=o[s]);return this.element.trigger(e,i),!(P.isFunction(n)&&!1===n.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},P.each({show:"fadeIn",hide:"fadeOut"},function(n,r){P.Widget.prototype["_"+n]=function(e,t,i){var s;"string"==typeof t&&(t={effect:t});var o=t?!0!==t&&"number"!=typeof t&&t.effect||r:n;"number"==typeof(t=t||{})&&(t={duration:t}),s=!P.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),s&&P.effects&&P.effects.effect[o]?e[n](t):o!==n&&e[o]?e[o](t.duration,t.easing,i):e.queue(function(t){P(this)[n](),i&&i.call(e[0]),t()})}});var n,x,C,s,r,h,l,c,z;P.widget;function H(t,e,i){return[parseFloat(t[0])*(c.test(t[0])?e/100:1),parseFloat(t[1])*(c.test(t[1])?i/100:1)]}function I(t,e){return parseInt(P.css(t,e),10)||0}x=Math.max,C=Math.abs,s=/left|center|right/,r=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,l=/^\w+/,c=/%$/,z=P.fn.position,P.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,e,i=P("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),s=i.children()[0];return P("body").append(i),t=s.offsetWidth,i.css("overflow","scroll"),t===(e=s.offsetWidth)&&(e=i[0].clientWidth),i.remove(),n=t-e},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),s="scroll"===e||"auto"===e&&t.width<t.element[0].scrollWidth;return{width:"scroll"===i||"auto"===i&&t.height<t.element[0].scrollHeight?P.position.scrollbarWidth():0,height:s?P.position.scrollbarWidth():0}},getWithinInfo:function(t){var e=P(t||window),i=P.isWindow(e[0]),s=!!e[0]&&9===e[0].nodeType;return{element:e,isWindow:i,isDocument:s,offset:!i&&!s?P(t).offset():{left:0,top:0},scrollLeft:e.scrollLeft(),scrollTop:e.scrollTop(),width:e.outerWidth(),height:e.outerHeight()}}},P.fn.position=function(p){if(!p||!p.of)return z.apply(this,arguments);p=P.extend({},p);var f,u,d,g,m,t,e,v=P(p.of),_=P.position.getWithinInfo(p.within),b=P.position.getScrollInfo(_),w=(p.collision||"flip").split(" "),y={},i=9===(e=(t=v)[0]).nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:P.isWindow(e)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:e.preventDefault?{width:0,height:0,offset:{top:e.pageY,left:e.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()};return v[0].preventDefault&&(p.at="left top"),u=i.width,d=i.height,g=i.offset,m=P.extend({},g),P.each(["my","at"],function(){var t,e,i=(p[this]||"").split(" ");1===i.length&&(i=s.test(i[0])?i.concat(["center"]):r.test(i[0])?["center"].concat(i):["center","center"]),i[0]=s.test(i[0])?i[0]:"center",i[1]=r.test(i[1])?i[1]:"center",t=h.exec(i[0]),e=h.exec(i[1]),y[this]=[t?t[0]:0,e?e[0]:0],p[this]=[l.exec(i[0])[0],l.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===p.at[0]?m.left+=u:"center"===p.at[0]&&(m.left+=u/2),"bottom"===p.at[1]?m.top+=d:"center"===p.at[1]&&(m.top+=d/2),f=H(y.at,u,d),m.left+=f[0],m.top+=f[1],this.each(function(){var i,t,r=P(this),a=r.outerWidth(),h=r.outerHeight(),e=I(this,"marginLeft"),s=I(this,"marginTop"),o=a+e+I(this,"marginRight")+b.width,n=h+s+I(this,"marginBottom")+b.height,l=P.extend({},m),c=H(y.my,r.outerWidth(),r.outerHeight());"right"===p.my[0]?l.left-=a:"center"===p.my[0]&&(l.left-=a/2),"bottom"===p.my[1]?l.top-=h:"center"===p.my[1]&&(l.top-=h/2),l.left+=c[0],l.top+=c[1],i={marginLeft:e,marginTop:s},P.each(["left","top"],function(t,e){P.ui.position[w[t]]&&P.ui.position[w[t]][e](l,{targetWidth:u,targetHeight:d,elemWidth:a,elemHeight:h,collisionPosition:i,collisionWidth:o,collisionHeight:n,offset:[f[0]+c[0],f[1]+c[1]],my:p.my,at:p.at,within:_,elem:r})}),p.using&&(t=function(t){var e=g.left-l.left,i=e+u-a,s=g.top-l.top,o=s+d-h,n={target:{element:v,left:g.left,top:g.top,width:u,height:d},element:{element:r,left:l.left,top:l.top,width:a,height:h},horizontal:i<0?"left":0<e?"right":"center",vertical:o<0?"top":0<s?"bottom":"middle"};u<a&&C(e+i)<u&&(n.horizontal="center"),d<h&&C(s+o)<d&&(n.vertical="middle"),x(C(e),C(i))>x(C(s),C(o))?n.important="horizontal":n.important="vertical",p.using.call(this,t,n)}),r.offset(P.extend(l,{using:t}))})},P.ui.position={fit:{left:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollLeft:s.offset.left,n=s.width,r=t.left-e.collisionPosition.marginLeft,a=o-r,h=r+e.collisionWidth-n-o;e.collisionWidth>n?0<a&&h<=0?(i=t.left+a+e.collisionWidth-n-o,t.left+=a-i):t.left=!(0<h&&a<=0)&&h<a?o+n-e.collisionWidth:o:0<a?t.left+=a:0<h?t.left-=h:t.left=x(t.left-r,t.left)},top:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollTop:s.offset.top,n=e.within.height,r=t.top-e.collisionPosition.marginTop,a=o-r,h=r+e.collisionHeight-n-o;e.collisionHeight>n?0<a&&h<=0?(i=t.top+a+e.collisionHeight-n-o,t.top+=a-i):t.top=!(0<h&&a<=0)&&h<a?o+n-e.collisionHeight:o:0<a?t.top+=a:0<h?t.top-=h:t.top=x(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,o=e.within,n=o.offset.left+o.scrollLeft,r=o.width,a=o.isWindow?o.scrollLeft:o.offset.left,h=t.left-e.collisionPosition.marginLeft,l=h-a,c=h+e.collisionWidth-r-a,p="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,f="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,u=-2*e.offset[0];l<0?((i=t.left+p+f+u+e.collisionWidth-r-n)<0||i<C(l))&&(t.left+=p+f+u):0<c&&(0<(s=t.left-e.collisionPosition.marginLeft+p+f+u-a)||C(s)<c)&&(t.left+=p+f+u)},top:function(t,e){var i,s,o=e.within,n=o.offset.top+o.scrollTop,r=o.height,a=o.isWindow?o.scrollTop:o.offset.top,h=t.top-e.collisionPosition.marginTop,l=h-a,c=h+e.collisionHeight-r-a,p="top"===e.my[1]?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,u=-2*e.offset[1];l<0?((s=t.top+p+f+u+e.collisionHeight-r-n)<0||s<C(l))&&(t.top+=p+f+u):0<c&&(0<(i=t.top-e.collisionPosition.marginTop+p+f+u-a)||C(i)<c)&&(t.top+=p+f+u)}},flipfit:{left:function(){P.ui.position.flip.left.apply(this,arguments),P.ui.position.fit.left.apply(this,arguments)},top:function(){P.ui.position.flip.top.apply(this,arguments),P.ui.position.fit.top.apply(this,arguments)}}};P.ui.position,P.extend(P.expr[":"],{data:P.expr.createPseudo?P.expr.createPseudo(function(e){return function(t){return!!P.data(t,e)}}):function(t,e,i){return!!P.data(t,i[3])}}),P.fn.extend({disableSelection:(t="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}),enableSelection:function(){return this.off(".ui-disableSelection")}}),P.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):P(this[0].form)},P.ui.formResetMixin={_formResetHandler:function(){var e=P(this);setTimeout(function(){var t=e.data("ui-form-reset-instances");P.each(t,function(){this.refresh()})})},_bindFormResetHandler:function(){var t;this.form=this.element.form(),this.form.length&&((t=this.form.data("ui-form-reset-instances")||[]).length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t))},_unbindFormResetHandler:function(){var t;this.form.length&&((t=this.form.data("ui-form-reset-instances")).splice(P.inArray(this,t),1),t.length?this.form.data("ui-form-reset-instances",t):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset"))}},P.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},P.fn.scrollParent=function(t){var e=this.css("position"),i="absolute"===e,s=t?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var t=P(this);return(!i||"static"!==t.css("position"))&&s.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==e&&o.length?o:P(this[0].ownerDocument||document)},P.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var t,p=!1;P(document).on("mouseup",function(){p=!1});P.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(t){if(!0===P.data(t.target,e.widgetName+".preventClickEvent"))return P.removeData(t.target,e.widgetName+".preventClickEvent"),t.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!p){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var e=this,i=1===t.which,s=!("string"!=typeof this.options.cancel||!t.target.nodeName)&&P(t.target).closest(this.options.cancel).length;return i&&!s&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(t),!this._mouseStarted)?(t.preventDefault(),!0):(!0===P.data(t.target,this.widgetName+".preventClickEvent")&&P.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return e._mouseMove(t)},this._mouseUpDelegate=function(t){return e._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),p=!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(P.ui.ie&&(!document.documentMode||document.documentMode<9)&&!t.button)return this._mouseUp(t);if(!t.which)if(t.originalEvent.altKey||t.originalEvent.ctrlKey||t.originalEvent.metaKey||t.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,t),this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&P.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,p=!1,t.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),P.ui.plugin={add:function(t,e,i){var s,o=P.ui[t].prototype;for(s in i)o.plugins[s]=o.plugins[s]||[],o.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var o,n=t.plugins[e];if(n&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(o=0;o<n.length;o++)t.options[n[o][0]]&&n[o][1].apply(t.element,i)}},P.ui.safeActiveElement=function(e){var i;try{i=e.activeElement}catch(t){i=e.body}return(i=i||e.body).nodeName||(i=e.body),i},P.ui.safeBlur=function(t){t&&"body"!==t.nodeName.toLowerCase()&&P(t).trigger("blur")};P.widget("ui.draggable",P.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){(this.helper||this.element).is(".ui-draggable-dragging")?this.destroyOnClear=!0:(this._removeHandleClassName(),this._mouseDestroy())},_mouseCapture:function(t){var e=this.options;return!(this.helper||e.disabled||0<P(t.target).closest(".ui-resizable-handle").length)&&(this.handle=this._getHandle(t),!!this.handle&&(this._blurActiveElement(t),this._blockFrames(!0===e.iframeFix?"iframe":e.iframeFix),!0))},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=P(this);return P("<div>").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var e=P.ui.safeActiveElement(this.document[0]);P(t.target).closest(e).length||P.ui.safeBlur(e)},_mouseStart:function(t){var e=this.options;return this.helper=this._createHelper(t),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),P.ui.ddmanager&&(P.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0<this.helper.parents().filter(function(){return"fixed"===P(this).css("position")}).length,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this._setContainment(),!1===this._trigger("start",t)?(this._clear(),!1):(this._cacheHelperProportions(),P.ui.ddmanager&&!e.dropBehaviour&&P.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),P.ui.ddmanager&&P.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(t,e){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!e){var i=this._uiHash();if(!1===this._trigger("drag",t,i))return this._mouseUp(new P.Event("mouseup",t)),!1;this.position=i.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",P.ui.ddmanager&&P.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var e=this,i=!1;return P.ui.ddmanager&&!this.options.dropBehaviour&&(i=P.ui.ddmanager.drop(this,t)),this.dropped&&(i=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!i||"valid"===this.options.revert&&i||!0===this.options.revert||P.isFunction(this.options.revert)&&this.options.revert.call(this.element,i)?P(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){!1!==e._trigger("stop",t)&&e._clear()}):!1!==this._trigger("stop",t)&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),P.ui.ddmanager&&P.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.trigger("focus"),P.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new P.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(t){return!this.options.handle||!!P(t.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(t){var e=this.options,i=P.isFunction(e.helper),s=i?P(e.helper.apply(this.element[0],[t])):"clone"===e.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===e.appendTo?this.element[0].parentNode:e.appendTo),i&&s[0]===this.element[0]&&this._setPositionRelative(),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),P.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),e=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==e&&P.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,e,i,s=this.options,o=this.document[0];this.relativeContainer=null,s.containment?"window"!==s.containment?"document"!==s.containment?s.containment.constructor!==Array?("parent"===s.containment&&(s.containment=this.helper[0].parentNode),(i=(e=P(s.containment))[0])&&(t=/(scroll|auto)/.test(e.css("overflow")),this.containment=[(parseInt(e.css("borderLeftWidth"),10)||0)+(parseInt(e.css("paddingLeft"),10)||0),(parseInt(e.css("borderTopWidth"),10)||0)+(parseInt(e.css("paddingTop"),10)||0),(t?Math.max(i.scrollWidth,i.offsetWidth):i.offsetWidth)-(parseInt(e.css("borderRightWidth"),10)||0)-(parseInt(e.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(i.scrollHeight,i.offsetHeight):i.offsetHeight)-(parseInt(e.css("borderBottomWidth"),10)||0)-(parseInt(e.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=e)):this.containment=s.containment:this.containment=[0,0,P(o).width()-this.helperProportions.width-this.margins.left,(P(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=[P(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,P(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,P(window).scrollLeft()+P(window).width()-this.helperProportions.width-this.margins.left,P(window).scrollTop()+(P(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=null},_convertPositionTo:function(t,e){e=e||this.position;var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,o,n,r=this.options,a=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return a&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(i=this.relativeContainer?(s=this.relativeContainer.offset(),[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),r.grid&&(o=r.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/r.grid[1])*r.grid[1]:this.originalPageY,l=!i||o-this.offset.click.top>=i[1]||o-this.offset.click.top>i[3]?o:o-this.offset.click.top>=i[1]?o-r.grid[1]:o+r.grid[1],n=r.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/r.grid[0])*r.grid[0]:this.originalPageX,h=!i||n-this.offset.click.left>=i[0]||n-this.offset.click.left>i[2]?n:n-this.offset.click.left>=i[0]?n-r.grid[0]:n+r.grid[0]),"y"===r.axis&&(h=this.originalPageX),"x"===r.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(t,e,i){return i=i||this._uiHash(),P.ui.plugin.call(this,t,[e,i,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),i.offset=this.positionAbs),P.Widget.prototype._trigger.call(this,t,e,i)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),P.ui.plugin.add("draggable","connectToSortable",{start:function(e,t,i){var s=P.extend({},t,{item:i.element});i.sortables=[],P(i.options.connectToSortable).each(function(){var t=P(this).sortable("instance");t&&!t.options.disabled&&(i.sortables.push(t),t.refreshPositions(),t._trigger("activate",e,s))})},stop:function(e,t,i){var s=P.extend({},t,{item:i.element});i.cancelHelperRemoval=!1,P.each(i.sortables,function(){var t=this;t.isOver?(t.isOver=0,i.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,s))})},drag:function(i,s,o){P.each(o.sortables,function(){var t=!1,e=this;e.positionAbs=o.positionAbs,e.helperProportions=o.helperProportions,e.offset.click=o.offset.click,e._intersectsWith(e.containerCache)&&(t=!0,P.each(o.sortables,function(){return this.positionAbs=o.positionAbs,this.helperProportions=o.helperProportions,this.offset.click=o.offset.click,this!==e&&this._intersectsWith(this.containerCache)&&P.contains(e.element[0],this.element[0])&&(t=!1),t})),t?(e.isOver||(e.isOver=1,o._parent=s.helper.parent(),e.currentItem=s.helper.appendTo(e.element).data("ui-sortable-item",!0),e.options._helper=e.options.helper,e.options.helper=function(){return s.helper[0]},i.target=e.currentItem[0],e._mouseCapture(i,!0),e._mouseStart(i,!0,!0),e.offset.click.top=o.offset.click.top,e.offset.click.left=o.offset.click.left,e.offset.parent.left-=o.offset.parent.left-e.offset.parent.left,e.offset.parent.top-=o.offset.parent.top-e.offset.parent.top,o._trigger("toSortable",i),o.dropped=e.element,P.each(o.sortables,function(){this.refreshPositions()}),o.currentItem=o.element,e.fromOutside=o),e.currentItem&&(e._mouseDrag(i),s.position=e.position)):e.isOver&&(e.isOver=0,e.cancelHelperRemoval=!0,e.options._revert=e.options.revert,e.options.revert=!1,e._trigger("out",i,e._uiHash(e)),e._mouseStop(i,!0),e.options.revert=e.options._revert,e.options.helper=e.options._helper,e.placeholder&&e.placeholder.remove(),s.helper.appendTo(o._parent),o._refreshOffsets(i),s.position=o._generatePosition(i,!0),o._trigger("fromSortable",i),o.dropped=!1,P.each(o.sortables,function(){this.refreshPositions()}))})}}),P.ui.plugin.add("draggable","cursor",{start:function(t,e,i){var s=P("body"),o=i.options;s.css("cursor")&&(o._cursor=s.css("cursor")),s.css("cursor",o.cursor)},stop:function(t,e,i){var s=i.options;s._cursor&&P("body").css("cursor",s._cursor)}}),P.ui.plugin.add("draggable","opacity",{start:function(t,e,i){var s=P(e.helper),o=i.options;s.css("opacity")&&(o._opacity=s.css("opacity")),s.css("opacity",o.opacity)},stop:function(t,e,i){var s=i.options;s._opacity&&P(e.helper).css("opacity",s._opacity)}}),P.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,e,i){var s=i.options,o=!1,n=i.scrollParentNotHidden[0],r=i.document[0];n!==r&&"HTML"!==n.tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+n.offsetHeight-t.pageY<s.scrollSensitivity?n.scrollTop=o=n.scrollTop+s.scrollSpeed:t.pageY-i.overflowOffset.top<s.scrollSensitivity&&(n.scrollTop=o=n.scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+n.offsetWidth-t.pageX<s.scrollSensitivity?n.scrollLeft=o=n.scrollLeft+s.scrollSpeed:t.pageX-i.overflowOffset.left<s.scrollSensitivity&&(n.scrollLeft=o=n.scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(t.pageY-P(r).scrollTop()<s.scrollSensitivity?o=P(r).scrollTop(P(r).scrollTop()-s.scrollSpeed):P(window).height()-(t.pageY-P(r).scrollTop())<s.scrollSensitivity&&(o=P(r).scrollTop(P(r).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(t.pageX-P(r).scrollLeft()<s.scrollSensitivity?o=P(r).scrollLeft(P(r).scrollLeft()-s.scrollSpeed):P(window).width()-(t.pageX-P(r).scrollLeft())<s.scrollSensitivity&&(o=P(r).scrollLeft(P(r).scrollLeft()+s.scrollSpeed)))),!1!==o&&P.ui.ddmanager&&!s.dropBehaviour&&P.ui.ddmanager.prepareOffsets(i,t)}}),P.ui.plugin.add("draggable","snap",{start:function(t,e,i){var s=i.options;i.snapElements=[],P(s.snap.constructor!==String?s.snap.items||":data(ui-draggable)":s.snap).each(function(){var t=P(this),e=t.offset();this!==i.element[0]&&i.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:e.top,left:e.left})})},drag:function(t,e,i){for(var s,o,n,r,a,h,l,c,p,f=i.options,u=f.snapTolerance,d=e.offset.left,g=d+i.helperProportions.width,m=e.offset.top,v=m+i.helperProportions.height,_=i.snapElements.length-1;0<=_;_--)h=(a=i.snapElements[_].left-i.margins.left)+i.snapElements[_].width,c=(l=i.snapElements[_].top-i.margins.top)+i.snapElements[_].height,g<a-u||h+u<d||v<l-u||c+u<m||!P.contains(i.snapElements[_].item.ownerDocument,i.snapElements[_].item)?(i.snapElements[_].snapping&&i.options.snap.release&&i.options.snap.release.call(i.element,t,P.extend(i._uiHash(),{snapItem:i.snapElements[_].item})),i.snapElements[_].snapping=!1):("inner"!==f.snapMode&&(s=Math.abs(l-v)<=u,o=Math.abs(c-m)<=u,n=Math.abs(a-g)<=u,r=Math.abs(h-d)<=u,s&&(e.position.top=i._convertPositionTo("relative",{top:l-i.helperProportions.height,left:0}).top),o&&(e.position.top=i._convertPositionTo("relative",{top:c,left:0}).top),n&&(e.position.left=i._convertPositionTo("relative",{top:0,left:a-i.helperProportions.width}).left),r&&(e.position.left=i._convertPositionTo("relative",{top:0,left:h}).left)),p=s||o||n||r,"outer"!==f.snapMode&&(s=Math.abs(l-m)<=u,o=Math.abs(c-v)<=u,n=Math.abs(a-d)<=u,r=Math.abs(h-g)<=u,s&&(e.position.top=i._convertPositionTo("relative",{top:l,left:0}).top),o&&(e.position.top=i._convertPositionTo("relative",{top:c-i.helperProportions.height,left:0}).top),n&&(e.position.left=i._convertPositionTo("relative",{top:0,left:a}).left),r&&(e.position.left=i._convertPositionTo("relative",{top:0,left:h-i.helperProportions.width}).left)),!i.snapElements[_].snapping&&(s||o||n||r||p)&&i.options.snap.snap&&i.options.snap.snap.call(i.element,t,P.extend(i._uiHash(),{snapItem:i.snapElements[_].item})),i.snapElements[_].snapping=s||o||n||r||p)}}),P.ui.plugin.add("draggable","stack",{start:function(t,e,i){var s,o=i.options,n=P.makeArray(P(o.stack)).sort(function(t,e){return(parseInt(P(t).css("zIndex"),10)||0)-(parseInt(P(e).css("zIndex"),10)||0)});n.length&&(s=parseInt(P(n[0]).css("zIndex"),10)||0,P(n).each(function(t){P(this).css("zIndex",s+t)}),this.css("zIndex",s+n.length))}}),P.ui.plugin.add("draggable","zIndex",{start:function(t,e,i){var s=P(e.helper),o=i.options;s.css("zIndex")&&(o._zIndex=s.css("zIndex")),s.css("zIndex",o.zIndex)},stop:function(t,e,i){var s=i.options;s._zIndex&&P(e.helper).css("zIndex",s._zIndex)}});P.ui.draggable;P.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,e=this.options,i=e.accept;this.isover=!1,this.isout=!0,this.accept=P.isFunction(i)?i:function(t){return t.is(i)},this.proportions=function(){if(!arguments.length)return t||(t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight});t=arguments[0]},this._addToManager(e.scope),e.addClasses&&this._addClass("ui-droppable")},_addToManager:function(t){P.ui.ddmanager.droppables[t]=P.ui.ddmanager.droppables[t]||[],P.ui.ddmanager.droppables[t].push(this)},_splice:function(t){for(var e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var t=P.ui.ddmanager.droppables[this.options.scope];this._splice(t)},_setOption:function(t,e){var i;"accept"===t?this.accept=P.isFunction(e)?e:function(t){return t.is(e)}:"scope"===t&&(i=P.ui.ddmanager.droppables[this.options.scope],this._splice(i),this._addToManager(e)),this._super(t,e)},_activate:function(t){var e=P.ui.ddmanager.current;this._addActiveClass(),e&&this._trigger("activate",t,this.ui(e))},_deactivate:function(t){var e=P.ui.ddmanager.current;this._removeActiveClass(),e&&this._trigger("deactivate",t,this.ui(e))},_over:function(t){var e=P.ui.ddmanager.current;e&&(e.currentItem||e.element)[0]!==this.element[0]&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this._addHoverClass(),this._trigger("over",t,this.ui(e)))},_out:function(t){var e=P.ui.ddmanager.current;e&&(e.currentItem||e.element)[0]!==this.element[0]&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this._removeHoverClass(),this._trigger("out",t,this.ui(e)))},_drop:function(e,t){var i=t||P.ui.ddmanager.current,s=!1;return!(!i||(i.currentItem||i.element)[0]===this.element[0])&&(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var t=P(this).droppable("instance");if(t.options.greedy&&!t.options.disabled&&t.options.scope===i.options.scope&&t.accept.call(t.element[0],i.currentItem||i.element)&&f(i,P.extend(t,{offset:t.element.offset()}),t.options.tolerance,e))return!(s=!0)}),!s&&(!!this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(i)),this.element)))},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var f=P.ui.intersect=function(t,e,i,s){if(!e.offset)return!1;var o=(t.positionAbs||t.position.absolute).left+t.margins.left,n=(t.positionAbs||t.position.absolute).top+t.margins.top,r=o+t.helperProportions.width,a=n+t.helperProportions.height,h=e.offset.left,l=e.offset.top,c=h+e.proportions().width,p=l+e.proportions().height;switch(i){case"fit":return h<=o&&r<=c&&l<=n&&a<=p;case"intersect":return h<o+t.helperProportions.width/2&&r-t.helperProportions.width/2<c&&l<n+t.helperProportions.height/2&&a-t.helperProportions.height/2<p;case"pointer":return u(s.pageY,l,e.proportions().height)&&u(s.pageX,h,e.proportions().width);case"touch":return(l<=n&&n<=p||l<=a&&a<=p||n<l&&p<a)&&(h<=o&&o<=c||h<=r&&r<=c||o<h&&c<r);default:return!1}};function u(t,e,i){return e<=t&&t<e+i}!(P.ui.ddmanager={current:null,droppables:{default:[]},prepareOffsets:function(t,e){var i,s,o=P.ui.ddmanager.droppables[t.options.scope]||[],n=e?e.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();t:for(i=0;i<o.length;i++)if(!(o[i].options.disabled||t&&!o[i].accept.call(o[i].element[0],t.currentItem||t.element))){for(s=0;s<r.length;s++)if(r[s]===o[i].element[0]){o[i].proportions().height=0;continue t}o[i].visible="none"!==o[i].element.css("display"),o[i].visible&&("mousedown"===n&&o[i]._activate.call(o[i],e),o[i].offset=o[i].element.offset(),o[i].proportions({width:o[i].element[0].offsetWidth,height:o[i].element[0].offsetHeight}))}},drop:function(t,e){var i=!1;return P.each((P.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&f(t,this,this.options.tolerance,e)&&(i=this._drop.call(this,e)||i),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,e)))}),i},dragStart:function(t,e){t.element.parentsUntil("body").on("scroll.droppable",function(){t.options.refreshPositions||P.ui.ddmanager.prepareOffsets(t,e)})},drag:function(n,r){n.options.refreshPositions&&P.ui.ddmanager.prepareOffsets(n,r),P.each(P.ui.ddmanager.droppables[n.options.scope]||[],function(){var t,e,i,s,o;this.options.disabled||this.greedyChild||!this.visible||(o=!(s=f(n,this,this.options.tolerance,r))&&this.isover?"isout":s&&!this.isover?"isover":null)&&(this.options.greedy&&(e=this.options.scope,(i=this.element.parents(":data(ui-droppable)").filter(function(){return P(this).droppable("instance").options.scope===e})).length&&((t=P(i[0]).droppable("instance")).greedyChild="isover"===o)),t&&"isover"===o&&(t.isover=!1,t.isout=!0,t._out.call(t,r)),this[o]=!0,this["isout"===o?"isover":"isout"]=!1,this["isover"===o?"_over":"_out"].call(this,r),t&&"isout"===o&&(t.isout=!1,t.isover=!0,t._over.call(t,r)))})},dragStop:function(t,e){t.element.parentsUntil("body").off("scroll.droppable"),t.options.refreshPositions||P.ui.ddmanager.prepareOffsets(t,e)}})!==P.uiBackCompat&&P.widget("ui.droppable",P.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}});P.ui.droppable;P.widget("ui.resizable",P.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(t,e){if("hidden"===P(t).css("overflow"))return!1;var i,s=e&&"left"===e?"scrollLeft":"scrollTop";return 0<t[s]||(t[s]=1,i=0<t[s],t[s]=0,i)},_create:function(){var t,e=this.options,i=this;this._addClass("ui-resizable"),P.extend(this,{_aspectRatio:!!e.aspectRatio,aspectRatio:e.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:e.helper||e.ghost||e.animate?e.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(P("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&P(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();function t(t){P(t).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles()}},_setupHandles:function(){var t,e,i,s,o,n=this.options,r=this;if(this.handles=n.handles||(P(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=P(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e<i.length;e++)s="ui-resizable-"+(t=P.trim(i[e])),o=P("<div>"),this._addClass(o,"ui-resizable-handle "+s),o.css({zIndex:n.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.append(o);this._renderAxis=function(t){var e,i,s,o;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=P(this.handles[e]),this._on(this.handles[e],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=P(this.handles[e],this.element),o=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),s=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(s,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),n.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=P(this.handles[e])[0])!==t.target&&!P.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s,o=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),o.containment&&(e+=P(o.containment).scrollLeft()||0,i+=P(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=P(".ui-resizable-"+this.axis).css("cursor"),P("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e,i,s=this.originalMousePosition,o=this.axis,n=t.pageX-s.left||0,r=t.pageY-s.top||0,a=this._change[o];return this._updatePrevProperties(),a&&(e=a.apply(this,[t,n,r]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),i=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),P.isEmptyObject(i)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,o,n,r,a,h=this.options,l=this;return this._helper&&(s=(i=(e=this._proportionallyResizeElements).length&&/textarea/i.test(e[0].nodeName))&&this._hasScroll(e[0],"left")?0:l.sizeDiff.height,o=i?0:l.sizeDiff.width,n={width:l.helper.width()-o,height:l.helper.height()-s},r=parseFloat(l.element.css("left"))+(l.position.left-l.originalPosition.left)||null,a=parseFloat(l.element.css("top"))+(l.position.top-l.originalPosition.top)||null,h.animate||this.element.css(P.extend(n,{top:a,left:r})),l.helper.height(l.size.height),l.helper.width(l.size.width),this._helper&&!h.animate&&this._proportionallyResize()),P("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,o,n=this.options,r={minWidth:this._isNumber(n.minWidth)?n.minWidth:0,maxWidth:this._isNumber(n.maxWidth)?n.maxWidth:1/0,minHeight:this._isNumber(n.minHeight)?n.minHeight:0,maxHeight:this._isNumber(n.maxHeight)?n.maxHeight:1/0};(this._aspectRatio||t)&&(e=r.minHeight*this.aspectRatio,s=r.minWidth/this.aspectRatio,i=r.maxHeight*this.aspectRatio,o=r.maxWidth/this.aspectRatio,e>r.minWidth&&(r.minWidth=e),s>r.minHeight&&(r.minHeight=s),i<r.maxWidth&&(r.maxWidth=i),o<r.maxHeight&&(r.maxHeight=o)),this._vBoundaries=r},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,n=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,r=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return n&&(t.width=e.minWidth),r&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),n&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),r&&c&&(t.top=h-e.minHeight),o&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],o=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(o[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e<this._proportionallyResizeElements.length;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var t=this.element,e=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||P("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return P.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return P.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return P.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return P.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){P.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),P.ui.plugin.add("resizable","animate",{stop:function(e){var i=P(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),n=o&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,a={width:i.size.width-r,height:i.size.height-n},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,l=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(P.extend(a,l&&h?{top:l,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&P(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),P.ui.plugin.add("resizable","containment",{start:function(){var i,s,t,e,o,n,r,a=P(this).resizable("instance"),h=a.options,l=a.element,c=h.containment,p=c instanceof P?c.get(0):/parent/.test(c)?l.parent().get(0):c;p&&(a.containerElement=P(p),/document/.test(c)||c===document?(a.containerOffset={left:0,top:0},a.containerPosition={left:0,top:0},a.parentData={element:P(document),left:0,top:0,width:P(document).width(),height:P(document).height()||document.body.parentNode.scrollHeight}):(i=P(p),s=[],P(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=a._num(i.css("padding"+e))}),a.containerOffset=i.offset(),a.containerPosition=i.position(),a.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=a.containerOffset,e=a.containerSize.height,o=a.containerSize.width,n=a._hasScroll(p,"left")?p.scrollWidth:o,r=a._hasScroll(p)?p.scrollHeight:e,a.parentData={element:p,left:t.left,top:t.top,width:n,height:r}))},resize:function(t){var e,i,s,o,n=P(this).resizable("instance"),r=n.options,a=n.containerOffset,h=n.position,l=n._aspectRatio||t.shiftKey,c={top:0,left:0},p=n.containerElement,f=!0;p[0]!==document&&/static/.test(p.css("position"))&&(c=a),h.left<(n._helper?a.left:0)&&(n.size.width=n.size.width+(n._helper?n.position.left-a.left:n.position.left-c.left),l&&(n.size.height=n.size.width/n.aspectRatio,f=!1),n.position.left=r.helper?a.left:0),h.top<(n._helper?a.top:0)&&(n.size.height=n.size.height+(n._helper?n.position.top-a.top:n.position.top),l&&(n.size.width=n.size.height*n.aspectRatio,f=!1),n.position.top=n._helper?a.top:0),s=n.containerElement.get(0)===n.element.parent().get(0),o=/relative|absolute/.test(n.containerElement.css("position")),s&&o?(n.offset.left=n.parentData.left+n.position.left,n.offset.top=n.parentData.top+n.position.top):(n.offset.left=n.element.offset().left,n.offset.top=n.element.offset().top),e=Math.abs(n.sizeDiff.width+(n._helper?n.offset.left-c.left:n.offset.left-a.left)),i=Math.abs(n.sizeDiff.height+(n._helper?n.offset.top-c.top:n.offset.top-a.top)),e+n.size.width>=n.parentData.width&&(n.size.width=n.parentData.width-e,l&&(n.size.height=n.size.width/n.aspectRatio,f=!1)),i+n.size.height>=n.parentData.height&&(n.size.height=n.parentData.height-i,l&&(n.size.width=n.size.height*n.aspectRatio,f=!1)),f||(n.position.left=n.prevPosition.left,n.position.top=n.prevPosition.top,n.size.width=n.prevSize.width,n.size.height=n.prevSize.height)},stop:function(){var t=P(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,o=t.containerElement,n=P(t.helper),r=n.offset(),a=n.outerWidth()-t.sizeDiff.width,h=n.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(o.css("position"))&&P(this).css({left:r.left-s.left-i.left,width:a,height:h}),t._helper&&!e.animate&&/static/.test(o.css("position"))&&P(this).css({left:r.left-s.left-i.left,width:a,height:h})}}),P.ui.plugin.add("resizable","alsoResize",{start:function(){var t=P(this).resizable("instance").options;P(t.alsoResize).each(function(){var t=P(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=P(this).resizable("instance"),s=e.options,o=e.originalSize,n=e.originalPosition,r={height:e.size.height-o.height||0,width:e.size.width-o.width||0,top:e.position.top-n.top||0,left:e.position.left-n.left||0};P(s.alsoResize).each(function(){var t=P(this),s=P(this).data("ui-resizable-alsoresize"),o={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];P.each(e,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&0<=i&&(o[e]=i||null)}),t.css(o)})},stop:function(){P(this).removeData("ui-resizable-alsoresize")}}),P.ui.plugin.add("resizable","ghost",{start:function(){var t=P(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==P.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=P(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=P(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),P.ui.plugin.add("resizable","grid",{resize:function(){var t,e=P(this).resizable("instance"),i=e.options,s=e.size,o=e.originalSize,n=e.originalPosition,r=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=a[0]||1,l=a[1]||1,c=Math.round((s.width-o.width)/h)*h,p=Math.round((s.height-o.height)/l)*l,f=o.width+c,u=o.height+p,d=i.maxWidth&&i.maxWidth<f,g=i.maxHeight&&i.maxHeight<u,m=i.minWidth&&i.minWidth>f,v=i.minHeight&&i.minHeight>u;i.grid=a,m&&(f+=h),v&&(u+=l),d&&(f-=h),g&&(u-=l),/^(se|s|e)$/.test(r)?(e.size.width=f,e.size.height=u):/^(ne)$/.test(r)?(e.size.width=f,e.size.height=u,e.position.top=n.top-p):/^(sw)$/.test(r)?(e.size.width=f,e.size.height=u,e.position.left=n.left-c):((u-l<=0||f-h<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0<u-l?(e.size.height=u,e.position.top=n.top-p):(u=l-t.height,e.size.height=u,e.position.top=n.top+o.height-u),0<f-h?(e.size.width=f,e.position.left=n.left-c):(f=h-t.width,e.size.width=f,e.position.left=n.left+o.width-f))}});P.ui.resizable,P.widget("ui.selectable",P.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var s=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){s.elementPos=P(s.element[0]).offset(),s.selectees=P(s.options.filter,s.element[0]),s._addClass(s.selectees,"ui-selectee"),s.selectees.each(function(){var t=P(this),e=t.offset(),i={left:e.left-s.elementPos.left,top:e.top-s.elementPos.top};P.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=P("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(i){var s=this,t=this.options;this.opos=[i.pageX,i.pageY],this.elementPos=P(this.element[0]).offset(),this.options.disabled||(this.selectees=P(t.filter,this.element[0]),this._trigger("start",i),P(t.appendTo).append(this.helper),this.helper.css({left:i.pageX,top:i.pageY,width:0,height:0}),t.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var t=P.data(this,"selectable-item");t.startselected=!0,i.metaKey||i.ctrlKey||(s._removeClass(t.$element,"ui-selected"),t.selected=!1,s._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,s._trigger("unselecting",i,{unselecting:t.element}))}),P(i.target).parents().addBack().each(function(){var t,e=P.data(this,"selectable-item");if(e)return t=!i.metaKey&&!i.ctrlKey||!e.$element.hasClass("ui-selected"),s._removeClass(e.$element,t?"ui-unselecting":"ui-selected")._addClass(e.$element,t?"ui-selecting":"ui-unselecting"),e.unselecting=!t,e.selecting=t,(e.selected=t)?s._trigger("selecting",i,{selecting:e.element}):s._trigger("unselecting",i,{unselecting:e.element}),!1}))},_mouseDrag:function(s){if(this.dragged=!0,!this.options.disabled){var t,o=this,n=this.options,r=this.opos[0],a=this.opos[1],h=s.pageX,l=s.pageY;return h<r&&(t=h,h=r,r=t),l<a&&(t=l,l=a,a=t),this.helper.css({left:r,top:a,width:h-r,height:l-a}),this.selectees.each(function(){var t=P.data(this,"selectable-item"),e=!1,i={};t&&t.element!==o.element[0]&&(i.left=t.left+o.elementPos.left,i.right=t.right+o.elementPos.left,i.top=t.top+o.elementPos.top,i.bottom=t.bottom+o.elementPos.top,"touch"===n.tolerance?e=!(i.left>h||i.right<r||i.top>l||i.bottom<a):"fit"===n.tolerance&&(e=i.left>r&&i.right<h&&i.top>a&&i.bottom<l),e?(t.selected&&(o._removeClass(t.$element,"ui-selected"),t.selected=!1),t.unselecting&&(o._removeClass(t.$element,"ui-unselecting"),t.unselecting=!1),t.selecting||(o._addClass(t.$element,"ui-selecting"),t.selecting=!0,o._trigger("selecting",s,{selecting:t.element}))):(t.selecting&&((s.metaKey||s.ctrlKey)&&t.startselected?(o._removeClass(t.$element,"ui-selecting"),t.selecting=!1,o._addClass(t.$element,"ui-selected"),t.selected=!0):(o._removeClass(t.$element,"ui-selecting"),t.selecting=!1,t.startselected&&(o._addClass(t.$element,"ui-unselecting"),t.unselecting=!0),o._trigger("unselecting",s,{unselecting:t.element}))),t.selected&&(s.metaKey||s.ctrlKey||t.startselected||(o._removeClass(t.$element,"ui-selected"),t.selected=!1,o._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,o._trigger("unselecting",s,{unselecting:t.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,P(".ui-unselecting",this.element[0]).each(function(){var t=P.data(this,"selectable-item");i._removeClass(t.$element,"ui-unselecting"),t.unselecting=!1,t.startselected=!1,i._trigger("unselected",e,{unselected:t.element})}),P(".ui-selecting",this.element[0]).each(function(){var t=P.data(this,"selectable-item");i._removeClass(t.$element,"ui-selecting")._addClass(t.$element,"ui-selected"),t.selecting=!1,t.selected=!0,t.startselected=!0,i._trigger("selected",e,{selected:t.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),P.widget("ui.sortable",P.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return e<=t&&t<e+i},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),P.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;0<=t;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,e){var i=null,s=!1,o=this;return!this.reverting&&(!this.options.disabled&&"static"!==this.options.type&&(this._refreshItems(t),P(t.target).parents().each(function(){if(P.data(this,o.widgetName+"-item")===o)return i=P(this),!1}),P.data(t.target,o.widgetName+"-item")===o&&(i=P(t.target)),!!i&&(!(this.options.handle&&!e&&(P(this.options.handle,i).find("*").addBack().each(function(){this===t.target&&(s=!0)}),!s))&&(this.currentItem=i,this._removeCurrentsFromItems(),!0))))},_mouseStart:function(t,e,i){var s,o,n=this.options;if((this.currentContainer=this).refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},P.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),n.containment&&this._setContainment(),n.cursor&&"auto"!==n.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",n.cursor),this.storedStylesheet=P("<style>*{ cursor: "+n.cursor+" !important; }</style>").appendTo(o)),n.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",n.opacity)),n.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",n.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!i)for(s=this.containers.length-1;0<=s;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return P.ui.ddmanager&&(P.ui.ddmanager.current=this),P.ui.ddmanager&&!n.dropBehaviour&&P.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var e,i,s,o,n=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<n.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+n.scrollSpeed:t.pageY-this.overflowOffset.top<n.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-n.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<n.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+n.scrollSpeed:t.pageX-this.overflowOffset.left<n.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-n.scrollSpeed)):(t.pageY-this.document.scrollTop()<n.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-n.scrollSpeed):this.window.height()-(t.pageY-this.document.scrollTop())<n.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+n.scrollSpeed)),t.pageX-this.document.scrollLeft()<n.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-n.scrollSpeed):this.window.width()-(t.pageX-this.document.scrollLeft())<n.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+n.scrollSpeed))),!1!==r&&P.ui.ddmanager&&!n.dropBehaviour&&P.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),e=this.items.length-1;0<=e;e--)if(s=(i=this.items[e]).item[0],(o=this._intersectsWithPointer(i))&&i.instance===this.currentContainer&&!(s===this.currentItem[0]||this.placeholder[1===o?"next":"prev"]()[0]===s||P.contains(this.placeholder[0],s)||"semi-dynamic"===this.options.type&&P.contains(this.element[0],s))){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(i))break;this._rearrange(t,i),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),P.ui.ddmanager&&P.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,e){var i,s,o,n;if(t)return P.ui.ddmanager&&!this.options.dropBehaviour&&P.ui.ddmanager.drop(this,t),this.options.revert?(s=(i=this).placeholder.offset(),n={},(o=this.options.axis)&&"x"!==o||(n.left=s.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(n.top=s.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,P(this.helper).animate(n,parseInt(this.options.revert,10)||500,function(){i._clear(t)})):this._clear(t,e),!1},cancel:function(){if(this.dragging){this._mouseUp(new P.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var t=this.containers.length-1;0<=t;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),P.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?P(this.domPosition.prev).after(this.currentItem):P(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var t=this._getItemsAsjQuery(e&&e.connected),i=[];return e=e||{},P(t).each(function(){var t=(P(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);t&&i.push((e.key||t[1]+"[]")+"="+(e.key&&e.expression?t[1]:t[2]))}),!i.length&&e.key&&i.push(e.key+"="),i.join("&")},toArray:function(t){var e=this._getItemsAsjQuery(t&&t.connected),i=[];return t=t||{},e.each(function(){i.push(P(t.item||this).attr(t.attribute||"id")||"")}),i},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,o=s+this.helperProportions.height,n=t.left,r=n+t.width,a=t.top,h=a+t.height,l=this.offset.click.top,c=this.offset.click.left,p="x"===this.options.axis||a<s+l&&s+l<h,f="y"===this.options.axis||n<e+c&&e+c<r,u=p&&f;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?u:n<e+this.helperProportions.width/2&&i-this.helperProportions.width/2<r&&a<s+this.helperProportions.height/2&&o-this.helperProportions.height/2<h},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),o="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width);return!(!s||!o)&&(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1))},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&i||"left"===o&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!=t&&(0<t?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!=t&&(0<t?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(t){var e,i,s,o,n=[],r=[],a=this._connectWith();if(a&&t)for(e=a.length-1;0<=e;e--)for(i=(s=P(a[e],this.document[0])).length-1;0<=i;i--)(o=P.data(s[i],this.widgetFullName))&&o!==this&&!o.options.disabled&&r.push([P.isFunction(o.options.items)?o.options.items.call(o.element):P(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);function h(){n.push(this)}for(r.push([P.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):P(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),e=r.length-1;0<=e;e--)r[e][0].each(h);return P(n)},_removeCurrentsFromItems:function(){var i=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=P.grep(this.items,function(t){for(var e=0;e<i.length;e++)if(i[e]===t.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var e,i,s,o,n,r,a,h,l=this.items,c=[[P.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):P(this.options.items,this.element),this]],p=this._connectWith();if(p&&this.ready)for(e=p.length-1;0<=e;e--)for(i=(s=P(p[e],this.document[0])).length-1;0<=i;i--)(o=P.data(s[i],this.widgetFullName))&&o!==this&&!o.options.disabled&&(c.push([P.isFunction(o.options.items)?o.options.items.call(o.element[0],t,{item:this.currentItem}):P(o.options.items,o.element),o]),this.containers.push(o));for(e=c.length-1;0<=e;e--)for(n=c[e][1],i=0,h=(r=c[e][0]).length;i<h;i++)(a=P(r[i])).data(this.widgetName+"-item",n),l.push({item:a,instance:n,width:0,height:0,left:0,top:0})},refreshPositions:function(t){var e,i,s,o;for(this.floating=!!this.items.length&&("x"===this.options.axis||this._isFloating(this.items[0].item)),this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset()),e=this.items.length-1;0<=e;e--)(i=this.items[e]).instance!==this.currentContainer&&this.currentContainer&&i.item[0]!==this.currentItem[0]||(s=this.options.toleranceElement?P(this.options.toleranceElement,i.item):i.item,t||(i.width=s.outerWidth(),i.height=s.outerHeight()),o=s.offset(),i.left=o.left,i.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(e=this.containers.length-1;0<=e;e--)o=this.containers[e].element.offset(),this.containers[e].containerCache.left=o.left,this.containers[e].containerCache.top=o.top,this.containers[e].containerCache.width=this.containers[e].element.outerWidth(),this.containers[e].containerCache.height=this.containers[e].element.outerHeight();return this},_createPlaceholder:function(i){var s,o=(i=i||this).options;o.placeholder&&o.placeholder.constructor!==String||(s=o.placeholder,o.placeholder={element:function(){var t=i.currentItem[0].nodeName.toLowerCase(),e=P("<"+t+">",i.document[0]);return i._addClass(e,"ui-sortable-placeholder",s||i.currentItem[0].className)._removeClass(e,"ui-sortable-helper"),"tbody"===t?i._createTrPlaceholder(i.currentItem.find("tr").eq(0),P("<tr>",i.document[0]).appendTo(e)):"tr"===t?i._createTrPlaceholder(i.currentItem,e):"img"===t&&e.attr("src",i.currentItem.attr("src")),s||e.css("visibility","hidden"),e},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10)))}}),i.placeholder=P(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){P("<td>&#160;</td>",i.document[0]).attr("colspan",P(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,o,n,r,a,h,l,c=null,p=null,f=this.containers.length-1;0<=f;f--)if(!P.contains(this.currentItem[0],this.containers[f].element[0]))if(this._intersectsWith(this.containers[f].containerCache)){if(c&&P.contains(this.containers[f].element[0],c.element[0]))continue;c=this.containers[f],p=f}else this.containers[f].containerCache.over&&(this.containers[f]._trigger("out",t,this._uiHash(this)),this.containers[f].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(i=1e4,s=null,o=(h=c.floating||this._isFloating(this.currentItem))?"left":"top",n=h?"width":"height",l=h?"pageX":"pageY",e=this.items.length-1;0<=e;e--)P.contains(this.containers[p].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(r=this.items[e].item.offset()[o],a=!1,t[l]-r>this.items[e][n]/2&&(a=!0),Math.abs(t[l]-r)<i&&(i=Math.abs(t[l]-r),s=this.items[e],this.direction=a?"up":"down"));if(!s&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return void(this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1));s?this._rearrange(t,s,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var e=this.options,i=P.isFunction(e.helper)?P(e.helper.apply(this.element[0],[t,this.currentItem])):"clone"===e.helper?this.currentItem.clone():this.currentItem;return i.parents("body").length||P("parent"!==e.appendTo?e.appendTo:this.currentItem[0].parentNode)[0].appendChild(i[0]),i[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),i[0].style.width&&!e.forceHelperSize||i.width(this.currentItem.width()),i[0].style.height&&!e.forceHelperSize||i.height(this.currentItem.height()),i},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),P.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&P.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&P.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,e,i,s=this.options;"parent"===s.containment&&(s.containment=this.helper[0].parentNode),"document"!==s.containment&&"window"!==s.containment||(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===s.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===s.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(s.containment)||(t=P(s.containment)[0],e=P(s.containment).offset(),i="hidden"!==P(t).css("overflow"),this.containment=[e.left+(parseInt(P(t).css("borderLeftWidth"),10)||0)+(parseInt(P(t).css("paddingLeft"),10)||0)-this.margins.left,e.top+(parseInt(P(t).css("borderTopWidth"),10)||0)+(parseInt(P(t).css("paddingTop"),10)||0)-this.margins.top,e.left+(i?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(P(t).css("borderLeftWidth"),10)||0)-(parseInt(P(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,e.top+(i?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(P(t).css("borderTopWidth"),10)||0)-(parseInt(P(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,e){e=e||this.position;var i="absolute"===t?1:-1,s="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&P.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:s.scrollTop())*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*i}},_generatePosition:function(t){var e,i,s=this.options,o=t.pageX,n=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&P.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(n=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(n=this.containment[3]+this.offset.click.top)),s.grid&&(e=this.originalPageY+Math.round((n-this.originalPageY)/s.grid[1])*s.grid[1],n=!this.containment||e-this.offset.click.top>=this.containment[1]&&e-this.offset.click.top<=this.containment[3]?e:e-this.offset.click.top>=this.containment[1]?e-s.grid[1]:e+s.grid[1],i=this.originalPageX+Math.round((o-this.originalPageX)/s.grid[0])*s.grid[0],o=!this.containment||i-this.offset.click.left>=this.containment[0]&&i-this.offset.click.left<=this.containment[2]?i:i-this.offset.click.left>=this.containment[0]?i-s.grid[0]:i+s.grid[0])),{top:n-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var o=this.counter;this._delay(function(){o===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function o(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;0<=i;i--)e||s.push(o("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(o("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i<s.length;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){!1===P.Widget.prototype._trigger.apply(this,arguments)&&this.cancel()},_uiHash:function(t){var e=t||this;return{helper:e.helper,placeholder:e.placeholder||P([]),position:e.position,originalPosition:e.originalPosition,offset:e.positionAbs,item:e.currentItem,sender:t?t.element:null}}});var d,g,m,v,e,_,b,w,y,S,W,T,k,D,E,N,O,R,L,M,A,F="ui-effects-",B="ui-effects-style",X="ui-effects-animated",Y=P;function q(t,e,i){var s=w[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:t<0?0:s.max<t?s.max:t)}function j(r){var a=_(),h=a._rgba=[];return r=r.toLowerCase(),W(e,function(t,e){var i,s=e.re.exec(r),o=s&&e.parse(s),n=e.space||"rgba";if(o)return i=a[n](o),a[b[n].cache]=i[b[n].cache],h=a._rgba=i._rgba,!1}),h.length?("0,0,0,0"===h.join()&&d.extend(h,m.transparent),a):m[r]}function $(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}function U(t){var e,i,s=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,o={};if(s&&s.length&&s[0]&&s[s[0]])for(i=s.length;i--;)"string"==typeof s[e=s[i]]&&(o[P.camelCase(e)]=s[e]);else for(e in s)"string"==typeof s[e]&&(o[e]=s[e]);return o}function K(t,e,i,s){return P.isPlainObject(t)&&(t=(e=t).effect),t={effect:t},null==e&&(e={}),P.isFunction(e)&&(s=e,i=null,e={}),"number"!=typeof e&&!P.fx.speeds[e]||(s=i,i=e,e={}),P.isFunction(i)&&(s=i,i=null),e&&P.extend(t,e),i=i||e.duration,t.duration=P.fx.off?0:"number"==typeof i?i:i in P.fx.speeds?P.fx.speeds[i]:P.fx.speeds._default,t.complete=s||e.complete,t}function V(t){return!t||"number"==typeof t||P.fx.speeds[t]||("string"==typeof t&&!P.effects.effect[t]||(P.isFunction(t)||"object"==typeof t&&!t.effect))}function Q(t,e){var i=e.outerWidth(),s=e.outerHeight(),o=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}P.effects={effect:{}},v=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],_=(d=Y).Color=function(t,e,i,s){return new d.Color.fn.parse(t,e,i,s)},b={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},w={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},y=_.support={},S=d("<p>")[0],W=d.each,S.style.cssText="background-color:rgba(1,1,1,.5)",y.rgba=-1<S.style.backgroundColor.indexOf("rgba"),W(b,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),_.fn=d.extend(_.prototype,{parse:function(o,t,e,i){if(o===g)return this._rgba=[null,null,null,null],this;(o.jquery||o.nodeType)&&(o=d(o).css(t),t=g);var n=this,s=d.type(o),r=this._rgba=[];return t!==g&&(o=[o,t,e,i],s="array"),"string"===s?this.parse(j(o)||m._default):"array"===s?(W(b.rgba.props,function(t,e){r[e.idx]=q(o[e.idx],e)}),this):"object"===s?(W(b,o instanceof _?function(t,e){o[e.cache]&&(n[e.cache]=o[e.cache].slice())}:function(t,i){var s=i.cache;W(i.props,function(t,e){if(!n[s]&&i.to){if("alpha"===t||null==o[t])return;n[s]=i.to(n._rgba)}n[s][e.idx]=q(o[t],e,!0)}),n[s]&&d.inArray(null,n[s].slice(0,3))<0&&(n[s][3]=1,i.from&&(n._rgba=i.from(n[s])))}),this):void 0},is:function(t){var o=_(t),n=!0,r=this;return W(b,function(t,e){var i,s=o[e.cache];return s&&(i=r[e.cache]||e.to&&e.to(r._rgba)||[],W(e.props,function(t,e){if(null!=s[e.idx])return n=s[e.idx]===i[e.idx]})),n}),n},_space:function(){var i=[],s=this;return W(b,function(t,e){s[e.cache]&&i.push(t)}),i.pop()},transition:function(t,r){var e=(l=_(t))._space(),i=b[e],s=0===this.alpha()?_("transparent"):this,a=s[i.cache]||i.to(s._rgba),h=a.slice(),l=l[i.cache];return W(i.props,function(t,e){var i=e.idx,s=a[i],o=l[i],n=w[e.type]||{};null!==o&&(null===s?h[i]=o:(n.mod&&(n.mod/2<o-s?s+=n.mod:n.mod/2<s-o&&(s-=n.mod)),h[i]=q((o-s)*r+s,e)))}),this[e](h)},blend:function(t){if(1===this._rgba[3])return this;var e=this._rgba.slice(),i=e.pop(),s=_(t)._rgba;return _(d.map(e,function(t,e){return(1-i)*s[e]+i*t}))},toRgbaString:function(){var t="rgba(",e=d.map(this._rgba,function(t,e){return null==t?2<e?1:0:t});return 1===e[3]&&(e.pop(),t="rgb("),t+e.join()+")"},toHslaString:function(){var t="hsla(",e=d.map(this.hsla(),function(t,e){return null==t&&(t=2<e?1:0),e&&e<3&&(t=Math.round(100*t)+"%"),t});return 1===e[3]&&(e.pop(),t="hsl("),t+e.join()+")"},toHexString:function(t){var e=this._rgba.slice(),i=e.pop();return t&&e.push(~~(255*i)),"#"+d.map(e,function(t){return 1===(t=(t||0).toString(16)).length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),_.fn.parse.prototype=_.fn,b.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/255,i=t[1]/255,s=t[2]/255,o=t[3],n=Math.max(e,i,s),r=Math.min(e,i,s),a=n-r,h=n+r,l=.5*h,c=r===n?0:e===n?60*(i-s)/a+360:i===n?60*(s-e)/a+120:60*(e-i)/a+240,p=0==a?0:l<=.5?a/h:a/(2-h);return[Math.round(c)%360,p,l,null==o?1:o]},b.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],n=s<=.5?s*(1+i):s+i-s*i,r=2*s-n;return[Math.round(255*$(r,n,e+1/3)),Math.round(255*$(r,n,e)),Math.round(255*$(r,n,e-1/3)),o]},W(b,function(h,t){var i=t.props,r=t.cache,a=t.to,l=t.from;_.fn[h]=function(t){if(a&&!this[r]&&(this[r]=a(this._rgba)),t===g)return this[r].slice();var e,s=d.type(t),o="array"===s||"object"===s?t:arguments,n=this[r].slice();return W(i,function(t,e){var i=o["object"===s?t:e.idx];null==i&&(i=n[e.idx]),n[e.idx]=q(i,e)}),l?((e=_(l(n)))[r]=n,e):_(n)},W(i,function(r,a){_.fn[r]||(_.fn[r]=function(t){var e,i=d.type(t),s="alpha"===r?this._hsla?"hsla":"rgba":h,o=this[s](),n=o[a.idx];return"undefined"===i?n:("function"===i&&(t=t.call(this,n),i=d.type(t)),null==t&&a.empty?this:("string"===i&&(e=v.exec(t))&&(t=n+parseFloat(e[2])*("+"===e[1]?1:-1)),o[a.idx]=t,this[s](o)))})})}),_.hook=function(t){var e=t.split(" ");W(e,function(t,n){d.cssHooks[n]={set:function(t,e){var i,s,o="";if("transparent"!==e&&("string"!==d.type(e)||(i=j(e)))){if(e=_(i||e),!y.rgba&&1!==e._rgba[3]){for(s="backgroundColor"===n?t.parentNode:t;(""===o||"transparent"===o)&&s&&s.style;)try{o=d.css(s,"backgroundColor"),s=s.parentNode}catch(t){}e=e.blend(o&&"transparent"!==o?o:"_default")}e=e.toRgbaString()}try{t.style[n]=e}catch(t){}}},d.fx.step[n]=function(t){t.colorInit||(t.start=_(t.elem,n),t.end=_(t.end),t.colorInit=!0),d.cssHooks[n].set(t.elem,t.start.transition(t.end,t.pos))}})},_.hook("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor"),d.cssHooks.borderColor={expand:function(i){var s={};return W(["Top","Right","Bottom","Left"],function(t,e){s["border"+e+"Color"]=i}),s}},m=d.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"},E=["add","remove","toggle"],N={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1},P.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,e){P.fx.step[e]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(Y.style(t.elem,e,t.end),t.setAttr=!0)}}),P.fn.addBack||(P.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),P.effects.animateClass=function(o,t,e,i){var n=P.speed(t,e,i);return this.queue(function(){var i=P(this),t=i.attr("class")||"",e=(e=n.children?i.find("*").addBack():i).map(function(){return{el:P(this),start:U(this)}}),s=function(){P.each(E,function(t,e){o[e]&&i[e+"Class"](o[e])})};s(),e=e.map(function(){return this.end=U(this.el[0]),this.diff=function(t,e){var i,s,o={};for(i in e)s=e[i],t[i]!==s&&(N[i]||!P.fx.step[i]&&isNaN(parseFloat(s))||(o[i]=s));return o}(this.start,this.end),this}),i.attr("class",t),e=e.map(function(){var t=this,e=P.Deferred(),i=P.extend({},n,{queue:!1,complete:function(){e.resolve(t)}});return this.el.animate(this.diff,i),e.promise()}),P.when.apply(P,e.get()).done(function(){s(),P.each(arguments,function(){var e=this.el;P.each(this.diff,function(t){e.css(t,"")})}),n.complete.call(i[0])})})},P.fn.extend({addClass:(D=P.fn.addClass,function(t,e,i,s){return e?P.effects.animateClass.call(this,{add:t},e,i,s):D.apply(this,arguments)}),removeClass:(k=P.fn.removeClass,function(t,e,i,s){return 1<arguments.length?P.effects.animateClass.call(this,{remove:t},e,i,s):k.apply(this,arguments)}),toggleClass:(T=P.fn.toggleClass,function(t,e,i,s,o){return"boolean"==typeof e||void 0===e?i?P.effects.animateClass.call(this,e?{add:t}:{remove:t},i,s,o):T.apply(this,arguments):P.effects.animateClass.call(this,{toggle:t},e,i,s)}),switchClass:function(t,e,i,s,o){return P.effects.animateClass.call(this,{add:e,remove:t},i,s,o)}}),P.expr&&P.expr.filters&&P.expr.filters.animated&&(P.expr.filters.animated=(O=P.expr.filters.animated,function(t){return!!P(t).data(X)||O(t)})),!1!==P.uiBackCompat&&P.extend(P.effects,{save:function(t,e){for(var i=0,s=e.length;i<s;i++)null!==e[i]&&t.data(F+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,o=e.length;s<o;s++)null!==e[s]&&(i=t.data(F+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(i){if(i.parent().is(".ui-effects-wrapper"))return i.parent();var s={width:i.outerWidth(!0),height:i.outerHeight(!0),float:i.css("float")},t=P("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},o=document.activeElement;try{o.id}catch(t){o=document.body}return i.wrap(t),i[0]!==o&&!P.contains(i[0],o)||P(o).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(P.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),P.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!P.contains(t[0],e)||P(e).trigger("focus")),t}}),P.extend(P.effects,{version:"1.12.1",define:function(t,e,i){return i||(i=e,e="effect"),P.effects.effect[t]=i,P.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,o="vertical"!==i?(e||100)/100:1;return{height:t.height()*o,width:t.width()*s,outerHeight:t.outerHeight()*o,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1<e&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(B,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(B)||"",t.removeData(B)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(t){var e,i=t.css("position"),s=t.position();return t.css({marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()),/^(static|relative)/.test(i)&&(i="absolute",e=P("<"+t[0].nodeName+">").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(F+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=F+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){P.effects.restoreStyle(t),P.effects.removePlaceholder(t)},setTransition:function(s,t,o,n){return n=n||{},P.each(t,function(t,e){var i=s.cssUnit(e);0<i[0]&&(n[e]=i[0]*o+i[1])}),n}}),P.fn.extend({effect:function(){function t(t){var e=P(this),i=P.effects.mode(e,a)||n;e.data(X,!0),h.push(i),n&&("show"===i||i===n&&"hide"===i)&&e.show(),n&&"none"===i||P.effects.saveStyle(e),P.isFunction(t)&&t()}var s=K.apply(this,arguments),o=P.effects.effect[s.effect],n=o.mode,e=s.queue,i=e||"fx",r=s.complete,a=s.mode,h=[];if(P.fx.off||!o)return a?this[a](s.duration,r):this.each(function(){r&&r.call(this)});function l(t){var e=P(this);function i(){P.isFunction(r)&&r.call(e[0]),P.isFunction(t)&&t()}s.mode=h.shift(),!1===P.uiBackCompat||n?"none"===s.mode?(e[a](),i()):o.call(e[0],s,function(){e.removeData(X),P.effects.cleanUp(e),"hide"===s.mode&&e.hide(),i()}):(e.is(":hidden")?"hide"===a:"show"===a)?(e[a](),i()):o.call(e[0],s,i)}return!1===e?this.each(t).each(l):this.queue(i,t).queue(i,l)},show:(M=P.fn.show,function(t){if(V(t))return M.apply(this,arguments);var e=K.apply(this,arguments);return e.mode="show",this.effect.call(this,e)}),hide:(L=P.fn.hide,function(t){if(V(t))return L.apply(this,arguments);var e=K.apply(this,arguments);return e.mode="hide",this.effect.call(this,e)}),toggle:(R=P.fn.toggle,function(t){if(V(t)||"boolean"==typeof t)return R.apply(this,arguments);var e=K.apply(this,arguments);return e.mode="toggle",this.effect.call(this,e)}),cssUnit:function(t){var i=this.css(t),s=[];return P.each(["em","px","%","pt"],function(t,e){0<i.indexOf(e)&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):Q(this.css("clip"),this)},transfer:function(t,e){var i=P(this),s=P(t.to),o="fixed"===s.css("position"),n=P("body"),r=o?n.scrollTop():0,a=o?n.scrollLeft():0,h=s.offset(),l={top:h.top-r,left:h.left-a,height:s.innerHeight(),width:s.innerWidth()},c=i.offset(),p=P("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(t.className).css({top:c.top-r,left:c.left-a,height:i.innerHeight(),width:i.innerWidth(),position:o?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){p.remove(),P.isFunction(e)&&e()})}}),P.fx.step.clip=function(t){t.clipInit||(t.start=P(t.elem).cssClip(),"string"==typeof t.end&&(t.end=Q(t.end,t.elem)),t.clipInit=!0),P(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},A={},P.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){A[t]=function(t){return Math.pow(t,e+2)}}),P.extend(A,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),P.each(A,function(t,e){P.easing["easeIn"+t]=e,P.easing["easeOut"+t]=function(t){return 1-e(1-t)},P.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});P.effects,P.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=P(this),o=t.direction||"up",n=s.cssClip(),r={clip:P.extend({},n)},a=P.effects.createPlaceholder(s);r.clip[i[o][0]]=r.clip[i[o][1]],"show"===t.mode&&(s.cssClip(r.clip),a&&a.css(P.effects.clipToBox(r)),r.clip=n),a&&a.animate(P.effects.clipToBox(r),t.duration,t.easing),s.animate(r,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("bounce",function(t,e){var i,s,o,n=P(this),r=t.mode,a="hide"===r,h="show"===r,l=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(h||a?1:0),u=t.duration/f,d=t.easing,g="up"===l||"down"===l?"top":"left",m="up"===l||"left"===l,v=0,_=n.queue().length;for(P.effects.createPlaceholder(n),o=n.css(g),c=c||n["top"==g?"outerHeight":"outerWidth"]()/3,h&&((s={opacity:1})[g]=o,n.css("opacity",0).css(g,m?2*-c:2*c).animate(s,u,d)),a&&(c/=Math.pow(2,p-1)),(s={})[g]=o;v<p;v++)(i={})[g]=(m?"-=":"+=")+c,n.animate(i,u,d).animate(s,u,d),c=a?2*c:c/2;a&&((i={opacity:0})[g]=(m?"-=":"+=")+c,n.animate(i,u,d)),n.queue(e),P.effects.unshift(n,_,1+f)}),P.effects.define("drop","hide",function(t,e){var i,s=P(this),o="show"===t.mode,n=t.direction||"left",r="up"===n||"down"===n?"top":"left",a="up"===n||"left"===n?"-=":"+=",h="+="==a?"-=":"+=",l={opacity:0};P.effects.createPlaceholder(s),i=t.distance||s["top"==r?"outerHeight":"outerWidth"](!0)/2,l[r]=a+i,o&&(s.css(l),l[r]=h+i,l.opacity=1),s.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;P(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("fold","hide",function(e,t){var i=P(this),s=e.mode,o="show"===s,n="hide"===s,r=e.size||15,a=/([0-9]+)%/.exec(r),h=!!e.horizFirst?["right","bottom"]:["bottom","right"],l=e.duration/2,c=P.effects.createPlaceholder(i),p=i.cssClip(),f={clip:P.extend({},p)},u={clip:P.extend({},p)},d=[p[h[0]],p[h[1]]],g=i.queue().length;a&&(r=parseInt(a[1],10)/100*d[n?0:1]),f.clip[h[0]]=r,u.clip[h[0]]=r,u.clip[h[1]]=0,o&&(i.cssClip(u.clip),c&&c.css(P.effects.clipToBox(u)),u.clip=p),i.queue(function(t){c&&c.animate(P.effects.clipToBox(f),l,e.easing).animate(P.effects.clipToBox(u),l,e.easing),t()}).animate(f,l,e.easing).animate(u,l,e.easing).queue(t),P.effects.unshift(i,g,4)}),P.effects.define("highlight","show",function(t,e){var i=P(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),P.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("size",function(o,e){var t,n,i,s=P(this),r=["fontSize"],a=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=o.mode,c="effect"!==l,p=o.scale||"both",f=o.origin||["middle","center"],u=s.css("position"),d=s.position(),g=P.effects.scaledDimensions(s),m=o.from||g,v=o.to||P.effects.scaledDimensions(s,0);P.effects.createPlaceholder(s),"show"===l&&(i=m,m=v,v=i),n={from:{y:m.height/g.height,x:m.width/g.width},to:{y:v.height/g.height,x:v.width/g.width}},"box"!==p&&"both"!==p||(n.from.y!==n.to.y&&(m=P.effects.setTransition(s,a,n.from.y,m),v=P.effects.setTransition(s,a,n.to.y,v)),n.from.x!==n.to.x&&(m=P.effects.setTransition(s,h,n.from.x,m),v=P.effects.setTransition(s,h,n.to.x,v))),"content"!==p&&"both"!==p||n.from.y!==n.to.y&&(m=P.effects.setTransition(s,r,n.from.y,m),v=P.effects.setTransition(s,r,n.to.y,v)),f&&(t=P.effects.getBaseline(f,g),m.top=(g.outerHeight-m.outerHeight)*t.y+d.top,m.left=(g.outerWidth-m.outerWidth)*t.x+d.left,v.top=(g.outerHeight-v.outerHeight)*t.y+d.top,v.left=(g.outerWidth-v.outerWidth)*t.x+d.left),s.css(m),"content"!==p&&"both"!==p||(a=a.concat(["marginTop","marginBottom"]).concat(r),h=h.concat(["marginLeft","marginRight"]),s.find("*[width]").each(function(){var t=P(this),e=P.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},s={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=P.effects.setTransition(t,a,n.from.y,i),s=P.effects.setTransition(t,a,n.to.y,s)),n.from.x!==n.to.x&&(i=P.effects.setTransition(t,h,n.from.x,i),s=P.effects.setTransition(t,h,n.to.x,s)),c&&P.effects.saveStyle(t),t.css(i),t.animate(s,o.duration,o.easing,function(){c&&P.effects.restoreStyle(t)})})),s.animate(v,{queue:!1,duration:o.duration,easing:o.easing,complete:function(){var t=s.offset();0===v.opacity&&s.css("opacity",m.opacity),c||(s.css("position","static"===u?"relative":u).offset(t),P.effects.saveStyle(s)),e()}})}),P.effects.define("scale",function(t,e){var i=P(this),s=t.mode,o=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),n=P.extend(!0,{from:P.effects.scaledDimensions(i),to:P.effects.scaledDimensions(i,o,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(n.from.opacity=1,n.to.opacity=0),P.effects.effect.size.call(this,n,e)}),P.effects.define("puff","hide",function(t,e){var i=P.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});P.effects.effect.scale.call(this,i,e)}),P.effects.define("pulsate","show",function(t,e){var i=P(this),s=t.mode,o="show"===s,n=o||"hide"===s,r=2*(t.times||5)+(n?1:0),a=t.duration/r,h=0,l=1,c=i.queue().length;for(!o&&i.is(":visible")||(i.css("opacity",0).show(),h=1);l<r;l++)i.animate({opacity:h},a,t.easing),h=1-h;i.animate({opacity:h},a,t.easing),i.queue(e),P.effects.unshift(i,c,1+r)}),P.effects.define("shake",function(t,e){var i=1,s=P(this),o=t.direction||"left",n=t.distance||20,r=t.times||3,a=2*r+1,h=Math.round(t.duration/a),l="up"===o||"down"===o?"top":"left",c="up"===o||"left"===o,p={},f={},u={},d=s.queue().length;for(P.effects.createPlaceholder(s),p[l]=(c?"-=":"+=")+n,f[l]=(c?"+=":"-=")+2*n,u[l]=(c?"-=":"+=")+2*n,s.animate(p,h,t.easing);i<r;i++)s.animate(f,h,t.easing).animate(u,h,t.easing);s.animate(f,h,t.easing).animate(p,h/2,t.easing).queue(e),P.effects.unshift(s,d,1+a)}),P.effects.define("slide","show",function(t,e){var i,s,o=P(this),n={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=t.mode,a=t.direction||"left",h="up"===a||"down"===a?"top":"left",l="up"===a||"left"===a,c=t.distance||o["top"==h?"outerHeight":"outerWidth"](!0),p={};P.effects.createPlaceholder(o),i=o.cssClip(),s=o.position()[h],p[h]=(l?-1:1)*c+s,p.clip=o.cssClip(),p.clip[n[a][1]]=p.clip[n[a][0]],"show"===r&&(o.cssClip(p.clip),o.css(h,p[h]),p.clip=i,p[h]=s),o.animate(p,{queue:!1,duration:t.duration,easing:t.easing,complete:e})});!1!==P.uiBackCompat&&P.effects.define("transfer",function(t,e){P(this).transfer(t,e)})}); })(this);
 
 // 3rdParty/jquery-ui/touchPunch.js
-(function (window, undefined) { !function(o){function t(o,t){if(!(o.originalEvent.touches.length>1)){o.preventDefault();var e=o.originalEvent.changedTouches[0],u=document.createEvent("MouseEvents");u.initMouseEvent(t,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,!1,!1,!1,!1,0,null),o.target.dispatchEvent(u)}}if(o.support.touch="ontouchend"in document,o.support.touch){var e,u=o.ui.mouse.prototype,n=u._mouseInit,c=u._mouseDestroy;u._touchStart=function(o){var u=this;!e&&u._mouseCapture(o.originalEvent.changedTouches[0])&&(e=!0,u._touchMoved=!1,t(o,"mouseover"),t(o,"mousemove"),t(o,"mousedown"))},u._touchMove=function(o){e&&(this._touchMoved=!0,t(o,"mousemove"))},u._touchEnd=function(o){e&&(t(o,"mouseup"),t(o,"mouseout"),this._touchMoved||t(o,"click"),e=!1)},u._mouseInit=function(){var t=this;t.element.bind({touchstart:o.proxy(t,"_touchStart"),touchmove:o.proxy(t,"_touchMove"),touchend:o.proxy(t,"_touchEnd")}),n.call(t)},u._mouseDestroy=function(){var t=this;t.element.unbind({touchstart:o.proxy(t,"_touchStart"),touchmove:o.proxy(t,"_touchMove"),touchend:o.proxy(t,"_touchEnd")}),c.call(t)}}}(jQuery); })(this);
+(function (window, undefined) { !function(t){var o,e,u,n;function c(o,t){var e,u;1<o.originalEvent.touches.length||(o.preventDefault(),e=o.originalEvent.changedTouches[0],(u=document.createEvent("MouseEvents")).initMouseEvent(t,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,!1,!1,!1,!1,0,null),o.target.dispatchEvent(u))}t.support.touch="ontouchend"in document,t.support.touch&&(o=t.ui.mouse.prototype,e=o._mouseInit,u=o._mouseDestroy,o._touchStart=function(o){!n&&this._mouseCapture(o.originalEvent.changedTouches[0])&&(n=!0,this._touchMoved=!1,c(o,"mouseover"),c(o,"mousemove"),c(o,"mousedown"))},o._touchMove=function(o){n&&(this._touchMoved=!0,c(o,"mousemove"))},o._touchEnd=function(o){n&&(c(o,"mouseup"),c(o,"mouseout"),this._touchMoved||c(o,"click"),n=!1)},o._mouseInit=function(){var o=this;o.element.bind({touchstart:t.proxy(o,"_touchStart"),touchmove:t.proxy(o,"_touchMove"),touchend:t.proxy(o,"_touchEnd")}),e.call(o)},o._mouseDestroy=function(){var o=this;o.element.unbind({touchstart:t.proxy(o,"_touchStart"),touchmove:t.proxy(o,"_touchMove"),touchend:t.proxy(o,"_touchEnd")}),u.call(o)})}(jQuery); })(this);
 
 // 3rdParty/jquery-ui/nestedSortable.js
-(function (window, undefined) { !function(t){t.widget("mjs.nestedSortable",t.extend({},t.ui.sortable.prototype,{options:{tabSize:20,disableNesting:"mjs-nestedSortable-no-nesting",errorClass:"mjs-nestedSortable-error",doNotClear:!1,listType:"ol",maxLevels:0,protectRoot:!1,rootID:null,rtl:!1,isAllowed:function(t,e){return!0}},_create:function(){if(this.element.data("sortable",this.element.data("nestedSortable")),!this.element.is(this.options.listType))throw new Error("nestedSortable: Please check the listType option is set to your actual list type");return t.ui.sortable.prototype._create.apply(this,arguments)},destroy:function(){return this.element.removeData("nestedSortable").unbind(".nestedSortable"),t.ui.sortable.prototype.destroy.apply(this,arguments)},_mouseDrag:function(e){this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);var i=this.options;if(this.options.scroll){var s=!1;this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<i.scrollSensitivity?this.scrollParent[0].scrollTop=s=this.scrollParent[0].scrollTop+i.scrollSpeed:e.pageY-this.overflowOffset.top<i.scrollSensitivity&&(this.scrollParent[0].scrollTop=s=this.scrollParent[0].scrollTop-i.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<i.scrollSensitivity?this.scrollParent[0].scrollLeft=s=this.scrollParent[0].scrollLeft+i.scrollSpeed:e.pageX-this.overflowOffset.left<i.scrollSensitivity&&(this.scrollParent[0].scrollLeft=s=this.scrollParent[0].scrollLeft-i.scrollSpeed)):(e.pageY-t(document).scrollTop()<i.scrollSensitivity?s=t(document).scrollTop(t(document).scrollTop()-i.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<i.scrollSensitivity&&(s=t(document).scrollTop(t(document).scrollTop()+i.scrollSpeed)),e.pageX-t(document).scrollLeft()<i.scrollSensitivity?s=t(document).scrollLeft(t(document).scrollLeft()-i.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<i.scrollSensitivity&&(s=t(document).scrollLeft(t(document).scrollLeft()+i.scrollSpeed))),!1!==s&&t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)}this.positionAbs=this._convertPositionTo("absolute");var o=this.placeholder.offset().top;this.options.axis&&"y"==this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"==this.options.axis||(this.helper[0].style.top=this.position.top+"px");for(var l=this.items.length-1;l>=0;l--){var r=this.items[l],n=r.item[0],h=this._intersectsWithPointer(r);if(h&&!(n==this.currentItem[0]||this.placeholder[1==h?"next":"prev"]()[0]==n||t.contains(this.placeholder[0],n)||"semi-dynamic"==this.options.type&&t.contains(this.element[0],n))){if(t(n).mouseenter(),this.direction=1==h?"down":"up","pointer"!=this.options.tolerance&&!this._intersectsWithSides(r))break;t(n).mouseleave(),this._rearrange(e,r),this._clearEmpty(n),this._trigger("change",e,this._uiHash());break}}var a=this.placeholder[0].parentNode.parentNode&&t(this.placeholder[0].parentNode.parentNode).closest(".ui-sortable").length?t(this.placeholder[0].parentNode.parentNode):null,p=this._getLevel(this.placeholder),c=this._getChildLevels(this.helper),d=this.placeholder[0].previousSibling?t(this.placeholder[0].previousSibling):null;if(null!=d)for(;"li"!=d[0].nodeName.toLowerCase()||d[0]==this.currentItem[0]||d[0]==this.helper[0];){if(!d[0].previousSibling){d=null;break}d=t(d[0].previousSibling)}var u=this.placeholder[0].nextSibling?t(this.placeholder[0].nextSibling):null;if(null!=u)for(;"li"!=u[0].nodeName.toLowerCase()||u[0]==this.currentItem[0]||u[0]==this.helper[0];){if(!u[0].nextSibling){u=null;break}u=t(u[0].nextSibling)}var f=document.createElement(i.listType);return this.beyondMaxLevels=0,null!=a&&null==u&&(i.rtl&&this.positionAbs.left+this.helper.outerWidth()>a.offset().left+a.outerWidth()||!i.rtl&&this.positionAbs.left<a.offset().left)?(a.after(this.placeholder[0]),this._clearEmpty(a[0]),this._trigger("change",e,this._uiHash())):null!=d&&(i.rtl&&this.positionAbs.left+this.helper.outerWidth()<d.offset().left+d.outerWidth()-i.tabSize||!i.rtl&&this.positionAbs.left>d.offset().left+i.tabSize)?(this._isAllowed(d,p,p+c+1),d.children(i.listType).length||d[0].appendChild(f),o&&o<=d.offset().top?d.children(i.listType).prepend(this.placeholder):d.children(i.listType)[0].appendChild(this.placeholder[0]),this._trigger("change",e,this._uiHash())):this._isAllowed(a,p,p+c),this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){this.beyondMaxLevels&&(this.placeholder.removeClass(this.options.errorClass),this.domPosition.prev?t(this.domPosition.prev).after(this.placeholder):t(this.domPosition.parent).prepend(this.placeholder),this._trigger("revert",e,this._uiHash()));for(var s=this.items.length-1;s>=0;s--){var o=this.items[s].item[0];this._clearEmpty(o)}t.ui.sortable.prototype._mouseStop.apply(this,arguments)},serialize:function(e){var i=t.extend({},this.options,e),s=this._getItemsAsjQuery(i&&i.connected),o=[];return t(s).each(function(){var e=(t(i.item||this).attr(i.attribute||"id")||"").match(i.expression||/(.+)[-=_](.+)/),s=(t(i.item||this).parent(i.listType).parent(i.items).attr(i.attribute||"id")||"").match(i.expression||/(.+)[-=_](.+)/);e&&o.push((i.key||e[1])+"["+(i.key&&i.expression?e[1]:e[2])+"]="+(s?i.key&&i.expression?s[1]:s[2]:i.rootID))}),!o.length&&i.key&&o.push(i.key+"="),o.join("&")},toHierarchy:function(e){function i(e){var o=(t(e).attr(s.attribute||"id")||"").match(s.expression||/(.+)[-=_](.+)/);if(o){var l={id:o[2]};return t(e).children(s.listType).children(s.items).length>0&&(l.children=[],t(e).children(s.listType).children(s.items).each(function(){var t=i(this);l.children.push(t)})),l}}var s=t.extend({},this.options,e),o=(s.startDepthCount,[]);return t(this.element).children(s.items).each(function(){var t=i(this);o.push(t)}),o},toArray:function(e){function i(e,r,n){var h,a,p=n+1;if(t(e).children(s.listType).children(s.items).length>0&&(r++,t(e).children(s.listType).children(s.items).each(function(){p=i(t(this),r,p)}),r--),h=t(e).attr(s.attribute||"id").match(s.expression||/(.+)[-=_](.+)/),r===o+1)a=s.rootID;else{a=t(e).parent(s.listType).parent(s.items).attr(s.attribute||"id").match(s.expression||/(.+)[-=_](.+)/)[2]}return h&&l.push({item_id:h[2],parent_id:a,depth:r,left:n,right:p}),n=p+1}var s=t.extend({},this.options,e),o=s.startDepthCount||0,l=[],r=2;return l.push({item_id:s.rootID,parent_id:"none",depth:o,left:"1",right:2*(t(s.items,this.element).length+1)}),t(this.element).children(s.items).each(function(){r=i(this,o+1,r)}),l=l.sort(function(t,e){return t.left-e.left})},_clearEmpty:function(e){var i=t(e).children(this.options.listType);!i.length||i.children().length||this.options.doNotClear||i.remove()},_getLevel:function(t){var e=1;if(this.options.listType)for(var i=t.closest(this.options.listType);i&&i.length>0&&!i.is(".ui-sortable");)e++,i=i.parent().closest(this.options.listType);return e},_getChildLevels:function(e,i){var s=this,o=this.options,l=0;return i=i||0,t(e).children(o.listType).children(o.items).each(function(t,e){l=Math.max(s._getChildLevels(e,i+1),l)}),i?l+1:l},_isAllowed:function(e,i,s){var o=this.options,l=!!t(this.domPosition.parent).hasClass("ui-sortable"),r=this.placeholder.closest(".ui-sortable").nestedSortable("option","maxLevels");!o.isAllowed(this.currentItem,e)||e&&e.hasClass(o.disableNesting)||o.protectRoot&&(null==e&&!l||l&&i>1)?(this.placeholder.addClass(o.errorClass),this.beyondMaxLevels=r<s&&0!=r?s-r:1):r<s&&0!=r?(this.placeholder.addClass(o.errorClass),this.beyondMaxLevels=s-r):(this.placeholder.removeClass(o.errorClass),this.beyondMaxLevels=0)}})),t.mjs.nestedSortable.prototype.options=t.extend({},t.ui.sortable.prototype.options,t.mjs.nestedSortable.prototype.options)}(jQuery); })(this);
+(function (window, undefined) { !function(f){f.widget("mjs.nestedSortable",f.extend({},f.ui.sortable.prototype,{options:{tabSize:20,disableNesting:"mjs-nestedSortable-no-nesting",errorClass:"mjs-nestedSortable-error",doNotClear:!1,listType:"ol",maxLevels:0,protectRoot:!1,rootID:null,rtl:!1,isAllowed:function(t,e){return!0}},_create:function(){if(this.element.data("sortable",this.element.data("nestedSortable")),!this.element.is(this.options.listType))throw new Error("nestedSortable: Please check the listType option is set to your actual list type");return f.ui.sortable.prototype._create.apply(this,arguments)},destroy:function(){return this.element.removeData("nestedSortable").unbind(".nestedSortable"),f.ui.sortable.prototype.destroy.apply(this,arguments)},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);var e,s=this.options;this.options.scroll&&(e=!1,this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<s.scrollSensitivity?this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop+s.scrollSpeed:t.pageY-this.overflowOffset.top<s.scrollSensitivity&&(this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop-s.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<s.scrollSensitivity?this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft+s.scrollSpeed:t.pageX-this.overflowOffset.left<s.scrollSensitivity&&(this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft-s.scrollSpeed)):(t.pageY-f(document).scrollTop()<s.scrollSensitivity?e=f(document).scrollTop(f(document).scrollTop()-s.scrollSpeed):f(window).height()-(t.pageY-f(document).scrollTop())<s.scrollSensitivity&&(e=f(document).scrollTop(f(document).scrollTop()+s.scrollSpeed)),t.pageX-f(document).scrollLeft()<s.scrollSensitivity?e=f(document).scrollLeft(f(document).scrollLeft()-s.scrollSpeed):f(window).width()-(t.pageX-f(document).scrollLeft())<s.scrollSensitivity&&(e=f(document).scrollLeft(f(document).scrollLeft()+s.scrollSpeed))),!1!==e&&f.ui.ddmanager&&!s.dropBehaviour&&f.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute");var i=this.placeholder.offset().top;this.options.axis&&"y"==this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"==this.options.axis||(this.helper[0].style.top=this.position.top+"px");for(var o=this.items.length-1;0<=o;o--){var r=this.items[o],l=r.item[0],n=this._intersectsWithPointer(r);if(n&&!(l==this.currentItem[0]||this.placeholder[1==n?"next":"prev"]()[0]==l||f.contains(this.placeholder[0],l)||"semi-dynamic"==this.options.type&&f.contains(this.element[0],l))){if(f(l).mouseenter(),this.direction=1==n?"down":"up","pointer"!=this.options.tolerance&&!this._intersectsWithSides(r))break;f(l).mouseleave(),this._rearrange(t,r),this._clearEmpty(l),this._trigger("change",t,this._uiHash());break}}var h=this.placeholder[0].parentNode.parentNode&&f(this.placeholder[0].parentNode.parentNode).closest(".ui-sortable").length?f(this.placeholder[0].parentNode.parentNode):null,a=this._getLevel(this.placeholder),p=this._getChildLevels(this.helper),c=this.placeholder[0].previousSibling?f(this.placeholder[0].previousSibling):null;if(null!=c)for(;"li"!=c[0].nodeName.toLowerCase()||c[0]==this.currentItem[0]||c[0]==this.helper[0];){if(!c[0].previousSibling){c=null;break}c=f(c[0].previousSibling)}var d=this.placeholder[0].nextSibling?f(this.placeholder[0].nextSibling):null;if(null!=d)for(;"li"!=d[0].nodeName.toLowerCase()||d[0]==this.currentItem[0]||d[0]==this.helper[0];){if(!d[0].nextSibling){d=null;break}d=f(d[0].nextSibling)}var u=document.createElement(s.listType);return this.beyondMaxLevels=0,null!=h&&null==d&&(s.rtl&&this.positionAbs.left+this.helper.outerWidth()>h.offset().left+h.outerWidth()||!s.rtl&&this.positionAbs.left<h.offset().left)?(h.after(this.placeholder[0]),this._clearEmpty(h[0]),this._trigger("change",t,this._uiHash())):null!=c&&(s.rtl&&this.positionAbs.left+this.helper.outerWidth()<c.offset().left+c.outerWidth()-s.tabSize||!s.rtl&&this.positionAbs.left>c.offset().left+s.tabSize)?(this._isAllowed(c,a,a+p+1),c.children(s.listType).length||c[0].appendChild(u),i&&i<=c.offset().top?c.children(s.listType).prepend(this.placeholder):c.children(s.listType)[0].appendChild(this.placeholder[0]),this._trigger("change",t,this._uiHash())):this._isAllowed(h,a,a+p),this._contactContainers(t),f.ui.ddmanager&&f.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,e){this.beyondMaxLevels&&(this.placeholder.removeClass(this.options.errorClass),this.domPosition.prev?f(this.domPosition.prev).after(this.placeholder):f(this.domPosition.parent).prepend(this.placeholder),this._trigger("revert",t,this._uiHash()));for(var s=this.items.length-1;0<=s;s--){var i=this.items[s].item[0];this._clearEmpty(i)}f.ui.sortable.prototype._mouseStop.apply(this,arguments)},serialize:function(t){var s=f.extend({},this.options,t),e=this._getItemsAsjQuery(s&&s.connected),i=[];return f(e).each(function(){var t=(f(s.item||this).attr(s.attribute||"id")||"").match(s.expression||/(.+)[-=_](.+)/),e=(f(s.item||this).parent(s.listType).parent(s.items).attr(s.attribute||"id")||"").match(s.expression||/(.+)[-=_](.+)/);t&&i.push((s.key||t[1])+"["+(s.key&&s.expression?t[1]:t[2])+"]="+(e?s.key&&s.expression?e[1]:e[2]:s.rootID))}),!i.length&&s.key&&i.push(s.key+"="),i.join("&")},toHierarchy:function(t){var o=f.extend({},this.options,t),e=(o.startDepthCount,[]);return f(this.element).children(o.items).each(function(){var t=function e(t){var s=(f(t).attr(o.attribute||"id")||"").match(o.expression||/(.+)[-=_](.+)/);if(s){var i={id:s[2]};return 0<f(t).children(o.listType).children(o.items).length&&(i.children=[],f(t).children(o.listType).children(o.items).each(function(){var t=e(this);i.children.push(t)})),i}}(this);e.push(t)}),e},toArray:function(t){var h=f.extend({},this.options,t),a=h.startDepthCount||0,p=[],e=2;return p.push({item_id:h.rootID,parent_id:"none",depth:a,left:"1",right:2*(f(h.items,this.element).length+1)}),f(this.element).children(h.items).each(function(){e=function t(e,s,i){var o,r,l=i+1;0<f(e).children(h.listType).children(h.items).length&&(s++,f(e).children(h.listType).children(h.items).each(function(){l=t(f(this),s,l)}),s--);o=f(e).attr(h.attribute||"id").match(h.expression||/(.+)[-=_](.+)/);{var n;r=s===a+1?h.rootID:(n=f(e).parent(h.listType).parent(h.items).attr(h.attribute||"id").match(h.expression||/(.+)[-=_](.+)/),n[2])}o&&p.push({item_id:o[2],parent_id:r,depth:s,left:i,right:l});i=l+1;return i}(this,a+1,e)}),p=p.sort(function(t,e){return t.left-e.left})},_clearEmpty:function(t){var e=f(t).children(this.options.listType);!e.length||e.children().length||this.options.doNotClear||e.remove()},_getLevel:function(t){var e=1;if(this.options.listType)for(var s=t.closest(this.options.listType);s&&0<s.length&&!s.is(".ui-sortable");)e++,s=s.parent().closest(this.options.listType);return e},_getChildLevels:function(t,s){var i=this,e=this.options,o=0;return s=s||0,f(t).children(e.listType).children(e.items).each(function(t,e){o=Math.max(i._getChildLevels(e,s+1),o)}),s?o+1:o},_isAllowed:function(t,e,s){var i=this.options,o=!!f(this.domPosition.parent).hasClass("ui-sortable"),r=this.placeholder.closest(".ui-sortable").nestedSortable("option","maxLevels");!i.isAllowed(this.currentItem,t)||t&&t.hasClass(i.disableNesting)||i.protectRoot&&(null==t&&!o||o&&1<e)?(this.placeholder.addClass(i.errorClass),this.beyondMaxLevels=r<s&&0!=r?s-r:1):r<s&&0!=r?(this.placeholder.addClass(i.errorClass),this.beyondMaxLevels=s-r):(this.placeholder.removeClass(i.errorClass),this.beyondMaxLevels=0)}})),f.mjs.nestedSortable.prototype.options=f.extend({},f.ui.sortable.prototype.options,f.mjs.nestedSortable.prototype.options)}(jQuery); })(this);
 
 // 3rdParty/polyfill/focus-visible.js
-(function (window, undefined) { function applyFocusVisiblePolyfill(e){function t(e){return!!(e&&e!==document&&"HTML"!==e.nodeName&&"BODY"!==e.nodeName&&"classList"in e&&"contains"in e.classList)}function n(e){var t=e.type,n=e.tagName;return!("INPUT"!=n||!L[t]||e.readOnly)||("TEXTAREA"==n&&!e.readOnly||!!e.isContentEditable)}function o(e){e.classList.contains("focus-visible")||(e.classList.add("focus-visible"),e.setAttribute("data-focus-visible-added",""))}function i(e){e.hasAttribute("data-focus-visible-added")&&(e.classList.remove("focus-visible"),e.removeAttribute("data-focus-visible-added"))}function d(n){n.metaKey||n.altKey||n.ctrlKey||(t(e.activeElement)&&o(e.activeElement),l=!0)}function s(e){l=!1}function u(e){t(e.target)&&(l||n(e.target))&&o(e.target)}function a(e){t(e.target)&&(e.target.classList.contains("focus-visible")||e.target.hasAttribute("data-focus-visible-added"))&&(E=!0,window.clearTimeout(f),f=window.setTimeout(function(){E=!1,window.clearTimeout(f)},100),i(e.target))}function c(e){"hidden"==document.visibilityState&&(E&&(l=!0),r())}function r(){document.addEventListener("mousemove",v),document.addEventListener("mousedown",v),document.addEventListener("mouseup",v),document.addEventListener("pointermove",v),document.addEventListener("pointerdown",v),document.addEventListener("pointerup",v),document.addEventListener("touchmove",v),document.addEventListener("touchstart",v),document.addEventListener("touchend",v)}function m(){document.removeEventListener("mousemove",v),document.removeEventListener("mousedown",v),document.removeEventListener("mouseup",v),document.removeEventListener("pointermove",v),document.removeEventListener("pointerdown",v),document.removeEventListener("pointerup",v),document.removeEventListener("touchmove",v),document.removeEventListener("touchstart",v),document.removeEventListener("touchend",v)}function v(e){e.target.nodeName&&"html"===e.target.nodeName.toLowerCase()||(l=!1,m())}var l=!0,E=!1,f=null,L={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};document.addEventListener("keydown",d,!0),document.addEventListener("mousedown",s,!0),document.addEventListener("pointerdown",s,!0),document.addEventListener("touchstart",s,!0),document.addEventListener("visibilitychange",c,!0),r(),e.addEventListener("focus",u,!0),e.addEventListener("blur",a,!0),e.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&e.host?e.host.setAttribute("data-js-focus-visible",""):e.nodeType===Node.DOCUMENT_NODE&&document.documentElement.classList.add("js-focus-visible")}if("undefined"!=typeof window&&"undefined"!=typeof document){window.applyFocusVisiblePolyfill=applyFocusVisiblePolyfill;var event;try{event=new CustomEvent("focus-visible-polyfill-ready")}catch(e){event=document.createEvent("CustomEvent"),event.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(event)}"undefined"!=typeof document&&applyFocusVisiblePolyfill(document); })(this);
+(function (window, undefined) { function applyFocusVisiblePolyfill(t){var i=!0,n=!1,o=null,d={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(e){return!!(e&&e!==document&&"HTML"!==e.nodeName&&"BODY"!==e.nodeName&&"classList"in e&&"contains"in e.classList)}function u(e){e.classList.contains("focus-visible")||(e.classList.add("focus-visible"),e.setAttribute("data-focus-visible-added",""))}function e(e){i=!1}function a(){document.addEventListener("mousemove",c),document.addEventListener("mousedown",c),document.addEventListener("mouseup",c),document.addEventListener("pointermove",c),document.addEventListener("pointerdown",c),document.addEventListener("pointerup",c),document.addEventListener("touchmove",c),document.addEventListener("touchstart",c),document.addEventListener("touchend",c)}function c(e){e.target.nodeName&&"html"===e.target.nodeName.toLowerCase()||(i=!1,document.removeEventListener("mousemove",c),document.removeEventListener("mousedown",c),document.removeEventListener("mouseup",c),document.removeEventListener("pointermove",c),document.removeEventListener("pointerdown",c),document.removeEventListener("pointerup",c),document.removeEventListener("touchmove",c),document.removeEventListener("touchstart",c),document.removeEventListener("touchend",c))}document.addEventListener("keydown",function(e){e.metaKey||e.altKey||e.ctrlKey||(s(t.activeElement)&&u(t.activeElement),i=!0)},!0),document.addEventListener("mousedown",e,!0),document.addEventListener("pointerdown",e,!0),document.addEventListener("touchstart",e,!0),document.addEventListener("visibilitychange",function(e){"hidden"==document.visibilityState&&(n&&(i=!0),a())},!0),a(),t.addEventListener("focus",function(e){var t,n,o;s(e.target)&&(i||(t=e.target,n=t.type,"INPUT"==(o=t.tagName)&&d[n]&&!t.readOnly||("TEXTAREA"==o&&!t.readOnly||!!t.isContentEditable)))&&u(e.target)},!0),t.addEventListener("blur",function(e){var t;s(e.target)&&(e.target.classList.contains("focus-visible")||e.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(o),o=window.setTimeout(function(){n=!1,window.clearTimeout(o)},100),(t=e.target).hasAttribute("data-focus-visible-added")&&(t.classList.remove("focus-visible"),t.removeAttribute("data-focus-visible-added")))},!0),t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host?t.host.setAttribute("data-js-focus-visible",""):t.nodeType===Node.DOCUMENT_NODE&&document.documentElement.classList.add("js-focus-visible")}if("undefined"!=typeof window&&"undefined"!=typeof document){var event;window.applyFocusVisiblePolyfill=applyFocusVisiblePolyfill;try{event=new CustomEvent("focus-visible-polyfill-ready")}catch(e){(event=document.createEvent("CustomEvent")).initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(event)}"undefined"!=typeof document&&applyFocusVisiblePolyfill(document); })(this);
 
 // WCF.Assets.js
-(function (window, undefined) { !function(){var e=!1,t=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){},Class.extend=function(n){function r(){!e&&this.init&&this.init.apply(this,arguments)}var i=this.prototype;e=!0;var o=new this;e=!1;for(var a in n)o[a]="function"==typeof n[a]&&"function"==typeof i[a]&&t.test(n[a])?function(e,t){return function(){var n=this._super;this._super=i[e];var r=t.apply(this,arguments);return this._super=n,r}}(a,n[a]):n[a];return r.prototype=o,r.prototype.constructor=r,r.extend=arguments.callee,r}}(),function(e,t){"use strict";function n(){}function r(e,t){if(e){"object"==typeof e&&(e=[].slice.call(e));for(var n=0,r=e.length;n<r;n++)t.call(e,e[n],n)}}function i(e,n){var r=Object.prototype.toString.call(n).slice(8,-1);return n!==t&&null!==n&&r===e}function o(e){return i("Function",e)}function a(e){return i("Array",e)}function l(e){var t=e.split("/"),n=t[t.length-1],r=n.indexOf("?");return-1!==r?n.substring(0,r):n}function u(e){e=e||n,e._done||(e(),e._done=1)}function c(e,t,r,i){var o="object"==typeof e?e:{test:e,success:!!t&&(a(t)?t:[t]),failure:!!r&&(a(r)?r:[r]),callback:i||n},l=!!o.test;return l&&o.success?(o.success.push(o.callback),N.load.apply(null,o.success)):l||!o.failure?i():(o.failure.push(o.callback),N.load.apply(null,o.failure)),N}function s(e){var t,n,r={};if("object"==typeof e)for(t in e)!e[t]||(r={name:t,url:e[t]});else r={name:l(e),url:e};return(n=S[r.name])&&n.url===r.url?n:(S[r.name]=r,r)}function p(e){e=e||S;for(var t in e)if(e.hasOwnProperty(t)&&e[t].state!==F)return!1;return!0}function d(e){e.state=P,r(e.onpreload,function(e){e.call()})}function f(e){e.state===t&&(e.state=I,e.onpreload=[],b({url:e.url,type:"cache"},function(){d(e)}))}function h(){var e=arguments,t=e[e.length-1],n=[].slice.call(e,1),i=n[0];return o(t)||(t=null),a(e[0])?(e[0].push(t),N.load.apply(null,e[0]),N):(i?(r(n,function(e){o(e)||!e||f(s(e))}),v(s(e[0]),o(i)?i:function(){N.load.apply(null,n)})):v(s(e[0])),N)}function g(){var e=arguments,t=e[e.length-1],n={};return o(t)||(t=null),a(e[0])?(e[0].push(t),N.load.apply(null,e[0]),N):(r(e,function(e){e!==t&&(e=s(e),n[e.name]=e)}),r(e,function(e){e!==t&&(e=s(e),v(e,function(){p(n)&&u(t)}))}),N)}function v(e,t){return t=t||n,e.state===F?void t():e.state===D?void N.ready(e.name,t):e.state===I?void e.onpreload.push(function(){v(e,t)}):(e.state=D,void b(e,function(){e.state=F,t(),r(k[e.name],function(e){u(e)}),O&&p()&&r(k.ALL,function(e){u(e)})}))}function m(e){e=e||"";var t=e.split("?")[0].split(".");return t[t.length-1].toLowerCase()}function b(t,r){function i(t){t=t||e.event,l.onload=l.onreadystatechange=l.onerror=null,r()}function o(n){n=n||e.event,("load"===n.type||/loaded|complete/.test(l.readyState)&&(!x.documentMode||x.documentMode<9))&&(e.clearTimeout(t.errorTimeout),e.clearTimeout(t.cssTimeout),l.onload=l.onreadystatechange=l.onerror=null,r())}function a(){if(t.state!==F&&t.cssRetries<=20){for(var n=0,r=x.styleSheets.length;n<r;n++)if(x.styleSheets[n].href===l.href)return void o({type:"load"});t.cssRetries++,t.cssTimeout=e.setTimeout(a,250)}}var l,u,c;r=r||n,u=m(t.url),"css"===u?(l=x.createElement("link"),l.type="text/"+(t.type||"css"),l.rel="stylesheet",l.href=t.url,t.cssRetries=0,t.cssTimeout=e.setTimeout(a,500)):(l=x.createElement("script"),l.type="text/"+(t.type||"javascript"),l.src=t.url),l.onload=l.onreadystatechange=o,l.onerror=i,l.async=!1,l.defer=!1,t.errorTimeout=e.setTimeout(function(){i({type:"timeout"})},7e3),c=x.head||x.getElementsByTagName("head")[0],c.insertBefore(l,c.lastChild)}function w(){for(var e,t=x.getElementsByTagName("script"),n=0,r=t.length;n<r;n++)if(!!(e=t[n].getAttribute("data-headjs-load")))return void N.load(e)}function y(e,t){var n,i,l;return e===x?(O?u(t):L.push(t),N):(o(e)&&(t=e,e="ALL"),a(e)?(n={},r(e,function(e){n[e]=S[e],N.ready(e,function(){p(n)&&u(t)})}),N):"string"==typeof e&&o(t)?(i=S[e])&&i.state===F||"ALL"===e&&p()&&O?(u(t),N):(l=k[e],l?l.push(t):l=k[e]=[t],N):N)}function T(){if(!x.body)return e.clearTimeout(N.readyTimeout),void(N.readyTimeout=e.setTimeout(T,50));O||(O=!0,w(),r(L,function(e){u(e)}))}function E(){x.addEventListener?(x.removeEventListener("DOMContentLoaded",E,!1),T()):"complete"===x.readyState&&(x.detachEvent("onreadystatechange",E),T())}var O,A,x=e.document,L=[],k={},S={},C="async"in x.createElement("script")||"MozAppearance"in x.documentElement.style||e.opera,M=e.head_conf&&e.head_conf.head||"head",N=e[M]=e[M]||function(){N.ready.apply(null,arguments)},I=1,P=2,D=3,F=4;if("complete"===x.readyState)T();else if(x.addEventListener)x.addEventListener("DOMContentLoaded",E,!1),e.addEventListener("load",T,!1);else{x.attachEvent("onreadystatechange",E),e.attachEvent("onload",T),A=!1;try{A=!e.frameElement&&x.documentElement}catch(e){}A&&A.doScroll&&function t(){if(!O){try{A.doScroll("left")}catch(n){return e.clearTimeout(N.readyTimeout),void(N.readyTimeout=e.setTimeout(t,50))}T()}}()}N.load=N.js=C?g:h,N.test=c,N.ready=y,N.ready(x,function(){p()&&r(k.ALL,function(e){u(e)}),N.feature&&N.feature("domloaded",!0)})}(window),function(e){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],e):e(jQuery)}(function(e){function t(t){return!t||void 0!==t.allowPageScroll||void 0===t.swipe&&void 0===t.swipeStatus||(t.allowPageScroll=c),void 0!==t.click&&void 0===t.tap&&(t.tap=t.click),t||(t={}),t=e.extend({},e.fn.swipe.defaults,t),this.each(function(){var r=e(this),i=r.data(k);i||(i=new n(this,t),r.data(k,i))})}function n(t,n){function S(t){if(!(ce()||e(t.target).closest(n.excludedElements,Xe).length>0)){var r,i=t.originalEvent?t.originalEvent:t,o=A?i.touches[0]:i;return Qe=y,(A?Ye=i.touches.length:t.preventDefault(),Fe=0,ze=null,Ue=null,Re=0,_e=0,je=0,Ve=1,qe=0,Be=he(),He=me(),le(),!A||Ye===n.fingers||n.fingers===b||H()?(pe(0,o),We=Le(),2==Ye&&(pe(1,i.touches[1]),_e=je=ye(Be[0].start,Be[1].start)),(n.swipeStatus||n.pinchStatus)&&(r=F(i,Qe))):r=!1,!1===r)?(Qe=O,F(i,Qe),r):(n.hold&&(et=setTimeout(e.proxy(function(){Xe.trigger("hold",[i.target]),n.hold&&(r=n.hold.call(Xe,i,i.target))},this),n.longTapThreshold)),se(!0),null)}}function C(e){var t=e.originalEvent?e.originalEvent:e;if(Qe!==E&&Qe!==O&&!ue()){var r,i=A?t.touches[0]:t,o=de(i);if(Ze=Le(),A&&(Ye=t.touches.length),n.hold&&clearTimeout(et),Qe=T,2==Ye&&(0==_e?(pe(1,t.touches[1]),_e=je=ye(Be[0].start,Be[1].start)):(de(t.touches[1]),je=ye(Be[0].end,Be[1].end),Ue=Ee(Be[0].end,Be[1].end)),Ve=Te(_e,je),qe=Math.abs(_e-je)),Ye===n.fingers||n.fingers===b||!A||H()){if(ze=xe(o.start,o.end),q(e,ze),Fe=Oe(o.start,o.end),Re=we(),ge(ze,Fe),(n.swipeStatus||n.pinchStatus)&&(r=F(t,Qe)),!n.triggerOnTouchEnd||n.triggerOnTouchLeave){var a=!0;if(n.triggerOnTouchLeave){var l=ke(this);a=Se(o.end,l)}!n.triggerOnTouchEnd&&a?Qe=D(T):n.triggerOnTouchLeave&&!a&&(Qe=D(E)),Qe!=O&&Qe!=E||F(t,Qe)}}else Qe=O,F(t,Qe);!1===r&&(Qe=O,F(t,Qe))}}function M(e){var t=e.originalEvent;return A&&t.touches.length>0?(ae(),!0):(ue()&&(Ye=Ke),Ze=Le(),Re=we(),_()||!R()?(Qe=O,F(t,Qe)):n.triggerOnTouchEnd||0==n.triggerOnTouchEnd&&Qe===T?(e.preventDefault(),Qe=E,F(t,Qe)):!n.triggerOnTouchEnd&&G()?(Qe=E,z(t,Qe,f)):Qe===T&&(Qe=O,F(t,Qe)),se(!1),null)}function N(){Ye=0,Ze=0,We=0,_e=0,je=0,Ve=1,le(),se(!1)}function I(e){var t=e.originalEvent;n.triggerOnTouchLeave&&(Qe=D(E),F(t,Qe))}function P(){Xe.unbind(Me,S),Xe.unbind(De,N),Xe.unbind(Ne,C),Xe.unbind(Ie,M),Pe&&Xe.unbind(Pe,I),se(!1)}function D(e){var t=e,r=V(),i=R(),o=_();return!r||o?t=O:!i||e!=T||n.triggerOnTouchEnd&&!n.triggerOnTouchLeave?!i&&e==E&&n.triggerOnTouchLeave&&(t=O):t=E,t}function F(e,t){var n=void 0;return B()||Y()?n=z(e,t,p):(X()||H())&&!1!==n&&(n=z(e,t,d)),ie()&&!1!==n?n=z(e,t,h):oe()&&!1!==n?n=z(e,t,g):re()&&!1!==n&&(n=z(e,t,f)),t===O&&N(e),t===E&&(A?0==e.touches.length&&N(e):N(e)),n}function z(t,c,s){var v=void 0;if(s==p){if(Xe.trigger("swipeStatus",[c,ze||null,Fe||0,Re||0,Ye,Be]),n.swipeStatus&&!1===(v=n.swipeStatus.call(Xe,t,c,ze||null,Fe||0,Re||0,Ye,Be)))return!1;if(c==E&&Q()){if(Xe.trigger("swipe",[ze,Fe,Re,Ye,Be]),n.swipe&&!1===(v=n.swipe.call(Xe,t,ze,Fe,Re,Ye,Be)))return!1;switch(ze){case r:Xe.trigger("swipeLeft",[ze,Fe,Re,Ye,Be]),n.swipeLeft&&(v=n.swipeLeft.call(Xe,t,ze,Fe,Re,Ye,Be));break;case i:Xe.trigger("swipeRight",[ze,Fe,Re,Ye,Be]),n.swipeRight&&(v=n.swipeRight.call(Xe,t,ze,Fe,Re,Ye,Be));break;case o:Xe.trigger("swipeUp",[ze,Fe,Re,Ye,Be]),n.swipeUp&&(v=n.swipeUp.call(Xe,t,ze,Fe,Re,Ye,Be));break;case a:Xe.trigger("swipeDown",[ze,Fe,Re,Ye,Be]),n.swipeDown&&(v=n.swipeDown.call(Xe,t,ze,Fe,Re,Ye,Be))}}}if(s==d){if(Xe.trigger("pinchStatus",[c,Ue||null,qe||0,Re||0,Ye,Ve,Be]),n.pinchStatus&&!1===(v=n.pinchStatus.call(Xe,t,c,Ue||null,qe||0,Re||0,Ye,Ve,Be)))return!1;if(c==E&&U())switch(Ue){case l:Xe.trigger("pinchIn",[Ue||null,qe||0,Re||0,Ye,Ve,Be]),n.pinchIn&&(v=n.pinchIn.call(Xe,t,Ue||null,qe||0,Re||0,Ye,Ve,Be));break;case u:Xe.trigger("pinchOut",[Ue||null,qe||0,Re||0,Ye,Ve,Be]),n.pinchOut&&(v=n.pinchOut.call(Xe,t,Ue||null,qe||0,Re||0,Ye,Ve,Be))}}return s==f?c!==O&&c!==E||(clearTimeout(Je),clearTimeout(et),K()&&!ee()?($e=Le(),Je=setTimeout(e.proxy(function(){$e=null,Xe.trigger("tap",[t.target]),n.tap&&(v=n.tap.call(Xe,t,t.target))},this),n.doubleTapThreshold)):($e=null,Xe.trigger("tap",[t.target]),n.tap&&(v=n.tap.call(Xe,t,t.target)))):s==h?c!==O&&c!==E||(clearTimeout(Je),$e=null,Xe.trigger("doubletap",[t.target]),n.doubleTap&&(v=n.doubleTap.call(Xe,t,t.target))):s==g&&(c!==O&&c!==E||(clearTimeout(Je),$e=null,Xe.trigger("longtap",[t.target]),n.longTap&&(v=n.longTap.call(Xe,t,t.target)))),v}function R(){var e=!0;return null!==n.threshold&&(e=Fe>=n.threshold),e}function _(){var e=!1;return null!==n.cancelThreshold&&null!==ze&&(e=ve(ze)-Fe>=n.cancelThreshold),e}function j(){return null===n.pinchThreshold||qe>=n.pinchThreshold}function V(){return!n.maxTimeThreshold||!(Re>=n.maxTimeThreshold)}function q(e,t){if(n.allowPageScroll===c||H())e.preventDefault();else{var l=n.allowPageScroll===s;switch(t){case r:(n.swipeLeft&&l||!l&&n.allowPageScroll!=v)&&e.preventDefault();break;case i:(n.swipeRight&&l||!l&&n.allowPageScroll!=v)&&e.preventDefault();break;case o:(n.swipeUp&&l||!l&&n.allowPageScroll!=m)&&e.preventDefault();break;case a:(n.swipeDown&&l||!l&&n.allowPageScroll!=m)&&e.preventDefault()}}}function U(){var e=W(),t=Z(),n=j();return e&&t&&n}function H(){return!!(n.pinchStatus||n.pinchIn||n.pinchOut)}function X(){return!(!U()||!H())}function Q(){var e=V(),t=R(),n=W(),r=Z();return!_()&&r&&n&&t&&e}function Y(){return!!(n.swipe||n.swipeStatus||n.swipeLeft||n.swipeRight||n.swipeUp||n.swipeDown)}function B(){return!(!Q()||!Y())}function W(){return Ye===n.fingers||n.fingers===b||!A}function Z(){return 0!==Be[0].end.x}function G(){return!!n.tap}function K(){return!!n.doubleTap}function $(){return!!n.longTap}function J(){if(null==$e)return!1;var e=Le();return K()&&e-$e<=n.doubleTapThreshold}function ee(){return J()}function te(){return(1===Ye||!A)&&(isNaN(Fe)||Fe<n.threshold)}function ne(){return Re>n.longTapThreshold&&Fe<w}function re(){return!(!te()||!G())}function ie(){return!(!J()||!K())}function oe(){return!(!ne()||!$())}function ae(){Ge=Le(),Ke=event.touches.length+1}function le(){Ge=0,Ke=0}function ue(){var e=!1;if(Ge){Le()-Ge<=n.fingerReleaseThreshold&&(e=!0)}return e}function ce(){return!(!0!==Xe.data(k+"_intouch"))}function se(e){!0===e?(Xe.bind(Ne,C),Xe.bind(Ie,M),Pe&&Xe.bind(Pe,I)):(Xe.unbind(Ne,C,!1),Xe.unbind(Ie,M,!1),Pe&&Xe.unbind(Pe,I,!1)),Xe.data(k+"_intouch",!0===e)}function pe(e,t){var n=void 0!==t.identifier?t.identifier:0;return Be[e].identifier=n,Be[e].start.x=Be[e].end.x=t.pageX||t.clientX,Be[e].start.y=Be[e].end.y=t.pageY||t.clientY,Be[e]}function de(e){var t=void 0!==e.identifier?e.identifier:0,n=fe(t);return n.end.x=e.pageX||e.clientX,n.end.y=e.pageY||e.clientY,n}function fe(e){for(var t=0;t<Be.length;t++)if(Be[t].identifier==e)return Be[t]}function he(){for(var e=[],t=0;t<=5;t++)e.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return e}function ge(e,t){t=Math.max(t,ve(e)),He[e].distance=t}function ve(e){if(He[e])return He[e].distance}function me(){var e={};return e[r]=be(r),e[i]=be(i),e[o]=be(o),e[a]=be(a),e}function be(e){return{direction:e,distance:0}}function we(){return Ze-We}function ye(e,t){var n=Math.abs(e.x-t.x),r=Math.abs(e.y-t.y);return Math.round(Math.sqrt(n*n+r*r))}function Te(e,t){return(t/e*1).toFixed(2)}function Ee(){return Ve<1?u:l}function Oe(e,t){return Math.round(Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)))}function Ae(e,t){var n=e.x-t.x,r=t.y-e.y,i=Math.atan2(r,n),o=Math.round(180*i/Math.PI);return o<0&&(o=360-Math.abs(o)),o}function xe(e,t){var n=Ae(e,t);return n<=45&&n>=0?r:n<=360&&n>=315?r:n>=135&&n<=225?i:n>45&&n<135?a:o}function Le(){return(new Date).getTime()}function ke(t){t=e(t);var n=t.offset();return{left:n.left,right:n.left+t.outerWidth(),top:n.top,bottom:n.top+t.outerHeight()}}function Se(e,t){return e.x>t.left&&e.x<t.right&&e.y>t.top&&e.y<t.bottom}var Ce=A||L||!n.fallbackToMouseEvents,Me=Ce?L?x?"MSPointerDown":"pointerdown":"touchstart":"mousedown",Ne=Ce?L?x?"MSPointerMove":"pointermove":"touchmove":"mousemove",Ie=Ce?L?x?"MSPointerUp":"pointerup":"touchend":"mouseup",Pe=Ce?null:"mouseleave",De=L?x?"MSPointerCancel":"pointercancel":"touchcancel",Fe=0,ze=null,Re=0,_e=0,je=0,Ve=1,qe=0,Ue=0,He=null,Xe=e(t),Qe="start",Ye=0,Be=null,We=0,Ze=0,Ge=0,Ke=0,$e=0,Je=null,et=null;try{Xe.bind(Me,S),Xe.bind(De,N)}catch(t){e.error("events not supported "+Me+","+De+" on jQuery.swipe")}this.enable=function(){return Xe.bind(Me,S),Xe.bind(De,N),Xe},this.disable=function(){return P(),Xe},this.destroy=function(){return P(),Xe.data(k,null),Xe},this.option=function(t,r){if(void 0!==n[t]){if(void 0===r)return n[t];n[t]=r}else e.error("Option "+t+" does not exist on jQuery.swipe.options");return null}}var r="left",i="right",o="up",a="down",l="in",u="out",c="none",s="auto",p="swipe",d="pinch",f="tap",h="doubletap",g="longtap",v="horizontal",m="vertical",b="all",w=10,y="start",T="move",E="end",O="cancel",A="ontouchstart"in window,x=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,L=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,k="TouchSwipe",S={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"};e.fn.swipe=function(n){var r=e(this),i=r.data(k);if(i&&"string"==typeof n){if(i[n])return i[n].apply(this,Array.prototype.slice.call(arguments,1));e.error("Method "+n+" does not exist on jQuery.swipe")}else if(!(i||"object"!=typeof n&&n))return t.apply(this,arguments);return r},e.fn.swipe.defaults=S,e.fn.swipe.phases={PHASE_START:y,PHASE_MOVE:T,PHASE_END:E,PHASE_CANCEL:O},e.fn.swipe.directions={LEFT:r,RIGHT:i,UP:o,DOWN:a,IN:l,OUT:u},e.fn.swipe.pageScroll={NONE:c,HORIZONTAL:v,VERTICAL:m,AUTO:s},e.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:b}}),function(e){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(e)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(e.substr(0,4))}(navigator.userAgent||navigator.vendor||window.opera),function(e){var t={init:function(){var t=["paddingTop","paddingRight","paddingBottom","paddingLeft","fontSize","lineHeight","fontFamily","width","fontWeight","border-top-width","border-right-width","border-bottom-width","border-left-width","-moz-box-sizing","-webkit-box-sizing","box-sizing"];return this.each(function(){function n(){for(var e=0;e<t.length;e++)a.css(t[e],o.css(t[e]))}function r(){var e=o.val().replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&/g,"&amp;").replace(/\n/g,"<br/>");a.html(e+"&nbsp;").css({width:parseInt(o.width(),10)+"px"}),i()}function i(){var e=a.height(),t="hidden",n=l?e+s+u:e+s;n>d?(n=d,t="auto"):p>n&&(n=p),o.height()!==n&&o.css({overflow:t,height:n+"px"})}if("textarea"!==this.type)return!1;var o=e(this).css({resize:"none",overflow:"hidden"}),a=e("<div></div>").css({position:"absolute",display:"none","word-wrap":"break-word","white-space":"pre-wrap","border-style":"solid"}).appendTo(document.body);n();var l="border-box"==o.css("box-sizing")||"border-box"==o.css("-moz-box-sizing")||"border-box"==o.css("-webkit-box-sizing"),u=parseInt(o.css("border-top-width"))+parseInt(o.css("padding-top"))+parseInt(o.css("padding-bottom"))+parseInt(o.css("border-bottom-width")),c=parseInt(o.css("height"),10),s=parseInt(o.css("line-height"),10)||parseInt(o.css("font-size"),10),p=2*s>c?2*s:c,d=parseInt(o.css("max-height"),10)>-1?parseInt(o.css("max-height"),10):Number.MAX_VALUE;o.bind("keyup change cut paste",function(){r()}),e(window).bind("resize",function(){a.width()!==parseInt(o.width(),10)&&r()}),o.bind("blur",function(){i()}),o.bind("updateHeight",function(){n(),r()}),e(function(){r()})})}};e.fn.flexible=function(n){return t[n]?t[n].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof n&&n?void e.error("Method "+n+" does not exist on jQuery.flexible"):t.init.apply(this,arguments)}}(jQuery),function(e,t,n,r){"use strict";function i(e,t){for(var n=0,r=e.length;n<r;n++)g(e[n],t)}function o(e){for(var t,n=0,r=e.length;n<r;n++)t=e[n],E(t,_[l(t)])}function a(e){return function(t){ne(t)&&(g(t,e),i(t.querySelectorAll(j),e))}}function l(e){var t=e.getAttribute("is"),n=e.nodeName.toUpperCase(),r=q.call(R,t?D+t.toUpperCase():P+n);return t&&-1<r&&!u(n,t)?-1:r}function u(e,t){return-1<j.indexOf(e+'[is="'+t+'"]')}function c(e){var t=e.currentTarget,n=e.attrChange,r=e.attrName,i=e.target;he&&(!i||i===t)&&t.attributeChangedCallback&&"style"!==r&&t.attributeChangedCallback(r,n===e[k]?null:e.prevValue,n===e[C]?null:e.newValue)}function s(e){var t=a(e);return function(e){v.push(t,e.target)}}function p(e){fe&&(fe=!1,e.currentTarget.removeEventListener(N,p)),i((e.target||t).querySelectorAll(j),e.detail===x?x:A),te&&h()}function d(e,t){var n=this;oe.call(n,e,t),m.call(n,{target:n})}function f(e,t){$(e,t),y?y.observe(e,ue):(de&&(e.setAttribute=d,e[O]=w(e),e.addEventListener(I,m)),e.addEventListener(M,c)),e.createdCallback&&he&&(e.created=!0,e.createdCallback(),e.created=!1)}function h(){for(var e,t=0,n=re.length;t<n;t++)e=re[t],V.contains(e)||(re.splice(t,1),g(e,x))}function g(e,t){var n,r=l(e);-1<r&&(T(e,_[r]),r=0,t!==A||e[A]?t===x&&!e[x]&&(e[A]=!1,e[x]=!0,r=1):(e[x]=!1,e[A]=!0,r=1,te&&q.call(re,e)<0&&re.push(e)),r&&(n=e[t+"Callback"])&&n.call(e))}if(!(r in t)){var v,m,b,w,y,T,E,O="__"+r+(1e5*Math.random()>>0),A="attached",x="detached",L="extends",k="ADDITION",S="MODIFICATION",C="REMOVAL",M="DOMAttrModified",N="DOMContentLoaded",I="DOMSubtreeModified",P="<",D="=",F=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,z=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],R=[],_=[],j="",V=t.documentElement,q=R.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},U=n.prototype,H=U.hasOwnProperty,X=U.isPrototypeOf,Q=n.defineProperty,Y=n.getOwnPropertyDescriptor,B=n.getOwnPropertyNames,W=n.getPrototypeOf,Z=n.setPrototypeOf,G=!!n.__proto__,K=n.create||function e(t){return t?(e.prototype=t,new e):this},$=Z||(G?function(e,t){return e.__proto__=t,e}:B&&Y?function(){function e(e,t){for(var n,r=B(t),i=0,o=r.length;i<o;i++)n=r[i],H.call(e,n)||Q(e,n,Y(t,n))}return function(t,n){do{e(t,n)}while((n=W(n))&&!X.call(n,t));return t}}():function(e,t){for(var n in t)e[n]=t[n];return e}),J=e.MutationObserver||e.WebKitMutationObserver,ee=(e.HTMLElement||e.Element||e.Node).prototype,te=!X.call(ee,V),ne=te?function(e){return 1===e.nodeType}:function(e){return X.call(ee,e)},re=te&&[],ie=ee.cloneNode,oe=ee.setAttribute,ae=ee.removeAttribute,le=t.createElement,ue=J&&{attributes:!0,characterData:!0,attributeOldValue:!0},ce=J||function(e){de=!1,V.removeEventListener(M,ce)},se=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,10)},pe=!1,de=!0,fe=!0,he=!0;Z||G?(T=function(e,t){X.call(t,e)||f(e,t)},E=f):(T=function(e,t){e[O]||(e[O]=n(!0),f(e,t))},E=T),te?(de=!1,function(){var e=Y(ee,"addEventListener"),t=e.value,n=function(e){var t=new CustomEvent(M,{bubbles:!0});t.attrName=e,t.prevValue=this.getAttribute(e),t.newValue=null,t[C]=t.attrChange=2,ae.call(this,e),this.dispatchEvent(t)},r=function(e,t){var n=this.hasAttribute(e),r=n&&this.getAttribute(e),i=new CustomEvent(M,{bubbles:!0});oe.call(this,e,t),i.attrName=e,i.prevValue=n?r:null,i.newValue=t,n?i[S]=i.attrChange=1:i[k]=i.attrChange=0,this.dispatchEvent(i)},i=function(e){var t,n=e.currentTarget,r=n[O],i=e.propertyName;r.hasOwnProperty(i)&&(r=r[i],t=new CustomEvent(M,{bubbles:!0}),t.attrName=r.name,t.prevValue=r.value||null,t.newValue=r.value=n[i]||null,null==t.prevValue?t[k]=t.attrChange=0:t[S]=t.attrChange=1,n.dispatchEvent(t))};e.value=function(e,o,a){e===M&&this.attributeChangedCallback&&this.setAttribute!==r&&(this[O]={className:{name:"class",value:this.className}},this.setAttribute=r,this.removeAttribute=n,t.call(this,"propertychange",i)),t.call(this,e,o,a)},Q(ee,"addEventListener",e)}()):J||(V.addEventListener(M,ce),V.setAttribute(O,1),V.removeAttribute(O),de&&(m=function(e){var t,n,r,i=this;if(i===e.target){t=i[O],i[O]=n=w(i);for(r in n){if(!(r in t))return b(0,i,r,t[r],n[r],k);if(n[r]!==t[r])return b(1,i,r,t[r],n[r],S)}for(r in t)if(!(r in n))return b(2,i,r,t[r],n[r],C)}},b=function(e,t,n,r,i,o){var a={attrChange:e,currentTarget:t,attrName:n,prevValue:r,newValue:i};a[o]=e,c(a)},w=function(e){for(var t,n,r={},i=e.attributes,o=0,a=i.length;o<a;o++)t=i[o],"setAttribute"!==(n=t.name)&&(r[n]=t.value);return r})),t[r]=function(e,n){if(r=e.toUpperCase(),pe||(pe=!0,J?(y=function(e,t){function n(e,t){for(var n=0,r=e.length;n<r;t(e[n++]));}return new J(function(r){for(var i,o,a=0,l=r.length;a<l;a++)i=r[a],"childList"===i.type?(n(i.addedNodes,e),n(i.removedNodes,t)):(o=i.target,he&&o.attributeChangedCallback&&"style"!==i.attributeName&&o.attributeChangedCallback(i.attributeName,i.oldValue,o.getAttribute(i.attributeName)))})}(a(A),a(x)),y.observe(t,{childList:!0,subtree:!0})):(v=[],se(function e(){for(;v.length;)v.shift().call(null,v.shift());se(e)}),t.addEventListener("DOMNodeInserted",s(A)),t.addEventListener("DOMNodeRemoved",s(x))),t.addEventListener(N,p),t.addEventListener("readystatechange",p),t.createElement=function(e,n){var r=le.apply(t,arguments),i=""+e,o=q.call(R,(n?D:P)+(n||i).toUpperCase()),a=-1<o;return n&&(r.setAttribute("is",n=n.toLowerCase()),a&&(a=u(i.toUpperCase(),n))),he=!t.createElement.innerHTMLHelper,a&&E(r,_[o]),r},ee.cloneNode=function(e){var t=ie.call(this,!!e),n=l(t);return-1<n&&E(t,_[n]),e&&o(t.querySelectorAll(j)),t}),-2<q.call(R,D+r)+q.call(R,P+r))throw new Error("A "+e+" type is already registered");if(!F.test(r)||-1<q.call(z,r))throw new Error("The type "+e+" is invalid");var r,c=function(){return f?t.createElement(h,r):t.createElement(h)},d=n||U,f=H.call(d,L),h=f?n[L].toUpperCase():r,g=R.push((f?D:P)+r)-1;return j=j.concat(j.length?",":"",f?h+'[is="'+e.toLowerCase()+'"]':h),c.prototype=_[g]=H.call(d,"prototype")?d.prototype:K(ee),i(t.querySelectorAll(j),A),c}}}(window,document,Object,"registerElement"),function(e,t,n){"use strict";function r(){return e.performance!==n&&e.performance.now!==n?e.performance.now():Date.now()}function i(e){return.5*(1-Math.cos(Math.PI*e))}function o(e){if("object"!=typeof e||e.behavior===n||"auto"===e.behavior||"instant"===e.behavior)return!0;if("smooth"===e.behavior)return!1;throw new TypeError(e.behavior+" is not a valid value for enumeration ScrollBehavior")}function a(e,t,n){e.scrollTop=n,e.scrollLeft=t}function l(t,o){function a(){var f,h,g,v=r(),m=(v-d)/s;return m=m>1?1:m,f=i(m),h=l+(t-l)*f,g=u+(o-u)*f,p(h,g),h===t&&g===o?(l=u=d=null,e.cancelAnimationFrame(c),n):(c=e.requestAnimationFrame(a),n)}var l=e.scrollX||e.pageXOffset,u=e.scrollY||e.pageYOffset,d=r();c&&e.cancelAnimationFrame(c),c=e.requestAnimationFrame(a)}function u(o,u){function p(){var t,l,u,m=r(),b=(m-v)/s;return b=b>1?1:b,t=i(b),l=d+(h-d)*t,u=f+(g-f)*t,a(o,l,u),l===h&&u===g?(d=f=v=null,e.cancelAnimationFrame(c),n):(c=e.requestAnimationFrame(p),n)}if(o===t.documentElement||o===t.body)return l(u.left,u.top),n;var d=o.scrollLeft,f=o.scrollTop,h=u.left,g=u.top,v=r();c&&e.cancelAnimationFrame(c),c=e.requestAnimationFrame(p)}if(!("scrollBehavior"in t.documentElement.style)){var c,s=768,p=e.scrollTo,d=e.scrollBy,f=e.Element.prototype.scrollIntoView;e.scroll=e.scrollTo=function(){return o(arguments[0])?p.call(e,arguments[0].left||arguments[0],arguments[0].top||arguments[1]):l.call(e,~~arguments[0].left,~~arguments[0].top)},e.scrollBy=function(){if(o(arguments[0]))return d.call(e,arguments[0].left||arguments[0],arguments[0].top||arguments[1]);var t=e.scrollX||e.pageXOffset,n=e.scrollY||e.pageYOffset;return l(~~arguments[0].left+t,~~arguments[0].top+n)},Element.prototype.scrollIntoView=function(){var n,r,i,a;return o(arguments[0])?f.call(this,arguments[0]||!0):(a=e.getComputedStyle(t.body,null),r=parseInt(a.getPropertyValue("padding-left"),10),i=parseInt(a.getPropertyValue("padding-top"),10),n={top:this.offsetTop-2*i,left:this.offsetLeft-2*r},u(t.body,n))}}}(window,document); })(this);
+(function (window, undefined) { !function(){var o=!1,a=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){},Class.extend=function(e){function t(){!o&&this.init&&this.init.apply(this,arguments)}var i=this.prototype;o=!0;var n=new this;for(var r in o=!1,e)n[r]="function"==typeof e[r]&&"function"==typeof i[r]&&a.test(e[r])?function(n,r){return function(){var e=this._super;this._super=i[n];var t=r.apply(this,arguments);return this._super=e,t}}(r,e[r]):e[r];return((t.prototype=n).constructor=t).extend=arguments.callee,t}}(),function(u,r){"use strict";function s(){}function o(e,t){if(e){"object"==typeof e&&(e=[].slice.call(e));for(var n=0,r=e.length;n<r;n++)t.call(e,e[n],n)}}function t(e,t){var n=Object.prototype.toString.call(t).slice(8,-1);return t!==r&&null!==t&&n===e}function a(e){return t("Function",e)}function l(e){return t("Array",e)}function c(e){(e=e||s)._done||(e(),e._done=1)}function i(e){var t,n,r,i,o,a={};if("object"==typeof e)for(t in e)e[t]&&(a={name:t,url:e[t]});else a={name:(r=e.split("/"),i=r[r.length-1],-1!==(o=i.indexOf("?"))?i.substring(0,o):i),url:e};return(n=y[a.name])&&n.url===a.url?n:y[a.name]=a}function p(e){for(var t in e=e||y)if(e.hasOwnProperty(t)&&e[t].state!==k)return;return 1}function d(t){t.state===r&&(t.state=A,t.onpreload=[],n({url:t.url,type:"cache"},function(){var e;(e=t).state=x,o(e.onpreload,function(e){e.call()})}))}function f(e,t){t=t||s,e.state!==k?e.state!==L?e.state!==A?(e.state=L,n(e,function(){e.state=k,t(),o(w[e.name],function(e){c(e)}),g&&p()&&o(w.ALL,function(e){c(e)})})):e.onpreload.push(function(){f(e,t)}):O.ready(e.name,t):t()}function n(r,t){function e(e){e=e||u.event,o.onload=o.onreadystatechange=o.onerror=null,t()}function i(e){("load"===(e=e||u.event).type||/loaded|complete/.test(o.readyState)&&(!v.documentMode||v.documentMode<9))&&(u.clearTimeout(r.errorTimeout),u.clearTimeout(r.cssTimeout),o.onload=o.onreadystatechange=o.onerror=null,t())}var o,n,a,l;t=t||s,a=r.url,"css"===(l=(a=a||"").split("?")[0].split("."))[l.length-1].toLowerCase()?((o=v.createElement("link")).type="text/"+(r.type||"css"),o.rel="stylesheet",o.href=r.url,r.cssRetries=0,r.cssTimeout=u.setTimeout(function e(){if(r.state!==k&&r.cssRetries<=20){for(var t=0,n=v.styleSheets.length;t<n;t++)if(v.styleSheets[t].href===o.href)return void i({type:"load"});r.cssRetries++,r.cssTimeout=u.setTimeout(e,250)}},500)):((o=v.createElement("script")).type="text/"+(r.type||"javascript"),o.src=r.url),o.onload=o.onreadystatechange=i,o.onerror=e,o.async=!1,o.defer=!1,r.errorTimeout=u.setTimeout(function(){e({type:"timeout"})},6e4),(n=v.head||v.getElementsByTagName("head")[0]).insertBefore(o,n.lastChild)}function e(){if(!v.body)return u.clearTimeout(O.readyTimeout),void(O.readyTimeout=u.setTimeout(e,50));g||(g=!0,function(){for(var e,t=v.getElementsByTagName("script"),n=0,r=t.length;n<r;n++)if(e=t[n].getAttribute("data-headjs-load"))return O.load(e)}(),o(b,function(e){c(e)}))}function h(){v.addEventListener?(v.removeEventListener("DOMContentLoaded",h,!1),e()):"complete"===v.readyState&&(v.detachEvent("onreadystatechange",h),e())}var g,m,v=u.document,b=[],w={},y={},T="async"in v.createElement("script")||"MozAppearance"in v.documentElement.style||u.opera,E=u.head_conf&&u.head_conf.head||"head",O=u[E]=u[E]||function(){O.ready.apply(null,arguments)},A=1,x=2,L=3,k=4;if("complete"===v.readyState)e();else if(v.addEventListener)v.addEventListener("DOMContentLoaded",h,!1),u.addEventListener("load",e,!1);else{v.attachEvent("onreadystatechange",h),u.attachEvent("onload",e),m=!1;try{m=!u.frameElement&&v.documentElement}catch(e){}m&&m.doScroll&&function t(){if(!g){try{m.doScroll("left")}catch(e){return u.clearTimeout(O.readyTimeout),void(O.readyTimeout=u.setTimeout(t,50))}e()}}()}O.load=O.js=T?function(){var e=arguments,t=e[e.length-1],n={};return a(t)||(t=null),l(e[0])?(e[0].push(t),O.load.apply(null,e[0])):(o(e,function(e){e!==t&&(e=i(e),n[e.name]=e)}),o(e,function(e){e!==t&&f(e=i(e),function(){p(n)&&c(t)})})),O}:function(){var e=arguments,t=e[e.length-1],n=[].slice.call(e,1),r=n[0];return a(t)||(t=null),l(e[0])?(e[0].push(t),O.load.apply(null,e[0])):r?(o(n,function(e){a(e)||!e||d(i(e))}),f(i(e[0]),a(r)?r:function(){O.load.apply(null,n)})):f(i(e[0])),O},O.test=function(e,t,n,r){var i="object"==typeof e?e:{test:e,success:!!t&&(l(t)?t:[t]),failure:!!n&&(l(n)?n:[n]),callback:r||s},o=!!i.test;return o&&i.success?(i.success.push(i.callback),O.load.apply(null,i.success)):o||!i.failure?r():(i.failure.push(i.callback),O.load.apply(null,i.failure)),O},O.ready=function(e,t){var n,r,i;return e===v?(g?c(t):b.push(t),O):(a(e)&&(t=e,e="ALL"),l(e)?(n={},o(e,function(e){n[e]=y[e],O.ready(e,function(){p(n)&&c(t)})}),O):"string"==typeof e&&a(t)?((r=y[e])&&r.state===k||"ALL"===e&&p()&&g?c(t):(i=w[e])?i.push(t):i=w[e]=[t],O):O)},O.ready(v,function(){p()&&o(w.ALL,function(e){c(e)}),O.feature&&O.feature("domloaded",!0)})}(window),function(e){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],e):e(jQuery)}(function(oe){var ae="left",le="right",ue="up",se="down",ce="in",pe="out",de="none",fe="auto",he="swipe",ge="pinch",me="tap",ve="doubletap",be="longtap",we="horizontal",ye="vertical",Te="all",Ee=10,Oe="start",Ae="move",xe="end",Le="cancel",ke="ontouchstart"in window,Se=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,Ce=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,Me="TouchSwipe";function r(e,v){var t=ke||Ce||!v.fallbackToMouseEvents,n=t?Ce?Se?"MSPointerDown":"pointerdown":"touchstart":"mousedown",r=t?Ce?Se?"MSPointerMove":"pointermove":"touchmove":"mousemove",i=t?Ce?Se?"MSPointerUp":"pointerup":"touchend":"mouseup",o=t?null:"mouseleave",a=Ce?Se?"MSPointerCancel":"pointercancel":"touchcancel",b=0,w=null,y=0,T=0,E=0,O=1,A=0,x=0,L=null,l=oe(e),k="start",S=0,C=null,u=0,M=0,s=0,c=0,p=0,d=null,N=null;try{l.bind(n,f),l.bind(a,m)}catch(e){oe.error("events not supported "+n+","+a+" on jQuery.swipe")}function f(e){if(!0!==l.data(Me+"_intouch")&&!(0<oe(e.target).closest(v.excludedElements,l).length)){var t,n,r=e.originalEvent?e.originalEvent:e,i=ke?r.touches[0]:r;return(k=Oe,ke?S=r.touches.length:e.preventDefault(),x=w=null,O=1,A=E=T=y=b=0,C=function(){for(var e=[],t=0;t<=5;t++)e.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return e}(),(n={})[ae]=te(ae),n[le]=te(le),n[ue]=te(ue),n[se]=te(se),L=n,Z(),!ke||S===v.fingers||v.fingers===Te||q()?($(0,i),u=ie(),2==S&&($(1,r.touches[1]),T=E=re(C[0].start,C[1].start)),(v.swipeStatus||v.pinchStatus)&&(t=F(r,k))):t=!1,!1===t)?(F(r,k=Le),t):(v.hold&&(N=setTimeout(oe.proxy(function(){l.trigger("hold",[r.target]),v.hold&&(t=v.hold.call(l,r,r.target))},this),v.longTapThreshold)),K(!0),null)}}function h(e){var t,n,r,i,o,a,l,u,s,c,p,d,f,h,g,m=e.originalEvent?e.originalEvent:e;k===xe||k===Le||G()||(n=J(ke?m.touches[0]:m),M=ie(),ke&&(S=m.touches.length),v.hold&&clearTimeout(N),k=Ae,2==S&&(0==T?($(1,m.touches[1]),T=E=re(C[0].start,C[1].start)):(J(m.touches[1]),E=re(C[0].end,C[1].end),C[0].end,C[1].end,x=O<1?pe:ce),O=(E/T*1).toFixed(2),A=Math.abs(T-E)),S===v.fingers||v.fingers===Te||!ke||q()?(f=n.start,h=n.end,g=function(e,t){var n=e.x-t.x,r=t.y-e.y,i=Math.atan2(r,n),o=Math.round(180*i/Math.PI);o<0&&(o=360-Math.abs(o));return o}(f,h),function(e,t){if(v.allowPageScroll===de||q())e.preventDefault();else{var n=v.allowPageScroll===fe;switch(t){case ae:(v.swipeLeft&&n||!n&&v.allowPageScroll!=we)&&e.preventDefault();break;case le:(v.swipeRight&&n||!n&&v.allowPageScroll!=we)&&e.preventDefault();break;case ue:(v.swipeUp&&n||!n&&v.allowPageScroll!=ye)&&e.preventDefault();break;case se:(v.swipeDown&&n||!n&&v.allowPageScroll!=ye)&&e.preventDefault()}}}(e,w=g<=45&&0<=g||g<=360&&315<=g?ae:135<=g&&g<=225?le:45<g&&g<135?se:ue),p=n.start,d=n.end,b=Math.round(Math.sqrt(Math.pow(d.x-p.x,2)+Math.pow(d.y-p.y,2))),y=ne(),s=w,c=b,c=Math.max(c,ee(s)),L[s].distance=c,(v.swipeStatus||v.pinchStatus)&&(t=F(m,k)),v.triggerOnTouchEnd&&!v.triggerOnTouchLeave||(r=!0,v.triggerOnTouchLeave&&(i={left:(u=(l=oe(l=this)).offset()).left,right:u.left+l.outerWidth(),top:u.top,bottom:u.top+l.outerHeight()},o=n.end,a=i,r=o.x>a.left&&o.x<a.right&&o.y>a.top&&o.y<a.bottom),!v.triggerOnTouchEnd&&r?k=D(Ae):v.triggerOnTouchLeave&&!r&&(k=D(xe)),k!=Le&&k!=xe||F(m,k))):F(m,k=Le),!1===t&&F(m,k=Le))}function g(e){var t=e.originalEvent;return ke&&0<t.touches.length?(s=ie(),c=event.touches.length+1,!0):(G()&&(S=c),M=ie(),y=ne(),_()||!R()?F(t,k=Le):v.triggerOnTouchEnd||0==v.triggerOnTouchEnd&&k===Ae?(e.preventDefault(),F(t,k=xe)):!v.triggerOnTouchEnd&&Y()?z(t,k=xe,me):k===Ae&&F(t,k=Le),K(!1),null)}function m(){E=T=u=M=S=0,Z(),K(!(O=1))}function I(e){var t=e.originalEvent;v.triggerOnTouchLeave&&F(t,k=D(xe))}function P(){l.unbind(n,f),l.unbind(a,m),l.unbind(r,h),l.unbind(i,g),o&&l.unbind(o,I),K(!1)}function D(e){var t=e,n=j(),r=R(),i=_();return!n||i?t=Le:!r||e!=Ae||v.triggerOnTouchEnd&&!v.triggerOnTouchLeave?!r&&e==xe&&v.triggerOnTouchLeave&&(t=Le):t=xe,t}function F(e,t){var n=void 0;return U()&&H()||H()?n=z(e,t,he):(V()&&q()||q())&&!1!==n&&(n=z(e,t,ge)),W()&&B()&&!1!==n?n=z(e,t,ve):y>v.longTapThreshold&&b<Ee&&v.longTap&&!1!==n?n=z(e,t,be):1!==S&&ke||!(isNaN(b)||b<v.threshold)||!Y()||!1===n||(n=z(e,t,me)),t===Le&&m(),t!==xe||ke&&0!=e.touches.length||m(),n}function z(e,t,n){var r=void 0;if(n==he){if(l.trigger("swipeStatus",[t,w||null,b||0,y||0,S,C]),v.swipeStatus&&!1===(r=v.swipeStatus.call(l,e,t,w||null,b||0,y||0,S,C)))return!1;if(t==xe&&U()){if(l.trigger("swipe",[w,b,y,S,C]),v.swipe&&!1===(r=v.swipe.call(l,e,w,b,y,S,C)))return!1;switch(w){case ae:l.trigger("swipeLeft",[w,b,y,S,C]),v.swipeLeft&&(r=v.swipeLeft.call(l,e,w,b,y,S,C));break;case le:l.trigger("swipeRight",[w,b,y,S,C]),v.swipeRight&&(r=v.swipeRight.call(l,e,w,b,y,S,C));break;case ue:l.trigger("swipeUp",[w,b,y,S,C]),v.swipeUp&&(r=v.swipeUp.call(l,e,w,b,y,S,C));break;case se:l.trigger("swipeDown",[w,b,y,S,C]),v.swipeDown&&(r=v.swipeDown.call(l,e,w,b,y,S,C))}}}if(n==ge){if(l.trigger("pinchStatus",[t,x||null,A||0,y||0,S,O,C]),v.pinchStatus&&!1===(r=v.pinchStatus.call(l,e,t,x||null,A||0,y||0,S,O,C)))return!1;if(t==xe&&V())switch(x){case ce:l.trigger("pinchIn",[x||null,A||0,y||0,S,O,C]),v.pinchIn&&(r=v.pinchIn.call(l,e,x||null,A||0,y||0,S,O,C));break;case pe:l.trigger("pinchOut",[x||null,A||0,y||0,S,O,C]),v.pinchOut&&(r=v.pinchOut.call(l,e,x||null,A||0,y||0,S,O,C))}}return n==me?t!==Le&&t!==xe||(clearTimeout(d),clearTimeout(N),B()&&!W()?(p=ie(),d=setTimeout(oe.proxy(function(){p=null,l.trigger("tap",[e.target]),v.tap&&(r=v.tap.call(l,e,e.target))},this),v.doubleTapThreshold)):(p=null,l.trigger("tap",[e.target]),v.tap&&(r=v.tap.call(l,e,e.target)))):n==ve?t!==Le&&t!==xe||(clearTimeout(d),p=null,l.trigger("doubletap",[e.target]),v.doubleTap&&(r=v.doubleTap.call(l,e,e.target))):n==be&&(t!==Le&&t!==xe||(clearTimeout(d),p=null,l.trigger("longtap",[e.target]),v.longTap&&(r=v.longTap.call(l,e,e.target)))),r}function R(){var e=!0;return null!==v.threshold&&(e=b>=v.threshold),e}function _(){var e=!1;return null!==v.cancelThreshold&&null!==w&&(e=ee(w)-b>=v.cancelThreshold),e}function j(){var e=!v.maxTimeThreshold||!(y>=v.maxTimeThreshold);return e}function V(){var e=X(),t=Q(),n=null===v.pinchThreshold||A>=v.pinchThreshold;return e&&t&&n}function q(){return v.pinchStatus||v.pinchIn||v.pinchOut}function U(){var e=j(),t=R(),n=X(),r=Q();return!_()&&r&&n&&t&&e}function H(){return v.swipe||v.swipeStatus||v.swipeLeft||v.swipeRight||v.swipeUp||v.swipeDown}function X(){return S===v.fingers||v.fingers===Te||!ke}function Q(){return 0!==C[0].end.x}function Y(){return v.tap}function B(){return!!v.doubleTap}function W(){if(null==p)return!1;var e=ie();return B()&&e-p<=v.doubleTapThreshold}function Z(){c=s=0}function G(){var e=!1;return s&&ie()-s<=v.fingerReleaseThreshold&&(e=!0),e}function K(e){!0===e?(l.bind(r,h),l.bind(i,g),o&&l.bind(o,I)):(l.unbind(r,h,!1),l.unbind(i,g,!1),o&&l.unbind(o,I,!1)),l.data(Me+"_intouch",!0===e)}function $(e,t){var n=void 0!==t.identifier?t.identifier:0;return C[e].identifier=n,C[e].start.x=C[e].end.x=t.pageX||t.clientX,C[e].start.y=C[e].end.y=t.pageY||t.clientY,C[e]}function J(e){var t=function(e){for(var t=0;t<C.length;t++)if(C[t].identifier==e)return C[t]}(void 0!==e.identifier?e.identifier:0);return t.end.x=e.pageX||e.clientX,t.end.y=e.pageY||e.clientY,t}function ee(e){if(L[e])return L[e].distance}function te(e){return{direction:e,distance:0}}function ne(){return M-u}function re(e,t){var n=Math.abs(e.x-t.x),r=Math.abs(e.y-t.y);return Math.round(Math.sqrt(n*n+r*r))}function ie(){return(new Date).getTime()}this.enable=function(){return l.bind(n,f),l.bind(a,m),l},this.disable=function(){return P(),l},this.destroy=function(){return P(),l.data(Me,null),l},this.option=function(e,t){if(void 0!==v[e]){if(void 0===t)return v[e];v[e]=t}else oe.error("Option "+e+" does not exist on jQuery.swipe.options");return null}}oe.fn.swipe=function(e){var t=oe(this),n=t.data(Me);if(n&&"string"==typeof e){if(n[e])return n[e].apply(this,Array.prototype.slice.call(arguments,1));oe.error("Method "+e+" does not exist on jQuery.swipe")}else if(!(n||"object"!=typeof e&&e))return function(n){!n||void 0!==n.allowPageScroll||void 0===n.swipe&&void 0===n.swipeStatus||(n.allowPageScroll=de);void 0!==n.click&&void 0===n.tap&&(n.tap=n.click);n=n||{};return n=oe.extend({},oe.fn.swipe.defaults,n),this.each(function(){var e=oe(this),t=e.data(Me);t||(t=new r(this,n),e.data(Me,t))})}.apply(this,arguments);return t},oe.fn.swipe.defaults={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"},oe.fn.swipe.phases={PHASE_START:Oe,PHASE_MOVE:Ae,PHASE_END:xe,PHASE_CANCEL:Le},oe.fn.swipe.directions={LEFT:ae,RIGHT:le,UP:ue,DOWN:se,IN:ce,OUT:pe},oe.fn.swipe.pageScroll={NONE:de,HORIZONTAL:we,VERTICAL:ye,AUTO:fe},oe.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:Te}}),function(e){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(e)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(e.substr(0,4))}(navigator.userAgent||navigator.vendor||window.opera),function(d){var t={init:function(){var p=["paddingTop","paddingRight","paddingBottom","paddingLeft","fontSize","lineHeight","fontFamily","width","fontWeight","border-top-width","border-right-width","border-bottom-width","border-left-width","-moz-box-sizing","-webkit-box-sizing","box-sizing"];return this.each(function(){function e(){for(var e=0;e<p.length;e++)i.css(p[e],r.css(p[e]))}function t(){var e=r.val().replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&/g,"&amp;").replace(/\n/g,"<br/>");i.html(e+"&nbsp;").css({width:parseInt(r.width(),10)+"px"}),n()}function n(){var e=i.height(),t="hidden",n=o?e+u+a:e+u;c<n?(n=c,t="auto"):n<s&&(n=s),r.height()!==n&&r.css({overflow:t,height:n+"px"})}if("textarea"!==this.type)return!1;var r=d(this).css({resize:"none",overflow:"hidden"}),i=d("<div></div>").css({position:"absolute",display:"none","word-wrap":"break-word","white-space":"pre-wrap","border-style":"solid"}).appendTo(document.body);e();var o="border-box"==r.css("box-sizing")||"border-box"==r.css("-moz-box-sizing")||"border-box"==r.css("-webkit-box-sizing"),a=parseInt(r.css("border-top-width"))+parseInt(r.css("padding-top"))+parseInt(r.css("padding-bottom"))+parseInt(r.css("border-bottom-width")),l=parseInt(r.css("height"),10),u=parseInt(r.css("line-height"),10)||parseInt(r.css("font-size"),10),s=l<2*u?2*u:l,c=-1<parseInt(r.css("max-height"),10)?parseInt(r.css("max-height"),10):Number.MAX_VALUE;r.bind("keyup change cut paste",function(){t()}),d(window).bind("resize",function(){i.width()!==parseInt(r.width(),10)&&t()}),r.bind("blur",function(){n()}),r.bind("updateHeight",function(){e(),t()}),d(function(){t()})})}};d.fn.flexible=function(e){return t[e]?t[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?void d.error("Method "+e+" does not exist on jQuery.flexible"):t.init.apply(this,arguments)}}(jQuery),function(e,p,n,t){"use strict";function d(e,t){for(var n=0,r=e.length;n<r;n++)o(e[n],t)}function f(t){return function(e){Y(e)&&(o(e,t),d(e.querySelectorAll(C),t))}}function h(e){var t=e.getAttribute("is"),n=e.nodeName.toUpperCase(),r=N.call(k,t?A+t.toUpperCase():O+n);return t&&-1<r&&!g(n,t)?-1:r}function g(e,t){return-1<C.indexOf(e+'[is="'+t+'"]')}function l(e){var t=e.currentTarget,n=e.attrChange,r=e.attrName,i=e.target;!oe||i&&i!==t||!t.attributeChangedCallback||"style"===r||t.attributeChangedCallback(r,n===e[u]?null:e.prevValue,n===e[c]?null:e.newValue)}function m(e){var t=f(e);return function(e){ee.push(t,e.target)}}function v(e){ie&&(ie=!1,e.currentTarget.removeEventListener(E,v)),d((e.target||p).querySelectorAll(C),e.detail===w?w:b),Q&&function(){for(var e,t=0,n=B.length;t<n;t++)e=B[t],M.contains(e)||(B.splice(t,1),o(e,w))}()}function r(e,t){Z.call(this,e,t),ae.call(this,{target:this})}function i(e,t){U(e,t),se?se.observe(e,$):(re&&(e.setAttribute=r,e[a]=ue(e),e.addEventListener("DOMSubtreeModified",ae)),e.addEventListener(T,l)),e.createdCallback&&oe&&(e.created=!0,e.createdCallback(),e.created=!1)}function o(e,t){var n,r=h(e);-1<r&&(ce(e,S[r]),r=0,t!==b||e[b]?t!==w||e[w]||(e[b]=!1,e[w]=!0,r=1):(e[w]=!1,e[b]=!0,r=1,Q&&N.call(B,e)<0&&B.push(e)),r&&(n=e[t+"Callback"])&&n.call(e))}var a,b,w,y,u,s,c,T,E,O,A,x,L,k,S,C,M,N,I,P,D,F,z,R,_,j,V,q,U,H,X,Q,Y,B,W,Z,G,K,$,J,ee,te,ne,re,ie,oe,ae,le,ue,se,ce,pe,de,fe;function he(e){var t=new CustomEvent(T,{bubbles:!0});t.attrName=e,t.prevValue=this.getAttribute(e),t.newValue=null,t[c]=t.attrChange=2,G.call(this,e),this.dispatchEvent(t)}function ge(e,t){var n=this.hasAttribute(e),r=n&&this.getAttribute(e),i=new CustomEvent(T,{bubbles:!0});Z.call(this,e,t),i.attrName=e,i.prevValue=n?r:null,i.newValue=t,n?i[s]=i.attrChange=1:i[u]=i.attrChange=0,this.dispatchEvent(i)}function me(e){var t,n=e.currentTarget,r=n[a],i=e.propertyName;r.hasOwnProperty(i)&&(r=r[i],(t=new CustomEvent(T,{bubbles:!0})).attrName=r.name,t.prevValue=r.value||null,t.newValue=r.value=n[i]||null,null==t.prevValue?t[u]=t.attrChange=0:t[s]=t.attrChange=1,n.dispatchEvent(t))}t in p||(a="__"+t+(1e5*Math.random()>>0),b="attached",w="detached",y="extends",u="ADDITION",s="MODIFICATION",c="REMOVAL",T="DOMAttrModified",E="DOMContentLoaded",O="<",A="=",x=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,L=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],k=[],S=[],C="",M=p.documentElement,N=k.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},I=n.prototype,P=I.hasOwnProperty,D=I.isPrototypeOf,F=n.defineProperty,z=n.getOwnPropertyDescriptor,R=n.getOwnPropertyNames,_=n.getPrototypeOf,j=n.setPrototypeOf,V=!!n.__proto__,q=n.create||function e(t){return t?(e.prototype=t,new e):this},U=j||(V?function(e,t){return e.__proto__=t,e}:R&&z?function(e,t){for(;function(e,t){for(var n,r=R(t),i=0,o=r.length;i<o;i++)n=r[i],P.call(e,n)||F(e,n,z(t,n))}(e,t),(t=_(t))&&!D.call(t,e););return e}:function(e,t){for(var n in t)e[n]=t[n];return e}),H=e.MutationObserver||e.WebKitMutationObserver,X=(e.HTMLElement||e.Element||e.Node).prototype,Q=!D.call(X,M),Y=Q?function(e){return 1===e.nodeType}:function(e){return D.call(X,e)},B=Q&&[],W=X.cloneNode,Z=X.setAttribute,G=X.removeAttribute,K=p.createElement,$=H&&{attributes:!0,characterData:!0,attributeOldValue:!0},J=H||function(e){re=!1,M.removeEventListener(T,J)},te=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,10)},oe=ie=re=!(ne=!1),fe=j||V?(ce=function(e,t){D.call(t,e)||i(e,t)},i):ce=function(e,t){e[a]||(e[a]=n(!0),i(e,t))},Q?(re=!1,pe=z(X,"addEventListener"),de=pe.value,pe.value=function(e,t,n){e===T&&this.attributeChangedCallback&&this.setAttribute!==ge&&(this[a]={className:{name:"class",value:this.className}},this.setAttribute=ge,this.removeAttribute=he,de.call(this,"propertychange",me)),de.call(this,e,t,n)},F(X,"addEventListener",pe)):H||(M.addEventListener(T,J),M.setAttribute(a,1),M.removeAttribute(a),re&&(ae=function(e){var t,n,r,i=this;if(i===e.target){for(r in t=i[a],i[a]=n=ue(i),n){if(!(r in t))return le(0,i,r,t[r],n[r],u);if(n[r]!==t[r])return le(1,i,r,t[r],n[r],s)}for(r in t)if(!(r in n))return le(2,i,r,t[r],n[r],c)}},le=function(e,t,n,r,i,o){var a={attrChange:e,currentTarget:t,attrName:n,prevValue:r,newValue:i};a[o]=e,l(a)},ue=function(e){for(var t,n,r={},i=e.attributes,o=0,a=i.length;o<a;o++)"setAttribute"!==(n=(t=i[o]).name)&&(r[n]=t.value);return r})),p[t]=function(e,t){function o(e,t){for(var n=0,r=e.length;n<r;t(e[n++]));}var a,l,n=e.toUpperCase();if(ne||(ne=!0,H?(a=f(b),l=f(w),(se=new H(function(e){for(var t,n,r=0,i=e.length;r<i;r++)"childList"===(t=e[r]).type?(o(t.addedNodes,a),o(t.removedNodes,l)):(n=t.target,oe&&n.attributeChangedCallback&&"style"!==t.attributeName&&n.attributeChangedCallback(t.attributeName,t.oldValue,n.getAttribute(t.attributeName)))})).observe(p,{childList:!0,subtree:!0})):(ee=[],te(function e(){for(;ee.length;)ee.shift().call(null,ee.shift());te(e)}),p.addEventListener("DOMNodeInserted",m(b)),p.addEventListener("DOMNodeRemoved",m(w))),p.addEventListener(E,v),p.addEventListener("readystatechange",v),p.createElement=function(e,t){var n=K.apply(p,arguments),r=""+e,i=N.call(k,(t?A:O)+(t||r).toUpperCase()),o=-1<i;return t&&(n.setAttribute("is",t=t.toLowerCase()),o=o&&g(r.toUpperCase(),t)),oe=!p.createElement.innerHTMLHelper,o&&fe(n,S[i]),n},X.cloneNode=function(e){var t=W.call(this,!!e),n=h(t);return-1<n&&fe(t,S[n]),e&&function(e){for(var t,n=0,r=e.length;n<r;n++)t=e[n],fe(t,S[h(t)])}(t.querySelectorAll(C)),t}),-2<N.call(k,A+n)+N.call(k,O+n))throw new Error("A "+e+" type is already registered");if(!x.test(n)||-1<N.call(L,n))throw new Error("The type "+e+" is invalid");function r(){return u?p.createElement(s,n):p.createElement(s)}var n,i=t||I,u=P.call(i,y),s=u?t[y].toUpperCase():n,c=k.push((u?A:O)+n)-1;return C=C.concat(C.length?",":"",u?s+'[is="'+e.toLowerCase()+'"]':s),r.prototype=S[c]=P.call(i,"prototype")?i.prototype:q(X),d(p.querySelectorAll(C),b),r})}(window,document,Object,"registerElement"),function(h,i,g){"use strict";function m(){return h.performance!==g&&h.performance.now!==g?h.performance.now():Date.now()}function v(e){return.5*(1-Math.cos(Math.PI*e))}function o(e){if("object"!=typeof e||e.behavior===g||"auto"===e.behavior||"instant"===e.behavior)return 1;if("smooth"!==e.behavior)throw new TypeError(e.behavior+" is not a valid value for enumeration ScrollBehavior")}function n(o,a){var l=h.scrollX||h.pageXOffset,u=h.scrollY||h.pageYOffset,s=m();b&&h.cancelAnimationFrame(b),b=h.requestAnimationFrame(function e(){var t=(m()-s)/w,n=v(t=1<t?1:t),r=l+(o-l)*n,i=u+(a-u)*n;return c(r,i),r===o&&i===a?(l=u=s=null,h.cancelAnimationFrame(b)):b=h.requestAnimationFrame(e),g})}function a(u,e){if(u===i.documentElement||u===i.body)return n(e.left,e.top),g;var s=u.scrollLeft,c=u.scrollTop,p=e.left,d=e.top,f=m();b&&h.cancelAnimationFrame(b),b=h.requestAnimationFrame(function e(){var t,n,r,i=(m()-f)/w,o=v(i=1<i?1:i),a=s+(p-s)*o,l=c+(d-c)*o;return n=a,r=l,(t=u).scrollTop=r,t.scrollLeft=n,a===p&&l===d?(s=c=f=null,h.cancelAnimationFrame(b)):b=h.requestAnimationFrame(e),g})}var b,w,c,r,l;"scrollBehavior"in i.documentElement.style||(w=768,c=h.scrollTo,r=h.scrollBy,l=h.Element.prototype.scrollIntoView,h.scroll=h.scrollTo=function(){return o(arguments[0])?c.call(h,arguments[0].left||arguments[0],arguments[0].top||arguments[1]):n.call(h,~~arguments[0].left,~~arguments[0].top)},h.scrollBy=function(){if(o(arguments[0]))return r.call(h,arguments[0].left||arguments[0],arguments[0].top||arguments[1]);var e=h.scrollX||h.pageXOffset,t=h.scrollY||h.pageYOffset;return n(~~arguments[0].left+e,~~arguments[0].top+t)},Element.prototype.scrollIntoView=function(){var e,t,n,r;return o(arguments[0])?l.call(this,arguments[0]||!0):(r=h.getComputedStyle(i.body,null),t=parseInt(r.getPropertyValue("padding-left"),10),n=parseInt(r.getPropertyValue("padding-top"),10),e={top:this.offsetTop-2*n,left:this.offsetLeft-2*t},a(i.body,e))})}(window,document); })(this);
 
 // WCF.js
-(function (window, undefined) { "use strict";function wcfEval(expression){return eval(expression)}!function(){var e=jQuery.fn.data;jQuery.fn.data=function(t,i){var n=[].slice.call(arguments);if(t)switch(typeof t){case"object":for(var s in t)if(s.match(/ID$/)){var a=t[s];delete t[s],s=s.replace(/ID$/,"-id"),t[s]=a}n[0]=t;break;case"string":t.match(/ID$/)&&(n[0]=t.replace(/ID$/,"-id"))}var o=e.apply(this,n);if(void 0===t)for(var s in o)s.match(/Id$/)&&(o[s.replace(/Id$/,"ID")]=o[s],delete o[s]);return o},window.console||(window.console={});for(var t=["log","info","warn","exception","assert","dir","dirxml","trace","group","groupEnd","groupCollapsed","profile","profileEnd","count","clear","time","timeEnd","timeStamp","table","error"],i=0;i<t.length;i++)void 0===console[t[i]]&&(console[t[i]]=function(){});void 0===console.debug&&(console.debug=function(e){console.log(e)})}(),window.shuffle=function(e){for(var t,i,n=e.length;0!==n;)i=Math.floor(Math.random()*n),n-=1,t=e[n],e[n]=e[i],e[i]=t;return this},function(e){var t=navigator.userAgent.toLowerCase(),i=/(chrome)[ \/]([\w.]+)/.exec(t)||/(webkit)[ \/]([\w.]+)/.exec(t)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(t)||/(msie) ([\w.]+)/.exec(t)||t.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(t)||[],n={browser:i[1]||"",version:i[2]||"0"},s={};n.browser&&(s[n.browser]=!0,s.version=n.version),s.chrome?s.webkit=!0:s.webkit&&(s.safari=!0),e.browser=e.browser||{},e.browser=$.extend(e.browser,s),e.browser.touch=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&window.navigator.msMaxTouchPoints>0,e.browser.smartphone="bottom"==$("html").css("caption-side"),e.browser.mozilla&&t.match(/trident/)&&(e.browser.mozilla=!1,e.browser.msie=!0),e.browser.iOS=/\((ipad|iphone|ipod);/.test(t),e.browser.iOS&&$("html").addClass("iOS"),e.browser.android=-1!==t.indexOf("android"),e.browser.editor="redactor",e.browser.ckeditor=!1,e.browser.redactor=!0,e.browser.iOS&&(e.fn.focus=function(e,t){return arguments.length>0?this.on("focus",null,e,t):this.trigger("focus")})}(jQuery),null==window.WCF&&(window.WCF={}),$.extend(!0,{removeArrayValue:function(e,t){return $.grep(e,function(e,i){return t!==e})},wcfEscapeID:function(e){return e.replace(/(:|\.)/g,"\\$1")},wcfIsset:function(e){return!!$("#"+$.wcfEscapeID(e)).length},getLength:function(e){var t=0;for(var i in e)e.hasOwnProperty(i)&&t++;return t}}),$.fn.extend({getTagName:function(){return this.length?this.get(0).tagName.toLowerCase():""},getDimensions:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"inner":i={height:this.innerHeight(),width:this.innerWidth()};break;case"outer":i={height:this.outerHeight(),width:this.outerWidth()};break;default:i={height:this.height(),width:this.width()}}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},getOffsets:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"offset":i=this.offset();break;case"position":default:i=this.position()}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},makePositioned:function(e,t){"absolute"!=e&&"fixed"!=e&&(e="absolute");var i=this.getOffsets("position");return this.css({position:e,left:i.left,margin:0,top:i.top}),t&&this.remove().appentTo("body"),this},disable:function(){return this.attr("disabled","disabled")},enable:function(){return this.removeAttr("disabled")},wcfIdentify:function(){return window.bc_wcfDomUtil.identify(this[0])},getCaret:function(){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return-1}else if(!this.is("textarea"))return-1;var e=0,t=this.get(0);if(document.selection){this.focus();var i=document.selection.createRange();i.moveStart("character",-this.val().length),e=i.text.length}else(t.selectionStart||"0"==t.selectionStart)&&(e=parseInt(t.selectionStart));return e},setCaret:function(e){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return!1}else if(!this.is("textarea"))return!1;var t=this.get(0);if(this.focus(),document.selection){var i=document.selection.createRange();i.moveStart("character",e),i.moveEnd("character",0),i.select()}else(t.selectionStart||"0"==t.selectionStart)&&(t.selectionStart=e,t.selectionEnd=e);return!0},wcfDropIn:function(e,t,i){return e||(e="up"),i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfDropOut:function(e,t,i){return e||(e="down"),i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfBlindIn:function(e,t,i){return e||(e="vertical"),i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfBlindOut:function(e,t,i){return e||(e="vertical"),i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfHighlight:function(e,t){return this.effect("highlight",e,600,t)},wcfFadeIn:function(e,t){return t&&parseInt(t)||(t=200),this.show(WCF.getEffect(this,"fade"),{},t,e)},wcfFadeOut:function(e,t){return t&&parseInt(t)||(t=200),this.hide(WCF.getEffect(this,"fade"),{},t,e)},cssAsNumber:function(e){if(this.length){var t=this.css(e);if(void 0!==t)return parseInt(t.replace(/px$/,""))}return 0},perfectScrollbar:function(e){var t=require("perfect-scrollbar");return this.each(function(){if("object"==typeof e||void 0===e){var i=e;$(this).data("psID")||t.initialize(this,i)}else{var n=e;"update"===n?t.update(this):"destroy"===n&&t.destroy(this)}return jQuery(this)})}}),$.extend(WCF,{activeDialogs:0,_idCounter:0,getRandomID:function(){return window.bc_wcfDomUtil.getUniqueId()},inArray:function(e,t){return-1!=$.inArray(e,t)},getEffect:function(e,t){return e.is("tr")?"highlight":t},getInlineCSS:function(e){var t={},i=e.attr("style");if(!i)return{};i=i.split(";");for(var n=0,s=i.length;n<s;n++){var a=$.trim(i[n]);""!=a&&(a=a.split(":"),t[$.trim(a[0])]=$.trim(a[1]))}return t},revertInlineCSS:function(e,t,i){for(var n=0,s=i.length;n<s;n++){var a=i[n];t[a]?e.css(a,t[a]):e.css(a,"")}},getUUID:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},base64toBlob:function(e,t,i){t=t||"",i=i||512;for(var n=atob(e),s=[],a=0;a<n.length;a+=i){for(var o=n.slice(a,a+i),r=new Array(o.length),l=0;l<o.length;l++)r[l]=o.charCodeAt(l);var c=new Uint8Array(r);s.push(c)}return new Blob(s,{type:t})},convertLegacyURL:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){for(var i=t.split(/([A-Z][a-z0-9]+)/),n="",s=0,a=i.length;s<a;s++){var o=i[s].trim();o.length&&(n.length&&(n+="-"),n+=o.toLowerCase())}return"index.php?"+n+"/&"})}}),WCF.Browser={_isChrome:null,isChrome:function(){return null===this._isChrome&&(this._isChrome=!1,/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&(this._isChrome=!0)),this._isChrome}},WCF.Dropdown={init:function(e){window.bc_wcfSimpleDropdown.initAll()},initDropdown:function(e,t){window.bc_wcfSimpleDropdown.init(e[0],t)},removeDropdown:function(e){window.bc_wcfSimpleDropdown.destroy(e)},initDropdownFragment:function(e,t){window.bc_wcfSimpleDropdown.initFragment(e[0],t[0])},registerCallback:function(e,t){window.bc_wcfSimpleDropdown.registerCallback(e,t)},_toggle:function(e,t){window.bc_wcfSimpleDropdown._toggle(e,t)},toggleDropdown:function(e,t){window.bc_wcfSimpleDropdown._toggle(null,e,null,t)},getDropdown:function(e){var t=window.bc_wcfSimpleDropdown.getDropdown(e);return t?$(t):null},getDropdownMenu:function(e){var t=window.bc_wcfSimpleDropdown.getDropdownMenu(e);return t?$(t):null},setAlignmentByID:function(e){window.bc_wcfSimpleDropdown.setAlignmentById(e)},setAlignment:function(e,t){window.bc_wcfSimpleDropdown.setAlignment(e[0],t[0])},_closeAll:function(){window.bc_wcfSimpleDropdown.closeAll()},close:function(e){window.bc_wcfSimpleDropdown.close(e)},destroy:function(e){window.bc_wcfSimpleDropdown.destroy(e)}},WCF.Dropdown.Interactive={},WCF.Dropdown.Interactive.Handler={_dropdownContainer:null,_dropdownMenus:{},create:function(e,t,i){null===this._dropdownContainer&&(this._dropdownContainer=$('<div class="dropdownMenuContainer" />').appendTo(document.body),WCF.CloseOverlayHandler.addCallback("WCF.Dropdown.Interactive.Handler",$.proxy(this.closeAll,this)));var n=new WCF.Dropdown.Interactive.Instance(this._dropdownContainer,e,t,i);return this._dropdownMenus[t]=n,n},open:function(e){return!!this._dropdownMenus[e]&&(this._dropdownMenus[e].open(),!0)},close:function(e){return!!this._dropdownMenus[e]&&(this._dropdownMenus[e].close(),!0)},closeAll:function(){for(var e in this._dropdownMenus)this._dropdownMenus.hasOwnProperty(e)&&this._dropdownMenus[e].close()},getOpenDropdown:function(){for(var e in this._dropdownMenus)if(this._dropdownMenus.hasOwnProperty(e)&&this._dropdownMenus[e].isOpen())return this._dropdownMenus[e];return null},getDropdown:function(e){return this._dropdownMenus[e]}},WCF.Dropdown.Interactive.Instance=Class.extend({_container:null,_itemList:null,_linkList:null,_options:{},_pointer:null,_triggerElement:null,init:function(e,t,i,n){this._options=n||{},this._triggerElement=t;var s=null;if(!0===n.staticDropdown)this._container=this._triggerElement.find(".interactiveDropdownStatic:eq(0)").data("source",i).click(function(e){e.stopPropagation()});else{this._container=$('<div class="interactiveDropdown" data-source="'+i+'" />').click(function(e){e.stopPropagation()});var a=$('<div class="interactiveDropdownHeader" />').appendTo(this._container);$('<span class="interactiveDropdownTitle">'+n.title+"</span>").appendTo(a),this._linkList=$('<ul class="interactiveDropdownLinks inlineList"></ul>').appendTo(a),s=$('<div class="interactiveDropdownItemsContainer" />').appendTo(this._container),this._itemList=$('<ul class="interactiveDropdownItems" />').appendTo(s),$('<a href="'+n.showAllLink+'" class="interactiveDropdownShowAll">'+WCF.Language.get("wcf.user.panel.showAll")+"</a>").appendTo(this._container)}this._pointer=$('<span class="elementPointer"><span /></span>').appendTo(this._container),require(["Ui/Screen"],function(e){e.is("screen-lg")&&null!==s&&s.perfectScrollbar({suppressScrollX:!0})}.bind(this)),this._container.appendTo(e)},getContainer:function(){return this._container},getItemList:function(){return this._itemList},getLinkList:function(){return this._linkList},open:function(){WCF.Dropdown._closeAll(),this._triggerElement.addClass("open"),this._container.addClass("open"),WCF.System.Event.fireEvent("com.woltlab.wcf.Search","close"),this.render()},close:function(){this._triggerElement.removeClass("open"),this._container.removeClass("open")},isOpen:function(){return this._triggerElement.hasClass("open")},toggle:function(){return this._container.hasClass("open")?(this.close(),!1):(WCF.Dropdown.Interactive.Handler.closeAll(),this.open(),!0)},resetItems:function(){this._itemList.empty(),this.close()},render:function(){require(["Ui/Alignment","Ui/Screen"],function(e,t){t.is("screen-lg")?e.set(this._container[0],this._triggerElement[0],{horizontal:"right",pointer:!0}):this._container.css({bottom:"",left:"",right:"",top:elById("pageHeaderPanel").clientHeight+"px"})}.bind(this))},rebuildScrollbar:function(){require(["Ui/Screen"],function(e){if(e.is("screen-lg")){var t=this._itemList.parent();t.perfectScrollbar("destroy"),t.perfectScrollbar({suppressScrollX:!0})}}.bind(this))}}),WCF.Clipboard={init:function(e,t,i,n){require(["EventHandler","WoltLabSuite/Core/Controller/Clipboard"],function(s,a){a.setup({hasMarkedItems:t>0,pageClassName:e,pageObjectId:n});for(var o in i)i.hasOwnProperty(o)&&function(e){s.add("com.woltlab.wcf.clipboard",e,function(t){null!==t.responseData&&i[e].hasOwnProperty(t.responseData.actionName)&&i[e][t.responseData.actionName].triggerEffect(t.responseData.objectIDs)})}(o)})},reload:function(){require(["WoltLabSuite/Core/Controller/Clipboard"],function(e){e.reload()})}},WCF.PeriodicalExecuter=Class.extend({_callback:null,_delay:0,_intervalID:null,_isExecuting:!1,init:function(e,t){if(!$.isFunction(e))return void console.debug("[WCF.PeriodicalExecuter] Given callback is invalid, aborting.");this._callback=e,this._interval=t,this.resume()},_execute:function(){if(!this._isExecuting)try{this._isExecuting=!0,this._callback(this),this._isExecuting=!1}catch(e){throw this._isExecuting=!1,e}},stop:function(){this._intervalID&&clearInterval(this._intervalID)},resume:function(){this.restart()},restart:function(){this._intervalID&&this.stop(),this._intervalID=setInterval($.proxy(this._execute,this),this._interval)},setInterval:function(e){this._interval=e,this.restart()}}),WCF.LoadingOverlayHandler={show:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.show()})},hide:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.hide()})},updateIcon:function(e,t){var i=void 0===t||t?"addClass":"removeClass";e.find(".icon")[i]("fa-spinner"),e.hasClass("icon")&&e[i]("fa-spinner")}},WCF.Action={},WCF.Action.Proxy=Class.extend({_ajaxRequest:null,init:function(e){this._ajaxRequest=null,e=$.extend(!0,{autoSend:!1,data:{},dataType:"json",after:null,init:null,jsonp:"callback",async:!0,failure:null,showLoadingOverlay:!0,success:null,suppressErrors:!1,type:"POST",url:"index.php?ajax-proxy/&t="+SECURITY_TOKEN,aborted:null,autoAbortPrevious:!1},e),"jsonp"===e.dataType?require(["AjaxJsonp"],function(t){t.send(e.url,e.success,e.failure,{parameterName:e.jsonp})}):require(["AjaxRequest"],function(t){this._ajaxRequest=new t({data:e.data,type:e.type,url:e.url,withCredentials:e.url==="index.php?ajax-proxy/&t="+SECURITY_TOKEN,responseType:"json"===e.dataType?"application/json":"",autoAbort:e.autoAbortPrevious,ignoreError:e.suppressErrors,silent:!e.showLoadingOverlay,failure:e.failure,finalize:e.after,success:e.success}),e.autoSend&&this._ajaxRequest.sendRequest()}.bind(this))},sendRequest:function(e){require(["AjaxRequest"],function(t){null!==this._ajaxRequest&&this._ajaxRequest.sendRequest(e)}.bind(this))},abortPrevious:function(){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.abortPrevious()}.bind(this))},setOption:function(e,t){require(["AjaxRequest"],function(i){null!==this._ajaxRequest&&this._ajaxRequest.setOption(e,t)}.bind(this))},showLoadingOverlayOnce:function(){},suppressErrors:function(){},_failure:function(e,t,i){},_success:function(e,t,i){},_after:function(){}}),WCF.Action.SimpleProxy=Class.extend({init:function(e,t){this.options=$.extend(!0,{action:"",className:"",elements:null,eventName:"click"},e),this.callbacks=$.extend(!0,{after:null,failure:null,init:null,success:null},t),this.options.elements&&(this.proxy=new WCF.Action.Proxy(this.callbacks),this.options.elements.each($.proxy(function(e,t){$(t).bind(this.options.eventName,$.proxy(this._handleEvent,this))},this)))},_handleEvent:function(e){this.proxy.setOption("data",{actionName:this.options.action,className:this.options.className,objectIDs:[$(e.target).data("objectID")]}),this.proxy.sendRequest()}}),WCF.Action.Delete=Class.extend({_buttonSelector:"",_callback:null,_className:"",_containerSelector:"",_containers:[],init:function(e,t,i){this._containerSelector=t,this._className=e,this._buttonSelector=i||".jsDeleteButton",this._callback=null,this.proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initElements(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Action.Delete"+this._className.hashCode(),$.proxy(this._initElements,this))},_initElements:function(){$(this._containerSelector).each(function(e,t){var i=$(t),n=i.wcfIdentify();if(!WCF.inArray(n,this._containers)){var s=i.find(this._buttonSelector);s.length&&(this._containers.push(n),s.click($.proxy(this._click,this)))}}.bind(this))},_click:function(e){var t=$(e.currentTarget);e.preventDefault(),t.data("confirmMessageHtml")||t.data("confirmMessage")?WCF.System.Confirmation.show(t.data("confirmMessageHtml")?t.data("confirmMessageHtml"):t.data("confirmMessage"),$.proxy(this._execute,this),{target:t},void 0,!!t.data("confirmMessageHtml")):(WCF.LoadingOverlayHandler.updateIcon(t),this._sendRequest(t))},_didTriggerEffect:function(e){},_execute:function(e,t){"cancel"!==e&&(WCF.LoadingOverlayHandler.updateIcon(t.target),this._sendRequest(t.target))},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"delete",className:this._className,interfaceName:"wcf\\data\\IDeleteAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this._callback&&this._callback(e.objectIDs),this.triggerEffect(e.objectIDs)},setCallback:function(e){if("function"!=typeof e)throw new TypeError("[WCF.Action.Delete] Expected a valid callback for '"+this._className+"'.");this._callback=e},triggerEffect:function(e){this._containers.forEach(function(t){var i=$("#"+t),n=i.find(this._buttonSelector);if(WCF.inArray(n.data("objectID"),e)){var s=this;i.wcfBlindOut("up",function(){var e=$(this).remove();s._containers.splice(s._containers.indexOf(e.wcfIdentify()),1),s._didTriggerEffect(e),n.data("eventName")&&WCF.System.Event.fireEvent("com.woltlab.wcf.action.delete",n.data("eventName"),{button:n,container:e})})}}.bind(this))}}),WCF.Action.NestedDelete=WCF.Action.Delete.extend({triggerEffect:function(e){for(var t in this._containers){var i=$("#"+this._containers[t]);if(WCF.inArray(i.find(this._buttonSelector).data("objectID"),e))if(i.has("ol").has("li").length)i.is(":only-child")?i.parent().replaceWith(i.find("> ol")):i.replaceWith(i.find("> ol > li")),this._containers.splice(this._containers.indexOf(i.wcfIdentify()),1),this._didTriggerEffect(i);else{var n=this;i.wcfBlindOut("up",function(){$(this).remove(),n._containers.splice(n._containers.indexOf($(this).wcfIdentify()),1),n._didTriggerEffect($(this))})}}}}),WCF.Action.Toggle=Class.extend({_buttonSelector:".jsToggleButton",_className:"",_containerSelector:"",_containers:[],init:function(e,t,i){this._containerSelector=t,this._className=e,this._buttonSelector=i||".jsToggleButton",this._containers=[];var n={success:$.proxy(this._success,this)};this.proxy=new WCF.Action.Proxy(n),this._initElements(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Action.Toggle"+this._className.hashCode(),$.proxy(this._initElements,this))},_initElements:function(){$(this._containerSelector).each($.proxy(function(e,t){var i=$(t),n=i.wcfIdentify();WCF.inArray(n,this._containers)||(this._containers.push(n),i.find(this._buttonSelector).click($.proxy(this._click,this)))},this))},_click:function(e){var t=$(e.currentTarget);e.preventDefault(),t.data("confirmMessageHtml")||t.data("confirmMessage")?WCF.System.Confirmation.show(t.data("confirmMessageHtml")?t.data("confirmMessageHtml"):t.data("confirmMessage"),$.proxy(this._execute,this),{target:t},void 0,!!t.data("confirmMessageHtml")):(WCF.LoadingOverlayHandler.updateIcon(t),this._sendRequest(t))},_execute:function(e,t){"cancel"!==e&&(WCF.LoadingOverlayHandler.updateIcon(t.target),this._sendRequest(t.target))},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"toggle",className:this._className,interfaceName:"wcf\\data\\IToggleAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this.triggerEffect(e.objectIDs)},triggerEffect:function(e){for(var t in this._containers){var i=$("#"+this._containers[t]),n=i.find(this._buttonSelector);WCF.inArray(n.data("objectID"),e)&&(i.wcfHighlight(),this._toggleButton(i,n))}},_toggleButton:function(e,t){var i="";WCF.LoadingOverlayHandler.updateIcon(t,!1),t.hasClass("fa-square-o")?(t.removeClass("fa-square-o").addClass("fa-check-square-o"),i=t.data("disableTitle")?t.data("disableTitle"):WCF.Language.get("wcf.global.button.disable"),t.attr("title",i)):(t.removeClass("fa-check-square-o").addClass("fa-square-o"),i=t.data("enableTitle")?t.data("enableTitle"):WCF.Language.get("wcf.global.button.enable"),t.attr("title",i)),e.toggleClass("disabled")}}),WCF.Action.Scroll=Class.extend({_callback:null,_reference:null,_target:null,_threshold:0,init:function(e,t,i,n){return this._threshold=parseInt(e),0===this._threshold?void console.debug("[WCF.Action.Scroll] Given threshold is invalid, aborting."):($.isFunction(t)&&(this._callback=t),null===this._callback?void console.debug("[WCF.Action.Scroll] Given callback is invalid, aborting."):(this._reference=$(i||window),this._target=$(n||document),this.start(),void this._scroll()))},_scroll:function(){var e=this._target.height(),t=this._reference.scrollTop();e-(this._reference.height()+t)<this._threshold&&this._callback(this)},start:function(){this._reference.on("scroll",$.proxy(this._scroll,this))},stop:function(){this._reference.off("scroll")}}),WCF.Date={},WCF.Date.Picker={init:function(){}},WCF.Date.Util={gmdate:function(e){var t=e||new Date;return Math.round(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDay(),t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds())/1e3)},getTimezoneDate:function(e,t){var i=new Date(e),n=6e4*i.getTimezoneOffset();return new Date(e+n+t)}},WCF.Dictionary=Class.extend({_variables:{},init:function(){this._variables={}},add:function(e,t){this._variables[e]=t},addObject:function(e){for(var t in e)this.add(t,e[t])},addDictionary:function(e){e.each($.proxy(function(e){this.add(e.key,e.value)},this))},get:function(e){return this.isset(e)?this._variables[e]:null},isset:function(e){return this._variables.hasOwnProperty(e)},remove:function(e){delete this._variables[e]},each:function(e){if($.isFunction(e))for(var t in this._variables){var i=this._variables[t],n={key:t,value:i};e(n)}},count:function(){return $.getLength(this._variables)},isEmpty:function(){return!this.count()}}),null==window.WCF.Language&&(WCF.Language={add:function(e,t){require(["Language"],function(i){i.add(e,t)})},addObject:function(e){require(["Language"],function(t){t.addObject(e)})},get:function(e,t){throw new Error('Call to deprecated WCF.Language.get("'+e+'")')}}),WCF.Number={round:function(e,t){return t=Math.pow(10,t||0),Math.round(e*t)/t}},WCF.String={addThousandsSeparator:function(e){return String(e).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+WCF.Language.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(e,t){e=String(WCF.Number.round(e,t||2));var i=e.split(".");return e=this.addThousandsSeparator(i[0]),i.length>1&&(e+=WCF.Language.get("wcf.global.decimalPoint")+i[1]),e=e.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")}},WCF.TabMenu={init:function(){require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.setup()})},reload:function(){this.init()}},WCF.Template=Class.extend({init:function(e){var t=new WCF.Dictionary,i=0;e=e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n"),e=e.replace(/\{literal\}(.*?)\{\/literal\}/g,$.proxy(function(e){var i="@@@@@@@@@@@"+Math.random()+"@@@@@@@@@@@";return t.add(i,e.replace(/\{\/?literal\}/g,"")),i},this)),e=e.replace(/\{\*.*?\*\}/g,"");var n=function(e){for(var t=e.split(""),i={},n=!0,s="",a="",o=!1,r=!1,l=!1,c=0,u=t.length;c<u;c++){var h=t[c];n&&"="!=h&&" "!=h?s+=h:n&&"="==h?(n=!1,r=!1,o=!1,l=!1):n||r||o||" "!=h?n||!r||l||"'"!=h?n||r||o||"'"!=h?n||!o||l||'"'!=h?n||r||o||'"'!=h?n||!o&&!r||l||"\\"!=h?n||(l=!1,a+=h):(l=!0,a+=h):(o=!0,a+=h):(o=!1,a+=h):(r=!0,a+=h):(r=!1,a+=h):(n=!0,i[s]=a,a=s="")}if(i[s]=a,o||r||l)throw new Error('Syntax error in parameterList: "'+e+'"');return i},s=function(e){return e.replace(/\\n/g,"\n").replace(/\\\\/g,"\\").replace(/\\'/g,"'")};e=e.replace(/\{(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.escapeHTML("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{#(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.formatNumeric("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{@(\$[^\}]+?)\}/g,function(e,t){return"' + "+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+" + '"}).replace(/\{lang\}(.+?)\{\/lang\}/g,function(e,t){return"' + WCF.Language.get('"+t+"', v) + '"}).replace(/\{include (.+?)\}/g,function(e,t){t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=n(t);if(void 0===i.file)throw new Error("Missing file attribute in include-tag");return i.file=i.file.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"' + "+i.file+".fetch(v) + '"}).replace(/\{if (.+?)\}/g,function(e,t){return"';\nif ("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{else ?if (.+?)\}/g,function(e,t){return"';\n}\nelse if ("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{implode (.+?)\}/g,function(e,t){i++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var s=n(t);if(void 0===s.from)throw new Error("Missing from attribute in implode-tag");if(void 0===s.item)throw new Error("Missing item attribute in implode-tag");return void 0===s.glue&&(s.glue="', '"),s.from=s.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\nvar $implode_"+i+" = false;\nfor ($implodeKey_"+i+" in "+s.from+") {\n\tv["+s.item+"] = "+s.from+"[$implodeKey_"+i+"];\n"+(void 0!==s.key?"\t\tv["+s.key+"] = $implodeKey_"+i+";\n":"")+"\tif ($implode_"+i+") $output += "+s.glue+";\n\t$implode_"+i+" = true;\n\t$output += '"}).replace(/\{foreach (.+?)\}/g,function(e,t){i++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var s=n(t);if(void 0===s.from)throw new Error("Missing from attribute in foreach-tag");if(void 0===s.item)throw new Error("Missing item attribute in foreach-tag");return s.from=s.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\n$foreach_"+i+" = false;\nfor ($foreachKey_"+i+" in "+s.from+") {\n\t$foreach_"+i+" = true;\n\tbreak;\n}\nif ($foreach_"+i+") {\n\tfor ($foreachKey_"+i+" in "+s.from+") {\n\t\tv["+s.item+"] = "+s.from+"[$foreachKey_"+i+"];\n"+(void 0!==s.key?"\t\tv["+s.key+"] = $foreachKey_"+i+";\n":"")+"\t\t$output += '"}).replace(/\{foreachelse\}/g,"';\n\t}\n}\nelse {\n\t{\n\t\t$output += '").replace(/\{\/foreach\}/g,"';\n\t}\n}\n$output += '").replace(/\{else\}/g,"';\n}\nelse {\n\t$output += '").replace(/\{\/(if|implode)\}/g,"';\n}\n$output += '");for(var a in WCF.Template.callbacks)e=WCF.Template.callbacks[a](e);e=e.replace("{ldelim}","{").replace("{rdelim}","}"),t.each(function(t){e=e.replace(t.key,t.value)}),e="$output += '"+e+"';";try{this.fetch=new Function("v","v = window.$.extend({}, v, { __wcf: window.WCF, __window: window }); var $output = ''; "+e+" return $output;")}catch(t){throw console.debug("var $output = ''; "+e+" return $output;"),t}},fetch:function(e){}}),WCF.Template.callbacks=[],WCF.ToggleOptions=Class.extend({_element:null,_showItems:[],_hideItems:[],_callback:null,init:function(e,t,i,n){this._element=$("#"+e),this._showItems=t,this._hideItems=i,void 0!==n&&(this._callback=n),this._element.click($.proxy(this._toggle,this)),this._toggle()},_toggle:function(){if(this._element.prop("checked")){for(var e=0,t=this._showItems.length;e<t;e++){var i=this._showItems[e];$("#"+i).show()}for(var e=0,t=this._hideItems.length;e<t;e++){var i=this._hideItems[e];$("#"+i).hide()}null!==this._callback&&this._callback()}}}),WCF.Collapsible={},WCF.Collapsible.Simple={init:function(){$(".jsCollapsible").each($.proxy(function(e,t){this._initButton(t)},this))},_initButton:function(e){var t=$(e);t.data("isOpen")||$("#"+t.data("collapsibleContainer")).hide(),t.click($.proxy(this._toggle,this))},_toggle:function(e){var t=$(e.currentTarget),i=t.data("isOpen"),n=$("#"+$.wcfEscapeID(t.data("collapsibleContainer")));return i?(n.stop().wcfBlindOut("vertical",$.proxy(function(){this._toggleImage(t)},this)),i=!1):(n.stop().wcfBlindIn("vertical",$.proxy(function(){this._toggleImage(t)},this)),i=!0),t.data("isOpen",i),e.stopPropagation(),!1},_toggleImage:function(e){var t=e.find("span.icon");e.data("isOpen")?t.removeClass("fa-chevron-right").addClass("fa-chevron-down"):t.removeClass("fa-chevron-down").addClass("fa-chevron-right")}},WCF.Collapsible.Remote=Class.extend({_className:"",_containers:{},_containerData:{},_proxy:null,init:function(e){this._className=e,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Collapsible.Remote",$.proxy(this._init,this))},_init:function(e){this._getContainers().each($.proxy(function(e,t){var i=$(t),n=i.wcfIdentify();void 0===this._containers[n]&&(this._containers[n]=i,this._initContainer(n))},this))},_initContainer:function(e){var t=this._getTarget(e),i=this._getButtonContainer(e),n=this._createButton(e,i);this._containerData[e]={button:n,buttonContainer:i,isOpen:this._containers[e].data("isOpen"),target:t},this._containers[e].data("isOpen")||$("#"+e).addClass("jsCollapsed")},_getContainers:function(){},_getTarget:function(e){},_getButtonContainer:function(e){},_createButton:function(e,t){var i=elBySel(".jsStaticCollapsibleButton",t[0]);return null!==i&&i.parentNode===t[0]?(i.classList.remove("jsStaticCollapsibleButton"),i=$(i)):i=$('<span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-down" title="'+WCF.Language.get("wcf.global.button.collapsible")+'">').prependTo(t),i.data("containerID",e).click($.proxy(this._toggleContainer,this)),i},_toggleContainer:function(e){var t=$(e.currentTarget),i=t.data("containerID"),n=this._containerData[i].isOpen,s=n?"open":"close",a=n?"close":"open";this._proxy.setOption("data",{actionName:"loadContainer",className:this._className,interfaceName:"wcf\\data\\ILoadableContainerAction",objectIDs:[this._getObjectID(i)],parameters:$.extend(!0,{containerID:i,currentState:s,newState:a},this._getAdditionalParameters(i))}),this._proxy.sendRequest(),$("#"+i).toggleClass("jsCollapsed")},_exchangeIcon:function(e,t){t=t||"spinner",e.removeClass("fa-chevron-down fa-chevron-right fa-spinner").addClass("fa-"+t)},_getObjectID:function(e){return $("#"+e).data("objectID")},_getAdditionalParameters:function(e){return{}},_updateContent:function(e,t,i){this._containerData[e].target.html(t)},_success:function(e,t,i){if(e.returnValues.containerID){var n=e.returnValues.containerID;if(this._containers[n]){this._containerData[n].isOpen=!!e.returnValues.isOpen;var s=e.returnValues.isOpen?"open":"close";this._updateContent(n,$.trim(e.returnValues.content),s)}}}}),WCF.Collapsible.SimpleRemote=WCF.Collapsible.Remote.extend({init:function(e){this._super(e),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1})},_initContainer:function(e){this._super(e),this._containerData[e].isOpen||(this._containerData[e].target.hide(),this._exchangeIcon(this._containerData[e].button,"chevron-right"))},_toggleContainer:function(e){var t=$(e.currentTarget),i=t.data("containerID"),n=this._containerData[i].isOpen,s=n?"open":"close",a=n?"close":"open";this._proxy.setOption("data",{actionName:"toggleContainer",className:this._className,interfaceName:"wcf\\data\\IToggleContainerAction",objectIDs:[this._getObjectID(i)],parameters:$.extend(!0,{containerID:i,currentState:s,newState:a},this._getAdditionalParameters(i))}),this._proxy.sendRequest(),this._exchangeIcon(this._containerData[i].button,"open"===a?"chevron-down":"chevron-right"),"open"===a?this._containerData[i].target.show():this._containerData[i].target.hide(),$("#"+i).toggleClass("jsCollapsed"),this._containerData[i].isOpen="open"===a}}),WCF.User={userID:0,username:"",init:function(e,t){this.userID=e,this.username=t}},WCF.Effect={},WCF.Effect.Scroll=Class.extend({scrollTo:function(e,t,i){if(!e.length)return!0;var n=e.getOffsets("offset").top,s=$(document).height(),a=$(window).height();return n>s-a&&(n=s-a)<0&&(n=0),!0===i?$("html,body").scrollTop(n):$("html,body").animate({scrollTop:n},400,function(e,t,i,n,s){return-n*((t=t/s-1)*t*t*t-1)+i}),!1}}),WCF.CloseOverlayHandler={addCallback:function(e,t){
-require(["Ui/CloseOverlay"],function(i){i.add(e,t)})},removeCallback:function(e){require(["Ui/CloseOverlay"],function(t){t.remove(e)})},forceExecution:function(){require(["Ui/CloseOverlay"],function(e){e.execute()})}},WCF.DOMNodeInsertedHandler={addCallback:function(e,t){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.add("__legacy__",t)})},_executeCallbacks:function(){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.trigger()})},execute:function(){this._executeCallbacks()}},WCF.DOMNodeRemovedHandler={_callbacks:new WCF.Dictionary,_isExecuting:!1,_isListening:!1,addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.DOMNodeRemovedHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){if(!this._isListening){if(window.MutationObserver){new MutationObserver(function(e){var t=!1;e.forEach(function(e){e.removedNodes.length&&(t=!0)}.bind(this)),t&&this._executeCallbacks({})}.bind(this)).observe(document.body,{childList:!0,subtree:!0})}else $(document).bind("DOMNodeRemoved",$.proxy(this._executeCallbacks,this));this._isListening=!0}},_executeCallbacks:function(e){this._isExecuting||(this._isExecuting=!0,this._callbacks.each(function(t){t.value(e)}),this._isExecuting=!1)}},WCF.Option={},WCF.Option.Handler=Class.extend({init:function(){this._initOptions(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Option.Handler",$.proxy(this._initOptions,this))},_initOptions:function(){$(".jsEnablesOptions").each($.proxy(this._initOption,this))},_initOption:function(e,t){this._change(t),$(t).change($.proxy(this._handleChange,this))},_handleChange:function(e){this._change($(e.target))},_change:function(option){option=$(option);var disableOptions=eval(option.data("disableOptions")),enableOptions=eval(option.data("enableOptions"));switch(option.getTagName()){case"input":switch(option.attr("type")){case"checkbox":this._execute(option.prop("checked"),disableOptions,enableOptions);break;case"radio":if(option.prop("checked")){var isActive=!0;option.data("isBoolean")&&1!=option.val()&&(isActive=!1),this._execute(isActive,disableOptions,enableOptions)}}break;case"select":var $value=option.val(),relevantDisableOptions=[],relevantEnableOptions=[];if(disableOptions.length>0)for(var $index in disableOptions){var $item=disableOptions[$index];$item.value==$value?relevantDisableOptions.push($item.option):relevantEnableOptions.push($item.option)}if(enableOptions.length>0)for(var $index in enableOptions){var $item=enableOptions[$index];$item.value==$value?relevantEnableOptions.push($item.option):relevantDisableOptions.push($item.option)}this._execute(!0,relevantDisableOptions,relevantEnableOptions)}},_execute:function(e,t,i){if(t.length>0)for(var n=0,s=t.length;n<s;n++){var a=t[n];if($.wcfIsset(a))this._enableOption(a,!e);else{var o=$("."+a+"Input");o.length&&this._enableOptions(o.children("dd").find("input, select, textarea"),!e)}}if(i.length>0)for(var n=0,s=i.length;n<s;n++){var a=i[n];if($.wcfIsset(a))this._enableOption(a,e);else{var o=$("."+a+"Input");o.length&&this._enableOptions(o.children("dd").find("input, select, textarea"),e)}}},_enableOption:function(e,t){this._enableOptionElement($("#"+$.wcfEscapeID(e)),t)},_enableOptionElement:function(e,t){e=$(e);var i=e.getTagName();if("select"==i||"input"==i&&("checkbox"==e.attr("type")||"file"==e.attr("type")||"radio"==e.attr("type"))){if("input"===i&&"radio"===e[0].type?e[0].checked||(t?e.enable():e.disable()):t?e.enable():e.disable(),e.parents(".optionTypeBoolean:eq(0)")){var n=e.wcfIdentify().replace(/\./g,"\\."),s=$("#"+n+"_no");t?s.enable():s.disable();var a=$("#"+n+"_never");a.length&&(t?a.enable():a.disable())}}else t?e.removeAttr("readonly"):e.attr("readonly",!0);t?e.closest("dl").removeClass("disabled"):e.closest("dl").addClass("disabled")},_enableOptions:function(e,t){for(var i=0,n=e.length;i<n;i++)this._enableOptionElement(e[i],t)}}),WCF.PageVisibilityHandler={_callbacks:new WCF.Dictionary,_isListening:!1,_hiddenFieldName:"",addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.PageVisibilityHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){if(!this._isListening){var e=null;void 0!==document.hidden?(this._hiddenFieldName="hidden",e="visibilitychange"):void 0!==document.mozHidden?(this._hiddenFieldName="mozHidden",e="mozvisibilitychange"):void 0!==document.msHidden?(this._hiddenFieldName="msHidden",e="msvisibilitychange"):void 0!==document.webkitHidden&&(this._hiddenFieldName="webkitHidden",e="webkitvisibilitychange"),null===e?console.debug("[WCF.PageVisibilityHandler] This browser does not support the page visibility API."):$(document).on(e,$.proxy(this._executeCallbacks,this)),this._isListening=!0}},_executeCallbacks:function(e){if(!this._isExecuting){this._isExecuting=!0;var t=document[this._hiddenFieldName];this._callbacks.each(function(e){e.value(t)}),this._isExecuting=!1}}},WCF.Table={},WCF.Table.EmptyTableHandler=Class.extend({_options:{},_rowClassName:"",init:function(e,t,i){this._rowClassName=t,this._tableContainer=e,this._options=$.extend(!0,{emptyMessage:null,emptyMessageHtml:null,messageType:"info",refreshPage:!1,updatePageNumber:!1,isTable:0!==this._tableContainer.find("table").length},i||{}),WCF.DOMNodeRemovedHandler.addCallback("WCF.Table.EmptyTableHandler."+t,$.proxy(this._remove,this))},_getRowCount:function(){return this._tableContainer.find((this._options.isTable?"table tr.":".tabularList .")+this._rowClassName).length},_handleEmptyTable:function(){if(this._options.emptyMessage)this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).text(this._options.emptyMessage));else if(this._options.emptyMessageHtml)this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).html(this._options.emptyMessageHtml));else if(this._options.refreshPage)if(this._options.updatePageNumber){var e=window.location.href.match(/(\?|&)pageNo=(\d+)/g);if(e){var t=e[e.length-1].match(/\d+/g);this._options.updatePageNumber>0?t++:t--,window.location=window.location.href.replace(e[e.length-1],e[e.length-1][0]+"pageNo="+t)}}else window.location.reload();else this._tableContainer.remove()},_remove:function(e){if($.getLength(e)){var t=$(e.target);if(t.hasClass(this._rowClassName))if(this._options.isTable){var i=t.parents("tbody:eq(0)");1==i.children("tr").length&&this._handleEmptyTable()}else 1===this._getRowCount()&&this._handleEmptyTable()}else this._getRowCount()||this._handleEmptyTable()}}),WCF.Search={},WCF.Search.Base=Class.extend({_callback:null,_caretAt:-1,_className:"",_commaSeperated:!1,_delay:0,_excludedSearchValues:[],_itemCount:0,_itemIndex:-1,_lastValue:"",_list:null,_oldSearchString:[],_proxy:null,_searchInput:null,_triggerLength:3,_timer:null,init:function(e,t,i,n,s){return null===t||void 0===t||$.isFunction(t)?(this._callback=t||null,this._caretAt=-1,this._delay=0,this._excludedSearchValues=[],this._lastValue="",i&&(this._excludedSearchValues=i),this._searchInput=$(e),this._searchInput.length?(this._searchInput.keydown($.proxy(this._keyDown,this)).keyup($.proxy(this._keyUp,this)).wrap('<span class="dropdown" />'),$.browser.mozilla&&$.browser.touch&&this._searchInput.on("input",$.proxy(this._keyUp,this)),this._list=$('<ul class="dropdownMenu" />').insertAfter(this._searchInput),this._commaSeperated=!!n,this._oldSearchString=[],this._itemCount=0,this._itemIndex=-1,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!0===s,success:$.proxy(this._success,this),autoAbortPrevious:!0}),this._searchInput.is("input")&&this._searchInput.attr("autocomplete","off"),this._searchInput.blur($.proxy(this._blur,this)),void WCF.Dropdown.initDropdownFragment(this._searchInput.parent(),this._list)):void console.debug("[WCF.Search.Base] Selector '"+e+"' for search input is invalid, aborting.")):void console.debug("[WCF.Search.Base] The given callback is invalid, aborting.")},_blur:function(){var e=this;new WCF.PeriodicalExecuter(function(t){e._list.is(":visible")&&e._clearList(!1),t.stop()},250)},_keyDown:function(e){if(e.which===$.ui.keyCode.ENTER){var t=this._searchInput.parents(".dropdown");t.data("disableAutoFocus")?-1!==this._itemIndex&&e.preventDefault():(t.data("preventSubmit")||-1!==this._itemIndex)&&e.preventDefault()}},_keyUp:function(e){switch(e.which){case 37:case 39:return;case 38:return void this._selectPreviousItem();case 40:return void this._selectNextItem();case 13:return this._selectElement(e)}var t=this._getSearchString(e);if(""===t)this._clearList(!1);else if(t.length>=this._triggerLength){if(this._lastValue===t)return;this._lastValue=t;var i={data:{excludedSearchValues:this._excludedSearchValues,searchString:t}};if(this._delay){null!==this._timer&&this._timer.stop();var n=this;this._timer=new WCF.PeriodicalExecuter(function(){n._queryServer(i),n._timer.stop(),n._timer=null},this._delay)}else this._queryServer(i)}else this._clearList(!1)},_queryServer:function(e){this._searchInput.parents(".searchBar").addClass("loading"),this._proxy.setOption("data",{actionName:"getSearchResultList",className:this._className,interfaceName:"wcf\\data\\ISearchAction",parameters:this._getParameters(e)}),this._proxy.sendRequest()},setDelay:function(e){this._delay=e},_selectNextItem:function(){0!==this._itemCount&&(this._itemIndex++,this._itemIndex===this._itemCount&&(this._itemIndex=0),this._highlightSelectedElement())},_selectPreviousItem:function(){0!==this._itemCount&&(this._itemIndex--,-1===this._itemIndex&&(this._itemIndex=this._itemCount-1),this._highlightSelectedElement())},_highlightSelectedElement:function(){this._list.find("li").removeClass("dropdownNavigationItem"),this._list.find("li:eq("+this._itemIndex+")").addClass("dropdownNavigationItem")},_selectElement:function(e){return 0===this._itemCount||(this._list.find("li.dropdownNavigationItem").trigger("click"),!1)},_getSearchString:function(e){var t=$.trim(this._searchInput.val());if(this._commaSeperated){if((e.keyCode||e.which)==$.ui.keyCode.COMMA)return"";for(var i=t.split(","),n=i.length,s=0;s<n;s++)i[s]=$.trim(i[s]);for(var s=0;s<n;s++){var a=i[s];if(!this._oldSearchString[s]){t=a;break}if(a!=this._oldSearchString[s]){t=a,this._caretAt=s;break}}this._oldSearchString=i}return t},_getParameters:function(e){return e},_success:function(e,t,i){if(this._clearList(!1),this._searchInput.parents(".searchBar").removeClass("loading"),$.getLength(e.returnValues))for(var n in e.returnValues){var s=e.returnValues[n];this._createListItem(s)}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var a=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(a).hasClass("dropdownOpen")||(WCF.Dropdown.toggleDropdown(a,!0),this._openDropdown()),this._itemIndex=-1,WCF.Dropdown.getDropdown(a).data("disableAutoFocus")||this._selectNextItem()},_openDropdown:function(){},_handleEmptyResult:function(){return!1},_createListItem:function(e){var t=$("<li><span>"+WCF.String.escapeHTML(e.label)+"</span></li>").appendTo(this._list);return t.data("objectID",e.objectID).data("label",e.label).click($.proxy(this._executeCallback,this)),this._itemCount++,t},_executeCallback:function(e){var t=!1,i=$(e.currentTarget);if(this._commaSeperated){var n=i.data("label");this._oldSearchString[this._caretAt]=n,this._searchInput.val(this._oldSearchString.join(", ")),$.browser.webkit&&this._searchInput.css({display:"block"});var s=this._searchInput.val().toLowerCase().indexOf(n.toLowerCase())+n.length;this._searchInput.focus().setCaret(s)}else null===this._callback?this._searchInput.val(i.data("label")):t=!0===this._callback(i.data());this._clearList(t)},_clearList:function(e){e&&!this._commaSeperated&&this._searchInput.val(""),WCF.Dropdown.getDropdown(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),this._list.end().empty(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1},addExcludedSearchValue:function(e){WCF.inArray(e,this._excludedSearchValues)||this._excludedSearchValues.push(e)},removeExcludedSearchValue:function(e){var t=$.inArray(e,this._excludedSearchValues);-1!=t&&this._excludedSearchValues.splice(t,1)}}),WCF.Search.User=WCF.Search.Base.extend({_className:"wcf\\data\\user\\UserAction",_includeUserGroups:!1,init:function(e,t,i,n,s){this._includeUserGroups=i,this._super(e,t,n,s)},_getParameters:function(e){return e.data.includeUserGroups=this._includeUserGroups?1:0,e},_createListItem:function(e){var t=this._super(e),i=null;if(e.icon?i=$(e.icon):this._includeUserGroups&&"group"===e.type&&(i=$('<span class="icon icon16 fa-users" />')),i){var n=t.find("span").detach(),s=$("<div />").addClass("box16").appendTo(t);s.append(i),s.append($("<div />").append(n))}return t.data("type",e.type),t}}),WCF.System={},WCF.System.Dependency={},WCF.System.Dependency.Manager={_callbacks:{},_loaded:[],_setupCallbacks:{},register:function(e,t){if(!$.isFunction(t))return void console.debug("[WCF.System.Dependency.Manager] Callback for identifier '"+e+"' is invalid, aborting.");WCF.inArray(e,this._loaded)?setTimeout(function(){t()},1):(this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t))},setup:function(e,t){if(!$.isFunction(t))return void console.debug("[WCF.System.Dependency.Manager] Setup callback for identifier '"+e+"' is invalid, aborting.");this._setupCallbacks[e]||(this._setupCallbacks[e]=[]),this._setupCallbacks[e].push(t)},invoke:function(e){if(this._setupCallbacks[e]){for(var t=0,i=this._setupCallbacks[e].length;t<i;t++)this._setupCallbacks[e][t]();delete this._setupCallbacks[e]}if(this._loaded.push(e),this._callbacks[e]){for(var t=0,i=this._callbacks[e].length;t<i;t++)this._callbacks[e][t]();delete this._callbacks[e]}},reset:function(e){var t=this._loaded.indexOf(e);-1!==t&&this._loaded.splice(t,1)}},WCF.System.FlexibleMenu={init:function(){},registerMenu:function(e){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(t){t.register(e)})},rebuild:function(e){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(t){t.rebuild(e)})}},WCF.System.Mobile={},WCF.System.ObjectStore={_objects:{},add:function(e,t){void 0===this._objects[e]&&(this._objects[e]=[]),this._objects[e].push(t)},invoke:function(e,t){if(this._objects[e])for(var i=0;i<this._objects[e].length;i++)t(this._objects[e][i])}},WCF.System.Captcha={_registeredCaptchas:[],addCallback:function(e,t){require(["WoltLabSuite/Core/Controller/Captcha"],function(i){try{i.add(e,t),this._registeredCaptchas.push(e)}catch(e){if(e instanceof TypeError)return void console.debug("[WCF.System.Captcha] Given callback is no function")}}.bind(this))},getData:function(e){var t;if(-1===this._registeredCaptchas.indexOf(e))return t;var i=require("WoltLabSuite/Core/Controller/Captcha");try{t=i.getData(e)}catch(t){console.debug('[WCF.System.Captcha] Unknow captcha id "'+e+'"')}return t},removeCallback:function(e){require(["WoltLabSuite/Core/Controller/Captcha"],function(t){try{t.delete(e),this._registeredCaptchas.splice(this._registeredCaptchas.indexOf(item),1)}catch(e){}}.bind(this))}},WCF.System.Page={},WCF.System.Notification=Class.extend({_cssClassNames:"",_message:"",init:function(e,t){this._cssClassNames=t||"",this._message=e||""},show:function(e,t,i,n){require(["Ui/Notification"],function(t){t.show(i||this._message,e,n||this._cssClassNames)}.bind(this))}}),WCF.System.Confirmation={show:function(e,t,i,n,s){if("object"==typeof n){var a=$("<div />");a.append(n),n=a.html()}require(["Ui/Confirmation"],function(a){a.show({legacyCallback:t,message:e,parameters:i,template:n||"",messageIsHtml:!0===s})})}},WCF.System.DisableScrolling={_depth:0,_oldOverflow:null,disable:function(){$.browser.touch||(0===this._depth&&(this._oldOverflow=$(document.body).css("overflow"),$(document.body).css("overflow","hidden")),this._depth++)},enable:function(){0!==this._depth&&0===--this._depth&&$(document.body).css("overflow",this._oldOverflow)}},WCF.System.DisableZoom={_depth:0,_oldViewportSettings:null,disable:function(){if(0===this._depth){var e=$("meta[name=viewport]");this._oldViewportSettings=e.attr("content"),e.attr("content",this._oldViewportSettings+",maximum-scale=1")}this._depth++},enable:function(){0!==this._depth&&0===--this._depth&&$("meta[name=viewport]").attr("content",this._oldViewportSettings)}},WCF.System.Fullscreen={enterFullscreen:function(e){e.requestFullscreen?e.requestFullscreen():e.msRequestFullscreen?e.msRequestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)},toggleFullscreen:function(e){null===this.getFullscreenElement()?this.enterFullscreen(e):this.exitFullscreen()},getFullscreenElement:function(){return document.fullscreenElement?document.fullscreenElement:document.mozFullScreenElement?document.mozFullScreenElement:document.webkitFullscreenElement?document.webkitFullscreenElement:document.msFullscreenElement?document.msFullscreenElement:null},exitFullscreen:function(){document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen()},isSupported:function(){return!!(document.documentElement.requestFullscreen||document.documentElement.msRequestFullscreen||document.documentElement.mozRequestFullScreen||document.documentElement.webkitRequestFullscreen)}},WCF.System.PageNavigation={init:function(e,t){require(["WoltLabSuite/Core/Ui/Page/JumpTo"],function(i){for(var n=elBySelAll(e),s=0,a=n.length;s<a;s++)i.init(n[s],t)})}},WCF.System.KeepAlive=Class.extend({init:function(e){new WCF.PeriodicalExecuter(function(e){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"keepAlive",className:"wcf\\data\\session\\SessionAction"},failure:function(){e.stop()},showLoadingOverlay:!1,success:function(e){WCF.System.PushNotification.executeCallbacks(e)},suppressErrors:!0})},1e3*e)}}),WCF.System.PushNotification={_callbacks:{},addCallback:function(e,t){void 0===this._callbacks[e]&&(this._callbacks[e]=[]),this._callbacks[e].push(t)},executeCallbacks:function(e){for(var t in e.returnValues)if(void 0!==this._callbacks[t])for(var i=0;i<this._callbacks[t].length;i++)this._callbacks[t][i](e.returnValues[t])}},WCF.System.Event={addListener:function(e,t,i){return window.__wcf_bc_eventHandler.add(e,t,i)},removeListener:function(e,t,i){return window.__wcf_bc_eventHandler.remove(e,t,i)},removeAllListeners:function(e,t){return window.__wcf_bc_eventHandler.removeAll(e,t)},fireEvent:function(e,t,i){window.__wcf_bc_eventHandler.fire(e,t,i)}},WCF.System.Worker=Class.extend({_aborted:!1,_actionName:"",_callback:null,_className:"",_dialog:null,_proxy:null,_title:"",init:function(e,t,i,n,s){this._aborted=!1,this._actionName=e,this._callback=s||null,this._className=t,this._dialog=null,this._proxy=new WCF.Action.Proxy({autoSend:!0,data:{actionName:this._actionName,className:this._className,parameters:n||{}},showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._title=i},_success:function(e){if(null===this._dialog&&(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.wcfDialog({closeConfirmMessage:WCF.Language.get("wcf.worker.abort.confirmMessage"),closeViaModal:!1,onClose:$.proxy(function(){this._aborted=!0,this._proxy.abortPrevious(),window.location.reload()},this),title:this._title})),!this._aborted)if(e.returnValues.template&&this._dialog.html(e.returnValues.template),this._dialog.find("progress").attr("value",e.returnValues.progress).text(e.returnValues.progress+"%").next("span").text(e.returnValues.progress+"%"),e.returnValues.progress<100){var t=e.returnValues.parameters||{};t.loopCount=e.returnValues.loopCount,this._proxy.setOption("data",{actionName:this._actionName,className:this._className,parameters:t}),this._proxy.sendRequest()}else if(null!==this._callback)this._callback(this,e);else{this._dialog.find(".fa-spinner").removeClass("fa-spinner").addClass("fa-check green"),this._dialog.find(".contentHeader h1").text(WCF.Language.get("wcf.global.worker.completed"));var i=$('<div class="formSubmit" />').appendTo(this._dialog);$('<button class="buttonPrimary">'+WCF.Language.get("wcf.global.button.next")+"</button>").appendTo(i).focus().click(function(){e.returnValues.redirectURL?window.location=e.returnValues.redirectURL:window.location.reload()}),this._dialog.wcfDialog("render")}}}),WCF.InlineEditor=Class.extend({_callbacks:[],_dropdowns:{},_elements:{},_notification:null,_options:[],_proxy:null,_triggerElements:{},_updateData:[],_elementSelector:null,_quickOption:null,init:function(e){if(this._elementSelector=e,$(e).length){this._setOptions();for(var t=0,i=this._options.length;t<i;t++)if(this._options[t].isQuickOption){this._quickOption=this._options[t].optionName;break}this.rebuild(),WCF.DOMNodeInsertedHandler.addCallback("WCF.InlineEditor"+this._elementSelector.hashCode(),$.proxy(this.rebuild,this)),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),WCF.CloseOverlayHandler.addCallback("WCF.InlineEditor",$.proxy(this._closeAll,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success"),"success")}},rebuild:function(){var e=$(this._elementSelector),t=this;e.each(function(e,i){var n=$(i),s=n.wcfIdentify();if(void 0===t._elements[s]){var a=t._getTriggerElement(n);if(null===a||1!==a.length)return;a.on(WCF_CLICK_EVENT,$.proxy(t._show,t)).data("elementID",s),t._quickOption&&a.disableSelection().data("optionName",t._quickOption).dblclick($.proxy(t._click,t)),t._elements[s]=n}})},_closeAll:function(){for(var e in this._elements)this._hide(e)},_setOptions:function(){this._options=[]},registerCallback:function(e){$.isFunction(e)&&this._callbacks.push(e)},_getTriggerElement:function(e){return null},_show:function(e){e.preventDefault();var t=$(e.currentTarget).data("elementID"),i=null;if(!this._dropdowns[t]){this._triggerElements[t]=i=this._getTriggerElement(this._elements[t]).addClass("dropdownToggle");var n=i[0].parentNode;n&&"LI"===n.nodeName&&1===n.childElementCount?n.classList.add("dropdown"):i.wrap('<span class="dropdown" />'),this._dropdowns[t]=$('<ul class="dropdownMenu" />').insertAfter(i)}this._dropdowns[t].empty();for(var s=!1,a="",o=0,r=this._options.length;o<r;o++){var l=this._options[o];if("divider"===l.optionName)""!==a&&"divider"!==a&&($('<li class="dropdownDivider" />').appendTo(this._dropdowns[t]),a=l.optionName);else if(this._validate(t,l.optionName)||this._validateCallbacks(t,l.optionName)){var c=$("<li><span>"+l.label+"</span></li>").appendTo(this._dropdowns[t]);c.data("elementID",t).data("optionName",l.optionName).data("isQuickOption",!!l.isQuickOption).click($.proxy(this._click,this)),s=!0,a=l.optionName}}if(s){var u=this._dropdowns[t].children().last();u.hasClass("dropdownDivider")&&u.remove();var h=null,d=0;if(this._dropdowns[t].children().each(function(e,t){var i=$(t);i.hasClass("dropdownDivider")||(i.data("isQuickOption")?h=i:d++)}),!d)return h.trigger("click"),this._triggerElements[t]&&WCF.Dropdown.close(this._triggerElements[t].parents(".dropdown").wcfIdentify()),!1}return null!==i&&WCF.Dropdown.initDropdown(i,e.originalEvent||e),!1},_validate:function(e,t){return!1},_validateCallbacks:function(e,t){var i=this._callbacks.length;if(i)for(var n=0;n<i;n++)if(this._callbacks[n].validate(this._elements[e],t))return!0;return!1},_success:function(e,t,i){this._updateData.length&&(this._updateState(e),this._updateData=[])},_updateState:function(e){},_click:function(e){var t=$(e.currentTarget),i=t.data("elementID"),n=t.data("optionName");this._execute(i,n)||this._executeCallback(i,n),this._hide(i)},_execute:function(e,t){return!1},_executeCallback:function(e,t){var i=this._callbacks.length;if(i)for(var n=0;n<i;n++)if(this._callbacks[n].execute(this._elements[e],t))return!0;return!1},_hide:function(e){this._dropdowns[e]&&this._dropdowns[e].empty().removeClass("dropdownOpen")}}),WCF.Upload=Class.extend({_name:"__files[]",_buttonSelector:null,_fileListSelector:null,_fileUpload:null,_className:"",_iframe:null,_internalFileID:0,_options:{},_uploadMatrix:[],_supportsAJAXUpload:!0,_overlay:null,init:function(e,t,i,n){this._buttonSelector=e,this._fileListSelector=t,this._className=i,this._internalFileID=0,this._options=$.extend(!0,{action:"upload",multiple:!1,url:"index.php?ajax-upload/&t="+SECURITY_TOKEN},n||{}),this._options.url=WCF.convertLegacyURL(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url);var s=new XMLHttpRequest;this._supportsAJAXUpload=s&&"upload"in s&&"onprogress"in s.upload,this._createButton()},_createButton:function(){if(this._supportsAJAXUpload){this._fileUpload=$('<input type="file" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/>"),this._fileUpload.change($.proxy(this._upload,this));var e=$('<p class="button uploadButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>");elAttr(e[0],"role","button"),e.prepend(this._fileUpload),this._fileUpload[0].addEventListener("focus",function(){this.classList.contains("focus-visible")&&e[0].classList.add("active")}),this._fileUpload[0].addEventListener("blur",function(){e[0].classList.remove("active")})}else{var e=$('<p class="button uploadFallbackButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>");elAttr(e[0],"role","button"),elAttr(e[0],"tabindex","0"),e.click($.proxy(this._showOverlay,this))}this._insertButton(e)},_insertButton:function(e){this._buttonSelector.prepend(e)},_removeButton:function(){var e=".uploadButton";this._supportsAJAXUpload||(e=".uploadFallbackButton"),this._buttonSelector.find(e).remove()},_upload:function(e,t,i,n){var s=null,a=[];if(void 0!==n)a=n;else if(t)a.push(t);else if(i){var o="";switch(i.type){case"image/png":o=".png";break;case"image/jpeg":o=".jpg";break;case"image/gif":o=".gif"}a.push({name:"pasted-from-clipboard"+o})}else a=this._fileUpload.prop("files");if(a.length){var r=new FormData;if(s=this._createUploadMatrix(a),!this._uploadMatrix[s].length)return null;for(var l=0,c=a.length;l<c;l++)if(this._uploadMatrix[s][l]){var u=this._uploadMatrix[s][l].data("internalFileID");i?r.append("__files["+u+"]",i,a[l].name):r.append("__files["+u+"]",a[l],a[l].name)}r.append("actionName",this._options.action),r.append("className",this._className);var h=this._getParameters();for(var d in h)r.append("parameters["+d+"]",h[d]);var p=this;$.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:r,contentType:!1,processData:!1,success:function(e,t,i){p._success(s,e)},error:$.proxy(this._error,this),xhr:function(){var e=$.ajaxSettings.xhr();return e&&e.upload.addEventListener("progress",function(e){p._progress(s,e)},!1),e},xhrFields:{withCredentials:!0}})}return s},_createUploadMatrix:function(e){if(e.length){var t=this._uploadMatrix.length;this._uploadMatrix[t]=[];for(var i=0,n=e.length;i<n;i++){var s=e[i],a=this._initFile(s);a.hasClass("uploadFailed")||(a.data("filename",s.name).data("internalFileID",this._internalFileID++),this._uploadMatrix[t][i]=a)}return t}return null},_success:function(e,t){},_error:function(e,t,i){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);for(var n in this._uploadMatrix[e])this._uploadMatrix[e][n].find("progress").attr("value",i)},_getParameters:function(){return{}},_initFile:function(e){return $("<li>"+e.name+" ("+e.size+')<progress max="100" /></li>').appendTo(this._fileListSelector)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix([e]),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)},_getFilename:function(){return $("#__fileUpload").val().split("\\").pop()}}),WCF.Upload.Parallel=WCF.Upload.extend({init:function(e,t,i,n){n=$.extend(!0,n||{},{multiple:!0}),this._super(e,t,i,n)},_upload:function(){for(var e=this._fileUpload.prop("files"),t=0,i=e.length;t<i;t++){var n=e[t],s=new FormData,a=this._createUploadMatrix(n);if(this._uploadMatrix[a].length){s.append("__files["+a+"]",n),s.append("actionName",this._options.action),s.append("className",this._className);var o=this._getParameters();for(var r in o)s.append("parameters["+r+"]",o[r]);this._sendRequest(a,s)}}},_sendRequest:function(e,t){var i=this;return $.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:t,contentType:!1,processData:!1,success:function(t,n,s){i._success(e,t)},error:$.proxy(this._error,this),xhr:function(){var t=$.ajaxSettings.xhr();return t&&t.upload.addEventListener("progress",function(t){i._progress(e,t)},!1),t}})},_createUploadMatrix:function(e){var t=this._initFile(e);return t.hasClass("uploadFailed")?null:(t.data("filename",e.name).data("internalFileID",this._internalFileID),this._uploadMatrix[this._internalFileID++]=t,this._internalFileID-1)},_success:function(e,t){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);this._uploadMatrix[e].find("progress").attr("value",i)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix(e),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){
-var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)}}),WCF.Sortable={},WCF.Sortable.List=Class.extend({_additionalParameters:{},_className:"",_containerID:"",_container:null,_notification:null,_offset:0,_options:{},_proxy:null,_structure:{},init:function(e,t,i,n,s,a){this._additionalParameters=a||{},this._containerID=$.wcfEscapeID(e),this._container=$("#"+this._containerID),this._className=t,this._offset=i||0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._structure={},this._options=$.extend(!0,{axis:"y",connectWith:"#"+this._containerID+" .sortableList",disableNesting:"sortableNoNesting",doNotClear:!0,errorClass:"sortableInvalidTarget",forcePlaceholderSize:!0,handle:"",helper:"clone",items:"li:not(.sortableNoSorting)",opacity:.6,placeholder:"sortablePlaceholder",tolerance:"pointer",toleranceElement:"> span"},n||{});var o=$("#"+this._containerID+" .sortableList");if(o.is("tbody")&&("li:not(.sortableNoSorting)"===this._options.items&&(this._options.items="tr:not(.sortableNoSorting)",this._options.toleranceElement=""),"clone"===this._options.helper)){this._options.helper=this._tableRowHelper.bind(this);var r=o.prev("thead");r&&r.find("th").each(function(e,t){t=$(t),t.width(t.width())})}if(s?o.sortable(this._options):o.nestedSortable(this._options),this._className){var l=this._container.find(".formSubmit");if(!l.length&&(l=this._container.next(".formSubmit"),!l.length))return void console.debug("[WCF.Sortable.Simple] Unable to find form submit for saving, aborting.");l.children('button[data-type="submit"]').click($.proxy(this._submit,this))}},_tableRowHelper:function(e,t){return t.children("td").each(function(e,t){t=$(t),t.width(t.width())}),t},_submit:function(){this._structure={},this._container.find(".sortableList").each($.proxy(function(e,t){var i=$(t),n=i.data("objectID");void 0!==n&&i.children(this._options.items).each($.proxy(function(e,t){var i=$(t).data("objectID");this._structure[n]||(this._structure[n]=[]),this._structure[n].push(i)},this))},this));var e=$.extend(!0,{data:{offset:this._offset,structure:this._structure}},this._additionalParameters);this._proxy.setOption("data",{actionName:"updatePosition",className:this._className,interfaceName:"wcf\\data\\ISortableAction",parameters:e}),this._proxy.sendRequest()},_success:function(e,t,i){null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit"))),this._notification.show()}}),WCF.Popover=Class.extend({_activeElementID:"",_identifier:"",_popoverObj:null,init:function(e){var t=!1;require(["Environment"],function(e){"desktop"!==e.platform()&&(t=!0)}.bind(this)),t||(this._activeElementID="",this._identifier=e,require(["WoltLabSuite/Core/Controller/Popover"],function(t){t.init({attributeName:"legacy",className:e,identifier:this._identifier,legacy:!0,loadCallback:this._legacyLoad.bind(this)})}.bind(this)))},_initContainers:function(){},_legacyLoad:function(e,t){this._activeElementID=e,this._popoverObj=t,this._loadContent()},_insertContent:function(e,t){this._popoverObj.setContent(this._identifier,e,t)}}),WCF.EditableItemList=Class.extend({_allowCustomInput:!1,_className:"",_data:{},_form:null,_itemList:null,_objectID:0,_objectTypeID:0,_search:null,_searchInput:null,init:function(e,t){if(this._itemList=$(e),this._searchInput=$(t),this._data={},!this._itemList.length||!this._searchInput.length)return void console.debug("[WCF.EditableItemList] Item list and/or search input do not exist, aborting.");if(this._objectID=this._getObjectID(),this._objectTypeID=this._getObjectTypeID(),this._itemList.find(".jsEditableItem").click($.proxy(this._click,this)),this._itemList.children("ul").length||$("<ul />").appendTo(this._itemList),this._itemList=this._itemList.children("ul"),this._form=this._itemList.parents("form").submit($.proxy(this._submit,this)),this._allowCustomInput){var i=this;this._searchInput.keydown($.proxy(this._keyDown,this)).keypress($.proxy(this._keyPress,this)).on("paste",function(){setTimeout(function(){i._onPaste()},100)})}this._searchInput.parents(".dropdown").data("preventSubmit",!0)},_keyDown:function(e){return null!==e||this._keyPress(null)},_keyPress:function(e){if(null===e||44===e.charCode||e.charCode===$.ui.keyCode.ENTER||$.browser.mozilla&&e.keyCode===$.ui.keyCode.ENTER){if(null!==e&&e.charCode===$.ui.keyCode.ENTER&&this._search&&-1!==this._search._itemIndex)return!1;var t=$.trim(this._searchInput.val());return e&&44===e.charCode&&(t=t.substring(0,this._searchInput.getCaret())),""===t?!0:(this.addItem({objectID:0,label:t}),e&&44===e.charCode?this._searchInput.val($.trim(this._searchInput.val().substr(this._searchInput.getCaret()))):this._searchInput.val(""),null!==e&&e.stopPropagation(),!1)}return!0},_onPaste:function(){var e=$.trim(this._searchInput.val());e=e.split(",");for(var t=0,i=e.length;t<i;t++){var n=$.trim(e[t]);""!==n&&this.addItem({objectID:0,label:n})}this._searchInput.val("")},load:function(e){},_click:function(e){var t=$(e.currentTarget),i=t.data("objectID"),n=t.data("label");return this._search&&this._search.removeExcludedSearchValue(n),this._removeItem(i,n),t.remove(),e.stopPropagation(),!1},_getObjectID:function(){return 0},_getObjectTypeID:function(){return 0},addItem:function(e){return!(!this._data[e.objectID]||0===e.objectID&&this._allowCustomInput)||($('<li class="badge">'+WCF.String.escapeHTML(e.label)+"</li>").data("objectID",e.objectID).data("label",e.label).appendTo(this._itemList).click($.proxy(this._click,this)),this._search&&this._search.addExcludedSearchValue(e.label),this._addItem(e.objectID,e.label),!0)},clearList:function(){this._itemList.children("li").each($.proxy(function(e,t){var i=$(t);this._search&&this._search.removeExcludedSearchValue(i.data("label")),i.remove(),this._removeItem(i.data("objectID"),i.data("label"))},this))},_submit:function(){this._keyDown(null)},_addItem:function(e,t){this._data[e]=t},_removeItem:function(e,t){delete this._data[e]},getSearchInput:function(){return this._searchInput}}),WCF.Language.Chooser=Class.extend({init:function(e,t,i,n,s,a){require(["WoltLabSuite/Core/Language/Chooser"],function(o){o.init(e,t,i,n,s,a)})}}),WCF.Style={},WCF.UserPanel=Class.extend({_container:null,_didLoad:!1,_link:null,_noItems:"",_revertOnEmpty:!0,init:function(e){if(this._container=$("#"+e),this._didLoad=!1,this._revertOnEmpty=!0,1!=this._container.length)return void console.debug("[WCF.UserPanel] Unable to find container identified by '"+e+"', aborting.");this._convert()},_convert:function(){this._container.addClass("dropdown"),this._link=this._container.children("a").remove();var e=$('<a href="'+this._link.attr("href")+'" class="dropdownToggle">'+this._link.html()+"</a>").appendTo(this._container).click($.proxy(this._click,this)),t=$('<ul class="dropdownMenu" />').appendTo(this._container);$('<li class="jsDropdownPlaceholder"><span>'+WCF.Language.get("wcf.global.loading")+"</span></li>").appendTo(t),this._addDefaultItems(t),this._container.dblclick($.proxy(function(){return window.location=this._link.attr("href"),!1},this)),WCF.Dropdown.initDropdown(e,!1)},_addDefaultItems:function(e){},_addDivider:function(e){$('<li class="dropdownDivider" />').appendTo(e)},_click:function(e){e.preventDefault(),this._didLoad||(new WCF.Action.Proxy({autoSend:!0,data:this._getParameters(),success:$.proxy(this._success,this)}),this._didLoad=!0)},_getParameters:function(){return{}},_success:function(e,t,i){var n=WCF.Dropdown.getDropdownMenu(this._container.wcfIdentify());n.children(".jsDropdownPlaceholder").remove(),e.returnValues&&e.returnValues.template?($(""+e.returnValues.template).prependTo(n),this._updateBadge(e.returnValues.totalCount),this._after(n)):($("<li><span>"+WCF.Language.get(this._noItems)+"</span></li>").prependTo(n),this._updateBadge(0))},_updateBadge:function(e){if(e=parseInt(e)||0){var t=this._container.find(".badge");t.length||(t=$('<span class="badge badgeUpdate" />').appendTo(this._container.children(".dropdownToggle")),t.before(" ")),t.html(e)}else this._container.find(".badge").remove()},_after:function(e){}}),jQuery.fn.extend({wcfDialog:function(e){var t=arguments;return require(["Dom/Util","Ui/Dialog"],function(i,n){var s=i.identify(this[0]);if("close"===e)n.close(s);else if("render"===e)n.rebuild(s);else if("option"===e)3===t.length&&("title"===t[1]&&"string"==typeof t[2]?n.setTitle(s,t[2]):0===t[1].indexOf("on")?n.setCallback(s,t[1],t[2]):"closeConfirmMessage"===t[1]&&null===t[2]&&n.setCallback(s,"onBeforeClose",null));else{this[0].parentNode.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&document.body.appendChild(this[0]);var a=1===t.length&&"object"==typeof t[0]?t[0]:{};n.openStatic(s,null,a),a.hasOwnProperty("title")&&n.setTitle(s,a.title)}}.bind(this)),this}}),$.widget("ui.wcfSlideshow",{_buttonList:null,_count:0,_index:0,_itemList:null,_items:null,_timer:null,_width:0,options:{cycle:!0,cycleInterval:5,itemGap:50},_create:function(){this._itemList=this.element.children("ul"),this._items=this._itemList.children("li"),this._count=this._items.length,this._index=0,this._count>1&&this._initSlideshow()},_initSlideshow:function(){var e=$(this._items.get(0)).outerHeight();this._items.addClass("slideshowItem"),this._width=this.element.css("height",e).innerWidth(),this._itemList.addClass("slideshowItemList").css("left",0),this._items.each($.proxy(function(t,i){$(i).show().css({height:e,left:(this._width+this.options.itemGap)*t,width:this._width})},this)),this.element.css({height:e,width:this._width}).hover($.proxy(this._hoverIn,this),$.proxy(this._hoverOut,this)),this._buttonList=$('<ul class="slideshowButtonList" />').appendTo(this.element);for(var t=0;t<this._count;t++){var i=$('<li><a><span class="icon icon16 fa-circle" /></a></li>').data("index",t).click($.proxy(this._click,this)).appendTo(this._buttonList);0==t&&i.find(".icon").addClass("active")}this._resetTimer(),$(window).resize($.proxy(this._resize,this))},rebuildHeight:function(){var e=$(this._items.get(0)).css("height","auto"),t=e.outerHeight();this._items.css("height",t+"px"),this.element.css("height",t+"px")},_resize:function(){this._width=this.element.css("width","auto").innerWidth(),this._items.each($.proxy(function(e,t){$(t).css({left:(this._width+this.options.itemGap)*e,width:this._width})},this)),this._index--,this.moveTo(null)},_hoverIn:function(){null!==this._timer&&this._timer.stop()},_hoverOut:function(){this._resetTimer()},_resetTimer:function(){if(this.options.cycle){null!==this._timer&&this._timer.stop();var e=this;this._timer=new WCF.PeriodicalExecuter(function(){e.moveTo(null)},1e3*this.options.cycleInterval)}},_click:function(e){this.moveTo($(e.currentTarget).data("index")),this._resetTimer()},moveTo:function(e){this._index=null===e?this._index+1:e,this._index==this._count&&(this._index=0),$(this._buttonList.find(".icon").removeClass("active").get(this._index)).addClass("active"),this._itemList.css("left",this._index*(this._width+this.options.itemGap)*-1),this._trigger("moveTo",null,{index:this._index})},getItem:function(e){return this._items[e]?this._items[e]:null}}),jQuery.fn.extend({datepicker:function(e){var t=this[0],i=Array.prototype.slice.call(arguments,1);switch(e){case"destroy":window.__wcf_bc_datePicker.destroy(t);break;case"getDate":return window.__wcf_bc_datePicker.getDate(t);case"option":if("onClose"===i[0])return i.length>1?this.datepicker("setOption","onClose",i[1]):function(){};console.warn("datepicker('option') supports only 'onClose'.");break;case"setDate":window.__wcf_bc_datePicker.setDate(t,i[0]);break;case"setOption":"onClose"===i[0]?window.__wcf_bc_datePicker.setCloseCallback(t,i[1]):console.warn("datepicker('setOption') supports only 'onClose'.");break;default:console.debug("Unsupported method '"+e+"' for datepicker()")}return this}}),jQuery.fn.extend({wcfTabs:function(e){var t=this[0],i=Array.prototype.slice.call(arguments,1);require(["Dom/Util","WoltLabSuite/Core/Ui/TabMenu"],function(n,s){var a=s.getTabMenu(n.identify(t));null!==a&&a[e].apply(a,i)})}}),$.widget("ui.wcfPages",{_api:null,SHOW_LINKS:11,SHOW_SUB_LINKS:20,options:{activePage:1,maxPage:1},_create:function(){require(["WoltLabSuite/Core/Ui/Pagination"],function(e){this._api=new e(this.element[0],{activePage:this.options.activePage,maxPage:this.options.maxPage,callbackShouldSwitch:function(e){return!1!==this._trigger("shouldSwitch",void 0,{nextPage:e})}.bind(this),callbackSwitch:function(e){this._trigger("switched",void 0,{activePage:e})}.bind(this)})}.bind(this))},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this._api=null,this.element[0].innerHTML=""},_setOption:function(e,t){if("activePage"==e&&t!=this.options[e]&&t>0&&t<=this.options.maxPage){var i=this._trigger("shouldSwitch",void 0,{nextPage:t});i||void 0!==i?this._api.switchPage(t):this._trigger("notSwitched",void 0,{activePage:t})}return this}}),WCF.Category={},WCF.Category.NestedList=Class.extend({_categories:{},init:function(){var e=this;$(".jsCategory").each(function(t,i){var n=$(i).data("parentCategoryID",null).change($.proxy(e._updateSelection,e));e._categories[n.val()]=n;var s=[];n.parents("li").find(".jsChildCategory").each(function(t,i){var a=$(i).data("parentCategoryID",n.val()).change($.proxy(e._updateSelection,e));e._categories[a.val()]=a,s.push(a.val()),a.is(":checked")&&n.prop("checked","checked")}),n.data("childCategoryIDs",s)})},_updateSelection:function(e){var t=$(e.currentTarget),i=t.data("parentCategoryID");if(t.is(":checked"))null!==i&&this._categories[i].prop("checked","checked");else if(null===i)for(var n=t.data("childCategoryIDs"),s=0,a=n.length;s<a;s++)this._categories[n[s]].prop("checked",!1)}}),WCF.Category.FlexibleCategoryList=Class.extend({_list:null,_categories:{},init:function(e){if(this._list=$("#"+e),this._buildStructure(),this._list.find("input:checked").each(function(){$(this).trigger("change")}),this._list.children("li").length<2)return void this._list.addClass("flexibleCategoryListDisabled")},_buildStructure:function(){var e=this;this._list.find(".jsCategory").each(function(t,i){var n=$(i).change(e._updateSelection.bind(e)),s=parseInt(n.val()),a=[];n.parents("li:eq(0)").find(".jsChildCategory").each(function(t,i){var s=$(i);s.data("parentCategory",n).change(e._updateSelection.bind(e));var o=parseInt(s.val());a.push(s);var r=[];s.parents("li:eq(0)").find(".jsSubChildCategory").each(function(t,i){var n=$(i);n.data("parentCategory",s).change(e._updateSelection.bind(e)),r.push(n)}),e._categories[o]=r}),e._categories[s]=a})},_updateSelection:function(e){var t=$(e.currentTarget),i=parseInt(t.val()),n=t.data("parentCategory");if(t.is(":checked"))n&&(n.prop("checked","checked"),(n=n.data("parentCategory"))&&n.prop("checked","checked"));else{if(this._categories[i])for(var s=0,a=this._categories[i].length;s<a;s++){var o=this._categories[i][s];o.prop("checked",!1);var r=parseInt(o.val());if(this._categories[r])for(var l=0,c=this._categories[r].length;l<c;l++)this._categories[r][l].prop("checked",!1)}if(n){for(var u=parseInt(n.val()),s=0,a=this._categories[u].length;s<a;s++)if(this._categories[u][s].prop("checked"))return;if(n=n.data("parentCategory")){u=parseInt(n.val());for(var s=0,a=this._categories[u].length;s<a;s++)if(this._categories[u][s].prop("checked"))return}}}}}),WCF.Condition={},WCF.Notice={}; })(this);
+(function (window, undefined) { "use strict";function wcfEval(expression){return eval(expression)}!function(){var o=jQuery.fn.data;jQuery.fn.data=function(e,t){var i,n=[].slice.call(arguments);if(e)switch(typeof e){case"object":for(var s in e){s.match(/ID$/)&&(i=e[s],delete e[s],e[s=s.replace(/ID$/,"-id")]=i)}n[0]=e;break;case"string":e.match(/ID$/)&&(n[0]=e.replace(/ID$/,"-id"))}var a=o.apply(this,n);if(void 0===e)for(var s in a)s.match(/Id$/)&&(a[s.replace(/Id$/,"ID")]=a[s],delete a[s]);return a},window.console||(window.console={});for(var e=["log","info","warn","exception","assert","dir","dirxml","trace","group","groupEnd","groupCollapsed","profile","profileEnd","count","clear","time","timeEnd","timeStamp","table","error"],t=0;t<e.length;t++)void 0===console[e[t]]&&(console[e[t]]=function(){});void 0===console.debug&&(console.debug=function(e){console.log(e)})}(),window.shuffle=function(e){for(var t,i,n=e.length;0!==n;)i=Math.floor(Math.random()*n),t=e[--n],e[n]=e[i],e[i]=t;return this},function(e){var t=navigator.userAgent.toLowerCase(),i=/(chrome)[ \/]([\w.]+)/.exec(t)||/(webkit)[ \/]([\w.]+)/.exec(t)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(t)||/(msie) ([\w.]+)/.exec(t)||t.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(t)||[],n={browser:i[1]||"",version:i[2]||"0"},s={};n.browser&&(s[n.browser]=!0,s.version=n.version),s.chrome?s.webkit=!0:s.webkit&&(s.safari=!0),e.browser=e.browser||{},e.browser=$.extend(e.browser,s),e.browser.touch=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&0<window.navigator.msMaxTouchPoints,e.browser.smartphone="bottom"==$("html").css("caption-side"),e.browser.mozilla&&t.match(/trident/)&&(e.browser.mozilla=!1,e.browser.msie=!0),e.browser.iOS=/\((ipad|iphone|ipod);/.test(t),e.browser.iOS&&$("html").addClass("iOS"),e.browser.android=-1!==t.indexOf("android"),e.browser.editor="redactor",e.browser.ckeditor=!1,e.browser.redactor=!0,e.browser.iOS&&(e.fn.focus=function(e,t){return 0<arguments.length?this.on("focus",null,e,t):this.trigger("focus")})}(jQuery),null==window.WCF&&(window.WCF={}),$.extend(!0,{removeArrayValue:function(e,i){return $.grep(e,function(e,t){return i!==e})},wcfEscapeID:function(e){return e.replace(/(:|\.)/g,"\\$1")},wcfIsset:function(e){return!!$("#"+$.wcfEscapeID(e)).length},getLength:function(e){var t=0;for(var i in e)e.hasOwnProperty(i)&&t++;return t}}),$.fn.extend({getTagName:function(){return this.length?this.get(0).tagName.toLowerCase():""},getDimensions:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"inner":i={height:this.innerHeight(),width:this.innerWidth()};break;case"outer":i={height:this.outerHeight(),width:this.outerWidth()};break;default:i={height:this.height(),width:this.width()}}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},getOffsets:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"offset":i=this.offset();break;case"position":default:i=this.position()}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},makePositioned:function(e,t){"absolute"!=e&&"fixed"!=e&&(e="absolute");var i=this.getOffsets("position");return this.css({position:e,left:i.left,margin:0,top:i.top}),t&&this.remove().appentTo("body"),this},disable:function(){return this.attr("disabled","disabled")},enable:function(){return this.removeAttr("disabled")},wcfIdentify:function(){return window.bc_wcfDomUtil.identify(this[0])},getCaret:function(){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return-1}else if(!this.is("textarea"))return-1;var e,t=0,i=this.get(0);return document.selection?(this.focus(),(e=document.selection.createRange()).moveStart("character",-this.val().length),t=e.text.length):!i.selectionStart&&"0"!=i.selectionStart||(t=parseInt(i.selectionStart)),t},setCaret:function(e){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return!1}else if(!this.is("textarea"))return!1;var t,i=this.get(0);return this.focus(),document.selection?((t=document.selection.createRange()).moveStart("character",e),t.moveEnd("character",0),t.select()):!i.selectionStart&&"0"!=i.selectionStart||(i.selectionStart=e,i.selectionEnd=e),!0},wcfDropIn:function(e,t,i){return e=e||"up",i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfDropOut:function(e,t,i){return e=e||"down",i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfBlindIn:function(e,t,i){return e=e||"vertical",i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfBlindOut:function(e,t,i){return e=e||"vertical",i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfHighlight:function(e,t){return this.effect("highlight",e,600,t)},wcfFadeIn:function(e,t){return t&&parseInt(t)||(t=200),this.show(WCF.getEffect(this,"fade"),{},t,e)},wcfFadeOut:function(e,t){return t&&parseInt(t)||(t=200),this.hide(WCF.getEffect(this,"fade"),{},t,e)},cssAsNumber:function(e){if(this.length){var t=this.css(e);if(void 0!==t)return parseInt(t.replace(/px$/,""))}return 0},perfectScrollbar:function(i){var n=require("perfect-scrollbar");return this.each(function(){var e,t;return"object"==typeof i||void 0===i?(e=i,$(this).data("psID")||n.initialize(this,e)):"update"===(t=i)?n.update(this):"destroy"===t&&n.destroy(this),jQuery(this)})}}),$.extend(WCF,{activeDialogs:0,_idCounter:0,getRandomID:function(){return window.bc_wcfDomUtil.getUniqueId()},inArray:function(e,t){return-1!=$.inArray(e,t)},getEffect:function(e,t){return e.is("tr")?"highlight":t},getInlineCSS:function(e){var t={},i=e.attr("style");if(!i)return{};for(var n=0,s=(i=i.split(";")).length;n<s;n++){var a=$.trim(i[n]);""!=a&&(a=a.split(":"),t[$.trim(a[0])]=$.trim(a[1]))}return t},revertInlineCSS:function(e,t,i){for(var n=0,s=i.length;n<s;n++){var a=i[n];t[a]?e.css(a,t[a]):e.css(a,"")}},getUUID:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},base64toBlob:function(e,t,i){t=t||"",i=i||512;for(var n=atob(e),s=[],a=0;a<n.length;a+=i){for(var o=n.slice(a,a+i),r=new Array(o.length),l=0;l<o.length;l++)r[l]=o.charCodeAt(l);var c=new Uint8Array(r);s.push(c)}return new Blob(s,{type:t})},convertLegacyURL:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){for(var i=t.split(/([A-Z][a-z0-9]+)/),n="",s=0,a=i.length;s<a;s++){var o=i[s].trim();o.length&&(n.length&&(n+="-"),n+=o.toLowerCase())}return"index.php?"+n+"/&"})}}),WCF.Browser={_isChrome:null,isChrome:function(){return null===this._isChrome&&(this._isChrome=!1,/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&(this._isChrome=!0)),this._isChrome}},WCF.Dropdown={init:function(e){window.bc_wcfSimpleDropdown.initAll()},initDropdown:function(e,t){window.bc_wcfSimpleDropdown.init(e[0],t)},removeDropdown:function(e){window.bc_wcfSimpleDropdown.destroy(e)},initDropdownFragment:function(e,t){window.bc_wcfSimpleDropdown.initFragment(e[0],t[0])},registerCallback:function(e,t){window.bc_wcfSimpleDropdown.registerCallback(e,t)},_toggle:function(e,t){window.bc_wcfSimpleDropdown._toggle(e,t)},toggleDropdown:function(e,t){window.bc_wcfSimpleDropdown._toggle(null,e,null,t)},getDropdown:function(e){var t=window.bc_wcfSimpleDropdown.getDropdown(e);return t?$(t):null},getDropdownMenu:function(e){var t=window.bc_wcfSimpleDropdown.getDropdownMenu(e);return t?$(t):null},setAlignmentByID:function(e){window.bc_wcfSimpleDropdown.setAlignmentById(e)},setAlignment:function(e,t){window.bc_wcfSimpleDropdown.setAlignment(e[0],t[0])},_closeAll:function(){window.bc_wcfSimpleDropdown.closeAll()},close:function(e){window.bc_wcfSimpleDropdown.close(e)},destroy:function(e){window.bc_wcfSimpleDropdown.destroy(e)}},WCF.Dropdown.Interactive={},WCF.Dropdown.Interactive.Handler={_dropdownContainer:null,_dropdownMenus:{},create:function(e,t,i){null===this._dropdownContainer&&(this._dropdownContainer=$('<div class="dropdownMenuContainer" />').appendTo(document.body),WCF.CloseOverlayHandler.addCallback("WCF.Dropdown.Interactive.Handler",$.proxy(this.closeAll,this)));var n=new WCF.Dropdown.Interactive.Instance(this._dropdownContainer,e,t,i);return this._dropdownMenus[t]=n},open:function(e){return!!this._dropdownMenus[e]&&(this._dropdownMenus[e].open(),!0)},close:function(e){return!!this._dropdownMenus[e]&&(this._dropdownMenus[e].close(),!0)},closeAll:function(){for(var e in this._dropdownMenus)this._dropdownMenus.hasOwnProperty(e)&&this._dropdownMenus[e].close()},getOpenDropdown:function(){for(var e in this._dropdownMenus)if(this._dropdownMenus.hasOwnProperty(e)&&this._dropdownMenus[e].isOpen())return this._dropdownMenus[e];return null},getDropdown:function(e){return this._dropdownMenus[e]}},WCF.Dropdown.Interactive.Instance=Class.extend({_container:null,_itemList:null,_linkList:null,_options:{},_pointer:null,_triggerElement:null,init:function(e,t,i,n){this._options=n||{},this._triggerElement=t;var s,a=null;!0===n.staticDropdown?this._container=this._triggerElement.find(".interactiveDropdownStatic:eq(0)").data("source",i).click(function(e){e.stopPropagation()}):(this._container=$('<div class="interactiveDropdown" data-source="'+i+'" />').click(function(e){e.stopPropagation()}),s=$('<div class="interactiveDropdownHeader" />').appendTo(this._container),$('<span class="interactiveDropdownTitle">'+n.title+"</span>").appendTo(s),this._linkList=$('<ul class="interactiveDropdownLinks inlineList"></ul>').appendTo(s),a=$('<div class="interactiveDropdownItemsContainer" />').appendTo(this._container),this._itemList=$('<ul class="interactiveDropdownItems" />').appendTo(a),$('<a href="'+n.showAllLink+'" class="interactiveDropdownShowAll">'+WCF.Language.get("wcf.user.panel.showAll")+"</a>").appendTo(this._container)),this._pointer=$('<span class="elementPointer"><span /></span>').appendTo(this._container),require(["Ui/Screen"],function(e){e.is("screen-lg")&&null!==a&&a.perfectScrollbar({suppressScrollX:!0})}.bind(this)),this._container.appendTo(e)},getContainer:function(){return this._container},getItemList:function(){return this._itemList},getLinkList:function(){return this._linkList},open:function(){WCF.Dropdown._closeAll(),this._triggerElement.addClass("open"),this._container.addClass("open"),WCF.System.Event.fireEvent("com.woltlab.wcf.Search","close"),this.render()},close:function(){this._triggerElement.removeClass("open"),this._container.removeClass("open"),WCF.System.Event.fireEvent("WCF.Dropdown.Interactive.Instance","close",{instance:this})},isOpen:function(){return this._triggerElement.hasClass("open")},toggle:function(){return this._container.hasClass("open")?(this.close(),!1):(WCF.Dropdown.Interactive.Handler.closeAll(),this.open(),!0)},resetItems:function(){this._itemList.empty(),this.close()},render:function(){require(["Ui/Alignment","Ui/Screen"],function(e,t){t.is("screen-lg")?e.set(this._container[0],this._triggerElement[0],{horizontal:"right",pointer:!0}):this._container.css({bottom:"",left:"",right:"",top:elById("pageHeaderPanel").clientHeight+"px"})}.bind(this))},rebuildScrollbar:function(){require(["Ui/Screen"],function(e){var t;e.is("screen-lg")&&((t=this._itemList.parent()).perfectScrollbar("destroy"),t.perfectScrollbar({suppressScrollX:!0}))}.bind(this))}}),WCF.Clipboard={init:function(n,s,a,o){require(["EventHandler","WoltLabSuite/Core/Controller/Clipboard"],function(e,t){for(var i in t.setup({hasMarkedItems:0<s,pageClassName:n,pageObjectId:o}),a)a.hasOwnProperty(i)&&function(t){e.add("com.woltlab.wcf.clipboard",t,function(e){null!==e.responseData&&a[t].hasOwnProperty(e.responseData.actionName)&&a[t][e.responseData.actionName].triggerEffect(e.responseData.objectIDs)})}(i)})},reload:function(){require(["WoltLabSuite/Core/Controller/Clipboard"],function(e){e.reload()})}},WCF.PeriodicalExecuter=Class.extend({_callback:null,_delay:0,_intervalID:null,_isExecuting:!1,init:function(e,t){$.isFunction(e)?(this._callback=e,this._interval=t,this.resume()):console.debug("[WCF.PeriodicalExecuter] Given callback is invalid, aborting.")},_execute:function(){if(!this._isExecuting)try{this._isExecuting=!0,this._callback(this),this._isExecuting=!1}catch(e){throw this._isExecuting=!1,e}},stop:function(){this._intervalID&&clearInterval(this._intervalID)},resume:function(){this.restart()},restart:function(){this._intervalID&&this.stop(),this._intervalID=setInterval($.proxy(this._execute,this),this._interval)},setInterval:function(e){this._interval=e,this.restart()}}),WCF.LoadingOverlayHandler={show:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.show()})},hide:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.hide()})},updateIcon:function(e,t){var i=void 0===t||t?"addClass":"removeClass";e.find(".icon")[i]("fa-spinner"),e.hasClass("icon")&&e[i]("fa-spinner")}},WCF.Action={},WCF.Action.Proxy=Class.extend({_ajaxRequest:null,init:function(t){this._ajaxRequest=null,"jsonp"===(t=$.extend(!0,{autoSend:!1,data:{},dataType:"json",after:null,init:null,jsonp:"callback",async:!0,failure:null,showLoadingOverlay:!0,success:null,suppressErrors:!1,type:"POST",url:"index.php?ajax-proxy/&t="+SECURITY_TOKEN,aborted:null,autoAbortPrevious:!1},t)).dataType?require(["AjaxJsonp"],function(e){e.send(t.url,t.success,t.failure,{parameterName:t.jsonp})}):require(["AjaxRequest"],function(e){this._ajaxRequest=new e({data:t.data,type:t.type,url:t.url,withCredentials:t.url==="index.php?ajax-proxy/&t="+SECURITY_TOKEN,responseType:"json"===t.dataType?"application/json":"",autoAbort:t.autoAbortPrevious,ignoreError:t.suppressErrors,silent:!t.showLoadingOverlay,failure:t.failure,finalize:t.after,success:t.success}),t.autoSend&&this._ajaxRequest.sendRequest()}.bind(this))},sendRequest:function(t){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.sendRequest(t)}.bind(this))},abortPrevious:function(){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.abortPrevious()}.bind(this))},setOption:function(t,i){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.setOption(t,i)}.bind(this))},showLoadingOverlayOnce:function(){},suppressErrors:function(){},_failure:function(e,t,i){},_success:function(e,t,i){},_after:function(){}}),WCF.Action.SimpleProxy=Class.extend({init:function(e,t){this.options=$.extend(!0,{action:"",className:"",elements:null,eventName:"click"},e),this.callbacks=$.extend(!0,{after:null,failure:null,init:null,success:null},t),this.options.elements&&(this.proxy=new WCF.Action.Proxy(this.callbacks),this.options.elements.each($.proxy(function(e,t){$(t).bind(this.options.eventName,$.proxy(this._handleEvent,this))},this)))},_handleEvent:function(e){this.proxy.setOption("data",{actionName:this.options.action,className:this.options.className,objectIDs:[$(e.target).data("objectID")]}),this.proxy.sendRequest()}}),WCF.Action.Delete=Class.extend({_buttonSelector:"",_callback:null,_className:"",_containerSelector:"",_containers:[],init:function(e,t,i){this._containerSelector=t,this._className=e,this._buttonSelector=i||".jsDeleteButton",this._callback=null,this.proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initElements(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Action.Delete"+this._className.hashCode(),$.proxy(this._initElements,this))},_initElements:function(){$(this._containerSelector).each(function(e,t){var i,n=$(t),s=n.wcfIdentify();WCF.inArray(s,this._containers)||(i=n.find(this._buttonSelector)).length&&(this._containers.push(s),i.click($.proxy(this._click,this)))}.bind(this))},_click:function(e){var t=$(e.currentTarget);e.preventDefault(),t.data("confirmMessageHtml")||t.data("confirmMessage")?WCF.System.Confirmation.show(t.data("confirmMessageHtml")?t.data("confirmMessageHtml"):t.data("confirmMessage"),$.proxy(this._execute,this),{target:t},void 0,!!t.data("confirmMessageHtml")):(WCF.LoadingOverlayHandler.updateIcon(t),this._sendRequest(t))},_didTriggerEffect:function(e){},_execute:function(e,t){"cancel"!==e&&(WCF.LoadingOverlayHandler.updateIcon(t.target),this._sendRequest(t.target))},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"delete",className:this._className,interfaceName:"wcf\\data\\IDeleteAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this._callback&&this._callback(e.objectIDs),this.triggerEffect(e.objectIDs)},setCallback:function(e){if("function"!=typeof e)throw new TypeError("[WCF.Action.Delete] Expected a valid callback for '"+this._className+"'.");this._callback=e},triggerEffect:function(s){this._containers.forEach(function(e){var t,i=$("#"+e),n=i.find(this._buttonSelector);WCF.inArray(n.data("objectID"),s)&&(t=this,i.wcfBlindOut("up",function(){var e=$(this).remove();t._containers.splice(t._containers.indexOf(e.wcfIdentify()),1),t._didTriggerEffect(e),n.data("eventName")&&WCF.System.Event.fireEvent("com.woltlab.wcf.action.delete",n.data("eventName"),{button:n,container:e})}))}.bind(this))}}),WCF.Action.NestedDelete=WCF.Action.Delete.extend({triggerEffect:function(e){for(var t in this._containers){var i,n=$("#"+this._containers[t]);WCF.inArray(n.find(this._buttonSelector).data("objectID"),e)&&(n.has("ol").has("li").length?(n.is(":only-child")?n.parent().replaceWith(n.find("> ol")):n.replaceWith(n.find("> ol > li")),this._containers.splice(this._containers.indexOf(n.wcfIdentify()),1),this._didTriggerEffect(n)):(i=this,n.wcfBlindOut("up",function(){$(this).remove(),i._containers.splice(i._containers.indexOf($(this).wcfIdentify()),1),i._didTriggerEffect($(this))})))}}}),WCF.Action.Toggle=Class.extend({_buttonSelector:".jsToggleButton",_className:"",_containerSelector:"",_containers:[],init:function(e,t,i){this._containerSelector=t,this._className=e,this._buttonSelector=i||".jsToggleButton",this._containers=[];var n={success:$.proxy(this._success,this)};this.proxy=new WCF.Action.Proxy(n),this._initElements(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Action.Toggle"+this._className.hashCode(),$.proxy(this._initElements,this))},_initElements:function(){$(this._containerSelector).each($.proxy(function(e,t){var i=$(t),n=i.wcfIdentify();WCF.inArray(n,this._containers)||(this._containers.push(n),i.find(this._buttonSelector).click($.proxy(this._click,this)))},this))},_click:function(e){var t=$(e.currentTarget);e.preventDefault(),t.data("confirmMessageHtml")||t.data("confirmMessage")?WCF.System.Confirmation.show(t.data("confirmMessageHtml")?t.data("confirmMessageHtml"):t.data("confirmMessage"),$.proxy(this._execute,this),{target:t},void 0,!!t.data("confirmMessageHtml")):(WCF.LoadingOverlayHandler.updateIcon(t),this._sendRequest(t))},_execute:function(e,t){"cancel"!==e&&(WCF.LoadingOverlayHandler.updateIcon(t.target),this._sendRequest(t.target))},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"toggle",className:this._className,interfaceName:"wcf\\data\\IToggleAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this.triggerEffect(e.objectIDs)},triggerEffect:function(e){for(var t in this._containers){var i=$("#"+this._containers[t]),n=i.find(this._buttonSelector);WCF.inArray(n.data("objectID"),e)&&(i.wcfHighlight(),this._toggleButton(i,n))}},_toggleButton:function(e,t){var i="";WCF.LoadingOverlayHandler.updateIcon(t,!1),i=t.hasClass("fa-square-o")?(t.removeClass("fa-square-o").addClass("fa-check-square-o"),t.data("disableTitle")?t.data("disableTitle"):WCF.Language.get("wcf.global.button.disable")):(t.removeClass("fa-check-square-o").addClass("fa-square-o"),t.data("enableTitle")?t.data("enableTitle"):WCF.Language.get("wcf.global.button.enable")),t.attr("title",i),e.toggleClass("disabled")}}),WCF.Action.Scroll=Class.extend({_callback:null,_reference:null,_target:null,_threshold:0,init:function(e,t,i,n){this._threshold=parseInt(e),0!==this._threshold?($.isFunction(t)&&(this._callback=t),null!==this._callback?(this._reference=$(i||window),this._target=$(n||document),this.start(),this._scroll()):console.debug("[WCF.Action.Scroll] Given callback is invalid, aborting.")):console.debug("[WCF.Action.Scroll] Given threshold is invalid, aborting.")},_scroll:function(){var e=this._target.height(),t=this._reference.scrollTop();e-(this._reference.height()+t)<this._threshold&&this._callback(this)},start:function(){this._reference.on("scroll",$.proxy(this._scroll,this))},stop:function(){this._reference.off("scroll")}}),WCF.Date={},WCF.Date.Picker={init:function(){}},WCF.Date.Util={gmdate:function(e){var t=e||new Date;return Math.round(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDay(),t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds())/1e3)},getTimezoneDate:function(e,t){var i=6e4*new Date(e).getTimezoneOffset();return new Date(e+i+t)}},WCF.Dictionary=Class.extend({_variables:{},init:function(){this._variables={}},add:function(e,t){this._variables[e]=t},addObject:function(e){for(var t in e)this.add(t,e[t])},addDictionary:function(e){e.each($.proxy(function(e){this.add(e.key,e.value)},this))},get:function(e){return this.isset(e)?this._variables[e]:null},isset:function(e){return this._variables.hasOwnProperty(e)},remove:function(e){delete this._variables[e]},each:function(e){if($.isFunction(e))for(var t in this._variables){e({key:t,value:this._variables[t]})}},count:function(){return $.getLength(this._variables)},isEmpty:function(){return!this.count()}}),null==window.WCF.Language&&(WCF.Language={add:function(t,i){require(["Language"],function(e){e.add(t,i)})},addObject:function(t){require(["Language"],function(e){e.addObject(t)})},get:function(e,t){throw new Error('Call to deprecated WCF.Language.get("'+e+'")')}}),WCF.Number={round:function(e,t){return t=Math.pow(10,t||0),Math.round(e*t)/t}},WCF.String={addThousandsSeparator:function(e){return String(e).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+WCF.Language.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(e,t){var i=(e=String(WCF.Number.round(e,t||2))).split(".");return e=this.addThousandsSeparator(i[0]),1<i.length&&(e+=WCF.Language.get("wcf.global.decimalPoint")+i[1]),e=e.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")}},WCF.TabMenu={init:function(){require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.setup()})},reload:function(){this.init()}},WCF.Template=Class.extend({init:function(t){var i=new WCF.Dictionary,n=0;t=(t=(t=t.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n")).replace(/\{literal\}(.*?)\{\/literal\}/g,$.proxy(function(e){var t="@@@@@@@@@@@"+Math.random()+"@@@@@@@@@@@";return i.add(t,e.replace(/\{\/?literal\}/g,"")),t},this))).replace(/\{\*.*?\*\}/g,"");function s(e){for(var t=e.split(""),i={},n=!0,s="",a="",o=!1,r=!1,l=!1,c=0,u=t.length;c<u;c++){var h=t[c];n&&"="!=h&&" "!=h?s+=h:n&&"="==h?l=o=r=n=!1:n||r||o||" "!=h?n||!r||l||"'"!=h?n||r||o||"'"!=h?n||!o||l||'"'!=h?n||r||o||'"'!=h?n||!o&&!r||l||"\\"!=h?n||(l=!1,a+=h):(l=!0,a+=h):(o=!0,a+=h):(o=!1,a+=h):(r=!0,a+=h):(r=!1,a+=h):(n=!0,i[s]=a,a=s="")}if(i[s]=a,o||r||l)throw new Error('Syntax error in parameterList: "'+e+'"');return i}function a(e){return e.replace(/\\n/g,"\n").replace(/\\\\/g,"\\").replace(/\\'/g,"'")}for(var e in t=t.replace(/\{(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.escapeHTML("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{#(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.formatNumeric("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{@(\$[^\}]+?)\}/g,function(e,t){return"' + "+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+" + '"}).replace(/\{lang\}(.+?)\{\/lang\}/g,function(e,t){return"' + WCF.Language.get('"+t+"', v) + '"}).replace(/\{include (.+?)\}/g,function(e,t){t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=s(t);if(void 0===i.file)throw new Error("Missing file attribute in include-tag");return i.file=i.file.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"' + "+i.file+".fetch(v) + '"}).replace(/\{if (.+?)\}/g,function(e,t){return"';\nif ("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{else ?if (.+?)\}/g,function(e,t){return"';\n}\nelse if ("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{implode (.+?)\}/g,function(e,t){n++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=s(t);if(void 0===i.from)throw new Error("Missing from attribute in implode-tag");if(void 0===i.item)throw new Error("Missing item attribute in implode-tag");return void 0===i.glue&&(i.glue="', '"),i.from=i.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\nvar $implode_"+n+" = false;\nfor ($implodeKey_"+n+" in "+i.from+") {\n\tv["+i.item+"] = "+i.from+"[$implodeKey_"+n+"];\n"+(void 0!==i.key?"\t\tv["+i.key+"] = $implodeKey_"+n+";\n":"")+"\tif ($implode_"+n+") $output += "+i.glue+";\n\t$implode_"+n+" = true;\n\t$output += '"}).replace(/\{foreach (.+?)\}/g,function(e,t){n++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=s(t);if(void 0===i.from)throw new Error("Missing from attribute in foreach-tag");if(void 0===i.item)throw new Error("Missing item attribute in foreach-tag");return i.from=i.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\n$foreach_"+n+" = false;\nfor ($foreachKey_"+n+" in "+i.from+") {\n\t$foreach_"+n+" = true;\n\tbreak;\n}\nif ($foreach_"+n+") {\n\tfor ($foreachKey_"+n+" in "+i.from+") {\n\t\tv["+i.item+"] = "+i.from+"[$foreachKey_"+n+"];\n"+(void 0!==i.key?"\t\tv["+i.key+"] = $foreachKey_"+n+";\n":"")+"\t\t$output += '"}).replace(/\{foreachelse\}/g,"';\n\t}\n}\nelse {\n\t{\n\t\t$output += '").replace(/\{\/foreach\}/g,"';\n\t}\n}\n$output += '").replace(/\{else\}/g,"';\n}\nelse {\n\t$output += '").replace(/\{\/(if|implode)\}/g,"';\n}\n$output += '"),WCF.Template.callbacks)t=WCF.Template.callbacks[e](t);t=t.replace("{ldelim}","{").replace("{rdelim}","}"),i.each(function(e){t=t.replace(e.key,e.value)}),t="$output += '"+t+"';";try{this.fetch=new Function("v","v = window.$.extend({}, v, { __wcf: window.WCF, __window: window }); var $output = ''; "+t+" return $output;")}catch(e){throw console.debug("var $output = ''; "+t+" return $output;"),e}},fetch:function(e){}}),WCF.Template.callbacks=[],WCF.ToggleOptions=Class.extend({_element:null,_showItems:[],_hideItems:[],_callback:null,init:function(e,t,i,n){this._element=$("#"+e),this._showItems=t,this._hideItems=i,void 0!==n&&(this._callback=n),this._element.click($.proxy(this._toggle,this)),this._toggle()},_toggle:function(){if(this._element.prop("checked")){for(var e=0,t=this._showItems.length;e<t;e++){var i=this._showItems[e];$("#"+i).show()}for(e=0,t=this._hideItems.length;e<t;e++){i=this._hideItems[e];$("#"+i).hide()}null!==this._callback&&this._callback()}}}),WCF.Collapsible={},WCF.Collapsible.Simple={init:function(){$(".jsCollapsible").each($.proxy(function(e,t){this._initButton(t)},this))},_initButton:function(e){var t=$(e);t.data("isOpen")||$("#"+t.data("collapsibleContainer")).hide(),t.click($.proxy(this._toggle,this))},_toggle:function(e){var t=$(e.currentTarget),i=t.data("isOpen"),n=$("#"+$.wcfEscapeID(t.data("collapsibleContainer"))),i=i?(n.stop().wcfBlindOut("vertical",$.proxy(function(){this._toggleImage(t)},this)),!1):(n.stop().wcfBlindIn("vertical",$.proxy(function(){this._toggleImage(t)},this)),!0);return t.data("isOpen",i),e.stopPropagation(),!1},_toggleImage:function(e){var t=e.find("span.icon");e.data("isOpen")?t.removeClass("fa-chevron-right").addClass("fa-chevron-down"):t.removeClass("fa-chevron-down").addClass("fa-chevron-right")}},WCF.Collapsible.Remote=Class.extend({_className:"",_containers:{},_containerData:{},_proxy:null,init:function(e){this._className=e,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Collapsible.Remote",$.proxy(this._init,this))},_init:function(e){this._getContainers().each($.proxy(function(e,t){var i=$(t),n=i.wcfIdentify();void 0===this._containers[n]&&(this._containers[n]=i,this._initContainer(n))},this))},_initContainer:function(e){var t=this._getTarget(e),i=this._getButtonContainer(e),n=this._createButton(e,i);this._containerData[e]={button:n,buttonContainer:i,isOpen:this._containers[e].data("isOpen"),target:t},this._containers[e].data("isOpen")||$("#"+e).addClass("jsCollapsed")},_getContainers:function(){},_getTarget:function(e){},_getButtonContainer:function(e){},_createButton:function(e,t){var i=elBySel(".jsStaticCollapsibleButton",t[0]);return(i=null!==i&&i.parentNode===t[0]?(i.classList.remove("jsStaticCollapsibleButton"),$(i)):$('<span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-down" title="'+WCF.Language.get("wcf.global.button.collapsible")+'">').prependTo(t)).data("containerID",e).click($.proxy(this._toggleContainer,this)),i},_toggleContainer:function(e){var t=$(e.currentTarget).data("containerID"),i=this._containerData[t].isOpen,n=i?"open":"close",s=i?"close":"open";this._proxy.setOption("data",{actionName:"loadContainer",className:this._className,interfaceName:"wcf\\data\\ILoadableContainerAction",objectIDs:[this._getObjectID(t)],parameters:$.extend(!0,{containerID:t,currentState:n,newState:s},this._getAdditionalParameters(t))}),this._proxy.sendRequest(),$("#"+t).toggleClass("jsCollapsed")},_exchangeIcon:function(e,t){t=t||"spinner",e.removeClass("fa-chevron-down fa-chevron-right fa-spinner").addClass("fa-"+t)},_getObjectID:function(e){return $("#"+e).data("objectID")},_getAdditionalParameters:function(e){return{}},_updateContent:function(e,t,i){this._containerData[e].target.html(t)},_success:function(e,t,i){var n,s;e.returnValues.containerID&&(n=e.returnValues.containerID,this._containers[n]&&(this._containerData[n].isOpen=!!e.returnValues.isOpen,s=e.returnValues.isOpen?"open":"close",this._updateContent(n,$.trim(e.returnValues.content),s)))}}),WCF.Collapsible.SimpleRemote=WCF.Collapsible.Remote.extend({init:function(e){this._super(e),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1})},_initContainer:function(e){this._super(e),this._containerData[e].isOpen||(this._containerData[e].target.hide(),this._exchangeIcon(this._containerData[e].button,"chevron-right"))},_toggleContainer:function(e){var t=$(e.currentTarget).data("containerID"),i=this._containerData[t].isOpen,n=i?"open":"close",s=i?"close":"open";this._proxy.setOption("data",{actionName:"toggleContainer",className:this._className,interfaceName:"wcf\\data\\IToggleContainerAction",objectIDs:[this._getObjectID(t)],parameters:$.extend(!0,{containerID:t,currentState:n,newState:s},this._getAdditionalParameters(t))}),this._proxy.sendRequest(),this._exchangeIcon(this._containerData[t].button,"open"==s?"chevron-down":"chevron-right"),"open"==s?this._containerData[t].target.show():this._containerData[t].target.hide(),$("#"+t).toggleClass("jsCollapsed"),this._containerData[t].isOpen="open"==s}}),WCF.User={userID:0,username:"",init:function(e,t){this.userID=e,this.username=t}},WCF.Effect={},WCF.Effect.Scroll=Class.extend({scrollTo:function(e,t,i){if(!e.length)return!0;var n=e.getOffsets("offset").top,s=$(document).height(),a=$(window).height();return s-a<n&&(n=s-a)<0&&(n=0),!0===i?$("html,body").scrollTop(n):$("html,body").animate({scrollTop:n},400,function(e,t,i,n,s){return-n*((t=t/s-1)*t*t*t-1)+i}),!1}}),WCF.CloseOverlayHandler={addCallback:function(t,i){require(["Ui/CloseOverlay"],function(e){e.add(t,i)})},removeCallback:function(t){require(["Ui/CloseOverlay"],function(e){e.remove(t)})},forceExecution:function(){require(["Ui/CloseOverlay"],function(e){e.execute()})}},WCF.DOMNodeInsertedHandler={addCallback:function(e,t){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.add("__legacy__",t)})},_executeCallbacks:function(){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.trigger()})},execute:function(){this._executeCallbacks()}},WCF.DOMNodeRemovedHandler={_callbacks:new WCF.Dictionary,_isExecuting:!1,_isListening:!1,addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.DOMNodeRemovedHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){this._isListening||(window.MutationObserver?new MutationObserver(function(e){var t=!1;e.forEach(function(e){e.removedNodes.length&&(t=!0)}.bind(this)),t&&this._executeCallbacks({})}.bind(this)).observe(document.body,{childList:!0,subtree:!0}):$(document).bind("DOMNodeRemoved",$.proxy(this._executeCallbacks,this)),this._isListening=!0)},_executeCallbacks:function(t){this._isExecuting||(this._isExecuting=!0,this._callbacks.each(function(e){e.value(t)}),this._isExecuting=!1)}},WCF.Option={},WCF.Option.Handler=Class.extend({init:function(){this._initOptions(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Option.Handler",$.proxy(this._initOptions,this))},_initOptions:function(){$(".jsEnablesOptions").each($.proxy(this._initOption,this))},_initOption:function(e,t){this._change(t),$(t).change($.proxy(this._handleChange,this))},_handleChange:function(e){this._change($(e.target))},_change:function(option){option=$(option);var disableOptions=eval(option.data("disableOptions")),enableOptions=eval(option.data("enableOptions")),isActive;switch(option.getTagName()){case"input":switch(option.attr("type")){case"checkbox":this._execute(option.prop("checked"),disableOptions,enableOptions);break;case"radio":option.prop("checked")&&(isActive=!0,option.data("isBoolean")&&1!=option.val()&&(isActive=!1),this._execute(isActive,disableOptions,enableOptions))}break;case"select":var $value=option.val(),relevantDisableOptions=[],relevantEnableOptions=[];if(0<disableOptions.length)for(var $index in disableOptions){var $item=disableOptions[$index];$item.value==$value?relevantDisableOptions.push($item.option):relevantEnableOptions.push($item.option)}if(0<enableOptions.length)for(var $index in enableOptions){var $item=enableOptions[$index];$item.value==$value?relevantEnableOptions.push($item.option):relevantDisableOptions.push($item.option)}this._execute(!0,relevantDisableOptions,relevantEnableOptions)}},_execute:function(e,t,i){if(0<t.length)for(var n=0,s=t.length;n<s;n++){var a=t[n];$.wcfIsset(a)?this._enableOption(a,!e):(o=$("."+$.wcfEscapeID(a)+"Input")).length&&this._enableOptions(o.children("dd").find("input, select, textarea"),!e)}if(0<i.length)for(n=0,s=i.length;n<s;n++){var o,a=i[n];$.wcfIsset(a)?this._enableOption(a,e):(o=$("."+$.wcfEscapeID(a)+"Input")).length&&this._enableOptions(o.children("dd").find("input, select, textarea"),e)}},_enableOption:function(e,t){this._enableOptionElement($("#"+$.wcfEscapeID(e)),t)},_enableOptionElement:function(e,t){var i,n,s,a=(e=$(e)).getTagName();"select"==a||"input"==a&&("checkbox"==e.attr("type")||"file"==e.attr("type")||"radio"==e.attr("type"))?("input"===a&&"radio"===e[0].type&&e[0].checked||(t?e.enable():e.disable()),e.parents(".optionTypeBoolean:eq(0)")&&(i=e.wcfIdentify().replace(/\./g,"\\."),n=$("#"+i+"_no"),t?n.enable():n.disable(),(s=$("#"+i+"_never")).length&&(t?s.enable():s.disable()))):t?e.removeAttr("readonly"):e.attr("readonly",!0),t?e.closest("dl").removeClass("disabled"):e.closest("dl").addClass("disabled")},_enableOptions:function(e,t){for(var i=0,n=e.length;i<n;i++)this._enableOptionElement(e[i],t)}}),WCF.PageVisibilityHandler={_callbacks:new WCF.Dictionary,_isListening:!1,_hiddenFieldName:"",addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.PageVisibilityHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){var e;this._isListening||(e=null,void 0!==document.hidden?(this._hiddenFieldName="hidden",e="visibilitychange"):void 0!==document.mozHidden?(this._hiddenFieldName="mozHidden",e="mozvisibilitychange"):void 0!==document.msHidden?(this._hiddenFieldName="msHidden",e="msvisibilitychange"):void 0!==document.webkitHidden&&(this._hiddenFieldName="webkitHidden",e="webkitvisibilitychange"),null===e?console.debug("[WCF.PageVisibilityHandler] This browser does not support the page visibility API."):$(document).on(e,$.proxy(this._executeCallbacks,this)),this._isListening=!0)},_executeCallbacks:function(e){var t;this._isExecuting||(this._isExecuting=!0,t=document[this._hiddenFieldName],this._callbacks.each(function(e){e.value(t)}),this._isExecuting=!1)}},WCF.Table={},WCF.Table.EmptyTableHandler=Class.extend({_options:{},_rowClassName:"",init:function(e,t,i){this._rowClassName=t,this._tableContainer=e,this._options=$.extend(!0,{emptyMessage:null,emptyMessageHtml:null,messageType:"info",refreshPage:!1,updatePageNumber:!1,isTable:0!==this._tableContainer.find("table").length},i||{}),WCF.DOMNodeRemovedHandler.addCallback("WCF.Table.EmptyTableHandler."+t,$.proxy(this._remove,this))},_getRowCount:function(){return this._tableContainer.find((this._options.isTable?"table tr.":".tabularList .")+this._rowClassName).length},_handleEmptyTable:function(){var e,t;this._options.emptyMessage?this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).text(this._options.emptyMessage)):this._options.emptyMessageHtml?this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).html(this._options.emptyMessageHtml)):this._options.refreshPage?this._options.updatePageNumber?(e=window.location.href.match(/(\?|&)pageNo=(\d+)/g))&&(t=e[e.length-1].match(/\d+/g),0<this._options.updatePageNumber?t++:t--,window.location=window.location.href.replace(e[e.length-1],e[e.length-1][0]+"pageNo="+t)):window.location.reload():this._tableContainer.remove()},_remove:function(e){var t;$.getLength(e)?(t=$(e.target)).hasClass(this._rowClassName)&&(this._options.isTable?1==t.parents("tbody:eq(0)").children("tr").length&&this._handleEmptyTable():1===this._getRowCount()&&this._handleEmptyTable()):this._getRowCount()||this._handleEmptyTable()}}),WCF.Search={},WCF.Search.Base=Class.extend({_callback:null,_caretAt:-1,_className:"",_commaSeperated:!1,_delay:0,_excludedSearchValues:[],_itemCount:0,_itemIndex:-1,_lastValue:"",_list:null,_oldSearchString:[],_proxy:null,_searchInput:null,_triggerLength:3,_timer:null,init:function(e,t,i,n,s){null==t||$.isFunction(t)?(this._callback=t||null,this._caretAt=-1,this._delay=0,this._excludedSearchValues=[],this._lastValue="",i&&(this._excludedSearchValues=i),this._searchInput=$(e),this._searchInput.length?(this._searchInput.keydown($.proxy(this._keyDown,this)).keyup($.proxy(this._keyUp,this)).wrap('<span class="dropdown" />'),$.browser.mozilla&&$.browser.touch&&this._searchInput.on("input",$.proxy(this._keyUp,this)),this._list=$('<ul class="dropdownMenu" />').insertAfter(this._searchInput),this._commaSeperated=!!n,this._oldSearchString=[],this._itemCount=0,this._itemIndex=-1,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!0===s,success:$.proxy(this._success,this),autoAbortPrevious:!0}),this._searchInput.is("input")&&this._searchInput.attr("autocomplete","off"),this._searchInput.blur($.proxy(this._blur,this)),WCF.Dropdown.initDropdownFragment(this._searchInput.parent(),this._list)):console.debug("[WCF.Search.Base] Selector '"+e+"' for search input is invalid, aborting.")):console.debug("[WCF.Search.Base] The given callback is invalid, aborting.")},_blur:function(){var t=this;new WCF.PeriodicalExecuter(function(e){t._list.is(":visible")&&t._clearList(!1),e.stop()},250)},_keyDown:function(e){var t;e.which===$.ui.keyCode.ENTER&&((t=this._searchInput.parents(".dropdown")).data("disableAutoFocus")?-1!==this._itemIndex&&e.preventDefault():!t.data("preventSubmit")&&-1===this._itemIndex||e.preventDefault())},_keyUp:function(e){switch(e.which){case 37:case 39:return;case 38:return void this._selectPreviousItem();case 40:return void this._selectNextItem();case 13:return this._selectElement(e)}var t=this._getSearchString(e);if(""===t)this._clearList(!1);else if(t.length>=this._triggerLength){if(this._lastValue===t)return;this._lastValue=t;var i,n={data:{excludedSearchValues:this._excludedSearchValues,searchString:t}};this._delay?(null!==this._timer&&this._timer.stop(),(i=this)._timer=new WCF.PeriodicalExecuter(function(){i._queryServer(n),i._timer.stop(),i._timer=null},this._delay)):this._queryServer(n)}else this._clearList(!1)},_queryServer:function(e){this._searchInput.parents(".searchBar").addClass("loading"),this._proxy.setOption("data",{actionName:"getSearchResultList",className:this._className,interfaceName:"wcf\\data\\ISearchAction",parameters:this._getParameters(e)}),this._proxy.sendRequest()},setDelay:function(e){this._delay=e},_selectNextItem:function(){0!==this._itemCount&&(this._itemIndex++,this._itemIndex===this._itemCount&&(this._itemIndex=0),this._highlightSelectedElement())},_selectPreviousItem:function(){0!==this._itemCount&&(this._itemIndex--,-1===this._itemIndex&&(this._itemIndex=this._itemCount-1),this._highlightSelectedElement())},_highlightSelectedElement:function(){this._list.find("li").removeClass("dropdownNavigationItem"),this._list.find("li:eq("+this._itemIndex+")").addClass("dropdownNavigationItem")},_selectElement:function(e){return 0===this._itemCount||(this._list.find("li.dropdownNavigationItem").trigger("click"),!1)},_getSearchString:function(e){var t=$.trim(this._searchInput.val());if(this._commaSeperated){if((e.keyCode||e.which)==$.ui.keyCode.COMMA)return"";for(var i=t.split(","),n=i.length,s=0;s<n;s++)i[s]=$.trim(i[s]);for(s=0;s<n;s++){var a=i[s];if(!this._oldSearchString[s]){t=a;break}if(a!=this._oldSearchString[s]){t=a,this._caretAt=s;break}}this._oldSearchString=i}return t},_getParameters:function(e){return e},_success:function(e,t,i){if(this._clearList(!1),this._searchInput.parents(".searchBar").removeClass("loading"),$.getLength(e.returnValues))for(var n in e.returnValues){var s=e.returnValues[n];this._createListItem(s)}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var a=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(a).hasClass("dropdownOpen")||(WCF.Dropdown.toggleDropdown(a,!0),this._openDropdown()),this._itemIndex=-1,WCF.Dropdown.getDropdown(a).data("disableAutoFocus")||this._selectNextItem()},_openDropdown:function(){},_handleEmptyResult:function(){return!1},_createListItem:function(e){var t=$("<li><span>"+WCF.String.escapeHTML(e.label)+"</span></li>").appendTo(this._list);return t.data("objectID",e.objectID).data("label",e.label).click($.proxy(this._executeCallback,this)),this._itemCount++,t},_executeCallback:function(e){var t,i,n=!1,s=$(e.currentTarget);this._commaSeperated?(t=s.data("label"),this._oldSearchString[this._caretAt]=t,this._searchInput.val(this._oldSearchString.join(", ")),$.browser.webkit&&this._searchInput.css({display:"block"}),i=this._searchInput.val().toLowerCase().indexOf(t.toLowerCase())+t.length,this._searchInput.focus().setCaret(i)):null===this._callback?this._searchInput.val(s.data("label")):n=!0===this._callback(s.data()),this._clearList(n)},_clearList:function(e){e&&!this._commaSeperated&&this._searchInput.val(""),WCF.Dropdown.getDropdown(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),this._list.end().empty(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1},addExcludedSearchValue:function(e){WCF.inArray(e,this._excludedSearchValues)||this._excludedSearchValues.push(e)},removeExcludedSearchValue:function(e){var t=$.inArray(e,this._excludedSearchValues);-1!=t&&this._excludedSearchValues.splice(t,1)}}),WCF.Search.User=WCF.Search.Base.extend({_className:"wcf\\data\\user\\UserAction",_includeUserGroups:!1,init:function(e,t,i,n,s){this._includeUserGroups=i,this._super(e,t,n,s)},_getParameters:function(e){return e.data.includeUserGroups=this._includeUserGroups?1:0,e},_createListItem:function(e){var t,i,n=this._super(e),s=null;return e.icon?s=$(e.icon):this._includeUserGroups&&"group"===e.type&&(s=$('<span class="icon icon16 fa-users" />')),s&&(t=n.find("span").detach(),(i=$("<div />").addClass("box16").appendTo(n)).append(s),i.append($("<div />").append(t))),n.data("type",e.type),n}}),WCF.System={},WCF.System.Dependency={},WCF.System.Dependency.Manager={_callbacks:{},_loaded:[],_setupCallbacks:{},register:function(e,t){$.isFunction(t)?WCF.inArray(e,this._loaded)?setTimeout(function(){t()},1):(this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t)):console.debug("[WCF.System.Dependency.Manager] Callback for identifier '"+e+"' is invalid, aborting.")},setup:function(e,t){$.isFunction(t)?(this._setupCallbacks[e]||(this._setupCallbacks[e]=[]),this._setupCallbacks[e].push(t)):console.debug("[WCF.System.Dependency.Manager] Setup callback for identifier '"+e+"' is invalid, aborting.")},invoke:function(e){if(this._setupCallbacks[e]){for(var t=0,i=this._setupCallbacks[e].length;t<i;t++)this._setupCallbacks[e][t]();delete this._setupCallbacks[e]}if(this._loaded.push(e),this._callbacks[e]){for(t=0,i=this._callbacks[e].length;t<i;t++)this._callbacks[e][t]();delete this._callbacks[e]}},reset:function(e){var t=this._loaded.indexOf(e);-1!==t&&this._loaded.splice(t,1)}},WCF.System.FlexibleMenu={init:function(){},registerMenu:function(t){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(e){e.register(t)})},rebuild:function(t){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(e){e.rebuild(t)})}},WCF.System.Mobile={},WCF.System.ObjectStore={_objects:{},add:function(e,t){void 0===this._objects[e]&&(this._objects[e]=[]),this._objects[e].push(t)},invoke:function(e,t){if(this._objects[e])for(var i=0;i<this._objects[e].length;i++)t(this._objects[e][i])}},WCF.System.Captcha={_registeredCaptchas:[],addCallback:function(t,i){require(["WoltLabSuite/Core/Controller/Captcha"],function(e){try{e.add(t,i),this._registeredCaptchas.push(t)}catch(e){if(e instanceof TypeError)return void console.debug("[WCF.System.Captcha] Given callback is no function")}}.bind(this))},getData:function(t){var e;if(-1===this._registeredCaptchas.indexOf(t))return e;var i=require("WoltLabSuite/Core/Controller/Captcha");try{e=i.getData(t)}catch(e){console.debug('[WCF.System.Captcha] Unknow captcha id "'+t+'"')}return e},removeCallback:function(t){require(["WoltLabSuite/Core/Controller/Captcha"],function(e){try{e.delete(t),this._registeredCaptchas.splice(this._registeredCaptchas.indexOf(item),1)}catch(e){}}.bind(this))}},WCF.System.Page={},WCF.System.Notification=Class.extend({_cssClassNames:"",_message:"",init:function(e,t){this._cssClassNames=t||"",this._message=e||""},show:function(t,e,i,n){require(["Ui/Notification"],function(e){e.show(i||this._message,t,n||this._cssClassNames)}.bind(this))}}),WCF.System.Confirmation={show:function(t,i,n,s,a){var e;"object"==typeof s&&((e=$("<div />")).append(s),s=e.html()),require(["Ui/Confirmation"],function(e){e.show({legacyCallback:i,message:t,parameters:n,template:s||"",messageIsHtml:!0===a})})}},WCF.System.DisableScrolling={_depth:0,_oldOverflow:null,disable:function(){$.browser.touch||(0===this._depth&&(this._oldOverflow=$(document.body).css("overflow"),$(document.body).css("overflow","hidden")),this._depth++)},enable:function(){0!==this._depth&&(this._depth--,0===this._depth&&$(document.body).css("overflow",this._oldOverflow))}},WCF.System.DisableZoom={_depth:0,_oldViewportSettings:null,disable:function(){var e;0===this._depth&&(e=$("meta[name=viewport]"),this._oldViewportSettings=e.attr("content"),e.attr("content",this._oldViewportSettings+",maximum-scale=1")),this._depth++},enable:function(){0!==this._depth&&(this._depth--,0===this._depth&&$("meta[name=viewport]").attr("content",this._oldViewportSettings))}},WCF.System.Fullscreen={enterFullscreen:function(e){e.requestFullscreen?e.requestFullscreen():e.msRequestFullscreen?e.msRequestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)},toggleFullscreen:function(e){null===this.getFullscreenElement()?this.enterFullscreen(e):this.exitFullscreen()},getFullscreenElement:function(){return document.fullscreenElement?document.fullscreenElement:document.mozFullScreenElement?document.mozFullScreenElement:document.webkitFullscreenElement?document.webkitFullscreenElement:document.msFullscreenElement?document.msFullscreenElement:null},exitFullscreen:function(){document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen()},isSupported:function(){return!!(document.documentElement.requestFullscreen||document.documentElement.msRequestFullscreen||document.documentElement.mozRequestFullScreen||document.documentElement.webkitRequestFullscreen)}},WCF.System.PageNavigation={init:function(s,a){require(["WoltLabSuite/Core/Ui/Page/JumpTo"],function(e){for(var t=elBySelAll(s),i=0,n=t.length;i<n;i++)e.init(t[i],a)})}},WCF.System.KeepAlive=Class.extend({init:function(e){new WCF.PeriodicalExecuter(function(e){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"keepAlive",className:"wcf\\data\\session\\SessionAction"},failure:function(){e.stop()},showLoadingOverlay:!1,success:function(e){WCF.System.PushNotification.executeCallbacks(e)},suppressErrors:!0})},1e3*e)}}),WCF.System.PushNotification={_callbacks:{},addCallback:function(e,t){void 0===this._callbacks[e]&&(this._callbacks[e]=[]),this._callbacks[e].push(t)},executeCallbacks:function(e){for(var t in e.returnValues)if(void 0!==this._callbacks[t])for(var i=0;i<this._callbacks[t].length;i++)this._callbacks[t][i](e.returnValues[t])}},WCF.System.Event={addListener:function(e,t,i){return window.__wcf_bc_eventHandler.add(e,t,i)},removeListener:function(e,t,i){return window.__wcf_bc_eventHandler.remove(e,t,i)},removeAllListeners:function(e,t){return window.__wcf_bc_eventHandler.removeAll(e,t)},fireEvent:function(e,t,i){window.__wcf_bc_eventHandler.fire(e,t,i)}},WCF.System.Worker=Class.extend({_aborted:!1,_actionName:"",_callback:null,_className:"",_dialog:null,_proxy:null,_title:"",init:function(e,t,i,n,s){this._aborted=!1,this._actionName=e,this._callback=s||null,this._className=t,this._dialog=null,this._proxy=new WCF.Action.Proxy({autoSend:!0,data:{actionName:this._actionName,className:this._className,parameters:n||{}},showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._title=i},_success:function(e){var t,i;null===this._dialog&&(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.wcfDialog({closeConfirmMessage:WCF.Language.get("wcf.worker.abort.confirmMessage"),closeViaModal:!1,onClose:$.proxy(function(){this._aborted=!0,this._proxy.abortPrevious(),window.location.reload()},this),title:this._title})),this._aborted||(e.returnValues.template&&this._dialog.html(e.returnValues.template),this._dialog.find("progress").attr("value",e.returnValues.progress).text(e.returnValues.progress+"%").next("span").text(e.returnValues.progress+"%"),e.returnValues.progress<100?((t=e.returnValues.parameters||{}).loopCount=e.returnValues.loopCount,this._proxy.setOption("data",{actionName:this._actionName,className:this._className,parameters:t}),this._proxy.sendRequest()):null!==this._callback?this._callback(this,e):(this._dialog.find(".fa-spinner").removeClass("fa-spinner").addClass("fa-check green"),this._dialog.find(".contentHeader h1").text(WCF.Language.get("wcf.global.worker.completed")),i=$('<div class="formSubmit" />').appendTo(this._dialog),$('<button class="buttonPrimary">'+WCF.Language.get("wcf.global.button.next")+"</button>").appendTo(i).focus().click(function(){e.returnValues.redirectURL?window.location=e.returnValues.redirectURL:window.location.reload()}),this._dialog.wcfDialog("render")))}}),WCF.InlineEditor=Class.extend({_callbacks:[],_dropdowns:{},_elements:{},_notification:null,_options:[],_proxy:null,_triggerElements:{},_updateData:[],_elementSelector:null,_quickOption:null,init:function(e){if(this._elementSelector=e,$(e).length){this._setOptions();for(var t=0,i=this._options.length;t<i;t++)if(this._options[t].isQuickOption){this._quickOption=this._options[t].optionName;break}this.rebuild(),WCF.DOMNodeInsertedHandler.addCallback("WCF.InlineEditor"+this._elementSelector.hashCode(),$.proxy(this.rebuild,this)),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),WCF.CloseOverlayHandler.addCallback("WCF.InlineEditor",$.proxy(this._closeAll,this)),this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success"),"success")}},rebuild:function(){var e=$(this._elementSelector),a=this;e.each(function(e,t){var i=$(t),n=i.wcfIdentify();if(void 0===a._elements[n]){var s=a._getTriggerElement(i);if(null===s||1!==s.length)return;s.on(WCF_CLICK_EVENT,$.proxy(a._show,a)).data("elementID",n),a._quickOption&&s.disableSelection().data("optionName",a._quickOption).dblclick($.proxy(a._click,a)),a._elements[n]=i}})},_closeAll:function(){for(var e in this._elements)this._hide(e)},_setOptions:function(){this._options=[]},registerCallback:function(e){$.isFunction(e)&&this._callbacks.push(e)},_getTriggerElement:function(e){return null},_show:function(e){e.preventDefault();var t,i=$(e.currentTarget).data("elementID"),n=null;this._dropdowns[i]||(this._triggerElements[i]=n=this._getTriggerElement(this._elements[i]).addClass("dropdownToggle"),(t=n[0].parentNode)&&"LI"===t.nodeName&&1===t.childElementCount?t.classList.add("dropdown"):n.wrap('<span class="dropdown" />'),this._dropdowns[i]=$('<ul class="dropdownMenu" />').insertAfter(n)),this._dropdowns[i].empty();for(var s=!1,a="",o=0,r=this._options.length;o<r;o++){var l=this._options[o];"divider"===l.optionName?""!==a&&"divider"!==a&&($('<li class="dropdownDivider" />').appendTo(this._dropdowns[i]),a=l.optionName):(this._validate(i,l.optionName)||this._validateCallbacks(i,l.optionName))&&($("<li><span>"+l.label+"</span></li>").appendTo(this._dropdowns[i]).data("elementID",i).data("optionName",l.optionName).data("isQuickOption",!!l.isQuickOption).click($.proxy(this._click,this)),s=!0,a=l.optionName)}if(s){var c=this._dropdowns[i].children().last();c.hasClass("dropdownDivider")&&c.remove();var u=null,h=0;if(this._dropdowns[i].children().each(function(e,t){var i=$(t);i.hasClass("dropdownDivider")||(i.data("isQuickOption")?u=i:h++)}),!h)return u.trigger("click"),this._triggerElements[i]&&WCF.Dropdown.close(this._triggerElements[i].parents(".dropdown").wcfIdentify()),!1}return null!==n&&WCF.Dropdown.initDropdown(n,e.originalEvent||e),!1},_validate:function(e,t){return!1},_validateCallbacks:function(e,t){var i=this._callbacks.length;if(i)for(var n=0;n<i;n++)if(this._callbacks[n].validate(this._elements[e],t))return!0;return!1},_success:function(e,t,i){this._updateData.length&&(this._updateState(e),this._updateData=[])},_updateState:function(e){},_click:function(e){var t=$(e.currentTarget),i=t.data("elementID"),n=t.data("optionName");this._execute(i,n)||this._executeCallback(i,n),this._hide(i)},_execute:function(e,t){return!1},_executeCallback:function(e,t){var i=this._callbacks.length;if(i)for(var n=0;n<i;n++)if(this._callbacks[n].execute(this._elements[e],t))return!0;return!1},_hide:function(e){this._dropdowns[e]&&this._dropdowns[e].empty().removeClass("dropdownOpen")}}),WCF.Upload=Class.extend({_name:"__files[]",_buttonSelector:null,_fileListSelector:null,_fileUpload:null,_className:"",_iframe:null,_internalFileID:0,_options:{},_uploadMatrix:[],_supportsAJAXUpload:!0,_overlay:null,init:function(e,t,i,n){this._buttonSelector=e,this._fileListSelector=t,this._className=i,this._internalFileID=0,this._options=$.extend(!0,{action:"upload",multiple:!1,url:"index.php?ajax-upload/&t="+SECURITY_TOKEN},n||{}),this._options.url=WCF.convertLegacyURL(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url);var s=new XMLHttpRequest;this._supportsAJAXUpload=s&&"upload"in s&&"onprogress"in s.upload,this._createButton()},_createButton:function(){var e;this._supportsAJAXUpload?(this._fileUpload=$('<input type="file" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/>"),this._fileUpload.change($.proxy(this._upload,this)),e=$('<p class="button uploadButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>"),elAttr(e[0],"role","button"),e.prepend(this._fileUpload),this._fileUpload[0].addEventListener("focus",function(){this.classList.contains("focus-visible")&&e[0].classList.add("active")}),this._fileUpload[0].addEventListener("blur",function(){e[0].classList.remove("active")})):(e=$('<p class="button uploadFallbackButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>"),elAttr(e[0],"role","button"),elAttr(e[0],"tabindex","0"),e.click($.proxy(this._showOverlay,this))),this._insertButton(e)},_insertButton:function(e){this._buttonSelector.prepend(e)},_removeButton:function(){var e=".uploadButton";this._supportsAJAXUpload||(e=".uploadFallbackButton"),this._buttonSelector.find(e).remove()},_upload:function(e,t,i,n){var s=null,a=[];if(void 0!==n)a=n;else if(t)a.push(t);else if(i){var o="";switch(i.type){case"image/png":o=".png";break;case"image/jpeg":o=".jpg";break;case"image/gif":o=".gif"}a.push({name:"pasted-from-clipboard"+o})}else a=this._fileUpload.prop("files");if(a.length){var r=new FormData,s=this._createUploadMatrix(a);if(!this._uploadMatrix[s].length)return null;for(var l,c=0,u=a.length;c<u;c++){this._uploadMatrix[s][c]&&(l=this._uploadMatrix[s][c].data("internalFileID"),i?r.append("__files["+l+"]",i,a[c].name):r.append("__files["+l+"]",a[c],a[c].name))}r.append("actionName",this._options.action),r.append("className",this._className);var h=this._getParameters();for(var d in h)r.append("parameters["+d+"]",h[d]);var p=this;$.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:r,contentType:!1,processData:!1,success:function(e,t,i){p._success(s,e)},error:$.proxy(this._error,this),xhr:function(){var e=$.ajaxSettings.xhr();return e&&e.upload.addEventListener("progress",function(e){p._progress(s,e)},!1),e},xhrFields:{withCredentials:!0}})}return s},_createUploadMatrix:function(e){if(e.length){var t=this._uploadMatrix.length;this._uploadMatrix[t]=[];for(var i=0,n=e.length;i<n;i++){var s=e[i],a=this._initFile(s);a.hasClass("uploadFailed")||(a.data("filename",s.name).data("internalFileID",this._internalFileID++),this._uploadMatrix[t][i]=a)}return t}return null},_success:function(e,t){},_error:function(e,t,i){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);for(var n in this._uploadMatrix[e])this._uploadMatrix[e][n].find("progress").attr("value",i)},_getParameters:function(){return{}},_initFile:function(e){return $("<li>"+e.name+" ("+e.size+')<progress max="100" /></li>').appendTo(this._fileListSelector)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix([e]),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)},_getFilename:function(){return $("#__fileUpload").val().split("\\").pop()}}),WCF.Upload.Parallel=WCF.Upload.extend({init:function(e,t,i,n){n=$.extend(!0,n||{},{multiple:!0}),this._super(e,t,i,n)},_upload:function(){for(var e=this._fileUpload.prop("files"),t=0,i=e.length;t<i;t++){var n=e[t],s=new FormData,a=this._createUploadMatrix(n);if(this._uploadMatrix[a].length){s.append("__files["+a+"]",n),s.append("actionName",this._options.action),s.append("className",this._className);var o=this._getParameters();for(var r in o)s.append("parameters["+r+"]",o[r]);this._sendRequest(a,s)}}},_sendRequest:function(n,e){var s=this;return $.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:e,contentType:!1,processData:!1,success:function(e,t,i){s._success(n,e)},error:$.proxy(this._error,this),xhr:function(){var e=$.ajaxSettings.xhr();return e&&e.upload.addEventListener("progress",function(e){s._progress(n,e)},!1),e}})},_createUploadMatrix:function(e){var t=this._initFile(e);return t.hasClass("uploadFailed")?null:(t.data("filename",e.name).data("internalFileID",this._internalFileID),this._uploadMatrix[this._internalFileID++]=t,this._internalFileID-1)},_success:function(e,t){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);this._uploadMatrix[e].find("progress").attr("value",i)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix(e),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)}}),WCF.Sortable={},WCF.Sortable.List=Class.extend({_additionalParameters:{},_className:"",_containerID:"",_container:null,_notification:null,_offset:0,_options:{},_proxy:null,_structure:{},init:function(e,t,i,n,s,a){this._additionalParameters=a||{},this._containerID=$.wcfEscapeID(e),this._container=$("#"+this._containerID),this._className=t,this._offset=i||0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._structure={},this._options=$.extend(!0,{axis:"y",connectWith:"#"+this._containerID+" .sortableList",disableNesting:"sortableNoNesting",doNotClear:!0,errorClass:"sortableInvalidTarget",forcePlaceholderSize:!0,handle:"",helper:"clone",items:"li:not(.sortableNoSorting)",opacity:.6,placeholder:"sortablePlaceholder",tolerance:"pointer",toleranceElement:"> span"},n||{});var o,r=$("#"+this._containerID+" .sortableList");if(r.is("tbody")&&("li:not(.sortableNoSorting)"===this._options.items&&(this._options.items="tr:not(.sortableNoSorting)",this._options.toleranceElement=""),"clone"===this._options.helper&&(this._options.helper=this._tableRowHelper.bind(this),(o=r.prev("thead"))&&o.find("th").each(function(e,t){(t=$(t)).width(t.width())}))),s?r.sortable(this._options):r.nestedSortable(this._options),this._className){var l=this._container.find(".formSubmit");if(!l.length&&!(l=this._container.next(".formSubmit")).length)return void console.debug("[WCF.Sortable.Simple] Unable to find form submit for saving, aborting.");l.children('button[data-type="submit"]').click($.proxy(this._submit,this))}},_tableRowHelper:function(e,t){return t.children("td").each(function(e,t){(t=$(t)).width(t.width())}),t},_submit:function(){this._structure={},this._container.find(".sortableList").each($.proxy(function(e,t){var i=$(t),n=i.data("objectID");void 0!==n&&i.children(this._options.items).each($.proxy(function(e,t){var i=$(t).data("objectID");this._structure[n]||(this._structure[n]=[]),this._structure[n].push(i)},this))},this));var e=$.extend(!0,{data:{offset:this._offset,structure:this._structure}},this._additionalParameters);this._proxy.setOption("data",{actionName:"updatePosition",className:this._className,interfaceName:"wcf\\data\\ISortableAction",parameters:e}),this._proxy.sendRequest()},_success:function(e,t,i){null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit"))),this._notification.show()}}),WCF.Popover=Class.extend({_activeElementID:"",_identifier:"",_popoverObj:null,init:function(t){var i=!1;require(["Environment"],function(e){"desktop"!==e.platform()&&(i=!0)}.bind(this)),i||(this._activeElementID="",this._identifier=t,require(["WoltLabSuite/Core/Controller/Popover"],function(e){e.init({attributeName:"legacy",className:t,identifier:this._identifier,legacy:!0,loadCallback:this._legacyLoad.bind(this)})}.bind(this)))},_initContainers:function(){},_legacyLoad:function(e,t){this._activeElementID=e,this._popoverObj=t,this._loadContent()},_insertContent:function(e,t){this._popoverObj.setContent(this._identifier,e,t)}}),WCF.EditableItemList=Class.extend({_allowCustomInput:!1,_className:"",_data:{},_form:null,_itemList:null,_objectID:0,_objectTypeID:0,_search:null,_searchInput:null,init:function(e,t){var i;this._itemList=$(e),this._searchInput=$(t),this._data={},this._itemList.length&&this._searchInput.length?(this._objectID=this._getObjectID(),this._objectTypeID=this._getObjectTypeID(),this._itemList.find(".jsEditableItem").click($.proxy(this._click,this)),this._itemList.children("ul").length||$("<ul />").appendTo(this._itemList),this._itemList=this._itemList.children("ul"),this._form=this._itemList.parents("form").submit($.proxy(this._submit,this)),this._allowCustomInput&&(i=this)._searchInput.keydown($.proxy(this._keyDown,this)).keypress($.proxy(this._keyPress,this)).on("paste",function(){setTimeout(function(){i._onPaste()},100)}),this._searchInput.parents(".dropdown").data("preventSubmit",!0)):console.debug("[WCF.EditableItemList] Item list and/or search input do not exist, aborting.")},_keyDown:function(e){return null!==e||this._keyPress(null)},_keyPress:function(e){if(null===e||44===e.charCode||e.charCode===$.ui.keyCode.ENTER||$.browser.mozilla&&e.keyCode===$.ui.keyCode.ENTER){if(null!==e&&e.charCode===$.ui.keyCode.ENTER&&this._search&&-1!==this._search._itemIndex)return!1;var t=$.trim(this._searchInput.val());return(e&&44===e.charCode&&(t=t.substring(0,this._searchInput.getCaret())),""===t)?!0:(this.addItem({objectID:0,label:t}),e&&44===e.charCode?this._searchInput.val($.trim(this._searchInput.val().substr(this._searchInput.getCaret()))):this._searchInput.val(""),null!==e&&e.stopPropagation(),!1)}return!0},_onPaste:function(){for(var e=$.trim(this._searchInput.val()),t=0,i=(e=e.split(",")).length;t<i;t++){var n=$.trim(e[t]);""!==n&&this.addItem({objectID:0,label:n})}this._searchInput.val("")},load:function(e){},_click:function(e){var t=$(e.currentTarget),i=t.data("objectID"),n=t.data("label");return this._search&&this._search.removeExcludedSearchValue(n),this._removeItem(i,n),t.remove(),e.stopPropagation(),!1},_getObjectID:function(){return 0},_getObjectTypeID:function(){return 0},addItem:function(e){return(!this._data[e.objectID]||0===e.objectID&&this._allowCustomInput)&&($('<li class="badge">'+WCF.String.escapeHTML(e.label)+"</li>").data("objectID",e.objectID).data("label",e.label).appendTo(this._itemList).click($.proxy(this._click,this)),this._search&&this._search.addExcludedSearchValue(e.label),this._addItem(e.objectID,e.label)),!0},clearList:function(){this._itemList.children("li").each($.proxy(function(e,t){var i=$(t);this._search&&this._search.removeExcludedSearchValue(i.data("label")),i.remove(),this._removeItem(i.data("objectID"),i.data("label"))},this))},_submit:function(){this._keyDown(null)},_addItem:function(e,t){this._data[e]=t},_removeItem:function(e,t){delete this._data[e]},getSearchInput:function(){return this._searchInput}}),WCF.Language.Chooser=Class.extend({init:function(t,i,n,s,a,o){require(["WoltLabSuite/Core/Language/Chooser"],function(e){e.init(t,i,n,s,a,o)})}}),WCF.Style={},WCF.UserPanel=Class.extend({_container:null,_didLoad:!1,_link:null,_noItems:"",_revertOnEmpty:!0,init:function(e){this._container=$("#"+e),this._didLoad=!1,this._revertOnEmpty=!0,1==this._container.length?this._convert():console.debug("[WCF.UserPanel] Unable to find container identified by '"+e+"', aborting.")},_convert:function(){this._container.addClass("dropdown"),this._link=this._container.children("a").remove();var e=$('<a href="'+this._link.attr("href")+'" class="dropdownToggle">'+this._link.html()+"</a>").appendTo(this._container).click($.proxy(this._click,this)),t=$('<ul class="dropdownMenu" />').appendTo(this._container);$('<li class="jsDropdownPlaceholder"><span>'+WCF.Language.get("wcf.global.loading")+"</span></li>").appendTo(t),this._addDefaultItems(t),this._container.dblclick($.proxy(function(){return window.location=this._link.attr("href"),!1},this)),WCF.Dropdown.initDropdown(e,!1)},_addDefaultItems:function(e){},_addDivider:function(e){$('<li class="dropdownDivider" />').appendTo(e)},_click:function(e){e.preventDefault(),this._didLoad||(new WCF.Action.Proxy({autoSend:!0,data:this._getParameters(),success:$.proxy(this._success,this)}),this._didLoad=!0)},_getParameters:function(){return{}},_success:function(e,t,i){var n=WCF.Dropdown.getDropdownMenu(this._container.wcfIdentify());n.children(".jsDropdownPlaceholder").remove(),e.returnValues&&e.returnValues.template?($(""+e.returnValues.template).prependTo(n),this._updateBadge(e.returnValues.totalCount),this._after(n)):($("<li><span>"+WCF.Language.get(this._noItems)+"</span></li>").prependTo(n),this._updateBadge(0))},_updateBadge:function(e){var t;(e=parseInt(e)||0)?((t=this._container.find(".badge")).length||(t=$('<span class="badge badgeUpdate" />').appendTo(this._container.children(".dropdownToggle"))).before(" "),t.html(e)):this._container.find(".badge").remove()},_after:function(e){}}),jQuery.fn.extend({wcfDialog:function(s){var a=arguments;return require(["Dom/Util","Ui/Dialog"],function(e,t){var i,n=e.identify(this[0]);"close"===s?t.close(n):"render"===s?t.rebuild(n):"option"===s?3===a.length&&("title"===a[1]&&"string"==typeof a[2]?t.setTitle(n,a[2]):0===a[1].indexOf("on")?t.setCallback(n,a[1],a[2]):"closeConfirmMessage"===a[1]&&null===a[2]&&t.setCallback(n,"onBeforeClose",null)):(this[0].parentNode.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&document.body.appendChild(this[0]),i=1===a.length&&"object"==typeof a[0]?a[0]:{},t.openStatic(n,null,i),i.hasOwnProperty("title")&&t.setTitle(n,i.title))}.bind(this)),this}}),$.widget("ui.wcfSlideshow",{_buttonList:null,_count:0,_index:0,_itemList:null,_items:null,_timer:null,_width:0,options:{cycle:!0,cycleInterval:5,itemGap:50},_create:function(){this._itemList=this.element.children("ul"),this._items=this._itemList.children("li"),this._count=this._items.length,this._index=0,1<this._count&&this._initSlideshow()},_initSlideshow:function(){var i=$(this._items.get(0)).outerHeight();this._items.addClass("slideshowItem"),this._width=this.element.css("height",i).innerWidth(),this._itemList.addClass("slideshowItemList").css("left",0),this._items.each($.proxy(function(e,t){$(t).show().css({height:i,left:(this._width+this.options.itemGap)*e,width:this._width})},this)),this.element.css({height:i,width:this._width}).hover($.proxy(this._hoverIn,this),$.proxy(this._hoverOut,this)),this._buttonList=$('<ul class="slideshowButtonList" />').appendTo(this.element);for(var e=0;e<this._count;e++){var t=$('<li><a><span class="icon icon16 fa-circle" /></a></li>').data("index",e).click($.proxy(this._click,this)).appendTo(this._buttonList);0==e&&t.find(".icon").addClass("active")}this._resetTimer(),$(window).resize($.proxy(this._resize,this))},rebuildHeight:function(){var e=$(this._items.get(0)).css("height","auto").outerHeight();this._items.css("height",e+"px"),this.element.css("height",e+"px")},_resize:function(){this._width=this.element.css("width","auto").innerWidth(),this._items.each($.proxy(function(e,t){$(t).css({left:(this._width+this.options.itemGap)*e,width:this._width})},this)),this._index--,this.moveTo(null)},_hoverIn:function(){null!==this._timer&&this._timer.stop()},_hoverOut:function(){this._resetTimer()},_resetTimer:function(){var e;this.options.cycle&&(null!==this._timer&&this._timer.stop(),(e=this)._timer=new WCF.PeriodicalExecuter(function(){e.moveTo(null)},1e3*this.options.cycleInterval))},_click:function(e){this.moveTo($(e.currentTarget).data("index")),this._resetTimer()},moveTo:function(e){this._index=null===e?this._index+1:e,this._index==this._count&&(this._index=0),$(this._buttonList.find(".icon").removeClass("active").get(this._index)).addClass("active"),this._itemList.css("left",this._index*(this._width+this.options.itemGap)*-1),this._trigger("moveTo",null,{index:this._index})},getItem:function(e){return this._items[e]?this._items[e]:null}}),jQuery.fn.extend({datepicker:function(e){var t=this[0],i=Array.prototype.slice.call(arguments,1);switch(e){case"destroy":window.__wcf_bc_datePicker.destroy(t);break;case"getDate":return window.__wcf_bc_datePicker.getDate(t);case"option":if("onClose"===i[0])return 1<i.length?this.datepicker("setOption","onClose",i[1]):function(){};console.warn("datepicker('option') supports only 'onClose'.");break;case"setDate":window.__wcf_bc_datePicker.setDate(t,i[0]);break;case"setOption":"onClose"===i[0]?window.__wcf_bc_datePicker.setCloseCallback(t,i[1]):console.warn("datepicker('setOption') supports only 'onClose'.");break;default:console.debug("Unsupported method '"+e+"' for datepicker()")}return this}}),jQuery.fn.extend({wcfTabs:function(n){var s=this[0],a=Array.prototype.slice.call(arguments,1);require(["Dom/Util","WoltLabSuite/Core/Ui/TabMenu"],function(e,t){var i=t.getTabMenu(e.identify(s));null!==i&&i[n].apply(i,a)})}}),$.widget("ui.wcfPages",{_api:null,SHOW_LINKS:11,SHOW_SUB_LINKS:20,options:{activePage:1,maxPage:1},_create:function(){require(["WoltLabSuite/Core/Ui/Pagination"],function(e){this._api=new e(this.element[0],{activePage:this.options.activePage,maxPage:this.options.maxPage,callbackShouldSwitch:function(e){return!1!==this._trigger("shouldSwitch",void 0,{nextPage:e})}.bind(this),callbackSwitch:function(e){this._trigger("switched",void 0,{activePage:e})}.bind(this)})}.bind(this))},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this._api=null,this.element[0].innerHTML=""},_setOption:function(e,t){var i;return"activePage"==e&&t!=this.options[e]&&0<t&&t<=this.options.maxPage&&((i=this._trigger("shouldSwitch",void 0,{nextPage:t}))||void 0!==i?this._api.switchPage(t):this._trigger("notSwitched",void 0,{activePage:t})),this}}),WCF.Category={},WCF.Category.NestedList=Class.extend({_categories:{},init:function(){var a=this;$(".jsCategory").each(function(e,t){var n=$(t).data("parentCategoryID",null).change($.proxy(a._updateSelection,a));a._categories[n.val()]=n;var s=[];n.parents("li").find(".jsChildCategory").each(function(e,t){var i=$(t).data("parentCategoryID",n.val()).change($.proxy(a._updateSelection,a));a._categories[i.val()]=i,s.push(i.val()),i.is(":checked")&&n.prop("checked","checked")}),n.data("childCategoryIDs",s)})},_updateSelection:function(e){var t=$(e.currentTarget),i=t.data("parentCategoryID");if(t.is(":checked"))null!==i&&this._categories[i].prop("checked","checked");else if(null===i)for(var n=t.data("childCategoryIDs"),s=0,a=n.length;s<a;s++)this._categories[n[s]].prop("checked",!1)}}),WCF.Category.FlexibleCategoryList=Class.extend({_list:null,_categories:{},init:function(e){this._list=$("#"+e),this._buildStructure(),this._list.find("input:checked").each(function(){$(this).trigger("change")}),this._list.children("li").length<2&&this._list.addClass("flexibleCategoryListDisabled")},_buildStructure:function(){var r=this;this._list.find(".jsCategory").each(function(e,t){var a=$(t).change(r._updateSelection.bind(r)),i=parseInt(a.val()),o=[];a.parents("li:eq(0)").find(".jsChildCategory").each(function(e,t){var n=$(t);n.data("parentCategory",a).change(r._updateSelection.bind(r));var i=parseInt(n.val());o.push(n);var s=[];n.parents("li:eq(0)").find(".jsSubChildCategory").each(function(e,t){var i=$(t);i.data("parentCategory",n).change(r._updateSelection.bind(r)),s.push(i)}),r._categories[i]=s}),r._categories[i]=o})},_updateSelection:function(e){var t=$(e.currentTarget),i=parseInt(t.val()),n=t.data("parentCategory");if(t.is(":checked"))n&&(n.prop("checked","checked"),(n=n.data("parentCategory"))&&n.prop("checked","checked"));else{if(this._categories[i])for(var s=0,a=this._categories[i].length;s<a;s++){var o=this._categories[i][s];o.prop("checked",!1);var r=parseInt(o.val());if(this._categories[r])for(var l=0,c=this._categories[r].length;l<c;l++)this._categories[r][l].prop("checked",!1)}if(n){for(var u=parseInt(n.val()),s=0,a=this._categories[u].length;s<a;s++)if(this._categories[u][s].prop("checked"))return;if(n=n.data("parentCategory")){u=parseInt(n.val());for(s=0,a=this._categories[u].length;s<a;s++)if(this._categories[u][s].prop("checked"))return}}}}}),WCF.Condition={},WCF.Notice={}; })(this);
 
 // WCF.Like.js
 (function (window, undefined) { "use strict";WCF.Like=Class.extend({init:function(){throw new Error("The `WCF.Like` API is obsolete and therefore no longer supported. Please use the current API `WoltLabSuite/Core/Ui/Reaction/Handler` instead.")},_domNodeInserted:function(){},_initContainers:function(){},_getContainers:function(){},_getWidgetContainer:function(){},_getObjectID:function(){},_addWidget:function(){},_buildWidget:function(){},_createWidget:function(){},_showLikeDetails:function(){},_click:function(){},_sendRequest:function(){},_success:function(){},_updateBadge:function(){},_updateSummary:function(){},_setActiveState:function(){}}); })(this);
 
 // WCF.ACL.js
-(function (window, undefined) { "use strict";WCF.ACL={},WCF.ACL.List=Class.extend({_categoryName:"",_container:null,_containerElements:{},_objectID:0,_objectTypeID:null,_options:{},_proxy:null,_search:null,_values:{group:{},user:{}},init:function(e,t,n,i,a,s,r){this._objectID=i||0,this._objectTypeID=t,this._categoryName=n,void 0===a&&(a=!0),this._values={group:{},user:{}},this._aclValuesFieldName=r||"aclValues",this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._container=$(e).hide().addClass("aclContainer");var c=this._container.children("dd"),l=$('<ul class="aclList containerList" />').appendTo(c),o=$('<input type="text" class="long" placeholder="'+WCF.Language.get("wcf.acl.search."+(a?"":"user.")+"description")+'" />').appendTo(c),h=$('<ul class="aclPermissionList containerList" />').hide().appendTo(c);elData(h[0],"grant",WCF.Language.get("wcf.acl.option.grant")),elData(h[0],"deny",WCF.Language.get("wcf.acl.option.deny")),this._containerElements={aclList:l,denyAll:null,grantAll:null,permissionList:h,searchInput:o},this._search=new WCF.Search.User(o,$.proxy(this.addObject,this),a);var p=this._container.parents("form:eq(0)");p.submit($.proxy(this.submit,this));var d=p.find("input[type=reset]:eq(0)");d.length&&d.click($.proxy(this._reset,this)),s?this._success(s):this._loadACL()},_reset:function(){this._values={group:{},user:{}},this._containerElements.aclList.empty(),this._containerElements.searchInput.val(""),this._containerElements.permissionList.hide().find("input[type=checkbox]").prop("checked",!1)},_loadACL:function(){this._proxy.setOption("data",{actionName:"loadAll",className:"wcf\\data\\acl\\option\\ACLOptionAction",parameters:{categoryName:this._categoryName,objectID:this._objectID,objectTypeID:this._objectTypeID}}),this._proxy.sendRequest()},addObject:function(e){var t=this._createListItem(e.objectID,e.label,e.type);this._savePermissions(),this._containerElements.aclList.children("li").removeClass("active"),t.addClass("active"),this._search.addExcludedSearchValue(e.label),this._containerElements.permissionList.find("input[type=checkbox]").prop("checked",!1),this._containerElements.searchInput.val(""),this._containerElements.permissionList.show(),WCF.DOMNodeInsertedHandler.execute()},_createListItem:function(e,t,n){var i=$('<li><span class="icon icon16 fa-user'+("group"===n?"s":"")+'" /> <span class="aclLabel">'+t+"</span></li>").appendTo(this._containerElements.aclList);return i.data("objectID",e).data("type",n).data("label",t).click($.proxy(this._click,this)),$('<span class="icon icon16 fa-times jsTooltip pointer" title="'+WCF.Language.get("wcf.global.button.delete")+'" />').click($.proxy(this._removeItem,this)).appendTo(i),i},_removeItem:function(e){var t=$(e.currentTarget).parent(),n=t.data("type"),i=t.data("objectID");this._search.removeExcludedSearchValue(t.data("label")),t.remove(),this._values[n][i]&&delete this._values[n][i],this._selectFirstEntry()},_selectFirstEntry:function(){var e=this._containerElements.aclList.children("li:eq(0)");e.length?this._select(e,!1):this._reset()},_success:function(e,t,n){if($.getLength(e.returnValues.options)){var i=0,a={};for(var s in e.returnValues.options){var r=e.returnValues.options[s],c=$("<li><span>"+r.label+"</span></li>").data("optionID",s).data("optionName",r.optionName),l=$('<input type="checkbox" id="grant'+s+'" />').appendTo(c).wrap('<label for="grant'+s+'" class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.grant")+'" />'),o=$('<input type="checkbox" id="deny'+s+'" />').appendTo(c).wrap('<label for="deny'+s+'" class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.deny")+'" />');l.data("type","grant").data("optionID",s).change($.proxy(this._change,this)),o.data("type","deny").data("optionID",s).change($.proxy(this._change,this)),a[r.categoryName]||(a[r.categoryName]=[]),""===r.categoryName?c.appendTo(this._containerElements.permissionList):a[r.categoryName].push(c),i++}if(i>1){var c=$('<li class="aclFullAccess"><span>'+WCF.Language.get("wcf.acl.option.fullAccess")+"</span></li>").prependTo(this._containerElements.permissionList);this._containerElements.grantAll=$('<input type="checkbox" id="grantAll_'+this._container.attr("id")+'" />').appendTo(c).wrap('<label class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.grant")+'" />'),this._containerElements.denyAll=$('<input type="checkbox" id="denyAll_'+this._container.attr("id")+'" />').appendTo(c).wrap('<label class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.deny")+'" />'),this._containerElements.grantAll.data("type","grant").change($.proxy(this._changeAll,this)),this._containerElements.denyAll.data("type","deny").change($.proxy(this._changeAll,this))}if($.getLength(a))for(var h in a){var p=a[h];e.returnValues.categories[h]&&$('<li class="aclCategory">'+e.returnValues.categories[h]+"</li>").appendTo(this._containerElements.permissionList);for(var d=0,u=p.length;d<u;d++)p[d].appendTo(this._containerElements.permissionList)}this._parseData(e,"group"),this._parseData(e,"user"),this._container.show(),require(["WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager"],function(e){e.checkDependencies()}),this._selectFirstEntry()}},_parseData:function(e,t){if($.getLength(e.returnValues[t].option)){for(var n in e.returnValues[t].label)this._createListItem(n,e.returnValues[t].label[n],t),this._search.addExcludedSearchValue(e.returnValues[t].label[n]);this._values[t]=e.returnValues[t].option,WCF.DOMNodeInsertedHandler.execute()}},_click:function(e){var t=$(e.currentTarget);t.hasClass("active")||this._select(t,!0)},_select:function(e,t){t&&this._savePermissions(),this._containerElements.aclList.children("li").removeClass("active"),e.addClass("active"),this._setupPermissions(e.data("type"),e.data("objectID"))},_change:function(e){var t=$(e.currentTarget),n=t.data("optionID"),i=t.data("type");t.is(":checked")?"deny"===i?($("#grant"+n).prop("checked",!1),null!==this._containerElements.grantAll&&this._containerElements.grantAll.prop("checked",!1)):($("#deny"+n).prop("checked",!1),null!==this._containerElements.denyAll&&this._containerElements.denyAll.prop("checked",!1)):"deny"===i&&null!==this._containerElements.denyAll?this._containerElements.denyAll.prop("checked",!1):"grant"===i&&null!==this._containerElements.grantAll&&this._containerElements.grantAll.prop("checked",!1);var a=!0;this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);if(n.data("type")===i&&n.attr("id")!==i+"All_"+this._container.attr("id")&&!n.is(":checked"))return a=!1,!1},this)),"deny"==i?null!==this._containerElements.denyAll&&(a?this._containerElements.denyAll.prop("checked",!0):this._containerElements.denyAll.prop("checked",!1)):null!==this._containerElements.grantAll&&(a?this._containerElements.grantAll.prop("checked",!0):this._containerElements.grantAll.prop("checked",!1))},_changeAll:function(e){var t=$(e.currentTarget),n=t.data("type");t.is(":checked")?"deny"===n?(this._containerElements.grantAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"deny"===n.data("type")&&n.attr("id")!=="denyAll_"+this._container.attr("id")&&n.prop("checked",!0).trigger("change")},this))):(this._containerElements.denyAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"grant"===n.data("type")&&n.attr("id")!=="grantAll_"+this._container.attr("id")&&n.prop("checked",!0).trigger("change")},this))):"deny"===n?(this._containerElements.grantAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"deny"===n.data("type")&&n.attr("id")!=="denyAll_"+this._container.attr("id")&&n.prop("checked",!1).trigger("change")},this))):(this._containerElements.denyAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"grant"===n.data("type")&&n.attr("id")!=="grantAll_"+this._container.attr("id")&&n.prop("checked",!1).trigger("change")},this)))},_setupPermissions:function(e,t){if(this._containerElements.permissionList.find("input[type='checkbox']").prop("checked",!1),this._values[e]&&this._values[e][t])for(var n in this._values[e][t])1==this._values[e][t][n]?$("#grant"+n).prop("checked",!0).trigger("change"):$("#deny"+n).prop("checked",!0).trigger("change");this._containerElements.permissionList.show()},_savePermissions:function(){var e=this._containerElements.aclList.find("li.active");if(e.length){var t=e.data("objectID"),n=e.data("type");this._values[n][t]={},this._containerElements.permissionList.find("input[type='checkbox']").each(function(e,i){var a=$(i);if(a.attr("id")!="grantAll_"+this._container.attr("id")&&a.attr("id")!="denyAll_"+this._container.attr("id")){var s="deny"===a.data("type")?0:1,r=a.data("optionID");a.is(":checked")?(this._values[n][t][r]=s,a.prop("checked",!1)):this._values[n]&&this._values[n][t]&&this._values[n][t][r]&&this._values[n][t][r]==s&&delete this._values[n][t][r]}}.bind(this))}},submit:function(e){this._savePermissions(),this._save("group"),this._save("user")},_save:function(e){if($.getLength(this._values[e])){var t=this._container.parents("form:eq(0)");for(var n in this._values[e]){var i=this._values[e][n];for(var a in i)$('<input type="hidden" name="'+this._aclValuesFieldName+"["+e+"]["+n+"]["+a+']" value="'+i[a]+'" />').appendTo(t)}}},getData:function(){return this._savePermissions(),this._values}}); })(this);
+(function (window, undefined) { "use strict";WCF.ACL={},WCF.ACL.List=Class.extend({_categoryName:"",_container:null,_containerElements:{},_objectID:0,_objectTypeID:null,_options:{},_proxy:null,_search:null,_values:{group:{},user:{}},init:function(e,t,n,i,a,s,r){this._objectID=i||0,this._objectTypeID=t,this._categoryName=n,void 0===a&&(a=!0),this._values={group:{},user:{}},this._aclValuesFieldName=r||"aclValues",this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._container=$(e).hide().addClass("aclContainer");var c=this._container.children("dd"),l=$('<ul class="aclList containerList" />').appendTo(c),o=$('<input type="text" class="long" placeholder="'+WCF.Language.get("wcf.acl.search."+(a?"":"user.")+"description")+'" />').appendTo(c),h=$('<ul class="aclPermissionList containerList" />').hide().appendTo(c);elData(h[0],"grant",WCF.Language.get("wcf.acl.option.grant")),elData(h[0],"deny",WCF.Language.get("wcf.acl.option.deny")),this._containerElements={aclList:l,denyAll:null,grantAll:null,permissionList:h,searchInput:o},this._search=new WCF.Search.User(o,$.proxy(this.addObject,this),a);var p=this._container.parents("form:eq(0)");p.submit($.proxy(this.submit,this));var d=p.find("input[type=reset]:eq(0)");d.length&&d.click($.proxy(this._reset,this)),s?this._success(s):this._loadACL()},_reset:function(){this._values={group:{},user:{}},this._containerElements.aclList.empty(),this._containerElements.searchInput.val(""),this._containerElements.permissionList.hide().find("input[type=checkbox]").prop("checked",!1)},_loadACL:function(){this._proxy.setOption("data",{actionName:"loadAll",className:"wcf\\data\\acl\\option\\ACLOptionAction",parameters:{categoryName:this._categoryName,objectID:this._objectID,objectTypeID:this._objectTypeID}}),this._proxy.sendRequest()},addObject:function(e){var t=this._createListItem(e.objectID,e.label,e.type);this._savePermissions(),this._containerElements.aclList.children("li").removeClass("active"),t.addClass("active"),this._search.addExcludedSearchValue(e.label),this._containerElements.permissionList.find("input[type=checkbox]").prop("checked",!1),this._containerElements.searchInput.val(""),this._containerElements.permissionList.show(),WCF.DOMNodeInsertedHandler.execute()},_createListItem:function(e,t,n){var i=$('<li><span class="icon icon16 fa-user'+("group"===n?"s":"")+'" /> <span class="aclLabel">'+t+"</span></li>").appendTo(this._containerElements.aclList);return i.data("objectID",e).data("type",n).data("label",t).click($.proxy(this._click,this)),$('<span class="icon icon16 fa-times jsTooltip pointer" title="'+WCF.Language.get("wcf.global.button.delete")+'" />').click($.proxy(this._removeItem,this)).appendTo(i),i},_removeItem:function(e){var t=$(e.currentTarget).parent(),n=t.data("type"),i=t.data("objectID");this._search.removeExcludedSearchValue(t.data("label")),t.remove(),this._values[n][i]&&delete this._values[n][i],this._selectFirstEntry()},_selectFirstEntry:function(){var e=this._containerElements.aclList.children("li:eq(0)");e.length?this._select(e,!1):this._reset()},_success:function(e,t,n){if($.getLength(e.returnValues.options)){var i=0,a={};for(var s in e.returnValues.options){var r=e.returnValues.options[s],c=$("<li><span>"+r.label+"</span></li>").data("optionID",s).data("optionName",r.optionName),l=$('<input type="checkbox" id="grant'+s+'" />').appendTo(c).wrap('<label for="grant'+s+'" class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.grant")+'" />'),o=$('<input type="checkbox" id="deny'+s+'" />').appendTo(c).wrap('<label for="deny'+s+'" class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.deny")+'" />');l.data("type","grant").data("optionID",s).change($.proxy(this._change,this)),o.data("type","deny").data("optionID",s).change($.proxy(this._change,this)),a[r.categoryName]||(a[r.categoryName]=[]),""===r.categoryName?c.appendTo(this._containerElements.permissionList):a[r.categoryName].push(c),i++}if(1<i&&(c=$('<li class="aclFullAccess"><span>'+WCF.Language.get("wcf.acl.option.fullAccess")+"</span></li>").prependTo(this._containerElements.permissionList),this._containerElements.grantAll=$('<input type="checkbox" id="grantAll_'+this._container.attr("id")+'" />').appendTo(c).wrap('<label class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.grant")+'" />'),this._containerElements.denyAll=$('<input type="checkbox" id="denyAll_'+this._container.attr("id")+'" />').appendTo(c).wrap('<label class="jsTooltip" title="'+WCF.Language.get("wcf.acl.option.deny")+'" />'),this._containerElements.grantAll.data("type","grant").change($.proxy(this._changeAll,this)),this._containerElements.denyAll.data("type","deny").change($.proxy(this._changeAll,this))),$.getLength(a))for(var h in a){var p=a[h];e.returnValues.categories[h]&&$('<li class="aclCategory">'+e.returnValues.categories[h]+"</li>").appendTo(this._containerElements.permissionList);for(var d=0,u=p.length;d<u;d++)p[d].appendTo(this._containerElements.permissionList)}this._parseData(e,"group"),this._parseData(e,"user"),this._container.show(),require(["WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager"],function(e){e.checkDependencies()}),this._selectFirstEntry()}},_parseData:function(e,t){if($.getLength(e.returnValues[t].option)){for(var n in e.returnValues[t].label)this._createListItem(n,e.returnValues[t].label[n],t),this._search.addExcludedSearchValue(e.returnValues[t].label[n]);this._values[t]=e.returnValues[t].option,WCF.DOMNodeInsertedHandler.execute()}},_click:function(e){var t=$(e.currentTarget);t.hasClass("active")||this._select(t,!0)},_select:function(e,t){t&&this._savePermissions(),this._containerElements.aclList.children("li").removeClass("active"),e.addClass("active"),this._setupPermissions(e.data("type"),e.data("objectID"))},_change:function(e){var t=$(e.currentTarget),n=t.data("optionID"),i=t.data("type");t.is(":checked")?"deny"===i?($("#grant"+n).prop("checked",!1),null!==this._containerElements.grantAll&&this._containerElements.grantAll.prop("checked",!1)):($("#deny"+n).prop("checked",!1),null!==this._containerElements.denyAll&&this._containerElements.denyAll.prop("checked",!1)):"deny"===i&&null!==this._containerElements.denyAll?this._containerElements.denyAll.prop("checked",!1):"grant"===i&&null!==this._containerElements.grantAll&&this._containerElements.grantAll.prop("checked",!1);var a=!0;this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);if(n.data("type")===i&&n.attr("id")!==i+"All_"+this._container.attr("id")&&!n.is(":checked"))return a=!1},this)),"deny"==i?null!==this._containerElements.denyAll&&(a?this._containerElements.denyAll.prop("checked",!0):this._containerElements.denyAll.prop("checked",!1)):null!==this._containerElements.grantAll&&(a?this._containerElements.grantAll.prop("checked",!0):this._containerElements.grantAll.prop("checked",!1))},_changeAll:function(e){var t=$(e.currentTarget),n=t.data("type");t.is(":checked")?"deny"===n?(this._containerElements.grantAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"deny"===n.data("type")&&n.attr("id")!=="denyAll_"+this._container.attr("id")&&n.prop("checked",!0).trigger("change")},this))):(this._containerElements.denyAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"grant"===n.data("type")&&n.attr("id")!=="grantAll_"+this._container.attr("id")&&n.prop("checked",!0).trigger("change")},this))):"deny"===n?(this._containerElements.grantAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"deny"===n.data("type")&&n.attr("id")!=="denyAll_"+this._container.attr("id")&&n.prop("checked",!1).trigger("change")},this))):(this._containerElements.denyAll.prop("checked",!1),this._containerElements.permissionList.find("input[type=checkbox]").each($.proxy(function(e,t){var n=$(t);"grant"===n.data("type")&&n.attr("id")!=="grantAll_"+this._container.attr("id")&&n.prop("checked",!1).trigger("change")},this)))},_setupPermissions:function(e,t){if(this._containerElements.permissionList.find("input[type='checkbox']").prop("checked",!1),this._values[e]&&this._values[e][t])for(var n in this._values[e][t])1==this._values[e][t][n]?$("#grant"+n).prop("checked",!0).trigger("change"):$("#deny"+n).prop("checked",!0).trigger("change");this._containerElements.permissionList.show()},_savePermissions:function(){var s,r,e=this._containerElements.aclList.find("li.active");e.length&&(s=e.data("objectID"),r=e.data("type"),this._values[r][s]={},this._containerElements.permissionList.find("input[type='checkbox']").each(function(e,t){var n,i,a=$(t);a.attr("id")!="grantAll_"+this._container.attr("id")&&a.attr("id")!="denyAll_"+this._container.attr("id")&&(n="deny"===a.data("type")?0:1,i=a.data("optionID"),a.is(":checked")?(this._values[r][s][i]=n,a.prop("checked",!1)):this._values[r]&&this._values[r][s]&&this._values[r][s][i]&&this._values[r][s][i]==n&&delete this._values[r][s][i])}.bind(this)))},submit:function(e){this._savePermissions(),this._save("group"),this._save("user")},_save:function(e){if($.getLength(this._values[e])){var t=this._container.parents("form:eq(0)");for(var n in this._values[e]){var i=this._values[e][n];for(var a in i)$('<input type="hidden" name="'+this._aclValuesFieldName+"["+e+"]["+n+"]["+a+']" value="'+i[a]+'" />').appendTo(t)}}},getData:function(){return this._savePermissions(),this._values}}); })(this);
 
 // WCF.Attachment.js
-(function (window, undefined) { "use strict";WCF.Attachment={},WCF.Attachment.Upload=WCF.Upload.extend({_autoInsert:[],_insertAllButton:null,_objectType:"",_objectID:0,_tmpHash:"",_parentObjectID:0,_editorId:"",_replaceOnLoad:{},_options:{},init:function(t,e,a,i,s,n,r,l,o){if(this._super(t,e,"wcf\\data\\attachment\\AttachmentAction",{multiple:!0,maxUploads:r}),this._autoInsert=[],this._objectType=a,this._objectID=parseInt(i),this._tmpHash=s,this._parentObjectID=parseInt(n),this._editorId=l,this._options=$.extend(!0,this._options,o||{}),this._buttonSelector.children("p.button").click($.proxy(this._validateLimit,this)),this._fileListSelector.find(".jsButtonInsertAttachment").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertThumbnail").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertFull").click($.proxy(this._insert,this)),WCF.DOMNodeRemovedHandler.addCallback("WCF.Attachment.Upload",$.proxy(this._removeLimitError,this)),WCF.System.Event.addListener("com.woltlab.wcf.action.delete","attachment_"+this._editorId,$.proxy(this._removeLimitError,this)),this._makeSortable(),this._insertAllButton=$('<p class="button jsButtonAttachmentInsertAll">'+WCF.Language.get("wcf.attachment.insertAll")+"</p>").hide(),this._editorId){this._insertAllButton.appendTo(this._buttonSelector),this._insertAllButton.click($.proxy(this._insertAll,this)),this._fileListSelector.children("li:not(.uploadFailed)").length&&this._insertAllButton.show(),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","submit_"+this._editorId,this._submitInline.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+this._editorId,this._reset.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId,function(t){t.tmpHashes&&Array.isArray(t.tmpHashes)||(t.tmpHashes=[]);var e=t.tmpHashes.indexOf(s);this._fileListSelector.children("li:not(.uploadFailed)").length>0?-1===e&&t.tmpHashes.push(s):-1!==e&&t.tmpHashes.splice(e)}.bind(this));var d=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,function(t){var e=this._getImageAttachments(),a=t.attributes[0]||0;if(e.hasOwnProperty(a)){var i=~~$("#"+this._editorId).data("redactor").opts.woltlab.attachmentThumbnailWidth,s=t.attributes[2];s=!0===s||"true"===s||~~s&&~~s<=i;var n=elCreate("img");n.className="woltlabAttachment",n.src=e[a][s?"thumbnailUrl":"url"],elData(n,"attachment-id",a);var r=t.attributes[1]||"none";"left"===r?n.classList.add("messageFloatObjectLeft"):"right"===r&&n.classList.add("messageFloatObjectRight");var l=t.metacode;l.parentNode.insertBefore(n,l),elRemove(l),t.cancel=!0}}.bind(this));WCF.System.Event.addListener("com.woltlab.wcf.redactor2","destroy_"+this._editorId,function(){WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","submit_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","reset_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId),WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,d)}.bind(this))}},_editorUpload:function(t){var e=null;this._fileListSelector.closest(".messageTabMenu").messageTabMenu("showTab","attachments",!0);var a=function(a){null===e?this._autoInsert.push(a):this._replaceOnLoad[a]=e,t.uploadID=a}.bind(this);t.file?this._upload(void 0,t.file,void 0,a):(this._upload(void 0,void 0,t.blob,a),e=t.replace||null)},_getImageAttachments:function(){var t={};return this._fileListSelector.children("li").each(function(e,a){var i=$(a);i.data("isImage")&&(t[~~i.data("objectID")]={thumbnailUrl:i.find(".jsButtonAttachmentInsertThumbnail").data("url"),url:i.find(".jsButtonAttachmentInsertFull").data("url")})}),t},_submitInline:function(t){if(this._tmpHash){t.tmpHash=this._tmpHash;var e={};WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","getMetaData_"+this._editorId,e),e.tmpHashes&&Array.isArray(e.tmpHashes)&&e.tmpHashes.length>0&&(t.tmpHash+=","+e.tmpHashes.join(","))}},_reset:function(){this._fileListSelector.hide().empty(),this._insertAllButton.hide(),this._validateLimit()},_validateLimit:function(){var t=this._buttonSelector.next("small.innerError"),e=this._options.maxUploads-this._fileListSelector.children("li:not(.uploadFailed)").length,a=this._fileUpload?this._fileUpload.prop("files").length:0;if(e<=0||e<a){var i=e<=0?WCF.Language.get("wcf.attachment.upload.error.reachedLimit"):WCF.Language.get("wcf.attachment.upload.error.reachedRemainingLimit").replace(/#remaining#/,e);return t.length||(t=$('<small class="innerError" />').insertAfter(this._buttonSelector)),t.html(i),!1}return t.remove(),!0},_removeLimitError:function(t){var e=this._fileListSelector.children("li");e.filter(":not(.uploadFailed)").length||this._insertAllButton.hide(),e.length||this._fileListSelector.hide(),this._editorId&&t.button&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","deleteAttachment_"+this._editorId,{attachmentId:t.button.data("objectID")})},_upload:function(t,e,a,i){var s=this._super.bind(this);require(["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ImageUtil","WoltLabSuite/Core/Image/Resizer","WoltLabSuite/Core/Ajax/Status"],function(n,r,l,o){o.show();var d=[];e?d.push(e):a?d.push(n.blobToFile(a,"pasted-from-clipboard")):d=this._fileUpload.prop("files");var c=Promise.resolve(d);if(this._options.autoScale&&this._options.autoScale.enable){var h=this._buttonSelector.data("maxSize"),m=new l;c=Array.prototype.reduce.call(d,function(t,e){return t.then(function(t){var a=new Promise(function(t,a){setTimeout(function(){t(e)},1e4)}),i=m.loadFile(e).then(function(t){var i=t.exif,s=this._options.autoScale.maxWidth,n=this._options.autoScale.maxHeight,l=this._options.autoScale.quality;if(window.devicePixelRatio>=2){var o=window.screen.width*window.devicePixelRatio,d=window.screen.height*window.devicePixelRatio;o-10<t.image.width&&t.image.width<o+10&&d-10<t.image.height&&(s=Math.min(s,window.screen.width))}return m.resize(t.image,s,n,l,e.size>h,a).then(function(t){if(void 0===t)return e;var a=this._options.autoScale.fileType;return("keep"===this._options.autoScale.fileType||r.containsTransparentPixels(t))&&(a=e.type),m.saveFile({exif:i,image:t},e.name,a,l)}.bind(this)).then(function(t){return t.size>e.size?(console.debug('[WCF.Attachment] File size of "'+e.name+'" increased, uploading untouched image.'),e):t})}.bind(this)).catch(function(t){return console.debug('[WCF.Attachment] Failed to resize image "'+e.name+'":',t),e});return Promise.race([a,i]).then(function(e){return t.push(e),t})}.bind(this))}.bind(this),Promise.resolve([]))}c.then(function(e){var a=void 0;return this._validateLimit()&&(a=s(t,void 0,void 0,e)),this._fileUpload&&(this._removeButton(),this._createButton()),"function"==typeof i&&i(a),a}.bind(this)).catch(function(t){console.debug("[WCF.Attachment] Failed to upload attachments:",t)}).finally(o.hide)}.bind(this),function(t){console.debug("[WCF.Attachment] Failed to load modules:",t)})},_createUploadMatrix:function(t){return this._fileListSelector.children("li.uploadFailed").remove(),this._super(t)},_getParameters:function(){return{objectType:this._objectType,objectID:this._objectID,tmpHash:this._tmpHash,parentObjectID:this._parentObjectID}},_initFile:function(t){var e=$('<li class="box64"><span class="icon icon64 fa-spinner" /><div><div><p>'+t.name+'</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data("filename",t.name);return this._fileListSelector.append(e),this._fileListSelector.show(),this._buttonSelector.data("maxSize")<t.size&&(e.find("progress").remove(),e.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),e.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error.tooLarge")+"</small>")),e.addClass("uploadFailed")),e},_useThumbnail:function(){return elDataBool(this._fileListSelector[0],"enable-thumbnails")},_success:function(t,e){var a;for(var i in this._uploadMatrix[t])if(this._uploadMatrix[t].hasOwnProperty(i)){var s=this._uploadMatrix[t][i];s.find("progress").remove();var n=s.data("filename"),r=s.data("internalFileID");if(e.returnValues&&e.returnValues.attachments[r]){a=e.returnValues.attachments[r],a.tinyURL?(s.children(".fa-spinner").replaceWith($('<img src="'+a.tinyURL+'" alt="" class="attachmentTinyThumbnail" />')),s.data("height",a.height),s.data("width",a.width),elData(s[0],"is-image",a.isImage)):s.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-"+a.iconName);var l=$('<a href=""></a>');l.text(n).attr("href",a.url),l[0].target="_blank",0!=a.isImage&&l.addClass("jsImageViewer").attr("title",n),s.find("p").empty().append(l),s.find("small").append(a.formattedFilesize);var o=s.find("ul").addClass("buttonGroup"),d=$('<li><span class="button small jsDeleteButton" data-object-id="'+a.attachmentID+'" data-confirm-message="'+WCF.Language.get("wcf.attachment.delete.sure")+'" data-event-name="attachment_'+this._editorId+'">'+WCF.Language.get("wcf.global.button.delete")+"</span></li>");if(o.append(d),s.data("objectID",a.attachmentID),this._editorId)if(a.tinyURL||!this._useThumbnail()&&a.isImage){if(a.thumbnailURL){var c=$('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="'+a.attachmentID+'" data-url="'+WCF.String.escapeHTML(a.thumbnailURL)+'">'+WCF.Language.get("wcf.attachment.insertThumbnail")+"</span></li>").appendTo(o);c.children("span.button").click($.proxy(this._insert,this))}var h=$('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="'+a.attachmentID+'" data-url="'+WCF.String.escapeHTML(a.url)+'">'+WCF.Language.get("wcf.attachment.insertFull")+"</span></li>").appendTo(o);h.children("span.button").click($.proxy(this._insert,this))}else{var m=$('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="'+a.attachmentID+'">'+WCF.Language.get("wcf.attachment.insert")+"</span></li>");m.appendTo(o).children("span.button").click($.proxy(this._insert,this))}if(this._replaceOnLoad.hasOwnProperty(t)){if(!s.hasClass("uploadFailed")){var u=this._replaceOnLoad[t];u&&u.parentNode&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","replaceAttachment_"+this._editorId,{attachmentId:a.attachmentID,img:u,src:a.thumbnailURL?a.thumbnailURL:a.url})}this._replaceOnLoad[t]=null}}else{s.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban");var p="";if(e.returnValues&&e.returnValues.errors[r]){var f=e.returnValues.errors[r];p=f.errorType,"uploadFailed"===p&&f.additionalData.phpLimitExceeded&&(p="uploadPhpLimit")}else p="uploadFailed";s.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error."+p)+"</small>")),s.addClass("uploadFailed")}if(WCF.inArray(t,this._autoInsert)&&(this._autoInsert.splice(this._autoInsert.indexOf(t),1),!s.hasClass("uploadFailed"))){var _=s.find(".jsButtonAttachmentInsertThumbnail");_.length||(_=s.find(".jsButtonAttachmentInsertFull")),_.trigger("click")}}this._makeSortable(),this._fileListSelector.children("li:not(.uploadFailed)").length?this._insertAllButton.show():this._insertAllButton.hide(),WCF.DOMNodeInsertedHandler.execute()},_insert:function(t){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId,{attachmentId:elData(t.currentTarget,"object-id"),url:elData(t.currentTarget,"url")})},_insertAll:function(){for(var t,e,a=this._useThumbnail(),i=0,s=this._fileListSelector[0].childNodes.length;i<s;i++)t=this._fileListSelector[0].childNodes[i],"LI"!==t.nodeName||t.classList.contains("uploadFailed")||(e=null,a&&(e=elBySel(".jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain",t)),null===e&&(e=elBySel(".jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain",t)),window.jQuery(e).trigger("click"))},_error:function(t){this._fileListSelector.find("li").each(function(e,a){var i=$(a);i.children(".fa-spinner").length&&(i.addClass("uploadFailed").children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),i.find("div > div").append($('<small class="innerError">'+(t.responseJSON&&t.responseJSON.message?t.responseJSON.message:WCF.Language.get("wcf.attachment.upload.error.uploadFailed"))+"</small>")))})},_makeSortable:function(){var t=this._fileListSelector.children("li:not(.uploadFailed)");t.length&&(t.addClass("sortableAttachment").children("img").addClass("sortableNode"),this._fileListSelector.hasClass("sortableList")||(this._fileListSelector.addClass("sortableList"),require(["Environment"],function(t){"desktop"===t.platform()&&new WCF.Sortable.List(this._fileListSelector.parent().wcfIdentify(),"",0,{axis:!1,items:"li.sortableAttachment",toleranceElement:null,start:function(t,e){e.placeholder[0].style.setProperty("height",e.helper[0].offsetHeight+"px","")},update:function(){var t=[];this._fileListSelector.children("li:not(.uploadFailed)").each(function(e,a){t.push($(a).data("objectID"))}),t.length&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"updatePosition",className:"wcf\\data\\attachment\\AttachmentAction",parameters:{attachmentIDs:t,objectID:this._objectID,objectType:this._objectType,tmpHash:this._tmpHash}}})}.bind(this)},!0)}.bind(this))))}}); })(this);
+(function (window, undefined) { "use strict";WCF.Attachment={},WCF.Attachment.Upload=WCF.Upload.extend({_autoInsert:[],_insertAllButton:null,_objectType:"",_objectID:0,_tmpHash:"",_parentObjectID:0,_editorId:"",_replaceOnLoad:{},_options:{},init:function(t,e,i,a,n,s,r,l,o){var d,c;this._super(t,e,"wcf\\data\\attachment\\AttachmentAction",{multiple:!0,maxUploads:r}),this._autoInsert=[],this._objectType=i,this._objectID=parseInt(a),this._tmpHash=n,this._parentObjectID=parseInt(s),this._editorId=l,this._options=$.extend(!0,this._options,o||{}),this._buttonSelector.children("p.button").click($.proxy(this._validateLimit,this)),this._fileListSelector.find(".jsButtonInsertAttachment").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertThumbnail").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertFull").click($.proxy(this._insert,this)),WCF.System.Event.addListener("com.woltlab.wcf.action.delete","attachment",this._onDelete.bind(this)),this._makeSortable(),this._insertAllButton=$('<p class="button jsButtonAttachmentInsertAll">'+WCF.Language.get("wcf.attachment.insertAll")+"</p>").hide(),this._editorId&&(this._insertAllButton.appendTo(this._buttonSelector),this._insertAllButton.click($.proxy(this._insertAll,this)),this._fileListSelector.children("li:not(.uploadFailed)").length&&this._insertAllButton.show(),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","submit_"+this._editorId,this._submitInline.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+this._editorId,this._reset.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId,function(t){t.tmpHashes&&Array.isArray(t.tmpHashes)||(t.tmpHashes=[]);var e=t.tmpHashes.indexOf(n);0<this._fileListSelector.children("li:not(.uploadFailed)").length?-1===e&&t.tmpHashes.push(n):-1!==e&&t.tmpHashes.splice(e)}.bind(this)),d=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,function(t){var e,i,a,n,s,r=this._getImageAttachments(),l=t.attributes[0]||0;r.hasOwnProperty(l)&&(e=~~$("#"+this._editorId).data("redactor").opts.woltlab.attachmentThumbnailWidth,i=!0===(i=t.attributes[2])||"true"===i||~~i&&~~i<=e,(a=elCreate("img")).className="woltlabAttachment",a.src=r[l][i?"thumbnailUrl":"url"],elData(a,"attachment-id",l),"left"===(n=t.attributes[1]||"none")?a.classList.add("messageFloatObjectLeft"):"right"===n&&a.classList.add("messageFloatObjectRight"),(s=t.metacode).parentNode.insertBefore(a,s),elRemove(s),t.cancel=!0)}.bind(this)),c=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","sync_"+this._tmpHash,this._sync.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","destroy_"+this._editorId,function(){WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","submit_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","reset_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId),WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,d),WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","sync_"+this._tmpHash,c)}.bind(this)))},_editorUpload:function(e){var i=null;this._fileListSelector.closest(".messageTabMenu").messageTabMenu("showTab","attachments",!0);var t=function(t){null===i?this._autoInsert.push(t):this._replaceOnLoad[t]=i,e.uploadID=t}.bind(this);e.file?this._upload(void 0,e.file,void 0,t):(this._upload(void 0,void 0,e.blob,t),i=e.replace||null)},_getImageAttachments:function(){var a={};return this._fileListSelector.children("li").each(function(t,e){var i=$(e);i.data("isImage")&&(a[~~i.data("objectID")]={thumbnailUrl:i.find(".jsButtonAttachmentInsertThumbnail").data("url"),url:i.find(".jsButtonAttachmentInsertFull").data("url")})}),a},_submitInline:function(t){var e;this._tmpHash&&(t.tmpHash=this._tmpHash,e={},WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","getMetaData_"+this._editorId,e),e.tmpHashes&&Array.isArray(e.tmpHashes)&&0<e.tmpHashes.length&&(t.tmpHash+=","+e.tmpHashes.join(",")))},_reset:function(){this._fileListSelector.hide().empty(),this._insertAllButton.hide(),this._validateLimit()},_validateLimit:function(){var t=this._buttonSelector.next("small.innerError"),e=this._options.maxUploads-this._fileListSelector.children("li:not(.uploadFailed)").length,i=this._fileUpload?this._fileUpload.prop("files").length:0;if(e<=0||e<i){var a=e<=0?WCF.Language.get("wcf.attachment.upload.error.reachedLimit"):WCF.Language.get("wcf.attachment.upload.error.reachedRemainingLimit").replace(/#remaining#/,e);return t.length||(t=$('<small class="innerError" />').insertAfter(this._buttonSelector)),t.html(a),!1}return t.remove(),!0},_removeLimitError:function(t){var e=this._fileListSelector.children("li");e.filter(":not(.uploadFailed)").length||this._insertAllButton.hide(),e.length||this._fileListSelector.hide(),this._editorId&&t.button&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","deleteAttachment_"+this._editorId,{attachmentId:t.button.data("objectID")})},_upload:function(s,r,l,o){var m=this._super.bind(this);require(["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ImageUtil","WoltLabSuite/Core/Image/Resizer","WoltLabSuite/Core/Ajax/Status"],function(t,d,e,i){i.show();var a=[];r?a.push(r):l?a.push(t.blobToFile(l,"pasted-from-clipboard")):a=this._fileUpload.prop("files");var c,h,n=Promise.resolve(a);this._options.autoScale&&this._options.autoScale.enable&&(c=this._buttonSelector.data("maxSize"),h=new e,n=Array.prototype.reduce.call(a,function(t,o){return t.then(function(e){if(-1===["image/png","image/jpeg"].indexOf(o.type))return e.push(o),e;var l=new Promise(function(t,e){setTimeout(function(){t(o)},1e4)}),t=h.loadFile(o).then(function(t){var e,i,a=t.exif,n=this._options.autoScale.maxWidth,s=this._options.autoScale.maxHeight,r=this._options.autoScale.quality;return 2<=window.devicePixelRatio&&(e=window.screen.width*window.devicePixelRatio,i=window.screen.height*window.devicePixelRatio,e-10<t.image.width&&t.image.width<10+e&&i-10<t.image.height&&(n=Math.min(n,window.screen.width))),h.resize(t.image,n,s,r,o.size>c,l).then(function(t){if(void 0===t)return o;var e=this._options.autoScale.fileType;return"keep"!==this._options.autoScale.fileType&&!d.containsTransparentPixels(t)||(e=o.type),h.saveFile({exif:a,image:t},o.name,e,r)}.bind(this)).then(function(t){return t.size>o.size?(console.debug('[WCF.Attachment] File size of "'+o.name+'" increased, uploading untouched image.'),o):t})}.bind(this)).catch(function(t){return console.debug('[WCF.Attachment] Failed to resize image "'+o.name+'":',t),o});return Promise.race([l,t]).then(function(t){return e.push(t),e})}.bind(this))}.bind(this),Promise.resolve([]))),n.then(function(t){var e=void 0;return this._validateLimit()&&(e=m(s,void 0,void 0,t)),this._fileUpload&&(this._removeButton(),this._createButton()),"function"==typeof o&&o(e),e}.bind(this)).catch(function(t){console.debug("[WCF.Attachment] Failed to upload attachments:",t)}).finally(i.hide)}.bind(this),function(t){console.debug("[WCF.Attachment] Failed to load modules:",t)})},_createUploadMatrix:function(t){return this._fileListSelector.children("li.uploadFailed").remove(),this._super(t)},_getParameters:function(){return{objectType:this._objectType,objectID:this._objectID,tmpHash:this._tmpHash,parentObjectID:this._parentObjectID}},_initFile:function(t){var e=$('<li class="box64 formAttachmentListItem"><span class="icon icon64 fa-spinner" /><div><div><p>'+t.name+'</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data("filename",t.name);return this._fileListSelector.append(e),this._fileListSelector.show(),this._buttonSelector.data("maxSize")<t.size&&(e.find("progress").remove(),e.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),e.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error.tooLarge")+"</small>")),e.addClass("uploadFailed")),e},_useThumbnail:function(){return!0},_success:function(t,e){var i,a,n,s,r,l,o,d,c,h,m;for(var u in this._uploadMatrix[t]){this._uploadMatrix[t].hasOwnProperty(u)&&((a=this._uploadMatrix[t][u]).find("progress").remove(),n=a.data("filename"),s=a.data("internalFileID"),e.returnValues&&e.returnValues.attachments[s]?(i=e.returnValues.attachments[s],elData(a[0],"object-id",i.attachmentID),i.tinyURL?(a.children(".fa-spinner").replaceWith($('<img src="'+i.tinyURL+'" alt="" class="attachmentTinyThumbnail" />')),a.data("height",i.height),a.data("width",i.width),elData(a[0],"is-image",i.isImage)):a.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-"+i.iconName),(r=$('<a href=""></a>')).text(n).attr("href",i.url),r[0].target="_blank",0!=i.isImage&&r.addClass("jsImageViewer").attr("title",n),a.find("p").empty().append(r),a.find("small").append(i.formattedFilesize),l=a.find("ul").addClass("buttonGroup"),o=$('<li><span class="button small jsDeleteButton" data-object-id="'+i.attachmentID+'" data-confirm-message="'+WCF.Language.get("wcf.attachment.delete.sure")+'" data-event-name="attachment">'+WCF.Language.get("wcf.global.button.delete")+"</span></li>"),l.append(o),a.data("objectID",i.attachmentID),this._editorId&&(i.tinyURL?(i.thumbnailURL&&$('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="'+i.attachmentID+'" data-url="'+WCF.String.escapeHTML(i.thumbnailURL)+'">'+WCF.Language.get("wcf.attachment.insertThumbnail")+"</span></li>").appendTo(l),$('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="'+i.attachmentID+'" data-url="'+WCF.String.escapeHTML(i.url)+'">'+WCF.Language.get("wcf.attachment.insertFull")+"</span></li>").appendTo(l)):$('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="'+i.attachmentID+'">'+WCF.Language.get("wcf.attachment.insert")+"</span></li>").appendTo(l)),this._triggerSync("new",{html:a[0].outerHTML}),this._registerEditorButtons(a[0]),this._replaceOnLoad.hasOwnProperty(t)&&(a.hasClass("uploadFailed")||(d=this._replaceOnLoad[t])&&d.parentNode&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","replaceAttachment_"+this._editorId,{attachmentId:i.attachmentID,img:d,src:i.thumbnailURL?i.thumbnailURL:i.url}),this._replaceOnLoad[t]=null)):(a.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),h="",e.returnValues&&e.returnValues.errors[s]?"uploadFailed"===(h=(c=e.returnValues.errors[s]).errorType)&&c.additionalData.phpLimitExceeded&&(h="uploadPhpLimit"):h="uploadFailed",a.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error."+h)+"</small>")),a.addClass("uploadFailed")),WCF.inArray(t,this._autoInsert)&&(this._autoInsert.splice(this._autoInsert.indexOf(t),1),a.hasClass("uploadFailed")||((m=a.find(".jsButtonAttachmentInsertThumbnail")).length||(m=a.find(".jsButtonAttachmentInsertFull")),m.trigger("click"))))}this._rebuildInterface()},_rebuildInterface:function(){this._makeSortable(),this._fileListSelector.children("li:not(.uploadFailed)").length?this._insertAllButton.show():this._insertAllButton.hide(),WCF.DOMNodeInsertedHandler.execute()},_registerEditorButtons:function(t){this._editorId&&elBySelAll(".jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain",t,function(t){t.addEventListener("click",this._insert.bind(this))}.bind(this))},_insert:function(t){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId,{attachmentId:elData(t.currentTarget,"object-id"),url:elData(t.currentTarget,"url")})},_insertAll:function(){for(var t,e,i=0,a=this._fileListSelector[0].childNodes.length;i<a;i++)"LI"!==(t=this._fileListSelector[0].childNodes[i]).nodeName||t.classList.contains("uploadFailed")||(null===(e=elBySel(".jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain",t))&&(e=elBySel(".jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain",t)),window.jQuery(e).trigger("click"))},_error:function(a){this._fileListSelector.find("li").each(function(t,e){var i=$(e);i.children(".fa-spinner").length&&(i.addClass("uploadFailed").children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),i.find("div > div").append($('<small class="innerError">'+(a.responseJSON&&a.responseJSON.message?a.responseJSON.message:WCF.Language.get("wcf.attachment.upload.error.uploadFailed"))+"</small>")))})},_makeSortable:function(){var t=this._fileListSelector.children("li:not(.uploadFailed)");t.length&&(t.addClass("sortableAttachment").children("img").addClass("sortableNode"),this._fileListSelector.hasClass("sortableList")||(this._fileListSelector.addClass("sortableList"),require(["Environment"],function(t){"desktop"===t.platform()&&new WCF.Sortable.List(this._fileListSelector.parent().wcfIdentify(),"",0,{axis:!1,items:"li.sortableAttachment",toleranceElement:null,start:function(t,e){e.placeholder[0].style.setProperty("height",e.helper[0].offsetHeight+"px","")},update:function(){var i=[];this._fileListSelector.children("li:not(.uploadFailed)").each(function(t,e){i.push($(e).data("objectID"))}),i.length&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"updatePosition",className:"wcf\\data\\attachment\\AttachmentAction",parameters:{attachmentIDs:i,objectID:this._objectID,objectType:this._objectType,tmpHash:this._tmpHash}}})}.bind(this)},!0)}.bind(this))))},_onDelete:function(t){var e=elData(t.button[0],"object-id"),i=elBySel('.formAttachmentListItem[data-object-id="'+e+'"]',this._fileListSelector[0]);null!==i&&elRemove(i),this._removeLimitError(t)},_sync:function(t){if(t.source!==this)switch(t.type){case"new":this._syncNew(t.data);break;default:throw new Error("Unexpected type '"+t.type+"'")}},_syncNew:function(a){require(["Dom/Util"],function(t){var e=t.createFragmentFromHtml(a.html),i=elBySel("li",e);i.id="",this._registerEditorButtons(i),this._fileListSelector[0].appendChild(i),elShow(this._fileListSelector[0]),this._rebuildInterface()}.bind(this))},_triggerSync:function(t,e){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","sync_"+this._tmpHash,{source:this,type:t,data:e})}}); })(this);
 
 // WCF.ColorPicker.js
-(function (window, undefined) { "use strict";WCF.ColorPicker=Class.extend({_bar:null,_barActive:!1,_barSelector:null,_callbackSubmit:null,_dialog:null,_didInit:!1,_elementID:"",_gradient:null,_gradientActive:!1,_gradientSelector:null,_hex:null,_hsv:{},_newColor:null,_oldColor:null,_rgba:{},_rgbaRegExp:null,init:function(t){this._callbackSubmit=null,this._elementID="",this._hsv={h:0,s:100,v:100},this._position={};var a=$(t);if(!a.length)return void console.debug("[WCF.ColorPicker] Selector does not match any element, aborting.");a.click($.proxy(this._open,this))},setCallbackSubmit:function(t){this._callbackSubmit=t},_open:function(t){this._didInit||(this._initColorPicker(),this._didInit=!0);var a=$(t.currentTarget);this._elementID=a.wcfIdentify(),this._parseColor(a);var i=this.hsvToRgb(this._hsv.h,this._hsv.s,this._hsv.v);this._oldColor.css({backgroundColor:"rgba("+i.r+", "+i.g+", "+i.b+", "+this._rgba.a.val()/100+")"}),this._dialog.wcfDialog({backdropCloseOnClick:!1,title:WCF.Language.get("wcf.style.colorPicker")}),window.setTimeout(function(){this._hex.focus()}.bind(this),200)},_parseColor:function(t){if(t.data("hsv")&&t.data("rgb")){var a=t.data("hsv");for(var i in a)this._hsv[i]=a[i];this._updateValues(t.data("rgb"),!0,!0),this._rgba.a.val(parseInt(t.data("alpha")))}else{t.data("color").match(/^rgb\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)$/)&&t.data("color","rgba("+RegExp.$1+", "+RegExp.$2+", "+RegExp.$3+", 1)"),null===this._rgbaRegExp&&(this._rgbaRegExp=new RegExp("^rgba\\((\\d{1,3}), ?(\\d{1,3}), ?(\\d{1,3}), ?(1|1\\.00?|0|0?\\.[0-9]{1,2})\\)$")),this._rgbaRegExp.exec(t.data("color"));var s=RegExp.$4;0===s.indexOf(".")&&(s="0"+s),s*=100,this._updateValues({r:RegExp.$1,g:RegExp.$2,b:RegExp.$3,a:Math.round(s)},!0,!0)}},_initColorPicker:function(){this._dialog=$('<div id="colorPickerContainer" />').hide().appendTo(document.body),this._gradient=$('<div id="colorPickerGradient" />').appendTo(this._dialog),this._gradientSelector=$('<span id="colorPickerGradientSelector"><span></span></span>').appendTo(this._gradient),this._bar=$('<div id="colorPickerBar" />').appendTo(this._dialog),this._barSelector=$('<span id="colorPickerBarSelector" />').appendTo(this._bar),this._gradient.mousedown($.proxy(this._mouseDownGradient,this)),this._bar.mousedown($.proxy(this._mouseDownBar,this));var t=this;$(document).mouseup(function(a){t._barActive?(t._barActive=!1,t._mouseBar(a)):t._gradientActive&&(t._gradientActive=!1,t._mouseGradient(a))}).mousemove(function(a){t._barActive?t._mouseBar(a):t._gradientActive&&t._mouseGradient(a)}),this._initColorPickerForm()},_initColorPickerForm:function(){var t=$('<div id="colorPickerForm" />').appendTo(this._dialog);$("<small>"+WCF.Language.get("wcf.style.colorPicker.new")+"</small>").appendTo(t);var a=$('<ul class="colors" />').appendTo(t);this._newColor=$('<li class="new"><span /></li>').appendTo(a).children("span"),this._oldColor=$('<li class="old"><span /></li>').appendTo(a).children("span"),$("<small>"+WCF.Language.get("wcf.style.colorPicker.current")+"</small>").appendTo(t);var i=$('<ul class="rgba" />').appendTo(t);this._createInputElement("r","R",0,255).appendTo(i),this._createInputElement("g","G",0,255).appendTo(i),this._createInputElement("b","B",0,255).appendTo(i),this._createInputElement("a","a",0,100).appendTo(i);var s=$('<ul class="hex"><li><label><span>#</span></label></li></ul>').appendTo(t);this._hex=$('<input type="text" maxlength="6" />').appendTo(s.find("label")),this._rgba.r.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._rgba.g.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._rgba.b.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._rgba.a.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._hex.blur($.proxy(this._blurHex,this)).keyup($.proxy(this._keyUpHex,this));var e=$('<div class="formSubmit" />').appendTo(this._dialog);$('<button class="buttonPrimary">'+WCF.Language.get("wcf.style.colorPicker.button.apply")+"</button>").appendTo(e).click($.proxy(this._submit,this));var r=this;this._hex.on("paste",function(){r._hex.attr("maxlength","7"),setTimeout(function(){var t=r._hex.val();"#"==t.substring(0,1)&&(t=t.substr(1)),t.length>6&&(t=t.substring(0,6)),r._hex.attr("maxlength","6").val(t)},50)}),t.find("input").focus(function(){this.select()})},_keyUpRGBA:function(t){13==t.which&&(this._blurRgba(),this._submit())},_keyUpHex:function(t){13==t.which&&(this._blurHex(),this._submit())},_submit:function(){var t=this.hsvToRgb(this._hsv.h,this._hsv.s,this._hsv.v),a={};for(var i in this._hsv)a[i]=this._hsv[i];var s=$("#"+this._elementID);s.data("hsv",a).css({backgroundColor:"rgba("+t.r+", "+t.g+", "+t.b+", "+this._rgba.a.val()/100+")"}).data("alpha",parseInt(this._rgba.a.val())),s.data("rgb",{r:this._rgba.r.val(),g:this._rgba.g.val(),b:this._rgba.b.val()}),$("#"+s.data("store")).val("rgba("+this._rgba.r.val()+", "+this._rgba.g.val()+", "+this._rgba.b.val()+", "+this._rgba.a.val()/100+")").trigger("change"),this._dialog.wcfDialog("close"),"function"==typeof this._callbackSubmit&&this._callbackSubmit({r:this._rgba.r.val(),g:this._rgba.g.val(),b:this._rgba.b.val(),a:this._rgba.a.val()/100})},_createInputElement:function(t,a,i,s){var e=$('<li class="'+t+'" />'),r=$("<label />").appendTo(e);return $("<span>"+a+"</span>").appendTo(r),this._rgba[t]=$('<input type="number" value="0" min="'+i+'" max="'+s+'" step="1" />').appendTo(r),e},_mouseDownGradient:function(t){this._gradientActive=!0,this._mouseGradient(t)},_mouseGradient:function(t){var a=this._gradient.getOffsets("offset"),i=Math.max(Math.min(t.pageX-a.left,255),0),s=Math.max(Math.min(t.pageY-a.top,255),0);this._hsv.s=100*Math.max(0,Math.min(1,i/255)),this._hsv.v=100*Math.max(0,Math.min(1,(255-s)/255)),this._updateValues(null)},_mouseDownBar:function(t){this._barActive=!0,this._mouseBar(t)},_mouseBar:function(t){var a=this._bar.getOffsets("offset"),i=Math.max(Math.min(t.pageY-a.top,255),0);this._barSelector.css({top:i+"px"}),this._hsv.h=Math.max(0,Math.min(359,Math.round((255-i)/255*360))),this._updateValues(null)},_blurRgba:function(){for(var t in this._rgba){var a=parseInt(this._rgba[t].val())||0;"a"===t?this._rgba[t].val(Math.max(0,Math.min(100,a))):this._rgba[t].val(Math.max(0,Math.min(255,a)))}this._updateValues({r:this._rgba.r.val(),g:this._rgba.g.val(),b:this._rgba.b.val()},!0,!0)},_blurHex:function(){var t=this.hexToRgb(this._hex.val());t!==Number.NaN&&this._updateValues(t,!0,!0)},_updateValues:function(t,a,i){a=!0===a,i=!0===i,null===t&&(t=this.hsvToRgb(this._hsv.h,this._hsv.s,this._hsv.v),0==this._rgba.a.val()&&(t.a=100)),void 0===t.a&&(t.a=this._rgba.a.val());for(var s in t)this._rgba[s].val(t[s]);if(this._hex.val(this.rgbToHex(t.r,t.g,t.b)),a||i){var e=this.rgbToHsv(t.r,t.g,t.b);a&&(this._hsv.h=e.h),i&&(this._hsv.s=e.s,this._hsv.v=e.v)}var r=Math.max(0,Math.min(255,255-this._hsv.h/360*255));this._barSelector.css({top:r+"px"});var o=Math.max(0,Math.min(255,this._hsv.s/100*255)),r=Math.max(0,Math.min(255,255-this._hsv.v/100*255));this._gradientSelector.css({left:o-6+"px",top:r-6+"px"}),this._newColor.css({backgroundColor:"rgba("+t.r+", "+t.g+", "+t.b+", "+t.a/100+")"});var h=this.hsvToRgb(this._hsv.h,100,100);this._gradient.css({backgroundColor:"rgb("+h.r+", "+h.g+", "+h.b+")"})},hsvToRgb:function(t,a,i){return window.__wcf_bc_colorUtil.hsvToRgb(t,a,i)},rgbToHsv:function(t,a,i){return window.__wcf_bc_colorUtil.rgbToHsv(t,a,i)},hexToRgb:function(t){return window.__wcf_bc_colorUtil.hexToRgb(t)},rgbToHex:function(t,a,i){return window.__wcf_bc_colorUtil.rgbToHex(t,a,i)}}),function(){void 0===window.__wcf_bc_colorUtil&&require(["ColorUtil"],function(t){}),"function"==typeof window.__wcf_bc_colorPickerInit&&window.__wcf_bc_colorPickerInit()}(); })(this);
+(function (window, undefined) { "use strict";WCF.ColorPicker=Class.extend({_bar:null,_barActive:!1,_barSelector:null,_callbackSubmit:null,_dialog:null,_didInit:!1,_elementID:"",_gradient:null,_gradientActive:!1,_gradientSelector:null,_hex:null,_hsv:{},_newColor:null,_oldColor:null,_rgba:{},_rgbaRegExp:null,init:function(t){this._callbackSubmit=null,this._elementID="",this._hsv={h:0,s:100,v:100},this._position={};var a=$(t);a.length?a.click($.proxy(this._open,this)):console.debug("[WCF.ColorPicker] Selector does not match any element, aborting.")},setCallbackSubmit:function(t){this._callbackSubmit=t},_open:function(t){this._didInit||(this._initColorPicker(),this._didInit=!0);var a=$(t.currentTarget);this._elementID=a.wcfIdentify(),this._parseColor(a);var i=this.hsvToRgb(this._hsv.h,this._hsv.s,this._hsv.v);this._oldColor.css({backgroundColor:"rgba("+i.r+", "+i.g+", "+i.b+", "+this._rgba.a.val()/100+")"}),this._dialog.wcfDialog({backdropCloseOnClick:!1,title:WCF.Language.get("wcf.style.colorPicker")}),window.setTimeout(function(){this._hex.focus()}.bind(this),200)},_parseColor:function(t){if(t.data("hsv")&&t.data("rgb")){var a=t.data("hsv");for(var i in a)this._hsv[i]=a[i];this._updateValues(t.data("rgb"),!0,!0),this._rgba.a.val(parseInt(t.data("alpha")))}else{t.data("color").match(/^rgb\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)$/)&&t.data("color","rgba("+RegExp.$1+", "+RegExp.$2+", "+RegExp.$3+", 1)"),null===this._rgbaRegExp&&(this._rgbaRegExp=new RegExp("^rgba\\((\\d{1,3}), ?(\\d{1,3}), ?(\\d{1,3}), ?(1|1\\.00?|0|0?\\.[0-9]{1,2})\\)$")),this._rgbaRegExp.exec(t.data("color"));var s=RegExp.$4;0===s.indexOf(".")&&(s="0"+s),s*=100,this._updateValues({r:RegExp.$1,g:RegExp.$2,b:RegExp.$3,a:Math.round(s)},!0,!0)}},_initColorPicker:function(){this._dialog=$('<div id="colorPickerContainer" />').hide().appendTo(document.body),this._gradient=$('<div id="colorPickerGradient" />').appendTo(this._dialog),this._gradientSelector=$('<span id="colorPickerGradientSelector"><span></span></span>').appendTo(this._gradient),this._bar=$('<div id="colorPickerBar" />').appendTo(this._dialog),this._barSelector=$('<span id="colorPickerBarSelector" />').appendTo(this._bar),this._gradient.mousedown($.proxy(this._mouseDownGradient,this)),this._bar.mousedown($.proxy(this._mouseDownBar,this));var a=this;$(document).mouseup(function(t){a._barActive?(a._barActive=!1,a._mouseBar(t)):a._gradientActive&&(a._gradientActive=!1,a._mouseGradient(t))}).mousemove(function(t){a._barActive?a._mouseBar(t):a._gradientActive&&a._mouseGradient(t)}),this._initColorPickerForm()},_initColorPickerForm:function(){var t=$('<div id="colorPickerForm" />').appendTo(this._dialog);$("<small>"+WCF.Language.get("wcf.style.colorPicker.new")+"</small>").appendTo(t);var a=$('<ul class="colors" />').appendTo(t);this._newColor=$('<li class="new"><span /></li>').appendTo(a).children("span"),this._oldColor=$('<li class="old"><span /></li>').appendTo(a).children("span"),$("<small>"+WCF.Language.get("wcf.style.colorPicker.current")+"</small>").appendTo(t);var i=$('<ul class="rgba" />').appendTo(t);this._createInputElement("r","R",0,255).appendTo(i),this._createInputElement("g","G",0,255).appendTo(i),this._createInputElement("b","B",0,255).appendTo(i),this._createInputElement("a","a",0,100).appendTo(i);var s=$('<ul class="hex"><li><label><span>#</span></label></li></ul>').appendTo(t);this._hex=$('<input type="text" maxlength="6" />').appendTo(s.find("label")),this._rgba.r.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._rgba.g.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._rgba.b.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._rgba.a.blur($.proxy(this._blurRgba,this)).keyup($.proxy(this._keyUpRGBA,this)),this._hex.blur($.proxy(this._blurHex,this)).keyup($.proxy(this._keyUpHex,this));var e=$('<div class="formSubmit" />').appendTo(this._dialog);$('<button class="buttonPrimary">'+WCF.Language.get("wcf.style.colorPicker.button.apply")+"</button>").appendTo(e).click($.proxy(this._submit,this));var r=this;this._hex.on("paste",function(){r._hex.attr("maxlength","7"),setTimeout(function(){var t=r._hex.val();"#"==t.substring(0,1)&&(t=t.substr(1)),6<t.length&&(t=t.substring(0,6)),r._hex.attr("maxlength","6").val(t)},50)}),t.find("input").focus(function(){this.select()})},_keyUpRGBA:function(t){13==t.which&&(this._blurRgba(),this._submit())},_keyUpHex:function(t){13==t.which&&(this._blurHex(),this._submit())},_submit:function(){var t=this.hsvToRgb(this._hsv.h,this._hsv.s,this._hsv.v),a={};for(var i in this._hsv)a[i]=this._hsv[i];var s=$("#"+this._elementID);s.data("hsv",a).css({backgroundColor:"rgba("+t.r+", "+t.g+", "+t.b+", "+this._rgba.a.val()/100+")"}).data("alpha",parseInt(this._rgba.a.val())),s.data("rgb",{r:this._rgba.r.val(),g:this._rgba.g.val(),b:this._rgba.b.val()}),$("#"+s.data("store")).val("rgba("+this._rgba.r.val()+", "+this._rgba.g.val()+", "+this._rgba.b.val()+", "+this._rgba.a.val()/100+")").trigger("change"),this._dialog.wcfDialog("close"),"function"==typeof this._callbackSubmit&&this._callbackSubmit({r:this._rgba.r.val(),g:this._rgba.g.val(),b:this._rgba.b.val(),a:this._rgba.a.val()/100})},_createInputElement:function(t,a,i,s){var e=$('<li class="'+t+'" />'),r=$("<label />").appendTo(e);return $("<span>"+a+"</span>").appendTo(r),this._rgba[t]=$('<input type="number" value="0" min="'+i+'" max="'+s+'" step="1" />').appendTo(r),e},_mouseDownGradient:function(t){this._gradientActive=!0,this._mouseGradient(t)},_mouseGradient:function(t){var a=this._gradient.getOffsets("offset"),i=Math.max(Math.min(t.pageX-a.left,255),0),s=Math.max(Math.min(t.pageY-a.top,255),0);this._hsv.s=100*Math.max(0,Math.min(1,i/255)),this._hsv.v=100*Math.max(0,Math.min(1,(255-s)/255)),this._updateValues(null)},_mouseDownBar:function(t){this._barActive=!0,this._mouseBar(t)},_mouseBar:function(t){var a=this._bar.getOffsets("offset"),i=Math.max(Math.min(t.pageY-a.top,255),0);this._barSelector.css({top:i+"px"}),this._hsv.h=Math.max(0,Math.min(359,Math.round((255-i)/255*360))),this._updateValues(null)},_blurRgba:function(){for(var t in this._rgba){var a=parseInt(this._rgba[t].val())||0;"a"===t?this._rgba[t].val(Math.max(0,Math.min(100,a))):this._rgba[t].val(Math.max(0,Math.min(255,a)))}this._updateValues({r:this._rgba.r.val(),g:this._rgba.g.val(),b:this._rgba.b.val()},!0,!0)},_blurHex:function(){var t=this.hexToRgb(this._hex.val());t!==Number.NaN&&this._updateValues(t,!0,!0)},_updateValues:function(t,a,i){for(var s in a=!0===a,i=!0===i,null===t&&(t=this.hsvToRgb(this._hsv.h,this._hsv.s,this._hsv.v),0==this._rgba.a.val()&&(t.a=100)),void 0===t.a&&(t.a=this._rgba.a.val()),t)this._rgba[s].val(t[s]);var e;this._hex.val(this.rgbToHex(t.r,t.g,t.b)),(a||i)&&(e=this.rgbToHsv(t.r,t.g,t.b),a&&(this._hsv.h=e.h),i&&(this._hsv.s=e.s,this._hsv.v=e.v));var r=Math.max(0,Math.min(255,255-this._hsv.h/360*255));this._barSelector.css({top:r+"px"});var o=Math.max(0,Math.min(255,this._hsv.s/100*255)),r=Math.max(0,Math.min(255,255-this._hsv.v/100*255));this._gradientSelector.css({left:o-6+"px",top:r-6+"px"}),this._newColor.css({backgroundColor:"rgba("+t.r+", "+t.g+", "+t.b+", "+t.a/100+")"});var h=this.hsvToRgb(this._hsv.h,100,100);this._gradient.css({backgroundColor:"rgb("+h.r+", "+h.g+", "+h.b+")"})},hsvToRgb:function(t,a,i){return window.__wcf_bc_colorUtil.hsvToRgb(t,a,i)},rgbToHsv:function(t,a,i){return window.__wcf_bc_colorUtil.rgbToHsv(t,a,i)},hexToRgb:function(t){return window.__wcf_bc_colorUtil.hexToRgb(t)},rgbToHex:function(t,a,i){return window.__wcf_bc_colorUtil.rgbToHex(t,a,i)}}),void 0===window.__wcf_bc_colorUtil&&require(["ColorUtil"],function(t){}),"function"==typeof window.__wcf_bc_colorPickerInit&&window.__wcf_bc_colorPickerInit(); })(this);
 
 // WCF.Comment.js
-(function (window, undefined) { "use strict";WCF.Comment={},WCF.Comment.Handler=Class.extend({_commentButtonList:{},_comments:{},_container:null,_containerID:"",_displayedComments:0,_loadNextComments:null,_loadNextResponses:{},_proxy:null,_responses:{},_responseCache:{},_commentData:{},_guestDialog:null,_permalinkComment:null,_permalinkResponse:null,_scrollTarget:null,init:function(e){if(this._commentButtonList={},this._comments={},this._containerID=e,this._displayedComments=0,this._loadNextComments=null,this._loadNextResponses={},this._permalinkComment=null,this._permalinkResponse=null,this._responseAdd=null,this._responseCache={},this._responseRevert=null,this._responses={},this._scrollTarget=null,this._onResponsesLoaded=null,this._container=$("#"+$.wcfEscapeID(this._containerID)),!this._container.length)return void console.debug("[WCF.Comment.Handler] Unable to find container identified by '"+this._containerID+"'");if(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initComments(),this._initResponses(),this._container.data("canAdd")&&(null===elBySel(".commentListAddComment .wysiwygTextarea",this._container[0])?console.error("Missing WYSIWYG implementation, adding comments is not available."):require(["WoltLabSuite/Core/Ui/Comment/Add","WoltLabSuite/Core/Ui/Comment/Response/Add"],function(e,t){new e(elBySel(".jsCommentAdd",this._container[0])),this._responseAdd=new t(elBySel(".jsCommentResponseAdd",this._container[0]),{callbackInsert:function(){null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null)}.bind(this)})}.bind(this))),require(["WoltLabSuite/Core/Ui/Comment/Edit","WoltLabSuite/Core/Ui/Comment/Response/Edit"],function(e,t){new e(this._container[0]),new t(this._container[0])}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Comment.Handler",$.proxy(this._domNodeInserted,this)),WCF.System.ObjectStore.add("WCF.Comment.Handler",this),window.addEventListener("hashchange",function(){var e=window.location.hash;if(e&&e.match(/.+\/(comment\d+)/)){var t=RegExp.$1;window.setTimeout(function(){var e=elById(t);e&&e.scrollIntoView({behavior:"smooth"})},100)}}),window.location.hash.match(/^#(?:[^\/]+\/)?comment(\d+)(?:\/response(\d+))?/)){var t=elById("comment"+RegExp.$1);if(t){var n;RegExp.$2?(n=elById("comment"+RegExp.$1+"response"+RegExp.$2),n?this._scrollTo(n,!0):this._loadResponseSegment(t,RegExp.$1,RegExp.$2)):this._scrollTo(t,!0)}else this._loadCommentSegment(RegExp.$1,RegExp.$2)}},_scrollTo:function(e,t){null===this._scrollTarget&&(this._scrollTarget=elCreate("span"),this._scrollTarget.className="commentScrollTarget",document.body.appendChild(this._scrollTarget)),this._scrollTarget.style.setProperty("top",e.getBoundingClientRect().top+window.pageYOffset-49+"px",""),require(["Ui/Scroll"],function(n){n.element(this._scrollTarget,function(){t&&(e.classList.contains("commentHighlightTarget")&&(e.classList.remove("commentHighlightTarget"),e.offsetTop),e.classList.add("commentHighlightTarget"))})}.bind(this))},_loadCommentSegment:function(e,t){this._permalinkComment=elCreate("li"),this._permalinkComment.className="commentPermalinkContainer loading",this._permalinkComment.innerHTML='<span class="icon icon48 fa-spinner"></span>',this._container[0].insertBefore(this._permalinkComment,this._container[0].firstChild),this._proxy.setOption("data",{actionName:"loadComment",className:"wcf\\data\\comment\\CommentAction",objectIDs:[e],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~t}}}),this._proxy.sendRequest()},_loadResponseSegment:function(e,t,n){this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>';var s=elBySel(".commentResponseList",e);s.insertBefore(this._permalinkResponse,s.firstChild),this._proxy.setOption("data",{actionName:"loadResponse",className:"wcf\\data\\comment\\CommentAction",objectIDs:[t],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~n}}}),this._proxy.sendRequest()},_handleLoadNextComments:function(){this._displayedComments<this._container.data("comments")?(null===this._loadNextComments&&(this._loadNextComments=$('<li class="commentLoadNext showMore"><button class="small">'+WCF.Language.get("wcf.comment.more")+"</button></li>").appendTo(this._container),this._loadNextComments.children("button").click($.proxy(this._loadComments,this))),this._loadNextComments.children("button").enable()):null!==this._loadNextComments&&this._loadNextComments.remove()},_handleLoadNextResponses:function(e){var t=this._comments[e];if(t.data("displayedResponses",t.find("ul.commentResponseList > li").length),t.data("displayedResponses")<t.data("responses")){if(void 0===this._loadNextResponses[e]){var n=t.data("responses")-t.data("displayedResponses");this._loadNextResponses[e]=$('<li class="jsCommentLoadNextResponses"><a>'+WCF.Language.get("wcf.comment.response.more",{count:n})+"</a></li>").appendTo(this._commentButtonList[e]),this._loadNextResponses[e].children("a").data("commentID",e).click($.proxy(this._loadResponses,this)),this._commentButtonList[e].parent().show()}}else void 0!==this._loadNextResponses[e]&&this._loadNextResponses[e].remove()},_loadComments:function(){this._loadNextComments.children("button").disable(),this._proxy.setOption("data",{actionName:"loadComments",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),lastCommentTime:this._container.data("lastCommentTime")}}}),this._proxy.sendRequest()},_loadResponses:function(e){this._loadResponsesExecute($(e.currentTarget).disable().data("commentID"),!1)},_loadResponsesExecute:function(e,t){this._proxy.setOption("data",{actionName:"loadResponses",className:"wcf\\data\\comment\\response\\CommentResponseAction",parameters:{data:{commentID:e,lastResponseTime:this._comments[e].data("lastResponseTime"),loadAllResponses:t?1:0}}}),this._proxy.sendRequest()},_domNodeInserted:function(){this._initComments(),this._initResponses()},_initComments:function(){var e=elBySel('link[rel="canonical"]');e=e?e.href:window.location.toString().replace(/#.+$/,"");var t=this._container[0].closest(".tabMenuContent");t&&(e+="#"+elData(t,"name"));var n=this,s=!1;this._container.find(".jsComment").each(function(t,o){var i=$(o).removeClass("jsComment"),a=i.data("commentID");n._comments[a]=i,i[0].id="comment"+a;var l=i.find("ul.commentResponseList");l.length||(l=i.find(".commentContent"));var r=$('<div class="commentOptionContainer" />').hide().insertAfter(l);n._commentButtonList[a]=$('<ul class="inlineList dotSeparated" />').appendTo(r),n._handleLoadNextResponses(a),n._initComment(a,i),n._initPermalink(i[0],e),n._displayedComments++,s=!0}),s&&this._handleLoadNextComments()},_initComment:function(e,t){if(this._container.data("canAdd")&&this._initAddResponse(e,t),t.data("canEdit")){$('<li><a href="#" class="jsCommentEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").appendTo(t.find("ul.buttonList:eq(0)"))}if(t.data("canDelete")){$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>").data("commentID",e).appendTo(t.find("ul.buttonList:eq(0)")).click($.proxy(this._delete,this))}var n=elBySel(".jsEnableComment",t[0]);n&&n.addEventListener(WCF_CLICK_EVENT,this._enableComment.bind(this))},_enableComment:function(e){e.preventDefault();var t=e.currentTarget.closest(".comment");this._proxy.setOption("data",{actionName:"enable",className:"wcf\\data\\comment\\CommentAction",objectIDs:[elData(t,"object-id")]}),this._proxy.sendRequest()},_initPermalink:function(e,t){var n=elCreate("a");n.href=t+(-1===t.indexOf("#")?"#":"/")+"comment"+elData(e,"object-id");var s=elBySel(".commentContent:not(.commentResponseContent) .containerHeadline time",e);s.parentNode.insertBefore(n,s),n.appendChild(s)},_initResponses:function(){var e=elBySel('link[rel="canonical"]');e=e?e.href:window.location.toString().replace(/#.+$/,"");var t=this._container[0].closest(".tabMenuContent");t&&(e+="#"+elData(t,"name"));for(var n in this._comments)this._comments.hasOwnProperty(n)&&elBySelAll(".jsCommentResponse",this._comments[n][0],function(t){var s=$(t).removeClass("jsCommentResponse"),o=s.data("responseID");this._responses[o]=s,t.id="comment"+n+"response"+o,this._initResponse(o,s),this._initPermalinkResponse(n,t,o,e);var i=elBySel(".jsEnableResponse",t);i&&i.addEventListener(WCF_CLICK_EVENT,this._enableCommentResponse.bind(this))}.bind(this))},_enableCommentResponse:function(e){e.preventDefault();var t=e.currentTarget.closest(".commentResponse");this._proxy.setOption("data",{actionName:"enableResponse",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{responseID:elData(t,"object-id")}}}),this._proxy.sendRequest()},_initPermalinkResponse:function(e,t,n,s){var o=elCreate("a");o.href=s+(-1===s.indexOf("#")?"#":"/")+"comment"+e+"/response"+n;var i=elBySel(".commentResponseContent .containerHeadline time",t);i.parentNode.insertBefore(o,i),o.appendChild(i)},_initResponse:function(e,t){if(t.data("canEdit")){$('<li><a href="#" class="jsCommentResponseEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)"))}if(t.data("canDelete")){var n=this;$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>").data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)")).click(function(e){n._delete(e,!0)})}},_initAddResponse:function(e,t){$('<li class="jsCommentShowAddResponse"><a>'+WCF.Language.get("wcf.comment.button.response.add")+"</a></li>").data("commentID",e).click($.proxy(this._showAddResponse,this)).appendTo(this._commentButtonList[e]);this._commentButtonList[e].parent().show()},_showAddResponse:function(e){if(e.preventDefault(),null===this._onResponsesLoaded){if(null===this._responseAdd)return void console.error("Missing response API.");var t=this._responseAdd.getContainer();if(null!==t){null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null);var n=$(e.currentTarget),s=n.data("commentID");this._onResponsesLoaded=function(){n.hide(),t.parentNode&&t.parentNode.classList.contains("jsCommentResponseAddContainer")&&elRemove(t.parentNode);var e=this._commentButtonList[s][0].closest(".commentOptionContainer");e.parentNode.insertBefore(t,e.nextSibling),"string"==typeof this._responseCache[s]?this._responseAdd.setContent(this._responseCache[s]):this._responseAdd.setContent(""),this._responseRevert=function(){this._responseCache[s]=this._responseAdd.getContent(),elRemove(t),n.show()}.bind(this),this._onResponsesLoaded=null}.bind(this),n.prev().hasClass("jsCommentLoadNextResponses")?(this._loadResponsesExecute(s,!0),n.parent().children(".button").disable()):this._onResponsesLoaded()}}},_delete:function(e,t){e.preventDefault(),WCF.System.Confirmation.show(WCF.Language.get("wcf.comment.delete.confirmMessage"),$.proxy(function(n){if("confirm"===n){var s={objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID")};!0!==t?s.commentID=$(e.currentTarget).data("commentID"):s.responseID=$(e.currentTarget).data("responseID"),this._proxy.setOption("data",{actionName:"remove",className:"wcf\\data\\comment\\CommentAction",parameters:{data:s}}),this._proxy.sendRequest()}},this))},_success:function(e,t,n){switch(e.actionName){case"enable":this._enable(e);break;case"enableResponse":this._enableResponse(e);break;case"loadComment":this._insertComment(e);break;case"loadComments":this._insertComments(e);break;case"loadResponse":this._insertResponse(e);break;case"loadResponses":this._insertResponses(e);break;case"remove":this._remove(e)}WCF.DOMNodeInsertedHandler.execute()},_enable:function(e){if(e.returnValues.commentID){var t=elBySel('.comment[data-object-id="'+e.returnValues.commentID+'"]',this._container[0]);if(t){elData(t,"is-disabled",0);var n=elBySel(".jsIconDisabled",t);n&&elRemove(n);var s=elBySel(".jsEnableComment",t);s&&elRemove(s.parentNode)}}},_enableResponse:function(e){if(e.returnValues.responseID){var t=elBySel('.commentResponse[data-object-id="'+e.returnValues.responseID+'"]',this._container[0]);if(t){elData(t,"is-disabled",0);var n=elBySel(".jsIconDisabled",t);n&&elRemove(n);var s=elBySel(".jsEnableResponse",t);s&&elRemove(s.parentNode)}}},_insertComment:function(e){if(""===e.returnValues.template)return void elRemove(this._permalinkComment);$(e.returnValues.template).insertBefore(this._permalinkComment);var t=this._permalinkComment.previousElementSibling;if(t.classList.add("commentPermalinkContainer"),elRemove(this._permalinkComment),this._permalinkComment=t,e.returnValues.response){this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>';var n=elBySel(".commentResponseList",t);n.insertBefore(this._permalinkResponse,n.firstChild),this._insertResponse({returnValues:{template:e.returnValues.response}})}t.offsetTop,t.classList.add("commentHighlightTarget")},_insertResponse:function(e){if(""===e.returnValues.template)return void elRemove(this._permalinkResponse);$(e.returnValues.template).insertBefore(this._permalinkResponse);var t=this._permalinkResponse.previousElementSibling;t.classList.add("commentResponsePermalinkContainer"),elRemove(this._permalinkResponse),this._permalinkResponse=t,t.offsetTop,t.classList.add("commentHighlightTarget")},_insertComments:function(e){if($(e.returnValues.template).insertBefore(this._loadNextComments),this._container.data("lastCommentTime",e.returnValues.lastCommentTime),this._permalinkComment){var t=elData(this._permalinkComment,"object-id");null!==elBySel('.comment[data-object-id="'+t+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkComment),this._permalinkComment=null)}this._initComments()},_insertResponses:function(e){var t=this._comments[e.returnValues.commentID];if($(e.returnValues.template).appendTo(t.find("ul.commentResponseList")),t.data("lastResponseTime",e.returnValues.lastResponseTime),this._handleLoadNextResponses(e.returnValues.commentID),this._permalinkResponse){var n=elData(this._permalinkResponse,"object-id");null!==elBySel('.commentResponse[data-object-id="'+n+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkResponse),this._permalinkResponse=null)}null!==this._onResponsesLoaded&&this._onResponsesLoaded()},_remove:function(e){if(e.returnValues.commentID)this._comments[e.returnValues.commentID].remove(),delete this._comments[e.returnValues.commentID];else{var t=this._responses[e.returnValues.responseID],n=this._comments[t.parents("li.comment:eq(0)").data("commentID")];n.data("responses",parseInt(n.data("responses"))-1);var s=t.parent();t.remove(),s.children().length||s.empty(),delete this._responses[e.returnValues.responseID]}},_prepareEdit:function(){console.warn("This method is no longer supported.")},_keyUp:function(){console.warn("This method is no longer supported.")},_save:function(){console.warn("This method is no longer supported.")},_failure:function(){console.warn("This method is no longer supported.")},_edit:function(){console.warn("This method is no longer supported.")},_update:function(){console.warn("This method is no longer supported.")},_createGuestDialog:function(){console.warn("This method is no longer supported.")},_keyDown:function(){console.warn("This method is no longer supported.")},_submit:function(){console.warn("This method is no longer supported.")},_keyUpEdit:function(){console.warn("This method is no longer supported.")},_saveEdit:function(){console.warn("This method is no longer supported.")},_cancelEdit:function(){console.warn("This method is no longer supported.")}}),WCF.Comment.Response={}; })(this);
+(function (window, undefined) { "use strict";WCF.Comment={},WCF.Comment.Handler=Class.extend({_commentButtonList:{},_comments:{},_container:null,_containerID:"",_displayedComments:0,_loadNextComments:null,_loadNextResponses:{},_proxy:null,_responses:{},_responseCache:{},_commentData:{},_guestDialog:null,_permalinkComment:null,_permalinkResponse:null,_scrollTarget:null,init:function(e){var t,n;this._commentButtonList={},this._comments={},this._containerID=e,this._displayedComments=0,this._loadNextComments=null,this._loadNextResponses={},this._permalinkComment=null,this._permalinkResponse=null,this._responseAdd=null,this._responseCache={},this._responseRevert=null,this._responses={},this._scrollTarget=null,this._onResponsesLoaded=null,this._container=$("#"+$.wcfEscapeID(this._containerID)),this._container.length?(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initComments(),this._initResponses(),this._container.data("canAdd")&&(null===elBySel(".commentListAddComment .wysiwygTextarea",this._container[0])?console.error("Missing WYSIWYG implementation, adding comments is not available."):require(["WoltLabSuite/Core/Ui/Comment/Add","WoltLabSuite/Core/Ui/Comment/Response/Add"],function(e,t){new e(elBySel(".jsCommentAdd",this._container[0])),this._responseAdd=new t(elBySel(".jsCommentResponseAdd",this._container[0]),{callbackInsert:function(){null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null)}.bind(this)})}.bind(this))),require(["WoltLabSuite/Core/Ui/Comment/Edit","WoltLabSuite/Core/Ui/Comment/Response/Edit"],function(e,t){new e(this._container[0]),new t(this._container[0])}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Comment.Handler",$.proxy(this._domNodeInserted,this)),WCF.System.ObjectStore.add("WCF.Comment.Handler",this),window.addEventListener("hashchange",function(){var t,e=window.location.hash;e&&e.match(/.+\/(comment\d+)/)&&(t=RegExp.$1,window.setTimeout(function(){var e=elById(t);e&&e.scrollIntoView({behavior:"smooth"})},100))}),window.location.hash.match(/^#(?:[^\/]+\/)?comment(\d+)(?:\/response(\d+))?/)&&((t=elById("comment"+RegExp.$1))?RegExp.$2?(n=elById("comment"+RegExp.$1+"response"+RegExp.$2))?this._scrollTo(n,!0):this._loadResponseSegment(t,RegExp.$1,RegExp.$2):this._scrollTo(t,!0):this._loadCommentSegment(RegExp.$1,RegExp.$2))):console.debug("[WCF.Comment.Handler] Unable to find container identified by '"+this._containerID+"'")},_scrollTo:function(t,n){null===this._scrollTarget&&(this._scrollTarget=elCreate("span"),this._scrollTarget.className="commentScrollTarget",document.body.appendChild(this._scrollTarget)),this._scrollTarget.style.setProperty("top",t.getBoundingClientRect().top+window.pageYOffset-49+"px",""),require(["Ui/Scroll"],function(e){e.element(this._scrollTarget,function(){n&&(t.classList.contains("commentHighlightTarget")&&(t.classList.remove("commentHighlightTarget"),t.offsetTop),t.classList.add("commentHighlightTarget"))})}.bind(this))},_loadCommentSegment:function(e,t){this._permalinkComment=elCreate("li"),this._permalinkComment.className="commentPermalinkContainer loading",this._permalinkComment.innerHTML='<span class="icon icon48 fa-spinner"></span>',this._container[0].insertBefore(this._permalinkComment,this._container[0].firstChild),this._proxy.setOption("data",{actionName:"loadComment",className:"wcf\\data\\comment\\CommentAction",objectIDs:[e],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~t}}}),this._proxy.sendRequest()},_loadResponseSegment:function(e,t,n){this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>';var s=elBySel(".commentResponseList",e);s.insertBefore(this._permalinkResponse,s.firstChild),this._proxy.setOption("data",{actionName:"loadResponse",className:"wcf\\data\\comment\\CommentAction",objectIDs:[t],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~n}}}),this._proxy.sendRequest()},_handleLoadNextComments:function(){this._displayedComments<this._container.data("comments")?(null===this._loadNextComments&&(this._loadNextComments=$('<li class="commentLoadNext showMore"><button class="small">'+WCF.Language.get("wcf.comment.more")+"</button></li>").appendTo(this._container),this._loadNextComments.children("button").click($.proxy(this._loadComments,this))),this._loadNextComments.children("button").enable()):null!==this._loadNextComments&&this._loadNextComments.remove()},_handleLoadNextResponses:function(e){var t,n=this._comments[e];n.data("displayedResponses",n.find("ul.commentResponseList > li").length),n.data("displayedResponses")<n.data("responses")?void 0===this._loadNextResponses[e]&&(t=n.data("responses")-n.data("displayedResponses"),this._loadNextResponses[e]=$('<li class="jsCommentLoadNextResponses"><a>'+WCF.Language.get("wcf.comment.response.more",{count:t})+"</a></li>").appendTo(this._commentButtonList[e]),this._loadNextResponses[e].children("a").data("commentID",e).click($.proxy(this._loadResponses,this)),this._commentButtonList[e].parent().show()):void 0!==this._loadNextResponses[e]&&this._loadNextResponses[e].remove()},_loadComments:function(){this._loadNextComments.children("button").disable(),this._proxy.setOption("data",{actionName:"loadComments",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),lastCommentTime:this._container.data("lastCommentTime")}}}),this._proxy.sendRequest()},_loadResponses:function(e){this._loadResponsesExecute($(e.currentTarget).disable().data("commentID"),!1)},_loadResponsesExecute:function(e,t){this._proxy.setOption("data",{actionName:"loadResponses",className:"wcf\\data\\comment\\response\\CommentResponseAction",parameters:{data:{commentID:e,lastResponseTime:this._comments[e].data("lastResponseTime"),loadAllResponses:t?1:0}}}),this._proxy.sendRequest()},_domNodeInserted:function(){this._initComments(),this._initResponses()},_initComments:function(){var a=(a=elBySel('link[rel="canonical"]'))?a.href:window.location.toString().replace(/#.+$/,""),e=this._container[0].closest(".tabMenuContent");e&&(a+="#"+elData(e,"name"));var l=this,m=!1;this._container.find(".jsComment").each(function(e,t){var n=$(t).removeClass("jsComment"),s=n.data("commentID");(l._comments[s]=n)[0].id="comment"+s;var o=n.find("ul.commentResponseList");o.length||(o=n.find(".commentContent"));var i=$('<div class="commentOptionContainer" />').hide().insertAfter(o);l._commentButtonList[s]=$('<ul class="inlineList dotSeparated" />').appendTo(i),l._handleLoadNextResponses(s),l._initComment(s,n),l._initPermalink(n[0],a),l._displayedComments++,m=!0}),m&&this._handleLoadNextComments()},_initComment:function(e,t){this._container.data("canAdd")&&this._initAddResponse(e,t),t.data("canEdit")&&$('<li><a href="#" class="jsCommentEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").appendTo(t.find("ul.buttonList:eq(0)")),t.data("canDelete")&&$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>").data("commentID",e).appendTo(t.find("ul.buttonList:eq(0)")).click($.proxy(this._delete,this));var n=elBySel(".jsEnableComment",t[0]);n&&n.addEventListener(WCF_CLICK_EVENT,this._enableComment.bind(this))},_enableComment:function(e){e.preventDefault();var t=e.currentTarget.closest(".comment");this._proxy.setOption("data",{actionName:"enable",className:"wcf\\data\\comment\\CommentAction",objectIDs:[elData(t,"object-id")]}),this._proxy.sendRequest()},_initPermalink:function(e,t){var n=elCreate("a");n.href=t+(-1===t.indexOf("#")?"#":"/")+"comment"+elData(e,"object-id");var s=elBySel(".commentContent:not(.commentResponseContent) .containerHeadline time",e);s.parentNode.insertBefore(n,s),n.appendChild(s)},_initResponses:function(){var o=(o=elBySel('link[rel="canonical"]'))?o.href:window.location.toString().replace(/#.+$/,""),e=this._container[0].closest(".tabMenuContent");for(var i in e&&(o+="#"+elData(e,"name")),this._comments)this._comments.hasOwnProperty(i)&&elBySelAll(".jsCommentResponse",this._comments[i][0],function(e){var t=$(e).removeClass("jsCommentResponse"),n=t.data("responseID");this._responses[n]=t,e.id="comment"+i+"response"+n,this._initResponse(n,t),this._initPermalinkResponse(i,e,n,o);var s=elBySel(".jsEnableResponse",e);s&&s.addEventListener(WCF_CLICK_EVENT,this._enableCommentResponse.bind(this))}.bind(this))},_enableCommentResponse:function(e){e.preventDefault();var t=e.currentTarget.closest(".commentResponse");this._proxy.setOption("data",{actionName:"enableResponse",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{responseID:elData(t,"object-id")}}}),this._proxy.sendRequest()},_initPermalinkResponse:function(e,t,n,s){var o=elCreate("a");o.href=s+(-1===s.indexOf("#")?"#":"/")+"comment"+e+"/response"+n;var i=elBySel(".commentResponseContent .containerHeadline time",t);i.parentNode.insertBefore(o,i),o.appendChild(i)},_initResponse:function(e,t){var n,s;t.data("canEdit")&&$('<li><a href="#" class="jsCommentResponseEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)")),t.data("canDelete")&&(n=$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>"),s=this,n.data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)")).click(function(e){s._delete(e,!0)}))},_initAddResponse:function(e,t){$('<li class="jsCommentShowAddResponse"><a>'+WCF.Language.get("wcf.comment.button.response.add")+"</a></li>").data("commentID",e).click($.proxy(this._showAddResponse,this)).appendTo(this._commentButtonList[e]);this._commentButtonList[e].parent().show()},_showAddResponse:function(e){var t,n,s;e.preventDefault(),null===this._onResponsesLoaded&&(null!==this._responseAdd?null!==(t=this._responseAdd.getContainer())&&(null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null),n=$(e.currentTarget),s=n.data("commentID"),this._onResponsesLoaded=function(){n.hide(),t.parentNode&&t.parentNode.classList.contains("jsCommentResponseAddContainer")&&elRemove(t.parentNode);var e=this._commentButtonList[s][0].closest(".commentOptionContainer");e.parentNode.insertBefore(t,e.nextSibling),"string"==typeof this._responseCache[s]?this._responseAdd.setContent(this._responseCache[s]):this._responseAdd.setContent(""),this._responseRevert=function(){this._responseCache[s]=this._responseAdd.getContent(),elRemove(t),n.show()}.bind(this),this._onResponsesLoaded=null}.bind(this),n.prev().hasClass("jsCommentLoadNextResponses")?(this._loadResponsesExecute(s,!0),n.parent().children(".button").disable()):this._onResponsesLoaded()):console.error("Missing response API."))},_delete:function(n,s){n.preventDefault(),WCF.System.Confirmation.show(WCF.Language.get("wcf.comment.delete.confirmMessage"),$.proxy(function(e){var t;"confirm"===e&&(t={objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID")},!0!==s?t.commentID=$(n.currentTarget).data("commentID"):t.responseID=$(n.currentTarget).data("responseID"),this._proxy.setOption("data",{actionName:"remove",className:"wcf\\data\\comment\\CommentAction",parameters:{data:t}}),this._proxy.sendRequest())},this))},_success:function(e,t,n){switch(e.actionName){case"enable":this._enable(e);break;case"enableResponse":this._enableResponse(e);break;case"loadComment":this._insertComment(e);break;case"loadComments":this._insertComments(e);break;case"loadResponse":this._insertResponse(e);break;case"loadResponses":this._insertResponses(e);break;case"remove":this._remove(e)}WCF.DOMNodeInsertedHandler.execute()},_enable:function(e){var t,n,s;!e.returnValues.commentID||(t=elBySel('.comment[data-object-id="'+e.returnValues.commentID+'"]',this._container[0]))&&(elData(t,"is-disabled",0),(n=elBySel(".jsIconDisabled",t))&&elRemove(n),(s=elBySel(".jsEnableComment",t))&&elRemove(s.parentNode))},_enableResponse:function(e){var t,n,s;!e.returnValues.responseID||(t=elBySel('.commentResponse[data-object-id="'+e.returnValues.responseID+'"]',this._container[0]))&&(elData(t,"is-disabled",0),(n=elBySel(".jsIconDisabled",t))&&elRemove(n),(s=elBySel(".jsEnableResponse",t))&&elRemove(s.parentNode))},_insertComment:function(e){var t,n;""!==e.returnValues.template?($(e.returnValues.template).insertBefore(this._permalinkComment),(t=this._permalinkComment.previousElementSibling).classList.add("commentPermalinkContainer"),elRemove(this._permalinkComment),this._permalinkComment=t,e.returnValues.response&&(this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>',(n=elBySel(".commentResponseList",t)).insertBefore(this._permalinkResponse,n.firstChild),this._insertResponse({returnValues:{template:e.returnValues.response}})),t.offsetTop,t.classList.add("commentHighlightTarget")):elRemove(this._permalinkComment)},_insertResponse:function(e){var t;""!==e.returnValues.template?($(e.returnValues.template).insertBefore(this._permalinkResponse),(t=this._permalinkResponse.previousElementSibling).classList.add("commentResponsePermalinkContainer"),elRemove(this._permalinkResponse),(this._permalinkResponse=t).offsetTop,t.classList.add("commentHighlightTarget")):elRemove(this._permalinkResponse)},_insertComments:function(e){var t;$(e.returnValues.template).insertBefore(this._loadNextComments),this._container.data("lastCommentTime",e.returnValues.lastCommentTime),this._permalinkComment&&(t=elData(this._permalinkComment,"object-id"),null!==elBySel('.comment[data-object-id="'+t+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkComment),this._permalinkComment=null)),this._initComments()},_insertResponses:function(e){var t,n=this._comments[e.returnValues.commentID];$(e.returnValues.template).appendTo(n.find("ul.commentResponseList")),n.data("lastResponseTime",e.returnValues.lastResponseTime),this._handleLoadNextResponses(e.returnValues.commentID),this._permalinkResponse&&(t=elData(this._permalinkResponse,"object-id"),null!==elBySel('.commentResponse[data-object-id="'+t+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkResponse),this._permalinkResponse=null)),null!==this._onResponsesLoaded&&this._onResponsesLoaded()},_remove:function(e){var t,n,s;e.returnValues.commentID?(this._comments[e.returnValues.commentID].remove(),delete this._comments[e.returnValues.commentID]):(t=this._responses[e.returnValues.responseID],(n=this._comments[t.parents("li.comment:eq(0)").data("commentID")]).data("responses",parseInt(n.data("responses"))-1),s=t.parent(),t.remove(),s.children().length||s.empty(),delete this._responses[e.returnValues.responseID])},_prepareEdit:function(){console.warn("This method is no longer supported.")},_keyUp:function(){console.warn("This method is no longer supported.")},_save:function(){console.warn("This method is no longer supported.")},_failure:function(){console.warn("This method is no longer supported.")},_edit:function(){console.warn("This method is no longer supported.")},_update:function(){console.warn("This method is no longer supported.")},_createGuestDialog:function(){console.warn("This method is no longer supported.")},_keyDown:function(){console.warn("This method is no longer supported.")},_submit:function(){console.warn("This method is no longer supported.")},_keyUpEdit:function(){console.warn("This method is no longer supported.")},_saveEdit:function(){console.warn("This method is no longer supported.")},_cancelEdit:function(){console.warn("This method is no longer supported.")}}),WCF.Comment.Response={}; })(this);
 
 // WCF.ImageViewer.js
-(function (window, undefined) { "use strict";WCF.ImageViewer=Class.extend({_triggerElement:null,init:function(){this._triggerElement=$('<span class="wcfImageViewerTriggerElement" />').data("disableSlideshow",!0).hide().appendTo(document.body),this._triggerElement.wcfImageViewer({enableSlideshow:0,imageSelector:".jsImageViewerEnabled",staticViewer:!0}),WCF.DOMNodeInsertedHandler.addCallback("WCF.ImageViewer",$.proxy(this._domNodeInserted,this)),WCF.DOMNodeInsertedHandler.execute()},_domNodeInserted:function(){this._initImageSizeCheck(),this._rebuildImageViewer()},_rebuildImageViewer:function(){var i=$("a.jsImageViewer");i.length&&i.removeClass("jsImageViewer").addClass("jsImageViewerEnabled").click($.proxy(this._click,this))},_click:function(i){i.ctrlKey||(i.preventDefault(),i.stopPropagation(),$(i.currentTarget).closest(".popover").length||this._triggerElement.wcfImageViewer("open",null,$(i.currentTarget).wcfIdentify()))},_initImageSizeCheck:function(){$(".jsResizeImage").each($.proxy(function(i,e){e.complete&&this._checkImageSize({currentTarget:e})},this)),$(".jsResizeImage").on("load",$.proxy(this._checkImageSize,this))},_checkImageSize:function(i){var e=$(i.currentTarget);if(!e.is(":visible"))return void e.off("load");if(e.removeClass("jsResizeImage"),!e.closest(".messageSignature").length){var t=new Image;t.src=e.attr("src");e.closest("div.messageText, div.messageTextPreview").width()<t.width?e.parents("a").length||(e.wrap('<a href="'+e.attr("src")+'" class="jsImageViewerEnabled embeddedImageLink" />'),e.parent().click($.proxy(this._click,this)),"right"==e.css("float")?e.parent().addClass("messageFloatObjectRight"):"left"==e.css("float")&&e.parent().addClass("messageFloatObjectLeft"),e[0].style.removeProperty("float"),e[0].style.removeProperty("margin")):e.removeClass("embeddedAttachmentLink")}}}),$.widget("ui.wcfImageViewer",{_active:-1,_activeImage:null,_container:null,_didInit:!1,_disableSlideshow:!1,_eventNamespace:"",_images:[],_isMobile:!1,_isOpen:!1,_items:-1,_maxDimensions:{height:0,width:0},_proxy:null,_slideshowEnabled:!1,_thumbnailContainerWidth:0,_thumbnailMarginRight:0,_thumbnailOffset:0,_thumbnailWidth:0,_timer:null,_ui:{buttonNext:null,buttonPrevious:null,header:null,image:null,imageContainer:null,imageList:null,slideshow:{container:null,enlarge:null,next:null,previous:null,toggle:null}},options:{shiftBy:5,enableSlideshow:1,speed:5,className:"",imageSelector:"",staticViewer:!1},_create:function(){this._active=-1,this._activeImage=null,this._container=null,this._didInit=!1,this._disableSlideshow=this.element.data("disableSlideshow"),this._eventNamespace=this.element.wcfIdentify(),this._images=[],this._isMobile=!1,this._isOpen=!1,this._items=-1,this._maxDimensions={height:document.documentElement.clientHeight,width:document.documentElement.clientWidth},this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._slideshowEnabled=!1,this._thumbnailContainerWidth=0,this._thumbnailMarginRight=0,this._thumbnailOffset=0,this._thumbnaiLWidth=0,this._timer=null,this._ui={},this.element.click($.proxy(this.open,this)),window.addEventListener("popstate",function(i){if(null!=i.state&&"imageViewer"===i.state.name&&i.state.container===this._eventNamespace)return this.open(i),void this.showImage(i.state.image);this.close(i)}.bind(this))},open:function(i,e){if(i&&i.preventDefault(),this._isOpen)return!1;if(i&&"popstate"===i.type||window.history.pushState({name:"imageViewer"},"",""),this.options.staticViewer){var t=this._getStaticImages();this._initUI(),this._createThumbnails(t,!0),this._render(!0,void 0,e),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable(),$.browser.touch&&setTimeout($.proxy(function(){this._isMobile&&!this._container.hasClass("maximized")&&this._toggleView()},this),500)}else 0===this._images.length?this._loadNextImages(!0):(this._render(!1,this.element.data("targetImageID")),this._items>1&&this._slideshowEnabled&&this.startSlideshow(),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable());return this._bindListener(),require(["Ui/Screen"],function(i){i.pageOverlayOpen()}),!0},close:function(i){return i&&i.preventDefault(),i&&"popstate"===i.type?!!this._isOpen&&(this._container.removeClass("open"),null!==this._timer&&this._timer.stop(),this._unbindListener(),this._isOpen=!1,WCF.System.DisableScrolling.enable(),WCF.System.DisableZoom.enable(),require(["Ui/Screen"],function(i){i.pageOverlayClose()}),!0):void window.history.back()},startSlideshow:function(){return!this._disableSlideshow&&!this._slideshowEnabled&&(null===this._timer?this._timer=new WCF.PeriodicalExecuter($.proxy(function(){var i=this._active+1;i==this._items&&(i=0),this.showImage(i)},this),1e3*this.options.speed):this._timer.resume(),this._slideshowEnabled=!0,this._ui.slideshow.toggle.children("span").removeClass("fa-play").addClass("fa-pause"),!0)},stopSlideshow:function(i){return!!this._slideshowEnabled&&(this._timer.stop(),i&&this._ui.slideshow.toggle.children("span").removeClass("fa-pause").addClass("fa-play"),this._slideshowEnabled=!1,!0)},_bindListener:function(){$(document).on("keydown."+this._eventNamespace,$.proxy(this._keyDown,this)),$(window).on("resize."+this._eventNamespace,$.proxy(this._renderImage,this))},_unbindListener:function(){$(document).off("keydown."+this._eventNamespace),$(window).off("resize."+this._eventNamespace)},_keyDown:function(i){switch(i.which){case $.ui.keyCode.ESCAPE:this.close();break;case $.ui.keyCode.LEFT:this._previousImage();break;case $.ui.keyCode.RIGHT:this._nextImage();break;case $.ui.keyCode.UP:this._container.hasClass("maximized")||this._toggleView();break;case $.ui.keyCode.DOWN:this._container.hasClass("maximized")&&this._toggleView();break;case $.ui.keyCode.ENTER:var e=this._ui.header.find("h1 > a");1==e.length?window.location=e.prop("href"):this._ui.slideshow.full.trigger("click");break;case 80:this._ui.slideshow.toggle.trigger("click");break;default:return!0}return!1},_render:function(i,e,t){this._container.addClass("open");var s=null;if(i&&(s=this._ui.imageList.children("li:eq(0)"),this._thumbnailMarginRight=parseInt(s.css("marginRight").replace(/px$/,""))||0,this._thumbnailWidth=s.outerWidth(!0),this._thumbnailContainerWidth=this._ui.imageList.parent().innerWidth(),this._items>1&&this.options.enableSlideshow&&!e&&!t&&this.startSlideshow()),e)this._ui.imageList.children("li").each($.proxy(function(i,t){var s=$(t);if(s.data("objectID")==e)return s.trigger("click"),this.moveToImage(s.data("index")),!1},this));else if(t){var a=0;$(this.options.imageSelector).each(function(i,e){if($(e).wcfIdentify()==t)return a=i,!1});var n=this._ui.imageList.children("li:eq("+a+")");if(-1!==this._active){var h=!1;this._active!=n.data("index")&&(h=!0),this._ui.images[this._activeImage].prop("src")!=this._images[this._active].image.url&&(h=!0),h&&(this._active=-1)}n.trigger("click"),this.moveToImage(n.data("index"))}else null!==s&&s.trigger("click");this._toggleButtons(),this._preload()},_preload:function(){if(this._images.length<this._items){this._images.length*this._thumbnailWidth-this._thumbnailOffset<this._thumbnailContainerWidth&&this._loadNextImages(!1)}},_showImage:function(i){this.showImage($(i.currentTarget).data("index"),!0)},showImage:function(i,e){if(this._active==i)return!1;this.stopSlideshow(e||!1),-1!=this._active&&this._images[this._active].listItem.removeClass("active"),this._active=i,window.history.replaceState({name:"imageViewer",container:this._eventNamespace,image:this._active},"","");var t=this._images[i];this._ui.imageList.children("li").removeClass("active"),t.listItem.addClass("active");var s=this._ui.imageContainer.getDimensions("inner"),a=this._activeImage?0:1;null!==this._activeImage&&this._ui.images[this._activeImage].removeClass("active"),this._activeImage=a;var n=this._active;if(this._ui.imageContainer.addClass("loading"),this._ui.images[a].off("load").prop("src","data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="),this._ui.images[a].on("load",$.proxy(function(){this._imageOnLoad(n,a)},this)),this._renderImage(a,t,s),!this.options.staticViewer){this._ui.header.find("> div > a").prop("href",t.user.link).prop("title",t.user.username).children("img").prop("src",t.user.avatarURL)}var h=WCF.String.escapeHTML(t.image.title);if(t.image.link&&(h='<a href="'+t.image.link+'">'+h+"</a>"),this._ui.header.find("h1").html(h),!this.options.staticViewer){var o=t.series&&t.series.title?WCF.String.escapeHTML(t.series.title):"";t.series.link&&(o='<a href="'+t.series.link+'">'+o+"</a>"),this._ui.header.find("h2").html(o)}return this._ui.header.find("h3").text(WCF.Language.get("wcf.imageViewer.seriesIndex").replace(/{x}/,t.listItem.data("index")+1).replace(/{y}/,this._items)),this._ui.slideshow.full.data("link",t.image.fullURL?t.image.fullURL:t.image.url),this.moveToImage(t.listItem.data("index")),this._toggleButtons(),!0},_imageOnLoad:function(i,e){i==this._active&&(this._ui.imageContainer.removeClass("loading"),this._ui.images[e].addClass("active"),this.options.staticViewer&&this._renderImage(e,null),this.startSlideshow())},_renderImage:function(i,e,t){var s=!0;e||(i=this._activeImage,e=this._images[this._active],t={height:$(window).height()-(this._container.hasClass("maximized")||this._container.hasClass("wcfImageViewerMobile")?0:200),width:this._ui.imageContainer.innerWidth()},s=!1),t.height-=22,t.width-=20;var a=this._ui.images[i];if(a.prop("src")!==e.image.url&&a.prop("src",e.image.url),s&&a[0].complete&&a.trigger("load"),this.options.staticViewer&&!e.image.height&&a[0].complete)if($.browser.mozilla||$.browser.safari){var n=new Image;n.src=e.image.url,e.image.height=n.height||a[0].naturalHeight,e.image.width=n.width||a[0].naturalWidth}else a.css({height:"auto",width:"auto"}),e.image.height=a[0].height,e.image.width=a[0].width;var h=e.image.height,o=e.image.width,l=0;h>t.height&&(l=t.height/h,h=t.height,o=Math.floor(o*l)),o>t.width&&(l=t.width/o,o=t.width,h=Math.floor(h*l));var r=Math.floor((t.width-o)/2);this._ui.images[i].css({height:h+"px",left:r+10+"px",marginTop:-1*Math.round(h/2)+"px",width:o+"px"})},_initUI:function(){if(this._didInit)return!1;this._didInit=!0,this._container=$('<div class="wcfImageViewer'+(this.options.staticViewer?" wcfImageViewerStatic":"")+'" />').appendTo(document.body);var i=$("<div><img /><img /></div>").appendTo(this._container),e=$('<footer><span class="wcfImageViewerButtonPrevious icon fa-angle-double-left" /><div><ul /></div><span class="wcfImageViewerButtonNext icon fa-angle-double-right" /></footer>').appendTo(this._container),t=$("<ul />").appendTo(i),s=$('<li class="wcfImageViewerSlideshowButtonPrevious"><span class="icon icon48 fa-angle-left" /></li>').appendTo(t),a=$('<li class="wcfImageViewerSlideshowButtonToggle pointer"><span class="icon icon48 fa-play" /></li>').appendTo(t),n=$('<li class="wcfImageViewerSlideshowButtonNext"><span class="icon icon48 fa-angle-right" /></li>').appendTo(t),h=$('<li class="wcfImageViewerSlideshowButtonEnlarge pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.enlarge")+'"><span class="icon icon48 fa-expand" /></li>').appendTo(t),o=$('<li class="wcfImageViewerSlideshowButtonFull pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.full")+'"><span class="icon icon48 fa-external-link" /></li>').appendTo(t);return this._ui={buttonNext:e.children("span.wcfImageViewerButtonNext"),buttonPrevious:e.children("span.wcfImageViewerButtonPrevious"),header:$("<header><div"+(this.options.staticViewer?">":' class="box64"><a class="jsTooltip"><img /></a>')+"<div><h1 /><h2 /><h3 /></div></div></header>").appendTo(this._container),imageContainer:i,images:[i.children("img:eq(0)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")}),i.children("img:eq(1)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")})],imageList:e.find("> div > ul"),slideshow:{container:t,enlarge:h,full:o,next:n,previous:s,toggle:a}},this._ui.buttonNext.click($.proxy(this._next,this)),this._ui.buttonPrevious.click($.proxy(this._previous,this)),n.click($.proxy(this._nextImage,this)),s.click($.proxy(this._previousImage,this)),h.click($.proxy(this._toggleView,this)),a.click($.proxy(function(){this._items<2||(this._slideshowEnabled?this.stopSlideshow(!0):(this._disableSlideshow=!1,this.startSlideshow()))},this)),o.click(function(i){window.location=$(i.currentTarget).data("link")}),$('<span class="wcfImageViewerButtonClose icon icon48 fa-times pointer jsTooltip" title="'+WCF.Language.get("wcf.global.button.close")+'" />').appendTo(this._ui.header).click($.proxy(this.close,this)),$.browser.mobile||i.click(function(e){e.target===i[0]&&this.close()}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),require(["Ui/Screen"],function(i){i.on("screen-sm-down",{match:$.proxy(this._enableMobileView,this),unmatch:$.proxy(this._disableMobileView,this)})}.bind(this)),!0},_enableMobileView:function(){this._container.addClass("wcfImageViewerMobile");var i=this;this._ui.imageContainer.swipe({swipeLeft:function(e){i._container.hasClass("maximized")&&i._nextImage(e)},swipeRight:function(e){i._container.hasClass("maximized")&&i._previousImage(e)},tap:function(e,t){switch(t.tagName){case"DIV":case"IMG":i._toggleView()}}}),this._isMobile=!0},_disableMobileView:function(){this._container.removeClass("wcfImageViewerMobile"),this._ui.imageContainer.swipe("destroy"),this._isMobile=!1},_toggleView:function(){this._ui.images[this._activeImage].addClass("animateTransformation"),this._container.toggleClass("maximized"),this._ui.slideshow.enlarge.toggleClass("active").children("span").toggleClass("fa-expand").toggleClass("fa-compress"),this._renderImage(null,void 0,null)},_next:function(i,e){if(this._ui.buttonNext.hasClass("pointer")){void 0==e&&this.stopSlideshow(!0);var t=Math.max(this._items*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight,0);this._thumbnailOffset=Math.min(this._thumbnailOffset+this._thumbnailWidth*(e||this.options.shiftBy),t),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)}this._preload(),this._toggleButtons()},_previous:function(i,e){this._ui.buttonPrevious.hasClass("pointer")&&(void 0==e&&this.stopSlideshow(!0),this._thumbnailOffset=Math.max(this._thumbnailOffset-this._thumbnailWidth*(e||this.options.shiftBy),0),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)),this._toggleButtons()},_nextImage:function(i){this._ui.slideshow.next.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active+1),i&&(i.preventDefault(),i.stopPropagation()))},_previousImage:function(i){this._ui.slideshow.previous.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active-1),i&&(i.preventDefault(),i.stopPropagation()))},moveToImage:function(i){var e=(i-3)*this._thumbnailWidth,t=e+5*this._thumbnailWidth,s=this._thumbnailOffset,a=this._thumbnailOffset+this._thumbnailContainerWidth,n=!1;if((e<s||t>a)&&(n=!0),n){var h=0;if(e<s){for(;e<s;)h++,s-=this._thumbnailWidth;this._previous(null,h)}else{for(;t>a;)h++,a+=this._thumbnailWidth;this._next(null,h)}}},_toggleButtons:function(){this._thumbnailOffset>0?this._ui.buttonPrevious.addClass("pointer"):this._ui.buttonPrevious.removeClass("pointer");var i=this._images.length*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight;this._thumbnailOffset>=i?this._ui.buttonNext.removeClass("pointer"):this._ui.buttonNext.addClass("pointer"),this._active>0?this._ui.slideshow.previous.addClass("pointer"):this._ui.slideshow.previous.removeClass("pointer"),this._active+1<this._images.length?this._ui.slideshow.next.addClass("pointer"):this._ui.slideshow.next.removeClass("pointer"),this._items<2?this._ui.slideshow.toggle.removeClass("pointer"):this._ui.slideshow.toggle.addClass("pointer")},_createThumbnails:function(i){this.options.staticViewer&&(this._images=[],this._ui.imageList.empty());for(var e=0,t=i.length;e<t;e++){var s=i[e],a=$('<li class="loading pointer"><img src="'+s.thumbnail.url+'" /></li>').appendTo(this._ui.imageList);a.data("index",this._images.length).data("objectID",s.objectID).click($.proxy(this._showImage,this));var n=a.children("img");if(n.get(0).complete)a.removeClass("loading"),this.options.staticViewer&&this._fixThumbnailDimensions(n);else{var h=this;n.on("load",function(){var i=$(this);i.parent().removeClass("loading"),h.options.staticViewer&&h._fixThumbnailDimensions(i)})}s.listItem=a,this._images.push(s)}},_fixThumbnailDimensions:function(i){var e=new Image;e.src=i.prop("src");var t=e.height,s=e.width;if(t==s)t=s=80;else if(t<s){var a=80/s;s=80,t*=a}else{var a=80/t;t=80,s*=a}i.css({height:t+"px",width:s+"px"})},_loadNextImages:function(i){this._proxy.setOption("data",{actionName:"loadNextImages",className:this.options.className,interfaceName:"wcf\\data\\IImageViewerAction",objectIDs:[this.element.data("objectID")],parameters:{maximumHeight:this._maxDimensions.height,maximumWidth:this._maxDimensions.width,offset:this._images.length,targetImageID:i&&this.element.data("targetImageID")?this.element.data("targetImageID"):0}}),this._proxy.setOption("showLoadingOverlay",!1),this._proxy.sendRequest()},_getStaticImages:function(){var i=[];return $(this.options.imageSelector).each(function(e,t){var s=$(t),a=s.find("> img, .attachmentThumbnailImage > img").first();a.length||(a=s.parentsUntil(".formAttachmentList").last().find(".attachmentTinyThumbnail")),i.push({image:{fullURL:a.data("source")?a.data("source").replace(/\\\//g,"/"):s.prop("href"),link:"",title:s.prop("title"),url:s.prop("href")},series:null,thumbnail:{url:a.prop("src")},user:null})}),this._items=i.length,i},_success:function(i,e,t){i.returnValues.items&&(this._items=i.returnValues.items);var s=this._initUI();this._createThumbnails(i.returnValues.images);var a=i.returnValues.targetImageID?i.returnValues.targetImageID:0;this._render(s,a),this._isOpen||(this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable())}}); })(this);
+(function (window, undefined) { "use strict";WCF.ImageViewer=Class.extend({_triggerElement:null,init:function(){this._triggerElement=$('<span class="wcfImageViewerTriggerElement" />').data("disableSlideshow",!0).hide().appendTo(document.body),this._triggerElement.wcfImageViewer({enableSlideshow:0,imageSelector:".jsImageViewerEnabled",staticViewer:!0}),WCF.DOMNodeInsertedHandler.addCallback("WCF.ImageViewer",$.proxy(this._domNodeInserted,this)),WCF.DOMNodeInsertedHandler.execute()},_domNodeInserted:function(){this._initImageSizeCheck(),this._rebuildImageViewer()},_rebuildImageViewer:function(){var i=$("a.jsImageViewer");i.length&&i.removeClass("jsImageViewer").addClass("jsImageViewerEnabled").click($.proxy(this._click,this))},_click:function(i){i.ctrlKey||(i.preventDefault(),i.stopPropagation(),$(i.currentTarget).closest(".popover").length||this._triggerElement.wcfImageViewer("open",null,$(i.currentTarget).wcfIdentify()))},_initImageSizeCheck:function(){$(".jsResizeImage").each($.proxy(function(i,e){e.complete&&this._checkImageSize({currentTarget:e})},this)),$(".jsResizeImage").on("load",$.proxy(this._checkImageSize,this))},_checkImageSize:function(i){var e,t=$(i.currentTarget);t.is(":visible")?(t.removeClass("jsResizeImage"),t.closest(".messageSignature").length||((e=new Image).src=t.attr("src"),t.closest("div.messageText, div.messageTextPreview").width()<e.width?t.parents("a").length||(t.wrap('<a href="'+t.attr("src")+'" class="jsImageViewerEnabled embeddedImageLink" />'),t.parent().click($.proxy(this._click,this)),"right"==t.css("float")?t.parent().addClass("messageFloatObjectRight"):"left"==t.css("float")&&t.parent().addClass("messageFloatObjectLeft"),t[0].style.removeProperty("float"),t[0].style.removeProperty("margin")):t.removeClass("embeddedAttachmentLink"))):t.off("load")}}),$.widget("ui.wcfImageViewer",{_active:-1,_activeImage:null,_container:null,_didInit:!1,_disableSlideshow:!1,_eventNamespace:"",_images:[],_isMobile:!1,_isOpen:!1,_messageSignature:null,_items:-1,_maxDimensions:{height:0,width:0},_proxy:null,_slideshowEnabled:!1,_thumbnailContainerWidth:0,_thumbnailMarginRight:0,_thumbnailOffset:0,_thumbnailWidth:0,_timer:null,_ui:{buttonNext:null,buttonPrevious:null,header:null,image:null,imageContainer:null,imageList:null,slideshow:{container:null,enlarge:null,next:null,previous:null,toggle:null}},options:{shiftBy:5,enableSlideshow:1,speed:5,className:"",imageSelector:"",staticViewer:!1},_create:function(){this._active=-1,this._activeImage=null,this._container=null,this._didInit=!1,this._disableSlideshow=this.element.data("disableSlideshow"),this._eventNamespace=this.element.wcfIdentify(),this._images=[],this._isMobile=!1,this._isOpen=!1,this._items=-1,this._maxDimensions={height:document.documentElement.clientHeight,width:document.documentElement.clientWidth},this._messageSignature=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._slideshowEnabled=!1,this._thumbnailContainerWidth=0,this._thumbnailMarginRight=0,this._thumbnailOffset=0,this._thumbnaiLWidth=0,this._timer=null,this._ui={},this.element.click($.proxy(this.open,this)),window.addEventListener("popstate",function(i){if(null!=i.state&&"imageViewer"===i.state.name&&i.state.container===this._eventNamespace)return this.open(i),void this.showImage(i.state.image);this.close(i)}.bind(this))},open:function(i,e){return i&&i.preventDefault(),!this._isOpen&&(i&&"popstate"===i.type||window.history.pushState({name:"imageViewer"},"",""),this._messageSignature=null,this.options.staticViewer?(e&&(this._messageSignature=document.getElementById(e).closest(".messageSignature")),this._active=-1,this._activeImage=null,t=this._getStaticImages(),this._initUI(),this._createThumbnails(t,!0),this._render(!0,void 0,e),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable(),$.browser.touch&&setTimeout($.proxy(function(){this._isMobile&&!this._container.hasClass("maximized")&&this._toggleView()},this),500)):0===this._images.length?this._loadNextImages(!0):(this._render(!1,this.element.data("targetImageID")),1<this._items&&this._slideshowEnabled&&this.startSlideshow(),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable()),this._bindListener(),require(["Ui/Screen"],function(i){i.pageOverlayOpen()}),!0);var t},close:function(i){if(i&&i.preventDefault(),i&&"popstate"===i.type)return!!this._isOpen&&(this._container.removeClass("open"),null!==this._timer&&this._timer.stop(),this._unbindListener(),this._isOpen=!1,WCF.System.DisableScrolling.enable(),WCF.System.DisableZoom.enable(),require(["Ui/Screen"],function(i){i.pageOverlayClose()}),!0);window.history.back()},startSlideshow:function(){return!this._disableSlideshow&&!this._slideshowEnabled&&(null===this._timer?this._timer=new WCF.PeriodicalExecuter($.proxy(function(){var i=this._active+1;i==this._items&&(i=0),this.showImage(i)},this),1e3*this.options.speed):this._timer.resume(),this._slideshowEnabled=!0,this._ui.slideshow.toggle.children("span").removeClass("fa-play").addClass("fa-pause"),!0)},stopSlideshow:function(i){return!!this._slideshowEnabled&&(this._timer.stop(),i&&this._ui.slideshow.toggle.children("span").removeClass("fa-pause").addClass("fa-play"),!(this._slideshowEnabled=!1))},_bindListener:function(){$(document).on("keydown."+this._eventNamespace,$.proxy(this._keyDown,this)),$(window).on("resize."+this._eventNamespace,$.proxy(this._renderImage,this))},_unbindListener:function(){$(document).off("keydown."+this._eventNamespace),$(window).off("resize."+this._eventNamespace)},_keyDown:function(i){switch(i.which){case $.ui.keyCode.ESCAPE:this.close();break;case $.ui.keyCode.LEFT:this._previousImage();break;case $.ui.keyCode.RIGHT:this._nextImage();break;case $.ui.keyCode.UP:this._container.hasClass("maximized")||this._toggleView();break;case $.ui.keyCode.DOWN:this._container.hasClass("maximized")&&this._toggleView();break;case $.ui.keyCode.ENTER:var e=this._ui.header.find("h1 > a");1==e.length?window.location=e.prop("href"):this._ui.slideshow.full.trigger("click");break;case 80:this._ui.slideshow.toggle.trigger("click");break;default:return!0}return!1},_render:function(i,s,t){this._container.addClass("open");var a,n,e,h,o=null;i&&(o=this._ui.imageList.children("li:eq(0)"),this._thumbnailMarginRight=parseInt(o.css("marginRight").replace(/px$/,""))||0,this._thumbnailWidth=o.outerWidth(!0),this._thumbnailContainerWidth=this._ui.imageList.parent().innerWidth(),1<this._items&&this.options.enableSlideshow&&!s&&!t&&this.startSlideshow()),s?this._ui.imageList.children("li").each($.proxy(function(i,e){var t=$(e);if(t.data("objectID")==s)return t.trigger("click"),this.moveToImage(t.data("index")),!1},this)):t?(a=[],$(this.options.imageSelector).each(function(i,e){e.closest(".messageSignature")===this._messageSignature&&a.push(e)}.bind(this)),n=0,a.forEach(function(i,e){i.id===t&&(n=e)}),e=this._ui.imageList.children("li:eq("+n+")"),-1!==this._active&&(h=!1,this._active!=e.data("index")&&(h=!0),this._ui.images[this._activeImage].prop("src")!=this._images[this._active].image.url&&(h=!0),h&&(this._active=-1)),e.trigger("click"),this.moveToImage(e.data("index"))):null!==o&&o.trigger("click"),this._toggleButtons(),this._preload()},_preload:function(){this._images.length<this._items&&this._images.length*this._thumbnailWidth-this._thumbnailOffset<this._thumbnailContainerWidth&&this._loadNextImages(!1)},_showImage:function(i){this.showImage($(i.currentTarget).data("index"),!0)},showImage:function(i,e){if(this._active==i)return!1;this.stopSlideshow(e||!1),-1!=this._active&&this._images[this._active].listItem.removeClass("active"),this._active=i,window.history.replaceState({name:"imageViewer",container:this._eventNamespace,image:this._active},"","");var t=this._images[i];this._ui.imageList.children("li").removeClass("active"),t.listItem.addClass("active");var s=this._ui.imageContainer.getDimensions("inner"),a=this._activeImage?0:1;null!==this._activeImage&&this._ui.images[this._activeImage].removeClass("active"),this._activeImage=a;var n=this._active;this._ui.imageContainer.addClass("loading"),this._ui.images[a].off("load").prop("src","data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="),this._ui.images[a].on("load",$.proxy(function(){this._imageOnLoad(n,a)},this)),this._renderImage(a,t,s),this.options.staticViewer||this._ui.header.find("> div > a").prop("href",t.user.link).prop("title",t.user.username).children("img").prop("src",t.user.avatarURL);var h,o=WCF.String.escapeHTML(t.image.title);return t.image.link&&(o='<a href="'+t.image.link+'">'+o+"</a>"),this._ui.header.find("h1").html(o),this.options.staticViewer||(h=t.series&&t.series.title?WCF.String.escapeHTML(t.series.title):"",t.series.link&&(h='<a href="'+t.series.link+'">'+h+"</a>"),this._ui.header.find("h2").html(h)),this._ui.header.find("h3").text(WCF.Language.get("wcf.imageViewer.seriesIndex").replace(/{x}/,t.listItem.data("index")+1).replace(/{y}/,this._items)),this._ui.slideshow.full.data("link",t.image.fullURL?t.image.fullURL:t.image.url),this.moveToImage(t.listItem.data("index")),this._toggleButtons(),!0},_imageOnLoad:function(i,e){i==this._active&&(this._ui.imageContainer.removeClass("loading"),this._ui.images[e].addClass("active"),this.options.staticViewer&&this._renderImage(e,null),this.startSlideshow())},_renderImage:function(i,e,t){var s=!0;e||(i=this._activeImage,e=this._images[this._active],s=!(t={height:$(window).height()-(this._container.hasClass("maximized")||this._container.hasClass("wcfImageViewerMobile")?0:200),width:this._ui.imageContainer.innerWidth()})),t.height-=22,t.width-=20;var a,n=this._ui.images[i];n.prop("src")!==e.image.url&&n.prop("src",e.image.url),s&&n[0].complete&&n.trigger("load"),this.options.staticViewer&&!e.image.height&&n[0].complete&&($.browser.mozilla||$.browser.safari?((a=new Image).src=e.image.url,e.image.height=a.height||n[0].naturalHeight,e.image.width=a.width||n[0].naturalWidth):(n.css({height:"auto",width:"auto"}),e.image.height=n[0].height,e.image.width=n[0].width));var h=e.image.height,o=e.image.width,l=0;h>t.height&&(l=t.height/h,h=t.height,o=Math.floor(o*l)),o>t.width&&(l=t.width/o,o=t.width,h=Math.floor(h*l));var r=Math.floor((t.width-o)/2);this._ui.images[i].css({height:h+"px",left:r+10+"px",marginTop:-1*Math.round(h/2)+"px",width:o+"px"})},_initUI:function(){if(this._didInit)return!1;this._didInit=!0,this._container=$('<div class="wcfImageViewer'+(this.options.staticViewer?" wcfImageViewerStatic":"")+'" />').appendTo(document.body);var e=$("<div><img /><img /></div>").appendTo(this._container),i=$('<footer><span class="wcfImageViewerButtonPrevious icon fa-angle-double-left" /><div><ul /></div><span class="wcfImageViewerButtonNext icon fa-angle-double-right" /></footer>').appendTo(this._container),t=$("<ul />").appendTo(e),s=$('<li class="wcfImageViewerSlideshowButtonPrevious"><span class="icon icon48 fa-angle-left" /></li>').appendTo(t),a=$('<li class="wcfImageViewerSlideshowButtonToggle pointer"><span class="icon icon48 fa-play" /></li>').appendTo(t),n=$('<li class="wcfImageViewerSlideshowButtonNext"><span class="icon icon48 fa-angle-right" /></li>').appendTo(t),h=$('<li class="wcfImageViewerSlideshowButtonEnlarge pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.enlarge")+'"><span class="icon icon48 fa-expand" /></li>').appendTo(t),o=$('<li class="wcfImageViewerSlideshowButtonFull pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.full")+'"><span class="icon icon48 fa-external-link" /></li>').appendTo(t);return this._ui={buttonNext:i.children("span.wcfImageViewerButtonNext"),buttonPrevious:i.children("span.wcfImageViewerButtonPrevious"),header:$("<header><div"+(this.options.staticViewer?">":' class="box64"><a class="jsTooltip"><img /></a>')+"<div><h1 /><h2 /><h3 /></div></div></header>").appendTo(this._container),imageContainer:e,images:[e.children("img:eq(0)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")}),e.children("img:eq(1)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")})],imageList:i.find("> div > ul"),slideshow:{container:t,enlarge:h,full:o,next:n,previous:s,toggle:a}},this._ui.buttonNext.click($.proxy(this._next,this)),this._ui.buttonPrevious.click($.proxy(this._previous,this)),n.click($.proxy(this._nextImage,this)),s.click($.proxy(this._previousImage,this)),h.click($.proxy(this._toggleView,this)),a.click($.proxy(function(){this._items<2||(this._slideshowEnabled?this.stopSlideshow(!0):(this._disableSlideshow=!1,this.startSlideshow()))},this)),o.click(function(i){window.location=$(i.currentTarget).data("link")}),$('<span class="wcfImageViewerButtonClose icon icon48 fa-times pointer jsTooltip" title="'+WCF.Language.get("wcf.global.button.close")+'" />').appendTo(this._ui.header).click($.proxy(this.close,this)),$.browser.mobile||e.click(function(i){i.target===e[0]&&this.close()}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),require(["Ui/Screen"],function(i){i.on("screen-sm-down",{match:$.proxy(this._enableMobileView,this),unmatch:$.proxy(this._disableMobileView,this)})}.bind(this)),!0},_enableMobileView:function(){this._container.addClass("wcfImageViewerMobile");var t=this;this._ui.imageContainer.swipe({swipeLeft:function(i){t._container.hasClass("maximized")&&t._nextImage(i)},swipeRight:function(i){t._container.hasClass("maximized")&&t._previousImage(i)},tap:function(i,e){switch(e.tagName){case"DIV":case"IMG":t._toggleView()}}}),this._isMobile=!0},_disableMobileView:function(){this._container.removeClass("wcfImageViewerMobile"),this._ui.imageContainer.swipe("destroy"),this._isMobile=!1},_toggleView:function(){this._ui.images[this._activeImage].addClass("animateTransformation"),this._container.toggleClass("maximized"),this._ui.slideshow.enlarge.toggleClass("active").children("span").toggleClass("fa-expand").toggleClass("fa-compress"),this._renderImage(null,void 0,null)},_next:function(i,e){var t;this._ui.buttonNext.hasClass("pointer")&&(null==e&&this.stopSlideshow(!0),t=Math.max(this._items*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight,0),this._thumbnailOffset=Math.min(this._thumbnailOffset+this._thumbnailWidth*(e||this.options.shiftBy),t),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)),this._preload(),this._toggleButtons()},_previous:function(i,e){this._ui.buttonPrevious.hasClass("pointer")&&(null==e&&this.stopSlideshow(!0),this._thumbnailOffset=Math.max(this._thumbnailOffset-this._thumbnailWidth*(e||this.options.shiftBy),0),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)),this._toggleButtons()},_nextImage:function(i){this._ui.slideshow.next.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active+1),i&&(i.preventDefault(),i.stopPropagation()))},_previousImage:function(i){this._ui.slideshow.previous.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active-1),i&&(i.preventDefault(),i.stopPropagation()))},moveToImage:function(i){var e=(i-3)*this._thumbnailWidth,t=e+5*this._thumbnailWidth,s=this._thumbnailOffset,a=this._thumbnailOffset+this._thumbnailContainerWidth;if(e<s||a<t?!0:!1){var n=0;if(e<s){for(;e<s;)n++,s-=this._thumbnailWidth;this._previous(null,n)}else{for(;a<t;)n++,a+=this._thumbnailWidth;this._next(null,n)}}},_toggleButtons:function(){0<this._thumbnailOffset?this._ui.buttonPrevious.addClass("pointer"):this._ui.buttonPrevious.removeClass("pointer");var i=this._images.length*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight;this._thumbnailOffset>=i?this._ui.buttonNext.removeClass("pointer"):this._ui.buttonNext.addClass("pointer"),0<this._active?this._ui.slideshow.previous.addClass("pointer"):this._ui.slideshow.previous.removeClass("pointer"),this._active+1<this._images.length?this._ui.slideshow.next.addClass("pointer"):this._ui.slideshow.next.removeClass("pointer"),this._items<2?this._ui.slideshow.toggle.removeClass("pointer"):this._ui.slideshow.toggle.addClass("pointer")},_createThumbnails:function(i){this.options.staticViewer&&(this._images=[],this._ui.imageList.empty());for(var e=0,t=i.length;e<t;e++){var s=i[e],a=$('<li class="loading pointer"><img src="'+s.thumbnail.url+'" /></li>').appendTo(this._ui.imageList);a.data("index",this._images.length).data("objectID",s.objectID).click($.proxy(this._showImage,this));var n,h=a.children("img");h.get(0).complete?(a.removeClass("loading"),this.options.staticViewer&&this._fixThumbnailDimensions(h)):(n=this,h.on("load",function(){var i=$(this);i.parent().removeClass("loading"),n.options.staticViewer&&n._fixThumbnailDimensions(i)})),s.listItem=a,this._images.push(s)}},_fixThumbnailDimensions:function(i){var e=new Image;e.src=i.prop("src");var t,s=e.height,a=e.width;s==a?s=a=80:s<a?(t=80/a,a=80,s*=t):(t=80/s,s=80,a*=t),i.css({height:s+"px",width:a+"px"})},_loadNextImages:function(i){this._proxy.setOption("data",{actionName:"loadNextImages",className:this.options.className,interfaceName:"wcf\\data\\IImageViewerAction",objectIDs:[this.element.data("objectID")],parameters:{maximumHeight:this._maxDimensions.height,maximumWidth:this._maxDimensions.width,offset:this._images.length,targetImageID:i&&this.element.data("targetImageID")?this.element.data("targetImageID"):0}}),this._proxy.setOption("showLoadingOverlay",!1),this._proxy.sendRequest()},_getStaticImages:function(){var a=[];return $(this.options.imageSelector).each(function(i,e){var t,s;e.closest(".messageSignature")===this._messageSignature&&((s=(t=$(e)).find("> img, .attachmentThumbnailImage > img").first()).length||(s=t.parentsUntil(".formAttachmentList").last().find(".attachmentTinyThumbnail")),a.push({image:{fullURL:s.data("source")?s.data("source").replace(/\\\//g,"/"):t.prop("href"),link:"",title:t.prop("title"),url:t.prop("href")},series:null,thumbnail:{url:s.prop("src")},user:null}))}.bind(this)),this._items=a.length,a},_success:function(i,e,t){i.returnValues.items&&(this._items=i.returnValues.items);var s=this._initUI();this._createThumbnails(i.returnValues.images);var a=i.returnValues.targetImageID?i.returnValues.targetImageID:0;this._render(s,a),this._isOpen||(this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable())}}); })(this);
 
 // WCF.Label.js
-(function (window, undefined) { "use strict";WCF.Label={},WCF.Label.ACPList=Class.extend({_labelInput:null,_labelList:[],init:function(){this._labelInput=$("#label").keydown($.proxy(this._keyPressed,this)).keyup($.proxy(this._keyPressed,this)).blur($.proxy(this._keyPressed,this)),$.browser.mozilla&&$.browser.touch&&this._labelInput.on("input",$.proxy(this._keyPressed,this)),$("#labelList").find('input[type="radio"]').each($.proxy(function(e,t){var i=$(t);"custom"!==i.prop("value")&&this._labelList.push($(i.next("span")))},this)),this._labelInput[0].value.length>0&&this._keyPressed()},_keyPressed:function(){var e=this._labelInput.prop("value");""===e&&(e=WCF.Language.get("wcf.acp.label.defaultValue"));for(var t=0,i=this._labelList.length;t<i;t++)this._labelList[t].text(e)}}),WCF.Label.ACPList.Connect=Class.extend({init:function(){var e=$("#connect .structuredList li");e.length&&e.each($.proxy(function(e,t){$(t).find('input[type="checkbox"]').click($.proxy(this._click,this))},this))},_click:function(e){var t=$(e.currentTarget);if(t.is(":checked")){t=t.parents("li");for(var i=t.data("depth");;){if(t=t.next(),!t.length)return!0;if(t.data("depth")<=i)return!0;t.find('input[type="checkbox"]').prop("checked","checked")}}}}),WCF.Label.Chooser=Class.extend({_container:null,_groups:{},_showWithoutSelection:!1,init:function(e,t,i,a){if(this._container=null,this._groups={},this._showWithoutSelection=!0===a,this._initContainers(t),$.getLength(e))for(var n in e){var s=this._groups[n];s&&WCF.Dropdown.getDropdownMenu(s.wcfIdentify()).find("> ul > li:not(.dropdownDivider)").each($.proxy(function(t,i){var a=$(i),s=a.data("labelID")||0;s&&e[n]==s&&this._selectLabel(a,!0)},this))}for(var o in this._containers){var l=this._containers[o];void 0===l.data("labelID")&&l.data("labelID",0)}this._container=$(t),i?$(i).click($.proxy(this._submit,this)):this._container.is("form")&&this._container.submit($.proxy(this._submit,this))},_initContainers:function(e){function t(e){e.addEventListener("wheel",function(e){e.preventDefault()},{passive:!1})}$(e).find(".labelChooser").each($.proxy(function(e,i){var a=$(i),n=a.data("groupID");if(!this._groups[n]){var s=a.wcfIdentify(),o=WCF.Dropdown.getDropdownMenu(s);null===o&&(WCF.Dropdown.initDropdown(a.find(".dropdownToggle")),o=WCF.Dropdown.getDropdownMenu(s));var l=o;if("div"==o.getTagName()&&o.children(".scrollableDropdownMenu").length&&(l=$("<ul />").appendTo(o),o=o.children(".scrollableDropdownMenu")),this._groups[n]=a,o.children("li").data("groupID",n).click($.proxy(this._click,this)),a.data("forceSelection")&&!this._showWithoutSelection||$('<li class="dropdownDivider" />').appendTo(l),this._showWithoutSelection){t($('<li data-label-id="-1"><span><span class="badge label">'+WCF.Language.get("wcf.label.withoutSelection")+"</span></span></li>").data("groupID",n).appendTo(l).click($.proxy(this._click,this))[0])}if(!a.data("forceSelection")){var r=$('<li data-label-id="0"><span><span class="badge label">'+WCF.Language.get("wcf.label.none")+"</span></span></li>").data("groupID",n).appendTo(l);r.click($.proxy(this._click,this)),t(r[0])}}},this))},_click:function(e){this._selectLabel($(e.currentTarget),!1)},_selectLabel:function(e,t){var i=this._groups[e.data("groupID")];t&&void 0!==i.data("labelID")||(e.data("labelID")?i.data("labelID",e.data("labelID")):i.data("labelID",0),e=e.find("span > span"),i.find(".dropdownToggle > span").removeClass().addClass(e.attr("class")).text(e.text()),!t&&this._container[0]&&"FORM"===this._container[0].nodeName&&null===elBySel('input:not([type="hidden"]):not([type="submit"]):not([type="reset"]), select, textarea',this._container[0])&&setTimeout(function(){this._container.trigger("submit")}.bind(this),100))},_submit:function(){var e=this._container.find(".formSubmit");e.find('input[type="hidden"]').each(function(e,t){var i=$(t);0===i.attr("name").indexOf("labelIDs[")&&i.remove()});for(var t in this._groups){var i=this._groups[t];i.data("labelID")&&$('<input type="hidden" name="labelIDs['+t+']" value="'+i.data("labelID")+'" />').appendTo(e)}},destroy:function(){for(var e in this._groups)WCF.Dropdown.destroy(this._groups[e].wcfIdentify())}}),WCF.Label.ArticleLabelChooser=WCF.Label.Chooser.extend({_labelGroupsToCategories:null,init:function(e,t,i,a,n){this._super(t,i,a,n),this._labelGroupsToCategories=e,this._updateLabelGroups(),$("#categoryID").change($.proxy(this._updateLabelGroups,this))},_updateLabelGroups:function(){$(".labelChooser").each(function(e,t){$(t).parents("dl:eq(0)").hide()});var e=parseInt($("#categoryID").val());if(this._labelGroupsToCategories[e])for(var t=0,i=this._labelGroupsToCategories[e].length;t<i;t++)$("#labelGroup"+this._labelGroupsToCategories[e][t]).parents("dl:eq(0)").show()},_submit:function(){for(var e in this._groups)this._groups[e].is(":visible")||delete this._groups[e];this._super()}}); })(this);
+(function (window, undefined) { "use strict";WCF.Label={},WCF.Label.ACPList=Class.extend({_labelInput:{},_labelList:{},init:function(){},_keyPressed:function(){}}),WCF.Label.ACPList.Connect=Class.extend({init:function(){var t=$("#connect .structuredList li");t.length&&t.each($.proxy(function(t,e){$(e).find('input[type="checkbox"]').click($.proxy(this._click,this))},this))},_click:function(t){var e=$(t.currentTarget);if(e.is(":checked"))for(var i=(e=e.parents("li")).data("depth");;){if(!(e=e.next()).length)return!0;if(e.data("depth")<=i)return!0;e.find('input[type="checkbox"]').prop("checked","checked")}}}),WCF.Label.Chooser=Class.extend({_container:null,_groups:{},_showWithoutSelection:!1,init:function(a,t,e,i){if(this._container=null,this._groups={},this._showWithoutSelection=!0===i,this._initContainers(t),$.getLength(a))for(var o in a){var n=this._groups[o];n&&WCF.Dropdown.getDropdownMenu(n.wcfIdentify()).find("> ul > li:not(.dropdownDivider)").each($.proxy(function(t,e){var i=$(e),n=i.data("labelID")||0;n&&a[o]==n&&this._selectLabel(i,!0)},this))}for(var s in this._containers){var r=this._containers[s];void 0===r.data("labelID")&&r.data("labelID",0)}this._container=$(t),e?$(e).click($.proxy(this._submit,this)):this._container.is("form")&&this._container.submit($.proxy(this._submit,this))},_initContainers:function(t){function l(t){t.addEventListener("wheel",function(t){t.preventDefault()},{passive:!1})}$(t).find(".labelChooser").each($.proxy(function(t,e){var i,n,a,o,s=$(e),r=s.data("groupID");this._groups[r]||(i=s.wcfIdentify(),null===(n=WCF.Dropdown.getDropdownMenu(i))&&(WCF.Dropdown.initDropdown(s.find(".dropdownToggle")),n=WCF.Dropdown.getDropdownMenu(i)),"div"==(a=n).getTagName()&&n.children(".scrollableDropdownMenu").length&&(a=$("<ul />").appendTo(n),n=n.children(".scrollableDropdownMenu")),this._groups[r]=s,n.children("li").data("groupID",r).click($.proxy(this._click,this)),s.data("forceSelection")&&!this._showWithoutSelection||$('<li class="dropdownDivider" />').appendTo(a),this._showWithoutSelection&&l($('<li data-label-id="-1"><span><span class="badge label">'+WCF.Language.get("wcf.label.withoutSelection")+"</span></span></li>").data("groupID",r).appendTo(a).click($.proxy(this._click,this))[0]),s.data("forceSelection")||((o=$('<li data-label-id="0"><span><span class="badge label">'+WCF.Language.get("wcf.label.none")+"</span></span></li>").data("groupID",r).appendTo(a)).click($.proxy(this._click,this)),l(o[0])))},this))},_click:function(t){this._selectLabel($(t.currentTarget),!1)},_selectLabel:function(t,e){var i=this._groups[t.data("groupID")];e&&void 0!==i.data("labelID")||(t.data("labelID")?i.data("labelID",t.data("labelID")):i.data("labelID",0),t=t.find("span > span"),i.find(".dropdownToggle > span").removeClass().addClass(t.attr("class")).text(t.text()),!e&&this._container[0]&&"FORM"===this._container[0].nodeName&&null===elBySel('input:not([type="hidden"]):not([type="submit"]):not([type="reset"]), select, textarea',this._container[0])&&setTimeout(function(){this._container.trigger("submit")}.bind(this),100))},_submit:function(){var t=this._container.find(".formSubmit");for(var e in t.find('input[type="hidden"]').each(function(t,e){var i=$(e);0===i.attr("name").indexOf("labelIDs[")&&i.remove()}),this._groups){var i=this._groups[e];i.data("labelID")&&$('<input type="hidden" name="labelIDs['+e+']" value="'+i.data("labelID")+'" />').appendTo(t)}},destroy:function(){for(var t in this._groups)WCF.Dropdown.destroy(this._groups[t].wcfIdentify())}}),WCF.Label.ArticleLabelChooser=WCF.Label.Chooser.extend({_labelGroupsToCategories:null,init:function(t,e,i,n,a){this._super(e,i,n,a),this._labelGroupsToCategories=t,this._updateLabelGroups(),$("#categoryID").change($.proxy(this._updateLabelGroups,this))},_updateLabelGroups:function(){$(".labelChooser").each(function(t,e){$(e).parents("dl:eq(0)").hide()});var t=parseInt($("#categoryID").val());if(this._labelGroupsToCategories[t])for(var e=0,i=this._labelGroupsToCategories[t].length;e<i;e++)$("#labelGroup"+this._labelGroupsToCategories[t][e]).parents("dl:eq(0)").show()},_submit:function(){for(var t in this._groups)this._groups[t].is(":visible")||delete this._groups[t];this._super()}}); })(this);
 
 // WCF.Location.js
-(function (window, undefined) { "use strict";function gm_authFailure(){WCF.System.Event.fireEvent("com.woltlab.wcf.googleMaps","authenticationFailure")}WCF.Location={},WCF.Location.Util={getLocation:function(t,e){var o=WCF.Location.GoogleMaps.Settings.get("accessUserLocation");navigator.geolocation&&null!==o&&o?navigator.geolocation.getCurrentPosition(function(e){t(e.coords.latitude,e.coords.longitude)},function(){t(void 0,void 0)},{timeout:e||5e3}):t(void 0,void 0)}},WCF.Location.GoogleMaps={},WCF.Location.GoogleMaps.Settings={_settings:{},get:function(t){return void 0===t?this._settings:void 0!==this._settings[t]?this._settings[t]:null},set:function(t,e){if($.isPlainObject(t))for(var o in t)this._settings[o]=t[o];else this._settings[t]=e}},WCF.Location.GoogleMaps.Map=Class.extend({_map:null,_markers:[],init:function(t,e){this._mapContainer=$("#"+t),this._mapOptions=$.extend(!0,this._getDefaultMapOptions(),e),this._map=new google.maps.Map(this._mapContainer[0],this._mapOptions),this._markers=[],this._mapContainer.parents(".sidebar").length&&require(["Ui/Screen"],function(t){t.on("screen-sm-down",{setup:$.proxy(this._addSidebarMapListener,this)})}.bind(this)),this.refresh()},_addInfoWindowEventListener:function(t,e){google.maps.event.addListener(t,"click",$.proxy(function(){e.open(this._map,t)},this))},_addSidebarMapListener:function(){$(".content > .mobileSidebarToggleButton").click($.proxy(this.refresh,this))},_getDefaultMapOptions:function(){var t={};switch(t.center=new google.maps.LatLng(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),t.disableDoubleClickZoom=WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),t.draggable=WCF.Location.GoogleMaps.Settings.get("draggable"),WCF.Location.GoogleMaps.Settings.get("mapType")){case"map":t.mapTypeId=google.maps.MapTypeId.ROADMAP;break;case"satellite":t.mapTypeId=google.maps.MapTypeId.SATELLITE;break;case"physical":t.mapTypeId=google.maps.MapTypeId.TERRAIN;break;case"hybrid":default:t.mapTypeId=google.maps.MapTypeId.HYBRID}if(t.mapTypeControl="off"!=WCF.Location.GoogleMaps.Settings.get("mapTypeControl"),t.mapTypeControl)switch(WCF.Location.GoogleMaps.Settings.get("mapTypeControl")){case"dropdown":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DROPDOWN_MENU};break;case"horizontalBar":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR};break;default:t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DEFAULT}}return t.scaleControl=WCF.Location.GoogleMaps.Settings.get("scaleControl"),t.scrollwheel=WCF.Location.GoogleMaps.Settings.get("scrollwheel"),t.zoom=WCF.Location.GoogleMaps.Settings.get("zoom"),t},addDraggableMarker:function(t,e){var o=new google.maps.Marker({clickable:!1,draggable:!0,map:this._map,position:new google.maps.LatLng(t,e),zIndex:1});return this._markers.push(o),o},addMarker:function(t,e,o,s,i){var a=new google.maps.Marker({map:this._map,position:new google.maps.LatLng(t,e),title:o});if(s&&a.setIcon(s),i){var n=new google.maps.InfoWindow({content:i});this._addInfoWindowEventListener(a,n),a.infoWindow=n}return this._markers.push(a),a},getMarkers:function(){return this._markers},getMap:function(){return this._map},refresh:function(){var t=this._map.getCenter();google.maps.event.trigger(this._map,"resize"),this._map.setCenter(t)},refreshBounds:function(){var t=null,e=null,o=null,s=null;for(var i in this._markers){var a=this._markers[i],n=a.getPosition().lat(),r=a.getPosition().lng();null===t?(t=e=n,o=s=r):(t>n?t=n:e<n&&(e=n),o>n?o=n:s<r&&(s=r))}this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(t,o),new google.maps.LatLng(e,s)))},removeMarkers:function(){for(var t in this._markers)this._markers[t].setMap(null);this._markers=[]},setBounds:function(t,e){this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(e.latitude,e.longitude),new google.maps.LatLng(t.latitude,t.longitude)))},setCenter:function(t,e){this._map.setCenter(new google.maps.LatLng(t,e))}}),WCF.Location.GoogleMaps.LargeMap=WCF.Location.GoogleMaps.Map.extend({_actionClassName:null,_additionalParameters:{},_locationSearch:null,_locationSearchInputSelector:null,_markerClusterer:null,_objectIDs:[],_previousNorthEast:null,_previousSouthWest:null,_stringifyExcludedObjectIds:!1,init:function(t,e,o,s,i){this._stringifyExcludedObjectIds=!1,e&&e.stringifyExcludedObjectIds&&(this._stringifyExcludedObjectIds=e.stringifyExcludedObjectIds,delete e.stringifyExcludedObjectIds),this._super(t,e),this._actionClassName=o,this._locationSearchInputSelector=s||"",this._additionalParameters=i||{},this._objectIDs=[],this._locationSearchInputSelector&&(this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(s,$.proxy(this._centerMap,this))),this._markerClusterer=new MarkerClusterer(this._map,this._markers,{maxZoom:17,imagePath:WCF.Location.GoogleMaps.Settings.get("markerClustererImagePath")+"m"}),this._markerSpiderfier=new OverlappingMarkerSpiderfier(this._map,{keepSpiderfied:!0,markersWontHide:!0,markersWontMove:!0}),this._markerSpiderfier.addListener("click",$.proxy(function(t){t.infoWindow&&t.infoWindow.open(this._map,t)},this)),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._previousNorthEast=null,this._previousSouthWest=null,google.maps.event.addListener(this._map,"idle",$.proxy(this._loadMarkers,this))},_addInfoWindowEventListener:function(t,e){},_centerMap:function(t){this.setCenter(t.location.lat(),t.location.lng()),$(this._locationSearchInputSelector).val(t.label)},_loadMarkers:function(){var t=this._map.getBounds().getNorthEast(),e=this._map.getBounds().getSouthWest();return!(this._previousNorthEast&&this._previousNorthEast.lat()>=t.lat()&&this._previousNorthEast.lng()>=t.lng()&&this._previousSouthWest.lat()<=e.lat()&&this._previousSouthWest.lng()<=e.lng())&&(this._previousNorthEast=t,this._previousSouthWest=e,this._proxy.setOption("data",{actionName:"getMapMarkers",className:this._actionClassName,parameters:$.extend(this._additionalParameters,{excludedObjectIDs:this._stringifyExcludedObjectIds?JSON.stringify(this._objectIDs):this._objectIDs,eastLongitude:t.lng(),northLatitude:t.lat(),southLatitude:e.lat(),westLongitude:e.lng()})}),this._proxy.sendRequest(),!0)},_success:function(t,e,o){if(t.returnValues&&t.returnValues.markers)for(var s in t.returnValues.markers){var i=t.returnValues.markers[s];this.addMarker(i.latitude,i.longitude,i.title,null,i.infoWindow),i.objectID?this._objectIDs.push(i.objectID):i.objectIDs&&(this._objectIDs=this._objectIDs.concat(i.objectIDs))}},addMarker:function(t,e,o,s,i){var a=this._super(t,e,o,s,i);return this._markerClusterer.addMarker(a),this._markerSpiderfier.addMarker(a),a}}),WCF.Location.GoogleMaps.SuggestionMap=WCF.Location.GoogleMaps.LargeMap.extend({_locationSuggestionsButton:null,_suggestionSelectionCallback:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i);var a=$('<div class="gmnoprint googleMapsCustomControlContainer"><div class="gm-style-mtc"><div class="googleMapsCustomControl">'+WCF.Language.get("wcf.map.showLocationSuggestions")+"</div></div></div>");this._locationSuggestionsButton=a.find(".googleMapsCustomControl").click($.proxy(this._toggleLocationSuggestions,this)),this._map.controls[google.maps.ControlPosition.TOP_RIGHT].push(a.get(0))},_loadMarkers:function(){this._locationSuggestionsButton.hasClass("active")&&(this._super()||(this._loadSuggestions=!1))},_success:function(t,e,o){var s=this._markers.length;this._super(t,e,o),this._loadSuggestions&&s==this._markers.length&&(this._loadSuggestions=!1,new WCF.System.Notification(WCF.Language.get("wcf.map.noLocationSuggestions"),"info").show())},_toggleLocationSuggestions:function(){var t=!this._locationSuggestionsButton.hasClass("active");t&&(this._loadSuggestions=!0),this.showSuggestions(t)},addMarker:function(t,e,o,s,i){var a=$(i),n=$('<a class="googleMapsUseLocationSuggestionLink" />').text(WCF.Language.get("wcf.map.useLocationSuggestion")).click(this._suggestionSelectionCallback);a.append($("<p />").append(n));var r=this._super(t,e,o,"//mt.google.com/vt/icon/name=icons/spotlight/spotlight-waypoint-a.png",a.get(0));return n.data("marker",r),r},setSuggestionSelectionCallback:function(t){this._suggestionSelectionCallback=t},showSuggestions:function(t){void 0===t&&(t=!0),this._locationSuggestionsButton.toggleClass("active",t);for(var e=[],o=0,s=this._markers.length;o<s;o++){var i=this._markers[o];i.draggable||(i.setVisible(t),t&&e.push(i))}this._markerClusterer.clearMarkers(),t&&this._markerClusterer.addMarkers(e),this._loadMarkers()}}),WCF.Location.GoogleMaps.LocationSearch=WCF.Search.Base.extend({_geocoder:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i),this.setDelay(500),this._geocoder=new google.maps.Geocoder},_createListItem:function(t){var e=$("<li><span>"+WCF.String.escapeHTML(t.formatted_address)+"</span></li>").appendTo(this._list);return e.data("location",t.geometry.location).data("label",t.formatted_address).click($.proxy(this._executeCallback,this)),this._itemCount++,e},_keyUp:function(t){switch(t.which){case $.ui.keyCode.LEFT:case $.ui.keyCode.RIGHT:return;case $.ui.keyCode.UP:return void this._selectPreviousItem();case $.ui.keyCode.DOWN:return void this._selectNextItem();case $.ui.keyCode.ENTER:return this._selectElement(t)}var e=this._getSearchString(t);""===e?this._clearList(!0):e.length>=this._triggerLength?this._delay?(null!==this._timer&&this._timer.stop(),this._timer=new WCF.PeriodicalExecuter($.proxy(function(){this._geocoder.geocode({address:e},$.proxy(this._success,this)),this._timer.stop(),this._timer=null},this),this._delay)):this._geocoder.geocode({address:e},$.proxy(this._success,this)):this._clearList(!1)},_success:function(t,e){if(this._clearList(!1),e==google.maps.GeocoderStatus.OK){if($.getLength(t)){var o=0;for(var s in t)if(this._createListItem(t[s]),10==++o)break}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var i=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(i).hasClass("dropdownOpen")||WCF.Dropdown.toggleDropdown(i,!0),this._itemIndex=-1,WCF.Dropdown.getDropdown(i).data("disableAutoFocus")||this._selectNextItem()}}}),WCF.Location.GoogleMaps.LocationInput=Class.extend({_locationSearch:null,_map:null,_marker:null,init:function(t,e,o,s,i,a){this._searchInput=o,a?(this._map=new WCF.Location.GoogleMaps.SuggestionMap(t,e,a),this._map.setSuggestionSelectionCallback($.proxy(this._useSuggestion,this))):this._map=new WCF.Location.GoogleMaps.Map(t,e),this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(o,$.proxy(this._setMarkerByLocation,this)),s&&i?this._marker=this._map.addDraggableMarker(s,i):(this._marker=this._map.addDraggableMarker(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),WCF.Location.Util.getLocation($.proxy(function(t,e){void 0!==t&&void 0!==e&&(WCF.Location.GoogleMaps.Util.moveMarker(this._marker,t,e),WCF.Location.GoogleMaps.Util.focusMarker(this._marker))},this))),this._marker.addListener("dragend",$.proxy(this._updateLocation,this))},_useSuggestion:function(t){var e=$(t.currentTarget).data("marker");this._marker.setPosition(e.getPosition()),this._updateLocation(),this._map.showSuggestions(!1)},_updateLocation:function(){WCF.Location.GoogleMaps.Util.reverseGeocoding($.proxy(function(t){null!==t&&$(this._searchInput).val(t)},this),this._marker)},_setMarkerByLocation:function(t){this._marker.setPosition(t.location),WCF.Location.GoogleMaps.Util.focusMarker(this._marker),$(this._searchInput).val(t.label)},getMap:function(){return this._map},getMarker:function(){return this._marker}}),WCF.Location.GoogleMaps.Util={_geocoder:null,focusMarker:function(t){t.getMap().setCenter(t.getPosition())},getMarkerPosition:function(t){return{latitude:t.getPosition().lat(),longitude:t.getPosition().lng()}},moveMarker:function(t,e,o,s){t.setPosition(new google.maps.LatLng(e,o)),s&&google.maps.event.trigger(t,"dragend")},reverseGeocoding:function(t,e,o,s,i){e&&(o=e.getPosition().lat(),s=e.getPosition().lng()),null===this._geocoder&&(this._geocoder=new google.maps.Geocoder);var a=new google.maps.LatLng(o,s);this._geocoder.geocode({latLng:a},function(e,o){t(o==google.maps.GeocoderStatus.OK?i?e:e[0].formatted_address:null)})}}; })(this);
+(function (window, undefined) { "use strict";function gm_authFailure(){WCF.System.Event.fireEvent("com.woltlab.wcf.googleMaps","authenticationFailure")}WCF.Location={},WCF.Location.Util={getLocation:function(e,t){var o=WCF.Location.GoogleMaps.Settings.get("accessUserLocation");navigator.geolocation&&null!==o&&o?navigator.geolocation.getCurrentPosition(function(t){e(t.coords.latitude,t.coords.longitude)},function(){e(void 0,void 0)},{timeout:t||5e3}):e(void 0,void 0)}},WCF.Location.GoogleMaps={},WCF.Location.GoogleMaps.Settings={_settings:{},get:function(t){return void 0===t?this._settings:void 0!==this._settings[t]?this._settings[t]:null},set:function(t,e){if($.isPlainObject(t))for(var o in t)this._settings[o]=t[o];else this._settings[t]=e}},WCF.Location.GoogleMaps.Map=Class.extend({_map:null,_markers:[],init:function(t,e){this._mapContainer=$("#"+t),this._mapOptions=$.extend(!0,this._getDefaultMapOptions(),e),this._map=new google.maps.Map(this._mapContainer[0],this._mapOptions),this._markers=[],this._mapContainer.parents(".sidebar").length&&require(["Ui/Screen"],function(t){t.on("screen-sm-down",{setup:$.proxy(this._addSidebarMapListener,this)})}.bind(this)),this.refresh()},_addInfoWindowEventListener:function(t,e){google.maps.event.addListener(t,"click",$.proxy(function(){e.open(this._map,t)},this))},_addSidebarMapListener:function(){$(".content > .mobileSidebarToggleButton").click($.proxy(this.refresh,this))},_getDefaultMapOptions:function(){var t={};switch(t.center=new google.maps.LatLng(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),t.disableDoubleClickZoom=WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),t.draggable=WCF.Location.GoogleMaps.Settings.get("draggable"),WCF.Location.GoogleMaps.Settings.get("mapType")){case"map":t.mapTypeId=google.maps.MapTypeId.ROADMAP;break;case"satellite":t.mapTypeId=google.maps.MapTypeId.SATELLITE;break;case"physical":t.mapTypeId=google.maps.MapTypeId.TERRAIN;break;case"hybrid":default:t.mapTypeId=google.maps.MapTypeId.HYBRID}if(t.mapTypeControl="off"!=WCF.Location.GoogleMaps.Settings.get("mapTypeControl"),t.mapTypeControl)switch(WCF.Location.GoogleMaps.Settings.get("mapTypeControl")){case"dropdown":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DROPDOWN_MENU};break;case"horizontalBar":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR};break;default:t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DEFAULT}}return t.scaleControl=WCF.Location.GoogleMaps.Settings.get("scaleControl"),t.scrollwheel=WCF.Location.GoogleMaps.Settings.get("scrollwheel"),t.zoom=WCF.Location.GoogleMaps.Settings.get("zoom"),t},addDraggableMarker:function(t,e){var o=new google.maps.Marker({clickable:!1,draggable:!0,map:this._map,position:new google.maps.LatLng(t,e),zIndex:1});return this._markers.push(o),o},addMarker:function(t,e,o,s,i){var a,n=new google.maps.Marker({map:this._map,position:new google.maps.LatLng(t,e),title:o});return s&&n.setIcon(s),i&&(a=new google.maps.InfoWindow({content:i}),this._addInfoWindowEventListener(n,a),n.infoWindow=a),this._markers.push(n),n},getMarkers:function(){return this._markers},getMap:function(){return this._map},refresh:function(){var t=this._map.getCenter();google.maps.event.trigger(this._map,"resize"),this._map.setCenter(t)},refreshBounds:function(){var t=null,e=null,o=null,s=null;for(var i in this._markers){var a=this._markers[i],n=a.getPosition().lat(),r=a.getPosition().lng();null===t?(t=e=n,o=s=r):(n<t?t=n:e<n&&(e=n),n<o?o=n:s<r&&(s=r))}this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(t,o),new google.maps.LatLng(e,s)))},removeMarkers:function(){for(var t in this._markers)this._markers[t].setMap(null);this._markers=[]},setBounds:function(t,e){this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(e.latitude,e.longitude),new google.maps.LatLng(t.latitude,t.longitude)))},setCenter:function(t,e){this._map.setCenter(new google.maps.LatLng(t,e))}}),WCF.Location.GoogleMaps.LargeMap=WCF.Location.GoogleMaps.Map.extend({_actionClassName:null,_additionalParameters:{},_locationSearch:null,_locationSearchInputSelector:null,_markerClusterer:null,_objectIDs:[],_previousNorthEast:null,_previousSouthWest:null,_stringifyExcludedObjectIds:!1,init:function(t,e,o,s,i){this._stringifyExcludedObjectIds=!1,e&&e.stringifyExcludedObjectIds&&(this._stringifyExcludedObjectIds=e.stringifyExcludedObjectIds,delete e.stringifyExcludedObjectIds),this._super(t,e),this._actionClassName=o,this._locationSearchInputSelector=s||"",this._additionalParameters=i||{},this._objectIDs=[],this._locationSearchInputSelector&&(this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(s,$.proxy(this._centerMap,this))),this._markerClusterer=new MarkerClusterer(this._map,this._markers,{maxZoom:17,imagePath:WCF.Location.GoogleMaps.Settings.get("markerClustererImagePath")+"m"}),this._markerSpiderfier=new OverlappingMarkerSpiderfier(this._map,{keepSpiderfied:!0,markersWontHide:!0,markersWontMove:!0}),this._markerSpiderfier.addListener("click",$.proxy(function(t){t.infoWindow&&t.infoWindow.open(this._map,t)},this)),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._previousNorthEast=null,this._previousSouthWest=null,google.maps.event.addListener(this._map,"idle",$.proxy(this._loadMarkers,this))},_addInfoWindowEventListener:function(t,e){},_centerMap:function(t){this.setCenter(t.location.lat(),t.location.lng()),$(this._locationSearchInputSelector).val(t.label)},_loadMarkers:function(){var t=this._map.getBounds().getNorthEast(),e=this._map.getBounds().getSouthWest();return!(this._previousNorthEast&&this._previousNorthEast.lat()>=t.lat()&&this._previousNorthEast.lng()>=t.lng()&&this._previousSouthWest.lat()<=e.lat()&&this._previousSouthWest.lng()<=e.lng())&&(this._previousNorthEast=t,this._previousSouthWest=e,this._proxy.setOption("data",{actionName:"getMapMarkers",className:this._actionClassName,parameters:$.extend(this._additionalParameters,{excludedObjectIDs:this._stringifyExcludedObjectIds?JSON.stringify(this._objectIDs):this._objectIDs,eastLongitude:t.lng(),northLatitude:t.lat(),southLatitude:e.lat(),westLongitude:e.lng()})}),this._proxy.sendRequest(),!0)},_success:function(t,e,o){if(t.returnValues&&t.returnValues.markers)for(var s in t.returnValues.markers){var i=t.returnValues.markers[s];this.addMarker(i.latitude,i.longitude,i.title,null,i.infoWindow),i.objectID?this._objectIDs.push(i.objectID):i.objectIDs&&(this._objectIDs=this._objectIDs.concat(i.objectIDs))}},addMarker:function(t,e,o,s,i){var a=this._super(t,e,o,s,i);return this._markerClusterer.addMarker(a),this._markerSpiderfier.addMarker(a),a}}),WCF.Location.GoogleMaps.SuggestionMap=WCF.Location.GoogleMaps.LargeMap.extend({_locationSuggestionsButton:null,_suggestionSelectionCallback:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i);var a=$('<div class="gmnoprint googleMapsCustomControlContainer"><div class="gm-style-mtc"><div class="googleMapsCustomControl">'+WCF.Language.get("wcf.map.showLocationSuggestions")+"</div></div></div>");this._locationSuggestionsButton=a.find(".googleMapsCustomControl").click($.proxy(this._toggleLocationSuggestions,this)),this._map.controls[google.maps.ControlPosition.TOP_RIGHT].push(a.get(0))},_loadMarkers:function(){this._locationSuggestionsButton.hasClass("active")&&(this._super()||(this._loadSuggestions=!1))},_success:function(t,e,o){var s=this._markers.length;this._super(t,e,o),this._loadSuggestions&&s==this._markers.length&&(this._loadSuggestions=!1,new WCF.System.Notification(WCF.Language.get("wcf.map.noLocationSuggestions"),"info").show())},_toggleLocationSuggestions:function(){var t=!this._locationSuggestionsButton.hasClass("active");t&&(this._loadSuggestions=!0),this.showSuggestions(t)},addMarker:function(t,e,o,s,i){var a=$(i),n=$('<a class="googleMapsUseLocationSuggestionLink" />').text(WCF.Language.get("wcf.map.useLocationSuggestion")).click(this._suggestionSelectionCallback);a.append($("<p />").append(n));var r=this._super(t,e,o,"//mt.google.com/vt/icon/name=icons/spotlight/spotlight-waypoint-a.png",a.get(0));return n.data("marker",r),r},setSuggestionSelectionCallback:function(t){this._suggestionSelectionCallback=t},showSuggestions:function(t){void 0===t&&(t=!0),this._locationSuggestionsButton.toggleClass("active",t);for(var e=[],o=0,s=this._markers.length;o<s;o++){var i=this._markers[o];i.draggable||(i.setVisible(t),t&&e.push(i))}this._markerClusterer.clearMarkers(),t&&this._markerClusterer.addMarkers(e),this._loadMarkers()}}),WCF.Location.GoogleMaps.LocationSearch=WCF.Search.Base.extend({_geocoder:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i),this.setDelay(500),this._geocoder=new google.maps.Geocoder},_createListItem:function(t){var e=$("<li><span>"+WCF.String.escapeHTML(t.formatted_address)+"</span></li>").appendTo(this._list);return e.data("location",t.geometry.location).data("label",t.formatted_address).click($.proxy(this._executeCallback,this)),this._itemCount++,e},_keyUp:function(t){switch(t.which){case $.ui.keyCode.LEFT:case $.ui.keyCode.RIGHT:return;case $.ui.keyCode.UP:return void this._selectPreviousItem();case $.ui.keyCode.DOWN:return void this._selectNextItem();case $.ui.keyCode.ENTER:return this._selectElement(t)}var e=this._getSearchString(t);""===e?this._clearList(!0):e.length>=this._triggerLength?this._delay?(null!==this._timer&&this._timer.stop(),this._timer=new WCF.PeriodicalExecuter($.proxy(function(){this._geocoder.geocode({address:e},$.proxy(this._success,this)),this._timer.stop(),this._timer=null},this),this._delay)):this._geocoder.geocode({address:e},$.proxy(this._success,this)):this._clearList(!1)},_success:function(t,e){if(this._clearList(!1),e==google.maps.GeocoderStatus.OK){if($.getLength(t)){var o=0;for(var s in t)if(this._createListItem(t[s]),10==++o)break}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var i=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(i).hasClass("dropdownOpen")||WCF.Dropdown.toggleDropdown(i,!0),this._itemIndex=-1,WCF.Dropdown.getDropdown(i).data("disableAutoFocus")||this._selectNextItem()}}}),WCF.Location.GoogleMaps.LocationInput=Class.extend({_locationSearch:null,_map:null,_marker:null,init:function(t,e,o,s,i,a){this._searchInput=o,a?(this._map=new WCF.Location.GoogleMaps.SuggestionMap(t,e,a),this._map.setSuggestionSelectionCallback($.proxy(this._useSuggestion,this))):this._map=new WCF.Location.GoogleMaps.Map(t,e),this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(o,$.proxy(this._setMarkerByLocation,this)),s&&i?this._marker=this._map.addDraggableMarker(s,i):(this._marker=this._map.addDraggableMarker(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),WCF.Location.Util.getLocation($.proxy(function(t,e){void 0!==t&&void 0!==e&&(WCF.Location.GoogleMaps.Util.moveMarker(this._marker,t,e),WCF.Location.GoogleMaps.Util.focusMarker(this._marker))},this))),this._marker.addListener("dragend",$.proxy(this._updateLocation,this))},_useSuggestion:function(t){var e=$(t.currentTarget).data("marker");this._marker.setPosition(e.getPosition()),this._updateLocation(),this._map.showSuggestions(!1)},_updateLocation:function(){WCF.Location.GoogleMaps.Util.reverseGeocoding($.proxy(function(t){null!==t&&$(this._searchInput).val(t)},this),this._marker)},_setMarkerByLocation:function(t){this._marker.setPosition(t.location),WCF.Location.GoogleMaps.Util.focusMarker(this._marker),$(this._searchInput).val(t.label)},getMap:function(){return this._map},getMarker:function(){return this._marker}}),WCF.Location.GoogleMaps.Util={_geocoder:null,focusMarker:function(t){t.getMap().setCenter(t.getPosition())},getMarkerPosition:function(t){return{latitude:t.getPosition().lat(),longitude:t.getPosition().lng()}},moveMarker:function(t,e,o,s){t.setPosition(new google.maps.LatLng(e,o)),s&&google.maps.event.trigger(t,"dragend")},reverseGeocoding:function(o,t,e,s,i){t&&(e=t.getPosition().lat(),s=t.getPosition().lng()),null===this._geocoder&&(this._geocoder=new google.maps.Geocoder);var a=new google.maps.LatLng(e,s);this._geocoder.geocode({latLng:a},function(t,e){e==google.maps.GeocoderStatus.OK?o(i?t:t[0].formatted_address):o(null)})}}; })(this);
 
 // WCF.Message.js
-(function (window, undefined) { "use strict";WCF.Message={},WCF.Message.BBCode={},WCF.Message.BBCode.CodeViewer=Class.extend({init:function(){}}),WCF.Message.EditHistory=Class.extend({_oldIDInputs:null,_newIDInputs:null,_containerSelector:"",_buttonSelector:".jsRevertButton",init:function(e,t,i,s,n){this._oldIDInputs=e,this._newIDInputs=t,this._containerSelector=i,this._buttonSelector=s||".jsRevertButton",this._options=$.extend({isVersionTracker:!1,versionTrackerObjectType:"",versionTrackerObjectId:0,redirectUrl:""},n),this.proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initInputs(),this._initElements()},_initInputs:function(){var e=this;this._newIDInputs.change(function(t){var i=parseInt($(this).val());"current"===$(this).val()&&(i=1/0),e._oldIDInputs.each(function(e){var t=parseInt($(this).val());"current"===$(this).val()&&(t=1/0),t>=i?$(this).disable():$(this).enable()})}),this._oldIDInputs.change(function(t){var i=parseInt($(this).val());"current"===$(this).val()&&(i=1/0),e._newIDInputs.each(function(e){var t=parseInt($(this).val());"current"===$(this).val()&&(t=1/0),t<=i?$(this).disable():$(this).enable()})}),this._oldIDInputs.filter(":checked").change(),this._newIDInputs.filter(":checked").change()},_initElements:function(){var e=this;$(this._containerSelector).each(function(t,i){$(i).find(e._buttonSelector).click($.proxy(e._click,e))})},_click:function(e){var t=$(e.currentTarget);if(e.preventDefault(),t.data("confirmMessage")){var i=this;WCF.System.Confirmation.show(t.data("confirmMessage"),function(e){"cancel"!==e&&i._sendRequest(t)},void 0,void 0,!0)}else this._sendRequest(t)},_sendRequest:function(e){this._options.isVersionTracker?(this.proxy.setOption("url",window.WSC_API_URL+"index.php?ajax-invoke/&t="+window.SECURITY_TOKEN),this.proxy.setOption("data",{actionName:"revert",className:"wcf\\system\\version\\VersionTracker",parameters:{objectType:this._options.versionTrackerObjectType,objectID:this._options.versionTrackerObjectId,versionID:$(e).data("objectID")}})):this.proxy.setOption("data",{actionName:"revert",className:"wcf\\data\\edit\\history\\entry\\EditHistoryEntryAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this._options.redirectUrl?(new WCF.System.Notification).show(function(){window.location=this._options.redirectUrl}.bind(this)):window.location.reload(!0)}}),WCF.Message.FormGuard=Class.extend({init:function(){var e=$("form.jsFormGuard").removeClass("jsFormGuard").submit(function(){$(this).find(".formSubmit input[type=submit]").disable()});$(window).on("unload",function(){e.find(".formSubmit input[type=submit]").enable()})}}),WCF.Message.Preview=Class.extend({_className:"",_messageFieldID:"",_messageField:null,_proxy:null,_previewButton:null,_previewButtonLabel:"",init:function(e,t,i){return this._className=e,this._messageFieldID=$.wcfEscapeID(t),this._textarea=$("#"+this._messageFieldID),this._textarea.length?(i=$.wcfEscapeID(i),this._previewButton=$("#"+i),this._previewButton.length?(this._previewButton.click($.proxy(this._click,this)),void(this._proxy=new WCF.Action.Proxy({failure:$.proxy(this._failure,this),success:$.proxy(this._success,this)}))):void console.debug("[WCF.Message.Preview] Unable to find preview button identified by '"+i+"'")):void console.debug("[WCF.Message.Preview] Unable to find message field identified by '"+this._messageFieldID+"'")},_click:function(e){var t=this._getMessage();return null===t?void console.debug("[WCF.Message.Preview] Unable to access Redactor instance of '"+this._messageFieldID+"'"):(this._proxy.setOption("data",{actionName:"getMessagePreview",className:this._className,parameters:this._getParameters(t)}),this._proxy.sendRequest(),this._previewButtonLabel=this._previewButton.html(),this._previewButton.html(WCF.Language.get("wcf.global.loading")).disable(),e.stopPropagation(),!1)},_getParameters:function(e){var t={};return $("#settings_"+this._messageFieldID).find("input[type=checkbox]").each(function(e,i){var s=$(i);s.is(":checked")&&(t[s.prop("name")]=s.prop("value"))}),{data:{message:e},options:t}},_getMessage:function(){return this._textarea.redactor("code.get")},_success:function(e,t,i){this._previewButton.html(this._previewButtonLabel).enable(),this._textarea.parent().children("small.innerError").remove(),this._handleResponse(e)},_handleResponse:function(e){},_failure:function(e){if(null===e||void 0===e.returnValues||void 0===e.returnValues.errorType)return!0;this._previewButton.html(this._previewButtonLabel).enable();var t=this._textarea.parent().children("small.innerError").empty();t.length||(t=$('<small class="innerError" />').appendTo(this._textarea.parent()));var i="empty"===e.returnValues.errorType?WCF.Language.get("wcf.global.form.error.empty"):e.returnValues.errorMessage;return e.returnValues.realErrorMessage&&(i=e.returnValues.realErrorMessage),t.html(i),!1}}),WCF.Message.DefaultPreview=WCF.Message.Preview.extend({_dialog:null,_options:{},init:function(e){if(arguments.length>1&&"string"==typeof e)throw new Error("Outdated API call, please update your implementation.");if(this._options=$.extend({disallowedBBCodesPermission:"user.message.disallowedBBCodes",messageFieldID:"",previewButtonID:"",messageObjectType:"",messageObjectID:0},e),!this._options.messageObjectType)throw new Error("Field 'messageObjectType' cannot be empty.");this._super("wcf\\data\\bbcode\\MessagePreviewAction",this._options.messageFieldID,this._options.previewButtonID)},_handleResponse:function(e){require(["WoltLabSuite/Core/Ui/Dialog"],function(t){t.open(this,'<div class="htmlContent">'+e.returnValues.message+"</div>")}.bind(this))},_getParameters:function(e){var t=this._super(e);for(var i in this._options)this._options.hasOwnProperty(i)&&"messageFieldID"!==i&&"previewButtonID"!==i&&(t[i]=this._options[i]);return t},_dialogSetup:function(){return{id:"messagePreview",options:{title:WCF.Language.get("wcf.global.preview")},source:null}}}),WCF.Message.Multilingualism=Class.extend({_availableLanguages:{},_languageID:0,_languageInput:null,init:function(e,t,i){if(this._availableLanguages=t,this._languageID=e||0,this._languageInput=$("#languageID"),this._updateLabel(),this._languageInput.find(".dropdownMenu > li").click($.proxy(this._click,this)),!i){var s=this._languageInput.find(".dropdownMenu");$('<li class="dropdownDivider" />').appendTo(s),$('<li><span><span class="badge">'+this._availableLanguages[0]+"</span></span></li>").click($.proxy(this._disable,this)).appendTo(s)}this._languageInput.parents("form").submit($.proxy(this._submit,this))},_click:function(e){this._languageID=$(e.currentTarget).data("languageID"),this._updateLabel()},_disable:function(){this._languageID=0,this._updateLabel()},_updateLabel:function(){this._languageInput.find(".dropdownToggle > span").text(this._availableLanguages[this._languageID])},_submit:function(){this._languageInput.next("input[name=languageID]").prop("value",this._languageID)}}),WCF.Message.SmileyCategories=Class.extend({_cache:[],_proxy:null,_wysiwygSelector:"",init:function(e,t,i){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._wysiwygSelector=e,this._smiliesTabMenuId=t||"smilies-"+this._wysiwygSelector,this._formBuilderUsage=i||!1,$("#"+this._smiliesTabMenuId).on("messagetabmenushow",$.proxy(this._click,this))},_click:function(e,t){if(e.preventDefault(),this._formBuilderUsage){if(!t.activeTab.tab.children("a").prop("href").match(/#([a-zA-Z0-9_-]+)$/))return void console.debug("[WCF.Message.SmileyCategories] Cannot extract category id for tab '"+t.activeTab.tab.wcfIdentify()+"'.");if(!RegExp.$1.match(this._smiliesTabMenuId.replace(/Container$/,"")+"_smileyCategoryTab(\\d+)Container"))return void console.debug("[WCF.Message.SmileyCategories] Cannot extract category id for tab '"+t.activeTab.tab.wcfIdentify()+"'.");var i=parseInt(RegExp.$1)}else var i=parseInt(t.activeTab.tab.data("smileyCategoryID"));if(i&&!t.activeTab.container.children("ul.smileyList").length){if(void 0!==this._cache[i])return void t.activeTab.container.html(this._cache[i]);this._proxy.setOption("data",{actionName:"getSmilies",className:"wcf\\data\\smiley\\category\\SmileyCategoryAction",objectIDs:[i]}),this._proxy.sendRequest()}},_success:function(e,t,i){var s=parseInt(e.returnValues.smileyCategoryID);this._cache[s]=e.returnValues.template,this._formBuilderUsage?$("#"+this._smiliesTabMenuId.replace(/Container$/,"")+"_smileyCategoryTab"+s+"Container").html(e.returnValues.template):$("#smilies-"+this._wysiwygSelector+"-"+s).html(e.returnValues.template)}}),WCF.Message.Smilies=Class.extend({init:function(e){require(["WoltLabSuite/Core/Ui/Smiley/Insert"],function(t){new t(e)})}}),WCF.Message.InlineEditor=Class.extend({_container:{},_containerID:0,_dropdowns:{},_messageContainerSelector:".jsMessage",_messageEditorIDPrefix:"messageEditor",init:function(e,t,i){require(["WoltLabSuite/Core/Ui/Message/InlineEditor"],function(t){new t({className:this._getClassName(),containerId:e,editorPrefix:this._messageEditorIDPrefix,messageSelector:this._messageContainerSelector,quoteManager:i||null,callbackDropdownInit:this._callbackDropdownInit.bind(this)})}.bind(this))},_click:function(e,t){t=null===e?~~t:~~elData(e.currentTarget,"container-id"),require(["WoltLabSuite/Core/Ui/Message/InlineEditor"],function(e){e.legacyEdit(t)}.bind(this)),e&&e.preventDefault()},_initDropdownMenu:function(e,t){},_callbackDropdownInit:function(e,t){return this._initDropdownMenu($(e).wcfIdentify(),$(t)),null},_getClassName:function(){return""}}),WCF.Message.Submit={_buttons:{},registerButton:function(e,t){WCF.Browser.isChrome()&&(this._buttons[e]=$(t))},execute:function(e){this._buttons[e]&&this._buttons[e].trigger("click")}},WCF.Message.Quote={},WCF.Message.Quote.Handler=Class.extend({_activeContainerID:"",_className:"",_containers:{},_containerSelector:"",_copyQuote:null,_message:"",_messageBodySelector:"",_objectID:0,_objectType:"",_proxy:null,_quoteManager:null,_selectionChangeTimer:null,_isMouseDown:!1,init:function(e,t,i,s,n,a,o){if(this._className=t,""===this._className)return void console.debug("[WCF.Message.QuoteManager] Empty class name given, aborting.");if(this._objectType=i,""===this._objectType)return void console.debug("[WCF.Message.QuoteManager] Empty object type name given, aborting.");this._containerSelector=s,this._message="",this._messageBodySelector=n,this._objectID=0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._selectionChangeTimer=null,this._isMouseDown=!1,this._initContainers(),o=o&&e.supportPaste(),this._initCopyQuote(o),$(document).mouseup($.proxy(this._mouseUp,this)),document.addEventListener("selectionchange",this._selectionchange.bind(this)),this._quoteManager=e,this._quoteManager.register(this._objectType,this),WCF.DOMNodeInsertedHandler.addCallback("WCF.Message.Quote.Handler"+i.hashCode(),$.proxy(this._initContainers,this));var r=null;document.addEventListener("selectionchange",function(){this._copyQuote[0].classList.contains("active")&&(this._copyQuote[0].classList.add("touchForceInaccessible"),null!==r&&window.clearTimeout(r),r=window.setTimeout(function(){this._copyQuote[0].classList.remove("touchForceInaccessible"),r=null}.bind(this),50))}.bind(this))},_initContainers:function(){var e=this;$(this._containerSelector).each(function(t,i){var s=$(i),n=s.wcfIdentify();if(!e._containers[n]){if(e._containers[n]=s,s.hasClass("jsInvalidQuoteTarget"))return!0;e._messageBodySelector&&s.data("body",s.find(e._messageBodySelector).data("containerID",n)),s.mousedown($.proxy(e._mouseDown,e)),s[0].classList.add("jsQuoteMessageContainer"),e._containers[n].find(".jsQuoteMessage").click($.proxy(e._saveFullQuote,e))}})},_selectionchange:function(){if(!this._isMouseDown){if(""===this._activeContainerID){var e=window.getSelection();if(1!==e.rangeCount||e.isCollapsed)return;var t=e.getRangeAt(0),i=elClosest(t.startContainer,".jsQuoteMessageContainer"),s=elClosest(t.endContainer,".jsQuoteMessageContainer");if(i&&i===s&&!i.classList.contains("jsInvalidQuoteTarget")){var n=t.commonAncestorContainer;n.nodeType!==Node.ELEMENT_NODE&&(n=n.parentNode);var a=n.offsetParent;if(i.contains(a)&&a.scrollTop+a.clientHeight<n.offsetTop)return;this._activeContainerID=i.id}}null!==this._selectionChangeTimer&&window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=window.setTimeout(this._mouseUp.bind(this),100)}},_mouseDown:function(e){this._copyQuote.removeClass("active"),this._activeContainerID=e.currentTarget.classList.contains("jsInvalidQuoteTarget")?"":e.currentTarget.id,null!==this._selectionChangeTimer&&(window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=null),this._isMouseDown=!0},_getNodeText:function(e){var t=function(e){switch(e.tagName){case"BLOCKQUOTE":case"SCRIPT":return NodeFilter.FILTER_REJECT;case"IMG":if(!e.classList.contains("smiley")||0===e.alt.length)return NodeFilter.FILTER_REJECT;default:return NodeFilter.FILTER_ACCEPT}};t.acceptNode=t;for(var i,s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,t,!0),n="",a=[];s.nextNode();){var o=s.currentNode;if(o.nodeType===Node.ELEMENT_NODE)switch(o.tagName){case"A":if(i=o.textContent,i.indexOf("…")>0){var r=i.split(/\u2026/);if(2===r.length){var l=o.href;0===l.indexOf(r[0])&&l.substr(-1*r[1].length)===r[1]&&(n+=l,a.push(o))}}break;case"BR":case"LI":case"UL":n+="\n";break;case"TD":$.browser.msie||(n+="\n");break;case"P":n+="\n\n";break;case"IMG":n+=" "+o.alt+" ";break;case"DIV":(o.classList.contains("codeBoxHeadline")||o.classList.contains("codeBoxLine"))&&(n+="\n")}else{if("A"===o.parentNode.nodeName&&-1!==a.indexOf(o.parentNode))continue;n+=o.nodeValue.replace(/\n/g," ")}}return n},_mouseUp:function(e){if(e&&e.originalEvent instanceof Event&&(null!==this._selectionChangeTimer&&(window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=null),this._isMouseDown=!1),""===this._activeContainerID)return void this._copyQuote.removeClass("active");var t=window.getSelection();if(1!==t.rangeCount||t.isCollapsed)return void this._copyQuote.removeClass("active");var i=this._containers[this._activeContainerID],s=i.data("objectID");i=i.data("body")||i;for(var n=t.anchorNode;n&&n!==i[0];)n=n.parentNode;if(n!==i[0])return void this._copyQuote.removeClass("active");var a=this._getSelectedText(),o=$.trim(a);if(""===o)return void this._copyQuote.removeClass("active");var r=t.getRangeAt(0),l=r.startContainer.nodeType===Node.TEXT_NODE?r.startContainer.parentNode:r.startContainer,c=r.endContainer.nodeType===Node.TEXT_NODE?r.endContainer.parentNode:r.endContainer;if(l.closest("blockquote")||c.closest("blockquote"))return void this._copyQuote.removeClass("active");var u=this._getNodeText(i[0]);if(-1!==this._normalize(u).indexOf(this._normalize(o))){this._copyQuote.addClass("active");var h=this._getBoundingRectangle(i,window.getSelection()),d=this._copyQuote.getDimensions("outer"),_=(h.right-h.left)/2-d.width/2+h.left,g=i[0].getBoundingClientRect();_<g.left?_=g.left:_+d.width>g.right&&(_=g.right-d.width),this._copyQuote.css({top:h.bottom+7+"px",left:_+"px"}),this._copyQuote.removeClass("active"),null===this._selectionChangeTimer?this._activeContainerID="":(window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=null);var p=this;window.setTimeout(function(){var e=$.trim(p._getSelectedText());""!==e&&(p._copyQuote.addClass("active"),p._message=e,p._objectID=s)},10)}},_normalize:function(e){return e.replace(/\r?\n|\r/g,"\n").replace(/\s/g," ").replace(/\s{2,}/g," ")},_getBoundingRectangle:function(e,t){var i=null;if(t.rangeCount>0){var s=t.getRangeAt(0).getBoundingClientRect(),n=$(document).scrollTop();i={bottom:s.bottom+n,left:s.left,right:s.right,top:s.top+n}}return i},_initCopyQuote:function(e){if(this._copyQuote=$("#quoteManagerCopy"),!this._copyQuote.length){this._copyQuote=$('<div id="quoteManagerCopy" class="balloonTooltip interactive"><span class="jsQuoteManagerStore">'+WCF.Language.get("wcf.message.quote.quoteSelected")+"</span></div>").appendTo(document.body);var t=this._copyQuote.children("span.jsQuoteManagerStore").click($.proxy(this._saveQuote,this));e&&$('<span class="jsQuoteManagerQuoteAndInsert">'+WCF.Language.get("wcf.message.quote.quoteAndReply")+"</span>").click($.proxy(this._saveAndInsertQuote,this)).insertAfter(t)}},_getSelectedText:function(){var e=window.getSelection();return e.rangeCount?this._getNodeText(e.getRangeAt(0).cloneContents()):""},_saveFullQuote:function(e){e.preventDefault();var t=$(e.currentTarget);this._proxy.setOption("data",{actionName:"saveFullQuote",className:this._className,interfaceName:"wcf\\data\\IMessageQuoteAction",objectIDs:[t.data("objectID")]}),this._proxy.sendRequest(),t.data("isQuoted")?t.data("isQuoted",!1).children("a").removeClass("active"):t.data("isQuoted",!0).children("a").addClass("active");var i=t.parents(".buttonGroupNavigation");i.hasClass("jsMobileButtonGroupNavigation")&&i.children(".dropdownLabel").trigger("click")},_saveQuote:function(e){this._proxy.setOption("data",{actionName:"saveQuote",className:this._className,interfaceName:"wcf\\data\\IMessageQuoteAction",objectIDs:[this._objectID],parameters:{message:this._message,renderQuote:!0===e}}),this._proxy.sendRequest()},_saveAndInsertQuote:function(){this._saveQuote(!0)},_success:function(e){if(void 0!==e.returnValues.count){void 0!==e.returnValues.fullQuoteMessageIDs&&(e.returnValues.fullQuoteObjectIDs=e.returnValues.fullQuoteMessageIDs);var t=void 0!==e.returnValues.fullQuoteObjectIDs?e.returnValues.fullQuoteObjectIDs:{};this._quoteManager.updateCount(e.returnValues.count,t)}switch(e.actionName){case"saveQuote":case"saveFullQuote":e.returnValues.renderedQuote&&WCF.System.Event.fireEvent("com.woltlab.wcf.message.quote","insert",{forceInsert:"saveQuote"===e.actionName,quote:e.returnValues.renderedQuote})}},updateFullQuoteObjectIDs:function(e){for(var t in this._containers)this._containers[t].find(".jsQuoteMessage").each(function(t,i){var s=$(i).data("isQuoted",0);s.children("a").removeClass("active"),WCF.inArray(s.data("objectID"),e)&&s.data("isQuoted",1).children("a").addClass("active")})}}),WCF.Message.Quote.Manager=Class.extend({_buttons:{},_count:0,_dialog:null,_editorId:"",_editorIdAlternative:"",_form:null,_handlers:{},_hasTemplate:!1,_insertQuotes:!0,_proxy:null,_removeOnSubmit:[],_supportPaste:!1,_supportPasteOverride:!1,init:function(e,t,i,s){if(this._buttons={insert:null,remove:null},this._count=parseInt(e)||0,this._dialog=null,this._editorId="",this._editorIdAlternative="",this._form=null,this._handlers={},this._hasTemplate=!1,this._insertQuotes=!0,this._removeOnSubmit=[],this._supportPaste=!1,this._supportPasteOverride=!1,t){var n=$("#"+t);n.length&&(this._editorId=t,this._supportPaste=!0,this._form=n.parents("form:eq(0)"),this._form.length?(this._form.submit(this._submit.bind(this)),this._removeOnSubmit=s||[]):(this._form=null,this._supportPaste=!0===i))}this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this),url:"index.php?message-quote/&t="+SECURITY_TOKEN}),this._toggleShowQuotes(),WCF.System.Event.addListener("com.woltlab.wcf.quote","reload",this.countQuotes.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.message.quote","insert",function(e){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertQuote_"+(this._editorIdAlternative?this._editorIdAlternative:this._editorId),{author:e.quote.username,content:e.quote.text,isText:!e.quote.isFullQuote,link:e.quote.link})}.bind(this))},setAlternativeEditor:function(e){this._editorIdAlternative||this._supportPaste||(this._hasTemplate=!1,this._supportPaste=!0,this._supportPasteOverride=!0),"object"==typeof e&&(e=e[0].id),this._editorIdAlternative=e},clearAlternativeEditor:function(){this._supportPasteOverride&&(this._hasTemplate=!1,this._supportPaste=!1,this._supportPasteOverride=!1),this._editorIdAlternative=""},register:function(e,t){this._handlers[e]=t},updateCount:function(e,t){this._count=parseInt(e)||0,this._toggleShowQuotes();for(var i in this._handlers)if(this._handlers.hasOwnProperty(i)){var s=t[i]||[];this._handlers[i].updateFullQuoteObjectIDs(s)}},insertQuotes:function(e,t,i){if(!this._insertQuotes)return void(this._insertQuotes=!0);new WCF.Action.Proxy({autoSend:!0,data:{actionName:"getRenderedQuotes",className:e,interfaceName:"wcf\\data\\IMessageQuoteAction",parameters:{parentObjectID:t}},success:i})},_toggleShowQuotes:function(){require(["WoltLabSuite/Core/Ui/Page/Action"],function(e){if(this._count){var t=e.get("showQuotes");void 0===t&&(t=elCreate("a"),t.addEventListener("mousedown",this._click.bind(this)),e.add("showQuotes",t)),t.textContent=WCF.Language.get("wcf.message.quote.showQuotes").replace(/#count#/,this._count),e.show("showQuotes")}else e.hide("showQuotes");this._hasTemplate=!1}.bind(this))},_click:function(){var e=document.activeElement;e.classList.contains("redactor-layer")&&$("#"+elData(e,"element-id")).redactor("selection.save"),this._hasTemplate?this._dialog.wcfDialog("open"):(this._proxy.showLoadingOverlayOnce(),this._proxy.setOption("data",{actionName:"getQuotes",supportPaste:this._supportPaste}),this._proxy.sendRequest())},renderDialog:function(e){null===this._dialog&&(this._dialog=$("#messageQuoteList"),this._dialog.length||(this._dialog=$('<div id="messageQuoteList" />').hide().appendTo(document.body))),this._dialog.html(e);var t=$('<div class="formSubmit" />').appendTo(this._dialog);this._supportPaste&&(this._buttons.insert=$('<button class="buttonPrimary">'+WCF.Language.get("wcf.message.quote.insertAllQuotes")+"</button>").click($.proxy(this._insertSelected,this)).appendTo(t)),this._buttons.remove=$("<button>"+WCF.Language.get("wcf.message.quote.removeAllQuotes")+"</button>").click($.proxy(this._removeSelected,this)).appendTo(t),this._dialog.wcfDialog({title:WCF.Language.get("wcf.message.quote.manageQuotes")}),this._dialog.wcfDialog("render"),this._hasTemplate=!0;var i=this._dialog.find(".jsInsertQuote");if(this._supportPaste?i.click($.proxy(this._insertQuote,this)):i.hide(),this._dialog.find("input.jsCheckbox").change($.proxy(this._changeButtons,this)),this._removeOnSubmit.length){var s=this;this._dialog.find("input.jsRemoveQuote").each(function(e,t){var i=$(t).change($.proxy(this._change,this));WCF.inArray(i.parent("li").attr("data-quote-id"),s._removeOnSubmit)&&i.attr("checked","checked")})}},_changeButtons:function(){this._dialog.find("input.jsCheckbox:checked").length?(this._supportPaste&&this._buttons.insert.html(WCF.Language.get("wcf.message.quote.insertSelectedQuotes")),this._buttons.remove.html(WCF.Language.get("wcf.message.quote.removeSelectedQuotes"))):(this._supportPaste&&this._buttons.insert.html(WCF.Language.get("wcf.message.quote.insertAllQuotes")),this._buttons.remove.html(WCF.Language.get("wcf.message.quote.removeAllQuotes")))},_change:function(e){var t=$(e.currentTarget),i=t.parent("li").attr("data-quote-id");if(t.prop("checked"))this._removeOnSubmit.push(i);else{var s=this._removeOnSubmit.indexOf(i);-1!==s&&this._removeOnSubmit.splice(s,1)}},_insertSelected:function(){this._dialog.find("input.jsCheckbox:checked").length||this._dialog.find("input.jsCheckbox").prop("checked","checked"),this._dialog.find("input.jsCheckbox:checked").each($.proxy(function(e,t){this._insertQuote(null,t)},this)),this._dialog.wcfDialog("close")},_insertQuote:function(e,t){var i=$(e?e.currentTarget:t).parents("li:eq(0)"),s=i.children(".jsFullQuote")[0].textContent.trim(),n=i.parents(".message:eq(0)"),a=n.data("username"),o=n.data("link"),r=!elDataBool(i[0],"is-full-quote");WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertQuote_"+(this._editorIdAlternative?this._editorIdAlternative:this._editorId),{author:a,content:s,isText:r,link:o}),this._removeOnSubmit.push(i.data("quote-id")),null!==e&&this._dialog.wcfDialog("close")},_removeSelected:function(){this._dialog.find("input.jsCheckbox:checked").length||this._dialog.find("input.jsCheckbox").prop("checked","checked");var e=[];if(this._dialog.find("input.jsCheckbox:checked").each(function(t,i){e.push($(i).parents("li").attr("data-quote-id"))}),e.length){var t=[];for(var i in this._handlers)this._handlers.hasOwnProperty(i)&&t.push(i);this._proxy.setOption("data",{actionName:"remove",getFullQuoteObjectIDs:this._handlers.length>0,objectTypes:t,quoteIDs:e}),this._proxy.sendRequest(),this._dialog.wcfDialog("close")}},_submit:function(){if(this._supportPaste&&this._removeOnSubmit.length>0)for(var e=this._form.find(".formSubmit"),t=0,i=this._removeOnSubmit.length;t<i;t++)$('<input type="hidden" name="__removeQuoteIDs[]" value="'+this._removeOnSubmit[t]+'" />').appendTo(e)},getQuotesMarkedForRemoval:function(){return this._removeOnSubmit},markQuotesForRemoval:function(){this._removeOnSubmit.length&&(this._proxy.setOption("data",{actionName:"markForRemoval",quoteIDs:this._removeOnSubmit}),this._proxy.suppressErrors(),this._proxy.sendRequest())},removeMarkedQuotes:function(){this._removeOnSubmit.length&&(this._proxy.setOption("data",{actionName:"removeMarkedQuotes",getFullQuoteObjectIDs:this._handlers.length>0}),this._proxy.sendRequest())},countQuotes:function(){var e=[];for(var t in this._handlers)this._handlers.hasOwnProperty(t)&&e.push(t);this._proxy.setOption("data",{actionName:"count",getFullQuoteObjectIDs:e.length>0,objectTypes:e}),this._proxy.sendRequest()},_success:function(e){if(null!==e){if(void 0!==e.count){var t=void 0!==e.fullQuoteObjectIDs?e.fullQuoteObjectIDs:{};this.updateCount(e.count,t)}void 0!==e.template&&(""==$.trim(e.template)?this.updateCount(0,{}):this.renderDialog(e.template))}},supportPaste:function(){return this._supportPaste}}),WCF.Message.Share={},WCF.Message.Share.Content=Class.extend({_cache:{},_dialog:null,_shareButtonsTemplate:"",init:function(e){this._shareButtonsTemplate=e||"",this._cache={},this._dialog=null,this._initLinks(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Message.Share.Content",$.proxy(this._initLinks,this))},_initLinks:function(){$("a.jsButtonShare").removeClass("jsButtonShare").click($.proxy(this._click,this))},_click:function(e){e.preventDefault();var t=$(e.currentTarget),i=t.prop("href"),s=t.data("linkTitle")?t.data("linkTitle"):i,n=i.hashCode();if(void 0===this._cache[n]){var a=!1;null===this._dialog?(this._dialog=$('<div id="shareContentDialog" />').hide().appendTo(document.body),a=!0):this._dialog.empty();var o=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalink">'+WCF.Language.get("wcf.message.share.permalink")+"</label></h2></section>").appendTo(this._dialog);$('<input type="text" id="__sharePermalink" class="long" readonly />').attr("value",i).appendTo(o);var o=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkBBCode">'+WCF.Language.get("wcf.message.share.permalink.bbcode")+"</label></h2></section>").appendTo(this._dialog);$('<input type="text" id="__sharePermalinkBBCode" class="long" readonly />').attr("value","[url='"+i+"']"+s+"[/url]").appendTo(o);var o=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkHTML">'+WCF.Language.get("wcf.message.share.permalink.html")+"</label></h2></section>").appendTo(this._dialog);$('<input type="text" id="__sharePermalinkHTML" class="long" readonly />').attr("value",'<a href="'+i+'">'+WCF.String.escapeHTML(s)+"</a>").appendTo(o),""!==this._shareButtonsTemplate&&(o=$('<section class="section"><h2 class="sectionTitle">'+WCF.Language.get("wcf.message.share")+"</h2>"+this._shareButtonsTemplate+"</section>").appendTo(this._dialog),elData(o.children(".jsMessageShareButtons")[0],"url",WCF.String.escapeHTML(i))),this._cache[n]=this._dialog.html(),a?this._dialog.wcfDialog({title:WCF.Language.get("wcf.message.share")}):this._dialog.wcfDialog("open")}else this._dialog.html(this._cache[n]).wcfDialog("open");this._enableSelection()},_enableSelection:function(){var e=this._dialog.find("input").click(function(){$(this).select()});navigator.userAgent.match(/iP(ad|hone|od)/)&&e.keydown(function(){return!1}).removeAttr("readonly").click(function(){this.setSelectionRange(0,9999)})}}),WCF.Message.Share.Page=Class.extend({init:function(){require(["WoltLabSuite/Core/Ui/Message/Share"],function(e){e.init()})}}),WCF.Message.UserMention=Class.extend({init:function(){throw new Error("Support for mentions in Redactor are now enabled by adding the attribute 'data-support-mention=\"true\"' to the textarea element.")}}),$.widget("wcf.messageTabMenu",{_tabs:[],_tabsByName:{},options:{collapsible:!0},_create:function(){var e=this.element.find("> nav"),t=e.find("> ul > li:not(.jsFlexibleMenuDropdown)"),i=this.element.find("> div, > fieldset");if(t.length!=i.length)return void console.debug("[wcf.messageTabMenu] Amount of tabs does not equal amount of tab containers, aborting.");var s=this.element.data("preselect");i.each(function(e,i){if(null!==elBySel(".innerError",i))return s=$(t[e]).data("name"),!1}),"true"===s&&(s=!0),this._tabs=[],this._tabsByName={};for(var n=0;n<t.length;n++){var a=$(t[n]),o=$(i[n]),r=a.data("name");if(void 0===r){var l=a.children("a").prop("href");void 0!==l&&l.match(/#([a-zA-Z_-]+)$/)&&(r=RegExp.$1),void 0===r&&(r=a.wcfIdentify())}this._tabs.push({container:o,name:r,tab:a}),this._tabsByName[r]=n;var c=a.children("a").data("index",n).on("mousedown",this._showTab.bind(this));c.attr("role","button").attr("tabindex","0").attr("aria-haspopup",!0).attr("aria-expanded",!1).attr("aria-controls",o[0].id),c.on("keydown",function(e){13!==e.which&&32!==e.which||(e.preventDefault(),this._showTab(e))}.bind(this)),(s===r||!0===s&&0===n)&&c.trigger("mousedown")}!0===s&&this._tabs.length&&!window.matchMedia("(max-width: 544px)").matches&&this._tabs[0].tab.children("a").trigger("click");var u=this.element.data("collapsible");void 0!==u&&(this.options.collapsible=u);var h=elData(this.element[0],"wysiwyg-container-id");h&&WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+h,function(){for(var e=0,t=this._tabs.length;e<t;e++)this._tabs[e].container.removeClass("active"),this._tabs[e].tab.removeClass("active")}.bind(this))},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this.element.remove()},_showTab:function(e,t,i){var s=null===e?t:$(e.currentTarget).data("index");i=!this.options.collapsible||!0===i;for(var n=null,a=0;a<this._tabs.length;a++){var o=this._tabs[a];if(a==s){if(!o.tab.hasClass("active")){o.tab.addClass("active"),o.container.addClass("active"),n=o,o.tab.children("a").attr("aria-expanded",!0);var r=o.container[0];if(null===elBySel(".messageTabMenuContent.active",r)&&null!==elBySel(".messageTabMenuContent",r)){var l=elBySel("nav > ul > li[data-name] > a",r);null!==l&&$(l).trigger("mousedown")}continue}if(!0===i)continue}o.tab.removeClass("active"),o.container.removeClass("active"),o.tab.children("a").attr("aria-expanded",!1)}null!==e&&(e.preventDefault(),e.stopPropagation()),null!==n&&this._trigger("show",{},{activeTab:n}),$(window).trigger("resize")},showTab:function(e,t){if($.isNumeric(e)||void 0!==this._tabsByName[e]&&(e=this._tabsByName[e]),void 0===this._tabs[e])return void console.debug("[wcf.messageTabMenu] Cannot locate tab identified by '"+e+"'");this._showTab(null,e,t)},getTab:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].tab:null},getContainer:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].container:null}}); })(this);
+(function (window, undefined) { "use strict";WCF.Message={},WCF.Message.BBCode={},WCF.Message.BBCode.CodeViewer=Class.extend({init:function(){}}),WCF.Message.EditHistory=Class.extend({_oldIDInputs:null,_newIDInputs:null,_containerSelector:"",_buttonSelector:".jsRevertButton",init:function(e,t,s,i,n){this._oldIDInputs=e,this._newIDInputs=t,this._containerSelector=s,this._buttonSelector=i||".jsRevertButton",this._options=$.extend({isVersionTracker:!1,versionTrackerObjectType:"",versionTrackerObjectId:0,redirectUrl:""},n),this.proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initInputs(),this._initElements()},_initInputs:function(){var t=this;this._newIDInputs.change(function(e){var s=parseInt($(this).val());"current"===$(this).val()&&(s=1/0),t._oldIDInputs.each(function(e){var t=parseInt($(this).val());"current"===$(this).val()&&(t=1/0),s<=t?$(this).disable():$(this).enable()})}),this._oldIDInputs.change(function(e){var s=parseInt($(this).val());"current"===$(this).val()&&(s=1/0),t._newIDInputs.each(function(e){var t=parseInt($(this).val());"current"===$(this).val()&&(t=1/0),t<=s?$(this).disable():$(this).enable()})}),this._oldIDInputs.filter(":checked").change(),this._newIDInputs.filter(":checked").change()},_initElements:function(){var s=this;$(this._containerSelector).each(function(e,t){$(t).find(s._buttonSelector).click($.proxy(s._click,s))})},_click:function(e){var t,s=$(e.currentTarget);e.preventDefault(),s.data("confirmMessage")?(t=this,WCF.System.Confirmation.show(s.data("confirmMessage"),function(e){"cancel"!==e&&t._sendRequest(s)},void 0,void 0,!0)):this._sendRequest(s)},_sendRequest:function(e){this._options.isVersionTracker?(this.proxy.setOption("url",window.WSC_API_URL+"index.php?ajax-invoke/&t="+window.SECURITY_TOKEN),this.proxy.setOption("data",{actionName:"revert",className:"wcf\\system\\version\\VersionTracker",parameters:{objectType:this._options.versionTrackerObjectType,objectID:this._options.versionTrackerObjectId,versionID:$(e).data("objectID")}})):this.proxy.setOption("data",{actionName:"revert",className:"wcf\\data\\edit\\history\\entry\\EditHistoryEntryAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,s){this._options.redirectUrl?(new WCF.System.Notification).show(function(){window.location=this._options.redirectUrl}.bind(this)):window.location.reload(!0)}}),WCF.Message.FormGuard=Class.extend({init:function(){var e=$("form.jsFormGuard").removeClass("jsFormGuard").submit(function(){$(this).find(".formSubmit input[type=submit]").disable()});$(window).on("unload",function(){e.find(".formSubmit input[type=submit]").enable()})}}),WCF.Message.Preview=Class.extend({_className:"",_messageFieldID:"",_messageField:null,_proxy:null,_previewButton:null,_previewButtonLabel:"",init:function(e,t,s){this._className=e,this._messageFieldID=$.wcfEscapeID(t),this._textarea=$("#"+this._messageFieldID),this._textarea.length?(s=$.wcfEscapeID(s),this._previewButton=$("#"+s),this._previewButton.length?(this._previewButton.click($.proxy(this._click,this)),this._proxy=new WCF.Action.Proxy({failure:$.proxy(this._failure,this),success:$.proxy(this._success,this)})):console.debug("[WCF.Message.Preview] Unable to find preview button identified by '"+s+"'")):console.debug("[WCF.Message.Preview] Unable to find message field identified by '"+this._messageFieldID+"'")},_click:function(e){e.preventDefault();var t=this._getMessage();if(null!==t)return this._proxy.setOption("data",{actionName:"getMessagePreview",className:this._className,parameters:this._getParameters(t)}),this._proxy.sendRequest(),this._previewButtonLabel=this._previewButton.html(),this._previewButton.html(WCF.Language.get("wcf.global.loading")).disable(),e.stopPropagation(),!1;console.debug("[WCF.Message.Preview] Unable to access Redactor instance of '"+this._messageFieldID+"'")},_getParameters:function(e){var i={};return $("#settings_"+this._messageFieldID).find("input[type=checkbox]").each(function(e,t){var s=$(t);s.is(":checked")&&(i[s.prop("name")]=s.prop("value"))}),{data:{message:e},options:i}},_getMessage:function(){return this._textarea.redactor("code.get")},_success:function(e,t,s){this._previewButton.html(this._previewButtonLabel).enable(),this._textarea.parent().children("small.innerError").remove(),this._handleResponse(e)},_handleResponse:function(e){},_failure:function(e){if(null===e||void 0===e.returnValues||void 0===e.returnValues.errorType)return!0;this._previewButton.html(this._previewButtonLabel).enable();var t=this._textarea.parent().children("small.innerError").empty();t.length||(t=$('<small class="innerError" />').appendTo(this._textarea.parent()));var s="empty"===e.returnValues.errorType?WCF.Language.get("wcf.global.form.error.empty"):e.returnValues.errorMessage;return e.returnValues.realErrorMessage&&(s=e.returnValues.realErrorMessage),t.html(s),!1}}),WCF.Message.DefaultPreview=WCF.Message.Preview.extend({_dialog:null,_options:{},init:function(e){if(1<arguments.length&&"string"==typeof e)throw new Error("Outdated API call, please update your implementation.");if(this._options=$.extend({disallowedBBCodesPermission:"user.message.disallowedBBCodes",messageFieldID:"",previewButtonID:"",messageObjectType:"",messageObjectID:0},e),!this._options.messageObjectType)throw new Error("Field 'messageObjectType' cannot be empty.");this._super("wcf\\data\\bbcode\\MessagePreviewAction",this._options.messageFieldID,this._options.previewButtonID)},_handleResponse:function(t){require(["WoltLabSuite/Core/Ui/Dialog"],function(e){e.open(this,'<div class="htmlContent">'+t.returnValues.message+"</div>")}.bind(this))},_getParameters:function(e){var t=this._super(e);for(var s in this._options)this._options.hasOwnProperty(s)&&"messageFieldID"!==s&&"previewButtonID"!==s&&(t[s]=this._options[s]);return t},_dialogSetup:function(){return{id:"messagePreview",options:{title:WCF.Language.get("wcf.global.preview")},source:null}}}),WCF.Message.I18nPreview=WCF.Message.Preview.extend({_activeMessageField:"",_dialog:null,_options:{},init:function(e){if(this._activeMessageField="",this._options=$.extend({disallowedBBCodesPermission:"user.message.disallowedBBCodes",messageFields:[],messageObjectType:"",messageObjectID:0},e),!this._options.messageObjectType)throw new Error("Field 'messageObjectType' cannot be empty.");if(this._options.messageFields.length<1)throw new TypeError("Expected a non empty list of message field ids");this._super("wcf\\data\\bbcode\\MessagePreviewAction",this._options.messageFields[0],"buttonMessagePreview")},_click:function(e){for(var t=this._messageFieldID="",s=this._textarea=null,i=0,n=this._options.messageFields.length;i<n;i++)if(t=this._options.messageFields[i],s=elById(t),null!==elBySel('.redactor-layer[data-element-id="'+s.id+'"]').offsetParent){this._messageFieldID=t,this._textarea=$(s);break}if(""===this._messageFieldID)throw new Error("Unable to identify the active message field.");this._super(e)},_getParameters:function(e){var t=this._super(e);for(var s in this._options)this._options.hasOwnProperty(s)&&-1===["messageFields","messageFieldID","previewButtonID"].indexOf(s)&&(t[s]=this._options[s]);return t},_handleResponse:function(t){require(["WoltLabSuite/Core/Ui/Dialog"],function(e){e.open(this,'<div class="htmlContent">'+t.returnValues.message+"</div>")}.bind(this))},_dialogSetup:function(){return{id:"messagePreview",options:{title:WCF.Language.get("wcf.global.preview")},source:null}}}),WCF.Message.Multilingualism=Class.extend({_availableLanguages:{},_languageID:0,_languageInput:null,init:function(e,t,s){var i;this._availableLanguages=t,this._languageID=e||0,this._languageInput=$("#languageID"),this._updateLabel(),this._languageInput.find(".dropdownMenu > li").click($.proxy(this._click,this)),s||(i=this._languageInput.find(".dropdownMenu"),$('<li class="dropdownDivider" />').appendTo(i),$('<li><span><span class="badge">'+this._availableLanguages[0]+"</span></span></li>").click($.proxy(this._disable,this)).appendTo(i)),this._languageInput.parents("form").submit($.proxy(this._submit,this))},_click:function(e){this._languageID=$(e.currentTarget).data("languageID"),this._updateLabel()},_disable:function(){this._languageID=0,this._updateLabel()},_updateLabel:function(){this._languageInput.find(".dropdownToggle > span").text(this._availableLanguages[this._languageID])},_submit:function(){this._languageInput.next("input[name=languageID]").prop("value",this._languageID)}}),WCF.Message.SmileyCategories=Class.extend({_cache:[],_proxy:null,_wysiwygSelector:"",init:function(e,t,s){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._wysiwygSelector=e,this._smiliesTabMenuId=t||"smilies-"+this._wysiwygSelector,this._formBuilderUsage=s||!1,$("#"+this._smiliesTabMenuId).on("messagetabmenushow",$.proxy(this._click,this))},_click:function(e,t){if(e.preventDefault(),this._formBuilderUsage){if(!t.activeTab.tab.children("a").prop("href").match(/#([a-zA-Z0-9_-]+)$/))return void console.debug("[WCF.Message.SmileyCategories] Cannot extract category id for tab '"+t.activeTab.tab.wcfIdentify()+"'.");if(!RegExp.$1.match(this._smiliesTabMenuId.replace(/Container$/,"")+"_smileyCategoryTab(\\d+)Container"))return void console.debug("[WCF.Message.SmileyCategories] Cannot extract category id for tab '"+t.activeTab.tab.wcfIdentify()+"'.");var s=parseInt(RegExp.$1)}else s=parseInt(t.activeTab.tab.data("smileyCategoryID"));s&&(t.activeTab.container.children("ul.smileyList").length||(void 0===this._cache[s]?(this._proxy.setOption("data",{actionName:"getSmilies",className:"wcf\\data\\smiley\\category\\SmileyCategoryAction",objectIDs:[s]}),this._proxy.sendRequest()):t.activeTab.container.html(this._cache[s])))},_success:function(e,t,s){var i=parseInt(e.returnValues.smileyCategoryID);this._cache[i]=e.returnValues.template,this._formBuilderUsage?$("#"+this._smiliesTabMenuId.replace(/Container$/,"")+"_smileyCategoryTab"+i+"Container").html(e.returnValues.template):$("#smilies-"+this._wysiwygSelector+"-"+i).html(e.returnValues.template)}}),WCF.Message.Smilies=Class.extend({init:function(t){require(["WoltLabSuite/Core/Ui/Smiley/Insert"],function(e){new e(t)})}}),WCF.Message.InlineEditor=Class.extend({_container:{},_containerID:0,_dropdowns:{},_messageContainerSelector:".jsMessage",_messageEditorIDPrefix:"messageEditor",init:function(t,e,s){require(["WoltLabSuite/Core/Ui/Message/InlineEditor"],function(e){new e({className:this._getClassName(),containerId:t,editorPrefix:this._messageEditorIDPrefix,messageSelector:this._messageContainerSelector,quoteManager:s||null,callbackDropdownInit:this._callbackDropdownInit.bind(this)})}.bind(this))},_click:function(e,t){t=null===e?~~t:~~elData(e.currentTarget,"container-id"),require(["WoltLabSuite/Core/Ui/Message/InlineEditor"],function(e){e.legacyEdit(t)}.bind(this)),e&&e.preventDefault()},_initDropdownMenu:function(e,t){},_callbackDropdownInit:function(e,t){return this._initDropdownMenu($(e).wcfIdentify(),$(t)),null},_getClassName:function(){return""}}),WCF.Message.Submit={_buttons:{},registerButton:function(e,t){WCF.Browser.isChrome()&&(this._buttons[e]=$(t))},execute:function(e){this._buttons[e]&&this._buttons[e].trigger("click")}},WCF.Message.Quote={},WCF.Message.Quote.Handler=Class.extend({_activeContainerID:"",_className:"",_containers:{},_containerSelector:"",_copyQuote:null,_message:"",_messageBodySelector:"",_objectID:0,_objectType:"",_proxy:null,_quoteManager:null,_selectionChangeTimer:null,_isMouseDown:!1,init:function(e,t,s,i,n,a,o){var r;this._className=t,""!==this._className?(this._objectType=s,""!==this._objectType?(this._containerSelector=i,this._message="",this._messageBodySelector=n,this._objectID=0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._selectionChangeTimer=null,this._isMouseDown=!1,this._initContainers(),o=o&&e.supportPaste(),this._initCopyQuote(o),$(document).mouseup($.proxy(this._mouseUp,this)),document.addEventListener("selectionchange",this._selectionchange.bind(this)),this._quoteManager=e,this._quoteManager.register(this._objectType,this),WCF.DOMNodeInsertedHandler.addCallback("WCF.Message.Quote.Handler"+s.hashCode(),$.proxy(this._initContainers,this)),r=this._copyQuote[0],document.addEventListener("touchstart",function(e){var t;r.classList.contains("active")&&((t=e.target)===r||r.contains(t)||(r.classList.add("touchForceInaccessible"),document.addEventListener("touchend",function(){r.classList.remove("touchForceInaccessible")},{once:!0})))},{passive:!0})):console.debug("[WCF.Message.QuoteManager] Empty object type name given, aborting.")):console.debug("[WCF.Message.QuoteManager] Empty class name given, aborting.")},_initContainers:function(){var n=this;$(this._containerSelector).each(function(e,t){var s=$(t),i=s.wcfIdentify();if(!n._containers[i]){if((n._containers[i]=s).hasClass("jsInvalidQuoteTarget"))return!0;n._messageBodySelector&&s.data("body",s.find(n._messageBodySelector).data("containerID",i)),s.mousedown($.proxy(n._mouseDown,n)),s[0].classList.add("jsQuoteMessageContainer"),n._containers[i].find(".jsQuoteMessage").click($.proxy(n._saveFullQuote,n))}})},_selectionchange:function(){if(!this._isMouseDown){if(""===this._activeContainerID){var e=window.getSelection();if(1!==e.rangeCount||e.isCollapsed)return;var t=e.getRangeAt(0),s=elClosest(t.startContainer,".jsQuoteMessageContainer"),i=elClosest(t.endContainer,".jsQuoteMessageContainer");if(s&&s===i&&!s.classList.contains("jsInvalidQuoteTarget")){var n=t.commonAncestorContainer;n.nodeType!==Node.ELEMENT_NODE&&(n=n.parentNode);var a=n.offsetParent;if(s.contains(a)&&a.scrollTop+a.clientHeight<n.offsetTop)return;this._activeContainerID=s.id}}null!==this._selectionChangeTimer&&window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=window.setTimeout(this._mouseUp.bind(this),100)}},_mouseDown:function(e){this._copyQuote.removeClass("active"),this._activeContainerID=e.currentTarget.classList.contains("jsInvalidQuoteTarget")?"":e.currentTarget.id,null!==this._selectionChangeTimer&&(window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=null),this._isMouseDown=!0},_getNodeText:function(e){function t(e){switch(e.tagName){case"BLOCKQUOTE":case"SCRIPT":return NodeFilter.FILTER_REJECT;case"IMG":if(!e.classList.contains("smiley")||0===e.alt.length)return NodeFilter.FILTER_REJECT;default:return NodeFilter.FILTER_ACCEPT}}t.acceptNode=t;for(var s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,t,!0),i="",n=[];s.nextNode();){var a,o,r,l=s.currentNode;if(l.nodeType===Node.ELEMENT_NODE)switch(l.tagName){case"A":0<(r=l.textContent).indexOf("…")&&(2!==(a=r.split(/\u2026/)).length||0===(o=l.href).indexOf(a[0])&&o.substr(-1*a[1].length)===a[1]&&(i+=o,n.push(l)));break;case"BR":case"LI":case"UL":i+="\n";break;case"TD":$.browser.msie||(i+="\n");break;case"P":i+="\n\n";break;case"IMG":i+=" "+l.alt+" ";break;case"DIV":(l.classList.contains("codeBoxHeadline")||l.classList.contains("codeBoxLine"))&&(i+="\n")}else{if("A"===l.parentNode.nodeName&&-1!==n.indexOf(l.parentNode))continue;i+=l.nodeValue.replace(/\n/g," ")}}return i},_mouseUp:function(e){if(e&&e.originalEvent instanceof Event&&(null!==this._selectionChangeTimer&&(window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=null),this._isMouseDown=!1),""!==this._activeContainerID){var t=window.getSelection();if(1!==t.rangeCount||t.isCollapsed)this._copyQuote.removeClass("active");else{for(var s,i,n,a,o,r,l,c,u,h,d,_=(g=this._containers[this._activeContainerID]).data("objectID"),g=g.data("body")||g,p=t.anchorNode;p&&p!==g[0];)p=p.parentNode;p===g[0]?(s=this._getSelectedText(),""!==(i=$.trim(s))?(a=(n=t.getRangeAt(0)).startContainer.nodeType===Node.TEXT_NODE?n.startContainer.parentNode:n.startContainer,o=n.endContainer.nodeType===Node.TEXT_NODE?n.endContainer.parentNode:n.endContainer,a.closest("blockquote")||o.closest("blockquote")?this._copyQuote.removeClass("active"):(r=this._getNodeText(g[0]),-1!==this._normalize(r).indexOf(this._normalize(i))&&(this._copyQuote.addClass("active"),l=this._getBoundingRectangle(g,window.getSelection()),c=this._copyQuote.getDimensions("outer"),(u=(l.right-l.left)/2-c.width/2+l.left)<(h=g[0].getBoundingClientRect()).left?u=h.left:u+c.width>h.right&&(u=h.right-c.width),this._copyQuote.css({top:l.bottom+7+"px",left:u+"px"}),this._copyQuote.removeClass("active"),null===this._selectionChangeTimer?this._activeContainerID="":(window.clearTimeout(this._selectionChangeTimer),this._selectionChangeTimer=null),d=this,window.setTimeout(function(){var e=$.trim(d._getSelectedText());""!==e&&(d._copyQuote.addClass("active"),d._message=e,d._objectID=_)},10)))):this._copyQuote.removeClass("active")):this._copyQuote.removeClass("active")}}else this._copyQuote.removeClass("active")},_normalize:function(e){return e.replace(/\r?\n|\r/g,"\n").replace(/\s/g," ").replace(/\s{2,}/g," ")},_getBoundingRectangle:function(e,t){var s,i,n=null;return 0<t.rangeCount&&(s=t.getRangeAt(0).getBoundingClientRect(),i=$(document).scrollTop(),n={bottom:s.bottom+i,left:s.left,right:s.right,top:s.top+i}),n},_initCopyQuote:function(e){var t;this._copyQuote=$("#quoteManagerCopy"),this._copyQuote.length||(this._copyQuote=$('<div id="quoteManagerCopy" class="balloonTooltip interactive"><span class="jsQuoteManagerStore">'+WCF.Language.get("wcf.message.quote.quoteSelected")+"</span></div>").appendTo(document.body),t=this._copyQuote.children("span.jsQuoteManagerStore").click($.proxy(this._saveQuote,this)),e&&$('<span class="jsQuoteManagerQuoteAndInsert">'+WCF.Language.get("wcf.message.quote.quoteAndReply")+"</span>").click($.proxy(this._saveAndInsertQuote,this)).insertAfter(t))},_getSelectedText:function(){var e=window.getSelection();return e.rangeCount?this._getNodeText(e.getRangeAt(0).cloneContents()):""},_saveFullQuote:function(e){e.preventDefault();var t=$(e.currentTarget);this._proxy.setOption("data",{actionName:"saveFullQuote",className:this._className,interfaceName:"wcf\\data\\IMessageQuoteAction",objectIDs:[t.data("objectID")]}),this._proxy.sendRequest(),t.data("isQuoted")?t.data("isQuoted",!1).children("a").removeClass("active"):t.data("isQuoted",!0).children("a").addClass("active");var s=t.parents(".buttonGroupNavigation");s.hasClass("jsMobileButtonGroupNavigation")&&s.children(".dropdownLabel").trigger("click")},_saveQuote:function(e){this._proxy.setOption("data",{actionName:"saveQuote",className:this._className,interfaceName:"wcf\\data\\IMessageQuoteAction",objectIDs:[this._objectID],parameters:{message:this._message,renderQuote:!0===e}}),this._proxy.sendRequest();var t=window.getSelection();t.rangeCount&&(t.removeAllRanges(),this._copyQuote[0].classList.remove("active"))},_saveAndInsertQuote:function(){this._saveQuote(!0)},_success:function(e){var t;switch(void 0!==e.returnValues.count&&(void 0!==e.returnValues.fullQuoteMessageIDs&&(e.returnValues.fullQuoteObjectIDs=e.returnValues.fullQuoteMessageIDs),t=void 0!==e.returnValues.fullQuoteObjectIDs?e.returnValues.fullQuoteObjectIDs:{},this._quoteManager.updateCount(e.returnValues.count,t)),e.actionName){case"saveQuote":case"saveFullQuote":e.returnValues.renderedQuote&&WCF.System.Event.fireEvent("com.woltlab.wcf.message.quote","insert",{forceInsert:"saveQuote"===e.actionName,quote:e.returnValues.renderedQuote})}},updateFullQuoteObjectIDs:function(i){for(var e in this._containers)this._containers[e].find(".jsQuoteMessage").each(function(e,t){var s=$(t).data("isQuoted",0);s.children("a").removeClass("active"),WCF.inArray(s.data("objectID"),i)&&s.data("isQuoted",1).children("a").addClass("active")})}}),WCF.Message.Quote.Manager=Class.extend({_buttons:{},_count:0,_dialog:null,_editorId:"",_editorIdAlternative:"",_form:null,_handlers:{},_hasTemplate:!1,_insertQuotes:!0,_proxy:null,_removeOnSubmit:[],_supportPaste:!1,_supportPasteOverride:!1,init:function(e,t,s,i){var n;this._buttons={insert:null,remove:null},this._count=parseInt(e)||0,this._dialog=null,this._editorId="",this._editorIdAlternative="",this._form=null,this._handlers={},this._hasTemplate=!1,this._insertQuotes=!0,this._removeOnSubmit=[],this._supportPaste=!1,this._supportPasteOverride=!1,!t||(n=$("#"+t)).length&&(this._editorId=t,this._supportPaste=!0,this._form=n.parents("form:eq(0)"),this._form.length?(this._form.submit(this._submit.bind(this)),this._removeOnSubmit=i||[]):(this._form=null,this._supportPaste=!0===s)),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this),url:"index.php?message-quote/&t="+SECURITY_TOKEN}),this._toggleShowQuotes(),WCF.System.Event.addListener("com.woltlab.wcf.quote","reload",this.countQuotes.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.message.quote","insert",function(e){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertQuote_"+(this._editorIdAlternative?this._editorIdAlternative:this._editorId),{author:e.quote.username,content:e.quote.text,isText:!e.quote.isFullQuote,link:e.quote.link})}.bind(this))},setAlternativeEditor:function(e){this._editorIdAlternative||this._supportPaste||(this._hasTemplate=!1,this._supportPaste=!0,this._supportPasteOverride=!0),"object"==typeof e&&(e=e[0].id),this._editorIdAlternative=e},clearAlternativeEditor:function(){this._supportPasteOverride&&(this._hasTemplate=!1,this._supportPaste=!1,this._supportPasteOverride=!1),this._editorIdAlternative=""},register:function(e,t){this._handlers[e]=t},updateCount:function(e,t){for(var s in this._count=parseInt(e)||0,this._toggleShowQuotes(),this._handlers){var i;this._handlers.hasOwnProperty(s)&&(i=t[s]||[],this._handlers[s].updateFullQuoteObjectIDs(i))}},insertQuotes:function(e,t,s){this._insertQuotes?new WCF.Action.Proxy({autoSend:!0,data:{actionName:"getRenderedQuotes",className:e,interfaceName:"wcf\\data\\IMessageQuoteAction",parameters:{parentObjectID:t}},success:s}):this._insertQuotes=!0},_toggleShowQuotes:function(){require(["WoltLabSuite/Core/Ui/Page/Action"],function(e){var t,s="showQuotes";this._count?(void 0===(t=e.get(s))&&((t=elCreate("a")).addEventListener("mousedown",this._click.bind(this)),e.add(s,t)),t.textContent=WCF.Language.get("wcf.message.quote.showQuotes",{count:this._count}),e.show(s)):e.remove(s),this._hasTemplate=!1}.bind(this))},_click:function(){var e=document.activeElement;e.classList.contains("redactor-layer")&&$("#"+elData(e,"element-id")).redactor("selection.save"),this._hasTemplate?this._dialog.wcfDialog("open"):(this._proxy.showLoadingOverlayOnce(),this._proxy.setOption("data",{actionName:"getQuotes",supportPaste:this._supportPaste}),this._proxy.sendRequest())},renderDialog:function(e){null===this._dialog&&(this._dialog=$("#messageQuoteList"),this._dialog.length||(this._dialog=$('<div id="messageQuoteList" />').hide().appendTo(document.body))),this._dialog.html(e);var t=$('<div class="formSubmit" />').appendTo(this._dialog);this._supportPaste&&(this._buttons.insert=$('<button class="buttonPrimary">'+WCF.Language.get("wcf.message.quote.insertAllQuotes")+"</button>").click($.proxy(this._insertSelected,this)).appendTo(t)),this._buttons.remove=$("<button>"+WCF.Language.get("wcf.message.quote.removeAllQuotes")+"</button>").click($.proxy(this._removeSelected,this)).appendTo(t),this._dialog.wcfDialog({title:WCF.Language.get("wcf.message.quote.manageQuotes")}),this._dialog.wcfDialog("render"),this._hasTemplate=!0;var i,s=this._dialog.find(".jsInsertQuote");this._supportPaste?s.click($.proxy(this._insertQuote,this)):s.hide(),this._dialog.find("input.jsCheckbox").change($.proxy(this._changeButtons,this)),this._removeOnSubmit.length&&(i=this)._dialog.find("input.jsRemoveQuote").each(function(e,t){var s=$(t).change($.proxy(this._change,this));WCF.inArray(s.parent("li").attr("data-quote-id"),i._removeOnSubmit)&&s.attr("checked","checked")})},_changeButtons:function(){this._dialog.find("input.jsCheckbox:checked").length?(this._supportPaste&&this._buttons.insert.html(WCF.Language.get("wcf.message.quote.insertSelectedQuotes")),this._buttons.remove.html(WCF.Language.get("wcf.message.quote.removeSelectedQuotes"))):(this._supportPaste&&this._buttons.insert.html(WCF.Language.get("wcf.message.quote.insertAllQuotes")),this._buttons.remove.html(WCF.Language.get("wcf.message.quote.removeAllQuotes")))},_change:function(e){var t,s=$(e.currentTarget),i=s.parent("li").attr("data-quote-id");s.prop("checked")?this._removeOnSubmit.push(i):-1!==(t=this._removeOnSubmit.indexOf(i))&&this._removeOnSubmit.splice(t,1)},_insertSelected:function(){this._dialog.find("input.jsCheckbox:checked").length||this._dialog.find("input.jsCheckbox").prop("checked","checked"),this._dialog.find("input.jsCheckbox:checked").each($.proxy(function(e,t){this._insertQuote(null,t)},this)),this._dialog.wcfDialog("close")},_insertQuote:function(e,t){var s=$(e?e.currentTarget:t).parents("li:eq(0)"),i=s.children(".jsFullQuote")[0].textContent.trim(),n=s.parents(".message:eq(0)"),a=n.data("username"),o=n.data("link"),r=!elDataBool(s[0],"is-full-quote");WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertQuote_"+(this._editorIdAlternative?this._editorIdAlternative:this._editorId),{author:a,content:i,isText:r,link:o}),this._removeOnSubmit.push(s.data("quote-id")),null!==e&&require(["WoltLabSuite/Core/Environment"],function(e){var t=function(){this._dialog.wcfDialog("close")}.bind(this);"ios"===e.platform()?window.setTimeout(t,100):t()}.bind(this))},_removeSelected:function(){this._dialog.find("input.jsCheckbox:checked").length||this._dialog.find("input.jsCheckbox").prop("checked","checked");var s=[];if(this._dialog.find("input.jsCheckbox:checked").each(function(e,t){s.push($(t).parents("li").attr("data-quote-id"))}),s.length){var e=[];for(var t in this._handlers)this._handlers.hasOwnProperty(t)&&e.push(t);this._proxy.setOption("data",{actionName:"remove",getFullQuoteObjectIDs:0<this._handlers.length,objectTypes:e,quoteIDs:s}),this._proxy.sendRequest(),this._dialog.wcfDialog("close")}},_submit:function(){if(this._supportPaste&&0<this._removeOnSubmit.length)for(var e=this._form.find(".formSubmit"),t=0,s=this._removeOnSubmit.length;t<s;t++)$('<input type="hidden" name="__removeQuoteIDs[]" value="'+this._removeOnSubmit[t]+'" />').appendTo(e)},getQuotesMarkedForRemoval:function(){return this._removeOnSubmit},markQuotesForRemoval:function(){this._removeOnSubmit.length&&(this._proxy.setOption("data",{actionName:"markForRemoval",quoteIDs:this._removeOnSubmit}),this._proxy.suppressErrors(),this._proxy.sendRequest())},removeMarkedQuotes:function(){this._removeOnSubmit.length&&(this._proxy.setOption("data",{actionName:"removeMarkedQuotes",getFullQuoteObjectIDs:0<this._handlers.length}),this._proxy.sendRequest())},countQuotes:function(){var e=[];for(var t in this._handlers)this._handlers.hasOwnProperty(t)&&e.push(t);this._proxy.setOption("data",{actionName:"count",getFullQuoteObjectIDs:0<e.length,objectTypes:e}),this._proxy.sendRequest()},_success:function(e){var t;null!==e&&(void 0!==e.count&&(t=void 0!==e.fullQuoteObjectIDs?e.fullQuoteObjectIDs:{},this.updateCount(e.count,t)),void 0!==e.template&&(""==$.trim(e.template)?this.updateCount(0,{}):this.renderDialog(e.template)))},supportPaste:function(){return this._supportPaste}}),WCF.Message.Share={},WCF.Message.Share.Content=Class.extend({_cache:{},_dialog:null,_shareButtonsTemplate:"",init:function(e){this._shareButtonsTemplate=e||"",this._cache={},this._dialog=null,this._initLinks(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Message.Share.Content",$.proxy(this._initLinks,this))},_initLinks:function(){$("a.jsButtonShare").removeClass("jsButtonShare").click($.proxy(this._click,this))},_click:function(e){e.preventDefault();var t,s,i=$(e.currentTarget),n=i.prop("href"),a=i.data("linkTitle")?i.data("linkTitle"):n,o=n.hashCode();void 0===this._cache[o]?(t=!1,null===this._dialog?(this._dialog=$('<div id="shareContentDialog" />').hide().appendTo(document.body),t=!0):this._dialog.empty(),s=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalink">'+WCF.Language.get("wcf.message.share.permalink")+"</label></h2></section>").appendTo(this._dialog),$('<input type="text" id="__sharePermalink" class="long" readonly />').attr("value",n).appendTo(s),s=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkBBCode">'+WCF.Language.get("wcf.message.share.permalink.bbcode")+"</label></h2></section>").appendTo(this._dialog),$('<input type="text" id="__sharePermalinkBBCode" class="long" readonly />').attr("value","[url='"+n+"']"+a+"[/url]").appendTo(s),s=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkHTML">'+WCF.Language.get("wcf.message.share.permalink.html")+"</label></h2></section>").appendTo(this._dialog),$('<input type="text" id="__sharePermalinkHTML" class="long" readonly />').attr("value",'<a href="'+n+'">'+WCF.String.escapeHTML(a)+"</a>").appendTo(s),""!==this._shareButtonsTemplate&&(s=$('<section class="section"><h2 class="sectionTitle">'+WCF.Language.get("wcf.message.share")+"</h2>"+this._shareButtonsTemplate+"</section>").appendTo(this._dialog),elData(s.children(".jsMessageShareButtons")[0],"url",WCF.String.escapeHTML(n))),this._cache[o]=this._dialog.html(),t?this._dialog.wcfDialog({title:WCF.Language.get("wcf.message.share")}):this._dialog.wcfDialog("open")):this._dialog.html(this._cache[o]).wcfDialog("open"),this._enableSelection()},_enableSelection:function(){var e=this._dialog.find("input").click(function(){$(this).select()});navigator.userAgent.match(/iP(ad|hone|od)/)&&e.keydown(function(){return!1}).removeAttr("readonly").click(function(){this.setSelectionRange(0,9999)})}}),WCF.Message.Share.Page=Class.extend({init:function(){require(["WoltLabSuite/Core/Ui/Message/Share"],function(e){e.init()})}}),WCF.Message.UserMention=Class.extend({init:function(){throw new Error("Support for mentions in Redactor are now enabled by adding the attribute 'data-support-mention=\"true\"' to the textarea element.")}}),$.widget("wcf.messageTabMenu",{_tabs:[],_tabsByName:{},options:{collapsible:!0},_create:function(){var s=this.element.find("> nav").find("> ul > li:not(.jsFlexibleMenuDropdown)"),e=this.element.find("> div, > fieldset");if(s.length==e.length){var i=this.element.data("preselect");e.each(function(e,t){if(null!==elBySel(".innerError",t))return i=$(s[e]).data("name"),!1}),"true"===i&&(i=!0),this._tabs=[],this._tabsByName={};for(var t=0;t<s.length;t++){var n,a=$(s[t]),o=$(e[t]),r=a.data("name");void 0===r&&(void 0!==(n=a.children("a").prop("href"))&&n.match(/#([a-zA-Z_-]+)$/)&&(r=RegExp.$1),void 0===r&&(r=a.wcfIdentify())),this._tabs.push({container:o,name:r,tab:a}),this._tabsByName[r]=t;var l=a.children("a").data("index",t).on("mousedown",this._showTab.bind(this));l.attr("role","button").attr("tabindex","0").attr("aria-haspopup",!0).attr("aria-expanded",!1).attr("aria-controls",o[0].id),l.on("keydown",function(e){13!==e.which&&32!==e.which||(e.preventDefault(),this._showTab(e))}.bind(this)),(i===r||!0===i&&0===t)&&l.trigger("mousedown")}!0===i&&this._tabs.length&&!window.matchMedia("(max-width: 544px)").matches&&this._tabs[0].tab.children("a").trigger("click");var c=this.element.data("collapsible");void 0!==c&&(this.options.collapsible=c);var u=elData(this.element[0],"wysiwyg-container-id");u&&WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+u,function(){for(var e=0,t=this._tabs.length;e<t;e++)this._tabs[e].container.removeClass("active"),this._tabs[e].tab.removeClass("active")}.bind(this))}else console.debug("[wcf.messageTabMenu] Amount of tabs does not equal amount of tab containers, aborting.")},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this.element.remove()},_showTab:function(e,t,s){var i=null===e?t:$(e.currentTarget).data("index");s=!this.options.collapsible||!0===s;for(var n=null,a=0;a<this._tabs.length;a++){var o=this._tabs[a];if(a==i){if(!o.tab.hasClass("active")){o.tab.addClass("active"),o.container.addClass("active"),(n=o).tab.children("a").attr("aria-expanded",!0);var r,l=o.container[0];null!==elBySel(".messageTabMenuContent.active",l)||null===elBySel(".messageTabMenuContent",l)||null!==(r=elBySel("nav > ul > li[data-name] > a",l))&&$(r).trigger("mousedown");continue}if(!0===s)continue}o.tab.removeClass("active"),o.container.removeClass("active"),o.tab.children("a").attr("aria-expanded",!1)}null!==e&&(e.preventDefault(),e.stopPropagation()),null!==n&&this._trigger("show",{},{activeTab:n}),$(window).trigger("resize")},showTab:function(e,t){$.isNumeric(e)||void 0!==this._tabsByName[e]&&(e=this._tabsByName[e]),void 0!==this._tabs[e]?this._showTab(null,e,t):console.debug("[wcf.messageTabMenu] Cannot locate tab identified by '"+e+"'")},getTab:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].tab:null},getContainer:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].container:null}}); })(this);
 
 // WCF.Poll.js
-(function (window, undefined) { "use strict";WCF.Poll={},WCF.Poll.Management=Class.extend({_container:null,_count:0,_editorId:"",_maxOptions:0,init:function(t,e,i,n,o){if(this._count=0,this._maxOptions=i||-1,this._container=$("#"+t).children("ol:eq(0)"),this._fieldName=o||"pollOptions",!this._container.length)return void console.debug("[WCF.Poll.Management] Invalid container id given, aborting.");e=e||[],this._createOptionList(e),n?(this._editorId=n,WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+n,this._reset.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","submit_"+n,this._submit.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","validate_"+n,this._validate.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","handleError_"+n,this._handleError.bind(this))):this._container.closest("form").submit($.proxy(this._submit,this)),require(["WoltLabSuite/Core/Ui/Sortable/List"],function(e){new e({containerId:t,options:{toleranceElement:"> div"}})})},_createOptionList:function(t){for(var e=0,i=t.length;e<i;e++){var n=t[e];this._createOption(n.optionValue,n.optionID)}t.length<this._maxOptions&&this._createOption()},_createOption:function(t,e,i){t=t||"",e=parseInt(e)||0,i=i||null;var n=$('<li class="sortableNode" />').data("optionID",e);null===i?n.appendTo(this._container):n.insertAfter(i);var o=$('<div class="pollOptionInput" />').appendTo(n);$('<span class="icon icon16 fa-arrows sortableNodeHandle" />').appendTo(o),$('<a role="button" href="#" class="icon icon16 fa-plus jsTooltip jsAddOption pointer" title="'+WCF.Language.get("wcf.poll.button.addOption")+'" />').click($.proxy(this._addOption,this)).appendTo(o),$('<a role="button" href="#" class="icon icon16 fa-times jsTooltip jsDeleteOption pointer" title="'+WCF.Language.get("wcf.poll.button.removeOption")+'" />').click($.proxy(this._removeOption,this)).appendTo(o);var s=$('<input type="text" value="'+t+'" maxlength="255" />').keydown($.proxy(this._keyDown,this)).appendTo(o);s.click(function(){document.activeElement!==this&&this.focus()}),null!==i&&s.focus(),WCF.DOMNodeInsertedHandler.execute(),++this._count===this._maxOptions&&this._container.find("span.jsAddOption").removeClass("pointer").addClass("disabled")},_keyDown:function(t){13===t.which&&($(t.currentTarget).parent().children(".jsAddOption").trigger("click"),t.preventDefault())},_addOption:function(t){if(t.preventDefault(),this._count===this._maxOptions)return!1;var e=$(t.currentTarget).closest("li",this._container[0]);this._createOption(void 0,void 0,e)},_removeOption:function(t){t.preventDefault(),$(t.currentTarget).closest("li",this._container[0]).remove(),this._count--,this._container.find("span.jsAddOption").addClass("pointer").removeClass("disabled"),0==this._container.children("li").length&&this._createOption()},_submit:function(t){var e=[];if(this._container.children("li").each(function(t,i){var n=$(i),o=$.trim(n.find("input").val());""!=o&&e.push(n.data("optionID")+"_"+o)}),"object"==typeof t.originalEvent&&t.originalEvent instanceof Event){if(e.length)for(var i=this._container.parents("form").find(".formSubmit"),n=0,o=e.length;n<o;n++)$('<input type="hidden" name="'+this._fieldName+"["+n+']">').val(e[n]).appendTo(i)}else{t.poll={pollOptions:e};this._container.parents(".messageTabMenuContent:eq(0)").find("input").each(function(e,i){i.name&&("checkbox"!==i.type||i.checked)&&(t.poll[i.name]=i.value)})}},_reset:function(){for(var t=this._container[0];t.childElementCount>1;)t.removeChild(t.children[1]);elBySel("input",t.children[0]).value="",this._container.parents(".messageTabMenuContent:eq(0)").find("input").each(function(t,e){e.name&&("checkbox"===e.type?e.checked=!1:"text"===e.type?e.value="":"number"===e.type&&(e.value=e.min))}),require(["WoltLabSuite/Core/Date/Picker"],function(t){t.clear("pollEndTime_"+this._editorId)}.bind(this))},_validate:function(t){if(""!==elById("pollQuestion_"+this._editorId).value.trim()){var e=0;if(elBySelAll('li input[type="text"]',this._container[0],function(t){""!==t.value.trim()&&e++}),0===e)t.api.throwError(this._container[0],WCF.Language.get("wcf.global.form.error.empty")),t.valid=!1;else{var i=elById("pollMaxVotes_"+this._editorId),n=~~i.value;n&&n>e&&(t.api.throwError(i,WCF.Language.get("wcf.poll.maxVotes.error.invalid")),t.valid=!1)}}},_handleError:function(t){switch(t.returnValues.fieldName){case"pollEndTime":case"pollMaxVotes":var e="pollEndTime"===t.returnValues.fieldName?"endTime":"maxVotes",i=elCreate("small");i.className="innerError",i.innerHTML=WCF.Language.get("wcf.poll."+e+".error."+t.returnValues.errorType);var n=elById(t.returnValues.fieldName+"_"+this._editorId),o=n.parentElement;o.classList.contains("inputAddon")&&(n=o,o=o.parentElement),o.insertBefore(i,n.nextSibling),t.cancel=!0}}}),WCF.Poll.Manager=Class.extend({_cache:{},_canViewParticipants:{},_canViewResult:{},_canVote:{},_inputElements:{},_participants:{},_polls:{},_proxy:null,init:function(t){var e=$(t);if(!e.length)return void console.debug("[WCF.Poll.Manager] Given selector '"+t+"' does not match, aborting.");this._cache={},this._canViewParticipants={},this._canViewResult={},this._inputElements={},this._participants={},this._polls={},this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),url:"index.php?poll/&t="+SECURITY_TOKEN});var i=this;e.each(function(t,e){var n=$(e),o=n.data("pollID");void 0===i._polls[o]&&(i._cache[o]={result:"",vote:""},i._polls[o]=n,i._canViewParticipants[o]=!!n.data("canViewParticipants"),i._canViewResult[o]=!!n.data("canViewResult"),i._canVote[o]=!!n.data("canVote"),i._bindListeners(o),n.data("inVote")&&i._prepareVote(o),i._toggleButtons(o))})},_bindListeners:function(t){this._polls[t].find(".jsButtonPollShowParticipants").data("pollID",t).click($.proxy(this._showParticipants,this)),this._polls[t].find(".jsButtonPollShowResult").data("pollID",t).click($.proxy(this._showResult,this)),this._polls[t].find(".jsButtonPollShowVote").data("pollID",t).click($.proxy(this._showVote,this)),this._polls[t].find(".jsButtonPollVote").data("pollID",t).click($.proxy(this._vote,this))},_showResult:function(t,e){var i=null===t?e:$(t.currentTarget).data("pollID");this._canViewResult[i]&&this._polls[i].data("inVote")&&(this._cache[i].result?(this._polls[i].find(".pollInnerContainer").html(this._cache[i].result),this._polls[i].data("inVote",!1),this._toggleButtons(i)):(this._proxy.setOption("data",{actionName:"getResult",pollID:i}),this._proxy.sendRequest()))},_showParticipants:function(t){var e=$(t.currentTarget).data("pollID");this._participants[e]||(this._participants[e]=new WCF.User.List("wcf\\data\\poll\\PollAction",this._polls[e].data("question"),{pollID:e})),this._participants[e].open()},_showVote:function(t,e){var i=null===t?e:$(t.currentTarget).data("pollID");this._canVote[i]&&(this._polls[i].data("inVote")||(this._cache[i].vote?(this._polls[i].find(".pollInnerContainer").html(this._cache[i].vote),this._polls[i].data("inVote",!0),this._prepareVote(i),this._toggleButtons(i)):(this._proxy.setOption("data",{actionName:"getVote",pollID:i}),this._proxy.sendRequest())))},_success:function(t,e,i){if(t&&t.actionName){var n=t.pollID;switch(t.resultTemplate&&(this._cache[n].result=t.resultTemplate),t.voteTemplate&&(this._cache[n].vote=t.voteTemplate),t.actionName){case"getResult":this._showResult(null,n);break;case"getVote":this._showVote(null,n);break;case"vote":this._canViewResult[n]=!0,this._canVote[n]=!!t.canVote,this._polls[n].data("isPublic")&&(this._canViewParticipants[n]=!0),this._showResult(null,n)}}},_prepareVote:function(t){this._polls[t].find(".jsButtonPollVote").disable();var e=this._polls[t].find(".pollInnerContainer > .jsPollVote"),i=this;this._inputElements[t]=e.find("input").change(function(){i._handleVoteButton(t)}),this._handleVoteButton(t);var n=e.data("maxVotes");this._inputElements[t].filter("[type=checkbox]").length&&(this._inputElements[t].change(function(){i._enforceMaxVotes(t,n)}),this._enforceMaxVotes(t,n))},_enforceMaxVotes:function(t,e){var i=this._inputElements[t];i.filter(":checked").length==e?i.filter(":not(:checked)").disable():i.enable()},_handleVoteButton:function(t){var e=this._inputElements[t],i=this._polls[t].find(".jsButtonPollVote");e.filter(":checked").length?i.enable():i.disable()},_toggleButtons:function(t){var e=this._polls[t].children(".formSubmit");e.find(".jsButtonPollShowParticipants, .jsButtonPollShowResult, .jsButtonPollShowVote, .jsButtonPollVote").hide();var i=!0;this._polls[t].data("inVote")?(i=!1,e.find(".jsButtonPollVote").show(),this._canViewResult[t]&&e.find(".jsButtonPollShowResult").show()):(this._canVote[t]&&(i=!1,e.find(".jsButtonPollShowVote").show()),this._canViewParticipants[t]&&(i=!1,e.find(".jsButtonPollShowParticipants").show())),i&&e.hide()},_vote:function(t){var e=$(t.currentTarget).data("pollID");if(this._canVote[e]){var i=[];this._inputElements[e].each(function(t,e){var n=$(e);n.is(":checked")&&i.push(n.data("optionID"))}),i.length&&(this._proxy.setOption("data",{actionName:"vote",optionIDs:i,pollID:e}),this._proxy.sendRequest())}}}); })(this);
+(function (window, undefined) { "use strict";WCF.Poll={},WCF.Poll.Management=Class.extend({_container:null,_count:0,_editorId:"",_maxOptions:0,init:function(e,t,i,n,o){this._count=0,this._maxOptions=i||-1,this._container=$("#"+e).children("ol:eq(0)"),this._fieldName=o||"pollOptions",this._container.length?(t=t||[],this._createOptionList(t),n?(this._editorId=n,WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+n,this._reset.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","submit_"+n,this._submit.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","validate_"+n,this._validate.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","handleError_"+n,this._handleError.bind(this))):this._container.closest("form").submit($.proxy(this._submit,this)),require(["WoltLabSuite/Core/Ui/Sortable/List"],function(t){new t({containerId:e,options:{toleranceElement:"> div"}})})):console.debug("[WCF.Poll.Management] Invalid container id given, aborting.")},_createOptionList:function(t){for(var e=0,i=t.length;e<i;e++){var n=t[e];this._createOption(n.optionValue,n.optionID)}t.length<this._maxOptions&&this._createOption()},_createOption:function(t,e,i){t=t||"",e=parseInt(e)||0,i=i||null;var n=$('<li class="sortableNode" />').data("optionID",e);null===i?n.appendTo(this._container):n.insertAfter(i);var o=$('<div class="pollOptionInput" />').appendTo(n);$('<span class="icon icon16 fa-arrows sortableNodeHandle" />').appendTo(o),$('<a role="button" href="#" class="icon icon16 fa-plus jsTooltip jsAddOption pointer" title="'+WCF.Language.get("wcf.poll.button.addOption")+'" />').click($.proxy(this._addOption,this)).appendTo(o),$('<a role="button" href="#" class="icon icon16 fa-times jsTooltip jsDeleteOption pointer" title="'+WCF.Language.get("wcf.poll.button.removeOption")+'" />').click($.proxy(this._removeOption,this)).appendTo(o);var s=$('<input type="text" value="'+t+'" maxlength="255" />').keydown($.proxy(this._keyDown,this)).appendTo(o);s.click(function(){document.activeElement!==this&&this.focus()}),null!==i&&s.focus(),WCF.DOMNodeInsertedHandler.execute(),this._count++,this._count===this._maxOptions&&this._container.find("span.jsAddOption").removeClass("pointer").addClass("disabled")},_keyDown:function(t){13===t.which&&($(t.currentTarget).parent().children(".jsAddOption").trigger("click"),t.preventDefault())},_addOption:function(t){if(t.preventDefault(),this._count===this._maxOptions)return!1;var e=$(t.currentTarget).closest("li",this._container[0]);this._createOption(void 0,void 0,e)},_removeOption:function(t){t.preventDefault(),$(t.currentTarget).closest("li",this._container[0]).remove(),this._count--,this._container.find("span.jsAddOption").addClass("pointer").removeClass("disabled"),0==this._container.children("li").length&&this._createOption()},_submit:function(i){var o=[];if(this._container.children("li").each(function(t,e){var i=$(e),n=$.trim(i.find("input").val());""!=n&&o.push(i.data("optionID")+"_"+n)}),"object"==typeof i.originalEvent&&i.originalEvent instanceof Event){if(o.length)for(var t=this._container.parents("form").find(".formSubmit"),e=0,n=o.length;e<n;e++)$('<input type="hidden" name="'+this._fieldName+"["+e+']">').val(o[e]).appendTo(t)}else i.poll={pollOptions:o},this._container.parents(".messageTabMenuContent:eq(0)").find("input").each(function(t,e){e.name&&("checkbox"===e.type&&!e.checked||(i.poll[e.name]=e.value))})},_reset:function(){for(var t=this._container[0];1<t.childElementCount;)t.removeChild(t.children[1]);elBySel("input",t.children[0]).value="",this._container.parents(".messageTabMenuContent:eq(0)").find("input").each(function(t,e){e.name&&("checkbox"===e.type?e.checked=!1:"text"===e.type?e.value="":"number"===e.type&&(e.value=e.min))}),require(["WoltLabSuite/Core/Date/Picker"],function(t){t.clear("pollEndTime_"+this._editorId)}.bind(this))},_validate:function(t){var e,i,n;""!==elById("pollQuestion_"+this._editorId).value.trim()&&(e=0,elBySelAll('li input[type="text"]',this._container[0],function(t){""!==t.value.trim()&&e++}),0===e?(t.api.throwError(this._container[0],WCF.Language.get("wcf.global.form.error.empty")),t.valid=!1):(n=~~(i=elById("pollMaxVotes_"+this._editorId)).value)&&e<n&&(t.api.throwError(i,WCF.Language.get("wcf.poll.maxVotes.error.invalid")),t.valid=!1))},_handleError:function(t){switch(t.returnValues.fieldName){case"pollEndTime":case"pollMaxVotes":var e="pollEndTime"===t.returnValues.fieldName?"endTime":"maxVotes",i=elCreate("small");i.className="innerError",i.innerHTML=WCF.Language.get("wcf.poll."+e+".error."+t.returnValues.errorType);var n=elById(t.returnValues.fieldName+"_"+this._editorId),o=n.parentElement;o.classList.contains("inputAddon")&&(o=(n=o).parentElement),o.insertBefore(i,n.nextSibling),t.cancel=!0}}}),WCF.Poll.Manager=Class.extend({_cache:{},_canViewParticipants:{},_canViewResult:{},_canVote:{},_inputElements:{},_participants:{},_polls:{},_proxy:null,init:function(t){var o,e=$(t);e.length?(this._cache={},this._canViewParticipants={},this._canViewResult={},this._inputElements={},this._participants={},this._polls={},this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),url:"index.php?poll/&t="+SECURITY_TOKEN}),o=this,e.each(function(t,e){var i=$(e),n=i.data("pollID");void 0===o._polls[n]&&(o._cache[n]={result:"",vote:""},o._polls[n]=i,o._canViewParticipants[n]=!!i.data("canViewParticipants"),o._canViewResult[n]=!!i.data("canViewResult"),o._canVote[n]=!!i.data("canVote"),o._bindListeners(n),i.data("inVote")&&o._prepareVote(n),o._toggleButtons(n))})):console.debug("[WCF.Poll.Manager] Given selector '"+t+"' does not match, aborting.")},_bindListeners:function(t){this._polls[t].find(".jsButtonPollShowParticipants").data("pollID",t).click($.proxy(this._showParticipants,this)),this._polls[t].find(".jsButtonPollShowResult").data("pollID",t).click($.proxy(this._showResult,this)),this._polls[t].find(".jsButtonPollShowVote").data("pollID",t).click($.proxy(this._showVote,this)),this._polls[t].find(".jsButtonPollVote").data("pollID",t).click($.proxy(this._vote,this))},_showResult:function(t,e){var i=null===t?e:$(t.currentTarget).data("pollID");this._canViewResult[i]&&this._polls[i].data("inVote")&&(this._cache[i].result?(this._polls[i].find(".pollInnerContainer").html(this._cache[i].result),this._polls[i].data("inVote",!1),this._toggleButtons(i)):(this._proxy.setOption("data",{actionName:"getResult",pollID:i}),this._proxy.sendRequest()))},_showParticipants:function(t){var e=$(t.currentTarget).data("pollID");this._participants[e]||(this._participants[e]=new WCF.User.List("wcf\\data\\poll\\PollAction",this._polls[e].data("question"),{pollID:e})),this._participants[e].open()},_showVote:function(t,e){var i=null===t?e:$(t.currentTarget).data("pollID");this._canVote[i]&&(this._polls[i].data("inVote")||(this._cache[i].vote?(this._polls[i].find(".pollInnerContainer").html(this._cache[i].vote),this._polls[i].data("inVote",!0),this._prepareVote(i),this._toggleButtons(i)):(this._proxy.setOption("data",{actionName:"getVote",pollID:i}),this._proxy.sendRequest())))},_success:function(t,e,i){if(t&&t.actionName){var n=t.pollID;switch(t.resultTemplate&&(this._cache[n].result=t.resultTemplate),t.voteTemplate&&(this._cache[n].vote=t.voteTemplate),t.actionName){case"getResult":this._showResult(null,n);break;case"getVote":this._showVote(null,n);break;case"vote":this._canViewResult[n]=!0,this._canVote[n]=!!t.canVote,this._polls[n].data("isPublic")&&(this._canViewParticipants[n]=!0);var o=elBySel(".jsPollTotalVotes",this._polls[n][0]);o.textContent=WCF.String.formatNumeric(t.totalVotes),elData(o,"tooltip",t.totalVotesTooltip),this._showResult(null,n)}}},_prepareVote:function(t){this._polls[t].find(".jsButtonPollVote").disable();var e=this._polls[t].find(".pollInnerContainer > .jsPollVote"),i=this;this._inputElements[t]=e.find("input").change(function(){i._handleVoteButton(t)}),this._handleVoteButton(t);var n=e.data("maxVotes");this._inputElements[t].filter("[type=checkbox]").length&&(this._inputElements[t].change(function(){i._enforceMaxVotes(t,n)}),this._enforceMaxVotes(t,n))},_enforceMaxVotes:function(t,e){var i=this._inputElements[t];i.filter(":checked").length==e?i.filter(":not(:checked)").disable():i.enable()},_handleVoteButton:function(t){var e=this._inputElements[t],i=this._polls[t].find(".jsButtonPollVote");e.filter(":checked").length?i.enable():i.disable()},_toggleButtons:function(t){var e=this._polls[t].children(".formSubmit");e.find(".jsButtonPollShowParticipants, .jsButtonPollShowResult, .jsButtonPollShowVote, .jsButtonPollVote").hide();var i=!0;this._polls[t].data("inVote")?(i=!1,e.find(".jsButtonPollVote").show(),this._canViewResult[t]&&e.find(".jsButtonPollShowResult").show()):(this._canVote[t]&&(i=!1,e.find(".jsButtonPollShowVote").show()),this._canViewParticipants[t]&&(i=!1,e.find(".jsButtonPollShowParticipants").show())),i&&e.hide()},_vote:function(t){var n,e=$(t.currentTarget).data("pollID");this._canVote[e]&&(n=[],this._inputElements[e].each(function(t,e){var i=$(e);i.is(":checked")&&n.push(i.data("optionID"))}),n.length&&(this._proxy.setOption("data",{actionName:"vote",optionIDs:n,pollID:e}),this._proxy.sendRequest()))}}); })(this);
 
 // WCF.Search.Message.js
-(function (window, undefined) { "use strict";WCF.Search.Message={},WCF.Search.Message.KeywordList=WCF.Search.Base.extend({_className:"wcf\\data\\search\\keyword\\SearchKeywordAction",_divider:null,_forceSubmit:!1,init:function(e,i,s){if(!$.isFunction(i))return void console.debug("[WCF.Search.Message.KeywordList] The given callback is invalid, aborting.");this._callback=i,this._excludedSearchValues=[],s&&(this._excludedSearchValues=s),this._searchInput=$(e).keyup($.proxy(this._keyUp,this)).keydown($.proxy(function(e){13===e.which&&this._itemCount&&-1!==this._itemIndex&&e.preventDefault()},this));var t=WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify()),r=t.find("li.dropdownDivider").last();this._divider=$('<li class="dropdownDivider" />').hide().insertBefore(r),this._list=$('<li class="dropdownList"><ul /></li>').hide().insertBefore(r).children("ul"),t.find("input, label").on("click",function(e){e.stopPropagation()}),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)})},_createListItem:function(e){this._divider.show(),this._list.parent().show(),this._super(e)},_clearList:function(e){e&&this._searchInput.val(""),this._divider.hide(),this._list.empty().parent().hide(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1}}); })(this);
+(function (window, undefined) { "use strict";WCF.Search.Message={},WCF.Search.Message.KeywordList=WCF.Search.Base.extend({_className:"wcf\\data\\search\\keyword\\SearchKeywordAction",_divider:null,_forceSubmit:!1,init:function(e,i,s){var t,r;$.isFunction(i)?(this._callback=i,this._excludedSearchValues=[],s&&(this._excludedSearchValues=s),this._searchInput=$(e).keyup($.proxy(this._keyUp,this)).keydown($.proxy(function(e){13===e.which&&this._itemCount&&-1!==this._itemIndex&&e.preventDefault()},this)),r=(t=WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify())).find("li.dropdownDivider").last(),this._divider=$('<li class="dropdownDivider" />').hide().insertBefore(r),this._list=$('<li class="dropdownList"><ul /></li>').hide().insertBefore(r).children("ul"),t.find("input, label").on("click",function(e){e.stopPropagation()}),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)})):console.debug("[WCF.Search.Message.KeywordList] The given callback is invalid, aborting.")},_createListItem:function(e){this._divider.show(),this._list.parent().show(),this._super(e)},_clearList:function(e){e&&this._searchInput.val(""),this._divider.hide(),this._list.empty().parent().hide(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1}}); })(this);
 
 // WCF.User.js
-(function (window, undefined) { "use strict";WCF.User.Login=Class.extend({_loginSubmitButton:null,_password:null,_passwordContainer:null,_useCookies:null,_useCookiesContainer:null,init:function(t){this._loginSubmitButton=$("#loginSubmitButton"),this._password=$("#password"),this._passwordContainer=this._password.parents("dl"),this._useCookies=$("#useCookies"),this._useCookiesContainer=this._useCookies.parents("dl"),$("#loginForm").find("input[name=action]").change($.proxy(this._change,this)),t&&WCF.User.QuickLogin.init()},_change:function(t){"register"===$(t.currentTarget).val()?this._setState(!1,WCF.Language.get("wcf.user.button.register")):this._setState(!0,WCF.Language.get("wcf.user.button.login"))},_setState:function(t,e){t?(this._password.enable(),this._passwordContainer.removeClass("disabled"),this._useCookies.enable(),this._useCookiesContainer.removeClass("disabled")):(this._password.disable(),this._passwordContainer.addClass("disabled"),this._useCookies.disable(),this._useCookiesContainer.addClass("disabled")),this._loginSubmitButton.val(e)}}),WCF.User.Panel={},WCF.User.Panel.Abstract=Class.extend({_badge:null,_dropdown:null,_identifier:"",_loadData:!0,_markAllAsReadLink:null,_options:{},_proxy:null,_triggerElement:null,_button:null,_callbackFocus:null,_wasInsideDropdown:!1,init:function(t,e,i){if(this._dropdown=null,this._loadData=!0,this._identifier=e,this._triggerElement=t,this._options=i,this._callbackFocus=null,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._triggerElement.click($.proxy(this.toggle,this)),this._button=elBySel("a",this._triggerElement[0]),this._button&&(elAttr(this._button,"role","button"),elAttr(this._button,"tabindex","0"),elAttr(this._button,"aria-haspopup",!0),elAttr(this._button,"aria-expanded",!1)),this._options.showAllLink&&this._triggerElement.dblclick($.proxy(this._dblClick,this)),!0===this._options.staticDropdown)this._loadData=!1;else{var s=this._triggerElement.find("span.badge");s.length&&(this._badge=s)}},toggle:function(t){if(t instanceof Event&&t.preventDefault(),null===this._dropdown&&(this._dropdown=this._initDropdown()),this._dropdown.toggle()){if(!this._loadData&&null!==this._badge){(parseInt(this._badge.text())||0)&&!this._dropdown.getItemList().children(".interactiveDropdownItemOutstanding").length&&(this._loadData=!0)}this._loadData&&(this._loadData=!1,this._load()),elAttr(this._button,"aria-expanded",!0),null===this._callbackFocus&&(this._callbackFocus=this._maintainFocus.bind(this)),document.body.addEventListener("focus",this._callbackFocus,{capture:!0})}else elAttr(this._button,"aria-expanded",!1),document.body.removeEventListener("focus",this._callbackFocus);return!1},_dblClick:function(t){return t.preventDefault(),window.location=this._options.showAllLink,!1},_initDropdown:function(){var t=WCF.Dropdown.Interactive.Handler.create(this._triggerElement,this._identifier,this._options);return $('<li class="loading"><span class="icon icon24 fa-spinner" /> <span>'+WCF.Language.get("wcf.global.loading")+"</span></li>").appendTo(t.getItemList()),t},_load:function(){},_success:function(t){if(void 0!==t.returnValues.template){var e=this._dropdown.getItemList().empty();if($(t.returnValues.template).appendTo(e),e.children().length||$('<li class="noItems">'+this._options.noItems+"</li>").appendTo(e),this._options.enableMarkAsRead){var i=this._dropdown.getItemList().children(".interactiveDropdownItemOutstanding");if(null===this._markAllAsReadLink&&i.length){(this._markAllAsReadLink=$('<li class="interactiveDropdownItemMarkAllAsRead"><a href="#" title="'+WCF.Language.get("wcf.user.panel.markAllAsRead")+'" class="jsTooltip"><span class="icon icon24 fa-check" /></a></li>').appendTo(this._dropdown.getLinkList())).click(function(t){return this._dropdown.close(),this._markAllAsRead(),!1}.bind(this))}i.each(function(t,e){var i=$(e).addClass("interactiveDropdownItemOutstandingIcon"),s=i.data("objectID");$('<div class="interactiveDropdownItemMarkAsRead"><a href="#" title="'+WCF.Language.get("wcf.user.panel.markAsRead")+'" class="jsTooltip"><span class="icon icon16 fa-check" /></a></div>').appendTo(i).click(function(t){return this._markAsRead(t,s),!1}.bind(this))}.bind(this))}this._dropdown.getItemList().children().each(function(t,e){var i=$(e),s=i.data("link");s&&($.browser.msie?i.click(function(t){if("A"!==t.target.tagName)return window.location=s,!1}):(i.addClass("interactiveDropdownItemShadow"),$('<a href="'+s+'" class="interactiveDropdownItemShadowLink" />').appendTo(i)),i.data("linkReplaceAll")&&i.find("> .box48 a:not(.userLink)").prop("href",s))}),this._dropdown.rebuildScrollbar()}if(void 0!==t.returnValues.totalCount&&this.updateBadge(t.returnValues.totalCount),this._options.enableMarkAsRead)if(t.returnValues.markAsRead){var s=this._dropdown.getItemList().children("li[data-object-id="+t.returnValues.markAsRead+"]");s.length&&(s.removeClass("interactiveDropdownItemOutstanding").data("isRead",!0),s.children(".interactiveDropdownItemMarkAsRead").remove())}else t.returnValues.markAllAsRead&&(this.resetItems(),this.updateBadge(0))},_markAsRead:function(t,e){},_markAllAsRead:function(){},updateBadge:function(t){t=parseInt(t)||0,t?(null===this._badge&&(this._badge=$('<span class="badge badgeUpdate" />').appendTo(this._triggerElement.children("a")),this._badge.before(" ")),this._badge.text(t)):null!==this._badge&&(this._badge.remove(),this._badge=null),this._options.enableMarkAsRead&&(t||null===this._markAllAsReadLink||(this._markAllAsReadLink.remove(),this._markAllAsReadLink=null)),WCF.System.Event.fireEvent("com.woltlab.wcf.userMenu","updateBadge",{count:t,identifier:this._identifier})},resetItems:function(){null!==this._dropdown&&(this._dropdown.resetItems(),this._loadData=!0)},_maintainFocus:function(t){if(!document.activeElement||document.activeElement.classList.contains("focus-visible")){var e=this._dropdown.getContainer()[0];e.contains(t.target)?this._wasInsideDropdown=!0:this._wasInsideDropdown?(this._button.focus(),this._wasInsideDropdown=!1):elBySel("a",e).focus()}}}),WCF.User.Panel.Notification=WCF.User.Panel.Abstract.extend({_favico:null,init:function(t){t.enableMarkAsRead=!0,this._super($("#userNotifications"),"userNotifications",t);try{if(this._favico=new Favico({animation:"none",type:"circle"}),null!==this._badge){var e=parseInt(this._badge.text())||0;this._favico.badge(e)}}catch(t){console.debug("[WCF.User.Panel.Notification] Failed to initialized Favico: "+t.message)}WCF.System.PushNotification.addCallback("userNotificationCount",$.proxy(this.updateUserNotificationCount,this)),require(["EventHandler"],function(t){t.add("com.woltlab.wcf.UserMenuMobile","more",function(t){"com.woltlab.wcf.notifications"===t.identifier&&this.toggle()}.bind(this))}.bind(this))},_initDropdown:function(){var t=this._super();return $('<li><a href="'+this._options.settingsLink+'" title="'+WCF.Language.get("wcf.user.panel.settings")+'" class="jsTooltip"><span class="icon icon24 fa-cog" /></a></li>').appendTo(t.getLinkList()),t},_load:function(){this._proxy.setOption("data",{actionName:"getOutstandingNotifications",className:"wcf\\data\\user\\notification\\UserNotificationAction"}),this._proxy.sendRequest()},_markAsRead:function(t,e){this._proxy.setOption("data",{actionName:"markAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction",objectIDs:[e]}),this._proxy.sendRequest()},_markAllAsRead:function(t){this._proxy.setOption("data",{actionName:"markAllAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction"}),this._proxy.sendRequest()},resetItems:function(){this._super(),this._markAllAsReadLink&&(this._markAllAsReadLink.remove(),this._markAllAsReadLink=null)},updateBadge:function(t){t=parseInt(t)||0,$("#userNotifications").attr("data-count",t),null!==this._favico&&this._favico.badge(t),this._super(t)},updateUserNotificationCount:function(t){null!==this._dropdown&&this._dropdown.resetItems(),this.updateBadge(t)}}),WCF.User.Panel.UserMenu=WCF.User.Panel.Abstract.extend({init:function(){this._super($("#userMenu"),"userMenu",{pointerOffset:"13px",staticDropdown:!0})}}),WCF.User.QuickLogin={init:function(){require(["EventHandler","Ui/Dialog"],function(t,e){var i=elById("loginForm"),s=elBySel(".loginFormLogin",i);s&&!s.nextElementSibling&&i.classList.add("loginFormLoginOnly");for(var a=elBySel(".loginFormRegister",i),n=function(t){if(t instanceof Event&&(t.preventDefault(),t.stopPropagation()),i.style.removeProperty("display"),e.openStatic("loginForm",null,{title:WCF.Language.get("wcf.user.login")}),null!==s&&null!==a){var n=s.offsetTop,o=0;if(i.clientWidth>2*s.clientWidth)for(;n<a.offsetTop-50;)o+=100,s.style.setProperty("margin-bottom",o+"px","")}},o=document.getElementsByClassName("loginLink"),r=0,l=o.length;r<l;r++)o[r].addEventListener(WCF_CLICK_EVENT,n);var c=i.querySelector("#loginForm input[name=url]");null===c||c.value.match(/^https?:\/\//)||c.setAttribute("value",window.location.protocol+"//"+window.location.host+c.getAttribute("value")),t.add("com.woltlab.wcf.UserMenuMobile","more",function(t){"com.woltlab.wcf.login"===t.identifier&&(t.handler.close(!0),n())})})}},WCF.User.Profile={},WCF.User.Profile.ActivityPointList={_cache:{},_dialog:null,_didInit:!1,_proxy:null,init:function(){this._didInit||(this._cache={},this._dialog=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.User.Profile.ActivityPointList",$.proxy(this._init,this)),this._didInit=!0)},_init:function(){$(".activityPointsDisplay").removeClass("activityPointsDisplay").click($.proxy(this._click,this))},_click:function(t){t.preventDefault();var e=$(t.currentTarget).data("userID");void 0===this._cache[e]?(this._proxy.setOption("data",{actionName:"getDetailedActivityPointList",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[e]}),this._proxy.sendRequest()):this._show(e)},_show:function(t){null===this._dialog?(this._dialog=$("<div>"+this._cache[t]+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.user.activityPoint")})):(this._dialog.html(this._cache[t]),this._dialog.wcfDialog("open"))},_success:function(t,e,i){this._cache[t.returnValues.userID]=t.returnValues.template,this._show(t.returnValues.userID)}},WCF.User.Profile.TabMenu=Class.extend({_hasContent:{},_profileContent:null,_proxy:null,_userID:0,init:function(t){this._profileContent=$("#profileContent"),this._userID=t;var e=this._profileContent.data("active"),i=!1;this._profileContent.find("div.tabMenuContent").each($.proxy(function(t,s){var a=$(s).wcfIdentify();e===a?this._hasContent[a]=!0:(this._hasContent[a]=!1,i=!0)},this)),i&&(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._profileContent.on("wcftabsbeforeactivate",$.proxy(this._loadContent,this)),this._profileContent.find("> nav.tabMenu > ul > li").each($.proxy(function(t,e){var i=$(e);if(i.hasClass("ui-state-active"))return t&&this._loadContent(null,{newPanel:$("#"+i.attr("aria-controls"))}),!1},this))),$('.userProfileUser .contentDescription a[href$="#likes"]').click(function(t){t.preventDefault(),require(["Ui/TabMenu"],function(t){t.getTabMenu("profileContent").select("likes")})}.bind(this))},_loadContent:function(t,e){var i=$(e.newPanel),s=i.attr("id");this._hasContent[s]||(this._proxy.setOption("data",{actionName:"getContent",className:"wcf\\data\\user\\profile\\menu\\item\\UserProfileMenuItemAction",parameters:{data:{containerID:s,menuItem:i.data("menuItem"),userID:this._userID}}}),this._proxy.sendRequest())},_success:function(t,e,i){var s=t.returnValues.containerID;this._hasContent[s]=!0,require(["Dom/ChangeListener","Dom/Util"],function(e,i){i.insertHtml(t.returnValues.template,elById(s),"append"),e.trigger()})}}),WCF.User.Profile.Editor=Class.extend({_actionName:"",_active:!1,_buttons:{},_cachedTemplate:"",_proxy:null,_tab:null,_userID:0,init:function(t,e){this._actionName="",this._active=!1,this._cachedTemplate="",this._tab=$("#about"),this._userID=t,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initButtons(),e&&this._beginEdit()},_initButtons:function(){this._buttons={beginEdit:$(".jsButtonEditProfile:eq(0)").click(this._beginEdit.bind(this))}},_beginEdit:function(t){t&&t.preventDefault(),this._active||(this._active=!0,this._actionName="beginEdit",this._buttons.beginEdit.parent().addClass("active"),$("#profileContent").wcfTabs("select","about"),this._proxy.setOption("data",{actionName:"beginEdit",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[this._userID]}),this._proxy.sendRequest())},_save:function(){var t=null;if(elBySelAll(".redactor-layer",this._tab[0],function(e){var i={api:{throwError:elInnerError},valid:!0};WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","validate_"+elData(e,"element-id"),i),i.valid||null!==t||(t=e.parentNode)}),t)return void t.scrollIntoView({behavior:"smooth"});this._actionName="save";var e=/values\[([a-zA-Z0-9._-]+)\]/,i={};this._tab.find("input, textarea, select").each(function(t,s){var a=$(s),n=null;switch(a.getTagName()){case"input":var o=a.attr("type");if(("radio"===o||"checkbox"===o)&&!a.prop("checked"))return;break;case"textarea":a.data("redactor")&&(n=a.redactor("code.get"))}var r=a.attr("name");if(e.test(r)){var l=RegExp.$1;null===n&&(n=a.val()),"checkbox"===a.attr("type")&&/\[\]$/.test(r)?(Array.isArray(i[l])||(i[l]=[]),i[l].push(n)):i[l]=n}}),this._proxy.setOption("data",{actionName:"save",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[this._userID],parameters:{values:i}}),this._proxy.sendRequest()},_restore:function(){this._actionName="restore",this._active=!1,this._buttons.beginEdit.parent().removeClass("active"),this._destroyEditor(),this._tab.html(this._cachedTemplate).children().css({height:"auto"})},_success:function(t,e,i){switch(this._actionName){case"beginEdit":this._prepareEdit(t);break;case"save":t.returnValues.success?(this._cachedTemplate=t.returnValues.template,this._restore()):this._prepareEdit(t,!0)}},_prepareEdit:function(t,e){this._destroyEditor();var i=this;this._tab.html(function(s,a){return!0!==e&&(i._cachedTemplate=a),t.returnValues.template}),this._tab.find("input[type=text]").attr("autocomplete","off"),this._tab.find(".formSubmit > button[data-type=save]").click($.proxy(this._save,this)),this._tab.find(".formSubmit > button[data-type=restore]").click($.proxy(this._restore,this)),this._tab.find("input").keyup(function(t){if(t.which===$.ui.keyCode.ENTER)return i._save(),t.preventDefault(),!1})},_destroyEditor:function(){this._tab.find("textarea").each(function(t,e){var i=$(e);i.data("redactor")&&i.redactor("core.destroy")})}}),WCF.User.Registration={},WCF.User.Registration.Validation=Class.extend({_actionName:"",_className:"",_confirmElement:null,_element:null,_errorMessages:{},_options:{},_proxy:null,init:function(t,e,i){this._element=t,this._element.blur($.proxy(this._blur,this)),this._confirmElement=e||null,null!==this._confirmElement&&this._confirmElement.blur($.proxy(this._blurConfirm,this)),i=i||{},this._setOptions(i),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),showLoadingOverlay:!1}),this._setErrorMessages()},_setOptions:function(t){},_setErrorMessages:function(){this._errorMessages={ajaxError:"",notEqual:""}},_blur:function(t){var e=this._element.val();if(!e)return this._showError(this._element,WCF.Language.get("wcf.global.form.error.empty"));if(null!==this._confirmElement){var i=this._confirmElement.val();if(""!=i&&e!=i)return this._showError(this._confirmElement,this._errorMessages.notEqual)}this._validateOptions()&&(this._proxy.setOption("data",{actionName:this._actionName,className:this._className,parameters:this._getParameters()}),this._proxy.sendRequest())},_getParameters:function(){return{}},_validateOptions:function(){return!0},_blurConfirm:function(t){if(!this._confirmElement.val())return this._showError(this._confirmElement,WCF.Language.get("wcf.global.form.error.empty"));this._blur(t)},_success:function(t,e,i){t.returnValues.isValid?(this._showSuccess(this._element),null!==this._confirmElement&&this._confirmElement.val()&&this._showSuccess(this._confirmElement)):this._showError(this._element,WCF.Language.get(this._errorMessages.ajaxError+t.returnValues.error))},_showError:function(t,e){t.parent().parent().addClass("formError").removeClass("formSuccess");var i=t.parent().find("small.innerError");i.length||(i=$("<small />").addClass("innerError").insertAfter(t)),i.text(e)},_showSuccess:function(t){t.parent().parent().addClass("formSuccess").removeClass("formError"),t.next("small.innerError").remove()}}),WCF.User.Registration.Validation.Username=WCF.User.Registration.Validation.extend({_actionName:"validateUsername",_className:"wcf\\data\\user\\UserRegistrationAction",_setOptions:function(t){this._options=$.extend(!0,{minlength:3,maxlength:25},t)},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.username.error."}},_validateOptions:function(){var t=this._element.val();return!(t.length<this._options.minlength||t.length>this._options.maxlength)||(this._showError(this._element,WCF.Language.get("wcf.user.username.error.invalid")),!1)},_getParameters:function(){return{username:this._element.val()}}}),WCF.User.Registration.Validation.EmailAddress=WCF.User.Registration.Validation.extend({_actionName:"validateEmailAddress",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{email:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.email.error.",notEqual:WCF.Language.get("wcf.user.confirmEmail.error.notEqual")}}}),WCF.User.Registration.Validation.Password=WCF.User.Registration.Validation.extend({_actionName:"validatePassword",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{password:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.password.error.",notEqual:WCF.Language.get("wcf.user.confirmPassword.error.notEqual")}}}),WCF.User.Registration.LostPassword=Class.extend({_email:null,_username:null,init:function(){this._email=$("#emailInput"),this._username=$("#usernameInput"),this._email.keyup($.proxy(this._checkEmail,this)),this._username.keyup($.proxy(this._checkUsername,this)),$.browser.mozilla&&$.browser.touch&&(this._email.on("input",$.proxy(this._checkEmail,this)),this._username.on("input",$.proxy(this._checkUsername,this))),this._checkEmail(),this._checkUsername()},_checkEmail:function(){""==this._email.val()?(this._username.enable(),this._username.parents("dl:eq(0)").removeClass("disabled")):(this._username.disable(),this._username.parents("dl:eq(0)").addClass("disabled"),this._username.val(""))},_checkUsername:function(){""==this._username.val()?(this._email.enable(),this._email.parents("dl:eq(0)").removeClass("disabled")):(this._email.disable(),this._email.parents("dl:eq(0)").addClass("disabled"),this._email.val(""))}}),WCF.Notification={},WCF.Notification.List=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".contentHeaderNavigation .jsMarkAllAsConfirmed").click(function(){WCF.System.Confirmation.show(WCF.Language.get("wcf.user.notification.markAllAsConfirmed.confirmMessage"),function(t){"confirm"===t&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"markAllAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction"},success:function(){window.location.reload()}})})}),this._convertList()},_convertList:function(){$(".userNotificationItemList > .notificationItem").each(function(t,e){var i=$(e);if(!i.data("isRead")){i.find("a:not(.userLink)").prop("href",i.data("link"));$('<a href="#" class="icon icon24 fa-check notificationItemMarkAsConfirmed jsTooltip" title="'+WCF.Language.get("wcf.user.notification.markAsConfirmed")+'" />').appendTo(i).click($.proxy(this._markAsConfirmed,this))}i.find("a:not(.notificationItemMarkAsConfirmed)").length||i.find(".details > p:eq(0)").html(function(t,e){return'<a href="'+i.data("link")+'">'+e+"</a>"})}.bind(this)),WCF.DOMNodeInsertedHandler.execute()},_markAsConfirmed:function(t){t.preventDefault();var e=$(t.currentTarget).parents(".notificationItem:eq(0)").data("objectID");return this._proxy.setOption("data",{actionName:"markAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction",objectIDs:[e]}),this._proxy.sendRequest(),!1},_success:function(t,e,i){var s=$(".userNotificationItemList > .notificationItem[data-object-id="+t.returnValues.markAsRead+"]");s.data("isRead",!0),s.find(".newContentBadge").remove(),s.find(".notificationItemMarkAsConfirmed").remove(),s.removeClass("notificationUnconfirmed")}}),WCF.User.SignaturePreview=WCF.Message.Preview.extend({_handleResponse:function(t){var e=$("#previewContainer");e.length||(e=$('<section class="section" id="previewContainer"><h2 class="sectionTitle">'+WCF.Language.get("wcf.global.preview")+'</h2><div class="htmlContent messageSignatureConstraints"></div></section>').insertBefore($("#signatureContainer")).wcfFadeIn()),e.children("div").first().html(t.returnValues.message)}}),WCF.User.RecentActivityLoader=Class.extend({_container:null,_filteredByFollowedUsers:!1,_loadButton:null,_proxy:null,_userID:0,init:function(t,e){if(this._container=$("#recentActivities"),this._filteredByFollowedUsers=!0===e,this._userID=t,null!==this._userID&&!this._userID)return void console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.");this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._container.children("li").length?(this._loadButton=$('<li class="showMore"><button class="small">'+WCF.Language.get("wcf.user.recentActivity.more")+"</button></li>").appendTo(this._container),this._loadButton=this._loadButton.children("button").click($.proxy(this._click,this))):$('<li class="showMore"><small>'+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small></li>").appendTo(this._container),WCF.User.userID&&$(".jsRecentActivitySwitchContext .button").click($.proxy(this._switchContext,this))},_click:function(){this._loadButton.enable();var t={lastEventID:this._container.data("lastEventID"),lastEventTime:this._container.data("lastEventTime")};this._userID?t.userID=this._userID:this._filteredByFollowedUsers&&(t.filteredByFollowedUsers=1),this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction",parameters:t}),this._proxy.sendRequest()},_switchContext:function(t){t.preventDefault(),$(t.currentTarget).hasClass("active")||new WCF.Action.Proxy({autoSend:!0,data:{actionName:"switchContext",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"},success:function(){window.location.hash="#dashboardBoxRecentActivity",window.location.reload()}})},_success:function(t,e,i){t.returnValues.template?($(t.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastEventTime",t.returnValues.lastEventTime),this._container.data("lastEventID",t.returnValues.lastEventID),this._loadButton.enable()):($("<small>"+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small>").appendTo(this._loadButton.parent()),this._loadButton.remove())}}),WCF.User.LikeLoader=Class.extend({_container:null,_likeType:"received",_likeValue:1,_loadButton:null,_noMoreEntries:null,_proxy:null,_userID:0,init:function(t){if(this._container=$("#likeList"),this._userID=t,!this._userID)return void console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.");this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)});var e=$('<li class="likeListMore showMore"><button class="small">'+WCF.Language.get("wcf.like.likes.more")+"</button><small>"+WCF.Language.get("wcf.like.likes.noMoreEntries")+"</small></li>").appendTo(this._container);this._loadButton=e.children("button").click($.proxy(this._click,this)),this._noMoreEntries=e.children("small").hide(),2==this._container.find("> li").length&&(this._loadButton.hide(),this._noMoreEntries.show()),$("#likeType .button").click($.proxy(this._clickLikeType,this)),$("#likeValue .button").click($.proxy(this._clickLikeValue,this))},_clickLikeType:function(t){var e=$(t.currentTarget);this._likeType!=e.data("likeType")&&(this._likeType=e.data("likeType"),$("#likeType .button").removeClass("active"),e.addClass("active"),this._reload())},_clickLikeValue:function(t){var e=$(t.currentTarget);this._likeValue!=e.data("likeValue")&&(this._likeValue=e.data("likeValue"),$("#likeValue .button").removeClass("active"),e.addClass("active"),$("#likeType > li:first-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesReceived")),$("#likeType > li:last-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesGiven")),this._container.find("> li.likeListMore button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.more")),this._container.find("> li.likeListMore small").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.noMoreEntries")),this._reload())},_reload:function(){this._container.find("> li:not(:first-child):not(:last-child)").remove(),this._container.data("lastLikeTime",0),this._click()},_click:function(){this._loadButton.enable();var t={lastLikeTime:this._container.data("lastLikeTime"),userID:this._userID,likeType:this._likeType,likeValue:this._likeValue};this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\like\\LikeAction",parameters:t}),this._proxy.sendRequest()},_success:function(t,e,i){t.returnValues.template?($(t.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastLikeTime",t.returnValues.lastLikeTime),this._noMoreEntries.hide(),this._loadButton.show().enable()):(this._noMoreEntries.show(),this._loadButton.hide())}}),WCF.User.ProfilePreview=WCF.Popover.extend({_proxy:null,_userProfiles:{},init:function(){this._super(".userLink"),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1}),WCF.System.ObjectStore.add("WCF.User.ProfilePreview",this)},_loadContent:function(){var t=$("#"+this._activeElementID),e=t.data("userID");if(this._userProfiles[e])this._insertContent(this._activeElementID,this._userProfiles[e],!0);else{this._proxy.setOption("data",{actionName:"getUserProfile",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[e]});var i=this._activeElementID,s=this;this._proxy.setOption("success",function(t,a,n){s._userProfiles[e]=t.returnValues.template,s._insertContent(i,t.returnValues.template,!0)}),this._proxy.setOption("failure",function(t,a,n,o){return s._userProfiles[e]=t.message,s._insertContent(i,t.message,!0),!1}),this._proxy.sendRequest()}},purge:function(t){delete this._userProfiles[t],this._data={}}}),WCF.User.Action={},WCF.User.Action.Follow=Class.extend({_containerList:null,_followButtonSelector:".jsFollowButton",_userID:0,init:function(t,e){t.length&&(this._containerList=t,e&&(this._followButtonSelector=e),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._containerList.each($.proxy(function(t,e){$(e).find(this._followButtonSelector).click($.proxy(this._click,this))},this)))},_click:function(t){t.preventDefault();var e=$(t.target);e.is("a")||(e=e.closest("a")),this._userID=e.data("objectID"),this._proxy.setOption("data",{actionName:e.data("following")?"unfollow":"follow",className:"wcf\\data\\user\\follow\\UserFollowAction",parameters:{data:{userID:this._userID}}}),this._proxy.sendRequest()},_success:function(t,e,i){this._containerList.each($.proxy(function(e,i){var s=$(i).find(this._followButtonSelector).get(0);if(s&&$(s).data("objectID")==this._userID)return s=$(s),t.returnValues.following?(s.attr("data-tooltip",WCF.Language.get("wcf.user.button.unfollow")).children(".icon").removeClass("fa-plus").addClass("fa-minus"),s.children(".invisible").text(WCF.Language.get("wcf.user.button.unfollow"))):(s.attr("data-tooltip",WCF.Language.get("wcf.user.button.follow")).children(".icon").removeClass("fa-minus").addClass("fa-plus"),s.children(".invisible").text(WCF.Language.get("wcf.user.button.follow"))),s.data("following",t.returnValues.following),!1},this)),(new WCF.System.Notification).show()}}),WCF.User.Action.Ignore=Class.extend({_containerList:null,_ignoreButtonSelector:".jsIgnoreButton",_userID:0,init:function(t,e){t.length&&(this._containerList=t,e&&(this._ignoreButtonSelector=e),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._containerList.each($.proxy(function(t,e){$(e).find(this._ignoreButtonSelector).click($.proxy(this._click,this))},this)))},_click:function(t){t.preventDefault();var e=$(t.target);e.is("a")||(e=e.closest("a")),this._userID=e.data("objectID"),this._proxy.setOption("data",{actionName:e.data("ignored")?"unignore":"ignore",className:"wcf\\data\\user\\ignore\\UserIgnoreAction",parameters:{data:{userID:this._userID}}}),this._proxy.sendRequest()},_success:function(t,e,i){this._containerList.each($.proxy(function(e,i){var s=$(i).find(this._ignoreButtonSelector).get(0);if(s&&$(s).data("objectID")==this._userID)return s=$(s),t.returnValues.isIgnoredUser?(s.attr("data-tooltip",WCF.Language.get("wcf.user.button.unignore")).children(".icon").removeClass("fa-ban").addClass("fa-circle-o"),s.children(".invisible").text(WCF.Language.get("wcf.user.button.unignore"))):(s.attr("data-tooltip",WCF.Language.get("wcf.user.button.ignore")).children(".icon").removeClass("fa-circle-o").addClass("fa-ban"),s.children(".invisible").text(WCF.Language.get("wcf.user.button.ignore"))),s.data("ignored",t.returnValues.isIgnoredUser),!1},this)),(new WCF.System.Notification).show();var s=this;WCF.System.ObjectStore.invoke("WCF.User.ProfilePreview",function(t){t.purge(s._userID)})}}),WCF.User.Avatar={},WCF.User.Avatar.Upload=WCF.Upload.extend({_userID:0,init:function(t){this._super($("#avatarUpload > dd > div"),void 0,"wcf\\data\\user\\avatar\\UserAvatarAction"),this._userID=t||0,$("#avatarForm input[type=radio]").change(function(){"custom"==$(this).val()?$("#avatarUpload > dd > div").show():$("#avatarUpload > dd > div").hide()}),$("#avatarForm input[type=radio][value=custom]:checked").length||$("#avatarUpload > dd > div").hide()},_initFile:function(t){return $("#avatarUpload > dt > img")},_success:function(t,e){if(e.returnValues.url){this._updateImage(e.returnValues.url),$("#avatarUpload > dd > .innerError").remove();new WCF.System.Notification(WCF.Language.get("wcf.user.avatar.upload.success")).show()}else e.returnValues.errorType&&this._getInnerErrorElement().text(WCF.Language.get("wcf.user.avatar.upload.error."+e.returnValues.errorType))},_updateImage:function(t){$("#avatarUpload > dt > img").remove();var e=$('<img src="'+t+'" class="userAvatarImage" alt="" />').css({height:"auto","max-height":"96px","max-width":"96px",width:"auto"});$("#avatarUpload > dt").prepend(e),WCF.DOMNodeInsertedHandler.execute()},_getInnerErrorElement:function(){var t=$("#avatarUpload > dd > .innerError");return t.length||(t=$('<small class="innerError"></span>'),$("#avatarUpload > dd").append(t)),t},_getParameters:function(){return{userID:this._userID}}}),WCF.User.List=Class.extend({_additionalParameters:{},_cache:{},_className:"",_dialog:null,_dialogTitle:"",_pageCount:0,_pageNo:1,_proxy:null,init:function(t,e,i){this._additionalParameters=i||{},this._cache={},this._className=t,this._dialog=null,this._dialogTitle=e,this._pageCount=0,this._pageNo=1,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},open:function(){this._pageNo=1,this._showPage()},_showPage:function(t,e){if(e&&e.activePage&&(this._pageNo=e.activePage),0!=this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount))return void console.debug("[WCF.User.List] Cannot access page "+this._pageNo+" of "+this._pageCount);if(this._cache[this._pageNo]){var i=!1;null===this._dialog&&(this._dialog=$("#userList"+this._className.hashCode()),
-0===this._dialog.length&&(this._dialog=$('<div id="userList'+this._className.hashCode()+'" />').hide().appendTo(document.body),i=!0)),this._dialog.empty(),this._dialog.html(this._cache[this._pageNo]),this._pageCount>1?this._dialog.find(".jsPagination").wcfPages({activePage:this._pageNo,maxPage:this._pageCount}).on("wcfpagesswitched",$.proxy(this._showPage,this)):this._dialog.find(".jsPagination").hide(),i?this._dialog.wcfDialog({title:this._dialogTitle}):(this._dialog.wcfDialog("option","title",this._dialogTitle),this._dialog.wcfDialog("open").wcfDialog("render")),WCF.DOMNodeInsertedHandler.execute()}else this._additionalParameters.pageNo=this._pageNo,this._proxy.setOption("data",{actionName:"getGroupedUserList",className:this._className,interfaceName:"wcf\\data\\IGroupedUserListAction",parameters:this._additionalParameters}),this._proxy.sendRequest()},_success:function(t,e,i){t.returnValues.pageCount&&(this._pageCount=t.returnValues.pageCount),this._cache[this._pageNo]=t.returnValues.template,this._showPage()}}),WCF.User.ObjectWatch={},WCF.User.ObjectWatch.Subscribe=Class.extend({_buttonSelector:".jsSubscribeButton",_buttons:{},_dialog:null,_notification:null,_reloadOnUnsubscribe:!1,init:function(t){this._buttons={},this._notification=null,this._reloadOnUnsubscribe=!0===t,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(this._buttonSelector).each($.proxy(function(t,e){var i=$(e);i.addClass("pointer");var s=i.data("objectType"),a=i.data("objectID");void 0===this._buttons[s]&&(this._buttons[s]={}),this._buttons[s][a]=i.click($.proxy(this._click,this))},this)),WCF.System.Event.addListener("com.woltlab.wcf.objectWatch","update",$.proxy(this._updateSubscriptionStatus,this))},_click:function(t){t.preventDefault();var e=$(t.currentTarget);this._proxy.setOption("data",{actionName:"manageSubscription",className:"wcf\\data\\user\\object\\watch\\UserObjectWatchAction",parameters:{objectID:e.data("objectID"),objectType:e.data("objectType")}}),this._proxy.sendRequest()},_success:function(t,e,i){if("manageSubscription"===t.actionName){null===this._dialog?(this._dialog=$("<div>"+t.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.user.objectWatch.manageSubscription")})):(this._dialog.html(t.returnValues.template),this._dialog.wcfDialog("open")),this._dialog.find(".formSubmit > .jsButtonSave").data("objectID",t.returnValues.objectID).data("objectType",t.returnValues.objectType).click($.proxy(this._save,this));var s=this._dialog.find("input[name=enableNotification]").disable();this._dialog.find("input[name=subscribe]").change(function(t){1==$(t.currentTarget).val()?s.enable():s.disable()});var a=this._dialog.find("input[name=subscribe]:checked");a.length&&1==a.val()&&s.enable()}else"saveSubscription"===t.actionName&&this._dialog.is(":visible")&&(this._dialog.wcfDialog("close"),this._updateSubscriptionStatus({isSubscribed:t.returnValues.subscribe,objectID:t.returnValues.objectID}),null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit"))),this._notification.show())},_save:function(t){var e=this._buttons[$(t.currentTarget).data("objectType")][$(t.currentTarget).data("objectID")],i=this._dialog.find("input[name=subscribe]:checked").val(),s=this._dialog.find("input[name=enableNotification]").is(":checked")?1:0;this._proxy.setOption("data",{actionName:"saveSubscription",className:"wcf\\data\\user\\object\\watch\\UserObjectWatchAction",parameters:{enableNotification:s,objectID:e.data("objectID"),objectType:e.data("objectType"),subscribe:i}}),this._proxy.sendRequest()},_updateSubscriptionStatus:function(t){var e=$(this._buttonSelector+"[data-object-id="+t.objectID+"]"),i=e.children(".icon");if(t.isSubscribed)i.removeClass("fa-bookmark-o").addClass("fa-bookmark"),e.data("isSubscribed",!0);else if(e.data("removeOnUnsubscribe")?e.parent().remove():(i.removeClass("fa-bookmark").addClass("fa-bookmark-o"),e.data("isSubscribed",!1)),this._reloadOnUnsubscribe)return void window.location.reload();WCF.System.Event.fireEvent("com.woltlab.wcf.objectWatch","updatedSubscription",t)}}); })(this);
+(function (window, undefined) { "use strict";WCF.User.Login=Class.extend({_loginSubmitButton:null,_password:null,_passwordContainer:null,_useCookies:null,_useCookiesContainer:null,init:function(t){this._loginSubmitButton=$("#loginSubmitButton"),this._password=$("#password"),this._passwordContainer=this._password.parents("dl"),this._useCookies=$("#useCookies"),this._useCookiesContainer=this._useCookies.parents("dl"),$("#loginForm").find("input[name=action]").change($.proxy(this._change,this)),t&&WCF.User.QuickLogin.init()},_change:function(t){"register"===$(t.currentTarget).val()?this._setState(!1,WCF.Language.get("wcf.user.button.register")):this._setState(!0,WCF.Language.get("wcf.user.button.login"))},_setState:function(t,e){t?(this._password.enable(),this._passwordContainer.removeClass("disabled"),this._useCookies.enable(),this._useCookiesContainer.removeClass("disabled")):(this._password.disable(),this._passwordContainer.addClass("disabled"),this._useCookies.disable(),this._useCookiesContainer.addClass("disabled")),this._loginSubmitButton.val(e)}}),WCF.User.Panel={},WCF.User.Panel.Abstract=Class.extend({_badge:null,_dropdown:null,_identifier:"",_loadData:!0,_markAllAsReadLink:null,_options:{},_proxy:null,_triggerElement:null,_button:null,_callbackFocus:null,_callbackCloseUuid:"",_wasInsideDropdown:!1,init:function(t,e,i){var s;this._dropdown=null,this._loadData=!0,this._identifier=e,this._triggerElement=t,this._options=i,this._callbackFocus=null,this._callbackCloseUuid="",this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._triggerElement.click($.proxy(this.toggle,this)),this._button=elBySel("a",this._triggerElement[0]),this._button&&(elAttr(this._button,"role","button"),elAttr(this._button,"tabindex","0"),elAttr(this._button,"aria-haspopup",!0),elAttr(this._button,"aria-expanded",!1)),this._options.showAllLink&&this._triggerElement.dblclick($.proxy(this._dblClick,this)),!0===this._options.staticDropdown?this._loadData=!1:(s=this._triggerElement.find("span.badge")).length&&(this._badge=s)},toggle:function(t){return t instanceof Event&&t.preventDefault(),null===this._dropdown&&(this._dropdown=this._initDropdown()),this._dropdown.toggle()?(this._loadData||null===this._badge||!parseInt(this._badge.text())||this._dropdown.getItemList().children(".interactiveDropdownItemOutstanding").length||(this._loadData=!0),this._loadData&&(this._loadData=!1,this._load()),elAttr(this._button,"aria-expanded",!0),null===this._callbackFocus&&(this._callbackFocus=this._maintainFocus.bind(this)),document.body.addEventListener("focus",this._callbackFocus,{capture:!0}),this._callbackCloseUuid=WCF.System.Event.addListener("WCF.Dropdown.Interactive.Instance","close",function(t){t.instance===this._dropdown&&(WCF.System.Event.removeListener("WCF.Dropdown.Interactive.Instance","close",this._callbackCloseUuid),document.body.removeEventListener("focus",this._callbackFocus,{capture:!0}))}.bind(this))):(elAttr(this._button,"aria-expanded",!1),WCF.System.Event.removeListener("WCF.Dropdown.Interactive.Instance","close",this._callbackCloseUuid),document.body.removeEventListener("focus",this._callbackFocus,{capture:!0})),!1},_dblClick:function(t){return t.preventDefault(),window.location=this._options.showAllLink,!1},_initDropdown:function(){var t=WCF.Dropdown.Interactive.Handler.create(this._triggerElement,this._identifier,this._options);return $('<li class="loading"><span class="icon icon24 fa-spinner" /> <span>'+WCF.Language.get("wcf.global.loading")+"</span></li>").appendTo(t.getItemList()),t},_load:function(){},_success:function(t){var e,i,s;void 0!==t.returnValues.template&&(e=this._dropdown.getItemList().empty(),$(t.returnValues.template).appendTo(e),e.children().length||$('<li class="noItems">'+this._options.noItems+"</li>").appendTo(e),this._options.enableMarkAsRead&&(i=this._dropdown.getItemList().children(".interactiveDropdownItemOutstanding"),null===this._markAllAsReadLink&&i.length&&(this._markAllAsReadLink=$('<li class="interactiveDropdownItemMarkAllAsRead"><a href="#" title="'+WCF.Language.get("wcf.user.panel.markAllAsRead")+'" class="jsTooltip"><span class="icon icon24 fa-check" /></a></li>').appendTo(this._dropdown.getLinkList())).click(function(t){return this._dropdown.close(),this._markAllAsRead(),!1}.bind(this)),i.each(function(t,e){var i=$(e).addClass("interactiveDropdownItemOutstandingIcon"),s=i.data("objectID");$('<div class="interactiveDropdownItemMarkAsRead"><a href="#" title="'+WCF.Language.get("wcf.user.panel.markAsRead")+'" class="jsTooltip"><span class="icon icon16 fa-check" /></a></div>').appendTo(i).click(function(t){return this._markAsRead(t,s),!1}.bind(this))}.bind(this))),this._dropdown.getItemList().children().each(function(t,e){var i=$(e),s=i.data("link");s&&($.browser.msie?i.click(function(t){if("A"!==t.target.tagName)return window.location=s,!1}):(i.addClass("interactiveDropdownItemShadow"),$('<a href="'+s+'" class="interactiveDropdownItemShadowLink" />').appendTo(i)),i.data("linkReplaceAll")&&i.find("> .box48 a:not(.userLink)").prop("href",s))}),this._dropdown.rebuildScrollbar()),void 0!==t.returnValues.totalCount&&this.updateBadge(t.returnValues.totalCount),this._options.enableMarkAsRead&&(t.returnValues.markAsRead?(s=this._dropdown.getItemList().children("li[data-object-id="+t.returnValues.markAsRead+"]")).length&&(s.removeClass("interactiveDropdownItemOutstanding").data("isRead",!0),s.children(".interactiveDropdownItemMarkAsRead").remove()):t.returnValues.markAllAsRead&&(this.resetItems(),this.updateBadge(0)))},_markAsRead:function(t,e){},_markAllAsRead:function(){},updateBadge:function(t){(t=parseInt(t)||0)?(null===this._badge&&(this._badge=$('<span class="badge badgeUpdate" />').appendTo(this._triggerElement.children("a")),this._badge.before(" ")),this._badge.text(t)):null!==this._badge&&(this._badge.remove(),this._badge=null),this._options.enableMarkAsRead&&(t||null===this._markAllAsReadLink||(this._markAllAsReadLink.remove(),this._markAllAsReadLink=null)),WCF.System.Event.fireEvent("com.woltlab.wcf.userMenu","updateBadge",{count:t,identifier:this._identifier})},resetItems:function(){null!==this._dropdown&&(this._dropdown.resetItems(),this._loadData=!0)},_maintainFocus:function(t){var e;document.activeElement&&!document.activeElement.classList.contains("focus-visible")||((e=this._dropdown.getContainer()[0]).contains(t.target)?this._wasInsideDropdown=!0:this._wasInsideDropdown?(this._button.focus(),this._wasInsideDropdown=!1):elBySel("a",e).focus())}}),WCF.User.Panel.Notification=WCF.User.Panel.Abstract.extend({_favico:null,init:function(t){t.enableMarkAsRead=!0,this._super($("#userNotifications"),"userNotifications",t);try{var e;this._favico=new Favico({animation:"none",type:"circle"}),null!==this._badge&&(e=parseInt(this._badge.text())||0,this._favico.badge(e))}catch(t){console.debug("[WCF.User.Panel.Notification] Failed to initialized Favico: "+t.message)}WCF.System.PushNotification.addCallback("userNotificationCount",$.proxy(this.updateUserNotificationCount,this)),require(["EventHandler"],function(t){t.add("com.woltlab.wcf.UserMenuMobile","more",function(t){"com.woltlab.wcf.notifications"===t.identifier&&this.toggle()}.bind(this))}.bind(this))},_initDropdown:function(){var t=this._super();return $('<li><a href="'+this._options.settingsLink+'" title="'+WCF.Language.get("wcf.user.panel.settings")+'" class="jsTooltip"><span class="icon icon24 fa-cog" /></a></li>').appendTo(t.getLinkList()),t},_load:function(){this._proxy.setOption("data",{actionName:"getOutstandingNotifications",className:"wcf\\data\\user\\notification\\UserNotificationAction"}),this._proxy.sendRequest()},_markAsRead:function(t,e){this._proxy.setOption("data",{actionName:"markAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction",objectIDs:[e]}),this._proxy.sendRequest()},_markAllAsRead:function(t){this._proxy.setOption("data",{actionName:"markAllAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction"}),this._proxy.sendRequest()},resetItems:function(){this._super(),this._markAllAsReadLink&&(this._markAllAsReadLink.remove(),this._markAllAsReadLink=null)},updateBadge:function(t){t=parseInt(t)||0,$("#userNotifications").attr("data-count",t),null!==this._favico&&this._favico.badge(t),this._super(t)},updateUserNotificationCount:function(t){null!==this._dropdown&&this._dropdown.resetItems(),this.updateBadge(t)},_success:function(t){this._super(t),elBySelAll(".interactiveDropdownItemShadowLink",this._dropdown.getItemList()[0],function(t){t.addEventListener("click",function(t){t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||(this._dropdown.close(),WCF.System.Event.fireEvent("com.woltlab.wcf.UserMenuMobile","close"))}.bind(this))}.bind(this))}}),WCF.User.Panel.UserMenu=WCF.User.Panel.Abstract.extend({init:function(){this._super($("#userMenu"),"userMenu",{pointerOffset:"13px",staticDropdown:!0})}}),WCF.User.QuickLogin={init:function(){require(["EventHandler","Ui/Dialog"],function(t,s){var a=elById("loginForm"),n=elBySel(".loginFormLogin",a);n&&!n.nextElementSibling&&a.classList.add("loginFormLoginOnly");for(var o=elBySel(".loginFormRegister",a),e=function(t){if(t instanceof Event&&(t.preventDefault(),t.stopPropagation()),a.style.removeProperty("display"),s.openStatic("loginForm",null,{title:WCF.Language.get("wcf.user.login")}),null!==n&&null!==o){var e=n.offsetTop,i=0;if(a.clientWidth>2*n.clientWidth)for(;e<o.offsetTop-50;)i+=100,n.style.setProperty("margin-bottom",i+"px","")}},i=document.getElementsByClassName("loginLink"),r=0,l=i.length;r<l;r++)i[r].addEventListener(WCF_CLICK_EVENT,e);var c=a.querySelector("#loginForm input[name=url]");null===c||c.value.match(/^https?:\/\//)||c.setAttribute("value",window.location.protocol+"//"+window.location.host+c.getAttribute("value")),t.add("com.woltlab.wcf.UserMenuMobile","more",function(t){"com.woltlab.wcf.login"===t.identifier&&(t.handler.close(!0),e())})})}},WCF.User.Profile={},WCF.User.Profile.ActivityPointList={_cache:{},_dialog:null,_didInit:!1,_proxy:null,init:function(){this._didInit||(this._cache={},this._dialog=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.User.Profile.ActivityPointList",$.proxy(this._init,this)),this._didInit=!0)},_init:function(){$(".activityPointsDisplay").removeClass("activityPointsDisplay").click($.proxy(this._click,this))},_click:function(t){t.preventDefault();var e=$(t.currentTarget).data("userID");void 0===this._cache[e]?(this._proxy.setOption("data",{actionName:"getDetailedActivityPointList",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[e]}),this._proxy.sendRequest()):this._show(e)},_show:function(t){null===this._dialog?(this._dialog=$("<div>"+this._cache[t]+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.user.activityPoint")})):(this._dialog.html(this._cache[t]),this._dialog.wcfDialog("open"))},_success:function(t,e,i){this._cache[t.returnValues.userID]=t.returnValues.template,this._show(t.returnValues.userID)}},WCF.User.Profile.TabMenu=Class.extend({_hasContent:{},_profileContent:null,_proxy:null,_userID:0,init:function(t){this._profileContent=$("#profileContent"),this._userID=t;var s=this._profileContent.data("active"),a=!1;this._profileContent.find("div.tabMenuContent").each($.proxy(function(t,e){var i=$(e).wcfIdentify();s===i?this._hasContent[i]=!0:(this._hasContent[i]=!1,a=!0)},this)),a&&(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._profileContent.on("wcftabsbeforeactivate",$.proxy(this._loadContent,this)),this._profileContent.find("> nav.tabMenu > ul > li").each($.proxy(function(t,e){var i=$(e);if(i.hasClass("ui-state-active"))return t&&this._loadContent(null,{newPanel:$("#"+i.attr("aria-controls"))}),!1},this))),$('.userProfileUser .contentDescription a[href$="#likes"]').click(function(t){t.preventDefault(),require(["Ui/TabMenu"],function(t){t.getTabMenu("profileContent").select("likes")})}.bind(this))},_loadContent:function(t,e){var i=$(e.newPanel),s=i.attr("id");this._hasContent[s]||(this._proxy.setOption("data",{actionName:"getContent",className:"wcf\\data\\user\\profile\\menu\\item\\UserProfileMenuItemAction",parameters:{data:{containerID:s,menuItem:i.data("menuItem"),userID:this._userID}}}),this._proxy.sendRequest())},_success:function(i,t,e){var s=i.returnValues.containerID;this._hasContent[s]=!0,require(["Dom/ChangeListener","Dom/Util"],function(t,e){e.insertHtml(i.returnValues.template,elById(s),"append"),t.trigger()})}}),WCF.User.Profile.Editor=Class.extend({_actionName:"",_active:!1,_buttons:{},_cachedTemplate:"",_proxy:null,_tab:null,_userID:0,init:function(t,e){this._actionName="",this._active=!1,this._cachedTemplate="",this._tab=$("#about"),this._userID=t,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initButtons(),e&&this._beginEdit()},_initButtons:function(){this._buttons={beginEdit:$(".jsButtonEditProfile:eq(0)").click(this._beginEdit.bind(this))}},_beginEdit:function(t){t&&t.preventDefault(),this._active||(this._active=!0,this._actionName="beginEdit",this._buttons.beginEdit.parent().addClass("active"),$("#profileContent").wcfTabs("select","about"),this._proxy.setOption("data",{actionName:"beginEdit",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[this._userID]}),this._proxy.sendRequest())},_save:function(){var r,l,i=null;elBySelAll(".redactor-layer",this._tab[0],function(t){var e={api:{throwError:elInnerError},valid:!0};WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","validate_"+elData(t,"element-id"),e),e.valid||null!==i||(i=t.parentNode)}),i?i.scrollIntoView({behavior:"smooth"}):(this._actionName="save",r=/values\[([a-zA-Z0-9._-]+)\]/,l={},this._tab.find("input, textarea, select").each(function(t,e){var i=$(e),s=null;switch(i.getTagName()){case"input":var a=i.attr("type");if(("radio"===a||"checkbox"===a)&&!i.prop("checked"))return;break;case"textarea":i.data("redactor")&&(s=i.redactor("code.get"))}var n,o=i.attr("name");r.test(o)&&(n=RegExp.$1,null===s&&(s=i.val()),"checkbox"===i.attr("type")&&/\[\]$/.test(o)?(Array.isArray(l[n])||(l[n]=[]),l[n].push(s)):l[n]=s)}),this._proxy.setOption("data",{actionName:"save",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[this._userID],parameters:{values:l}}),this._proxy.sendRequest())},_restore:function(){this._actionName="restore",this._active=!1,this._buttons.beginEdit.parent().removeClass("active"),this._destroyEditor(),this._tab.html(this._cachedTemplate).children().css({height:"auto"})},_success:function(t,e,i){switch(this._actionName){case"beginEdit":this._prepareEdit(t);break;case"save":t.returnValues.success?(this._cachedTemplate=t.returnValues.template,this._restore()):this._prepareEdit(t,!0)}},_prepareEdit:function(i,s){this._destroyEditor();var a=this;this._tab.html(function(t,e){return!0!==s&&(a._cachedTemplate=e),i.returnValues.template}),this._tab.find("input[type=text]").attr("autocomplete","off"),this._tab.find(".formSubmit > button[data-type=save]").click($.proxy(this._save,this)),this._tab.find(".formSubmit > button[data-type=restore]").click($.proxy(this._restore,this)),this._tab.find("input").keyup(function(t){if(t.which===$.ui.keyCode.ENTER)return a._save(),t.preventDefault(),!1})},_destroyEditor:function(){this._tab.find("textarea").each(function(t,e){var i=$(e);i.data("redactor")&&i.redactor("core.destroy")})}}),WCF.User.Registration={},WCF.User.Registration.Validation=Class.extend({_actionName:"",_className:"",_confirmElement:null,_element:null,_errorMessages:{},_options:{},_proxy:null,init:function(t,e,i){this._element=t,this._element.blur($.proxy(this._blur,this)),this._confirmElement=e||null,null!==this._confirmElement&&this._confirmElement.blur($.proxy(this._blurConfirm,this)),i=i||{},this._setOptions(i),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),showLoadingOverlay:!1}),this._setErrorMessages()},_setOptions:function(t){},_setErrorMessages:function(){this._errorMessages={ajaxError:"",notEqual:""}},_blur:function(t){var e=this._element.val();if(!e)return this._showError(this._element,WCF.Language.get("wcf.global.form.error.empty"));if(null!==this._confirmElement){var i=this._confirmElement.val();if(""!=i&&e!=i)return this._showError(this._confirmElement,this._errorMessages.notEqual)}this._validateOptions()&&(this._proxy.setOption("data",{actionName:this._actionName,className:this._className,parameters:this._getParameters()}),this._proxy.sendRequest())},_getParameters:function(){return{}},_validateOptions:function(){return!0},_blurConfirm:function(t){if(!this._confirmElement.val())return this._showError(this._confirmElement,WCF.Language.get("wcf.global.form.error.empty"));this._blur(t)},_success:function(t,e,i){t.returnValues.isValid?(this._showSuccess(this._element),null!==this._confirmElement&&this._confirmElement.val()&&this._showSuccess(this._confirmElement)):this._showError(this._element,WCF.Language.get(this._errorMessages.ajaxError+t.returnValues.error))},_showError:function(t,e){t.parent().parent().addClass("formError").removeClass("formSuccess");var i=t.parent().find("small.innerError");i.length||(i=$("<small />").addClass("innerError").insertAfter(t)),i.text(e)},_showSuccess:function(t){t.parent().parent().addClass("formSuccess").removeClass("formError"),t.next("small.innerError").remove()}}),WCF.User.Registration.Validation.Username=WCF.User.Registration.Validation.extend({_actionName:"validateUsername",_className:"wcf\\data\\user\\UserRegistrationAction",_setOptions:function(t){this._options=$.extend(!0,{minlength:3,maxlength:25},t)},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.username.error."}},_validateOptions:function(){var t=this._element.val();return!(t.length<this._options.minlength||t.length>this._options.maxlength)||(this._showError(this._element,WCF.Language.get("wcf.user.username.error.invalid")),!1)},_getParameters:function(){return{username:this._element.val()}}}),WCF.User.Registration.Validation.EmailAddress=WCF.User.Registration.Validation.extend({_actionName:"validateEmailAddress",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{email:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.email.error.",notEqual:WCF.Language.get("wcf.user.confirmEmail.error.notEqual")}}}),WCF.User.Registration.Validation.Password=WCF.User.Registration.Validation.extend({_actionName:"validatePassword",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{password:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.password.error.",notEqual:WCF.Language.get("wcf.user.confirmPassword.error.notEqual")}}}),WCF.User.Registration.LostPassword=Class.extend({_email:null,_username:null,init:function(){this._email=$("#emailInput"),this._username=$("#usernameInput"),this._email.keyup($.proxy(this._checkEmail,this)),this._username.keyup($.proxy(this._checkUsername,this)),$.browser.mozilla&&$.browser.touch&&(this._email.on("input",$.proxy(this._checkEmail,this)),this._username.on("input",$.proxy(this._checkUsername,this))),this._checkEmail(),this._checkUsername()},_checkEmail:function(){""==this._email.val()?(this._username.enable(),this._username.parents("dl:eq(0)").removeClass("disabled")):(this._username.disable(),this._username.parents("dl:eq(0)").addClass("disabled"),this._username.val(""))},_checkUsername:function(){""==this._username.val()?(this._email.enable(),this._email.parents("dl:eq(0)").removeClass("disabled")):(this._email.disable(),this._email.parents("dl:eq(0)").addClass("disabled"),this._email.val(""))}}),WCF.Notification={},WCF.Notification.List=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".contentHeaderNavigation .jsMarkAllAsConfirmed").click(function(){WCF.System.Confirmation.show(WCF.Language.get("wcf.user.notification.markAllAsConfirmed.confirmMessage"),function(t){"confirm"===t&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"markAllAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction"},success:function(){window.location.reload()}})})}),this._convertList()},_convertList:function(){$(".userNotificationItemList > .notificationItem").each(function(t,e){var i=$(e);i.data("isRead")||(i.find("a:not(.userLink)").prop("href",i.data("link")),$('<a href="#" class="icon icon24 fa-check notificationItemMarkAsConfirmed jsTooltip" title="'+WCF.Language.get("wcf.user.notification.markAsConfirmed")+'" />').appendTo(i).click($.proxy(this._markAsConfirmed,this)));var s=e.querySelector(".details > p:first-child");s.classList.add("pointer"),s.addEventListener("click",function(t){window.location.href=i.data("link")})}.bind(this)),WCF.DOMNodeInsertedHandler.execute()},_markAsConfirmed:function(t){t.preventDefault();var e=$(t.currentTarget).parents(".notificationItem:eq(0)").data("objectID");return this._proxy.setOption("data",{actionName:"markAsConfirmed",className:"wcf\\data\\user\\notification\\UserNotificationAction",objectIDs:[e]}),this._proxy.sendRequest(),!1},_success:function(t,e,i){var s=$(".userNotificationItemList > .notificationItem[data-object-id="+t.returnValues.markAsRead+"]");s.data("isRead",!0),s.find(".newContentBadge").remove(),s.find(".notificationItemMarkAsConfirmed").remove(),s.removeClass("notificationUnconfirmed")}}),WCF.User.SignaturePreview=WCF.Message.Preview.extend({_handleResponse:function(t){var e=$("#previewContainer");e.length||(e=$('<section class="section" id="previewContainer"><h2 class="sectionTitle">'+WCF.Language.get("wcf.global.preview")+'</h2><div class="htmlContent messageSignatureConstraints"></div></section>').insertBefore($("#signatureContainer")).wcfFadeIn()),e.children("div").first().html(t.returnValues.message)}}),WCF.User.RecentActivityLoader=Class.extend({_container:null,_filteredByFollowedUsers:!1,_loadButton:null,_proxy:null,_userID:0,init:function(t,e){this._container=$("#recentActivities"),this._filteredByFollowedUsers=!0===e,this._userID=t,null===this._userID||this._userID?(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._container.children("li").length?(this._loadButton=$('<li class="showMore"><button class="small">'+WCF.Language.get("wcf.user.recentActivity.more")+"</button></li>").appendTo(this._container),this._loadButton=this._loadButton.children("button").click($.proxy(this._click,this))):$('<li class="showMore"><small>'+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small></li>").appendTo(this._container),WCF.User.userID&&$(".jsRecentActivitySwitchContext .button").click($.proxy(this._switchContext,this))):console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.")},_click:function(){this._loadButton.enable();var t={lastEventID:this._container.data("lastEventID"),lastEventTime:this._container.data("lastEventTime")};this._userID?t.userID=this._userID:this._filteredByFollowedUsers&&(t.filteredByFollowedUsers=1),this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction",parameters:t}),this._proxy.sendRequest()},_switchContext:function(t){t.preventDefault(),$(t.currentTarget).hasClass("active")||new WCF.Action.Proxy({autoSend:!0,data:{actionName:"switchContext",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"},success:function(){window.location.hash="#dashboardBoxRecentActivity",window.location.reload()}})},_success:function(t,e,i){t.returnValues.template?($(t.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastEventTime",t.returnValues.lastEventTime),this._container.data("lastEventID",t.returnValues.lastEventID),this._loadButton.enable()):($("<small>"+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small>").appendTo(this._loadButton.parent()),this._loadButton.remove())}}),WCF.User.LikeLoader=Class.extend({_container:null,_likeType:"received",_likeValue:1,_loadButton:null,_noMoreEntries:null,_proxy:null,_userID:0,init:function(t){var e;this._container=$("#likeList"),this._userID=t,this._userID?(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),e=$('<li class="likeListMore showMore"><button class="small">'+WCF.Language.get("wcf.like.likes.more")+"</button><small>"+WCF.Language.get("wcf.like.likes.noMoreEntries")+"</small></li>").appendTo(this._container),this._loadButton=e.children("button").click($.proxy(this._click,this)),this._noMoreEntries=e.children("small").hide(),2==this._container.find("> li").length&&(this._loadButton.hide(),this._noMoreEntries.show()),$("#likeType .button").click($.proxy(this._clickLikeType,this)),$("#likeValue .button").click($.proxy(this._clickLikeValue,this))):console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.")},_clickLikeType:function(t){var e=$(t.currentTarget);this._likeType!=e.data("likeType")&&(this._likeType=e.data("likeType"),$("#likeType .button").removeClass("active"),e.addClass("active"),this._reload())},_clickLikeValue:function(t){var e=$(t.currentTarget);this._likeValue!=e.data("likeValue")&&(this._likeValue=e.data("likeValue"),$("#likeValue .button").removeClass("active"),e.addClass("active"),$("#likeType > li:first-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesReceived")),$("#likeType > li:last-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesGiven")),this._container.find("> li.likeListMore button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.more")),this._container.find("> li.likeListMore small").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.noMoreEntries")),this._reload())},_reload:function(){this._container.find("> li:not(:first-child):not(:last-child)").remove(),this._container.data("lastLikeTime",0),this._click()},_click:function(){this._loadButton.enable();var t={lastLikeTime:this._container.data("lastLikeTime"),userID:this._userID,likeType:this._likeType,likeValue:this._likeValue};this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\like\\LikeAction",parameters:t}),this._proxy.sendRequest()},_success:function(t,e,i){t.returnValues.template?($(t.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastLikeTime",t.returnValues.lastLikeTime),this._noMoreEntries.hide(),this._loadButton.show().enable()):(this._noMoreEntries.show(),this._loadButton.hide())}}),WCF.User.ProfilePreview=WCF.Popover.extend({_proxy:null,_userProfiles:{},init:function(){this._super(".userLink"),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1}),WCF.System.ObjectStore.add("WCF.User.ProfilePreview",this)},_loadContent:function(){var a,n,o=$("#"+this._activeElementID).data("userID");this._userProfiles[o]?this._insertContent(this._activeElementID,this._userProfiles[o],!0):(this._proxy.setOption("data",{actionName:"getUserProfile",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[o]}),a=this._activeElementID,(n=this)._proxy.setOption("success",function(t,e,i){n._userProfiles[o]=t.returnValues.template,n._insertContent(a,t.returnValues.template,!0)}),this._proxy.setOption("failure",function(t,e,i,s){return n._userProfiles[o]=t.message,n._insertContent(a,t.message,!0),!1}),this._proxy.sendRequest())},purge:function(t){delete this._userProfiles[t],this._data={}}}),WCF.User.Action={},WCF.User.Action.Follow=Class.extend({_containerList:null,_followButtonSelector:".jsFollowButton",_userID:0,init:function(t,e){t.length&&(this._containerList=t,e&&(this._followButtonSelector=e),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._containerList.each($.proxy(function(t,e){$(e).find(this._followButtonSelector).click($.proxy(this._click,this))},this)))},_click:function(t){t.preventDefault();var e=$(t.target);e.is("a")||(e=e.closest("a")),this._userID=e.data("objectID"),this._proxy.setOption("data",{actionName:e.data("following")?"unfollow":"follow",className:"wcf\\data\\user\\follow\\UserFollowAction",parameters:{data:{userID:this._userID}}}),this._proxy.sendRequest()},_success:function(s,t,e){this._containerList.each($.proxy(function(t,e){var i=$(e).find(this._followButtonSelector).get(0);if(i&&$(i).data("objectID")==this._userID)return i=$(i),s.returnValues.following?(i.attr("data-tooltip",WCF.Language.get("wcf.user.button.unfollow")).children(".icon").removeClass("fa-plus").addClass("fa-minus"),i.children(".invisible").text(WCF.Language.get("wcf.user.button.unfollow"))):(i.attr("data-tooltip",WCF.Language.get("wcf.user.button.follow")).children(".icon").removeClass("fa-minus").addClass("fa-plus"),i.children(".invisible").text(WCF.Language.get("wcf.user.button.follow"))),i.data("following",s.returnValues.following),!1},this)),(new WCF.System.Notification).show()}}),WCF.User.Action.Ignore=Class.extend({_containerList:null,_ignoreButtonSelector:".jsIgnoreButton",_userID:0,init:function(t,e){t.length&&(this._containerList=t,e&&(this._ignoreButtonSelector=e),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._containerList.each($.proxy(function(t,e){$(e).find(this._ignoreButtonSelector).click($.proxy(this._click,this))},this)))},_click:function(t){t.preventDefault();var e=$(t.target);e.is("a")||(e=e.closest("a")),this._userID=e.data("objectID"),this._proxy.setOption("data",{actionName:e.data("ignored")?"unignore":"ignore",className:"wcf\\data\\user\\ignore\\UserIgnoreAction",parameters:{data:{userID:this._userID}}}),this._proxy.sendRequest()},_success:function(s,t,e){this._containerList.each($.proxy(function(t,e){var i=$(e).find(this._ignoreButtonSelector).get(0);if(i&&$(i).data("objectID")==this._userID)return i=$(i),s.returnValues.isIgnoredUser?(i.attr("data-tooltip",WCF.Language.get("wcf.user.button.unignore")).children(".icon").removeClass("fa-ban").addClass("fa-circle-o"),i.children(".invisible").text(WCF.Language.get("wcf.user.button.unignore"))):(i.attr("data-tooltip",WCF.Language.get("wcf.user.button.ignore")).children(".icon").removeClass("fa-circle-o").addClass("fa-ban"),i.children(".invisible").text(WCF.Language.get("wcf.user.button.ignore"))),i.data("ignored",s.returnValues.isIgnoredUser),!1},this)),(new WCF.System.Notification).show();var i=this;WCF.System.ObjectStore.invoke("WCF.User.ProfilePreview",function(t){t.purge(i._userID)})}}),WCF.User.Avatar={},WCF.User.Avatar.Upload=WCF.Upload.extend({_userID:0,init:function(t){this._super($("#avatarUpload > dd > div"),void 0,"wcf\\data\\user\\avatar\\UserAvatarAction"),this._userID=t||0,$("#avatarForm input[type=radio]").change(function(){"custom"==$(this).val()?$("#avatarUpload > dd > div").show():$("#avatarUpload > dd > div").hide()}),$("#avatarForm input[type=radio][value=custom]:checked").length||$("#avatarUpload > dd > div").hide()},_initFile:function(t){return $("#avatarUpload > dt > img")},_success:function(t,e){e.returnValues.url?(this._updateImage(e.returnValues.url),$("#avatarUpload > dd > .innerError").remove(),new WCF.System.Notification(WCF.Language.get("wcf.user.avatar.upload.success")).show()):e.returnValues.errorType&&this._getInnerErrorElement().text(WCF.Language.get("wcf.user.avatar.upload.error."+e.returnValues.errorType))},_updateImage:function(t){$("#avatarUpload > dt > img").remove();var e=$('<img src="'+t+'" class="userAvatarImage" alt="" />').css({height:"auto","max-height":"96px","max-width":"96px",width:"auto"});$("#avatarUpload > dt").prepend(e),WCF.DOMNodeInsertedHandler.execute()},_getInnerErrorElement:function(){var t=$("#avatarUpload > dd > .innerError");return t.length||(t=$('<small class="innerError"></span>'),$("#avatarUpload > dd").append(t)),t},_getParameters:function(){return{userID:this._userID}}}),WCF.User.List=Class.extend({_additionalParameters:{},_cache:{},_className:"",_dialog:null,_dialogTitle:"",_pageCount:0,_pageNo:1,_proxy:null,init:function(t,e,i){this._additionalParameters=i||{},this._cache={},this._className=t,this._dialog=null,this._dialogTitle=e,this._pageCount=0,this._pageNo=1,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},open:function(){this._pageNo=1,this._showPage()},_showPage:function(t,e){var i;e&&e.activePage&&(this._pageNo=e.activePage),0!=this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount)?console.debug("[WCF.User.List] Cannot access page "+this._pageNo+" of "+this._pageCount):this._cache[this._pageNo]?(i=!1,null===this._dialog&&(this._dialog=$("#userList"+this._className.hashCode()),0===this._dialog.length&&(this._dialog=$('<div id="userList'+this._className.hashCode()+'" />').hide().appendTo(document.body),i=!0)),this._dialog.empty(),this._dialog.html(this._cache[this._pageNo]),1<this._pageCount?this._dialog.find(".jsPagination").wcfPages({activePage:this._pageNo,maxPage:this._pageCount}).on("wcfpagesswitched",$.proxy(this._showPage,this)):this._dialog.find(".jsPagination").hide(),i?this._dialog.wcfDialog({title:this._dialogTitle}):(this._dialog.wcfDialog("option","title",this._dialogTitle),this._dialog.wcfDialog("open").wcfDialog("render")),WCF.DOMNodeInsertedHandler.execute()):(this._additionalParameters.pageNo=this._pageNo,this._proxy.setOption("data",{actionName:"getGroupedUserList",className:this._className,interfaceName:"wcf\\data\\IGroupedUserListAction",parameters:this._additionalParameters}),this._proxy.sendRequest())},_success:function(t,e,i){t.returnValues.pageCount&&(this._pageCount=t.returnValues.pageCount),this._cache[this._pageNo]=t.returnValues.template,this._showPage()}}),WCF.User.ObjectWatch={},WCF.User.ObjectWatch.Subscribe=Class.extend({_buttonSelector:".jsSubscribeButton",_buttons:{},_dialog:null,_notification:null,_reloadOnUnsubscribe:!1,init:function(t){this._buttons={},this._notification=null,this._reloadOnUnsubscribe=!0===t,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(this._buttonSelector).each($.proxy(function(t,e){var i=$(e);i.addClass("pointer");var s=i.data("objectType"),a=i.data("objectID");void 0===this._buttons[s]&&(this._buttons[s]={}),this._buttons[s][a]=i.click($.proxy(this._click,this))},this)),WCF.System.Event.addListener("com.woltlab.wcf.objectWatch","update",$.proxy(this._updateSubscriptionStatus,this))},_click:function(t){t.preventDefault();var e=$(t.currentTarget);this._proxy.setOption("data",{actionName:"manageSubscription",className:"wcf\\data\\user\\object\\watch\\UserObjectWatchAction",parameters:{objectID:e.data("objectID"),objectType:e.data("objectType")}}),this._proxy.sendRequest()},_success:function(t,e,i){var s,a;"manageSubscription"===t.actionName?(null===this._dialog?(this._dialog=$("<div>"+t.returnValues.template+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.user.objectWatch.manageSubscription")})):(this._dialog.html(t.returnValues.template),this._dialog.wcfDialog("open")),this._dialog.find(".formSubmit > .jsButtonSave").data("objectID",t.returnValues.objectID).data("objectType",t.returnValues.objectType).click($.proxy(this._save,this)),s=this._dialog.find("input[name=enableNotification]").disable(),this._dialog.find("input[name=subscribe]").change(function(t){1==$(t.currentTarget).val()?s.enable():s.disable()}),(a=this._dialog.find("input[name=subscribe]:checked")).length&&1==a.val()&&s.enable()):"saveSubscription"===t.actionName&&this._dialog.is(":visible")&&(this._dialog.wcfDialog("close"),this._updateSubscriptionStatus({isSubscribed:t.returnValues.subscribe,objectID:t.returnValues.objectID}),null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.global.success.edit"))),this._notification.show())},_save:function(t){var e=this._buttons[$(t.currentTarget).data("objectType")][$(t.currentTarget).data("objectID")],i=this._dialog.find("input[name=subscribe]:checked").val(),s=this._dialog.find("input[name=enableNotification]").is(":checked")?1:0;this._proxy.setOption("data",{actionName:"saveSubscription",className:"wcf\\data\\user\\object\\watch\\UserObjectWatchAction",parameters:{enableNotification:s,objectID:e.data("objectID"),objectType:e.data("objectType"),subscribe:i}}),this._proxy.sendRequest()},_updateSubscriptionStatus:function(t){var e=$(this._buttonSelector+"[data-object-id="+t.objectID+"]"),i=e.children(".icon");if(t.isSubscribed)i.removeClass("fa-bookmark-o").addClass("fa-bookmark"),e.data("isSubscribed",!0);else if(e.data("removeOnUnsubscribe")?e.parent().remove():(i.removeClass("fa-bookmark").addClass("fa-bookmark-o"),e.data("isSubscribed",!1)),this._reloadOnUnsubscribe)return void window.location.reload();WCF.System.Event.fireEvent("com.woltlab.wcf.objectWatch","updatedSubscription",t)}}); })(this);
 
 // WCF.Moderation.js
-(function (window, undefined) { "use strict";WCF.Moderation={},WCF.Moderation.Management=Class.extend({_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:null,_languageItem:"",_proxy:null,_queueID:0,_redirectURL:"",init:function(e,t,i){return this._buttonSelector?this._className?(this._dialog=null,this._queueID=e,this._redirectURL=t,this._languageItem=i,this._proxy=new WCF.Action.Proxy({failure:$.proxy(this._failure,this),success:$.proxy(this._success,this)}),$(this._buttonSelector).click($.proxy(this._click,this)),void $("#moderationAssignUser").click($.proxy(this._clickAssignedUser,this))):void console.debug("[WCF.Moderation.Management] Missing class name, aborting."):void console.debug("[WCF.Moderation.Management] Missing button selector, aborting.")},_click:function(e){var t=$(e.currentTarget).wcfIdentify(),i="";this._confirmationTemplate[t]&&(i=this._confirmationTemplate[t]),WCF.System.Confirmation.show(WCF.Language.get(this._languageItem.replace(/{actionName}/,t)),$.proxy(function(e,i,a){if("confirm"===e){var o={actionName:t,className:this._className,objectIDs:[this._queueID]};this._confirmationTemplate[t]&&(o.parameters={},$(a).find("input, textarea").each(function(e,t){var i=$(t),a=i.val();"input"===i.getTagName()&&"checkbox"===i.attr("type")&&(i.is(":checked")||(a=null)),null!==a&&(o.parameters[i.attr("name")]=a)})),this._proxy.setOption("data",o),this._proxy.sendRequest(),$(this._buttonSelector).disable()}},this),{},i)},_clickAssignedUser:function(){this._proxy.setOption("data",{actionName:"getAssignUserForm",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[this._queueID]}),this._proxy.sendRequest()},_success:function(e,t,i){switch(e.actionName){case"getAssignUserForm":null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.template).wcfDialog({title:WCF.Language.get("wcf.moderation.assignedUser")})):this._dialog.html(e.returnValues.template).wcfDialog("open"),this._dialog.find("button[data-type=submit]").click($.proxy(this._assignUser,this));break;case"assignUser":var a=$("#moderationAssignedUserContainer > dd > span").empty();e.returnValues.userID?$('<a href="'+e.returnValues.link+'" data-user-id="'+e.returnValues.userID+'" class="userLink">'+WCF.String.escapeHTML(e.returnValues.username)+"</a>").appendTo(a):a.append(e.returnValues.username),a.append(" "),e.returnValues.newStatus&&$("#moderationStatusContainer > dd").text(WCF.Language.get("wcf.moderation.status."+e.returnValues.newStatus)),this._dialog.wcfDialog("close"),(new WCF.System.Notification).show();break;default:var o=this;new WCF.System.Notification(WCF.Language.get("wcf.global.success")).show(function(){window.location=o._redirectURL})}},_failure:function(e,t,i,a){if(e.returnValues&&e.returnValues.fieldName&&"assignedUsername"==e.returnValues.fieldName){this._dialog.find("small.innerError").remove();var o="";switch(e.returnValues.errorType){case"empty":o=WCF.Language.get("wcf.global.form.error.empty");break;case"notAffected":o=WCF.Language.get("wcf.moderation.assignedUser.error.notAffected");break;default:o=WCF.Language.get("wcf.user.username.error."+e.returnValues.errorType,{username:this._dialog.find("#assignedUsername").val()})}return $('<small class="innerError">'+o+"</small>").insertAfter(this._dialog.find("#assignedUsername")),!1}return!0},_assignUser:function(){var e=this._dialog.find("input[name=assignedUserID]:checked").val(),t="";if(-1==e&&(t=$.trim(this._dialog.find("#assignedUsername").val())),-1==e&&0==t.length)return this._dialog.find("small.innerError").remove(),void $('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(this._dialog.find("#assignedUsername"));this._proxy.setOption("data",{actionName:"assignUser",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[this._queueID],parameters:{assignedUserID:e,assignedUsername:t}}),this._proxy.sendRequest()}}),WCF.Moderation.Queue={},WCF.Moderation.Queue.MarkAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(document).on("dblclick",".moderationList .new .columnAvatar",$.proxy(this._dblclick,this))},_dblclick:function(e){this._proxy.setOption("data",{actionName:"markAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[$(e.currentTarget).parents(".moderationQueueEntry:eq(0)").data("queueID")]}),this._proxy.sendRequest()},_success:function(e,t,i){$(".moderationList .new").each(function(t,i){var a=$(i);WCF.inArray(a.data("queueID"),e.objectIDs)&&(a.removeClass("new"),a.find(".columnAvatar").off("dblclick"))})}}),WCF.Moderation.Queue.MarkAllAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".markAllAsReadButton").click($.proxy(this._click,this))},_click:function(e){e.preventDefault(),this._proxy.setOption("data",{actionName:"markAllAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction"}),this._proxy.sendRequest()},_success:function(e,t,i){var a=WCF.Dropdown.Interactive.Handler.getDropdown("outstandingModeration");a&&(a.getLinkList().find(".interactiveDropdownItemMarkAllAsRead").remove(),a.getItemList().find(".interactiveDropdownItemMarkAsRead").remove()),$("#outstandingModeration .badgeUpdate").remove();var o=$(".moderationList");o.find(".new").removeClass("new"),o.find(".columnAvatar").off("dblclick")}}),WCF.Moderation.Activation={},WCF.Moderation.Activation.Management=WCF.Moderation.Management.extend({init:function(e,t){this._buttonSelector="#enableContent, #removeContent",this._className="wcf\\data\\moderation\\queue\\ModerationQueueActivationAction",this._super(e,t,"wcf.moderation.activation.{actionName}.confirmMessage")}}),WCF.Moderation.Report={},WCF.Moderation.Report.Content=Class.extend({_buttons:{},_buttonSelector:"",_dialog:null,_notification:null,_objectID:0,_objectType:"",_proxy:null,init:function(e,t){this._objectType=e,this._buttonSelector=t,this._buttons={},this._notification=null,this._objectID=0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initButtons(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Moderation.Report"+this._objectType.hashCode(),$.proxy(this._initButtons,this))},_initButtons:function(){var e=this;$(this._buttonSelector).each(function(t,i){var a=$(i),o=a.wcfIdentify();e._buttons[o]||(e._buttons[o]=a,a.click($.proxy(e._click,e)))})},_click:function(e){e.preventDefault(),this._objectID=$(e.currentTarget).data("objectID"),this._proxy.setOption("data",{actionName:"prepareReport",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()},_success:function(e,t,i){e.returnValues.reported?(null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.moderation.report.success"))),this._dialog.wcfDialog("close"),this._notification.show()):e.returnValues.template&&(this._showDialog(e.returnValues.template),e.returnValues.alreadyReported||this._dialog.find(".jsSubmitReport").click($.proxy(this._submit,this)))},_showDialog:function(e){null===this._dialog&&(this._dialog=$("#moderationReport"),this._dialog.length||(this._dialog=$('<div id="moderationReport" />').hide().appendTo(document.body))),this._dialog.html(e).wcfDialog({title:WCF.Language.get("wcf.moderation.report.reportContent")}).wcfDialog("render")},_submit:function(){var e=this._dialog.find(".jsReportMessage").val();if(""==$.trim(e))return this._dialog.find(".section > dl").addClass("formError"),void(this._dialog.find(".innerError").length||this._dialog.find(".jsReportMessage").after($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>")));this._proxy.setOption("data",{actionName:"report",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{message:e,objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()}}),WCF.Moderation.Report.Management=WCF.Moderation.Management.extend({init:function(e,t){this._buttonSelector="#removeContent, #removeReport",this._className="wcf\\data\\moderation\\queue\\ModerationQueueReportAction",this._super(e,t,"wcf.moderation.report.{actionName}.confirmMessage"),this._confirmationTemplate.removeContent=$('<div class="section"><dl><dt><label for="message">'+WCF.Language.get("wcf.moderation.report.removeContent.reason")+'</label></dt><dd><textarea name="message" id="message" cols="40" rows="3" /></dd></dl></div>'),this._confirmationTemplate.removeReport=$('<div class="section"><dl><dt></dt><dd><label><input type="checkbox" name="markAsJustified" id="markAsJustified" value="1"> '+WCF.Language.get("wcf.moderation.report.removeReport.markAsJustified")+"</label></dd></dl></div>")}}),WCF.User.Panel.Moderation=WCF.User.Panel.Abstract.extend({init:function(e){e.enableMarkAsRead=!0,this._super($("#outstandingModeration"),"outstandingModeration",e),require(["EventHandler"],function(e){e.add("com.woltlab.wcf.UserMenuMobile","more",function(e){"com.woltlab.wcf.moderation"===e.identifier&&this.toggle()}.bind(this))}.bind(this))},_initDropdown:function(){var e=this._super();return $('<li><a href="'+this._options.deletedContentLink+'" title="'+this._options.deletedContent+'" class="jsTooltip"><span class="icon icon24 fa-trash-o" /></a></li>').appendTo(e.getLinkList()),e},_load:function(){this._proxy.setOption("data",{actionName:"getOutstandingQueues",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction"}),this._proxy.sendRequest()},_markAsRead:function(e,t){this._proxy.setOption("data",{actionName:"markAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[t]}),this._proxy.sendRequest()},_markAllAsRead:function(e){this._proxy.setOption("data",{actionName:"markAllAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction"}),this._proxy.sendRequest()},resetItems:function(){this._super(),this._loadData=!0}}); })(this);
+(function (window, undefined) { "use strict";WCF.Moderation={},WCF.Moderation.Management=Class.extend({_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:null,_languageItem:"",_proxy:null,_queueID:0,_redirectURL:"",init:function(e,t,i){this._buttonSelector?this._className?(this._dialog=null,this._queueID=e,this._redirectURL=t,this._languageItem=i,this._proxy=new WCF.Action.Proxy({failure:$.proxy(this._failure,this),success:$.proxy(this._success,this)}),$(this._buttonSelector).click($.proxy(this._click,this)),$("#moderationAssignUser").click($.proxy(this._clickAssignedUser,this))):console.debug("[WCF.Moderation.Management] Missing class name, aborting."):console.debug("[WCF.Moderation.Management] Missing button selector, aborting.")},_click:function(e){var a=$(e.currentTarget).wcfIdentify(),t="";this._confirmationTemplate[a]&&(t=this._confirmationTemplate[a]),WCF.System.Confirmation.show(WCF.Language.get(this._languageItem.replace(/{actionName}/,a)),$.proxy(function(e,t,i){var o;"confirm"===e&&(o={actionName:a,className:this._className,objectIDs:[this._queueID]},this._confirmationTemplate[a]&&(o.parameters={},$(i).find("input, textarea").each(function(e,t){var i=$(t),a=i.val();"input"===i.getTagName()&&"checkbox"===i.attr("type")&&(i.is(":checked")||(a=null)),null!==a&&(o.parameters[i.attr("name")]=a)})),this._proxy.setOption("data",o),this._proxy.sendRequest(),$(this._buttonSelector).disable())},this),{},t)},_clickAssignedUser:function(){this._proxy.setOption("data",{actionName:"getAssignUserForm",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[this._queueID]}),this._proxy.sendRequest()},_success:function(e,t,i){switch(e.actionName){case"getAssignUserForm":null===this._dialog?(this._dialog=$("<div />").hide().appendTo(document.body),this._dialog.html(e.returnValues.template).wcfDialog({title:WCF.Language.get("wcf.moderation.assignedUser")})):this._dialog.html(e.returnValues.template).wcfDialog("open"),this._dialog.find("button[data-type=submit]").click($.proxy(this._assignUser,this));break;case"assignUser":var a=$("#moderationAssignedUserContainer > dd > span").empty();e.returnValues.userID?$('<a href="'+e.returnValues.link+'" data-object-id="'+e.returnValues.userID+'" class="userLink">'+WCF.String.escapeHTML(e.returnValues.username)+"</a>").appendTo(a):a.append(e.returnValues.username),a.append(" "),e.returnValues.newStatus&&$("#moderationStatusContainer > dd").text(WCF.Language.get("wcf.moderation.status."+e.returnValues.newStatus)),this._dialog.wcfDialog("close"),(new WCF.System.Notification).show();break;default:var o=new WCF.System.Notification(WCF.Language.get("wcf.global.success")),n=this;o.show(function(){window.location=n._redirectURL})}},_failure:function(e,t,i,a){if(e.returnValues&&e.returnValues.fieldName&&"assignedUsername"==e.returnValues.fieldName){this._dialog.find("small.innerError").remove();var o="";switch(e.returnValues.errorType){case"empty":o=WCF.Language.get("wcf.global.form.error.empty");break;case"notAffected":o=WCF.Language.get("wcf.moderation.assignedUser.error.notAffected");break;default:o=WCF.Language.get("wcf.user.username.error."+e.returnValues.errorType,{username:this._dialog.find("#assignedUsername").val()})}return $('<small class="innerError">'+o+"</small>").insertAfter(this._dialog.find("#assignedUsername")),!1}return!0},_assignUser:function(){var e=this._dialog.find("input[name=assignedUserID]:checked").val(),t="";if(-1==e&&(t=$.trim(this._dialog.find("#assignedUsername").val())),-1==e&&0==t.length)return this._dialog.find("small.innerError").remove(),void $('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>").insertAfter(this._dialog.find("#assignedUsername"));this._proxy.setOption("data",{actionName:"assignUser",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[this._queueID],parameters:{assignedUserID:e,assignedUsername:t}}),this._proxy.sendRequest()}}),WCF.Moderation.Queue={},WCF.Moderation.Queue.MarkAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(document).on("dblclick",".moderationList .new .columnAvatar",$.proxy(this._dblclick,this))},_dblclick:function(e){this._proxy.setOption("data",{actionName:"markAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[$(e.currentTarget).parents(".moderationQueueEntry:eq(0)").data("queueID")]}),this._proxy.sendRequest()},_success:function(a,e,t){$(".moderationList .new").each(function(e,t){var i=$(t);WCF.inArray(i.data("queueID"),a.objectIDs)&&(i.removeClass("new"),i.find(".columnAvatar").off("dblclick"))})}}),WCF.Moderation.Queue.MarkAllAsRead=Class.extend({_proxy:null,init:function(){this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),$(".markAllAsReadButton").click($.proxy(this._click,this))},_click:function(e){e.preventDefault(),this._proxy.setOption("data",{actionName:"markAllAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction"}),this._proxy.sendRequest()},_success:function(e,t,i){var a=WCF.Dropdown.Interactive.Handler.getDropdown("outstandingModeration");a&&(a.getLinkList().find(".interactiveDropdownItemMarkAllAsRead").remove(),a.getItemList().find(".interactiveDropdownItemMarkAsRead").remove()),$("#outstandingModeration .badgeUpdate").remove();var o=$(".moderationList");o.find(".new").removeClass("new"),o.find(".columnAvatar").off("dblclick")}}),WCF.Moderation.Activation={},WCF.Moderation.Activation.Management=WCF.Moderation.Management.extend({init:function(e,t){this._buttonSelector="#enableContent, #removeContent",this._className="wcf\\data\\moderation\\queue\\ModerationQueueActivationAction",this._super(e,t,"wcf.moderation.activation.{actionName}.confirmMessage")}}),WCF.Moderation.Report={},WCF.Moderation.Report.Content=Class.extend({_buttons:{},_buttonSelector:"",_dialog:null,_notification:null,_objectID:0,_objectType:"",_proxy:null,init:function(e,t){this._objectType=e,this._buttonSelector=t,this._buttons={},this._notification=null,this._objectID=0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initButtons(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Moderation.Report"+this._objectType.hashCode(),$.proxy(this._initButtons,this))},_initButtons:function(){var o=this;$(this._buttonSelector).each(function(e,t){var i=$(t),a=i.wcfIdentify();o._buttons[a]||(o._buttons[a]=i).click($.proxy(o._click,o))})},_click:function(e){e.preventDefault(),this._objectID=$(e.currentTarget).data("objectID"),this._proxy.setOption("data",{actionName:"prepareReport",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()},_success:function(e,t,i){e.returnValues.reported?(null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.moderation.report.success"))),this._dialog.wcfDialog("close"),this._notification.show()):e.returnValues.template&&(this._showDialog(e.returnValues.template),e.returnValues.alreadyReported||this._dialog.find(".jsSubmitReport").click($.proxy(this._submit,this)))},_showDialog:function(e){null===this._dialog&&(this._dialog=$("#moderationReport"),this._dialog.length||(this._dialog=$('<div id="moderationReport" />').hide().appendTo(document.body))),this._dialog.html(e).wcfDialog({title:WCF.Language.get("wcf.moderation.report.reportContent")}).wcfDialog("render")},_submit:function(){var e=this._dialog.find(".jsReportMessage").val();if(""==$.trim(e))return this._dialog.find(".section > dl").addClass("formError"),void(this._dialog.find(".innerError").length||this._dialog.find(".jsReportMessage").after($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>")));this._proxy.setOption("data",{actionName:"report",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{message:e,objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()}}),WCF.Moderation.Report.Management=WCF.Moderation.Management.extend({init:function(e,t){this._buttonSelector="#removeContent, #removeReport",this._className="wcf\\data\\moderation\\queue\\ModerationQueueReportAction",this._super(e,t,"wcf.moderation.report.{actionName}.confirmMessage"),this._confirmationTemplate.removeContent=$('<div class="section"><dl><dt><label for="message">'+WCF.Language.get("wcf.moderation.report.removeContent.reason")+'</label></dt><dd><textarea name="message" id="message" cols="40" rows="3" /></dd></dl></div>'),this._confirmationTemplate.removeReport=$('<div class="section"><dl><dt></dt><dd><label><input type="checkbox" name="markAsJustified" id="markAsJustified" value="1"> '+WCF.Language.get("wcf.moderation.report.removeReport.markAsJustified")+"</label></dd></dl></div>")}}),WCF.User.Panel.Moderation=WCF.User.Panel.Abstract.extend({init:function(e){e.enableMarkAsRead=!0,this._super($("#outstandingModeration"),"outstandingModeration",e),require(["EventHandler"],function(e){e.add("com.woltlab.wcf.UserMenuMobile","more",function(e){"com.woltlab.wcf.moderation"===e.identifier&&this.toggle()}.bind(this))}.bind(this))},_initDropdown:function(){var e=this._super();return $('<li><a href="'+this._options.deletedContentLink+'" title="'+this._options.deletedContent+'" class="jsTooltip"><span class="icon icon24 fa-trash-o" /></a></li>').appendTo(e.getLinkList()),e},_load:function(){this._proxy.setOption("data",{actionName:"getOutstandingQueues",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction"}),this._proxy.sendRequest()},_markAsRead:function(e,t){this._proxy.setOption("data",{actionName:"markAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction",objectIDs:[t]}),this._proxy.sendRequest()},_markAllAsRead:function(e){this._proxy.setOption("data",{actionName:"markAllAsRead",className:"wcf\\data\\moderation\\queue\\ModerationQueueAction"}),this._proxy.sendRequest()},resetItems:function(){this._super(),this._loadData=!0}}); })(this);
 
index 642ca1e8e1fc054be00d3e1186163e222ac126eb..0cfd9c6d2341b6a359d981e5b33b266e38d87d1f 100644 (file)
@@ -1,31 +1,25 @@
 // WCF.Combined.tiny.min.js -- DO NOT EDIT
 
 // 3rdParty/jquery.js
-(function (window, undefined) { !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(e,t,n){t=t||ae;var r,i=t.createElement("script");if(i.text=e,n)for(r in be)n[r]&&(i[r]=n[r]);t.head.appendChild(i).parentNode.removeChild(i)}function r(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?pe[de.call(e)]||"object":typeof e}function i(e){var t=!!e&&"length"in e&&e.length,n=r(e);return!me(e)&&!xe(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function o(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}function a(e,t,n){return me(t)?we.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?we.grep(e,function(e){return e===t!==n}):"string"!=typeof t?we.grep(e,function(e){return fe.call(t,e)>-1!==n}):we.filter(t,e,n)}function s(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function u(e){var t={};return we.each(e.match(Le)||[],function(e,n){t[n]=!0}),t}function l(e){return e}function c(e){throw e}function f(e,t,n,r){var i;try{e&&me(i=e.promise)?i.call(e).done(t).fail(n):e&&me(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}function p(){ae.removeEventListener("DOMContentLoaded",p),e.removeEventListener("load",p),we.ready()}function d(e,t){return t.toUpperCase()}function h(e){return e.replace(Me,"ms-").replace(Re,d)}function g(){this.expando=we.expando+g.uid++}function v(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Be.test(e)?JSON.parse(e):e)}function y(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Fe,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=v(n)}catch(e){}$e.set(e,t,n)}else n=void 0;return n}function m(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return we.css(e,t,"")},u=s(),l=n&&n[3]||(we.cssNumber[t]?"":"px"),c=(we.cssNumber[t]||"px"!==l&&+u)&&ze.exec(we.css(e,t));if(c&&c[3]!==l){for(u/=2,l=l||c[3],c=+u||1;a--;)we.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,we.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function x(e){var t,n=e.ownerDocument,r=e.nodeName,i=Ge[r];return i||(t=n.body.appendChild(n.createElement(r)),i=we.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),Ge[r]=i,i)}function b(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)r=e[o],r.style&&(n=r.style.display,t?("none"===n&&(i[o]=We.get(r,"display")||null,i[o]||(r.style.display="")),""===r.style.display&&Ue(r)&&(i[o]=x(r))):"none"!==n&&(i[o]="none",We.set(r,"display",n)));for(o=0;o<a;o++)null!=i[o]&&(e[o].style.display=i[o]);return e}function w(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&o(e,t)?we.merge([e],n):n}function T(e,t){for(var n=0,r=e.length;n<r;n++)We.set(e[n],"globalEval",!t||We.get(t[n],"globalEval"))}function C(e,t,n,i,o){for(var a,s,u,l,c,f,p=t.createDocumentFragment(),d=[],h=0,g=e.length;h<g;h++)if((a=e[h])||0===a)if("object"===r(a))we.merge(d,a.nodeType?[a]:a);else if(Ze.test(a)){for(s=s||p.appendChild(t.createElement("div")),u=(Qe.exec(a)||["",""])[1].toLowerCase(),l=Ke[u]||Ke._default,s.innerHTML=l[1]+we.htmlPrefilter(a)+l[2],f=l[0];f--;)s=s.lastChild;we.merge(d,s.childNodes),s=p.firstChild,s.textContent=""}else d.push(t.createTextNode(a));for(p.textContent="",h=0;a=d[h++];)if(i&&we.inArray(a,i)>-1)o&&o.push(a);else if(c=we.contains(a.ownerDocument,a),s=w(p.appendChild(a),"script"),c&&T(s),n)for(f=0;a=s[f++];)Je.test(a.type||"")&&n.push(a);return p}function E(){return!0}function k(){return!1}function S(){try{return ae.activeElement}catch(e){}}function D(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)D(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=k;else if(!i)return e;return 1===o&&(a=i,i=function(e){return we().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=we.guid++)),e.each(function(){we.event.add(this,t,i,r,n)})}function N(e,t){return o(e,"table")&&o(11!==t.nodeType?t:t.firstChild,"tr")?we(e).children("tbody")[0]||e:e}function A(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function j(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function q(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(We.hasData(e)&&(o=We.access(e),a=We.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n<r;n++)we.event.add(t,i,l[i][n])}$e.hasData(e)&&(s=$e.access(e),u=we.extend({},s),$e.set(t,u))}}function L(e,t){var n=t.nodeName.toLowerCase();"input"===n&&Ye.test(e.type)?t.checked=e.checked:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}function H(e,t,r,i){t=le.apply([],t);var o,a,s,u,l,c,f=0,p=e.length,d=p-1,h=t[0],g=me(h);if(g||p>1&&"string"==typeof h&&!ye.checkClone&&at.test(h))return e.each(function(n){var o=e.eq(n);g&&(t[0]=h.call(this,n,o.html())),H(o,t,r,i)});if(p&&(o=C(t,e[0].ownerDocument,!1,e,i),a=o.firstChild,1===o.childNodes.length&&(o=a),a||i)){for(s=we.map(w(o,"script"),A),u=s.length;f<p;f++)l=o,f!==d&&(l=we.clone(l,!0,!0),u&&we.merge(s,w(l,"script"))),r.call(e[f],l,f);if(u)for(c=s[s.length-1].ownerDocument,we.map(s,j),f=0;f<u;f++)l=s[f],Je.test(l.type||"")&&!We.access(l,"globalEval")&&we.contains(c,l)&&(l.src&&"module"!==(l.type||"").toLowerCase()?we._evalUrl&&we._evalUrl(l.src):n(l.textContent.replace(st,""),c,l))}return e}function O(e,t,n){for(var r,i=t?we.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||we.cleanData(w(r)),r.parentNode&&(n&&we.contains(r.ownerDocument,r)&&T(w(r,"script")),r.parentNode.removeChild(r));return e}function P(e,t,n){var r,i,o,a,s=e.style;return n=n||lt(e),n&&(a=n.getPropertyValue(t)||n[t],""!==a||we.contains(e.ownerDocument,e)||(a=we.style(e,t)),!ye.pixelBoxStyles()&&ut.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function M(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function R(e){if(e in vt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=gt.length;n--;)if((e=gt[n]+t)in vt)return e}function I(e){var t=we.cssProps[e];return t||(t=we.cssProps[e]=R(e)||e),t}function W(e,t,n){var r=ze.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function $(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=we.css(e,n+Xe[a],!0,i)),r?("content"===n&&(u-=we.css(e,"padding"+Xe[a],!0,i)),"margin"!==n&&(u-=we.css(e,"border"+Xe[a]+"Width",!0,i))):(u+=we.css(e,"padding"+Xe[a],!0,i),"padding"!==n?u+=we.css(e,"border"+Xe[a]+"Width",!0,i):s+=we.css(e,"border"+Xe[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function B(e,t,n){var r=lt(e),i=P(e,t,r),o="border-box"===we.css(e,"boxSizing",!1,r),a=o;if(ut.test(i)){if(!n)return i;i="auto"}return a=a&&(ye.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===we.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+$(e,t,n||(o?"border":"content"),a,r,i)+"px"}function F(e,t,n,r,i){return new F.prototype.init(e,t,n,r,i)}function _(){mt&&(!1===ae.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(_):e.setTimeout(_,we.fx.interval),we.fx.tick())}function z(){return e.setTimeout(function(){yt=void 0}),yt=Date.now()}function X(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)n=Xe[r],i["margin"+n]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function U(e,t,n){for(var r,i=(Y.tweeners[t]||[]).concat(Y.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function V(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&Ue(e),v=We.get(e,"fxshow");n.queue||(a=we._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,we.queue(e,"fx").length||a.empty.fire()})}));for(r in t)if(i=t[r],xt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||we.style(e,r)}if((u=!we.isEmptyObject(t))||!we.isEmptyObject(d)){f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],l=v&&v.display,null==l&&(l=We.get(e,"display")),c=we.css(e,"display"),"none"===c&&(l?c=l:(b([e],!0),l=e.style.display||l,c=we.css(e,"display"),b([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===we.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1;for(r in d)u||(v?"hidden"in v&&(g=v.hidden):v=We.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&b([e],!0),p.done(function(){g||b([e]),We.remove(e,"fxshow");for(r in d)we.style(e,r,d[r])})),u=U(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}}function G(e,t){var n,r,i,o,a;for(n in e)if(r=h(n),i=t[r],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=we.cssHooks[r])&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function Y(e,t,n){var r,i,o=0,a=Y.prefilters.length,s=we.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=yt||z(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(u||s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:we.extend({},t),opts:we.extend(!0,{specialEasing:{},easing:we.easing._default},n),originalProperties:t,originalOptions:n,startTime:yt||z(),duration:n.duration,tweens:[],createTween:function(t,n){var r=we.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(G(c,l.opts.specialEasing);o<a;o++)if(r=Y.prefilters[o].call(l,e,c,l.opts))return me(r.stop)&&(we._queueHooks(l.elem,l.opts.queue).stop=r.stop.bind(r)),r;return we.map(c,U,l),me(l.opts.start)&&l.opts.start.call(e,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),we.fx.timer(we.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l}function Q(e){return(e.match(Le)||[]).join(" ")}function J(e){return e.getAttribute&&e.getAttribute("class")||""}function K(e){return Array.isArray(e)?e:"string"==typeof e?e.match(Le)||[]:[]}function Z(e,t,n,i){var o;if(Array.isArray(t))we.each(t,function(t,r){n||qt.test(e)?i(e,r):Z(e+"["+("object"==typeof r&&null!=r?t:"")+"]",r,n,i)});else if(n||"object"!==r(t))i(e,t);else for(o in t)Z(e+"["+o+"]",t[o],n,i)}function ee(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(Le)||[];if(me(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function te(e,t,n,r){function i(s){var u;return o[s]=!0,we.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===_t;return i(t.dataTypes[0])||!o["*"]&&i("*")}function ne(e,t){var n,r,i=we.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&we.extend(!0,e,r),e}function re(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function ie(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if(s=i.split(" "),s[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}var oe=[],ae=e.document,se=Object.getPrototypeOf,ue=oe.slice,le=oe.concat,ce=oe.push,fe=oe.indexOf,pe={},de=pe.toString,he=pe.hasOwnProperty,ge=he.toString,ve=ge.call(Object),ye={},me=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},xe=function(e){return null!=e&&e===e.window},be={type:!0,src:!0,noModule:!0},we=function(e,t){return new we.fn.init(e,t)},Te=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;we.fn=we.prototype={jquery:"3.3.1",constructor:we,length:0,toArray:function(){return ue.call(this)},get:function(e){return null==e?ue.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=we.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return we.each(this,e)},map:function(e){return this.pushStack(we.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ue.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ce,sort:oe.sort,splice:oe.splice},we.extend=we.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||me(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(we.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&we.isPlainObject(n)?n:{},a[t]=we.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},we.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==de.call(e))&&(!(t=se(e))||"function"==typeof(n=he.call(t,"constructor")&&t.constructor)&&ge.call(n)===ve)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){n(e)},each:function(e,t){var n,r=0;if(i(e))for(n=e.length;r<n&&!1!==t.call(e[r],r,e[r]);r++);else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(Te,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(i(Object(e))?we.merge(n,"string"==typeof e?[e]:e):ce.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:fe.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,o,a=0,s=[];if(i(e))for(r=e.length;a<r;a++)null!=(o=t(e[a],a,n))&&s.push(o);else for(a in e)null!=(o=t(e[a],a,n))&&s.push(o);return le.apply([],s)},guid:1,support:ye}),"function"==typeof Symbol&&(we.fn[Symbol.iterator]=oe[Symbol.iterator]),we.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){pe["[object "+t+"]"]=t.toLowerCase()});var Ce=function(e){function t(e,t,n,r){var i,o,a,s,u,c,p,d=t&&t.ownerDocument,h=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==h&&9!==h&&11!==h)return n;if(!r&&((t?t.ownerDocument||t:W)!==q&&j(t),t=t||q,H)){if(11!==h&&(u=ge.exec(e)))if(i=u[1]){if(9===h){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(d&&(a=d.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(u[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=u[3])&&b.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(b.qsa&&!z[e+" "]&&(!O||!O.test(e))){if(1!==h)d=t,p=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(xe,be):t.setAttribute("id",s=I),c=E(e),o=c.length;o--;)c[o]="#"+s+" "+f(c[o]);p=c.join(","),d=ve.test(e)&&l(t.parentNode)||t}if(p)try{return Q.apply(n,d.querySelectorAll(p)),n}catch(e){}finally{s===I&&t.removeAttribute("id")}}}return S(e.replace(oe,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>w.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[I]=!0,e}function i(e){var t=q.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)w.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&Te(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function u(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function l(e){return e&&void 0!==e.getElementsByTagName&&e}function c(){}function f(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=t.next,o=i||r,a=n&&"parentNode"===o,s=B++;return t.first?function(t,n,i){for(;t=t[r];)if(1===t.nodeType||a)return e(t,n,i);return!1}:function(t,n,u){var l,c,f,p=[$,s];if(u){for(;t=t[r];)if((1===t.nodeType||a)&&e(t,n,u))return!0}else for(;t=t[r];)if(1===t.nodeType||a)if(f=t[I]||(t[I]={}),c=f[t.uniqueID]||(f[t.uniqueID]={}),i&&i===t.nodeName.toLowerCase())t=t[r]||t;else{if((l=c[o])&&l[0]===$&&l[1]===s)return p[2]=l[2];if(c[o]=p,p[2]=e(t,n,u))return!0}return!1}}function d(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function h(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function g(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function v(e,t,n,i,o,a){return i&&!i[I]&&(i=v(i)),o&&!o[I]&&(o=v(o,a)),r(function(r,a,s,u){var l,c,f,p=[],d=[],v=a.length,y=r||h(t||"*",s.nodeType?[s]:s,[]),m=!e||!r&&t?y:g(y,p,e,s,u),x=n?o||(r?e:v||i)?[]:a:m;if(n&&n(m,x,s,u),i)for(l=g(x,d),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[d[c]]=!(m[d[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(m[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?K(r,f):p[c])>-1&&(r[l]=!(a[l]=f))}}else x=g(x===a?x.splice(v,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function y(e){for(var t,n,r,i=e.length,o=w.relative[e[0].type],a=o||w.relative[" "],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return K(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==D)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=w.relative[e[s].type])c=[p(d(c),n)];else{if(n=w.filter[e[s].type].apply(null,e[s].matches),n[I]){for(r=++s;r<i&&!w.relative[e[r].type];r++);return v(s>1&&d(c),s>1&&f(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(oe,"$1"),n,s<r&&y(e.slice(s,r)),r<i&&y(e=e.slice(r)),r<i&&f(e))}c.push(n)}return d(c)}function m(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,p,d=0,h="0",v=r&&[],y=[],m=D,x=r||o&&w.find.TAG("*",l),b=$+=null==m?1:Math.random()||.1,T=x.length;for(l&&(D=a===q||a||l);h!==T&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===q||(j(c),s=!H);p=e[f++];)if(p(c,a||q,s)){u.push(c);break}l&&($=b)}i&&((c=!p&&c)&&d--,r&&v.push(c))}if(d+=h,i&&h!==d){for(f=0;p=n[f++];)p(v,y,a,s);if(r){if(d>0)for(;h--;)v[h]||y[h]||(y[h]=G.call(u));y=g(y)}Q.apply(u,y),l&&!r&&y.length>0&&d+n.length>1&&t.uniqueSort(u)}return l&&($=b,D=m),v};return i?r(a):a}var x,b,w,T,C,E,k,S,D,N,A,j,q,L,H,O,P,M,R,I="sizzle"+1*new Date,W=e.document,$=0,B=0,F=n(),_=n(),z=n(),X=function(e,t){return e===t&&(A=!0),0},U={}.hasOwnProperty,V=[],G=V.pop,Y=V.push,Q=V.push,J=V.slice,K=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},Z="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",ee="[\\x20\\t\\r\\n\\f]",te="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",ne="\\["+ee+"*("+te+")(?:"+ee+"*([*^$|!~]?=)"+ee+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+te+"))|)"+ee+"*\\]",re=":("+te+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+ne+")*)|.*)\\)|)",ie=new RegExp(ee+"+","g"),oe=new RegExp("^"+ee+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ee+"+$","g"),ae=new RegExp("^"+ee+"*,"+ee+"*"),se=new RegExp("^"+ee+"*([>+~]|"+ee+")"+ee+"*"),ue=new RegExp("="+ee+"*([^\\]'\"]*?)"+ee+"*\\]","g"),le=new RegExp(re),ce=new RegExp("^"+te+"$"),fe={ID:new RegExp("^#("+te+")"),CLASS:new RegExp("^\\.("+te+")"),TAG:new RegExp("^("+te+"|[*])"),ATTR:new RegExp("^"+ne),PSEUDO:new RegExp("^"+re),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ee+"*(even|odd|(([+-]|)(\\d*)n|)"+ee+"*(?:([+-]|)"+ee+"*(\\d+)|))"+ee+"*\\)|)","i"),bool:new RegExp("^(?:"+Z+")$","i"),needsContext:new RegExp("^"+ee+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ee+"*((?:-\\d)?\\d*)"+ee+"*\\)|)(?=[^-]|$)","i")},pe=/^(?:input|select|textarea|button)$/i,de=/^h\d$/i,he=/^[^{]+\{\s*\[native \w/,ge=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,ye=new RegExp("\\\\([\\da-f]{1,6}"+ee+"?|("+ee+")|.)","ig"),me=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},xe=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,be=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},we=function(){j()},Te=p(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{Q.apply(V=J.call(W.childNodes),W.childNodes),V[W.childNodes.length].nodeType}catch(e){Q={apply:V.length?function(e,t){Y.apply(e,J.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}b=t.support={},C=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},j=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:W;return r!==q&&9===r.nodeType&&r.documentElement?(q=r,L=q.documentElement,H=!C(q),W!==q&&(n=q.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",we,!1):n.attachEvent&&n.attachEvent("onunload",we)),b.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),b.getElementsByTagName=i(function(e){return e.appendChild(q.createComment("")),!e.getElementsByTagName("*").length}),b.getElementsByClassName=he.test(q.getElementsByClassName),b.getById=i(function(e){return L.appendChild(e).id=I,!q.getElementsByName||!q.getElementsByName(I).length}),b.getById?(w.filter.ID=function(e){var t=e.replace(ye,me);return function(e){return e.getAttribute("id")===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&H){var n=t.getElementById(e);return n?[n]:[]}}):(w.filter.ID=function(e){var t=e.replace(ye,me);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},w.find.ID=function(e,t){if(void 0!==t.getElementById&&H){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),w.find.TAG=b.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):b.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},w.find.CLASS=b.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&H)return t.getElementsByClassName(e)},P=[],O=[],(b.qsa=he.test(q.querySelectorAll))&&(i(function(e){L.appendChild(e).innerHTML="<a id='"+I+"'></a><select id='"+I+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&O.push("[*^$]="+ee+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||O.push("\\["+ee+"*(?:value|"+Z+")"),e.querySelectorAll("[id~="+I+"-]").length||O.push("~="),e.querySelectorAll(":checked").length||O.push(":checked"),e.querySelectorAll("a#"+I+"+*").length||O.push(".#.+[+~]")}),i(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=q.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&O.push("name"+ee+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&O.push(":enabled",":disabled"),L.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&O.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),O.push(",.*:")})),(b.matchesSelector=he.test(M=L.matches||L.webkitMatchesSelector||L.mozMatchesSelector||L.oMatchesSelector||L.msMatchesSelector))&&i(function(e){b.disconnectedMatch=M.call(e,"*"),M.call(e,"[s!='']:x"),P.push("!=",re)}),O=O.length&&new RegExp(O.join("|")),P=P.length&&new RegExp(P.join("|")),t=he.test(L.compareDocumentPosition),R=t||he.test(L.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},X=t?function(e,t){if(e===t)return A=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!b.sortDetached&&t.compareDocumentPosition(e)===n?e===q||e.ownerDocument===W&&R(W,e)?-1:t===q||t.ownerDocument===W&&R(W,t)?1:N?K(N,e)-K(N,t):0:4&n?-1:1)}:function(e,t){if(e===t)return A=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===q?-1:t===q?1:i?-1:o?1:N?K(N,e)-K(N,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===W?-1:u[r]===W?1:0},q):q},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==q&&j(e),n=n.replace(ue,"='$1']"),b.matchesSelector&&H&&!z[n+" "]&&(!P||!P.test(n))&&(!O||!O.test(n)))try{var r=M.call(e,n);if(r||b.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,q,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==q&&j(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==q&&j(e);var n=w.attrHandle[t.toLowerCase()],r=n&&U.call(w.attrHandle,t.toLowerCase())?n(e,t,!H):void 0;return void 0!==r?r:b.attributes||!H?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+"").replace(xe,be)},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(A=!b.detectDuplicates,N=!b.sortStable&&e.slice(0),e.sort(X),A){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return N=null,e},T=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=T(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=T(t);return n},w=t.selectors={cacheLength:50,createPseudo:r,match:fe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ye,me),e[3]=(e[3]||e[4]||e[5]||"").replace(ye,me),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return fe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&le.test(n)&&(t=E(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ye,me).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=F[e+" "];return t||(t=new RegExp("(^|"+ee+")"+e+"("+ee+"|$)"))&&F(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ie," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",v=t.parentNode,y=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(v){if(o){for(;g;){for(p=t;p=p[g];)if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?v.firstChild:v.lastChild],a&&m){for(p=v,f=p[I]||(p[I]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],d=l[0]===$&&l[1],x=d&&l[2],p=d&&v.childNodes[d];p=++d&&p&&p[g]||(x=d=0)||h.pop();)if(1===p.nodeType&&++x&&p===t){c[e]=[$,d,x];break}}else if(m&&(p=t,f=p[I]||(p[I]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),l=c[e]||[],d=l[0]===$&&l[1],x=d),!1===x)for(;(p=++d&&p&&p[g]||(x=d=0)||h.pop())&&((s?p.nodeName.toLowerCase()!==y:1!==p.nodeType)||!++x||(m&&(f=p[I]||(p[I]={}),c=f[p.uniqueID]||(f[p.uniqueID]={}),c[e]=[$,x]),p!==t)););return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=w.pseudos[e]||w.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[I]?o(n):o.length>1?(i=[e,e,"",n],w.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=K(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(oe,"$1"));return i[I]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(ye,me),function(t){return(t.textContent||t.innerText||T(t)).indexOf(e)>-1}}),lang:r(function(e){return ce.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(ye,me).toLowerCase(),function(t){var n;do{if(n=H?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===L},focus:function(e){return e===q.activeElement&&(!q.hasFocus||q.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:s(!1),disabled:s(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,
-!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!w.pseudos.empty(e)},header:function(e){return de.test(e.nodeName)},input:function(e){return pe.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:u(function(){return[0]}),last:u(function(e,t){return[t-1]}),eq:u(function(e,t,n){return[n<0?n+t:n]}),even:u(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:u(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:u(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:u(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},w.pseudos.nth=w.pseudos.eq;for(x in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})w.pseudos[x]=function(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}(x);for(x in{submit:!0,reset:!0})w.pseudos[x]=function(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}(x);return c.prototype=w.filters=w.pseudos,w.setFilters=new c,E=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=_[e+" "];if(c)return n?0:c.slice(0);for(s=e,u=[],l=w.preFilter;s;){r&&!(i=ae.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=se.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(oe," ")}),s=s.slice(r.length));for(a in w.filter)!(i=fe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):_(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=z[e+" "];if(!o){for(t||(t=E(e)),n=t.length;n--;)o=y(t[n]),o[I]?r.push(o):i.push(o);o=z(e,m(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,c="function"==typeof e&&e,p=!r&&E(e=c.selector||e);if(n=n||[],1===p.length){if(o=p[0]=p[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&H&&w.relative[o[1].type]){if(!(t=(w.find.ID(a.matches[0].replace(ye,me),t)||[])[0]))return n;c&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=fe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!w.relative[s=a.type]);)if((u=w.find[s])&&(r=u(a.matches[0].replace(ye,me),ve.test(o[0].type)&&l(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&f(o)))return Q.apply(n,r),n;break}}return(c||k(e,p))(r,t,!H,n,!t||ve.test(e)&&l(t.parentNode)||t),n},b.sortStable=I.split("").sort(X).join("")===I,b.detectDuplicates=!!A,j(),b.sortDetached=i(function(e){return 1&e.compareDocumentPosition(q.createElement("fieldset"))}),i(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),b.attributes&&i(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(Z,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);we.find=Ce,we.expr=Ce.selectors,we.expr[":"]=we.expr.pseudos,we.uniqueSort=we.unique=Ce.uniqueSort,we.text=Ce.getText,we.isXMLDoc=Ce.isXML,we.contains=Ce.contains,we.escapeSelector=Ce.escape;var Ee=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&we(e).is(n))break;r.push(e)}return r},ke=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Se=we.expr.match.needsContext,De=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;we.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?we.find.matchesSelector(r,e)?[r]:[]:we.find.matches(e,we.grep(t,function(e){return 1===e.nodeType}))},we.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(we(e).filter(function(){for(t=0;t<r;t++)if(we.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)we.find(e,i[t],n);return r>1?we.uniqueSort(n):n},filter:function(e){return this.pushStack(a(this,e||[],!1))},not:function(e){return this.pushStack(a(this,e||[],!0))},is:function(e){return!!a(this,"string"==typeof e&&Se.test(e)?we(e):e||[],!1).length}});var Ne,Ae=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(we.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ne,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:Ae.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof we?t[0]:t,we.merge(this,we.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:ae,!0)),De.test(r[1])&&we.isPlainObject(t))for(r in t)me(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=ae.getElementById(r[2]),i&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):me(e)?void 0!==n.ready?n.ready(e):e(we):we.makeArray(e,this)}).prototype=we.fn,Ne=we(ae);var je=/^(?:parents|prev(?:Until|All))/,qe={children:!0,contents:!0,next:!0,prev:!0};we.fn.extend({has:function(e){var t=we(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(we.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&we(e);if(!Se.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&we.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?we.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?fe.call(we(e),this[0]):fe.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(we.uniqueSort(we.merge(this.get(),we(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),we.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return Ee(e,"parentNode")},parentsUntil:function(e,t,n){return Ee(e,"parentNode",n)},next:function(e){return s(e,"nextSibling")},prev:function(e){return s(e,"previousSibling")},nextAll:function(e){return Ee(e,"nextSibling")},prevAll:function(e){return Ee(e,"previousSibling")},nextUntil:function(e,t,n){return Ee(e,"nextSibling",n)},prevUntil:function(e,t,n){return Ee(e,"previousSibling",n)},siblings:function(e){return ke((e.parentNode||{}).firstChild,e)},children:function(e){return ke(e.firstChild)},contents:function(e){return o(e,"iframe")?e.contentDocument:(o(e,"template")&&(e=e.content||e),we.merge([],e.childNodes))}},function(e,t){we.fn[e]=function(n,r){var i=we.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=we.filter(r,i)),this.length>1&&(qe[e]||we.uniqueSort(i),je.test(e)&&i.reverse()),this.pushStack(i)}});var Le=/[^\x20\t\r\n\f]+/g;we.Callbacks=function(e){e="string"==typeof e?u(e):we.extend({},e);var t,n,i,o,a=[],s=[],l=-1,c=function(){for(o=o||e.once,i=t=!0;s.length;l=-1)for(n=s.shift();++l<a.length;)!1===a[l].apply(n[0],n[1])&&e.stopOnFalse&&(l=a.length,n=!1);e.memory||(n=!1),t=!1,o&&(a=n?[]:"")},f={add:function(){return a&&(n&&!t&&(l=a.length-1,s.push(n)),function t(n){we.each(n,function(n,i){me(i)?e.unique&&f.has(i)||a.push(i):i&&i.length&&"string"!==r(i)&&t(i)})}(arguments),n&&!t&&c()),this},remove:function(){return we.each(arguments,function(e,t){for(var n;(n=we.inArray(t,a,n))>-1;)a.splice(n,1),n<=l&&l--}),this},has:function(e){return e?we.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return o=s=[],a=n="",this},disabled:function(){return!a},lock:function(){return o=s=[],n||t||(a=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!i}};return f},we.extend({Deferred:function(t){var n=[["notify","progress",we.Callbacks("memory"),we.Callbacks("memory"),2],["resolve","done",we.Callbacks("once memory"),we.Callbacks("once memory"),0,"resolved"],["reject","fail",we.Callbacks("once memory"),we.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return we.Deferred(function(t){we.each(n,function(n,r){var i=me(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&me(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){function o(t,n,r,i){return function(){var s=this,u=arguments,f=function(){var e,f;if(!(t<a)){if((e=r.apply(s,u))===n.promise())throw new TypeError("Thenable self-resolution");f=e&&("object"==typeof e||"function"==typeof e)&&e.then,me(f)?i?f.call(e,o(a,n,l,i),o(a,n,c,i)):(a++,f.call(e,o(a,n,l,i),o(a,n,c,i),o(a,n,l,n.notifyWith))):(r!==l&&(s=void 0,u=[e]),(i||n.resolveWith)(s,u))}},p=i?f:function(){try{f()}catch(e){we.Deferred.exceptionHook&&we.Deferred.exceptionHook(e,p.stackTrace),t+1>=a&&(r!==c&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?p():(we.Deferred.getStackHook&&(p.stackTrace=we.Deferred.getStackHook()),e.setTimeout(p))}}var a=0;return we.Deferred(function(e){n[0][3].add(o(0,e,me(i)?i:l,e.notifyWith)),n[1][3].add(o(0,e,me(t)?t:l)),n[2][3].add(o(0,e,me(r)?r:c))}).promise()},promise:function(e){return null!=e?we.extend(e,i):i}},o={};return we.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=ue.call(arguments),o=we.Deferred(),a=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?ue.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(f(e,o.done(a(n)).resolve,o.reject,!t),"pending"===o.state()||me(i[n]&&i[n].then)))return o.then();for(;n--;)f(i[n],a(n),o.reject);return o.promise()}});var He=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;we.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&He.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},we.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=we.Deferred();we.fn.ready=function(e){return Oe.then(e).catch(function(e){we.readyException(e)}),this},we.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--we.readyWait:we.isReady)||(we.isReady=!0,!0!==e&&--we.readyWait>0||Oe.resolveWith(ae,[we]))}}),we.ready.then=Oe.then,"complete"===ae.readyState||"loading"!==ae.readyState&&!ae.documentElement.doScroll?e.setTimeout(we.ready):(ae.addEventListener("DOMContentLoaded",p),e.addEventListener("load",p));var Pe=function(e,t,n,i,o,a,s){var u=0,l=e.length,c=null==n;if("object"===r(n)){o=!0;for(u in n)Pe(e,t,u,n[u],!0,a,s)}else if(void 0!==i&&(o=!0,me(i)||(s=!0),c&&(s?(t.call(e,i),t=null):(c=t,t=function(e,t,n){return c.call(we(e),n)})),t))for(;u<l;u++)t(e[u],n,s?i:i.call(e[u],u,t(e[u],n)));return o?e:c?t.call(e):l?t(e[0],n):a},Me=/^-ms-/,Re=/-([a-z])/g,Ie=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};g.uid=1,g.prototype={cache:function(e){var t=e[this.expando];return t||(t={},Ie(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[h(t)]=n;else for(r in t)i[h(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][h(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){Array.isArray(t)?t=t.map(h):(t=h(t),t=t in r?[t]:t.match(Le)||[]),n=t.length;for(;n--;)delete r[t[n]]}(void 0===t||we.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!we.isEmptyObject(t)}};var We=new g,$e=new g,Be=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Fe=/[A-Z]/g;we.extend({hasData:function(e){return $e.hasData(e)||We.hasData(e)},data:function(e,t,n){return $e.access(e,t,n)},removeData:function(e,t){$e.remove(e,t)},_data:function(e,t,n){return We.access(e,t,n)},_removeData:function(e,t){We.remove(e,t)}}),we.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=$e.get(o),1===o.nodeType&&!We.get(o,"hasDataAttrs"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf("data-")&&(r=h(r.slice(5)),y(o,r,i[r])));We.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){$e.set(this,e)}):Pe(this,function(t){var n;if(o&&void 0===t){if(void 0!==(n=$e.get(o,e)))return n;if(void 0!==(n=y(o,e)))return n}else this.each(function(){$e.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){$e.remove(this,e)})}}),we.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=We.get(e,t),n&&(!r||Array.isArray(n)?r=We.access(e,t,we.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=we.queue(e,t),r=n.length,i=n.shift(),o=we._queueHooks(e,t),a=function(){we.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return We.get(e,n)||We.access(e,n,{empty:we.Callbacks("once memory").add(function(){We.remove(e,[t+"queue",n])})})}}),we.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?we.queue(this[0],e):void 0===t?this:this.each(function(){var n=we.queue(this,e,t);we._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&we.dequeue(this,e)})},dequeue:function(e){return this.each(function(){we.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=we.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";a--;)(n=We.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var _e=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ze=new RegExp("^(?:([+-])=|)("+_e+")([a-z%]*)$","i"),Xe=["Top","Right","Bottom","Left"],Ue=function(e,t){return e=t||e,"none"===e.style.display||""===e.style.display&&we.contains(e.ownerDocument,e)&&"none"===we.css(e,"display")},Ve=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},Ge={};we.fn.extend({show:function(){return b(this,!0)},hide:function(){return b(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Ue(this)?we(this).show():we(this).hide()})}});var Ye=/^(?:checkbox|radio)$/i,Qe=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,Je=/^$|^module$|\/(?:java|ecma)script/i,Ke={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};Ke.optgroup=Ke.option,Ke.tbody=Ke.tfoot=Ke.colgroup=Ke.caption=Ke.thead,Ke.th=Ke.td;var Ze=/<|&#?\w+;/;!function(){var e=ae.createDocumentFragment(),t=e.appendChild(ae.createElement("div")),n=ae.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),ye.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="<textarea>x</textarea>",ye.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var et=ae.documentElement,tt=/^key/,nt=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,rt=/^([^.]*)(?:\.(.+)|)/;we.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=We.get(e);if(v)for(n.handler&&(o=n,n=o.handler,i=o.selector),i&&we.find.matchesSelector(et,i),n.guid||(n.guid=we.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(t){return void 0!==we&&we.event.triggered!==t.type?we.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(Le)||[""],l=t.length;l--;)s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d&&(f=we.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=we.event.special[d]||{},c=we.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&we.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||(p=u[d]=[],p.delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),we.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=We.hasData(e)&&We.get(e);if(v&&(u=v.events)){for(t=(t||"").match(Le)||[""],l=t.length;l--;)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){for(f=we.event.special[d]||{},d=(r?f.delegateType:f.bindType)||d,p=u[d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||we.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)we.event.remove(e,d+t[l],n,r,!0);we.isEmptyObject(u)&&We.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=we.event.fix(e),u=new Array(arguments.length),l=(We.get(this,"events")||{})[s.type]||[],c=we.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){for(a=we.event.handlers.call(this,s,l),t=0;(i=a[t++])&&!s.isPropagationStopped();)for(s.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!s.isImmediatePropagationStopped();)s.rnamespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((we.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&e.button>=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)r=t[n],i=r.selector+" ",void 0===a[i]&&(a[i]=r.needsContext?we(i,this).index(l)>-1:we.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(e,t){Object.defineProperty(we.Event.prototype,e,{enumerable:!0,configurable:!0,get:me(t)?function(){if(this.originalEvent)return t(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[e]},set:function(t){Object.defineProperty(this,e,{enumerable:!0,configurable:!0,writable:!0,value:t})}})},fix:function(e){return e[we.expando]?e:new we.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==S()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===S()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&o(this,"input"))return this.click(),!1},_default:function(e){return o(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},we.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},we.Event=function(e,t){if(!(this instanceof we.Event))return new we.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?E:k,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&we.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[we.expando]=!0},we.Event.prototype={constructor:we.Event,isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=E,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=E,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=E,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},we.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&tt.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&nt.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},we.event.addProp),we.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){we.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||we.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),we.fn.extend({on:function(e,t,n,r){return D(this,e,t,n,r)},one:function(e,t,n,r){return D(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,we(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=k),this.each(function(){we.event.remove(this,e,n,t)})}});var it=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,ot=/<script|<style|<link/i,at=/checked\s*(?:[^=]|=\s*.checked.)/i,st=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;we.extend({htmlPrefilter:function(e){return e.replace(it,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=we.contains(e.ownerDocument,e);if(!(ye.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||we.isXMLDoc(e)))for(a=w(s),o=w(e),r=0,i=o.length;r<i;r++)L(o[r],a[r]);if(t)if(n)for(o=o||w(e),a=a||w(s),r=0,i=o.length;r<i;r++)q(o[r],a[r]);else q(e,s);return a=w(s,"script"),a.length>0&&T(a,!u&&w(e,"script")),s},cleanData:function(e){for(var t,n,r,i=we.event.special,o=0;void 0!==(n=e[o]);o++)if(Ie(n)){if(t=n[We.expando]){if(t.events)for(r in t.events)i[r]?we.event.remove(n,r):we.removeEvent(n,r,t.handle);n[We.expando]=void 0}n[$e.expando]&&(n[$e.expando]=void 0)}}}),we.fn.extend({detach:function(e){return O(this,e,!0)},remove:function(e){return O(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?we.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return H(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){N(this,e).appendChild(e)}})},prepend:function(){return H(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=N(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return H(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return H(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(we.cleanData(w(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return we.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ot.test(e)&&!Ke[(Qe.exec(e)||["",""])[1].toLowerCase()]){e=we.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(we.cleanData(w(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return H(this,arguments,function(t){var n=this.parentNode;we.inArray(this,e)<0&&(we.cleanData(w(this)),n&&n.replaceChild(t,this))},e)}}),we.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){we.fn[e]=function(e){for(var n,r=[],i=we(e),o=i.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),we(i[a])[t](n),ce.apply(r,n.get());return this.pushStack(r)}});var ut=new RegExp("^("+_e+")(?!px)[a-z%]+$","i"),lt=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},ct=new RegExp(Xe.join("|"),"i");!function(){function t(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",et.appendChild(u).appendChild(l);var t=e.getComputedStyle(l);r="1%"!==t.top,s=12===n(t.marginLeft),l.style.right="60%",a=36===n(t.right),i=36===n(t.width),l.style.position="absolute",o=36===l.offsetWidth||"absolute",et.removeChild(u),l=null}}function n(e){return Math.round(parseFloat(e))}var r,i,o,a,s,u=ae.createElement("div"),l=ae.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",ye.clearCloneStyle="content-box"===l.style.backgroundClip,we.extend(ye,{boxSizingReliable:function(){return t(),i},pixelBoxStyles:function(){return t(),a},pixelPosition:function(){return t(),r},reliableMarginLeft:function(){return t(),s},scrollboxSize:function(){return t(),o}}))}();var ft=/^(none|table(?!-c[ea]).+)/,pt=/^--/,dt={position:"absolute",visibility:"hidden",display:"block"},ht={letterSpacing:"0",fontWeight:"400"},gt=["Webkit","Moz","ms"],vt=ae.createElement("div").style;we.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=P(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=h(t),u=pt.test(t),l=e.style;if(u||(t=I(s)),a=we.cssHooks[t]||we.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];o=typeof n,"string"===o&&(i=ze.exec(n))&&i[1]&&(n=m(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(we.cssNumber[s]?"":"px")),ye.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=h(t);return pt.test(t)||(t=I(s)),a=we.cssHooks[t]||we.cssHooks[s],a&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=P(e,t,r)),"normal"===i&&t in ht&&(i=ht[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),we.each(["height","width"],function(e,t){we.cssHooks[t]={get:function(e,n,r){if(n)return!ft.test(we.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?B(e,t,r):Ve(e,dt,function(){return B(e,t,r)})},set:function(e,n,r){var i,o=lt(e),a="border-box"===we.css(e,"boxSizing",!1,o),s=r&&$(e,t,r,a,o);return a&&ye.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-$(e,t,"border",!1,o)-.5)),s&&(i=ze.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=we.css(e,t)),W(e,n,s)}}}),we.cssHooks.marginLeft=M(ye.reliableMarginLeft,function(e,t){if(t)return(parseFloat(P(e,"marginLeft"))||e.getBoundingClientRect().left-Ve(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),we.each({margin:"",padding:"",border:"Width"},function(e,t){we.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+Xe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(we.cssHooks[e+t].set=W)}),we.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=lt(e),i=t.length;a<i;a++)o[t[a]]=we.css(e,t[a],!1,r);return o}return void 0!==n?we.style(e,t,n):we.css(e,t)},e,t,arguments.length>1)}}),we.Tween=F,F.prototype={constructor:F,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||we.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(we.cssNumber[n]?"":"px")},cur:function(){var e=F.propHooks[this.prop];return e&&e.get?e.get(this):F.propHooks._default.get(this)},run:function(e){var t,n=F.propHooks[this.prop];return this.options.duration?this.pos=t=we.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):F.propHooks._default.set(this),this}},F.prototype.init.prototype=F.prototype,F.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=we.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){we.fx.step[e.prop]?we.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[we.cssProps[e.prop]]&&!we.cssHooks[e.prop]?e.elem[e.prop]=e.now:we.style(e.elem,e.prop,e.now+e.unit)}}},F.propHooks.scrollTop=F.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},we.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},we.fx=F.prototype.init,we.fx.step={};var yt,mt,xt=/^(?:toggle|show|hide)$/,bt=/queueHooks$/;we.Animation=we.extend(Y,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return m(n.elem,e,ze.exec(t),n),n}]},tweener:function(e,t){me(e)?(t=e,e=["*"]):e=e.match(Le);for(var n,r=0,i=e.length;r<i;r++)n=e[r],Y.tweeners[n]=Y.tweeners[n]||[],Y.tweeners[n].unshift(t)},prefilters:[V],prefilter:function(e,t){t?Y.prefilters.unshift(e):Y.prefilters.push(e)}}),we.speed=function(e,t,n){var r=e&&"object"==typeof e?we.extend({},e):{complete:n||!n&&t||me(e)&&e,duration:e,easing:n&&t||t&&!me(t)&&t};return we.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in we.fx.speeds?r.duration=we.fx.speeds[r.duration]:r.duration=we.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){me(r.old)&&r.old.call(this),r.queue&&we.dequeue(this,r.queue)},r},we.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Ue).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=we.isEmptyObject(e),o=we.speed(t,n,r),a=function(){var t=Y(this,we.extend({},e),o);(i||We.get(this,"finish"))&&t.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&!1!==e&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=we.timers,a=We.get(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&bt.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||we.dequeue(this,e)})},finish:function(e){return!1!==e&&(e=e||"fx"),
-this.each(function(){var t,n=We.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=we.timers,a=r?r.length:0;for(n.finish=!0,we.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),we.each(["toggle","show","hide"],function(e,t){var n=we.fn[t];we.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(X(t,!0),e,r,i)}}),we.each({slideDown:X("show"),slideUp:X("hide"),slideToggle:X("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){we.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),we.timers=[],we.fx.tick=function(){var e,t=0,n=we.timers;for(yt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||we.fx.stop(),yt=void 0},we.fx.timer=function(e){we.timers.push(e),we.fx.start()},we.fx.interval=13,we.fx.start=function(){mt||(mt=!0,_())},we.fx.stop=function(){mt=null},we.fx.speeds={slow:600,fast:200,_default:400},we.fn.delay=function(t,n){return t=we.fx?we.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e=ae.createElement("input"),t=ae.createElement("select"),n=t.appendChild(ae.createElement("option"));e.type="checkbox",ye.checkOn=""!==e.value,ye.optSelected=n.selected,e=ae.createElement("input"),e.value="t",e.type="radio",ye.radioValue="t"===e.value}();var wt,Tt=we.expr.attrHandle;we.fn.extend({attr:function(e,t){return Pe(this,we.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){we.removeAttr(this,e)})}}),we.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?we.prop(e,t,n):(1===o&&we.isXMLDoc(e)||(i=we.attrHooks[t.toLowerCase()]||(we.expr.match.bool.test(t)?wt:void 0)),void 0!==n?null===n?void we.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=we.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!ye.radioValue&&"radio"===t&&o(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(Le);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),wt={set:function(e,t,n){return!1===t?we.removeAttr(e,n):e.setAttribute(n,n),n}},we.each(we.expr.match.bool.source.match(/\w+/g),function(e,t){var n=Tt[t]||we.find.attr;Tt[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=Tt[a],Tt[a]=i,i=null!=n(e,t,r)?a:null,Tt[a]=o),i}});var Ct=/^(?:input|select|textarea|button)$/i,Et=/^(?:a|area)$/i;we.fn.extend({prop:function(e,t){return Pe(this,we.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[we.propFix[e]||e]})}}),we.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&we.isXMLDoc(e)||(t=we.propFix[t]||t,i=we.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=we.find.attr(e,"tabindex");return t?parseInt(t,10):Ct.test(e.nodeName)||Et.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),ye.optSelected||(we.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),we.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){we.propFix[this.toLowerCase()]=this}),we.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(me(e))return this.each(function(t){we(this).addClass(e.call(this,t,J(this)))});if(t=K(e),t.length)for(;n=this[u++];)if(i=J(n),r=1===n.nodeType&&" "+Q(i)+" "){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");s=Q(r),i!==s&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(me(e))return this.each(function(t){we(this).removeClass(e.call(this,t,J(this)))});if(!arguments.length)return this.attr("class","");if(t=K(e),t.length)for(;n=this[u++];)if(i=J(n),r=1===n.nodeType&&" "+Q(i)+" "){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");s=Q(r),i!==s&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):me(e)?this.each(function(n){we(this).toggleClass(e.call(this,n,J(this),t),t)}):this.each(function(){var t,i,o,a;if(r)for(i=0,o=we(this),a=K(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||(t=J(this),t&&We.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":We.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+Q(J(n))+" ").indexOf(t)>-1)return!0;return!1}});var kt=/\r/g;we.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=me(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,we(this).val()):e,null==i?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=we.map(i,function(e){return null==e?"":e+""})),(t=we.valHooks[this.type]||we.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=we.valHooks[i.type]||we.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"==typeof n?n.replace(kt,""):null==n?"":n)}}}),we.extend({valHooks:{option:{get:function(e){var t=we.find.attr(e,"value");return null!=t?t:Q(we.text(e))}},select:{get:function(e){var t,n,r,i=e.options,a=e.selectedIndex,s="select-one"===e.type,u=s?null:[],l=s?a+1:i.length;for(r=a<0?l:s?a:0;r<l;r++)if(n=i[r],(n.selected||r===a)&&!n.disabled&&(!n.parentNode.disabled||!o(n.parentNode,"optgroup"))){if(t=we(n).val(),s)return t;u.push(t)}return u},set:function(e,t){for(var n,r,i=e.options,o=we.makeArray(t),a=i.length;a--;)r=i[a],(r.selected=we.inArray(we.valHooks.option.get(r),o)>-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),we.each(["radio","checkbox"],function(){we.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=we.inArray(we(e).val(),t)>-1}},ye.checkOn||(we.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),ye.focusin="onfocusin"in e;var St=/^(?:focusinfocus|focusoutblur)$/,Dt=function(e){e.stopPropagation()};we.extend(we.event,{trigger:function(t,n,r,i){var o,a,s,u,l,c,f,p,d=[r||ae],h=he.call(t,"type")?t.type:t,g=he.call(t,"namespace")?t.namespace.split("."):[];if(a=p=s=r=r||ae,3!==r.nodeType&&8!==r.nodeType&&!St.test(h+we.event.triggered)&&(h.indexOf(".")>-1&&(g=h.split("."),h=g.shift(),g.sort()),l=h.indexOf(":")<0&&"on"+h,t=t[we.expando]?t:new we.Event(h,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:we.makeArray(n,[t]),f=we.event.special[h]||{},i||!f.trigger||!1!==f.trigger.apply(r,n))){if(!i&&!f.noBubble&&!xe(r)){for(u=f.delegateType||h,St.test(u+h)||(a=a.parentNode);a;a=a.parentNode)d.push(a),s=a;s===(r.ownerDocument||ae)&&d.push(s.defaultView||s.parentWindow||e)}for(o=0;(a=d[o++])&&!t.isPropagationStopped();)p=a,t.type=o>1?u:f.bindType||h,c=(We.get(a,"events")||{})[t.type]&&We.get(a,"handle"),c&&c.apply(a,n),(c=l&&a[l])&&c.apply&&Ie(a)&&(t.result=c.apply(a,n),!1===t.result&&t.preventDefault());return t.type=h,i||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(d.pop(),n)||!Ie(r)||l&&me(r[h])&&!xe(r)&&(s=r[l],s&&(r[l]=null),we.event.triggered=h,t.isPropagationStopped()&&p.addEventListener(h,Dt),r[h](),t.isPropagationStopped()&&p.removeEventListener(h,Dt),we.event.triggered=void 0,s&&(r[l]=s)),t.result}},simulate:function(e,t,n){var r=we.extend(new we.Event,n,{type:e,isSimulated:!0});we.event.trigger(r,null,t)}}),we.fn.extend({trigger:function(e,t){return this.each(function(){we.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return we.event.trigger(e,t,n,!0)}}),ye.focusin||we.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){we.event.simulate(t,e.target,we.event.fix(e))};we.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=We.access(r,t);i||r.addEventListener(e,n,!0),We.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=We.access(r,t)-1;i?We.access(r,t,i):(r.removeEventListener(e,n,!0),We.remove(r,t))}}});var Nt=e.location,At=Date.now(),jt=/\?/;we.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||we.error("Invalid XML: "+t),n};var qt=/\[\]$/,Lt=/\r?\n/g,Ht=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;we.param=function(e,t){var n,r=[],i=function(e,t){var n=me(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!we.isPlainObject(e))we.each(e,function(){i(this.name,this.value)});else for(n in e)Z(n,e[n],t,i);return r.join("&")},we.fn.extend({serialize:function(){return we.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=we.prop(this,"elements");return e?we.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!we(this).is(":disabled")&&Ot.test(this.nodeName)&&!Ht.test(e)&&(this.checked||!Ye.test(e))}).map(function(e,t){var n=we(this).val();return null==n?null:Array.isArray(n)?we.map(n,function(e){return{name:t.name,value:e.replace(Lt,"\r\n")}}):{name:t.name,value:n.replace(Lt,"\r\n")}}).get()}});var Pt=/%20/g,Mt=/#.*$/,Rt=/([?&])_=[^&]*/,It=/^(.*?):[ \t]*([^\r\n]*)$/gm,Wt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,$t=/^(?:GET|HEAD)$/,Bt=/^\/\//,Ft={},_t={},zt="*/".concat("*"),Xt=ae.createElement("a");Xt.href=Nt.href,we.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Nt.href,type:"GET",isLocal:Wt.test(Nt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":we.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?ne(ne(e,we.ajaxSettings),t):ne(we.ajaxSettings,e)},ajaxPrefilter:ee(Ft),ajaxTransport:ee(_t),ajax:function(t,n){function r(t,n,r,s){var l,p,d,b,w,T=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",C.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=re(h,C,r)),b=ie(h,b,C,l),l?(h.ifModified&&(w=C.getResponseHeader("Last-Modified"),w&&(we.lastModified[o]=w),(w=C.getResponseHeader("etag"))&&(we.etag[o]=w)),204===t||"HEAD"===h.type?T="nocontent":304===t?T="notmodified":(T=b.state,p=b.data,d=b.error,l=!d)):(d=T,!t&&T||(T="error",t<0&&(t=0))),C.status=t,C.statusText=(n||T)+"",l?y.resolveWith(g,[p,T,C]):y.rejectWith(g,[C,T,d]),C.statusCode(x),x=void 0,f&&v.trigger(l?"ajaxSuccess":"ajaxError",[C,h,l?p:d]),m.fireWith(g,[C,T]),f&&(v.trigger("ajaxComplete",[C,h]),--we.active||we.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=we.ajaxSetup({},n),g=h.context||h,v=h.context&&(g.nodeType||g.jquery)?we(g):we.event,y=we.Deferred(),m=we.Callbacks("once memory"),x=h.statusCode||{},b={},w={},T="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=It.exec(a);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)C.always(e[C.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return i&&i.abort(t),r(0,t),this}};if(y.promise(C),h.url=((t||h.url||Nt.href)+"").replace(Bt,Nt.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(Le)||[""],null==h.crossDomain){l=ae.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Xt.protocol+"//"+Xt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=we.param(h.data,h.traditional)),te(Ft,h,n,C),c)return C;f=we.event&&h.global,f&&0==we.active++&&we.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!$t.test(h.type),o=h.url.replace(Mt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Pt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(jt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Rt,"$1"),d=(jt.test(o)?"&":"?")+"_="+At+++d),h.url=o+d),h.ifModified&&(we.lastModified[o]&&C.setRequestHeader("If-Modified-Since",we.lastModified[o]),we.etag[o]&&C.setRequestHeader("If-None-Match",we.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&C.setRequestHeader("Content-Type",h.contentType),C.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+zt+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)C.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,C,h)||c))return C.abort();if(T="abort",m.add(h.complete),C.done(h.success),C.fail(h.error),i=te(_t,h,n,C)){if(C.readyState=1,f&&v.trigger("ajaxSend",[C,h]),c)return C;h.async&&h.timeout>0&&(u=e.setTimeout(function(){C.abort("timeout")},h.timeout));try{c=!1,i.send(b,r)}catch(e){if(c)throw e;r(-1,e)}}else r(-1,"No Transport");return C},getJSON:function(e,t,n){return we.get(e,t,n,"json")},getScript:function(e,t){return we.get(e,void 0,t,"script")}}),we.each(["get","post"],function(e,t){we[t]=function(e,n,r,i){return me(n)&&(i=i||r,r=n,n=void 0),we.ajax(we.extend({url:e,type:t,dataType:i,data:n,success:r},we.isPlainObject(e)&&e))}}),we._evalUrl=function(e){return we.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},we.fn.extend({wrapAll:function(e){var t;return this[0]&&(me(e)&&(e=e.call(this[0])),t=we(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return me(e)?this.each(function(t){we(this).wrapInner(e.call(this,t))}):this.each(function(){var t=we(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=me(e);return this.each(function(n){we(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){we(this).replaceWith(this.childNodes)}),this}}),we.expr.pseudos.hidden=function(e){return!we.expr.pseudos.visible(e)},we.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},we.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Vt=we.ajaxSettings.xhr();ye.cors=!!Vt&&"withCredentials"in Vt,ye.ajax=Vt=!!Vt,we.ajaxTransport(function(t){var n,r;if(ye.cors||Vt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Ut[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),we.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),we.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return we.globalEval(e),e}}}),we.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),we.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=we("<script>").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),ae.head.appendChild(t[0])},abort:function(){n&&n()}}}});var Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;we.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||we.expando+"_"+At++;return this[e]=!0,e}}),we.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Yt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=me(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Yt,"$1"+i):!1!==t.jsonp&&(t.url+=(jt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||we.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?we(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Gt.push(i)),a&&me(o)&&o(a[0]),a=o=void 0}),"script"}),ye.createHTMLDocument=function(){var e=ae.implementation.createHTMLDocument("").body;return e.innerHTML="<form></form><form></form>",2===e.childNodes.length}(),we.parseHTML=function(e,t,n){if("string"!=typeof e)return[];"boolean"==typeof t&&(n=t,t=!1);var r,i,o;return t||(ye.createHTMLDocument?(t=ae.implementation.createHTMLDocument(""),r=t.createElement("base"),r.href=ae.location.href,t.head.appendChild(r)):t=ae),i=De.exec(e),o=!n&&[],i?[t.createElement(i[1])]:(i=C([e],t,o),o&&o.length&&we(o).remove(),we.merge([],i.childNodes))},we.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=Q(e.slice(s)),e=e.slice(0,s)),me(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&we.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?we("<div>").append(we.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},we.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){we.fn[t]=function(e){return this.on(t,e)}}),we.expr.pseudos.animated=function(e){return we.grep(we.timers,function(t){return e===t.elem}).length},we.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=we.css(e,"position"),f=we(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=we.css(e,"top"),u=we.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),me(t)&&(t=t.call(e,n,we.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},we.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){we.offset.setOffset(this,e,t)});var t,n,r=this[0];if(r)return r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===we.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===we.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&(i=we(e).offset(),i.top+=we.css(e,"borderTopWidth",!0),i.left+=we.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-we.css(r,"marginTop",!0),left:t.left-i.left-we.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===we.css(e,"position");)e=e.offsetParent;return e||et})}}),we.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;we.fn[e]=function(r){return Pe(this,function(e,r,i){var o;if(xe(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),we.each(["top","left"],function(e,t){we.cssHooks[t]=M(ye.pixelPosition,function(e,n){if(n)return n=P(e,t),ut.test(n)?we(e).position()[t]+"px":n})}),we.each({Height:"height",Width:"width"},function(e,t){we.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){we.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return Pe(this,function(t,n,i){var o;return xe(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?we.css(t,n,s):we.style(t,n,i,s)},t,a?i:void 0,a)}})}),we.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){we.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),we.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),we.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),we.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),me(e))return r=ue.call(arguments,2),i=function(){return e.apply(t||this,r.concat(ue.call(arguments)))},i.guid=e.guid=e.guid||we.guid++,i},we.holdReady=function(e){e?we.readyWait++:we.ready(!0)},we.isArray=Array.isArray,we.parseJSON=JSON.parse,we.nodeName=o,we.isFunction=me,we.isWindow=xe,we.camelCase=h,we.type=r,we.now=Date.now,we.isNumeric=function(e){var t=we.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return we});var Qt=e.jQuery,Jt=e.$;return we.noConflict=function(t){return e.$===we&&(e.$=Jt),t&&e.jQuery===we&&(e.jQuery=Qt),we},t||(e.jQuery=e.$=we),we}); })(this);
+(function (window, undefined) { !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";function g(e){return null!=e&&e===e.window}var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,v=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},x=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},c={type:!0,src:!0,noModule:!0};function b(e,t,n){var r,i=(t=t||E).createElement("script");if(i.text=e,n)for(r in c)n[r]&&(i[r]=n[r]);t.head.appendChild(i).parentNode.removeChild(i)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.3.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!x(e)&&!g(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||x(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(o=i?(i=!1,n&&Array.isArray(n)?n:[]):n&&k.isPlainObject(n)?n:{},a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){b(e)},each:function(e,t){var n,r=0;if(d(e))for(n=e.length;r<n&&!1!==t.call(e[r],r,e[r]);r++);else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!=a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return v.apply([],a)},guid:1,support:m}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){function f(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(65536+r):String.fromCharCode(r>>10|55296,1023&r|56320)}function i(){T()}var e,d,b,o,a,h,p,g,w,u,l,T,C,s,E,v,c,y,m,k="sizzle"+ +new Date,x=n.document,S=0,r=0,D=ae(),N=ae(),A=ae(),j=function(e,t){return e===t&&(l=!0),0},q={}.hasOwnProperty,t=[],L=t.pop,H=t.push,O=t.push,P=t.slice,M=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",I="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",$="\\["+I+"*("+W+")(?:"+I+"*([*^$|!~]?=)"+I+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+W+"))|)"+I+"*\\]",B=":("+W+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+$+")*)|.*)\\)|)",F=new RegExp(I+"+","g"),_=new RegExp("^"+I+"+|((?:^|[^\\\\])(?:\\\\.)*)"+I+"+$","g"),z=new RegExp("^"+I+"*,"+I+"*"),X=new RegExp("^"+I+"*([>+~]|"+I+")"+I+"*"),U=new RegExp("="+I+"*([^\\]'\"]*?)"+I+"*\\]","g"),V=new RegExp(B),G=new RegExp("^"+W+"$"),Y={ID:new RegExp("^#("+W+")"),CLASS:new RegExp("^\\.("+W+")"),TAG:new RegExp("^("+W+"|[*])"),ATTR:new RegExp("^"+$),PSEUDO:new RegExp("^"+B),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+I+"*(even|odd|(([+-]|)(\\d*)n|)"+I+"*(?:([+-]|)"+I+"*(\\d+)|))"+I+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+I+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+I+"*((?:-\\d)?\\d*)"+I+"*\\)|)(?=[^-]|$)","i")},Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+I+"?|("+I+")|.)","ig"),ne=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,re=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},ie=ve(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(x.childNodes),x.childNodes),t[x.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){H.apply(e,P.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function oe(e,t,n,r){var i,o,a,s,u,l,c,f=t&&t.ownerDocument,p=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==p&&9!==p&&11!==p)return n;if(!r&&((t?t.ownerDocument||t:x)!==C&&T(t),t=t||C,E)){if(11!==p&&(u=Z.exec(e)))if(i=u[1]){if(9===p){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&m(t,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,t.getElementsByTagName(e)),n;if((i=u[3])&&d.getElementsByClassName&&t.getElementsByClassName)return O.apply(n,t.getElementsByClassName(i)),n}if(d.qsa&&!A[e+" "]&&(!v||!v.test(e))){if(1!==p)f=t,c=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(ne,re):t.setAttribute("id",s=k),o=(l=h(e)).length;o--;)l[o]="#"+s+" "+ge(l[o]);c=l.join(","),f=ee.test(e)&&de(t.parentNode)||t}if(c)try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){}finally{s===k&&t.removeAttribute("id")}}}return g(e.replace(_,"$1"),t,n,r)}function ae(){var n=[];function r(e,t){return n.push(e+" ")>b.cacheLength&&delete r[n.shift()],r[e+" "]=t}return r}function se(e){return e[k]=!0,e}function ue(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),r=n.length;r--;)b.attrHandle[n[r]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ie(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function pe(a){return se(function(o){return o=+o,se(function(e,t){for(var n,r=a([],e.length,o),i=r.length;i--;)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function de(e){return e&&void 0!==e.getElementsByTagName&&e}for(e in d=oe.support={},a=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},T=oe.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:x;return r!==C&&9===r.nodeType&&r.documentElement&&(s=(C=r).documentElement,E=!a(C),x!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",i,!1):n.attachEvent&&n.attachEvent("onunload",i)),d.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ue(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ue(function(e){return s.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,f);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,f);return function(e){var t=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if(void 0!==t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"!==e)return o;for(;n=o[i++];)1===n.nodeType&&r.push(n);return r},b.find.CLASS=d.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&E)return t.getElementsByClassName(e)},c=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ue(function(e){s.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+I+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+I+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ue(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+I+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),s.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(y=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.oMatchesSelector||s.msMatchesSelector))&&ue(function(e){d.disconnectedMatch=y.call(e,"*"),y.call(e,"[s!='']:x"),c.push("!=",B)}),v=v.length&&new RegExp(v.join("|")),c=c.length&&new RegExp(c.join("|")),t=K.test(s.compareDocumentPosition),m=t||K.test(s.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===x&&m(x,e)?-1:t===C||t.ownerDocument===x&&m(x,t)?1:u?M(u,e)-M(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?M(u,e)-M(u,t):0;if(i===o)return ce(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ce(a[r],s[r]):a[r]===x?-1:s[r]===x?1:0}),C},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),t=t.replace(U,"='$1']"),d.matchesSelector&&E&&!A[t+" "]&&(!c||!c.test(t))&&(!v||!v.test(t)))try{var n=y.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return 0<oe(t,C,null,[e]).length},oe.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),m(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&q.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},oe.escape=function(e){return(e+"").replace(ne,re)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return u=null,e},o=oe.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=o(t);return n},(b=oe.selectors={cacheLength:50,createPseudo:se,match:Y,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,f),e[3]=(e[3]||e[4]||e[5]||"").replace(te,f),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,f).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=D[e+" "];return t||(t=new RegExp("(^|"+I+")"+e+"("+I+"|$)"))&&D(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=oe.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!=m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){for(;l;){for(a=e;a=a[l];)if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){for(d=(s=(r=(i=(o=(a=c)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1])&&r[2],a=s&&c.childNodes[s];a=++s&&a&&a[l]||(d=s=0)||u.pop();)if(1===a.nodeType&&++d&&a===e){i[h]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1]),!1===d)for(;(a=++s&&a&&a[l]||(d=s=0)||u.pop())&&((x?a.nodeName.toLowerCase()!==f:1!==a.nodeType)||!++d||(p&&((i=(o=a[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,d]),a!==e)););return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,t){for(var n,r=a(e,o),i=r.length;i--;)e[n=M(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:se(function(e){var r=[],i=[],s=p(e.replace(_,"$1"));return s[k]?se(function(e,t,n,r){for(var i,o=s(e,null,r,[]),a=e.length;a--;)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:se(function(t){return function(e){return 0<oe(t,e).length}}),contains:se(function(t){return t=t.replace(te,f),function(e){return-1<(e.textContent||e.innerText||o(e)).indexOf(t)}}),lang:se(function(n){return G.test(n||"")||oe.error("unsupported lang: "+n),n=n.replace(te,f).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===s},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:fe(!1),disabled:fe(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:pe(function(){return[0]}),last:pe(function(e,t){return[t-1]}),eq:pe(function(e,t,n){return[n<0?n+t:n]}),even:pe(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:pe(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:pe(function(e,t,n){for(var r=n<0?n+t:n;0<=--r;)e.push(r);return e}),gt:pe(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=function(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=function(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}(e);function he(){}function ge(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function ve(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){for(;e=e[u];)if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[S,p];if(n){for(;e=e[u];)if((1===e.nodeType||f)&&s(e,t,n))return!0}else for(;e=e[u];)if(1===e.nodeType||f)if(i=(o=e[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function ye(i){return 1<i.length?function(e,t,n){for(var r=i.length;r--;)if(!i[r](e,t,n))return!1;return!0}:i[0]}function me(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function xe(d,h,g,v,y,e){return v&&!v[k]&&(v=xe(v)),y&&!y[k]&&(y=xe(y,e)),se(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)oe(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:me(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v)for(i=me(p,u),v(i,[],n,r),o=i.length;o--;)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a));if(e){if(y||d){if(y){for(i=[],o=p.length;o--;)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}for(o=p.length;o--;)(a=p[o])&&-1<(i=y?M(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=me(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):O.apply(t,p)})}function be(v,y){function e(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=S+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t===C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){for(a=0,t||o.ownerDocument===C||(T(o),n=!E);s=v[a++];)if(s(o,t||C,n)){r.push(o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){for(a=0;s=y[a++];)s(c,f,t,n);if(e){if(0<u)for(;l--;)c[l]||f[l]||(f[l]=L.call(r));f=me(f)}O.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&oe.uniqueSort(r)}return i&&(S=h,w=p),c}var m=0<y.length,x=0<v.length;return m?se(e):e}return he.prototype=b.filters=b.pseudos,b.setFilters=new he,h=oe.tokenize=function(e,t){var n,r,i,o,a,s,u,l=N[e+" "];if(l)return t?0:l.slice(0);for(a=e,s=[],u=b.preFilter;a;){for(o in n&&!(r=z.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(_," ")}),a=a.slice(n.length)),b.filter)!(r=Y[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?oe.error(e):N(e,s).slice(0)},p=oe.compile=function(e,t){var n,r=[],i=[],o=A[e+" "];if(!o){for(n=(t=t||h(e)).length;n--;)(o=function e(t){for(var i,n,r,o=t.length,a=b.relative[t[0].type],s=a||b.relative[" "],u=a?1:0,l=ve(function(e){return e===i},s,!0),c=ve(function(e){return-1<M(i,e)},s,!0),f=[function(e,t,n){var r=!a&&(n||t!==w)||((i=t).nodeType?l:c)(e,t,n);return i=null,r}];u<o;u++)if(n=b.relative[t[u].type])f=[ve(ye(f),n)];else{if((n=b.filter[t[u].type].apply(null,t[u].matches))[k]){for(r=++u;r<o&&!b.relative[t[r].type];r++);return xe(1<u&&ye(f),1<u&&ge(t.slice(0,u-1).concat({value:" "===t[u-2].type?"*":""})).replace(_,"$1"),n,u<r&&e(t.slice(u,r)),r<o&&e(t=t.slice(r)),r<o&&ge(t))}f.push(n)}return ye(f)}(t[n]))[k]?r.push(o):i.push(o);(o=A(e,be(i,r))).selector=e}return o},g=oe.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,f),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=Y.needsContext.test(e)?0:o.length;i--&&(a=o[i],!b.relative[s=a.type]);)if((u=b.find[s])&&(r=u(a.matches[0].replace(te,f),ee.test(o[0].type)&&de(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&ge(o)))return O.apply(n,r),n;break}}return(l||p(e,c))(r,t,!E,n,!t||ee.test(e)&&de(t.parentNode)||t),n},d.sortStable=k.split("").sort(j).join("")===k,d.detectDuplicates=!!l,T(),d.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ue(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ue(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(C);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;function T(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r}function S(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}var D=k.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return x(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):x(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this);if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),A.test(r[1])&&k.isPlainObject(t))for(r in t)x(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!D.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&x(i=e.promise)?i.call(e).done(t).fail(n):e&&x(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(M)||[],function(e,t){n[t]=!0}),n):k.extend({},r);function i(){for(s=s||r.once,a=o=!0;l.length;c=-1)for(t=l.shift();++c<u.length;)!1===u[c].apply(t[0],t[1])&&r.stopOnFalse&&(c=u.length,t=!1);r.memory||(t=!1),o=!1,s&&(u=t?[]:"")}var o,t,a,s,u=[],l=[],c=-1,f={add:function(){return u&&(t&&!o&&(c=u.length-1,l.push(t)),function n(e){k.each(e,function(e,t){x(t)?r.unique&&f.has(t)||u.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!o&&i()),this},remove:function(){return k.each(arguments,function(e,t){for(var n;-1<(n=k.inArray(t,u,n));)u.splice(n,1),n<=c&&c--}),this},has:function(e){return e?-1<k.inArray(e,u):0<u.length},empty:function(){return u=u&&[],this},disable:function(){return s=l=[],u=t="",this},disabled:function(){return!u},lock:function(){return s=l=[],t||o||(u=t=""),this},locked:function(){return!!s},fireWith:function(e,t){return s||(t=[e,(t=t||[]).slice?t.slice():t],l.push(t),o||i()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!a}};return f},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},catch:function(e){return a.then(null,e)},pipe:function(){var i=arguments;return k.Deferred(function(r){k.each(o,function(e,t){var n=x(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&x(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){function e(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,x(t)?s?t.call(e,l(u,o,R,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,I,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}}var n=this,r=arguments,t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,x(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,x(t)?t:R)),o[2][3].add(l(0,e,x(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){function t(t){return function(e){i[t]=this,o[t]=1<arguments.length?s.call(arguments):e,--n||a.resolveWith(i,o)}}var n=arguments.length,r=n,i=Array(r),o=s.call(arguments),a=k.Deferred();if(n<=1&&(W(e,a.done(t(r)).resolve,a.reject,!n),"pending"===a.state()||x(o[r]&&o[r].then)))return a.then();for(;r--;)W(o[r],t(r),a.reject);return a.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var B=k.Deferred();function F(){E.removeEventListener("DOMContentLoaded",F),C.removeEventListener("load",F),k.ready()}k.fn.ready=function(e){return B.then(e).catch(function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||B.resolveWith(E,[k])}}),k.ready.then=B.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.ready):(E.addEventListener("DOMContentLoaded",F),C.addEventListener("load",F));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,x(r)||(a=!0),l&&(t=a?(t.call(e,r),null):(l=t,function(e,t,n){return l.call(k(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,X=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(X,U)}function G(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType}function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(M)||[]).length;for(;n--;)delete r[t[n]]}void 0!==t&&!k.isEmptyObject(r)||(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0!==n)return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;return o&&void 0===e?void 0!==(t=J.get(o,n))||void 0!==(t=ee(o,n))?t:void 0:void this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0);if(this.length&&(i=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){for(t=a.length;t--;)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){function n(){--i||o.resolveWith(a,[a])}var r,i=1,o=k.Deferred(),a=this,s=this.length;for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";s--;)(r=Q.get(a[s],e+"queueHooks"))&&r.empty&&(i++,r.empty.add(n));return n(),o.promise(t)}});function te(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i}var ne=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,re=new RegExp("^(?:([+-])=|)("+ne+")([a-z%]*)$","i"),ie=["Top","Right","Bottom","Left"],oe=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&k.contains(e.ownerDocument,e)&&"none"===k.css(e,"display")};function ae(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=(k.cssNumber[t]||"px"!==l&&+u)&&re.exec(k.css(e,t));if(c&&c[3]!==l){for(u/=2,l=l||c[3],c=+u||1;a--;)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var se={};function ue(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&oe(r)&&(l[c]=(u=s=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=se[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),se[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return ue(this,!0)},hide:function(){return ue(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){oe(this)?k(this).show():k(this).hide()})}});var le=/^(?:checkbox|radio)$/i,ce=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,fe=/^$|^module$|\/(?:java|ecma)script/i,pe={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function de(e,t){var n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&N(e,t)?k.merge([e],n):n}function he(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}pe.optgroup=pe.option,pe.tbody=pe.tfoot=pe.colgroup=pe.caption=pe.thead,pe.th=pe.td;var ge,ve,ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))k.merge(p,o.nodeType?[o]:o);else if(ye.test(o)){for(a=a||f.appendChild(t.createElement("div")),s=(ce.exec(o)||["",""])[1].toLowerCase(),u=pe[s]||pe._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];c--;)a=a.lastChild;k.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));for(f.textContent="",d=0;o=p[d++];)if(r&&-1<k.inArray(o,r))i&&i.push(o);else if(l=k.contains(o.ownerDocument,o),a=de(f.appendChild(o),"script"),l&&he(a),n)for(c=0;o=a[c++];)fe.test(o.type||"")&&n.push(o);return f}ge=E.createDocumentFragment().appendChild(E.createElement("div")),(ve=E.createElement("input")).setAttribute("type","radio"),ve.setAttribute("checked","checked"),ve.setAttribute("name","t"),ge.appendChild(ve),m.checkClone=ge.cloneNode(!0).cloneNode(!0).lastChild.checked,ge.innerHTML="<textarea>x</textarea>",m.noCloneChecked=!!ge.cloneNode(!0).lastChild.defaultValue;var xe=E.documentElement,be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function ke(){try{return E.activeElement}catch(e){}}function Se(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Se(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(xe,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return void 0!==k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(M)||[""]).length;l--;)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){for(l=(t=(t||"").match(M)||[""]).length;l--;)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){for(f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){for(a=k.event.handlers.call(this,s,l),t=0;(i=a[t++])&&!s.isPropagationStopped();)for(s.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!s.isImmediatePropagationStopped();)s.rnamespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<k(i,this).index(l):k.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(k.Event.prototype,t,{enumerable:!0,configurable:!0,get:x(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ke()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===ke()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&N(this,"input"))return this.click(),!1},_default:function(e){return N(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Se(this,e,t,n,r)},one:function(e,t,n,r){return Se(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"!=typeof e)return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){k.event.remove(this,e,n,t)});for(i in e)this.off(i,t,e[i]);return this}});var De=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Ne=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Pe(n,r,i,o){r=v.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=x(d);if(h||1<f&&"string"==typeof d&&!m.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=me(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(de(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,de(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,He),c=0;c<s;c++)u=a[c],fe.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&k._evalUrl(u.src):b(u.textContent.replace(je,""),l,u))}return n}function Me(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(de(r)),r.parentNode&&(n&&k.contains(r.ownerDocument,r)&&he(de(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(De,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=k.contains(e.ownerDocument,e);if(!(m.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=de(c),r=0,i=(o=de(e)).length;r<i;r++)s=o[r],u=a[r],l=void 0,"input"===(l=u.nodeName.toLowerCase())&&le.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||de(e),a=a||de(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=de(c,"script")).length&&he(a,!f&&de(e,"script")),c},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return Me(this,e,!0)},remove:function(e){return Me(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){var t;1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(t=qe(this,e)).insertBefore(e,t.firstChild)})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(de(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!pe[(ce.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.cleanData(de(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(de(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Re,Ie,We,$e,Be,Fe,_e,ze=new RegExp("^("+ne+")(?!px)[a-z%]+$","i"),Xe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Ue=new RegExp(ie.join("|"),"i");function Ve(){var e;_e&&(Fe.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",_e.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",xe.appendChild(Fe).appendChild(_e),e=C.getComputedStyle(_e),Re="1%"!==e.top,Be=12===Ge(e.marginLeft),_e.style.right="60%",$e=36===Ge(e.right),Ie=36===Ge(e.width),_e.style.position="absolute",We=36===_e.offsetWidth||"absolute",xe.removeChild(Fe),_e=null)}function Ge(e){return Math.round(parseFloat(e))}function Ye(e,t,n){var r,i,o,a,s=e.style;return(n=n||Xe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||k.contains(e.ownerDocument,e)||(a=k.style(e,t)),!m.pixelBoxStyles()&&ze.test(a)&&Ue.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Qe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}Fe=E.createElement("div"),(_e=E.createElement("div")).style&&(_e.style.backgroundClip="content-box",_e.cloneNode(!0).style.backgroundClip="",m.clearCloneStyle="content-box"===_e.style.backgroundClip,k.extend(m,{boxSizingReliable:function(){return Ve(),Ie},pixelBoxStyles:function(){return Ve(),$e},pixelPosition:function(){return Ve(),Re},reliableMarginLeft:function(){return Ve(),Be},scrollboxSize:function(){return Ve(),We}}));var Je=/^(none|table(?!-c[ea]).+)/,Ke=/^--/,Ze={position:"absolute",visibility:"hidden",display:"block"},et={letterSpacing:"0",fontWeight:"400"},tt=["Webkit","Moz","ms"],nt=E.createElement("div").style;function rt(e){return k.cssProps[e]||(k.cssProps[e]=function(e){if(e in nt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=tt.length;n--;)if((e=tt[n]+t)in nt)return e}(e)||e)}function it(e,t,n){var r=re.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function ot(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=k.css(e,n+ie[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+ie[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+ie[a]+"Width",!0,i))):(u+=k.css(e,"padding"+ie[a],!0,i),"padding"!==n?u+=k.css(e,"border"+ie[a]+"Width",!0,i):s+=k.css(e,"border"+ie[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function at(e,t,n){var r=Xe(e),i=Ye(e,t,r),o="border-box"===k.css(e,"boxSizing",!1,r),a=o;if(ze.test(i)){if(!n)return i;i="auto"}return a=a&&(m.boxSizingReliable()||i===e.style[t]),"auto"!==i&&(parseFloat(i)||"inline"!==k.css(e,"display",!1,r))||(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+ot(e,t,n||(o?"border":"content"),a,r,i)+"px"}function st(e,t,n,r,i){return new st.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ye(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Ke.test(t),l=e.style;if(u||(t=rt(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=re.exec(n))&&i[1]&&(n=ae(e,t,i),o="number"),null!=n&&n==n&&("number"===o&&(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),m.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Ke.test(t)||(t=rt(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ye(e,t,r)),"normal"===i&&t in et&&(i=et[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,s){k.cssHooks[s]={get:function(e,t,n){if(t)return!Je.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?at(e,s,n):te(e,Ze,function(){return at(e,s,n)})},set:function(e,t,n){var r,i=Xe(e),o="border-box"===k.css(e,"boxSizing",!1,i),a=n&&ot(e,s,n,o,i);return o&&m.scrollboxSize()===i.position&&(a-=Math.ceil(e["offset"+s[0].toUpperCase()+s.slice(1)]-parseFloat(i[s])-ot(e,s,"border",!1,i)-.5)),a&&(r=re.exec(t))&&"px"!==(r[3]||"px")&&(e.style[s]=t,t=k.css(e,s)),it(0,t,a)}}}),k.cssHooks.marginLeft=Qe(m.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Ye(e,"marginLeft"))||e.getBoundingClientRect().left-te(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ie[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=it)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Xe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),(k.Tween=st).prototype={constructor:st,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=st.propHooks[this.prop];return e&&e.get?e.get(this):st.propHooks._default.get(this)},run:function(e){var t,n=st.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):st.propHooks._default.set(this),this}},st.prototype.init.prototype=st.prototype,st.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[k.cssProps[e.prop]]&&!k.cssHooks[e.prop]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}},st.propHooks.scrollTop=st.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=st.prototype.init,k.fx.step={};var ut,lt,ct,ft,pt=/^(?:toggle|show|hide)$/,dt=/queueHooks$/;function ht(){lt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ht):C.setTimeout(ht,k.fx.interval),k.fx.tick())}function gt(){return C.setTimeout(function(){ut=void 0}),ut=Date.now()}function vt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ie[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function yt(e,t,n){for(var r,i=(mt.tweeners[t]||[]).concat(mt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function mt(o,e,t){var n,a,r=0,i=mt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=ut||gt(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:ut||gt(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=mt.prefilters[r].call(l,o,c,l.opts))return x(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,yt,l),x(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(mt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return ae(n.elem,e,re.exec(t),n),n}]},tweener:function(e,t){for(var n,r=0,i=(e=x(e)?(t=e,["*"]):e.match(M)).length;r<i;r++)n=e[r],mt.tweeners[n]=mt.tweeners[n]||[],mt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&oe(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],pt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(ue([e],!0),l=e.style.display||l,c=k.css(e,"display"),ue([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&ue([e],!0),p.done(function(){for(r in g||ue([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=yt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?mt.prefilters.unshift(e):mt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||x(e)&&e,duration:e,easing:n&&t||t&&!x(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){x(r.old)&&r.old.call(this),r.queue&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(oe).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){function i(){var e=mt(this,k.extend({},t),a);(o||Q.get(this,"finish"))&&e.stop(!0)}var o=k.isEmptyObject(t),a=k.speed(e,n,r);return i.finish=i,o||!1===a.queue?this.each(i):this.queue(a.queue,i)},stop:function(i,e,o){function a(e){var t=e.stop;delete e.stop,t(o)}return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&dt.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(vt(r,!0),e,t,n)}}),k.each({slideDown:vt("show"),slideUp:vt("hide"),slideToggle:vt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(ut=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),ut=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){lt||(lt=!0,ht())},k.fx.stop=function(){lt=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},ct=E.createElement("input"),ft=E.createElement("select").appendChild(E.createElement("option")),ct.type="checkbox",m.checkOn=""!==ct.value,m.optSelected=ft.selected,(ct=E.createElement("input")).value="t",ct.type="radio",m.radioValue="t"===ct.value;var xt,bt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?xt:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):!(i&&"get"in i&&null!==(r=i.get(e,t)))&&null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),xt={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=bt[t]||k.find.attr;bt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=bt[o],bt[o]=r,r=null!=a(e,t,n)?o:null,bt[o]=i),r}});var wt=/^(?:input|select|textarea|button)$/i,Tt=/^(?:a|area)$/i;function Ct(e){return(e.match(M)||[]).join(" ")}function Et(e){return e.getAttribute&&e.getAttribute("class")||""}function kt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(M)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):wt.test(e.nodeName)||Tt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(x(t))return this.each(function(e){k(this).addClass(t.call(this,e,Et(this)))});if((e=kt(t)).length)for(;n=this[u++];)if(i=Et(n),r=1===n.nodeType&&" "+Ct(i)+" "){for(a=0;o=e[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=Ct(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(x(t))return this.each(function(e){k(this).removeClass(t.call(this,e,Et(this)))});if(!arguments.length)return this.attr("class","");if((e=kt(t)).length)for(;n=this[u++];)if(i=Et(n),r=1===n.nodeType&&" "+Ct(i)+" "){for(a=0;o=e[a++];)for(;-1<r.indexOf(" "+o+" ");)r=r.replace(" "+o+" "," ");i!==(s=Ct(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"==o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):x(i)?this.each(function(e){k(this).toggleClass(i.call(this,e,Et(this),t),t)}):this.each(function(){var e,t,n,r;if(a)for(t=0,n=k(this),r=kt(i);e=r[t++];)n.hasClass(e)?n.removeClass(e):n.addClass(e);else void 0!==i&&"boolean"!=o||((e=Et(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==i&&Q.get(this,"__className__")||""))})},hasClass:function(e){for(var t,n=0,r=" "+e+" ";t=this[n++];)if(1===t.nodeType&&-1<(" "+Ct(Et(t))+" ").indexOf(r))return!0;return!1}});var St=/\r/g;k.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=x(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(St,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:Ct(k.text(e))}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(((n=r[u]).selected||u===i)&&!n.disabled&&(!n.parentNode.disabled||!N(n.parentNode,"optgroup"))){if(t=k(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=k.makeArray(t),a=i.length;a--;)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},m.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),m.focusin="onfocusin"in C;function Dt(e){e.stopPropagation()}var Nt=/^(?:focusinfocus|focusoutblur)$/;k.extend(k.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f=[n||E],p=y.call(e,"type")?e.type:e,d=y.call(e,"namespace")?e.namespace.split("."):[],h=c=o=n=n||E;if(3!==n.nodeType&&8!==n.nodeType&&!Nt.test(p+k.event.triggered)&&(-1<p.indexOf(".")&&(p=(d=p.split(".")).shift(),d.sort()),s=p.indexOf(":")<0&&"on"+p,(e=e[k.expando]?e:new k.Event(p,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=d.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:k.makeArray(t,[e]),l=k.event.special[p]||{},r||!l.trigger||!1!==l.trigger.apply(n,t))){if(!r&&!l.noBubble&&!g(n)){for(a=l.delegateType||p,Nt.test(a+p)||(h=h.parentNode);h;h=h.parentNode)f.push(h),o=h;o===(n.ownerDocument||E)&&f.push(o.defaultView||o.parentWindow||C)}for(i=0;(h=f[i++])&&!e.isPropagationStopped();)c=h,e.type=1<i?a:l.bindType||p,(u=(Q.get(h,"events")||{})[e.type]&&Q.get(h,"handle"))&&u.apply(h,t),(u=s&&h[s])&&u.apply&&G(h)&&(e.result=u.apply(h,t),!1===e.result&&e.preventDefault());return e.type=p,r||e.isDefaultPrevented()||l._default&&!1!==l._default.apply(f.pop(),t)||!G(n)||s&&x(n[p])&&!g(n)&&((o=n[s])&&(n[s]=null),k.event.triggered=p,e.isPropagationStopped()&&c.addEventListener(p,Dt),n[p](),e.isPropagationStopped()&&c.removeEventListener(p,Dt),k.event.triggered=void 0,o&&(n[s]=o)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),m.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){function i(e){k.event.simulate(r,e.target,k.event.fix(e))}k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var At=C.location,jt=Date.now(),qt=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Lt=/\[\]$/,Ht=/\r?\n/g,Ot=/^(?:submit|button|image|reset|file)$/i,Pt=/^(?:input|select|textarea|keygen)/i;k.param=function(e,t){function n(e,t){var n=x(t)?t():t;i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)}var r,i=[];if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){n(this.name,this.value)});else for(r in e)!function n(r,e,i,o){var t;if(Array.isArray(e))k.each(e,function(e,t){i||Lt.test(r)?o(r,t):n(r+"["+("object"==typeof t&&null!=t?e:"")+"]",t,i,o)});else if(i||"object"!==w(e))o(r,e);else for(t in e)n(r+"["+t+"]",e[t],i,o)}(r,e[r],t,n);return i.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&Pt.test(this.nodeName)&&!Ot.test(e)&&(this.checked||!le.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(Ht,"\r\n")}}):{name:t.name,value:n.replace(Ht,"\r\n")}}).get()}});var Mt=/%20/g,Rt=/#.*$/,It=/([?&])_=[^&]*/,Wt=/^(.*?):[ \t]*([^\r\n]*)$/gm,$t=/^(?:GET|HEAD)$/,Bt=/^\/\//,Ft={},_t={},zt="*/".concat("*"),Xt=E.createElement("a");function Ut(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(M)||[];if(x(t))for(;n=i[r++];)"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Vt(t,i,o,a){var s={},u=t===_t;function l(e){var r;return s[e]=!0,k.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Gt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r=r||{})[n]=t[n]);return r&&k.extend(!0,e,r),e}Xt.href=At.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:At.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(At.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Gt(Gt(e,k.ajaxSettings),t):Gt(k.ajaxSettings,e)},ajaxPrefilter:Ut(Ft),ajaxTransport:Ut(_t),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n)for(n={};t=Wt.exec(p);)n[t[1].toLowerCase()]=t[2];t=n[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||At.href)+"").replace(Bt,At.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(M)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Xt.protocol+"//"+Xt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),Vt(Ft,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!$t.test(v.type),f=v.url.replace(Rt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Mt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(qt.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(It,"$1"),o=(qt.test(f)?"&":"?")+"_="+jt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+zt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Vt(_t,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a=a||i}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return x(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(x(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return x(n)?this.each(function(e){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=x(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Yt={0:200,1223:204},Qt=k.ajaxSettings.xhr();m.cors=!!Qt&&"withCredentials"in Qt,m.ajax=Qt=!!Qt,k.ajaxTransport(function(i){var o,a;if(m.cors||Qt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Yt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain)return{send:function(e,t){r=k("<script>").prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||k.expando+"_"+jt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=x(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(qt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&x(i)&&i(o[0]),o=i=void 0}),"script"}),m.createHTMLDocument=((Jt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Jt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=A.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=Ct(e.slice(s)),e=e.slice(0,s)),x(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),i=("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,r.left):(a=parseFloat(o)||0,parseFloat(u)||0),x(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===k.css(e,"position");)e=e.offsetParent;return e||xe})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;return g(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n?r?r[i]:e[t]:void(r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n)},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=Qe(m.pixelPosition,function(e,t){if(t)return t=Ye(e,n),ze.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return g(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),k.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),x(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=N,k.isFunction=x,k.isWindow=g,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var en=C.jQuery,tn=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=tn),e&&C.jQuery===k&&(C.jQuery=en),k},e||(C.jQuery=C.$=k),k}); })(this);
 
 // 3rdParty/jquery-ui.js
-(function (window, undefined) { !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){t.ui=t.ui||{};var e=(t.ui.version="1.12.1",0),i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,o,n;for(n=0;null!=(o=i[n]);n++)try{s=t._data(o,"events"),s&&s.remove&&t(o).triggerHandler("remove")}catch(t){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var o,n,r,a={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},o=t[h][e],n=t[h][e]=function(t,e){if(!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},t.extend(n,o,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),r=new i,r.options=t.widget.extend({},r.options),t.each(s,function(e,s){if(!t.isFunction(s))return void(a[e]=s);a[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,n=this._superApply;return this._super=t,this._superApply=o,e=s.apply(this,arguments),this._super=i,this._superApply=n,e}}()}),n.prototype=t.widget.extend(r,{widgetEventPrefix:o?r.widgetEventPrefix||e:e},a,{constructor:n,namespace:h,widgetName:e,widgetFullName:l}),o?(t.each(o._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,n,i._proto)}),delete o._childConstructors):i._childConstructors.push(n),t.widget.bridge(e,n),n},t.widget.extend=function(e){for(var s,o,n=i.call(arguments,1),r=0,a=n.length;r<a;r++)for(s in n[r])o=n[r][s],n[r].hasOwnProperty(s)&&void 0!==o&&(t.isPlainObject(o)?e[s]=t.isPlainObject(e[s])?t.widget.extend({},e[s],o):t.widget.extend({},o):e[s]=o);return e},t.widget.bridge=function(e,s){var o=s.prototype.widgetFullName||e;t.fn[e]=function(n){var r="string"==typeof n,a=i.call(arguments,1),h=this;return r?this.length||"instance"!==n?this.each(function(){var i,s=t.data(this,o);return"instance"===n?(h=s,!1):s?t.isFunction(s[n])&&"_"!==n.charAt(0)?(i=s[n].apply(s,a),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; attempted to call method '"+n+"'")}):h=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,o);e?(e.option(n||{}),e._init&&e._init()):t.data(this,o,new s(n,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,o,n,r=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(r={},s=e.split("."),e=s.shift(),s.length){for(o=r[e]=t.widget.extend({},this.options[e]),n=0;n<s.length-1;n++)o[s[n]]=o[s[n]]||{},o=o[s[n]];if(e=s.pop(),1===arguments.length)return void 0===o[e]?null:o[e];o[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];r[e]=i}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,o;for(i in e)o=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&o&&o.length&&(s=t(o.get()),this._removeClass(o,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,n){var r,a;for(a=0;a<i.length;a++)r=o.classesElementLookup[i[a]]||t(),r=t(e.add?t.unique(r.get().concat(e.element.get())):r.not(e.element).get()),o.classesElementLookup[i[a]]=r,s.push(i[a]),n&&e.classes[i[a]]&&s.push(e.classes[i[a]])}var s=[],o=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,o){-1!==t.inArray(e.target,o)&&(i.classesElementLookup[s]=t(o.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var o="string"==typeof t||null===t,n={extra:o?e:i,keys:o?t:e,element:o?this.element:t,add:s};return n.element.toggleClass(this._classes(n),s),this},_on:function(e,i,s){var o,n=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=o=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,o=this.widget()),t.each(s,function(s,r){function a(){if(e||!0!==n.options.disabled&&!t(this).hasClass("ui-state-disabled"))return("string"==typeof r?n[r]:r).apply(n,arguments)}"string"!=typeof r&&(a.guid=r.guid=r.guid||a.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+n.eventNamespace,c=h[2];c?o.on(l,c,a):i.on(l,a)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var o,n,r=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],n=i.originalEvent)for(o in n)o in i||(i[o]=n[o]);return this.element.trigger(i,s),!(t.isFunction(r)&&!1===r.apply(this.element[0],[i].concat(s))||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,o,n){"string"==typeof o&&(o={effect:o});var r,a=o?!0===o||"number"==typeof o?i:o.effect||i:e;o=o||{},"number"==typeof o&&(o={duration:o}),r=!t.isEmptyObject(o),o.complete=n,o.delay&&s.delay(o.delay),r&&t.effects&&t.effects.effect[a]?s[e](o):a!==e&&s[a]?s[a](o.duration,o.easing,n):s.queue(function(i){t(this)[e](),n&&n.call(s[0]),i()})}});t.widget;!function(){function e(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var o,n=Math.max,r=Math.abs,a=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==o)return o;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),n=s.children()[0];return t("body").append(s),e=n.offsetWidth,s.css("overflow","scroll"),i=n.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),o=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),o="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth;return{width:"scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight?t.position.scrollbarWidth():0,height:o?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),o=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:o,offset:s||o?{left:0,top:0}:t(e).offset(),scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(o){if(!o||!o.of)return f.apply(this,arguments);o=t.extend({},o);var p,u,d,g,m,v,_=t(o.of),b=t.position.getWithinInfo(o.within),w=t.position.getScrollInfo(b),y=(o.collision||"flip").split(" "),P={};return v=s(_),_[0].preventDefault&&(o.at="left top"),u=v.width,d=v.height,g=v.offset,m=t.extend({},g),t.each(["my","at"],function(){var t,e,i=(o[this]||"").split(" ");1===i.length&&(i=a.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=a.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),P[this]=[t?t[0]:0,e?e[0]:0],o[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===y.length&&(y[1]=y[0]),"right"===o.at[0]?m.left+=u:"center"===o.at[0]&&(m.left+=u/2),"bottom"===o.at[1]?m.top+=d:"center"===o.at[1]&&(m.top+=d/2),p=e(P.at,u,d),m.left+=p[0],m.top+=p[1],this.each(function(){var s,a,h=t(this),l=h.outerWidth(),c=h.outerHeight(),f=i(this,"marginLeft"),v=i(this,"marginTop"),x=l+f+i(this,"marginRight")+w.width,C=c+v+i(this,"marginBottom")+w.height,z=t.extend({},m),H=e(P.my,h.outerWidth(),h.outerHeight());"right"===o.my[0]?z.left-=l:"center"===o.my[0]&&(z.left-=l/2),"bottom"===o.my[1]?z.top-=c:"center"===o.my[1]&&(z.top-=c/2),z.left+=H[0],z.top+=H[1],s={marginLeft:f,marginTop:v},t.each(["left","top"],function(e,i){t.ui.position[y[e]]&&t.ui.position[y[e]][i](z,{targetWidth:u,targetHeight:d,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:x,collisionHeight:C,offset:[p[0]+H[0],p[1]+H[1]],my:o.my,at:o.at,within:b,elem:h})}),o.using&&(a=function(t){var e=g.left-z.left,i=e+u-l,s=g.top-z.top,a=s+d-c,p={target:{element:_,left:g.left,top:g.top,width:u,height:d},element:{element:h,left:z.left,top:z.top,width:l,height:c},horizontal:i<0?"left":e>0?"right":"center",vertical:a<0?"top":s>0?"bottom":"middle"};u<l&&r(e+i)<u&&(p.horizontal="center"),d<c&&r(s+a)<d&&(p.vertical="middle"),n(r(e),r(i))>n(r(s),r(a))?p.important="horizontal":p.important="vertical",o.using.call(this,t,p)}),h.offset(t.extend(z,{using:a}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollLeft:s.offset.left,r=s.width,a=t.left-e.collisionPosition.marginLeft,h=o-a,l=a+e.collisionWidth-r-o;e.collisionWidth>r?h>0&&l<=0?(i=t.left+h+e.collisionWidth-r-o,t.left+=h-i):t.left=l>0&&h<=0?o:h>l?o+r-e.collisionWidth:o:h>0?t.left+=h:l>0?t.left-=l:t.left=n(t.left-a,t.left)},top:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollTop:s.offset.top,r=e.within.height,a=t.top-e.collisionPosition.marginTop,h=o-a,l=a+e.collisionHeight-r-o;e.collisionHeight>r?h>0&&l<=0?(i=t.top+h+e.collisionHeight-r-o,t.top+=h-i):t.top=l>0&&h<=0?o:h>l?o+r-e.collisionHeight:o:h>0?t.top+=h:l>0?t.top-=l:t.top=n(t.top-a,t.top)}},flip:{left:function(t,e){var i,s,o=e.within,n=o.offset.left+o.scrollLeft,a=o.width,h=o.isWindow?o.scrollLeft:o.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,p=l+e.collisionWidth-a-h,f="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,u="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,d=-2*e.offset[0];c<0?((i=t.left+f+u+d+e.collisionWidth-a-n)<0||i<r(c))&&(t.left+=f+u+d):p>0&&((s=t.left-e.collisionPosition.marginLeft+f+u+d-h)>0||r(s)<p)&&(t.left+=f+u+d)},top:function(t,e){var i,s,o=e.within,n=o.offset.top+o.scrollTop,a=o.height,h=o.isWindow?o.scrollTop:o.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,p=l+e.collisionHeight-a-h,f="top"===e.my[1],u=f?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,d="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];c<0?((s=t.top+u+d+g+e.collisionHeight-a-n)<0||s<r(c))&&(t.top+=u+d+g):p>0&&((i=t.top-e.collisionPosition.marginTop+u+d+g-h)>0||r(i)<p)&&(t.top+=u+d+g)}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}();var s=(t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,o=e?/(auto|scroll|hidden)/:/(auto|scroll)/,n=this.parents().filter(function(){var e=t(this);return(!s||"static"!==e.css("position"))&&o.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&n.length?n:t(this[0].ownerDocument||document)},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),!1);t(document).on("mouseup",function(){s=!1});t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){if(!0===t.data(i.target,e.widgetName+".preventClickEvent"))return t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,o=1===e.which,n=!("string"!=typeof this.options.cancel||!e.target.nodeName)&&t(e.target).closest(this.options.cancel).length;return!(o&&!n&&this._mouseCapture(e))||(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=!1!==this._mouseStart(e),!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0))}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||document.documentMode<9)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,e),this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var o,n=t.ui[e].prototype;for(o in s)n.plugins[o]=n.plugins[o]||[],n.plugins[o].push([i,s[o]])},call:function(t,e,i,s){var o,n=t.plugins[e];if(n&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(o=0;o<n.length;o++)t.options[n[o][0]]&&n[o][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")};t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){if((this.helper||this.element).is(".ui-draggable-dragging"))return void(this.destroyOnClear=!0);this._removeHandleClassName(),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return!(this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0)&&(this.handle=this._getHandle(e),!!this.handle&&(this._blurActiveElement(e),this._blockFrames(!0===i.iframeFix?"iframe":i.iframeFix),!0))},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]);t(e.target).closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),!1===this._trigger("start",e)?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(!1===this._trigger("drag",e,s))return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||!0===this.options.revert||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){!1!==i._trigger("stop",e)&&i._clear()}):!1!==this._trigger("stop",e)&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return!this.options.handle||!!t(e.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),o=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return o.parents("body").length||o.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&o[0]===this.element[0]&&this._setPositionRelative(),o[0]===this.element[0]||/(fixed|absolute)/.test(o.css("position"))||o.css("position","absolute"),o},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,o=this.options,n=this.document[0];return this.relativeContainer=null,o.containment?"window"===o.containment?void(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):"document"===o.containment?void(this.containment=[0,0,t(n).width()-this.helperProportions.width-this.margins.left,(t(n).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):o.containment.constructor===Array?void(this.containment=o.containment):("parent"===o.containment&&(o.containment=this.helper[0].parentNode),i=t(o.containment),void((s=i[0])&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i))):void(this.containment=null)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,o,n,r=this.options,a=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return a&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),r.grid&&(o=r.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/r.grid[1])*r.grid[1]:this.originalPageY,l=i?o-this.offset.click.top>=i[1]||o-this.offset.click.top>i[3]?o:o-this.offset.click.top>=i[1]?o-r.grid[1]:o+r.grid[1]:o,n=r.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/r.grid[0])*r.grid[0]:this.originalPageX,h=i?n-this.offset.click.left>=i[0]||n-this.offset.click.left>i[2]?n:n-this.offset.click.left>=i[0]?n-r.grid[0]:n+r.grid[0]:n),"y"===r.axis&&(h=this.originalPageX),"x"===r.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var o=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,o))})},stop:function(e,i,s){var o=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,o))})},drag:function(e,i,s){t.each(s.sortables,function(){var o=!1,n=this;n.positionAbs=s.positionAbs,n.helperProportions=s.helperProportions,n.offset.click=s.offset.click,n._intersectsWith(n.containerCache)&&(o=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==n&&this._intersectsWith(this.containerCache)&&t.contains(n.element[0],this.element[0])&&(o=!1),o})),o?(n.isOver||(n.isOver=1,s._parent=i.helper.parent(),n.currentItem=i.helper.appendTo(n.element).data("ui-sortable-item",!0),n.options._helper=n.options.helper,n.options.helper=function(){return i.helper[0]},e.target=n.currentItem[0],n._mouseCapture(e,!0),n._mouseStart(e,!0,!0),n.offset.click.top=s.offset.click.top,n.offset.click.left=s.offset.click.left,n.offset.parent.left-=s.offset.parent.left-n.offset.parent.left,
-n.offset.parent.top-=s.offset.parent.top-n.offset.parent.top,s._trigger("toSortable",e),s.dropped=n.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,n.fromOutside=s),n.currentItem&&(n._mouseDrag(e),i.position=n.position)):n.isOver&&(n.isOver=0,n.cancelHelperRemoval=!0,n.options._revert=n.options.revert,n.options.revert=!1,n._trigger("out",e,n._uiHash(n)),n._mouseStop(e,!0),n.options.revert=n.options._revert,n.options.helper=n.options._helper,n.placeholder&&n.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var o=t("body"),n=s.options;o.css("cursor")&&(n._cursor=o.css("cursor")),o.css("cursor",n.cursor)},stop:function(e,i,s){var o=s.options;o._cursor&&t("body").css("cursor",o._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var o=t(i.helper),n=s.options;o.css("opacity")&&(n._opacity=o.css("opacity")),o.css("opacity",n.opacity)},stop:function(e,i,s){var o=s.options;o._opacity&&t(i.helper).css("opacity",o._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var o=s.options,n=!1,r=s.scrollParentNotHidden[0],a=s.document[0];r!==a&&"HTML"!==r.tagName?(o.axis&&"x"===o.axis||(s.overflowOffset.top+r.offsetHeight-e.pageY<o.scrollSensitivity?r.scrollTop=n=r.scrollTop+o.scrollSpeed:e.pageY-s.overflowOffset.top<o.scrollSensitivity&&(r.scrollTop=n=r.scrollTop-o.scrollSpeed)),o.axis&&"y"===o.axis||(s.overflowOffset.left+r.offsetWidth-e.pageX<o.scrollSensitivity?r.scrollLeft=n=r.scrollLeft+o.scrollSpeed:e.pageX-s.overflowOffset.left<o.scrollSensitivity&&(r.scrollLeft=n=r.scrollLeft-o.scrollSpeed))):(o.axis&&"x"===o.axis||(e.pageY-t(a).scrollTop()<o.scrollSensitivity?n=t(a).scrollTop(t(a).scrollTop()-o.scrollSpeed):t(window).height()-(e.pageY-t(a).scrollTop())<o.scrollSensitivity&&(n=t(a).scrollTop(t(a).scrollTop()+o.scrollSpeed))),o.axis&&"y"===o.axis||(e.pageX-t(a).scrollLeft()<o.scrollSensitivity?n=t(a).scrollLeft(t(a).scrollLeft()-o.scrollSpeed):t(window).width()-(e.pageX-t(a).scrollLeft())<o.scrollSensitivity&&(n=t(a).scrollLeft(t(a).scrollLeft()+o.scrollSpeed)))),!1!==n&&t.ui.ddmanager&&!o.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var o=s.options;s.snapElements=[],t(o.snap.constructor!==String?o.snap.items||":data(ui-draggable)":o.snap).each(function(){var e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var o,n,r,a,h,l,c,p,f,u,d=s.options,g=d.snapTolerance,m=i.offset.left,v=m+s.helperProportions.width,_=i.offset.top,b=_+s.helperProportions.height;for(f=s.snapElements.length-1;f>=0;f--)h=s.snapElements[f].left-s.margins.left,l=h+s.snapElements[f].width,c=s.snapElements[f].top-s.margins.top,p=c+s.snapElements[f].height,v<h-g||m>l+g||b<c-g||_>p+g||!t.contains(s.snapElements[f].item.ownerDocument,s.snapElements[f].item)?(s.snapElements[f].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[f].item})),s.snapElements[f].snapping=!1):("inner"!==d.snapMode&&(o=Math.abs(c-b)<=g,n=Math.abs(p-_)<=g,r=Math.abs(h-v)<=g,a=Math.abs(l-m)<=g,o&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),n&&(i.position.top=s._convertPositionTo("relative",{top:p,left:0}).top),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),u=o||n||r||a,"outer"!==d.snapMode&&(o=Math.abs(c-_)<=g,n=Math.abs(p-b)<=g,r=Math.abs(h-m)<=g,a=Math.abs(l-v)<=g,o&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),n&&(i.position.top=s._convertPositionTo("relative",{top:p-s.helperProportions.height,left:0}).top),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[f].snapping&&(o||n||r||a||u)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[f].item})),s.snapElements[f].snapping=o||n||r||a||u)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var o,n=s.options,r=t.makeArray(t(n.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});r.length&&(o=parseInt(t(r[0]).css("zIndex"),10)||0,t(r).each(function(e){t(this).css("zIndex",o+e)}),this.css("zIndex",o+r.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var o=t(i.helper),n=s.options;o.css("zIndex")&&(n._zIndex=o.css("zIndex")),o.css("zIndex",n.zIndex)},stop:function(e,i,s){var o=s.options;o._zIndex&&t(i.helper).css("zIndex",o._zIndex)}});t.ui.draggable;t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){if(!arguments.length)return e||(e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight});e=arguments[0]},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return!(!s||(s.currentItem||s.element)[0]===this.element[0])&&(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");if(i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&o(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e))return n=!0,!1}),!n&&(!!this.accept.call(this.element[0],s.currentItem||s.element)&&(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element)))},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var o=t.ui.intersect=function(){function t(t,e,i){return t>=e&&t<e+i}return function(e,i,s,o){if(!i.offset)return!1;var n=(e.positionAbs||e.position.absolute).left+e.margins.left,r=(e.positionAbs||e.position.absolute).top+e.margins.top,a=n+e.helperProportions.width,h=r+e.helperProportions.height,l=i.offset.left,c=i.offset.top,p=l+i.proportions().width,f=c+i.proportions().height;switch(s){case"fit":return l<=n&&a<=p&&c<=r&&h<=f;case"intersect":return l<n+e.helperProportions.width/2&&a-e.helperProportions.width/2<p&&c<r+e.helperProportions.height/2&&h-e.helperProportions.height/2<f;case"pointer":return t(o.pageY,c,i.proportions().height)&&t(o.pageX,l,i.proportions().width);case"touch":return(r>=c&&r<=f||h>=c&&h<=f||r<c&&h>f)&&(n>=l&&n<=p||a>=l&&a<=p||n<l&&a>p);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{default:[]},prepareOffsets:function(e,i){var s,o,n=t.ui.ddmanager.droppables[e.options.scope]||[],r=i?i.type:null,a=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;s<n.length;s++)if(!(n[s].options.disabled||e&&!n[s].accept.call(n[s].element[0],e.currentItem||e.element))){for(o=0;o<a.length;o++)if(a[o]===n[s].element[0]){n[s].proportions().height=0;continue t}n[s].visible="none"!==n[s].element.css("display"),n[s].visible&&("mousedown"===r&&n[s]._activate.call(n[s],i),n[s].offset=n[s].element.offset(),n[s].proportions({width:n[s].element[0].offsetWidth,height:n[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&o(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,r,a=o(e,this,this.options.tolerance,i),h=!a&&this.isover?"isout":a&&!this.isover?"isover":null;h&&(this.options.greedy&&(n=this.options.scope,r=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),r.length&&(s=t(r[0]).droppable("instance"),s.greedyChild="isover"===h)),s&&"isover"===h&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[h]=!0,this["isout"===h?"isover":"isout"]=!1,this["isover"===h?"_over":"_out"].call(this,i),s&&"isout"===h&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},!1!==t.uiBackCompat&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}});t.ui.droppable;t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",o=!1;return e[s]>0||(e[s]=1,o=e[s]>0,e[s]=0,o)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles()}},_setupHandles:function(){var e,i,s,o,n,r=this.options,a=this;if(this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;i<s.length;i++)e=t.trim(s[i]),o="ui-resizable-"+e,n=t("<div>"),this._addClass(n,"ui-resizable-handle "+o),n.css({zIndex:r.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(n);this._renderAxis=function(e){var i,s,o,n;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:a._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),n=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),o=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(o,n),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,o=!1;for(i in this.handles)((s=t(this.handles[i])[0])===e.target||t.contains(s,e.target))&&(o=!0);return!this.options.disabled&&o},_mouseStart:function(e){var i,s,o,n=this.options,r=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),n.containment&&(i+=t(n.containment).scrollLeft()||0,s+=t(n.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:r.width(),height:r.height()},this.originalSize=this._helper?{width:r.outerWidth(),height:r.outerHeight()}:{width:r.width(),height:r.height()},this.sizeDiff={width:r.outerWidth()-r.width(),height:r.outerHeight()-r.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof n.aspectRatio?n.aspectRatio:this.originalSize.width/this.originalSize.height||1,o=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===o?this.axis+"-resize":o),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,o=this.originalMousePosition,n=this.axis,r=e.pageX-o.left||0,a=e.pageY-o.top||0,h=this._change[n];return this._updatePrevProperties(),!!h&&(i=h.apply(this,[e,r,a]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1)},_mouseStop:function(e){this.resizing=!1;var i,s,o,n,r,a,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,n=s?0:c.sizeDiff.width,r={width:c.helper.width()-n,height:c.helper.height()-o},a=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(r,{top:h,left:a})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,o,n,r=this.options;n={minWidth:this._isNumber(r.minWidth)?r.minWidth:0,maxWidth:this._isNumber(r.maxWidth)?r.maxWidth:1/0,minHeight:this._isNumber(r.minHeight)?r.minHeight:0,maxHeight:this._isNumber(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,s=n.minWidth/this.aspectRatio,i=n.maxHeight*this.aspectRatio,o=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),s>n.minHeight&&(n.minHeight=s),i<n.maxWidth&&(n.maxWidth=i),o<n.maxHeight&&(n.maxHeight=o)),this._vBoundaries=n},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,n=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,r=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return n&&(t.width=e.minWidth),r&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),n&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),r&&c&&(t.top=h-e.minHeight),o&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],o=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(o[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e<this._proportionallyResizeElements.length;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,o=i._proportionallyResizeElements,n=o.length&&/textarea/i.test(o[0].nodeName),r=n&&i._hasScroll(o[0],"left")?0:i.sizeDiff.height,a=n?0:i.sizeDiff.width,h={width:i.size.width-a,height:i.size.height-r},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};o&&o.length&&t(o[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,o,n,r,a,h=t(this).resizable("instance"),l=h.options,c=h.element,p=l.containment,f=p instanceof t?p.get(0):/parent/.test(p)?c.parent().get(0):p;f&&(h.containerElement=t(f),/document/.test(p)||p===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(f),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,o=h.containerSize.height,n=h.containerSize.width,r=h._hasScroll(f,"left")?f.scrollWidth:n,a=h._hasScroll(f)?f.scrollHeight:o,h.parentData={element:f,left:s.left,top:s.top,width:r,height:a}))},resize:function(e){var i,s,o,n,r=t(this).resizable("instance"),a=r.options,h=r.containerOffset,l=r.position,c=r._aspectRatio||e.shiftKey,p={top:0,left:0},f=r.containerElement,u=!0;f[0]!==document&&/static/.test(f.css("position"))&&(p=h),l.left<(r._helper?h.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-h.left:r.position.left-p.left),c&&(r.size.height=r.size.width/r.aspectRatio,u=!1),r.position.left=a.helper?h.left:0),l.top<(r._helper?h.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-h.top:r.position.top),c&&(r.size.width=r.size.height*r.aspectRatio,u=!1),r.position.top=r._helper?h.top:0),o=r.containerElement.get(0)===r.element.parent().get(0),n=/relative|absolute/.test(r.containerElement.css("position")),o&&n?(r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top):(r.offset.left=r.element.offset().left,r.offset.top=r.element.offset().top),i=Math.abs(r.sizeDiff.width+(r._helper?r.offset.left-p.left:r.offset.left-h.left)),s=Math.abs(r.sizeDiff.height+(r._helper?r.offset.top-p.top:r.offset.top-h.top)),i+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-i,c&&(r.size.height=r.size.width/r.aspectRatio,u=!1)),s+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-s,c&&(r.size.width=r.size.height*r.aspectRatio,u=!1)),u||(r.position.left=r.prevPosition.left,r.position.top=r.prevPosition.top,r.size.width=r.prevSize.width,r.size.height=r.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,o=e.containerPosition,n=e.containerElement,r=t(e.helper),a=r.offset(),h=r.outerWidth()-e.sizeDiff.width,l=r.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(n.css("position"))&&t(this).css({left:a.left-o.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(n.css("position"))&&t(this).css({left:a.left-o.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),o=s.options,n=s.originalSize,r=s.originalPosition,a={height:s.size.height-n.height||0,width:s.size.width-n.width||0,top:s.position.top-r.top||0,left:s.position.left-r.left||0};t(o.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),o={},n=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(n,function(t,e){var i=(s[e]||0)+(a[e]||0);i&&i>=0&&(o[e]=i||null)}),e.css(o)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),!1!==t.uiBackCompat&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,o=i.size,n=i.originalSize,r=i.originalPosition,a=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,p=Math.round((o.width-n.width)/l)*l,f=Math.round((o.height-n.height)/c)*c,u=n.width+p,d=n.height+f,g=s.maxWidth&&s.maxWidth<u,m=s.maxHeight&&s.maxHeight<d,v=s.minWidth&&s.minWidth>u,_=s.minHeight&&s.minHeight>d;s.grid=h,v&&(u+=l),_&&(d+=c),g&&(u-=l),m&&(d-=c),/^(se|s|e)$/.test(a)?(i.size.width=u,i.size.height=d):/^(ne)$/.test(a)?(i.size.width=u,i.size.height=d,i.position.top=r.top-f):/^(sw)$/.test(a)?(i.size.width=u,i.size.height=d,i.position.left=r.left-p):((d-c<=0||u-l<=0)&&(e=i._getPaddingPlusBorderDimensions(this)),d-c>0?(i.size.height=d,i.position.top=r.top-f):(d=c-e.height,i.size.height=d,i.position.top=r.top+n.height-d),u-l>0?(i.size.width=u,i.position.left=r.left-p):(u=l-e.width,i.size.width=u,i.position.left=r.left+n.width-u))}});var n=(t.ui.resizable,t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),o={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:o.left,top:o.top,right:o.left+i.outerWidth(),bottom:o.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,o=t.data(this,"selectable-item");if(o)return s=!e.metaKey&&!e.ctrlKey||!o.$element.hasClass("ui-selected"),i._removeClass(o.$element,s?"ui-unselecting":"ui-selected")._addClass(o.$element,s?"ui-selecting":"ui-unselecting"),o.unselecting=!s,o.selecting=s,o.selected=s,s?i._trigger("selecting",e,{selecting:o.element}):i._trigger("unselecting",e,{unselecting:o.element}),!1}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){
-var i,s=this,o=this.options,n=this.opos[0],r=this.opos[1],a=e.pageX,h=e.pageY;return n>a&&(i=a,a=n,n=i),r>h&&(i=h,h=r,r=i),this.helper.css({left:n,top:r,width:a-n,height:h-r}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===o.tolerance?l=!(c.left>a||c.right<n||c.top>h||c.bottom<r):"fit"===o.tolerance&&(l=c.left>n&&c.right<a&&c.top>r&&c.bottom<h),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&t<e+i},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,o=!1,n=this;return!this.reverting&&(!this.options.disabled&&"static"!==this.options.type&&(this._refreshItems(e),t(e.target).parents().each(function(){if(t.data(this,n.widgetName+"-item")===n)return s=t(this),!1}),t.data(e.target,n.widgetName+"-item")===n&&(s=t(e.target)),!!s&&(!(this.options.handle&&!i&&(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(o=!0)}),!o))&&(this.currentItem=s,this._removeCurrentsFromItems(),!0))))},_mouseStart:function(e,i,s){var o,n,r=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,r.cursorAt&&this._adjustOffsetFromHelper(r.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),r.containment&&this._setContainment(),r.cursor&&"auto"!==r.cursor&&(n=this.document.find("body"),this.storedCursor=n.css("cursor"),n.css("cursor",r.cursor),this.storedStylesheet=t("<style>*{ cursor: "+r.cursor+" !important; }</style>").appendTo(n)),r.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",r.opacity)),r.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",r.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(o=this.containers.length-1;o>=0;o--)this.containers[o]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!r.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,o,n,r=this.options,a=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<r.scrollSensitivity?this.scrollParent[0].scrollTop=a=this.scrollParent[0].scrollTop+r.scrollSpeed:e.pageY-this.overflowOffset.top<r.scrollSensitivity&&(this.scrollParent[0].scrollTop=a=this.scrollParent[0].scrollTop-r.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<r.scrollSensitivity?this.scrollParent[0].scrollLeft=a=this.scrollParent[0].scrollLeft+r.scrollSpeed:e.pageX-this.overflowOffset.left<r.scrollSensitivity&&(this.scrollParent[0].scrollLeft=a=this.scrollParent[0].scrollLeft-r.scrollSpeed)):(e.pageY-this.document.scrollTop()<r.scrollSensitivity?a=this.document.scrollTop(this.document.scrollTop()-r.scrollSpeed):this.window.height()-(e.pageY-this.document.scrollTop())<r.scrollSensitivity&&(a=this.document.scrollTop(this.document.scrollTop()+r.scrollSpeed)),e.pageX-this.document.scrollLeft()<r.scrollSensitivity?a=this.document.scrollLeft(this.document.scrollLeft()-r.scrollSpeed):this.window.width()-(e.pageX-this.document.scrollLeft())<r.scrollSensitivity&&(a=this.document.scrollLeft(this.document.scrollLeft()+r.scrollSpeed))),!1!==a&&t.ui.ddmanager&&!r.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],o=s.item[0],(n=this._intersectsWithPointer(s))&&s.instance===this.currentContainer&&!(o===this.currentItem[0]||this.placeholder[1===n?"next":"prev"]()[0]===o||t.contains(this.placeholder[0],o)||"semi-dynamic"===this.options.type&&t.contains(this.element[0],o))){if(this.direction=1===n?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,o=this.placeholder.offset(),n=this.options.axis,r={};n&&"x"!==n||(r.left=o.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),n&&"y"!==n||(r.top=o.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(r,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,o=s+this.helperProportions.height,n=t.left,r=n+t.width,a=t.top,h=a+t.height,l=this.offset.click.top,c=this.offset.click.left,p="x"===this.options.axis||s+l>a&&s+l<h,f="y"===this.options.axis||e+c>n&&e+c<r,u=p&&f;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?u:n<e+this.helperProportions.width/2&&i-this.helperProportions.width/2<r&&a<s+this.helperProportions.height/2&&o-this.helperProportions.height/2<h},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),o="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width);return!(!s||!o)&&(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1))},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&i||"left"===o&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){a.push(this)}var s,o,n,r,a=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(n=t(l[s],this.document[0]),o=n.length-1;o>=0;o--)(r=t.data(n[o],this.widgetFullName))&&r!==this&&!r.options.disabled&&h.push([t.isFunction(r.options.items)?r.options.items.call(r.element):t(r.options.items,r.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),r]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(a)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;i<e.length;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,o,n,r,a,h,l,c=this.items,p=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],f=this._connectWith();if(f&&this.ready)for(i=f.length-1;i>=0;i--)for(o=t(f[i],this.document[0]),s=o.length-1;s>=0;s--)(n=t.data(o[s],this.widgetFullName))&&n!==this&&!n.options.disabled&&(p.push([t.isFunction(n.options.items)?n.options.items.call(n.element[0],e,{item:this.currentItem}):t(n.options.items,n.element),n]),this.containers.push(n));for(i=p.length-1;i>=0;i--)for(r=p[i][1],a=p[i][0],s=0,l=a.length;s<l;s++)h=t(a[s]),h.data(this.widgetName+"-item",r),c.push({item:h,instance:r,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=!!this.items.length&&("x"===this.options.axis||this._isFloating(this.items[0].item)),this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,o,n;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(o=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=o.outerWidth(),s.height=o.outerHeight()),n=o.offset(),s.left=n.left,s.top=n.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)n=this.containers[i].element.offset(),this.containers[i].containerCache.left=n.left,this.containers[i].containerCache.top=n.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),o=t("<"+s+">",e.document[0]);return e._addClass(o,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(o,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("<tr>",e.document[0]).appendTo(o)):"tr"===s?e._createTrPlaceholder(e.currentItem,o):"img"===s&&o.attr("src",e.currentItem.attr("src")),i||o.css("visibility","hidden"),o},update:function(t,o){i&&!s.forcePlaceholderSize||(o.height()||o.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),o.width()||o.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("<td>&#160;</td>",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,o,n,r,a,h,l,c,p,f=null,u=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(f&&t.contains(this.containers[i].element[0],f.element[0]))continue;f=this.containers[i],u=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",e,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(o=1e4,n=null,c=f.floating||this._isFloating(this.currentItem),r=c?"left":"top",a=c?"width":"height",p=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[u].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[r],l=!1,e[p]-h>this.items[s][a]/2&&(l=!0),Math.abs(e[p]-h)<o&&(o=Math.abs(e[p]-h),n=this.items[s],this.direction=l?"up":"down"));if(!n&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[u])return void(this.currentContainer.containerCache.over||(this.containers[u]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1));n?this._rearrange(e,n,null,!0):this._rearrange(e,null,this.containers[u].element,!0),this._trigger("change",e,this._uiHash()),this.containers[u]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[u],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[u]._trigger("over",e,this._uiHash(this)),this.containers[u].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),s[0].style.width&&!i.forceHelperSize||s.width(this.currentItem.width()),s[0].style.height&&!i.forceHelperSize||s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,o=this.options;"parent"===o.containment&&(o.containment=this.helper[0].parentNode),"document"!==o.containment&&"window"!==o.containment||(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===o.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===o.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(o.containment)||(e=t(o.containment)[0],i=t(o.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,o="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,n=/(html|body)/i.test(o[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():n?0:o.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():n?0:o.scrollLeft())*s}},_generatePosition:function(e){var i,s,o=this.options,n=e.pageX,r=e.pageY,a="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(a[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(n=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(r=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(n=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(r=this.containment[3]+this.offset.click.top)),o.grid&&(i=this.originalPageY+Math.round((r-this.originalPageY)/o.grid[1])*o.grid[1],r=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-o.grid[1]:i+o.grid[1]:i,s=this.originalPageX+Math.round((n-this.originalPageX)/o.grid[0])*o.grid[0],n=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-o.grid[0]:s+o.grid[0]:s)),{top:r-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:a.scrollTop()),left:n-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:a.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var o=this.counter;this._delay(function(){o===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,o=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)"auto"!==this._storedCSS[s]&&"static"!==this._storedCSS[s]||(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&o.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||o.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(o.push(function(t){this._trigger("remove",t,this._uiHash())}),o.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),o.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||o.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(o.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;s<o.length;s++)o[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){!1===t.Widget.prototype._trigger.apply(this,arguments)&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),"ui-effects-animated"),r=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=c[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:s.max<t?s.max:t)}function s(e){var i=h(),s=i._rgba=[];return e=e.toLowerCase(),u(a,function(t,o){var n,r=o.re.exec(e),a=r&&o.parse(r),h=o.space||"rgba";if(a)return n=i[h](a),i[l[h].cache]=n[l[h].cache],s=i._rgba=n._rgba,!1}),s.length?("0,0,0,0"===s.join()&&t.extend(s,n.transparent),i):n[e]}function o(t,e,i){return i=(i+1)%1,6*i<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}var n,r=/^([\-+])=\s*(\d+\.?\d*)/,a=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,o){return new t.Color.fn.parse(e,i,s,o)},l={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},c={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},p=h.support={},f=t("<p>")[0],u=t.each;f.style.cssText="background-color:rgba(1,1,1,.5)",p.rgba=f.style.backgroundColor.indexOf("rgba")>-1,u(l,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(e,o,r,a){if(void 0===e)return this._rgba=[null,null,null,null],this;(e.jquery||e.nodeType)&&(e=t(e).css(o),o=void 0);var c=this,p=t.type(e),f=this._rgba=[];return void 0!==o&&(e=[e,o,r,a],p="array"),"string"===p?this.parse(s(e)||n._default):"array"===p?(u(l.rgba.props,function(t,s){f[s.idx]=i(e[s.idx],s)}),this):"object"===p?(e instanceof h?u(l,function(t,i){e[i.cache]&&(c[i.cache]=e[i.cache].slice())}):u(l,function(s,o){var n=o.cache;u(o.props,function(t,s){if(!c[n]&&o.to){if("alpha"===t||null==e[t])return;c[n]=o.to(c._rgba)}c[n][s.idx]=i(e[t],s,!0)}),c[n]&&t.inArray(null,c[n].slice(0,3))<0&&(c[n][3]=1,o.from&&(c._rgba=o.from(c[n])))}),this):void 0},is:function(t){var e=h(t),i=!0,s=this;return u(l,function(t,o){var n,r=e[o.cache];return r&&(n=s[o.cache]||o.to&&o.to(s._rgba)||[],u(o.props,function(t,e){if(null!=r[e.idx])return i=r[e.idx]===n[e.idx]})),i}),i},_space:function(){var t=[],e=this;return u(l,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),o=s._space(),n=l[o],r=0===this.alpha()?h("transparent"):this,a=r[n.cache]||n.to(r._rgba),p=a.slice();return s=s[n.cache],u(n.props,function(t,o){var n=o.idx,r=a[n],h=s[n],l=c[o.type]||{};null!==h&&(null===r?p[n]=h:(l.mod&&(h-r>l.mod/2?r+=l.mod:r-h>l.mod/2&&(r-=l.mod)),p[n]=i((h-r)*e+r,o)))}),this[o](p)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),o=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*o[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&e<3&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,l.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,o=t[1]/255,n=t[2]/255,r=t[3],a=Math.max(s,o,n),h=Math.min(s,o,n),l=a-h,c=a+h,p=.5*c;return e=h===a?0:s===a?60*(o-n)/l+360:o===a?60*(n-s)/l+120:60*(s-o)/l+240,i=0===l?0:p<=.5?l/c:l/(2-c),[Math.round(e)%360,i,p,null==r?1:r]},l.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],n=t[3],r=s<=.5?s*(1+i):s+i-s*i,a=2*s-r;return[Math.round(255*o(a,r,e+1/3)),Math.round(255*o(a,r,e)),Math.round(255*o(a,r,e-1/3)),n]},u(l,function(e,s){var o=s.props,n=s.cache,a=s.to,l=s.from;h.fn[e]=function(e){if(a&&!this[n]&&(this[n]=a(this._rgba)),void 0===e)return this[n].slice();var s,r=t.type(e),c="array"===r||"object"===r?e:arguments,p=this[n].slice();return u(o,function(t,e){var s=c["object"===r?t:e.idx];null==s&&(s=p[e.idx]),p[e.idx]=i(s,e)}),l?(s=h(l(p)),s[n]=p,s):h(p)},u(o,function(i,s){h.fn[i]||(h.fn[i]=function(o){var n,a=t.type(o),h="alpha"===i?this._hsla?"hsla":"rgba":e,l=this[h](),c=l[s.idx];return"undefined"===a?c:("function"===a&&(o=o.call(this,c),a=t.type(o)),null==o&&s.empty?this:("string"===a&&(n=r.exec(o))&&(o=c+parseFloat(n[2])*("+"===n[1]?1:-1)),l[s.idx]=o,this[h](l)))})})}),h.hook=function(e){var i=e.split(" ");u(i,function(e,i){t.cssHooks[i]={set:function(e,o){var n,r,a=""
-;if("transparent"!==o&&("string"!==t.type(o)||(n=s(o)))){if(o=h(n||o),!p.rgba&&1!==o._rgba[3]){for(r="backgroundColor"===i?e.parentNode:e;(""===a||"transparent"===a)&&r&&r.style;)try{a=t.css(r,"backgroundColor"),r=r.parentNode}catch(t){}o=o.blend(a&&"transparent"!==a?a:"_default")}o=o.toRgbaString()}try{e.style[i]=o}catch(t){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor"),t.cssHooks.borderColor={expand:function(t){var e={};return u(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},n=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(r),function(){function e(e){var i,s,o=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,n={};if(o&&o.length&&o[0]&&o[o[0]])for(s=o.length;s--;)i=o[s],"string"==typeof o[i]&&(n[t.camelCase(i)]=o[i]);else for(i in o)"string"==typeof o[i]&&(n[i]=o[i]);return n}function i(e,i){var s,n,r={};for(s in i)n=i[s],e[s]!==n&&(o[s]||!t.fx.step[s]&&isNaN(parseFloat(n))||(r[s]=n));return r}var s=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(r.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(o,n,r,a){var h=t.speed(n,r,a);return this.queue(function(){var n,r=t(this),a=r.attr("class")||"",l=h.children?r.find("*").addBack():r;l=l.map(function(){return{el:t(this),start:e(this)}}),n=function(){t.each(s,function(t,e){o[e]&&r[e+"Class"](o[e])})},n(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),r.attr("class",a),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){n(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(r[0])})})},t.fn.extend({addClass:function(e){return function(i,s,o,n){return s?t.effects.animateClass.call(this,{add:i},s,o,n):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,o,n){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,o,n):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,o,n,r){return"boolean"==typeof s||void 0===s?o?t.effects.animateClass.call(this,s?{add:i}:{remove:i},o,n,r):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,o,n)}}(t.fn.toggleClass),switchClass:function(e,i,s,o,n){return t.effects.animateClass.call(this,{add:i,remove:e},s,o,n)}})}(),function(){function e(e,i,s,o){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(o=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(o=s,s=i,i={}),t.isFunction(s)&&(o=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=o||i.complete,e}function i(e){return!(e&&"number"!=typeof e&&!t.fx.speeds[e])||("string"==typeof e&&!t.effects.effect[e]||(!!t.isFunction(e)||"object"==typeof e&&!e.effect))}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),o=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,n=o.exec(t)||["",0,i,s,0];return{top:parseFloat(n[1])||0,right:"auto"===n[2]?i:parseFloat(n[2]),bottom:"auto"===n[3]?s:parseFloat(n[3]),left:parseFloat(n[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(n)||e(i)}}(t.expr.filters.animated)),!1!==t.uiBackCompat&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;i<s;i++)null!==e[i]&&t.data("ui-effects-"+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,o=e.length;s<o;s++)null!==e[s]&&(i=t.data("ui-effects-"+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),float:e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),o={width:e.width(),height:e.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return e.wrap(s),(e[0]===n||t.contains(e[0],n))&&t(n).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(o),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,o="vertical"!==i?(e||100)/100:1;return{height:t.height()*o,width:t.width()*s,outerHeight:t.outerHeight()*o,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data("ui-effects-style",t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data("ui-effects-style")||"",t.removeData("ui-effects-style")},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),o=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),float:e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data("ui-effects-placeholder",i)),e.css({position:s,left:o.left,top:o.top}),i},removePlaceholder:function(t){var e="ui-effects-placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,o){return o=o||{},t.each(i,function(t,i){var n=e.cssUnit(i);n[0]>0&&(o[i]=n[0]*s+n[1])}),o}}),t.fn.extend({effect:function(){function i(e){function i(){h.removeData(n),t.effects.cleanUp(h),"hide"===s.mode&&h.hide(),a()}function a(){t.isFunction(l)&&l.call(h[0]),t.isFunction(e)&&e()}var h=t(this);s.mode=p.shift(),!1===t.uiBackCompat||r?"none"===s.mode?(h[c](),a()):o.call(h[0],s,i):(h.is(":hidden")?"hide"===c:"show"===c)?(h[c](),a()):o.call(h[0],s,a)}var s=e.apply(this,arguments),o=t.effects.effect[s.effect],r=o.mode,a=s.queue,h=a||"fx",l=s.complete,c=s.mode,p=[],f=function(e){var i=t(this),s=t.effects.mode(i,c)||r;i.data(n,!0),p.push(s),r&&("show"===s||s===r&&"hide"===s)&&i.show(),r&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!o?c?this[c](s.duration,l):this.each(function(){l&&l.call(this)}):!1===a?this.each(f).each(i):this.queue(h,f).queue(h,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var o=e.apply(this,arguments);return o.mode="show",this.effect.call(this,o)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var o=e.apply(this,arguments);return o.mode="hide",this.effect.call(this,o)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var o=e.apply(this,arguments);return o.mode="toggle",this.effect.call(this,o)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),o=t(e.to),n="fixed"===o.css("position"),r=t("body"),a=n?r.scrollTop():0,h=n?r.scrollLeft():0,l=o.offset(),c={top:l.top-a,left:l.left-h,height:o.innerHeight(),width:o.innerWidth()},p=s.offset(),f=t("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(e.className).css({top:p.top-a,left:p.left-h,height:s.innerHeight(),width:s.innerWidth(),position:n?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){f.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return t<.5?i(2*t)/2:1-i(-2*t+2)/2}})}();t.effects,t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},o=t(this),n=e.direction||"up",r=o.cssClip(),a={clip:t.extend({},r)},h=t.effects.createPlaceholder(o);a.clip[s[n][0]]=a.clip[s[n][1]],"show"===e.mode&&(o.cssClip(a.clip),h&&h.css(t.effects.clipToBox(a)),a.clip=r),h&&h.animate(t.effects.clipToBox(a),e.duration,e.easing),o.animate(a,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,o,n,r=t(this),a=e.mode,h="hide"===a,l="show"===a,c=e.direction||"up",p=e.distance,f=e.times||5,u=2*f+(l||h?1:0),d=e.duration/u,g=e.easing,m="up"===c||"down"===c?"top":"left",v="up"===c||"left"===c,_=0,b=r.queue().length;for(t.effects.createPlaceholder(r),n=r.css(m),p||(p=r["top"===m?"outerHeight":"outerWidth"]()/3),l&&(o={opacity:1},o[m]=n,r.css("opacity",0).css(m,v?2*-p:2*p).animate(o,d,g)),h&&(p/=Math.pow(2,f-1)),o={},o[m]=n;_<f;_++)s={},s[m]=(v?"-=":"+=")+p,r.animate(s,d,g).animate(o,d,g),p=h?2*p:p/2;h&&(s={opacity:0},s[m]=(v?"-=":"+=")+p,r.animate(s,d,g)),r.queue(i),t.effects.unshift(r,b,u+1)}),t.effects.define("drop","hide",function(e,i){var s,o=t(this),n=e.mode,r="show"===n,a=e.direction||"left",h="up"===a||"down"===a?"top":"left",l="up"===a||"left"===a?"-=":"+=",c="+="===l?"-=":"+=",p={opacity:0};t.effects.createPlaceholder(o),s=e.distance||o["top"===h?"outerHeight":"outerWidth"](!0)/2,p[h]=l+s,r&&(o.css(p),p[h]=c+s,p.opacity=1),o.animate(p,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),o=e.mode,n="show"===o,r="hide"===o,a=e.size||15,h=/([0-9]+)%/.exec(a),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],p=e.duration/2,f=t.effects.createPlaceholder(s),u=s.cssClip(),d={clip:t.extend({},u)},g={clip:t.extend({},u)},m=[u[c[0]],u[c[1]]],v=s.queue().length;h&&(a=parseInt(h[1],10)/100*m[r?0:1]),d.clip[c[0]]=a,g.clip[c[0]]=a,g.clip[c[1]]=0,n&&(s.cssClip(g.clip),f&&f.css(t.effects.clipToBox(g)),g.clip=u),s.queue(function(i){f&&f.animate(t.effects.clipToBox(d),p,e.easing).animate(t.effects.clipToBox(g),p,e.easing),i()}).animate(d,p,e.easing).animate(g,p,e.easing).queue(i),t.effects.unshift(s,v,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),o={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(o.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(o,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,o,n,r=t(this),a=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,p="effect"!==c,f=e.scale||"both",u=e.origin||["middle","center"],d=r.css("position"),g=r.position(),m=t.effects.scaledDimensions(r),v=e.from||m,_=e.to||t.effects.scaledDimensions(r,0);t.effects.createPlaceholder(r),"show"===c&&(n=v,v=_,_=n),o={from:{y:v.height/m.height,x:v.width/m.width},to:{y:_.height/m.height,x:_.width/m.width}},"box"!==f&&"both"!==f||(o.from.y!==o.to.y&&(v=t.effects.setTransition(r,h,o.from.y,v),_=t.effects.setTransition(r,h,o.to.y,_)),o.from.x!==o.to.x&&(v=t.effects.setTransition(r,l,o.from.x,v),_=t.effects.setTransition(r,l,o.to.x,_))),"content"!==f&&"both"!==f||o.from.y!==o.to.y&&(v=t.effects.setTransition(r,a,o.from.y,v),_=t.effects.setTransition(r,a,o.to.y,_)),u&&(s=t.effects.getBaseline(u,m),v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left,_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left),r.css(v),"content"!==f&&"both"!==f||(h=h.concat(["marginTop","marginBottom"]).concat(a),l=l.concat(["marginLeft","marginRight"]),r.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),n={height:s.height*o.from.y,width:s.width*o.from.x,outerHeight:s.outerHeight*o.from.y,outerWidth:s.outerWidth*o.from.x},r={height:s.height*o.to.y,width:s.width*o.to.x,outerHeight:s.height*o.to.y,outerWidth:s.width*o.to.x};o.from.y!==o.to.y&&(n=t.effects.setTransition(i,h,o.from.y,n),r=t.effects.setTransition(i,h,o.to.y,r)),o.from.x!==o.to.x&&(n=t.effects.setTransition(i,l,o.from.x,n),r=t.effects.setTransition(i,l,o.to.x,r)),p&&t.effects.saveStyle(i),i.css(n),i.animate(r,e.duration,e.easing,function(){p&&t.effects.restoreStyle(i)})})),r.animate(_,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=r.offset();0===_.opacity&&r.css("opacity",v.opacity),p||(r.css("position","static"===d?"relative":d).offset(e),t.effects.saveStyle(r)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),o=e.mode,n=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==o?0:100),r=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,n,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(r.from.opacity=1,r.to.opacity=0),t.effects.effect.size.call(this,r,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),o=e.mode,n="show"===o,r="hide"===o,a=n||r,h=2*(e.times||5)+(a?1:0),l=e.duration/h,c=0,p=1,f=s.queue().length;for(!n&&s.is(":visible")||(s.css("opacity",0).show(),c=1);p<h;p++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,f,h+1)}),t.effects.define("shake",function(e,i){var s=1,o=t(this),n=e.direction||"left",r=e.distance||20,a=e.times||3,h=2*a+1,l=Math.round(e.duration/h),c="up"===n||"down"===n?"top":"left",p="up"===n||"left"===n,f={},u={},d={},g=o.queue().length;for(t.effects.createPlaceholder(o),f[c]=(p?"-=":"+=")+r,u[c]=(p?"+=":"-=")+2*r,d[c]=(p?"-=":"+=")+2*r,o.animate(f,l,e.easing);s<a;s++)o.animate(u,l,e.easing).animate(d,l,e.easing);o.animate(u,l,e.easing).animate(f,l/2,e.easing).queue(i),t.effects.unshift(o,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,o,n=t(this),r={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},a=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,p=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0),f={};t.effects.createPlaceholder(n),s=n.cssClip(),o=n.position()[l],f[l]=(c?-1:1)*p+o,f.clip=n.cssClip(),f.clip[r[h][1]]=f.clip[r[h][0]],"show"===a&&(n.cssClip(f.clip),n.css(l,f[l]),f.clip=s,f[l]=o),n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});!1!==t.uiBackCompat&&t.effects.define("transfer",function(e,i){t(this).transfer(e,i)})}); })(this);
+(function (window, undefined) { !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(P){P.ui=P.ui||{};P.ui.version="1.12.1";var o,i=0,a=Array.prototype.slice;P.cleanData=(o=P.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)try{(e=P._data(i,"events"))&&e.remove&&P(i).triggerHandler("remove")}catch(t){}o(t)}),P.widget=function(t,i,e){var s,o,n,r={},a=t.split(".")[0],h=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=P.Widget),P.isArray(e)&&(e=P.extend.apply(null,[{}].concat(e))),P.expr[":"][h.toLowerCase()]=function(t){return!!P.data(t,h)},P[a]=P[a]||{},s=P[a][t],o=P[a][t]=function(t,e){if(!this._createWidget)return new o(t,e);arguments.length&&this._createWidget(t,e)},P.extend(o,s,{version:e.version,_proto:P.extend({},e),_childConstructors:[]}),(n=new i).options=P.widget.extend({},n.options),P.each(e,function(e,s){function o(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}P.isFunction(s)?r[e]=function(){var t,e=this._super,i=this._superApply;return this._super=o,this._superApply=n,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:r[e]=s}),o.prototype=P.widget.extend(n,{widgetEventPrefix:s&&n.widgetEventPrefix||t},r,{constructor:o,namespace:a,widgetName:t,widgetFullName:h}),s?(P.each(s._childConstructors,function(t,e){var i=e.prototype;P.widget(i.namespace+"."+i.widgetName,o,e._proto)}),delete s._childConstructors):i._childConstructors.push(o),P.widget.bridge(t,o),o},P.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),o=0,n=s.length;o<n;o++)for(e in s[o])i=s[o][e],s[o].hasOwnProperty(e)&&void 0!==i&&(P.isPlainObject(i)?t[e]=P.isPlainObject(t[e])?P.widget.extend({},t[e],i):P.widget.extend({},i):t[e]=i);return t},P.widget.bridge=function(n,e){var r=e.prototype.widgetFullName||n;P.fn[n]=function(i){var t="string"==typeof i,s=a.call(arguments,1),o=this;return t?this.length||"instance"!==i?this.each(function(){var t,e=P.data(this,r);return"instance"===i?(o=e,!1):e?P.isFunction(e[i])&&"_"!==i.charAt(0)?(t=e[i].apply(e,s))!==e&&void 0!==t?(o=t&&t.jquery?o.pushStack(t.get()):t,!1):void 0:P.error("no such method '"+i+"' for "+n+" widget instance"):P.error("cannot call methods on "+n+" prior to initialization; attempted to call method '"+i+"'")}):o=void 0:(s.length&&(i=P.widget.extend.apply(null,[i].concat(s))),this.each(function(){var t=P.data(this,r);t?(t.option(i||{}),t._init&&t._init()):P.data(this,r,new e(i,this))})),o}},P.Widget=function(){},P.Widget._childConstructors=[],P.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=P(e||this.defaultElement||this)[0],this.element=P(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=P(),this.hoverable=P(),this.focusable=P(),this.classesElementLookup={},e!==this&&(P.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=P(e.style?e.ownerDocument:e.document||e),this.window=P(this.document[0].defaultView||this.document[0].parentWindow)),this.options=P.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:P.noop,_create:P.noop,_init:P.noop,destroy:function(){var i=this;this._destroy(),P.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:P.noop,widget:function(){return this.element},option:function(t,e){var i,s,o,n=t;if(0===arguments.length)return P.widget.extend({},this.options);if("string"==typeof t)if(n={},t=(i=t.split(".")).shift(),i.length){for(s=n[t]=P.widget.extend({},this.options[t]),o=0;o<i.length-1;o++)s[i[o]]=s[i[o]]||{},s=s[i[o]];if(t=i.pop(),1===arguments.length)return void 0===s[t]?null:s[t];s[t]=e}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];n[t]=e}return this._setOptions(n),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(t){var e,i,s;for(e in t)s=this.classesElementLookup[e],t[e]!==this.options.classes[e]&&s&&s.length&&(i=P(s.get()),this._removeClass(s,e),i.addClass(this._classes({element:i,keys:e,classes:t,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(o){var n=[],r=this;function t(t,e){for(var i,s=0;s<t.length;s++)i=r.classesElementLookup[t[s]]||P(),i=o.add?P(P.unique(i.get().concat(o.element.get()))):P(i.not(o.element).get()),r.classesElementLookup[t[s]]=i,n.push(t[s]),e&&o.classes[t[s]]&&n.push(o.classes[t[s]])}return o=P.extend({element:this.element,classes:this.options.classes||{}},o),this._on(o.element,{remove:"_untrackClassesElement"}),o.keys&&t(o.keys.match(/\S+/g)||[],!0),o.extra&&t(o.extra.match(/\S+/g)||[]),n.join(" ")},_untrackClassesElement:function(i){var s=this;P.each(s.classesElementLookup,function(t,e){-1!==P.inArray(i.target,e)&&(s.classesElementLookup[t]=P(e.not(i.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var o="string"==typeof t||null===t,n={extra:o?e:i,keys:o?t:e,element:o?this.element:t,add:s};return n.element.toggleClass(this._classes(n),s),this},_on:function(r,a,t){var h,l=this;"boolean"!=typeof r&&(t=a,a=r,r=!1),t?(a=h=P(a),this.bindings=this.bindings.add(a)):(t=a,a=this.element,h=this.widget()),P.each(t,function(t,e){function i(){if(r||!0!==l.options.disabled&&!P(this).hasClass("ui-state-disabled"))return("string"==typeof e?l[e]:e).apply(l,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||P.guid++);var s=t.match(/^([\w:-]*)\s*(.*)$/),o=s[1]+l.eventNamespace,n=s[2];n?h.on(o,n,i):a.on(o,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e).off(e),this.bindings=P(this.bindings.not(t).get()),this.focusable=P(this.focusable.not(t).get()),this.hoverable=P(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(P(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(P(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(P(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(P(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var s,o,n=this.options[t];if(i=i||{},(e=P.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],o=e.originalEvent)for(s in o)s in e||(e[s]=o[s]);return this.element.trigger(e,i),!(P.isFunction(n)&&!1===n.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},P.each({show:"fadeIn",hide:"fadeOut"},function(n,r){P.Widget.prototype["_"+n]=function(e,t,i){var s;"string"==typeof t&&(t={effect:t});var o=t?!0!==t&&"number"!=typeof t&&t.effect||r:n;"number"==typeof(t=t||{})&&(t={duration:t}),s=!P.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),s&&P.effects&&P.effects.effect[o]?e[n](t):o!==n&&e[o]?e[o](t.duration,t.easing,i):e.queue(function(t){P(this)[n](),i&&i.call(e[0]),t()})}});var n,x,C,s,r,h,l,c,z;P.widget;function H(t,e,i){return[parseFloat(t[0])*(c.test(t[0])?e/100:1),parseFloat(t[1])*(c.test(t[1])?i/100:1)]}function I(t,e){return parseInt(P.css(t,e),10)||0}x=Math.max,C=Math.abs,s=/left|center|right/,r=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,l=/^\w+/,c=/%$/,z=P.fn.position,P.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,e,i=P("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),s=i.children()[0];return P("body").append(i),t=s.offsetWidth,i.css("overflow","scroll"),t===(e=s.offsetWidth)&&(e=i[0].clientWidth),i.remove(),n=t-e},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),s="scroll"===e||"auto"===e&&t.width<t.element[0].scrollWidth;return{width:"scroll"===i||"auto"===i&&t.height<t.element[0].scrollHeight?P.position.scrollbarWidth():0,height:s?P.position.scrollbarWidth():0}},getWithinInfo:function(t){var e=P(t||window),i=P.isWindow(e[0]),s=!!e[0]&&9===e[0].nodeType;return{element:e,isWindow:i,isDocument:s,offset:!i&&!s?P(t).offset():{left:0,top:0},scrollLeft:e.scrollLeft(),scrollTop:e.scrollTop(),width:e.outerWidth(),height:e.outerHeight()}}},P.fn.position=function(p){if(!p||!p.of)return z.apply(this,arguments);p=P.extend({},p);var f,u,d,g,m,t,e,v=P(p.of),_=P.position.getWithinInfo(p.within),b=P.position.getScrollInfo(_),w=(p.collision||"flip").split(" "),y={},i=9===(e=(t=v)[0]).nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:P.isWindow(e)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:e.preventDefault?{width:0,height:0,offset:{top:e.pageY,left:e.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()};return v[0].preventDefault&&(p.at="left top"),u=i.width,d=i.height,g=i.offset,m=P.extend({},g),P.each(["my","at"],function(){var t,e,i=(p[this]||"").split(" ");1===i.length&&(i=s.test(i[0])?i.concat(["center"]):r.test(i[0])?["center"].concat(i):["center","center"]),i[0]=s.test(i[0])?i[0]:"center",i[1]=r.test(i[1])?i[1]:"center",t=h.exec(i[0]),e=h.exec(i[1]),y[this]=[t?t[0]:0,e?e[0]:0],p[this]=[l.exec(i[0])[0],l.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===p.at[0]?m.left+=u:"center"===p.at[0]&&(m.left+=u/2),"bottom"===p.at[1]?m.top+=d:"center"===p.at[1]&&(m.top+=d/2),f=H(y.at,u,d),m.left+=f[0],m.top+=f[1],this.each(function(){var i,t,r=P(this),a=r.outerWidth(),h=r.outerHeight(),e=I(this,"marginLeft"),s=I(this,"marginTop"),o=a+e+I(this,"marginRight")+b.width,n=h+s+I(this,"marginBottom")+b.height,l=P.extend({},m),c=H(y.my,r.outerWidth(),r.outerHeight());"right"===p.my[0]?l.left-=a:"center"===p.my[0]&&(l.left-=a/2),"bottom"===p.my[1]?l.top-=h:"center"===p.my[1]&&(l.top-=h/2),l.left+=c[0],l.top+=c[1],i={marginLeft:e,marginTop:s},P.each(["left","top"],function(t,e){P.ui.position[w[t]]&&P.ui.position[w[t]][e](l,{targetWidth:u,targetHeight:d,elemWidth:a,elemHeight:h,collisionPosition:i,collisionWidth:o,collisionHeight:n,offset:[f[0]+c[0],f[1]+c[1]],my:p.my,at:p.at,within:_,elem:r})}),p.using&&(t=function(t){var e=g.left-l.left,i=e+u-a,s=g.top-l.top,o=s+d-h,n={target:{element:v,left:g.left,top:g.top,width:u,height:d},element:{element:r,left:l.left,top:l.top,width:a,height:h},horizontal:i<0?"left":0<e?"right":"center",vertical:o<0?"top":0<s?"bottom":"middle"};u<a&&C(e+i)<u&&(n.horizontal="center"),d<h&&C(s+o)<d&&(n.vertical="middle"),x(C(e),C(i))>x(C(s),C(o))?n.important="horizontal":n.important="vertical",p.using.call(this,t,n)}),r.offset(P.extend(l,{using:t}))})},P.ui.position={fit:{left:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollLeft:s.offset.left,n=s.width,r=t.left-e.collisionPosition.marginLeft,a=o-r,h=r+e.collisionWidth-n-o;e.collisionWidth>n?0<a&&h<=0?(i=t.left+a+e.collisionWidth-n-o,t.left+=a-i):t.left=!(0<h&&a<=0)&&h<a?o+n-e.collisionWidth:o:0<a?t.left+=a:0<h?t.left-=h:t.left=x(t.left-r,t.left)},top:function(t,e){var i,s=e.within,o=s.isWindow?s.scrollTop:s.offset.top,n=e.within.height,r=t.top-e.collisionPosition.marginTop,a=o-r,h=r+e.collisionHeight-n-o;e.collisionHeight>n?0<a&&h<=0?(i=t.top+a+e.collisionHeight-n-o,t.top+=a-i):t.top=!(0<h&&a<=0)&&h<a?o+n-e.collisionHeight:o:0<a?t.top+=a:0<h?t.top-=h:t.top=x(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,o=e.within,n=o.offset.left+o.scrollLeft,r=o.width,a=o.isWindow?o.scrollLeft:o.offset.left,h=t.left-e.collisionPosition.marginLeft,l=h-a,c=h+e.collisionWidth-r-a,p="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,f="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,u=-2*e.offset[0];l<0?((i=t.left+p+f+u+e.collisionWidth-r-n)<0||i<C(l))&&(t.left+=p+f+u):0<c&&(0<(s=t.left-e.collisionPosition.marginLeft+p+f+u-a)||C(s)<c)&&(t.left+=p+f+u)},top:function(t,e){var i,s,o=e.within,n=o.offset.top+o.scrollTop,r=o.height,a=o.isWindow?o.scrollTop:o.offset.top,h=t.top-e.collisionPosition.marginTop,l=h-a,c=h+e.collisionHeight-r-a,p="top"===e.my[1]?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,u=-2*e.offset[1];l<0?((s=t.top+p+f+u+e.collisionHeight-r-n)<0||s<C(l))&&(t.top+=p+f+u):0<c&&(0<(i=t.top-e.collisionPosition.marginTop+p+f+u-a)||C(i)<c)&&(t.top+=p+f+u)}},flipfit:{left:function(){P.ui.position.flip.left.apply(this,arguments),P.ui.position.fit.left.apply(this,arguments)},top:function(){P.ui.position.flip.top.apply(this,arguments),P.ui.position.fit.top.apply(this,arguments)}}};P.ui.position,P.extend(P.expr[":"],{data:P.expr.createPseudo?P.expr.createPseudo(function(e){return function(t){return!!P.data(t,e)}}):function(t,e,i){return!!P.data(t,i[3])}}),P.fn.extend({disableSelection:(t="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}),enableSelection:function(){return this.off(".ui-disableSelection")}}),P.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):P(this[0].form)},P.ui.formResetMixin={_formResetHandler:function(){var e=P(this);setTimeout(function(){var t=e.data("ui-form-reset-instances");P.each(t,function(){this.refresh()})})},_bindFormResetHandler:function(){var t;this.form=this.element.form(),this.form.length&&((t=this.form.data("ui-form-reset-instances")||[]).length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t))},_unbindFormResetHandler:function(){var t;this.form.length&&((t=this.form.data("ui-form-reset-instances")).splice(P.inArray(this,t),1),t.length?this.form.data("ui-form-reset-instances",t):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset"))}},P.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},P.fn.scrollParent=function(t){var e=this.css("position"),i="absolute"===e,s=t?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var t=P(this);return(!i||"static"!==t.css("position"))&&s.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==e&&o.length?o:P(this[0].ownerDocument||document)},P.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var t,p=!1;P(document).on("mouseup",function(){p=!1});P.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(t){if(!0===P.data(t.target,e.widgetName+".preventClickEvent"))return P.removeData(t.target,e.widgetName+".preventClickEvent"),t.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!p){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var e=this,i=1===t.which,s=!("string"!=typeof this.options.cancel||!t.target.nodeName)&&P(t.target).closest(this.options.cancel).length;return i&&!s&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(t),!this._mouseStarted)?(t.preventDefault(),!0):(!0===P.data(t.target,this.widgetName+".preventClickEvent")&&P.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return e._mouseMove(t)},this._mouseUpDelegate=function(t){return e._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),p=!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(P.ui.ie&&(!document.documentMode||document.documentMode<9)&&!t.button)return this._mouseUp(t);if(!t.which)if(t.originalEvent.altKey||t.originalEvent.ctrlKey||t.originalEvent.metaKey||t.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,t),this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&P.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,p=!1,t.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),P.ui.plugin={add:function(t,e,i){var s,o=P.ui[t].prototype;for(s in i)o.plugins[s]=o.plugins[s]||[],o.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var o,n=t.plugins[e];if(n&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(o=0;o<n.length;o++)t.options[n[o][0]]&&n[o][1].apply(t.element,i)}},P.ui.safeActiveElement=function(e){var i;try{i=e.activeElement}catch(t){i=e.body}return(i=i||e.body).nodeName||(i=e.body),i},P.ui.safeBlur=function(t){t&&"body"!==t.nodeName.toLowerCase()&&P(t).trigger("blur")};P.widget("ui.draggable",P.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){(this.helper||this.element).is(".ui-draggable-dragging")?this.destroyOnClear=!0:(this._removeHandleClassName(),this._mouseDestroy())},_mouseCapture:function(t){var e=this.options;return!(this.helper||e.disabled||0<P(t.target).closest(".ui-resizable-handle").length)&&(this.handle=this._getHandle(t),!!this.handle&&(this._blurActiveElement(t),this._blockFrames(!0===e.iframeFix?"iframe":e.iframeFix),!0))},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=P(this);return P("<div>").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var e=P.ui.safeActiveElement(this.document[0]);P(t.target).closest(e).length||P.ui.safeBlur(e)},_mouseStart:function(t){var e=this.options;return this.helper=this._createHelper(t),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),P.ui.ddmanager&&(P.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0<this.helper.parents().filter(function(){return"fixed"===P(this).css("position")}).length,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this._setContainment(),!1===this._trigger("start",t)?(this._clear(),!1):(this._cacheHelperProportions(),P.ui.ddmanager&&!e.dropBehaviour&&P.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),P.ui.ddmanager&&P.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(t,e){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!e){var i=this._uiHash();if(!1===this._trigger("drag",t,i))return this._mouseUp(new P.Event("mouseup",t)),!1;this.position=i.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",P.ui.ddmanager&&P.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var e=this,i=!1;return P.ui.ddmanager&&!this.options.dropBehaviour&&(i=P.ui.ddmanager.drop(this,t)),this.dropped&&(i=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!i||"valid"===this.options.revert&&i||!0===this.options.revert||P.isFunction(this.options.revert)&&this.options.revert.call(this.element,i)?P(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){!1!==e._trigger("stop",t)&&e._clear()}):!1!==this._trigger("stop",t)&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),P.ui.ddmanager&&P.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.trigger("focus"),P.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new P.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(t){return!this.options.handle||!!P(t.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(t){var e=this.options,i=P.isFunction(e.helper),s=i?P(e.helper.apply(this.element[0],[t])):"clone"===e.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===e.appendTo?this.element[0].parentNode:e.appendTo),i&&s[0]===this.element[0]&&this._setPositionRelative(),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),P.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),e=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==e&&P.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,e,i,s=this.options,o=this.document[0];this.relativeContainer=null,s.containment?"window"!==s.containment?"document"!==s.containment?s.containment.constructor!==Array?("parent"===s.containment&&(s.containment=this.helper[0].parentNode),(i=(e=P(s.containment))[0])&&(t=/(scroll|auto)/.test(e.css("overflow")),this.containment=[(parseInt(e.css("borderLeftWidth"),10)||0)+(parseInt(e.css("paddingLeft"),10)||0),(parseInt(e.css("borderTopWidth"),10)||0)+(parseInt(e.css("paddingTop"),10)||0),(t?Math.max(i.scrollWidth,i.offsetWidth):i.offsetWidth)-(parseInt(e.css("borderRightWidth"),10)||0)-(parseInt(e.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(i.scrollHeight,i.offsetHeight):i.offsetHeight)-(parseInt(e.css("borderBottomWidth"),10)||0)-(parseInt(e.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=e)):this.containment=s.containment:this.containment=[0,0,P(o).width()-this.helperProportions.width-this.margins.left,(P(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=[P(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,P(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,P(window).scrollLeft()+P(window).width()-this.helperProportions.width-this.margins.left,P(window).scrollTop()+(P(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=null},_convertPositionTo:function(t,e){e=e||this.position;var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,o,n,r=this.options,a=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return a&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(i=this.relativeContainer?(s=this.relativeContainer.offset(),[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),r.grid&&(o=r.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/r.grid[1])*r.grid[1]:this.originalPageY,l=!i||o-this.offset.click.top>=i[1]||o-this.offset.click.top>i[3]?o:o-this.offset.click.top>=i[1]?o-r.grid[1]:o+r.grid[1],n=r.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/r.grid[0])*r.grid[0]:this.originalPageX,h=!i||n-this.offset.click.left>=i[0]||n-this.offset.click.left>i[2]?n:n-this.offset.click.left>=i[0]?n-r.grid[0]:n+r.grid[0]),"y"===r.axis&&(h=this.originalPageX),"x"===r.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:a?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:a?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(t,e,i){return i=i||this._uiHash(),P.ui.plugin.call(this,t,[e,i,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),i.offset=this.positionAbs),P.Widget.prototype._trigger.call(this,t,e,i)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),P.ui.plugin.add("draggable","connectToSortable",{start:function(e,t,i){var s=P.extend({},t,{item:i.element});i.sortables=[],P(i.options.connectToSortable).each(function(){var t=P(this).sortable("instance");t&&!t.options.disabled&&(i.sortables.push(t),t.refreshPositions(),t._trigger("activate",e,s))})},stop:function(e,t,i){var s=P.extend({},t,{item:i.element});i.cancelHelperRemoval=!1,P.each(i.sortables,function(){var t=this;t.isOver?(t.isOver=0,i.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,s))})},drag:function(i,s,o){P.each(o.sortables,function(){var t=!1,e=this;e.positionAbs=o.positionAbs,e.helperProportions=o.helperProportions,e.offset.click=o.offset.click,e._intersectsWith(e.containerCache)&&(t=!0,P.each(o.sortables,function(){return this.positionAbs=o.positionAbs,this.helperProportions=o.helperProportions,this.offset.click=o.offset.click,this!==e&&this._intersectsWith(this.containerCache)&&P.contains(e.element[0],this.element[0])&&(t=!1),t})),t?(e.isOver||(e.isOver=1,o._parent=s.helper.parent(),e.currentItem=s.helper.appendTo(e.element).data("ui-sortable-item",!0),e.options._helper=e.options.helper,e.options.helper=function(){return s.helper[0]},i.target=e.currentItem[0],e._mouseCapture(i,!0),e._mouseStart(i,!0,!0),e.offset.click.top=o.offset.click.top,e.offset.click.left=o.offset.click.left,e.offset.parent.left-=o.offset.parent.left-e.offset.parent.left,e.offset.parent.top-=o.offset.parent.top-e.offset.parent.top,o._trigger("toSortable",i),o.dropped=e.element,P.each(o.sortables,function(){this.refreshPositions()}),o.currentItem=o.element,e.fromOutside=o),e.currentItem&&(e._mouseDrag(i),s.position=e.position)):e.isOver&&(e.isOver=0,e.cancelHelperRemoval=!0,e.options._revert=e.options.revert,e.options.revert=!1,e._trigger("out",i,e._uiHash(e)),e._mouseStop(i,!0),e.options.revert=e.options._revert,e.options.helper=e.options._helper,e.placeholder&&e.placeholder.remove(),s.helper.appendTo(o._parent),o._refreshOffsets(i),s.position=o._generatePosition(i,!0),o._trigger("fromSortable",i),o.dropped=!1,P.each(o.sortables,function(){this.refreshPositions()}))})}}),P.ui.plugin.add("draggable","cursor",{start:function(t,e,i){var s=P("body"),o=i.options;s.css("cursor")&&(o._cursor=s.css("cursor")),s.css("cursor",o.cursor)},stop:function(t,e,i){var s=i.options;s._cursor&&P("body").css("cursor",s._cursor)}}),P.ui.plugin.add("draggable","opacity",{start:function(t,e,i){var s=P(e.helper),o=i.options;s.css("opacity")&&(o._opacity=s.css("opacity")),s.css("opacity",o.opacity)},stop:function(t,e,i){var s=i.options;s._opacity&&P(e.helper).css("opacity",s._opacity)}}),P.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,e,i){var s=i.options,o=!1,n=i.scrollParentNotHidden[0],r=i.document[0];n!==r&&"HTML"!==n.tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+n.offsetHeight-t.pageY<s.scrollSensitivity?n.scrollTop=o=n.scrollTop+s.scrollSpeed:t.pageY-i.overflowOffset.top<s.scrollSensitivity&&(n.scrollTop=o=n.scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+n.offsetWidth-t.pageX<s.scrollSensitivity?n.scrollLeft=o=n.scrollLeft+s.scrollSpeed:t.pageX-i.overflowOffset.left<s.scrollSensitivity&&(n.scrollLeft=o=n.scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(t.pageY-P(r).scrollTop()<s.scrollSensitivity?o=P(r).scrollTop(P(r).scrollTop()-s.scrollSpeed):P(window).height()-(t.pageY-P(r).scrollTop())<s.scrollSensitivity&&(o=P(r).scrollTop(P(r).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(t.pageX-P(r).scrollLeft()<s.scrollSensitivity?o=P(r).scrollLeft(P(r).scrollLeft()-s.scrollSpeed):P(window).width()-(t.pageX-P(r).scrollLeft())<s.scrollSensitivity&&(o=P(r).scrollLeft(P(r).scrollLeft()+s.scrollSpeed)))),!1!==o&&P.ui.ddmanager&&!s.dropBehaviour&&P.ui.ddmanager.prepareOffsets(i,t)}}),P.ui.plugin.add("draggable","snap",{start:function(t,e,i){var s=i.options;i.snapElements=[],P(s.snap.constructor!==String?s.snap.items||":data(ui-draggable)":s.snap).each(function(){var t=P(this),e=t.offset();this!==i.element[0]&&i.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:e.top,left:e.left})})},drag:function(t,e,i){for(var s,o,n,r,a,h,l,c,p,f=i.options,u=f.snapTolerance,d=e.offset.left,g=d+i.helperProportions.width,m=e.offset.top,v=m+i.helperProportions.height,_=i.snapElements.length-1;0<=_;_--)h=(a=i.snapElements[_].left-i.margins.left)+i.snapElements[_].width,c=(l=i.snapElements[_].top-i.margins.top)+i.snapElements[_].height,g<a-u||h+u<d||v<l-u||c+u<m||!P.contains(i.snapElements[_].item.ownerDocument,i.snapElements[_].item)?(i.snapElements[_].snapping&&i.options.snap.release&&i.options.snap.release.call(i.element,t,P.extend(i._uiHash(),{snapItem:i.snapElements[_].item})),i.snapElements[_].snapping=!1):("inner"!==f.snapMode&&(s=Math.abs(l-v)<=u,o=Math.abs(c-m)<=u,n=Math.abs(a-g)<=u,r=Math.abs(h-d)<=u,s&&(e.position.top=i._convertPositionTo("relative",{top:l-i.helperProportions.height,left:0}).top),o&&(e.position.top=i._convertPositionTo("relative",{top:c,left:0}).top),n&&(e.position.left=i._convertPositionTo("relative",{top:0,left:a-i.helperProportions.width}).left),r&&(e.position.left=i._convertPositionTo("relative",{top:0,left:h}).left)),p=s||o||n||r,"outer"!==f.snapMode&&(s=Math.abs(l-m)<=u,o=Math.abs(c-v)<=u,n=Math.abs(a-d)<=u,r=Math.abs(h-g)<=u,s&&(e.position.top=i._convertPositionTo("relative",{top:l,left:0}).top),o&&(e.position.top=i._convertPositionTo("relative",{top:c-i.helperProportions.height,left:0}).top),n&&(e.position.left=i._convertPositionTo("relative",{top:0,left:a}).left),r&&(e.position.left=i._convertPositionTo("relative",{top:0,left:h-i.helperProportions.width}).left)),!i.snapElements[_].snapping&&(s||o||n||r||p)&&i.options.snap.snap&&i.options.snap.snap.call(i.element,t,P.extend(i._uiHash(),{snapItem:i.snapElements[_].item})),i.snapElements[_].snapping=s||o||n||r||p)}}),P.ui.plugin.add("draggable","stack",{start:function(t,e,i){var s,o=i.options,n=P.makeArray(P(o.stack)).sort(function(t,e){return(parseInt(P(t).css("zIndex"),10)||0)-(parseInt(P(e).css("zIndex"),10)||0)});n.length&&(s=parseInt(P(n[0]).css("zIndex"),10)||0,P(n).each(function(t){P(this).css("zIndex",s+t)}),this.css("zIndex",s+n.length))}}),P.ui.plugin.add("draggable","zIndex",{start:function(t,e,i){var s=P(e.helper),o=i.options;s.css("zIndex")&&(o._zIndex=s.css("zIndex")),s.css("zIndex",o.zIndex)},stop:function(t,e,i){var s=i.options;s._zIndex&&P(e.helper).css("zIndex",s._zIndex)}});P.ui.draggable;P.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,e=this.options,i=e.accept;this.isover=!1,this.isout=!0,this.accept=P.isFunction(i)?i:function(t){return t.is(i)},this.proportions=function(){if(!arguments.length)return t||(t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight});t=arguments[0]},this._addToManager(e.scope),e.addClasses&&this._addClass("ui-droppable")},_addToManager:function(t){P.ui.ddmanager.droppables[t]=P.ui.ddmanager.droppables[t]||[],P.ui.ddmanager.droppables[t].push(this)},_splice:function(t){for(var e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var t=P.ui.ddmanager.droppables[this.options.scope];this._splice(t)},_setOption:function(t,e){var i;"accept"===t?this.accept=P.isFunction(e)?e:function(t){return t.is(e)}:"scope"===t&&(i=P.ui.ddmanager.droppables[this.options.scope],this._splice(i),this._addToManager(e)),this._super(t,e)},_activate:function(t){var e=P.ui.ddmanager.current;this._addActiveClass(),e&&this._trigger("activate",t,this.ui(e))},_deactivate:function(t){var e=P.ui.ddmanager.current;this._removeActiveClass(),e&&this._trigger("deactivate",t,this.ui(e))},_over:function(t){var e=P.ui.ddmanager.current;e&&(e.currentItem||e.element)[0]!==this.element[0]&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this._addHoverClass(),this._trigger("over",t,this.ui(e)))},_out:function(t){var e=P.ui.ddmanager.current;e&&(e.currentItem||e.element)[0]!==this.element[0]&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this._removeHoverClass(),this._trigger("out",t,this.ui(e)))},_drop:function(e,t){var i=t||P.ui.ddmanager.current,s=!1;return!(!i||(i.currentItem||i.element)[0]===this.element[0])&&(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var t=P(this).droppable("instance");if(t.options.greedy&&!t.options.disabled&&t.options.scope===i.options.scope&&t.accept.call(t.element[0],i.currentItem||i.element)&&f(i,P.extend(t,{offset:t.element.offset()}),t.options.tolerance,e))return!(s=!0)}),!s&&(!!this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(i)),this.element)))},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var f=P.ui.intersect=function(t,e,i,s){if(!e.offset)return!1;var o=(t.positionAbs||t.position.absolute).left+t.margins.left,n=(t.positionAbs||t.position.absolute).top+t.margins.top,r=o+t.helperProportions.width,a=n+t.helperProportions.height,h=e.offset.left,l=e.offset.top,c=h+e.proportions().width,p=l+e.proportions().height;switch(i){case"fit":return h<=o&&r<=c&&l<=n&&a<=p;case"intersect":return h<o+t.helperProportions.width/2&&r-t.helperProportions.width/2<c&&l<n+t.helperProportions.height/2&&a-t.helperProportions.height/2<p;case"pointer":return u(s.pageY,l,e.proportions().height)&&u(s.pageX,h,e.proportions().width);case"touch":return(l<=n&&n<=p||l<=a&&a<=p||n<l&&p<a)&&(h<=o&&o<=c||h<=r&&r<=c||o<h&&c<r);default:return!1}};function u(t,e,i){return e<=t&&t<e+i}!(P.ui.ddmanager={current:null,droppables:{default:[]},prepareOffsets:function(t,e){var i,s,o=P.ui.ddmanager.droppables[t.options.scope]||[],n=e?e.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();t:for(i=0;i<o.length;i++)if(!(o[i].options.disabled||t&&!o[i].accept.call(o[i].element[0],t.currentItem||t.element))){for(s=0;s<r.length;s++)if(r[s]===o[i].element[0]){o[i].proportions().height=0;continue t}o[i].visible="none"!==o[i].element.css("display"),o[i].visible&&("mousedown"===n&&o[i]._activate.call(o[i],e),o[i].offset=o[i].element.offset(),o[i].proportions({width:o[i].element[0].offsetWidth,height:o[i].element[0].offsetHeight}))}},drop:function(t,e){var i=!1;return P.each((P.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&f(t,this,this.options.tolerance,e)&&(i=this._drop.call(this,e)||i),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,e)))}),i},dragStart:function(t,e){t.element.parentsUntil("body").on("scroll.droppable",function(){t.options.refreshPositions||P.ui.ddmanager.prepareOffsets(t,e)})},drag:function(n,r){n.options.refreshPositions&&P.ui.ddmanager.prepareOffsets(n,r),P.each(P.ui.ddmanager.droppables[n.options.scope]||[],function(){var t,e,i,s,o;this.options.disabled||this.greedyChild||!this.visible||(o=!(s=f(n,this,this.options.tolerance,r))&&this.isover?"isout":s&&!this.isover?"isover":null)&&(this.options.greedy&&(e=this.options.scope,(i=this.element.parents(":data(ui-droppable)").filter(function(){return P(this).droppable("instance").options.scope===e})).length&&((t=P(i[0]).droppable("instance")).greedyChild="isover"===o)),t&&"isover"===o&&(t.isover=!1,t.isout=!0,t._out.call(t,r)),this[o]=!0,this["isout"===o?"isover":"isout"]=!1,this["isover"===o?"_over":"_out"].call(this,r),t&&"isout"===o&&(t.isout=!1,t.isover=!0,t._over.call(t,r)))})},dragStop:function(t,e){t.element.parentsUntil("body").off("scroll.droppable"),t.options.refreshPositions||P.ui.ddmanager.prepareOffsets(t,e)}})!==P.uiBackCompat&&P.widget("ui.droppable",P.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}});P.ui.droppable;P.widget("ui.resizable",P.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(t,e){if("hidden"===P(t).css("overflow"))return!1;var i,s=e&&"left"===e?"scrollLeft":"scrollTop";return 0<t[s]||(t[s]=1,i=0<t[s],t[s]=0,i)},_create:function(){var t,e=this.options,i=this;this._addClass("ui-resizable"),P.extend(this,{_aspectRatio:!!e.aspectRatio,aspectRatio:e.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:e.helper||e.ghost||e.animate?e.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(P("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&P(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();function t(t){P(t).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles()}},_setupHandles:function(){var t,e,i,s,o,n=this.options,r=this;if(this.handles=n.handles||(P(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=P(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e<i.length;e++)s="ui-resizable-"+(t=P.trim(i[e])),o=P("<div>"),this._addClass(o,"ui-resizable-handle "+s),o.css({zIndex:n.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.append(o);this._renderAxis=function(t){var e,i,s,o;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=P(this.handles[e]),this._on(this.handles[e],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=P(this.handles[e],this.element),o=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),s=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(s,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),n.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=P(this.handles[e])[0])!==t.target&&!P.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s,o=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),o.containment&&(e+=P(o.containment).scrollLeft()||0,i+=P(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=P(".ui-resizable-"+this.axis).css("cursor"),P("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e,i,s=this.originalMousePosition,o=this.axis,n=t.pageX-s.left||0,r=t.pageY-s.top||0,a=this._change[o];return this._updatePrevProperties(),a&&(e=a.apply(this,[t,n,r]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),i=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),P.isEmptyObject(i)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,o,n,r,a,h=this.options,l=this;return this._helper&&(s=(i=(e=this._proportionallyResizeElements).length&&/textarea/i.test(e[0].nodeName))&&this._hasScroll(e[0],"left")?0:l.sizeDiff.height,o=i?0:l.sizeDiff.width,n={width:l.helper.width()-o,height:l.helper.height()-s},r=parseFloat(l.element.css("left"))+(l.position.left-l.originalPosition.left)||null,a=parseFloat(l.element.css("top"))+(l.position.top-l.originalPosition.top)||null,h.animate||this.element.css(P.extend(n,{top:a,left:r})),l.helper.height(l.size.height),l.helper.width(l.size.width),this._helper&&!h.animate&&this._proportionallyResize()),P("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,o,n=this.options,r={minWidth:this._isNumber(n.minWidth)?n.minWidth:0,maxWidth:this._isNumber(n.maxWidth)?n.maxWidth:1/0,minHeight:this._isNumber(n.minHeight)?n.minHeight:0,maxHeight:this._isNumber(n.maxHeight)?n.maxHeight:1/0};(this._aspectRatio||t)&&(e=r.minHeight*this.aspectRatio,s=r.minWidth/this.aspectRatio,i=r.maxHeight*this.aspectRatio,o=r.maxWidth/this.aspectRatio,e>r.minWidth&&(r.minWidth=e),s>r.minHeight&&(r.minHeight=s),i<r.maxWidth&&(r.maxWidth=i),o<r.maxHeight&&(r.maxHeight=o)),this._vBoundaries=r},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,n=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,r=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return n&&(t.width=e.minWidth),r&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),n&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),r&&c&&(t.top=h-e.minHeight),o&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],o=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(o[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e<this._proportionallyResizeElements.length;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var t=this.element,e=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||P("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return P.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return P.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return P.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return P.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){P.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),P.ui.plugin.add("resizable","animate",{stop:function(e){var i=P(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),n=o&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,a={width:i.size.width-r,height:i.size.height-n},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,l=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(P.extend(a,l&&h?{top:l,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&P(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),P.ui.plugin.add("resizable","containment",{start:function(){var i,s,t,e,o,n,r,a=P(this).resizable("instance"),h=a.options,l=a.element,c=h.containment,p=c instanceof P?c.get(0):/parent/.test(c)?l.parent().get(0):c;p&&(a.containerElement=P(p),/document/.test(c)||c===document?(a.containerOffset={left:0,top:0},a.containerPosition={left:0,top:0},a.parentData={element:P(document),left:0,top:0,width:P(document).width(),height:P(document).height()||document.body.parentNode.scrollHeight}):(i=P(p),s=[],P(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=a._num(i.css("padding"+e))}),a.containerOffset=i.offset(),a.containerPosition=i.position(),a.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=a.containerOffset,e=a.containerSize.height,o=a.containerSize.width,n=a._hasScroll(p,"left")?p.scrollWidth:o,r=a._hasScroll(p)?p.scrollHeight:e,a.parentData={element:p,left:t.left,top:t.top,width:n,height:r}))},resize:function(t){var e,i,s,o,n=P(this).resizable("instance"),r=n.options,a=n.containerOffset,h=n.position,l=n._aspectRatio||t.shiftKey,c={top:0,left:0},p=n.containerElement,f=!0;p[0]!==document&&/static/.test(p.css("position"))&&(c=a),h.left<(n._helper?a.left:0)&&(n.size.width=n.size.width+(n._helper?n.position.left-a.left:n.position.left-c.left),l&&(n.size.height=n.size.width/n.aspectRatio,f=!1),n.position.left=r.helper?a.left:0),h.top<(n._helper?a.top:0)&&(n.size.height=n.size.height+(n._helper?n.position.top-a.top:n.position.top),l&&(n.size.width=n.size.height*n.aspectRatio,f=!1),n.position.top=n._helper?a.top:0),s=n.containerElement.get(0)===n.element.parent().get(0),o=/relative|absolute/.test(n.containerElement.css("position")),s&&o?(n.offset.left=n.parentData.left+n.position.left,n.offset.top=n.parentData.top+n.position.top):(n.offset.left=n.element.offset().left,n.offset.top=n.element.offset().top),e=Math.abs(n.sizeDiff.width+(n._helper?n.offset.left-c.left:n.offset.left-a.left)),i=Math.abs(n.sizeDiff.height+(n._helper?n.offset.top-c.top:n.offset.top-a.top)),e+n.size.width>=n.parentData.width&&(n.size.width=n.parentData.width-e,l&&(n.size.height=n.size.width/n.aspectRatio,f=!1)),i+n.size.height>=n.parentData.height&&(n.size.height=n.parentData.height-i,l&&(n.size.width=n.size.height*n.aspectRatio,f=!1)),f||(n.position.left=n.prevPosition.left,n.position.top=n.prevPosition.top,n.size.width=n.prevSize.width,n.size.height=n.prevSize.height)},stop:function(){var t=P(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,o=t.containerElement,n=P(t.helper),r=n.offset(),a=n.outerWidth()-t.sizeDiff.width,h=n.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(o.css("position"))&&P(this).css({left:r.left-s.left-i.left,width:a,height:h}),t._helper&&!e.animate&&/static/.test(o.css("position"))&&P(this).css({left:r.left-s.left-i.left,width:a,height:h})}}),P.ui.plugin.add("resizable","alsoResize",{start:function(){var t=P(this).resizable("instance").options;P(t.alsoResize).each(function(){var t=P(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=P(this).resizable("instance"),s=e.options,o=e.originalSize,n=e.originalPosition,r={height:e.size.height-o.height||0,width:e.size.width-o.width||0,top:e.position.top-n.top||0,left:e.position.left-n.left||0};P(s.alsoResize).each(function(){var t=P(this),s=P(this).data("ui-resizable-alsoresize"),o={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];P.each(e,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&0<=i&&(o[e]=i||null)}),t.css(o)})},stop:function(){P(this).removeData("ui-resizable-alsoresize")}}),P.ui.plugin.add("resizable","ghost",{start:function(){var t=P(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==P.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=P(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=P(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),P.ui.plugin.add("resizable","grid",{resize:function(){var t,e=P(this).resizable("instance"),i=e.options,s=e.size,o=e.originalSize,n=e.originalPosition,r=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=a[0]||1,l=a[1]||1,c=Math.round((s.width-o.width)/h)*h,p=Math.round((s.height-o.height)/l)*l,f=o.width+c,u=o.height+p,d=i.maxWidth&&i.maxWidth<f,g=i.maxHeight&&i.maxHeight<u,m=i.minWidth&&i.minWidth>f,v=i.minHeight&&i.minHeight>u;i.grid=a,m&&(f+=h),v&&(u+=l),d&&(f-=h),g&&(u-=l),/^(se|s|e)$/.test(r)?(e.size.width=f,e.size.height=u):/^(ne)$/.test(r)?(e.size.width=f,e.size.height=u,e.position.top=n.top-p):/^(sw)$/.test(r)?(e.size.width=f,e.size.height=u,e.position.left=n.left-c):((u-l<=0||f-h<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0<u-l?(e.size.height=u,e.position.top=n.top-p):(u=l-t.height,e.size.height=u,e.position.top=n.top+o.height-u),0<f-h?(e.size.width=f,e.position.left=n.left-c):(f=h-t.width,e.size.width=f,e.position.left=n.left+o.width-f))}});P.ui.resizable,P.widget("ui.selectable",P.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var s=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){s.elementPos=P(s.element[0]).offset(),s.selectees=P(s.options.filter,s.element[0]),s._addClass(s.selectees,"ui-selectee"),s.selectees.each(function(){var t=P(this),e=t.offset(),i={left:e.left-s.elementPos.left,top:e.top-s.elementPos.top};P.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=P("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(i){var s=this,t=this.options;this.opos=[i.pageX,i.pageY],this.elementPos=P(this.element[0]).offset(),this.options.disabled||(this.selectees=P(t.filter,this.element[0]),this._trigger("start",i),P(t.appendTo).append(this.helper),this.helper.css({left:i.pageX,top:i.pageY,width:0,height:0}),t.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var t=P.data(this,"selectable-item");t.startselected=!0,i.metaKey||i.ctrlKey||(s._removeClass(t.$element,"ui-selected"),t.selected=!1,s._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,s._trigger("unselecting",i,{unselecting:t.element}))}),P(i.target).parents().addBack().each(function(){var t,e=P.data(this,"selectable-item");if(e)return t=!i.metaKey&&!i.ctrlKey||!e.$element.hasClass("ui-selected"),s._removeClass(e.$element,t?"ui-unselecting":"ui-selected")._addClass(e.$element,t?"ui-selecting":"ui-unselecting"),e.unselecting=!t,e.selecting=t,(e.selected=t)?s._trigger("selecting",i,{selecting:e.element}):s._trigger("unselecting",i,{unselecting:e.element}),!1}))},_mouseDrag:function(s){if(this.dragged=!0,!this.options.disabled){var t,o=this,n=this.options,r=this.opos[0],a=this.opos[1],h=s.pageX,l=s.pageY;return h<r&&(t=h,h=r,r=t),l<a&&(t=l,l=a,a=t),this.helper.css({left:r,top:a,width:h-r,height:l-a}),this.selectees.each(function(){var t=P.data(this,"selectable-item"),e=!1,i={};t&&t.element!==o.element[0]&&(i.left=t.left+o.elementPos.left,i.right=t.right+o.elementPos.left,i.top=t.top+o.elementPos.top,i.bottom=t.bottom+o.elementPos.top,"touch"===n.tolerance?e=!(i.left>h||i.right<r||i.top>l||i.bottom<a):"fit"===n.tolerance&&(e=i.left>r&&i.right<h&&i.top>a&&i.bottom<l),e?(t.selected&&(o._removeClass(t.$element,"ui-selected"),t.selected=!1),t.unselecting&&(o._removeClass(t.$element,"ui-unselecting"),t.unselecting=!1),t.selecting||(o._addClass(t.$element,"ui-selecting"),t.selecting=!0,o._trigger("selecting",s,{selecting:t.element}))):(t.selecting&&((s.metaKey||s.ctrlKey)&&t.startselected?(o._removeClass(t.$element,"ui-selecting"),t.selecting=!1,o._addClass(t.$element,"ui-selected"),t.selected=!0):(o._removeClass(t.$element,"ui-selecting"),t.selecting=!1,t.startselected&&(o._addClass(t.$element,"ui-unselecting"),t.unselecting=!0),o._trigger("unselecting",s,{unselecting:t.element}))),t.selected&&(s.metaKey||s.ctrlKey||t.startselected||(o._removeClass(t.$element,"ui-selected"),t.selected=!1,o._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,o._trigger("unselecting",s,{unselecting:t.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,P(".ui-unselecting",this.element[0]).each(function(){var t=P.data(this,"selectable-item");i._removeClass(t.$element,"ui-unselecting"),t.unselecting=!1,t.startselected=!1,i._trigger("unselected",e,{unselected:t.element})}),P(".ui-selecting",this.element[0]).each(function(){var t=P.data(this,"selectable-item");i._removeClass(t.$element,"ui-selecting")._addClass(t.$element,"ui-selected"),t.selecting=!1,t.selected=!0,t.startselected=!0,i._trigger("selected",e,{selected:t.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),P.widget("ui.sortable",P.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return e<=t&&t<e+i},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),P.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;0<=t;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,e){var i=null,s=!1,o=this;return!this.reverting&&(!this.options.disabled&&"static"!==this.options.type&&(this._refreshItems(t),P(t.target).parents().each(function(){if(P.data(this,o.widgetName+"-item")===o)return i=P(this),!1}),P.data(t.target,o.widgetName+"-item")===o&&(i=P(t.target)),!!i&&(!(this.options.handle&&!e&&(P(this.options.handle,i).find("*").addBack().each(function(){this===t.target&&(s=!0)}),!s))&&(this.currentItem=i,this._removeCurrentsFromItems(),!0))))},_mouseStart:function(t,e,i){var s,o,n=this.options;if((this.currentContainer=this).refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},P.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),n.containment&&this._setContainment(),n.cursor&&"auto"!==n.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",n.cursor),this.storedStylesheet=P("<style>*{ cursor: "+n.cursor+" !important; }</style>").appendTo(o)),n.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",n.opacity)),n.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",n.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!i)for(s=this.containers.length-1;0<=s;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return P.ui.ddmanager&&(P.ui.ddmanager.current=this),P.ui.ddmanager&&!n.dropBehaviour&&P.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var e,i,s,o,n=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<n.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+n.scrollSpeed:t.pageY-this.overflowOffset.top<n.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-n.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<n.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+n.scrollSpeed:t.pageX-this.overflowOffset.left<n.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-n.scrollSpeed)):(t.pageY-this.document.scrollTop()<n.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-n.scrollSpeed):this.window.height()-(t.pageY-this.document.scrollTop())<n.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+n.scrollSpeed)),t.pageX-this.document.scrollLeft()<n.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-n.scrollSpeed):this.window.width()-(t.pageX-this.document.scrollLeft())<n.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+n.scrollSpeed))),!1!==r&&P.ui.ddmanager&&!n.dropBehaviour&&P.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),e=this.items.length-1;0<=e;e--)if(s=(i=this.items[e]).item[0],(o=this._intersectsWithPointer(i))&&i.instance===this.currentContainer&&!(s===this.currentItem[0]||this.placeholder[1===o?"next":"prev"]()[0]===s||P.contains(this.placeholder[0],s)||"semi-dynamic"===this.options.type&&P.contains(this.element[0],s))){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(i))break;this._rearrange(t,i),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),P.ui.ddmanager&&P.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,e){var i,s,o,n;if(t)return P.ui.ddmanager&&!this.options.dropBehaviour&&P.ui.ddmanager.drop(this,t),this.options.revert?(s=(i=this).placeholder.offset(),n={},(o=this.options.axis)&&"x"!==o||(n.left=s.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(n.top=s.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,P(this.helper).animate(n,parseInt(this.options.revert,10)||500,function(){i._clear(t)})):this._clear(t,e),!1},cancel:function(){if(this.dragging){this._mouseUp(new P.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var t=this.containers.length-1;0<=t;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),P.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?P(this.domPosition.prev).after(this.currentItem):P(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var t=this._getItemsAsjQuery(e&&e.connected),i=[];return e=e||{},P(t).each(function(){var t=(P(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);t&&i.push((e.key||t[1]+"[]")+"="+(e.key&&e.expression?t[1]:t[2]))}),!i.length&&e.key&&i.push(e.key+"="),i.join("&")},toArray:function(t){var e=this._getItemsAsjQuery(t&&t.connected),i=[];return t=t||{},e.each(function(){i.push(P(t.item||this).attr(t.attribute||"id")||"")}),i},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,o=s+this.helperProportions.height,n=t.left,r=n+t.width,a=t.top,h=a+t.height,l=this.offset.click.top,c=this.offset.click.left,p="x"===this.options.axis||a<s+l&&s+l<h,f="y"===this.options.axis||n<e+c&&e+c<r,u=p&&f;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?u:n<e+this.helperProportions.width/2&&i-this.helperProportions.width/2<r&&a<s+this.helperProportions.height/2&&o-this.helperProportions.height/2<h},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),o="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width);return!(!s||!o)&&(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1))},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&i||"left"===o&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!=t&&(0<t?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!=t&&(0<t?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(t){var e,i,s,o,n=[],r=[],a=this._connectWith();if(a&&t)for(e=a.length-1;0<=e;e--)for(i=(s=P(a[e],this.document[0])).length-1;0<=i;i--)(o=P.data(s[i],this.widgetFullName))&&o!==this&&!o.options.disabled&&r.push([P.isFunction(o.options.items)?o.options.items.call(o.element):P(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);function h(){n.push(this)}for(r.push([P.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):P(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),e=r.length-1;0<=e;e--)r[e][0].each(h);return P(n)},_removeCurrentsFromItems:function(){var i=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=P.grep(this.items,function(t){for(var e=0;e<i.length;e++)if(i[e]===t.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var e,i,s,o,n,r,a,h,l=this.items,c=[[P.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):P(this.options.items,this.element),this]],p=this._connectWith();if(p&&this.ready)for(e=p.length-1;0<=e;e--)for(i=(s=P(p[e],this.document[0])).length-1;0<=i;i--)(o=P.data(s[i],this.widgetFullName))&&o!==this&&!o.options.disabled&&(c.push([P.isFunction(o.options.items)?o.options.items.call(o.element[0],t,{item:this.currentItem}):P(o.options.items,o.element),o]),this.containers.push(o));for(e=c.length-1;0<=e;e--)for(n=c[e][1],i=0,h=(r=c[e][0]).length;i<h;i++)(a=P(r[i])).data(this.widgetName+"-item",n),l.push({item:a,instance:n,width:0,height:0,left:0,top:0})},refreshPositions:function(t){var e,i,s,o;for(this.floating=!!this.items.length&&("x"===this.options.axis||this._isFloating(this.items[0].item)),this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset()),e=this.items.length-1;0<=e;e--)(i=this.items[e]).instance!==this.currentContainer&&this.currentContainer&&i.item[0]!==this.currentItem[0]||(s=this.options.toleranceElement?P(this.options.toleranceElement,i.item):i.item,t||(i.width=s.outerWidth(),i.height=s.outerHeight()),o=s.offset(),i.left=o.left,i.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(e=this.containers.length-1;0<=e;e--)o=this.containers[e].element.offset(),this.containers[e].containerCache.left=o.left,this.containers[e].containerCache.top=o.top,this.containers[e].containerCache.width=this.containers[e].element.outerWidth(),this.containers[e].containerCache.height=this.containers[e].element.outerHeight();return this},_createPlaceholder:function(i){var s,o=(i=i||this).options;o.placeholder&&o.placeholder.constructor!==String||(s=o.placeholder,o.placeholder={element:function(){var t=i.currentItem[0].nodeName.toLowerCase(),e=P("<"+t+">",i.document[0]);return i._addClass(e,"ui-sortable-placeholder",s||i.currentItem[0].className)._removeClass(e,"ui-sortable-helper"),"tbody"===t?i._createTrPlaceholder(i.currentItem.find("tr").eq(0),P("<tr>",i.document[0]).appendTo(e)):"tr"===t?i._createTrPlaceholder(i.currentItem,e):"img"===t&&e.attr("src",i.currentItem.attr("src")),s||e.css("visibility","hidden"),e},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10)))}}),i.placeholder=P(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){P("<td>&#160;</td>",i.document[0]).attr("colspan",P(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,o,n,r,a,h,l,c=null,p=null,f=this.containers.length-1;0<=f;f--)if(!P.contains(this.currentItem[0],this.containers[f].element[0]))if(this._intersectsWith(this.containers[f].containerCache)){if(c&&P.contains(this.containers[f].element[0],c.element[0]))continue;c=this.containers[f],p=f}else this.containers[f].containerCache.over&&(this.containers[f]._trigger("out",t,this._uiHash(this)),this.containers[f].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(i=1e4,s=null,o=(h=c.floating||this._isFloating(this.currentItem))?"left":"top",n=h?"width":"height",l=h?"pageX":"pageY",e=this.items.length-1;0<=e;e--)P.contains(this.containers[p].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(r=this.items[e].item.offset()[o],a=!1,t[l]-r>this.items[e][n]/2&&(a=!0),Math.abs(t[l]-r)<i&&(i=Math.abs(t[l]-r),s=this.items[e],this.direction=a?"up":"down"));if(!s&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return void(this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1));s?this._rearrange(t,s,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var e=this.options,i=P.isFunction(e.helper)?P(e.helper.apply(this.element[0],[t,this.currentItem])):"clone"===e.helper?this.currentItem.clone():this.currentItem;return i.parents("body").length||P("parent"!==e.appendTo?e.appendTo:this.currentItem[0].parentNode)[0].appendChild(i[0]),i[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),i[0].style.width&&!e.forceHelperSize||i.width(this.currentItem.width()),i[0].style.height&&!e.forceHelperSize||i.height(this.currentItem.height()),i},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),P.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&P.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&P.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,e,i,s=this.options;"parent"===s.containment&&(s.containment=this.helper[0].parentNode),"document"!==s.containment&&"window"!==s.containment||(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===s.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===s.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(s.containment)||(t=P(s.containment)[0],e=P(s.containment).offset(),i="hidden"!==P(t).css("overflow"),this.containment=[e.left+(parseInt(P(t).css("borderLeftWidth"),10)||0)+(parseInt(P(t).css("paddingLeft"),10)||0)-this.margins.left,e.top+(parseInt(P(t).css("borderTopWidth"),10)||0)+(parseInt(P(t).css("paddingTop"),10)||0)-this.margins.top,e.left+(i?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(P(t).css("borderLeftWidth"),10)||0)-(parseInt(P(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,e.top+(i?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(P(t).css("borderTopWidth"),10)||0)-(parseInt(P(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,e){e=e||this.position;var i="absolute"===t?1:-1,s="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&P.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:s.scrollTop())*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*i}},_generatePosition:function(t){var e,i,s=this.options,o=t.pageX,n=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&P.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(n=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(n=this.containment[3]+this.offset.click.top)),s.grid&&(e=this.originalPageY+Math.round((n-this.originalPageY)/s.grid[1])*s.grid[1],n=!this.containment||e-this.offset.click.top>=this.containment[1]&&e-this.offset.click.top<=this.containment[3]?e:e-this.offset.click.top>=this.containment[1]?e-s.grid[1]:e+s.grid[1],i=this.originalPageX+Math.round((o-this.originalPageX)/s.grid[0])*s.grid[0],o=!this.containment||i-this.offset.click.left>=this.containment[0]&&i-this.offset.click.left<=this.containment[2]?i:i-this.offset.click.left>=this.containment[0]?i-s.grid[0]:i+s.grid[0])),{top:n-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var o=this.counter;this._delay(function(){o===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function o(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;0<=i;i--)e||s.push(o("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(o("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i<s.length;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){!1===P.Widget.prototype._trigger.apply(this,arguments)&&this.cancel()},_uiHash:function(t){var e=t||this;return{helper:e.helper,placeholder:e.placeholder||P([]),position:e.position,originalPosition:e.originalPosition,offset:e.positionAbs,item:e.currentItem,sender:t?t.element:null}}});var d,g,m,v,e,_,b,w,y,S,W,T,k,D,E,N,O,R,L,M,A,F="ui-effects-",B="ui-effects-style",X="ui-effects-animated",Y=P;function q(t,e,i){var s=w[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:t<0?0:s.max<t?s.max:t)}function j(r){var a=_(),h=a._rgba=[];return r=r.toLowerCase(),W(e,function(t,e){var i,s=e.re.exec(r),o=s&&e.parse(s),n=e.space||"rgba";if(o)return i=a[n](o),a[b[n].cache]=i[b[n].cache],h=a._rgba=i._rgba,!1}),h.length?("0,0,0,0"===h.join()&&d.extend(h,m.transparent),a):m[r]}function $(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}function U(t){var e,i,s=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,o={};if(s&&s.length&&s[0]&&s[s[0]])for(i=s.length;i--;)"string"==typeof s[e=s[i]]&&(o[P.camelCase(e)]=s[e]);else for(e in s)"string"==typeof s[e]&&(o[e]=s[e]);return o}function K(t,e,i,s){return P.isPlainObject(t)&&(t=(e=t).effect),t={effect:t},null==e&&(e={}),P.isFunction(e)&&(s=e,i=null,e={}),"number"!=typeof e&&!P.fx.speeds[e]||(s=i,i=e,e={}),P.isFunction(i)&&(s=i,i=null),e&&P.extend(t,e),i=i||e.duration,t.duration=P.fx.off?0:"number"==typeof i?i:i in P.fx.speeds?P.fx.speeds[i]:P.fx.speeds._default,t.complete=s||e.complete,t}function V(t){return!t||"number"==typeof t||P.fx.speeds[t]||("string"==typeof t&&!P.effects.effect[t]||(P.isFunction(t)||"object"==typeof t&&!t.effect))}function Q(t,e){var i=e.outerWidth(),s=e.outerHeight(),o=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}P.effects={effect:{}},v=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],_=(d=Y).Color=function(t,e,i,s){return new d.Color.fn.parse(t,e,i,s)},b={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},w={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},y=_.support={},S=d("<p>")[0],W=d.each,S.style.cssText="background-color:rgba(1,1,1,.5)",y.rgba=-1<S.style.backgroundColor.indexOf("rgba"),W(b,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),_.fn=d.extend(_.prototype,{parse:function(o,t,e,i){if(o===g)return this._rgba=[null,null,null,null],this;(o.jquery||o.nodeType)&&(o=d(o).css(t),t=g);var n=this,s=d.type(o),r=this._rgba=[];return t!==g&&(o=[o,t,e,i],s="array"),"string"===s?this.parse(j(o)||m._default):"array"===s?(W(b.rgba.props,function(t,e){r[e.idx]=q(o[e.idx],e)}),this):"object"===s?(W(b,o instanceof _?function(t,e){o[e.cache]&&(n[e.cache]=o[e.cache].slice())}:function(t,i){var s=i.cache;W(i.props,function(t,e){if(!n[s]&&i.to){if("alpha"===t||null==o[t])return;n[s]=i.to(n._rgba)}n[s][e.idx]=q(o[t],e,!0)}),n[s]&&d.inArray(null,n[s].slice(0,3))<0&&(n[s][3]=1,i.from&&(n._rgba=i.from(n[s])))}),this):void 0},is:function(t){var o=_(t),n=!0,r=this;return W(b,function(t,e){var i,s=o[e.cache];return s&&(i=r[e.cache]||e.to&&e.to(r._rgba)||[],W(e.props,function(t,e){if(null!=s[e.idx])return n=s[e.idx]===i[e.idx]})),n}),n},_space:function(){var i=[],s=this;return W(b,function(t,e){s[e.cache]&&i.push(t)}),i.pop()},transition:function(t,r){var e=(l=_(t))._space(),i=b[e],s=0===this.alpha()?_("transparent"):this,a=s[i.cache]||i.to(s._rgba),h=a.slice(),l=l[i.cache];return W(i.props,function(t,e){var i=e.idx,s=a[i],o=l[i],n=w[e.type]||{};null!==o&&(null===s?h[i]=o:(n.mod&&(n.mod/2<o-s?s+=n.mod:n.mod/2<s-o&&(s-=n.mod)),h[i]=q((o-s)*r+s,e)))}),this[e](h)},blend:function(t){if(1===this._rgba[3])return this;var e=this._rgba.slice(),i=e.pop(),s=_(t)._rgba;return _(d.map(e,function(t,e){return(1-i)*s[e]+i*t}))},toRgbaString:function(){var t="rgba(",e=d.map(this._rgba,function(t,e){return null==t?2<e?1:0:t});return 1===e[3]&&(e.pop(),t="rgb("),t+e.join()+")"},toHslaString:function(){var t="hsla(",e=d.map(this.hsla(),function(t,e){return null==t&&(t=2<e?1:0),e&&e<3&&(t=Math.round(100*t)+"%"),t});return 1===e[3]&&(e.pop(),t="hsl("),t+e.join()+")"},toHexString:function(t){var e=this._rgba.slice(),i=e.pop();return t&&e.push(~~(255*i)),"#"+d.map(e,function(t){return 1===(t=(t||0).toString(16)).length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),_.fn.parse.prototype=_.fn,b.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/255,i=t[1]/255,s=t[2]/255,o=t[3],n=Math.max(e,i,s),r=Math.min(e,i,s),a=n-r,h=n+r,l=.5*h,c=r===n?0:e===n?60*(i-s)/a+360:i===n?60*(s-e)/a+120:60*(e-i)/a+240,p=0==a?0:l<=.5?a/h:a/(2-h);return[Math.round(c)%360,p,l,null==o?1:o]},b.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],n=s<=.5?s*(1+i):s+i-s*i,r=2*s-n;return[Math.round(255*$(r,n,e+1/3)),Math.round(255*$(r,n,e)),Math.round(255*$(r,n,e-1/3)),o]},W(b,function(h,t){var i=t.props,r=t.cache,a=t.to,l=t.from;_.fn[h]=function(t){if(a&&!this[r]&&(this[r]=a(this._rgba)),t===g)return this[r].slice();var e,s=d.type(t),o="array"===s||"object"===s?t:arguments,n=this[r].slice();return W(i,function(t,e){var i=o["object"===s?t:e.idx];null==i&&(i=n[e.idx]),n[e.idx]=q(i,e)}),l?((e=_(l(n)))[r]=n,e):_(n)},W(i,function(r,a){_.fn[r]||(_.fn[r]=function(t){var e,i=d.type(t),s="alpha"===r?this._hsla?"hsla":"rgba":h,o=this[s](),n=o[a.idx];return"undefined"===i?n:("function"===i&&(t=t.call(this,n),i=d.type(t)),null==t&&a.empty?this:("string"===i&&(e=v.exec(t))&&(t=n+parseFloat(e[2])*("+"===e[1]?1:-1)),o[a.idx]=t,this[s](o)))})})}),_.hook=function(t){var e=t.split(" ");W(e,function(t,n){d.cssHooks[n]={set:function(t,e){var i,s,o="";if("transparent"!==e&&("string"!==d.type(e)||(i=j(e)))){if(e=_(i||e),!y.rgba&&1!==e._rgba[3]){for(s="backgroundColor"===n?t.parentNode:t;(""===o||"transparent"===o)&&s&&s.style;)try{o=d.css(s,"backgroundColor"),s=s.parentNode}catch(t){}e=e.blend(o&&"transparent"!==o?o:"_default")}e=e.toRgbaString()}try{t.style[n]=e}catch(t){}}},d.fx.step[n]=function(t){t.colorInit||(t.start=_(t.elem,n),t.end=_(t.end),t.colorInit=!0),d.cssHooks[n].set(t.elem,t.start.transition(t.end,t.pos))}})},_.hook("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor"),d.cssHooks.borderColor={expand:function(i){var s={};return W(["Top","Right","Bottom","Left"],function(t,e){s["border"+e+"Color"]=i}),s}},m=d.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"},E=["add","remove","toggle"],N={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1},P.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,e){P.fx.step[e]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(Y.style(t.elem,e,t.end),t.setAttr=!0)}}),P.fn.addBack||(P.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),P.effects.animateClass=function(o,t,e,i){var n=P.speed(t,e,i);return this.queue(function(){var i=P(this),t=i.attr("class")||"",e=(e=n.children?i.find("*").addBack():i).map(function(){return{el:P(this),start:U(this)}}),s=function(){P.each(E,function(t,e){o[e]&&i[e+"Class"](o[e])})};s(),e=e.map(function(){return this.end=U(this.el[0]),this.diff=function(t,e){var i,s,o={};for(i in e)s=e[i],t[i]!==s&&(N[i]||!P.fx.step[i]&&isNaN(parseFloat(s))||(o[i]=s));return o}(this.start,this.end),this}),i.attr("class",t),e=e.map(function(){var t=this,e=P.Deferred(),i=P.extend({},n,{queue:!1,complete:function(){e.resolve(t)}});return this.el.animate(this.diff,i),e.promise()}),P.when.apply(P,e.get()).done(function(){s(),P.each(arguments,function(){var e=this.el;P.each(this.diff,function(t){e.css(t,"")})}),n.complete.call(i[0])})})},P.fn.extend({addClass:(D=P.fn.addClass,function(t,e,i,s){return e?P.effects.animateClass.call(this,{add:t},e,i,s):D.apply(this,arguments)}),removeClass:(k=P.fn.removeClass,function(t,e,i,s){return 1<arguments.length?P.effects.animateClass.call(this,{remove:t},e,i,s):k.apply(this,arguments)}),toggleClass:(T=P.fn.toggleClass,function(t,e,i,s,o){return"boolean"==typeof e||void 0===e?i?P.effects.animateClass.call(this,e?{add:t}:{remove:t},i,s,o):T.apply(this,arguments):P.effects.animateClass.call(this,{toggle:t},e,i,s)}),switchClass:function(t,e,i,s,o){return P.effects.animateClass.call(this,{add:e,remove:t},i,s,o)}}),P.expr&&P.expr.filters&&P.expr.filters.animated&&(P.expr.filters.animated=(O=P.expr.filters.animated,function(t){return!!P(t).data(X)||O(t)})),!1!==P.uiBackCompat&&P.extend(P.effects,{save:function(t,e){for(var i=0,s=e.length;i<s;i++)null!==e[i]&&t.data(F+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,o=e.length;s<o;s++)null!==e[s]&&(i=t.data(F+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(i){if(i.parent().is(".ui-effects-wrapper"))return i.parent();var s={width:i.outerWidth(!0),height:i.outerHeight(!0),float:i.css("float")},t=P("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},o=document.activeElement;try{o.id}catch(t){o=document.body}return i.wrap(t),i[0]!==o&&!P.contains(i[0],o)||P(o).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(P.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),P.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!P.contains(t[0],e)||P(e).trigger("focus")),t}}),P.extend(P.effects,{version:"1.12.1",define:function(t,e,i){return i||(i=e,e="effect"),P.effects.effect[t]=i,P.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,o="vertical"!==i?(e||100)/100:1;return{height:t.height()*o,width:t.width()*s,outerHeight:t.outerHeight()*o,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1<e&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(B,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(B)||"",t.removeData(B)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(t){var e,i=t.css("position"),s=t.position();return t.css({marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()),/^(static|relative)/.test(i)&&(i="absolute",e=P("<"+t[0].nodeName+">").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(F+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=F+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){P.effects.restoreStyle(t),P.effects.removePlaceholder(t)},setTransition:function(s,t,o,n){return n=n||{},P.each(t,function(t,e){var i=s.cssUnit(e);0<i[0]&&(n[e]=i[0]*o+i[1])}),n}}),P.fn.extend({effect:function(){function t(t){var e=P(this),i=P.effects.mode(e,a)||n;e.data(X,!0),h.push(i),n&&("show"===i||i===n&&"hide"===i)&&e.show(),n&&"none"===i||P.effects.saveStyle(e),P.isFunction(t)&&t()}var s=K.apply(this,arguments),o=P.effects.effect[s.effect],n=o.mode,e=s.queue,i=e||"fx",r=s.complete,a=s.mode,h=[];if(P.fx.off||!o)return a?this[a](s.duration,r):this.each(function(){r&&r.call(this)});function l(t){var e=P(this);function i(){P.isFunction(r)&&r.call(e[0]),P.isFunction(t)&&t()}s.mode=h.shift(),!1===P.uiBackCompat||n?"none"===s.mode?(e[a](),i()):o.call(e[0],s,function(){e.removeData(X),P.effects.cleanUp(e),"hide"===s.mode&&e.hide(),i()}):(e.is(":hidden")?"hide"===a:"show"===a)?(e[a](),i()):o.call(e[0],s,i)}return!1===e?this.each(t).each(l):this.queue(i,t).queue(i,l)},show:(M=P.fn.show,function(t){if(V(t))return M.apply(this,arguments);var e=K.apply(this,arguments);return e.mode="show",this.effect.call(this,e)}),hide:(L=P.fn.hide,function(t){if(V(t))return L.apply(this,arguments);var e=K.apply(this,arguments);return e.mode="hide",this.effect.call(this,e)}),toggle:(R=P.fn.toggle,function(t){if(V(t)||"boolean"==typeof t)return R.apply(this,arguments);var e=K.apply(this,arguments);return e.mode="toggle",this.effect.call(this,e)}),cssUnit:function(t){var i=this.css(t),s=[];return P.each(["em","px","%","pt"],function(t,e){0<i.indexOf(e)&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):Q(this.css("clip"),this)},transfer:function(t,e){var i=P(this),s=P(t.to),o="fixed"===s.css("position"),n=P("body"),r=o?n.scrollTop():0,a=o?n.scrollLeft():0,h=s.offset(),l={top:h.top-r,left:h.left-a,height:s.innerHeight(),width:s.innerWidth()},c=i.offset(),p=P("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(t.className).css({top:c.top-r,left:c.left-a,height:i.innerHeight(),width:i.innerWidth(),position:o?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){p.remove(),P.isFunction(e)&&e()})}}),P.fx.step.clip=function(t){t.clipInit||(t.start=P(t.elem).cssClip(),"string"==typeof t.end&&(t.end=Q(t.end,t.elem)),t.clipInit=!0),P(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},A={},P.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){A[t]=function(t){return Math.pow(t,e+2)}}),P.extend(A,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),P.each(A,function(t,e){P.easing["easeIn"+t]=e,P.easing["easeOut"+t]=function(t){return 1-e(1-t)},P.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});P.effects,P.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=P(this),o=t.direction||"up",n=s.cssClip(),r={clip:P.extend({},n)},a=P.effects.createPlaceholder(s);r.clip[i[o][0]]=r.clip[i[o][1]],"show"===t.mode&&(s.cssClip(r.clip),a&&a.css(P.effects.clipToBox(r)),r.clip=n),a&&a.animate(P.effects.clipToBox(r),t.duration,t.easing),s.animate(r,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("bounce",function(t,e){var i,s,o,n=P(this),r=t.mode,a="hide"===r,h="show"===r,l=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(h||a?1:0),u=t.duration/f,d=t.easing,g="up"===l||"down"===l?"top":"left",m="up"===l||"left"===l,v=0,_=n.queue().length;for(P.effects.createPlaceholder(n),o=n.css(g),c=c||n["top"==g?"outerHeight":"outerWidth"]()/3,h&&((s={opacity:1})[g]=o,n.css("opacity",0).css(g,m?2*-c:2*c).animate(s,u,d)),a&&(c/=Math.pow(2,p-1)),(s={})[g]=o;v<p;v++)(i={})[g]=(m?"-=":"+=")+c,n.animate(i,u,d).animate(s,u,d),c=a?2*c:c/2;a&&((i={opacity:0})[g]=(m?"-=":"+=")+c,n.animate(i,u,d)),n.queue(e),P.effects.unshift(n,_,1+f)}),P.effects.define("drop","hide",function(t,e){var i,s=P(this),o="show"===t.mode,n=t.direction||"left",r="up"===n||"down"===n?"top":"left",a="up"===n||"left"===n?"-=":"+=",h="+="==a?"-=":"+=",l={opacity:0};P.effects.createPlaceholder(s),i=t.distance||s["top"==r?"outerHeight":"outerWidth"](!0)/2,l[r]=a+i,o&&(s.css(l),l[r]=h+i,l.opacity=1),s.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;P(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("fold","hide",function(e,t){var i=P(this),s=e.mode,o="show"===s,n="hide"===s,r=e.size||15,a=/([0-9]+)%/.exec(r),h=!!e.horizFirst?["right","bottom"]:["bottom","right"],l=e.duration/2,c=P.effects.createPlaceholder(i),p=i.cssClip(),f={clip:P.extend({},p)},u={clip:P.extend({},p)},d=[p[h[0]],p[h[1]]],g=i.queue().length;a&&(r=parseInt(a[1],10)/100*d[n?0:1]),f.clip[h[0]]=r,u.clip[h[0]]=r,u.clip[h[1]]=0,o&&(i.cssClip(u.clip),c&&c.css(P.effects.clipToBox(u)),u.clip=p),i.queue(function(t){c&&c.animate(P.effects.clipToBox(f),l,e.easing).animate(P.effects.clipToBox(u),l,e.easing),t()}).animate(f,l,e.easing).animate(u,l,e.easing).queue(t),P.effects.unshift(i,g,4)}),P.effects.define("highlight","show",function(t,e){var i=P(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),P.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),P.effects.define("size",function(o,e){var t,n,i,s=P(this),r=["fontSize"],a=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=o.mode,c="effect"!==l,p=o.scale||"both",f=o.origin||["middle","center"],u=s.css("position"),d=s.position(),g=P.effects.scaledDimensions(s),m=o.from||g,v=o.to||P.effects.scaledDimensions(s,0);P.effects.createPlaceholder(s),"show"===l&&(i=m,m=v,v=i),n={from:{y:m.height/g.height,x:m.width/g.width},to:{y:v.height/g.height,x:v.width/g.width}},"box"!==p&&"both"!==p||(n.from.y!==n.to.y&&(m=P.effects.setTransition(s,a,n.from.y,m),v=P.effects.setTransition(s,a,n.to.y,v)),n.from.x!==n.to.x&&(m=P.effects.setTransition(s,h,n.from.x,m),v=P.effects.setTransition(s,h,n.to.x,v))),"content"!==p&&"both"!==p||n.from.y!==n.to.y&&(m=P.effects.setTransition(s,r,n.from.y,m),v=P.effects.setTransition(s,r,n.to.y,v)),f&&(t=P.effects.getBaseline(f,g),m.top=(g.outerHeight-m.outerHeight)*t.y+d.top,m.left=(g.outerWidth-m.outerWidth)*t.x+d.left,v.top=(g.outerHeight-v.outerHeight)*t.y+d.top,v.left=(g.outerWidth-v.outerWidth)*t.x+d.left),s.css(m),"content"!==p&&"both"!==p||(a=a.concat(["marginTop","marginBottom"]).concat(r),h=h.concat(["marginLeft","marginRight"]),s.find("*[width]").each(function(){var t=P(this),e=P.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},s={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=P.effects.setTransition(t,a,n.from.y,i),s=P.effects.setTransition(t,a,n.to.y,s)),n.from.x!==n.to.x&&(i=P.effects.setTransition(t,h,n.from.x,i),s=P.effects.setTransition(t,h,n.to.x,s)),c&&P.effects.saveStyle(t),t.css(i),t.animate(s,o.duration,o.easing,function(){c&&P.effects.restoreStyle(t)})})),s.animate(v,{queue:!1,duration:o.duration,easing:o.easing,complete:function(){var t=s.offset();0===v.opacity&&s.css("opacity",m.opacity),c||(s.css("position","static"===u?"relative":u).offset(t),P.effects.saveStyle(s)),e()}})}),P.effects.define("scale",function(t,e){var i=P(this),s=t.mode,o=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),n=P.extend(!0,{from:P.effects.scaledDimensions(i),to:P.effects.scaledDimensions(i,o,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(n.from.opacity=1,n.to.opacity=0),P.effects.effect.size.call(this,n,e)}),P.effects.define("puff","hide",function(t,e){var i=P.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});P.effects.effect.scale.call(this,i,e)}),P.effects.define("pulsate","show",function(t,e){var i=P(this),s=t.mode,o="show"===s,n=o||"hide"===s,r=2*(t.times||5)+(n?1:0),a=t.duration/r,h=0,l=1,c=i.queue().length;for(!o&&i.is(":visible")||(i.css("opacity",0).show(),h=1);l<r;l++)i.animate({opacity:h},a,t.easing),h=1-h;i.animate({opacity:h},a,t.easing),i.queue(e),P.effects.unshift(i,c,1+r)}),P.effects.define("shake",function(t,e){var i=1,s=P(this),o=t.direction||"left",n=t.distance||20,r=t.times||3,a=2*r+1,h=Math.round(t.duration/a),l="up"===o||"down"===o?"top":"left",c="up"===o||"left"===o,p={},f={},u={},d=s.queue().length;for(P.effects.createPlaceholder(s),p[l]=(c?"-=":"+=")+n,f[l]=(c?"+=":"-=")+2*n,u[l]=(c?"-=":"+=")+2*n,s.animate(p,h,t.easing);i<r;i++)s.animate(f,h,t.easing).animate(u,h,t.easing);s.animate(f,h,t.easing).animate(p,h/2,t.easing).queue(e),P.effects.unshift(s,d,1+a)}),P.effects.define("slide","show",function(t,e){var i,s,o=P(this),n={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=t.mode,a=t.direction||"left",h="up"===a||"down"===a?"top":"left",l="up"===a||"left"===a,c=t.distance||o["top"==h?"outerHeight":"outerWidth"](!0),p={};P.effects.createPlaceholder(o),i=o.cssClip(),s=o.position()[h],p[h]=(l?-1:1)*c+s,p.clip=o.cssClip(),p.clip[n[a][1]]=p.clip[n[a][0]],"show"===r&&(o.cssClip(p.clip),o.css(h,p[h]),p.clip=i,p[h]=s),o.animate(p,{queue:!1,duration:t.duration,easing:t.easing,complete:e})});!1!==P.uiBackCompat&&P.effects.define("transfer",function(t,e){P(this).transfer(t,e)})}); })(this);
 
 // 3rdParty/jquery-ui/touchPunch.js
-(function (window, undefined) { !function(o){function t(o,t){if(!(o.originalEvent.touches.length>1)){o.preventDefault();var e=o.originalEvent.changedTouches[0],u=document.createEvent("MouseEvents");u.initMouseEvent(t,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,!1,!1,!1,!1,0,null),o.target.dispatchEvent(u)}}if(o.support.touch="ontouchend"in document,o.support.touch){var e,u=o.ui.mouse.prototype,n=u._mouseInit,c=u._mouseDestroy;u._touchStart=function(o){var u=this;!e&&u._mouseCapture(o.originalEvent.changedTouches[0])&&(e=!0,u._touchMoved=!1,t(o,"mouseover"),t(o,"mousemove"),t(o,"mousedown"))},u._touchMove=function(o){e&&(this._touchMoved=!0,t(o,"mousemove"))},u._touchEnd=function(o){e&&(t(o,"mouseup"),t(o,"mouseout"),this._touchMoved||t(o,"click"),e=!1)},u._mouseInit=function(){var t=this;t.element.bind({touchstart:o.proxy(t,"_touchStart"),touchmove:o.proxy(t,"_touchMove"),touchend:o.proxy(t,"_touchEnd")}),n.call(t)},u._mouseDestroy=function(){var t=this;t.element.unbind({touchstart:o.proxy(t,"_touchStart"),touchmove:o.proxy(t,"_touchMove"),touchend:o.proxy(t,"_touchEnd")}),c.call(t)}}}(jQuery); })(this);
+(function (window, undefined) { !function(t){var o,e,u,n;function c(o,t){var e,u;1<o.originalEvent.touches.length||(o.preventDefault(),e=o.originalEvent.changedTouches[0],(u=document.createEvent("MouseEvents")).initMouseEvent(t,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,!1,!1,!1,!1,0,null),o.target.dispatchEvent(u))}t.support.touch="ontouchend"in document,t.support.touch&&(o=t.ui.mouse.prototype,e=o._mouseInit,u=o._mouseDestroy,o._touchStart=function(o){!n&&this._mouseCapture(o.originalEvent.changedTouches[0])&&(n=!0,this._touchMoved=!1,c(o,"mouseover"),c(o,"mousemove"),c(o,"mousedown"))},o._touchMove=function(o){n&&(this._touchMoved=!0,c(o,"mousemove"))},o._touchEnd=function(o){n&&(c(o,"mouseup"),c(o,"mouseout"),this._touchMoved||c(o,"click"),n=!1)},o._mouseInit=function(){var o=this;o.element.bind({touchstart:t.proxy(o,"_touchStart"),touchmove:t.proxy(o,"_touchMove"),touchend:t.proxy(o,"_touchEnd")}),e.call(o)},o._mouseDestroy=function(){var o=this;o.element.unbind({touchstart:t.proxy(o,"_touchStart"),touchmove:t.proxy(o,"_touchMove"),touchend:t.proxy(o,"_touchEnd")}),u.call(o)})}(jQuery); })(this);
 
 // 3rdParty/jquery-ui/nestedSortable.js
-(function (window, undefined) { !function(t){t.widget("mjs.nestedSortable",t.extend({},t.ui.sortable.prototype,{options:{tabSize:20,disableNesting:"mjs-nestedSortable-no-nesting",errorClass:"mjs-nestedSortable-error",doNotClear:!1,listType:"ol",maxLevels:0,protectRoot:!1,rootID:null,rtl:!1,isAllowed:function(t,e){return!0}},_create:function(){if(this.element.data("sortable",this.element.data("nestedSortable")),!this.element.is(this.options.listType))throw new Error("nestedSortable: Please check the listType option is set to your actual list type");return t.ui.sortable.prototype._create.apply(this,arguments)},destroy:function(){return this.element.removeData("nestedSortable").unbind(".nestedSortable"),t.ui.sortable.prototype.destroy.apply(this,arguments)},_mouseDrag:function(e){this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);var i=this.options;if(this.options.scroll){var s=!1;this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<i.scrollSensitivity?this.scrollParent[0].scrollTop=s=this.scrollParent[0].scrollTop+i.scrollSpeed:e.pageY-this.overflowOffset.top<i.scrollSensitivity&&(this.scrollParent[0].scrollTop=s=this.scrollParent[0].scrollTop-i.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<i.scrollSensitivity?this.scrollParent[0].scrollLeft=s=this.scrollParent[0].scrollLeft+i.scrollSpeed:e.pageX-this.overflowOffset.left<i.scrollSensitivity&&(this.scrollParent[0].scrollLeft=s=this.scrollParent[0].scrollLeft-i.scrollSpeed)):(e.pageY-t(document).scrollTop()<i.scrollSensitivity?s=t(document).scrollTop(t(document).scrollTop()-i.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<i.scrollSensitivity&&(s=t(document).scrollTop(t(document).scrollTop()+i.scrollSpeed)),e.pageX-t(document).scrollLeft()<i.scrollSensitivity?s=t(document).scrollLeft(t(document).scrollLeft()-i.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<i.scrollSensitivity&&(s=t(document).scrollLeft(t(document).scrollLeft()+i.scrollSpeed))),!1!==s&&t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)}this.positionAbs=this._convertPositionTo("absolute");var o=this.placeholder.offset().top;this.options.axis&&"y"==this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"==this.options.axis||(this.helper[0].style.top=this.position.top+"px");for(var l=this.items.length-1;l>=0;l--){var r=this.items[l],n=r.item[0],h=this._intersectsWithPointer(r);if(h&&!(n==this.currentItem[0]||this.placeholder[1==h?"next":"prev"]()[0]==n||t.contains(this.placeholder[0],n)||"semi-dynamic"==this.options.type&&t.contains(this.element[0],n))){if(t(n).mouseenter(),this.direction=1==h?"down":"up","pointer"!=this.options.tolerance&&!this._intersectsWithSides(r))break;t(n).mouseleave(),this._rearrange(e,r),this._clearEmpty(n),this._trigger("change",e,this._uiHash());break}}var a=this.placeholder[0].parentNode.parentNode&&t(this.placeholder[0].parentNode.parentNode).closest(".ui-sortable").length?t(this.placeholder[0].parentNode.parentNode):null,p=this._getLevel(this.placeholder),c=this._getChildLevels(this.helper),d=this.placeholder[0].previousSibling?t(this.placeholder[0].previousSibling):null;if(null!=d)for(;"li"!=d[0].nodeName.toLowerCase()||d[0]==this.currentItem[0]||d[0]==this.helper[0];){if(!d[0].previousSibling){d=null;break}d=t(d[0].previousSibling)}var u=this.placeholder[0].nextSibling?t(this.placeholder[0].nextSibling):null;if(null!=u)for(;"li"!=u[0].nodeName.toLowerCase()||u[0]==this.currentItem[0]||u[0]==this.helper[0];){if(!u[0].nextSibling){u=null;break}u=t(u[0].nextSibling)}var f=document.createElement(i.listType);return this.beyondMaxLevels=0,null!=a&&null==u&&(i.rtl&&this.positionAbs.left+this.helper.outerWidth()>a.offset().left+a.outerWidth()||!i.rtl&&this.positionAbs.left<a.offset().left)?(a.after(this.placeholder[0]),this._clearEmpty(a[0]),this._trigger("change",e,this._uiHash())):null!=d&&(i.rtl&&this.positionAbs.left+this.helper.outerWidth()<d.offset().left+d.outerWidth()-i.tabSize||!i.rtl&&this.positionAbs.left>d.offset().left+i.tabSize)?(this._isAllowed(d,p,p+c+1),d.children(i.listType).length||d[0].appendChild(f),o&&o<=d.offset().top?d.children(i.listType).prepend(this.placeholder):d.children(i.listType)[0].appendChild(this.placeholder[0]),this._trigger("change",e,this._uiHash())):this._isAllowed(a,p,p+c),this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){this.beyondMaxLevels&&(this.placeholder.removeClass(this.options.errorClass),this.domPosition.prev?t(this.domPosition.prev).after(this.placeholder):t(this.domPosition.parent).prepend(this.placeholder),this._trigger("revert",e,this._uiHash()));for(var s=this.items.length-1;s>=0;s--){var o=this.items[s].item[0];this._clearEmpty(o)}t.ui.sortable.prototype._mouseStop.apply(this,arguments)},serialize:function(e){var i=t.extend({},this.options,e),s=this._getItemsAsjQuery(i&&i.connected),o=[];return t(s).each(function(){var e=(t(i.item||this).attr(i.attribute||"id")||"").match(i.expression||/(.+)[-=_](.+)/),s=(t(i.item||this).parent(i.listType).parent(i.items).attr(i.attribute||"id")||"").match(i.expression||/(.+)[-=_](.+)/);e&&o.push((i.key||e[1])+"["+(i.key&&i.expression?e[1]:e[2])+"]="+(s?i.key&&i.expression?s[1]:s[2]:i.rootID))}),!o.length&&i.key&&o.push(i.key+"="),o.join("&")},toHierarchy:function(e){function i(e){var o=(t(e).attr(s.attribute||"id")||"").match(s.expression||/(.+)[-=_](.+)/);if(o){var l={id:o[2]};return t(e).children(s.listType).children(s.items).length>0&&(l.children=[],t(e).children(s.listType).children(s.items).each(function(){var t=i(this);l.children.push(t)})),l}}var s=t.extend({},this.options,e),o=(s.startDepthCount,[]);return t(this.element).children(s.items).each(function(){var t=i(this);o.push(t)}),o},toArray:function(e){function i(e,r,n){var h,a,p=n+1;if(t(e).children(s.listType).children(s.items).length>0&&(r++,t(e).children(s.listType).children(s.items).each(function(){p=i(t(this),r,p)}),r--),h=t(e).attr(s.attribute||"id").match(s.expression||/(.+)[-=_](.+)/),r===o+1)a=s.rootID;else{a=t(e).parent(s.listType).parent(s.items).attr(s.attribute||"id").match(s.expression||/(.+)[-=_](.+)/)[2]}return h&&l.push({item_id:h[2],parent_id:a,depth:r,left:n,right:p}),n=p+1}var s=t.extend({},this.options,e),o=s.startDepthCount||0,l=[],r=2;return l.push({item_id:s.rootID,parent_id:"none",depth:o,left:"1",right:2*(t(s.items,this.element).length+1)}),t(this.element).children(s.items).each(function(){r=i(this,o+1,r)}),l=l.sort(function(t,e){return t.left-e.left})},_clearEmpty:function(e){var i=t(e).children(this.options.listType);!i.length||i.children().length||this.options.doNotClear||i.remove()},_getLevel:function(t){var e=1;if(this.options.listType)for(var i=t.closest(this.options.listType);i&&i.length>0&&!i.is(".ui-sortable");)e++,i=i.parent().closest(this.options.listType);return e},_getChildLevels:function(e,i){var s=this,o=this.options,l=0;return i=i||0,t(e).children(o.listType).children(o.items).each(function(t,e){l=Math.max(s._getChildLevels(e,i+1),l)}),i?l+1:l},_isAllowed:function(e,i,s){var o=this.options,l=!!t(this.domPosition.parent).hasClass("ui-sortable"),r=this.placeholder.closest(".ui-sortable").nestedSortable("option","maxLevels");!o.isAllowed(this.currentItem,e)||e&&e.hasClass(o.disableNesting)||o.protectRoot&&(null==e&&!l||l&&i>1)?(this.placeholder.addClass(o.errorClass),this.beyondMaxLevels=r<s&&0!=r?s-r:1):r<s&&0!=r?(this.placeholder.addClass(o.errorClass),this.beyondMaxLevels=s-r):(this.placeholder.removeClass(o.errorClass),this.beyondMaxLevels=0)}})),t.mjs.nestedSortable.prototype.options=t.extend({},t.ui.sortable.prototype.options,t.mjs.nestedSortable.prototype.options)}(jQuery); })(this);
+(function (window, undefined) { !function(f){f.widget("mjs.nestedSortable",f.extend({},f.ui.sortable.prototype,{options:{tabSize:20,disableNesting:"mjs-nestedSortable-no-nesting",errorClass:"mjs-nestedSortable-error",doNotClear:!1,listType:"ol",maxLevels:0,protectRoot:!1,rootID:null,rtl:!1,isAllowed:function(t,e){return!0}},_create:function(){if(this.element.data("sortable",this.element.data("nestedSortable")),!this.element.is(this.options.listType))throw new Error("nestedSortable: Please check the listType option is set to your actual list type");return f.ui.sortable.prototype._create.apply(this,arguments)},destroy:function(){return this.element.removeData("nestedSortable").unbind(".nestedSortable"),f.ui.sortable.prototype.destroy.apply(this,arguments)},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);var e,s=this.options;this.options.scroll&&(e=!1,this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<s.scrollSensitivity?this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop+s.scrollSpeed:t.pageY-this.overflowOffset.top<s.scrollSensitivity&&(this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop-s.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<s.scrollSensitivity?this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft+s.scrollSpeed:t.pageX-this.overflowOffset.left<s.scrollSensitivity&&(this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft-s.scrollSpeed)):(t.pageY-f(document).scrollTop()<s.scrollSensitivity?e=f(document).scrollTop(f(document).scrollTop()-s.scrollSpeed):f(window).height()-(t.pageY-f(document).scrollTop())<s.scrollSensitivity&&(e=f(document).scrollTop(f(document).scrollTop()+s.scrollSpeed)),t.pageX-f(document).scrollLeft()<s.scrollSensitivity?e=f(document).scrollLeft(f(document).scrollLeft()-s.scrollSpeed):f(window).width()-(t.pageX-f(document).scrollLeft())<s.scrollSensitivity&&(e=f(document).scrollLeft(f(document).scrollLeft()+s.scrollSpeed))),!1!==e&&f.ui.ddmanager&&!s.dropBehaviour&&f.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute");var i=this.placeholder.offset().top;this.options.axis&&"y"==this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"==this.options.axis||(this.helper[0].style.top=this.position.top+"px");for(var o=this.items.length-1;0<=o;o--){var r=this.items[o],l=r.item[0],n=this._intersectsWithPointer(r);if(n&&!(l==this.currentItem[0]||this.placeholder[1==n?"next":"prev"]()[0]==l||f.contains(this.placeholder[0],l)||"semi-dynamic"==this.options.type&&f.contains(this.element[0],l))){if(f(l).mouseenter(),this.direction=1==n?"down":"up","pointer"!=this.options.tolerance&&!this._intersectsWithSides(r))break;f(l).mouseleave(),this._rearrange(t,r),this._clearEmpty(l),this._trigger("change",t,this._uiHash());break}}var h=this.placeholder[0].parentNode.parentNode&&f(this.placeholder[0].parentNode.parentNode).closest(".ui-sortable").length?f(this.placeholder[0].parentNode.parentNode):null,a=this._getLevel(this.placeholder),p=this._getChildLevels(this.helper),c=this.placeholder[0].previousSibling?f(this.placeholder[0].previousSibling):null;if(null!=c)for(;"li"!=c[0].nodeName.toLowerCase()||c[0]==this.currentItem[0]||c[0]==this.helper[0];){if(!c[0].previousSibling){c=null;break}c=f(c[0].previousSibling)}var d=this.placeholder[0].nextSibling?f(this.placeholder[0].nextSibling):null;if(null!=d)for(;"li"!=d[0].nodeName.toLowerCase()||d[0]==this.currentItem[0]||d[0]==this.helper[0];){if(!d[0].nextSibling){d=null;break}d=f(d[0].nextSibling)}var u=document.createElement(s.listType);return this.beyondMaxLevels=0,null!=h&&null==d&&(s.rtl&&this.positionAbs.left+this.helper.outerWidth()>h.offset().left+h.outerWidth()||!s.rtl&&this.positionAbs.left<h.offset().left)?(h.after(this.placeholder[0]),this._clearEmpty(h[0]),this._trigger("change",t,this._uiHash())):null!=c&&(s.rtl&&this.positionAbs.left+this.helper.outerWidth()<c.offset().left+c.outerWidth()-s.tabSize||!s.rtl&&this.positionAbs.left>c.offset().left+s.tabSize)?(this._isAllowed(c,a,a+p+1),c.children(s.listType).length||c[0].appendChild(u),i&&i<=c.offset().top?c.children(s.listType).prepend(this.placeholder):c.children(s.listType)[0].appendChild(this.placeholder[0]),this._trigger("change",t,this._uiHash())):this._isAllowed(h,a,a+p),this._contactContainers(t),f.ui.ddmanager&&f.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,e){this.beyondMaxLevels&&(this.placeholder.removeClass(this.options.errorClass),this.domPosition.prev?f(this.domPosition.prev).after(this.placeholder):f(this.domPosition.parent).prepend(this.placeholder),this._trigger("revert",t,this._uiHash()));for(var s=this.items.length-1;0<=s;s--){var i=this.items[s].item[0];this._clearEmpty(i)}f.ui.sortable.prototype._mouseStop.apply(this,arguments)},serialize:function(t){var s=f.extend({},this.options,t),e=this._getItemsAsjQuery(s&&s.connected),i=[];return f(e).each(function(){var t=(f(s.item||this).attr(s.attribute||"id")||"").match(s.expression||/(.+)[-=_](.+)/),e=(f(s.item||this).parent(s.listType).parent(s.items).attr(s.attribute||"id")||"").match(s.expression||/(.+)[-=_](.+)/);t&&i.push((s.key||t[1])+"["+(s.key&&s.expression?t[1]:t[2])+"]="+(e?s.key&&s.expression?e[1]:e[2]:s.rootID))}),!i.length&&s.key&&i.push(s.key+"="),i.join("&")},toHierarchy:function(t){var o=f.extend({},this.options,t),e=(o.startDepthCount,[]);return f(this.element).children(o.items).each(function(){var t=function e(t){var s=(f(t).attr(o.attribute||"id")||"").match(o.expression||/(.+)[-=_](.+)/);if(s){var i={id:s[2]};return 0<f(t).children(o.listType).children(o.items).length&&(i.children=[],f(t).children(o.listType).children(o.items).each(function(){var t=e(this);i.children.push(t)})),i}}(this);e.push(t)}),e},toArray:function(t){var h=f.extend({},this.options,t),a=h.startDepthCount||0,p=[],e=2;return p.push({item_id:h.rootID,parent_id:"none",depth:a,left:"1",right:2*(f(h.items,this.element).length+1)}),f(this.element).children(h.items).each(function(){e=function t(e,s,i){var o,r,l=i+1;0<f(e).children(h.listType).children(h.items).length&&(s++,f(e).children(h.listType).children(h.items).each(function(){l=t(f(this),s,l)}),s--);o=f(e).attr(h.attribute||"id").match(h.expression||/(.+)[-=_](.+)/);{var n;r=s===a+1?h.rootID:(n=f(e).parent(h.listType).parent(h.items).attr(h.attribute||"id").match(h.expression||/(.+)[-=_](.+)/),n[2])}o&&p.push({item_id:o[2],parent_id:r,depth:s,left:i,right:l});i=l+1;return i}(this,a+1,e)}),p=p.sort(function(t,e){return t.left-e.left})},_clearEmpty:function(t){var e=f(t).children(this.options.listType);!e.length||e.children().length||this.options.doNotClear||e.remove()},_getLevel:function(t){var e=1;if(this.options.listType)for(var s=t.closest(this.options.listType);s&&0<s.length&&!s.is(".ui-sortable");)e++,s=s.parent().closest(this.options.listType);return e},_getChildLevels:function(t,s){var i=this,e=this.options,o=0;return s=s||0,f(t).children(e.listType).children(e.items).each(function(t,e){o=Math.max(i._getChildLevels(e,s+1),o)}),s?o+1:o},_isAllowed:function(t,e,s){var i=this.options,o=!!f(this.domPosition.parent).hasClass("ui-sortable"),r=this.placeholder.closest(".ui-sortable").nestedSortable("option","maxLevels");!i.isAllowed(this.currentItem,t)||t&&t.hasClass(i.disableNesting)||i.protectRoot&&(null==t&&!o||o&&1<e)?(this.placeholder.addClass(i.errorClass),this.beyondMaxLevels=r<s&&0!=r?s-r:1):r<s&&0!=r?(this.placeholder.addClass(i.errorClass),this.beyondMaxLevels=s-r):(this.placeholder.removeClass(i.errorClass),this.beyondMaxLevels=0)}})),f.mjs.nestedSortable.prototype.options=f.extend({},f.ui.sortable.prototype.options,f.mjs.nestedSortable.prototype.options)}(jQuery); })(this);
 
 // 3rdParty/polyfill/focus-visible.js
-(function (window, undefined) { function applyFocusVisiblePolyfill(e){function t(e){return!!(e&&e!==document&&"HTML"!==e.nodeName&&"BODY"!==e.nodeName&&"classList"in e&&"contains"in e.classList)}function n(e){var t=e.type,n=e.tagName;return!("INPUT"!=n||!L[t]||e.readOnly)||("TEXTAREA"==n&&!e.readOnly||!!e.isContentEditable)}function o(e){e.classList.contains("focus-visible")||(e.classList.add("focus-visible"),e.setAttribute("data-focus-visible-added",""))}function i(e){e.hasAttribute("data-focus-visible-added")&&(e.classList.remove("focus-visible"),e.removeAttribute("data-focus-visible-added"))}function d(n){n.metaKey||n.altKey||n.ctrlKey||(t(e.activeElement)&&o(e.activeElement),l=!0)}function s(e){l=!1}function u(e){t(e.target)&&(l||n(e.target))&&o(e.target)}function a(e){t(e.target)&&(e.target.classList.contains("focus-visible")||e.target.hasAttribute("data-focus-visible-added"))&&(E=!0,window.clearTimeout(f),f=window.setTimeout(function(){E=!1,window.clearTimeout(f)},100),i(e.target))}function c(e){"hidden"==document.visibilityState&&(E&&(l=!0),r())}function r(){document.addEventListener("mousemove",v),document.addEventListener("mousedown",v),document.addEventListener("mouseup",v),document.addEventListener("pointermove",v),document.addEventListener("pointerdown",v),document.addEventListener("pointerup",v),document.addEventListener("touchmove",v),document.addEventListener("touchstart",v),document.addEventListener("touchend",v)}function m(){document.removeEventListener("mousemove",v),document.removeEventListener("mousedown",v),document.removeEventListener("mouseup",v),document.removeEventListener("pointermove",v),document.removeEventListener("pointerdown",v),document.removeEventListener("pointerup",v),document.removeEventListener("touchmove",v),document.removeEventListener("touchstart",v),document.removeEventListener("touchend",v)}function v(e){e.target.nodeName&&"html"===e.target.nodeName.toLowerCase()||(l=!1,m())}var l=!0,E=!1,f=null,L={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};document.addEventListener("keydown",d,!0),document.addEventListener("mousedown",s,!0),document.addEventListener("pointerdown",s,!0),document.addEventListener("touchstart",s,!0),document.addEventListener("visibilitychange",c,!0),r(),e.addEventListener("focus",u,!0),e.addEventListener("blur",a,!0),e.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&e.host?e.host.setAttribute("data-js-focus-visible",""):e.nodeType===Node.DOCUMENT_NODE&&document.documentElement.classList.add("js-focus-visible")}if("undefined"!=typeof window&&"undefined"!=typeof document){window.applyFocusVisiblePolyfill=applyFocusVisiblePolyfill;var event;try{event=new CustomEvent("focus-visible-polyfill-ready")}catch(e){event=document.createEvent("CustomEvent"),event.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(event)}"undefined"!=typeof document&&applyFocusVisiblePolyfill(document); })(this);
+(function (window, undefined) { function applyFocusVisiblePolyfill(t){var i=!0,n=!1,o=null,d={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(e){return!!(e&&e!==document&&"HTML"!==e.nodeName&&"BODY"!==e.nodeName&&"classList"in e&&"contains"in e.classList)}function u(e){e.classList.contains("focus-visible")||(e.classList.add("focus-visible"),e.setAttribute("data-focus-visible-added",""))}function e(e){i=!1}function a(){document.addEventListener("mousemove",c),document.addEventListener("mousedown",c),document.addEventListener("mouseup",c),document.addEventListener("pointermove",c),document.addEventListener("pointerdown",c),document.addEventListener("pointerup",c),document.addEventListener("touchmove",c),document.addEventListener("touchstart",c),document.addEventListener("touchend",c)}function c(e){e.target.nodeName&&"html"===e.target.nodeName.toLowerCase()||(i=!1,document.removeEventListener("mousemove",c),document.removeEventListener("mousedown",c),document.removeEventListener("mouseup",c),document.removeEventListener("pointermove",c),document.removeEventListener("pointerdown",c),document.removeEventListener("pointerup",c),document.removeEventListener("touchmove",c),document.removeEventListener("touchstart",c),document.removeEventListener("touchend",c))}document.addEventListener("keydown",function(e){e.metaKey||e.altKey||e.ctrlKey||(s(t.activeElement)&&u(t.activeElement),i=!0)},!0),document.addEventListener("mousedown",e,!0),document.addEventListener("pointerdown",e,!0),document.addEventListener("touchstart",e,!0),document.addEventListener("visibilitychange",function(e){"hidden"==document.visibilityState&&(n&&(i=!0),a())},!0),a(),t.addEventListener("focus",function(e){var t,n,o;s(e.target)&&(i||(t=e.target,n=t.type,"INPUT"==(o=t.tagName)&&d[n]&&!t.readOnly||("TEXTAREA"==o&&!t.readOnly||!!t.isContentEditable)))&&u(e.target)},!0),t.addEventListener("blur",function(e){var t;s(e.target)&&(e.target.classList.contains("focus-visible")||e.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(o),o=window.setTimeout(function(){n=!1,window.clearTimeout(o)},100),(t=e.target).hasAttribute("data-focus-visible-added")&&(t.classList.remove("focus-visible"),t.removeAttribute("data-focus-visible-added")))},!0),t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host?t.host.setAttribute("data-js-focus-visible",""):t.nodeType===Node.DOCUMENT_NODE&&document.documentElement.classList.add("js-focus-visible")}if("undefined"!=typeof window&&"undefined"!=typeof document){var event;window.applyFocusVisiblePolyfill=applyFocusVisiblePolyfill;try{event=new CustomEvent("focus-visible-polyfill-ready")}catch(e){(event=document.createEvent("CustomEvent")).initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(event)}"undefined"!=typeof document&&applyFocusVisiblePolyfill(document); })(this);
 
 // WCF.Assets.js
-(function (window, undefined) { !function(){var e=!1,t=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){},Class.extend=function(n){function r(){!e&&this.init&&this.init.apply(this,arguments)}var i=this.prototype;e=!0;var o=new this;e=!1;for(var a in n)o[a]="function"==typeof n[a]&&"function"==typeof i[a]&&t.test(n[a])?function(e,t){return function(){var n=this._super;this._super=i[e];var r=t.apply(this,arguments);return this._super=n,r}}(a,n[a]):n[a];return r.prototype=o,r.prototype.constructor=r,r.extend=arguments.callee,r}}(),function(e,t){"use strict";function n(){}function r(e,t){if(e){"object"==typeof e&&(e=[].slice.call(e));for(var n=0,r=e.length;n<r;n++)t.call(e,e[n],n)}}function i(e,n){var r=Object.prototype.toString.call(n).slice(8,-1);return n!==t&&null!==n&&r===e}function o(e){return i("Function",e)}function a(e){return i("Array",e)}function l(e){var t=e.split("/"),n=t[t.length-1],r=n.indexOf("?");return-1!==r?n.substring(0,r):n}function u(e){e=e||n,e._done||(e(),e._done=1)}function c(e,t,r,i){var o="object"==typeof e?e:{test:e,success:!!t&&(a(t)?t:[t]),failure:!!r&&(a(r)?r:[r]),callback:i||n},l=!!o.test;return l&&o.success?(o.success.push(o.callback),N.load.apply(null,o.success)):l||!o.failure?i():(o.failure.push(o.callback),N.load.apply(null,o.failure)),N}function s(e){var t,n,r={};if("object"==typeof e)for(t in e)!e[t]||(r={name:t,url:e[t]});else r={name:l(e),url:e};return(n=S[r.name])&&n.url===r.url?n:(S[r.name]=r,r)}function p(e){e=e||S;for(var t in e)if(e.hasOwnProperty(t)&&e[t].state!==F)return!1;return!0}function d(e){e.state=P,r(e.onpreload,function(e){e.call()})}function f(e){e.state===t&&(e.state=I,e.onpreload=[],b({url:e.url,type:"cache"},function(){d(e)}))}function h(){var e=arguments,t=e[e.length-1],n=[].slice.call(e,1),i=n[0];return o(t)||(t=null),a(e[0])?(e[0].push(t),N.load.apply(null,e[0]),N):(i?(r(n,function(e){o(e)||!e||f(s(e))}),v(s(e[0]),o(i)?i:function(){N.load.apply(null,n)})):v(s(e[0])),N)}function g(){var e=arguments,t=e[e.length-1],n={};return o(t)||(t=null),a(e[0])?(e[0].push(t),N.load.apply(null,e[0]),N):(r(e,function(e){e!==t&&(e=s(e),n[e.name]=e)}),r(e,function(e){e!==t&&(e=s(e),v(e,function(){p(n)&&u(t)}))}),N)}function v(e,t){return t=t||n,e.state===F?void t():e.state===D?void N.ready(e.name,t):e.state===I?void e.onpreload.push(function(){v(e,t)}):(e.state=D,void b(e,function(){e.state=F,t(),r(k[e.name],function(e){u(e)}),O&&p()&&r(k.ALL,function(e){u(e)})}))}function m(e){e=e||"";var t=e.split("?")[0].split(".");return t[t.length-1].toLowerCase()}function b(t,r){function i(t){t=t||e.event,l.onload=l.onreadystatechange=l.onerror=null,r()}function o(n){n=n||e.event,("load"===n.type||/loaded|complete/.test(l.readyState)&&(!x.documentMode||x.documentMode<9))&&(e.clearTimeout(t.errorTimeout),e.clearTimeout(t.cssTimeout),l.onload=l.onreadystatechange=l.onerror=null,r())}function a(){if(t.state!==F&&t.cssRetries<=20){for(var n=0,r=x.styleSheets.length;n<r;n++)if(x.styleSheets[n].href===l.href)return void o({type:"load"});t.cssRetries++,t.cssTimeout=e.setTimeout(a,250)}}var l,u,c;r=r||n,u=m(t.url),"css"===u?(l=x.createElement("link"),l.type="text/"+(t.type||"css"),l.rel="stylesheet",l.href=t.url,t.cssRetries=0,t.cssTimeout=e.setTimeout(a,500)):(l=x.createElement("script"),l.type="text/"+(t.type||"javascript"),l.src=t.url),l.onload=l.onreadystatechange=o,l.onerror=i,l.async=!1,l.defer=!1,t.errorTimeout=e.setTimeout(function(){i({type:"timeout"})},7e3),c=x.head||x.getElementsByTagName("head")[0],c.insertBefore(l,c.lastChild)}function w(){for(var e,t=x.getElementsByTagName("script"),n=0,r=t.length;n<r;n++)if(!!(e=t[n].getAttribute("data-headjs-load")))return void N.load(e)}function y(e,t){var n,i,l;return e===x?(O?u(t):L.push(t),N):(o(e)&&(t=e,e="ALL"),a(e)?(n={},r(e,function(e){n[e]=S[e],N.ready(e,function(){p(n)&&u(t)})}),N):"string"==typeof e&&o(t)?(i=S[e])&&i.state===F||"ALL"===e&&p()&&O?(u(t),N):(l=k[e],l?l.push(t):l=k[e]=[t],N):N)}function T(){if(!x.body)return e.clearTimeout(N.readyTimeout),void(N.readyTimeout=e.setTimeout(T,50));O||(O=!0,w(),r(L,function(e){u(e)}))}function E(){x.addEventListener?(x.removeEventListener("DOMContentLoaded",E,!1),T()):"complete"===x.readyState&&(x.detachEvent("onreadystatechange",E),T())}var O,A,x=e.document,L=[],k={},S={},C="async"in x.createElement("script")||"MozAppearance"in x.documentElement.style||e.opera,M=e.head_conf&&e.head_conf.head||"head",N=e[M]=e[M]||function(){N.ready.apply(null,arguments)},I=1,P=2,D=3,F=4;if("complete"===x.readyState)T();else if(x.addEventListener)x.addEventListener("DOMContentLoaded",E,!1),e.addEventListener("load",T,!1);else{x.attachEvent("onreadystatechange",E),e.attachEvent("onload",T),A=!1;try{A=!e.frameElement&&x.documentElement}catch(e){}A&&A.doScroll&&function t(){if(!O){try{A.doScroll("left")}catch(n){return e.clearTimeout(N.readyTimeout),void(N.readyTimeout=e.setTimeout(t,50))}T()}}()}N.load=N.js=C?g:h,N.test=c,N.ready=y,N.ready(x,function(){p()&&r(k.ALL,function(e){u(e)}),N.feature&&N.feature("domloaded",!0)})}(window),function(e){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],e):e(jQuery)}(function(e){function t(t){return!t||void 0!==t.allowPageScroll||void 0===t.swipe&&void 0===t.swipeStatus||(t.allowPageScroll=c),void 0!==t.click&&void 0===t.tap&&(t.tap=t.click),t||(t={}),t=e.extend({},e.fn.swipe.defaults,t),this.each(function(){var r=e(this),i=r.data(k);i||(i=new n(this,t),r.data(k,i))})}function n(t,n){function S(t){if(!(ce()||e(t.target).closest(n.excludedElements,Xe).length>0)){var r,i=t.originalEvent?t.originalEvent:t,o=A?i.touches[0]:i;return Qe=y,(A?Ye=i.touches.length:t.preventDefault(),Fe=0,ze=null,Ue=null,Re=0,_e=0,je=0,Ve=1,qe=0,Be=he(),He=me(),le(),!A||Ye===n.fingers||n.fingers===b||H()?(pe(0,o),We=Le(),2==Ye&&(pe(1,i.touches[1]),_e=je=ye(Be[0].start,Be[1].start)),(n.swipeStatus||n.pinchStatus)&&(r=F(i,Qe))):r=!1,!1===r)?(Qe=O,F(i,Qe),r):(n.hold&&(et=setTimeout(e.proxy(function(){Xe.trigger("hold",[i.target]),n.hold&&(r=n.hold.call(Xe,i,i.target))},this),n.longTapThreshold)),se(!0),null)}}function C(e){var t=e.originalEvent?e.originalEvent:e;if(Qe!==E&&Qe!==O&&!ue()){var r,i=A?t.touches[0]:t,o=de(i);if(Ze=Le(),A&&(Ye=t.touches.length),n.hold&&clearTimeout(et),Qe=T,2==Ye&&(0==_e?(pe(1,t.touches[1]),_e=je=ye(Be[0].start,Be[1].start)):(de(t.touches[1]),je=ye(Be[0].end,Be[1].end),Ue=Ee(Be[0].end,Be[1].end)),Ve=Te(_e,je),qe=Math.abs(_e-je)),Ye===n.fingers||n.fingers===b||!A||H()){if(ze=xe(o.start,o.end),q(e,ze),Fe=Oe(o.start,o.end),Re=we(),ge(ze,Fe),(n.swipeStatus||n.pinchStatus)&&(r=F(t,Qe)),!n.triggerOnTouchEnd||n.triggerOnTouchLeave){var a=!0;if(n.triggerOnTouchLeave){var l=ke(this);a=Se(o.end,l)}!n.triggerOnTouchEnd&&a?Qe=D(T):n.triggerOnTouchLeave&&!a&&(Qe=D(E)),Qe!=O&&Qe!=E||F(t,Qe)}}else Qe=O,F(t,Qe);!1===r&&(Qe=O,F(t,Qe))}}function M(e){var t=e.originalEvent;return A&&t.touches.length>0?(ae(),!0):(ue()&&(Ye=Ke),Ze=Le(),Re=we(),_()||!R()?(Qe=O,F(t,Qe)):n.triggerOnTouchEnd||0==n.triggerOnTouchEnd&&Qe===T?(e.preventDefault(),Qe=E,F(t,Qe)):!n.triggerOnTouchEnd&&G()?(Qe=E,z(t,Qe,f)):Qe===T&&(Qe=O,F(t,Qe)),se(!1),null)}function N(){Ye=0,Ze=0,We=0,_e=0,je=0,Ve=1,le(),se(!1)}function I(e){var t=e.originalEvent;n.triggerOnTouchLeave&&(Qe=D(E),F(t,Qe))}function P(){Xe.unbind(Me,S),Xe.unbind(De,N),Xe.unbind(Ne,C),Xe.unbind(Ie,M),Pe&&Xe.unbind(Pe,I),se(!1)}function D(e){var t=e,r=V(),i=R(),o=_();return!r||o?t=O:!i||e!=T||n.triggerOnTouchEnd&&!n.triggerOnTouchLeave?!i&&e==E&&n.triggerOnTouchLeave&&(t=O):t=E,t}function F(e,t){var n=void 0;return B()||Y()?n=z(e,t,p):(X()||H())&&!1!==n&&(n=z(e,t,d)),ie()&&!1!==n?n=z(e,t,h):oe()&&!1!==n?n=z(e,t,g):re()&&!1!==n&&(n=z(e,t,f)),t===O&&N(e),t===E&&(A?0==e.touches.length&&N(e):N(e)),n}function z(t,c,s){var v=void 0;if(s==p){if(Xe.trigger("swipeStatus",[c,ze||null,Fe||0,Re||0,Ye,Be]),n.swipeStatus&&!1===(v=n.swipeStatus.call(Xe,t,c,ze||null,Fe||0,Re||0,Ye,Be)))return!1;if(c==E&&Q()){if(Xe.trigger("swipe",[ze,Fe,Re,Ye,Be]),n.swipe&&!1===(v=n.swipe.call(Xe,t,ze,Fe,Re,Ye,Be)))return!1;switch(ze){case r:Xe.trigger("swipeLeft",[ze,Fe,Re,Ye,Be]),n.swipeLeft&&(v=n.swipeLeft.call(Xe,t,ze,Fe,Re,Ye,Be));break;case i:Xe.trigger("swipeRight",[ze,Fe,Re,Ye,Be]),n.swipeRight&&(v=n.swipeRight.call(Xe,t,ze,Fe,Re,Ye,Be));break;case o:Xe.trigger("swipeUp",[ze,Fe,Re,Ye,Be]),n.swipeUp&&(v=n.swipeUp.call(Xe,t,ze,Fe,Re,Ye,Be));break;case a:Xe.trigger("swipeDown",[ze,Fe,Re,Ye,Be]),n.swipeDown&&(v=n.swipeDown.call(Xe,t,ze,Fe,Re,Ye,Be))}}}if(s==d){if(Xe.trigger("pinchStatus",[c,Ue||null,qe||0,Re||0,Ye,Ve,Be]),n.pinchStatus&&!1===(v=n.pinchStatus.call(Xe,t,c,Ue||null,qe||0,Re||0,Ye,Ve,Be)))return!1;if(c==E&&U())switch(Ue){case l:Xe.trigger("pinchIn",[Ue||null,qe||0,Re||0,Ye,Ve,Be]),n.pinchIn&&(v=n.pinchIn.call(Xe,t,Ue||null,qe||0,Re||0,Ye,Ve,Be));break;case u:Xe.trigger("pinchOut",[Ue||null,qe||0,Re||0,Ye,Ve,Be]),n.pinchOut&&(v=n.pinchOut.call(Xe,t,Ue||null,qe||0,Re||0,Ye,Ve,Be))}}return s==f?c!==O&&c!==E||(clearTimeout(Je),clearTimeout(et),K()&&!ee()?($e=Le(),Je=setTimeout(e.proxy(function(){$e=null,Xe.trigger("tap",[t.target]),n.tap&&(v=n.tap.call(Xe,t,t.target))},this),n.doubleTapThreshold)):($e=null,Xe.trigger("tap",[t.target]),n.tap&&(v=n.tap.call(Xe,t,t.target)))):s==h?c!==O&&c!==E||(clearTimeout(Je),$e=null,Xe.trigger("doubletap",[t.target]),n.doubleTap&&(v=n.doubleTap.call(Xe,t,t.target))):s==g&&(c!==O&&c!==E||(clearTimeout(Je),$e=null,Xe.trigger("longtap",[t.target]),n.longTap&&(v=n.longTap.call(Xe,t,t.target)))),v}function R(){var e=!0;return null!==n.threshold&&(e=Fe>=n.threshold),e}function _(){var e=!1;return null!==n.cancelThreshold&&null!==ze&&(e=ve(ze)-Fe>=n.cancelThreshold),e}function j(){return null===n.pinchThreshold||qe>=n.pinchThreshold}function V(){return!n.maxTimeThreshold||!(Re>=n.maxTimeThreshold)}function q(e,t){if(n.allowPageScroll===c||H())e.preventDefault();else{var l=n.allowPageScroll===s;switch(t){case r:(n.swipeLeft&&l||!l&&n.allowPageScroll!=v)&&e.preventDefault();break;case i:(n.swipeRight&&l||!l&&n.allowPageScroll!=v)&&e.preventDefault();break;case o:(n.swipeUp&&l||!l&&n.allowPageScroll!=m)&&e.preventDefault();break;case a:(n.swipeDown&&l||!l&&n.allowPageScroll!=m)&&e.preventDefault()}}}function U(){var e=W(),t=Z(),n=j();return e&&t&&n}function H(){return!!(n.pinchStatus||n.pinchIn||n.pinchOut)}function X(){return!(!U()||!H())}function Q(){var e=V(),t=R(),n=W(),r=Z();return!_()&&r&&n&&t&&e}function Y(){return!!(n.swipe||n.swipeStatus||n.swipeLeft||n.swipeRight||n.swipeUp||n.swipeDown)}function B(){return!(!Q()||!Y())}function W(){return Ye===n.fingers||n.fingers===b||!A}function Z(){return 0!==Be[0].end.x}function G(){return!!n.tap}function K(){return!!n.doubleTap}function $(){return!!n.longTap}function J(){if(null==$e)return!1;var e=Le();return K()&&e-$e<=n.doubleTapThreshold}function ee(){return J()}function te(){return(1===Ye||!A)&&(isNaN(Fe)||Fe<n.threshold)}function ne(){return Re>n.longTapThreshold&&Fe<w}function re(){return!(!te()||!G())}function ie(){return!(!J()||!K())}function oe(){return!(!ne()||!$())}function ae(){Ge=Le(),Ke=event.touches.length+1}function le(){Ge=0,Ke=0}function ue(){var e=!1;if(Ge){Le()-Ge<=n.fingerReleaseThreshold&&(e=!0)}return e}function ce(){return!(!0!==Xe.data(k+"_intouch"))}function se(e){!0===e?(Xe.bind(Ne,C),Xe.bind(Ie,M),Pe&&Xe.bind(Pe,I)):(Xe.unbind(Ne,C,!1),Xe.unbind(Ie,M,!1),Pe&&Xe.unbind(Pe,I,!1)),Xe.data(k+"_intouch",!0===e)}function pe(e,t){var n=void 0!==t.identifier?t.identifier:0;return Be[e].identifier=n,Be[e].start.x=Be[e].end.x=t.pageX||t.clientX,Be[e].start.y=Be[e].end.y=t.pageY||t.clientY,Be[e]}function de(e){var t=void 0!==e.identifier?e.identifier:0,n=fe(t);return n.end.x=e.pageX||e.clientX,n.end.y=e.pageY||e.clientY,n}function fe(e){for(var t=0;t<Be.length;t++)if(Be[t].identifier==e)return Be[t]}function he(){for(var e=[],t=0;t<=5;t++)e.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return e}function ge(e,t){t=Math.max(t,ve(e)),He[e].distance=t}function ve(e){if(He[e])return He[e].distance}function me(){var e={};return e[r]=be(r),e[i]=be(i),e[o]=be(o),e[a]=be(a),e}function be(e){return{direction:e,distance:0}}function we(){return Ze-We}function ye(e,t){var n=Math.abs(e.x-t.x),r=Math.abs(e.y-t.y);return Math.round(Math.sqrt(n*n+r*r))}function Te(e,t){return(t/e*1).toFixed(2)}function Ee(){return Ve<1?u:l}function Oe(e,t){return Math.round(Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)))}function Ae(e,t){var n=e.x-t.x,r=t.y-e.y,i=Math.atan2(r,n),o=Math.round(180*i/Math.PI);return o<0&&(o=360-Math.abs(o)),o}function xe(e,t){var n=Ae(e,t);return n<=45&&n>=0?r:n<=360&&n>=315?r:n>=135&&n<=225?i:n>45&&n<135?a:o}function Le(){return(new Date).getTime()}function ke(t){t=e(t);var n=t.offset();return{left:n.left,right:n.left+t.outerWidth(),top:n.top,bottom:n.top+t.outerHeight()}}function Se(e,t){return e.x>t.left&&e.x<t.right&&e.y>t.top&&e.y<t.bottom}var Ce=A||L||!n.fallbackToMouseEvents,Me=Ce?L?x?"MSPointerDown":"pointerdown":"touchstart":"mousedown",Ne=Ce?L?x?"MSPointerMove":"pointermove":"touchmove":"mousemove",Ie=Ce?L?x?"MSPointerUp":"pointerup":"touchend":"mouseup",Pe=Ce?null:"mouseleave",De=L?x?"MSPointerCancel":"pointercancel":"touchcancel",Fe=0,ze=null,Re=0,_e=0,je=0,Ve=1,qe=0,Ue=0,He=null,Xe=e(t),Qe="start",Ye=0,Be=null,We=0,Ze=0,Ge=0,Ke=0,$e=0,Je=null,et=null;try{Xe.bind(Me,S),Xe.bind(De,N)}catch(t){e.error("events not supported "+Me+","+De+" on jQuery.swipe")}this.enable=function(){return Xe.bind(Me,S),Xe.bind(De,N),Xe},this.disable=function(){return P(),Xe},this.destroy=function(){return P(),Xe.data(k,null),Xe},this.option=function(t,r){if(void 0!==n[t]){if(void 0===r)return n[t];n[t]=r}else e.error("Option "+t+" does not exist on jQuery.swipe.options");return null}}var r="left",i="right",o="up",a="down",l="in",u="out",c="none",s="auto",p="swipe",d="pinch",f="tap",h="doubletap",g="longtap",v="horizontal",m="vertical",b="all",w=10,y="start",T="move",E="end",O="cancel",A="ontouchstart"in window,x=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,L=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,k="TouchSwipe",S={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"};e.fn.swipe=function(n){var r=e(this),i=r.data(k);if(i&&"string"==typeof n){if(i[n])return i[n].apply(this,Array.prototype.slice.call(arguments,1));e.error("Method "+n+" does not exist on jQuery.swipe")}else if(!(i||"object"!=typeof n&&n))return t.apply(this,arguments);return r},e.fn.swipe.defaults=S,e.fn.swipe.phases={PHASE_START:y,PHASE_MOVE:T,PHASE_END:E,PHASE_CANCEL:O},e.fn.swipe.directions={LEFT:r,RIGHT:i,UP:o,DOWN:a,IN:l,OUT:u},e.fn.swipe.pageScroll={NONE:c,HORIZONTAL:v,VERTICAL:m,AUTO:s},e.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:b}}),function(e){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(e)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(e.substr(0,4))}(navigator.userAgent||navigator.vendor||window.opera),function(e){var t={init:function(){var t=["paddingTop","paddingRight","paddingBottom","paddingLeft","fontSize","lineHeight","fontFamily","width","fontWeight","border-top-width","border-right-width","border-bottom-width","border-left-width","-moz-box-sizing","-webkit-box-sizing","box-sizing"];return this.each(function(){function n(){for(var e=0;e<t.length;e++)a.css(t[e],o.css(t[e]))}function r(){var e=o.val().replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&/g,"&amp;").replace(/\n/g,"<br/>");a.html(e+"&nbsp;").css({width:parseInt(o.width(),10)+"px"}),i()}function i(){var e=a.height(),t="hidden",n=l?e+s+u:e+s;n>d?(n=d,t="auto"):p>n&&(n=p),o.height()!==n&&o.css({overflow:t,height:n+"px"})}if("textarea"!==this.type)return!1;var o=e(this).css({resize:"none",overflow:"hidden"}),a=e("<div></div>").css({position:"absolute",display:"none","word-wrap":"break-word","white-space":"pre-wrap","border-style":"solid"}).appendTo(document.body);n();var l="border-box"==o.css("box-sizing")||"border-box"==o.css("-moz-box-sizing")||"border-box"==o.css("-webkit-box-sizing"),u=parseInt(o.css("border-top-width"))+parseInt(o.css("padding-top"))+parseInt(o.css("padding-bottom"))+parseInt(o.css("border-bottom-width")),c=parseInt(o.css("height"),10),s=parseInt(o.css("line-height"),10)||parseInt(o.css("font-size"),10),p=2*s>c?2*s:c,d=parseInt(o.css("max-height"),10)>-1?parseInt(o.css("max-height"),10):Number.MAX_VALUE;o.bind("keyup change cut paste",function(){r()}),e(window).bind("resize",function(){a.width()!==parseInt(o.width(),10)&&r()}),o.bind("blur",function(){i()}),o.bind("updateHeight",function(){n(),r()}),e(function(){r()})})}};e.fn.flexible=function(n){return t[n]?t[n].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof n&&n?void e.error("Method "+n+" does not exist on jQuery.flexible"):t.init.apply(this,arguments)}}(jQuery),function(e,t,n,r){"use strict";function i(e,t){for(var n=0,r=e.length;n<r;n++)g(e[n],t)}function o(e){for(var t,n=0,r=e.length;n<r;n++)t=e[n],E(t,_[l(t)])}function a(e){return function(t){ne(t)&&(g(t,e),i(t.querySelectorAll(j),e))}}function l(e){var t=e.getAttribute("is"),n=e.nodeName.toUpperCase(),r=q.call(R,t?D+t.toUpperCase():P+n);return t&&-1<r&&!u(n,t)?-1:r}function u(e,t){return-1<j.indexOf(e+'[is="'+t+'"]')}function c(e){var t=e.currentTarget,n=e.attrChange,r=e.attrName,i=e.target;he&&(!i||i===t)&&t.attributeChangedCallback&&"style"!==r&&t.attributeChangedCallback(r,n===e[k]?null:e.prevValue,n===e[C]?null:e.newValue)}function s(e){var t=a(e);return function(e){v.push(t,e.target)}}function p(e){fe&&(fe=!1,e.currentTarget.removeEventListener(N,p)),i((e.target||t).querySelectorAll(j),e.detail===x?x:A),te&&h()}function d(e,t){var n=this;oe.call(n,e,t),m.call(n,{target:n})}function f(e,t){$(e,t),y?y.observe(e,ue):(de&&(e.setAttribute=d,e[O]=w(e),e.addEventListener(I,m)),e.addEventListener(M,c)),e.createdCallback&&he&&(e.created=!0,e.createdCallback(),e.created=!1)}function h(){for(var e,t=0,n=re.length;t<n;t++)e=re[t],V.contains(e)||(re.splice(t,1),g(e,x))}function g(e,t){var n,r=l(e);-1<r&&(T(e,_[r]),r=0,t!==A||e[A]?t===x&&!e[x]&&(e[A]=!1,e[x]=!0,r=1):(e[x]=!1,e[A]=!0,r=1,te&&q.call(re,e)<0&&re.push(e)),r&&(n=e[t+"Callback"])&&n.call(e))}if(!(r in t)){var v,m,b,w,y,T,E,O="__"+r+(1e5*Math.random()>>0),A="attached",x="detached",L="extends",k="ADDITION",S="MODIFICATION",C="REMOVAL",M="DOMAttrModified",N="DOMContentLoaded",I="DOMSubtreeModified",P="<",D="=",F=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,z=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],R=[],_=[],j="",V=t.documentElement,q=R.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},U=n.prototype,H=U.hasOwnProperty,X=U.isPrototypeOf,Q=n.defineProperty,Y=n.getOwnPropertyDescriptor,B=n.getOwnPropertyNames,W=n.getPrototypeOf,Z=n.setPrototypeOf,G=!!n.__proto__,K=n.create||function e(t){return t?(e.prototype=t,new e):this},$=Z||(G?function(e,t){return e.__proto__=t,e}:B&&Y?function(){function e(e,t){for(var n,r=B(t),i=0,o=r.length;i<o;i++)n=r[i],H.call(e,n)||Q(e,n,Y(t,n))}return function(t,n){do{e(t,n)}while((n=W(n))&&!X.call(n,t));return t}}():function(e,t){for(var n in t)e[n]=t[n];return e}),J=e.MutationObserver||e.WebKitMutationObserver,ee=(e.HTMLElement||e.Element||e.Node).prototype,te=!X.call(ee,V),ne=te?function(e){return 1===e.nodeType}:function(e){return X.call(ee,e)},re=te&&[],ie=ee.cloneNode,oe=ee.setAttribute,ae=ee.removeAttribute,le=t.createElement,ue=J&&{attributes:!0,characterData:!0,attributeOldValue:!0},ce=J||function(e){de=!1,V.removeEventListener(M,ce)},se=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,10)},pe=!1,de=!0,fe=!0,he=!0;Z||G?(T=function(e,t){X.call(t,e)||f(e,t)},E=f):(T=function(e,t){e[O]||(e[O]=n(!0),f(e,t))},E=T),te?(de=!1,function(){var e=Y(ee,"addEventListener"),t=e.value,n=function(e){var t=new CustomEvent(M,{bubbles:!0});t.attrName=e,t.prevValue=this.getAttribute(e),t.newValue=null,t[C]=t.attrChange=2,ae.call(this,e),this.dispatchEvent(t)},r=function(e,t){var n=this.hasAttribute(e),r=n&&this.getAttribute(e),i=new CustomEvent(M,{bubbles:!0});oe.call(this,e,t),i.attrName=e,i.prevValue=n?r:null,i.newValue=t,n?i[S]=i.attrChange=1:i[k]=i.attrChange=0,this.dispatchEvent(i)},i=function(e){var t,n=e.currentTarget,r=n[O],i=e.propertyName;r.hasOwnProperty(i)&&(r=r[i],t=new CustomEvent(M,{bubbles:!0}),t.attrName=r.name,t.prevValue=r.value||null,t.newValue=r.value=n[i]||null,null==t.prevValue?t[k]=t.attrChange=0:t[S]=t.attrChange=1,n.dispatchEvent(t))};e.value=function(e,o,a){e===M&&this.attributeChangedCallback&&this.setAttribute!==r&&(this[O]={className:{name:"class",value:this.className}},this.setAttribute=r,this.removeAttribute=n,t.call(this,"propertychange",i)),t.call(this,e,o,a)},Q(ee,"addEventListener",e)}()):J||(V.addEventListener(M,ce),V.setAttribute(O,1),V.removeAttribute(O),de&&(m=function(e){var t,n,r,i=this;if(i===e.target){t=i[O],i[O]=n=w(i);for(r in n){if(!(r in t))return b(0,i,r,t[r],n[r],k);if(n[r]!==t[r])return b(1,i,r,t[r],n[r],S)}for(r in t)if(!(r in n))return b(2,i,r,t[r],n[r],C)}},b=function(e,t,n,r,i,o){var a={attrChange:e,currentTarget:t,attrName:n,prevValue:r,newValue:i};a[o]=e,c(a)},w=function(e){for(var t,n,r={},i=e.attributes,o=0,a=i.length;o<a;o++)t=i[o],"setAttribute"!==(n=t.name)&&(r[n]=t.value);return r})),t[r]=function(e,n){if(r=e.toUpperCase(),pe||(pe=!0,J?(y=function(e,t){function n(e,t){for(var n=0,r=e.length;n<r;t(e[n++]));}return new J(function(r){for(var i,o,a=0,l=r.length;a<l;a++)i=r[a],"childList"===i.type?(n(i.addedNodes,e),n(i.removedNodes,t)):(o=i.target,he&&o.attributeChangedCallback&&"style"!==i.attributeName&&o.attributeChangedCallback(i.attributeName,i.oldValue,o.getAttribute(i.attributeName)))})}(a(A),a(x)),y.observe(t,{childList:!0,subtree:!0})):(v=[],se(function e(){for(;v.length;)v.shift().call(null,v.shift());se(e)}),t.addEventListener("DOMNodeInserted",s(A)),t.addEventListener("DOMNodeRemoved",s(x))),t.addEventListener(N,p),t.addEventListener("readystatechange",p),t.createElement=function(e,n){var r=le.apply(t,arguments),i=""+e,o=q.call(R,(n?D:P)+(n||i).toUpperCase()),a=-1<o;return n&&(r.setAttribute("is",n=n.toLowerCase()),a&&(a=u(i.toUpperCase(),n))),he=!t.createElement.innerHTMLHelper,a&&E(r,_[o]),r},ee.cloneNode=function(e){var t=ie.call(this,!!e),n=l(t);return-1<n&&E(t,_[n]),e&&o(t.querySelectorAll(j)),t}),-2<q.call(R,D+r)+q.call(R,P+r))throw new Error("A "+e+" type is already registered");if(!F.test(r)||-1<q.call(z,r))throw new Error("The type "+e+" is invalid");var r,c=function(){return f?t.createElement(h,r):t.createElement(h)},d=n||U,f=H.call(d,L),h=f?n[L].toUpperCase():r,g=R.push((f?D:P)+r)-1;return j=j.concat(j.length?",":"",f?h+'[is="'+e.toLowerCase()+'"]':h),c.prototype=_[g]=H.call(d,"prototype")?d.prototype:K(ee),i(t.querySelectorAll(j),A),c}}}(window,document,Object,"registerElement"),function(e,t,n){"use strict";function r(){return e.performance!==n&&e.performance.now!==n?e.performance.now():Date.now()}function i(e){return.5*(1-Math.cos(Math.PI*e))}function o(e){if("object"!=typeof e||e.behavior===n||"auto"===e.behavior||"instant"===e.behavior)return!0;if("smooth"===e.behavior)return!1;throw new TypeError(e.behavior+" is not a valid value for enumeration ScrollBehavior")}function a(e,t,n){e.scrollTop=n,e.scrollLeft=t}function l(t,o){function a(){var f,h,g,v=r(),m=(v-d)/s;return m=m>1?1:m,f=i(m),h=l+(t-l)*f,g=u+(o-u)*f,p(h,g),h===t&&g===o?(l=u=d=null,e.cancelAnimationFrame(c),n):(c=e.requestAnimationFrame(a),n)}var l=e.scrollX||e.pageXOffset,u=e.scrollY||e.pageYOffset,d=r();c&&e.cancelAnimationFrame(c),c=e.requestAnimationFrame(a)}function u(o,u){function p(){var t,l,u,m=r(),b=(m-v)/s;return b=b>1?1:b,t=i(b),l=d+(h-d)*t,u=f+(g-f)*t,a(o,l,u),l===h&&u===g?(d=f=v=null,e.cancelAnimationFrame(c),n):(c=e.requestAnimationFrame(p),n)}if(o===t.documentElement||o===t.body)return l(u.left,u.top),n;var d=o.scrollLeft,f=o.scrollTop,h=u.left,g=u.top,v=r();c&&e.cancelAnimationFrame(c),c=e.requestAnimationFrame(p)}if(!("scrollBehavior"in t.documentElement.style)){var c,s=768,p=e.scrollTo,d=e.scrollBy,f=e.Element.prototype.scrollIntoView;e.scroll=e.scrollTo=function(){return o(arguments[0])?p.call(e,arguments[0].left||arguments[0],arguments[0].top||arguments[1]):l.call(e,~~arguments[0].left,~~arguments[0].top)},e.scrollBy=function(){if(o(arguments[0]))return d.call(e,arguments[0].left||arguments[0],arguments[0].top||arguments[1]);var t=e.scrollX||e.pageXOffset,n=e.scrollY||e.pageYOffset;return l(~~arguments[0].left+t,~~arguments[0].top+n)},Element.prototype.scrollIntoView=function(){var n,r,i,a;return o(arguments[0])?f.call(this,arguments[0]||!0):(a=e.getComputedStyle(t.body,null),r=parseInt(a.getPropertyValue("padding-left"),10),i=parseInt(a.getPropertyValue("padding-top"),10),n={top:this.offsetTop-2*i,left:this.offsetLeft-2*r},u(t.body,n))}}}(window,document); })(this);
+(function (window, undefined) { !function(){var o=!1,a=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;this.Class=function(){},Class.extend=function(e){function t(){!o&&this.init&&this.init.apply(this,arguments)}var i=this.prototype;o=!0;var n=new this;for(var r in o=!1,e)n[r]="function"==typeof e[r]&&"function"==typeof i[r]&&a.test(e[r])?function(n,r){return function(){var e=this._super;this._super=i[n];var t=r.apply(this,arguments);return this._super=e,t}}(r,e[r]):e[r];return((t.prototype=n).constructor=t).extend=arguments.callee,t}}(),function(u,r){"use strict";function s(){}function o(e,t){if(e){"object"==typeof e&&(e=[].slice.call(e));for(var n=0,r=e.length;n<r;n++)t.call(e,e[n],n)}}function t(e,t){var n=Object.prototype.toString.call(t).slice(8,-1);return t!==r&&null!==t&&n===e}function a(e){return t("Function",e)}function l(e){return t("Array",e)}function c(e){(e=e||s)._done||(e(),e._done=1)}function i(e){var t,n,r,i,o,a={};if("object"==typeof e)for(t in e)e[t]&&(a={name:t,url:e[t]});else a={name:(r=e.split("/"),i=r[r.length-1],-1!==(o=i.indexOf("?"))?i.substring(0,o):i),url:e};return(n=y[a.name])&&n.url===a.url?n:y[a.name]=a}function p(e){for(var t in e=e||y)if(e.hasOwnProperty(t)&&e[t].state!==k)return;return 1}function d(t){t.state===r&&(t.state=A,t.onpreload=[],n({url:t.url,type:"cache"},function(){var e;(e=t).state=x,o(e.onpreload,function(e){e.call()})}))}function f(e,t){t=t||s,e.state!==k?e.state!==L?e.state!==A?(e.state=L,n(e,function(){e.state=k,t(),o(w[e.name],function(e){c(e)}),g&&p()&&o(w.ALL,function(e){c(e)})})):e.onpreload.push(function(){f(e,t)}):O.ready(e.name,t):t()}function n(r,t){function e(e){e=e||u.event,o.onload=o.onreadystatechange=o.onerror=null,t()}function i(e){("load"===(e=e||u.event).type||/loaded|complete/.test(o.readyState)&&(!v.documentMode||v.documentMode<9))&&(u.clearTimeout(r.errorTimeout),u.clearTimeout(r.cssTimeout),o.onload=o.onreadystatechange=o.onerror=null,t())}var o,n,a,l;t=t||s,a=r.url,"css"===(l=(a=a||"").split("?")[0].split("."))[l.length-1].toLowerCase()?((o=v.createElement("link")).type="text/"+(r.type||"css"),o.rel="stylesheet",o.href=r.url,r.cssRetries=0,r.cssTimeout=u.setTimeout(function e(){if(r.state!==k&&r.cssRetries<=20){for(var t=0,n=v.styleSheets.length;t<n;t++)if(v.styleSheets[t].href===o.href)return void i({type:"load"});r.cssRetries++,r.cssTimeout=u.setTimeout(e,250)}},500)):((o=v.createElement("script")).type="text/"+(r.type||"javascript"),o.src=r.url),o.onload=o.onreadystatechange=i,o.onerror=e,o.async=!1,o.defer=!1,r.errorTimeout=u.setTimeout(function(){e({type:"timeout"})},6e4),(n=v.head||v.getElementsByTagName("head")[0]).insertBefore(o,n.lastChild)}function e(){if(!v.body)return u.clearTimeout(O.readyTimeout),void(O.readyTimeout=u.setTimeout(e,50));g||(g=!0,function(){for(var e,t=v.getElementsByTagName("script"),n=0,r=t.length;n<r;n++)if(e=t[n].getAttribute("data-headjs-load"))return O.load(e)}(),o(b,function(e){c(e)}))}function h(){v.addEventListener?(v.removeEventListener("DOMContentLoaded",h,!1),e()):"complete"===v.readyState&&(v.detachEvent("onreadystatechange",h),e())}var g,m,v=u.document,b=[],w={},y={},T="async"in v.createElement("script")||"MozAppearance"in v.documentElement.style||u.opera,E=u.head_conf&&u.head_conf.head||"head",O=u[E]=u[E]||function(){O.ready.apply(null,arguments)},A=1,x=2,L=3,k=4;if("complete"===v.readyState)e();else if(v.addEventListener)v.addEventListener("DOMContentLoaded",h,!1),u.addEventListener("load",e,!1);else{v.attachEvent("onreadystatechange",h),u.attachEvent("onload",e),m=!1;try{m=!u.frameElement&&v.documentElement}catch(e){}m&&m.doScroll&&function t(){if(!g){try{m.doScroll("left")}catch(e){return u.clearTimeout(O.readyTimeout),void(O.readyTimeout=u.setTimeout(t,50))}e()}}()}O.load=O.js=T?function(){var e=arguments,t=e[e.length-1],n={};return a(t)||(t=null),l(e[0])?(e[0].push(t),O.load.apply(null,e[0])):(o(e,function(e){e!==t&&(e=i(e),n[e.name]=e)}),o(e,function(e){e!==t&&f(e=i(e),function(){p(n)&&c(t)})})),O}:function(){var e=arguments,t=e[e.length-1],n=[].slice.call(e,1),r=n[0];return a(t)||(t=null),l(e[0])?(e[0].push(t),O.load.apply(null,e[0])):r?(o(n,function(e){a(e)||!e||d(i(e))}),f(i(e[0]),a(r)?r:function(){O.load.apply(null,n)})):f(i(e[0])),O},O.test=function(e,t,n,r){var i="object"==typeof e?e:{test:e,success:!!t&&(l(t)?t:[t]),failure:!!n&&(l(n)?n:[n]),callback:r||s},o=!!i.test;return o&&i.success?(i.success.push(i.callback),O.load.apply(null,i.success)):o||!i.failure?r():(i.failure.push(i.callback),O.load.apply(null,i.failure)),O},O.ready=function(e,t){var n,r,i;return e===v?(g?c(t):b.push(t),O):(a(e)&&(t=e,e="ALL"),l(e)?(n={},o(e,function(e){n[e]=y[e],O.ready(e,function(){p(n)&&c(t)})}),O):"string"==typeof e&&a(t)?((r=y[e])&&r.state===k||"ALL"===e&&p()&&g?c(t):(i=w[e])?i.push(t):i=w[e]=[t],O):O)},O.ready(v,function(){p()&&o(w.ALL,function(e){c(e)}),O.feature&&O.feature("domloaded",!0)})}(window),function(e){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],e):e(jQuery)}(function(oe){var ae="left",le="right",ue="up",se="down",ce="in",pe="out",de="none",fe="auto",he="swipe",ge="pinch",me="tap",ve="doubletap",be="longtap",we="horizontal",ye="vertical",Te="all",Ee=10,Oe="start",Ae="move",xe="end",Le="cancel",ke="ontouchstart"in window,Se=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,Ce=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,Me="TouchSwipe";function r(e,v){var t=ke||Ce||!v.fallbackToMouseEvents,n=t?Ce?Se?"MSPointerDown":"pointerdown":"touchstart":"mousedown",r=t?Ce?Se?"MSPointerMove":"pointermove":"touchmove":"mousemove",i=t?Ce?Se?"MSPointerUp":"pointerup":"touchend":"mouseup",o=t?null:"mouseleave",a=Ce?Se?"MSPointerCancel":"pointercancel":"touchcancel",b=0,w=null,y=0,T=0,E=0,O=1,A=0,x=0,L=null,l=oe(e),k="start",S=0,C=null,u=0,M=0,s=0,c=0,p=0,d=null,N=null;try{l.bind(n,f),l.bind(a,m)}catch(e){oe.error("events not supported "+n+","+a+" on jQuery.swipe")}function f(e){if(!0!==l.data(Me+"_intouch")&&!(0<oe(e.target).closest(v.excludedElements,l).length)){var t,n,r=e.originalEvent?e.originalEvent:e,i=ke?r.touches[0]:r;return(k=Oe,ke?S=r.touches.length:e.preventDefault(),x=w=null,O=1,A=E=T=y=b=0,C=function(){for(var e=[],t=0;t<=5;t++)e.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return e}(),(n={})[ae]=te(ae),n[le]=te(le),n[ue]=te(ue),n[se]=te(se),L=n,Z(),!ke||S===v.fingers||v.fingers===Te||q()?($(0,i),u=ie(),2==S&&($(1,r.touches[1]),T=E=re(C[0].start,C[1].start)),(v.swipeStatus||v.pinchStatus)&&(t=F(r,k))):t=!1,!1===t)?(F(r,k=Le),t):(v.hold&&(N=setTimeout(oe.proxy(function(){l.trigger("hold",[r.target]),v.hold&&(t=v.hold.call(l,r,r.target))},this),v.longTapThreshold)),K(!0),null)}}function h(e){var t,n,r,i,o,a,l,u,s,c,p,d,f,h,g,m=e.originalEvent?e.originalEvent:e;k===xe||k===Le||G()||(n=J(ke?m.touches[0]:m),M=ie(),ke&&(S=m.touches.length),v.hold&&clearTimeout(N),k=Ae,2==S&&(0==T?($(1,m.touches[1]),T=E=re(C[0].start,C[1].start)):(J(m.touches[1]),E=re(C[0].end,C[1].end),C[0].end,C[1].end,x=O<1?pe:ce),O=(E/T*1).toFixed(2),A=Math.abs(T-E)),S===v.fingers||v.fingers===Te||!ke||q()?(f=n.start,h=n.end,g=function(e,t){var n=e.x-t.x,r=t.y-e.y,i=Math.atan2(r,n),o=Math.round(180*i/Math.PI);o<0&&(o=360-Math.abs(o));return o}(f,h),function(e,t){if(v.allowPageScroll===de||q())e.preventDefault();else{var n=v.allowPageScroll===fe;switch(t){case ae:(v.swipeLeft&&n||!n&&v.allowPageScroll!=we)&&e.preventDefault();break;case le:(v.swipeRight&&n||!n&&v.allowPageScroll!=we)&&e.preventDefault();break;case ue:(v.swipeUp&&n||!n&&v.allowPageScroll!=ye)&&e.preventDefault();break;case se:(v.swipeDown&&n||!n&&v.allowPageScroll!=ye)&&e.preventDefault()}}}(e,w=g<=45&&0<=g||g<=360&&315<=g?ae:135<=g&&g<=225?le:45<g&&g<135?se:ue),p=n.start,d=n.end,b=Math.round(Math.sqrt(Math.pow(d.x-p.x,2)+Math.pow(d.y-p.y,2))),y=ne(),s=w,c=b,c=Math.max(c,ee(s)),L[s].distance=c,(v.swipeStatus||v.pinchStatus)&&(t=F(m,k)),v.triggerOnTouchEnd&&!v.triggerOnTouchLeave||(r=!0,v.triggerOnTouchLeave&&(i={left:(u=(l=oe(l=this)).offset()).left,right:u.left+l.outerWidth(),top:u.top,bottom:u.top+l.outerHeight()},o=n.end,a=i,r=o.x>a.left&&o.x<a.right&&o.y>a.top&&o.y<a.bottom),!v.triggerOnTouchEnd&&r?k=D(Ae):v.triggerOnTouchLeave&&!r&&(k=D(xe)),k!=Le&&k!=xe||F(m,k))):F(m,k=Le),!1===t&&F(m,k=Le))}function g(e){var t=e.originalEvent;return ke&&0<t.touches.length?(s=ie(),c=event.touches.length+1,!0):(G()&&(S=c),M=ie(),y=ne(),_()||!R()?F(t,k=Le):v.triggerOnTouchEnd||0==v.triggerOnTouchEnd&&k===Ae?(e.preventDefault(),F(t,k=xe)):!v.triggerOnTouchEnd&&Y()?z(t,k=xe,me):k===Ae&&F(t,k=Le),K(!1),null)}function m(){E=T=u=M=S=0,Z(),K(!(O=1))}function I(e){var t=e.originalEvent;v.triggerOnTouchLeave&&F(t,k=D(xe))}function P(){l.unbind(n,f),l.unbind(a,m),l.unbind(r,h),l.unbind(i,g),o&&l.unbind(o,I),K(!1)}function D(e){var t=e,n=j(),r=R(),i=_();return!n||i?t=Le:!r||e!=Ae||v.triggerOnTouchEnd&&!v.triggerOnTouchLeave?!r&&e==xe&&v.triggerOnTouchLeave&&(t=Le):t=xe,t}function F(e,t){var n=void 0;return U()&&H()||H()?n=z(e,t,he):(V()&&q()||q())&&!1!==n&&(n=z(e,t,ge)),W()&&B()&&!1!==n?n=z(e,t,ve):y>v.longTapThreshold&&b<Ee&&v.longTap&&!1!==n?n=z(e,t,be):1!==S&&ke||!(isNaN(b)||b<v.threshold)||!Y()||!1===n||(n=z(e,t,me)),t===Le&&m(),t!==xe||ke&&0!=e.touches.length||m(),n}function z(e,t,n){var r=void 0;if(n==he){if(l.trigger("swipeStatus",[t,w||null,b||0,y||0,S,C]),v.swipeStatus&&!1===(r=v.swipeStatus.call(l,e,t,w||null,b||0,y||0,S,C)))return!1;if(t==xe&&U()){if(l.trigger("swipe",[w,b,y,S,C]),v.swipe&&!1===(r=v.swipe.call(l,e,w,b,y,S,C)))return!1;switch(w){case ae:l.trigger("swipeLeft",[w,b,y,S,C]),v.swipeLeft&&(r=v.swipeLeft.call(l,e,w,b,y,S,C));break;case le:l.trigger("swipeRight",[w,b,y,S,C]),v.swipeRight&&(r=v.swipeRight.call(l,e,w,b,y,S,C));break;case ue:l.trigger("swipeUp",[w,b,y,S,C]),v.swipeUp&&(r=v.swipeUp.call(l,e,w,b,y,S,C));break;case se:l.trigger("swipeDown",[w,b,y,S,C]),v.swipeDown&&(r=v.swipeDown.call(l,e,w,b,y,S,C))}}}if(n==ge){if(l.trigger("pinchStatus",[t,x||null,A||0,y||0,S,O,C]),v.pinchStatus&&!1===(r=v.pinchStatus.call(l,e,t,x||null,A||0,y||0,S,O,C)))return!1;if(t==xe&&V())switch(x){case ce:l.trigger("pinchIn",[x||null,A||0,y||0,S,O,C]),v.pinchIn&&(r=v.pinchIn.call(l,e,x||null,A||0,y||0,S,O,C));break;case pe:l.trigger("pinchOut",[x||null,A||0,y||0,S,O,C]),v.pinchOut&&(r=v.pinchOut.call(l,e,x||null,A||0,y||0,S,O,C))}}return n==me?t!==Le&&t!==xe||(clearTimeout(d),clearTimeout(N),B()&&!W()?(p=ie(),d=setTimeout(oe.proxy(function(){p=null,l.trigger("tap",[e.target]),v.tap&&(r=v.tap.call(l,e,e.target))},this),v.doubleTapThreshold)):(p=null,l.trigger("tap",[e.target]),v.tap&&(r=v.tap.call(l,e,e.target)))):n==ve?t!==Le&&t!==xe||(clearTimeout(d),p=null,l.trigger("doubletap",[e.target]),v.doubleTap&&(r=v.doubleTap.call(l,e,e.target))):n==be&&(t!==Le&&t!==xe||(clearTimeout(d),p=null,l.trigger("longtap",[e.target]),v.longTap&&(r=v.longTap.call(l,e,e.target)))),r}function R(){var e=!0;return null!==v.threshold&&(e=b>=v.threshold),e}function _(){var e=!1;return null!==v.cancelThreshold&&null!==w&&(e=ee(w)-b>=v.cancelThreshold),e}function j(){var e=!v.maxTimeThreshold||!(y>=v.maxTimeThreshold);return e}function V(){var e=X(),t=Q(),n=null===v.pinchThreshold||A>=v.pinchThreshold;return e&&t&&n}function q(){return v.pinchStatus||v.pinchIn||v.pinchOut}function U(){var e=j(),t=R(),n=X(),r=Q();return!_()&&r&&n&&t&&e}function H(){return v.swipe||v.swipeStatus||v.swipeLeft||v.swipeRight||v.swipeUp||v.swipeDown}function X(){return S===v.fingers||v.fingers===Te||!ke}function Q(){return 0!==C[0].end.x}function Y(){return v.tap}function B(){return!!v.doubleTap}function W(){if(null==p)return!1;var e=ie();return B()&&e-p<=v.doubleTapThreshold}function Z(){c=s=0}function G(){var e=!1;return s&&ie()-s<=v.fingerReleaseThreshold&&(e=!0),e}function K(e){!0===e?(l.bind(r,h),l.bind(i,g),o&&l.bind(o,I)):(l.unbind(r,h,!1),l.unbind(i,g,!1),o&&l.unbind(o,I,!1)),l.data(Me+"_intouch",!0===e)}function $(e,t){var n=void 0!==t.identifier?t.identifier:0;return C[e].identifier=n,C[e].start.x=C[e].end.x=t.pageX||t.clientX,C[e].start.y=C[e].end.y=t.pageY||t.clientY,C[e]}function J(e){var t=function(e){for(var t=0;t<C.length;t++)if(C[t].identifier==e)return C[t]}(void 0!==e.identifier?e.identifier:0);return t.end.x=e.pageX||e.clientX,t.end.y=e.pageY||e.clientY,t}function ee(e){if(L[e])return L[e].distance}function te(e){return{direction:e,distance:0}}function ne(){return M-u}function re(e,t){var n=Math.abs(e.x-t.x),r=Math.abs(e.y-t.y);return Math.round(Math.sqrt(n*n+r*r))}function ie(){return(new Date).getTime()}this.enable=function(){return l.bind(n,f),l.bind(a,m),l},this.disable=function(){return P(),l},this.destroy=function(){return P(),l.data(Me,null),l},this.option=function(e,t){if(void 0!==v[e]){if(void 0===t)return v[e];v[e]=t}else oe.error("Option "+e+" does not exist on jQuery.swipe.options");return null}}oe.fn.swipe=function(e){var t=oe(this),n=t.data(Me);if(n&&"string"==typeof e){if(n[e])return n[e].apply(this,Array.prototype.slice.call(arguments,1));oe.error("Method "+e+" does not exist on jQuery.swipe")}else if(!(n||"object"!=typeof e&&e))return function(n){!n||void 0!==n.allowPageScroll||void 0===n.swipe&&void 0===n.swipeStatus||(n.allowPageScroll=de);void 0!==n.click&&void 0===n.tap&&(n.tap=n.click);n=n||{};return n=oe.extend({},oe.fn.swipe.defaults,n),this.each(function(){var e=oe(this),t=e.data(Me);t||(t=new r(this,n),e.data(Me,t))})}.apply(this,arguments);return t},oe.fn.swipe.defaults={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"},oe.fn.swipe.phases={PHASE_START:Oe,PHASE_MOVE:Ae,PHASE_END:xe,PHASE_CANCEL:Le},oe.fn.swipe.directions={LEFT:ae,RIGHT:le,UP:ue,DOWN:se,IN:ce,OUT:pe},oe.fn.swipe.pageScroll={NONE:de,HORIZONTAL:we,VERTICAL:ye,AUTO:fe},oe.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:Te}}),function(e){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(e)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(e.substr(0,4))}(navigator.userAgent||navigator.vendor||window.opera),function(d){var t={init:function(){var p=["paddingTop","paddingRight","paddingBottom","paddingLeft","fontSize","lineHeight","fontFamily","width","fontWeight","border-top-width","border-right-width","border-bottom-width","border-left-width","-moz-box-sizing","-webkit-box-sizing","box-sizing"];return this.each(function(){function e(){for(var e=0;e<p.length;e++)i.css(p[e],r.css(p[e]))}function t(){var e=r.val().replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&/g,"&amp;").replace(/\n/g,"<br/>");i.html(e+"&nbsp;").css({width:parseInt(r.width(),10)+"px"}),n()}function n(){var e=i.height(),t="hidden",n=o?e+u+a:e+u;c<n?(n=c,t="auto"):n<s&&(n=s),r.height()!==n&&r.css({overflow:t,height:n+"px"})}if("textarea"!==this.type)return!1;var r=d(this).css({resize:"none",overflow:"hidden"}),i=d("<div></div>").css({position:"absolute",display:"none","word-wrap":"break-word","white-space":"pre-wrap","border-style":"solid"}).appendTo(document.body);e();var o="border-box"==r.css("box-sizing")||"border-box"==r.css("-moz-box-sizing")||"border-box"==r.css("-webkit-box-sizing"),a=parseInt(r.css("border-top-width"))+parseInt(r.css("padding-top"))+parseInt(r.css("padding-bottom"))+parseInt(r.css("border-bottom-width")),l=parseInt(r.css("height"),10),u=parseInt(r.css("line-height"),10)||parseInt(r.css("font-size"),10),s=l<2*u?2*u:l,c=-1<parseInt(r.css("max-height"),10)?parseInt(r.css("max-height"),10):Number.MAX_VALUE;r.bind("keyup change cut paste",function(){t()}),d(window).bind("resize",function(){i.width()!==parseInt(r.width(),10)&&t()}),r.bind("blur",function(){n()}),r.bind("updateHeight",function(){e(),t()}),d(function(){t()})})}};d.fn.flexible=function(e){return t[e]?t[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?void d.error("Method "+e+" does not exist on jQuery.flexible"):t.init.apply(this,arguments)}}(jQuery),function(e,p,n,t){"use strict";function d(e,t){for(var n=0,r=e.length;n<r;n++)o(e[n],t)}function f(t){return function(e){Y(e)&&(o(e,t),d(e.querySelectorAll(C),t))}}function h(e){var t=e.getAttribute("is"),n=e.nodeName.toUpperCase(),r=N.call(k,t?A+t.toUpperCase():O+n);return t&&-1<r&&!g(n,t)?-1:r}function g(e,t){return-1<C.indexOf(e+'[is="'+t+'"]')}function l(e){var t=e.currentTarget,n=e.attrChange,r=e.attrName,i=e.target;!oe||i&&i!==t||!t.attributeChangedCallback||"style"===r||t.attributeChangedCallback(r,n===e[u]?null:e.prevValue,n===e[c]?null:e.newValue)}function m(e){var t=f(e);return function(e){ee.push(t,e.target)}}function v(e){ie&&(ie=!1,e.currentTarget.removeEventListener(E,v)),d((e.target||p).querySelectorAll(C),e.detail===w?w:b),Q&&function(){for(var e,t=0,n=B.length;t<n;t++)e=B[t],M.contains(e)||(B.splice(t,1),o(e,w))}()}function r(e,t){Z.call(this,e,t),ae.call(this,{target:this})}function i(e,t){U(e,t),se?se.observe(e,$):(re&&(e.setAttribute=r,e[a]=ue(e),e.addEventListener("DOMSubtreeModified",ae)),e.addEventListener(T,l)),e.createdCallback&&oe&&(e.created=!0,e.createdCallback(),e.created=!1)}function o(e,t){var n,r=h(e);-1<r&&(ce(e,S[r]),r=0,t!==b||e[b]?t!==w||e[w]||(e[b]=!1,e[w]=!0,r=1):(e[w]=!1,e[b]=!0,r=1,Q&&N.call(B,e)<0&&B.push(e)),r&&(n=e[t+"Callback"])&&n.call(e))}var a,b,w,y,u,s,c,T,E,O,A,x,L,k,S,C,M,N,I,P,D,F,z,R,_,j,V,q,U,H,X,Q,Y,B,W,Z,G,K,$,J,ee,te,ne,re,ie,oe,ae,le,ue,se,ce,pe,de,fe;function he(e){var t=new CustomEvent(T,{bubbles:!0});t.attrName=e,t.prevValue=this.getAttribute(e),t.newValue=null,t[c]=t.attrChange=2,G.call(this,e),this.dispatchEvent(t)}function ge(e,t){var n=this.hasAttribute(e),r=n&&this.getAttribute(e),i=new CustomEvent(T,{bubbles:!0});Z.call(this,e,t),i.attrName=e,i.prevValue=n?r:null,i.newValue=t,n?i[s]=i.attrChange=1:i[u]=i.attrChange=0,this.dispatchEvent(i)}function me(e){var t,n=e.currentTarget,r=n[a],i=e.propertyName;r.hasOwnProperty(i)&&(r=r[i],(t=new CustomEvent(T,{bubbles:!0})).attrName=r.name,t.prevValue=r.value||null,t.newValue=r.value=n[i]||null,null==t.prevValue?t[u]=t.attrChange=0:t[s]=t.attrChange=1,n.dispatchEvent(t))}t in p||(a="__"+t+(1e5*Math.random()>>0),b="attached",w="detached",y="extends",u="ADDITION",s="MODIFICATION",c="REMOVAL",T="DOMAttrModified",E="DOMContentLoaded",O="<",A="=",x=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,L=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],k=[],S=[],C="",M=p.documentElement,N=k.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},I=n.prototype,P=I.hasOwnProperty,D=I.isPrototypeOf,F=n.defineProperty,z=n.getOwnPropertyDescriptor,R=n.getOwnPropertyNames,_=n.getPrototypeOf,j=n.setPrototypeOf,V=!!n.__proto__,q=n.create||function e(t){return t?(e.prototype=t,new e):this},U=j||(V?function(e,t){return e.__proto__=t,e}:R&&z?function(e,t){for(;function(e,t){for(var n,r=R(t),i=0,o=r.length;i<o;i++)n=r[i],P.call(e,n)||F(e,n,z(t,n))}(e,t),(t=_(t))&&!D.call(t,e););return e}:function(e,t){for(var n in t)e[n]=t[n];return e}),H=e.MutationObserver||e.WebKitMutationObserver,X=(e.HTMLElement||e.Element||e.Node).prototype,Q=!D.call(X,M),Y=Q?function(e){return 1===e.nodeType}:function(e){return D.call(X,e)},B=Q&&[],W=X.cloneNode,Z=X.setAttribute,G=X.removeAttribute,K=p.createElement,$=H&&{attributes:!0,characterData:!0,attributeOldValue:!0},J=H||function(e){re=!1,M.removeEventListener(T,J)},te=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,10)},oe=ie=re=!(ne=!1),fe=j||V?(ce=function(e,t){D.call(t,e)||i(e,t)},i):ce=function(e,t){e[a]||(e[a]=n(!0),i(e,t))},Q?(re=!1,pe=z(X,"addEventListener"),de=pe.value,pe.value=function(e,t,n){e===T&&this.attributeChangedCallback&&this.setAttribute!==ge&&(this[a]={className:{name:"class",value:this.className}},this.setAttribute=ge,this.removeAttribute=he,de.call(this,"propertychange",me)),de.call(this,e,t,n)},F(X,"addEventListener",pe)):H||(M.addEventListener(T,J),M.setAttribute(a,1),M.removeAttribute(a),re&&(ae=function(e){var t,n,r,i=this;if(i===e.target){for(r in t=i[a],i[a]=n=ue(i),n){if(!(r in t))return le(0,i,r,t[r],n[r],u);if(n[r]!==t[r])return le(1,i,r,t[r],n[r],s)}for(r in t)if(!(r in n))return le(2,i,r,t[r],n[r],c)}},le=function(e,t,n,r,i,o){var a={attrChange:e,currentTarget:t,attrName:n,prevValue:r,newValue:i};a[o]=e,l(a)},ue=function(e){for(var t,n,r={},i=e.attributes,o=0,a=i.length;o<a;o++)"setAttribute"!==(n=(t=i[o]).name)&&(r[n]=t.value);return r})),p[t]=function(e,t){function o(e,t){for(var n=0,r=e.length;n<r;t(e[n++]));}var a,l,n=e.toUpperCase();if(ne||(ne=!0,H?(a=f(b),l=f(w),(se=new H(function(e){for(var t,n,r=0,i=e.length;r<i;r++)"childList"===(t=e[r]).type?(o(t.addedNodes,a),o(t.removedNodes,l)):(n=t.target,oe&&n.attributeChangedCallback&&"style"!==t.attributeName&&n.attributeChangedCallback(t.attributeName,t.oldValue,n.getAttribute(t.attributeName)))})).observe(p,{childList:!0,subtree:!0})):(ee=[],te(function e(){for(;ee.length;)ee.shift().call(null,ee.shift());te(e)}),p.addEventListener("DOMNodeInserted",m(b)),p.addEventListener("DOMNodeRemoved",m(w))),p.addEventListener(E,v),p.addEventListener("readystatechange",v),p.createElement=function(e,t){var n=K.apply(p,arguments),r=""+e,i=N.call(k,(t?A:O)+(t||r).toUpperCase()),o=-1<i;return t&&(n.setAttribute("is",t=t.toLowerCase()),o=o&&g(r.toUpperCase(),t)),oe=!p.createElement.innerHTMLHelper,o&&fe(n,S[i]),n},X.cloneNode=function(e){var t=W.call(this,!!e),n=h(t);return-1<n&&fe(t,S[n]),e&&function(e){for(var t,n=0,r=e.length;n<r;n++)t=e[n],fe(t,S[h(t)])}(t.querySelectorAll(C)),t}),-2<N.call(k,A+n)+N.call(k,O+n))throw new Error("A "+e+" type is already registered");if(!x.test(n)||-1<N.call(L,n))throw new Error("The type "+e+" is invalid");function r(){return u?p.createElement(s,n):p.createElement(s)}var n,i=t||I,u=P.call(i,y),s=u?t[y].toUpperCase():n,c=k.push((u?A:O)+n)-1;return C=C.concat(C.length?",":"",u?s+'[is="'+e.toLowerCase()+'"]':s),r.prototype=S[c]=P.call(i,"prototype")?i.prototype:q(X),d(p.querySelectorAll(C),b),r})}(window,document,Object,"registerElement"),function(h,i,g){"use strict";function m(){return h.performance!==g&&h.performance.now!==g?h.performance.now():Date.now()}function v(e){return.5*(1-Math.cos(Math.PI*e))}function o(e){if("object"!=typeof e||e.behavior===g||"auto"===e.behavior||"instant"===e.behavior)return 1;if("smooth"!==e.behavior)throw new TypeError(e.behavior+" is not a valid value for enumeration ScrollBehavior")}function n(o,a){var l=h.scrollX||h.pageXOffset,u=h.scrollY||h.pageYOffset,s=m();b&&h.cancelAnimationFrame(b),b=h.requestAnimationFrame(function e(){var t=(m()-s)/w,n=v(t=1<t?1:t),r=l+(o-l)*n,i=u+(a-u)*n;return c(r,i),r===o&&i===a?(l=u=s=null,h.cancelAnimationFrame(b)):b=h.requestAnimationFrame(e),g})}function a(u,e){if(u===i.documentElement||u===i.body)return n(e.left,e.top),g;var s=u.scrollLeft,c=u.scrollTop,p=e.left,d=e.top,f=m();b&&h.cancelAnimationFrame(b),b=h.requestAnimationFrame(function e(){var t,n,r,i=(m()-f)/w,o=v(i=1<i?1:i),a=s+(p-s)*o,l=c+(d-c)*o;return n=a,r=l,(t=u).scrollTop=r,t.scrollLeft=n,a===p&&l===d?(s=c=f=null,h.cancelAnimationFrame(b)):b=h.requestAnimationFrame(e),g})}var b,w,c,r,l;"scrollBehavior"in i.documentElement.style||(w=768,c=h.scrollTo,r=h.scrollBy,l=h.Element.prototype.scrollIntoView,h.scroll=h.scrollTo=function(){return o(arguments[0])?c.call(h,arguments[0].left||arguments[0],arguments[0].top||arguments[1]):n.call(h,~~arguments[0].left,~~arguments[0].top)},h.scrollBy=function(){if(o(arguments[0]))return r.call(h,arguments[0].left||arguments[0],arguments[0].top||arguments[1]);var e=h.scrollX||h.pageXOffset,t=h.scrollY||h.pageYOffset;return n(~~arguments[0].left+e,~~arguments[0].top+t)},Element.prototype.scrollIntoView=function(){var e,t,n,r;return o(arguments[0])?l.call(this,arguments[0]||!0):(r=h.getComputedStyle(i.body,null),t=parseInt(r.getPropertyValue("padding-left"),10),n=parseInt(r.getPropertyValue("padding-top"),10),e={top:this.offsetTop-2*n,left:this.offsetLeft-2*t},a(i.body,e))})}(window,document); })(this);
 
 // WCF.js
-(function (window, undefined) { "use strict";function wcfEval(expression){return eval(expression)}!function(){var e=jQuery.fn.data;jQuery.fn.data=function(t,i){var n=[].slice.call(arguments);if(t)switch(typeof t){case"object":for(var s in t)if(s.match(/ID$/)){var a=t[s];delete t[s],s=s.replace(/ID$/,"-id"),t[s]=a}n[0]=t;break;case"string":t.match(/ID$/)&&(n[0]=t.replace(/ID$/,"-id"))}var o=e.apply(this,n);if(void 0===t)for(var s in o)s.match(/Id$/)&&(o[s.replace(/Id$/,"ID")]=o[s],delete o[s]);return o},window.console||(window.console={});for(var t=["log","info","warn","exception","assert","dir","dirxml","trace","group","groupEnd","groupCollapsed","profile","profileEnd","count","clear","time","timeEnd","timeStamp","table","error"],i=0;i<t.length;i++)void 0===console[t[i]]&&(console[t[i]]=function(){});void 0===console.debug&&(console.debug=function(e){console.log(e)})}(),window.shuffle=function(e){for(var t,i,n=e.length;0!==n;)i=Math.floor(Math.random()*n),n-=1,t=e[n],e[n]=e[i],e[i]=t;return this},function(e){var t=navigator.userAgent.toLowerCase(),i=/(chrome)[ \/]([\w.]+)/.exec(t)||/(webkit)[ \/]([\w.]+)/.exec(t)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(t)||/(msie) ([\w.]+)/.exec(t)||t.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(t)||[],n={browser:i[1]||"",version:i[2]||"0"},s={};n.browser&&(s[n.browser]=!0,s.version=n.version),s.chrome?s.webkit=!0:s.webkit&&(s.safari=!0),e.browser=e.browser||{},e.browser=$.extend(e.browser,s),e.browser.touch=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&window.navigator.msMaxTouchPoints>0,e.browser.smartphone="bottom"==$("html").css("caption-side"),e.browser.mozilla&&t.match(/trident/)&&(e.browser.mozilla=!1,e.browser.msie=!0),e.browser.iOS=/\((ipad|iphone|ipod);/.test(t),e.browser.iOS&&$("html").addClass("iOS"),e.browser.android=-1!==t.indexOf("android"),e.browser.editor="redactor",e.browser.ckeditor=!1,e.browser.redactor=!0,e.browser.iOS&&(e.fn.focus=function(e,t){return arguments.length>0?this.on("focus",null,e,t):this.trigger("focus")})}(jQuery),null==window.WCF&&(window.WCF={}),$.extend(!0,{removeArrayValue:function(e,t){return $.grep(e,function(e,i){return t!==e})},wcfEscapeID:function(e){return e.replace(/(:|\.)/g,"\\$1")},wcfIsset:function(e){return!!$("#"+$.wcfEscapeID(e)).length},getLength:function(e){var t=0;for(var i in e)e.hasOwnProperty(i)&&t++;return t}}),$.fn.extend({getTagName:function(){return this.length?this.get(0).tagName.toLowerCase():""},getDimensions:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"inner":i={height:this.innerHeight(),width:this.innerWidth()};break;case"outer":i={height:this.outerHeight(),width:this.outerWidth()};break;default:i={height:this.height(),width:this.width()}}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},getOffsets:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"offset":i=this.offset();break;case"position":default:i=this.position()}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},makePositioned:function(e,t){"absolute"!=e&&"fixed"!=e&&(e="absolute");var i=this.getOffsets("position");return this.css({position:e,left:i.left,margin:0,top:i.top}),t&&this.remove().appentTo("body"),this},disable:function(){return this.attr("disabled","disabled")},enable:function(){return this.removeAttr("disabled")},wcfIdentify:function(){return window.bc_wcfDomUtil.identify(this[0])},getCaret:function(){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return-1}else if(!this.is("textarea"))return-1;var e=0,t=this.get(0);if(document.selection){this.focus();var i=document.selection.createRange();i.moveStart("character",-this.val().length),e=i.text.length}else(t.selectionStart||"0"==t.selectionStart)&&(e=parseInt(t.selectionStart));return e},setCaret:function(e){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return!1}else if(!this.is("textarea"))return!1;var t=this.get(0);if(this.focus(),document.selection){var i=document.selection.createRange();i.moveStart("character",e),i.moveEnd("character",0),i.select()}else(t.selectionStart||"0"==t.selectionStart)&&(t.selectionStart=e,t.selectionEnd=e);return!0},wcfDropIn:function(e,t,i){return e||(e="up"),i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfDropOut:function(e,t,i){return e||(e="down"),i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfBlindIn:function(e,t,i){return e||(e="vertical"),i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfBlindOut:function(e,t,i){return e||(e="vertical"),i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfHighlight:function(e,t){return this.effect("highlight",e,600,t)},wcfFadeIn:function(e,t){return t&&parseInt(t)||(t=200),this.show(WCF.getEffect(this,"fade"),{},t,e)},wcfFadeOut:function(e,t){return t&&parseInt(t)||(t=200),this.hide(WCF.getEffect(this,"fade"),{},t,e)},cssAsNumber:function(e){if(this.length){var t=this.css(e);if(void 0!==t)return parseInt(t.replace(/px$/,""))}return 0},perfectScrollbar:function(e){var t=require("perfect-scrollbar");return this.each(function(){if("object"==typeof e||void 0===e){var i=e;$(this).data("psID")||t.initialize(this,i)}else{var n=e;"update"===n?t.update(this):"destroy"===n&&t.destroy(this)}return jQuery(this)})}}),$.extend(WCF,{activeDialogs:0,_idCounter:0,getRandomID:function(){return window.bc_wcfDomUtil.getUniqueId()},inArray:function(e,t){return-1!=$.inArray(e,t)},getEffect:function(e,t){return e.is("tr")?"highlight":t},getInlineCSS:function(e){var t={},i=e.attr("style");if(!i)return{};i=i.split(";");for(var n=0,s=i.length;n<s;n++){var a=$.trim(i[n]);""!=a&&(a=a.split(":"),t[$.trim(a[0])]=$.trim(a[1]))}return t},revertInlineCSS:function(e,t,i){for(var n=0,s=i.length;n<s;n++){var a=i[n];t[a]?e.css(a,t[a]):e.css(a,"")}},getUUID:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},base64toBlob:function(e,t,i){t=t||"",i=i||512;for(var n=atob(e),s=[],a=0;a<n.length;a+=i){for(var o=n.slice(a,a+i),r=new Array(o.length),l=0;l<o.length;l++)r[l]=o.charCodeAt(l);var c=new Uint8Array(r);s.push(c)}return new Blob(s,{type:t})},convertLegacyURL:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){for(var i=t.split(/([A-Z][a-z0-9]+)/),n="",s=0,a=i.length;s<a;s++){var o=i[s].trim();o.length&&(n.length&&(n+="-"),n+=o.toLowerCase())}return"index.php?"+n+"/&"})}}),WCF.Browser={_isChrome:null,isChrome:function(){return null===this._isChrome&&(this._isChrome=!1,/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&(this._isChrome=!0)),this._isChrome}},WCF.Dropdown={init:function(e){window.bc_wcfSimpleDropdown.initAll()},initDropdown:function(e,t){window.bc_wcfSimpleDropdown.init(e[0],t)},removeDropdown:function(e){window.bc_wcfSimpleDropdown.destroy(e)},initDropdownFragment:function(e,t){window.bc_wcfSimpleDropdown.initFragment(e[0],t[0])},registerCallback:function(e,t){window.bc_wcfSimpleDropdown.registerCallback(e,t)},_toggle:function(e,t){window.bc_wcfSimpleDropdown._toggle(e,t)},toggleDropdown:function(e,t){window.bc_wcfSimpleDropdown._toggle(null,e,null,t)},getDropdown:function(e){var t=window.bc_wcfSimpleDropdown.getDropdown(e);return t?$(t):null},getDropdownMenu:function(e){var t=window.bc_wcfSimpleDropdown.getDropdownMenu(e);return t?$(t):null},setAlignmentByID:function(e){window.bc_wcfSimpleDropdown.setAlignmentById(e)},setAlignment:function(e,t){window.bc_wcfSimpleDropdown.setAlignment(e[0],t[0])},_closeAll:function(){window.bc_wcfSimpleDropdown.closeAll()},close:function(e){window.bc_wcfSimpleDropdown.close(e)},destroy:function(e){window.bc_wcfSimpleDropdown.destroy(e)}},WCF.Dropdown.Interactive={},WCF.Dropdown.Interactive.Handler={_dropdownContainer:{},_dropdownMenus:{},create:function(){},open:function(){},close:function(){},closeAll:function(){},getOpenDropdown:function(){},getDropdown:function(){}},WCF.Dropdown.Interactive.Instance=Class.extend({_container:{},_itemList:{},_linkList:{},_options:{},_pointer:{},_triggerElement:{},init:function(){},getContainer:function(){},getItemList:function(){},getLinkList:function(){},open:function(){},close:function(){},isOpen:function(){},toggle:function(){},resetItems:function(){},render:function(){},rebuildScrollbar:function(){}}),WCF.Clipboard={init:function(){},reload:function(){}},WCF.PeriodicalExecuter=Class.extend({_callback:null,_delay:0,_intervalID:null,_isExecuting:!1,init:function(e,t){if(!$.isFunction(e))return void console.debug("[WCF.PeriodicalExecuter] Given callback is invalid, aborting.");this._callback=e,this._interval=t,this.resume()},_execute:function(){if(!this._isExecuting)try{this._isExecuting=!0,this._callback(this),this._isExecuting=!1}catch(e){throw this._isExecuting=!1,e}},stop:function(){this._intervalID&&clearInterval(this._intervalID)},resume:function(){this.restart()},restart:function(){this._intervalID&&this.stop(),this._intervalID=setInterval($.proxy(this._execute,this),this._interval)},setInterval:function(e){this._interval=e,this.restart()}}),WCF.LoadingOverlayHandler={show:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.show()})},hide:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.hide()})},updateIcon:function(e,t){var i=void 0===t||t?"addClass":"removeClass";e.find(".icon")[i]("fa-spinner"),e.hasClass("icon")&&e[i]("fa-spinner")}},WCF.Action={},WCF.Action.Proxy=Class.extend({_ajaxRequest:null,init:function(e){this._ajaxRequest=null,e=$.extend(!0,{autoSend:!1,data:{},dataType:"json",after:null,init:null,jsonp:"callback",async:!0,failure:null,showLoadingOverlay:!0,success:null,suppressErrors:!1,type:"POST",url:"index.php?ajax-proxy/&t="+SECURITY_TOKEN,aborted:null,autoAbortPrevious:!1},e),"jsonp"===e.dataType?require(["AjaxJsonp"],function(t){t.send(e.url,e.success,e.failure,{parameterName:e.jsonp})}):require(["AjaxRequest"],function(t){this._ajaxRequest=new t({data:e.data,type:e.type,url:e.url,withCredentials:e.url==="index.php?ajax-proxy/&t="+SECURITY_TOKEN,responseType:"json"===e.dataType?"application/json":"",autoAbort:e.autoAbortPrevious,ignoreError:e.suppressErrors,silent:!e.showLoadingOverlay,failure:e.failure,finalize:e.after,success:e.success}),e.autoSend&&this._ajaxRequest.sendRequest()}.bind(this))},sendRequest:function(e){require(["AjaxRequest"],function(t){null!==this._ajaxRequest&&this._ajaxRequest.sendRequest(e)}.bind(this))},abortPrevious:function(){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.abortPrevious()}.bind(this))},setOption:function(e,t){require(["AjaxRequest"],function(i){null!==this._ajaxRequest&&this._ajaxRequest.setOption(e,t)}.bind(this))},showLoadingOverlayOnce:function(){},suppressErrors:function(){},_failure:function(e,t,i){},_success:function(e,t,i){},_after:function(){}}),WCF.Action.SimpleProxy=Class.extend({init:function(e,t){this.options=$.extend(!0,{action:"",className:"",elements:null,eventName:"click"},e),this.callbacks=$.extend(!0,{after:null,failure:null,init:null,success:null},t),this.options.elements&&(this.proxy=new WCF.Action.Proxy(this.callbacks),this.options.elements.each($.proxy(function(e,t){$(t).bind(this.options.eventName,$.proxy(this._handleEvent,this))},this)))},_handleEvent:function(e){this.proxy.setOption("data",{actionName:this.options.action,className:this.options.className,objectIDs:[$(e.target).data("objectID")]}),this.proxy.sendRequest()}}),WCF.Action.Delete=Class.extend({_buttonSelector:"",_callback:null,_className:"",_containerSelector:"",_containers:[],init:function(e,t,i){this._containerSelector=t,this._className=e,this._buttonSelector=i||".jsDeleteButton",this._callback=null,this.proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initElements(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Action.Delete"+this._className.hashCode(),$.proxy(this._initElements,this))},_initElements:function(){$(this._containerSelector).each(function(e,t){var i=$(t),n=i.wcfIdentify();if(!WCF.inArray(n,this._containers)){var s=i.find(this._buttonSelector);s.length&&(this._containers.push(n),s.click($.proxy(this._click,this)))}}.bind(this))},_click:function(e){var t=$(e.currentTarget);e.preventDefault(),t.data("confirmMessageHtml")||t.data("confirmMessage")?WCF.System.Confirmation.show(t.data("confirmMessageHtml")?t.data("confirmMessageHtml"):t.data("confirmMessage"),$.proxy(this._execute,this),{target:t},void 0,!!t.data("confirmMessageHtml")):(WCF.LoadingOverlayHandler.updateIcon(t),this._sendRequest(t))},_didTriggerEffect:function(e){},_execute:function(e,t){"cancel"!==e&&(WCF.LoadingOverlayHandler.updateIcon(t.target),this._sendRequest(t.target))},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"delete",className:this._className,interfaceName:"wcf\\data\\IDeleteAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this._callback&&this._callback(e.objectIDs),this.triggerEffect(e.objectIDs)},setCallback:function(e){if("function"!=typeof e)throw new TypeError("[WCF.Action.Delete] Expected a valid callback for '"+this._className+"'.");this._callback=e},triggerEffect:function(e){this._containers.forEach(function(t){var i=$("#"+t),n=i.find(this._buttonSelector);if(WCF.inArray(n.data("objectID"),e)){var s=this;i.wcfBlindOut("up",function(){var e=$(this).remove();s._containers.splice(s._containers.indexOf(e.wcfIdentify()),1),s._didTriggerEffect(e),n.data("eventName")&&WCF.System.Event.fireEvent("com.woltlab.wcf.action.delete",n.data("eventName"),{button:n,container:e})})}}.bind(this))}}),WCF.Action.NestedDelete=WCF.Action.Delete.extend({triggerEffect:function(){},_buttonSelector:"",_callback:{},_className:"",_containerSelector:"",_containers:{},init:function(){},_initElements:function(){},_click:function(){},_didTriggerEffect:function(){},_execute:function(){},_sendRequest:function(){},_success:function(){},setCallback:function(){}}),WCF.Action.Toggle=Class.extend({_buttonSelector:"",_className:"",_containerSelector:"",_containers:{},init:function(){},_initElements:function(){},_click:function(){},_execute:function(){},_sendRequest:function(){},_success:function(){},triggerEffect:function(){},_toggleButton:function(){}}),WCF.Action.Scroll=Class.extend({_callback:null,_reference:null,_target:null,_threshold:0,init:function(e,t,i,n){return this._threshold=parseInt(e),0===this._threshold?void console.debug("[WCF.Action.Scroll] Given threshold is invalid, aborting."):($.isFunction(t)&&(this._callback=t),null===this._callback?void console.debug("[WCF.Action.Scroll] Given callback is invalid, aborting."):(this._reference=$(i||window),this._target=$(n||document),this.start(),void this._scroll()))},_scroll:function(){var e=this._target.height(),t=this._reference.scrollTop();e-(this._reference.height()+t)<this._threshold&&this._callback(this)},start:function(){this._reference.on("scroll",$.proxy(this._scroll,this))},stop:function(){this._reference.off("scroll")}}),WCF.Date={},WCF.Date.Picker={init:function(){}},WCF.Date.Util={gmdate:function(e){var t=e||new Date;return Math.round(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDay(),t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds())/1e3)},getTimezoneDate:function(e,t){var i=new Date(e),n=6e4*i.getTimezoneOffset();return new Date(e+n+t)}},WCF.Dictionary=Class.extend({_variables:{},init:function(){this._variables={}},add:function(e,t){this._variables[e]=t},addObject:function(e){for(var t in e)this.add(t,e[t])},addDictionary:function(e){e.each($.proxy(function(e){this.add(e.key,e.value)},this))},get:function(e){return this.isset(e)?this._variables[e]:null},isset:function(e){return this._variables.hasOwnProperty(e)},remove:function(e){delete this._variables[e]},each:function(e){if($.isFunction(e))for(var t in this._variables){var i=this._variables[t],n={key:t,value:i};e(n)}},count:function(){return $.getLength(this._variables)},isEmpty:function(){return!this.count()}}),null==window.WCF.Language&&(WCF.Language={add:function(e,t){require(["Language"],function(i){i.add(e,t)})},addObject:function(e){require(["Language"],function(t){t.addObject(e)})},get:function(e,t){throw new Error('Call to deprecated WCF.Language.get("'+e+'")')}}),WCF.Number={round:function(e,t){return t=Math.pow(10,t||0),Math.round(e*t)/t}},WCF.String={addThousandsSeparator:function(e){return String(e).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+WCF.Language.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(e,t){e=String(WCF.Number.round(e,t||2));var i=e.split(".");return e=this.addThousandsSeparator(i[0]),i.length>1&&(e+=WCF.Language.get("wcf.global.decimalPoint")+i[1]),e=e.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")}},WCF.TabMenu={init:function(){require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.setup()})},reload:function(){this.init()}},WCF.Template=Class.extend({init:function(e){var t=new WCF.Dictionary,i=0;e=e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n"),e=e.replace(/\{literal\}(.*?)\{\/literal\}/g,$.proxy(function(e){var i="@@@@@@@@@@@"+Math.random()+"@@@@@@@@@@@";return t.add(i,e.replace(/\{\/?literal\}/g,"")),i},this)),e=e.replace(/\{\*.*?\*\}/g,"");var n=function(e){for(var t=e.split(""),i={},n=!0,s="",a="",o=!1,r=!1,l=!1,c=0,u=t.length;c<u;c++){var h=t[c];n&&"="!=h&&" "!=h?s+=h:n&&"="==h?(n=!1,r=!1,o=!1,l=!1):n||r||o||" "!=h?n||!r||l||"'"!=h?n||r||o||"'"!=h?n||!o||l||'"'!=h?n||r||o||'"'!=h?n||!o&&!r||l||"\\"!=h?n||(l=!1,a+=h):(l=!0,a+=h):(o=!0,a+=h):(o=!1,a+=h):(r=!0,a+=h):(r=!1,a+=h):(n=!0,i[s]=a,a=s="")}if(i[s]=a,o||r||l)throw new Error('Syntax error in parameterList: "'+e+'"');return i},s=function(e){return e.replace(/\\n/g,"\n").replace(/\\\\/g,"\\").replace(/\\'/g,"'")};e=e.replace(/\{(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.escapeHTML("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{#(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.formatNumeric("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{@(\$[^\}]+?)\}/g,function(e,t){return"' + "+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+" + '"}).replace(/\{lang\}(.+?)\{\/lang\}/g,function(e,t){return"' + WCF.Language.get('"+t+"', v) + '"}).replace(/\{include (.+?)\}/g,function(e,t){t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=n(t);if(void 0===i.file)throw new Error("Missing file attribute in include-tag");return i.file=i.file.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"' + "+i.file+".fetch(v) + '"}).replace(/\{if (.+?)\}/g,function(e,t){return"';\nif ("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{else ?if (.+?)\}/g,function(e,t){return"';\n}\nelse if ("+(t=s(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{implode (.+?)\}/g,function(e,t){i++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var s=n(t);if(void 0===s.from)throw new Error("Missing from attribute in implode-tag");if(void 0===s.item)throw new Error("Missing item attribute in implode-tag");return void 0===s.glue&&(s.glue="', '"),s.from=s.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\nvar $implode_"+i+" = false;\nfor ($implodeKey_"+i+" in "+s.from+") {\n\tv["+s.item+"] = "+s.from+"[$implodeKey_"+i+"];\n"+(void 0!==s.key?"\t\tv["+s.key+"] = $implodeKey_"+i+";\n":"")+"\tif ($implode_"+i+") $output += "+s.glue+";\n\t$implode_"+i+" = true;\n\t$output += '"}).replace(/\{foreach (.+?)\}/g,function(e,t){i++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var s=n(t);if(void 0===s.from)throw new Error("Missing from attribute in foreach-tag");if(void 0===s.item)throw new Error("Missing item attribute in foreach-tag");return s.from=s.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\n$foreach_"+i+" = false;\nfor ($foreachKey_"+i+" in "+s.from+") {\n\t$foreach_"+i+" = true;\n\tbreak;\n}\nif ($foreach_"+i+") {\n\tfor ($foreachKey_"+i+" in "+s.from+") {\n\t\tv["+s.item+"] = "+s.from+"[$foreachKey_"+i+"];\n"+(void 0!==s.key?"\t\tv["+s.key+"] = $foreachKey_"+i+";\n":"")+"\t\t$output += '"}).replace(/\{foreachelse\}/g,"';\n\t}\n}\nelse {\n\t{\n\t\t$output += '").replace(/\{\/foreach\}/g,"';\n\t}\n}\n$output += '").replace(/\{else\}/g,"';\n}\nelse {\n\t$output += '").replace(/\{\/(if|implode)\}/g,"';\n}\n$output += '");for(var a in WCF.Template.callbacks)e=WCF.Template.callbacks[a](e);e=e.replace("{ldelim}","{").replace("{rdelim}","}"),t.each(function(t){e=e.replace(t.key,t.value)}),e="$output += '"+e+"';";try{this.fetch=new Function("v","v = window.$.extend({}, v, { __wcf: window.WCF, __window: window }); var $output = ''; "+e+" return $output;")}catch(t){throw console.debug("var $output = ''; "+e+" return $output;"),t}},fetch:function(e){}}),WCF.Template.callbacks=[],WCF.ToggleOptions=Class.extend({_element:null,_showItems:[],_hideItems:[],_callback:null,init:function(e,t,i,n){this._element=$("#"+e),this._showItems=t,this._hideItems=i,void 0!==n&&(this._callback=n),this._element.click($.proxy(this._toggle,this)),this._toggle()},_toggle:function(){if(this._element.prop("checked")){for(var e=0,t=this._showItems.length;e<t;e++){var i=this._showItems[e];$("#"+i).show()}for(var e=0,t=this._hideItems.length;e<t;e++){var i=this._hideItems[e];$("#"+i).hide()}null!==this._callback&&this._callback()}}}),WCF.Collapsible={},WCF.Collapsible.Simple={init:function(){$(".jsCollapsible").each($.proxy(function(e,t){this._initButton(t)},this))},_initButton:function(e){var t=$(e);t.data("isOpen")||$("#"+t.data("collapsibleContainer")).hide(),t.click($.proxy(this._toggle,this))},_toggle:function(e){var t=$(e.currentTarget),i=t.data("isOpen"),n=$("#"+$.wcfEscapeID(t.data("collapsibleContainer")));return i?(n.stop().wcfBlindOut("vertical",$.proxy(function(){this._toggleImage(t)},this)),i=!1):(n.stop().wcfBlindIn("vertical",$.proxy(function(){this._toggleImage(t)},this)),i=!0),t.data("isOpen",i),e.stopPropagation(),!1},_toggleImage:function(e){var t=e.find("span.icon");e.data("isOpen")?t.removeClass("fa-chevron-right").addClass("fa-chevron-down"):t.removeClass("fa-chevron-down").addClass("fa-chevron-right")}},WCF.Collapsible.Remote=Class.extend({_className:"",_containers:{},_containerData:{},_proxy:null,init:function(e){this._className=e,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Collapsible.Remote",$.proxy(this._init,this))},_init:function(e){this._getContainers().each($.proxy(function(e,t){var i=$(t),n=i.wcfIdentify();void 0===this._containers[n]&&(this._containers[n]=i,this._initContainer(n))},this))},_initContainer:function(e){var t=this._getTarget(e),i=this._getButtonContainer(e),n=this._createButton(e,i);this._containerData[e]={button:n,buttonContainer:i,isOpen:this._containers[e].data("isOpen"),target:t},this._containers[e].data("isOpen")||$("#"+e).addClass("jsCollapsed")},_getContainers:function(){},_getTarget:function(e){},_getButtonContainer:function(e){},_createButton:function(e,t){var i=elBySel(".jsStaticCollapsibleButton",t[0]);return null!==i&&i.parentNode===t[0]?(i.classList.remove("jsStaticCollapsibleButton"),i=$(i)):i=$('<span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-down" title="'+WCF.Language.get("wcf.global.button.collapsible")+'">').prependTo(t),i.data("containerID",e).click($.proxy(this._toggleContainer,this)),i},_toggleContainer:function(e){var t=$(e.currentTarget),i=t.data("containerID"),n=this._containerData[i].isOpen,s=n?"open":"close",a=n?"close":"open";this._proxy.setOption("data",{actionName:"loadContainer",className:this._className,interfaceName:"wcf\\data\\ILoadableContainerAction",objectIDs:[this._getObjectID(i)],parameters:$.extend(!0,{containerID:i,currentState:s,newState:a},this._getAdditionalParameters(i))}),this._proxy.sendRequest(),$("#"+i).toggleClass("jsCollapsed")},_exchangeIcon:function(e,t){t=t||"spinner",e.removeClass("fa-chevron-down fa-chevron-right fa-spinner").addClass("fa-"+t)},_getObjectID:function(e){return $("#"+e).data("objectID")},_getAdditionalParameters:function(e){return{}},_updateContent:function(e,t,i){this._containerData[e].target.html(t)},_success:function(e,t,i){if(e.returnValues.containerID){var n=e.returnValues.containerID;if(this._containers[n]){this._containerData[n].isOpen=!!e.returnValues.isOpen;var s=e.returnValues.isOpen?"open":"close";this._updateContent(n,$.trim(e.returnValues.content),s)}}}}),WCF.Collapsible.SimpleRemote=WCF.Collapsible.Remote.extend({init:function(e){this._super(e),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1})},_initContainer:function(e){this._super(e),this._containerData[e].isOpen||(this._containerData[e].target.hide(),this._exchangeIcon(this._containerData[e].button,"chevron-right"))},_toggleContainer:function(e){var t=$(e.currentTarget),i=t.data("containerID"),n=this._containerData[i].isOpen,s=n?"open":"close",a=n?"close":"open";this._proxy.setOption("data",{actionName:"toggleContainer",className:this._className,interfaceName:"wcf\\data\\IToggleContainerAction",objectIDs:[this._getObjectID(i)],parameters:$.extend(!0,{containerID:i,currentState:s,newState:a},this._getAdditionalParameters(i))}),this._proxy.sendRequest(),this._exchangeIcon(this._containerData[i].button,"open"===a?"chevron-down":"chevron-right"),"open"===a?this._containerData[i].target.show():this._containerData[i].target.hide(),$("#"+i).toggleClass("jsCollapsed"),this._containerData[i].isOpen="open"===a}}),WCF.User={userID:0,username:"",init:function(e,t){this.userID=e,this.username=t}},WCF.Effect={},WCF.Effect.Scroll=Class.extend({scrollTo:function(e,t,i){if(!e.length)return!0;var n=e.getOffsets("offset").top,s=$(document).height(),a=$(window).height();return n>s-a&&(n=s-a)<0&&(n=0),!0===i?$("html,body").scrollTop(n):$("html,body").animate({scrollTop:n},400,function(e,t,i,n,s){return-n*((t=t/s-1)*t*t*t-1)+i}),!1}}),WCF.CloseOverlayHandler={addCallback:function(e,t){require(["Ui/CloseOverlay"],function(i){i.add(e,t)})},removeCallback:function(e){require(["Ui/CloseOverlay"],function(t){t.remove(e)})},forceExecution:function(){require(["Ui/CloseOverlay"],function(e){e.execute()})}},WCF.DOMNodeInsertedHandler={addCallback:function(e,t){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.add("__legacy__",t)})},_executeCallbacks:function(){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.trigger()})},execute:function(){this._executeCallbacks()}},WCF.DOMNodeRemovedHandler={_callbacks:new WCF.Dictionary,_isExecuting:!1,_isListening:!1,addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.DOMNodeRemovedHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){if(!this._isListening){if(window.MutationObserver){new MutationObserver(function(e){var t=!1;e.forEach(function(e){e.removedNodes.length&&(t=!0)}.bind(this)),t&&this._executeCallbacks({})}.bind(this)).observe(document.body,{childList:!0,subtree:!0})}else $(document).bind("DOMNodeRemoved",$.proxy(this._executeCallbacks,this));this._isListening=!0}},_executeCallbacks:function(e){this._isExecuting||(this._isExecuting=!0,this._callbacks.each(function(t){t.value(e)}),this._isExecuting=!1)}},WCF.Option={},WCF.Option.Handler=Class.extend({init:function(){},_initOptions:function(){},_initOption:function(){},_handleChange:function(){},_change:function(){},_execute:function(){},_enableOption:function(){},_enableOptionElement:function(){},_enableOptions:function(){}}),WCF.PageVisibilityHandler={_callbacks:new WCF.Dictionary,_isListening:!1,_hiddenFieldName:"",addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.PageVisibilityHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){if(!this._isListening){var e=null;void 0!==document.hidden?(this._hiddenFieldName="hidden",e="visibilitychange"):void 0!==document.mozHidden?(this._hiddenFieldName="mozHidden",e="mozvisibilitychange"):void 0!==document.msHidden?(this._hiddenFieldName="msHidden",e="msvisibilitychange"):void 0!==document.webkitHidden&&(this._hiddenFieldName="webkitHidden",e="webkitvisibilitychange"),null===e?console.debug("[WCF.PageVisibilityHandler] This browser does not support the page visibility API."):$(document).on(e,$.proxy(this._executeCallbacks,this)),this._isListening=!0}},_executeCallbacks:function(e){if(!this._isExecuting){this._isExecuting=!0;var t=document[this._hiddenFieldName];this._callbacks.each(function(e){e.value(t)}),this._isExecuting=!1}}},WCF.Table={},WCF.Table.EmptyTableHandler=Class.extend({_options:{},_rowClassName:"",init:function(e,t,i){this._rowClassName=t,this._tableContainer=e,this._options=$.extend(!0,{emptyMessage:null,emptyMessageHtml:null,messageType:"info",refreshPage:!1,updatePageNumber:!1,isTable:0!==this._tableContainer.find("table").length},i||{}),WCF.DOMNodeRemovedHandler.addCallback("WCF.Table.EmptyTableHandler."+t,$.proxy(this._remove,this))},_getRowCount:function(){return this._tableContainer.find((this._options.isTable?"table tr.":".tabularList .")+this._rowClassName).length},_handleEmptyTable:function(){if(this._options.emptyMessage)this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).text(this._options.emptyMessage));else if(this._options.emptyMessageHtml)this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).html(this._options.emptyMessageHtml));else if(this._options.refreshPage)if(this._options.updatePageNumber){var e=window.location.href.match(/(\?|&)pageNo=(\d+)/g);if(e){var t=e[e.length-1].match(/\d+/g);this._options.updatePageNumber>0?t++:t--,window.location=window.location.href.replace(e[e.length-1],e[e.length-1][0]+"pageNo="+t)}}else window.location.reload();else this._tableContainer.remove()},_remove:function(e){if($.getLength(e)){var t=$(e.target);if(t.hasClass(this._rowClassName))if(this._options.isTable){var i=t.parents("tbody:eq(0)");1==i.children("tr").length&&this._handleEmptyTable()}else 1===this._getRowCount()&&this._handleEmptyTable()}else this._getRowCount()||this._handleEmptyTable()}}),WCF.Search={},WCF.Search.Base=Class.extend({_callback:null,_caretAt:-1,_className:"",_commaSeperated:!1,_delay:0,_excludedSearchValues:[],_itemCount:0,_itemIndex:-1,_lastValue:"",_list:null,_oldSearchString:[],_proxy:null,_searchInput:null,_triggerLength:3,_timer:null,init:function(e,t,i,n,s){return null===t||void 0===t||$.isFunction(t)?(this._callback=t||null,this._caretAt=-1,this._delay=0,this._excludedSearchValues=[],this._lastValue="",i&&(this._excludedSearchValues=i),this._searchInput=$(e),this._searchInput.length?(this._searchInput.keydown($.proxy(this._keyDown,this)).keyup($.proxy(this._keyUp,this)).wrap('<span class="dropdown" />'),$.browser.mozilla&&$.browser.touch&&this._searchInput.on("input",$.proxy(this._keyUp,this)),this._list=$('<ul class="dropdownMenu" />').insertAfter(this._searchInput),this._commaSeperated=!!n,this._oldSearchString=[],this._itemCount=0,this._itemIndex=-1,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!0===s,
-success:$.proxy(this._success,this),autoAbortPrevious:!0}),this._searchInput.is("input")&&this._searchInput.attr("autocomplete","off"),this._searchInput.blur($.proxy(this._blur,this)),void WCF.Dropdown.initDropdownFragment(this._searchInput.parent(),this._list)):void console.debug("[WCF.Search.Base] Selector '"+e+"' for search input is invalid, aborting.")):void console.debug("[WCF.Search.Base] The given callback is invalid, aborting.")},_blur:function(){var e=this;new WCF.PeriodicalExecuter(function(t){e._list.is(":visible")&&e._clearList(!1),t.stop()},250)},_keyDown:function(e){if(e.which===$.ui.keyCode.ENTER){var t=this._searchInput.parents(".dropdown");t.data("disableAutoFocus")?-1!==this._itemIndex&&e.preventDefault():(t.data("preventSubmit")||-1!==this._itemIndex)&&e.preventDefault()}},_keyUp:function(e){switch(e.which){case 37:case 39:return;case 38:return void this._selectPreviousItem();case 40:return void this._selectNextItem();case 13:return this._selectElement(e)}var t=this._getSearchString(e);if(""===t)this._clearList(!1);else if(t.length>=this._triggerLength){if(this._lastValue===t)return;this._lastValue=t;var i={data:{excludedSearchValues:this._excludedSearchValues,searchString:t}};if(this._delay){null!==this._timer&&this._timer.stop();var n=this;this._timer=new WCF.PeriodicalExecuter(function(){n._queryServer(i),n._timer.stop(),n._timer=null},this._delay)}else this._queryServer(i)}else this._clearList(!1)},_queryServer:function(e){this._searchInput.parents(".searchBar").addClass("loading"),this._proxy.setOption("data",{actionName:"getSearchResultList",className:this._className,interfaceName:"wcf\\data\\ISearchAction",parameters:this._getParameters(e)}),this._proxy.sendRequest()},setDelay:function(e){this._delay=e},_selectNextItem:function(){0!==this._itemCount&&(this._itemIndex++,this._itemIndex===this._itemCount&&(this._itemIndex=0),this._highlightSelectedElement())},_selectPreviousItem:function(){0!==this._itemCount&&(this._itemIndex--,-1===this._itemIndex&&(this._itemIndex=this._itemCount-1),this._highlightSelectedElement())},_highlightSelectedElement:function(){this._list.find("li").removeClass("dropdownNavigationItem"),this._list.find("li:eq("+this._itemIndex+")").addClass("dropdownNavigationItem")},_selectElement:function(e){return 0===this._itemCount||(this._list.find("li.dropdownNavigationItem").trigger("click"),!1)},_getSearchString:function(e){var t=$.trim(this._searchInput.val());if(this._commaSeperated){if((e.keyCode||e.which)==$.ui.keyCode.COMMA)return"";for(var i=t.split(","),n=i.length,s=0;s<n;s++)i[s]=$.trim(i[s]);for(var s=0;s<n;s++){var a=i[s];if(!this._oldSearchString[s]){t=a;break}if(a!=this._oldSearchString[s]){t=a,this._caretAt=s;break}}this._oldSearchString=i}return t},_getParameters:function(e){return e},_success:function(e,t,i){if(this._clearList(!1),this._searchInput.parents(".searchBar").removeClass("loading"),$.getLength(e.returnValues))for(var n in e.returnValues){var s=e.returnValues[n];this._createListItem(s)}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var a=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(a).hasClass("dropdownOpen")||(WCF.Dropdown.toggleDropdown(a,!0),this._openDropdown()),this._itemIndex=-1,WCF.Dropdown.getDropdown(a).data("disableAutoFocus")||this._selectNextItem()},_openDropdown:function(){},_handleEmptyResult:function(){return!1},_createListItem:function(e){var t=$("<li><span>"+WCF.String.escapeHTML(e.label)+"</span></li>").appendTo(this._list);return t.data("objectID",e.objectID).data("label",e.label).click($.proxy(this._executeCallback,this)),this._itemCount++,t},_executeCallback:function(e){var t=!1,i=$(e.currentTarget);if(this._commaSeperated){var n=i.data("label");this._oldSearchString[this._caretAt]=n,this._searchInput.val(this._oldSearchString.join(", ")),$.browser.webkit&&this._searchInput.css({display:"block"});var s=this._searchInput.val().toLowerCase().indexOf(n.toLowerCase())+n.length;this._searchInput.focus().setCaret(s)}else null===this._callback?this._searchInput.val(i.data("label")):t=!0===this._callback(i.data());this._clearList(t)},_clearList:function(e){e&&!this._commaSeperated&&this._searchInput.val(""),WCF.Dropdown.getDropdown(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),this._list.end().empty(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1},addExcludedSearchValue:function(e){WCF.inArray(e,this._excludedSearchValues)||this._excludedSearchValues.push(e)},removeExcludedSearchValue:function(e){var t=$.inArray(e,this._excludedSearchValues);-1!=t&&this._excludedSearchValues.splice(t,1)}}),WCF.Search.User=WCF.Search.Base.extend({_className:"wcf\\data\\user\\UserAction",_includeUserGroups:!1,init:function(e,t,i,n,s){this._includeUserGroups=i,this._super(e,t,n,s)},_getParameters:function(e){return e.data.includeUserGroups=this._includeUserGroups?1:0,e},_createListItem:function(e){var t=this._super(e),i=null;if(e.icon?i=$(e.icon):this._includeUserGroups&&"group"===e.type&&(i=$('<span class="icon icon16 fa-users" />')),i){var n=t.find("span").detach(),s=$("<div />").addClass("box16").appendTo(t);s.append(i),s.append($("<div />").append(n))}return t.data("type",e.type),t}}),WCF.System={},WCF.System.Dependency={},WCF.System.Dependency.Manager={_callbacks:{},_loaded:[],_setupCallbacks:{},register:function(e,t){if(!$.isFunction(t))return void console.debug("[WCF.System.Dependency.Manager] Callback for identifier '"+e+"' is invalid, aborting.");WCF.inArray(e,this._loaded)?setTimeout(function(){t()},1):(this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t))},setup:function(e,t){if(!$.isFunction(t))return void console.debug("[WCF.System.Dependency.Manager] Setup callback for identifier '"+e+"' is invalid, aborting.");this._setupCallbacks[e]||(this._setupCallbacks[e]=[]),this._setupCallbacks[e].push(t)},invoke:function(e){if(this._setupCallbacks[e]){for(var t=0,i=this._setupCallbacks[e].length;t<i;t++)this._setupCallbacks[e][t]();delete this._setupCallbacks[e]}if(this._loaded.push(e),this._callbacks[e]){for(var t=0,i=this._callbacks[e].length;t<i;t++)this._callbacks[e][t]();delete this._callbacks[e]}},reset:function(e){var t=this._loaded.indexOf(e);-1!==t&&this._loaded.splice(t,1)}},WCF.System.FlexibleMenu={init:function(){},registerMenu:function(e){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(t){t.register(e)})},rebuild:function(e){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(t){t.rebuild(e)})}},WCF.System.Mobile={},WCF.System.ObjectStore={_objects:{},add:function(e,t){void 0===this._objects[e]&&(this._objects[e]=[]),this._objects[e].push(t)},invoke:function(e,t){if(this._objects[e])for(var i=0;i<this._objects[e].length;i++)t(this._objects[e][i])}},WCF.System.Captcha={_registeredCaptchas:[],addCallback:function(e,t){require(["WoltLabSuite/Core/Controller/Captcha"],function(i){try{i.add(e,t),this._registeredCaptchas.push(e)}catch(e){if(e instanceof TypeError)return void console.debug("[WCF.System.Captcha] Given callback is no function")}}.bind(this))},getData:function(e){var t;if(-1===this._registeredCaptchas.indexOf(e))return t;var i=require("WoltLabSuite/Core/Controller/Captcha");try{t=i.getData(e)}catch(t){console.debug('[WCF.System.Captcha] Unknow captcha id "'+e+'"')}return t},removeCallback:function(e){require(["WoltLabSuite/Core/Controller/Captcha"],function(t){try{t.delete(e),this._registeredCaptchas.splice(this._registeredCaptchas.indexOf(item),1)}catch(e){}}.bind(this))}},WCF.System.Page={},WCF.System.Notification=Class.extend({_cssClassNames:"",_message:"",init:function(e,t){this._cssClassNames=t||"",this._message=e||""},show:function(e,t,i,n){require(["Ui/Notification"],function(t){t.show(i||this._message,e,n||this._cssClassNames)}.bind(this))}}),WCF.System.Confirmation={show:function(e,t,i,n,s){if("object"==typeof n){var a=$("<div />");a.append(n),n=a.html()}require(["Ui/Confirmation"],function(a){a.show({legacyCallback:t,message:e,parameters:i,template:n||"",messageIsHtml:!0===s})})}},WCF.System.DisableScrolling={_depth:0,_oldOverflow:null,disable:function(){$.browser.touch||(0===this._depth&&(this._oldOverflow=$(document.body).css("overflow"),$(document.body).css("overflow","hidden")),this._depth++)},enable:function(){0!==this._depth&&0===--this._depth&&$(document.body).css("overflow",this._oldOverflow)}},WCF.System.DisableZoom={_depth:0,_oldViewportSettings:null,disable:function(){if(0===this._depth){var e=$("meta[name=viewport]");this._oldViewportSettings=e.attr("content"),e.attr("content",this._oldViewportSettings+",maximum-scale=1")}this._depth++},enable:function(){0!==this._depth&&0===--this._depth&&$("meta[name=viewport]").attr("content",this._oldViewportSettings)}},WCF.System.Fullscreen={enterFullscreen:function(e){e.requestFullscreen?e.requestFullscreen():e.msRequestFullscreen?e.msRequestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)},toggleFullscreen:function(e){null===this.getFullscreenElement()?this.enterFullscreen(e):this.exitFullscreen()},getFullscreenElement:function(){return document.fullscreenElement?document.fullscreenElement:document.mozFullScreenElement?document.mozFullScreenElement:document.webkitFullscreenElement?document.webkitFullscreenElement:document.msFullscreenElement?document.msFullscreenElement:null},exitFullscreen:function(){document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen()},isSupported:function(){return!!(document.documentElement.requestFullscreen||document.documentElement.msRequestFullscreen||document.documentElement.mozRequestFullScreen||document.documentElement.webkitRequestFullscreen)}},WCF.System.PageNavigation={init:function(e,t){require(["WoltLabSuite/Core/Ui/Page/JumpTo"],function(i){for(var n=elBySelAll(e),s=0,a=n.length;s<a;s++)i.init(n[s],t)})}},WCF.System.KeepAlive=Class.extend({init:function(e){new WCF.PeriodicalExecuter(function(e){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"keepAlive",className:"wcf\\data\\session\\SessionAction"},failure:function(){e.stop()},showLoadingOverlay:!1,success:function(e){WCF.System.PushNotification.executeCallbacks(e)},suppressErrors:!0})},1e3*e)}}),WCF.System.PushNotification={_callbacks:{},addCallback:function(e,t){void 0===this._callbacks[e]&&(this._callbacks[e]=[]),this._callbacks[e].push(t)},executeCallbacks:function(e){for(var t in e.returnValues)if(void 0!==this._callbacks[t])for(var i=0;i<this._callbacks[t].length;i++)this._callbacks[t][i](e.returnValues[t])}},WCF.System.Event={addListener:function(e,t,i){return window.__wcf_bc_eventHandler.add(e,t,i)},removeListener:function(e,t,i){return window.__wcf_bc_eventHandler.remove(e,t,i)},removeAllListeners:function(e,t){return window.__wcf_bc_eventHandler.removeAll(e,t)},fireEvent:function(e,t,i){window.__wcf_bc_eventHandler.fire(e,t,i)}},WCF.System.Worker=Class.extend({_aborted:!1,_actionName:"",_callback:{},_className:"",_dialog:{},_proxy:{},_title:"",init:function(){},_success:function(){}}),WCF.InlineEditor=Class.extend({_callbacks:{},_dropdowns:{},_elements:{},_notification:{},_options:{},_proxy:{},_triggerElements:{},_updateData:{},init:function(){},_closeAll:function(){},_setOptions:function(){},registerCallback:function(){},_getTriggerElement:function(){},_show:function(){},_validate:function(){},_validateCallbacks:function(){},_success:function(){},_updateState:function(){},_click:function(){},_execute:function(){},_executeCallback:function(){},_hide:function(){}}),WCF.Upload=Class.extend({_name:"__files[]",_buttonSelector:null,_fileListSelector:null,_fileUpload:null,_className:"",_iframe:null,_internalFileID:0,_options:{},_uploadMatrix:[],_supportsAJAXUpload:!0,_overlay:null,init:function(e,t,i,n){this._buttonSelector=e,this._fileListSelector=t,this._className=i,this._internalFileID=0,this._options=$.extend(!0,{action:"upload",multiple:!1,url:"index.php?ajax-upload/&t="+SECURITY_TOKEN},n||{}),this._options.url=WCF.convertLegacyURL(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url);var s=new XMLHttpRequest;this._supportsAJAXUpload=s&&"upload"in s&&"onprogress"in s.upload,this._createButton()},_createButton:function(){if(this._supportsAJAXUpload){this._fileUpload=$('<input type="file" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/>"),this._fileUpload.change($.proxy(this._upload,this));var e=$('<p class="button uploadButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>");elAttr(e[0],"role","button"),e.prepend(this._fileUpload),this._fileUpload[0].addEventListener("focus",function(){this.classList.contains("focus-visible")&&e[0].classList.add("active")}),this._fileUpload[0].addEventListener("blur",function(){e[0].classList.remove("active")})}else{var e=$('<p class="button uploadFallbackButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>");elAttr(e[0],"role","button"),elAttr(e[0],"tabindex","0"),e.click($.proxy(this._showOverlay,this))}this._insertButton(e)},_insertButton:function(e){this._buttonSelector.prepend(e)},_removeButton:function(){var e=".uploadButton";this._supportsAJAXUpload||(e=".uploadFallbackButton"),this._buttonSelector.find(e).remove()},_upload:function(e,t,i,n){var s=null,a=[];if(void 0!==n)a=n;else if(t)a.push(t);else if(i){var o="";switch(i.type){case"image/png":o=".png";break;case"image/jpeg":o=".jpg";break;case"image/gif":o=".gif"}a.push({name:"pasted-from-clipboard"+o})}else a=this._fileUpload.prop("files");if(a.length){var r=new FormData;if(s=this._createUploadMatrix(a),!this._uploadMatrix[s].length)return null;for(var l=0,c=a.length;l<c;l++)if(this._uploadMatrix[s][l]){var u=this._uploadMatrix[s][l].data("internalFileID");i?r.append("__files["+u+"]",i,a[l].name):r.append("__files["+u+"]",a[l],a[l].name)}r.append("actionName",this._options.action),r.append("className",this._className);var h=this._getParameters();for(var d in h)r.append("parameters["+d+"]",h[d]);var p=this;$.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:r,contentType:!1,processData:!1,success:function(e,t,i){p._success(s,e)},error:$.proxy(this._error,this),xhr:function(){var e=$.ajaxSettings.xhr();return e&&e.upload.addEventListener("progress",function(e){p._progress(s,e)},!1),e},xhrFields:{withCredentials:!0}})}return s},_createUploadMatrix:function(e){if(e.length){var t=this._uploadMatrix.length;this._uploadMatrix[t]=[];for(var i=0,n=e.length;i<n;i++){var s=e[i],a=this._initFile(s);a.hasClass("uploadFailed")||(a.data("filename",s.name).data("internalFileID",this._internalFileID++),this._uploadMatrix[t][i]=a)}return t}return null},_success:function(e,t){},_error:function(e,t,i){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);for(var n in this._uploadMatrix[e])this._uploadMatrix[e][n].find("progress").attr("value",i)},_getParameters:function(){return{}},_initFile:function(e){return $("<li>"+e.name+" ("+e.size+')<progress max="100" /></li>').appendTo(this._fileListSelector)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix([e]),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)},_getFilename:function(){return $("#__fileUpload").val().split("\\").pop()}}),WCF.Upload.Parallel=WCF.Upload.extend({init:function(e,t,i,n){n=$.extend(!0,n||{},{multiple:!0}),this._super(e,t,i,n)},_upload:function(){for(var e=this._fileUpload.prop("files"),t=0,i=e.length;t<i;t++){var n=e[t],s=new FormData,a=this._createUploadMatrix(n);if(this._uploadMatrix[a].length){s.append("__files["+a+"]",n),s.append("actionName",this._options.action),s.append("className",this._className);var o=this._getParameters();for(var r in o)s.append("parameters["+r+"]",o[r]);this._sendRequest(a,s)}}},_sendRequest:function(e,t){var i=this;return $.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:t,contentType:!1,processData:!1,success:function(t,n,s){i._success(e,t)},error:$.proxy(this._error,this),xhr:function(){var t=$.ajaxSettings.xhr();return t&&t.upload.addEventListener("progress",function(t){i._progress(e,t)},!1),t}})},_createUploadMatrix:function(e){var t=this._initFile(e);return t.hasClass("uploadFailed")?null:(t.data("filename",e.name).data("internalFileID",this._internalFileID),this._uploadMatrix[this._internalFileID++]=t,this._internalFileID-1)},_success:function(e,t){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);this._uploadMatrix[e].find("progress").attr("value",i)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix(e),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)}}),WCF.Sortable={},WCF.Sortable.List=Class.extend({_additionalParameters:{},_className:"",_containerID:"",_container:{},_notification:{},_offset:0,_options:{},_proxy:{},_structure:{},init:function(){},_tableRowHelper:function(){},_submit:function(){},_success:function(){}}),WCF.Popover=Class.extend({_activeElementID:"",_identifier:"",_popoverObj:null,init:function(e){var t=!1;require(["Environment"],function(e){"desktop"!==e.platform()&&(t=!0)}.bind(this)),t||(this._activeElementID="",this._identifier=e,require(["WoltLabSuite/Core/Controller/Popover"],function(t){t.init({attributeName:"legacy",className:e,identifier:this._identifier,legacy:!0,loadCallback:this._legacyLoad.bind(this)})}.bind(this)))},_initContainers:function(){},_legacyLoad:function(e,t){this._activeElementID=e,this._popoverObj=t,this._loadContent()},_insertContent:function(e,t){this._popoverObj.setContent(this._identifier,e,t)}}),WCF.EditableItemList=Class.extend({_allowCustomInput:!1,_className:"",_data:{},_form:null,_itemList:null,_objectID:0,_objectTypeID:0,_search:null,_searchInput:null,init:function(e,t){if(this._itemList=$(e),this._searchInput=$(t),this._data={},!this._itemList.length||!this._searchInput.length)return void console.debug("[WCF.EditableItemList] Item list and/or search input do not exist, aborting.");if(this._objectID=this._getObjectID(),this._objectTypeID=this._getObjectTypeID(),this._itemList.find(".jsEditableItem").click($.proxy(this._click,this)),this._itemList.children("ul").length||$("<ul />").appendTo(this._itemList),this._itemList=this._itemList.children("ul"),this._form=this._itemList.parents("form").submit($.proxy(this._submit,this)),this._allowCustomInput){var i=this;this._searchInput.keydown($.proxy(this._keyDown,this)).keypress($.proxy(this._keyPress,this)).on("paste",function(){setTimeout(function(){i._onPaste()},100)})}this._searchInput.parents(".dropdown").data("preventSubmit",!0)},_keyDown:function(e){return null!==e||this._keyPress(null)},_keyPress:function(e){if(null===e||44===e.charCode||e.charCode===$.ui.keyCode.ENTER||$.browser.mozilla&&e.keyCode===$.ui.keyCode.ENTER){if(null!==e&&e.charCode===$.ui.keyCode.ENTER&&this._search&&-1!==this._search._itemIndex)return!1;var t=$.trim(this._searchInput.val());return e&&44===e.charCode&&(t=t.substring(0,this._searchInput.getCaret())),""===t?!0:(this.addItem({objectID:0,label:t}),e&&44===e.charCode?this._searchInput.val($.trim(this._searchInput.val().substr(this._searchInput.getCaret()))):this._searchInput.val(""),null!==e&&e.stopPropagation(),!1)}return!0},_onPaste:function(){var e=$.trim(this._searchInput.val());e=e.split(",");for(var t=0,i=e.length;t<i;t++){var n=$.trim(e[t]);""!==n&&this.addItem({objectID:0,label:n})}this._searchInput.val("")},load:function(e){},_click:function(e){var t=$(e.currentTarget),i=t.data("objectID"),n=t.data("label");return this._search&&this._search.removeExcludedSearchValue(n),this._removeItem(i,n),t.remove(),e.stopPropagation(),!1},_getObjectID:function(){return 0},_getObjectTypeID:function(){return 0},addItem:function(e){return!(!this._data[e.objectID]||0===e.objectID&&this._allowCustomInput)||($('<li class="badge">'+WCF.String.escapeHTML(e.label)+"</li>").data("objectID",e.objectID).data("label",e.label).appendTo(this._itemList).click($.proxy(this._click,this)),this._search&&this._search.addExcludedSearchValue(e.label),this._addItem(e.objectID,e.label),!0)},clearList:function(){this._itemList.children("li").each($.proxy(function(e,t){var i=$(t);this._search&&this._search.removeExcludedSearchValue(i.data("label")),i.remove(),this._removeItem(i.data("objectID"),i.data("label"))},this))},_submit:function(){this._keyDown(null)},_addItem:function(e,t){this._data[e]=t},_removeItem:function(e,t){delete this._data[e]},getSearchInput:function(){return this._searchInput}}),WCF.Language.Chooser=Class.extend({init:function(e,t,i,n,s,a){require(["WoltLabSuite/Core/Language/Chooser"],function(o){o.init(e,t,i,n,s,a)})}}),WCF.Style={},WCF.UserPanel=Class.extend({_container:null,_didLoad:!1,_link:null,_noItems:"",_revertOnEmpty:!0,init:function(e){if(this._container=$("#"+e),this._didLoad=!1,this._revertOnEmpty=!0,1!=this._container.length)return void console.debug("[WCF.UserPanel] Unable to find container identified by '"+e+"', aborting.");this._convert()},_convert:function(){this._container.addClass("dropdown"),this._link=this._container.children("a").remove();var e=$('<a href="'+this._link.attr("href")+'" class="dropdownToggle">'+this._link.html()+"</a>").appendTo(this._container).click($.proxy(this._click,this)),t=$('<ul class="dropdownMenu" />').appendTo(this._container);$('<li class="jsDropdownPlaceholder"><span>'+WCF.Language.get("wcf.global.loading")+"</span></li>").appendTo(t),this._addDefaultItems(t),this._container.dblclick($.proxy(function(){return window.location=this._link.attr("href"),!1},this)),WCF.Dropdown.initDropdown(e,!1)},_addDefaultItems:function(e){},_addDivider:function(e){$('<li class="dropdownDivider" />').appendTo(e)},_click:function(e){e.preventDefault(),this._didLoad||(new WCF.Action.Proxy({autoSend:!0,data:this._getParameters(),success:$.proxy(this._success,this)}),this._didLoad=!0)},_getParameters:function(){return{}},_success:function(e,t,i){var n=WCF.Dropdown.getDropdownMenu(this._container.wcfIdentify());n.children(".jsDropdownPlaceholder").remove(),e.returnValues&&e.returnValues.template?($(""+e.returnValues.template).prependTo(n),this._updateBadge(e.returnValues.totalCount),this._after(n)):($("<li><span>"+WCF.Language.get(this._noItems)+"</span></li>").prependTo(n),this._updateBadge(0))},_updateBadge:function(e){if(e=parseInt(e)||0){var t=this._container.find(".badge");t.length||(t=$('<span class="badge badgeUpdate" />').appendTo(this._container.children(".dropdownToggle")),t.before(" ")),t.html(e)}else this._container.find(".badge").remove()},_after:function(e){}}),jQuery.fn.extend({wcfDialog:function(e){var t=arguments;return require(["Dom/Util","Ui/Dialog"],function(i,n){var s=i.identify(this[0]);if("close"===e)n.close(s);else if("render"===e)n.rebuild(s);else if("option"===e)3===t.length&&("title"===t[1]&&"string"==typeof t[2]?n.setTitle(s,t[2]):0===t[1].indexOf("on")?n.setCallback(s,t[1],t[2]):"closeConfirmMessage"===t[1]&&null===t[2]&&n.setCallback(s,"onBeforeClose",null));else{this[0].parentNode.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&document.body.appendChild(this[0]);var a=1===t.length&&"object"==typeof t[0]?t[0]:{};n.openStatic(s,null,a),a.hasOwnProperty("title")&&n.setTitle(s,a.title)}}.bind(this)),this}}),$.widget("ui.wcfSlideshow",{_buttonList:null,_count:0,_index:0,_itemList:null,_items:null,_timer:null,_width:0,options:{cycle:!0,cycleInterval:5,itemGap:50},_create:function(){this._itemList=this.element.children("ul"),this._items=this._itemList.children("li"),this._count=this._items.length,this._index=0,this._count>1&&this._initSlideshow()},_initSlideshow:function(){var e=$(this._items.get(0)).outerHeight();this._items.addClass("slideshowItem"),this._width=this.element.css("height",e).innerWidth(),this._itemList.addClass("slideshowItemList").css("left",0),this._items.each($.proxy(function(t,i){$(i).show().css({height:e,left:(this._width+this.options.itemGap)*t,width:this._width})},this)),this.element.css({height:e,width:this._width}).hover($.proxy(this._hoverIn,this),$.proxy(this._hoverOut,this)),this._buttonList=$('<ul class="slideshowButtonList" />').appendTo(this.element);for(var t=0;t<this._count;t++){var i=$('<li><a><span class="icon icon16 fa-circle" /></a></li>').data("index",t).click($.proxy(this._click,this)).appendTo(this._buttonList);0==t&&i.find(".icon").addClass("active")}this._resetTimer(),$(window).resize($.proxy(this._resize,this))},rebuildHeight:function(){var e=$(this._items.get(0)).css("height","auto"),t=e.outerHeight();this._items.css("height",t+"px"),this.element.css("height",t+"px")},_resize:function(){this._width=this.element.css("width","auto").innerWidth(),this._items.each($.proxy(function(e,t){$(t).css({left:(this._width+this.options.itemGap)*e,width:this._width})},this)),this._index--,this.moveTo(null)},_hoverIn:function(){null!==this._timer&&this._timer.stop()},_hoverOut:function(){this._resetTimer()},_resetTimer:function(){if(this.options.cycle){null!==this._timer&&this._timer.stop();var e=this;this._timer=new WCF.PeriodicalExecuter(function(){e.moveTo(null)},1e3*this.options.cycleInterval)}},_click:function(e){this.moveTo($(e.currentTarget).data("index")),this._resetTimer()},moveTo:function(e){this._index=null===e?this._index+1:e,this._index==this._count&&(this._index=0),$(this._buttonList.find(".icon").removeClass("active").get(this._index)).addClass("active"),this._itemList.css("left",this._index*(this._width+this.options.itemGap)*-1),this._trigger("moveTo",null,{index:this._index})},getItem:function(e){return this._items[e]?this._items[e]:null}}),jQuery.fn.extend({datepicker:function(e){var t=this[0],i=Array.prototype.slice.call(arguments,1);switch(e){case"destroy":window.__wcf_bc_datePicker.destroy(t);break;case"getDate":return window.__wcf_bc_datePicker.getDate(t);case"option":if("onClose"===i[0])return i.length>1?this.datepicker("setOption","onClose",i[1]):function(){};console.warn("datepicker('option') supports only 'onClose'.");break;case"setDate":window.__wcf_bc_datePicker.setDate(t,i[0]);break;case"setOption":"onClose"===i[0]?window.__wcf_bc_datePicker.setCloseCallback(t,i[1]):console.warn("datepicker('setOption') supports only 'onClose'.");break;default:console.debug("Unsupported method '"+e+"' for datepicker()")}return this}}),jQuery.fn.extend({wcfTabs:function(e){var t=this[0],i=Array.prototype.slice.call(arguments,1);require(["Dom/Util","WoltLabSuite/Core/Ui/TabMenu"],function(n,s){var a=s.getTabMenu(n.identify(t));null!==a&&a[e].apply(a,i)})}}),$.widget("ui.wcfPages",{_api:null,SHOW_LINKS:11,SHOW_SUB_LINKS:20,options:{activePage:1,maxPage:1},_create:function(){require(["WoltLabSuite/Core/Ui/Pagination"],function(e){this._api=new e(this.element[0],{activePage:this.options.activePage,maxPage:this.options.maxPage,callbackShouldSwitch:function(e){return!1!==this._trigger("shouldSwitch",void 0,{nextPage:e})}.bind(this),callbackSwitch:function(e){this._trigger("switched",void 0,{activePage:e})}.bind(this)})}.bind(this))},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this._api=null,this.element[0].innerHTML=""},_setOption:function(e,t){if("activePage"==e&&t!=this.options[e]&&t>0&&t<=this.options.maxPage){var i=this._trigger("shouldSwitch",void 0,{nextPage:t});i||void 0!==i?this._api.switchPage(t):this._trigger("notSwitched",void 0,{activePage:t})}return this}}),WCF.Category={},WCF.Category.NestedList=Class.extend({_categories:{},init:function(){},_updateSelection:function(){}}),WCF.Category.FlexibleCategoryList=Class.extend({_list:{},_categories:{},init:function(){},_buildStructure:function(){},_updateSelection:function(){}}),WCF.Condition={},WCF.Notice={}; })(this);
+(function (window, undefined) { "use strict";function wcfEval(expression){return eval(expression)}!function(){var o=jQuery.fn.data;jQuery.fn.data=function(e,t){var i,n=[].slice.call(arguments);if(e)switch(typeof e){case"object":for(var s in e){s.match(/ID$/)&&(i=e[s],delete e[s],e[s=s.replace(/ID$/,"-id")]=i)}n[0]=e;break;case"string":e.match(/ID$/)&&(n[0]=e.replace(/ID$/,"-id"))}var a=o.apply(this,n);if(void 0===e)for(var s in a)s.match(/Id$/)&&(a[s.replace(/Id$/,"ID")]=a[s],delete a[s]);return a},window.console||(window.console={});for(var e=["log","info","warn","exception","assert","dir","dirxml","trace","group","groupEnd","groupCollapsed","profile","profileEnd","count","clear","time","timeEnd","timeStamp","table","error"],t=0;t<e.length;t++)void 0===console[e[t]]&&(console[e[t]]=function(){});void 0===console.debug&&(console.debug=function(e){console.log(e)})}(),window.shuffle=function(e){for(var t,i,n=e.length;0!==n;)i=Math.floor(Math.random()*n),t=e[--n],e[n]=e[i],e[i]=t;return this},function(e){var t=navigator.userAgent.toLowerCase(),i=/(chrome)[ \/]([\w.]+)/.exec(t)||/(webkit)[ \/]([\w.]+)/.exec(t)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(t)||/(msie) ([\w.]+)/.exec(t)||t.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(t)||[],n={browser:i[1]||"",version:i[2]||"0"},s={};n.browser&&(s[n.browser]=!0,s.version=n.version),s.chrome?s.webkit=!0:s.webkit&&(s.safari=!0),e.browser=e.browser||{},e.browser=$.extend(e.browser,s),e.browser.touch=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&0<window.navigator.msMaxTouchPoints,e.browser.smartphone="bottom"==$("html").css("caption-side"),e.browser.mozilla&&t.match(/trident/)&&(e.browser.mozilla=!1,e.browser.msie=!0),e.browser.iOS=/\((ipad|iphone|ipod);/.test(t),e.browser.iOS&&$("html").addClass("iOS"),e.browser.android=-1!==t.indexOf("android"),e.browser.editor="redactor",e.browser.ckeditor=!1,e.browser.redactor=!0,e.browser.iOS&&(e.fn.focus=function(e,t){return 0<arguments.length?this.on("focus",null,e,t):this.trigger("focus")})}(jQuery),null==window.WCF&&(window.WCF={}),$.extend(!0,{removeArrayValue:function(e,i){return $.grep(e,function(e,t){return i!==e})},wcfEscapeID:function(e){return e.replace(/(:|\.)/g,"\\$1")},wcfIsset:function(e){return!!$("#"+$.wcfEscapeID(e)).length},getLength:function(e){var t=0;for(var i in e)e.hasOwnProperty(i)&&t++;return t}}),$.fn.extend({getTagName:function(){return this.length?this.get(0).tagName.toLowerCase():""},getDimensions:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"inner":i={height:this.innerHeight(),width:this.innerWidth()};break;case"outer":i={height:this.outerHeight(),width:this.outerWidth()};break;default:i={height:this.height(),width:this.width()}}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},getOffsets:function(e){var t={},i={},n=!1;switch(this.is(":hidden")&&(t=WCF.getInlineCSS(this),n=!0,this.css({display:"block",visibility:"hidden"})),e){case"offset":i=this.offset();break;case"position":default:i=this.position()}return n&&WCF.revertInlineCSS(this,t,["display","visibility"]),i},makePositioned:function(e,t){"absolute"!=e&&"fixed"!=e&&(e="absolute");var i=this.getOffsets("position");return this.css({position:e,left:i.left,margin:0,top:i.top}),t&&this.remove().appentTo("body"),this},disable:function(){return this.attr("disabled","disabled")},enable:function(){return this.removeAttr("disabled")},wcfIdentify:function(){return window.bc_wcfDomUtil.identify(this[0])},getCaret:function(){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return-1}else if(!this.is("textarea"))return-1;var e,t=0,i=this.get(0);return document.selection?(this.focus(),(e=document.selection.createRange()).moveStart("character",-this.val().length),t=e.text.length):!i.selectionStart&&"0"!=i.selectionStart||(t=parseInt(i.selectionStart)),t},setCaret:function(e){if(this.is("input")){if("text"!=this.attr("type")&&"password"!=this.attr("type"))return!1}else if(!this.is("textarea"))return!1;var t,i=this.get(0);return this.focus(),document.selection?((t=document.selection.createRange()).moveStart("character",e),t.moveEnd("character",0),t.select()):!i.selectionStart&&"0"!=i.selectionStart||(i.selectionStart=e,i.selectionEnd=e),!0},wcfDropIn:function(e,t,i){return e=e||"up",i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfDropOut:function(e,t,i){return e=e||"down",i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"drop"),{direction:e},i,t)},wcfBlindIn:function(e,t,i){return e=e||"vertical",i&&parseInt(i)||(i=200),this.show(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfBlindOut:function(e,t,i){return e=e||"vertical",i&&parseInt(i)||(i=200),this.hide(WCF.getEffect(this,"blind"),{direction:e},i,t)},wcfHighlight:function(e,t){return this.effect("highlight",e,600,t)},wcfFadeIn:function(e,t){return t&&parseInt(t)||(t=200),this.show(WCF.getEffect(this,"fade"),{},t,e)},wcfFadeOut:function(e,t){return t&&parseInt(t)||(t=200),this.hide(WCF.getEffect(this,"fade"),{},t,e)},cssAsNumber:function(e){if(this.length){var t=this.css(e);if(void 0!==t)return parseInt(t.replace(/px$/,""))}return 0},perfectScrollbar:function(i){var n=require("perfect-scrollbar");return this.each(function(){var e,t;return"object"==typeof i||void 0===i?(e=i,$(this).data("psID")||n.initialize(this,e)):"update"===(t=i)?n.update(this):"destroy"===t&&n.destroy(this),jQuery(this)})}}),$.extend(WCF,{activeDialogs:0,_idCounter:0,getRandomID:function(){return window.bc_wcfDomUtil.getUniqueId()},inArray:function(e,t){return-1!=$.inArray(e,t)},getEffect:function(e,t){return e.is("tr")?"highlight":t},getInlineCSS:function(e){var t={},i=e.attr("style");if(!i)return{};for(var n=0,s=(i=i.split(";")).length;n<s;n++){var a=$.trim(i[n]);""!=a&&(a=a.split(":"),t[$.trim(a[0])]=$.trim(a[1]))}return t},revertInlineCSS:function(e,t,i){for(var n=0,s=i.length;n<s;n++){var a=i[n];t[a]?e.css(a,t[a]):e.css(a,"")}},getUUID:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},base64toBlob:function(e,t,i){t=t||"",i=i||512;for(var n=atob(e),s=[],a=0;a<n.length;a+=i){for(var o=n.slice(a,a+i),r=new Array(o.length),l=0;l<o.length;l++)r[l]=o.charCodeAt(l);var c=new Uint8Array(r);s.push(c)}return new Blob(s,{type:t})},convertLegacyURL:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){for(var i=t.split(/([A-Z][a-z0-9]+)/),n="",s=0,a=i.length;s<a;s++){var o=i[s].trim();o.length&&(n.length&&(n+="-"),n+=o.toLowerCase())}return"index.php?"+n+"/&"})}}),WCF.Browser={_isChrome:null,isChrome:function(){return null===this._isChrome&&(this._isChrome=!1,/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())&&(this._isChrome=!0)),this._isChrome}},WCF.Dropdown={init:function(e){window.bc_wcfSimpleDropdown.initAll()},initDropdown:function(e,t){window.bc_wcfSimpleDropdown.init(e[0],t)},removeDropdown:function(e){window.bc_wcfSimpleDropdown.destroy(e)},initDropdownFragment:function(e,t){window.bc_wcfSimpleDropdown.initFragment(e[0],t[0])},registerCallback:function(e,t){window.bc_wcfSimpleDropdown.registerCallback(e,t)},_toggle:function(e,t){window.bc_wcfSimpleDropdown._toggle(e,t)},toggleDropdown:function(e,t){window.bc_wcfSimpleDropdown._toggle(null,e,null,t)},getDropdown:function(e){var t=window.bc_wcfSimpleDropdown.getDropdown(e);return t?$(t):null},getDropdownMenu:function(e){var t=window.bc_wcfSimpleDropdown.getDropdownMenu(e);return t?$(t):null},setAlignmentByID:function(e){window.bc_wcfSimpleDropdown.setAlignmentById(e)},setAlignment:function(e,t){window.bc_wcfSimpleDropdown.setAlignment(e[0],t[0])},_closeAll:function(){window.bc_wcfSimpleDropdown.closeAll()},close:function(e){window.bc_wcfSimpleDropdown.close(e)},destroy:function(e){window.bc_wcfSimpleDropdown.destroy(e)}},WCF.Dropdown.Interactive={},WCF.Dropdown.Interactive.Handler={_dropdownContainer:{},_dropdownMenus:{},create:function(){},open:function(){},close:function(){},closeAll:function(){},getOpenDropdown:function(){},getDropdown:function(){}},WCF.Dropdown.Interactive.Instance=Class.extend({_container:{},_itemList:{},_linkList:{},_options:{},_pointer:{},_triggerElement:{},init:function(){},getContainer:function(){},getItemList:function(){},getLinkList:function(){},open:function(){},close:function(){},isOpen:function(){},toggle:function(){},resetItems:function(){},render:function(){},rebuildScrollbar:function(){}}),WCF.Clipboard={init:function(){},reload:function(){}},WCF.PeriodicalExecuter=Class.extend({_callback:null,_delay:0,_intervalID:null,_isExecuting:!1,init:function(e,t){$.isFunction(e)?(this._callback=e,this._interval=t,this.resume()):console.debug("[WCF.PeriodicalExecuter] Given callback is invalid, aborting.")},_execute:function(){if(!this._isExecuting)try{this._isExecuting=!0,this._callback(this),this._isExecuting=!1}catch(e){throw this._isExecuting=!1,e}},stop:function(){this._intervalID&&clearInterval(this._intervalID)},resume:function(){this.restart()},restart:function(){this._intervalID&&this.stop(),this._intervalID=setInterval($.proxy(this._execute,this),this._interval)},setInterval:function(e){this._interval=e,this.restart()}}),WCF.LoadingOverlayHandler={show:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.show()})},hide:function(){require(["WoltLabSuite/Core/Ajax/Status"],function(e){e.hide()})},updateIcon:function(e,t){var i=void 0===t||t?"addClass":"removeClass";e.find(".icon")[i]("fa-spinner"),e.hasClass("icon")&&e[i]("fa-spinner")}},WCF.Action={},WCF.Action.Proxy=Class.extend({_ajaxRequest:null,init:function(t){this._ajaxRequest=null,"jsonp"===(t=$.extend(!0,{autoSend:!1,data:{},dataType:"json",after:null,init:null,jsonp:"callback",async:!0,failure:null,showLoadingOverlay:!0,success:null,suppressErrors:!1,type:"POST",url:"index.php?ajax-proxy/&t="+SECURITY_TOKEN,aborted:null,autoAbortPrevious:!1},t)).dataType?require(["AjaxJsonp"],function(e){e.send(t.url,t.success,t.failure,{parameterName:t.jsonp})}):require(["AjaxRequest"],function(e){this._ajaxRequest=new e({data:t.data,type:t.type,url:t.url,withCredentials:t.url==="index.php?ajax-proxy/&t="+SECURITY_TOKEN,responseType:"json"===t.dataType?"application/json":"",autoAbort:t.autoAbortPrevious,ignoreError:t.suppressErrors,silent:!t.showLoadingOverlay,failure:t.failure,finalize:t.after,success:t.success}),t.autoSend&&this._ajaxRequest.sendRequest()}.bind(this))},sendRequest:function(t){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.sendRequest(t)}.bind(this))},abortPrevious:function(){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.abortPrevious()}.bind(this))},setOption:function(t,i){require(["AjaxRequest"],function(e){null!==this._ajaxRequest&&this._ajaxRequest.setOption(t,i)}.bind(this))},showLoadingOverlayOnce:function(){},suppressErrors:function(){},_failure:function(e,t,i){},_success:function(e,t,i){},_after:function(){}}),WCF.Action.SimpleProxy=Class.extend({init:function(e,t){this.options=$.extend(!0,{action:"",className:"",elements:null,eventName:"click"},e),this.callbacks=$.extend(!0,{after:null,failure:null,init:null,success:null},t),this.options.elements&&(this.proxy=new WCF.Action.Proxy(this.callbacks),this.options.elements.each($.proxy(function(e,t){$(t).bind(this.options.eventName,$.proxy(this._handleEvent,this))},this)))},_handleEvent:function(e){this.proxy.setOption("data",{actionName:this.options.action,className:this.options.className,objectIDs:[$(e.target).data("objectID")]}),this.proxy.sendRequest()}}),WCF.Action.Delete=Class.extend({_buttonSelector:"",_callback:null,_className:"",_containerSelector:"",_containers:[],init:function(e,t,i){this._containerSelector=t,this._className=e,this._buttonSelector=i||".jsDeleteButton",this._callback=null,this.proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initElements(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Action.Delete"+this._className.hashCode(),$.proxy(this._initElements,this))},_initElements:function(){$(this._containerSelector).each(function(e,t){var i,n=$(t),s=n.wcfIdentify();WCF.inArray(s,this._containers)||(i=n.find(this._buttonSelector)).length&&(this._containers.push(s),i.click($.proxy(this._click,this)))}.bind(this))},_click:function(e){var t=$(e.currentTarget);e.preventDefault(),t.data("confirmMessageHtml")||t.data("confirmMessage")?WCF.System.Confirmation.show(t.data("confirmMessageHtml")?t.data("confirmMessageHtml"):t.data("confirmMessage"),$.proxy(this._execute,this),{target:t},void 0,!!t.data("confirmMessageHtml")):(WCF.LoadingOverlayHandler.updateIcon(t),this._sendRequest(t))},_didTriggerEffect:function(e){},_execute:function(e,t){"cancel"!==e&&(WCF.LoadingOverlayHandler.updateIcon(t.target),this._sendRequest(t.target))},_sendRequest:function(e){this.proxy.setOption("data",{actionName:"delete",className:this._className,interfaceName:"wcf\\data\\IDeleteAction",objectIDs:[$(e).data("objectID")]}),this.proxy.sendRequest()},_success:function(e,t,i){this._callback&&this._callback(e.objectIDs),this.triggerEffect(e.objectIDs)},setCallback:function(e){if("function"!=typeof e)throw new TypeError("[WCF.Action.Delete] Expected a valid callback for '"+this._className+"'.");this._callback=e},triggerEffect:function(s){this._containers.forEach(function(e){var t,i=$("#"+e),n=i.find(this._buttonSelector);WCF.inArray(n.data("objectID"),s)&&(t=this,i.wcfBlindOut("up",function(){var e=$(this).remove();t._containers.splice(t._containers.indexOf(e.wcfIdentify()),1),t._didTriggerEffect(e),n.data("eventName")&&WCF.System.Event.fireEvent("com.woltlab.wcf.action.delete",n.data("eventName"),{button:n,container:e})}))}.bind(this))}}),WCF.Action.NestedDelete=WCF.Action.Delete.extend({triggerEffect:function(){},_buttonSelector:"",_callback:{},_className:"",_containerSelector:"",_containers:{},init:function(){},_initElements:function(){},_click:function(){},_didTriggerEffect:function(){},_execute:function(){},_sendRequest:function(){},_success:function(){},setCallback:function(){}}),WCF.Action.Toggle=Class.extend({_buttonSelector:"",_className:"",_containerSelector:"",_containers:{},init:function(){},_initElements:function(){},_click:function(){},_execute:function(){},_sendRequest:function(){},_success:function(){},triggerEffect:function(){},_toggleButton:function(){}}),WCF.Action.Scroll=Class.extend({_callback:null,_reference:null,_target:null,_threshold:0,init:function(e,t,i,n){this._threshold=parseInt(e),0!==this._threshold?($.isFunction(t)&&(this._callback=t),null!==this._callback?(this._reference=$(i||window),this._target=$(n||document),this.start(),this._scroll()):console.debug("[WCF.Action.Scroll] Given callback is invalid, aborting.")):console.debug("[WCF.Action.Scroll] Given threshold is invalid, aborting.")},_scroll:function(){var e=this._target.height(),t=this._reference.scrollTop();e-(this._reference.height()+t)<this._threshold&&this._callback(this)},start:function(){this._reference.on("scroll",$.proxy(this._scroll,this))},stop:function(){this._reference.off("scroll")}}),WCF.Date={},WCF.Date.Picker={init:function(){}},WCF.Date.Util={gmdate:function(e){var t=e||new Date;return Math.round(Date.UTC(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDay(),t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds())/1e3)},getTimezoneDate:function(e,t){var i=6e4*new Date(e).getTimezoneOffset();return new Date(e+i+t)}},WCF.Dictionary=Class.extend({_variables:{},init:function(){this._variables={}},add:function(e,t){this._variables[e]=t},addObject:function(e){for(var t in e)this.add(t,e[t])},addDictionary:function(e){e.each($.proxy(function(e){this.add(e.key,e.value)},this))},get:function(e){return this.isset(e)?this._variables[e]:null},isset:function(e){return this._variables.hasOwnProperty(e)},remove:function(e){delete this._variables[e]},each:function(e){if($.isFunction(e))for(var t in this._variables){e({key:t,value:this._variables[t]})}},count:function(){return $.getLength(this._variables)},isEmpty:function(){return!this.count()}}),null==window.WCF.Language&&(WCF.Language={add:function(t,i){require(["Language"],function(e){e.add(t,i)})},addObject:function(t){require(["Language"],function(e){e.addObject(t)})},get:function(e,t){throw new Error('Call to deprecated WCF.Language.get("'+e+'")')}}),WCF.Number={round:function(e,t){return t=Math.pow(10,t||0),Math.round(e*t)/t}},WCF.String={addThousandsSeparator:function(e){return String(e).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+WCF.Language.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(e,t){var i=(e=String(WCF.Number.round(e,t||2))).split(".");return e=this.addThousandsSeparator(i[0]),1<i.length&&(e+=WCF.Language.get("wcf.global.decimalPoint")+i[1]),e=e.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")}},WCF.TabMenu={init:function(){require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.setup()})},reload:function(){this.init()}},WCF.Template=Class.extend({init:function(t){var i=new WCF.Dictionary,n=0;t=(t=(t=t.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n")).replace(/\{literal\}(.*?)\{\/literal\}/g,$.proxy(function(e){var t="@@@@@@@@@@@"+Math.random()+"@@@@@@@@@@@";return i.add(t,e.replace(/\{\/?literal\}/g,"")),t},this))).replace(/\{\*.*?\*\}/g,"");function s(e){for(var t=e.split(""),i={},n=!0,s="",a="",o=!1,r=!1,l=!1,c=0,u=t.length;c<u;c++){var h=t[c];n&&"="!=h&&" "!=h?s+=h:n&&"="==h?l=o=r=n=!1:n||r||o||" "!=h?n||!r||l||"'"!=h?n||r||o||"'"!=h?n||!o||l||'"'!=h?n||r||o||'"'!=h?n||!o&&!r||l||"\\"!=h?n||(l=!1,a+=h):(l=!0,a+=h):(o=!0,a+=h):(o=!1,a+=h):(r=!0,a+=h):(r=!1,a+=h):(n=!0,i[s]=a,a=s="")}if(i[s]=a,o||r||l)throw new Error('Syntax error in parameterList: "'+e+'"');return i}function a(e){return e.replace(/\\n/g,"\n").replace(/\\\\/g,"\\").replace(/\\'/g,"'")}for(var e in t=t.replace(/\{(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.escapeHTML("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{#(\$[^\}]+?)\}/g,function(e,t){return"' + WCF.String.formatNumeric("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") + '"}).replace(/\{@(\$[^\}]+?)\}/g,function(e,t){return"' + "+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+" + '"}).replace(/\{lang\}(.+?)\{\/lang\}/g,function(e,t){return"' + WCF.Language.get('"+t+"', v) + '"}).replace(/\{include (.+?)\}/g,function(e,t){t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=s(t);if(void 0===i.file)throw new Error("Missing file attribute in include-tag");return i.file=i.file.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"' + "+i.file+".fetch(v) + '"}).replace(/\{if (.+?)\}/g,function(e,t){return"';\nif ("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{else ?if (.+?)\}/g,function(e,t){return"';\n}\nelse if ("+(t=a(t.replace(/\$([^.\[\(\)\]\s]+)/g,"(v['$1'])")))+") {\n\t$output += '"}).replace(/\{implode (.+?)\}/g,function(e,t){n++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=s(t);if(void 0===i.from)throw new Error("Missing from attribute in implode-tag");if(void 0===i.item)throw new Error("Missing item attribute in implode-tag");return void 0===i.glue&&(i.glue="', '"),i.from=i.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\nvar $implode_"+n+" = false;\nfor ($implodeKey_"+n+" in "+i.from+") {\n\tv["+i.item+"] = "+i.from+"[$implodeKey_"+n+"];\n"+(void 0!==i.key?"\t\tv["+i.key+"] = $implodeKey_"+n+";\n":"")+"\tif ($implode_"+n+") $output += "+i.glue+";\n\t$implode_"+n+" = true;\n\t$output += '"}).replace(/\{foreach (.+?)\}/g,function(e,t){n++,t=t.replace(/\\\\/g,"\\").replace(/\\'/g,"'");var i=s(t);if(void 0===i.from)throw new Error("Missing from attribute in foreach-tag");if(void 0===i.item)throw new Error("Missing item attribute in foreach-tag");return i.from=i.from.replace(/\$([^.\[\(\)\]\s]+)/g,"(v.$1)"),"';\n$foreach_"+n+" = false;\nfor ($foreachKey_"+n+" in "+i.from+") {\n\t$foreach_"+n+" = true;\n\tbreak;\n}\nif ($foreach_"+n+") {\n\tfor ($foreachKey_"+n+" in "+i.from+") {\n\t\tv["+i.item+"] = "+i.from+"[$foreachKey_"+n+"];\n"+(void 0!==i.key?"\t\tv["+i.key+"] = $foreachKey_"+n+";\n":"")+"\t\t$output += '"}).replace(/\{foreachelse\}/g,"';\n\t}\n}\nelse {\n\t{\n\t\t$output += '").replace(/\{\/foreach\}/g,"';\n\t}\n}\n$output += '").replace(/\{else\}/g,"';\n}\nelse {\n\t$output += '").replace(/\{\/(if|implode)\}/g,"';\n}\n$output += '"),WCF.Template.callbacks)t=WCF.Template.callbacks[e](t);t=t.replace("{ldelim}","{").replace("{rdelim}","}"),i.each(function(e){t=t.replace(e.key,e.value)}),t="$output += '"+t+"';";try{this.fetch=new Function("v","v = window.$.extend({}, v, { __wcf: window.WCF, __window: window }); var $output = ''; "+t+" return $output;")}catch(e){throw console.debug("var $output = ''; "+t+" return $output;"),e}},fetch:function(e){}}),WCF.Template.callbacks=[],WCF.ToggleOptions=Class.extend({_element:null,_showItems:[],_hideItems:[],_callback:null,init:function(e,t,i,n){this._element=$("#"+e),this._showItems=t,this._hideItems=i,void 0!==n&&(this._callback=n),this._element.click($.proxy(this._toggle,this)),this._toggle()},_toggle:function(){if(this._element.prop("checked")){for(var e=0,t=this._showItems.length;e<t;e++){var i=this._showItems[e];$("#"+i).show()}for(e=0,t=this._hideItems.length;e<t;e++){i=this._hideItems[e];$("#"+i).hide()}null!==this._callback&&this._callback()}}}),WCF.Collapsible={},WCF.Collapsible.Simple={init:function(){$(".jsCollapsible").each($.proxy(function(e,t){this._initButton(t)},this))},_initButton:function(e){var t=$(e);t.data("isOpen")||$("#"+t.data("collapsibleContainer")).hide(),t.click($.proxy(this._toggle,this))},_toggle:function(e){var t=$(e.currentTarget),i=t.data("isOpen"),n=$("#"+$.wcfEscapeID(t.data("collapsibleContainer"))),i=i?(n.stop().wcfBlindOut("vertical",$.proxy(function(){this._toggleImage(t)},this)),!1):(n.stop().wcfBlindIn("vertical",$.proxy(function(){this._toggleImage(t)},this)),!0);return t.data("isOpen",i),e.stopPropagation(),!1},_toggleImage:function(e){var t=e.find("span.icon");e.data("isOpen")?t.removeClass("fa-chevron-right").addClass("fa-chevron-down"):t.removeClass("fa-chevron-down").addClass("fa-chevron-right")}},WCF.Collapsible.Remote=Class.extend({_className:"",_containers:{},_containerData:{},_proxy:null,init:function(e){this._className=e,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Collapsible.Remote",$.proxy(this._init,this))},_init:function(e){this._getContainers().each($.proxy(function(e,t){var i=$(t),n=i.wcfIdentify();void 0===this._containers[n]&&(this._containers[n]=i,this._initContainer(n))},this))},_initContainer:function(e){var t=this._getTarget(e),i=this._getButtonContainer(e),n=this._createButton(e,i);this._containerData[e]={button:n,buttonContainer:i,isOpen:this._containers[e].data("isOpen"),target:t},this._containers[e].data("isOpen")||$("#"+e).addClass("jsCollapsed")},_getContainers:function(){},_getTarget:function(e){},_getButtonContainer:function(e){},_createButton:function(e,t){var i=elBySel(".jsStaticCollapsibleButton",t[0]);return(i=null!==i&&i.parentNode===t[0]?(i.classList.remove("jsStaticCollapsibleButton"),$(i)):$('<span class="collapsibleButton jsTooltip pointer icon icon16 fa-chevron-down" title="'+WCF.Language.get("wcf.global.button.collapsible")+'">').prependTo(t)).data("containerID",e).click($.proxy(this._toggleContainer,this)),i},_toggleContainer:function(e){var t=$(e.currentTarget).data("containerID"),i=this._containerData[t].isOpen,n=i?"open":"close",s=i?"close":"open";this._proxy.setOption("data",{actionName:"loadContainer",className:this._className,interfaceName:"wcf\\data\\ILoadableContainerAction",objectIDs:[this._getObjectID(t)],parameters:$.extend(!0,{containerID:t,currentState:n,newState:s},this._getAdditionalParameters(t))}),this._proxy.sendRequest(),$("#"+t).toggleClass("jsCollapsed")},_exchangeIcon:function(e,t){t=t||"spinner",e.removeClass("fa-chevron-down fa-chevron-right fa-spinner").addClass("fa-"+t)},_getObjectID:function(e){return $("#"+e).data("objectID")},_getAdditionalParameters:function(e){return{}},_updateContent:function(e,t,i){this._containerData[e].target.html(t)},_success:function(e,t,i){var n,s;e.returnValues.containerID&&(n=e.returnValues.containerID,this._containers[n]&&(this._containerData[n].isOpen=!!e.returnValues.isOpen,s=e.returnValues.isOpen?"open":"close",this._updateContent(n,$.trim(e.returnValues.content),s)))}}),WCF.Collapsible.SimpleRemote=WCF.Collapsible.Remote.extend({init:function(e){this._super(e),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1})},_initContainer:function(e){this._super(e),this._containerData[e].isOpen||(this._containerData[e].target.hide(),this._exchangeIcon(this._containerData[e].button,"chevron-right"))},_toggleContainer:function(e){var t=$(e.currentTarget).data("containerID"),i=this._containerData[t].isOpen,n=i?"open":"close",s=i?"close":"open";this._proxy.setOption("data",{actionName:"toggleContainer",className:this._className,interfaceName:"wcf\\data\\IToggleContainerAction",objectIDs:[this._getObjectID(t)],parameters:$.extend(!0,{containerID:t,currentState:n,newState:s},this._getAdditionalParameters(t))}),this._proxy.sendRequest(),this._exchangeIcon(this._containerData[t].button,"open"==s?"chevron-down":"chevron-right"),"open"==s?this._containerData[t].target.show():this._containerData[t].target.hide(),$("#"+t).toggleClass("jsCollapsed"),this._containerData[t].isOpen="open"==s}}),WCF.User={userID:0,username:"",init:function(e,t){this.userID=e,this.username=t}},WCF.Effect={},WCF.Effect.Scroll=Class.extend({scrollTo:function(e,t,i){if(!e.length)return!0;var n=e.getOffsets("offset").top,s=$(document).height(),a=$(window).height();return s-a<n&&(n=s-a)<0&&(n=0),!0===i?$("html,body").scrollTop(n):$("html,body").animate({scrollTop:n},400,function(e,t,i,n,s){return-n*((t=t/s-1)*t*t*t-1)+i}),!1}}),WCF.CloseOverlayHandler={addCallback:function(t,i){require(["Ui/CloseOverlay"],function(e){e.add(t,i)})},removeCallback:function(t){require(["Ui/CloseOverlay"],function(e){e.remove(t)})},forceExecution:function(){require(["Ui/CloseOverlay"],function(e){e.execute()})}},WCF.DOMNodeInsertedHandler={addCallback:function(e,t){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.add("__legacy__",t)})},_executeCallbacks:function(){require(["WoltLabSuite/Core/Dom/Change/Listener"],function(e){e.trigger()})},execute:function(){this._executeCallbacks()}},WCF.DOMNodeRemovedHandler={_callbacks:new WCF.Dictionary,_isExecuting:!1,_isListening:!1,addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.DOMNodeRemovedHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){this._isListening||(window.MutationObserver?new MutationObserver(function(e){var t=!1;e.forEach(function(e){e.removedNodes.length&&(t=!0)}.bind(this)),t&&this._executeCallbacks({})}.bind(this)).observe(document.body,{childList:!0,subtree:!0}):$(document).bind("DOMNodeRemoved",$.proxy(this._executeCallbacks,this)),this._isListening=!0)},_executeCallbacks:function(t){this._isExecuting||(this._isExecuting=!0,this._callbacks.each(function(e){e.value(t)}),this._isExecuting=!1)}},WCF.Option={},WCF.Option.Handler=Class.extend({init:function(){},_initOptions:function(){},_initOption:function(){},_handleChange:function(){},_change:function(){},_execute:function(){},_enableOption:function(){},_enableOptionElement:function(){},_enableOptions:function(){}}),WCF.PageVisibilityHandler={_callbacks:new WCF.Dictionary,_isListening:!1,_hiddenFieldName:"",addCallback:function(e,t){if(this._bindListener(),this._callbacks.isset(e))return console.debug("[WCF.PageVisibilityHandler] identifier '"+e+"' is already bound to a callback"),!1;this._callbacks.add(e,t)},removeCallback:function(e){this._callbacks.isset(e)&&this._callbacks.remove(e)},_bindListener:function(){var e;this._isListening||(e=null,void 0!==document.hidden?(this._hiddenFieldName="hidden",e="visibilitychange"):void 0!==document.mozHidden?(this._hiddenFieldName="mozHidden",e="mozvisibilitychange"):void 0!==document.msHidden?(this._hiddenFieldName="msHidden",e="msvisibilitychange"):void 0!==document.webkitHidden&&(this._hiddenFieldName="webkitHidden",e="webkitvisibilitychange"),null===e?console.debug("[WCF.PageVisibilityHandler] This browser does not support the page visibility API."):$(document).on(e,$.proxy(this._executeCallbacks,this)),this._isListening=!0)},_executeCallbacks:function(e){var t;this._isExecuting||(this._isExecuting=!0,t=document[this._hiddenFieldName],this._callbacks.each(function(e){e.value(t)}),this._isExecuting=!1)}},WCF.Table={},WCF.Table.EmptyTableHandler=Class.extend({_options:{},_rowClassName:"",init:function(e,t,i){this._rowClassName=t,this._tableContainer=e,this._options=$.extend(!0,{emptyMessage:null,emptyMessageHtml:null,messageType:"info",refreshPage:!1,updatePageNumber:!1,isTable:0!==this._tableContainer.find("table").length},i||{}),WCF.DOMNodeRemovedHandler.addCallback("WCF.Table.EmptyTableHandler."+t,$.proxy(this._remove,this))},_getRowCount:function(){return this._tableContainer.find((this._options.isTable?"table tr.":".tabularList .")+this._rowClassName).length},_handleEmptyTable:function(){var e,t;this._options.emptyMessage?this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).text(this._options.emptyMessage)):this._options.emptyMessageHtml?this._tableContainer.replaceWith($("<p />").addClass(this._options.messageType).html(this._options.emptyMessageHtml)):this._options.refreshPage?this._options.updatePageNumber?(e=window.location.href.match(/(\?|&)pageNo=(\d+)/g))&&(t=e[e.length-1].match(/\d+/g),0<this._options.updatePageNumber?t++:t--,window.location=window.location.href.replace(e[e.length-1],e[e.length-1][0]+"pageNo="+t)):window.location.reload():this._tableContainer.remove()},_remove:function(e){var t;$.getLength(e)?(t=$(e.target)).hasClass(this._rowClassName)&&(this._options.isTable?1==t.parents("tbody:eq(0)").children("tr").length&&this._handleEmptyTable():1===this._getRowCount()&&this._handleEmptyTable()):this._getRowCount()||this._handleEmptyTable()}}),WCF.Search={},WCF.Search.Base=Class.extend({_callback:null,_caretAt:-1,_className:"",_commaSeperated:!1,_delay:0,_excludedSearchValues:[],_itemCount:0,_itemIndex:-1,_lastValue:"",_list:null,_oldSearchString:[],_proxy:null,_searchInput:null,_triggerLength:3,_timer:null,init:function(e,t,i,n,s){null==t||$.isFunction(t)?(this._callback=t||null,this._caretAt=-1,this._delay=0,this._excludedSearchValues=[],this._lastValue="",i&&(this._excludedSearchValues=i),this._searchInput=$(e),this._searchInput.length?(this._searchInput.keydown($.proxy(this._keyDown,this)).keyup($.proxy(this._keyUp,this)).wrap('<span class="dropdown" />'),$.browser.mozilla&&$.browser.touch&&this._searchInput.on("input",$.proxy(this._keyUp,this)),this._list=$('<ul class="dropdownMenu" />').insertAfter(this._searchInput),this._commaSeperated=!!n,this._oldSearchString=[],this._itemCount=0,this._itemIndex=-1,this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!0===s,success:$.proxy(this._success,this),autoAbortPrevious:!0}),this._searchInput.is("input")&&this._searchInput.attr("autocomplete","off"),this._searchInput.blur($.proxy(this._blur,this)),WCF.Dropdown.initDropdownFragment(this._searchInput.parent(),this._list)):console.debug("[WCF.Search.Base] Selector '"+e+"' for search input is invalid, aborting.")):console.debug("[WCF.Search.Base] The given callback is invalid, aborting.")},_blur:function(){var t=this;new WCF.PeriodicalExecuter(function(e){t._list.is(":visible")&&t._clearList(!1),e.stop()},250)},_keyDown:function(e){var t;e.which===$.ui.keyCode.ENTER&&((t=this._searchInput.parents(".dropdown")).data("disableAutoFocus")?-1!==this._itemIndex&&e.preventDefault():!t.data("preventSubmit")&&-1===this._itemIndex||e.preventDefault())},_keyUp:function(e){switch(e.which){case 37:case 39:return;case 38:return void this._selectPreviousItem();case 40:return void this._selectNextItem();case 13:return this._selectElement(e)}var t=this._getSearchString(e);if(""===t)this._clearList(!1);else if(t.length>=this._triggerLength){if(this._lastValue===t)return;this._lastValue=t;var i,n={data:{excludedSearchValues:this._excludedSearchValues,searchString:t}};this._delay?(null!==this._timer&&this._timer.stop(),(i=this)._timer=new WCF.PeriodicalExecuter(function(){i._queryServer(n),i._timer.stop(),i._timer=null},this._delay)):this._queryServer(n)}else this._clearList(!1)},_queryServer:function(e){this._searchInput.parents(".searchBar").addClass("loading"),this._proxy.setOption("data",{actionName:"getSearchResultList",className:this._className,interfaceName:"wcf\\data\\ISearchAction",parameters:this._getParameters(e)}),this._proxy.sendRequest()},setDelay:function(e){this._delay=e},_selectNextItem:function(){0!==this._itemCount&&(this._itemIndex++,this._itemIndex===this._itemCount&&(this._itemIndex=0),this._highlightSelectedElement())},_selectPreviousItem:function(){0!==this._itemCount&&(this._itemIndex--,-1===this._itemIndex&&(this._itemIndex=this._itemCount-1),this._highlightSelectedElement())},_highlightSelectedElement:function(){this._list.find("li").removeClass("dropdownNavigationItem"),this._list.find("li:eq("+this._itemIndex+")").addClass("dropdownNavigationItem")},_selectElement:function(e){return 0===this._itemCount||(this._list.find("li.dropdownNavigationItem").trigger("click"),!1)},_getSearchString:function(e){var t=$.trim(this._searchInput.val());if(this._commaSeperated){if((e.keyCode||e.which)==$.ui.keyCode.COMMA)return"";for(var i=t.split(","),n=i.length,s=0;s<n;s++)i[s]=$.trim(i[s]);for(s=0;s<n;s++){var a=i[s];if(!this._oldSearchString[s]){t=a;break}if(a!=this._oldSearchString[s]){t=a,this._caretAt=s;break}}this._oldSearchString=i}return t},_getParameters:function(e){return e},_success:function(e,t,i){if(this._clearList(!1),this._searchInput.parents(".searchBar").removeClass("loading"),$.getLength(e.returnValues))for(var n in e.returnValues){var s=e.returnValues[n];this._createListItem(s)}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var a=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(a).hasClass("dropdownOpen")||(WCF.Dropdown.toggleDropdown(a,!0),this._openDropdown()),this._itemIndex=-1,WCF.Dropdown.getDropdown(a).data("disableAutoFocus")||this._selectNextItem()},_openDropdown:function(){},_handleEmptyResult:function(){return!1},_createListItem:function(e){var t=$("<li><span>"+WCF.String.escapeHTML(e.label)+"</span></li>").appendTo(this._list);return t.data("objectID",e.objectID).data("label",e.label).click($.proxy(this._executeCallback,this)),this._itemCount++,t},_executeCallback:function(e){var t,i,n=!1,s=$(e.currentTarget);this._commaSeperated?(t=s.data("label"),this._oldSearchString[this._caretAt]=t,this._searchInput.val(this._oldSearchString.join(", ")),$.browser.webkit&&this._searchInput.css({display:"block"}),i=this._searchInput.val().toLowerCase().indexOf(t.toLowerCase())+t.length,this._searchInput.focus().setCaret(i)):null===this._callback?this._searchInput.val(s.data("label")):n=!0===this._callback(s.data()),this._clearList(n)},_clearList:function(e){e&&!this._commaSeperated&&this._searchInput.val(""),WCF.Dropdown.getDropdown(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify()).removeClass("dropdownOpen"),this._list.end().empty(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1},addExcludedSearchValue:function(e){WCF.inArray(e,this._excludedSearchValues)||this._excludedSearchValues.push(e)},removeExcludedSearchValue:function(e){var t=$.inArray(e,this._excludedSearchValues);-1!=t&&this._excludedSearchValues.splice(t,1)}}),WCF.Search.User=WCF.Search.Base.extend({_className:"wcf\\data\\user\\UserAction",_includeUserGroups:!1,init:function(e,t,i,n,s){this._includeUserGroups=i,this._super(e,t,n,s)},_getParameters:function(e){return e.data.includeUserGroups=this._includeUserGroups?1:0,e},_createListItem:function(e){var t,i,n=this._super(e),s=null;return e.icon?s=$(e.icon):this._includeUserGroups&&"group"===e.type&&(s=$('<span class="icon icon16 fa-users" />')),s&&(t=n.find("span").detach(),(i=$("<div />").addClass("box16").appendTo(n)).append(s),i.append($("<div />").append(t))),n.data("type",e.type),n}}),WCF.System={},WCF.System.Dependency={},WCF.System.Dependency.Manager={_callbacks:{},_loaded:[],_setupCallbacks:{},register:function(e,t){$.isFunction(t)?WCF.inArray(e,this._loaded)?setTimeout(function(){t()},1):(this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t)):console.debug("[WCF.System.Dependency.Manager] Callback for identifier '"+e+"' is invalid, aborting.")},setup:function(e,t){$.isFunction(t)?(this._setupCallbacks[e]||(this._setupCallbacks[e]=[]),this._setupCallbacks[e].push(t)):console.debug("[WCF.System.Dependency.Manager] Setup callback for identifier '"+e+"' is invalid, aborting.")},invoke:function(e){if(this._setupCallbacks[e]){for(var t=0,i=this._setupCallbacks[e].length;t<i;t++)this._setupCallbacks[e][t]();delete this._setupCallbacks[e]}if(this._loaded.push(e),this._callbacks[e]){for(t=0,i=this._callbacks[e].length;t<i;t++)this._callbacks[e][t]();delete this._callbacks[e]}},reset:function(e){var t=this._loaded.indexOf(e);-1!==t&&this._loaded.splice(t,1)}},WCF.System.FlexibleMenu={init:function(){},registerMenu:function(t){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(e){e.register(t)})},rebuild:function(t){require(["WoltLabSuite/Core/Ui/FlexibleMenu"],function(e){e.rebuild(t)})}},WCF.System.Mobile={},WCF.System.ObjectStore={_objects:{},add:function(e,t){void 0===this._objects[e]&&(this._objects[e]=[]),this._objects[e].push(t)},invoke:function(e,t){if(this._objects[e])for(var i=0;i<this._objects[e].length;i++)t(this._objects[e][i])}},WCF.System.Captcha={_registeredCaptchas:[],addCallback:function(t,i){require(["WoltLabSuite/Core/Controller/Captcha"],function(e){try{e.add(t,i),this._registeredCaptchas.push(t)}catch(e){if(e instanceof TypeError)return void console.debug("[WCF.System.Captcha] Given callback is no function")}}.bind(this))},getData:function(t){var e;if(-1===this._registeredCaptchas.indexOf(t))return e;var i=require("WoltLabSuite/Core/Controller/Captcha");try{e=i.getData(t)}catch(e){console.debug('[WCF.System.Captcha] Unknow captcha id "'+t+'"')}return e},removeCallback:function(t){require(["WoltLabSuite/Core/Controller/Captcha"],function(e){try{e.delete(t),this._registeredCaptchas.splice(this._registeredCaptchas.indexOf(item),1)}catch(e){}}.bind(this))}},WCF.System.Page={},WCF.System.Notification=Class.extend({_cssClassNames:"",_message:"",init:function(e,t){this._cssClassNames=t||"",this._message=e||""},show:function(t,e,i,n){require(["Ui/Notification"],function(e){e.show(i||this._message,t,n||this._cssClassNames)}.bind(this))}}),WCF.System.Confirmation={show:function(t,i,n,s,a){var e;"object"==typeof s&&((e=$("<div />")).append(s),s=e.html()),require(["Ui/Confirmation"],function(e){e.show({legacyCallback:i,message:t,parameters:n,template:s||"",messageIsHtml:!0===a})})}},WCF.System.DisableScrolling={_depth:0,_oldOverflow:null,disable:function(){$.browser.touch||(0===this._depth&&(this._oldOverflow=$(document.body).css("overflow"),$(document.body).css("overflow","hidden")),this._depth++)},enable:function(){0!==this._depth&&(this._depth--,0===this._depth&&$(document.body).css("overflow",this._oldOverflow))}},WCF.System.DisableZoom={_depth:0,_oldViewportSettings:null,disable:function(){var e;0===this._depth&&(e=$("meta[name=viewport]"),this._oldViewportSettings=e.attr("content"),e.attr("content",this._oldViewportSettings+",maximum-scale=1")),this._depth++},enable:function(){0!==this._depth&&(this._depth--,0===this._depth&&$("meta[name=viewport]").attr("content",this._oldViewportSettings))}},WCF.System.Fullscreen={enterFullscreen:function(e){e.requestFullscreen?e.requestFullscreen():e.msRequestFullscreen?e.msRequestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)},toggleFullscreen:function(e){null===this.getFullscreenElement()?this.enterFullscreen(e):this.exitFullscreen()},getFullscreenElement:function(){return document.fullscreenElement?document.fullscreenElement:document.mozFullScreenElement?document.mozFullScreenElement:document.webkitFullscreenElement?document.webkitFullscreenElement:document.msFullscreenElement?document.msFullscreenElement:null},exitFullscreen:function(){document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen()},isSupported:function(){return!!(document.documentElement.requestFullscreen||document.documentElement.msRequestFullscreen||document.documentElement.mozRequestFullScreen||document.documentElement.webkitRequestFullscreen)}},WCF.System.PageNavigation={init:function(s,a){require(["WoltLabSuite/Core/Ui/Page/JumpTo"],function(e){for(var t=elBySelAll(s),i=0,n=t.length;i<n;i++)e.init(t[i],a)})}},WCF.System.KeepAlive=Class.extend({init:function(e){new WCF.PeriodicalExecuter(function(e){new WCF.Action.Proxy({autoSend:!0,data:{actionName:"keepAlive",className:"wcf\\data\\session\\SessionAction"},failure:function(){e.stop()},showLoadingOverlay:!1,success:function(e){WCF.System.PushNotification.executeCallbacks(e)},suppressErrors:!0})},1e3*e)}}),WCF.System.PushNotification={_callbacks:{},addCallback:function(e,t){void 0===this._callbacks[e]&&(this._callbacks[e]=[]),this._callbacks[e].push(t)},executeCallbacks:function(e){for(var t in e.returnValues)if(void 0!==this._callbacks[t])for(var i=0;i<this._callbacks[t].length;i++)this._callbacks[t][i](e.returnValues[t])}},WCF.System.Event={addListener:function(e,t,i){return window.__wcf_bc_eventHandler.add(e,t,i)},removeListener:function(e,t,i){return window.__wcf_bc_eventHandler.remove(e,t,i)},removeAllListeners:function(e,t){return window.__wcf_bc_eventHandler.removeAll(e,t)},fireEvent:function(e,t,i){window.__wcf_bc_eventHandler.fire(e,t,i)}},WCF.System.Worker=Class.extend({_aborted:!1,_actionName:"",_callback:{},_className:"",_dialog:{},_proxy:{},_title:"",init:function(){},_success:function(){}}),WCF.InlineEditor=Class.extend({_callbacks:{},_dropdowns:{},_elements:{},_notification:{},_options:{},_proxy:{},_triggerElements:{},_updateData:{},init:function(){},_closeAll:function(){},_setOptions:function(){},registerCallback:function(){},_getTriggerElement:function(){},_show:function(){},_validate:function(){},_validateCallbacks:function(){},_success:function(){},_updateState:function(){},_click:function(){},_execute:function(){},_executeCallback:function(){},_hide:function(){}}),WCF.Upload=Class.extend({_name:"__files[]",_buttonSelector:null,_fileListSelector:null,_fileUpload:null,_className:"",_iframe:null,_internalFileID:0,_options:{},_uploadMatrix:[],_supportsAJAXUpload:!0,_overlay:null,init:function(e,t,i,n){this._buttonSelector=e,this._fileListSelector=t,this._className=i,this._internalFileID=0,this._options=$.extend(!0,{action:"upload",multiple:!1,url:"index.php?ajax-upload/&t="+SECURITY_TOKEN},n||{}),this._options.url=WCF.convertLegacyURL(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url);var s=new XMLHttpRequest;this._supportsAJAXUpload=s&&"upload"in s&&"onprogress"in s.upload,this._createButton()},_createButton:function(){var e;this._supportsAJAXUpload?(this._fileUpload=$('<input type="file" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/>"),this._fileUpload.change($.proxy(this._upload,this)),e=$('<p class="button uploadButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>"),elAttr(e[0],"role","button"),e.prepend(this._fileUpload),this._fileUpload[0].addEventListener("focus",function(){this.classList.contains("focus-visible")&&e[0].classList.add("active")}),this._fileUpload[0].addEventListener("blur",function(){e[0].classList.remove("active")})):(e=$('<p class="button uploadFallbackButton"><span>'+WCF.Language.get("wcf.global.button.upload")+"</span></p>"),elAttr(e[0],"role","button"),elAttr(e[0],"tabindex","0"),e.click($.proxy(this._showOverlay,this))),this._insertButton(e)},_insertButton:function(e){this._buttonSelector.prepend(e)},_removeButton:function(){var e=".uploadButton";this._supportsAJAXUpload||(e=".uploadFallbackButton"),this._buttonSelector.find(e).remove()},_upload:function(e,t,i,n){var s=null,a=[];if(void 0!==n)a=n;else if(t)a.push(t);else if(i){var o="";switch(i.type){case"image/png":o=".png";break;case"image/jpeg":o=".jpg";break;case"image/gif":o=".gif"}a.push({name:"pasted-from-clipboard"+o})}else a=this._fileUpload.prop("files");if(a.length){var r=new FormData,s=this._createUploadMatrix(a);if(!this._uploadMatrix[s].length)return null;for(var l,c=0,u=a.length;c<u;c++){this._uploadMatrix[s][c]&&(l=this._uploadMatrix[s][c].data("internalFileID"),i?r.append("__files["+l+"]",i,a[c].name):r.append("__files["+l+"]",a[c],a[c].name))}r.append("actionName",this._options.action),r.append("className",this._className);var h=this._getParameters();for(var d in h)r.append("parameters["+d+"]",h[d]);var p=this;$.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:r,contentType:!1,processData:!1,success:function(e,t,i){p._success(s,e)},error:$.proxy(this._error,this),xhr:function(){var e=$.ajaxSettings.xhr();return e&&e.upload.addEventListener("progress",function(e){p._progress(s,e)},!1),e},xhrFields:{withCredentials:!0}})}return s},_createUploadMatrix:function(e){if(e.length){var t=this._uploadMatrix.length;this._uploadMatrix[t]=[];for(var i=0,n=e.length;i<n;i++){var s=e[i],a=this._initFile(s);a.hasClass("uploadFailed")||(a.data("filename",s.name).data("internalFileID",this._internalFileID++),this._uploadMatrix[t][i]=a)}return t}return null},_success:function(e,t){},_error:function(e,t,i){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);for(var n in this._uploadMatrix[e])this._uploadMatrix[e][n].find("progress").attr("value",i)},_getParameters:function(){return{}},_initFile:function(e){return $("<li>"+e.name+" ("+e.size+')<progress max="100" /></li>').appendTo(this._fileListSelector)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix([e]),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)},_getFilename:function(){return $("#__fileUpload").val().split("\\").pop()}}),WCF.Upload.Parallel=WCF.Upload.extend({init:function(e,t,i,n){n=$.extend(!0,n||{},{multiple:!0}),this._super(e,t,i,n)},_upload:function(){for(var e=this._fileUpload.prop("files"),t=0,i=e.length;t<i;t++){var n=e[t],s=new FormData,a=this._createUploadMatrix(n);if(this._uploadMatrix[a].length){s.append("__files["+a+"]",n),s.append("actionName",this._options.action),s.append("className",this._className);var o=this._getParameters();for(var r in o)s.append("parameters["+r+"]",o[r]);this._sendRequest(a,s)}}},_sendRequest:function(n,e){var s=this;return $.ajax({type:"POST",url:this._options.url,enctype:"multipart/form-data",data:e,contentType:!1,processData:!1,success:function(e,t,i){s._success(n,e)},error:$.proxy(this._error,this),xhr:function(){var e=$.ajaxSettings.xhr();return e&&e.upload.addEventListener("progress",function(e){s._progress(n,e)},!1),e}})},_createUploadMatrix:function(e){var t=this._initFile(e);return t.hasClass("uploadFailed")?null:(t.data("filename",e.name).data("internalFileID",this._internalFileID),this._uploadMatrix[this._internalFileID++]=t,this._internalFileID-1)},_success:function(e,t){},_progress:function(e,t){var i=Math.round(100*t.loaded/t.total);this._uploadMatrix[e].find("progress").attr("value",i)},_showOverlay:function(){if(null===this._iframe&&(this._iframe=$('<iframe name="__fileUploadIFrame" />').hide().appendTo(document.body)),!this._overlay){this._overlay=$('<div><form enctype="multipart/form-data" method="post" action="'+this._options.url+'" target="__fileUploadIFrame" /></div>').hide().appendTo(document.body);var e=this._overlay.find("form");$('<dl class="wide"><dd><input type="file" id="__fileUpload" name="'+this._name+'" '+(this._options.multiple?'multiple="true" ':"")+"/></dd></dl>").appendTo(e),$('<div class="formSubmit"><input type="submit" value="Upload" accesskey="s" /></div></form>').appendTo(e),$('<input type="hidden" name="isFallback" value="1" />').appendTo(e),$('<input type="hidden" name="actionName" value="'+this._options.action+'" />').appendTo(e),$('<input type="hidden" name="className" value="'+this._className+'" />').appendTo(e);var t=this._getParameters();for(var i in t)$('<input type="hidden" name="'+i+'" value="'+t[i]+'" />').appendTo(e);e.submit($.proxy(function(){var e={name:this._getFilename(),size:""},t=this._createUploadMatrix(e),i=this;this._iframe.data("loading",!0).off("load").load(function(){i._evaluateResponse(t)}),this._overlay.wcfDialog("close")},this))}this._overlay.wcfDialog({title:WCF.Language.get("wcf.global.button.upload")})},_evaluateResponse:function(e){var t=$.parseJSON(this._iframe.contents().find("pre").html());this._success(e,t)}}),WCF.Sortable={},WCF.Sortable.List=Class.extend({_additionalParameters:{},_className:"",_containerID:"",_container:{},_notification:{},_offset:0,_options:{},_proxy:{},_structure:{},init:function(){},_tableRowHelper:function(){},_submit:function(){},_success:function(){}}),WCF.Popover=Class.extend({_activeElementID:"",_identifier:"",_popoverObj:null,init:function(t){var i=!1;require(["Environment"],function(e){"desktop"!==e.platform()&&(i=!0)}.bind(this)),i||(this._activeElementID="",this._identifier=t,require(["WoltLabSuite/Core/Controller/Popover"],function(e){e.init({attributeName:"legacy",className:t,identifier:this._identifier,legacy:!0,loadCallback:this._legacyLoad.bind(this)})}.bind(this)))},_initContainers:function(){},_legacyLoad:function(e,t){this._activeElementID=e,this._popoverObj=t,this._loadContent()},_insertContent:function(e,t){this._popoverObj.setContent(this._identifier,e,t)}}),WCF.EditableItemList=Class.extend({_allowCustomInput:!1,_className:"",_data:{},_form:null,_itemList:null,_objectID:0,_objectTypeID:0,_search:null,_searchInput:null,init:function(e,t){var i;this._itemList=$(e),this._searchInput=$(t),this._data={},this._itemList.length&&this._searchInput.length?(this._objectID=this._getObjectID(),this._objectTypeID=this._getObjectTypeID(),this._itemList.find(".jsEditableItem").click($.proxy(this._click,this)),this._itemList.children("ul").length||$("<ul />").appendTo(this._itemList),this._itemList=this._itemList.children("ul"),this._form=this._itemList.parents("form").submit($.proxy(this._submit,this)),this._allowCustomInput&&(i=this)._searchInput.keydown($.proxy(this._keyDown,this)).keypress($.proxy(this._keyPress,this)).on("paste",function(){setTimeout(function(){i._onPaste()},100)}),this._searchInput.parents(".dropdown").data("preventSubmit",!0)):console.debug("[WCF.EditableItemList] Item list and/or search input do not exist, aborting.")},_keyDown:function(e){return null!==e||this._keyPress(null)},_keyPress:function(e){if(null===e||44===e.charCode||e.charCode===$.ui.keyCode.ENTER||$.browser.mozilla&&e.keyCode===$.ui.keyCode.ENTER){if(null!==e&&e.charCode===$.ui.keyCode.ENTER&&this._search&&-1!==this._search._itemIndex)return!1;var t=$.trim(this._searchInput.val());return(e&&44===e.charCode&&(t=t.substring(0,this._searchInput.getCaret())),""===t)?!0:(this.addItem({objectID:0,label:t}),e&&44===e.charCode?this._searchInput.val($.trim(this._searchInput.val().substr(this._searchInput.getCaret()))):this._searchInput.val(""),null!==e&&e.stopPropagation(),!1)}return!0},_onPaste:function(){for(var e=$.trim(this._searchInput.val()),t=0,i=(e=e.split(",")).length;t<i;t++){var n=$.trim(e[t]);""!==n&&this.addItem({objectID:0,label:n})}this._searchInput.val("")},load:function(e){},_click:function(e){var t=$(e.currentTarget),i=t.data("objectID"),n=t.data("label");return this._search&&this._search.removeExcludedSearchValue(n),this._removeItem(i,n),t.remove(),e.stopPropagation(),!1},_getObjectID:function(){return 0},_getObjectTypeID:function(){return 0},addItem:function(e){return(!this._data[e.objectID]||0===e.objectID&&this._allowCustomInput)&&($('<li class="badge">'+WCF.String.escapeHTML(e.label)+"</li>").data("objectID",e.objectID).data("label",e.label).appendTo(this._itemList).click($.proxy(this._click,this)),this._search&&this._search.addExcludedSearchValue(e.label),this._addItem(e.objectID,e.label)),!0},clearList:function(){this._itemList.children("li").each($.proxy(function(e,t){var i=$(t);this._search&&this._search.removeExcludedSearchValue(i.data("label")),i.remove(),this._removeItem(i.data("objectID"),i.data("label"))},this))},_submit:function(){this._keyDown(null)},_addItem:function(e,t){this._data[e]=t},_removeItem:function(e,t){delete this._data[e]},getSearchInput:function(){return this._searchInput}}),WCF.Language.Chooser=Class.extend({init:function(t,i,n,s,a,o){require(["WoltLabSuite/Core/Language/Chooser"],function(e){e.init(t,i,n,s,a,o)})}}),WCF.Style={},WCF.UserPanel=Class.extend({_container:null,_didLoad:!1,_link:null,_noItems:"",_revertOnEmpty:!0,init:function(e){this._container=$("#"+e),this._didLoad=!1,this._revertOnEmpty=!0,1==this._container.length?this._convert():console.debug("[WCF.UserPanel] Unable to find container identified by '"+e+"', aborting.")},_convert:function(){this._container.addClass("dropdown"),this._link=this._container.children("a").remove();var e=$('<a href="'+this._link.attr("href")+'" class="dropdownToggle">'+this._link.html()+"</a>").appendTo(this._container).click($.proxy(this._click,this)),t=$('<ul class="dropdownMenu" />').appendTo(this._container);$('<li class="jsDropdownPlaceholder"><span>'+WCF.Language.get("wcf.global.loading")+"</span></li>").appendTo(t),this._addDefaultItems(t),this._container.dblclick($.proxy(function(){return window.location=this._link.attr("href"),!1},this)),WCF.Dropdown.initDropdown(e,!1)},_addDefaultItems:function(e){},_addDivider:function(e){$('<li class="dropdownDivider" />').appendTo(e)},_click:function(e){e.preventDefault(),this._didLoad||(new WCF.Action.Proxy({autoSend:!0,data:this._getParameters(),success:$.proxy(this._success,this)}),this._didLoad=!0)},_getParameters:function(){return{}},_success:function(e,t,i){var n=WCF.Dropdown.getDropdownMenu(this._container.wcfIdentify());n.children(".jsDropdownPlaceholder").remove(),e.returnValues&&e.returnValues.template?($(""+e.returnValues.template).prependTo(n),this._updateBadge(e.returnValues.totalCount),this._after(n)):($("<li><span>"+WCF.Language.get(this._noItems)+"</span></li>").prependTo(n),this._updateBadge(0))},_updateBadge:function(e){var t;(e=parseInt(e)||0)?((t=this._container.find(".badge")).length||(t=$('<span class="badge badgeUpdate" />').appendTo(this._container.children(".dropdownToggle"))).before(" "),t.html(e)):this._container.find(".badge").remove()},_after:function(e){}}),jQuery.fn.extend({wcfDialog:function(s){var a=arguments;return require(["Dom/Util","Ui/Dialog"],function(e,t){var i,n=e.identify(this[0]);"close"===s?t.close(n):"render"===s?t.rebuild(n):"option"===s?3===a.length&&("title"===a[1]&&"string"==typeof a[2]?t.setTitle(n,a[2]):0===a[1].indexOf("on")?t.setCallback(n,a[1],a[2]):"closeConfirmMessage"===a[1]&&null===a[2]&&t.setCallback(n,"onBeforeClose",null)):(this[0].parentNode.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&document.body.appendChild(this[0]),i=1===a.length&&"object"==typeof a[0]?a[0]:{},t.openStatic(n,null,i),i.hasOwnProperty("title")&&t.setTitle(n,i.title))}.bind(this)),this}}),$.widget("ui.wcfSlideshow",{_buttonList:null,_count:0,_index:0,_itemList:null,_items:null,_timer:null,_width:0,options:{cycle:!0,cycleInterval:5,itemGap:50},_create:function(){this._itemList=this.element.children("ul"),this._items=this._itemList.children("li"),this._count=this._items.length,this._index=0,1<this._count&&this._initSlideshow()},_initSlideshow:function(){var i=$(this._items.get(0)).outerHeight();this._items.addClass("slideshowItem"),this._width=this.element.css("height",i).innerWidth(),this._itemList.addClass("slideshowItemList").css("left",0),this._items.each($.proxy(function(e,t){$(t).show().css({height:i,left:(this._width+this.options.itemGap)*e,width:this._width})},this)),this.element.css({height:i,width:this._width}).hover($.proxy(this._hoverIn,this),$.proxy(this._hoverOut,this)),this._buttonList=$('<ul class="slideshowButtonList" />').appendTo(this.element);for(var e=0;e<this._count;e++){var t=$('<li><a><span class="icon icon16 fa-circle" /></a></li>').data("index",e).click($.proxy(this._click,this)).appendTo(this._buttonList);0==e&&t.find(".icon").addClass("active")}this._resetTimer(),$(window).resize($.proxy(this._resize,this))},rebuildHeight:function(){var e=$(this._items.get(0)).css("height","auto").outerHeight();this._items.css("height",e+"px"),this.element.css("height",e+"px")},_resize:function(){this._width=this.element.css("width","auto").innerWidth(),this._items.each($.proxy(function(e,t){$(t).css({left:(this._width+this.options.itemGap)*e,width:this._width})},this)),this._index--,this.moveTo(null)},_hoverIn:function(){null!==this._timer&&this._timer.stop()},_hoverOut:function(){this._resetTimer()},_resetTimer:function(){var e;this.options.cycle&&(null!==this._timer&&this._timer.stop(),(e=this)._timer=new WCF.PeriodicalExecuter(function(){e.moveTo(null)},1e3*this.options.cycleInterval))},_click:function(e){this.moveTo($(e.currentTarget).data("index")),this._resetTimer()},moveTo:function(e){this._index=null===e?this._index+1:e,this._index==this._count&&(this._index=0),$(this._buttonList.find(".icon").removeClass("active").get(this._index)).addClass("active"),this._itemList.css("left",this._index*(this._width+this.options.itemGap)*-1),this._trigger("moveTo",null,{index:this._index})},getItem:function(e){return this._items[e]?this._items[e]:null}}),jQuery.fn.extend({datepicker:function(e){var t=this[0],i=Array.prototype.slice.call(arguments,1);switch(e){case"destroy":window.__wcf_bc_datePicker.destroy(t);break;case"getDate":return window.__wcf_bc_datePicker.getDate(t);case"option":if("onClose"===i[0])return 1<i.length?this.datepicker("setOption","onClose",i[1]):function(){};console.warn("datepicker('option') supports only 'onClose'.");break;case"setDate":window.__wcf_bc_datePicker.setDate(t,i[0]);break;case"setOption":"onClose"===i[0]?window.__wcf_bc_datePicker.setCloseCallback(t,i[1]):console.warn("datepicker('setOption') supports only 'onClose'.");break;default:console.debug("Unsupported method '"+e+"' for datepicker()")}return this}}),jQuery.fn.extend({wcfTabs:function(n){var s=this[0],a=Array.prototype.slice.call(arguments,1);require(["Dom/Util","WoltLabSuite/Core/Ui/TabMenu"],function(e,t){var i=t.getTabMenu(e.identify(s));null!==i&&i[n].apply(i,a)})}}),$.widget("ui.wcfPages",{_api:null,SHOW_LINKS:11,SHOW_SUB_LINKS:20,options:{activePage:1,maxPage:1},_create:function(){require(["WoltLabSuite/Core/Ui/Pagination"],function(e){this._api=new e(this.element[0],{activePage:this.options.activePage,maxPage:this.options.maxPage,callbackShouldSwitch:function(e){return!1!==this._trigger("shouldSwitch",void 0,{nextPage:e})}.bind(this),callbackSwitch:function(e){this._trigger("switched",void 0,{activePage:e})}.bind(this)})}.bind(this))},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this._api=null,this.element[0].innerHTML=""},_setOption:function(e,t){var i;return"activePage"==e&&t!=this.options[e]&&0<t&&t<=this.options.maxPage&&((i=this._trigger("shouldSwitch",void 0,{nextPage:t}))||void 0!==i?this._api.switchPage(t):this._trigger("notSwitched",void 0,{activePage:t})),this}}),WCF.Category={},WCF.Category.NestedList=Class.extend({_categories:{},init:function(){},_updateSelection:function(){}}),WCF.Category.FlexibleCategoryList=Class.extend({_list:{},_categories:{},init:function(){},_buildStructure:function(){},_updateSelection:function(){}}),WCF.Condition={},WCF.Notice={}; })(this);
 
 // WCF.Like.js
 (function (window, undefined) { "use strict";WCF.Like=Class.extend({init:function(){throw new Error("The `WCF.Like` API is obsolete and therefore no longer supported. Please use the current API `WoltLabSuite/Core/Ui/Reaction/Handler` instead.")},_domNodeInserted:function(){},_initContainers:function(){},_getContainers:function(){},_getWidgetContainer:function(){},_getObjectID:function(){},_addWidget:function(){},_buildWidget:function(){},_createWidget:function(){},_showLikeDetails:function(){},_click:function(){},_sendRequest:function(){},_success:function(){},_updateBadge:function(){},_updateSummary:function(){},_setActiveState:function(){}}); })(this);
@@ -34,35 +28,35 @@ success:$.proxy(this._success,this),autoAbortPrevious:!0}),this._searchInput.is(
 (function (window, undefined) { "use strict";WCF.ACL={},WCF.ACL.List=Class.extend({_categoryName:"",_container:{},_containerElements:{},_objectID:0,_objectTypeID:{},_options:{},_proxy:{},_search:{},_values:{},init:function(){},_reset:function(){},_loadACL:function(){},addObject:function(){},_createListItem:function(){},_removeItem:function(){},_selectFirstEntry:function(){},_success:function(){},_parseData:function(){},_click:function(){},_select:function(){},_change:function(){},_changeAll:function(){},_setupPermissions:function(){},_savePermissions:function(){},submit:function(){},_save:function(){}}); })(this);
 
 // WCF.Attachment.js
-(function (window, undefined) { "use strict";WCF.Attachment={},WCF.Attachment.Upload=WCF.Upload.extend({_autoInsert:[],_insertAllButton:null,_objectType:"",_objectID:0,_tmpHash:"",_parentObjectID:0,_editorId:"",_replaceOnLoad:{},_options:{},init:function(t,e,a,i,s,n,r,l,o){if(this._super(t,e,"wcf\\data\\attachment\\AttachmentAction",{multiple:!0,maxUploads:r}),this._autoInsert=[],this._objectType=a,this._objectID=parseInt(i),this._tmpHash=s,this._parentObjectID=parseInt(n),this._editorId=l,this._options=$.extend(!0,this._options,o||{}),this._buttonSelector.children("p.button").click($.proxy(this._validateLimit,this)),this._fileListSelector.find(".jsButtonInsertAttachment").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertThumbnail").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertFull").click($.proxy(this._insert,this)),WCF.DOMNodeRemovedHandler.addCallback("WCF.Attachment.Upload",$.proxy(this._removeLimitError,this)),WCF.System.Event.addListener("com.woltlab.wcf.action.delete","attachment_"+this._editorId,$.proxy(this._removeLimitError,this)),this._makeSortable(),this._insertAllButton=$('<p class="button jsButtonAttachmentInsertAll">'+WCF.Language.get("wcf.attachment.insertAll")+"</p>").hide(),this._editorId){this._insertAllButton.appendTo(this._buttonSelector),this._insertAllButton.click($.proxy(this._insertAll,this)),this._fileListSelector.children("li:not(.uploadFailed)").length&&this._insertAllButton.show(),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","submit_"+this._editorId,this._submitInline.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+this._editorId,this._reset.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId,function(t){t.tmpHashes&&Array.isArray(t.tmpHashes)||(t.tmpHashes=[]);var e=t.tmpHashes.indexOf(s);this._fileListSelector.children("li:not(.uploadFailed)").length>0?-1===e&&t.tmpHashes.push(s):-1!==e&&t.tmpHashes.splice(e)}.bind(this));var d=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,function(t){var e=this._getImageAttachments(),a=t.attributes[0]||0;if(e.hasOwnProperty(a)){var i=~~$("#"+this._editorId).data("redactor").opts.woltlab.attachmentThumbnailWidth,s=t.attributes[2];s=!0===s||"true"===s||~~s&&~~s<=i;var n=elCreate("img");n.className="woltlabAttachment",n.src=e[a][s?"thumbnailUrl":"url"],elData(n,"attachment-id",a);var r=t.attributes[1]||"none";"left"===r?n.classList.add("messageFloatObjectLeft"):"right"===r&&n.classList.add("messageFloatObjectRight");var l=t.metacode;l.parentNode.insertBefore(n,l),elRemove(l),t.cancel=!0}}.bind(this));WCF.System.Event.addListener("com.woltlab.wcf.redactor2","destroy_"+this._editorId,function(){WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","submit_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","reset_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId),WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,d)}.bind(this))}},_editorUpload:function(t){var e=null;this._fileListSelector.closest(".messageTabMenu").messageTabMenu("showTab","attachments",!0);var a=function(a){null===e?this._autoInsert.push(a):this._replaceOnLoad[a]=e,t.uploadID=a}.bind(this);t.file?this._upload(void 0,t.file,void 0,a):(this._upload(void 0,void 0,t.blob,a),e=t.replace||null)},_getImageAttachments:function(){var t={};return this._fileListSelector.children("li").each(function(e,a){var i=$(a);i.data("isImage")&&(t[~~i.data("objectID")]={thumbnailUrl:i.find(".jsButtonAttachmentInsertThumbnail").data("url"),url:i.find(".jsButtonAttachmentInsertFull").data("url")})}),t},_submitInline:function(t){if(this._tmpHash){t.tmpHash=this._tmpHash;var e={};WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","getMetaData_"+this._editorId,e),e.tmpHashes&&Array.isArray(e.tmpHashes)&&e.tmpHashes.length>0&&(t.tmpHash+=","+e.tmpHashes.join(","))}},_reset:function(){this._fileListSelector.hide().empty(),this._insertAllButton.hide(),this._validateLimit()},_validateLimit:function(){var t=this._buttonSelector.next("small.innerError"),e=this._options.maxUploads-this._fileListSelector.children("li:not(.uploadFailed)").length,a=this._fileUpload?this._fileUpload.prop("files").length:0;if(e<=0||e<a){var i=e<=0?WCF.Language.get("wcf.attachment.upload.error.reachedLimit"):WCF.Language.get("wcf.attachment.upload.error.reachedRemainingLimit").replace(/#remaining#/,e);return t.length||(t=$('<small class="innerError" />').insertAfter(this._buttonSelector)),t.html(i),!1}return t.remove(),!0},_removeLimitError:function(t){var e=this._fileListSelector.children("li");e.filter(":not(.uploadFailed)").length||this._insertAllButton.hide(),e.length||this._fileListSelector.hide(),this._editorId&&t.button&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","deleteAttachment_"+this._editorId,{attachmentId:t.button.data("objectID")})},_upload:function(t,e,a,i){var s=this._super.bind(this);require(["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ImageUtil","WoltLabSuite/Core/Image/Resizer","WoltLabSuite/Core/Ajax/Status"],function(n,r,l,o){o.show();var d=[];e?d.push(e):a?d.push(n.blobToFile(a,"pasted-from-clipboard")):d=this._fileUpload.prop("files");var c=Promise.resolve(d);if(this._options.autoScale&&this._options.autoScale.enable){var h=this._buttonSelector.data("maxSize"),m=new l;c=Array.prototype.reduce.call(d,function(t,e){return t.then(function(t){var a=new Promise(function(t,a){setTimeout(function(){t(e)},1e4)}),i=m.loadFile(e).then(function(t){var i=t.exif,s=this._options.autoScale.maxWidth,n=this._options.autoScale.maxHeight,l=this._options.autoScale.quality;if(window.devicePixelRatio>=2){var o=window.screen.width*window.devicePixelRatio,d=window.screen.height*window.devicePixelRatio;o-10<t.image.width&&t.image.width<o+10&&d-10<t.image.height&&(s=Math.min(s,window.screen.width))}return m.resize(t.image,s,n,l,e.size>h,a).then(function(t){if(void 0===t)return e;var a=this._options.autoScale.fileType;return("keep"===this._options.autoScale.fileType||r.containsTransparentPixels(t))&&(a=e.type),m.saveFile({exif:i,image:t},e.name,a,l)}.bind(this)).then(function(t){return t.size>e.size?(console.debug('[WCF.Attachment] File size of "'+e.name+'" increased, uploading untouched image.'),e):t})}.bind(this)).catch(function(t){return console.debug('[WCF.Attachment] Failed to resize image "'+e.name+'":',t),e});return Promise.race([a,i]).then(function(e){return t.push(e),t})}.bind(this))}.bind(this),Promise.resolve([]))}c.then(function(e){var a=void 0;return this._validateLimit()&&(a=s(t,void 0,void 0,e)),this._fileUpload&&(this._removeButton(),this._createButton()),"function"==typeof i&&i(a),a}.bind(this)).catch(function(t){console.debug("[WCF.Attachment] Failed to upload attachments:",t)}).finally(o.hide)}.bind(this),function(t){console.debug("[WCF.Attachment] Failed to load modules:",t)})},_createUploadMatrix:function(t){return this._fileListSelector.children("li.uploadFailed").remove(),this._super(t)},_getParameters:function(){return{objectType:this._objectType,objectID:this._objectID,tmpHash:this._tmpHash,parentObjectID:this._parentObjectID}},_initFile:function(t){var e=$('<li class="box64"><span class="icon icon64 fa-spinner" /><div><div><p>'+t.name+'</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data("filename",t.name);return this._fileListSelector.append(e),this._fileListSelector.show(),this._buttonSelector.data("maxSize")<t.size&&(e.find("progress").remove(),e.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),e.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error.tooLarge")+"</small>")),e.addClass("uploadFailed")),e},_useThumbnail:function(){return elDataBool(this._fileListSelector[0],"enable-thumbnails")},_success:function(t,e){var a;for(var i in this._uploadMatrix[t])if(this._uploadMatrix[t].hasOwnProperty(i)){var s=this._uploadMatrix[t][i];s.find("progress").remove();var n=s.data("filename"),r=s.data("internalFileID");if(e.returnValues&&e.returnValues.attachments[r]){a=e.returnValues.attachments[r],a.tinyURL?(s.children(".fa-spinner").replaceWith($('<img src="'+a.tinyURL+'" alt="" class="attachmentTinyThumbnail" />')),s.data("height",a.height),s.data("width",a.width),elData(s[0],"is-image",a.isImage)):s.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-"+a.iconName);var l=$('<a href=""></a>');l.text(n).attr("href",a.url),l[0].target="_blank",0!=a.isImage&&l.addClass("jsImageViewer").attr("title",n),s.find("p").empty().append(l),s.find("small").append(a.formattedFilesize);var o=s.find("ul").addClass("buttonGroup"),d=$('<li><span class="button small jsDeleteButton" data-object-id="'+a.attachmentID+'" data-confirm-message="'+WCF.Language.get("wcf.attachment.delete.sure")+'" data-event-name="attachment_'+this._editorId+'">'+WCF.Language.get("wcf.global.button.delete")+"</span></li>");if(o.append(d),s.data("objectID",a.attachmentID),this._editorId)if(a.tinyURL||!this._useThumbnail()&&a.isImage){if(a.thumbnailURL){var c=$('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="'+a.attachmentID+'" data-url="'+WCF.String.escapeHTML(a.thumbnailURL)+'">'+WCF.Language.get("wcf.attachment.insertThumbnail")+"</span></li>").appendTo(o);c.children("span.button").click($.proxy(this._insert,this))}var h=$('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="'+a.attachmentID+'" data-url="'+WCF.String.escapeHTML(a.url)+'">'+WCF.Language.get("wcf.attachment.insertFull")+"</span></li>").appendTo(o);h.children("span.button").click($.proxy(this._insert,this))}else{var m=$('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="'+a.attachmentID+'">'+WCF.Language.get("wcf.attachment.insert")+"</span></li>");m.appendTo(o).children("span.button").click($.proxy(this._insert,this))}if(this._replaceOnLoad.hasOwnProperty(t)){if(!s.hasClass("uploadFailed")){var u=this._replaceOnLoad[t];u&&u.parentNode&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","replaceAttachment_"+this._editorId,{attachmentId:a.attachmentID,img:u,src:a.thumbnailURL?a.thumbnailURL:a.url})}this._replaceOnLoad[t]=null}}else{s.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban");var p="";if(e.returnValues&&e.returnValues.errors[r]){var f=e.returnValues.errors[r];p=f.errorType,"uploadFailed"===p&&f.additionalData.phpLimitExceeded&&(p="uploadPhpLimit")}else p="uploadFailed";s.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error."+p)+"</small>")),s.addClass("uploadFailed")}if(WCF.inArray(t,this._autoInsert)&&(this._autoInsert.splice(this._autoInsert.indexOf(t),1),!s.hasClass("uploadFailed"))){var _=s.find(".jsButtonAttachmentInsertThumbnail");_.length||(_=s.find(".jsButtonAttachmentInsertFull")),_.trigger("click")}}this._makeSortable(),this._fileListSelector.children("li:not(.uploadFailed)").length?this._insertAllButton.show():this._insertAllButton.hide(),WCF.DOMNodeInsertedHandler.execute()},_insert:function(t){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId,{attachmentId:elData(t.currentTarget,"object-id"),url:elData(t.currentTarget,"url")})},_insertAll:function(){for(var t,e,a=this._useThumbnail(),i=0,s=this._fileListSelector[0].childNodes.length;i<s;i++)t=this._fileListSelector[0].childNodes[i],"LI"!==t.nodeName||t.classList.contains("uploadFailed")||(e=null,a&&(e=elBySel(".jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain",t)),null===e&&(e=elBySel(".jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain",t)),window.jQuery(e).trigger("click"))},_error:function(t){this._fileListSelector.find("li").each(function(e,a){var i=$(a);i.children(".fa-spinner").length&&(i.addClass("uploadFailed").children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),i.find("div > div").append($('<small class="innerError">'+(t.responseJSON&&t.responseJSON.message?t.responseJSON.message:WCF.Language.get("wcf.attachment.upload.error.uploadFailed"))+"</small>")))})},_makeSortable:function(){var t=this._fileListSelector.children("li:not(.uploadFailed)");t.length&&(t.addClass("sortableAttachment").children("img").addClass("sortableNode"),this._fileListSelector.hasClass("sortableList")||(this._fileListSelector.addClass("sortableList"),require(["Environment"],function(t){"desktop"===t.platform()&&new WCF.Sortable.List(this._fileListSelector.parent().wcfIdentify(),"",0,{axis:!1,items:"li.sortableAttachment",toleranceElement:null,start:function(t,e){e.placeholder[0].style.setProperty("height",e.helper[0].offsetHeight+"px","")},update:function(){var t=[];this._fileListSelector.children("li:not(.uploadFailed)").each(function(e,a){t.push($(a).data("objectID"))}),t.length&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"updatePosition",className:"wcf\\data\\attachment\\AttachmentAction",parameters:{attachmentIDs:t,objectID:this._objectID,objectType:this._objectType,tmpHash:this._tmpHash}}})}.bind(this)},!0)}.bind(this))))}}); })(this);
+(function (window, undefined) { "use strict";WCF.Attachment={},WCF.Attachment.Upload=WCF.Upload.extend({_autoInsert:[],_insertAllButton:null,_objectType:"",_objectID:0,_tmpHash:"",_parentObjectID:0,_editorId:"",_replaceOnLoad:{},_options:{},init:function(t,e,i,a,n,s,r,l,o){var d,c;this._super(t,e,"wcf\\data\\attachment\\AttachmentAction",{multiple:!0,maxUploads:r}),this._autoInsert=[],this._objectType=i,this._objectID=parseInt(a),this._tmpHash=n,this._parentObjectID=parseInt(s),this._editorId=l,this._options=$.extend(!0,this._options,o||{}),this._buttonSelector.children("p.button").click($.proxy(this._validateLimit,this)),this._fileListSelector.find(".jsButtonInsertAttachment").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertThumbnail").click($.proxy(this._insert,this)),this._fileListSelector.find(".jsButtonAttachmentInsertFull").click($.proxy(this._insert,this)),WCF.System.Event.addListener("com.woltlab.wcf.action.delete","attachment",this._onDelete.bind(this)),this._makeSortable(),this._insertAllButton=$('<p class="button jsButtonAttachmentInsertAll">'+WCF.Language.get("wcf.attachment.insertAll")+"</p>").hide(),this._editorId&&(this._insertAllButton.appendTo(this._buttonSelector),this._insertAllButton.click($.proxy(this._insertAll,this)),this._fileListSelector.children("li:not(.uploadFailed)").length&&this._insertAllButton.show(),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","submit_"+this._editorId,this._submitInline.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+this._editorId,this._reset.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId,this._editorUpload.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId,function(t){t.tmpHashes&&Array.isArray(t.tmpHashes)||(t.tmpHashes=[]);var e=t.tmpHashes.indexOf(n);0<this._fileListSelector.children("li:not(.uploadFailed)").length?-1===e&&t.tmpHashes.push(n):-1!==e&&t.tmpHashes.splice(e)}.bind(this)),d=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,function(t){var e,i,a,n,s,r=this._getImageAttachments(),l=t.attributes[0]||0;r.hasOwnProperty(l)&&(e=~~$("#"+this._editorId).data("redactor").opts.woltlab.attachmentThumbnailWidth,i=!0===(i=t.attributes[2])||"true"===i||~~i&&~~i<=e,(a=elCreate("img")).className="woltlabAttachment",a.src=r[l][i?"thumbnailUrl":"url"],elData(a,"attachment-id",l),"left"===(n=t.attributes[1]||"none")?a.classList.add("messageFloatObjectLeft"):"right"===n&&a.classList.add("messageFloatObjectRight"),(s=t.metacode).parentNode.insertBefore(a,s),elRemove(s),t.cancel=!0)}.bind(this)),c=WCF.System.Event.addListener("com.woltlab.wcf.redactor2","sync_"+this._tmpHash,this._sync.bind(this)),WCF.System.Event.addListener("com.woltlab.wcf.redactor2","destroy_"+this._editorId,function(){WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","submit_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","reset_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","dragAndDrop_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","pasteFromClipboard_"+this._editorId),WCF.System.Event.removeAllListeners("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._editorId),WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","metacode_attach_"+this._editorId,d),WCF.System.Event.removeListener("com.woltlab.wcf.redactor2","sync_"+this._tmpHash,c)}.bind(this)))},_editorUpload:function(e){var i=null;this._fileListSelector.closest(".messageTabMenu").messageTabMenu("showTab","attachments",!0);var t=function(t){null===i?this._autoInsert.push(t):this._replaceOnLoad[t]=i,e.uploadID=t}.bind(this);e.file?this._upload(void 0,e.file,void 0,t):(this._upload(void 0,void 0,e.blob,t),i=e.replace||null)},_getImageAttachments:function(){var a={};return this._fileListSelector.children("li").each(function(t,e){var i=$(e);i.data("isImage")&&(a[~~i.data("objectID")]={thumbnailUrl:i.find(".jsButtonAttachmentInsertThumbnail").data("url"),url:i.find(".jsButtonAttachmentInsertFull").data("url")})}),a},_submitInline:function(t){var e;this._tmpHash&&(t.tmpHash=this._tmpHash,e={},WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","getMetaData_"+this._editorId,e),e.tmpHashes&&Array.isArray(e.tmpHashes)&&0<e.tmpHashes.length&&(t.tmpHash+=","+e.tmpHashes.join(",")))},_reset:function(){this._fileListSelector.hide().empty(),this._insertAllButton.hide(),this._validateLimit()},_validateLimit:function(){var t=this._buttonSelector.next("small.innerError"),e=this._options.maxUploads-this._fileListSelector.children("li:not(.uploadFailed)").length,i=this._fileUpload?this._fileUpload.prop("files").length:0;if(e<=0||e<i){var a=e<=0?WCF.Language.get("wcf.attachment.upload.error.reachedLimit"):WCF.Language.get("wcf.attachment.upload.error.reachedRemainingLimit").replace(/#remaining#/,e);return t.length||(t=$('<small class="innerError" />').insertAfter(this._buttonSelector)),t.html(a),!1}return t.remove(),!0},_removeLimitError:function(t){var e=this._fileListSelector.children("li");e.filter(":not(.uploadFailed)").length||this._insertAllButton.hide(),e.length||this._fileListSelector.hide(),this._editorId&&t.button&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","deleteAttachment_"+this._editorId,{attachmentId:t.button.data("objectID")})},_upload:function(s,r,l,o){var m=this._super.bind(this);require(["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ImageUtil","WoltLabSuite/Core/Image/Resizer","WoltLabSuite/Core/Ajax/Status"],function(t,d,e,i){i.show();var a=[];r?a.push(r):l?a.push(t.blobToFile(l,"pasted-from-clipboard")):a=this._fileUpload.prop("files");var c,h,n=Promise.resolve(a);this._options.autoScale&&this._options.autoScale.enable&&(c=this._buttonSelector.data("maxSize"),h=new e,n=Array.prototype.reduce.call(a,function(t,o){return t.then(function(e){if(-1===["image/png","image/jpeg"].indexOf(o.type))return e.push(o),e;var l=new Promise(function(t,e){setTimeout(function(){t(o)},1e4)}),t=h.loadFile(o).then(function(t){var e,i,a=t.exif,n=this._options.autoScale.maxWidth,s=this._options.autoScale.maxHeight,r=this._options.autoScale.quality;return 2<=window.devicePixelRatio&&(e=window.screen.width*window.devicePixelRatio,i=window.screen.height*window.devicePixelRatio,e-10<t.image.width&&t.image.width<10+e&&i-10<t.image.height&&(n=Math.min(n,window.screen.width))),h.resize(t.image,n,s,r,o.size>c,l).then(function(t){if(void 0===t)return o;var e=this._options.autoScale.fileType;return"keep"!==this._options.autoScale.fileType&&!d.containsTransparentPixels(t)||(e=o.type),h.saveFile({exif:a,image:t},o.name,e,r)}.bind(this)).then(function(t){return t.size>o.size?(console.debug('[WCF.Attachment] File size of "'+o.name+'" increased, uploading untouched image.'),o):t})}.bind(this)).catch(function(t){return console.debug('[WCF.Attachment] Failed to resize image "'+o.name+'":',t),o});return Promise.race([l,t]).then(function(t){return e.push(t),e})}.bind(this))}.bind(this),Promise.resolve([]))),n.then(function(t){var e=void 0;return this._validateLimit()&&(e=m(s,void 0,void 0,t)),this._fileUpload&&(this._removeButton(),this._createButton()),"function"==typeof o&&o(e),e}.bind(this)).catch(function(t){console.debug("[WCF.Attachment] Failed to upload attachments:",t)}).finally(i.hide)}.bind(this),function(t){console.debug("[WCF.Attachment] Failed to load modules:",t)})},_createUploadMatrix:function(t){return this._fileListSelector.children("li.uploadFailed").remove(),this._super(t)},_getParameters:function(){return{objectType:this._objectType,objectID:this._objectID,tmpHash:this._tmpHash,parentObjectID:this._parentObjectID}},_initFile:function(t){var e=$('<li class="box64 formAttachmentListItem"><span class="icon icon64 fa-spinner" /><div><div><p>'+t.name+'</p><small><progress max="100"></progress></small></div><ul></ul></div></li>').data("filename",t.name);return this._fileListSelector.append(e),this._fileListSelector.show(),this._buttonSelector.data("maxSize")<t.size&&(e.find("progress").remove(),e.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),e.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error.tooLarge")+"</small>")),e.addClass("uploadFailed")),e},_useThumbnail:function(){return!0},_success:function(t,e){var i,a,n,s,r,l,o,d,c,h,m;for(var u in this._uploadMatrix[t]){this._uploadMatrix[t].hasOwnProperty(u)&&((a=this._uploadMatrix[t][u]).find("progress").remove(),n=a.data("filename"),s=a.data("internalFileID"),e.returnValues&&e.returnValues.attachments[s]?(i=e.returnValues.attachments[s],elData(a[0],"object-id",i.attachmentID),i.tinyURL?(a.children(".fa-spinner").replaceWith($('<img src="'+i.tinyURL+'" alt="" class="attachmentTinyThumbnail" />')),a.data("height",i.height),a.data("width",i.width),elData(a[0],"is-image",i.isImage)):a.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-"+i.iconName),(r=$('<a href=""></a>')).text(n).attr("href",i.url),r[0].target="_blank",0!=i.isImage&&r.addClass("jsImageViewer").attr("title",n),a.find("p").empty().append(r),a.find("small").append(i.formattedFilesize),l=a.find("ul").addClass("buttonGroup"),o=$('<li><span class="button small jsDeleteButton" data-object-id="'+i.attachmentID+'" data-confirm-message="'+WCF.Language.get("wcf.attachment.delete.sure")+'" data-event-name="attachment">'+WCF.Language.get("wcf.global.button.delete")+"</span></li>"),l.append(o),a.data("objectID",i.attachmentID),this._editorId&&(i.tinyURL?(i.thumbnailURL&&$('<li><span class="button small jsButtonAttachmentInsertThumbnail" data-object-id="'+i.attachmentID+'" data-url="'+WCF.String.escapeHTML(i.thumbnailURL)+'">'+WCF.Language.get("wcf.attachment.insertThumbnail")+"</span></li>").appendTo(l),$('<li><span class="button small jsButtonAttachmentInsertFull" data-object-id="'+i.attachmentID+'" data-url="'+WCF.String.escapeHTML(i.url)+'">'+WCF.Language.get("wcf.attachment.insertFull")+"</span></li>").appendTo(l)):$('<li><span class="button small jsButtonAttachmentInsertPlain" data-object-id="'+i.attachmentID+'">'+WCF.Language.get("wcf.attachment.insert")+"</span></li>").appendTo(l)),this._triggerSync("new",{html:a[0].outerHTML}),this._registerEditorButtons(a[0]),this._replaceOnLoad.hasOwnProperty(t)&&(a.hasClass("uploadFailed")||(d=this._replaceOnLoad[t])&&d.parentNode&&WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","replaceAttachment_"+this._editorId,{attachmentId:i.attachmentID,img:d,src:i.thumbnailURL?i.thumbnailURL:i.url}),this._replaceOnLoad[t]=null)):(a.children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),h="",e.returnValues&&e.returnValues.errors[s]?"uploadFailed"===(h=(c=e.returnValues.errors[s]).errorType)&&c.additionalData.phpLimitExceeded&&(h="uploadPhpLimit"):h="uploadFailed",a.find("div > div").append($('<small class="innerError">'+WCF.Language.get("wcf.attachment.upload.error."+h)+"</small>")),a.addClass("uploadFailed")),WCF.inArray(t,this._autoInsert)&&(this._autoInsert.splice(this._autoInsert.indexOf(t),1),a.hasClass("uploadFailed")||((m=a.find(".jsButtonAttachmentInsertThumbnail")).length||(m=a.find(".jsButtonAttachmentInsertFull")),m.trigger("click"))))}this._rebuildInterface()},_rebuildInterface:function(){this._makeSortable(),this._fileListSelector.children("li:not(.uploadFailed)").length?this._insertAllButton.show():this._insertAllButton.hide(),WCF.DOMNodeInsertedHandler.execute()},_registerEditorButtons:function(t){this._editorId&&elBySelAll(".jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain",t,function(t){t.addEventListener("click",this._insert.bind(this))}.bind(this))},_insert:function(t){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","insertAttachment_"+this._editorId,{attachmentId:elData(t.currentTarget,"object-id"),url:elData(t.currentTarget,"url")})},_insertAll:function(){for(var t,e,i=0,a=this._fileListSelector[0].childNodes.length;i<a;i++)"LI"!==(t=this._fileListSelector[0].childNodes[i]).nodeName||t.classList.contains("uploadFailed")||(null===(e=elBySel(".jsButtonAttachmentInsertThumbnail, .jsButtonAttachmentInsertPlain",t))&&(e=elBySel(".jsButtonAttachmentInsertFull, .jsButtonAttachmentInsertPlain",t)),window.jQuery(e).trigger("click"))},_error:function(a){this._fileListSelector.find("li").each(function(t,e){var i=$(e);i.children(".fa-spinner").length&&(i.addClass("uploadFailed").children(".fa-spinner").removeClass("fa-spinner").addClass("fa-ban"),i.find("div > div").append($('<small class="innerError">'+(a.responseJSON&&a.responseJSON.message?a.responseJSON.message:WCF.Language.get("wcf.attachment.upload.error.uploadFailed"))+"</small>")))})},_makeSortable:function(){var t=this._fileListSelector.children("li:not(.uploadFailed)");t.length&&(t.addClass("sortableAttachment").children("img").addClass("sortableNode"),this._fileListSelector.hasClass("sortableList")||(this._fileListSelector.addClass("sortableList"),require(["Environment"],function(t){"desktop"===t.platform()&&new WCF.Sortable.List(this._fileListSelector.parent().wcfIdentify(),"",0,{axis:!1,items:"li.sortableAttachment",toleranceElement:null,start:function(t,e){e.placeholder[0].style.setProperty("height",e.helper[0].offsetHeight+"px","")},update:function(){var i=[];this._fileListSelector.children("li:not(.uploadFailed)").each(function(t,e){i.push($(e).data("objectID"))}),i.length&&new WCF.Action.Proxy({autoSend:!0,data:{actionName:"updatePosition",className:"wcf\\data\\attachment\\AttachmentAction",parameters:{attachmentIDs:i,objectID:this._objectID,objectType:this._objectType,tmpHash:this._tmpHash}}})}.bind(this)},!0)}.bind(this))))},_onDelete:function(t){var e=elData(t.button[0],"object-id"),i=elBySel('.formAttachmentListItem[data-object-id="'+e+'"]',this._fileListSelector[0]);null!==i&&elRemove(i),this._removeLimitError(t)},_sync:function(t){if(t.source!==this)switch(t.type){case"new":this._syncNew(t.data);break;default:throw new Error("Unexpected type '"+t.type+"'")}},_syncNew:function(a){require(["Dom/Util"],function(t){var e=t.createFragmentFromHtml(a.html),i=elBySel("li",e);i.id="",this._registerEditorButtons(i),this._fileListSelector[0].appendChild(i),elShow(this._fileListSelector[0]),this._rebuildInterface()}.bind(this))},_triggerSync:function(t,e){WCF.System.Event.fireEvent("com.woltlab.wcf.redactor2","sync_"+this._tmpHash,{source:this,type:t,data:e})}}); })(this);
 
 // WCF.ColorPicker.js
 (function (window, undefined) { "use strict";WCF.ColorPicker=Class.extend({_bar:{},_barActive:!1,_barSelector:{},_dialog:{},_didInit:!1,_elementID:"",_gradient:{},_gradientActive:!1,_gradientSelector:{},_hex:{},_hsv:{},_newColor:{},_oldColor:{},_rgba:{},_rgbaRegExp:{},init:function(){},_open:function(){},_parseColor:function(){},_initColorPicker:function(){},_initColorPickerForm:function(){},_keyUpRGBA:function(){},_keyUpHex:function(){},_submit:function(){},_createInputElement:function(){},_mouseDownGradient:function(){},_mouseGradient:function(){},_mouseDownBar:function(){},_mouseBar:function(){},_blurRgba:function(){},_blurHex:function(){},_updateValues:function(){},hsvToRgb:function(n,o,t){return window.__wcf_bc_colorUtil.hsvToRgb(n,o,t)},rgbToHsv:function(n,o,t){return window.__wcf_bc_colorUtil.rgbToHsv(n,o,t)},hexToRgb:function(n){return window.__wcf_bc_colorUtil.hexToRgb(n)},rgbToHex:function(n,o,t){return window.__wcf_bc_colorUtil.rgbToHex(n,o,t)}}); })(this);
 
 // WCF.Comment.js
-(function (window, undefined) { "use strict";WCF.Comment={},WCF.Comment.Handler=Class.extend({_commentButtonList:{},_comments:{},_container:null,_containerID:"",_displayedComments:0,_loadNextComments:null,_loadNextResponses:{},_proxy:null,_responses:{},_responseCache:{},_commentData:{},_guestDialog:null,_permalinkComment:null,_permalinkResponse:null,_scrollTarget:null,init:function(e){if(this._commentButtonList={},this._comments={},this._containerID=e,this._displayedComments=0,this._loadNextComments=null,this._loadNextResponses={},this._permalinkComment=null,this._permalinkResponse=null,this._responseAdd=null,this._responseCache={},this._responseRevert=null,this._responses={},this._scrollTarget=null,this._onResponsesLoaded=null,this._container=$("#"+$.wcfEscapeID(this._containerID)),!this._container.length)return void console.debug("[WCF.Comment.Handler] Unable to find container identified by '"+this._containerID+"'");if(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initComments(),this._initResponses(),this._container.data("canAdd")&&(null===elBySel(".commentListAddComment .wysiwygTextarea",this._container[0])?console.error("Missing WYSIWYG implementation, adding comments is not available."):require(["WoltLabSuite/Core/Ui/Comment/Add","WoltLabSuite/Core/Ui/Comment/Response/Add"],function(e,t){new e(elBySel(".jsCommentAdd",this._container[0])),this._responseAdd=new t(elBySel(".jsCommentResponseAdd",this._container[0]),{callbackInsert:function(){null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null)}.bind(this)})}.bind(this))),require(["WoltLabSuite/Core/Ui/Comment/Edit","WoltLabSuite/Core/Ui/Comment/Response/Edit"],function(e,t){new e(this._container[0]),new t(this._container[0])}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Comment.Handler",$.proxy(this._domNodeInserted,this)),WCF.System.ObjectStore.add("WCF.Comment.Handler",this),window.addEventListener("hashchange",function(){var e=window.location.hash;if(e&&e.match(/.+\/(comment\d+)/)){var t=RegExp.$1;window.setTimeout(function(){var e=elById(t);e&&e.scrollIntoView({behavior:"smooth"})},100)}}),window.location.hash.match(/^#(?:[^\/]+\/)?comment(\d+)(?:\/response(\d+))?/)){var t=elById("comment"+RegExp.$1);if(t){var n;RegExp.$2?(n=elById("comment"+RegExp.$1+"response"+RegExp.$2),n?this._scrollTo(n,!0):this._loadResponseSegment(t,RegExp.$1,RegExp.$2)):this._scrollTo(t,!0)}else this._loadCommentSegment(RegExp.$1,RegExp.$2)}},_scrollTo:function(e,t){null===this._scrollTarget&&(this._scrollTarget=elCreate("span"),this._scrollTarget.className="commentScrollTarget",document.body.appendChild(this._scrollTarget)),this._scrollTarget.style.setProperty("top",e.getBoundingClientRect().top+window.pageYOffset-49+"px",""),require(["Ui/Scroll"],function(n){n.element(this._scrollTarget,function(){t&&(e.classList.contains("commentHighlightTarget")&&(e.classList.remove("commentHighlightTarget"),e.offsetTop),e.classList.add("commentHighlightTarget"))})}.bind(this))},_loadCommentSegment:function(e,t){this._permalinkComment=elCreate("li"),this._permalinkComment.className="commentPermalinkContainer loading",this._permalinkComment.innerHTML='<span class="icon icon48 fa-spinner"></span>',this._container[0].insertBefore(this._permalinkComment,this._container[0].firstChild),this._proxy.setOption("data",{actionName:"loadComment",className:"wcf\\data\\comment\\CommentAction",objectIDs:[e],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~t}}}),this._proxy.sendRequest()},_loadResponseSegment:function(e,t,n){this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>';var s=elBySel(".commentResponseList",e);s.insertBefore(this._permalinkResponse,s.firstChild),this._proxy.setOption("data",{actionName:"loadResponse",className:"wcf\\data\\comment\\CommentAction",objectIDs:[t],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~n}}}),this._proxy.sendRequest()},_handleLoadNextComments:function(){this._displayedComments<this._container.data("comments")?(null===this._loadNextComments&&(this._loadNextComments=$('<li class="commentLoadNext showMore"><button class="small">'+WCF.Language.get("wcf.comment.more")+"</button></li>").appendTo(this._container),this._loadNextComments.children("button").click($.proxy(this._loadComments,this))),this._loadNextComments.children("button").enable()):null!==this._loadNextComments&&this._loadNextComments.remove()},_handleLoadNextResponses:function(e){var t=this._comments[e];if(t.data("displayedResponses",t.find("ul.commentResponseList > li").length),t.data("displayedResponses")<t.data("responses")){if(void 0===this._loadNextResponses[e]){var n=t.data("responses")-t.data("displayedResponses");this._loadNextResponses[e]=$('<li class="jsCommentLoadNextResponses"><a>'+WCF.Language.get("wcf.comment.response.more",{count:n})+"</a></li>").appendTo(this._commentButtonList[e]),this._loadNextResponses[e].children("a").data("commentID",e).click($.proxy(this._loadResponses,this)),this._commentButtonList[e].parent().show()}}else void 0!==this._loadNextResponses[e]&&this._loadNextResponses[e].remove()},_loadComments:function(){this._loadNextComments.children("button").disable(),this._proxy.setOption("data",{actionName:"loadComments",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),lastCommentTime:this._container.data("lastCommentTime")}}}),this._proxy.sendRequest()},_loadResponses:function(e){this._loadResponsesExecute($(e.currentTarget).disable().data("commentID"),!1)},_loadResponsesExecute:function(e,t){this._proxy.setOption("data",{actionName:"loadResponses",className:"wcf\\data\\comment\\response\\CommentResponseAction",parameters:{data:{commentID:e,lastResponseTime:this._comments[e].data("lastResponseTime"),loadAllResponses:t?1:0}}}),this._proxy.sendRequest()},_domNodeInserted:function(){this._initComments(),this._initResponses()},_initComments:function(){var e=elBySel('link[rel="canonical"]');e=e?e.href:window.location.toString().replace(/#.+$/,"");var t=this._container[0].closest(".tabMenuContent");t&&(e+="#"+elData(t,"name"));var n=this,s=!1;this._container.find(".jsComment").each(function(t,o){var i=$(o).removeClass("jsComment"),a=i.data("commentID");n._comments[a]=i,i[0].id="comment"+a;var l=i.find("ul.commentResponseList");l.length||(l=i.find(".commentContent"));var r=$('<div class="commentOptionContainer" />').hide().insertAfter(l);n._commentButtonList[a]=$('<ul class="inlineList dotSeparated" />').appendTo(r),n._handleLoadNextResponses(a),n._initComment(a,i),n._initPermalink(i[0],e),n._displayedComments++,s=!0}),s&&this._handleLoadNextComments()},_initComment:function(e,t){if(this._container.data("canAdd")&&this._initAddResponse(e,t),t.data("canEdit")){$('<li><a href="#" class="jsCommentEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").appendTo(t.find("ul.buttonList:eq(0)"))}if(t.data("canDelete")){$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>").data("commentID",e).appendTo(t.find("ul.buttonList:eq(0)")).click($.proxy(this._delete,this))}var n=elBySel(".jsEnableComment",t[0]);n&&n.addEventListener(WCF_CLICK_EVENT,this._enableComment.bind(this))},_enableComment:function(e){e.preventDefault();var t=e.currentTarget.closest(".comment");this._proxy.setOption("data",{actionName:"enable",className:"wcf\\data\\comment\\CommentAction",objectIDs:[elData(t,"object-id")]}),this._proxy.sendRequest()},_initPermalink:function(e,t){var n=elCreate("a");n.href=t+(-1===t.indexOf("#")?"#":"/")+"comment"+elData(e,"object-id");var s=elBySel(".commentContent:not(.commentResponseContent) .containerHeadline time",e);s.parentNode.insertBefore(n,s),n.appendChild(s)},_initResponses:function(){var e=elBySel('link[rel="canonical"]');e=e?e.href:window.location.toString().replace(/#.+$/,"");var t=this._container[0].closest(".tabMenuContent");t&&(e+="#"+elData(t,"name"));for(var n in this._comments)this._comments.hasOwnProperty(n)&&elBySelAll(".jsCommentResponse",this._comments[n][0],function(t){var s=$(t).removeClass("jsCommentResponse"),o=s.data("responseID");this._responses[o]=s,t.id="comment"+n+"response"+o,this._initResponse(o,s),this._initPermalinkResponse(n,t,o,e);var i=elBySel(".jsEnableResponse",t);i&&i.addEventListener(WCF_CLICK_EVENT,this._enableCommentResponse.bind(this))}.bind(this))},_enableCommentResponse:function(e){e.preventDefault();var t=e.currentTarget.closest(".commentResponse");this._proxy.setOption("data",{actionName:"enableResponse",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{responseID:elData(t,"object-id")}}}),this._proxy.sendRequest()},_initPermalinkResponse:function(e,t,n,s){var o=elCreate("a");o.href=s+(-1===s.indexOf("#")?"#":"/")+"comment"+e+"/response"+n;var i=elBySel(".commentResponseContent .containerHeadline time",t);i.parentNode.insertBefore(o,i),o.appendChild(i)},_initResponse:function(e,t){if(t.data("canEdit")){$('<li><a href="#" class="jsCommentResponseEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)"))}if(t.data("canDelete")){var n=this;$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>").data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)")).click(function(e){n._delete(e,!0)})}},_initAddResponse:function(e,t){$('<li class="jsCommentShowAddResponse"><a>'+WCF.Language.get("wcf.comment.button.response.add")+"</a></li>").data("commentID",e).click($.proxy(this._showAddResponse,this)).appendTo(this._commentButtonList[e]);this._commentButtonList[e].parent().show()},_showAddResponse:function(e){if(e.preventDefault(),null===this._onResponsesLoaded){if(null===this._responseAdd)return void console.error("Missing response API.");var t=this._responseAdd.getContainer();if(null!==t){null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null);var n=$(e.currentTarget),s=n.data("commentID");this._onResponsesLoaded=function(){n.hide(),t.parentNode&&t.parentNode.classList.contains("jsCommentResponseAddContainer")&&elRemove(t.parentNode);var e=this._commentButtonList[s][0].closest(".commentOptionContainer");e.parentNode.insertBefore(t,e.nextSibling),"string"==typeof this._responseCache[s]?this._responseAdd.setContent(this._responseCache[s]):this._responseAdd.setContent(""),this._responseRevert=function(){this._responseCache[s]=this._responseAdd.getContent(),elRemove(t),n.show()}.bind(this),this._onResponsesLoaded=null}.bind(this),n.prev().hasClass("jsCommentLoadNextResponses")?(this._loadResponsesExecute(s,!0),n.parent().children(".button").disable()):this._onResponsesLoaded()}}},_delete:function(e,t){e.preventDefault(),WCF.System.Confirmation.show(WCF.Language.get("wcf.comment.delete.confirmMessage"),$.proxy(function(n){if("confirm"===n){var s={objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID")};!0!==t?s.commentID=$(e.currentTarget).data("commentID"):s.responseID=$(e.currentTarget).data("responseID"),this._proxy.setOption("data",{actionName:"remove",className:"wcf\\data\\comment\\CommentAction",parameters:{data:s}}),this._proxy.sendRequest()}},this))},_success:function(e,t,n){switch(e.actionName){case"enable":this._enable(e);break;case"enableResponse":this._enableResponse(e);break;case"loadComment":this._insertComment(e);break;case"loadComments":this._insertComments(e);break;case"loadResponse":this._insertResponse(e);break;case"loadResponses":this._insertResponses(e);break;case"remove":this._remove(e)}WCF.DOMNodeInsertedHandler.execute()},_enable:function(e){if(e.returnValues.commentID){var t=elBySel('.comment[data-object-id="'+e.returnValues.commentID+'"]',this._container[0]);if(t){elData(t,"is-disabled",0);var n=elBySel(".jsIconDisabled",t);n&&elRemove(n);var s=elBySel(".jsEnableComment",t);s&&elRemove(s.parentNode)}}},_enableResponse:function(e){if(e.returnValues.responseID){var t=elBySel('.commentResponse[data-object-id="'+e.returnValues.responseID+'"]',this._container[0]);if(t){elData(t,"is-disabled",0);var n=elBySel(".jsIconDisabled",t);n&&elRemove(n);var s=elBySel(".jsEnableResponse",t);s&&elRemove(s.parentNode)}}},_insertComment:function(e){if(""===e.returnValues.template)return void elRemove(this._permalinkComment);$(e.returnValues.template).insertBefore(this._permalinkComment);var t=this._permalinkComment.previousElementSibling;if(t.classList.add("commentPermalinkContainer"),elRemove(this._permalinkComment),this._permalinkComment=t,e.returnValues.response){this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>';var n=elBySel(".commentResponseList",t);n.insertBefore(this._permalinkResponse,n.firstChild),this._insertResponse({returnValues:{template:e.returnValues.response}})}t.offsetTop,t.classList.add("commentHighlightTarget")},_insertResponse:function(e){if(""===e.returnValues.template)return void elRemove(this._permalinkResponse);$(e.returnValues.template).insertBefore(this._permalinkResponse);var t=this._permalinkResponse.previousElementSibling;t.classList.add("commentResponsePermalinkContainer"),elRemove(this._permalinkResponse),this._permalinkResponse=t,t.offsetTop,t.classList.add("commentHighlightTarget")},_insertComments:function(e){if($(e.returnValues.template).insertBefore(this._loadNextComments),this._container.data("lastCommentTime",e.returnValues.lastCommentTime),this._permalinkComment){var t=elData(this._permalinkComment,"object-id");null!==elBySel('.comment[data-object-id="'+t+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkComment),this._permalinkComment=null)}this._initComments()},_insertResponses:function(e){var t=this._comments[e.returnValues.commentID];if($(e.returnValues.template).appendTo(t.find("ul.commentResponseList")),t.data("lastResponseTime",e.returnValues.lastResponseTime),this._handleLoadNextResponses(e.returnValues.commentID),this._permalinkResponse){var n=elData(this._permalinkResponse,"object-id");null!==elBySel('.commentResponse[data-object-id="'+n+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkResponse),this._permalinkResponse=null)}null!==this._onResponsesLoaded&&this._onResponsesLoaded()},_remove:function(e){if(e.returnValues.commentID)this._comments[e.returnValues.commentID].remove(),delete this._comments[e.returnValues.commentID];else{var t=this._responses[e.returnValues.responseID],n=this._comments[t.parents("li.comment:eq(0)").data("commentID")];n.data("responses",parseInt(n.data("responses"))-1);var s=t.parent();t.remove(),s.children().length||s.empty(),delete this._responses[e.returnValues.responseID]}},_prepareEdit:function(){console.warn("This method is no longer supported.")},_keyUp:function(){console.warn("This method is no longer supported.")},_save:function(){console.warn("This method is no longer supported.")},_failure:function(){console.warn("This method is no longer supported.")},_edit:function(){console.warn("This method is no longer supported.")},_update:function(){console.warn("This method is no longer supported.")},_createGuestDialog:function(){console.warn("This method is no longer supported.")},_keyDown:function(){console.warn("This method is no longer supported.")},_submit:function(){console.warn("This method is no longer supported.")},_keyUpEdit:function(){console.warn("This method is no longer supported.")},_saveEdit:function(){console.warn("This method is no longer supported.")},_cancelEdit:function(){console.warn("This method is no longer supported.")}}),WCF.Comment.Response={}; })(this);
+(function (window, undefined) { "use strict";WCF.Comment={},WCF.Comment.Handler=Class.extend({_commentButtonList:{},_comments:{},_container:null,_containerID:"",_displayedComments:0,_loadNextComments:null,_loadNextResponses:{},_proxy:null,_responses:{},_responseCache:{},_commentData:{},_guestDialog:null,_permalinkComment:null,_permalinkResponse:null,_scrollTarget:null,init:function(e){var t,n;this._commentButtonList={},this._comments={},this._containerID=e,this._displayedComments=0,this._loadNextComments=null,this._loadNextResponses={},this._permalinkComment=null,this._permalinkResponse=null,this._responseAdd=null,this._responseCache={},this._responseRevert=null,this._responses={},this._scrollTarget=null,this._onResponsesLoaded=null,this._container=$("#"+$.wcfEscapeID(this._containerID)),this._container.length?(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initComments(),this._initResponses(),this._container.data("canAdd")&&(null===elBySel(".commentListAddComment .wysiwygTextarea",this._container[0])?console.error("Missing WYSIWYG implementation, adding comments is not available."):require(["WoltLabSuite/Core/Ui/Comment/Add","WoltLabSuite/Core/Ui/Comment/Response/Add"],function(e,t){new e(elBySel(".jsCommentAdd",this._container[0])),this._responseAdd=new t(elBySel(".jsCommentResponseAdd",this._container[0]),{callbackInsert:function(){null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null)}.bind(this)})}.bind(this))),require(["WoltLabSuite/Core/Ui/Comment/Edit","WoltLabSuite/Core/Ui/Comment/Response/Edit"],function(e,t){new e(this._container[0]),new t(this._container[0])}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Comment.Handler",$.proxy(this._domNodeInserted,this)),WCF.System.ObjectStore.add("WCF.Comment.Handler",this),window.addEventListener("hashchange",function(){var t,e=window.location.hash;e&&e.match(/.+\/(comment\d+)/)&&(t=RegExp.$1,window.setTimeout(function(){var e=elById(t);e&&e.scrollIntoView({behavior:"smooth"})},100))}),window.location.hash.match(/^#(?:[^\/]+\/)?comment(\d+)(?:\/response(\d+))?/)&&((t=elById("comment"+RegExp.$1))?RegExp.$2?(n=elById("comment"+RegExp.$1+"response"+RegExp.$2))?this._scrollTo(n,!0):this._loadResponseSegment(t,RegExp.$1,RegExp.$2):this._scrollTo(t,!0):this._loadCommentSegment(RegExp.$1,RegExp.$2))):console.debug("[WCF.Comment.Handler] Unable to find container identified by '"+this._containerID+"'")},_scrollTo:function(t,n){null===this._scrollTarget&&(this._scrollTarget=elCreate("span"),this._scrollTarget.className="commentScrollTarget",document.body.appendChild(this._scrollTarget)),this._scrollTarget.style.setProperty("top",t.getBoundingClientRect().top+window.pageYOffset-49+"px",""),require(["Ui/Scroll"],function(e){e.element(this._scrollTarget,function(){n&&(t.classList.contains("commentHighlightTarget")&&(t.classList.remove("commentHighlightTarget"),t.offsetTop),t.classList.add("commentHighlightTarget"))})}.bind(this))},_loadCommentSegment:function(e,t){this._permalinkComment=elCreate("li"),this._permalinkComment.className="commentPermalinkContainer loading",this._permalinkComment.innerHTML='<span class="icon icon48 fa-spinner"></span>',this._container[0].insertBefore(this._permalinkComment,this._container[0].firstChild),this._proxy.setOption("data",{actionName:"loadComment",className:"wcf\\data\\comment\\CommentAction",objectIDs:[e],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~t}}}),this._proxy.sendRequest()},_loadResponseSegment:function(e,t,n){this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>';var s=elBySel(".commentResponseList",e);s.insertBefore(this._permalinkResponse,s.firstChild),this._proxy.setOption("data",{actionName:"loadResponse",className:"wcf\\data\\comment\\CommentAction",objectIDs:[t],parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),responseID:~~n}}}),this._proxy.sendRequest()},_handleLoadNextComments:function(){this._displayedComments<this._container.data("comments")?(null===this._loadNextComments&&(this._loadNextComments=$('<li class="commentLoadNext showMore"><button class="small">'+WCF.Language.get("wcf.comment.more")+"</button></li>").appendTo(this._container),this._loadNextComments.children("button").click($.proxy(this._loadComments,this))),this._loadNextComments.children("button").enable()):null!==this._loadNextComments&&this._loadNextComments.remove()},_handleLoadNextResponses:function(e){var t,n=this._comments[e];n.data("displayedResponses",n.find("ul.commentResponseList > li").length),n.data("displayedResponses")<n.data("responses")?void 0===this._loadNextResponses[e]&&(t=n.data("responses")-n.data("displayedResponses"),this._loadNextResponses[e]=$('<li class="jsCommentLoadNextResponses"><a>'+WCF.Language.get("wcf.comment.response.more",{count:t})+"</a></li>").appendTo(this._commentButtonList[e]),this._loadNextResponses[e].children("a").data("commentID",e).click($.proxy(this._loadResponses,this)),this._commentButtonList[e].parent().show()):void 0!==this._loadNextResponses[e]&&this._loadNextResponses[e].remove()},_loadComments:function(){this._loadNextComments.children("button").disable(),this._proxy.setOption("data",{actionName:"loadComments",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID"),lastCommentTime:this._container.data("lastCommentTime")}}}),this._proxy.sendRequest()},_loadResponses:function(e){this._loadResponsesExecute($(e.currentTarget).disable().data("commentID"),!1)},_loadResponsesExecute:function(e,t){this._proxy.setOption("data",{actionName:"loadResponses",className:"wcf\\data\\comment\\response\\CommentResponseAction",parameters:{data:{commentID:e,lastResponseTime:this._comments[e].data("lastResponseTime"),loadAllResponses:t?1:0}}}),this._proxy.sendRequest()},_domNodeInserted:function(){this._initComments(),this._initResponses()},_initComments:function(){var a=(a=elBySel('link[rel="canonical"]'))?a.href:window.location.toString().replace(/#.+$/,""),e=this._container[0].closest(".tabMenuContent");e&&(a+="#"+elData(e,"name"));var l=this,m=!1;this._container.find(".jsComment").each(function(e,t){var n=$(t).removeClass("jsComment"),s=n.data("commentID");(l._comments[s]=n)[0].id="comment"+s;var o=n.find("ul.commentResponseList");o.length||(o=n.find(".commentContent"));var i=$('<div class="commentOptionContainer" />').hide().insertAfter(o);l._commentButtonList[s]=$('<ul class="inlineList dotSeparated" />').appendTo(i),l._handleLoadNextResponses(s),l._initComment(s,n),l._initPermalink(n[0],a),l._displayedComments++,m=!0}),m&&this._handleLoadNextComments()},_initComment:function(e,t){this._container.data("canAdd")&&this._initAddResponse(e,t),t.data("canEdit")&&$('<li><a href="#" class="jsCommentEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").appendTo(t.find("ul.buttonList:eq(0)")),t.data("canDelete")&&$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>").data("commentID",e).appendTo(t.find("ul.buttonList:eq(0)")).click($.proxy(this._delete,this));var n=elBySel(".jsEnableComment",t[0]);n&&n.addEventListener(WCF_CLICK_EVENT,this._enableComment.bind(this))},_enableComment:function(e){e.preventDefault();var t=e.currentTarget.closest(".comment");this._proxy.setOption("data",{actionName:"enable",className:"wcf\\data\\comment\\CommentAction",objectIDs:[elData(t,"object-id")]}),this._proxy.sendRequest()},_initPermalink:function(e,t){var n=elCreate("a");n.href=t+(-1===t.indexOf("#")?"#":"/")+"comment"+elData(e,"object-id");var s=elBySel(".commentContent:not(.commentResponseContent) .containerHeadline time",e);s.parentNode.insertBefore(n,s),n.appendChild(s)},_initResponses:function(){var o=(o=elBySel('link[rel="canonical"]'))?o.href:window.location.toString().replace(/#.+$/,""),e=this._container[0].closest(".tabMenuContent");for(var i in e&&(o+="#"+elData(e,"name")),this._comments)this._comments.hasOwnProperty(i)&&elBySelAll(".jsCommentResponse",this._comments[i][0],function(e){var t=$(e).removeClass("jsCommentResponse"),n=t.data("responseID");this._responses[n]=t,e.id="comment"+i+"response"+n,this._initResponse(n,t),this._initPermalinkResponse(i,e,n,o);var s=elBySel(".jsEnableResponse",e);s&&s.addEventListener(WCF_CLICK_EVENT,this._enableCommentResponse.bind(this))}.bind(this))},_enableCommentResponse:function(e){e.preventDefault();var t=e.currentTarget.closest(".commentResponse");this._proxy.setOption("data",{actionName:"enableResponse",className:"wcf\\data\\comment\\CommentAction",parameters:{data:{responseID:elData(t,"object-id")}}}),this._proxy.sendRequest()},_initPermalinkResponse:function(e,t,n,s){var o=elCreate("a");o.href=s+(-1===s.indexOf("#")?"#":"/")+"comment"+e+"/response"+n;var i=elBySel(".commentResponseContent .containerHeadline time",t);i.parentNode.insertBefore(o,i),o.appendChild(i)},_initResponse:function(e,t){var n,s;t.data("canEdit")&&$('<li><a href="#" class="jsCommentResponseEditButton jsTooltip" title="'+WCF.Language.get("wcf.global.button.edit")+'"><span class="icon icon16 fa-pencil" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.edit")+"</span></a></li>").data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)")),t.data("canDelete")&&(n=$('<li><a href="#" class="jsTooltip" title="'+WCF.Language.get("wcf.global.button.delete")+'"><span class="icon icon16 fa-times" /> <span class="invisible">'+WCF.Language.get("wcf.global.button.delete")+"</span></a></li>"),s=this,n.data("responseID",e).appendTo(t.find("ul.buttonList:eq(0)")).click(function(e){s._delete(e,!0)}))},_initAddResponse:function(e,t){$('<li class="jsCommentShowAddResponse"><a>'+WCF.Language.get("wcf.comment.button.response.add")+"</a></li>").data("commentID",e).click($.proxy(this._showAddResponse,this)).appendTo(this._commentButtonList[e]);this._commentButtonList[e].parent().show()},_showAddResponse:function(e){var t,n,s;e.preventDefault(),null===this._onResponsesLoaded&&(null!==this._responseAdd?null!==(t=this._responseAdd.getContainer())&&(null!==this._responseRevert&&(this._responseRevert(),this._responseRevert=null),n=$(e.currentTarget),s=n.data("commentID"),this._onResponsesLoaded=function(){n.hide(),t.parentNode&&t.parentNode.classList.contains("jsCommentResponseAddContainer")&&elRemove(t.parentNode);var e=this._commentButtonList[s][0].closest(".commentOptionContainer");e.parentNode.insertBefore(t,e.nextSibling),"string"==typeof this._responseCache[s]?this._responseAdd.setContent(this._responseCache[s]):this._responseAdd.setContent(""),this._responseRevert=function(){this._responseCache[s]=this._responseAdd.getContent(),elRemove(t),n.show()}.bind(this),this._onResponsesLoaded=null}.bind(this),n.prev().hasClass("jsCommentLoadNextResponses")?(this._loadResponsesExecute(s,!0),n.parent().children(".button").disable()):this._onResponsesLoaded()):console.error("Missing response API."))},_delete:function(n,s){n.preventDefault(),WCF.System.Confirmation.show(WCF.Language.get("wcf.comment.delete.confirmMessage"),$.proxy(function(e){var t;"confirm"===e&&(t={objectID:this._container.data("objectID"),objectTypeID:this._container.data("objectTypeID")},!0!==s?t.commentID=$(n.currentTarget).data("commentID"):t.responseID=$(n.currentTarget).data("responseID"),this._proxy.setOption("data",{actionName:"remove",className:"wcf\\data\\comment\\CommentAction",parameters:{data:t}}),this._proxy.sendRequest())},this))},_success:function(e,t,n){switch(e.actionName){case"enable":this._enable(e);break;case"enableResponse":this._enableResponse(e);break;case"loadComment":this._insertComment(e);break;case"loadComments":this._insertComments(e);break;case"loadResponse":this._insertResponse(e);break;case"loadResponses":this._insertResponses(e);break;case"remove":this._remove(e)}WCF.DOMNodeInsertedHandler.execute()},_enable:function(e){var t,n,s;!e.returnValues.commentID||(t=elBySel('.comment[data-object-id="'+e.returnValues.commentID+'"]',this._container[0]))&&(elData(t,"is-disabled",0),(n=elBySel(".jsIconDisabled",t))&&elRemove(n),(s=elBySel(".jsEnableComment",t))&&elRemove(s.parentNode))},_enableResponse:function(e){var t,n,s;!e.returnValues.responseID||(t=elBySel('.commentResponse[data-object-id="'+e.returnValues.responseID+'"]',this._container[0]))&&(elData(t,"is-disabled",0),(n=elBySel(".jsIconDisabled",t))&&elRemove(n),(s=elBySel(".jsEnableResponse",t))&&elRemove(s.parentNode))},_insertComment:function(e){var t,n;""!==e.returnValues.template?($(e.returnValues.template).insertBefore(this._permalinkComment),(t=this._permalinkComment.previousElementSibling).classList.add("commentPermalinkContainer"),elRemove(this._permalinkComment),this._permalinkComment=t,e.returnValues.response&&(this._permalinkResponse=elCreate("li"),this._permalinkResponse.className="commentResponsePermalinkContainer loading",this._permalinkResponse.innerHTML='<span class="icon icon32 fa-spinner"></span>',(n=elBySel(".commentResponseList",t)).insertBefore(this._permalinkResponse,n.firstChild),this._insertResponse({returnValues:{template:e.returnValues.response}})),t.offsetTop,t.classList.add("commentHighlightTarget")):elRemove(this._permalinkComment)},_insertResponse:function(e){var t;""!==e.returnValues.template?($(e.returnValues.template).insertBefore(this._permalinkResponse),(t=this._permalinkResponse.previousElementSibling).classList.add("commentResponsePermalinkContainer"),elRemove(this._permalinkResponse),(this._permalinkResponse=t).offsetTop,t.classList.add("commentHighlightTarget")):elRemove(this._permalinkResponse)},_insertComments:function(e){var t;$(e.returnValues.template).insertBefore(this._loadNextComments),this._container.data("lastCommentTime",e.returnValues.lastCommentTime),this._permalinkComment&&(t=elData(this._permalinkComment,"object-id"),null!==elBySel('.comment[data-object-id="'+t+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkComment),this._permalinkComment=null)),this._initComments()},_insertResponses:function(e){var t,n=this._comments[e.returnValues.commentID];$(e.returnValues.template).appendTo(n.find("ul.commentResponseList")),n.data("lastResponseTime",e.returnValues.lastResponseTime),this._handleLoadNextResponses(e.returnValues.commentID),this._permalinkResponse&&(t=elData(this._permalinkResponse,"object-id"),null!==elBySel('.commentResponse[data-object-id="'+t+'"]:not(.commentPermalinkContainer)',this._container[0])&&(elRemove(this._permalinkResponse),this._permalinkResponse=null)),null!==this._onResponsesLoaded&&this._onResponsesLoaded()},_remove:function(e){var t,n,s;e.returnValues.commentID?(this._comments[e.returnValues.commentID].remove(),delete this._comments[e.returnValues.commentID]):(t=this._responses[e.returnValues.responseID],(n=this._comments[t.parents("li.comment:eq(0)").data("commentID")]).data("responses",parseInt(n.data("responses"))-1),s=t.parent(),t.remove(),s.children().length||s.empty(),delete this._responses[e.returnValues.responseID])},_prepareEdit:function(){console.warn("This method is no longer supported.")},_keyUp:function(){console.warn("This method is no longer supported.")},_save:function(){console.warn("This method is no longer supported.")},_failure:function(){console.warn("This method is no longer supported.")},_edit:function(){console.warn("This method is no longer supported.")},_update:function(){console.warn("This method is no longer supported.")},_createGuestDialog:function(){console.warn("This method is no longer supported.")},_keyDown:function(){console.warn("This method is no longer supported.")},_submit:function(){console.warn("This method is no longer supported.")},_keyUpEdit:function(){console.warn("This method is no longer supported.")},_saveEdit:function(){console.warn("This method is no longer supported.")},_cancelEdit:function(){console.warn("This method is no longer supported.")}}),WCF.Comment.Response={}; })(this);
 
 // WCF.ImageViewer.js
-(function (window, undefined) { "use strict";WCF.ImageViewer=Class.extend({_triggerElement:null,init:function(){this._triggerElement=$('<span class="wcfImageViewerTriggerElement" />').data("disableSlideshow",!0).hide().appendTo(document.body),this._triggerElement.wcfImageViewer({enableSlideshow:0,imageSelector:".jsImageViewerEnabled",staticViewer:!0}),WCF.DOMNodeInsertedHandler.addCallback("WCF.ImageViewer",$.proxy(this._domNodeInserted,this)),WCF.DOMNodeInsertedHandler.execute()},_domNodeInserted:function(){this._initImageSizeCheck(),this._rebuildImageViewer()},_rebuildImageViewer:function(){var i=$("a.jsImageViewer");i.length&&i.removeClass("jsImageViewer").addClass("jsImageViewerEnabled").click($.proxy(this._click,this))},_click:function(i){i.ctrlKey||(i.preventDefault(),i.stopPropagation(),$(i.currentTarget).closest(".popover").length||this._triggerElement.wcfImageViewer("open",null,$(i.currentTarget).wcfIdentify()))},_initImageSizeCheck:function(){$(".jsResizeImage").each($.proxy(function(i,e){e.complete&&this._checkImageSize({currentTarget:e})},this)),$(".jsResizeImage").on("load",$.proxy(this._checkImageSize,this))},_checkImageSize:function(i){var e=$(i.currentTarget);if(!e.is(":visible"))return void e.off("load");if(e.removeClass("jsResizeImage"),!e.closest(".messageSignature").length){var t=new Image;t.src=e.attr("src");e.closest("div.messageText, div.messageTextPreview").width()<t.width?e.parents("a").length||(e.wrap('<a href="'+e.attr("src")+'" class="jsImageViewerEnabled embeddedImageLink" />'),e.parent().click($.proxy(this._click,this)),"right"==e.css("float")?e.parent().addClass("messageFloatObjectRight"):"left"==e.css("float")&&e.parent().addClass("messageFloatObjectLeft"),e[0].style.removeProperty("float"),e[0].style.removeProperty("margin")):e.removeClass("embeddedAttachmentLink")}}}),$.widget("ui.wcfImageViewer",{_active:-1,_activeImage:null,_container:null,_didInit:!1,_disableSlideshow:!1,_eventNamespace:"",_images:[],_isMobile:!1,_isOpen:!1,_items:-1,_maxDimensions:{height:0,width:0},_proxy:null,_slideshowEnabled:!1,_thumbnailContainerWidth:0,_thumbnailMarginRight:0,_thumbnailOffset:0,_thumbnailWidth:0,_timer:null,_ui:{buttonNext:null,buttonPrevious:null,header:null,image:null,imageContainer:null,imageList:null,slideshow:{container:null,enlarge:null,next:null,previous:null,toggle:null}},options:{shiftBy:5,enableSlideshow:1,speed:5,className:"",imageSelector:"",staticViewer:!1},_create:function(){this._active=-1,this._activeImage=null,this._container=null,this._didInit=!1,this._disableSlideshow=this.element.data("disableSlideshow"),this._eventNamespace=this.element.wcfIdentify(),this._images=[],this._isMobile=!1,this._isOpen=!1,this._items=-1,this._maxDimensions={height:document.documentElement.clientHeight,width:document.documentElement.clientWidth},this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._slideshowEnabled=!1,this._thumbnailContainerWidth=0,this._thumbnailMarginRight=0,this._thumbnailOffset=0,this._thumbnaiLWidth=0,this._timer=null,this._ui={},this.element.click($.proxy(this.open,this)),window.addEventListener("popstate",function(i){if(null!=i.state&&"imageViewer"===i.state.name&&i.state.container===this._eventNamespace)return this.open(i),void this.showImage(i.state.image);this.close(i)}.bind(this))},open:function(i,e){if(i&&i.preventDefault(),this._isOpen)return!1;if(i&&"popstate"===i.type||window.history.pushState({name:"imageViewer"},"",""),this.options.staticViewer){var t=this._getStaticImages();this._initUI(),this._createThumbnails(t,!0),this._render(!0,void 0,e),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable(),$.browser.touch&&setTimeout($.proxy(function(){this._isMobile&&!this._container.hasClass("maximized")&&this._toggleView()},this),500)}else 0===this._images.length?this._loadNextImages(!0):(this._render(!1,this.element.data("targetImageID")),this._items>1&&this._slideshowEnabled&&this.startSlideshow(),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable());return this._bindListener(),require(["Ui/Screen"],function(i){i.pageOverlayOpen()}),!0},close:function(i){return i&&i.preventDefault(),i&&"popstate"===i.type?!!this._isOpen&&(this._container.removeClass("open"),null!==this._timer&&this._timer.stop(),this._unbindListener(),this._isOpen=!1,WCF.System.DisableScrolling.enable(),WCF.System.DisableZoom.enable(),require(["Ui/Screen"],function(i){i.pageOverlayClose()}),!0):void window.history.back()},startSlideshow:function(){return!this._disableSlideshow&&!this._slideshowEnabled&&(null===this._timer?this._timer=new WCF.PeriodicalExecuter($.proxy(function(){var i=this._active+1;i==this._items&&(i=0),this.showImage(i)},this),1e3*this.options.speed):this._timer.resume(),this._slideshowEnabled=!0,this._ui.slideshow.toggle.children("span").removeClass("fa-play").addClass("fa-pause"),!0)},stopSlideshow:function(i){return!!this._slideshowEnabled&&(this._timer.stop(),i&&this._ui.slideshow.toggle.children("span").removeClass("fa-pause").addClass("fa-play"),this._slideshowEnabled=!1,!0)},_bindListener:function(){$(document).on("keydown."+this._eventNamespace,$.proxy(this._keyDown,this)),$(window).on("resize."+this._eventNamespace,$.proxy(this._renderImage,this))},_unbindListener:function(){$(document).off("keydown."+this._eventNamespace),$(window).off("resize."+this._eventNamespace)},_keyDown:function(i){switch(i.which){case $.ui.keyCode.ESCAPE:this.close();break;case $.ui.keyCode.LEFT:this._previousImage();break;case $.ui.keyCode.RIGHT:this._nextImage();break;case $.ui.keyCode.UP:this._container.hasClass("maximized")||this._toggleView();break;case $.ui.keyCode.DOWN:this._container.hasClass("maximized")&&this._toggleView();break;case $.ui.keyCode.ENTER:var e=this._ui.header.find("h1 > a");1==e.length?window.location=e.prop("href"):this._ui.slideshow.full.trigger("click");break;case 80:this._ui.slideshow.toggle.trigger("click");break;default:return!0}return!1},_render:function(i,e,t){this._container.addClass("open");var s=null;if(i&&(s=this._ui.imageList.children("li:eq(0)"),this._thumbnailMarginRight=parseInt(s.css("marginRight").replace(/px$/,""))||0,this._thumbnailWidth=s.outerWidth(!0),this._thumbnailContainerWidth=this._ui.imageList.parent().innerWidth(),this._items>1&&this.options.enableSlideshow&&!e&&!t&&this.startSlideshow()),e)this._ui.imageList.children("li").each($.proxy(function(i,t){var s=$(t);if(s.data("objectID")==e)return s.trigger("click"),this.moveToImage(s.data("index")),!1},this));else if(t){var a=0;$(this.options.imageSelector).each(function(i,e){if($(e).wcfIdentify()==t)return a=i,!1});var n=this._ui.imageList.children("li:eq("+a+")");if(-1!==this._active){var h=!1;this._active!=n.data("index")&&(h=!0),this._ui.images[this._activeImage].prop("src")!=this._images[this._active].image.url&&(h=!0),h&&(this._active=-1)}n.trigger("click"),this.moveToImage(n.data("index"))}else null!==s&&s.trigger("click");this._toggleButtons(),this._preload()},_preload:function(){if(this._images.length<this._items){this._images.length*this._thumbnailWidth-this._thumbnailOffset<this._thumbnailContainerWidth&&this._loadNextImages(!1)}},_showImage:function(i){this.showImage($(i.currentTarget).data("index"),!0)},showImage:function(i,e){if(this._active==i)return!1;this.stopSlideshow(e||!1),-1!=this._active&&this._images[this._active].listItem.removeClass("active"),this._active=i,window.history.replaceState({name:"imageViewer",container:this._eventNamespace,image:this._active},"","");var t=this._images[i];this._ui.imageList.children("li").removeClass("active"),t.listItem.addClass("active");var s=this._ui.imageContainer.getDimensions("inner"),a=this._activeImage?0:1;null!==this._activeImage&&this._ui.images[this._activeImage].removeClass("active"),this._activeImage=a;var n=this._active;if(this._ui.imageContainer.addClass("loading"),this._ui.images[a].off("load").prop("src","data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="),this._ui.images[a].on("load",$.proxy(function(){this._imageOnLoad(n,a)},this)),this._renderImage(a,t,s),!this.options.staticViewer){this._ui.header.find("> div > a").prop("href",t.user.link).prop("title",t.user.username).children("img").prop("src",t.user.avatarURL)}var h=WCF.String.escapeHTML(t.image.title);if(t.image.link&&(h='<a href="'+t.image.link+'">'+h+"</a>"),this._ui.header.find("h1").html(h),!this.options.staticViewer){var o=t.series&&t.series.title?WCF.String.escapeHTML(t.series.title):"";t.series.link&&(o='<a href="'+t.series.link+'">'+o+"</a>"),this._ui.header.find("h2").html(o)}return this._ui.header.find("h3").text(WCF.Language.get("wcf.imageViewer.seriesIndex").replace(/{x}/,t.listItem.data("index")+1).replace(/{y}/,this._items)),this._ui.slideshow.full.data("link",t.image.fullURL?t.image.fullURL:t.image.url),this.moveToImage(t.listItem.data("index")),this._toggleButtons(),!0},_imageOnLoad:function(i,e){i==this._active&&(this._ui.imageContainer.removeClass("loading"),this._ui.images[e].addClass("active"),this.options.staticViewer&&this._renderImage(e,null),this.startSlideshow())},_renderImage:function(i,e,t){var s=!0;e||(i=this._activeImage,e=this._images[this._active],t={height:$(window).height()-(this._container.hasClass("maximized")||this._container.hasClass("wcfImageViewerMobile")?0:200),width:this._ui.imageContainer.innerWidth()},s=!1),t.height-=22,t.width-=20;var a=this._ui.images[i];if(a.prop("src")!==e.image.url&&a.prop("src",e.image.url),s&&a[0].complete&&a.trigger("load"),this.options.staticViewer&&!e.image.height&&a[0].complete)if($.browser.mozilla||$.browser.safari){var n=new Image;n.src=e.image.url,e.image.height=n.height||a[0].naturalHeight,e.image.width=n.width||a[0].naturalWidth}else a.css({height:"auto",width:"auto"}),e.image.height=a[0].height,e.image.width=a[0].width;var h=e.image.height,o=e.image.width,l=0;h>t.height&&(l=t.height/h,h=t.height,o=Math.floor(o*l)),o>t.width&&(l=t.width/o,o=t.width,h=Math.floor(h*l));var r=Math.floor((t.width-o)/2);this._ui.images[i].css({height:h+"px",left:r+10+"px",marginTop:-1*Math.round(h/2)+"px",width:o+"px"})},_initUI:function(){if(this._didInit)return!1;this._didInit=!0,this._container=$('<div class="wcfImageViewer'+(this.options.staticViewer?" wcfImageViewerStatic":"")+'" />').appendTo(document.body);var i=$("<div><img /><img /></div>").appendTo(this._container),e=$('<footer><span class="wcfImageViewerButtonPrevious icon fa-angle-double-left" /><div><ul /></div><span class="wcfImageViewerButtonNext icon fa-angle-double-right" /></footer>').appendTo(this._container),t=$("<ul />").appendTo(i),s=$('<li class="wcfImageViewerSlideshowButtonPrevious"><span class="icon icon48 fa-angle-left" /></li>').appendTo(t),a=$('<li class="wcfImageViewerSlideshowButtonToggle pointer"><span class="icon icon48 fa-play" /></li>').appendTo(t),n=$('<li class="wcfImageViewerSlideshowButtonNext"><span class="icon icon48 fa-angle-right" /></li>').appendTo(t),h=$('<li class="wcfImageViewerSlideshowButtonEnlarge pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.enlarge")+'"><span class="icon icon48 fa-expand" /></li>').appendTo(t),o=$('<li class="wcfImageViewerSlideshowButtonFull pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.full")+'"><span class="icon icon48 fa-external-link" /></li>').appendTo(t);return this._ui={buttonNext:e.children("span.wcfImageViewerButtonNext"),buttonPrevious:e.children("span.wcfImageViewerButtonPrevious"),header:$("<header><div"+(this.options.staticViewer?">":' class="box64"><a class="jsTooltip"><img /></a>')+"<div><h1 /><h2 /><h3 /></div></div></header>").appendTo(this._container),imageContainer:i,images:[i.children("img:eq(0)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")}),i.children("img:eq(1)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")})],imageList:e.find("> div > ul"),slideshow:{container:t,enlarge:h,full:o,next:n,previous:s,toggle:a}},this._ui.buttonNext.click($.proxy(this._next,this)),this._ui.buttonPrevious.click($.proxy(this._previous,this)),n.click($.proxy(this._nextImage,this)),s.click($.proxy(this._previousImage,this)),h.click($.proxy(this._toggleView,this)),a.click($.proxy(function(){this._items<2||(this._slideshowEnabled?this.stopSlideshow(!0):(this._disableSlideshow=!1,this.startSlideshow()))},this)),o.click(function(i){window.location=$(i.currentTarget).data("link")}),$('<span class="wcfImageViewerButtonClose icon icon48 fa-times pointer jsTooltip" title="'+WCF.Language.get("wcf.global.button.close")+'" />').appendTo(this._ui.header).click($.proxy(this.close,this)),$.browser.mobile||i.click(function(e){e.target===i[0]&&this.close()}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),require(["Ui/Screen"],function(i){i.on("screen-sm-down",{match:$.proxy(this._enableMobileView,this),unmatch:$.proxy(this._disableMobileView,this)})}.bind(this)),!0},_enableMobileView:function(){this._container.addClass("wcfImageViewerMobile");var i=this;this._ui.imageContainer.swipe({swipeLeft:function(e){i._container.hasClass("maximized")&&i._nextImage(e)},swipeRight:function(e){i._container.hasClass("maximized")&&i._previousImage(e)},tap:function(e,t){switch(t.tagName){case"DIV":case"IMG":i._toggleView()}}}),this._isMobile=!0},_disableMobileView:function(){this._container.removeClass("wcfImageViewerMobile"),this._ui.imageContainer.swipe("destroy"),this._isMobile=!1},_toggleView:function(){this._ui.images[this._activeImage].addClass("animateTransformation"),this._container.toggleClass("maximized"),this._ui.slideshow.enlarge.toggleClass("active").children("span").toggleClass("fa-expand").toggleClass("fa-compress"),this._renderImage(null,void 0,null)},_next:function(i,e){if(this._ui.buttonNext.hasClass("pointer")){void 0==e&&this.stopSlideshow(!0);var t=Math.max(this._items*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight,0);this._thumbnailOffset=Math.min(this._thumbnailOffset+this._thumbnailWidth*(e||this.options.shiftBy),t),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)}this._preload(),this._toggleButtons()},_previous:function(i,e){this._ui.buttonPrevious.hasClass("pointer")&&(void 0==e&&this.stopSlideshow(!0),this._thumbnailOffset=Math.max(this._thumbnailOffset-this._thumbnailWidth*(e||this.options.shiftBy),0),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)),this._toggleButtons()},_nextImage:function(i){this._ui.slideshow.next.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active+1),i&&(i.preventDefault(),i.stopPropagation()))},_previousImage:function(i){this._ui.slideshow.previous.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active-1),i&&(i.preventDefault(),i.stopPropagation()))},moveToImage:function(i){var e=(i-3)*this._thumbnailWidth,t=e+5*this._thumbnailWidth,s=this._thumbnailOffset,a=this._thumbnailOffset+this._thumbnailContainerWidth,n=!1;if((e<s||t>a)&&(n=!0),n){var h=0;if(e<s){for(;e<s;)h++,s-=this._thumbnailWidth;this._previous(null,h)}else{for(;t>a;)h++,a+=this._thumbnailWidth;this._next(null,h)}}},_toggleButtons:function(){this._thumbnailOffset>0?this._ui.buttonPrevious.addClass("pointer"):this._ui.buttonPrevious.removeClass("pointer");var i=this._images.length*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight;this._thumbnailOffset>=i?this._ui.buttonNext.removeClass("pointer"):this._ui.buttonNext.addClass("pointer"),this._active>0?this._ui.slideshow.previous.addClass("pointer"):this._ui.slideshow.previous.removeClass("pointer"),this._active+1<this._images.length?this._ui.slideshow.next.addClass("pointer"):this._ui.slideshow.next.removeClass("pointer"),this._items<2?this._ui.slideshow.toggle.removeClass("pointer"):this._ui.slideshow.toggle.addClass("pointer")},_createThumbnails:function(i){this.options.staticViewer&&(this._images=[],this._ui.imageList.empty());for(var e=0,t=i.length;e<t;e++){var s=i[e],a=$('<li class="loading pointer"><img src="'+s.thumbnail.url+'" /></li>').appendTo(this._ui.imageList);a.data("index",this._images.length).data("objectID",s.objectID).click($.proxy(this._showImage,this));var n=a.children("img");if(n.get(0).complete)a.removeClass("loading"),this.options.staticViewer&&this._fixThumbnailDimensions(n);else{var h=this;n.on("load",function(){var i=$(this);i.parent().removeClass("loading"),h.options.staticViewer&&h._fixThumbnailDimensions(i)})}s.listItem=a,this._images.push(s)}},_fixThumbnailDimensions:function(i){var e=new Image;e.src=i.prop("src");var t=e.height,s=e.width;if(t==s)t=s=80;else if(t<s){var a=80/s;s=80,t*=a}else{var a=80/t;t=80,s*=a}i.css({height:t+"px",width:s+"px"})},_loadNextImages:function(i){this._proxy.setOption("data",{actionName:"loadNextImages",className:this.options.className,interfaceName:"wcf\\data\\IImageViewerAction",objectIDs:[this.element.data("objectID")],parameters:{maximumHeight:this._maxDimensions.height,maximumWidth:this._maxDimensions.width,offset:this._images.length,targetImageID:i&&this.element.data("targetImageID")?this.element.data("targetImageID"):0}}),this._proxy.setOption("showLoadingOverlay",!1),this._proxy.sendRequest()},_getStaticImages:function(){var i=[];return $(this.options.imageSelector).each(function(e,t){var s=$(t),a=s.find("> img, .attachmentThumbnailImage > img").first();a.length||(a=s.parentsUntil(".formAttachmentList").last().find(".attachmentTinyThumbnail")),i.push({image:{fullURL:a.data("source")?a.data("source").replace(/\\\//g,"/"):s.prop("href"),link:"",title:s.prop("title"),url:s.prop("href")},series:null,thumbnail:{url:a.prop("src")},user:null})}),this._items=i.length,i},_success:function(i,e,t){i.returnValues.items&&(this._items=i.returnValues.items);var s=this._initUI();this._createThumbnails(i.returnValues.images);var a=i.returnValues.targetImageID?i.returnValues.targetImageID:0;this._render(s,a),this._isOpen||(this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable())}}); })(this);
+(function (window, undefined) { "use strict";WCF.ImageViewer=Class.extend({_triggerElement:null,init:function(){this._triggerElement=$('<span class="wcfImageViewerTriggerElement" />').data("disableSlideshow",!0).hide().appendTo(document.body),this._triggerElement.wcfImageViewer({enableSlideshow:0,imageSelector:".jsImageViewerEnabled",staticViewer:!0}),WCF.DOMNodeInsertedHandler.addCallback("WCF.ImageViewer",$.proxy(this._domNodeInserted,this)),WCF.DOMNodeInsertedHandler.execute()},_domNodeInserted:function(){this._initImageSizeCheck(),this._rebuildImageViewer()},_rebuildImageViewer:function(){var i=$("a.jsImageViewer");i.length&&i.removeClass("jsImageViewer").addClass("jsImageViewerEnabled").click($.proxy(this._click,this))},_click:function(i){i.ctrlKey||(i.preventDefault(),i.stopPropagation(),$(i.currentTarget).closest(".popover").length||this._triggerElement.wcfImageViewer("open",null,$(i.currentTarget).wcfIdentify()))},_initImageSizeCheck:function(){$(".jsResizeImage").each($.proxy(function(i,e){e.complete&&this._checkImageSize({currentTarget:e})},this)),$(".jsResizeImage").on("load",$.proxy(this._checkImageSize,this))},_checkImageSize:function(i){var e,t=$(i.currentTarget);t.is(":visible")?(t.removeClass("jsResizeImage"),t.closest(".messageSignature").length||((e=new Image).src=t.attr("src"),t.closest("div.messageText, div.messageTextPreview").width()<e.width?t.parents("a").length||(t.wrap('<a href="'+t.attr("src")+'" class="jsImageViewerEnabled embeddedImageLink" />'),t.parent().click($.proxy(this._click,this)),"right"==t.css("float")?t.parent().addClass("messageFloatObjectRight"):"left"==t.css("float")&&t.parent().addClass("messageFloatObjectLeft"),t[0].style.removeProperty("float"),t[0].style.removeProperty("margin")):t.removeClass("embeddedAttachmentLink"))):t.off("load")}}),$.widget("ui.wcfImageViewer",{_active:-1,_activeImage:null,_container:null,_didInit:!1,_disableSlideshow:!1,_eventNamespace:"",_images:[],_isMobile:!1,_isOpen:!1,_messageSignature:null,_items:-1,_maxDimensions:{height:0,width:0},_proxy:null,_slideshowEnabled:!1,_thumbnailContainerWidth:0,_thumbnailMarginRight:0,_thumbnailOffset:0,_thumbnailWidth:0,_timer:null,_ui:{buttonNext:null,buttonPrevious:null,header:null,image:null,imageContainer:null,imageList:null,slideshow:{container:null,enlarge:null,next:null,previous:null,toggle:null}},options:{shiftBy:5,enableSlideshow:1,speed:5,className:"",imageSelector:"",staticViewer:!1},_create:function(){this._active=-1,this._activeImage=null,this._container=null,this._didInit=!1,this._disableSlideshow=this.element.data("disableSlideshow"),this._eventNamespace=this.element.wcfIdentify(),this._images=[],this._isMobile=!1,this._isOpen=!1,this._items=-1,this._maxDimensions={height:document.documentElement.clientHeight,width:document.documentElement.clientWidth},this._messageSignature=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._slideshowEnabled=!1,this._thumbnailContainerWidth=0,this._thumbnailMarginRight=0,this._thumbnailOffset=0,this._thumbnaiLWidth=0,this._timer=null,this._ui={},this.element.click($.proxy(this.open,this)),window.addEventListener("popstate",function(i){if(null!=i.state&&"imageViewer"===i.state.name&&i.state.container===this._eventNamespace)return this.open(i),void this.showImage(i.state.image);this.close(i)}.bind(this))},open:function(i,e){return i&&i.preventDefault(),!this._isOpen&&(i&&"popstate"===i.type||window.history.pushState({name:"imageViewer"},"",""),this._messageSignature=null,this.options.staticViewer?(e&&(this._messageSignature=document.getElementById(e).closest(".messageSignature")),this._active=-1,this._activeImage=null,t=this._getStaticImages(),this._initUI(),this._createThumbnails(t,!0),this._render(!0,void 0,e),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable(),$.browser.touch&&setTimeout($.proxy(function(){this._isMobile&&!this._container.hasClass("maximized")&&this._toggleView()},this),500)):0===this._images.length?this._loadNextImages(!0):(this._render(!1,this.element.data("targetImageID")),1<this._items&&this._slideshowEnabled&&this.startSlideshow(),this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable()),this._bindListener(),require(["Ui/Screen"],function(i){i.pageOverlayOpen()}),!0);var t},close:function(i){if(i&&i.preventDefault(),i&&"popstate"===i.type)return!!this._isOpen&&(this._container.removeClass("open"),null!==this._timer&&this._timer.stop(),this._unbindListener(),this._isOpen=!1,WCF.System.DisableScrolling.enable(),WCF.System.DisableZoom.enable(),require(["Ui/Screen"],function(i){i.pageOverlayClose()}),!0);window.history.back()},startSlideshow:function(){return!this._disableSlideshow&&!this._slideshowEnabled&&(null===this._timer?this._timer=new WCF.PeriodicalExecuter($.proxy(function(){var i=this._active+1;i==this._items&&(i=0),this.showImage(i)},this),1e3*this.options.speed):this._timer.resume(),this._slideshowEnabled=!0,this._ui.slideshow.toggle.children("span").removeClass("fa-play").addClass("fa-pause"),!0)},stopSlideshow:function(i){return!!this._slideshowEnabled&&(this._timer.stop(),i&&this._ui.slideshow.toggle.children("span").removeClass("fa-pause").addClass("fa-play"),!(this._slideshowEnabled=!1))},_bindListener:function(){$(document).on("keydown."+this._eventNamespace,$.proxy(this._keyDown,this)),$(window).on("resize."+this._eventNamespace,$.proxy(this._renderImage,this))},_unbindListener:function(){$(document).off("keydown."+this._eventNamespace),$(window).off("resize."+this._eventNamespace)},_keyDown:function(i){switch(i.which){case $.ui.keyCode.ESCAPE:this.close();break;case $.ui.keyCode.LEFT:this._previousImage();break;case $.ui.keyCode.RIGHT:this._nextImage();break;case $.ui.keyCode.UP:this._container.hasClass("maximized")||this._toggleView();break;case $.ui.keyCode.DOWN:this._container.hasClass("maximized")&&this._toggleView();break;case $.ui.keyCode.ENTER:var e=this._ui.header.find("h1 > a");1==e.length?window.location=e.prop("href"):this._ui.slideshow.full.trigger("click");break;case 80:this._ui.slideshow.toggle.trigger("click");break;default:return!0}return!1},_render:function(i,s,t){this._container.addClass("open");var a,n,e,h,o=null;i&&(o=this._ui.imageList.children("li:eq(0)"),this._thumbnailMarginRight=parseInt(o.css("marginRight").replace(/px$/,""))||0,this._thumbnailWidth=o.outerWidth(!0),this._thumbnailContainerWidth=this._ui.imageList.parent().innerWidth(),1<this._items&&this.options.enableSlideshow&&!s&&!t&&this.startSlideshow()),s?this._ui.imageList.children("li").each($.proxy(function(i,e){var t=$(e);if(t.data("objectID")==s)return t.trigger("click"),this.moveToImage(t.data("index")),!1},this)):t?(a=[],$(this.options.imageSelector).each(function(i,e){e.closest(".messageSignature")===this._messageSignature&&a.push(e)}.bind(this)),n=0,a.forEach(function(i,e){i.id===t&&(n=e)}),e=this._ui.imageList.children("li:eq("+n+")"),-1!==this._active&&(h=!1,this._active!=e.data("index")&&(h=!0),this._ui.images[this._activeImage].prop("src")!=this._images[this._active].image.url&&(h=!0),h&&(this._active=-1)),e.trigger("click"),this.moveToImage(e.data("index"))):null!==o&&o.trigger("click"),this._toggleButtons(),this._preload()},_preload:function(){this._images.length<this._items&&this._images.length*this._thumbnailWidth-this._thumbnailOffset<this._thumbnailContainerWidth&&this._loadNextImages(!1)},_showImage:function(i){this.showImage($(i.currentTarget).data("index"),!0)},showImage:function(i,e){if(this._active==i)return!1;this.stopSlideshow(e||!1),-1!=this._active&&this._images[this._active].listItem.removeClass("active"),this._active=i,window.history.replaceState({name:"imageViewer",container:this._eventNamespace,image:this._active},"","");var t=this._images[i];this._ui.imageList.children("li").removeClass("active"),t.listItem.addClass("active");var s=this._ui.imageContainer.getDimensions("inner"),a=this._activeImage?0:1;null!==this._activeImage&&this._ui.images[this._activeImage].removeClass("active"),this._activeImage=a;var n=this._active;this._ui.imageContainer.addClass("loading"),this._ui.images[a].off("load").prop("src","data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="),this._ui.images[a].on("load",$.proxy(function(){this._imageOnLoad(n,a)},this)),this._renderImage(a,t,s),this.options.staticViewer||this._ui.header.find("> div > a").prop("href",t.user.link).prop("title",t.user.username).children("img").prop("src",t.user.avatarURL);var h,o=WCF.String.escapeHTML(t.image.title);return t.image.link&&(o='<a href="'+t.image.link+'">'+o+"</a>"),this._ui.header.find("h1").html(o),this.options.staticViewer||(h=t.series&&t.series.title?WCF.String.escapeHTML(t.series.title):"",t.series.link&&(h='<a href="'+t.series.link+'">'+h+"</a>"),this._ui.header.find("h2").html(h)),this._ui.header.find("h3").text(WCF.Language.get("wcf.imageViewer.seriesIndex").replace(/{x}/,t.listItem.data("index")+1).replace(/{y}/,this._items)),this._ui.slideshow.full.data("link",t.image.fullURL?t.image.fullURL:t.image.url),this.moveToImage(t.listItem.data("index")),this._toggleButtons(),!0},_imageOnLoad:function(i,e){i==this._active&&(this._ui.imageContainer.removeClass("loading"),this._ui.images[e].addClass("active"),this.options.staticViewer&&this._renderImage(e,null),this.startSlideshow())},_renderImage:function(i,e,t){var s=!0;e||(i=this._activeImage,e=this._images[this._active],s=!(t={height:$(window).height()-(this._container.hasClass("maximized")||this._container.hasClass("wcfImageViewerMobile")?0:200),width:this._ui.imageContainer.innerWidth()})),t.height-=22,t.width-=20;var a,n=this._ui.images[i];n.prop("src")!==e.image.url&&n.prop("src",e.image.url),s&&n[0].complete&&n.trigger("load"),this.options.staticViewer&&!e.image.height&&n[0].complete&&($.browser.mozilla||$.browser.safari?((a=new Image).src=e.image.url,e.image.height=a.height||n[0].naturalHeight,e.image.width=a.width||n[0].naturalWidth):(n.css({height:"auto",width:"auto"}),e.image.height=n[0].height,e.image.width=n[0].width));var h=e.image.height,o=e.image.width,l=0;h>t.height&&(l=t.height/h,h=t.height,o=Math.floor(o*l)),o>t.width&&(l=t.width/o,o=t.width,h=Math.floor(h*l));var r=Math.floor((t.width-o)/2);this._ui.images[i].css({height:h+"px",left:r+10+"px",marginTop:-1*Math.round(h/2)+"px",width:o+"px"})},_initUI:function(){if(this._didInit)return!1;this._didInit=!0,this._container=$('<div class="wcfImageViewer'+(this.options.staticViewer?" wcfImageViewerStatic":"")+'" />').appendTo(document.body);var e=$("<div><img /><img /></div>").appendTo(this._container),i=$('<footer><span class="wcfImageViewerButtonPrevious icon fa-angle-double-left" /><div><ul /></div><span class="wcfImageViewerButtonNext icon fa-angle-double-right" /></footer>').appendTo(this._container),t=$("<ul />").appendTo(e),s=$('<li class="wcfImageViewerSlideshowButtonPrevious"><span class="icon icon48 fa-angle-left" /></li>').appendTo(t),a=$('<li class="wcfImageViewerSlideshowButtonToggle pointer"><span class="icon icon48 fa-play" /></li>').appendTo(t),n=$('<li class="wcfImageViewerSlideshowButtonNext"><span class="icon icon48 fa-angle-right" /></li>').appendTo(t),h=$('<li class="wcfImageViewerSlideshowButtonEnlarge pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.enlarge")+'"><span class="icon icon48 fa-expand" /></li>').appendTo(t),o=$('<li class="wcfImageViewerSlideshowButtonFull pointer jsTooltip" title="'+WCF.Language.get("wcf.imageViewer.button.full")+'"><span class="icon icon48 fa-external-link" /></li>').appendTo(t);return this._ui={buttonNext:i.children("span.wcfImageViewerButtonNext"),buttonPrevious:i.children("span.wcfImageViewerButtonPrevious"),header:$("<header><div"+(this.options.staticViewer?">":' class="box64"><a class="jsTooltip"><img /></a>')+"<div><h1 /><h2 /><h3 /></div></div></header>").appendTo(this._container),imageContainer:e,images:[e.children("img:eq(0)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")}),e.children("img:eq(1)").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd",function(){$(this).removeClass("animateTransformation")})],imageList:i.find("> div > ul"),slideshow:{container:t,enlarge:h,full:o,next:n,previous:s,toggle:a}},this._ui.buttonNext.click($.proxy(this._next,this)),this._ui.buttonPrevious.click($.proxy(this._previous,this)),n.click($.proxy(this._nextImage,this)),s.click($.proxy(this._previousImage,this)),h.click($.proxy(this._toggleView,this)),a.click($.proxy(function(){this._items<2||(this._slideshowEnabled?this.stopSlideshow(!0):(this._disableSlideshow=!1,this.startSlideshow()))},this)),o.click(function(i){window.location=$(i.currentTarget).data("link")}),$('<span class="wcfImageViewerButtonClose icon icon48 fa-times pointer jsTooltip" title="'+WCF.Language.get("wcf.global.button.close")+'" />').appendTo(this._ui.header).click($.proxy(this.close,this)),$.browser.mobile||e.click(function(i){i.target===e[0]&&this.close()}.bind(this)),WCF.DOMNodeInsertedHandler.execute(),require(["Ui/Screen"],function(i){i.on("screen-sm-down",{match:$.proxy(this._enableMobileView,this),unmatch:$.proxy(this._disableMobileView,this)})}.bind(this)),!0},_enableMobileView:function(){this._container.addClass("wcfImageViewerMobile");var t=this;this._ui.imageContainer.swipe({swipeLeft:function(i){t._container.hasClass("maximized")&&t._nextImage(i)},swipeRight:function(i){t._container.hasClass("maximized")&&t._previousImage(i)},tap:function(i,e){switch(e.tagName){case"DIV":case"IMG":t._toggleView()}}}),this._isMobile=!0},_disableMobileView:function(){this._container.removeClass("wcfImageViewerMobile"),this._ui.imageContainer.swipe("destroy"),this._isMobile=!1},_toggleView:function(){this._ui.images[this._activeImage].addClass("animateTransformation"),this._container.toggleClass("maximized"),this._ui.slideshow.enlarge.toggleClass("active").children("span").toggleClass("fa-expand").toggleClass("fa-compress"),this._renderImage(null,void 0,null)},_next:function(i,e){var t;this._ui.buttonNext.hasClass("pointer")&&(null==e&&this.stopSlideshow(!0),t=Math.max(this._items*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight,0),this._thumbnailOffset=Math.min(this._thumbnailOffset+this._thumbnailWidth*(e||this.options.shiftBy),t),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)),this._preload(),this._toggleButtons()},_previous:function(i,e){this._ui.buttonPrevious.hasClass("pointer")&&(null==e&&this.stopSlideshow(!0),this._thumbnailOffset=Math.max(this._thumbnailOffset-this._thumbnailWidth*(e||this.options.shiftBy),0),this._ui.imageList.css("marginLeft",-1*this._thumbnailOffset)),this._toggleButtons()},_nextImage:function(i){this._ui.slideshow.next.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active+1),i&&(i.preventDefault(),i.stopPropagation()))},_previousImage:function(i){this._ui.slideshow.previous.hasClass("pointer")&&(this._disableSlideshow=!0,this.stopSlideshow(!0),this.showImage(this._active-1),i&&(i.preventDefault(),i.stopPropagation()))},moveToImage:function(i){var e=(i-3)*this._thumbnailWidth,t=e+5*this._thumbnailWidth,s=this._thumbnailOffset,a=this._thumbnailOffset+this._thumbnailContainerWidth;if(e<s||a<t?!0:!1){var n=0;if(e<s){for(;e<s;)n++,s-=this._thumbnailWidth;this._previous(null,n)}else{for(;a<t;)n++,a+=this._thumbnailWidth;this._next(null,n)}}},_toggleButtons:function(){0<this._thumbnailOffset?this._ui.buttonPrevious.addClass("pointer"):this._ui.buttonPrevious.removeClass("pointer");var i=this._images.length*this._thumbnailWidth-this._thumbnailContainerWidth-this._thumbnailMarginRight;this._thumbnailOffset>=i?this._ui.buttonNext.removeClass("pointer"):this._ui.buttonNext.addClass("pointer"),0<this._active?this._ui.slideshow.previous.addClass("pointer"):this._ui.slideshow.previous.removeClass("pointer"),this._active+1<this._images.length?this._ui.slideshow.next.addClass("pointer"):this._ui.slideshow.next.removeClass("pointer"),this._items<2?this._ui.slideshow.toggle.removeClass("pointer"):this._ui.slideshow.toggle.addClass("pointer")},_createThumbnails:function(i){this.options.staticViewer&&(this._images=[],this._ui.imageList.empty());for(var e=0,t=i.length;e<t;e++){var s=i[e],a=$('<li class="loading pointer"><img src="'+s.thumbnail.url+'" /></li>').appendTo(this._ui.imageList);a.data("index",this._images.length).data("objectID",s.objectID).click($.proxy(this._showImage,this));var n,h=a.children("img");h.get(0).complete?(a.removeClass("loading"),this.options.staticViewer&&this._fixThumbnailDimensions(h)):(n=this,h.on("load",function(){var i=$(this);i.parent().removeClass("loading"),n.options.staticViewer&&n._fixThumbnailDimensions(i)})),s.listItem=a,this._images.push(s)}},_fixThumbnailDimensions:function(i){var e=new Image;e.src=i.prop("src");var t,s=e.height,a=e.width;s==a?s=a=80:s<a?(t=80/a,a=80,s*=t):(t=80/s,s=80,a*=t),i.css({height:s+"px",width:a+"px"})},_loadNextImages:function(i){this._proxy.setOption("data",{actionName:"loadNextImages",className:this.options.className,interfaceName:"wcf\\data\\IImageViewerAction",objectIDs:[this.element.data("objectID")],parameters:{maximumHeight:this._maxDimensions.height,maximumWidth:this._maxDimensions.width,offset:this._images.length,targetImageID:i&&this.element.data("targetImageID")?this.element.data("targetImageID"):0}}),this._proxy.setOption("showLoadingOverlay",!1),this._proxy.sendRequest()},_getStaticImages:function(){var a=[];return $(this.options.imageSelector).each(function(i,e){var t,s;e.closest(".messageSignature")===this._messageSignature&&((s=(t=$(e)).find("> img, .attachmentThumbnailImage > img").first()).length||(s=t.parentsUntil(".formAttachmentList").last().find(".attachmentTinyThumbnail")),a.push({image:{fullURL:s.data("source")?s.data("source").replace(/\\\//g,"/"):t.prop("href"),link:"",title:t.prop("title"),url:t.prop("href")},series:null,thumbnail:{url:s.prop("src")},user:null}))}.bind(this)),this._items=a.length,a},_success:function(i,e,t){i.returnValues.items&&(this._items=i.returnValues.items);var s=this._initUI();this._createThumbnails(i.returnValues.images);var a=i.returnValues.targetImageID?i.returnValues.targetImageID:0;this._render(s,a),this._isOpen||(this._isOpen=!0,WCF.System.DisableScrolling.disable(),WCF.System.DisableZoom.disable())}}); })(this);
 
 // WCF.Label.js
-(function (window, undefined) { "use strict";WCF.Label={},WCF.Label.ACPList=Class.extend({_labelInput:{},_labelList:{},init:function(){},_keyPressed:function(){}}),WCF.Label.ACPList.Connect=Class.extend({init:function(){},_click:function(){}}),WCF.Label.Chooser=Class.extend({_container:null,_groups:{},_showWithoutSelection:!1,init:function(t,e,i,n){if(this._container=null,this._groups={},this._showWithoutSelection=!0===n,this._initContainers(e),$.getLength(t))for(var a in t){var o=this._groups[a];o&&WCF.Dropdown.getDropdownMenu(o.wcfIdentify()).find("> ul > li:not(.dropdownDivider)").each($.proxy(function(e,i){var n=$(i),o=n.data("labelID")||0;o&&t[a]==o&&this._selectLabel(n,!0)},this))}for(var s in this._containers){var l=this._containers[s];void 0===l.data("labelID")&&l.data("labelID",0)}this._container=$(e),i?$(i).click($.proxy(this._submit,this)):this._container.is("form")&&this._container.submit($.proxy(this._submit,this))},_initContainers:function(t){function e(t){t.addEventListener("wheel",function(t){t.preventDefault()},{passive:!1})}$(t).find(".labelChooser").each($.proxy(function(t,i){var n=$(i),a=n.data("groupID");if(!this._groups[a]){var o=n.wcfIdentify(),s=WCF.Dropdown.getDropdownMenu(o);null===s&&(WCF.Dropdown.initDropdown(n.find(".dropdownToggle")),s=WCF.Dropdown.getDropdownMenu(o));var l=s;if("div"==s.getTagName()&&s.children(".scrollableDropdownMenu").length&&(l=$("<ul />").appendTo(s),s=s.children(".scrollableDropdownMenu")),this._groups[a]=n,s.children("li").data("groupID",a).click($.proxy(this._click,this)),n.data("forceSelection")&&!this._showWithoutSelection||$('<li class="dropdownDivider" />').appendTo(l),this._showWithoutSelection){e($('<li data-label-id="-1"><span><span class="badge label">'+WCF.Language.get("wcf.label.withoutSelection")+"</span></span></li>").data("groupID",a).appendTo(l).click($.proxy(this._click,this))[0])}if(!n.data("forceSelection")){var r=$('<li data-label-id="0"><span><span class="badge label">'+WCF.Language.get("wcf.label.none")+"</span></span></li>").data("groupID",a).appendTo(l);r.click($.proxy(this._click,this)),e(r[0])}}},this))},_click:function(t){this._selectLabel($(t.currentTarget),!1)},_selectLabel:function(t,e){var i=this._groups[t.data("groupID")];e&&void 0!==i.data("labelID")||(t.data("labelID")?i.data("labelID",t.data("labelID")):i.data("labelID",0),t=t.find("span > span"),i.find(".dropdownToggle > span").removeClass().addClass(t.attr("class")).text(t.text()),!e&&this._container[0]&&"FORM"===this._container[0].nodeName&&null===elBySel('input:not([type="hidden"]):not([type="submit"]):not([type="reset"]), select, textarea',this._container[0])&&setTimeout(function(){this._container.trigger("submit")}.bind(this),100))},_submit:function(){var t=this._container.find(".formSubmit");t.find('input[type="hidden"]').each(function(t,e){var i=$(e);0===i.attr("name").indexOf("labelIDs[")&&i.remove()});for(var e in this._groups){var i=this._groups[e];i.data("labelID")&&$('<input type="hidden" name="labelIDs['+e+']" value="'+i.data("labelID")+'" />').appendTo(t)}},destroy:function(){for(var t in this._groups)WCF.Dropdown.destroy(this._groups[t].wcfIdentify())}}),WCF.Label.ArticleLabelChooser=WCF.Label.Chooser.extend({_labelGroupsToCategories:{},init:function(){},_updateLabelGroups:function(){},_submit:function(){}}); })(this);
+(function (window, undefined) { "use strict";WCF.Label={},WCF.Label.ACPList=Class.extend({_labelInput:{},_labelList:{},init:function(){},_keyPressed:function(){}}),WCF.Label.ACPList.Connect=Class.extend({init:function(){},_click:function(){}}),WCF.Label.Chooser=Class.extend({_container:null,_groups:{},_showWithoutSelection:!1,init:function(a,t,e,n){if(this._container=null,this._groups={},this._showWithoutSelection=!0===n,this._initContainers(t),$.getLength(a))for(var o in a){var i=this._groups[o];i&&WCF.Dropdown.getDropdownMenu(i.wcfIdentify()).find("> ul > li:not(.dropdownDivider)").each($.proxy(function(t,e){var n=$(e),i=n.data("labelID")||0;i&&a[o]==i&&this._selectLabel(n,!0)},this))}for(var s in this._containers){var l=this._containers[s];void 0===l.data("labelID")&&l.data("labelID",0)}this._container=$(t),e?$(e).click($.proxy(this._submit,this)):this._container.is("form")&&this._container.submit($.proxy(this._submit,this))},_initContainers:function(t){function r(t){t.addEventListener("wheel",function(t){t.preventDefault()},{passive:!1})}$(t).find(".labelChooser").each($.proxy(function(t,e){var n,i,a,o,s=$(e),l=s.data("groupID");this._groups[l]||(n=s.wcfIdentify(),null===(i=WCF.Dropdown.getDropdownMenu(n))&&(WCF.Dropdown.initDropdown(s.find(".dropdownToggle")),i=WCF.Dropdown.getDropdownMenu(n)),"div"==(a=i).getTagName()&&i.children(".scrollableDropdownMenu").length&&(a=$("<ul />").appendTo(i),i=i.children(".scrollableDropdownMenu")),this._groups[l]=s,i.children("li").data("groupID",l).click($.proxy(this._click,this)),s.data("forceSelection")&&!this._showWithoutSelection||$('<li class="dropdownDivider" />').appendTo(a),this._showWithoutSelection&&r($('<li data-label-id="-1"><span><span class="badge label">'+WCF.Language.get("wcf.label.withoutSelection")+"</span></span></li>").data("groupID",l).appendTo(a).click($.proxy(this._click,this))[0]),s.data("forceSelection")||((o=$('<li data-label-id="0"><span><span class="badge label">'+WCF.Language.get("wcf.label.none")+"</span></span></li>").data("groupID",l).appendTo(a)).click($.proxy(this._click,this)),r(o[0])))},this))},_click:function(t){this._selectLabel($(t.currentTarget),!1)},_selectLabel:function(t,e){var n=this._groups[t.data("groupID")];e&&void 0!==n.data("labelID")||(t.data("labelID")?n.data("labelID",t.data("labelID")):n.data("labelID",0),t=t.find("span > span"),n.find(".dropdownToggle > span").removeClass().addClass(t.attr("class")).text(t.text()),!e&&this._container[0]&&"FORM"===this._container[0].nodeName&&null===elBySel('input:not([type="hidden"]):not([type="submit"]):not([type="reset"]), select, textarea',this._container[0])&&setTimeout(function(){this._container.trigger("submit")}.bind(this),100))},_submit:function(){var t=this._container.find(".formSubmit");for(var e in t.find('input[type="hidden"]').each(function(t,e){var n=$(e);0===n.attr("name").indexOf("labelIDs[")&&n.remove()}),this._groups){var n=this._groups[e];n.data("labelID")&&$('<input type="hidden" name="labelIDs['+e+']" value="'+n.data("labelID")+'" />').appendTo(t)}},destroy:function(){for(var t in this._groups)WCF.Dropdown.destroy(this._groups[t].wcfIdentify())}}),WCF.Label.ArticleLabelChooser=WCF.Label.Chooser.extend({_labelGroupsToCategories:{},init:function(){},_updateLabelGroups:function(){},_submit:function(){}}); })(this);
 
 // WCF.Location.js
-(function (window, undefined) { "use strict";function gm_authFailure(){WCF.System.Event.fireEvent("com.woltlab.wcf.googleMaps","authenticationFailure")}WCF.Location={},WCF.Location.Util={getLocation:function(t,e){var o=WCF.Location.GoogleMaps.Settings.get("accessUserLocation");navigator.geolocation&&null!==o&&o?navigator.geolocation.getCurrentPosition(function(e){t(e.coords.latitude,e.coords.longitude)},function(){t(void 0,void 0)},{timeout:e||5e3}):t(void 0,void 0)}},WCF.Location.GoogleMaps={},WCF.Location.GoogleMaps.Settings={_settings:{},get:function(t){return void 0===t?this._settings:void 0!==this._settings[t]?this._settings[t]:null},set:function(t,e){if($.isPlainObject(t))for(var o in t)this._settings[o]=t[o];else this._settings[t]=e}},WCF.Location.GoogleMaps.Map=Class.extend({_map:null,_markers:[],init:function(t,e){this._mapContainer=$("#"+t),this._mapOptions=$.extend(!0,this._getDefaultMapOptions(),e),this._map=new google.maps.Map(this._mapContainer[0],this._mapOptions),this._markers=[],this._mapContainer.parents(".sidebar").length&&require(["Ui/Screen"],function(t){t.on("screen-sm-down",{setup:$.proxy(this._addSidebarMapListener,this)})}.bind(this)),this.refresh()},_addInfoWindowEventListener:function(t,e){google.maps.event.addListener(t,"click",$.proxy(function(){e.open(this._map,t)},this))},_addSidebarMapListener:function(){$(".content > .mobileSidebarToggleButton").click($.proxy(this.refresh,this))},_getDefaultMapOptions:function(){var t={};switch(t.center=new google.maps.LatLng(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),t.disableDoubleClickZoom=WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),t.draggable=WCF.Location.GoogleMaps.Settings.get("draggable"),WCF.Location.GoogleMaps.Settings.get("mapType")){case"map":t.mapTypeId=google.maps.MapTypeId.ROADMAP;break;case"satellite":t.mapTypeId=google.maps.MapTypeId.SATELLITE;break;case"physical":t.mapTypeId=google.maps.MapTypeId.TERRAIN;break;case"hybrid":default:t.mapTypeId=google.maps.MapTypeId.HYBRID}if(t.mapTypeControl="off"!=WCF.Location.GoogleMaps.Settings.get("mapTypeControl"),t.mapTypeControl)switch(WCF.Location.GoogleMaps.Settings.get("mapTypeControl")){case"dropdown":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DROPDOWN_MENU};break;case"horizontalBar":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR};break;default:t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DEFAULT}}return t.scaleControl=WCF.Location.GoogleMaps.Settings.get("scaleControl"),t.scrollwheel=WCF.Location.GoogleMaps.Settings.get("scrollwheel"),t.zoom=WCF.Location.GoogleMaps.Settings.get("zoom"),t},addDraggableMarker:function(t,e){var o=new google.maps.Marker({clickable:!1,draggable:!0,map:this._map,position:new google.maps.LatLng(t,e),zIndex:1});return this._markers.push(o),o},addMarker:function(t,e,o,s,i){var a=new google.maps.Marker({map:this._map,position:new google.maps.LatLng(t,e),title:o});if(s&&a.setIcon(s),i){var n=new google.maps.InfoWindow({content:i});this._addInfoWindowEventListener(a,n),a.infoWindow=n}return this._markers.push(a),a},getMarkers:function(){return this._markers},getMap:function(){return this._map},refresh:function(){var t=this._map.getCenter();google.maps.event.trigger(this._map,"resize"),this._map.setCenter(t)},refreshBounds:function(){var t=null,e=null,o=null,s=null;for(var i in this._markers){var a=this._markers[i],n=a.getPosition().lat(),r=a.getPosition().lng();null===t?(t=e=n,o=s=r):(t>n?t=n:e<n&&(e=n),o>n?o=n:s<r&&(s=r))}this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(t,o),new google.maps.LatLng(e,s)))},removeMarkers:function(){for(var t in this._markers)this._markers[t].setMap(null);this._markers=[]},setBounds:function(t,e){this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(e.latitude,e.longitude),new google.maps.LatLng(t.latitude,t.longitude)))},setCenter:function(t,e){this._map.setCenter(new google.maps.LatLng(t,e))}}),WCF.Location.GoogleMaps.LargeMap=WCF.Location.GoogleMaps.Map.extend({_actionClassName:null,_additionalParameters:{},_locationSearch:null,_locationSearchInputSelector:null,_markerClusterer:null,_objectIDs:[],_previousNorthEast:null,_previousSouthWest:null,_stringifyExcludedObjectIds:!1,init:function(t,e,o,s,i){this._stringifyExcludedObjectIds=!1,e&&e.stringifyExcludedObjectIds&&(this._stringifyExcludedObjectIds=e.stringifyExcludedObjectIds,delete e.stringifyExcludedObjectIds),this._super(t,e),this._actionClassName=o,this._locationSearchInputSelector=s||"",this._additionalParameters=i||{},this._objectIDs=[],this._locationSearchInputSelector&&(this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(s,$.proxy(this._centerMap,this))),this._markerClusterer=new MarkerClusterer(this._map,this._markers,{maxZoom:17,imagePath:WCF.Location.GoogleMaps.Settings.get("markerClustererImagePath")+"m"}),this._markerSpiderfier=new OverlappingMarkerSpiderfier(this._map,{keepSpiderfied:!0,markersWontHide:!0,markersWontMove:!0}),this._markerSpiderfier.addListener("click",$.proxy(function(t){t.infoWindow&&t.infoWindow.open(this._map,t)},this)),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._previousNorthEast=null,this._previousSouthWest=null,google.maps.event.addListener(this._map,"idle",$.proxy(this._loadMarkers,this))},_addInfoWindowEventListener:function(t,e){},_centerMap:function(t){this.setCenter(t.location.lat(),t.location.lng()),$(this._locationSearchInputSelector).val(t.label)},_loadMarkers:function(){var t=this._map.getBounds().getNorthEast(),e=this._map.getBounds().getSouthWest();return!(this._previousNorthEast&&this._previousNorthEast.lat()>=t.lat()&&this._previousNorthEast.lng()>=t.lng()&&this._previousSouthWest.lat()<=e.lat()&&this._previousSouthWest.lng()<=e.lng())&&(this._previousNorthEast=t,this._previousSouthWest=e,this._proxy.setOption("data",{actionName:"getMapMarkers",className:this._actionClassName,parameters:$.extend(this._additionalParameters,{excludedObjectIDs:this._stringifyExcludedObjectIds?JSON.stringify(this._objectIDs):this._objectIDs,eastLongitude:t.lng(),northLatitude:t.lat(),southLatitude:e.lat(),westLongitude:e.lng()})}),this._proxy.sendRequest(),!0)},_success:function(t,e,o){if(t.returnValues&&t.returnValues.markers)for(var s in t.returnValues.markers){var i=t.returnValues.markers[s];this.addMarker(i.latitude,i.longitude,i.title,null,i.infoWindow),i.objectID?this._objectIDs.push(i.objectID):i.objectIDs&&(this._objectIDs=this._objectIDs.concat(i.objectIDs))}},addMarker:function(t,e,o,s,i){var a=this._super(t,e,o,s,i);return this._markerClusterer.addMarker(a),this._markerSpiderfier.addMarker(a),a}}),WCF.Location.GoogleMaps.SuggestionMap=WCF.Location.GoogleMaps.LargeMap.extend({_locationSuggestionsButton:null,_suggestionSelectionCallback:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i);var a=$('<div class="gmnoprint googleMapsCustomControlContainer"><div class="gm-style-mtc"><div class="googleMapsCustomControl">'+WCF.Language.get("wcf.map.showLocationSuggestions")+"</div></div></div>");this._locationSuggestionsButton=a.find(".googleMapsCustomControl").click($.proxy(this._toggleLocationSuggestions,this)),this._map.controls[google.maps.ControlPosition.TOP_RIGHT].push(a.get(0))},_loadMarkers:function(){this._locationSuggestionsButton.hasClass("active")&&(this._super()||(this._loadSuggestions=!1))},_success:function(t,e,o){var s=this._markers.length;this._super(t,e,o),this._loadSuggestions&&s==this._markers.length&&(this._loadSuggestions=!1,new WCF.System.Notification(WCF.Language.get("wcf.map.noLocationSuggestions"),"info").show())},_toggleLocationSuggestions:function(){var t=!this._locationSuggestionsButton.hasClass("active");t&&(this._loadSuggestions=!0),this.showSuggestions(t)},addMarker:function(t,e,o,s,i){var a=$(i),n=$('<a class="googleMapsUseLocationSuggestionLink" />').text(WCF.Language.get("wcf.map.useLocationSuggestion")).click(this._suggestionSelectionCallback);a.append($("<p />").append(n));var r=this._super(t,e,o,"//mt.google.com/vt/icon/name=icons/spotlight/spotlight-waypoint-a.png",a.get(0));return n.data("marker",r),r},setSuggestionSelectionCallback:function(t){this._suggestionSelectionCallback=t},showSuggestions:function(t){void 0===t&&(t=!0),this._locationSuggestionsButton.toggleClass("active",t);for(var e=[],o=0,s=this._markers.length;o<s;o++){var i=this._markers[o];i.draggable||(i.setVisible(t),t&&e.push(i))}this._markerClusterer.clearMarkers(),t&&this._markerClusterer.addMarkers(e),this._loadMarkers()}}),WCF.Location.GoogleMaps.LocationSearch=WCF.Search.Base.extend({_geocoder:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i),this.setDelay(500),this._geocoder=new google.maps.Geocoder},_createListItem:function(t){var e=$("<li><span>"+WCF.String.escapeHTML(t.formatted_address)+"</span></li>").appendTo(this._list);return e.data("location",t.geometry.location).data("label",t.formatted_address).click($.proxy(this._executeCallback,this)),this._itemCount++,e},_keyUp:function(t){switch(t.which){case $.ui.keyCode.LEFT:case $.ui.keyCode.RIGHT:return;case $.ui.keyCode.UP:return void this._selectPreviousItem();case $.ui.keyCode.DOWN:return void this._selectNextItem();case $.ui.keyCode.ENTER:return this._selectElement(t)}var e=this._getSearchString(t);""===e?this._clearList(!0):e.length>=this._triggerLength?this._delay?(null!==this._timer&&this._timer.stop(),this._timer=new WCF.PeriodicalExecuter($.proxy(function(){this._geocoder.geocode({address:e},$.proxy(this._success,this)),this._timer.stop(),this._timer=null},this),this._delay)):this._geocoder.geocode({address:e},$.proxy(this._success,this)):this._clearList(!1)},_success:function(t,e){if(this._clearList(!1),e==google.maps.GeocoderStatus.OK){if($.getLength(t)){var o=0;for(var s in t)if(this._createListItem(t[s]),10==++o)break}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var i=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(i).hasClass("dropdownOpen")||WCF.Dropdown.toggleDropdown(i,!0),this._itemIndex=-1,WCF.Dropdown.getDropdown(i).data("disableAutoFocus")||this._selectNextItem()}}}),WCF.Location.GoogleMaps.LocationInput=Class.extend({_locationSearch:null,_map:null,_marker:null,init:function(t,e,o,s,i,a){this._searchInput=o,a?(this._map=new WCF.Location.GoogleMaps.SuggestionMap(t,e,a),this._map.setSuggestionSelectionCallback($.proxy(this._useSuggestion,this))):this._map=new WCF.Location.GoogleMaps.Map(t,e),this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(o,$.proxy(this._setMarkerByLocation,this)),s&&i?this._marker=this._map.addDraggableMarker(s,i):(this._marker=this._map.addDraggableMarker(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),WCF.Location.Util.getLocation($.proxy(function(t,e){void 0!==t&&void 0!==e&&(WCF.Location.GoogleMaps.Util.moveMarker(this._marker,t,e),WCF.Location.GoogleMaps.Util.focusMarker(this._marker))},this))),this._marker.addListener("dragend",$.proxy(this._updateLocation,this))},_useSuggestion:function(t){var e=$(t.currentTarget).data("marker");this._marker.setPosition(e.getPosition()),this._updateLocation(),this._map.showSuggestions(!1)},_updateLocation:function(){WCF.Location.GoogleMaps.Util.reverseGeocoding($.proxy(function(t){null!==t&&$(this._searchInput).val(t)},this),this._marker)},_setMarkerByLocation:function(t){this._marker.setPosition(t.location),WCF.Location.GoogleMaps.Util.focusMarker(this._marker),$(this._searchInput).val(t.label)},getMap:function(){return this._map},getMarker:function(){return this._marker}}),WCF.Location.GoogleMaps.Util={_geocoder:null,focusMarker:function(t){t.getMap().setCenter(t.getPosition())},getMarkerPosition:function(t){return{latitude:t.getPosition().lat(),longitude:t.getPosition().lng()}},moveMarker:function(t,e,o,s){t.setPosition(new google.maps.LatLng(e,o)),s&&google.maps.event.trigger(t,"dragend")},reverseGeocoding:function(t,e,o,s,i){e&&(o=e.getPosition().lat(),s=e.getPosition().lng()),null===this._geocoder&&(this._geocoder=new google.maps.Geocoder);var a=new google.maps.LatLng(o,s);this._geocoder.geocode({latLng:a},function(e,o){t(o==google.maps.GeocoderStatus.OK?i?e:e[0].formatted_address:null)})}}; })(this);
+(function (window, undefined) { "use strict";function gm_authFailure(){WCF.System.Event.fireEvent("com.woltlab.wcf.googleMaps","authenticationFailure")}WCF.Location={},WCF.Location.Util={getLocation:function(e,t){var o=WCF.Location.GoogleMaps.Settings.get("accessUserLocation");navigator.geolocation&&null!==o&&o?navigator.geolocation.getCurrentPosition(function(t){e(t.coords.latitude,t.coords.longitude)},function(){e(void 0,void 0)},{timeout:t||5e3}):e(void 0,void 0)}},WCF.Location.GoogleMaps={},WCF.Location.GoogleMaps.Settings={_settings:{},get:function(t){return void 0===t?this._settings:void 0!==this._settings[t]?this._settings[t]:null},set:function(t,e){if($.isPlainObject(t))for(var o in t)this._settings[o]=t[o];else this._settings[t]=e}},WCF.Location.GoogleMaps.Map=Class.extend({_map:null,_markers:[],init:function(t,e){this._mapContainer=$("#"+t),this._mapOptions=$.extend(!0,this._getDefaultMapOptions(),e),this._map=new google.maps.Map(this._mapContainer[0],this._mapOptions),this._markers=[],this._mapContainer.parents(".sidebar").length&&require(["Ui/Screen"],function(t){t.on("screen-sm-down",{setup:$.proxy(this._addSidebarMapListener,this)})}.bind(this)),this.refresh()},_addInfoWindowEventListener:function(t,e){google.maps.event.addListener(t,"click",$.proxy(function(){e.open(this._map,t)},this))},_addSidebarMapListener:function(){$(".content > .mobileSidebarToggleButton").click($.proxy(this.refresh,this))},_getDefaultMapOptions:function(){var t={};switch(t.center=new google.maps.LatLng(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),t.disableDoubleClickZoom=WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),t.draggable=WCF.Location.GoogleMaps.Settings.get("draggable"),WCF.Location.GoogleMaps.Settings.get("mapType")){case"map":t.mapTypeId=google.maps.MapTypeId.ROADMAP;break;case"satellite":t.mapTypeId=google.maps.MapTypeId.SATELLITE;break;case"physical":t.mapTypeId=google.maps.MapTypeId.TERRAIN;break;case"hybrid":default:t.mapTypeId=google.maps.MapTypeId.HYBRID}if(t.mapTypeControl="off"!=WCF.Location.GoogleMaps.Settings.get("mapTypeControl"),t.mapTypeControl)switch(WCF.Location.GoogleMaps.Settings.get("mapTypeControl")){case"dropdown":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DROPDOWN_MENU};break;case"horizontalBar":t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.HORIZONTAL_BAR};break;default:t.mapTypeControlOptions={style:google.maps.MapTypeControlStyle.DEFAULT}}return t.scaleControl=WCF.Location.GoogleMaps.Settings.get("scaleControl"),t.scrollwheel=WCF.Location.GoogleMaps.Settings.get("scrollwheel"),t.zoom=WCF.Location.GoogleMaps.Settings.get("zoom"),t},addDraggableMarker:function(t,e){var o=new google.maps.Marker({clickable:!1,draggable:!0,map:this._map,position:new google.maps.LatLng(t,e),zIndex:1});return this._markers.push(o),o},addMarker:function(t,e,o,s,i){var a,n=new google.maps.Marker({map:this._map,position:new google.maps.LatLng(t,e),title:o});return s&&n.setIcon(s),i&&(a=new google.maps.InfoWindow({content:i}),this._addInfoWindowEventListener(n,a),n.infoWindow=a),this._markers.push(n),n},getMarkers:function(){return this._markers},getMap:function(){return this._map},refresh:function(){var t=this._map.getCenter();google.maps.event.trigger(this._map,"resize"),this._map.setCenter(t)},refreshBounds:function(){var t=null,e=null,o=null,s=null;for(var i in this._markers){var a=this._markers[i],n=a.getPosition().lat(),r=a.getPosition().lng();null===t?(t=e=n,o=s=r):(n<t?t=n:e<n&&(e=n),n<o?o=n:s<r&&(s=r))}this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(t,o),new google.maps.LatLng(e,s)))},removeMarkers:function(){for(var t in this._markers)this._markers[t].setMap(null);this._markers=[]},setBounds:function(t,e){this._map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(e.latitude,e.longitude),new google.maps.LatLng(t.latitude,t.longitude)))},setCenter:function(t,e){this._map.setCenter(new google.maps.LatLng(t,e))}}),WCF.Location.GoogleMaps.LargeMap=WCF.Location.GoogleMaps.Map.extend({_actionClassName:null,_additionalParameters:{},_locationSearch:null,_locationSearchInputSelector:null,_markerClusterer:null,_objectIDs:[],_previousNorthEast:null,_previousSouthWest:null,_stringifyExcludedObjectIds:!1,init:function(t,e,o,s,i){this._stringifyExcludedObjectIds=!1,e&&e.stringifyExcludedObjectIds&&(this._stringifyExcludedObjectIds=e.stringifyExcludedObjectIds,delete e.stringifyExcludedObjectIds),this._super(t,e),this._actionClassName=o,this._locationSearchInputSelector=s||"",this._additionalParameters=i||{},this._objectIDs=[],this._locationSearchInputSelector&&(this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(s,$.proxy(this._centerMap,this))),this._markerClusterer=new MarkerClusterer(this._map,this._markers,{maxZoom:17,imagePath:WCF.Location.GoogleMaps.Settings.get("markerClustererImagePath")+"m"}),this._markerSpiderfier=new OverlappingMarkerSpiderfier(this._map,{keepSpiderfied:!0,markersWontHide:!0,markersWontMove:!0}),this._markerSpiderfier.addListener("click",$.proxy(function(t){t.infoWindow&&t.infoWindow.open(this._map,t)},this)),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)}),this._previousNorthEast=null,this._previousSouthWest=null,google.maps.event.addListener(this._map,"idle",$.proxy(this._loadMarkers,this))},_addInfoWindowEventListener:function(t,e){},_centerMap:function(t){this.setCenter(t.location.lat(),t.location.lng()),$(this._locationSearchInputSelector).val(t.label)},_loadMarkers:function(){var t=this._map.getBounds().getNorthEast(),e=this._map.getBounds().getSouthWest();return!(this._previousNorthEast&&this._previousNorthEast.lat()>=t.lat()&&this._previousNorthEast.lng()>=t.lng()&&this._previousSouthWest.lat()<=e.lat()&&this._previousSouthWest.lng()<=e.lng())&&(this._previousNorthEast=t,this._previousSouthWest=e,this._proxy.setOption("data",{actionName:"getMapMarkers",className:this._actionClassName,parameters:$.extend(this._additionalParameters,{excludedObjectIDs:this._stringifyExcludedObjectIds?JSON.stringify(this._objectIDs):this._objectIDs,eastLongitude:t.lng(),northLatitude:t.lat(),southLatitude:e.lat(),westLongitude:e.lng()})}),this._proxy.sendRequest(),!0)},_success:function(t,e,o){if(t.returnValues&&t.returnValues.markers)for(var s in t.returnValues.markers){var i=t.returnValues.markers[s];this.addMarker(i.latitude,i.longitude,i.title,null,i.infoWindow),i.objectID?this._objectIDs.push(i.objectID):i.objectIDs&&(this._objectIDs=this._objectIDs.concat(i.objectIDs))}},addMarker:function(t,e,o,s,i){var a=this._super(t,e,o,s,i);return this._markerClusterer.addMarker(a),this._markerSpiderfier.addMarker(a),a}}),WCF.Location.GoogleMaps.SuggestionMap=WCF.Location.GoogleMaps.LargeMap.extend({_locationSuggestionsButton:null,_suggestionSelectionCallback:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i);var a=$('<div class="gmnoprint googleMapsCustomControlContainer"><div class="gm-style-mtc"><div class="googleMapsCustomControl">'+WCF.Language.get("wcf.map.showLocationSuggestions")+"</div></div></div>");this._locationSuggestionsButton=a.find(".googleMapsCustomControl").click($.proxy(this._toggleLocationSuggestions,this)),this._map.controls[google.maps.ControlPosition.TOP_RIGHT].push(a.get(0))},_loadMarkers:function(){this._locationSuggestionsButton.hasClass("active")&&(this._super()||(this._loadSuggestions=!1))},_success:function(t,e,o){var s=this._markers.length;this._super(t,e,o),this._loadSuggestions&&s==this._markers.length&&(this._loadSuggestions=!1,new WCF.System.Notification(WCF.Language.get("wcf.map.noLocationSuggestions"),"info").show())},_toggleLocationSuggestions:function(){var t=!this._locationSuggestionsButton.hasClass("active");t&&(this._loadSuggestions=!0),this.showSuggestions(t)},addMarker:function(t,e,o,s,i){var a=$(i),n=$('<a class="googleMapsUseLocationSuggestionLink" />').text(WCF.Language.get("wcf.map.useLocationSuggestion")).click(this._suggestionSelectionCallback);a.append($("<p />").append(n));var r=this._super(t,e,o,"//mt.google.com/vt/icon/name=icons/spotlight/spotlight-waypoint-a.png",a.get(0));return n.data("marker",r),r},setSuggestionSelectionCallback:function(t){this._suggestionSelectionCallback=t},showSuggestions:function(t){void 0===t&&(t=!0),this._locationSuggestionsButton.toggleClass("active",t);for(var e=[],o=0,s=this._markers.length;o<s;o++){var i=this._markers[o];i.draggable||(i.setVisible(t),t&&e.push(i))}this._markerClusterer.clearMarkers(),t&&this._markerClusterer.addMarkers(e),this._loadMarkers()}}),WCF.Location.GoogleMaps.LocationSearch=WCF.Search.Base.extend({_geocoder:null,init:function(t,e,o,s,i){this._super(t,e,o,s,i),this.setDelay(500),this._geocoder=new google.maps.Geocoder},_createListItem:function(t){var e=$("<li><span>"+WCF.String.escapeHTML(t.formatted_address)+"</span></li>").appendTo(this._list);return e.data("location",t.geometry.location).data("label",t.formatted_address).click($.proxy(this._executeCallback,this)),this._itemCount++,e},_keyUp:function(t){switch(t.which){case $.ui.keyCode.LEFT:case $.ui.keyCode.RIGHT:return;case $.ui.keyCode.UP:return void this._selectPreviousItem();case $.ui.keyCode.DOWN:return void this._selectNextItem();case $.ui.keyCode.ENTER:return this._selectElement(t)}var e=this._getSearchString(t);""===e?this._clearList(!0):e.length>=this._triggerLength?this._delay?(null!==this._timer&&this._timer.stop(),this._timer=new WCF.PeriodicalExecuter($.proxy(function(){this._geocoder.geocode({address:e},$.proxy(this._success,this)),this._timer.stop(),this._timer=null},this),this._delay)):this._geocoder.geocode({address:e},$.proxy(this._success,this)):this._clearList(!1)},_success:function(t,e){if(this._clearList(!1),e==google.maps.GeocoderStatus.OK){if($.getLength(t)){var o=0;for(var s in t)if(this._createListItem(t[s]),10==++o)break}else if(!this._handleEmptyResult())return;WCF.CloseOverlayHandler.addCallback("WCF.Search.Base",$.proxy(function(){this._clearList()},this));var i=this._searchInput.parents(".dropdown").wcfIdentify();WCF.Dropdown.getDropdownMenu(i).hasClass("dropdownOpen")||WCF.Dropdown.toggleDropdown(i,!0),this._itemIndex=-1,WCF.Dropdown.getDropdown(i).data("disableAutoFocus")||this._selectNextItem()}}}),WCF.Location.GoogleMaps.LocationInput=Class.extend({_locationSearch:null,_map:null,_marker:null,init:function(t,e,o,s,i,a){this._searchInput=o,a?(this._map=new WCF.Location.GoogleMaps.SuggestionMap(t,e,a),this._map.setSuggestionSelectionCallback($.proxy(this._useSuggestion,this))):this._map=new WCF.Location.GoogleMaps.Map(t,e),this._locationSearch=new WCF.Location.GoogleMaps.LocationSearch(o,$.proxy(this._setMarkerByLocation,this)),s&&i?this._marker=this._map.addDraggableMarker(s,i):(this._marker=this._map.addDraggableMarker(WCF.Location.GoogleMaps.Settings.get("defaultLatitude"),WCF.Location.GoogleMaps.Settings.get("defaultLongitude")),WCF.Location.Util.getLocation($.proxy(function(t,e){void 0!==t&&void 0!==e&&(WCF.Location.GoogleMaps.Util.moveMarker(this._marker,t,e),WCF.Location.GoogleMaps.Util.focusMarker(this._marker))},this))),this._marker.addListener("dragend",$.proxy(this._updateLocation,this))},_useSuggestion:function(t){var e=$(t.currentTarget).data("marker");this._marker.setPosition(e.getPosition()),this._updateLocation(),this._map.showSuggestions(!1)},_updateLocation:function(){WCF.Location.GoogleMaps.Util.reverseGeocoding($.proxy(function(t){null!==t&&$(this._searchInput).val(t)},this),this._marker)},_setMarkerByLocation:function(t){this._marker.setPosition(t.location),WCF.Location.GoogleMaps.Util.focusMarker(this._marker),$(this._searchInput).val(t.label)},getMap:function(){return this._map},getMarker:function(){return this._marker}}),WCF.Location.GoogleMaps.Util={_geocoder:null,focusMarker:function(t){t.getMap().setCenter(t.getPosition())},getMarkerPosition:function(t){return{latitude:t.getPosition().lat(),longitude:t.getPosition().lng()}},moveMarker:function(t,e,o,s){t.setPosition(new google.maps.LatLng(e,o)),s&&google.maps.event.trigger(t,"dragend")},reverseGeocoding:function(o,t,e,s,i){t&&(e=t.getPosition().lat(),s=t.getPosition().lng()),null===this._geocoder&&(this._geocoder=new google.maps.Geocoder);var a=new google.maps.LatLng(e,s);this._geocoder.geocode({latLng:a},function(t,e){e==google.maps.GeocoderStatus.OK?o(i?t:t[0].formatted_address):o(null)})}}; })(this);
 
 // WCF.Message.js
-(function (window, undefined) { "use strict";WCF.Message={},WCF.Message.BBCode={},WCF.Message.BBCode.CodeViewer=Class.extend({init:function(){}}),WCF.Message.EditHistory=Class.extend({_oldIDInputs:{},_newIDInputs:{},_containerSelector:"",_buttonSelector:"",init:function(){},_initInputs:function(){},_initElements:function(){},_click:function(){},_sendRequest:function(){},_success:function(){}}),WCF.Message.FormGuard=Class.extend({init:function(){var e=$("form.jsFormGuard").removeClass("jsFormGuard").submit(function(){$(this).find(".formSubmit input[type=submit]").disable()});$(window).on("unload",function(){e.find(".formSubmit input[type=submit]").enable()})}}),WCF.Message.Preview=Class.extend({_className:"",_messageFieldID:"",_messageField:{},_proxy:{},_previewButton:{},_previewButtonLabel:"",init:function(){},_click:function(){},_getParameters:function(){},_getMessage:function(){},_success:function(){},_handleResponse:function(){},_failure:function(){}}),WCF.Message.DefaultPreview=WCF.Message.Preview.extend({_dialog:{},_options:{},init:function(){},_handleResponse:function(){},_getParameters:function(){},_dialogSetup:function(){},_className:"",_messageFieldID:"",_messageField:{},_proxy:{},_previewButton:{},_previewButtonLabel:"",_click:function(){},_getMessage:function(){},_success:function(){},_failure:function(){}}),WCF.Message.Multilingualism=Class.extend({_availableLanguages:{},_languageID:0,_languageInput:{},init:function(){},_click:function(){},_disable:function(){},_updateLabel:function(){},_submit:function(){}}),WCF.Message.SmileyCategories=Class.extend({_cache:{},_proxy:{},_wysiwygSelector:"",init:function(){},_click:function(){},_success:function(){}}),WCF.Message.Smilies=Class.extend({_editorId:"",init:function(){},_smileyClick:function(){}}),WCF.Message.InlineEditor=Class.extend({_container:{},_containerID:0,_dropdowns:{},_messageContainerSelector:"",_messageEditorIDPrefix:"",init:function(){},_click:function(){},_initDropdownMenu:function(){},_callbackDropdownInit:function(){},_getClassName:function(){}}),WCF.Message.Submit={_buttons:{},registerButton:function(){},execute:function(){}},WCF.Message.Quote={},WCF.Message.Quote.Handler=Class.extend({_activeContainerID:"",_className:"",_containers:{},_containerSelector:"",_copyQuote:{},_message:"",_messageBodySelector:"",_objectID:0,_objectType:"",_proxy:{},_quoteManager:{},init:function(){},_initContainers:function(){},_mouseDown:function(){},_getNodeText:function(){},_mouseUp:function(){},_normalize:function(){},_getBoundingRectangle:function(){},_initCopyQuote:function(){},_getSelectedText:function(){},_saveFullQuote:function(){},_saveQuote:function(){},_saveAndInsertQuote:function(){},_success:function(){},updateFullQuoteObjectIDs:function(){}}),WCF.Message.Quote.Manager=Class.extend({_buttons:{},_count:0,_dialog:{},_editorId:"",_editorIdAlternative:"",_form:{},_handlers:{},_hasTemplate:!1,_insertQuotes:!0,_proxy:{},_removeOnSubmit:{},_supportPaste:!1,init:function(){},setAlternativeEditor:function(){},clearAlternativeEditor:function(){},register:function(){},updateCount:function(){},insertQuotes:function(){},_toggleShowQuotes:function(){},_click:function(){},renderDialog:function(){},_changeButtons:function(){},_change:function(){},_insertSelected:function(){},_insertQuote:function(){},_removeSelected:function(){},_submit:function(){},getQuotesMarkedForRemoval:function(){},markQuotesForRemoval:function(){},removeMarkedQuotes:function(){},countQuotes:function(){},_success:function(){},supportPaste:function(){}}),WCF.Message.Share={},WCF.Message.Share.Content=Class.extend({_cache:{},_dialog:null,_shareButtonsTemplate:"",init:function(e){this._shareButtonsTemplate=e||"",this._cache={},this._dialog=null,this._initLinks(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Message.Share.Content",$.proxy(this._initLinks,this))},_initLinks:function(){$("a.jsButtonShare").removeClass("jsButtonShare").click($.proxy(this._click,this))},_click:function(e){e.preventDefault();var t=$(e.currentTarget),n=t.prop("href"),i=t.data("linkTitle")?t.data("linkTitle"):n,a=n.hashCode();if(void 0===this._cache[a]){var s=!1;null===this._dialog?(this._dialog=$('<div id="shareContentDialog" />').hide().appendTo(document.body),s=!0):this._dialog.empty();var o=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalink">'+WCF.Language.get("wcf.message.share.permalink")+"</label></h2></section>").appendTo(this._dialog);$('<input type="text" id="__sharePermalink" class="long" readonly />').attr("value",n).appendTo(o);var o=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkBBCode">'+WCF.Language.get("wcf.message.share.permalink.bbcode")+"</label></h2></section>").appendTo(this._dialog);$('<input type="text" id="__sharePermalinkBBCode" class="long" readonly />').attr("value","[url='"+n+"']"+i+"[/url]").appendTo(o);var o=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkHTML">'+WCF.Language.get("wcf.message.share.permalink.html")+"</label></h2></section>").appendTo(this._dialog);$('<input type="text" id="__sharePermalinkHTML" class="long" readonly />').attr("value",'<a href="'+n+'">'+WCF.String.escapeHTML(i)+"</a>").appendTo(o),""!==this._shareButtonsTemplate&&(o=$('<section class="section"><h2 class="sectionTitle">'+WCF.Language.get("wcf.message.share")+"</h2>"+this._shareButtonsTemplate+"</section>").appendTo(this._dialog),elData(o.children(".jsMessageShareButtons")[0],"url",WCF.String.escapeHTML(n))),this._cache[a]=this._dialog.html(),s?this._dialog.wcfDialog({title:WCF.Language.get("wcf.message.share")}):this._dialog.wcfDialog("open")}else this._dialog.html(this._cache[a]).wcfDialog("open");this._enableSelection()},_enableSelection:function(){var e=this._dialog.find("input").click(function(){$(this).select()});navigator.userAgent.match(/iP(ad|hone|od)/)&&e.keydown(function(){return!1}).removeAttr("readonly").click(function(){this.setSelectionRange(0,9999)})}}),WCF.Message.Share.Page=Class.extend({init:function(){require(["WoltLabSuite/Core/Ui/Message/Share"],function(e){e.init()})}}),WCF.Message.UserMention=Class.extend({init:function(){throw new Error("Support for mentions in Redactor are now enabled by adding the attribute 'data-support-mention=\"true\"' to the textarea element.")}}),$.widget("wcf.messageTabMenu",{_tabs:[],_tabsByName:{},options:{collapsible:!0},_create:function(){var e=this.element.find("> nav"),t=e.find("> ul > li:not(.jsFlexibleMenuDropdown)"),n=this.element.find("> div, > fieldset");if(t.length!=n.length)return void console.debug("[wcf.messageTabMenu] Amount of tabs does not equal amount of tab containers, aborting.");var i=this.element.data("preselect");n.each(function(e,n){if(null!==elBySel(".innerError",n))return i=$(t[e]).data("name"),!1}),"true"===i&&(i=!0),this._tabs=[],this._tabsByName={};for(var a=0;a<t.length;a++){var s=$(t[a]),o=$(n[a]),l=s.data("name");if(void 0===l){var c=s.children("a").prop("href");void 0!==c&&c.match(/#([a-zA-Z_-]+)$/)&&(l=RegExp.$1),void 0===l&&(l=s.wcfIdentify())}this._tabs.push({container:o,name:l,tab:s}),this._tabsByName[l]=a;var r=s.children("a").data("index",a).on("mousedown",this._showTab.bind(this));r.attr("role","button").attr("tabindex","0").attr("aria-haspopup",!0).attr("aria-expanded",!1).attr("aria-controls",o[0].id),r.on("keydown",function(e){13!==e.which&&32!==e.which||(e.preventDefault(),this._showTab(e))}.bind(this)),(i===l||!0===i&&0===a)&&r.trigger("mousedown")}!0===i&&this._tabs.length&&!window.matchMedia("(max-width: 544px)").matches&&this._tabs[0].tab.children("a").trigger("click");var u=this.element.data("collapsible");void 0!==u&&(this.options.collapsible=u);var d=elData(this.element[0],"wysiwyg-container-id");d&&WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+d,function(){for(var e=0,t=this._tabs.length;e<t;e++)this._tabs[e].container.removeClass("active"),this._tabs[e].tab.removeClass("active")}.bind(this))},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this.element.remove()},_showTab:function(e,t,n){var i=null===e?t:$(e.currentTarget).data("index");n=!this.options.collapsible||!0===n;for(var a=null,s=0;s<this._tabs.length;s++){var o=this._tabs[s];if(s==i){if(!o.tab.hasClass("active")){o.tab.addClass("active"),o.container.addClass("active"),a=o,o.tab.children("a").attr("aria-expanded",!0);var l=o.container[0];if(null===elBySel(".messageTabMenuContent.active",l)&&null!==elBySel(".messageTabMenuContent",l)){var c=elBySel("nav > ul > li[data-name] > a",l);null!==c&&$(c).trigger("mousedown")}continue}if(!0===n)continue}o.tab.removeClass("active"),o.container.removeClass("active"),o.tab.children("a").attr("aria-expanded",!1)}null!==e&&(e.preventDefault(),e.stopPropagation()),null!==a&&this._trigger("show",{},{activeTab:a}),$(window).trigger("resize")},showTab:function(e,t){if($.isNumeric(e)||void 0!==this._tabsByName[e]&&(e=this._tabsByName[e]),void 0===this._tabs[e])return void console.debug("[wcf.messageTabMenu] Cannot locate tab identified by '"+e+"'");this._showTab(null,e,t)},getTab:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].tab:null},getContainer:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].container:null}}); })(this);
+(function (window, undefined) { "use strict";WCF.Message={},WCF.Message.BBCode={},WCF.Message.BBCode.CodeViewer=Class.extend({init:function(){}}),WCF.Message.EditHistory=Class.extend({_oldIDInputs:{},_newIDInputs:{},_containerSelector:"",_buttonSelector:"",init:function(){},_initInputs:function(){},_initElements:function(){},_click:function(){},_sendRequest:function(){},_success:function(){}}),WCF.Message.FormGuard=Class.extend({init:function(){var e=$("form.jsFormGuard").removeClass("jsFormGuard").submit(function(){$(this).find(".formSubmit input[type=submit]").disable()});$(window).on("unload",function(){e.find(".formSubmit input[type=submit]").enable()})}}),WCF.Message.Preview=Class.extend({_className:"",_messageFieldID:"",_messageField:{},_proxy:{},_previewButton:{},_previewButtonLabel:"",init:function(){},_click:function(){},_getParameters:function(){},_getMessage:function(){},_success:function(){},_handleResponse:function(){},_failure:function(){}}),WCF.Message.DefaultPreview=WCF.Message.Preview.extend({_dialog:{},_options:{},init:function(){},_handleResponse:function(){},_getParameters:function(){},_dialogSetup:function(){},_className:"",_messageFieldID:"",_messageField:{},_proxy:{},_previewButton:{},_previewButtonLabel:"",_click:function(){},_getMessage:function(){},_success:function(){},_failure:function(){}}),WCF.Message.Multilingualism=Class.extend({_availableLanguages:{},_languageID:0,_languageInput:{},init:function(){},_click:function(){},_disable:function(){},_updateLabel:function(){},_submit:function(){}}),WCF.Message.SmileyCategories=Class.extend({_cache:{},_proxy:{},_wysiwygSelector:"",init:function(){},_click:function(){},_success:function(){}}),WCF.Message.Smilies=Class.extend({_editorId:"",init:function(){},_smileyClick:function(){}}),WCF.Message.InlineEditor=Class.extend({_container:{},_containerID:0,_dropdowns:{},_messageContainerSelector:"",_messageEditorIDPrefix:"",init:function(){},_click:function(){},_initDropdownMenu:function(){},_callbackDropdownInit:function(){},_getClassName:function(){}}),WCF.Message.Submit={_buttons:{},registerButton:function(){},execute:function(){}},WCF.Message.Quote={},WCF.Message.Quote.Handler=Class.extend({_activeContainerID:"",_className:"",_containers:{},_containerSelector:"",_copyQuote:{},_message:"",_messageBodySelector:"",_objectID:0,_objectType:"",_proxy:{},_quoteManager:{},init:function(){},_initContainers:function(){},_mouseDown:function(){},_getNodeText:function(){},_mouseUp:function(){},_normalize:function(){},_getBoundingRectangle:function(){},_initCopyQuote:function(){},_getSelectedText:function(){},_saveFullQuote:function(){},_saveQuote:function(){},_saveAndInsertQuote:function(){},_success:function(){},updateFullQuoteObjectIDs:function(){}}),WCF.Message.Quote.Manager=Class.extend({_buttons:{},_count:0,_dialog:{},_editorId:"",_editorIdAlternative:"",_form:{},_handlers:{},_hasTemplate:!1,_insertQuotes:!0,_proxy:{},_removeOnSubmit:{},_supportPaste:!1,init:function(){},setAlternativeEditor:function(){},clearAlternativeEditor:function(){},register:function(){},updateCount:function(){},insertQuotes:function(){},_toggleShowQuotes:function(){},_click:function(){},renderDialog:function(){},_changeButtons:function(){},_change:function(){},_insertSelected:function(){},_insertQuote:function(){},_removeSelected:function(){},_submit:function(){},getQuotesMarkedForRemoval:function(){},markQuotesForRemoval:function(){},removeMarkedQuotes:function(){},countQuotes:function(){},_success:function(){},supportPaste:function(){}}),WCF.Message.Share={},WCF.Message.Share.Content=Class.extend({_cache:{},_dialog:null,_shareButtonsTemplate:"",init:function(e){this._shareButtonsTemplate=e||"",this._cache={},this._dialog=null,this._initLinks(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Message.Share.Content",$.proxy(this._initLinks,this))},_initLinks:function(){$("a.jsButtonShare").removeClass("jsButtonShare").click($.proxy(this._click,this))},_click:function(e){e.preventDefault();var t,n,i=$(e.currentTarget),a=i.prop("href"),s=i.data("linkTitle")?i.data("linkTitle"):a,o=a.hashCode();void 0===this._cache[o]?(t=!1,null===this._dialog?(this._dialog=$('<div id="shareContentDialog" />').hide().appendTo(document.body),t=!0):this._dialog.empty(),n=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalink">'+WCF.Language.get("wcf.message.share.permalink")+"</label></h2></section>").appendTo(this._dialog),$('<input type="text" id="__sharePermalink" class="long" readonly />').attr("value",a).appendTo(n),n=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkBBCode">'+WCF.Language.get("wcf.message.share.permalink.bbcode")+"</label></h2></section>").appendTo(this._dialog),$('<input type="text" id="__sharePermalinkBBCode" class="long" readonly />').attr("value","[url='"+a+"']"+s+"[/url]").appendTo(n),n=$('<section class="section"><h2 class="sectionTitle"><label for="__sharePermalinkHTML">'+WCF.Language.get("wcf.message.share.permalink.html")+"</label></h2></section>").appendTo(this._dialog),$('<input type="text" id="__sharePermalinkHTML" class="long" readonly />').attr("value",'<a href="'+a+'">'+WCF.String.escapeHTML(s)+"</a>").appendTo(n),""!==this._shareButtonsTemplate&&(n=$('<section class="section"><h2 class="sectionTitle">'+WCF.Language.get("wcf.message.share")+"</h2>"+this._shareButtonsTemplate+"</section>").appendTo(this._dialog),elData(n.children(".jsMessageShareButtons")[0],"url",WCF.String.escapeHTML(a))),this._cache[o]=this._dialog.html(),t?this._dialog.wcfDialog({title:WCF.Language.get("wcf.message.share")}):this._dialog.wcfDialog("open")):this._dialog.html(this._cache[o]).wcfDialog("open"),this._enableSelection()},_enableSelection:function(){var e=this._dialog.find("input").click(function(){$(this).select()});navigator.userAgent.match(/iP(ad|hone|od)/)&&e.keydown(function(){return!1}).removeAttr("readonly").click(function(){this.setSelectionRange(0,9999)})}}),WCF.Message.Share.Page=Class.extend({init:function(){require(["WoltLabSuite/Core/Ui/Message/Share"],function(e){e.init()})}}),WCF.Message.UserMention=Class.extend({init:function(){throw new Error("Support for mentions in Redactor are now enabled by adding the attribute 'data-support-mention=\"true\"' to the textarea element.")}}),$.widget("wcf.messageTabMenu",{_tabs:[],_tabsByName:{},options:{collapsible:!0},_create:function(){var n=this.element.find("> nav").find("> ul > li:not(.jsFlexibleMenuDropdown)"),e=this.element.find("> div, > fieldset");if(n.length==e.length){var i=this.element.data("preselect");e.each(function(e,t){if(null!==elBySel(".innerError",t))return i=$(n[e]).data("name"),!1}),"true"===i&&(i=!0),this._tabs=[],this._tabsByName={};for(var t=0;t<n.length;t++){var a,s=$(n[t]),o=$(e[t]),l=s.data("name");void 0===l&&(void 0!==(a=s.children("a").prop("href"))&&a.match(/#([a-zA-Z_-]+)$/)&&(l=RegExp.$1),void 0===l&&(l=s.wcfIdentify())),this._tabs.push({container:o,name:l,tab:s}),this._tabsByName[l]=t;var c=s.children("a").data("index",t).on("mousedown",this._showTab.bind(this));c.attr("role","button").attr("tabindex","0").attr("aria-haspopup",!0).attr("aria-expanded",!1).attr("aria-controls",o[0].id),c.on("keydown",function(e){13!==e.which&&32!==e.which||(e.preventDefault(),this._showTab(e))}.bind(this)),(i===l||!0===i&&0===t)&&c.trigger("mousedown")}!0===i&&this._tabs.length&&!window.matchMedia("(max-width: 544px)").matches&&this._tabs[0].tab.children("a").trigger("click");var r=this.element.data("collapsible");void 0!==r&&(this.options.collapsible=r);var u=elData(this.element[0],"wysiwyg-container-id");u&&WCF.System.Event.addListener("com.woltlab.wcf.redactor2","reset_"+u,function(){for(var e=0,t=this._tabs.length;e<t;e++)this._tabs[e].container.removeClass("active"),this._tabs[e].tab.removeClass("active")}.bind(this))}else console.debug("[wcf.messageTabMenu] Amount of tabs does not equal amount of tab containers, aborting.")},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments),this.element.remove()},_showTab:function(e,t,n){var i=null===e?t:$(e.currentTarget).data("index");n=!this.options.collapsible||!0===n;for(var a=null,s=0;s<this._tabs.length;s++){var o=this._tabs[s];if(s==i){if(!o.tab.hasClass("active")){o.tab.addClass("active"),o.container.addClass("active"),(a=o).tab.children("a").attr("aria-expanded",!0);var l,c=o.container[0];null!==elBySel(".messageTabMenuContent.active",c)||null===elBySel(".messageTabMenuContent",c)||null!==(l=elBySel("nav > ul > li[data-name] > a",c))&&$(l).trigger("mousedown");continue}if(!0===n)continue}o.tab.removeClass("active"),o.container.removeClass("active"),o.tab.children("a").attr("aria-expanded",!1)}null!==e&&(e.preventDefault(),e.stopPropagation()),null!==a&&this._trigger("show",{},{activeTab:a}),$(window).trigger("resize")},showTab:function(e,t){$.isNumeric(e)||void 0!==this._tabsByName[e]&&(e=this._tabsByName[e]),void 0!==this._tabs[e]?this._showTab(null,e,t):console.debug("[wcf.messageTabMenu] Cannot locate tab identified by '"+e+"'")},getTab:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].tab:null},getContainer:function(e){return void 0!==this._tabsByName[e]?this._tabs[this._tabsByName[e]].container:null}}); })(this);
 
 // WCF.Poll.js
-(function (window, undefined) { "use strict";WCF.Poll={},WCF.Poll.Management=Class.extend({_container:{},_count:0,_editorId:"",_maxOptions:0,init:function(){},_createOptionList:function(){},_createOption:function(){},_keyDown:function(){},_addOption:function(){},_removeOption:function(){},_submit:function(){},_reset:function(){},_validate:function(){}}),WCF.Poll.Manager=Class.extend({_cache:{},_canViewParticipants:{},_canViewResult:{},_canVote:{},_inputElements:{},_participants:{},_polls:{},_proxy:null,init:function(t){var e=$(t);if(!e.length)return void console.debug("[WCF.Poll.Manager] Given selector '"+t+"' does not match, aborting.");this._cache={},this._canViewParticipants={},this._canViewResult={},this._inputElements={},this._participants={},this._polls={},this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),url:"index.php?poll/&t="+SECURITY_TOKEN});var i=this;e.each(function(t,e){var o=$(e),n=o.data("pollID");void 0===i._polls[n]&&(i._cache[n]={result:"",vote:""},i._polls[n]=o,i._canViewParticipants[n]=!!o.data("canViewParticipants"),i._canViewResult[n]=!!o.data("canViewResult"),i._canVote[n]=!!o.data("canVote"),i._bindListeners(n),o.data("inVote")&&i._prepareVote(n),i._toggleButtons(n))})},_bindListeners:function(t){this._polls[t].find(".jsButtonPollShowParticipants").data("pollID",t).click($.proxy(this._showParticipants,this)),this._polls[t].find(".jsButtonPollShowResult").data("pollID",t).click($.proxy(this._showResult,this)),this._polls[t].find(".jsButtonPollShowVote").data("pollID",t).click($.proxy(this._showVote,this)),this._polls[t].find(".jsButtonPollVote").data("pollID",t).click($.proxy(this._vote,this))},_showResult:function(t,e){var i=null===t?e:$(t.currentTarget).data("pollID");this._canViewResult[i]&&this._polls[i].data("inVote")&&(this._cache[i].result?(this._polls[i].find(".pollInnerContainer").html(this._cache[i].result),this._polls[i].data("inVote",!1),this._toggleButtons(i)):(this._proxy.setOption("data",{actionName:"getResult",pollID:i}),this._proxy.sendRequest()))},_showParticipants:function(t){var e=$(t.currentTarget).data("pollID");this._participants[e]||(this._participants[e]=new WCF.User.List("wcf\\data\\poll\\PollAction",this._polls[e].data("question"),{pollID:e})),this._participants[e].open()},_showVote:function(t,e){var i=null===t?e:$(t.currentTarget).data("pollID");this._canVote[i]&&(this._polls[i].data("inVote")||(this._cache[i].vote?(this._polls[i].find(".pollInnerContainer").html(this._cache[i].vote),this._polls[i].data("inVote",!0),this._prepareVote(i),this._toggleButtons(i)):(this._proxy.setOption("data",{actionName:"getVote",pollID:i}),this._proxy.sendRequest())))},_success:function(t,e,i){if(t&&t.actionName){var o=t.pollID;switch(t.resultTemplate&&(this._cache[o].result=t.resultTemplate),t.voteTemplate&&(this._cache[o].vote=t.voteTemplate),t.actionName){case"getResult":this._showResult(null,o);break;case"getVote":this._showVote(null,o);break;case"vote":this._canViewResult[o]=!0,this._canVote[o]=!!t.canVote,this._polls[o].data("isPublic")&&(this._canViewParticipants[o]=!0),this._showResult(null,o)}}},_prepareVote:function(t){this._polls[t].find(".jsButtonPollVote").disable();var e=this._polls[t].find(".pollInnerContainer > .jsPollVote"),i=this;this._inputElements[t]=e.find("input").change(function(){i._handleVoteButton(t)}),this._handleVoteButton(t);var o=e.data("maxVotes");this._inputElements[t].filter("[type=checkbox]").length&&(this._inputElements[t].change(function(){i._enforceMaxVotes(t,o)}),this._enforceMaxVotes(t,o))},_enforceMaxVotes:function(t,e){var i=this._inputElements[t];i.filter(":checked").length==e?i.filter(":not(:checked)").disable():i.enable()},_handleVoteButton:function(t){var e=this._inputElements[t],i=this._polls[t].find(".jsButtonPollVote");e.filter(":checked").length?i.enable():i.disable()},_toggleButtons:function(t){var e=this._polls[t].children(".formSubmit");e.find(".jsButtonPollShowParticipants, .jsButtonPollShowResult, .jsButtonPollShowVote, .jsButtonPollVote").hide();var i=!0;this._polls[t].data("inVote")?(i=!1,e.find(".jsButtonPollVote").show(),this._canViewResult[t]&&e.find(".jsButtonPollShowResult").show()):(this._canVote[t]&&(i=!1,e.find(".jsButtonPollShowVote").show()),this._canViewParticipants[t]&&(i=!1,e.find(".jsButtonPollShowParticipants").show())),i&&e.hide()},_vote:function(t){var e=$(t.currentTarget).data("pollID");if(this._canVote[e]){var i=[];this._inputElements[e].each(function(t,e){var o=$(e);o.is(":checked")&&i.push(o.data("optionID"))}),i.length&&(this._proxy.setOption("data",{actionName:"vote",optionIDs:i,pollID:e}),this._proxy.sendRequest())}}}); })(this);
+(function (window, undefined) { "use strict";WCF.Poll={},WCF.Poll.Management=Class.extend({_container:{},_count:0,_editorId:"",_maxOptions:0,init:function(){},_createOptionList:function(){},_createOption:function(){},_keyDown:function(){},_addOption:function(){},_removeOption:function(){},_submit:function(){},_reset:function(){},_validate:function(){}}),WCF.Poll.Manager=Class.extend({_cache:{},_canViewParticipants:{},_canViewResult:{},_canVote:{},_inputElements:{},_participants:{},_polls:{},_proxy:null,init:function(t){var s,e=$(t);e.length?(this._cache={},this._canViewParticipants={},this._canViewResult={},this._inputElements={},this._participants={},this._polls={},this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),url:"index.php?poll/&t="+SECURITY_TOKEN}),s=this,e.each(function(t,e){var o=$(e),i=o.data("pollID");void 0===s._polls[i]&&(s._cache[i]={result:"",vote:""},s._polls[i]=o,s._canViewParticipants[i]=!!o.data("canViewParticipants"),s._canViewResult[i]=!!o.data("canViewResult"),s._canVote[i]=!!o.data("canVote"),s._bindListeners(i),o.data("inVote")&&s._prepareVote(i),s._toggleButtons(i))})):console.debug("[WCF.Poll.Manager] Given selector '"+t+"' does not match, aborting.")},_bindListeners:function(t){this._polls[t].find(".jsButtonPollShowParticipants").data("pollID",t).click($.proxy(this._showParticipants,this)),this._polls[t].find(".jsButtonPollShowResult").data("pollID",t).click($.proxy(this._showResult,this)),this._polls[t].find(".jsButtonPollShowVote").data("pollID",t).click($.proxy(this._showVote,this)),this._polls[t].find(".jsButtonPollVote").data("pollID",t).click($.proxy(this._vote,this))},_showResult:function(t,e){var o=null===t?e:$(t.currentTarget).data("pollID");this._canViewResult[o]&&this._polls[o].data("inVote")&&(this._cache[o].result?(this._polls[o].find(".pollInnerContainer").html(this._cache[o].result),this._polls[o].data("inVote",!1),this._toggleButtons(o)):(this._proxy.setOption("data",{actionName:"getResult",pollID:o}),this._proxy.sendRequest()))},_showParticipants:function(t){var e=$(t.currentTarget).data("pollID");this._participants[e]||(this._participants[e]=new WCF.User.List("wcf\\data\\poll\\PollAction",this._polls[e].data("question"),{pollID:e})),this._participants[e].open()},_showVote:function(t,e){var o=null===t?e:$(t.currentTarget).data("pollID");this._canVote[o]&&(this._polls[o].data("inVote")||(this._cache[o].vote?(this._polls[o].find(".pollInnerContainer").html(this._cache[o].vote),this._polls[o].data("inVote",!0),this._prepareVote(o),this._toggleButtons(o)):(this._proxy.setOption("data",{actionName:"getVote",pollID:o}),this._proxy.sendRequest())))},_success:function(t,e,o){if(t&&t.actionName){var i=t.pollID;switch(t.resultTemplate&&(this._cache[i].result=t.resultTemplate),t.voteTemplate&&(this._cache[i].vote=t.voteTemplate),t.actionName){case"getResult":this._showResult(null,i);break;case"getVote":this._showVote(null,i);break;case"vote":this._canViewResult[i]=!0,this._canVote[i]=!!t.canVote,this._polls[i].data("isPublic")&&(this._canViewParticipants[i]=!0);var s=elBySel(".jsPollTotalVotes",this._polls[i][0]);s.textContent=WCF.String.formatNumeric(t.totalVotes),elData(s,"tooltip",t.totalVotesTooltip),this._showResult(null,i)}}},_prepareVote:function(t){this._polls[t].find(".jsButtonPollVote").disable();var e=this._polls[t].find(".pollInnerContainer > .jsPollVote"),o=this;this._inputElements[t]=e.find("input").change(function(){o._handleVoteButton(t)}),this._handleVoteButton(t);var i=e.data("maxVotes");this._inputElements[t].filter("[type=checkbox]").length&&(this._inputElements[t].change(function(){o._enforceMaxVotes(t,i)}),this._enforceMaxVotes(t,i))},_enforceMaxVotes:function(t,e){var o=this._inputElements[t];o.filter(":checked").length==e?o.filter(":not(:checked)").disable():o.enable()},_handleVoteButton:function(t){var e=this._inputElements[t],o=this._polls[t].find(".jsButtonPollVote");e.filter(":checked").length?o.enable():o.disable()},_toggleButtons:function(t){var e=this._polls[t].children(".formSubmit");e.find(".jsButtonPollShowParticipants, .jsButtonPollShowResult, .jsButtonPollShowVote, .jsButtonPollVote").hide();var o=!0;this._polls[t].data("inVote")?(o=!1,e.find(".jsButtonPollVote").show(),this._canViewResult[t]&&e.find(".jsButtonPollShowResult").show()):(this._canVote[t]&&(o=!1,e.find(".jsButtonPollShowVote").show()),this._canViewParticipants[t]&&(o=!1,e.find(".jsButtonPollShowParticipants").show())),o&&e.hide()},_vote:function(t){var i,e=$(t.currentTarget).data("pollID");this._canVote[e]&&(i=[],this._inputElements[e].each(function(t,e){var o=$(e);o.is(":checked")&&i.push(o.data("optionID"))}),i.length&&(this._proxy.setOption("data",{actionName:"vote",optionIDs:i,pollID:e}),this._proxy.sendRequest()))}}); })(this);
 
 // WCF.Search.Message.js
-(function (window, undefined) { "use strict";WCF.Search.Message={},WCF.Search.Message.KeywordList=WCF.Search.Base.extend({_className:"wcf\\data\\search\\keyword\\SearchKeywordAction",_divider:null,_forceSubmit:!1,init:function(e,i,s){if(!$.isFunction(i))return void console.debug("[WCF.Search.Message.KeywordList] The given callback is invalid, aborting.");this._callback=i,this._excludedSearchValues=[],s&&(this._excludedSearchValues=s),this._searchInput=$(e).keyup($.proxy(this._keyUp,this)).keydown($.proxy(function(e){13===e.which&&this._itemCount&&-1!==this._itemIndex&&e.preventDefault()},this));var t=WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify()),r=t.find("li.dropdownDivider").last();this._divider=$('<li class="dropdownDivider" />').hide().insertBefore(r),this._list=$('<li class="dropdownList"><ul /></li>').hide().insertBefore(r).children("ul"),t.find("input, label").on("click",function(e){e.stopPropagation()}),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)})},_createListItem:function(e){this._divider.show(),this._list.parent().show(),this._super(e)},_clearList:function(e){e&&this._searchInput.val(""),this._divider.hide(),this._list.empty().parent().hide(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1}}); })(this);
+(function (window, undefined) { "use strict";WCF.Search.Message={},WCF.Search.Message.KeywordList=WCF.Search.Base.extend({_className:"wcf\\data\\search\\keyword\\SearchKeywordAction",_divider:null,_forceSubmit:!1,init:function(e,i,s){var t,r;$.isFunction(i)?(this._callback=i,this._excludedSearchValues=[],s&&(this._excludedSearchValues=s),this._searchInput=$(e).keyup($.proxy(this._keyUp,this)).keydown($.proxy(function(e){13===e.which&&this._itemCount&&-1!==this._itemIndex&&e.preventDefault()},this)),r=(t=WCF.Dropdown.getDropdownMenu(this._searchInput.parents(".dropdown").wcfIdentify())).find("li.dropdownDivider").last(),this._divider=$('<li class="dropdownDivider" />').hide().insertBefore(r),this._list=$('<li class="dropdownList"><ul /></li>').hide().insertBefore(r).children("ul"),t.find("input, label").on("click",function(e){e.stopPropagation()}),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1,success:$.proxy(this._success,this)})):console.debug("[WCF.Search.Message.KeywordList] The given callback is invalid, aborting.")},_createListItem:function(e){this._divider.show(),this._list.parent().show(),this._super(e)},_clearList:function(e){e&&this._searchInput.val(""),this._divider.hide(),this._list.empty().parent().hide(),WCF.CloseOverlayHandler.removeCallback("WCF.Search.Base"),this._itemCount=0,this._itemIndex=-1}}); })(this);
 
 // WCF.User.js
-(function (window, undefined) { "use strict";WCF.User.Login=Class.extend({_loginSubmitButton:null,_password:null,_passwordContainer:null,_useCookies:null,_useCookiesContainer:null,init:function(e){this._loginSubmitButton=$("#loginSubmitButton"),this._password=$("#password"),this._passwordContainer=this._password.parents("dl"),this._useCookies=$("#useCookies"),this._useCookiesContainer=this._useCookies.parents("dl"),$("#loginForm").find("input[name=action]").change($.proxy(this._change,this)),e&&WCF.User.QuickLogin.init()},_change:function(e){"register"===$(e.currentTarget).val()?this._setState(!1,WCF.Language.get("wcf.user.button.register")):this._setState(!0,WCF.Language.get("wcf.user.button.login"))},_setState:function(e,t){e?(this._password.enable(),this._passwordContainer.removeClass("disabled"),this._useCookies.enable(),this._useCookiesContainer.removeClass("disabled")):(this._password.disable(),this._passwordContainer.addClass("disabled"),this._useCookies.disable(),this._useCookiesContainer.addClass("disabled")),this._loginSubmitButton.val(t)}}),WCF.User.Panel={},WCF.User.Panel.Abstract=Class.extend({_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},init:function(){},toggle:function(){},_dblClick:function(){},_initDropdown:function(){},_load:function(){},_success:function(){},_markAsRead:function(){},_markAllAsRead:function(){},updateBadge:function(){},resetItems:function(){}}),WCF.User.Panel.Notification=WCF.User.Panel.Abstract.extend({_favico:{},init:function(){},_initDropdown:function(){},_load:function(){},_markAsRead:function(){},_markAllAsRead:function(){},resetItems:function(){},updateBadge:function(){},updateUserNotificationCount:function(){},_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},toggle:function(){},_dblClick:function(){},_success:function(){}}),WCF.User.Panel.UserMenu=WCF.User.Panel.Abstract.extend({init:function(){},_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},toggle:function(){},_dblClick:function(){},_initDropdown:function(){},_load:function(){},_success:function(){},_markAsRead:function(){},_markAllAsRead:function(){},updateBadge:function(){},resetItems:function(){}}),WCF.User.QuickLogin={init:function(){require(["EventHandler","Ui/Dialog"],function(e,t){var i=elById("loginForm"),s=elBySel(".loginFormLogin",i);s&&!s.nextElementSibling&&i.classList.add("loginFormLoginOnly");for(var n=elBySel(".loginFormRegister",i),a=function(e){if(e instanceof Event&&(e.preventDefault(),e.stopPropagation()),i.style.removeProperty("display"),t.openStatic("loginForm",null,{title:WCF.Language.get("wcf.user.login")}),null!==s&&null!==n){var a=s.offsetTop,o=0;if(i.clientWidth>2*s.clientWidth)for(;a<n.offsetTop-50;)o+=100,s.style.setProperty("margin-bottom",o+"px","")}},o=document.getElementsByClassName("loginLink"),r=0,l=o.length;r<l;r++)o[r].addEventListener(WCF_CLICK_EVENT,a);var c=i.querySelector("#loginForm input[name=url]");null===c||c.value.match(/^https?:\/\//)||c.setAttribute("value",window.location.protocol+"//"+window.location.host+c.getAttribute("value")),e.add("com.woltlab.wcf.UserMenuMobile","more",function(e){"com.woltlab.wcf.login"===e.identifier&&(e.handler.close(!0),a())})})}},WCF.User.Profile={},WCF.User.Profile.ActivityPointList={_cache:{},_dialog:null,_didInit:!1,_proxy:null,init:function(){this._didInit||(this._cache={},this._dialog=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.User.Profile.ActivityPointList",$.proxy(this._init,this)),this._didInit=!0)},_init:function(){$(".activityPointsDisplay").removeClass("activityPointsDisplay").click($.proxy(this._click,this))},_click:function(e){e.preventDefault();var t=$(e.currentTarget).data("userID");void 0===this._cache[t]?(this._proxy.setOption("data",{actionName:"getDetailedActivityPointList",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[t]}),this._proxy.sendRequest()):this._show(t)},_show:function(e){null===this._dialog?(this._dialog=$("<div>"+this._cache[e]+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.user.activityPoint")})):(this._dialog.html(this._cache[e]),this._dialog.wcfDialog("open"))},_success:function(e,t,i){this._cache[e.returnValues.userID]=e.returnValues.template,this._show(e.returnValues.userID)}},WCF.User.Profile.TabMenu=Class.extend({_hasContent:{},_profileContent:null,_proxy:null,_userID:0,init:function(e){this._profileContent=$("#profileContent"),this._userID=e;var t=this._profileContent.data("active"),i=!1;this._profileContent.find("div.tabMenuContent").each($.proxy(function(e,s){var n=$(s).wcfIdentify();t===n?this._hasContent[n]=!0:(this._hasContent[n]=!1,i=!0)},this)),i&&(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._profileContent.on("wcftabsbeforeactivate",$.proxy(this._loadContent,this)),this._profileContent.find("> nav.tabMenu > ul > li").each($.proxy(function(e,t){var i=$(t);if(i.hasClass("ui-state-active"))return e&&this._loadContent(null,{newPanel:$("#"+i.attr("aria-controls"))}),!1},this))),$('.userProfileUser .contentDescription a[href$="#likes"]').click(function(e){e.preventDefault(),require(["Ui/TabMenu"],function(e){e.getTabMenu("profileContent").select("likes")})}.bind(this))},_loadContent:function(e,t){var i=$(t.newPanel),s=i.attr("id");this._hasContent[s]||(this._proxy.setOption("data",{actionName:"getContent",className:"wcf\\data\\user\\profile\\menu\\item\\UserProfileMenuItemAction",parameters:{data:{containerID:s,menuItem:i.data("menuItem"),userID:this._userID}}}),this._proxy.sendRequest())},_success:function(e,t,i){var s=e.returnValues.containerID;this._hasContent[s]=!0,require(["Dom/ChangeListener","Dom/Util"],function(t,i){i.insertHtml(e.returnValues.template,elById(s),"append"),t.trigger()})}}),WCF.User.Profile.Editor=Class.extend({_actionName:"",_active:!1,_buttons:{},_cachedTemplate:"",_proxy:{},_tab:{},_userID:0,init:function(){},_initButtons:function(){},_beginEdit:function(){},_save:function(){},_restore:function(){},_success:function(){},_prepareEdit:function(){},_destroyEditor:function(){}}),WCF.User.Registration={},WCF.User.Registration.Validation=Class.extend({_actionName:"",_className:"",_confirmElement:null,_element:null,_errorMessages:{},_options:{},_proxy:null,init:function(e,t,i){this._element=e,this._element.blur($.proxy(this._blur,this)),this._confirmElement=t||null,null!==this._confirmElement&&this._confirmElement.blur($.proxy(this._blurConfirm,this)),i=i||{},this._setOptions(i),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),showLoadingOverlay:!1}),this._setErrorMessages()},_setOptions:function(e){},_setErrorMessages:function(){this._errorMessages={ajaxError:"",notEqual:""}},_blur:function(e){var t=this._element.val();if(!t)return this._showError(this._element,WCF.Language.get("wcf.global.form.error.empty"));if(null!==this._confirmElement){var i=this._confirmElement.val();if(""!=i&&t!=i)return this._showError(this._confirmElement,this._errorMessages.notEqual)}this._validateOptions()&&(this._proxy.setOption("data",{actionName:this._actionName,className:this._className,parameters:this._getParameters()}),this._proxy.sendRequest())},_getParameters:function(){return{}},_validateOptions:function(){return!0},_blurConfirm:function(e){if(!this._confirmElement.val())return this._showError(this._confirmElement,WCF.Language.get("wcf.global.form.error.empty"));this._blur(e)},_success:function(e,t,i){e.returnValues.isValid?(this._showSuccess(this._element),null!==this._confirmElement&&this._confirmElement.val()&&this._showSuccess(this._confirmElement)):this._showError(this._element,WCF.Language.get(this._errorMessages.ajaxError+e.returnValues.error))},_showError:function(e,t){e.parent().parent().addClass("formError").removeClass("formSuccess");var i=e.parent().find("small.innerError");i.length||(i=$("<small />").addClass("innerError").insertAfter(e)),i.text(t)},_showSuccess:function(e){e.parent().parent().addClass("formSuccess").removeClass("formError"),e.next("small.innerError").remove()}}),WCF.User.Registration.Validation.Username=WCF.User.Registration.Validation.extend({_actionName:"validateUsername",_className:"wcf\\data\\user\\UserRegistrationAction",_setOptions:function(e){this._options=$.extend(!0,{minlength:3,maxlength:25},e)},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.username.error."}},_validateOptions:function(){var e=this._element.val();return!(e.length<this._options.minlength||e.length>this._options.maxlength)||(this._showError(this._element,WCF.Language.get("wcf.user.username.error.invalid")),!1)},_getParameters:function(){return{username:this._element.val()}}}),WCF.User.Registration.Validation.EmailAddress=WCF.User.Registration.Validation.extend({_actionName:"validateEmailAddress",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{email:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.email.error.",notEqual:WCF.Language.get("wcf.user.confirmEmail.error.notEqual")}}}),WCF.User.Registration.Validation.Password=WCF.User.Registration.Validation.extend({_actionName:"validatePassword",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{password:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.password.error.",notEqual:WCF.Language.get("wcf.user.confirmPassword.error.notEqual")}}}),WCF.User.Registration.LostPassword=Class.extend({_email:null,_username:null,init:function(){this._email=$("#emailInput"),this._username=$("#usernameInput"),this._email.keyup($.proxy(this._checkEmail,this)),this._username.keyup($.proxy(this._checkUsername,this)),$.browser.mozilla&&$.browser.touch&&(this._email.on("input",$.proxy(this._checkEmail,this)),this._username.on("input",$.proxy(this._checkUsername,this))),this._checkEmail(),this._checkUsername()},_checkEmail:function(){""==this._email.val()?(this._username.enable(),this._username.parents("dl:eq(0)").removeClass("disabled")):(this._username.disable(),this._username.parents("dl:eq(0)").addClass("disabled"),this._username.val(""))},_checkUsername:function(){""==this._username.val()?(this._email.enable(),this._email.parents("dl:eq(0)").removeClass("disabled")):(this._email.disable(),this._email.parents("dl:eq(0)").addClass("disabled"),this._email.val(""))}}),WCF.Notification={},WCF.Notification.List=Class.extend({_proxy:{},init:function(){},_convertList:function(){},_markAsConfirmed:function(){},_success:function(){}}),WCF.User.SignaturePreview=WCF.Message.Preview.extend({_handleResponse:function(){},_className:"",_messageFieldID:"",_messageField:{},_proxy:{},_previewButton:{},_previewButtonLabel:"",init:function(){},_click:function(){},_getParameters:function(){},_getMessage:function(){},_success:function(){},_failure:function(){}}),WCF.User.RecentActivityLoader=Class.extend({_container:null,_filteredByFollowedUsers:!1,_loadButton:null,_proxy:null,_userID:0,init:function(e,t){if(this._container=$("#recentActivities"),this._filteredByFollowedUsers=!0===t,this._userID=e,null!==this._userID&&!this._userID)return void console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.");this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._container.children("li").length?(this._loadButton=$('<li class="showMore"><button class="small">'+WCF.Language.get("wcf.user.recentActivity.more")+"</button></li>").appendTo(this._container),this._loadButton=this._loadButton.children("button").click($.proxy(this._click,this))):$('<li class="showMore"><small>'+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small></li>").appendTo(this._container),WCF.User.userID&&$(".jsRecentActivitySwitchContext .button").click($.proxy(this._switchContext,this))},_click:function(){this._loadButton.enable();var e={lastEventID:this._container.data("lastEventID"),lastEventTime:this._container.data("lastEventTime")};this._userID?e.userID=this._userID:this._filteredByFollowedUsers&&(e.filteredByFollowedUsers=1),this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction",parameters:e}),this._proxy.sendRequest()},_switchContext:function(e){e.preventDefault(),$(e.currentTarget).hasClass("active")||new WCF.Action.Proxy({autoSend:!0,data:{actionName:"switchContext",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"},success:function(){window.location.hash="#dashboardBoxRecentActivity",window.location.reload()}})},_success:function(e,t,i){e.returnValues.template?($(e.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastEventTime",e.returnValues.lastEventTime),this._container.data("lastEventID",e.returnValues.lastEventID),this._loadButton.enable()):($("<small>"+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small>").appendTo(this._loadButton.parent()),this._loadButton.remove())}}),WCF.User.LikeLoader=Class.extend({_container:null,_likeType:"received",_likeValue:1,_loadButton:null,_noMoreEntries:null,_proxy:null,_userID:0,init:function(e){if(this._container=$("#likeList"),this._userID=e,!this._userID)return void console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.");this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)});var t=$('<li class="likeListMore showMore"><button class="small">'+WCF.Language.get("wcf.like.likes.more")+"</button><small>"+WCF.Language.get("wcf.like.likes.noMoreEntries")+"</small></li>").appendTo(this._container);this._loadButton=t.children("button").click($.proxy(this._click,this)),this._noMoreEntries=t.children("small").hide(),2==this._container.find("> li").length&&(this._loadButton.hide(),this._noMoreEntries.show()),$("#likeType .button").click($.proxy(this._clickLikeType,this)),$("#likeValue .button").click($.proxy(this._clickLikeValue,this))},_clickLikeType:function(e){var t=$(e.currentTarget);this._likeType!=t.data("likeType")&&(this._likeType=t.data("likeType"),$("#likeType .button").removeClass("active"),t.addClass("active"),this._reload())},_clickLikeValue:function(e){var t=$(e.currentTarget);this._likeValue!=t.data("likeValue")&&(this._likeValue=t.data("likeValue"),$("#likeValue .button").removeClass("active"),t.addClass("active"),$("#likeType > li:first-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesReceived")),$("#likeType > li:last-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesGiven")),this._container.find("> li.likeListMore button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.more")),this._container.find("> li.likeListMore small").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.noMoreEntries")),this._reload())},_reload:function(){this._container.find("> li:not(:first-child):not(:last-child)").remove(),this._container.data("lastLikeTime",0),this._click()},_click:function(){this._loadButton.enable();var e={lastLikeTime:this._container.data("lastLikeTime"),userID:this._userID,likeType:this._likeType,likeValue:this._likeValue};this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\like\\LikeAction",parameters:e}),this._proxy.sendRequest()},_success:function(e,t,i){e.returnValues.template?($(e.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastLikeTime",e.returnValues.lastLikeTime),this._noMoreEntries.hide(),this._loadButton.show().enable()):(this._noMoreEntries.show(),this._loadButton.hide())}}),WCF.User.ProfilePreview=WCF.Popover.extend({_proxy:null,_userProfiles:{},init:function(){this._super(".userLink"),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1}),WCF.System.ObjectStore.add("WCF.User.ProfilePreview",this)},_loadContent:function(){var e=$("#"+this._activeElementID),t=e.data("userID");if(this._userProfiles[t])this._insertContent(this._activeElementID,this._userProfiles[t],!0);else{this._proxy.setOption("data",{actionName:"getUserProfile",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[t]});var i=this._activeElementID,s=this;this._proxy.setOption("success",function(e,n,a){s._userProfiles[t]=e.returnValues.template,s._insertContent(i,e.returnValues.template,!0)}),this._proxy.setOption("failure",function(e,n,a,o){return s._userProfiles[t]=e.message,s._insertContent(i,e.message,!0),!1}),this._proxy.sendRequest()}},purge:function(e){delete this._userProfiles[e],this._data={}}}),WCF.User.Action={},WCF.User.Action.Follow=Class.extend({_containerList:{},_followButtonSelector:"",_userID:0,init:function(){},_click:function(){},_success:function(){}}),WCF.User.Action.Ignore=Class.extend({_containerList:{},_ignoreButtonSelector:"",_userID:0,init:function(){},_click:function(){},_success:function(){}}),WCF.User.Avatar={},WCF.User.Avatar.Upload=WCF.Upload.extend({_userID:0,init:function(){},_initFile:function(){},_success:function(){},_updateImage:function(){},_getInnerErrorElement:function(){},_getParameters:function(){},_name:"",_buttonSelector:{},_fileListSelector:{},_fileUpload:{},_className:"",_iframe:{},_internalFileID:0,_options:{},_uploadMatrix:{},_supportsAJAXUpload:!0,_overlay:{},_createButton:function(){},_insertButton:function(){},_removeButton:function(){},_upload:function(){},_createUploadMatrix:function(){},_error:function(){},_progress:function(){},_showOverlay:function(){},_evaluateResponse:function(){},_getFilename:function(){}}),WCF.User.List=Class.extend({_additionalParameters:{},_cache:{},_className:"",_dialog:null,_dialogTitle:"",_pageCount:0,_pageNo:1,_proxy:null,init:function(e,t,i){this._additionalParameters=i||{},this._cache={},this._className=e,this._dialog=null,this._dialogTitle=t,this._pageCount=0,this._pageNo=1,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},open:function(){this._pageNo=1,this._showPage()},_showPage:function(e,t){if(t&&t.activePage&&(this._pageNo=t.activePage),0!=this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount))return void console.debug("[WCF.User.List] Cannot access page "+this._pageNo+" of "+this._pageCount);if(this._cache[this._pageNo]){var i=!1;null===this._dialog&&(this._dialog=$("#userList"+this._className.hashCode()),0===this._dialog.length&&(this._dialog=$('<div id="userList'+this._className.hashCode()+'" />').hide().appendTo(document.body),i=!0)),this._dialog.empty(),this._dialog.html(this._cache[this._pageNo]),this._pageCount>1?this._dialog.find(".jsPagination").wcfPages({activePage:this._pageNo,maxPage:this._pageCount}).on("wcfpagesswitched",$.proxy(this._showPage,this)):this._dialog.find(".jsPagination").hide(),i?this._dialog.wcfDialog({title:this._dialogTitle}):(this._dialog.wcfDialog("option","title",this._dialogTitle),this._dialog.wcfDialog("open").wcfDialog("render")),WCF.DOMNodeInsertedHandler.execute()}else this._additionalParameters.pageNo=this._pageNo,this._proxy.setOption("data",{actionName:"getGroupedUserList",className:this._className,interfaceName:"wcf\\data\\IGroupedUserListAction",parameters:this._additionalParameters}),this._proxy.sendRequest()},_success:function(e,t,i){e.returnValues.pageCount&&(this._pageCount=e.returnValues.pageCount),this._cache[this._pageNo]=e.returnValues.template,this._showPage()}}),WCF.User.ObjectWatch={},WCF.User.ObjectWatch.Subscribe=Class.extend({_buttonSelector:"",_buttons:{},_dialog:{},_notification:{},_reloadOnUnsubscribe:!1,init:function(){},_click:function(){},_success:function(){},_save:function(){},_updateSubscriptionStatus:function(){}}); })(this);
+(function (window, undefined) { "use strict";WCF.User.Login=Class.extend({_loginSubmitButton:null,_password:null,_passwordContainer:null,_useCookies:null,_useCookiesContainer:null,init:function(e){this._loginSubmitButton=$("#loginSubmitButton"),this._password=$("#password"),this._passwordContainer=this._password.parents("dl"),this._useCookies=$("#useCookies"),this._useCookiesContainer=this._useCookies.parents("dl"),$("#loginForm").find("input[name=action]").change($.proxy(this._change,this)),e&&WCF.User.QuickLogin.init()},_change:function(e){"register"===$(e.currentTarget).val()?this._setState(!1,WCF.Language.get("wcf.user.button.register")):this._setState(!0,WCF.Language.get("wcf.user.button.login"))},_setState:function(e,t){e?(this._password.enable(),this._passwordContainer.removeClass("disabled"),this._useCookies.enable(),this._useCookiesContainer.removeClass("disabled")):(this._password.disable(),this._passwordContainer.addClass("disabled"),this._useCookies.disable(),this._useCookiesContainer.addClass("disabled")),this._loginSubmitButton.val(t)}}),WCF.User.Panel={},WCF.User.Panel.Abstract=Class.extend({_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},init:function(){},toggle:function(){},_dblClick:function(){},_initDropdown:function(){},_load:function(){},_success:function(){},_markAsRead:function(){},_markAllAsRead:function(){},updateBadge:function(){},resetItems:function(){}}),WCF.User.Panel.Notification=WCF.User.Panel.Abstract.extend({_favico:{},init:function(){},_initDropdown:function(){},_load:function(){},_markAsRead:function(){},_markAllAsRead:function(){},resetItems:function(){},updateBadge:function(){},updateUserNotificationCount:function(){},_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},toggle:function(){},_dblClick:function(){},_success:function(){}}),WCF.User.Panel.UserMenu=WCF.User.Panel.Abstract.extend({init:function(){},_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},toggle:function(){},_dblClick:function(){},_initDropdown:function(){},_load:function(){},_success:function(){},_markAsRead:function(){},_markAllAsRead:function(){},updateBadge:function(){},resetItems:function(){}}),WCF.User.QuickLogin={init:function(){require(["EventHandler","Ui/Dialog"],function(e,s){var n=elById("loginForm"),a=elBySel(".loginFormLogin",n);a&&!a.nextElementSibling&&n.classList.add("loginFormLoginOnly");for(var o=elBySel(".loginFormRegister",n),t=function(e){if(e instanceof Event&&(e.preventDefault(),e.stopPropagation()),n.style.removeProperty("display"),s.openStatic("loginForm",null,{title:WCF.Language.get("wcf.user.login")}),null!==a&&null!==o){var t=a.offsetTop,i=0;if(n.clientWidth>2*a.clientWidth)for(;t<o.offsetTop-50;)i+=100,a.style.setProperty("margin-bottom",i+"px","")}},i=document.getElementsByClassName("loginLink"),r=0,l=i.length;r<l;r++)i[r].addEventListener(WCF_CLICK_EVENT,t);var c=n.querySelector("#loginForm input[name=url]");null===c||c.value.match(/^https?:\/\//)||c.setAttribute("value",window.location.protocol+"//"+window.location.host+c.getAttribute("value")),e.add("com.woltlab.wcf.UserMenuMobile","more",function(e){"com.woltlab.wcf.login"===e.identifier&&(e.handler.close(!0),t())})})}},WCF.User.Profile={},WCF.User.Profile.ActivityPointList={_cache:{},_dialog:null,_didInit:!1,_proxy:null,init:function(){this._didInit||(this._cache={},this._dialog=null,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._init(),WCF.DOMNodeInsertedHandler.addCallback("WCF.User.Profile.ActivityPointList",$.proxy(this._init,this)),this._didInit=!0)},_init:function(){$(".activityPointsDisplay").removeClass("activityPointsDisplay").click($.proxy(this._click,this))},_click:function(e){e.preventDefault();var t=$(e.currentTarget).data("userID");void 0===this._cache[t]?(this._proxy.setOption("data",{actionName:"getDetailedActivityPointList",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[t]}),this._proxy.sendRequest()):this._show(t)},_show:function(e){null===this._dialog?(this._dialog=$("<div>"+this._cache[e]+"</div>").hide().appendTo(document.body),this._dialog.wcfDialog({title:WCF.Language.get("wcf.user.activityPoint")})):(this._dialog.html(this._cache[e]),this._dialog.wcfDialog("open"))},_success:function(e,t,i){this._cache[e.returnValues.userID]=e.returnValues.template,this._show(e.returnValues.userID)}},WCF.User.Profile.TabMenu=Class.extend({_hasContent:{},_profileContent:null,_proxy:null,_userID:0,init:function(e){this._profileContent=$("#profileContent"),this._userID=e;var s=this._profileContent.data("active"),n=!1;this._profileContent.find("div.tabMenuContent").each($.proxy(function(e,t){var i=$(t).wcfIdentify();s===i?this._hasContent[i]=!0:(this._hasContent[i]=!1,n=!0)},this)),n&&(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._profileContent.on("wcftabsbeforeactivate",$.proxy(this._loadContent,this)),this._profileContent.find("> nav.tabMenu > ul > li").each($.proxy(function(e,t){var i=$(t);if(i.hasClass("ui-state-active"))return e&&this._loadContent(null,{newPanel:$("#"+i.attr("aria-controls"))}),!1},this))),$('.userProfileUser .contentDescription a[href$="#likes"]').click(function(e){e.preventDefault(),require(["Ui/TabMenu"],function(e){e.getTabMenu("profileContent").select("likes")})}.bind(this))},_loadContent:function(e,t){var i=$(t.newPanel),s=i.attr("id");this._hasContent[s]||(this._proxy.setOption("data",{actionName:"getContent",className:"wcf\\data\\user\\profile\\menu\\item\\UserProfileMenuItemAction",parameters:{data:{containerID:s,menuItem:i.data("menuItem"),userID:this._userID}}}),this._proxy.sendRequest())},_success:function(i,e,t){var s=i.returnValues.containerID;this._hasContent[s]=!0,require(["Dom/ChangeListener","Dom/Util"],function(e,t){t.insertHtml(i.returnValues.template,elById(s),"append"),e.trigger()})}}),WCF.User.Profile.Editor=Class.extend({_actionName:"",_active:!1,_buttons:{},_cachedTemplate:"",_proxy:{},_tab:{},_userID:0,init:function(){},_initButtons:function(){},_beginEdit:function(){},_save:function(){},_restore:function(){},_success:function(){},_prepareEdit:function(){},_destroyEditor:function(){}}),WCF.User.Registration={},WCF.User.Registration.Validation=Class.extend({_actionName:"",_className:"",_confirmElement:null,_element:null,_errorMessages:{},_options:{},_proxy:null,init:function(e,t,i){this._element=e,this._element.blur($.proxy(this._blur,this)),this._confirmElement=t||null,null!==this._confirmElement&&this._confirmElement.blur($.proxy(this._blurConfirm,this)),i=i||{},this._setOptions(i),this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this),showLoadingOverlay:!1}),this._setErrorMessages()},_setOptions:function(e){},_setErrorMessages:function(){this._errorMessages={ajaxError:"",notEqual:""}},_blur:function(e){var t=this._element.val();if(!t)return this._showError(this._element,WCF.Language.get("wcf.global.form.error.empty"));if(null!==this._confirmElement){var i=this._confirmElement.val();if(""!=i&&t!=i)return this._showError(this._confirmElement,this._errorMessages.notEqual)}this._validateOptions()&&(this._proxy.setOption("data",{actionName:this._actionName,className:this._className,parameters:this._getParameters()}),this._proxy.sendRequest())},_getParameters:function(){return{}},_validateOptions:function(){return!0},_blurConfirm:function(e){if(!this._confirmElement.val())return this._showError(this._confirmElement,WCF.Language.get("wcf.global.form.error.empty"));this._blur(e)},_success:function(e,t,i){e.returnValues.isValid?(this._showSuccess(this._element),null!==this._confirmElement&&this._confirmElement.val()&&this._showSuccess(this._confirmElement)):this._showError(this._element,WCF.Language.get(this._errorMessages.ajaxError+e.returnValues.error))},_showError:function(e,t){e.parent().parent().addClass("formError").removeClass("formSuccess");var i=e.parent().find("small.innerError");i.length||(i=$("<small />").addClass("innerError").insertAfter(e)),i.text(t)},_showSuccess:function(e){e.parent().parent().addClass("formSuccess").removeClass("formError"),e.next("small.innerError").remove()}}),WCF.User.Registration.Validation.Username=WCF.User.Registration.Validation.extend({_actionName:"validateUsername",_className:"wcf\\data\\user\\UserRegistrationAction",_setOptions:function(e){this._options=$.extend(!0,{minlength:3,maxlength:25},e)},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.username.error."}},_validateOptions:function(){var e=this._element.val();return!(e.length<this._options.minlength||e.length>this._options.maxlength)||(this._showError(this._element,WCF.Language.get("wcf.user.username.error.invalid")),!1)},_getParameters:function(){return{username:this._element.val()}}}),WCF.User.Registration.Validation.EmailAddress=WCF.User.Registration.Validation.extend({_actionName:"validateEmailAddress",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{email:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.email.error.",notEqual:WCF.Language.get("wcf.user.confirmEmail.error.notEqual")}}}),WCF.User.Registration.Validation.Password=WCF.User.Registration.Validation.extend({_actionName:"validatePassword",_className:"wcf\\data\\user\\UserRegistrationAction",_getParameters:function(){return{password:this._element.val()}},_setErrorMessages:function(){this._errorMessages={ajaxError:"wcf.user.password.error.",notEqual:WCF.Language.get("wcf.user.confirmPassword.error.notEqual")}}}),WCF.User.Registration.LostPassword=Class.extend({_email:null,_username:null,init:function(){this._email=$("#emailInput"),this._username=$("#usernameInput"),this._email.keyup($.proxy(this._checkEmail,this)),this._username.keyup($.proxy(this._checkUsername,this)),$.browser.mozilla&&$.browser.touch&&(this._email.on("input",$.proxy(this._checkEmail,this)),this._username.on("input",$.proxy(this._checkUsername,this))),this._checkEmail(),this._checkUsername()},_checkEmail:function(){""==this._email.val()?(this._username.enable(),this._username.parents("dl:eq(0)").removeClass("disabled")):(this._username.disable(),this._username.parents("dl:eq(0)").addClass("disabled"),this._username.val(""))},_checkUsername:function(){""==this._username.val()?(this._email.enable(),this._email.parents("dl:eq(0)").removeClass("disabled")):(this._email.disable(),this._email.parents("dl:eq(0)").addClass("disabled"),this._email.val(""))}}),WCF.Notification={},WCF.Notification.List=Class.extend({_proxy:{},init:function(){},_convertList:function(){},_markAsConfirmed:function(){},_success:function(){}}),WCF.User.SignaturePreview=WCF.Message.Preview.extend({_handleResponse:function(){},_className:"",_messageFieldID:"",_messageField:{},_proxy:{},_previewButton:{},_previewButtonLabel:"",init:function(){},_click:function(){},_getParameters:function(){},_getMessage:function(){},_success:function(){},_failure:function(){}}),WCF.User.RecentActivityLoader=Class.extend({_container:null,_filteredByFollowedUsers:!1,_loadButton:null,_proxy:null,_userID:0,init:function(e,t){this._container=$("#recentActivities"),this._filteredByFollowedUsers=!0===t,this._userID=e,null===this._userID||this._userID?(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._container.children("li").length?(this._loadButton=$('<li class="showMore"><button class="small">'+WCF.Language.get("wcf.user.recentActivity.more")+"</button></li>").appendTo(this._container),this._loadButton=this._loadButton.children("button").click($.proxy(this._click,this))):$('<li class="showMore"><small>'+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small></li>").appendTo(this._container),WCF.User.userID&&$(".jsRecentActivitySwitchContext .button").click($.proxy(this._switchContext,this))):console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.")},_click:function(){this._loadButton.enable();var e={lastEventID:this._container.data("lastEventID"),lastEventTime:this._container.data("lastEventTime")};this._userID?e.userID=this._userID:this._filteredByFollowedUsers&&(e.filteredByFollowedUsers=1),this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction",parameters:e}),this._proxy.sendRequest()},_switchContext:function(e){e.preventDefault(),$(e.currentTarget).hasClass("active")||new WCF.Action.Proxy({autoSend:!0,data:{actionName:"switchContext",className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"},success:function(){window.location.hash="#dashboardBoxRecentActivity",window.location.reload()}})},_success:function(e,t,i){e.returnValues.template?($(e.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastEventTime",e.returnValues.lastEventTime),this._container.data("lastEventID",e.returnValues.lastEventID),this._loadButton.enable()):($("<small>"+WCF.Language.get("wcf.user.recentActivity.noMoreEntries")+"</small>").appendTo(this._loadButton.parent()),this._loadButton.remove())}}),WCF.User.LikeLoader=Class.extend({_container:null,_likeType:"received",_likeValue:1,_loadButton:null,_noMoreEntries:null,_proxy:null,_userID:0,init:function(e){var t;this._container=$("#likeList"),this._userID=e,this._userID?(this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),t=$('<li class="likeListMore showMore"><button class="small">'+WCF.Language.get("wcf.like.likes.more")+"</button><small>"+WCF.Language.get("wcf.like.likes.noMoreEntries")+"</small></li>").appendTo(this._container),this._loadButton=t.children("button").click($.proxy(this._click,this)),this._noMoreEntries=t.children("small").hide(),2==this._container.find("> li").length&&(this._loadButton.hide(),this._noMoreEntries.show()),$("#likeType .button").click($.proxy(this._clickLikeType,this)),$("#likeValue .button").click($.proxy(this._clickLikeValue,this))):console.debug("[WCF.User.RecentActivityLoader] Invalid parameter 'userID' given.")},_clickLikeType:function(e){var t=$(e.currentTarget);this._likeType!=t.data("likeType")&&(this._likeType=t.data("likeType"),$("#likeType .button").removeClass("active"),t.addClass("active"),this._reload())},_clickLikeValue:function(e){var t=$(e.currentTarget);this._likeValue!=t.data("likeValue")&&(this._likeValue=t.data("likeValue"),$("#likeValue .button").removeClass("active"),t.addClass("active"),$("#likeType > li:first-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesReceived")),$("#likeType > li:last-child > .button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likesGiven")),this._container.find("> li.likeListMore button").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.more")),this._container.find("> li.likeListMore small").text(WCF.Language.get("wcf.like."+(-1==this._likeValue?"dis":"")+"likes.noMoreEntries")),this._reload())},_reload:function(){this._container.find("> li:not(:first-child):not(:last-child)").remove(),this._container.data("lastLikeTime",0),this._click()},_click:function(){this._loadButton.enable();var e={lastLikeTime:this._container.data("lastLikeTime"),userID:this._userID,likeType:this._likeType,likeValue:this._likeValue};this._proxy.setOption("data",{actionName:"load",className:"wcf\\data\\like\\LikeAction",parameters:e}),this._proxy.sendRequest()},_success:function(e,t,i){e.returnValues.template?($(e.returnValues.template).insertBefore(this._loadButton.parent()),this._container.data("lastLikeTime",e.returnValues.lastLikeTime),this._noMoreEntries.hide(),this._loadButton.show().enable()):(this._noMoreEntries.show(),this._loadButton.hide())}}),WCF.User.ProfilePreview=WCF.Popover.extend({_proxy:null,_userProfiles:{},init:function(){this._super(".userLink"),this._proxy=new WCF.Action.Proxy({showLoadingOverlay:!1}),WCF.System.ObjectStore.add("WCF.User.ProfilePreview",this)},_loadContent:function(){var n,a,o=$("#"+this._activeElementID).data("userID");this._userProfiles[o]?this._insertContent(this._activeElementID,this._userProfiles[o],!0):(this._proxy.setOption("data",{actionName:"getUserProfile",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[o]}),n=this._activeElementID,(a=this)._proxy.setOption("success",function(e,t,i){a._userProfiles[o]=e.returnValues.template,a._insertContent(n,e.returnValues.template,!0)}),this._proxy.setOption("failure",function(e,t,i,s){return a._userProfiles[o]=e.message,a._insertContent(n,e.message,!0),!1}),this._proxy.sendRequest())},purge:function(e){delete this._userProfiles[e],this._data={}}}),WCF.User.Action={},WCF.User.Action.Follow=Class.extend({_containerList:{},_followButtonSelector:"",_userID:0,init:function(){},_click:function(){},_success:function(){}}),WCF.User.Action.Ignore=Class.extend({_containerList:{},_ignoreButtonSelector:"",_userID:0,init:function(){},_click:function(){},_success:function(){}}),WCF.User.Avatar={},WCF.User.Avatar.Upload=WCF.Upload.extend({_userID:0,init:function(){},_initFile:function(){},_success:function(){},_updateImage:function(){},_getInnerErrorElement:function(){},_getParameters:function(){},_name:"",_buttonSelector:{},_fileListSelector:{},_fileUpload:{},_className:"",_iframe:{},_internalFileID:0,_options:{},_uploadMatrix:{},_supportsAJAXUpload:!0,_overlay:{},_createButton:function(){},_insertButton:function(){},_removeButton:function(){},_upload:function(){},_createUploadMatrix:function(){},_error:function(){},_progress:function(){},_showOverlay:function(){},_evaluateResponse:function(){},_getFilename:function(){}}),WCF.User.List=Class.extend({_additionalParameters:{},_cache:{},_className:"",_dialog:null,_dialogTitle:"",_pageCount:0,_pageNo:1,_proxy:null,init:function(e,t,i){this._additionalParameters=i||{},this._cache={},this._className=e,this._dialog=null,this._dialogTitle=t,this._pageCount=0,this._pageNo=1,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)})},open:function(){this._pageNo=1,this._showPage()},_showPage:function(e,t){var i;t&&t.activePage&&(this._pageNo=t.activePage),0!=this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount)?console.debug("[WCF.User.List] Cannot access page "+this._pageNo+" of "+this._pageCount):this._cache[this._pageNo]?(i=!1,null===this._dialog&&(this._dialog=$("#userList"+this._className.hashCode()),0===this._dialog.length&&(this._dialog=$('<div id="userList'+this._className.hashCode()+'" />').hide().appendTo(document.body),i=!0)),this._dialog.empty(),this._dialog.html(this._cache[this._pageNo]),1<this._pageCount?this._dialog.find(".jsPagination").wcfPages({activePage:this._pageNo,maxPage:this._pageCount}).on("wcfpagesswitched",$.proxy(this._showPage,this)):this._dialog.find(".jsPagination").hide(),i?this._dialog.wcfDialog({title:this._dialogTitle}):(this._dialog.wcfDialog("option","title",this._dialogTitle),this._dialog.wcfDialog("open").wcfDialog("render")),WCF.DOMNodeInsertedHandler.execute()):(this._additionalParameters.pageNo=this._pageNo,this._proxy.setOption("data",{actionName:"getGroupedUserList",className:this._className,interfaceName:"wcf\\data\\IGroupedUserListAction",parameters:this._additionalParameters}),this._proxy.sendRequest())},_success:function(e,t,i){e.returnValues.pageCount&&(this._pageCount=e.returnValues.pageCount),this._cache[this._pageNo]=e.returnValues.template,this._showPage()}}),WCF.User.ObjectWatch={},WCF.User.ObjectWatch.Subscribe=Class.extend({_buttonSelector:"",_buttons:{},_dialog:{},_notification:{},_reloadOnUnsubscribe:!1,init:function(){},_click:function(){},_success:function(){},_save:function(){},_updateSubscriptionStatus:function(){}}); })(this);
 
 // WCF.Moderation.js
-(function (window, undefined) { "use strict";WCF.Moderation={},WCF.Moderation.Management=Class.extend({_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:{},_languageItem:"",_proxy:{},_queueID:0,_redirectURL:"",init:function(){},_click:function(){},_clickAssignedUser:function(){},_success:function(){},_failure:function(){},_assignUser:function(){}}),WCF.Moderation.Queue={},WCF.Moderation.Queue.MarkAsRead=Class.extend({_proxy:{},init:function(){},_dblclick:function(){},_success:function(){}}),WCF.Moderation.Queue.MarkAllAsRead=Class.extend({_proxy:{},init:function(){},_click:function(){},_success:function(){}}),WCF.Moderation.Activation={},WCF.Moderation.Activation.Management=WCF.Moderation.Management.extend({init:function(){},_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:{},_languageItem:"",_proxy:{},_queueID:0,_redirectURL:"",_click:function(){},_clickAssignedUser:function(){},_success:function(){},_failure:function(){},_assignUser:function(){}}),WCF.Moderation.Report={},WCF.Moderation.Report.Content=Class.extend({_buttons:{},_buttonSelector:"",_dialog:null,_notification:null,_objectID:0,_objectType:"",_proxy:null,init:function(t,e){this._objectType=t,this._buttonSelector=e,this._buttons={},this._notification=null,this._objectID=0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initButtons(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Moderation.Report"+this._objectType.hashCode(),$.proxy(this._initButtons,this))},_initButtons:function(){var t=this;$(this._buttonSelector).each(function(e,i){var n=$(i),o=n.wcfIdentify();t._buttons[o]||(t._buttons[o]=n,n.click($.proxy(t._click,t)))})},_click:function(t){t.preventDefault(),this._objectID=$(t.currentTarget).data("objectID"),this._proxy.setOption("data",{actionName:"prepareReport",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()},_success:function(t,e,i){t.returnValues.reported?(null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.moderation.report.success"))),this._dialog.wcfDialog("close"),this._notification.show()):t.returnValues.template&&(this._showDialog(t.returnValues.template),t.returnValues.alreadyReported||this._dialog.find(".jsSubmitReport").click($.proxy(this._submit,this)))},_showDialog:function(t){null===this._dialog&&(this._dialog=$("#moderationReport"),this._dialog.length||(this._dialog=$('<div id="moderationReport" />').hide().appendTo(document.body))),this._dialog.html(t).wcfDialog({title:WCF.Language.get("wcf.moderation.report.reportContent")}).wcfDialog("render")},_submit:function(){var t=this._dialog.find(".jsReportMessage").val();if(""==$.trim(t))return this._dialog.find(".section > dl").addClass("formError"),void(this._dialog.find(".innerError").length||this._dialog.find(".jsReportMessage").after($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>")));this._proxy.setOption("data",{actionName:"report",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{message:t,objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()}}),WCF.Moderation.Report.Management=WCF.Moderation.Management.extend({init:function(){},_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:{},_languageItem:"",_proxy:{},_queueID:0,_redirectURL:"",_click:function(){},_clickAssignedUser:function(){},_success:function(){},_failure:function(){},_assignUser:function(){}}),WCF.User.Panel.Moderation=WCF.User.Panel.Abstract.extend({init:function(){},_initDropdown:function(){},_load:function(){},_markAsRead:function(){},_markAllAsRead:function(){},resetItems:function(){},_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},toggle:function(){},_dblClick:function(){},_success:function(){},updateBadge:function(){}}); })(this);
+(function (window, undefined) { "use strict";WCF.Moderation={},WCF.Moderation.Management=Class.extend({_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:{},_languageItem:"",_proxy:{},_queueID:0,_redirectURL:"",init:function(){},_click:function(){},_clickAssignedUser:function(){},_success:function(){},_failure:function(){},_assignUser:function(){}}),WCF.Moderation.Queue={},WCF.Moderation.Queue.MarkAsRead=Class.extend({_proxy:{},init:function(){},_dblclick:function(){},_success:function(){}}),WCF.Moderation.Queue.MarkAllAsRead=Class.extend({_proxy:{},init:function(){},_click:function(){},_success:function(){}}),WCF.Moderation.Activation={},WCF.Moderation.Activation.Management=WCF.Moderation.Management.extend({init:function(){},_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:{},_languageItem:"",_proxy:{},_queueID:0,_redirectURL:"",_click:function(){},_clickAssignedUser:function(){},_success:function(){},_failure:function(){},_assignUser:function(){}}),WCF.Moderation.Report={},WCF.Moderation.Report.Content=Class.extend({_buttons:{},_buttonSelector:"",_dialog:null,_notification:null,_objectID:0,_objectType:"",_proxy:null,init:function(t,e){this._objectType=t,this._buttonSelector=e,this._buttons={},this._notification=null,this._objectID=0,this._proxy=new WCF.Action.Proxy({success:$.proxy(this._success,this)}),this._initButtons(),WCF.DOMNodeInsertedHandler.addCallback("WCF.Moderation.Report"+this._objectType.hashCode(),$.proxy(this._initButtons,this))},_initButtons:function(){var o=this;$(this._buttonSelector).each(function(t,e){var i=$(e),n=i.wcfIdentify();o._buttons[n]||(o._buttons[n]=i).click($.proxy(o._click,o))})},_click:function(t){t.preventDefault(),this._objectID=$(t.currentTarget).data("objectID"),this._proxy.setOption("data",{actionName:"prepareReport",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()},_success:function(t,e,i){t.returnValues.reported?(null===this._notification&&(this._notification=new WCF.System.Notification(WCF.Language.get("wcf.moderation.report.success"))),this._dialog.wcfDialog("close"),this._notification.show()):t.returnValues.template&&(this._showDialog(t.returnValues.template),t.returnValues.alreadyReported||this._dialog.find(".jsSubmitReport").click($.proxy(this._submit,this)))},_showDialog:function(t){null===this._dialog&&(this._dialog=$("#moderationReport"),this._dialog.length||(this._dialog=$('<div id="moderationReport" />').hide().appendTo(document.body))),this._dialog.html(t).wcfDialog({title:WCF.Language.get("wcf.moderation.report.reportContent")}).wcfDialog("render")},_submit:function(){var t=this._dialog.find(".jsReportMessage").val();if(""==$.trim(t))return this._dialog.find(".section > dl").addClass("formError"),void(this._dialog.find(".innerError").length||this._dialog.find(".jsReportMessage").after($('<small class="innerError">'+WCF.Language.get("wcf.global.form.error.empty")+"</small>")));this._proxy.setOption("data",{actionName:"report",className:"wcf\\data\\moderation\\queue\\ModerationQueueReportAction",parameters:{message:t,objectID:this._objectID,objectType:this._objectType}}),this._proxy.sendRequest()}}),WCF.Moderation.Report.Management=WCF.Moderation.Management.extend({init:function(){},_buttonSelector:"",_className:"",_confirmationTemplate:{},_dialog:{},_languageItem:"",_proxy:{},_queueID:0,_redirectURL:"",_click:function(){},_clickAssignedUser:function(){},_success:function(){},_failure:function(){},_assignUser:function(){}}),WCF.User.Panel.Moderation=WCF.User.Panel.Abstract.extend({init:function(){},_initDropdown:function(){},_load:function(){},_markAsRead:function(){},_markAllAsRead:function(){},resetItems:function(){},_badge:{},_dropdown:{},_identifier:"",_loadData:!0,_markAllAsReadLink:{},_options:{},_proxy:{},_triggerElement:{},toggle:function(){},_dblClick:function(){},_success:function(){},updateBadge:function(){}}); })(this);
 
index 16b635fca6cba2d59f72ae8e2647d7d336215726..fa61f9a1406aa37e71f0b0f4bf12352ffb3d05ef 100644 (file)
@@ -188,6 +188,11 @@ $.widget('ui.wcfImageViewer', {
         * @var boolean
         */
        _isOpen: false,
+
+       /**
+        * @var HTMLElement|null
+        */
+       _messageSignature: null,
        
        /**
         * number of total images
@@ -304,6 +309,7 @@ $.widget('ui.wcfImageViewer', {
                        height: document.documentElement.clientHeight,
                        width: document.documentElement.clientWidth
                };
+               this._messageSignature = null;
                this._proxy = new WCF.Action.Proxy({
                        success: $.proxy(this._success, this)
                });
@@ -352,7 +358,16 @@ $.widget('ui.wcfImageViewer', {
                        }, '', '');
                }
                
+               this._messageSignature = null;
                if (this.options.staticViewer) {
+                       if (targetImageElementID) {
+                               this._messageSignature = document.getElementById(targetImageElementID).closest(".messageSignature");
+                       }
+
+                       // Reset the internal state because it could refer to a different set of images.
+                       this._active = -1;
+                       this._activeImage = null;
+
                        var $images = this._getStaticImages();
                        this._initUI();
                        this._createThumbnails($images, true);
@@ -601,14 +616,25 @@ $.widget('ui.wcfImageViewer', {
                        }, this));
                }
                else if (targetImageElementID) {
+                       var images = [];
+
+                       $(this.options.imageSelector).each((function (_index, image) {
+                               // If the target image is inside a signature, then only include images within
+                               // the same signature. Otherwise this check will exclude images that are within
+                               // a user's signature.
+                               if (image.closest(".messageSignature") !== this._messageSignature) {
+                                       return;
+                               }
+
+                               images.push(image);
+                       }).bind(this));
+
                        var $i = 0;
-                       $(this.options.imageSelector).each(function(index, element) {
-                               if ($(element).wcfIdentify() == targetImageElementID) {
+                       images.forEach(function (image, index) {
+                               if (image.id === targetImageElementID) {
                                        $i = index;
-                                       
-                                       return false;
                                }
-                       });
+                       })
                        
                        var $item = this._ui.imageList.children('li:eq(' + $i + ')');
                        
@@ -1261,8 +1287,15 @@ $.widget('ui.wcfImageViewer', {
         */
        _getStaticImages: function() {
                var $images = [ ];
-               
-               $(this.options.imageSelector).each(function(index, link) {
+
+               $(this.options.imageSelector).each((function(index, link) {
+                       // If the target image is inside a signature, then only include images within
+                       // the same signature. Otherwise this check will exclude images that are within
+                       // a user's signature.
+                       if (link.closest(".messageSignature") !== this._messageSignature) {
+                               return;
+                       }
+
                        var $link = $(link);
                        var $thumbnail = $link.find('> img, .attachmentThumbnailImage > img').first();
                        if (!$thumbnail.length) {
@@ -1282,7 +1315,7 @@ $.widget('ui.wcfImageViewer', {
                                },
                                user: null
                        });
-               });
+               }).bind(this));
                
                this._items = $images.length;
                
index 21ad0901bb7a8a6f5f2321f1410c56b26c60d2ea..8c37661d59227dc28d937849f8214e255ac32509 100644 (file)
@@ -5,60 +5,15 @@
  */
 WCF.Label = {};
 
+/** @deprecated 5.3 */
+WCF.Label.ACPList = Class.extend({
+       _labelInput: {},
+       _labelList: {},
+       init: function() {},
+       _keyPressed: function() {}
+});
+
 if (COMPILER_TARGET_DEFAULT) {
-       /**
-        * Provides enhancements for ACP label management.
-        */
-       WCF.Label.ACPList = Class.extend({
-               /**
-                * input element
-                * @var        jQuery
-                */
-               _labelInput: null,
-               
-               /**
-                * list of pre-defined label items
-                * @var        array<jQuery>
-                */
-               _labelList: [],
-               
-               /**
-                * Initializes the ACP label list.
-                */
-               init: function () {
-                       this._labelInput = $('#label').keydown($.proxy(this._keyPressed, this)).keyup($.proxy(this._keyPressed, this)).blur($.proxy(this._keyPressed, this));
-                       
-                       if ($.browser.mozilla && $.browser.touch) {
-                               this._labelInput.on('input', $.proxy(this._keyPressed, this));
-                       }
-                       
-                       $('#labelList').find('input[type="radio"]').each($.proxy(function (index, input) {
-                               var $input = $(input);
-                               
-                               // ignore custom values
-                               if ($input.prop('value') !== 'custom') {
-                                       this._labelList.push($($input.next('span')));
-                               }
-                       }, this));
-                       
-                       if (this._labelInput[0].value.length > 0) {
-                               this._keyPressed();
-                       }
-               },
-               
-               /**
-                * Renders label name as label or falls back to a default value if label is empty.
-                */
-               _keyPressed: function () {
-                       var $text = this._labelInput.prop('value');
-                       if ($text === '') $text = WCF.Language.get('wcf.acp.label.defaultValue');
-                       
-                       for (var $i = 0, $length = this._labelList.length; $i < $length; $i++) {
-                               this._labelList[$i].text($text);
-                       }
-               }
-       });
-       
        /**
         * Provides simple logic to inherit associations within structured lists.
         */
@@ -105,13 +60,6 @@ if (COMPILER_TARGET_DEFAULT) {
        });
 }
 else {
-       WCF.Label.ACPList = Class.extend({
-               _labelInput: {},
-               _labelList: {},
-               init: function() {},
-               _keyPressed: function() {}
-       });
-       
        WCF.Label.ACPList.Connect = Class.extend({
                init: function() {},
                _click: function() {}
index 4f1d7117f6d09a0a01a4c949de918e97178ac51d..ed4843597da175fb88840f837883e4b641922518 100644 (file)
@@ -328,6 +328,8 @@ if (COMPILER_TARGET_DEFAULT) {
                 * Reads message field input and triggers an AJAX request.
                 */
                _click: function (event) {
+                       event.preventDefault();
+                       
                        var $message = this._getMessage();
                        if ($message === null) {
                                console.debug("[WCF.Message.Preview] Unable to access Redactor instance of '" + this._messageFieldID + "'");
@@ -506,6 +508,83 @@ if (COMPILER_TARGET_DEFAULT) {
                }
        });
        
+       WCF.Message.I18nPreview = WCF.Message.Preview.extend({
+               _activeMessageField: '',
+               _dialog: null,
+               _options: {},
+               
+               init: function (options) {
+                       this._activeMessageField = '';
+                       this._options = $.extend({
+                               disallowedBBCodesPermission: 'user.message.disallowedBBCodes',
+                               messageFields: [],
+                               messageObjectType: '',
+                               messageObjectID: 0
+                       }, options);
+                       
+                       if (!this._options.messageObjectType) {
+                               throw new Error("Field 'messageObjectType' cannot be empty.");
+                       }
+                       if (this._options.messageFields.length < 1) {
+                               throw new TypeError('Expected a non empty list of message field ids');
+                       }
+                       
+                       this._super('wcf\\data\\bbcode\\MessagePreviewAction', this._options.messageFields[0], 'buttonMessagePreview');
+               },
+               
+               _click: function (event) {
+                       this._messageFieldID = '';
+                       this._textarea = null;
+                       
+                       // Pick the first message field that is currently visible.
+                       var messageFieldId = '', messageField = null;
+                       for (var i = 0, length = this._options.messageFields.length; i < length; i++) {
+                               messageFieldId = this._options.messageFields[i];
+                               messageField = elById(messageFieldId);
+                               
+                               // Check if the editor instance has an offset parent. If it is null, the editor is invisible.
+                               if (elBySel('.redactor-layer[data-element-id="' + messageField.id + '"]').offsetParent !== null) {
+                                       this._messageFieldID = messageFieldId;
+                                       this._textarea = $(messageField);
+                                       break;
+                               }
+                       }
+                       
+                       if (this._messageFieldID === '') {
+                               throw new Error('Unable to identify the active message field.');
+                       }
+                       
+                       this._super(event);
+               },
+               
+               _getParameters: function (message) {
+                       var $parameters = this._super(message);
+                       
+                       for (var key in this._options) {
+                               if (this._options.hasOwnProperty(key) && ['messageFields', 'messageFieldID', 'previewButtonID'].indexOf(key) === -1) {
+                                       $parameters[key] = this._options[key];
+                               }
+                       }
+                       return $parameters;
+               },
+               
+               _handleResponse: function (data) {
+                       require(['WoltLabSuite/Core/Ui/Dialog'], (function (UiDialog) {
+                               UiDialog.open(this, '<div class="htmlContent">' + data.returnValues.message + '</div>');
+                       }).bind(this));
+               },
+               
+               _dialogSetup: function () {
+                       return {
+                               id: 'messagePreview',
+                               options: {
+                                       title: WCF.Language.get('wcf.global.preview')
+                               },
+                               source: null
+                       }
+               }
+       });
+       
        /**
         * Handles multilingualism for messages.
         *
@@ -1078,24 +1157,19 @@ if (COMPILER_TARGET_DEFAULT) {
                        WCF.DOMNodeInsertedHandler.addCallback('WCF.Message.Quote.Handler' + objectType.hashCode(), $.proxy(this._initContainers, this));
                        
                        // Prevent the tooltip from being selectable while the touch pointer is being moved.
-                       var timer = null;
-                       document.addEventListener('selectionchange', (function() {
-                               if (!this._copyQuote[0].classList.contains('active')) {
-                                       return;
-                               }
-                               
-                               this._copyQuote[0].classList.add('touchForceInaccessible');
-                               
-                               if (timer !== null) {
-                                       window.clearTimeout(timer);
+                       var tooltip = this._copyQuote[0];
+                       document.addEventListener("touchstart", function (event) {
+                               if (tooltip.classList.contains("active")) {
+                                       var target = event.target;
+                                       if (target !== tooltip && !tooltip.contains(target)) {
+                                               tooltip.classList.add("touchForceInaccessible");
+                                               
+                                               document.addEventListener("touchend", function () {
+                                                       tooltip.classList.remove("touchForceInaccessible");
+                                               }, {once: true});
+                                       }
                                }
-                               
-                               timer = window.setTimeout((function() {
-                                       this._copyQuote[0].classList.remove('touchForceInaccessible');
-                                       
-                                       timer = null;
-                               }).bind(this), 50);
-                       }).bind(this));
+                       }, {passive: true});
                },
                
                /**
@@ -1520,6 +1594,12 @@ if (COMPILER_TARGET_DEFAULT) {
                                }
                        });
                        this._proxy.sendRequest();
+                       
+                       var selection = window.getSelection();
+                       if (selection.rangeCount) {
+                               selection.removeAllRanges();
+                               this._copyQuote[0].classList.remove("active");
+                       }
                },
                
                /**
@@ -1833,12 +1913,14 @@ if (COMPILER_TARGET_DEFAULT) {
                                                UiPageAction.add(buttonName, button);
                                        }
                                        
-                                       button.textContent = WCF.Language.get('wcf.message.quote.showQuotes').replace(/#count#/, this._count);
+                                       button.textContent = WCF.Language.get('wcf.message.quote.showQuotes', {
+                                               count: this._count
+                                       });
                                        
                                        UiPageAction.show(buttonName);
                                }
                                else {
-                                       UiPageAction.hide(buttonName);
+                                       UiPageAction.remove(buttonName);
                                }
                                
                                this._hasTemplate = false;
@@ -2002,7 +2084,19 @@ if (COMPILER_TARGET_DEFAULT) {
                        
                        // close dialog
                        if (event !== null) {
-                               this._dialog.wcfDialog('close');
+                               require(["WoltLabSuite/Core/Environment"], (function (Environment) {
+                                       var callback = (function () {
+                                               this._dialog.wcfDialog("close");
+                                       }).bind(this);
+
+                                       // Slightly delay the closing of the overlay, preventing some unexpected
+                                       // changes to the scroll position on iOS.
+                                       if (Environment.platform() === "ios") {
+                                               window.setTimeout(callback, 100);
+                                       } else {
+                                               callback();
+                                       }
+                               }.bind(this)));
                        }
                },
                
index 1ad9e957f9cb82a818353f16722cd116079cbad6..63cf11955a8235e9b68f0223ec0dc40f5f2838b5 100644 (file)
@@ -179,7 +179,7 @@ if (COMPILER_TARGET_DEFAULT) {
                                case 'assignUser':
                                        var $span = $('#moderationAssignedUserContainer > dd > span').empty();
                                        if (data.returnValues.userID) {
-                                               $('<a href="' + data.returnValues.link + '" data-user-id="' + data.returnValues.userID + '" class="userLink">' + WCF.String.escapeHTML(data.returnValues.username) + '</a>').appendTo($span);
+                                               $('<a href="' + data.returnValues.link + '" data-object-id="' + data.returnValues.userID + '" class="userLink">' + WCF.String.escapeHTML(data.returnValues.username) + '</a>').appendTo($span);
                                        }
                                        else {
                                                $span.append(data.returnValues.username);
index e8d8cd1fcc67095c6132efbb57ed0cb799c8a11d..68d0207d1d935b7c9a369d848f4c1e0193f3617a 100644 (file)
@@ -603,6 +603,10 @@ WCF.Poll.Manager = Class.extend({
                                        this._canViewParticipants[$pollID] = true;
                                }
                                
+                               var totalVotes = elBySel('.jsPollTotalVotes', this._polls[$pollID][0]);
+                               totalVotes.textContent = WCF.String.formatNumeric(data.totalVotes);
+                               elData(totalVotes, 'tooltip', data.totalVotesTooltip);
+                               
                                this._showResult(null, $pollID);
                        break;
                }
index 2b5a12225fd765f598f997d312472cde75ee8d90..174694e1a5c594cda1f283ca0ecb7cb2b390c2a2 100644 (file)
@@ -174,6 +174,11 @@ if (COMPILER_TARGET_DEFAULT) {
                 */
                 _callbackFocus: null,
                
+               /**
+                * @var {string}
+                */
+               _callbackCloseUuid: '',
+               
                /**
                 * @var        boolean
                 */
@@ -193,6 +198,7 @@ if (COMPILER_TARGET_DEFAULT) {
                        this._triggerElement = triggerElement;
                        this._options = options;
                        this._callbackFocus = null;
+                       this._callbackCloseUuid = '';
                        
                        this._proxy = new WCF.Action.Proxy({
                                showLoadingOverlay: false,
@@ -259,10 +265,19 @@ if (COMPILER_TARGET_DEFAULT) {
                                        this._callbackFocus = this._maintainFocus.bind(this);
                                }
                                document.body.addEventListener('focus', this._callbackFocus, { capture: true });
+                               
+                               this._callbackCloseUuid = WCF.System.Event.addListener('WCF.Dropdown.Interactive.Instance', 'close', (function (data) {
+                                       if (data.instance === this._dropdown) {
+                                               WCF.System.Event.removeListener('WCF.Dropdown.Interactive.Instance', 'close', this._callbackCloseUuid);
+                                               document.body.removeEventListener('focus', this._callbackFocus, { capture: true });
+                                       }
+                               }).bind(this));
                        }
                        else {
                                elAttr(this._button, 'aria-expanded', false);
-                               document.body.removeEventListener('focus', this._callbackFocus);
+                               
+                               WCF.System.Event.removeListener('WCF.Dropdown.Interactive.Instance', 'close', this._callbackCloseUuid);
+                               document.body.removeEventListener('focus', this._callbackFocus, { capture: true });
                        }
                        
                        return false;
@@ -607,6 +622,23 @@ if (COMPILER_TARGET_DEFAULT) {
                        }
                        
                        this.updateBadge(count);
+               },
+               
+               _success: function(data) {
+                       this._super(data);
+                       
+                       elBySelAll('.interactiveDropdownItemShadowLink', this._dropdown.getItemList()[0], (function (link) {
+                               link.addEventListener('click', (function (event) {
+                                       if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
+                                               // Only close the drop-down if no key modifier was pressed.
+                                               return;
+                                       }
+                                       
+                                       this._dropdown.close();
+
+                                       WCF.System.Event.fireEvent('com.woltlab.wcf.UserMenuMobile', 'close');
+                               }).bind(this));
+                       }.bind(this)));
                }
        });
        
@@ -1603,6 +1635,7 @@ WCF.User.Registration.Validation.EmailAddress = WCF.User.Registration.Validation
  * Password validation for registration.
  * 
  * @see        WCF.User.Registration.Validation
+ * @deprecated 5.3
  */
 WCF.User.Registration.Validation.Password = WCF.User.Registration.Validation.extend({
        /**
@@ -1769,11 +1802,11 @@ if (COMPILER_TARGET_DEFAULT) {
                                }
                                
                                // work-around for legacy notifications
-                               if (!$item.find('a:not(.notificationItemMarkAsConfirmed)').length) {
-                                       $item.find('.details > p:eq(0)').html(function (index, oldHTML) {
-                                               return '<a href="' + $item.data('link') + '">' + oldHTML + '</a>';
-                                       });
-                               }
+                               var details = item.querySelector('.details > p:first-child');
+                               details.classList.add("pointer");
+                               details.addEventListener('click', function(event) {
+                                       window.location.href = $item.data('link');
+                               });
                        }).bind(this));
                        
                        WCF.DOMNodeInsertedHandler.execute();
@@ -2170,6 +2203,7 @@ WCF.User.LikeLoader = Class.extend({
  * Loads user profile previews.
  * 
  * @see        WCF.Popover
+ * @deprecated since 5.3, taken care of by `WoltLabSuite/Core/BootstrapFrontend` via `WoltLabSuite/Core/Controller/Popover`
  */
 WCF.User.ProfilePreview = WCF.Popover.extend({
        /**
index 00cf55583ad4b7a2832defd8c612df516c693547..8763adf6af21a125c0f52ae9f0d5d6467916ee8c 100755 (executable)
@@ -1203,6 +1203,10 @@ if (COMPILER_TARGET_DEFAULT) {
                close: function () {
                        this._triggerElement.removeClass('open');
                        this._container.removeClass('open');
+                       
+                       WCF.System.Event.fireEvent('WCF.Dropdown.Interactive.Instance', 'close', {
+                               instance: this
+                       });
                },
                
                /**
@@ -3698,7 +3702,7 @@ if (COMPILER_TARGET_DEFAULT) {
                                                this._enableOption($target, !isActive);
                                        }
                                        else {
-                                               var $dl = $('.' + $target + 'Input');
+                                               var $dl = $('.' + $.wcfEscapeID($target) + 'Input');
                                                if ($dl.length) {
                                                        this._enableOptions($dl.children('dd').find('input, select, textarea'), !isActive);
                                                }
@@ -3713,7 +3717,7 @@ if (COMPILER_TARGET_DEFAULT) {
                                                this._enableOption($target, isActive);
                                        }
                                        else {
-                                               var $dl = $('.' + $target + 'Input');
+                                               var $dl = $('.' + $.wcfEscapeID($target) + 'Input');
                                                if ($dl.length) {
                                                        this._enableOptions($dl.children('dd').find('input, select, textarea'), isActive);
                                                }
@@ -5100,7 +5104,7 @@ WCF.System.Fullscreen = {
        /**
         * Puts the given element into full screen mode.
         * Note: This must be a raw HTMLElement, not a jQuery wrapped one.
-        * Note: This must be called from an user triggered event listener for
+        * Note: This must be called from a user triggered event listener for
         *      security reasons.
         * 
         * @param       object          Element to show full screen.
index 828cf612f4e043df29bfd48d3fc1e628557a8c6a..d04d9a81d5eb3a8aa725c609f13f49bd0ec8a0ce 100644 (file)
@@ -3,19 +3,20 @@
 
 
 // WoltLabSuite.Core.min.js
-var requirejs,require,define;!function(global,Promise,undef){function commentReplace(e,t){return t||""}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return e&&hasProp(e,t)&&e[t]}function obj(){return Object.create(null)}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,n){return t&&eachProp(t,function(t,a){!i&&hasProp(e,a)||(!n||"object"!=typeof t||!t||Array.isArray(t)||"function"==typeof t||t instanceof RegExp?e[a]=t:(e[a]||(e[a]={}),mixin(e[a],t,i,n)))}),e}function getGlobal(e){if(!e)return e;var t=global;return e.split(".").forEach(function(e){t=t[e]}),t}function newContext(e){function t(e){var t,i,n=e.length;for(t=0;t<n;t++)if("."===(i=e[t]))e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;t>0&&(e.splice(t-1,2),t-=2)}}function i(e,i,n){var a,r,o,s,l,c,d,u,h,p,f=i&&i.split("/"),m=f,g=B.map,v=g&&g["*"];if(e&&(e=e.split("/"),c=e.length-1,B.nodeIdCompat&&jsSuffixRegExp.test(e[c])&&(e[c]=e[c].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&f&&(m=f.slice(0,f.length-1),e=m.concat(e)),t(e),e=e.join("/")),n&&g&&(f||v)){r=e.split("/");e:for(o=r.length;o>0;o-=1){if(l=r.slice(0,o).join("/"),f)for(s=f.length;s>0;s-=1)if((a=getOwn(g,f.slice(0,s).join("/")))&&(a=getOwn(a,l))){d=a,u=o;break e}!h&&v&&getOwn(v,l)&&(h=getOwn(v,l),p=o)}!d&&h&&(d=h,u=p),d&&(r.splice(0,u,d),e=r.join("/"))}return getOwn(B.pkgs,e)||e}function n(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t}function a(e){var t,i,n,a;for(t=0;t<queue.length;t+=1){if("string"!=typeof queue[t][0]){if(!e)break;queue[t].unshift(e),e=undef}n=queue.shift(),i=n[0],t-=1,i in x||i in T||(i in M?C.apply(undef,n):T[i]=n)}e&&(a=getOwn(B.shim,e)||{},C(e,a.deps||[],a.exportsFn))}function r(e,t){var n=function(i,r,o,s){var l,c;if(t&&a(),"string"==typeof i){if(S[i])return S[i](e);if(!((l=E(i,e,!0).id)in x))throw new Error("Not loaded: "+l);return x[l]}return i&&!Array.isArray(i)&&(c=i,i=undef,Array.isArray(r)&&(i=r,r=o,o=s),t)?n.config(c)(i,r,o):(r=r||function(){return slice.call(arguments,0)},V.then(function(){return a(),C(undef,i||[],r,o,e)}))};return n.isBrowser="undefined"!=typeof document&&"undefined"!=typeof navigator,n.nameToUrl=function(e,t,i){var a,r,o,s,l,c,d,u=getOwn(B.pkgs,e);if(u&&(e=u),d=getOwn(H,e))return n.nameToUrl(d,t,i);if(urlRegExp.test(e))l=e+(t||"");else{for(a=B.paths,r=e.split("/"),o=r.length;o>0;o-=1)if(s=r.slice(0,o).join("/"),c=getOwn(a,s)){Array.isArray(c)&&(c=c[0]),r.splice(0,o,c);break}l=r.join("/"),l+=t||(/^data\:|^blob\:|\?/.test(l)||i?"":".js"),l=("/"===l.charAt(0)||l.match(/^[\w\+\.\-]+:/)?"":B.baseUrl)+l}return B.urlArgs&&!/^blob\:/.test(l)?l+B.urlArgs(e,l):l},n.toUrl=function(t){var a,r=t.lastIndexOf("."),o=t.split("/")[0],s="."===o||".."===o;return-1!==r&&(!s||r>1)&&(a=t.substring(r,t.length),t=t.substring(0,r)),n.nameToUrl(i(t,e),a,!0)},n.defined=function(t){return E(t,e,!0).id in x},n.specified=function(t){return(t=E(t,e,!0).id)in x||t in M},n}function o(e,t,i){e&&(x[e]=i,requirejs.onResourceLoad&&requirejs.onResourceLoad(D,t.map,t.deps)),t.finished=!0,t.resolve(i)}function s(e,t){e.finished=!0,e.rejected=!0,e.reject(t)}function l(e){return function(t){return i(t,e,!0)}}function c(e){e.factoryCalled=!0;var t,i=e.map.id;try{t=D.execCb(i,e.factory,e.values,x[i])}catch(t){return s(e,t)}i?t===undef&&(e.cjsModule?t=e.cjsModule.exports:e.usingExports&&(t=x[i])):N.splice(N.indexOf(e),1),o(i,e,t)}function d(e,t){this.rejected||this.depDefined[t]||(this.depDefined[t]=!0,this.depCount+=1,this.values[t]=e,this.depending||this.depCount!==this.depMax||c(this))}function u(e,t){var i={};return i.promise=new Promise(function(t,n){i.resolve=t,i.reject=function(t){e||N.splice(N.indexOf(i),1),n(t)}}),i.map=e?t||E(e):{},i.depCount=0,i.depMax=0,i.values=[],i.depDefined=[],i.depFinished=d,i.map.pr&&(i.deps=[E(i.map.pr)]),i}function h(e,t){var i;return e?(i=e in M&&M[e])||(i=M[e]=u(e,t)):(i=u(),N.push(i)),i}function p(e,t){return function(i){e.rejected||(i.dynaId||(i.dynaId="id"+(F+=1),i.requireModules=[t]),s(e,i))}}function f(e,t,i,n){i.depMax+=1,L(e,t).then(function(e){i.depFinished(e,n)},p(i,e.id)).catch(p(i,i.map.id))}function m(e){function t(t){i||o(e,h(e),t)}var i;return t.error=function(t){h(e).reject(t)},t.fromText=function(t,n){var r=h(e),o=E(E(e).n),l=o.id;i=!0,r.factory=function(e,t){return t},n&&(t=n),hasProp(B.config,e)&&(B.config[l]=B.config[e]);try{y.exec(t)}catch(e){s(r,new Error("fromText eval for "+l+" failed: "+e))}a(l),r.deps=[o],f(o,null,r,r.deps.length)},t}function g(e,t,i){e.load(t.n,r(i),m(t.id),B)}function v(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function _(e,t,i){var n=e.map.id;t[n]=!0,!e.finished&&e.deps&&e.deps.forEach(function(n){var a=n.id,r=!hasProp(S,a)&&h(a,n);!r||r.finished||i[a]||(hasProp(t,a)?e.deps.forEach(function(t,i){t.id===a&&e.depFinished(x[a],i)}):_(r,t,i))}),i[n]=!0}function b(e){var t,i,n,a=[],r=1e3*B.waitSeconds,o=r&&O+r<(new Date).getTime();if(0===P&&(e?e.finished||_(e,{},{}):N.length&&N.forEach(function(e){_(e,{},{})})),o){for(i in M)n=M[i],n.finished||a.push(n.map.id);t=new Error("Timeout for modules: "+a),t.requireModules=a,y.onError(t)}else(P||N.length)&&(A||(A=!0,setTimeout(function(){A=!1,b()},70)))}function w(e){return setTimeout(function(){e.dynaId&&W[e.dynaId]||(W[e.dynaId]=!0,y.onError(e))}),e}var y,C,E,L,S,A,I,D,x=obj(),T=obj(),B={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k=obj(),N=[],M=obj(),U=obj(),j=obj(),P=0,O=(new Date).getTime(),F=0,W=obj(),R=obj(),H=obj(),V=Promise.resolve();return I="function"==typeof importScripts?function(e){var t=e.url;R[t]||(R[t]=!0,h(e.id),importScripts(t),a(e.id))}:function(e){var t,i=e.id,n=e.url;R[n]||(R[n]=!0,t=document.createElement("script"),t.setAttribute("data-requiremodule",i),t.type=B.scriptType||"text/javascript",t.charset="utf-8",t.async=!0,P+=1,t.addEventListener("load",function(){P-=1,a(i)},!1),t.addEventListener("error",function(){P-=1;var e,n=getOwn(B.paths,i);if(n&&Array.isArray(n)&&n.length>1){t.parentNode.removeChild(t),n.shift();var a=h(i);a.map=E(i),a.map.url=y.nameToUrl(i),I(a.map)}else e=new Error("Load failed: "+i+": "+t.src),e.requireModules=[i],h(i).reject(e)},!1),t.src=n,10===document.documentMode?asap.then(function(){document.head.appendChild(t)}):document.head.appendChild(t))},L=function(e,t){var i,n,a=e.id,r=B.shim[a];if(a in T)i=T[a],delete T[a],C.apply(undef,i);else if(!(a in M))if(e.pr){if(!(n=getOwn(H,a)))return L(E(e.pr)).then(function(i){var n=e.prn?e:E(a,t,!0),r=n.id,o=getOwn(B.shim,r);return r in j||(j[r]=!0,o&&o.deps?y(o.deps,function(){g(i,n,t)}):g(i,n,t)),h(r).promise});e.url=y.nameToUrl(n),I(e)}else r&&r.deps?y(r.deps,function(){I(e)}):I(e);return h(a).promise},E=function(e,t,n){if("string"!=typeof e)return e;var a,r,o,s,c,d,u=e+" & "+(t||"")+" & "+!!n;return o=v(e),s=o[0],e=o[1],!s&&u in k?k[u]:(s&&(s=i(s,t,n),a=s in x&&x[s]),s?a&&a.normalize?(e=a.normalize(e,l(t)),d=!0):e=-1===e.indexOf("!")?i(e,t,n):e:(e=i(e,t,n),o=v(e),s=o[0],e=o[1],r=y.nameToUrl(e)),c={id:s?s+"!"+e:e,n:e,pr:s,url:r,prn:s&&d},s||(k[u]=c),c)},S={require:function(e){return r(e)},exports:function(e){var t=x[e];return void 0!==t?t:x[e]={}},module:function(e){return{id:e,uri:"",exports:S.exports(e),config:function(){return getOwn(B.config,e)||{}}}}},C=function(e,t,i,n,a){if(e){if(e in U)return;U[e]=!0}var r=h(e);return t&&!Array.isArray(t)&&(i=t,t=[]),t=t?slice.call(t,0):null,n||(hasProp(B,"defaultErrback")?B.defaultErrback&&(n=B.defaultErrback):n=w),n&&r.promise.catch(n),a=a||e,"function"==typeof i?(!t.length&&i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t)),r.factory=i,r.deps=t,r.depending=!0,t.forEach(function(i,n){var o;t[n]=o=E(i,a,!0),i=o.id,"require"===i?r.values[n]=S.require(e):"exports"===i?(r.values[n]=S.exports(e),r.usingExports=!0):"module"===i?r.values[n]=r.cjsModule=S.module(e):void 0===i?r.values[n]=void 0:f(o,a,r,n)}),r.depending=!1,r.depCount===r.depMax&&c(r)):e&&o(e,r,i),O=(new Date).getTime(),e||b(r),r.promise},y=r(null,!0),y.config=function(t){if(t.context&&t.context!==e){var i=getOwn(contexts,t.context);return i?i.req.config(t):newContext(t.context).config(t)}if(k=obj(),t.baseUrl&&"/"!==t.baseUrl.charAt(t.baseUrl.length-1)&&(t.baseUrl+="/"),"string"==typeof t.urlArgs){var a=t.urlArgs;t.urlArgs=function(e,t){return(-1===t.indexOf("?")?"?":"&")+a}}var r=B.shim,o={paths:!0,bundles:!0,config:!0,map:!0};return eachProp(t,function(e,t){o[t]?(B[t]||(B[t]={}),mixin(B[t],e,!0,!0)):B[t]=e}),t.bundles&&eachProp(t.bundles,function(e,t){e.forEach(function(e){e!==t&&(H[e]=t)})}),t.shim&&(eachProp(t.shim,function(e,t){Array.isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=n(e)),r[t]=e}),B.shim=r),t.packages&&t.packages.forEach(function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(B.paths[i]=e.location),B.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),(t.deps||t.callback)&&y(t.deps,t.callback),y},y.onError=function(e){throw e},D={id:e,defined:x,waiting:T,config:B,deferreds:M,req:y,execCb:function(e,t,i,n){return t.apply(n,i)}},contexts[e]=D,y}if(!Promise)throw new Error("No Promise implementation available");var topReq,dataMain,src,subPath,bootstrapConfig=requirejs||require,hasOwn=Object.prototype.hasOwnProperty,contexts={},queue=[],currDirRegExp=/^\.\//,urlRegExp=/^\/|\:|\?|\.js$/,commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,slice=Array.prototype.slice;if("function"!=typeof requirejs){var asap=Promise.resolve(void 0);requirejs=topReq=newContext("_"),"function"!=typeof require&&(require=topReq),topReq.exec=function(text){return eval(text)},topReq.contexts=contexts,define=function(){queue.push(slice.call(arguments,0))},define.amd={jQuery:!0},bootstrapConfig&&topReq.config(bootstrapConfig),topReq.isBrowser&&!contexts._.config.skipDataMain&&(dataMain=document.querySelectorAll("script[data-main]")[0],(dataMain=dataMain&&dataMain.getAttribute("data-main"))&&(dataMain=dataMain.replace(jsSuffixRegExp,""),bootstrapConfig&&bootstrapConfig.baseUrl||-1!==dataMain.indexOf("!")||(src=dataMain.split("/"),dataMain=src.pop(),subPath=src.length?src.join("/")+"/":"./",topReq.config({baseUrl:subPath})),topReq([dataMain])))}}(this,"undefined"!=typeof Promise?Promise:void 0),define("requireLib",function(){}),requirejs.config({paths:{enquire:"3rdParty/enquire",favico:"3rdParty/favico","perfect-scrollbar":"3rdParty/perfect-scrollbar",Pica:"3rdParty/pica",prism:"3rdParty/prism"},shim:{enquire:{exports:"enquire"},favico:{exports:"Favico"},"perfect-scrollbar":{exports:"PerfectScrollbar"}},map:{"*":{Ajax:"WoltLabSuite/Core/Ajax",AjaxJsonp:"WoltLabSuite/Core/Ajax/Jsonp",AjaxRequest:"WoltLabSuite/Core/Ajax/Request",CallbackList:"WoltLabSuite/Core/CallbackList",ColorUtil:"WoltLabSuite/Core/ColorUtil",Core:"WoltLabSuite/Core/Core",DateUtil:"WoltLabSuite/Core/Date/Util",Devtools:"WoltLabSuite/Core/Devtools",Dictionary:"WoltLabSuite/Core/Dictionary","Dom/ChangeListener":"WoltLabSuite/Core/Dom/Change/Listener","Dom/Traverse":"WoltLabSuite/Core/Dom/Traverse","Dom/Util":"WoltLabSuite/Core/Dom/Util",Environment:"WoltLabSuite/Core/Environment",EventHandler:"WoltLabSuite/Core/Event/Handler",EventKey:"WoltLabSuite/Core/Event/Key",Language:"WoltLabSuite/Core/Language",List:"WoltLabSuite/Core/List",ObjectMap:"WoltLabSuite/Core/ObjectMap",Permission:"WoltLabSuite/Core/Permission",StringUtil:"WoltLabSuite/Core/StringUtil","Ui/Alignment":"WoltLabSuite/Core/Ui/Alignment","Ui/CloseOverlay":"WoltLabSuite/Core/Ui/CloseOverlay","Ui/Confirmation":"WoltLabSuite/Core/Ui/Confirmation","Ui/Dialog":"WoltLabSuite/Core/Ui/Dialog","Ui/Notification":"WoltLabSuite/Core/Ui/Notification","Ui/ReusableDropdown":"WoltLabSuite/Core/Ui/Dropdown/Reusable","Ui/Screen":"WoltLabSuite/Core/Ui/Screen","Ui/Scroll":"WoltLabSuite/Core/Ui/Scroll","Ui/SimpleDropdown":"WoltLabSuite/Core/Ui/Dropdown/Simple","Ui/TabMenu":"WoltLabSuite/Core/Ui/TabMenu",Upload:"WoltLabSuite/Core/Upload",User:"WoltLabSuite/Core/User"}},waitSeconds:0}),define("jquery",[],function(){return window.jQuery}),define("require.config",function(){}),function(e,t){e.elAttr=function(e,t,i){if(void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elAttrBool=function(e,t){var i=elAttr(e,t);return"1"===i||"true"===i},e.elByClass=function(e,i){return(i||t).getElementsByClassName(e)},e.elById=function(e){return t.getElementById(e)},e.elBySel=function(e,i){return(i||t).querySelector(e)},e.elBySelAll=function(e,i,n){var a=(i||t).querySelectorAll(e);return"function"==typeof n&&Array.prototype.forEach.call(a,n),a},e.elByTag=function(e,i){return(i||t).getElementsByTagName(e)},e.elCreate=function(e){return t.createElement(e)},e.elClosest=function(e,t){if(!(e instanceof Node))throw new TypeError("Provided element is not a Node.");return e.nodeType===Node.TEXT_NODE&&null===(e=e.parentNode)?null:("string"!=typeof t&&(t=""),0===t.length?e:e.closest(t))},e.elData=function(e,t,i){if(t="data-"+t,void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elDataBool=function(e,t){var i=elData(e,t);return"1"===i||"true"===i},e.elHide=function(e){e.style.setProperty("display","none","")},e.elIsHidden=function(e){return"none"===e.style.getPropertyValue("display")},e.elInnerError=function(e,t,i){var n=e.parentNode;if(null===n)throw new Error("Only elements that have a parent element or document are valid.");if("string"!=typeof t){if(void 0!==t&&null!==t&&!1!==t)throw new TypeError("The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.");t=""}var a=e.nextElementSibling;return null!==a&&"SMALL"===a.nodeName&&a.classList.contains("innerError")||(""===t?a=null:(a=elCreate("small"),a.className="innerError",n.insertBefore(a,e.nextSibling))),""===t?null!==a&&(n.removeChild(a),a=null):a[i?"innerHTML":"textContent"]=t,a},e.elRemove=function(e){e.parentNode.removeChild(e)},e.elShow=function(e){e.style.removeProperty("display")},e.elToggle=function(e){"none"===e.style.getPropertyValue("display")?elShow(e):elHide(e)},e.forEach=function(e,t){for(var i=0,n=e.length;i<n;i++)t(e[i],i)},e.objOwns=function(e,t){return e.hasOwnProperty(t)};"touchstart"in t.documentElement||"ontouchstart"in e||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints;Object.defineProperty(e,"WCF_CLICK_EVENT",{value:"click"}),function(){function t(){e.history.state&&e.history.state.name&&"initial"!==e.history.state.name?(e.history.replaceState({name:"skip",depth:++i},""),e.history.back(),setTimeout(t,1)):e.history.replaceState({name:"initial"},"")}var i=0;t(),e.addEventListener("popstate",function(t){t.state&&t.state.name&&"skip"===t.state.name&&e.history.go(t.state.depth)})}(),e.String.prototype.hashCode=function(){var e,t=0;if(this.length)for(var i=0,n=this.length;i<n;i++)e=this.charCodeAt(i),t=(t<<5)-t+e,t&=t;return t}}(window,document),define("wcf.globalHelper",function(){}),define("WoltLabSuite/Core/Core",[],function(){"use strict";var e=function(e){return"object"==typeof e&&(Array.isArray(e)||n.isPlainObject(e))?t(e):e},t=function(t){if(!t)return null;if(Array.isArray(t))return t.slice();var i={};for(var n in t)t.hasOwnProperty(n)&&void 0!==t[n]&&(i[n]=e(t[n]));return i},i="wsc"+window.WCF_PATH.hashCode()+"-",n={clone:function(t){return e(t)},convertLegacyUrl:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){var i=t.split(/([A-Z][a-z0-9]+)/);t="";for(var n=0,a=i.length;n<a;n++){var r=i[n].trim();r.length&&(t.length&&(t+="-"),t+=r.toLowerCase())}return"index.php?"+t+"/&"})},extend:function(e){e=e||{};for(var t=this.clone(e),i=1,n=arguments.length;i<n;i++){var a=arguments[i];if(a)for(var r in a)objOwns(a,r)&&(Array.isArray(a[r])||"object"!=typeof a[r]?t[r]=a[r]:this.isPlainObject(a[r])?t[r]=this.extend(e[r],a[r]):t[r]=a[r])}return t},inherit:function(e,t,i){if(void 0===e||null===e)throw new TypeError("The constructor must not be undefined or null.");if(void 0===t||null===t)throw new TypeError("The super constructor must not be undefined or null.");if(void 0===t.prototype)throw new TypeError("The super constructor must have a prototype.");e._super=t,e.prototype=n.extend(Object.create(t.prototype,{constructor:{configurable:!0,enumerable:!1,value:e,writable:!0}}),i||{})},isPlainObject:function(e){return"object"==typeof e&&null!==e&&!e.nodeType&&Object.getPrototypeOf(e)===Object.prototype},getType:function(e){return Object.prototype.toString.call(e).replace(/^\[object (.+)\]$/,"$1")},getUuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},serialize:function(e,t){var i=[];for(var n in e)if(objOwns(e,n)){var a=t?t+"["+n+"]":n,r=e[n];"object"==typeof r?i.push(this.serialize(r,a)):i.push(encodeURIComponent(a)+"="+encodeURIComponent(r))}return i.join("&")},triggerEvent:function(e,t){if("click"===t&&e instanceof HTMLElement)return void e.click();var i;try{i=new Event(t,{bubbles:!0,cancelable:!0})}catch(e){i=document.createEvent("Event"),i.initEvent(t,!0,!0)}e.dispatchEvent(i)},getStoragePrefix:function(){return i}};return n}),define("WoltLabSuite/Core/Dictionary",["Core"],function(e){"use strict";function t(){this._dictionary=i?new Map:{}}var i=objOwns(window,"Map")&&"function"==typeof window.Map;return t.prototype={set:function(e,t){if("number"==typeof e&&(e=e.toString()),"string"!=typeof e)throw new TypeError("Only strings can be used as keys, rejected '"+e+"' ("+typeof e+").");i?this._dictionary.set(e,t):this._dictionary[e]=t},delete:function(e){"number"==typeof e&&(e=e.toString()),i?this._dictionary.delete(e):this._dictionary[e]=void 0},has:function(e){return"number"==typeof e&&(e=e.toString()),i?this._dictionary.has(e):objOwns(this._dictionary,e)&&void 0!==this._dictionary[e]},get:function(e){if("number"==typeof e&&(e=e.toString()),this.has(e))return i?this._dictionary.get(e):this._dictionary[e]},forEach:function(e){if("function"!=typeof e)throw new TypeError("forEach() expects a callback as first parameter.");if(i)this._dictionary.forEach(e);else for(var t=Object.keys(this._dictionary),n=0,a=t.length;n<a;n++)e(this._dictionary[t[n]],t[n])},merge:function(){for(var e=0,i=arguments.length;e<i;e++){var n=arguments[e];if(!(n instanceof t))throw new TypeError("Expected an object of type Dictionary, but argument "+e+" is not.");n.forEach(function(e,t){this.set(t,e)}.bind(this))}},toObject:function(){if(!i)return e.clone(this._dictionary);var t={};return this._dictionary.forEach(function(e,i){t[i]=e}),t}},t.fromObject=function(e){var i=new t;for(var n in e)objOwns(e,n)&&i.set(n,e[n]);return i},Object.defineProperty(t.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return i?this._dictionary.size:Object.keys(this._dictionary).length}}),t}),define("WoltLabSuite/Core/Template.grammar",["require"],function(e){var t=function(e,t,i,n){for(i=i||{},n=e.length;n--;i[e[n]]=t);return i},i=[2,37],n=[5,9,11,12,13,18,19,21,22,23,25,26,27,28,30,31,32,33,35,37,39],a=[1,24],r=[1,25],o=[1,31],s=[1,29],l=[1,30],c=[1,26],d=[1,27],u=[1,33],h=[11,12,15,40,41,45,47,49,50,52],p=[9,11,12,13,18,19,21,23,26,28,30,31,32,33,35,37],f=[11,12,15,40,41,44,45,46,47,49,50,52],m=[18,35,37],g=[12,15],v={trace:function(){},yy:{},symbols_:{error:2,TEMPLATE:3,CHUNK_STAR:4,EOF:5,CHUNK_STAR_repetition0:6,CHUNK:7,PLAIN_ANY:8,T_LITERAL:9,COMMAND:10,T_ANY:11,T_WS:12,"{if":13,COMMAND_PARAMETERS:14,"}":15,COMMAND_repetition0:16,COMMAND_option0:17,"{/if}":18,"{include":19,COMMAND_PARAMETER_LIST:20,"{implode":21,"{/implode}":22,"{foreach":23,COMMAND_option1:24,"{/foreach}":25,"{lang}":26,"{/lang}":27,"{":28,VARIABLE:29,"{#":30,"{@":31,"{ldelim}":32,"{rdelim}":33,ELSE:34,"{else}":35,ELSE_IF:36,"{elseif":37,FOREACH_ELSE:38,"{foreachelse}":39,T_VARIABLE:40,T_VARIABLE_NAME:41,VARIABLE_repetition0:42,VARIABLE_SUFFIX:43,"[":44,"]":45,".":46,"(":47,VARIABLE_SUFFIX_option0:48,")":49,"=":50,COMMAND_PARAMETER_VALUE:51,T_QUOTED_STRING:52,COMMAND_PARAMETERS_repetition_plus0:53,COMMAND_PARAMETER:54,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",9:"T_LITERAL",11:"T_ANY",12:"T_WS",13:"{if",15:"}",18:"{/if}",19:"{include",21:"{implode",22:"{/implode}",23:"{foreach",25:"{/foreach}",26:"{lang}",27:"{/lang}",28:"{",30:"{#",31:"{@",32:"{ldelim}",33:"{rdelim}",35:"{else}",37:"{elseif",39:"{foreachelse}",40:"T_VARIABLE",41:"T_VARIABLE_NAME",44:"[",45:"]",46:".",47:"(",49:")",50:"=",52:"T_QUOTED_STRING"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[8,1],[8,1],[10,7],[10,3],[10,5],[10,6],[10,3],[10,3],[10,3],[10,3],[10,1],[10,1],[34,2],[36,4],[38,2],[29,3],[43,3],[43,2],[43,3],[20,5],[20,3],[51,1],[51,1],[14,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,3],[6,0],[6,2],[16,0],[16,2],[17,0],[17,1],[24,0],[24,1],[42,0],[42,2],[48,0],[48,1],[53,1],[53,2]],performAction:function(e,t,i,n,a,r,o){var s=r.length-1;switch(a){case 1:return r[s-1]+";";case 2:var l=r[s].reduce(function(e,t){return t.encode&&!e[1]?e[0]+=" + '"+t.value:t.encode&&e[1]?e[0]+=t.value:!t.encode&&e[1]?e[0]+="' + "+t.value:t.encode||e[1]||(e[0]+=" + "+t.value),e[1]=t.encode,e},["''",!1]);l[1]&&(l[0]+="'"),this.$=l[0];break;case 3:case 4:this.$={encode:!0,value:r[s].replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n")};break;case 5:this.$={encode:!1,value:r[s]};break;case 8:this.$="(function() { if ("+r[s-5]+") { return "+r[s-3]+"; } "+r[s-2].join(" ")+" "+(r[s-1]||"")+" return ''; })()";break;case 9:if(!r[s-1].file)throw new Error("Missing parameter file");this.$=r[s-1].file+".fetch(v)";break;case 10:if(!r[s-3].from)throw new Error("Missing parameter from");if(!r[s-3].item)throw new Error("Missing parameter item");r[s-3].glue||(r[s-3].glue="', '"),this.$="(function() { return "+r[s-3].from+".map(function(item) { v["+r[s-3].item+"] = item; return "+r[s-1]+"; }).join("+r[s-3].glue+"); })()";break;case 11:if(!r[s-4].from)throw new Error("Missing parameter from");if(!r[s-4].item)throw new Error("Missing parameter item");this.$="(function() {var looped = false, result = '';if ("+r[s-4].from+" instanceof Array) {for (var i = 0; i < "+r[s-4].from+".length; i++) { looped = true;v["+r[s-4].key+"] = i;v["+r[s-4].item+"] = "+r[s-4].from+"[i];result += "+r[s-2]+";}} else {for (var key in "+r[s-4].from+") {if (!"+r[s-4].from+".hasOwnProperty(key)) continue;looped = true;v["+r[s-4].key+"] = key;v["+r[s-4].item+"] = "+r[s-4].from+"[key];result += "+r[s-2]+";}}return (looped ? result : "+(r[s-1]||"''")+"); })()";break;case 12:this.$="Language.get("+r[s-1]+", v)";break;case 13:this.$="StringUtil.escapeHTML("+r[s-1]+")";break;case 14:this.$="StringUtil.formatNumeric("+r[s-1]+")";break;case 15:this.$=r[s-1];break;case 16:this.$="'{'";break;case 17:this.$="'}'";break;case 18:this.$="else { return "+r[s]+"; }";break;case 19:this.$="else if ("+r[s-2]+") { return "+r[s]+"; }";break;case 20:this.$=r[s];break;case 21:this.$="v['"+r[s-1]+"']"+r[s].join("");break;case 22:this.$=r[s-2]+r[s-1]+r[s];break;case 23:this.$="['"+r[s]+"']";break;case 24:case 36:this.$=r[s-2]+(r[s-1]||"")+r[s];break;case 25:this.$=r[s],this.$[r[s-4]]=r[s-2];break;case 26:this.$={},this.$[r[s-2]]=r[s];break;case 29:this.$=r[s].join("");break;case 37:case 39:case 45:this.$=[];break;case 38:case 40:case 46:case 50:r[s-1].push(r[s]);break;case 49:this.$=[r[s]]}},table:[t([5,9,11,12,13,19,21,23,26,28,30,31,32,33],i,{3:1,4:2,6:3}),{1:[3]},{5:[1,4]},t([5,18,22,25,27,35,37,39],[2,2],{7:5,8:6,10:8,9:[1,7],11:[1,9],12:[1,10],13:[1,11],19:[1,12],21:[1,13],23:[1,14],26:[1,15],28:[1,16],30:[1,17],31:[1,18],32:[1,19],33:[1,20]}),{1:[2,1]},t(n,[2,38]),t(n,[2,3]),t(n,[2,4]),t(n,[2,5]),t(n,[2,6]),t(n,[2,7]),{11:a,12:r,14:21,29:28,40:o,41:s,47:l,50:c,52:d,53:22,54:23},{20:32,41:u},{20:34,41:u},{20:35,41:u},t([9,11,12,13,19,21,23,26,27,28,30,31,32,33],i,{6:3,4:36}),{29:37,40:o},{29:38,40:o},{29:39,40:o},t(n,[2,16]),t(n,[2,17]),{15:[1,40]},t([15,45,49],[2,29],{29:28,54:41,11:a,12:r,40:o,41:s,47:l,50:c,52:d}),t(h,[2,49]),t(h,[2,30]),t(h,[2,31]),t(h,[2,32]),t(h,[2,33]),t(h,[2,34]),t(h,[2,35]),{11:a,12:r,14:42,29:28,40:o,41:s,47:l,50:c,52:d,53:22,54:23},{41:[1,43]},{15:[1,44]},{50:[1,45]},{15:[1,46]},{15:[1,47]},{27:[1,48]},{15:[1,49]},{15:[1,50]},{15:[1,51]},t(p,i,{6:3,4:52}),t(h,[2,50]),{49:[1,53]},t(f,[2,45],{42:54}),t(n,[2,9]),{29:57,40:o,51:55,52:[1,56]},t([9,11,12,13,19,21,22,23,26,28,30,31,32,33],i,{6:3,4:58}),t([9,11,12,13,19,21,23,25,26,28,30,31,32,33,39],i,{6:3,4:59}),t(n,[2,12]),t(n,[2,13]),t(n,[2,14]),t(n,[2,15]),t(m,[2,39],{16:60}),t(h,[2,36]),t([11,12,15,40,41,45,49,50,52],[2,21],{43:61,44:[1,62],46:[1,63],47:[1,64]}),{12:[1,65],15:[2,26]},t(g,[2,27]),t(g,[2,28]),{22:[1,66]},{24:67,25:[2,43],38:68,39:[1,69]},{17:70,18:[2,41],34:72,35:[1,74],36:71,37:[1,73]},t(f,[2,46]),{11:a,12:r,14:75,29:28,40:o,41:s,47:l,50:c,52:d,53:22,54:23},{41:[1,76]},{11:a,12:r,14:78,29:28,40:o,41:s,47:l,48:77,49:[2,47],50:c,52:d,53:22,54:23},{20:79,41:u},t(n,[2,10]),{25:[1,80]},{25:[2,44]},t([9,11,12,13,19,21,23,25,26,28,30,31,32,33],i,{6:3,4:81}),{18:[1,82]},t(m,[2,40]),{18:[2,42]},{11:a,12:r,14:83,29:28,40:o,41:s,47:l,50:c,52:d,53:22,54:23},t([9,11,12,13,18,19,21,23,26,28,30,31,32,33],i,{6:3,4:84}),{45:[1,85]},t(f,[2,23]),{49:[1,86]},{49:[2,48]},{15:[2,25]},t(n,[2,11]),{25:[2,20]},t(n,[2,8]),{15:[1,87]},{18:[2,18]},t(f,[2,22]),t(f,[2,24]),t(p,i,{6:3,4:88}),t(m,[2,19])],defaultActions:{4:[2,1],68:[2,44],72:[2,42],78:[2,48],79:[2,25],81:[2,20],84:[2,18]},parseError:function(e,t){function i(e,t){this.message=e,this.hash=t}if(!t.recoverable)throw i.prototype=Error,new i(e,t);this.trace(e)},parse:function(e){var t=this,i=[0],n=[null],a=[],r=this.table,o="",s=0,l=0,c=0,d=a.slice.call(arguments,1),u=Object.create(this.lexer),h={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(h.yy[p]=this.yy[p]);u.setInput(e,h.yy),h.yy.lexer=u,h.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var f=u.yylloc;a.push(f);var m=u.options&&u.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,v,_,b,w,y,C,E,L,S=function(){var e;return e=u.lex()||1,"number"!=typeof e&&(e=t.symbols_[e]||e),e},A={};;){if(_=i[i.length-1],this.defaultActions[_]?b=this.defaultActions[_]:(null!==g&&void 0!==g||(g=S()),b=r[_]&&r[_][g]),void 0===b||!b.length||!b[0]){var I="";L=[];for(y in r[_])this.terminals_[y]&&y>2&&L.push("'"+this.terminals_[y]+"'");I=u.showPosition?"Parse error on line "+(s+1)+":\n"+u.showPosition()+"\nExpecting "+L.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(s+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(I,{text:u.match,token:this.terminals_[g]||g,line:u.yylineno,loc:f,expected:L})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(b[0]){case 1:i.push(g),n.push(u.yytext),a.push(u.yylloc),i.push(b[1]),g=null,v?(g=v,v=null):(l=u.yyleng,o=u.yytext,s=u.yylineno,f=u.yylloc,c>0&&c--);break;case 2:if(C=this.productions_[b[1]][1],A.$=n[n.length-C],A._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(A._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(w=this.performAction.apply(A,[o,l,s,h.yy,b[1],n,a].concat(d))))return w;C&&(i=i.slice(0,-1*C*2),n=n.slice(0,-1*C),a=a.slice(0,-1*C)),i.push(this.productions_[b[1]][0]),n.push(A.$),a.push(A._$),E=r[i[i.length-2]][i[i.length-1]],i.push(E);break;case 3:return!0}}return!0}},_=function(){return{EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,n,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),n=e[0].match(/(?:\r\n?|\n).*/g),n&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in a)this[r]=a[r];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var e,t,i,n;this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),r=0;r<a.length;r++)if((i=this._input.match(this.rules[a[r]]))&&(!t||i[0].length>t[0].length)){if(t=i,n=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,a[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,a[n]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{
-text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return e=this.conditionStack.length-1-Math.abs(e||0),e>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,i,n){switch(i){case 0:break;case 1:return t.yytext=t.yytext.substring(9,t.yytext.length-10),9;case 2:case 3:return 52;case 4:return 40;case 5:return 41;case 6:return 46;case 7:return 44;case 8:return 45;case 9:return 47;case 10:return 49;case 11:return 50;case 12:return 32;case 13:return 33;case 14:return this.begin("command"),30;case 15:return this.begin("command"),31;case 16:return this.begin("command"),13;case 17:case 18:return this.begin("command"),37;case 19:return 35;case 20:return 18;case 21:return 26;case 22:return 27;case 23:return this.begin("command"),19;case 24:return this.begin("command"),21;case 25:return 22;case 26:return this.begin("command"),23;case 27:return 39;case 28:return 25;case 29:return this.begin("command"),28;case 30:return this.popState(),15;case 31:return 12;case 32:return 5;case 33:return 11}},rules:[/^(?:\{\*[\s\S]*?\*\})/,/^(?:\{literal\}[\s\S]*?\{\/literal\})/,/^(?:"([^"]|\\\.)*")/,/^(?:'([^']|\\\.)*')/,/^(?:\$)/,/^(?:[_a-zA-Z][_a-zA-Z0-9]*)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:=)/,/^(?:\{ldelim\})/,/^(?:\{rdelim\})/,/^(?:\{#)/,/^(?:\{@)/,/^(?:\{if )/,/^(?:\{else if )/,/^(?:\{elseif )/,/^(?:\{else\})/,/^(?:\{\/if\})/,/^(?:\{lang\})/,/^(?:\{\/lang\})/,/^(?:\{include )/,/^(?:\{implode )/,/^(?:\{\/implode\})/,/^(?:\{foreach )/,/^(?:\{foreachelse\})/,/^(?:\{\/foreach\})/,/^(?:\{(?!\s))/,/^(?:\})/,/^(?:\s+)/,/^(?:$)/,/^(?:[^{])/],conditions:{command:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],inclusive:!0},INITIAL:{rules:[0,1,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,33],inclusive:!0}}}}();return v.lexer=_,v}),define("WoltLabSuite/Core/NumberUtil",[],function(){"use strict";return{round:function(e,t){return void 0===t||0==+t?Math.round(e):(e=+e,t=+t,isNaN(e)||"number"!=typeof t||t%1!=0?NaN:(e=e.toString().split("e"),e=Math.round(+(e[0]+"e"+(e[1]?+e[1]-t:-t))),e=e.toString().split("e"),+(e[0]+"e"+(e[1]?+e[1]+t:t))))}}}),define("WoltLabSuite/Core/StringUtil",["Language","./NumberUtil"],function(e,t){"use strict";return{addThousandsSeparator:function(t){return void 0===e&&(e=require("Language")),String(t).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+e.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(i,n){void 0===e&&(e=require("Language")),i=String(t.round(i,n||-2));var a=i.split(".");return i=this.addThousandsSeparator(a[0]),a.length>1&&(i+=e.get("wcf.global.decimalPoint")+a[1]),i=i.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")},shortUnit:function(e){var i="";return e>=1e6?(e/=1e6,e=e>10?Math.floor(e):t.round(e,-1),i="M"):e>=1e3&&(e/=1e3,e=e>10?Math.floor(e):t.round(e,-1),i="k"),this.formatNumeric(e)+i}}}),define("WoltLabSuite/Core/Template",["./Template.grammar","./StringUtil","Language"],function(e,t,i){"use strict";function n(){this.yy={}}function a(n){void 0===i&&(i=require("Language")),void 0===t&&(t=require("StringUtil"));try{n=e.parse(n),n="var tmp = {};\nfor (var key in v) tmp[key] = v[key];\nv = tmp;\nv.__wcf = window.WCF; v.__window = window;\nreturn "+n,this.fetch=new Function("StringUtil","Language","v",n).bind(void 0,t,i)}catch(e){throw console.debug(e.message),e}}return n.prototype=e,e.Parser=n,e=new n,Object.defineProperty(a,"callbacks",{enumerable:!1,configurable:!1,get:function(){throw new Error("WCF.Template.callbacks is no longer supported")},set:function(e){throw new Error("WCF.Template.callbacks is no longer supported")}}),a.prototype={fetch:function(e){throw new Error("This Template is not initialized.")}},a}),define("WoltLabSuite/Core/Language",["Dictionary","./Template"],function(e,t){"use strict";var i=new e;return{addObject:function(t){i.merge(e.fromObject(t))},add:function(e,t){i.set(e,t)},get:function(e,n){n||(n={});var a=i.get(e);if(void 0===a)return e;if(void 0===t&&(t=require("WoltLabSuite/Core/Template")),"string"==typeof a){try{i.set(e,new t(a))}catch(n){i.set(e,new t("{literal}"+a.replace(/\{\/literal\}/g,"{/literal}{ldelim}/literal}{literal}")+"{/literal}"))}a=i.get(e)}return a instanceof t&&(a=a.fetch(n)),a}}}),define("WoltLabSuite/Core/CallbackList",["Dictionary"],function(e){"use strict";function t(){this._dictionary=new e}return t.prototype={add:function(e,t){if("function"!=typeof t)throw new TypeError("Expected a valid callback as second argument for identifier '"+e+"'.");this._dictionary.has(e)||this._dictionary.set(e,[]),this._dictionary.get(e).push(t)},remove:function(e){this._dictionary.delete(e)},forEach:function(e,t){if(null===e)this._dictionary.forEach(function(e,i){e.forEach(t)});else{var i=this._dictionary.get(e);void 0!==i&&i.forEach(t)}}},t}),define("WoltLabSuite/Core/Dom/Change/Listener",["CallbackList"],function(e){"use strict";var t=new e,i=!1;return{add:t.add.bind(t),remove:t.remove.bind(t),trigger:function(){if(!i)try{i=!0,t.forEach(null,function(e){e()})}finally{i=!1}}}}),define("WoltLabSuite/Core/Environment",[],function(){"use strict";var e="other",t="none",i="desktop",n=!1;return{setup:function(){if("object"==typeof window.chrome)e="chrome";else for(var a=window.getComputedStyle(document.documentElement),r=0,o=a.length;r<o;r++){var s=a[r];0===s.indexOf("-ms-")?e="microsoft":0===s.indexOf("-moz-")?e="firefox":"firefox"!==e&&0===s.indexOf("-webkit-")&&(e="safari")}var l=window.navigator.userAgent.toLowerCase();-1!==l.indexOf("crios")?(e="chrome",i="ios"):/(?:iphone|ipad|ipod)/.test(l)?(e="safari",i="ios"):-1!==l.indexOf("android")?i="android":-1!==l.indexOf("iemobile")&&(e="microsoft",i="windows"),"desktop"!==i||-1===l.indexOf("mobile")&&-1===l.indexOf("tablet")||(i="mobile"),t="redactor",n=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&window.navigator.msMaxTouchPoints>0||window.DocumentTouch&&document instanceof DocumentTouch,"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1&&(e="safari",i="ios")},browser:function(){return e},editor:function(){return t},platform:function(){return i},touch:function(){return n}}}),define("WoltLabSuite/Core/Dom/Util",["Environment","StringUtil"],function(e,t){"use strict";function i(e,t,i){if(!t.contains(e))throw new Error("Ancestor element does not contain target element.");for(var n,a=i+"Sibling";null!==e&&e!==t;){if(null!==e[i+"ElementSibling"])return!1;if(e[a])for(n=e[a];n;){if(""!==n.textContent.trim())return!1;n=n[a]}e=e.parentNode}return!0}var n=0,a={createFragmentFromHtml:function(e){var t=elCreate("div");this.setInnerHtml(t,e);for(var i=document.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return i},getUniqueId:function(){var e;do{e="wcf"+n++}while(null!==elById(e));return e},identify:function(e){if(!(e instanceof Element))throw new TypeError("Expected a valid DOM element as argument.");var t=elAttr(e,"id");return t||(t=this.getUniqueId(),elAttr(e,"id",t)),t},outerHeight:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetHeight;return i+=~~t.marginTop+~~t.marginBottom},outerWidth:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetWidth;return i+=~~t.marginLeft+~~t.marginRight},outerDimensions:function(e){var t=window.getComputedStyle(e);return{height:this.outerHeight(e,t),width:this.outerWidth(e,t)}},offset:function(e){var t=e.getBoundingClientRect();return{top:Math.round(t.top+(window.scrollY||window.pageYOffset)),left:Math.round(t.left+(window.scrollX||window.pageXOffset))}},prepend:function(e,t){0===t.childNodes.length?t.appendChild(e):t.insertBefore(e,t.childNodes[0])},insertAfter:function(e,t){null!==t.nextSibling?t.parentNode.insertBefore(e,t.nextSibling):t.parentNode.appendChild(e)},setStyles:function(e,t){var i=!1;for(var n in t)t.hasOwnProperty(n)&&(/ !important$/.test(t[n])?(i=!0,t[n]=t[n].replace(/ !important$/,"")):i=!1,"important"!==e.style.getPropertyPriority(n)||i||e.style.removeProperty(n),e.style.setProperty(n,t[n],i?"important":""))},styleAsInt:function(e,t){var i=e.getPropertyValue(t);return null===i?0:parseInt(i)},setInnerHtml:function(e,t){e.innerHTML=t;for(var i,n,a=elBySelAll("script",e),r=0,o=a.length;r<o;r++)n=a[r],i=elCreate("script"),n.src?i.src=n.src:i.textContent=n.textContent,e.appendChild(i),elRemove(n)},insertHtml:function(e,t,i){var n=elCreate("div");if(this.setInnerHtml(n,e),n.childNodes.length){var a=n.childNodes[0];switch(i){case"append":t.appendChild(a);break;case"after":this.insertAfter(a,t);break;case"prepend":this.prepend(a,t);break;case"before":t.parentNode.insertBefore(a,t);break;default:throw new Error("Unknown insert method '"+i+"'.")}for(var r;n.childNodes.length;)r=n.childNodes[0],this.insertAfter(r,a),a=r}},contains:function(e,t){for(;null!==t;)if(t=t.parentNode,e===t)return!0;return!1},getDataAttributes:function(e,i,n,a){i=i||"",/^data-/.test(i)||(i="data-"+i),n=!0===n,a=!0===a;for(var r,o,s,l={},c=0,d=e.attributes.length;c<d;c++)if(r=e.attributes[c],0===r.name.indexOf(i)){if(o=r.name.replace(new RegExp("^"+i),""),n){s=o.split("-"),o="";for(var u=0,h=s.length;u<h;u++)o.length&&(a&&"id"===s[u]?s[u]="ID":s[u]=t.ucfirst(s[u])),o+=s[u]}l[o]=r.value}return l},unwrapChildNodes:function(e){for(var t=e.parentNode;e.childNodes.length;)t.insertBefore(e.childNodes[0],e);elRemove(e)},replaceElement:function(e,t){for(;e.childNodes.length;)t.appendChild(e.childNodes[0]);e.parentNode.insertBefore(t,e),elRemove(e)},isAtNodeStart:function(e,t){return i(e,t,"previous")},isAtNodeEnd:function(e,t){return i(e,t,"next")},getFixedParent:function(e){for(;e&&e!==document.body;){if("fixed"===window.getComputedStyle(e).getPropertyValue("position"))return e;e=e.offsetParent}return null}};return window.bc_wcfDomUtil=a,a}),define("WoltLabSuite/Core/ObjectMap",[],function(){"use strict";function e(){this._map=t?new WeakMap:{key:[],value:[]}}var t=objOwns(window,"WeakMap")&&"function"==typeof window.WeakMap;return e.prototype={set:function(e,i){if("object"!=typeof e||null===e)throw new TypeError("Only objects can be used as key");if("object"!=typeof i||null===i)throw new TypeError("Only objects can be used as value");t?this._map.set(e,i):(this._map.key.push(e),this._map.value.push(i))},delete:function(e){if(t)this._map.delete(e);else{var i=this._map.key.indexOf(e);this._map.key.splice(i),this._map.value.splice(i)}},has:function(e){return t?this._map.has(e):-1!==this._map.key.indexOf(e)},get:function(e){if(t)return this._map.get(e);var i=this._map.key.indexOf(e);return-1!==i?this._map.value[i]:void 0}},e}),define("WoltLabSuite/Core/Dom/Traverse",[],function(){"use strict";var e=[function(e,t){return!0},function(e,t){return e.matches(t)},function(e,t){return e.classList.contains(t)},function(e,t){return e.nodeName===t}],t=function(t,i,n){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(var a=[],r=0;r<t.childElementCount;r++)e[i](t.children[r],n)&&a.push(t.children[r]);return a},i=function(t,i,n,a){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(t=t.parentNode;t instanceof Element;){if(t===a)return null;if(e[i](t,n))return t;t=t.parentNode}return null},n=function(t,i,n,a){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");return t instanceof Element&&null!==t[i]&&e[n](t[i],a)?t[i]:null};return{childBySel:function(e,i){return t(e,1,i)[0]||null},childByClass:function(e,i){return t(e,2,i)[0]||null},childByTag:function(e,i){return t(e,3,i)[0]||null},childrenBySel:function(e,i){return t(e,1,i)},childrenByClass:function(e,i){return t(e,2,i)},childrenByTag:function(e,i){return t(e,3,i)},parentBySel:function(e,t,n){return i(e,1,t,n)},parentByClass:function(e,t,n){return i(e,2,t,n)},parentByTag:function(e,t,n){return i(e,3,t,n)},next:function(e){return n(e,"nextElementSibling",0,null)},nextBySel:function(e,t){return n(e,"nextElementSibling",1,t)},nextByClass:function(e,t){return n(e,"nextElementSibling",2,t)},nextByTag:function(e,t){return n(e,"nextElementSibling",3,t)},prev:function(e){return n(e,"previousElementSibling",0,null)},prevBySel:function(e,t){return n(e,"previousElementSibling",1,t)},prevByClass:function(e,t){return n(e,"previousElementSibling",2,t)},prevByTag:function(e,t){return n(e,"previousElementSibling",3,t)}}}),define("WoltLabSuite/Core/Ui/Confirmation",["Core","Language","Ui/Dialog"],function(e,t,i){"use strict";var n=!1,a=null,r=null,o={},s=null;return{show:function(t){if(void 0===i&&(i=require("Ui/Dialog")),!n){if(o=e.extend({cancel:null,confirm:null,legacyCallback:null,message:"",messageIsHtml:!1,parameters:{},template:""},t),o.message="string"==typeof o.message?o.message.trim():"",!o.message.length)throw new Error("Expected a non-empty string for option 'message'.");if("function"!=typeof o.confirm&&"function"!=typeof o.legacyCallback)throw new TypeError("Expected a valid callback for option 'confirm'.");null===r&&this._createDialog(),r.innerHTML="string"==typeof o.template?o.template.trim():"",o.messageIsHtml?s.innerHTML=o.message:s.textContent=o.message,n=!0,i.open(this)}},_dialogSetup:function(){return{id:"wcfSystemConfirmation",options:{onClose:this._onClose.bind(this),onShow:this._onShow.bind(this),title:t.get("wcf.global.confirmation.title")}}},getContentElement:function(){return r},_createDialog:function(){var e=elCreate("div");elAttr(e,"id","wcfSystemConfirmation"),e.classList.add("systemConfirmation"),s=elCreate("p"),e.appendChild(s),r=elCreate("div"),elAttr(r,"id","wcfSystemConfirmationContent"),e.appendChild(r);var n=elCreate("div");n.classList.add("formSubmit"),e.appendChild(n),a=elCreate("button"),a.classList.add("buttonPrimary"),a.textContent=t.get("wcf.global.confirmation.confirm"),a.addEventListener(WCF_CLICK_EVENT,this._confirm.bind(this)),n.appendChild(a);var o=elCreate("button");o.textContent=t.get("wcf.global.confirmation.cancel"),o.addEventListener(WCF_CLICK_EVENT,function(){i.close("wcfSystemConfirmation")}),n.appendChild(o),document.body.appendChild(e)},_confirm:function(){"function"==typeof o.legacyCallback?o.legacyCallback("confirm",o.parameters,r):o.confirm(o.parameters,r),n=!1,i.close("wcfSystemConfirmation")},_onClose:function(){n&&(a.blur(),n=!1,"function"==typeof o.legacyCallback?o.legacyCallback("cancel",o.parameters,r):"function"==typeof o.cancel&&o.cancel(o.parameters))},_onShow:function(){a.blur(),a.focus()}}}),define("WoltLabSuite/Core/Ui/Screen",["Core","Dictionary","Environment"],function(e,t,i){"use strict";var n=null,a=new t,r=0,o=null,s=0,l=0,c=t.fromObject({"screen-xs":"(max-width: 544px)","screen-sm":"(min-width: 545px) and (max-width: 768px)","screen-sm-down":"(max-width: 768px)","screen-sm-up":"(min-width: 545px)","screen-sm-md":"(min-width: 545px) and (max-width: 1024px)","screen-md":"(min-width: 769px) and (max-width: 1024px)","screen-md-down":"(max-width: 1024px)","screen-md-up":"(min-width: 769px)","screen-lg":"(min-width: 1025px)","screen-lg-only":"(min-width: 1025px) and (max-width: 1280px)","screen-lg-down":"(max-width: 1280px)","screen-xl":"(min-width: 1281px)"}),d=new t;return{on:function(t,i){var n=e.getUuid(),a=this._getQueryObject(t);return"function"==typeof i.match&&a.callbacksMatch.set(n,i.match),"function"==typeof i.unmatch&&a.callbacksUnmatch.set(n,i.unmatch),"function"==typeof i.setup&&(a.mql.matches?i.setup():a.callbacksSetup.set(n,i.setup)),n},remove:function(e,t){var i=this._getQueryObject(e);i.callbacksMatch.delete(t),i.callbacksUnmatch.delete(t),i.callbacksSetup.delete(t)},is:function(e){return this._getQueryObject(e).mql.matches},scrollDisable:function(){if(0===r){s=document.body.scrollTop,o="body",s||(s=document.documentElement.scrollTop,o="documentElement");var e=elById("pageContainer");"ios"===i.platform()?(e.style.setProperty("position","relative",""),e.style.setProperty("top","-"+s+"px","")):e.style.setProperty("margin-top","-"+s+"px",""),document.documentElement.classList.add("disableScrolling")}r++},scrollEnable:function(){if(r&&0===--r){document.documentElement.classList.remove("disableScrolling");var e=elById("pageContainer");"ios"===i.platform()?(e.style.removeProperty("position"),e.style.removeProperty("top")):e.style.removeProperty("margin-top"),s&&(document[o].scrollTop=~~s)}},pageOverlayOpen:function(){0===l&&document.documentElement.classList.add("pageOverlayActive"),l++},pageOverlayClose:function(){l&&0===--l&&document.documentElement.classList.remove("pageOverlayActive")},pageOverlayIsActive:function(){return l>0},setDialogContainer:function(e){n=e},_getQueryObject:function(e){if("string"!=typeof e||""===e.trim())throw new TypeError("Expected a non-empty string for parameter 'query'.");d.has(e)&&(e=d.get(e)),c.has(e)&&(e=c.get(e));var i=a.get(e);return i||(i={callbacksMatch:new t,callbacksUnmatch:new t,callbacksSetup:new t,mql:window.matchMedia(e)},i.mql.addListener(this._mqlChange.bind(this)),a.set(e,i),e!==i.mql.media&&d.set(i.mql.media,e)),i},_mqlChange:function(e){var i=this._getQueryObject(e.media);if(e.matches)i.callbacksSetup.size?(i.callbacksSetup.forEach(function(e){e()}),i.callbacksSetup=new t):i.callbacksMatch.forEach(function(e){e()});else{if(i.callbacksSetup.size)return;i.callbacksUnmatch.forEach(function(e){e()})}}}}),define("WoltLabSuite/Core/Event/Key",[],function(){"use strict";function e(e,t,i){if(!(e instanceof Event))throw new TypeError("Expected a valid event when testing for key '"+t+"'.");return e.key===t||e.which===i}return{ArrowDown:function(t){return e(t,"ArrowDown",40)},ArrowLeft:function(t){return e(t,"ArrowLeft",37)},ArrowRight:function(t){return e(t,"ArrowRight",39)},ArrowUp:function(t){return e(t,"ArrowUp",38)},Comma:function(t){return e(t,",",44)},End:function(t){return e(t,"End",35)},Enter:function(t){return e(t,"Enter",13)},Escape:function(t){return e(t,"Escape",27)},Home:function(t){return e(t,"Home",36)},Space:function(t){return e(t,"Space",32)},Tab:function(t){return e(t,"Tab",9)}}}),define("WoltLabSuite/Core/Ui/Alignment",["Core","Language","Dom/Traverse","Dom/Util"],function(e,t,i,n){"use strict";return{set:function(a,r,o){o=e.extend({verticalOffset:0,pointer:!1,pointerClassNames:[],refDimensionsElement:null,horizontal:"left",vertical:"bottom",allowFlip:"both"},o),Array.isArray(o.pointerClassNames)&&o.pointerClassNames.length===(o.pointer?1:2)||(o.pointerClassNames=[]),-1===["left","right","center"].indexOf(o.horizontal)&&(o.horizontal="left"),"bottom"!==o.vertical&&(o.vertical="top"),-1===["both","horizontal","vertical","none"].indexOf(o.allowFlip)&&(o.allowFlip="both"),n.setStyles(a,{bottom:"auto !important",left:"0 !important",right:"auto !important",top:"0 !important",visibility:"hidden !important"});var s=n.outerDimensions(a),l=n.outerDimensions(o.refDimensionsElement instanceof Element?o.refDimensionsElement:r),c=n.offset(r),d=window.innerHeight,u=document.body.clientWidth,h={result:null},p=!1;if("center"===o.horizontal&&(p=!0,h=this._tryAlignmentHorizontal(o.horizontal,s,l,c,u),h.result||("both"===o.allowFlip||"horizontal"===o.allowFlip?o.horizontal="left":h.result=!0)),"rtl"===t.get("wcf.global.pageDirection")&&(o.horizontal="left"===o.horizontal?"right":"left"),!h.result){var f=h;if(h=this._tryAlignmentHorizontal(o.horizontal,s,l,c,u),!h.result&&("both"===o.allowFlip||"horizontal"===o.allowFlip)){var m=this._tryAlignmentHorizontal("left"===o.horizontal?"right":"left",s,l,c,u);m.result?h=m:p&&(h=f)}}var g=h.left,v=h.right,_=this._tryAlignmentVertical(o.vertical,s,l,c,d,o.verticalOffset);if(!_.result&&("both"===o.allowFlip||"vertical"===o.allowFlip)){var b=this._tryAlignmentVertical("top"===o.vertical?"bottom":"top",s,l,c,d,o.verticalOffset);b.result&&(_=b)}var w=_.bottom,y=_.top;if(o.pointer){var C=i.childrenByClass(a,"elementPointer");if(null===(C=C[0]||null))throw new Error("Expected the .elementPointer element to be a direct children.");"center"===h.align?(C.classList.add("center"),C.classList.remove("left"),C.classList.remove("right")):(C.classList.add(h.align),C.classList.remove("center"),C.classList.remove("left"===h.align?"right":"left")),"top"===_.align?C.classList.add("flipVertical"):C.classList.remove("flipVertical")}else if(2===o.pointerClassNames.length){a.classList["auto"===y?"add":"remove"](o.pointerClassNames[0]),a.classList["auto"===g?"add":"remove"](o.pointerClassNames[1])}"auto"!==w&&(w=Math.round(w)+"px"),"auto"!==g&&(g=Math.ceil(g)+"px"),"auto"!==v&&(v=Math.floor(v)+"px"),"auto"!==y&&(y=Math.round(y)+"px"),n.setStyles(a,{bottom:w,left:g,right:v,top:y}),elShow(a),a.style.removeProperty("visibility")},_tryAlignmentHorizontal:function(e,t,i,n,a){var r="auto",o="auto",s=!0;return"left"===e?(r=n.left)+t.width>a&&(s=!1):"right"===e?n.left+i.width<t.width?s=!1:(o=a-(n.left+i.width))<0&&(s=!1):(r=n.left+i.width/2-t.width/2,((r=~~r)<0||r+t.width>a)&&(s=!1)),{align:e,left:r,right:o,result:s}},_tryAlignmentVertical:function(e,t,i,n,a,r){var o="auto",s="auto",l=!0,c=50,d=elById("pageHeaderPanel");if(null!==d){var u=window.getComputedStyle(d).position;c="fixed"===u||"static"===u?d.offsetHeight:0}if("top"===e){var h=document.body.clientHeight;o=h-n.top+r,h-(o+t.height)<(window.scrollY||window.pageYOffset)+c&&(l=!1)}else(s=n.top+i.height+r)+t.height-(window.scrollY||window.pageYOffset)>a&&(l=!1);return{align:e,bottom:o,top:s,result:l}}}}),define("WoltLabSuite/Core/Ui/CloseOverlay",["CallbackList"],function(e){"use strict";var t=new e,i={setup:function(){document.body.addEventListener(WCF_CLICK_EVENT,this.execute.bind(this))},add:t.add.bind(t),remove:t.remove.bind(t),execute:function(){t.forEach(null,function(e){e()})}};return i.setup(),i}),define("WoltLabSuite/Core/Ui/Dropdown/Simple",["CallbackList","Core","Dictionary","EventKey","Ui/Alignment","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/CloseOverlay"],function(e,t,i,n,a,r,o,s,l){"use strict";var c=null,d=new e,u=!1,h=new i,p=new i,f=null,m=null,g="";return{setup:function(){u||(u=!0,f=elCreate("div"),f.className="dropdownMenuContainer",document.body.appendChild(f),c=elByClass("dropdownToggle"),this.initAll(),l.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.closeAll.bind(this)),r.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.initAll.bind(this)),document.addEventListener("scroll",this._onScroll.bind(this)),window.bc_wcfSimpleDropdown=this,m=this._dropdownMenuKeyDown.bind(this))},initAll:function(){for(var e=0,t=c.length;e<t;e++)this.init(c[e],!1)},init:function(e,i){if(this.setup(),elAttr(e,"role","button"),elAttr(e,"tabindex","0"),elAttr(e,"aria-haspopup",!0),elAttr(e,"aria-expanded",!1),e.classList.contains("jsDropdownEnabled")||elData(e,"target"))return!1;var n=o.parentByClass(e,"dropdown");if(null===n)throw new Error("Invalid dropdown passed, button '"+s.identify(e)+"' does not have a parent with .dropdown.");var a=o.nextByClass(e,"dropdownMenu");if(null===a)throw new Error("Invalid dropdown passed, button '"+s.identify(e)+"' does not have a menu as next sibling.");f.appendChild(a);var r=s.identify(n);if(!h.has(r)&&(e.classList.add("jsDropdownEnabled"),e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this)),e.addEventListener("keydown",this._handleKeyDown.bind(this)),h.set(r,n),p.set(r,a),r.match(/^wcf\d+$/)||elData(a,"source",r),a.childElementCount&&a.children[0].classList.contains("scrollableDropdownMenu"))){a=a.children[0],elData(a,"scroll-to-active",!0);var l=null,c=null;a.addEventListener("wheel",function(e){null===l&&(l=a.clientHeight),null===c&&(c=a.scrollHeight),e.deltaY<0&&0===a.scrollTop?e.preventDefault():e.deltaY>0&&a.scrollTop+l===c&&e.preventDefault()},{passive:!1})}elData(e,"target",r),i&&setTimeout(function(){elData(e,"dropdown-lazy-init",i instanceof MouseEvent),t.triggerEvent(e,WCF_CLICK_EVENT),setTimeout(function(){e.removeAttribute("data-dropdown-lazy-init")},10)},10)},initFragment:function(e,t){this.setup();var i=s.identify(e);h.has(i)||(h.set(i,e),f.appendChild(t),p.set(i,t))},registerCallback:function(e,t){d.add(e,t)},getDropdown:function(e){return h.get(e)},getDropdownMenu:function(e){return p.get(e)},toggleDropdown:function(e,t,i){this._toggle(null,e,t,i)},setAlignment:function(e,t,i){var n,r=elBySel(".dropdownToggle",e);null!==r&&r.parentNode.classList.contains("inputAddonTextarea")&&(n=r),a.set(t,i||e,{pointerClassNames:["dropdownArrowBottom","dropdownArrowRight"],refDimensionsElement:n||null,horizontal:"right"===elData(t,"dropdown-alignment-horizontal")?"right":"left",vertical:"top"===elData(t,"dropdown-alignment-vertical")?"top":"bottom",allowFlip:elData(t,"dropdown-allow-flip")||"both"})},setAlignmentById:function(e){var t=h.get(e);if(void 0===t)throw new Error("Unknown dropdown identifier '"+e+"'.");var i=p.get(e);this.setAlignment(t,i)},isOpen:function(e){var t=p.get(e);return void 0!==t&&t.classList.contains("dropdownOpen")},open:function(e,t){var i=p.get(e);void 0===i||i.classList.contains("dropdownOpen")||this.toggleDropdown(e,void 0,t)},close:function(e){var t=h.get(e);void 0!==t&&(t.classList.remove("dropdownOpen"),p.get(e).classList.remove("dropdownOpen"))},closeAll:function(){h.forEach(function(e,t){e.classList.contains("dropdownOpen")&&(e.classList.remove("dropdownOpen"),p.get(t).classList.remove("dropdownOpen"),this._notifyCallbacks(t,"close"))}.bind(this))},destroy:function(e){if(!h.has(e))return!1;try{this.close(e),elRemove(p.get(e))}catch(e){}return p.delete(e),h.delete(e),!0},_onDialogScroll:function(e){for(var t=e.currentTarget,i=elBySelAll(".dropdown.dropdownOpen",t),n=0,a=i.length;n<a;n++){var r=i[n],o=s.identify(r),l=s.offset(r),c=s.offset(t);l.top+r.clientHeight<=c.top?this.toggleDropdown(o):l.top>=c.top+t.offsetHeight?this.toggleDropdown(o):l.left<=c.left?this.toggleDropdown(o):l.left>=c.left+t.offsetWidth?this.toggleDropdown(o):this.setAlignment(h.get(o),p.get(o))}},_onScroll:function(){h.forEach(function(e,t){if(e.classList.contains("dropdownOpen"))if(elDataBool(e,"is-overlay-dropdown-button"))this.setAlignment(e,p.get(t));else{var i=p.get(e.id);elDataBool(i,"dropdown-ignore-page-scroll")||this.close(t)}}.bind(this))},_notifyCallbacks:function(e,t){d.forEach(e,function(i){i(e,t)})},_toggle:function(e,t,i,n){null!==e&&(e.preventDefault(),e.stopPropagation(),t=elData(e.currentTarget,"target"),void 0===n&&e instanceof MouseEvent&&(n=!0));var a=h.get(t),r=!1;if(void 0!==a){var s,l;if(e&&(s=e.currentTarget,(l=s.parentNode)!==a&&(l.classList.add("dropdown"),l.id=a.id,a.classList.remove("dropdown"),a.id="",a=l,h.set(t,l))),void 0===n&&(s=a.closest(".dropdownToggle"),s||!(s=elBySel(".dropdownToggle",a))&&a.id&&(s=elBySel('[data-target="'+a.id+'"]')),s&&elDataBool(s,"dropdown-lazy-init")&&(n=!0)),elDataBool(a,"dropdown-prevent-toggle")&&a.classList.contains("dropdownOpen")&&(r=!0),""===elData(a,"is-overlay-dropdown-button")){var c=o.parentByClass(a,"dialogContent");elData(a,"is-overlay-dropdown-button",null!==c),null!==c&&c.addEventListener("scroll",this._onDialogScroll.bind(this))}}return g="",h.forEach(function(e,a){var o=p.get(a);if(e.classList.contains("dropdownOpen"))if(!1===r){e.classList.remove("dropdownOpen"),o.classList.remove("dropdownOpen");var s=elBySel(".dropdownToggle",e);s&&elAttr(s,"aria-expanded",!1),this._notifyCallbacks(a,"close")}else g=t;else if(a===t&&o.childElementCount>0){g=t,e.classList.add("dropdownOpen"),o.classList.add("dropdownOpen");var s=elBySel(".dropdownToggle",e);if(s&&elAttr(s,"aria-expanded",!0),o.childElementCount&&elDataBool(o.children[0],"scroll-to-active")){var l=o.children[0];l.removeAttribute("data-scroll-to-active");for(var c=null,d=0,u=l.childElementCount;d<u;d++)if(l.children[d].classList.contains("active")){c=l.children[d];break}c&&(l.scrollTop=Math.max(c.offsetTop+c.clientHeight-o.clientHeight,0))}var h=elBySel(".scrollableDropdownMenu",o);null!==h&&h.classList[h.scrollHeight>h.clientHeight?"add":"remove"]("forceScrollbar"),this._notifyCallbacks(a,"open");var f=null;n||(elAttr(o,"role","menu"),elAttr(o,"tabindex",-1),o.removeEventListener("keydown",m),o.addEventListener("keydown",m),elBySelAll("li",o,function(e){e.clientHeight&&(null===f?f=e:e.classList.contains("active")&&(f=e),elAttr(e,"role","menuitem"),elAttr(e,"tabindex",-1))})),this.setAlignment(e,o,i),null!==f&&f.focus()}}.bind(this)),window.WCF.Dropdown.Interactive.Handler.closeAll(),null===e},_handleKeyDown:function(e){"INPUT"!==e.currentTarget.nodeName&&(n.Enter(e)||n.Space(e))&&(e.preventDefault(),this._toggle(e))},_dropdownMenuKeyDown:function(e){var t,i,a=document.activeElement;if("LI"===a.nodeName)if(n.ArrowDown(e)||n.ArrowUp(e)||n.End(e)||n.Home(e)){e.preventDefault();var r=Array.prototype.slice.call(elBySelAll("li",a.closest(".dropdownMenu")));(n.ArrowUp(e)||n.End(e))&&r.reverse();var o=null,s=function(e){return!e.classList.contains("dropdownDivider")&&e.clientHeight>0},l=r.indexOf(a);(n.End(e)||n.Home(e))&&(l=-1);for(var c=l+1;c<r.length;c++)if(s(r[c])){o=r[c];break}if(null===o)for(c=0;c<r.length;c++)if(s(r[c])){o=r[c];break}o.focus()}else if(n.Enter(e)||n.Space(e)){e.preventDefault();var d=a;1!==d.childElementCount||"SPAN"!==d.children[0].nodeName&&"A"!==d.children[0].nodeName||(d=d.children[0]),i=h.get(g),t=elBySel(".dropdownToggle",i),require(["Core"],function(e){var n=elData(i,"a11y-mouse-event")||"click";e.triggerEvent(d,n),t&&t.focus()})}else(n.Escape(e)||n.Tab(e))&&(e.preventDefault(),i=h.get(g),t=elBySel(".dropdownToggle",i),null!==t||i.classList.contains("dropdown")||(t=i),this._toggle(null,g),t&&t.focus())}}}),define("WoltLabSuite/Core/Devtools",[],function(){"use strict";var e={editorAutosave:!0,eventLogging:!1},t=function(){window.sessionStorage&&window.sessionStorage.setItem("__wsc_devtools_config",JSON.stringify(e))},i={help:function(){window.console.log(""),window.console.log("%cAvailable commands:","text-decoration: underline");var e=[];for(var t in i)"_internal_"!==t&&i.hasOwnProperty(t)&&e.push(t);e.sort().forEach(function(e){window.console.log("\tDevtools."+e+"()")}),window.console.log("")},toggleEditorAutosave:function(i){e.editorAutosave=!0!==i&&!e.editorAutosave,t(),window.console.log("%c\tEditor autosave "+(e.editorAutosave?"enabled":"disabled"),"font-style: italic")},toggleEventLogging:function(i){e.eventLogging=!0===i||!e.eventLogging,t(),window.console.log("%c\tEvent logging "+(e.eventLogging?"enabled":"disabled"),"font-style: italic")},_internal_:{enable:function(){if(window.Devtools=i,window.console.log("%cDevtools for WoltLab Suite loaded","font-weight: bold"),window.sessionStorage){var t=window.sessionStorage.getItem("__wsc_devtools_config");try{null!==t&&(e=JSON.parse(t))}catch(e){}e.editorAutosave||i.toggleEditorAutosave(!0),e.eventLogging&&i.toggleEventLogging(!0)}window.console.log("Settings are saved per browser session, enter `Devtools.help()` to learn more."),window.console.log("")},editorAutosave:function(){return e.editorAutosave},eventLog:function(t,i){e.eventLogging&&window.console.log("[Devtools.EventLogging] Firing event: "+i+" @ "+t)}}};return i}),define("WoltLabSuite/Core/Event/Handler",["Core","Devtools","Dictionary"],function(e,t,i){"use strict";var n=new i;return{add:function(t,a,r){
-if("function"!=typeof r)throw new TypeError("[WoltLabSuite/Core/Event/Handler] Expected a valid callback for '"+a+"@"+t+"'.");var o=n.get(t);void 0===o&&(o=new i,n.set(t,o));var s=o.get(a);void 0===s&&(s=new i,o.set(a,s));var l=e.getUuid();return s.set(l,r),l},fire:function(e,i,a){t._internal_.eventLog(e,i),a=a||{};var r=n.get(e);if(void 0!==r){var o=r.get(i);void 0!==o&&o.forEach(function(e){e(a)})}},remove:function(e,t,i){var a=n.get(e);if(void 0!==a){var r=a.get(t);void 0!==r&&r.delete(i)}},removeAll:function(e,t){"string"!=typeof t&&(t=void 0);var i=n.get(e);void 0!==i&&(void 0===t?n.delete(e):i.delete(t))},removeAllBySuffix:function(e,t){var i=n.get(e);if(void 0!==i){t="_"+t;var a=-1*t.length;i.forEach(function(i,n){n.substr(a)===t&&this.removeAll(e,n)}.bind(this))}}}}),define("WoltLabSuite/Core/List",[],function(){"use strict";function e(){this._set=t?new Set:[]}var t=objOwns(window,"Set")&&"function"==typeof window.Set;return e.prototype={add:function(e){t?this._set.add(e):this.has(e)||this._set.push(e)},clear:function(){t?this._set.clear():this._set=[]},delete:function(e){if(t)return this._set.delete(e);var i=this._set.indexOf(e);return-1!==i&&(this._set.splice(i,1),!0)},forEach:function(e){if(t)this._set.forEach(e);else for(var i=0,n=this._set.length;i<n;i++)e(this._set[i])},has:function(e){return t?this._set.has(e):-1!==this._set.indexOf(e)}},Object.defineProperty(e.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return t?this._set.size:this._set.length}}),e}),define("WoltLabSuite/Core/Ui/Dialog",["Ajax","Core","Dictionary","Environment","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/Screen","Ui/SimpleDropdown","EventHandler","List","EventKey"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p,f){"use strict";var m=null,g=null,v=null,_=new i,b=!1,w=new r,y=new i,C=null,E=null,L=elByClass("jsStaticDialog"),S=["onBeforeClose","onClose","onShow"],A=["number","password","search","tel","text","url"],I=['a[href]:not([tabindex^="-"]):not([inert])','area[href]:not([tabindex^="-"]):not([inert])',"input:not([disabled]):not([inert])","select:not([disabled]):not([inert])","textarea:not([disabled]):not([inert])","button:not([disabled]):not([inert])",'iframe:not([tabindex^="-"]):not([inert])','audio:not([tabindex^="-"]):not([inert])','video:not([tabindex^="-"]):not([inert])','[contenteditable]:not([tabindex^="-"]):not([inert])','[tabindex]:not([tabindex^="-"]):not([inert])'];return{setup:function(){void 0===e&&(e=require("Ajax")),v=elCreate("div"),v.classList.add("dialogOverlay"),elAttr(v,"aria-hidden","true"),v.addEventListener("mousedown",this._closeOnBackdrop.bind(this)),v.addEventListener("wheel",function(e){e.target===v&&e.preventDefault()},{passive:!1}),elById("content").appendChild(v),E=function(e){return 27!==e.keyCode||"INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName||(this.close(m),!1)}.bind(this),d.on("screen-xs",{match:function(){b=!0},unmatch:function(){b=!1},setup:function(){b=!0}}),this._initStaticDialogs(),o.add("Ui/Dialog",this._initStaticDialogs.bind(this)),d.setDialogContainer(v),window.addEventListener("resize",function(){_.forEach(function(e){elAttrBool(e.dialog,"aria-hidden")||this.rebuild(elData(e.dialog,"id"))}.bind(this))}.bind(this))},_initStaticDialogs:function(){for(var e,t,i;L.length;)e=L[0],e.classList.remove("jsStaticDialog"),(i=elData(e,"dialog-id"))&&(t=elById(i))&&function(e,t){t.classList.remove("jsStaticDialogContent"),elData(t,"is-static-dialog",!0),elHide(t),e.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.openStatic(t.id,null,{title:elData(t,"title")})}.bind(this))}.bind(this)(e,t)},open:function(i,n){var a=w.get(i);if(t.isPlainObject(a))return this.openStatic(a.id,n);if("function"!=typeof i._dialogSetup)throw new Error("Callback object does not implement the method '_dialogSetup()'.");var r=i._dialogSetup();if(!t.isPlainObject(r))throw new Error("Expected an object literal as return value of '_dialogSetup()'.");a={id:r.id};var o=!0;if(void 0===r.source){var s=elById(r.id);if(null===s)throw new Error("Element id '"+r.id+"' is invalid and no source attribute was given. If you want to use the `html` argument instead, please add `source: null` to your dialog configuration.");r.source=document.createDocumentFragment(),r.source.appendChild(s),s.removeAttribute("id"),elShow(s)}else if(null===r.source)r.source=n;else if("function"==typeof r.source)r.source();else if(t.isPlainObject(r.source)){if("string"!=typeof n||""===n.trim())return e.api(this,r.source.data,function(e){e.returnValues&&"string"==typeof e.returnValues.template&&(this.open(i,e.returnValues.template),"function"==typeof r.source.after&&r.source.after(_.get(r.id).content,e))}.bind(this)),{};r.source=n}else{if("string"==typeof r.source){var s=elCreate("div");elAttr(s,"id",r.id),l.setInnerHtml(s,r.source),r.source=document.createDocumentFragment(),r.source.appendChild(s)}if(!r.source.nodeType||r.source.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)throw new Error("Expected at least a document fragment as 'source' attribute.");o=!1}return w.set(i,a),y.set(r.id,i),this.openStatic(r.id,r.source,r.options,o)},openStatic:function(e,i,r,o){d.pageOverlayOpen(),"desktop"!==n.platform()&&(this.isOpen(e)||d.scrollDisable()),_.has(e)?this._updateDialog(e,i):(r=t.extend({backdropCloseOnClick:!0,closable:!0,closeButtonLabel:a.get("wcf.global.button.close"),closeConfirmMessage:"",disableContentPadding:!1,title:"",onBeforeClose:null,onClose:null,onShow:null},r),r.closable||(r.backdropCloseOnClick=!1),r.closeConfirmMessage&&(r.onBeforeClose=function(e){c.show({confirm:this.close.bind(this,e),message:r.closeConfirmMessage})}.bind(this)),this._createDialog(e,i,r));var s=_.get(e);return"ios"===n.platform()&&window.setTimeout(function(){var e=elBySel("input, textarea",s.content);null!==e&&e.focus()}.bind(this),200),s},setTitle:function(e,t){e=this._getDialogId(e);var i=_.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");var n=elByClass("dialogTitle",i.dialog);n.length&&(n[0].textContent=t)},setCallback:function(e,t,i){if("object"==typeof e){var n=w.get(e);void 0!==n&&(e=n.id)}var a=_.get(e);if(void 0===a)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if(-1===S.indexOf(t))throw new Error("Invalid callback identifier, '"+t+"' is not recognized.");if("function"!=typeof i&&null!==i)throw new Error("Only functions or the 'null' value are acceptable callback values ('"+typeof i+"' given).");a[t]=i},_createDialog:function(e,t,i,n){var a=null;if(null===t&&null===(a=elById(e)))throw new Error("Expected either a HTML string or an existing element id.");var r=elCreate("div");r.classList.add("dialogContainer"),elAttr(r,"aria-hidden","true"),elAttr(r,"role","dialog"),elData(r,"id",e);var o=elCreate("header");r.appendChild(o);var s=l.getUniqueId();elAttr(r,"aria-labelledby",s);var c=elCreate("span");if(c.classList.add("dialogTitle"),c.textContent=i.title,elAttr(c,"id",s),o.appendChild(c),i.closable){var d=elCreate("a");d.className="dialogCloseButton jsTooltip",d.href="#",elAttr(d,"role","button"),elAttr(d,"tabindex","0"),elAttr(d,"title",i.closeButtonLabel),elAttr(d,"aria-label",i.closeButtonLabel),d.addEventListener(WCF_CLICK_EVENT,this._close.bind(this)),o.appendChild(d);var u=elCreate("span");u.className="icon icon24 fa-times",d.appendChild(u)}var h=elCreate("div");h.classList.add("dialogContent"),i.disableContentPadding&&h.classList.add("dialogContentNoPadding"),r.appendChild(h),h.addEventListener("wheel",function(e){for(var t,i,n,a=!1,r=e.target;;){if(t=r.clientHeight,i=r.scrollHeight,t<i){if(n=r.scrollTop,e.deltaY<0&&n>0){a=!0;break}if(e.deltaY>0&&n+t<i){a=!0;break}}if(!r||r===h)break;r=r.parentNode}!1===a&&e.preventDefault()},{passive:!1});var f;if(null===a)if("string"==typeof t)f=elCreate("div"),f.id=e,l.setInnerHtml(f,t);else{if(!(t instanceof DocumentFragment))throw new TypeError("'html' must either be a string or a DocumentFragment");for(var m,g=[],b=0,w=t.childNodes.length;b<w;b++)m=t.childNodes[b],m.nodeType===Node.ELEMENT_NODE&&g.push(m);"DIV"!==g[0].nodeName||g.length>1?(f=elCreate("div"),f.id=e,f.appendChild(t)):f=g[0]}else f=a;h.appendChild(f),"none"===f.style.getPropertyValue("display")&&elShow(f),_.set(e,{backdropCloseOnClick:i.backdropCloseOnClick,closable:i.closable,content:f,dialog:r,header:o,onBeforeClose:i.onBeforeClose,onClose:i.onClose,onShow:i.onShow,submitButton:null,inputFields:new p}),l.prepend(r,v),"function"==typeof i.onSetup&&i.onSetup(f),!0!==n&&this._updateDialog(e,null)},_updateDialog:function(e,t){var i=_.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("string"==typeof t&&l.setInnerHtml(i.content,t),"true"===elAttr(i.dialog,"aria-hidden")){null===g&&(g=this._maintainFocus.bind(this),document.body.addEventListener("focus",g,{capture:!0})),i.closable&&"true"===elAttr(v,"aria-hidden")&&window.addEventListener("keyup",E),i.dialog.parentNode.insertBefore(i.dialog,i.dialog.parentNode.firstChild),elAttr(i.dialog,"aria-hidden","false"),elAttr(v,"aria-hidden","false"),elData(v,"close-on-click",i.backdropCloseOnClick?"true":"false"),m=e,C=document.activeElement;var n=elBySel(".dialogCloseButton",i.header);n&&elAttr(n,"inert",!0),this._setFocusToFirstItem(i.dialog),n&&n.removeAttribute("inert"),"function"==typeof i.onShow&&i.onShow(i.content),elDataBool(i.content,"is-static-dialog")&&h.fire("com.woltlab.wcf.dialog","openStatic",{content:i.content,id:e}),u.closeAll(),window.WCF.Dropdown.Interactive.Handler.closeAll()}this.rebuild(e),o.trigger()},_maintainFocus:function(e){if(m){var t=_.get(m);t.dialog.contains(e.target)||e.target.closest(".dropdownMenuContainer")||e.target.closest(".datePicker")||this._setFocusToFirstItem(t.dialog,!0)}},_setFocusToFirstItem:function(e,t){var i=this._getFirstFocusableChild(e);null!==i&&(t&&("username"!==i.id&&"username"!==i.name||"safari"===n.browser()&&"ios"===n.platform()&&(i=null)),i&&setTimeout(function(){i.focus()},1))},_getFirstFocusableChild:function(e){for(var t=elBySelAll(I.join(","),e),i=0,n=t.length;i<n;i++)if(t[i].offsetWidth&&t[i].offsetHeight&&t[i].getClientRects().length)return t[i];return null},rebuild:function(e){e=this._getDialogId(e);var t=_.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("true"!==elAttr(t.dialog,"aria-hidden")){var i=t.content.parentNode,a=elBySel(".formSubmit",t.content),r=0;null!==a?(i.classList.add("dialogForm"),a.classList.add("dialogFormSubmit"),r+=l.outerHeight(a),r-=1,i.style.setProperty("margin-bottom",r+"px","")):(i.classList.remove("dialogForm"),i.style.removeProperty("margin-bottom")),r+=l.outerHeight(t.header);var o=window.innerHeight*(b?1:.8)-r;i.style.setProperty("max-height",~~o+"px",""),"chrome"===n.browser()&&(t.content.scrollHeight>o?t.content.style.setProperty("margin-right","-1px",""):t.content.style.removeProperty("margin-right")),"chrome"!==n.browser()&&"safari"!==n.browser()||t.content.parentNode.classList.add("jsWebKitFractionalPixelFix");var s=y.get(e);if(void 0!==s&&"function"==typeof s._dialogSubmit){var c=elBySelAll('input[data-dialog-submit-on-enter="true"]',t.content),d=elBySel('.formSubmit > input[type="submit"], .formSubmit > button[data-type="submit"]',t.content);if(null===d)return void(0===c.length&&console.warn("Broken dialog, expected a submit button.",t.content));if(t.submitButton!==d){t.submitButton=d,d.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),this._submit(e)}.bind(this));for(var u,h=null,p=0,m=c.length;p<m;p++)u=c[p],t.inputFields.has(u)||(-1!==A.indexOf(u.type)?(t.inputFields.add(u),null===h&&(h=function(t){f.Enter(t)&&(t.preventDefault(),this._submit(e))}.bind(this)),u.addEventListener("keydown",h)):console.warn("Unsupported input type.",u))}}}},_submit:function(e){var t=_.get(e),i=!0;t.inputFields.forEach(function(e){e.required&&(""===e.value.trim()?(elInnerError(e,a.get("wcf.global.form.error.empty")),i=!1):elInnerError(e,!1))}),i&&y.get(e)._dialogSubmit()},_close:function(e){e.preventDefault();var t=_.get(m);if("function"==typeof t.onBeforeClose)return t.onBeforeClose(m),!1;this.close(m)},_closeOnBackdrop:function(e){if(e.target!==v)return!0;"true"===elData(v,"close-on-click")?this._close(e):e.preventDefault()},close:function(e){e=this._getDialogId(e);var t=_.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");elAttr(t.dialog,"aria-hidden","true"),document.activeElement.closest(".dialogContainer")===t.dialog&&document.activeElement.blur(),"function"==typeof t.onClose&&t.onClose(e),m=null;for(var i=0;i<v.childElementCount;i++){var a=v.children[i];if("false"===elAttr(a,"aria-hidden")){m=elData(a,"id");break}}d.pageOverlayClose(),null===m?(elAttr(v,"aria-hidden","true"),elData(v,"close-on-click","false"),t.closable&&window.removeEventListener("keyup",E)):(t=_.get(m),elData(v,"close-on-click",t.backdropCloseOnClick?"true":"false")),"desktop"!==n.platform()&&d.scrollEnable()},getDialog:function(e){return _.get(this._getDialogId(e))},isOpen:function(e){var t=this.getDialog(e);return void 0!==t&&"false"===elAttr(t.dialog,"aria-hidden")},destroy:function(e){if("object"!=typeof e||e instanceof String)throw new TypeError("Expected the callback object as parameter.");if(w.has(e)){var t=w.get(e).id;this.isOpen(t)&&this.close(t),_.has(t)&&(elRemove(_.get(t).dialog),_.delete(t)),w.delete(e)}},_getDialogId:function(e){if("object"==typeof e){var t=w.get(e);if(void 0!==t)return t.id}return e.toString()},_ajaxSetup:function(){return{}}}}),define("WoltLabSuite/Core/Ajax/Status",["Language"],function(e){"use strict";var t=0,i=null,n=null;return{_init:function(){i=elCreate("div"),i.classList.add("spinner"),elAttr(i,"role","status");var t=elCreate("span");t.className="icon icon48 fa-spinner",i.appendChild(t);var n=elCreate("span");n.textContent=e.get("wcf.global.loading"),i.appendChild(n),document.body.appendChild(i)},show:function(){null===i&&this._init(),t++,null===n&&(n=window.setTimeout(function(){t&&i.classList.add("active"),n=null},250))},hide:function(){0===--t&&(null!==n&&window.clearTimeout(n),i.classList.remove("active"))}}}),define("WoltLabSuite/Core/Ajax/Request",["Core","Language","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,a,r){"use strict";function o(e){this._data=null,this._options={},this._previousXhr=null,this._xhr=null,this._init(e)}var s=!1,l=!1;return o.prototype={_init:function(t){this._options=e.extend({data:{},contentType:"application/x-www-form-urlencoded; charset=UTF-8",responseType:"application/json",type:"POST",url:"",withCredentials:!1,autoAbort:!1,ignoreError:!1,pinData:!1,silent:!1,includeRequestedWith:!0,failure:null,finalize:null,success:null,progress:null,uploadProgress:null,callbackObject:null},t),"object"==typeof t.callbackObject&&(this._options.callbackObject=t.callbackObject),this._options.url=e.convertLegacyUrl(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),0===this._options.url.indexOf(WSC_API_URL)&&(this._options.includeRequestedWith=!0,this._options.withCredentials=!0),this._options.pinData&&(this._data=e.extend({},this._options.data)),null!==this._options.callbackObject&&("function"==typeof this._options.callbackObject._ajaxFailure&&(this._options.failure=this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxFinalize&&(this._options.finalize=this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxSuccess&&(this._options.success=this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxProgress&&(this._options.progress=this._options.callbackObject._ajaxProgress.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxUploadProgress&&(this._options.uploadProgress=this._options.callbackObject._ajaxUploadProgress.bind(this._options.callbackObject))),!1===s&&(s=!0,window.addEventListener("beforeunload",function(){l=!0}))},sendRequest:function(t){(!0===t||this._options.autoAbort)&&this.abortPrevious(),this._options.silent||r.show(),this._xhr instanceof XMLHttpRequest&&(this._previousXhr=this._xhr),this._xhr=new XMLHttpRequest,this._xhr.open(this._options.type,this._options.url,!0),this._options.contentType&&this._xhr.setRequestHeader("Content-Type",this._options.contentType),(this._options.withCredentials||this._options.includeRequestedWith)&&this._xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),this._options.withCredentials&&(this._xhr.withCredentials=!0);var i=this,n=e.clone(this._options);if(this._xhr.onload=function(){this.readyState===XMLHttpRequest.DONE&&(this.status>=200&&this.status<300||304===this.status?n.responseType&&0!==this.getResponseHeader("Content-Type").indexOf(n.responseType)?i._failure(this,n):i._success(this,n):i._failure(this,n))},this._xhr.onerror=function(){i._failure(this,n)},this._options.progress&&(this._xhr.onprogress=this._options.progress),this._options.uploadProgress&&(this._xhr.upload.onprogress=this._options.uploadProgress),"POST"===this._options.type){var a=this._options.data;"object"==typeof a&&"FormData"!==e.getType(a)&&(a=e.serialize(a)),this._xhr.send(a)}else this._xhr.send()},abortPrevious:function(){null!==this._previousXhr&&(this._previousXhr.abort(),this._previousXhr=null,this._options.silent||r.hide())},setOption:function(e,t){this._options[e]=t},getOption:function(e){return objOwns(this._options,e)?this._options[e]:null},setData:function(t){null!==this._data&&"FormData"!==e.getType(t)&&(t=e.extend(this._data,t)),this._options.data=t},_success:function(e,t){if(t.silent||r.hide(),"function"==typeof t.success){var i=null;if("application/json"===e.getResponseHeader("Content-Type").split(";",1)[0].trim()){try{i=JSON.parse(e.responseText)}catch(i){return void this._failure(e,t)}i&&i.returnValues&&void 0!==i.returnValues.template&&(i.returnValues.template=i.returnValues.template.trim()),i&&i.forceBackgroundQueuePerform&&require(["WoltLabSuite/Core/BackgroundQueue"],function(e){e.invoke()})}t.success(i,e.responseText,e,t.data)}this._finalize(t)},_failure:function(e,i){if(!l){i.silent||r.hide();var o=null;try{o=JSON.parse(e.responseText)}catch(e){}var s=!0;if("function"==typeof i.failure&&(s=i.failure(o||{},e.responseText||"",e,i.data)),!0!==i.ignoreError&&!1!==s){var c=this.getErrorHtml(o,e);c&&(void 0===a&&(a=require("Ui/Dialog")),a.openStatic(n.getUniqueId(),c,{title:t.get("wcf.global.error.title")}))}this._finalize(i)}},getErrorHtml:function(e,t){var i="",n="";if(null!==e?(e.file&&e.line&&(i+="<br><p>File:</p><p>"+e.file+" in line "+e.line+"</p>"),e.stacktrace?i+="<br><p>Stacktrace:</p><p>"+e.stacktrace+"</p>":e.exceptionID&&(i+="<br><p>Exception ID: <code>"+e.exceptionID+"</code></p>"),n=e.message,e.previous.forEach(function(e){i+="<hr><p>"+e.message+"</p>",i+="<br><p>Stacktrace</p><p>"+e.stacktrace+"</p>"})):n=t.responseText,!n||"undefined"===n){if(!ENABLE_DEBUG_MODE)return null;n="XMLHttpRequest failed without a responseText. Check your browser console."}return'<div class="ajaxDebugMessage"><p>'+n+"</p>"+i+"</div>"},_finalize:function(e){"function"==typeof e.finalize&&e.finalize(this._xhr),this._previousXhr=null,i.trigger();for(var t=elBySelAll('a[href*="#"]'),n=0,a=t.length;n<a;n++){var r=t[n],o=elAttr(r,"href");-1===o.indexOf("AJAXProxy")&&-1===o.indexOf("ajax-proxy")||(o=o.substr(o.indexOf("#")),elAttr(r,"href",document.location.toString().replace(/#.*/,"")+o))}}},o}),define("WoltLabSuite/Core/Ajax",["AjaxRequest","Core","ObjectMap"],function(e,t,i){"use strict";var n=new i;return{api:function(t,i,a,r){void 0===e&&(e=require("AjaxRequest")),"object"!=typeof i&&(i={});var o=n.get(t);if(void 0===o){if("function"!=typeof t._ajaxSetup)throw new TypeError("Callback object must implement at least _ajaxSetup().");var s=t._ajaxSetup();s.pinData=!0,s.callbackObject=t,s.url||(s.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,s.withCredentials=!0),o=new e(s),n.set(t,o)}var l=null,c=null;return"function"==typeof a&&(l=o.getOption("success"),o.setOption("success",a)),"function"==typeof r&&(c=o.getOption("failure"),o.setOption("failure",r)),o.setData(i),o.sendRequest(),null!==l&&o.setOption("success",l),null!==c&&o.setOption("failure",c),o},apiOnce:function(t){void 0===e&&(e=require("AjaxRequest")),t.pinData=!1,t.callbackObject=null,t.url||(t.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,t.withCredentials=!0),new e(t).sendRequest(!1)},getRequestObject:function(e){if(!n.has(e))throw new Error("Expected a previously used callback object, provided object is unknown.");return n.get(e)}}}),define("WoltLabSuite/Core/BackgroundQueue",["Ajax"],function(e){"use strict";var t=0,i=!1,n="";return{setUrl:function(e){n=e},invoke:function(){if(""===n)return void console.error("The background queue has not been initialized yet.");i||(i=!0,e.api(this))},_ajaxSuccess:function(e){t++,e>0&&t<5?window.setTimeout(function(){i=!1,this.invoke()}.bind(this),1e3):(i=!1,t=0)},_ajaxSetup:function(){return{url:n,ignoreError:!0,silent:!0}}}}),function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||g)return!1;try{d.clearRect(0,0,l,s),d.drawImage(e,0,0,l,s)}catch(e){}b=setTimeout(function(){t(e)},N.duration),k.setIcon(c)}function i(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,i,n){return t+t+i+i+n+n});var i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return!!i&&{r:parseInt(i[1],16),g:parseInt(i[2],16),b:parseInt(i[3],16)}}function n(e,t){var i,n={};for(i in e)n[i]=e[i];for(i in t)n[i]=t[i];return n}function a(){return w.hidden||w.msHidden||w.webkitHidden||w.mozHidden}e=e||{};var r,o,s,l,c,d,u,h,p,f,m,g,v,_,b,w,y={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1,element:null,dataUrl:!1,win:window};v={},v.ff="undefined"!=typeof InstallTrigger,v.chrome=!!window.chrome,v.opera=!!window.opera||navigator.userAgent.indexOf("Opera")>=0,v.ie=!1,v.safari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,v.supported=v.chrome||v.ff||v.opera;var C=[];m=function(){},h=g=!1;var E={};E.ready=function(){h=!0,E.reset(),m()},E.reset=function(){h&&(C=[],p=!1,f=!1,d.clearRect(0,0,l,s),d.drawImage(u,0,0,l,s),k.setIcon(c),window.clearTimeout(_),window.clearTimeout(b))},E.start=function(){if(h&&!f){var e=function(){p=C[0],f=!1,C.length>0&&(C.shift(),E.start())};if(C.length>0){f=!0;var t=function(){["type","animation","bgColor","textColor","fontFamily","fontStyle"].forEach(function(e){e in C[0].options&&(r[e]=C[0].options[e])}),N.run(C[0].options,function(){e()},!1)};p?N.run(p.options,function(){t()},!0):t()}}};var L={},S=function(e){return e.n="number"==typeof e.n?Math.abs(0|e.n):e.n,e.x=l*e.x,e.y=s*e.y,e.w=l*e.w,e.h=s*e.h,e.len=(""+e.n).length,e};L.circle=function(e){e=S(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),d.clearRect(0,0,l,s),d.drawImage(u,0,0,l,s),d.beginPath(),d.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+r.fontFamily,d.textAlign="center",t?(d.moveTo(e.x+e.w/2,e.y),d.lineTo(e.x+e.w-e.h/2,e.y),d.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),d.lineTo(e.x+e.w,e.y+e.h-e.h/2),d.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),d.lineTo(e.x+e.h/2,e.y+e.h),d.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),d.lineTo(e.x,e.y+e.h/2),d.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):d.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),d.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",d.fill(),d.closePath(),d.beginPath(),d.stroke(),d.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?d.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):d.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),d.closePath()},L.rectangle=function(e){e=S(e);2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w),d.clearRect(0,0,l,s),d.drawImage(u,0,0,l,s),d.beginPath(),d.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.9:1))+"px "+r.fontFamily,d.textAlign="center",d.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",d.fillRect(e.x,e.y,e.w,e.h),d.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?d.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):d.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),d.closePath()};var A=function(e,t){t=("string"==typeof t?{animation:t}:t)||{},m=function(){try{if("number"==typeof e?e>0:""!==e){var n={type:"badge",options:{n:e}};if("animation"in t&&N.types[""+t.animation]&&(n.options.animation=""+t.animation),"type"in t&&L[""+t.type]&&(n.options.type=""+t.type),["bgColor","textColor"].forEach(function(e){e in t&&(n.options[e]=i(t[e]))}),["fontStyle","fontFamily"].forEach(function(e){e in t&&(n.options[e]=t[e])}),C.push(n),C.length>100)throw new Error("Too many badges requests in queue.");E.start()}else E.reset()}catch(e){throw new Error("Error setting badge. Message: "+e.message)}},h&&m()},I=function(e){m=function(){try{var t=e.width,i=e.height,n=document.createElement("img"),a=t/l<i/s?t/l:i/s;n.setAttribute("crossOrigin","anonymous"),n.onload=function(){d.clearRect(0,0,l,s),d.drawImage(n,0,0,l,s),k.setIcon(c)},n.setAttribute("src",e.getAttribute("src")),n.height=i/a,n.width=t/a}catch(e){throw new Error("Error setting image. Message: "+e.message)}},h&&m()},D=function(e){m=function(){k.setIconSrc(e)},h&&m()},x=function(e){m=function(){try{if("stop"===e)return g=!0,E.reset(),void(g=!1);e.addEventListener("play",function(){t(this)},!1)}catch(e){throw new Error("Error setting video. Message: "+e.message)}},h&&m()},T=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),v.supported){var i=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,m=function(){try{if("stop"===e)return g=!0,E.reset(),void(g=!1);i=document.createElement("video"),i.width=l,i.height=s,navigator.getUserMedia({video:!0,audio:!1},function(e){i.src=URL.createObjectURL(e),i.play(),t(i)},function(){})}catch(e){throw new Error("Error setting webcam. Message: "+e.message)}},h&&m()}},B=function(e,t){var n=e;null==t&&"[object Object]"==Object.prototype.toString.call(e)||(n={},n[e]=t);for(var a=Object.keys(n),o=0;o<a.length;o++)"bgColor"==a[o]||"textColor"==a[o]?r[a[o]]=i(n[a[o]]):r[a[o]]=n[a[o]];C.push(p),E.start()},k={};k.getIcons=function(){var e=[];return r.element?e=[r.element]:r.elementId?(e=[w.getElementById(r.elementId)],e[0].setAttribute("href",e[0].getAttribute("src"))):(e=function(){for(var e=[],t=w.getElementsByTagName("head")[0].getElementsByTagName("link"),i=0;i<t.length;i++)/(^|\s)icon(\s|$)/i.test(t[i].getAttribute("rel"))&&e.push(t[i]);return e}(),0===e.length&&(e=[w.createElement("link")],e[0].setAttribute("rel","icon"),w.getElementsByTagName("head")[0].appendChild(e[0]))),e.forEach(function(e){e.setAttribute("type","image/png")}),e},k.setIcon=function(e){var t=e.toDataURL("image/png");k.setIconSrc(t)},k.setIconSrc=function(e){if(r.dataUrl&&r.dataUrl(e),r.element)r.element.setAttribute("href",e),r.element.setAttribute("src",e);else if(r.elementId){var t=w.getElementById(r.elementId);t.setAttribute("href",e),t.setAttribute("src",e)}else if(v.ff||v.opera){var i=o[o.length-1],n=w.createElement("link");o=[n],v.opera&&n.setAttribute("rel","icon"),n.setAttribute("rel","icon"),n.setAttribute("type","image/png"),w.getElementsByTagName("head")[0].appendChild(n),n.setAttribute("href",e),i.parentNode&&i.parentNode.removeChild(i)}else o.forEach(function(t){t.setAttribute("href",e)})};var N={};return N.duration=40,N.types={},N.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],N.run=function(e,t,i,o){var s=N.types[a()?"none":r.animation];if(o=!0===i?void 0!==o?o:s.length-1:void 0!==o?o:0,t=t||function(){},!(o<s.length&&o>=0))return void t();L[r.type](n(e,s[o])),_=setTimeout(function(){i?o-=1:o+=1,N.run(e,t,i,o)},N.duration),k.setIcon(c)},function(){r=n(y,e),r.bgColor=i(r.bgColor),r.textColor=i(r.textColor),r.position=r.position.toLowerCase(),r.animation=N.types[""+r.animation]?r.animation:y.animation,w=r.win.document;var t=r.position.indexOf("up")>-1,a=r.position.indexOf("left")>-1;if(t||a)for(var h in N.types)for(var p=0;p<N.types[h].length;p++){var f=N.types[h][p];t&&(f.y<.6?f.y=f.y-.4:f.y=f.y-2*f.y+(1-f.w)),a&&(f.x<.6?f.x=f.x-.4:f.x=f.x-2*f.x+(1-f.h)),N.types[h][p]=f}r.type=L[""+r.type]?r.type:y.type,o=k.getIcons(),c=document.createElement("canvas"),u=document.createElement("img");var m=o[o.length-1];m.hasAttribute("href")?(u.setAttribute("crossOrigin","anonymous"),u.onload=function(){s=u.height>0?u.height:32,l=u.width>0?u.width:32,c.height=s,c.width=l,d=c.getContext("2d"),E.ready()},u.setAttribute("src",m.getAttribute("href"))):(s=32,l=32,u.height=s,u.width=l,c.height=s,c.width=l,d=c.getContext("2d"),E.ready())}(),{badge:A,video:x,image:I,rawImageSrc:D,webcam:T,setOpt:B,reset:E.reset,browser:{supported:v.supported}}};void 0!==define&&define.amd?define("favico",[],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(),function(e,t,i){var n=window.matchMedia;"undefined"!=typeof module&&module.exports?module.exports=i(n):"function"==typeof define&&define.amd?define("enquire",[],function(){return t.enquire=i(n)}):t.enquire=i(n)}(0,this,function(e){"use strict";function t(e,t){var i=0,n=e.length;for(i;i<n&&!1!==t(e[i],i);i++);}function i(e){return"[object Array]"===Object.prototype.toString.apply(e)}function n(e){return"function"==typeof e}function a(e){this.options=e,!e.deferSetup&&this.setup()}function r(t,i){this.query=t,this.isUnconditional=i,this.handlers=[],this.mql=e(t);var n=this;this.listener=function(e){n.mql=e,n.assess()},this.mql.addListener(this.listener)}function o(){if(!e)throw new Error("matchMedia not present, legacy browsers require a polyfill");this.queries={},this.browserIsIncapable=!e("only all").matches}return a.prototype={setup:function(){this.options.setup&&this.options.setup(),this.initialised=!0},on:function(){!this.initialised&&this.setup(),this.options.match&&this.options.match()},off:function(){this.options.unmatch&&this.options.unmatch()},destroy:function(){this.options.destroy?this.options.destroy():this.off()},equals:function(e){return this.options===e||this.options.match===e}},r.prototype={addHandler:function(e){var t=new a(e);this.handlers.push(t),this.matches()&&t.on()},removeHandler:function(e){var i=this.handlers;t(i,function(t,n){if(t.equals(e))return t.destroy(),!i.splice(n,1)})},
-matches:function(){return this.mql.matches||this.isUnconditional},clear:function(){t(this.handlers,function(e){e.destroy()}),this.mql.removeListener(this.listener),this.handlers.length=0},assess:function(){var e=this.matches()?"on":"off";t(this.handlers,function(t){t[e]()})}},o.prototype={register:function(e,a,o){var s=this.queries,l=o&&this.browserIsIncapable;return s[e]||(s[e]=new r(e,l)),n(a)&&(a={match:a}),i(a)||(a=[a]),t(a,function(t){n(t)&&(t={match:t}),s[e].addHandler(t)}),this},unregister:function(e,t){var i=this.queries[e];return i&&(t?i.removeHandler(t):(i.clear(),delete this.queries[e])),this}},new o}),function e(t,i,n){function a(o,s){if(!i[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var d=i[o]={exports:{}};t[o][0].call(d.exports,function(e){var i=t[o][1][e];return a(i||e)},d,d.exports,e,t,i,n)}return i[o].exports}for(var r="function"==typeof require&&require,o=0;o<n.length;o++)a(n[o]);return a}({1:[function(e,t,i){"use strict";var n=e("../main");"function"==typeof define&&define.amd?define("perfect-scrollbar",n):(window.PerfectScrollbar=n,void 0===window.Ps&&(window.Ps=n))},{"../main":7}],2:[function(e,t,i){"use strict";function n(e,t){var i=e.className.split(" ");i.indexOf(t)<0&&i.push(t),e.className=i.join(" ")}function a(e,t){var i=e.className.split(" "),n=i.indexOf(t);n>=0&&i.splice(n,1),e.className=i.join(" ")}i.add=function(e,t){e.classList?e.classList.add(t):n(e,t)},i.remove=function(e,t){e.classList?e.classList.remove(t):a(e,t)},i.list=function(e){return e.classList?Array.prototype.slice.apply(e.classList):e.className.split(" ")}},{}],3:[function(e,t,i){"use strict";function n(e,t){return window.getComputedStyle(e)[t]}function a(e,t,i){return"number"==typeof i&&(i=i.toString()+"px"),e.style[t]=i,e}function r(e,t){for(var i in t){var n=t[i];"number"==typeof n&&(n=n.toString()+"px"),e.style[i]=n}return e}var o={};o.e=function(e,t){var i=document.createElement(e);return i.className=t,i},o.appendTo=function(e,t){return t.appendChild(e),e},o.css=function(e,t,i){return"object"==typeof t?r(e,t):void 0===i?n(e,t):a(e,t,i)},o.matches=function(e,t){return void 0!==e.matches?e.matches(t):void 0!==e.matchesSelector?e.matchesSelector(t):void 0!==e.webkitMatchesSelector?e.webkitMatchesSelector(t):void 0!==e.mozMatchesSelector?e.mozMatchesSelector(t):void 0!==e.msMatchesSelector?e.msMatchesSelector(t):void 0},o.remove=function(e){void 0!==e.remove?e.remove():e.parentNode&&e.parentNode.removeChild(e)},o.queryChildren=function(e,t){return Array.prototype.filter.call(e.childNodes,function(e){return o.matches(e,t)})},t.exports=o},{}],4:[function(e,t,i){"use strict";var n=function(e){this.element=e,this.events={}};n.prototype.bind=function(e,t){void 0===this.events[e]&&(this.events[e]=[]),this.events[e].push(t),this.element.addEventListener(e,t,!1)},n.prototype.unbind=function(e,t){var i=void 0!==t;this.events[e]=this.events[e].filter(function(n){return!(!i||n===t)||(this.element.removeEventListener(e,n,!1),!1)},this)},n.prototype.unbindAll=function(){for(var e in this.events)this.unbind(e)};var a=function(){this.eventElements=[]};a.prototype.eventElement=function(e){var t=this.eventElements.filter(function(t){return t.element===e})[0];return void 0===t&&(t=new n(e),this.eventElements.push(t)),t},a.prototype.bind=function(e,t,i){this.eventElement(e).bind(t,i)},a.prototype.unbind=function(e,t,i){this.eventElement(e).unbind(t,i)},a.prototype.unbindAll=function(){for(var e=0;e<this.eventElements.length;e++)this.eventElements[e].unbindAll()},a.prototype.once=function(e,t,i){var n=this.eventElement(e),a=function(e){n.unbind(t,a),i(e)};n.bind(t,a)},t.exports=a},{}],5:[function(e,t,i){"use strict";t.exports=function(){function e(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return e()+e()+"-"+e()+"-"+e()+"-"+e()+"-"+e()+e()+e()}}()},{}],6:[function(e,t,i){"use strict";var n=e("./class"),a=e("./dom"),r=i.toInt=function(e){return parseInt(e,10)||0},o=i.clone=function(e){if(e){if(e.constructor===Array)return e.map(o);if("object"==typeof e){var t={};for(var i in e)t[i]=o(e[i]);return t}return e}return null};i.extend=function(e,t){var i=o(e);for(var n in t)i[n]=o(t[n]);return i},i.isEditable=function(e){return a.matches(e,"input,[contenteditable]")||a.matches(e,"select,[contenteditable]")||a.matches(e,"textarea,[contenteditable]")||a.matches(e,"button,[contenteditable]")},i.removePsClasses=function(e){for(var t=n.list(e),i=0;i<t.length;i++){var a=t[i];0===a.indexOf("ps-")&&n.remove(e,a)}},i.outerWidth=function(e){return r(a.css(e,"width"))+r(a.css(e,"paddingLeft"))+r(a.css(e,"paddingRight"))+r(a.css(e,"borderLeftWidth"))+r(a.css(e,"borderRightWidth"))},i.startScrolling=function(e,t){n.add(e,"ps-in-scrolling"),void 0!==t?n.add(e,"ps-"+t):(n.add(e,"ps-x"),n.add(e,"ps-y"))},i.stopScrolling=function(e,t){n.remove(e,"ps-in-scrolling"),void 0!==t?n.remove(e,"ps-"+t):(n.remove(e,"ps-x"),n.remove(e,"ps-y"))},i.env={isWebKit:"WebkitAppearance"in document.documentElement.style,supportsTouch:"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,supportsIePointer:null!==window.navigator.msMaxTouchPoints}},{"./class":2,"./dom":3}],7:[function(e,t,i){"use strict";var n=e("./plugin/destroy"),a=e("./plugin/initialize"),r=e("./plugin/update");t.exports={initialize:a,update:r,destroy:n}},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(e,t,i){"use strict";t.exports={handlers:["click-rail","drag-scrollbar","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1,theme:"default"}},{}],9:[function(e,t,i){"use strict";var n=e("../lib/helper"),a=e("../lib/dom"),r=e("./instances");t.exports=function(e){var t=r.get(e);t&&(t.event.unbindAll(),a.remove(t.scrollbarX),a.remove(t.scrollbarY),a.remove(t.scrollbarXRail),a.remove(t.scrollbarYRail),n.removePsClasses(e),r.remove(e))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(e,t,i){"use strict";function n(e,t){function i(e){return e.getBoundingClientRect()}var n=function(e){e.stopPropagation()};t.event.bind(t.scrollbarY,"click",n),t.event.bind(t.scrollbarYRail,"click",function(n){var a=n.pageY-window.pageYOffset-i(t.scrollbarYRail).top,s=a>t.scrollbarYTop?1:-1;o(e,"top",e.scrollTop+s*t.containerHeight),r(e),n.stopPropagation()}),t.event.bind(t.scrollbarX,"click",n),t.event.bind(t.scrollbarXRail,"click",function(n){var a=n.pageX-window.pageXOffset-i(t.scrollbarXRail).left,s=a>t.scrollbarXLeft?1:-1;o(e,"left",e.scrollLeft+s*t.containerWidth),r(e),n.stopPropagation()})}var a=e("../instances"),r=e("../update-geometry"),o=e("../update-scroll");t.exports=function(e){n(e,a.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(e,t,i){"use strict";function n(e,t){function i(i){var a=n+i*t.railXRatio,o=Math.max(0,t.scrollbarXRail.getBoundingClientRect().left)+t.railXRatio*(t.railXWidth-t.scrollbarXWidth);t.scrollbarXLeft=a<0?0:a>o?o:a;var s=r.toInt(t.scrollbarXLeft*(t.contentWidth-t.containerWidth)/(t.containerWidth-t.railXRatio*t.scrollbarXWidth))-t.negativeScrollAdjustment;c(e,"left",s)}var n=null,a=null,s=function(t){i(t.pageX-a),l(e),t.stopPropagation(),t.preventDefault()},d=function(){r.stopScrolling(e,"x"),t.event.unbind(t.ownerDocument,"mousemove",s)};t.event.bind(t.scrollbarX,"mousedown",function(i){a=i.pageX,n=r.toInt(o.css(t.scrollbarX,"left"))*t.railXRatio,r.startScrolling(e,"x"),t.event.bind(t.ownerDocument,"mousemove",s),t.event.once(t.ownerDocument,"mouseup",d),i.stopPropagation(),i.preventDefault()})}function a(e,t){function i(i){var a=n+i*t.railYRatio,o=Math.max(0,t.scrollbarYRail.getBoundingClientRect().top)+t.railYRatio*(t.railYHeight-t.scrollbarYHeight);t.scrollbarYTop=a<0?0:a>o?o:a;var s=r.toInt(t.scrollbarYTop*(t.contentHeight-t.containerHeight)/(t.containerHeight-t.railYRatio*t.scrollbarYHeight));c(e,"top",s)}var n=null,a=null,s=function(t){i(t.pageY-a),l(e),t.stopPropagation(),t.preventDefault()},d=function(){r.stopScrolling(e,"y"),t.event.unbind(t.ownerDocument,"mousemove",s)};t.event.bind(t.scrollbarY,"mousedown",function(i){a=i.pageY,n=r.toInt(o.css(t.scrollbarY,"top"))*t.railYRatio,r.startScrolling(e,"y"),t.event.bind(t.ownerDocument,"mousemove",s),t.event.once(t.ownerDocument,"mouseup",d),i.stopPropagation(),i.preventDefault()})}var r=e("../../lib/helper"),o=e("../../lib/dom"),s=e("../instances"),l=e("../update-geometry"),c=e("../update-scroll");t.exports=function(e){var t=s.get(e);n(e,t),a(e,t)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var a=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===a&&n>0||a>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}var n=!1;t.event.bind(e,"mouseenter",function(){n=!0}),t.event.bind(e,"mouseleave",function(){n=!1});var o=!1;t.event.bind(t.ownerDocument,"keydown",function(c){if(!(c.isDefaultPrevented&&c.isDefaultPrevented()||c.defaultPrevented)){var d=r.matches(t.scrollbarX,":focus")||r.matches(t.scrollbarY,":focus");if(n||d){var u=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(u){if("IFRAME"===u.tagName)u=u.contentDocument.activeElement;else for(;u.shadowRoot;)u=u.shadowRoot.activeElement;if(a.isEditable(u))return}var h=0,p=0;switch(c.which){case 37:h=c.metaKey?-t.contentWidth:c.altKey?-t.containerWidth:-30;break;case 38:p=c.metaKey?t.contentHeight:c.altKey?t.containerHeight:30;break;case 39:h=c.metaKey?t.contentWidth:c.altKey?t.containerWidth:30;break;case 40:p=c.metaKey?-t.contentHeight:c.altKey?-t.containerHeight:-30;break;case 33:p=90;break;case 32:p=c.shiftKey?90:-90;break;case 34:p=-90;break;case 35:p=c.ctrlKey?-t.contentHeight:-t.containerHeight;break;case 36:p=c.ctrlKey?e.scrollTop:t.containerHeight;break;default:return}l(e,"top",e.scrollTop-p),l(e,"left",e.scrollLeft+h),s(e),o=i(h,p),o&&c.preventDefault()}}})}var a=e("../../lib/helper"),r=e("../../lib/dom"),o=e("../instances"),s=e("../update-geometry"),l=e("../update-scroll");t.exports=function(e){n(e,o.get(e))}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var a=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===a&&n>0||a>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}function n(e){var t=e.deltaX,i=-1*e.deltaY;return void 0!==t&&void 0!==i||(t=-1*e.wheelDeltaX/6,i=e.wheelDeltaY/6),e.deltaMode&&1===e.deltaMode&&(t*=10,i*=10),t!==t&&i!==i&&(t=0,i=e.wheelDelta),e.shiftKey?[-i,-t]:[t,i]}function a(t,i){var n=e.querySelector("textarea:hover, select[multiple]:hover, .ps-child:hover");if(n){if(!window.getComputedStyle(n).overflow.match(/(scroll|auto)/))return!1;var a=n.scrollHeight-n.clientHeight;if(a>0&&!(0===n.scrollTop&&i>0||n.scrollTop===a&&i<0))return!0;var r=n.scrollLeft-n.clientWidth;if(r>0&&!(0===n.scrollLeft&&t<0||n.scrollLeft===r&&t>0))return!0}return!1}function s(s){var c=n(s),d=c[0],u=c[1];a(d,u)||(l=!1,t.settings.useBothWheelAxes?t.scrollbarYActive&&!t.scrollbarXActive?(u?o(e,"top",e.scrollTop-u*t.settings.wheelSpeed):o(e,"top",e.scrollTop+d*t.settings.wheelSpeed),l=!0):t.scrollbarXActive&&!t.scrollbarYActive&&(d?o(e,"left",e.scrollLeft+d*t.settings.wheelSpeed):o(e,"left",e.scrollLeft-u*t.settings.wheelSpeed),l=!0):(o(e,"top",e.scrollTop-u*t.settings.wheelSpeed),o(e,"left",e.scrollLeft+d*t.settings.wheelSpeed)),r(e),(l=l||i(d,u))&&(s.stopPropagation(),s.preventDefault()))}var l=!1;void 0!==window.onwheel?t.event.bind(e,"wheel",s):void 0!==window.onmousewheel&&t.event.bind(e,"mousewheel",s)}var a=e("../instances"),r=e("../update-geometry"),o=e("../update-scroll");t.exports=function(e){n(e,a.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(e,t,i){"use strict";function n(e,t){t.event.bind(e,"scroll",function(){r(e)})}var a=e("../instances"),r=e("../update-geometry");t.exports=function(e){n(e,a.get(e))}},{"../instances":18,"../update-geometry":19}],15:[function(e,t,i){"use strict";function n(e,t){function i(){var e=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===e.toString().length?null:e.getRangeAt(0).commonAncestorContainer}function n(){c||(c=setInterval(function(){if(!r.get(e))return void clearInterval(c);s(e,"top",e.scrollTop+d.top),s(e,"left",e.scrollLeft+d.left),o(e)},50))}function l(){c&&(clearInterval(c),c=null),a.stopScrolling(e)}var c=null,d={top:0,left:0},u=!1;t.event.bind(t.ownerDocument,"selectionchange",function(){e.contains(i())?u=!0:(u=!1,l())}),t.event.bind(window,"mouseup",function(){u&&(u=!1,l())}),t.event.bind(window,"keyup",function(){u&&(u=!1,l())}),t.event.bind(window,"mousemove",function(t){if(u){var i={x:t.pageX,y:t.pageY},r={left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight};i.x<r.left+3?(d.left=-5,a.startScrolling(e,"x")):i.x>r.right-3?(d.left=5,a.startScrolling(e,"x")):d.left=0,i.y<r.top+3?(d.top=r.top+3-i.y<5?-5:-20,a.startScrolling(e,"y")):i.y>r.bottom-3?(d.top=i.y-r.bottom+3<5?5:20,a.startScrolling(e,"y")):d.top=0,0===d.top&&0===d.left?l():n()}})}var a=e("../../lib/helper"),r=e("../instances"),o=e("../update-geometry"),s=e("../update-scroll");t.exports=function(e){n(e,r.get(e))}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(e,t,i){"use strict";function n(e,t,i,n){function a(i,n){var a=e.scrollTop,r=e.scrollLeft,o=Math.abs(i),s=Math.abs(n);if(s>o){if(n<0&&a===t.contentHeight-t.containerHeight||n>0&&0===a)return!t.settings.swipePropagation}else if(o>s&&(i<0&&r===t.contentWidth-t.containerWidth||i>0&&0===r))return!t.settings.swipePropagation;return!0}function l(t,i){s(e,"top",e.scrollTop-i),s(e,"left",e.scrollLeft-t),o(e)}function c(){w=!0}function d(){w=!1}function u(e){return e.targetTouches?e.targetTouches[0]:e}function h(e){return!(!e.targetTouches||1!==e.targetTouches.length)||!(!e.pointerType||"mouse"===e.pointerType||e.pointerType===e.MSPOINTER_TYPE_MOUSE)}function p(e){if(h(e)){y=!0;var t=u(e);g.pageX=t.pageX,g.pageY=t.pageY,v=(new Date).getTime(),null!==b&&clearInterval(b),e.stopPropagation()}}function f(e){if(!y&&t.settings.swipePropagation&&p(e),!w&&y&&h(e)){var i=u(e),n={pageX:i.pageX,pageY:i.pageY},r=n.pageX-g.pageX,o=n.pageY-g.pageY;l(r,o),g=n;var s=(new Date).getTime(),c=s-v;c>0&&(_.x=r/c,_.y=o/c,v=s),a(r,o)&&(e.stopPropagation(),e.preventDefault())}}function m(){!w&&y&&(y=!1,clearInterval(b),b=setInterval(function(){return r.get(e)&&(_.x||_.y)?Math.abs(_.x)<.01&&Math.abs(_.y)<.01?void clearInterval(b):(l(30*_.x,30*_.y),_.x*=.8,void(_.y*=.8)):void clearInterval(b)},10))}var g={},v=0,_={},b=null,w=!1,y=!1;i?(t.event.bind(window,"touchstart",c),t.event.bind(window,"touchend",d),t.event.bind(e,"touchstart",p),t.event.bind(e,"touchmove",f),t.event.bind(e,"touchend",m)):n&&(window.PointerEvent?(t.event.bind(window,"pointerdown",c),t.event.bind(window,"pointerup",d),t.event.bind(e,"pointerdown",p),t.event.bind(e,"pointermove",f),t.event.bind(e,"pointerup",m)):window.MSPointerEvent&&(t.event.bind(window,"MSPointerDown",c),t.event.bind(window,"MSPointerUp",d),t.event.bind(e,"MSPointerDown",p),t.event.bind(e,"MSPointerMove",f),t.event.bind(e,"MSPointerUp",m)))}var a=e("../../lib/helper"),r=e("../instances"),o=e("../update-geometry"),s=e("../update-scroll");t.exports=function(e){if(a.env.supportsTouch||a.env.supportsIePointer){n(e,r.get(e),a.env.supportsTouch,a.env.supportsIePointer)}}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(e,t,i){"use strict";var n=e("../lib/helper"),a=e("../lib/class"),r=e("./instances"),o=e("./update-geometry"),s={"click-rail":e("./handler/click-rail"),"drag-scrollbar":e("./handler/drag-scrollbar"),keyboard:e("./handler/keyboard"),wheel:e("./handler/mouse-wheel"),touch:e("./handler/touch"),selection:e("./handler/selection")},l=e("./handler/native-scroll");t.exports=function(e,t){t="object"==typeof t?t:{},a.add(e,"ps-container");var i=r.add(e);i.settings=n.extend(i.settings,t),a.add(e,"ps-theme-"+i.settings.theme),i.settings.handlers.forEach(function(t){s[t](e)}),l(e),o(e)}},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(e,t,i){"use strict";function n(e){function t(){l.add(e,"ps-focus")}function i(){l.remove(e,"ps-focus")}var n=this;n.settings=s.clone(c),n.containerWidth=null,n.containerHeight=null,n.contentWidth=null,n.contentHeight=null,n.isRtl="rtl"===d.css(e,"direction"),n.isNegativeScroll=function(){var t=e.scrollLeft,i=null;return e.scrollLeft=-1,i=e.scrollLeft<0,e.scrollLeft=t,i}(),n.negativeScrollAdjustment=n.isNegativeScroll?e.scrollWidth-e.clientWidth:0,n.event=new u,n.ownerDocument=e.ownerDocument||document,n.scrollbarXRail=d.appendTo(d.e("div","ps-scrollbar-x-rail"),e),n.scrollbarX=d.appendTo(d.e("div","ps-scrollbar-x"),n.scrollbarXRail),n.scrollbarX.setAttribute("tabindex",0),n.event.bind(n.scrollbarX,"focus",t),n.event.bind(n.scrollbarX,"blur",i),n.scrollbarXActive=null,n.scrollbarXWidth=null,n.scrollbarXLeft=null,n.scrollbarXBottom=s.toInt(d.css(n.scrollbarXRail,"bottom")),n.isScrollbarXUsingBottom=n.scrollbarXBottom===n.scrollbarXBottom,n.scrollbarXTop=n.isScrollbarXUsingBottom?null:s.toInt(d.css(n.scrollbarXRail,"top")),n.railBorderXWidth=s.toInt(d.css(n.scrollbarXRail,"borderLeftWidth"))+s.toInt(d.css(n.scrollbarXRail,"borderRightWidth")),d.css(n.scrollbarXRail,"display","block"),n.railXMarginWidth=s.toInt(d.css(n.scrollbarXRail,"marginLeft"))+s.toInt(d.css(n.scrollbarXRail,"marginRight")),d.css(n.scrollbarXRail,"display",""),n.railXWidth=null,n.railXRatio=null,n.scrollbarYRail=d.appendTo(d.e("div","ps-scrollbar-y-rail"),e),n.scrollbarY=d.appendTo(d.e("div","ps-scrollbar-y"),n.scrollbarYRail),n.scrollbarY.setAttribute("tabindex",0),n.event.bind(n.scrollbarY,"focus",t),n.event.bind(n.scrollbarY,"blur",i),n.scrollbarYActive=null,n.scrollbarYHeight=null,n.scrollbarYTop=null,n.scrollbarYRight=s.toInt(d.css(n.scrollbarYRail,"right")),n.isScrollbarYUsingRight=n.scrollbarYRight===n.scrollbarYRight,n.scrollbarYLeft=n.isScrollbarYUsingRight?null:s.toInt(d.css(n.scrollbarYRail,"left")),n.scrollbarYOuterWidth=n.isRtl?s.outerWidth(n.scrollbarY):null,n.railBorderYWidth=s.toInt(d.css(n.scrollbarYRail,"borderTopWidth"))+s.toInt(d.css(n.scrollbarYRail,"borderBottomWidth")),d.css(n.scrollbarYRail,"display","block"),n.railYMarginHeight=s.toInt(d.css(n.scrollbarYRail,"marginTop"))+s.toInt(d.css(n.scrollbarYRail,"marginBottom")),d.css(n.scrollbarYRail,"display",""),n.railYHeight=null,n.railYRatio=null}function a(e){return e.getAttribute("data-ps-id")}function r(e,t){e.setAttribute("data-ps-id",t)}function o(e){e.removeAttribute("data-ps-id")}var s=e("../lib/helper"),l=e("../lib/class"),c=e("./default-setting"),d=e("../lib/dom"),u=e("../lib/event-manager"),h=e("../lib/guid"),p={};i.add=function(e){var t=h();return r(e,t),p[t]=new n(e),p[t]},i.remove=function(e){delete p[a(e)],o(e)},i.get=function(e){return p[a(e)]}},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(e,t,i){"use strict";function n(e,t){return e.settings.minScrollbarLength&&(t=Math.max(t,e.settings.minScrollbarLength)),e.settings.maxScrollbarLength&&(t=Math.min(t,e.settings.maxScrollbarLength)),t}function a(e,t){var i={width:t.railXWidth};t.isRtl?i.left=t.negativeScrollAdjustment+e.scrollLeft+t.containerWidth-t.contentWidth:i.left=e.scrollLeft,t.isScrollbarXUsingBottom?i.bottom=t.scrollbarXBottom-e.scrollTop:i.top=t.scrollbarXTop+e.scrollTop,s.css(t.scrollbarXRail,i);var n={top:e.scrollTop,height:t.railYHeight};t.isScrollbarYUsingRight?t.isRtl?n.right=t.contentWidth-(t.negativeScrollAdjustment+e.scrollLeft)-t.scrollbarYRight-t.scrollbarYOuterWidth:n.right=t.scrollbarYRight-e.scrollLeft:t.isRtl?n.left=t.negativeScrollAdjustment+e.scrollLeft+2*t.containerWidth-t.contentWidth-t.scrollbarYLeft-t.scrollbarYOuterWidth:n.left=t.scrollbarYLeft+e.scrollLeft,s.css(t.scrollbarYRail,n),s.css(t.scrollbarX,{left:t.scrollbarXLeft,width:t.scrollbarXWidth-t.railBorderXWidth}),s.css(t.scrollbarY,{top:t.scrollbarYTop,height:t.scrollbarYHeight-t.railBorderYWidth})}var r=e("../lib/helper"),o=e("../lib/class"),s=e("../lib/dom"),l=e("./instances"),c=e("./update-scroll");t.exports=function(e){var t=l.get(e);t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight;var i;e.contains(t.scrollbarXRail)||(i=s.queryChildren(e,".ps-scrollbar-x-rail"),i.length>0&&i.forEach(function(e){s.remove(e)}),s.appendTo(t.scrollbarXRail,e)),e.contains(t.scrollbarYRail)||(i=s.queryChildren(e,".ps-scrollbar-y-rail"),i.length>0&&i.forEach(function(e){s.remove(e)}),s.appendTo(t.scrollbarYRail,e)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset<t.contentWidth?(t.scrollbarXActive=!0,t.railXWidth=t.containerWidth-t.railXMarginWidth,t.railXRatio=t.containerWidth/t.railXWidth,t.scrollbarXWidth=n(t,r.toInt(t.railXWidth*t.containerWidth/t.contentWidth)),t.scrollbarXLeft=r.toInt((t.negativeScrollAdjustment+e.scrollLeft)*(t.railXWidth-t.scrollbarXWidth)/(t.contentWidth-t.containerWidth))):t.scrollbarXActive=!1,!t.settings.suppressScrollY&&t.containerHeight+t.settings.scrollYMarginOffset<t.contentHeight?(t.scrollbarYActive=!0,t.railYHeight=t.containerHeight-t.railYMarginHeight,t.railYRatio=t.containerHeight/t.railYHeight,t.scrollbarYHeight=n(t,r.toInt(t.railYHeight*t.containerHeight/t.contentHeight)),t.scrollbarYTop=r.toInt(e.scrollTop*(t.railYHeight-t.scrollbarYHeight)/(t.contentHeight-t.containerHeight))):t.scrollbarYActive=!1,t.scrollbarXLeft>=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),a(e,t),t.scrollbarXActive?o.add(e,"ps-active-x"):(o.remove(e,"ps-active-x"),t.scrollbarXWidth=0,t.scrollbarXLeft=0,c(e,"left",0)),t.scrollbarYActive?o.add(e,"ps-active-y"):(o.remove(e,"ps-active-y"),t.scrollbarYHeight=0,t.scrollbarYTop=0,c(e,"top",0))}},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(e,t,i){"use strict";var n,a,r=e("./instances"),o=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!0),t};t.exports=function(e,t,i){if(void 0===e)throw"You must provide an element to the update-scroll function";if(void 0===t)throw"You must provide an axis to the update-scroll function";if(void 0===i)throw"You must provide a value to the update-scroll function";"top"===t&&i<=0&&(e.scrollTop=i=0,e.dispatchEvent(o("ps-y-reach-start"))),"left"===t&&i<=0&&(e.scrollLeft=i=0,e.dispatchEvent(o("ps-x-reach-start")));var s=r.get(e);"top"===t&&i>=s.contentHeight-s.containerHeight&&(i=s.contentHeight-s.containerHeight,i-e.scrollTop<=1?i=e.scrollTop:e.scrollTop=i,e.dispatchEvent(o("ps-y-reach-end"))),"left"===t&&i>=s.contentWidth-s.containerWidth&&(i=s.contentWidth-s.containerWidth,i-e.scrollLeft<=1?i=e.scrollLeft:e.scrollLeft=i,e.dispatchEvent(o("ps-x-reach-end"))),n||(n=e.scrollTop),a||(a=e.scrollLeft),"top"===t&&i<n&&e.dispatchEvent(o("ps-scroll-up")),"top"===t&&i>n&&e.dispatchEvent(o("ps-scroll-down")),"left"===t&&i<a&&e.dispatchEvent(o("ps-scroll-left")),"left"===t&&i>a&&e.dispatchEvent(o("ps-scroll-right")),"top"===t&&(e.scrollTop=n=i,e.dispatchEvent(o("ps-scroll-y"))),"left"===t&&(e.scrollLeft=a=i,e.dispatchEvent(o("ps-scroll-x")))}},{"./instances":18}],21:[function(e,t,i){"use strict";var n=e("../lib/helper"),a=e("../lib/dom"),r=e("./instances"),o=e("./update-geometry"),s=e("./update-scroll");t.exports=function(e){var t=r.get(e);t&&(t.negativeScrollAdjustment=t.isNegativeScroll?e.scrollWidth-e.clientWidth:0,a.css(t.scrollbarXRail,"display","block"),a.css(t.scrollbarYRail,"display","block"),t.railXMarginWidth=n.toInt(a.css(t.scrollbarXRail,"marginLeft"))+n.toInt(a.css(t.scrollbarXRail,"marginRight")),t.railYMarginHeight=n.toInt(a.css(t.scrollbarYRail,"marginTop"))+n.toInt(a.css(t.scrollbarYRail,"marginBottom")),a.css(t.scrollbarXRail,"display","none"),a.css(t.scrollbarYRail,"display","none"),o(e),s(e,"top",e.scrollTop),s(e,"left",e.scrollLeft),a.css(t.scrollbarXRail,"display",""),a.css(t.scrollbarYRail,"display",""))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]),define("WoltLabSuite/Core/Date/Util",["Language"],function(e){"use strict";return{formatDate:function(t){return this.format(t,e.get("wcf.date.dateFormat"))},formatTime:function(t){return this.format(t,e.get("wcf.date.timeFormat"))},formatDateTime:function(t){return this.format(t,e.get("wcf.date.dateTimeFormat").replace(/%date%/,e.get("wcf.date.dateFormat")).replace(/%time%/,e.get("wcf.date.timeFormat")))},format:function(t,i){var n,a="";"c"===i&&(i="Y-m-dTH:i:sP");for(var r=0,o=i.length;r<o;r++){switch(i[r]){case"s":n=("0"+t.getSeconds().toString()).slice(-2);break;case"i":n=t.getMinutes(),n<10&&(n="0"+n);break;case"a":n=t.getHours()>11?"pm":"am";break;case"g":n=t.getHours(),0===n?n=12:n>12&&(n-=12);break;case"h":n=t.getHours(),0===n?n=12:n>12&&(n-=12),n=("0"+n.toString()).slice(-2);break;case"A":n=t.getHours()>11?"PM":"AM";break;case"G":n=t.getHours();break;case"H":n=t.getHours(),n=("0"+n.toString()).slice(-2);break;case"d":n=t.getDate(),n=("0"+n.toString()).slice(-2);break;case"j":n=t.getDate();break;case"l":n=e.get("__days")[t.getDay()];break;case"D":n=e.get("__daysShort")[t.getDay()];break;case"S":n="";break;case"m":n=t.getMonth()+1,n=("0"+n.toString()).slice(-2);break;case"n":n=t.getMonth()+1;break;case"F":n=e.get("__months")[t.getMonth()];break;case"M":n=e.get("__monthsShort")[t.getMonth()];break;case"y":n=t.getFullYear().toString().substr(2);break;case"Y":n=t.getFullYear();break;case"P":var s=t.getTimezoneOffset();n=s>0?"-":"+",s=Math.abs(s),n+=("0"+(~~(s/60)).toString()).slice(-2),n+=":",n+=("0"+(s%60).toString()).slice(-2);break;case"r":n=t.toString();break;case"U":n=Math.round(t.getTime()/1e3);break;case"\\":n="",r+1<o&&(n=i[++r]);break;default:n=i[r]}a+=n}return a},gmdate:function(e){return e instanceof Date||(e=new Date),Math.round(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDay(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds())/1e3)},getTimeElement:function(t){var i=elCreate("time");i.className="datetime";var n=this.formatDate(t),a=this.formatTime(t);return elAttr(i,"datetime",this.format(t,"c")),elData(i,"timestamp",(t.getTime()-t.getMilliseconds())/1e3),elData(i,"date",n),elData(i,"time",a),elData(i,"offset",60*t.getTimezoneOffset()),t.getTime()>Date.now()&&(elData(i,"is-future-date","true"),i.textContent=e.get("wcf.date.dateTimeFormat").replace("%time%",a).replace("%date%",n)),i},getTimezoneDate:function(e,t){var i=new Date(e),n=6e4*i.getTimezoneOffset();return new Date(e+n+t)}}}),define("WoltLabSuite/Core/Timer/Repeating",[],function(){"use strict";function e(e,t){if("function"!=typeof e)throw new TypeError("Expected a valid callback as first argument.");if(t<0||t>864e5)throw new RangeError("Invalid delta "+t+". Delta must be in the interval [0, 86400000].");this._callback=e.bind(void 0,this),this._delta=t,this._timer=void 0,this.restart()}return e.prototype={restart:function(){this.stop(),this._timer=setInterval(this._callback,this._delta)},stop:function(){void 0!==this._timer&&(clearInterval(this._timer),this._timer=void 0)},setDelta:function(e){this._delta=e,this.restart()}},e}),define("WoltLabSuite/Core/Date/Time/Relative",["Dom/ChangeListener","Language","WoltLabSuite/Core/Date/Util","WoltLabSuite/Core/Timer/Repeating"],function(e,t,i,n){"use strict";var a=elByTag("time"),r=!0,o=!1,s=null;return{setup:function(){new n(this._refresh.bind(this),6e4),e.add("WoltLabSuite/Core/Date/Time/Relative",this._refresh.bind(this)),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this))},_onVisibilityChange:function(){document.hidden?(r=!1,o=!1):(r=!0,o&&(this._refresh(),o=!1))},_refresh:function(){if(!r)return void(o||(o=!0));var e=new Date,n=(e.getTime()-e.getMilliseconds())/1e3;null===s&&(s=n-window.TIME_NOW);for(var l=0,c=a.length;l<c;l++){var d=a[l];if(d.classList.contains("datetime")&&!elData(d,"is-future-date")){var u=~~elData(d,"timestamp")+s,h=elData(d,"date"),p=elData(d,"time"),f=elData(d,"offset");if(elAttr(d,"title")||elAttr(d,"title",t.get("wcf.date.dateTimeFormat").replace(/%date%/,h).replace(/%time%/,p)),u>=n||n<u+60)d.textContent=t.get("wcf.date.relative.now");else if(n<u+3540){var m=Math.max(Math.round((n-u)/60),1);d.textContent=t.get("wcf.date.relative.minutes",{minutes:m})}else if(n<u+86400){var g=Math.round((n-u)/3600);d.textContent=t.get("wcf.date.relative.hours",{hours:g})}else if(n<u+518400){var v=new Date(e.getFullYear(),e.getMonth(),e.getDate()),_=Math.ceil((v/1e3-u)/86400),b=i.getTimezoneDate(1e3*u,1e3*f),w=b.getDay(),y=t.get("__days")[w];d.textContent=t.get("wcf.date.relative.pastDays",{days:_,day:y,time:p})}else d.textContent=t.get("wcf.date.shortDateTimeFormat").replace(/%date%/,h).replace(/%time%/,p)}}}}}),define("WoltLabSuite/Core/Ui/Page/Menu/Abstract",["Core","Environment","EventHandler","Language","ObjectMap","Dom/Traverse","Dom/Util","Ui/Screen"],function(e,t,i,n,a,r,o,s){"use strict";function l(e,t,i){this.init(e,t,i)}var c=elById("pageContainer"),d="";return l.prototype={init:function(e,n,r){if("packageInstallationSetup"!==elData(document.body,"template")){this._activeList=[],this._depth=0,this._enabled=!0,this._eventIdentifier=e,this._items=new a,this._menu=elById(n),this._removeActiveList=!1;var s=this.open.bind(this);this._button=elBySel(r),this._button.addEventListener(WCF_CLICK_EVENT,s),this._initItems(),this._initHeader(),i.add(this._eventIdentifier,"open",s),i.add(this._eventIdentifier,"close",this.close.bind(this)),i.add(this._eventIdentifier,"updateButtonState",this._updateButtonState.bind(this));var l,c=elByClass("menuOverlayItemList",this._menu);this._menu.addEventListener("animationend",function(){if(!this._menu.classList.contains("open"))for(var e=0,t=c.length;e<t;e++)l=c[e],l.classList.remove("active"),l.classList.remove("hidden")}.bind(this)),this._menu.children[0].addEventListener("transitionend",function(){if(this._menu.classList.add("allowScroll"),this._removeActiveList){this._removeActiveList=!1;var e=this._activeList.pop();e&&e.classList.remove("activeList")}}.bind(this));var d=elCreate("div");d.className="menuOverlayMobileBackdrop",d.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),o.insertAfter(d,this._menu),this._updateButtonState(),"android"===t.platform()&&this._initializeAndroid()}},open:function(e){return!!this._enabled&&(e instanceof Event&&e.preventDefault(),this._menu.classList.add("open"),this._menu.classList.add("allowScroll"),this._menu.children[0].classList.add("activeList"),s.scrollDisable(),c.classList.add("menuOverlay-"+this._menu.id),s.pageOverlayOpen(),!0)},close:function(e){return e instanceof Event&&e.preventDefault(),!!this._menu.classList.contains("open")&&(this._menu.classList.remove("open"),s.scrollEnable(),s.pageOverlayClose(),
-c.classList.remove("menuOverlay-"+this._menu.id),!0)},enable:function(){this._enabled=!0},disable:function(){this._enabled=!1,this.close(!0)},_initializeAndroid:function(){var t,i,n;switch(this._menu.id){case"pageUserMenuMobile":t="right";break;case"pageMainMenuMobile":t="left";break;default:return}i=this._menu.nextElementSibling,n=null,document.addEventListener("touchstart",function(i){var a,r,o,l;if(a=i.touches,r=this._menu.classList.contains("open"),"left"===t?(o=!r&&a[0].clientX<20,l=r&&Math.abs(this._menu.offsetWidth-a[0].clientX)<20):"right"===t&&(o=r&&Math.abs(document.body.clientWidth-this._menu.offsetWidth-a[0].clientX)<20,l=!r&&document.body.clientWidth-a[0].clientX<20),a.length>1)return void(d&&e.triggerEvent(document,"touchend"));if(!d&&(o||l)){if(s.pageOverlayIsActive()){for(var u=!1,h=0;h<c.classList.length;h++)c.classList[h]==="menuOverlay-"+this._menu.id&&(u=!0);if(!u)return}document.documentElement.classList.contains("redactorActive")||(n={x:a[0].clientX,y:a[0].clientY},o&&(d="left"),l&&(d="right"))}}.bind(this)),document.addEventListener("touchend",function(e){if(d&&null!==n){if(!this._menu.classList.contains("open"))return n=null,void(d="");var a;a=e?e.changedTouches[0].clientX:n.x,this._menu.classList.add("androidMenuTouchEnd"),this._menu.style.removeProperty("transform"),i.style.removeProperty(t),this._menu.addEventListener("transitionend",function(){this._menu.classList.remove("androidMenuTouchEnd")}.bind(this),{once:!0}),"left"===t?("left"===d&&a<n.x+100&&this.close(),"right"===d&&a<n.x-100&&this.close()):"right"===t&&("left"===d&&a>n.x+100&&this.close(),"right"===d&&a>n.x-100&&this.close()),n=null,d=""}}.bind(this)),document.addEventListener("touchmove",function(e){if(d&&null!==n){var a=e.touches,r=!1,o=!1;"left"===d&&(r=a[0].clientX>n.x+5),"right"===d&&(r=a[0].clientX<n.x-5),o=Math.abs(a[0].clientY-n.y)>20;var s=this._menu.classList.contains("open");if(s||!r||o||(this.open(),s=!0),s){var l=a[0].clientX;"right"===t&&(l=document.body.clientWidth-l),l>this._menu.offsetWidth&&(l=this._menu.offsetWidth),l<0&&(l=0),this._menu.style.setProperty("transform","translateX("+("left"===t?1:-1)*(l-this._menu.offsetWidth)+"px)"),i.style.setProperty(t,Math.min(this._menu.offsetWidth,l)+"px")}}}.bind(this))},_initItems:function(){elBySelAll(".menuOverlayItemLink",this._menu,this._initItem.bind(this))},_initItem:function(e){var t=e.parentNode,n=elData(t,"more");if(n)return void e.addEventListener(WCF_CLICK_EVENT,function(a){a.preventDefault(),a.stopPropagation(),i.fire(this._eventIdentifier,"more",{handler:this,identifier:n,item:e,parent:t})}.bind(this));var a,o=e.nextElementSibling;if(null!==o)if("OL"!==o.nodeName&&o.classList.contains("menuOverlayItemLinkIcon"))for(a=elCreate("span"),a.className="menuOverlayItemWrapper",t.insertBefore(a,e),a.appendChild(e);a.nextElementSibling;)a.appendChild(a.nextElementSibling);else{var s="#"!==elAttr(e,"href"),l=t.parentNode,c=elData(o,"title");this._items.set(e,{itemList:o,parentItemList:l}),""===c&&(c=r.childByClass(e,"menuOverlayItemTitle").textContent,elData(o,"title",c));var d=this._showItemList.bind(this,e);if(s){a=elCreate("span"),a.className="menuOverlayItemWrapper",t.insertBefore(a,e),a.appendChild(e);var u=elCreate("a");elAttr(u,"href","#"),u.className="menuOverlayItemLinkIcon"+(e.classList.contains("active")?" active":""),u.innerHTML='<span class="icon icon24 fa-angle-right"></span>',u.addEventListener(WCF_CLICK_EVENT,d),a.appendChild(u)}else e.classList.add("menuOverlayItemLinkMore"),e.addEventListener(WCF_CLICK_EVENT,d);var h=elCreate("li");h.className="menuOverlayHeader",a=elCreate("span"),a.className="menuOverlayItemWrapper";var p=elCreate("a");elAttr(p,"href","#"),p.className="menuOverlayItemLink menuOverlayBackLink",p.textContent=elData(l,"title"),p.addEventListener(WCF_CLICK_EVENT,this._hideItemList.bind(this,e));var f=elCreate("a");if(elAttr(f,"href","#"),f.className="menuOverlayItemLinkIcon",f.innerHTML='<span class="icon icon24 fa-times"></span>',f.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),a.appendChild(p),a.appendChild(f),h.appendChild(a),o.insertBefore(h,o.firstElementChild),!h.nextElementSibling.classList.contains("menuOverlayTitle")){var m=elCreate("li");m.className="menuOverlayTitle";var g=elCreate("span");g.textContent=c,m.appendChild(g),o.insertBefore(m,h.nextElementSibling)}}},_initHeader:function(){var e=elCreate("li");e.className="menuOverlayHeader";var t=elCreate("span");t.className="menuOverlayItemWrapper",e.appendChild(t);var i=elCreate("span");i.className="menuOverlayLogoWrapper",t.appendChild(i);var n=elCreate("span");n.className="menuOverlayLogo",n.style.setProperty("background-image",'url("'+elData(this._menu,"page-logo")+'")',""),i.appendChild(n);var a=elCreate("a");elAttr(a,"href","#"),a.className="menuOverlayItemLinkIcon",a.innerHTML='<span class="icon icon24 fa-times"></span>',a.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),t.appendChild(a);var o=r.childByClass(this._menu,"menuOverlayItemList");o.insertBefore(e,o.firstElementChild)},_hideItemList:function(e,t){t instanceof Event&&t.preventDefault(),this._menu.classList.remove("allowScroll"),this._removeActiveList=!0,this._items.get(e).parentItemList.classList.remove("hidden"),this._updateDepth(!1)},_showItemList:function(e,t){t instanceof Event&&t.preventDefault();var n=this._items.get(e),a=elData(n.itemList,"load");if(a&&!elDataBool(e,"loaded")){var r=t.currentTarget.firstElementChild;return r.classList.contains("fa-angle-right")&&(r.classList.remove("fa-angle-right"),r.classList.add("fa-spinner")),void i.fire(this._eventIdentifier,"load_"+a)}this._menu.classList.remove("allowScroll"),n.itemList.classList.add("activeList"),n.parentItemList.classList.add("hidden"),this._activeList.push(n.itemList),this._updateDepth(!0)},_updateDepth:function(e){this._depth+=e?1:-1;var t=-100*this._depth;"rtl"===n.get("wcf.global.pageDirection")&&(t*=-1),this._menu.children[0].style.setProperty("transform","translateX("+t+"%)","")},_updateButtonState:function(){var e=!1;elBySelAll(".badgeUpdate",this._menu,function(t){~~t.textContent>0&&(e=!0)}),this._button.classList[e?"add":"remove"]("pageMenuMobileButtonHasContent")}},l}),define("WoltLabSuite/Core/Ui/Page/Menu/Main",["Core","Language","Dom/Traverse","./Abstract"],function(e,t,i,n){"use strict";function a(){this.init()}var r=null,o=null,s=null,l=null,c=null;return e.inherit(a,n,{init:function(){a._super.prototype.init.call(this,"com.woltlab.wcf.MainMenuMobile","pageMainMenuMobile","#pageHeader .mainMenu"),r=elById("pageMainMenuMobilePageOptionsTitle"),null!==r&&(s=i.childByClass(r,"menuOverlayItemList"),l=elBySel(".jsPageNavigationIcons"),c=function(e){this.close(),e.stopPropagation()}.bind(this)),elAttr(this._button,"aria-label",t.get("wcf.menu.page")),elAttr(this._button,"role","button")},open:function(e){if(!a._super.prototype.open.call(this,e))return!1;if(null===r)return!0;if(o=l&&l.childElementCount>0){for(var t,i;l.childElementCount;)t=l.children[0],t.classList.add("menuOverlayItem"),t.classList.add("menuOverlayItemOption"),t.addEventListener(WCF_CLICK_EVENT,c),i=t.children[0],i.classList.add("menuOverlayItemLink"),i.classList.add("box24"),i.children[1].classList.remove("invisible"),i.children[1].classList.add("menuOverlayItemTitle"),r.parentNode.insertBefore(t,r.nextSibling);elShow(r)}else elHide(r);return!0},close:function(e){if(!a._super.prototype.close.call(this,e))return!1;if(o){elHide(r);for(var t,i=r.nextElementSibling;i&&i.classList.contains("menuOverlayItemOption");)i.classList.remove("menuOverlayItem"),i.classList.remove("menuOverlayItemOption"),i.removeEventListener(WCF_CLICK_EVENT,c),t=i.children[0],t.classList.remove("menuOverlayItemLink"),t.classList.remove("box24"),t.children[1].classList.add("invisible"),t.children[1].classList.remove("menuOverlayItemTitle"),l.appendChild(i),i=i.nextElementSibling}return!0}}),a}),define("WoltLabSuite/Core/Ui/Page/Menu/User",["Core","EventHandler","Language","./Abstract"],function(e,t,i,n){"use strict";function a(){this.init()}return e.inherit(a,n,{init:function(){var e=elBySel("#pageUserMenuMobile > .menuOverlayItemList");if(1===e.childElementCount&&e.children[0].classList.contains("menuOverlayTitle"))return void elBySel("#pageHeader .userPanel").classList.add("hideUserPanel");a._super.prototype.init.call(this,"com.woltlab.wcf.UserMenuMobile","pageUserMenuMobile","#pageHeader .userPanel"),t.add("com.woltlab.wcf.userMenu","updateBadge",function(e){elBySelAll(".menuOverlayItemBadge",this._menu,function(t){if(elData(t,"badge-identifier")===e.identifier){var i=elBySel(".badge",t);e.count?(null===i&&(i=elCreate("span"),i.className="badge badgeUpdate",t.appendChild(i)),i.textContent=e.count):null!==i&&elRemove(i),this._updateButtonState()}}.bind(this))}.bind(this)),elAttr(this._button,"aria-label",i.get("wcf.menu.user")),elAttr(this._button,"role","button")},close:function(e){if(void 0!==this._menu){var t=WCF.Dropdown.Interactive.Handler.getOpenDropdown();t?(e.preventDefault(),e.stopPropagation(),t.close()):a._super.prototype.close.call(this,e)}}}),a}),define("WoltLabSuite/Core/Ui/Dropdown/Reusable",["Dictionary","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!n.has(e))throw new Error("Unknown dropdown identifier '"+e+"'");return n.get(e)}var n=new e,a=0;return{init:function(e,i){if(!n.has(e)){var r=elCreate("div");r.id="reusableDropdownGhost"+a++,t.initFragment(r,i),n.set(e,r.id)}},getDropdownMenu:function(e){return t.getDropdownMenu(i(e))},registerCallback:function(e,n){t.registerCallback(i(e),n)},toggleDropdown:function(e,n){t.toggleDropdown(i(e),n)}}}),define("WoltLabSuite/Core/Ui/Mobile",["Core","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Alignment","Ui/CloseOverlay","Ui/Screen","./Page/Menu/Main","./Page/Menu/User","WoltLabSuite/Core/Ui/Dropdown/Reusable"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p){"use strict";var f=elByClass("buttonGroupNavigation"),m=null,g=null,v=null,_=!1,b=!1,w=new a,y=null,C=elByClass("message"),E={},L=null,S=null,A=null,I=[],D=!1;return{setup:function(i){E=e.extend({enableMobileMenu:!0},i),y=elById("main"),elBySelAll(".sidebar",void 0,function(e){I.push(e)}),t.touch()&&document.documentElement.classList.add("touch"),"desktop"!==t.platform()&&document.documentElement.classList.add("mobile");var n=elBySel(".messageGroupList");n&&(A=elByClass("messageGroup",n)),d.on("screen-md-down",{match:this.enable.bind(this),unmatch:this.disable.bind(this),setup:this._init.bind(this)}),d.on("screen-sm-down",{match:this.enableShadow.bind(this),unmatch:this.disableShadow.bind(this),setup:this.enableShadow.bind(this)}),d.on("screen-xs",{match:this._enableSidebarXS.bind(this),unmatch:this._disableSidebarXS.bind(this),setup:this._setupSidebarXS.bind(this)}),!t.touch()||"ios"!==t.platform()&&"android"!==t.platform()||d.on("screen-lg",{match:this._enableLGTouchNavigation.bind(this),unmatch:this._disableLGTouchNavigation.bind(this),setup:this._setupLGTouchNavigation.bind(this)})},enable:function(){_=!0,E.enableMobileMenu&&(L.enable(),S.enable())},enableShadow:function(){A&&this.rebuildShadow(A,".messageGroupLink")},disable:function(){_=!1,E.enableMobileMenu&&(L.disable(),S.disable())},disableShadow:function(){A&&this.removeShadow(A),g&&m()},_init:function(){_=!0,this._initSearchBar(),this._initButtonGroupNavigation(),this._initMessages(),this._initMobileMenu(),c.add("WoltLabSuite/Core/Ui/Mobile",this._closeAllMenus.bind(this)),r.add("WoltLabSuite/Core/Ui/Mobile",function(){this._initButtonGroupNavigation(),this._initMessages()}.bind(this))},_initSearchBar:function(){var e=elById("pageHeaderSearch"),n=elById("pageHeaderSearchInput"),a=null;i.add("com.woltlab.wcf.MainMenuMobile","more",function(i){"com.woltlab.wcf.search"===i.identifier&&(i.handler.close(!0),"ios"===t.platform()&&(a=document.body.scrollTop,d.scrollDisable()),e.style.setProperty("top",elById("pageHeader").offsetHeight+"px",""),e.classList.add("open"),n.focus(),"ios"===t.platform()&&(document.body.scrollTop=0))}),y.addEventListener(WCF_CLICK_EVENT,function(){e&&e.classList.remove("open"),"ios"===t.platform()&&null!==a&&(d.scrollEnable(),document.body.scrollTop=a,a=null)})},_initButtonGroupNavigation:function(){for(var e=0,t=f.length;e<t;e++){var i=f[e];if(!i.classList.contains("jsMobileButtonGroupNavigation")){i.classList.add("jsMobileButtonGroupNavigation");var n=elBySel(".buttonList",i);if(0!==n.childElementCount){i.parentNode.classList.add("hasMobileNavigation");var a=elCreate("a");a.className="dropdownLabel";var r=elCreate("span");r.className="icon icon24 fa-ellipsis-v",a.appendChild(r),function(e,t,i){t.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),e.classList.toggle("open")}),i.addEventListener(WCF_CLICK_EVENT,function(t){t.stopPropagation(),e.classList.remove("open")})}(i,a,n),i.insertBefore(a,i.firstChild)}}}},_initMessages:function(){Array.prototype.forEach.call(C,function(e){if(!w.has(e)){var t=elBySel(".jsMobileNavigation",e);if(t){t.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation(),window.setTimeout(function(){t.classList.remove("open")},10)});var i=elBySel(".messageQuickOptions",e);i&&t.childElementCount&&(i.classList.add("active"),i.addEventListener(WCF_CLICK_EVENT,function(n){_&&d.is("screen-sm-down")&&"LABEL"!==n.target.nodeName&&"INPUT"!==n.target.nodeName&&(n.preventDefault(),n.stopPropagation(),this._toggleMobileNavigation(e,i,t))}.bind(this)))}w.add(e)}}.bind(this))},_initMobileMenu:function(){E.enableMobileMenu&&(L=new u,S=new h)},_closeAllMenus:function(){elBySelAll(".jsMobileButtonGroupNavigation.open, .jsMobileNavigation.open",null,function(e){e.classList.remove("open")}),_&&g&&m()},rebuildShadow:function(e,t){for(var i,n,a,r=0,s=e.length;r<s;r++)i=e[r],n=i.parentNode,null===(a=o.childByClass(n,"mobileLinkShadow"))&&elBySel(t,i).href&&(a=elCreate("a"),a.className="mobileLinkShadow",a.href=elBySel(t,i).href,n.appendChild(a),n.classList.add("mobileLinkShadowContainer"))},removeShadow:function(e){for(var t,i,n,a=0,r=e.length;a<r;a++)t=e[a],i=t.parentNode,i.classList.contains("mobileLinkShadowContainer")&&(n=o.childByClass(i,"mobileLinkShadow"),null!==n&&elRemove(n),i.classList.remove("mobileLinkShadowContainer"))},_enableSidebarXS:function(){D=!0},_disableSidebarXS:function(){D=!1,I.forEach(function(e){e.classList.remove("open")})},_setupSidebarXS:function(){I.forEach(function(e){e.addEventListener("mousedown",function(t){D&&t.target===e&&(t.preventDefault(),e.classList.toggle("open"))})}),D=!0},_toggleMobileNavigation:function(e,t,i){if(null===g)g=elCreate("ul"),g.className="dropdownMenu",p.init("com.woltlab.wcf.jsMobileNavigation",g),m=function(){g.classList.remove("dropdownOpen")};else if(g.classList.contains("dropdownOpen")&&(m(),v===e))return;g.innerHTML="",c.execute(),this._rebuildMobileNavigation(i);var n=i.previousElementSibling;if(n&&n.classList.contains("messageFooterButtonsExtra")){var a=elCreate("li");a.className="dropdownDivider",g.appendChild(a),this._rebuildMobileNavigation(n)}l.set(g,t,{horizontal:"right",allowFlip:"vertical"}),g.classList.add("dropdownOpen"),v=e},_setupLGTouchNavigation:function(){b=!0,elBySelAll(".boxMenuHasChildren > a",null,function(e){e.addEventListener("touchstart",function(t){b&&"false"===elAttr(e,"aria-expanded")&&(t.preventDefault(),elAttr(e,"aria-expanded","true"),e.addEventListener("touchend",function(){document.body.addEventListener("touchstart",function(){document.body.addEventListener("touchend",function(t){s.contains(e.parentNode,t.target)||t.target===e.parentNode||elAttr(e,"aria-expanded","false")},{once:!0})},{once:!0})},{once:!0}))})})},_enableLGTouchNavigation:function(){b=!0},_disableLGTouchNavigation:function(){b=!1},_rebuildMobileNavigation:function(t){elBySelAll(".button",t,function(t){if(!t.classList.contains("ignoreMobileNavigation")||t.classList.contains("reactButton")){var i=elCreate("li");t.classList.contains("active")&&(i.className="active"),i.innerHTML='<a href="#">'+elBySel("span:not(.icon)",t).textContent+"</a>",i.children[0].addEventListener(WCF_CLICK_EVENT,function(i){i.preventDefault(),i.stopPropagation(),"A"===t.nodeName?t.click():e.triggerEvent(t,WCF_CLICK_EVENT),m()}),g.appendChild(i)}})}}}),define("WoltLabSuite/Core/Ui/Scroll",["Dom/Util"],function(e){"use strict";var t=null,i=null,n=null,a=null;return{element:function(a,r){if(!(a instanceof Element))throw new TypeError("Expected a valid DOM element.");if(void 0!==r&&"function"!=typeof r)throw new TypeError("Expected a valid callback function.");if(!document.body.contains(a))throw new Error("Element must be part of the visible DOM.");if(null!==t)throw new Error("Cannot scroll to element, a concurrent request is running.");r&&(t=r,null===i&&(i=this._onScroll.bind(this)),window.addEventListener("scroll",i));var o=e.offset(a).top;if(null===n){n=50;var s=elById("pageHeaderPanel");if(null!==s){var l=window.getComputedStyle(s).position;n="fixed"===l||"static"===l?s.offsetHeight:0}}n>0&&(o<=n?o=0:o-=n);var c=window.pageYOffset;window.scrollTo({left:0,top:o,behavior:"smooth"}),window.setTimeout(function(){c===window.pageYOffset&&this._onScroll()}.bind(this),100)},_onScroll:function(){null!==a&&window.clearTimeout(a),a=window.setTimeout(function(){null!==t&&t(),window.removeEventListener("scroll",i),t=null,a=null},100)}}}),define("WoltLabSuite/Core/Ui/TabMenu/Simple",["Dictionary","Environment","EventHandler","Dom/Traverse","Dom/Util"],function(e,t,i,n,a){"use strict";function r(t){this._container=t,this._containers=new e,this._isLegacy=null,this._store=null,this._tabs=new e}return r.prototype={validate:function(){if(!this._container.classList.contains("tabMenuContainer"))return!1;var e=n.childByTag(this._container,"NAV");if(null===e)return!1;var t=elByTag("li",e);if(0===t.length)return!1;var i,r,o,s,l=n.childrenByTag(this._container,"DIV");for(o=0,s=l.length;o<s;o++)i=l[o],r=elData(i,"name"),r||(r=a.identify(i)),elData(i,"name",r),this._containers.set(r,i);var c,d=this._container.id;for(o=0,s=t.length;o<s;o++)if(c=t[o],r=this._getTabName(c)){if(this._tabs.has(r))throw new Error("Tab names must be unique, li[data-name='"+r+"'] (tab menu id: '"+d+"') exists more than once.");if(void 0===(i=this._containers.get(r)))throw new Error("Expected content element for li[data-name='"+r+"'] (tab menu id: '"+d+"').");if(i.parentNode!==this._container)throw new Error("Expected content element '"+r+"' (tab menu id: '"+d+"') to be a direct children.");if(1!==c.childElementCount||"A"!==c.children[0].nodeName)throw new Error("Expected exactly one <a> as children for li[data-name='"+r+"'] (tab menu id: '"+d+"').");this._tabs.set(r,c)}if(!this._tabs.size)throw new Error("Expected at least one tab (tab menu id: '"+d+"').");return this._isLegacy&&(elData(this._container,"is-legacy",!0),this._tabs.forEach(function(e,t){elAttr(e,"aria-controls",t)})),!0},init:function(e){e=e||null,this._tabs.forEach(function(i){if((!e||e.get(elData(i,"name"))!==i)&&(i.children[0].addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this)),"ios"===t.platform())){var n=!1;i.children[0].addEventListener("touchstart",function(){n=!0}),i.children[0].addEventListener("touchmove",function(){n=!1}),i.children[0].addEventListener("touchend",function(e){n&&(n=!1,e.preventDefault(),this._onClick(e))}.bind(this))}}.bind(this));var i=null;if(!e){var n=r.getIdentifierFromHash(),a=null;if(""!==n&&(a=this._tabs.get(n))&&this._container.parentNode.classList.contains("tabMenuContainer")&&(i=this._container),!a){var o=elData(this._container,"preselect")||elData(this._container,"active");"true"!==o&&o||(o=!0),!0===o?this._tabs.forEach(function(e){a||elIsHidden(e)||e.previousElementSibling&&!elIsHidden(e.previousElementSibling)||(a=e)}):"false"!==o&&(a=this._tabs.get(o))}a&&(this._containers.forEach(function(e){e.classList.add("hidden")}),this.select(null,a,!0));var s=elData(this._container,"store");if(s){var l=elCreate("input");l.type="hidden",l.name=s,l.value=elData(this.getActiveTab(),"name"),this._container.appendChild(l),this._store=l}}return i},select:function(e,t,n){if(!(t=t||this._tabs.get(e))){if(~~e==e){e=~~e;var a=0;this._tabs.forEach(function(i){a===e&&(t=i),a++})}if(!t)throw new Error("Expected a valid tab name, '"+e+"' given (tab menu id: '"+this._container.id+"').")}e=e||elData(t,"name");var o=this.getActiveTab(),s=null;if(o){var l=elData(o,"name");if(l===e)return;n||i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"beforeSelect",{tab:o,tabName:l}),o.classList.remove("active"),s=this._containers.get(elData(o,"name")),s.classList.remove("active"),s.classList.add("hidden"),this._isLegacy&&(o.classList.remove("ui-state-active"),s.classList.remove("ui-state-active"))}t.classList.add("active");var c=this._containers.get(e);if(c.classList.add("active"),c.classList.remove("hidden"),this._isLegacy&&(t.classList.add("ui-state-active"),c.classList.add("ui-state-active")),this._store&&(this._store.value=e),!n){i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"select",{active:t,activeName:e,previous:o,previousName:o?elData(o,"name"):null});var d=this._isLegacy&&"function"==typeof window.jQuery?window.jQuery:null;d&&d(this._container).trigger("wcftabsbeforeactivate",{newTab:d(t),oldTab:d(o),newPanel:d(c),oldPanel:d(s)});var u=window.location.href.replace(/#+[^#]*$/,"");r.getIdentifierFromHash()===e?u+=window.location.hash:u+="#"+e,window.history.replaceState(void 0,void 0,u)}require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.scrollToTab(t)})},selectFirstVisible:function(){var e;return this._tabs.forEach(function(t){e||elIsHidden(t)||(e=t)}.bind(this)),e&&this.select(void 0,e,!1),!!e},rebuild:function(){var t=new e;t.merge(this._tabs),this.validate(),this.init(t)},hasTab:function(e){return this._tabs.has(e)},_onClick:function(e){e.preventDefault(),this.select(null,e.currentTarget.parentNode)},_getTabName:function(e){var t=elData(e,"name");return t||1===e.childElementCount&&"A"===e.children[0].nodeName&&e.children[0].href.match(/#([^#]+)$/)&&(t=RegExp.$1,null===elById(t)?t=null:(this._isLegacy=!0,elData(e,"name",t))),t},getActiveTab:function(){return elBySel("#"+this._container.id+" > nav > ul > li.active")},getContainers:function(){return this._containers},getTabs:function(){return this._tabs}},r.getIdentifierFromHash=function(){return window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)?RegExp.$1:""},r}),define("WoltLabSuite/Core/Ui/TabMenu",["Dictionary","EventHandler","Dom/ChangeListener","Dom/Util","Ui/CloseOverlay","Ui/Screen","Ui/Scroll","./TabMenu/Simple"],function(e,t,i,n,a,r,o,s){"use strict";var l=null,c=!1,d=new e;return{setup:function(){this._init(),this._selectErroneousTabs(),i.add("WoltLabSuite/Core/Ui/TabMenu",this._init.bind(this)),a.add("WoltLabSuite/Core/Ui/TabMenu",function(){l&&(l.classList.remove("active"),l=null)}),r.on("screen-sm-down",{enable:this._scrollEnable.bind(this,!1),disable:this._scrollDisable.bind(this),setup:this._scrollEnable.bind(this,!0)}),window.addEventListener("hashchange",function(){var e=s.getIdentifierFromHash(),t=e?elById(e):null;null!==t&&t.classList.contains("tabMenuContent")&&d.forEach(function(t){t.hasTab(e)&&t.select(e)})});var e=s.getIdentifierFromHash();e&&window.setTimeout(function(){var t=elById(e);if(t&&t.classList.contains("tabMenuContent")){var i=window.scrollY||window.pageYOffset;if(i>0){var a=t.parentNode,r=a.offsetTop-50;if(r<0&&(r=0),i>r){var o=n.offset(a).top;o<=50?o=0:o-=50,window.scrollTo(0,o)}}}},100)},_init:function(){for(var e,t,i,a,r,c=elBySelAll(".tabMenuContainer:not(.staticTabMenuContainer)"),u=0,h=c.length;u<h;u++)if(e=c[u],t=n.identify(e),!d.has(t)&&(r=new s(e),r.validate())){a=r.init(),d.set(t,r),a instanceof Element&&(r=this.getTabMenu(a.parentNode.id),r.select(a.id,null,!0)),i=elBySel("#"+t+" > nav > ul"),function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),t.target===e?(e.classList.add("active"),l=e):(e.classList.remove("active"),l=null)})}(i),elBySelAll(".tabMenu, .menu",e,function(e){var t=this._rebuildMenuOverflow.bind(this,e),i=null;elBySel("ul",e).addEventListener("scroll",function(){null!==i&&window.clearTimeout(i),i=window.setTimeout(t,10)})}.bind(this));var p=e.closest("form");if(null!==p){var f=elBySel('input[type="submit"]',p);null!==f&&function(e,t){t.addEventListener(WCF_CLICK_EVENT,function(t){if(!t.defaultPrevented)for(var i,n=elBySelAll("input, select",e),a=0,r=n.length;a<r;a++)if(i=n[a],!i.checkValidity()){t.preventDefault();var s=this.getTabMenu(i.closest(".tabMenuContainer").id);return s.select(elData(i.closest(".tabMenuContent"),"name")),void o.element(i,function(){this.reportValidity()}.bind(i))}}.bind(this))}.bind(this)(e,f)}}},_selectErroneousTabs:function(){d.forEach(function(e){var t=!1;e.getContainers().forEach(function(i){!t&&elByClass("formError",i).length&&(t=!0,e.select(i.id))})})},getTabMenu:function(e){return d.get(e)},_scrollEnable:function(e){c=!0,d.forEach(function(t){var i=t.getActiveTab();e?this._rebuildMenuOverflow(i.closest(".menu, .tabMenu")):this.scrollToTab(i)}.bind(this))},_scrollDisable:function(){c=!1},scrollToTab:function(e){if(c){var t=e.closest("ul"),i=t.clientWidth,n=t.scrollLeft,a=t.scrollWidth;if(i!==a){var r=e.offsetLeft,o=!1;r<n&&(o=!0);var s=!1;if(!o){var l=i-(r-n),d=e.clientWidth;null!==e.nextElementSibling&&(s=!0,d+=20),l<d&&(o=!0)}o&&this._scrollMenu(t,r,n,a,i,s)}}},_scrollMenu:function(e,t,i,n,a,r){r?t-=15:t>0&&(t-=15),t=t<0?0:Math.min(t,n-a),i!==t&&(e.classList.add("enableAnimation"),i<t?e.firstElementChild.style.setProperty("margin-left",i-t+"px",""):e.style.setProperty("padding-left",i-t+"px",""),setTimeout(function(){e.classList.remove("enableAnimation"),e.firstElementChild.style.removeProperty("margin-left"),e.style.removeProperty("padding-left"),e.scrollLeft=t},300))},_rebuildMenuOverflow:function(e){if(c){var t=e.clientWidth,i=elBySel("ul",e),n=i.scrollLeft,a=i.scrollWidth,r=n>0,o=elBySel(".tabMenuOverlayLeft",e);r?(null===o&&(o=elCreate("span"),o.className="tabMenuOverlayLeft icon icon24 fa-angle-left",o.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft-~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.insertBefore(o,e.firstChild)),o.classList.add("active")):null!==o&&o.classList.remove("active");var s=t+n<a,l=elBySel(".tabMenuOverlayRight",e);s?(null===l&&(l=elCreate("span"),l.className="tabMenuOverlayRight icon icon24 fa-angle-right",l.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft+~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.appendChild(l)),l.classList.add("active")):null!==l&&l.classList.remove("active")}}}}),define("WoltLabSuite/Core/Ui/FlexibleMenu",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a,r){"use strict";var o=new t,s=new t,l=new t,c=new t;return{setup:function(){null!==elById("mainMenu")&&this.register("mainMenu");var e=elBySel(".navigationHeader");null!==e&&this.register(a.identify(e)),window.addEventListener("resize",this.rebuildAll.bind(this)),i.add("WoltLabSuite/Core/Ui/FlexibleMenu",this.registerTabMenus.bind(this))},register:function(e){var t=elById(e);if(null===t)throw"Expected a valid element id, '"+e+"' does not exist.";if(!o.has(e)){var i=n.childByTag(t,"UL");if(null===i)throw"Expected an <ul> element as child of container '"+e+"'.";o.set(e,t),c.set(e,i),this.rebuild(e)}},registerTabMenus:function(){for(var e=elBySelAll(".tabMenuContainer:not(.jsFlexibleMenuEnabled), .messageTabMenu:not(.jsFlexibleMenuEnabled)"),t=0,i=e.length;t<i;t++){var r=e[t],o=n.childByTag(r,"NAV");null!==o&&(r.classList.add("jsFlexibleMenuEnabled"),this.register(a.identify(o)))}},rebuildAll:function(){o.forEach(function(e,t){this.rebuild(t)}.bind(this))},rebuild:function(t){var i=o.get(t);if(void 0===i)throw"Expected a valid element id, '"+t+"' is unknown.";var d=window.getComputedStyle(i),u=i.parentNode.clientWidth;u-=a.styleAsInt(d,"margin-left"),u-=a.styleAsInt(d,"margin-right");var h=c.get(t),p=n.childrenByTag(h,"LI"),f=s.get(t),m=0;if(void 0!==f){for(var g=0,v=p.length;g<v;g++){var _=p[g];_.classList.contains("dropdown")||elShow(_)}null!==f.parentNode&&(m=a.outerWidth(f))}var b=h.scrollWidth-m,w=[];if(b>u)for(var g=p.length-1;g>=0;g--){var _=p[g];if(!(_.classList.contains("dropdown")||_.classList.contains("active")||_.classList.contains("ui-state-active"))&&(w.push(_),elHide(_),h.scrollWidth<u))break}if(w.length){var y;if(void 0===f){f=elCreate("li"),f.className="dropdown jsFlexibleMenuDropdown";var C=elCreate("a");C.className="icon icon16 fa-list",f.appendChild(C),y=elCreate("ul"),y.classList.add("dropdownMenu"),f.appendChild(y),s.set(t,f),l.set(t,y),r.init(C)}else y=l.get(t);null===f.parentNode&&h.appendChild(f);var E=document.createDocumentFragment(),L=this;w.forEach(function(i){var n=elCreate("li");n.innerHTML=i.innerHTML,n.addEventListener(WCF_CLICK_EVENT,function(n){n.preventDefault(),e.triggerEvent(elBySel("a",i),WCF_CLICK_EVENT),setTimeout(function(){L.rebuild(t)},59)}.bind(this)),E.appendChild(n)}),y.innerHTML="",y.appendChild(E)}else void 0!==f&&null!==f.parentNode&&elRemove(f)}}}),define("WoltLabSuite/Core/Ui/Tooltip",["Environment","Dom/ChangeListener","Ui/Alignment"],function(e,t,i){"use strict";var n=null,a=null,r=null,o=null,s=null,l=null;return{setup:function(){"desktop"===e.platform()&&(l=elCreate("div"),elAttr(l,"id","balloonTooltip"),l.classList.add("balloonTooltip"),l.addEventListener("transitionend",function(){l.classList.contains("active")||["bottom","left","right","top"].forEach(function(e){l.style.removeProperty(e)})}),s=elCreate("span"),elAttr(s,"id","balloonTooltipText"),l.appendChild(s),o=elCreate("span"),o.classList.add("elementPointer"),o.appendChild(elCreate("span")),l.appendChild(o),document.body.appendChild(l),r=elByClass("jsTooltip"),n=this._mouseEnter.bind(this),a=this._mouseLeave.bind(this),this.init(),t.add("WoltLabSuite/Core/Ui/Tooltip",this.init.bind(this)),window.addEventListener("scroll",this._mouseLeave.bind(this)))},init:function(){0!==r.length&&elBySelAll(".jsTooltip",void 0,function(e){e.classList.remove("jsTooltip");var t=elAttr(e,"title").trim();t.length&&(elData(e,"tooltip",t),e.removeAttribute("title"),elAttr(e,"aria-label",t),e.addEventListener("mouseenter",n),e.addEventListener("mouseleave",a),e.addEventListener(WCF_CLICK_EVENT,a))})},_mouseEnter:function(e){var t=e.currentTarget,n=elAttr(t,"title");if(n="string"==typeof n?n.trim():"",""!==n&&(elData(t,"tooltip",n),t.removeAttribute("title")),n=elData(t,"tooltip"),l.style.removeProperty("top"),l.style.removeProperty("left"),!n.length)return void l.classList.remove("active");l.classList.add("active"),s.textContent=n,i.set(l,t,{horizontal:"center",verticalOffset:4,pointer:!0,pointerClassNames:["inverse"],vertical:"top"})},_mouseLeave:function(){l.classList.remove("active")}}}),define("WoltLabSuite/Core/Date/Picker",["DateUtil","Dom/Traverse","Dom/Util","EventHandler","Language","ObjectMap","Dom/ChangeListener","Ui/Alignment","WoltLabSuite/Core/Ui/CloseOverlay"],function(e,t,i,n,a,r,o,s,l){"use strict";var c=!1,d=0,u=!1,h=new r,p=null,f=0,m=0,g=[],v=null,_=null,b=null,w=null,y=null,C=null,E=null,L=null,S=null,A=null,I=null,D={init:function(){this._setup();for(var t=elBySelAll('input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)'),i=new Date,n=0,r=t.length;n<r;n++){var o=t[n];o.classList.add("inputDatePicker"),o.readOnly=!0;var s="datetime"===elAttr(o,"type"),l=s&&elDataBool(o,"time-only"),c=elDataBool(o,"disable-clear"),d=s&&elDataBool(o,"ignore-timezone"),u=o.classList.contains("birthday");elData(o,"is-date-time",s),elData(o,"is-time-only",l);var p=null,f=elAttr(o,"value"),m=/^\d+-\d+-\d+$/.test(f);if(elAttr(o,"value")){if(l){p=new Date;var g=f.split(":");p.setHours(g[0],g[1])}else{if(d||u||m){var v=new Date(f).getTimezoneOffset(),_=v>0?"-":"+";v=Math.abs(v);var b=Math.floor(v/60).toString(),w=(v%60).toString();_+=2===b.length?b:"0"+b,_+=":",_+=2===w.length?w:"0"+w,
-u||m?f+="T00:00:00"+_:f=f.replace(/[+-][0-9]{2}:[0-9]{2}$/,_)}p=new Date(f)}var y=p.getTime();if(isNaN(y))f="";else{elData(o,"value",y);f=e[l?"formatTime":"formatDate"+(s?"Time":"")](p)}}var C=0===f.length;if(u?(elData(o,"min-date","120"),elData(o,"max-date",(new Date).getFullYear()+"-12-31")):(o.min&&elData(o,"min-date",o.min),o.max&&elData(o,"max-date",o.max)),this._initDateRange(o,i,!0),this._initDateRange(o,i,!1),elData(o,"min-date")===elData(o,"max-date"))throw new Error("Minimum and maximum date cannot be the same (element id '"+o.id+"').");o.type="text",o.value=f,elData(o,"empty",C),elData(o,"placeholder")&&elAttr(o,"placeholder",elData(o,"placeholder"));var E=elCreate("input");if(E.id=o.id+"DatePicker",E.name=o.name,E.type="hidden",null!==p&&(E.value=l?e.format(p,"H:i"):d?e.format(p,"Y-m-dTH:i:s"):e.format(p,s?"c":"Y-m-d")),o.parentNode.insertBefore(E,o),o.removeAttribute("name"),o.addEventListener(WCF_CLICK_EVENT,A),!o.disabled){var L=elCreate("div");L.className="inputAddon";var S=elCreate("a");S.className="inputSuffix button jsTooltip",S.href="#",elAttr(S,"role","button"),elAttr(S,"tabindex","0"),elAttr(S,"title",a.get("wcf.date.datePicker")),elAttr(S,"aria-label",a.get("wcf.date.datePicker")),elAttr(S,"aria-haspopup",!0),elAttr(S,"aria-expanded",!1),S.addEventListener(WCF_CLICK_EVENT,A),L.appendChild(S);var I=elCreate("span");I.className="icon icon16 fa-calendar",S.appendChild(I),o.parentNode.insertBefore(L,o),L.insertBefore(o,S),c||(S=elCreate("a"),S.className="inputSuffix button",S.addEventListener(WCF_CLICK_EVENT,this.clear.bind(this,o)),C&&S.style.setProperty("visibility","hidden",""),L.appendChild(S),I=elCreate("span"),I.className="icon icon16 fa-times",S.appendChild(I))}for(var D=!1,x=["tiny","short","medium","long"],T=0;T<4;T++)o.classList.contains(x[T])&&(D=!0);D||o.classList.add("short"),h.set(o,{clearButton:S,shadow:E,disableClear:c,isDateTime:s,isEmpty:C,isTimeOnly:l,ignoreTimezone:d,onClose:null})}},_initDateRange:function(e,t,i){var n="data-"+(i?"min":"max")+"-date",a=e.hasAttribute(n)?elAttr(e,n).trim():"";if(a.match(/^(\d{4})-(\d{2})-(\d{2})$/))a=new Date(a).getTime();else if("now"===a)a=t.getTime();else if(a.match(/^\d{1,3}$/)){var r=new Date(t.getTime());r.setFullYear(r.getFullYear()+~~a*(i?-1:1)),a=r.getTime()}else if(a.match(/^datePicker-(.+)$/)){if(a=RegExp.$1,null===elById(a))throw new Error("Reference date picker identified by '"+a+"' does not exists (element id: '"+e.id+"').")}else a=/^\d{4}\-\d{2}\-\d{2}T/.test(a)?new Date(a).getTime():new Date(i?1902:2038,0,1).getTime();elAttr(e,n,a)},_setup:function(){c||(c=!0,d=~~a.get("wcf.date.firstDayOfTheWeek"),A=this._open.bind(this),o.add("WoltLabSuite/Core/Date/Picker",this.init.bind(this)),l.add("WoltLabSuite/Core/Date/Picker",this._close.bind(this)))},_open:function(e){e.preventDefault(),e.stopPropagation(),this._createPicker(),null===I&&(I=this._maintainFocus.bind(this),document.body.addEventListener("focus",I,{capture:!0}));var i="INPUT"===e.currentTarget.nodeName?e.currentTarget:e.currentTarget.previousElementSibling;if(i===p)return void this._close();var n=t.parentByClass(i,"dialogContent");null!==n&&(elDataBool(n,"has-datepicker-scroll-listener")||(n.addEventListener("scroll",this._onDialogScroll.bind(this)),elData(n,"has-datepicker-scroll-listener",1))),p=i;var a,r=h.get(p),o=elData(p,"value");o?(a=new Date(+o),"Invalid Date"===a.toString()&&(a=new Date)):a=new Date,m=elData(p,"min-date"),m.match(/^datePicker-(.+)$/)&&(m=elData(elById(RegExp.$1),"value")),m=new Date(+m),m.getTime()>a.getTime()&&(a=m),f=elData(p,"max-date"),f.match(/^datePicker-(.+)$/)&&(f=elData(elById(RegExp.$1),"value")),f=new Date(+f),r.isDateTime?(_.value=a.getHours(),b.value=a.getMinutes(),S.classList.add("datePickerTime")):S.classList.remove("datePickerTime"),S.classList[r.isTimeOnly?"add":"remove"]("datePickerTimeOnly"),this._renderPicker(a.getDate(),a.getMonth(),a.getFullYear()),s.set(S,p),elAttr(p.nextElementSibling,"aria-expanded",!0),u=!1},_close:function(){if(null!==S&&S.classList.contains("active")){S.classList.remove("active");var e=h.get(p);"function"==typeof e.onClose&&e.onClose(),n.fire("WoltLabSuite/Core/Date/Picker","close",{element:p}),elAttr(p.nextElementSibling,"aria-expanded",!1),p=null,m=0,f=0}},_onDialogScroll:function(e){if(null!==p){var t=e.currentTarget,n=i.offset(p),a=i.offset(t);n.top+p.clientHeight<=a.top?this._close():n.top>=a.top+t.offsetHeight?this._close():n.left<=a.left?this._close():n.left>=a.left+t.offsetWidth?this._close():s.set(S,p)}},_renderPicker:function(e,t,i){this._renderGrid(e,t,i);for(var n="",a=m.getFullYear(),r=f.getFullYear();a<=r;a++)n+='<option value="'+a+'">'+a+"</option>";L.innerHTML=n,L.value=i,w.value=t,S.classList.add("active")},_renderGrid:function(t,i,n){var a,r,o=void 0!==t,s=void 0!==i;if(t=~~t||~~elData(v,"day"),i=~~i,n=~~n,s||n){var l=0!==n,c=document.createDocumentFragment();c.appendChild(v),s||(i=~~elData(v,"month")),n=n||~~elData(v,"year");var u=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-"+("0"+t.toString()).slice(-2));for(u<m?(n=m.getFullYear(),i=m.getMonth(),t=m.getDate(),w.value=i,L.value=n,l=!0):u>f&&(n=f.getFullYear(),i=f.getMonth(),t=f.getDate(),w.value=i,L.value=n,l=!0),u=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");u.getDay()!==d;)u.setDate(u.getDate()-1);elShow(g[35].parentNode);var h,p=new Date(m.getFullYear(),m.getMonth(),m.getDate());for(r=0;r<42;r++){if(35===r&&u.getMonth()!==i){elHide(g[35].parentNode);break}a=g[r],a.textContent=u.getDate(),h=u.getMonth()===i,h&&(u<p?h=!1:u>f&&(h=!1)),a.classList[h?"remove":"add"]("otherMonth"),h&&(a.href="#",elAttr(a,"role","button"),elAttr(a,"tabindex","0"),elAttr(a,"title",e.formatDate(u)),elAttr(a,"aria-label",e.formatDate(u))),u.setDate(u.getDate()+1)}if(elData(v,"month",i),elData(v,"year",n),S.insertBefore(c,E),!o&&(u=new Date(n,i,t),u.getDate()!==t)){for(;u.getMonth()!==i;)u.setDate(u.getDate()-1);t=u.getDate()}if(l){for(r=0;r<12;r++){var _=w.children[r];_.disabled=n===m.getFullYear()&&_.value<m.getMonth()||n===f.getFullYear()&&_.value>f.getMonth()}var b=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");b.setMonth(b.getMonth()+1),y.classList[b<f?"add":"remove"]("active");var A=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");A.setDate(A.getDate()-1),C.classList[A>m?"add":"remove"]("active")}}if(t){for(r=0;r<35;r++)a=g[r],a.classList[a.classList.contains("otherMonth")||~~a.textContent!==t?"remove":"add"]("active");elData(v,"day",t)}this._formatValue()},_formatValue:function(){var e,t=h.get(p);"true"!==elData(p,"empty")&&(e=t.isDateTime?new Date(elData(v,"year"),elData(v,"month"),elData(v,"day"),_.value,b.value):new Date(elData(v,"year"),elData(v,"month"),elData(v,"day")),this.setDate(p,e))},_createPicker:function(){if(null===S){S=elCreate("div"),S.className="datePicker",S.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()});var t=elCreate("header");S.appendChild(t),C=elCreate("a"),C.className="previous jsTooltip",C.href="#",elAttr(C,"role","button"),elAttr(C,"tabindex","0"),elAttr(C,"title",a.get("wcf.date.datePicker.previousMonth")),elAttr(C,"aria-label",a.get("wcf.date.datePicker.previousMonth")),C.innerHTML='<span class="icon icon16 fa-arrow-left"></span>',C.addEventListener(WCF_CLICK_EVENT,this.previousMonth.bind(this)),t.appendChild(C);var i=elCreate("span");t.appendChild(i),w=elCreate("select"),w.className="month jsTooltip",elAttr(w,"title",a.get("wcf.date.datePicker.month")),elAttr(w,"aria-label",a.get("wcf.date.datePicker.month")),w.addEventListener("change",this._changeMonth.bind(this)),i.appendChild(w);var n,r="",o=a.get("__monthsShort");for(n=0;n<12;n++)r+='<option value="'+n+'">'+o[n]+"</option>";w.innerHTML=r,L=elCreate("select"),L.className="year jsTooltip",elAttr(L,"title",a.get("wcf.date.datePicker.year")),elAttr(L,"aria-label",a.get("wcf.date.datePicker.year")),L.addEventListener("change",this._changeYear.bind(this)),i.appendChild(L),y=elCreate("a"),y.className="next jsTooltip",y.href="#",elAttr(y,"role","button"),elAttr(y,"tabindex","0"),elAttr(y,"title",a.get("wcf.date.datePicker.nextMonth")),elAttr(y,"aria-label",a.get("wcf.date.datePicker.nextMonth")),y.innerHTML='<span class="icon icon16 fa-arrow-right"></span>',y.addEventListener(WCF_CLICK_EVENT,this.nextMonth.bind(this)),t.appendChild(y),v=elCreate("ul"),S.appendChild(v);var s=elCreate("li");s.className="weekdays",v.appendChild(s);var l,c=a.get("__daysShort");for(n=0;n<7;n++){var u=n+d;u>6&&(u-=7),l=elCreate("span"),l.textContent=c[u],s.appendChild(l)}var h,p,f=this._click.bind(this);for(n=0;n<6;n++){p=elCreate("li"),v.appendChild(p);for(var m=0;m<7;m++)h=elCreate("a"),h.addEventListener(WCF_CLICK_EVENT,f),g.push(h),p.appendChild(h)}E=elCreate("footer"),S.appendChild(E),_=elCreate("select"),_.className="hour",elAttr(_,"title",a.get("wcf.date.datePicker.hour")),elAttr(_,"aria-label",a.get("wcf.date.datePicker.hour")),_.addEventListener("change",this._formatValue.bind(this));var A="",I=new Date(2e3,0,1),D=a.get("wcf.date.timeFormat").replace(/:/,"").replace(/[isu]/g,"");for(n=0;n<24;n++)I.setHours(n),A+='<option value="'+n+'">'+e.format(I,D)+"</option>";for(_.innerHTML=A,E.appendChild(_),E.appendChild(document.createTextNode(" : ")),b=elCreate("select"),b.className="minute",elAttr(b,"title",a.get("wcf.date.datePicker.minute")),elAttr(b,"aria-label",a.get("wcf.date.datePicker.minute")),b.addEventListener("change",this._formatValue.bind(this)),A="",n=0;n<60;n++)A+='<option value="'+n+'">'+(n<10?"0"+n.toString():n)+"</option>";b.innerHTML=A,E.appendChild(b),document.body.appendChild(S)}},previousMonth:function(e){e.preventDefault(),"0"===w.value?(w.value=11,L.value=~~L.value-1):w.value=~~w.value-1,this._renderGrid(void 0,w.value,L.value)},nextMonth:function(e){e.preventDefault(),"11"===w.value?(w.value=0,L.value=1+~~L.value):w.value=1+~~w.value,this._renderGrid(void 0,w.value,L.value)},_changeMonth:function(e){this._renderGrid(void 0,e.currentTarget.value)},_changeYear:function(e){this._renderGrid(void 0,void 0,e.currentTarget.value)},_click:function(e){if(e.preventDefault(),!e.currentTarget.classList.contains("otherMonth")){elData(p,"empty",!1),this._renderGrid(e.currentTarget.textContent);h.get(p).isDateTime||this._close()}},getDate:function(e){return e=this._getElement(e),e.hasAttribute("data-value")?new Date(+elData(e,"value")):null},setDate:function(t,i){t=this._getElement(t);var n=h.get(t);elData(t,"value",i.getTime());var a,r="";n.isDateTime?n.isTimeOnly?(a=e.formatTime(i),r="H:i"):n.ignoreTimezone?(a=e.formatDateTime(i),r="Y-m-dTH:i:s"):(a=e.formatDateTime(i),r="c"):(a=e.formatDate(i),r="Y-m-d"),t.value=a,n.shadow.value=e.format(i,r),n.disableClear||n.clearButton.style.removeProperty("visibility")},getValue:function(e){e=this._getElement(e);var t=h.get(e);return t?t.shadow.value:""},clear:function(e){e=this._getElement(e);var t=h.get(e);e.removeAttribute("data-value"),e.value="",t.disableClear||t.clearButton.style.setProperty("visibility","hidden",""),t.isEmpty=!0,t.shadow.value=""},destroy:function(e){e=this._getElement(e);var t=h.get(e),i=e.parentNode;i.parentNode.insertBefore(e,i),elRemove(i),elAttr(e,"type","date"+(t.isDateTime?"time":"")),e.name=t.shadow.name,e.value=t.shadow.value,e.removeAttribute("data-value"),e.removeEventListener(WCF_CLICK_EVENT,A),elRemove(t.shadow),e.classList.remove("inputDatePicker"),e.readOnly=!1,h.delete(e)},setCloseCallback:function(e,t){e=this._getElement(e),h.get(e).onClose=t},_getElement:function(e){if("string"==typeof e&&(e=elById(e)),!(e instanceof Element&&e.classList.contains("inputDatePicker")&&h.has(e)))throw new Error("Expected a valid date picker input element or id.");return e},_maintainFocus:function(e){null!==S&&S.classList.contains("active")&&(S.contains(e.target)?u=!0:u?(p.nextElementSibling.focus(),u=!1):elBySel(".previous",S).focus())}};return window.__wcf_bc_datePicker=D,D}),define("WoltLabSuite/Core/Ui/Page/Action",["Dictionary","Dom/Util"],function(e,t){"use strict";var i=new e,n=null,a=!1;return{setup:function(){a=!0,n=elCreate("ul"),n.className="pageAction",document.body.appendChild(n)},add:function(e,r,o){!1===a&&this.setup();var s=elCreate("li");if(r.classList.add("button"),r.classList.add("buttonPrimary"),s.appendChild(r),elAttr(s,"aria-hidden","toTop"===e?"true":"false"),elData(s,"name",e),"toTop"===e)s.className="toTop initiallyHidden",n.appendChild(s);else{var l=null;o&&void 0!==(l=i.get(o))&&(l=l.parentNode),null===l&&n.childElementCount&&(l=n.children[0]),null===l?t.prepend(s,n):n.insertBefore(s,l)}i.set(e,r),this._renderContainer()},has:function(e){return i.has(e)},get:function(e){return i.get(e)},remove:function(e){var t=i.get(e);if(void 0!==t){var a=t.parentNode;a.addEventListener("animationend",function(){try{n.removeChild(a),i.delete(e)}catch(e){}}),this.hide(e)}},hide:function(e){var t=i.get(e);t&&(elAttr(t.parentNode,"aria-hidden","true"),this._renderContainer())},show:function(e){var t=i.get(e);t&&(t.parentNode.classList.contains("initiallyHidden")&&t.parentNode.classList.remove("initiallyHidden"),elAttr(t.parentNode,"aria-hidden","false"),this._renderContainer())},_renderContainer:function(){var e=!1;if(n.childElementCount)for(var t=0,i=n.childElementCount;t<i;t++)if("false"===elAttr(n.children[t],"aria-hidden")){e=!0;break}n.classList[e?"add":"remove"]("active")}}}),define("WoltLabSuite/Core/Ui/Page/JumpToTop",["Environment","Language","./Action"],function(e,t,i){"use strict";function n(){this.init()}return n.prototype={init:function(){if("desktop"===e.platform()){this._callbackScrollEnd=this._afterScroll.bind(this),this._timeoutScroll=null;var n=elCreate("a");n.className="jsTooltip",n.href="#",elAttr(n,"title",t.get("wcf.global.scrollUp")),elAttr(n,"aria-hidden","true"),n.innerHTML='<span class="icon icon32 fa-angle-up"></span>',n.addEventListener(WCF_CLICK_EVENT,this._jump.bind(this)),i.add("toTop",n),window.addEventListener("scroll",this._scroll.bind(this)),this._afterScroll()}},_jump:function(e){e.preventDefault(),elById("top").scrollIntoView({behavior:"smooth"})},_scroll:function(){null!==this._timeoutScroll&&window.clearTimeout(this._timeoutScroll),this._timeoutScroll=window.setTimeout(this._callbackScrollEnd,100)},_afterScroll:function(){this._timeoutScroll=null,i[window.pageYOffset>=300?"show":"hide"]("toTop")}},n}),define("WoltLabSuite/Core/Bootstrap",["favico","enquire","perfect-scrollbar","WoltLabSuite/Core/Date/Time/Relative","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Mobile","WoltLabSuite/Core/Ui/TabMenu","WoltLabSuite/Core/Ui/FlexibleMenu","Ui/Dialog","WoltLabSuite/Core/Ui/Tooltip","WoltLabSuite/Core/Language","WoltLabSuite/Core/Environment","WoltLabSuite/Core/Date/Picker","EventHandler","Core","WoltLabSuite/Core/Ui/Page/JumpToTop","Devtools","Dom/ChangeListener"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p,f,m,g,v){"use strict";return window.Favico=e,window.enquire=t,null==window.WCF&&(window.WCF={}),null==window.WCF.Language&&(window.WCF.Language={}),window.WCF.Language.get=d.get,window.WCF.Language.add=d.add,window.WCF.Language.addObject=d.addObject,window.__wcf_bc_eventHandler=p,{setup:function(e){e=f.extend({enableMobileMenu:!0},e),window.ENABLE_DEVELOPER_TOOLS&&g._internal_.enable(),u.setup(),n.setup(),h.init(),a.setup(),r.setup({enableMobileMenu:e.enableMobileMenu}),o.setup(),l.setup(),c.setup();for(var t=elBySelAll("form[method=get]"),i=0,s=t.length;i<s;i++)t[i].setAttribute("method","post");"microsoft"===u.browser()&&(window.onbeforeunload=function(){});var d=0;d=window.setInterval(function(){"function"==typeof window.jQuery&&(window.clearInterval(d),window.jQuery(function(){new m}),window.jQuery.holdReady(!1))},20),this._initA11y(),v.add("WoltLabSuite/Core/Bootstrap",this._initA11y.bind(this))},_initA11y:function(){elBySelAll("nav:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")}),elBySelAll("article:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")})}}}),define("WoltLabSuite/Core/Controller/Style/Changer",["Ajax","Language","Ui/Dialog"],function(e,t,i){"use strict";return{setup:function(){elBySelAll(".jsButtonStyleChanger",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this.showDialog.bind(this))}.bind(this))},showDialog:function(e){e.preventDefault(),i.open(this)},_dialogSetup:function(){return{id:"styleChanger",options:{disableContentPadding:!0,title:t.get("wcf.style.changeStyle")},source:{data:{actionName:"getStyleChooser",className:"wcf\\data\\style\\StyleAction"},after:function(e){for(var t=elBySelAll(".styleList > li",e),i=0,n=t.length;i<n;i++){var a=t[i];a.classList.add("pointer"),a.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}}.bind(this)}}},_click:function(t){t.preventDefault(),e.apiOnce({data:{actionName:"changeStyle",className:"wcf\\data\\style\\StyleAction",objectIDs:[elData(t.currentTarget,"style-id")]},success:function(){window.location.reload()}})}}}),define("WoltLabSuite/Core/Controller/Popover",["Ajax","Dictionary","Environment","Dom/ChangeListener","Dom/Util","Ui/Alignment"],function(e,t,i,n,a,r){"use strict";var o=null,s=new t,l=new t,c=new t,d=null,u=!1,h=null,p=null,f=null,m=null,g=null,v=null,_=null,b=null;return{_setup:function(){if(null===f){f=elCreate("div"),f.className="popover forceHide",m=elCreate("div"),m.className="popoverContent",f.appendChild(m);var e=elCreate("span");e.className="elementPointer",e.appendChild(elCreate("span")),f.appendChild(e),document.body.appendChild(f),g=this._hide.bind(this),_=this._mouseEnter.bind(this),b=this._mouseLeave.bind(this),f.addEventListener("mouseenter",this._popoverMouseEnter.bind(this)),f.addEventListener("mouseleave",b),f.addEventListener("animationend",this._clearContent.bind(this)),window.addEventListener("beforeunload",function(){u=!0,null!==h&&window.clearTimeout(h),this._hide(!0)}.bind(this)),n.add("WoltLabSuite/Core/Controller/Popover",this._init.bind(this))}},init:function(e){"desktop"===i.platform()&&(e.attributeName=e.attributeName||"data-object-id",e.legacy=!0===e.legacy,this._setup(),c.has(e.identifier)||(c.set(e.identifier,{attributeName:e.attributeName,elements:e.legacy?e.className:elByClass(e.className),legacy:e.legacy,loadCallback:e.loadCallback}),this._init(e.identifier)))},_init:function(e){"string"==typeof e&&e.length?this._initElements(c.get(e),e):c.forEach(this._initElements.bind(this))},_initElements:function(e,t){for(var i=e.legacy?elBySelAll(e.elements):e.elements,n=0,r=i.length;n<r;n++){var o=i[n],c=a.identify(o);if(s.has(c))return;if(null!==o.closest(".popover"))return void s.set(c,{content:null,state:0});var d=e.legacy?c:~~o.getAttribute(e.attributeName);if(0!==d){o.addEventListener("mouseenter",_),o.addEventListener("mouseleave",b),"A"===o.nodeName&&elAttr(o,"href")&&o.addEventListener(WCF_CLICK_EVENT,g);var u=t+"-"+d;elData(o,"cache-id",u),l.set(c,{element:o,identifier:t,objectId:d}),s.has(u)||s.set(t+"-"+d,{content:null,state:0})}}},setContent:function(e,t,i){var n=e+"-"+t,r=s.get(n);if(void 0===r)throw new Error("Unable to find element for object id '"+t+"' (identifier: '"+e+"').");var c=a.createFragmentFromHtml(i);if(c.childElementCount||(c=a.createFragmentFromHtml("<p>"+i+"</p>")),r.content=c,r.state=2,o){var d=l.get(o).element;elData(d,"cache-id")===n&&this._show()}},_mouseEnter:function(e){if(!u){null!==h&&(window.clearTimeout(h),h=null);var t=a.identify(e.currentTarget);o===t&&null!==p&&(window.clearTimeout(p),p=null),d=t,h=window.setTimeout(function(){h=null,d===t&&this._show()}.bind(this),800)}},_mouseLeave:function(){d=null,null===p&&(null===v&&(v=this._hide.bind(this)),null!==p&&window.clearTimeout(p),p=window.setTimeout(v,500))},_popoverMouseEnter:function(){null!==p&&(window.clearTimeout(p),p=null)},_show:function(){null!==p&&(window.clearTimeout(p),p=null);var e=!1;f.classList.contains("active")?o!==d&&(this._hide(),e=!0):m.childElementCount&&(e=!0),e&&(f.classList.add("forceHide"),f.offsetTop,this._clearContent(),f.classList.remove("forceHide")),o=d;var t=l.get(o);if(void 0!==t){var i=s.get(elData(t.element,"cache-id"));2===i.state?(m.appendChild(i.content),this._rebuild(o)):0===i.state&&(i.state=1,c.get(t.identifier).loadCallback(t.objectId,this))}},_hide:function(){null!==p&&(window.clearTimeout(p),p=null),f.classList.remove("active")},_clearContent:function(){if(o&&m.childElementCount&&!f.classList.contains("active"))for(var e=s.get(elData(l.get(o).element,"cache-id"));m.childNodes.length;)e.content.appendChild(m.childNodes[0])},_rebuild:function(){f.classList.contains("active")||(f.classList.remove("forceHide"),f.classList.add("active"),r.set(f,l.get(o).element,{pointer:!0,vertical:"top"}))},_ajaxSetup:function(){return{silent:!0}},ajaxApi:function(t,i,n){if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'success'.");e.api(this,t,i,n)}}}),define("WoltLabSuite/Core/Ui/User/Ignore",["List","Dom/ChangeListener"],function(e,t){"use strict";var i=elByClass("ignoredUserMessage"),n=null,a=new e;return{init:function(){n=this._removeClass.bind(this),this._rebuild(),t.add("WoltLabSuite/Core/Ui/User/Ignore",this._rebuild.bind(this))},_rebuild:function(){for(var e,t=0,r=i.length;t<r;t++)e=i[t],a.has(e)||(e.addEventListener(WCF_CLICK_EVENT,n),a.add(e))},_removeClass:function(e){e.preventDefault();var t=e.currentTarget;t.classList.remove("ignoredUserMessage"),t.removeEventListener(WCF_CLICK_EVENT,n),a.delete(t),window.getSelection().removeAllRanges()}}}),define("WoltLabSuite/Core/Ui/Page/Header/Menu",["Environment","Language","Ui/Screen"],function(e,t,i){"use strict";var n,a,r,o,s=!1,l=0,c=[],d=[];return{init:function(){if(o=elBySel(".mainMenu .boxMenu"),null===(r=o&&o.childElementCount?o.children[0]:null))throw new Error("Unable to find the menu.");i.on("screen-lg",{enable:this._enable.bind(this),disable:this._disable.bind(this),setup:this._setup.bind(this)})},_enable:function(){s=!0,"safari"===e.browser()?window.setTimeout(this._rebuildVisibility.bind(this),1e3):(this._rebuildVisibility(),window.setTimeout(this._rebuildVisibility.bind(this),1e3))},_disable:function(){s=!1},_showNext:function(e){if(e.preventDefault(),d.length){var t=d.slice(0,3).pop();this._setMarginLeft(o.clientWidth-(t.offsetLeft+t.clientWidth)),o.lastElementChild===t&&n.classList.remove("active"),a.classList.add("active")}},_showPrevious:function(e){if(e.preventDefault(),c.length){var t=c.slice(-3)[0];this._setMarginLeft(-1*t.offsetLeft),o.firstElementChild===t&&a.classList.remove("active"),n.classList.add("active")}},_setMarginLeft:function(e){l=Math.min(l+e,0),r.style.setProperty("margin-left",l+"px","")},_rebuildVisibility:function(){if(s){c=[],d=[];var e=o.clientWidth;if(o.scrollWidth>e||l<0)for(var t,i=0,r=o.childElementCount;i<r;i++){t=o.children[i];var u=t.offsetLeft;u<0?c.push(t):u+t.clientWidth>e&&d.push(t)}a.classList[c.length?"add":"remove"]("active"),n.classList[d.length?"add":"remove"]("active")}},_setup:function(){this._setupOverflow(),this._setupA11y()},_setupOverflow:function(){n=elCreate("a"),n.className="mainMenuShowNext",n.href="#",n.innerHTML='<span class="icon icon32 fa-angle-right"></span>',elAttr(n,"aria-hidden","true"),n.addEventListener(WCF_CLICK_EVENT,this._showNext.bind(this)),o.parentNode.appendChild(n),a=elCreate("a"),a.className="mainMenuShowPrevious",a.href="#",a.innerHTML='<span class="icon icon32 fa-angle-left"></span>',elAttr(a,"aria-hidden","true"),a.addEventListener(WCF_CLICK_EVENT,this._showPrevious.bind(this)),o.parentNode.insertBefore(a,o.parentNode.firstChild);var e=this._rebuildVisibility.bind(this);r.addEventListener("transitionend",e),window.addEventListener("resize",function(){r.style.setProperty("margin-left","0px",""),l=0,e()}),this._enable()},_setupA11y:function(){elBySelAll(".boxMenuHasChildren",o,function(e){var i=!1,n=elBySel(".boxMenuLink",e);n&&(elAttr(n,"aria-haspopup",!0),elAttr(n,"aria-expanded",i));var a=elCreate("button");a.className="visuallyHidden",a.tabindex=0,elAttr(a,"role","button"),elAttr(a,"aria-label",t.get("wcf.global.button.showMenu")),e.insertBefore(a,n.nextSibling),a.addEventListener(WCF_CLICK_EVENT,function(){i=!i,elAttr(n,"aria-expanded",i),elAttr(a,"aria-label",i?t.get("wcf.global.button.hideMenu"):t.get("wcf.global.button.showMenu"))})}.bind(this))}}}),define("WoltLabSuite/Core/BootstrapFrontend",["WoltLabSuite/Core/BackgroundQueue","WoltLabSuite/Core/Bootstrap","WoltLabSuite/Core/Controller/Style/Changer","WoltLabSuite/Core/Controller/Popover","WoltLabSuite/Core/Ui/User/Ignore","WoltLabSuite/Core/Ui/Page/Header/Menu"],function(e,t,i,n,a,r){"use strict";return{setup:function(n){n.backgroundQueue.url=WSC_API_URL+n.backgroundQueue.url.substr(WCF_PATH.length),t.setup(),r.init(),n.styleChanger&&i.setup(),n.enableUserPopover&&this._initUserPopover(),e.setUrl(n.backgroundQueue.url),(Math.random()<.1||n.backgroundQueue.force)&&e.invoke(),a.init()},_initUserPopover:function(){n.init({attributeName:"data-user-id",className:"userLink",identifier:"com.woltlab.wcf.user",loadCallback:function(e,t){var i=function(i){t.setContent("com.woltlab.wcf.user",e,i.returnValues.template)};t.ajaxApi({actionName:"getUserProfile",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[e]},i,i)}})}}}),define("WoltLabSuite/Core/Clipboard",["Environment","Ui/Screen"],function(e,t){"use strict";return{copyTextToClipboard:function(i){if(navigator.clipboard)return navigator.clipboard.writeText(i);if(window.getSelection){var n=elCreate("textarea");n.contentEditable=!0,n.readOnly=!1;var a=!1;if("ios"===e.platform()){a=!0,t.scrollDisable();var r=~~(window.innerHeight/4)+window.pageYOffset;n.style.cssText="font-size: 16px; position: absolute; left: 1px; top: "+r+"px; width: 50px; height: 50px; overflow: hidden;border: 5px solid red;"}else n.style.cssText="position: absolute; left: -9999px; top: -9999px; width: 0; height: 0;";document.body.appendChild(n);try{n.value=i;var o=document.createRange();o.selectNodeContents(n);var s=window.getSelection();return s.removeAllRanges(),s.addRange(o),n.setSelectionRange(0,999999),document.execCommand("copy")?Promise.resolve():Promise.reject(new Error("execCommand('copy') failed"))}finally{elRemove(n),a&&t.scrollEnable()}}return Promise.reject(new Error("Neither navigator.clipboard, nor window.getSelection is supported."))},copyElementTextToClipboard:function(e){return this.copyTextToClipboard(e.textContent)}}}),define("WoltLabSuite/Core/ColorUtil",[],function(){"use strict";var e={hsvToRgb:function(e,t,i){var n,a,r,o,s,l={r:0,g:0,b:0};if(n=Math.floor(e/60),a=e/60-n,t/=100,i/=100,r=i*(1-t),o=i*(1-t*a),s=i*(1-t*(1-a)),0==t)l.r=l.g=l.b=i;else switch(n){case 1:l.r=o,l.g=i,l.b=r;break;case 2:l.r=r,l.g=i,l.b=s;break;case 3:l.r=r,l.g=o,l.b=i;break;case 4:l.r=s,l.g=r,l.b=i;break;case 5:l.r=i,l.g=r,l.b=o;break;case 0:case 6:l.r=i,l.g=s,l.b=r}return{r:Math.round(255*l.r),g:Math.round(255*l.g),b:Math.round(255*l.b)}},rgbToHsv:function(e,t,i){var n,a,r,o,s,l;if(e/=255,t/=255,i/=255,o=Math.max(Math.max(e,t),i),s=Math.min(Math.min(e,t),i),l=o-s,n=0,o!==s){switch(o){case e:n=(t-i)/l*60;break;case t:n=60*(2+(i-e)/l);break;case i:n=60*(4+(e-t)/l)}n<0&&(n+=360)}return a=0===o?0:l/o,r=o,{h:Math.round(n),s:Math.round(100*a),v:Math.round(100*r)}},hexToRgb:function(e){if(/^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(e)){var t=e.split("");return"#"===t[0]&&t.shift(),3===t.length?{r:parseInt(t[0]+""+t[0],16),g:parseInt(t[1]+""+t[1],16),b:parseInt(t[2]+""+t[2],16)}:{r:parseInt(t[0]+""+t[1],16),g:parseInt(t[2]+""+t[3],16),b:parseInt(t[4]+""+t[5],16)}}return Number.NaN},rgbToHex:function(e,t,i){var n="0123456789ABCDEF";return void 0===t&&e.toString().match(/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/)&&(e=RegExp.$1,t=RegExp.$2,i=RegExp.$3),n.charAt((e-e%16)/16)+""+n.charAt(e%16)+n.charAt((t-t%16)/16)+n.charAt(t%16)+n.charAt((i-i%16)/16)+n.charAt(i%16)}};return window.__wcf_bc_colorUtil=e,e}),define("WoltLabSuite/Core/FileUtil",["Dictionary","StringUtil"],function(e,t){"use strict";var i=e.fromObject({zip:"archive",rar:"archive",tar:"archive",gz:"archive",mp3:"audio",ogg:"audio",wav:"audio",php:"code",html:"code",htm:"code",tpl:"code",js:"code",xls:"excel",ods:"excel",xlsx:"excel",gif:"image",jpg:"image",jpeg:"image",png:"image",bmp:"image",webp:"image",avi:"video",wmv:"video",mov:"video",mp4:"video",mpg:"video",mpeg:"video",flv:"video",pdf:"pdf",ppt:"powerpoint",pptx:"powerpoint",txt:"text",doc:"word",docx:"word",odt:"word"}),n=e.fromObject({"application/zip":"zip","application/x-zip-compressed":"zip","application/rar":"rar","application/vnd.rar":"rar","application/x-rar-compressed":"rar","application/x-tar":"tar","application/x-gzip":"gz","application/gzip":"gz","audio/mpeg":"mp3","audio/mp3":"mp3","audio/ogg":"ogg","audio/x-wav":"wav","application/x-php":"php","text/html":"html","application/javascript":"js","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","image/gif":"gif","image/jpeg":"jpg","image/png":"png","image/x-ms-bmp":"bmp","image/bmp":"bmp","image/webp":"webp","video/x-msvideo":"avi","video/x-ms-wmv":"wmv","video/quicktime":"mov","video/mp4":"mp4","video/mpeg":"mpg","video/x-flv":"flv","application/pdf":"pdf","application/vnd.ms-powerpoint":"ppt","application/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","text/plain":"txt","application/msword":"doc","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application/vnd.oasis.opendocument.text":"odt"});return{formatFilesize:function(e,i){void 0===i&&(i=2);var n="Byte";return e>=1e3&&(e/=1e3,n="kB"),e>=1e3&&(e/=1e3,n="MB"),e>=1e3&&(e/=1e3,n="GB"),e>=1e3&&(e/=1e3,n="TB"),t.formatNumeric(e,-i)+" "+n},getIconNameByFilename:function(e){var t=e.lastIndexOf(".");if(!1!==t){var n=e.substr(t+1);if(i.has(n))return i.get(n)}return""},getExtensionByMimeType:function(e){return n.has(e)?"."+n.get(e):""},blobToFile:function(e,t){var i=this.getExtensionByMimeType(e.type),n=window.File;try{new n([],"ie11-check")}catch(e){n=function(e,t,i){var n=Blob.call(this,e,i);return n.name=t,n.lastModifiedDate=new Date,n},n.prototype=Object.create(window.File.prototype)}return new n([e],t+i,{type:e.type})}}}),define("WoltLabSuite/Core/Permission",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if("boolean"!=typeof i)throw new TypeError("Permission value has to be boolean.");t.set(e,i)},addObject:function(e){for(var t in e)objOwns(e,t)&&this.add(t,e[t])},get:function(e){return!!t.has(e)&&t.get(e)}}});var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){function t(e,t,i,n,a){this.type=e,this.content=t,this.alias=i,this.length=0|(n||"").length,this.greedy=!!a}var i=/\blang(?:uage)?-([\w-]+)\b/i,n=0,a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof t?new t(e.type,a.util.encode(e.content),e.alias):Array.isArray(e)?e.map(a.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function e(t,i){var n,r,o=a.util.type(t);switch(i=i||{},o){case"Object":if(r=a.util.objId(t),i[r])return i[r];n={},i[r]=n;for(var s in t)t.hasOwnProperty(s)&&(n[s]=e(t[s],i));return n;case"Array":return r=a.util.objId(t),i[r]?i[r]:(n=[],i[r]=n,t.forEach(function(t,a){n[a]=e(t,i)}),n);default:return t}}},languages:{extend:function(e,t){var i=a.util.clone(a.languages[e]);for(var n in t)i[n]=t[n];return i},insertBefore:function(e,t,i,n){n=n||a.languages;var r=n[e],o={};for(var s in r)if(r.hasOwnProperty(s)){if(s==t)for(var l in i)i.hasOwnProperty(l)&&(o[l]=i[l]);i.hasOwnProperty(s)||(o[s]=r[s])}var c=n[e];return n[e]=o,a.languages.DFS(a.languages,function(t,i){i===c&&t!=e&&(this[t]=o)}),o},DFS:function e(t,i,n,r){r=r||{};var o=a.util.objId
-;for(var s in t)if(t.hasOwnProperty(s)){i.call(t,s,t[s],n||s);var l=t[s],c=a.util.type(l);"Object"!==c||r[o(l)]?"Array"!==c||r[o(l)]||(r[o(l)]=!0,e(l,i,s,r)):(r[o(l)]=!0,e(l,i,null,r))}}},plugins:{},highlightAll:function(e,t){a.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,i){var n={callback:i,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",n);for(var r,o=n.elements||e.querySelectorAll(n.selector),s=0;r=o[s++];)a.highlightElement(r,!0===t,n.callback)},highlightElement:function(t,n,r){for(var o,s="none",l=t;l&&!i.test(l.className);)l=l.parentNode;l&&(s=(l.className.match(i)||[,"none"])[1].toLowerCase(),o=a.languages[s]),t.className=t.className.replace(i,"").replace(/\s+/g," ")+" language-"+s,t.parentNode&&(l=t.parentNode,/pre/i.test(l.nodeName)&&(l.className=l.className.replace(i,"").replace(/\s+/g," ")+" language-"+s));var c=t.textContent,d={element:t,language:s,grammar:o,code:c},u=function(e){d.highlightedCode=e,a.hooks.run("before-insert",d),d.element.innerHTML=d.highlightedCode,a.hooks.run("after-highlight",d),a.hooks.run("complete",d),r&&r.call(d.element)};if(a.hooks.run("before-sanity-check",d),!d.code)return void a.hooks.run("complete",d);if(a.hooks.run("before-highlight",d),!d.grammar)return void u(a.util.encode(d.code));if(n&&e.Worker){var h=new Worker(a.filename);h.onmessage=function(e){u(e.data)},h.postMessage(JSON.stringify({language:d.language,code:d.code,immediateClose:!0}))}else u(a.highlight(d.code,d.grammar,d.language))},highlight:function(e,i,n){var r={code:e,grammar:i,language:n};return a.hooks.run("before-tokenize",r),r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),t.stringify(a.util.encode(r.tokens),r.language)},matchGrammar:function(e,i,n,r,o,s,l){for(var c in n)if(n.hasOwnProperty(c)&&n[c]){if(c==l)return;var d=n[c];d="Array"===a.util.type(d)?d:[d];for(var u=0;u<d.length;++u){var h=d[u],p=h.inside,f=!!h.lookbehind,m=!!h.greedy,g=0,v=h.alias;if(m&&!h.pattern.global){var _=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,_+"g")}h=h.pattern||h;for(var b=r,w=o;b<i.length;w+=i[b].length,++b){var y=i[b];if(i.length>e.length)return;if(!(y instanceof t)){if(m&&b!=i.length-1){h.lastIndex=w;var C=h.exec(e);if(!C)break;for(var E=C.index+(f?C[1].length:0),L=C.index+C[0].length,S=b,A=w,I=i.length;S<I&&(A<L||!i[S].type&&!i[S-1].greedy);++S)A+=i[S].length,E>=A&&(++b,w=A);if(i[b]instanceof t)continue;D=S-b,y=e.slice(w,A),C.index-=w}else{h.lastIndex=0;var C=h.exec(y),D=1}if(C){f&&(g=C[1]?C[1].length:0);var E=C.index+g,C=C[0].slice(g),L=E+C.length,x=y.slice(0,E),T=y.slice(L),B=[b,D];x&&(++b,w+=x.length,B.push(x));var k=new t(c,p?a.tokenize(C,p):C,v,C,m);if(B.push(k),T&&B.push(T),Array.prototype.splice.apply(i,B),1!=D&&a.matchGrammar(e,i,n,b,w,!0,c),s)break}else if(s)break}}}}},tokenize:function(e,t){var i=[e],n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}return a.matchGrammar(e,i,t,0,0,!1),i},hooks:{all:{},add:function(e,t){var i=a.hooks.all;i[e]=i[e]||[],i[e].push(t)},run:function(e,t){var i=a.hooks.all[e];if(i&&i.length)for(var n,r=0;n=i[r++];)n(t)}},Token:t};if(e.Prism=a,t.stringify=function(e,i){if("string"==typeof e)return e;if(Array.isArray(e))return e.map(function(e){return t.stringify(e,i)}).join("");var n={type:e.type,content:t.stringify(e.content,i),tag:"span",classes:["token",e.type],attributes:{},language:i};if(e.alias){var r=Array.isArray(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(n.classes,r)}a.hooks.run("wrap",n);var o=Object.keys(n.attributes).map(function(e){return e+'="'+(n.attributes[e]||"").replace(/"/g,"&quot;")+'"'}).join(" ");return"<"+n.tag+' class="'+n.classes.join(" ")+'"'+(o?" "+o:"")+">"+n.content+"</"+n.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",function(t){var i=JSON.parse(t.data),n=i.language,r=i.code,o=i.immediateClose;e.postMessage(a.highlight(r,a.languages[n],n)),o&&e.close()},!1),a):a;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(a.filename=r.src,a.manual||r.hasAttribute("data-manual")||(a.highlightAutomaticallyCallback=function(){a.manual||a.highlightAll()},"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(a.highlightAutomaticallyCallback):window.setTimeout(a.highlightAutomaticallyCallback,16):document.addEventListener("DOMContentLoaded",a.highlightAutomaticallyCallback))),a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),define("prism/prism",function(){}),window.Prism=window.Prism||{},window.Prism.manual=!0,define("WoltLabSuite/Core/Prism",["prism/prism"],function(){return Prism.wscSplitIntoLines=function(e){function t(){var e=elCreate("span");return elData(e,"number",o++),r.appendChild(e),e}var i,n,a,r=document.createDocumentFragment(),o=1;for(i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT,function(){return NodeFilter.FILTER_ACCEPT},!1),a=t();n=i.nextNode();)n.data.split(/\r?\n/).forEach(function(i,r){var o,s;for(r>=1&&(a.appendChild(document.createTextNode("\n")),a=t()),o=document.createTextNode(i),s=n.parentNode;s!==e;){var l=s.cloneNode(!1);l.appendChild(o),o=l,s=s.parentNode}a.appendChild(o)});return r},Prism}),define("WoltLabSuite/Core/Upload",["AjaxRequest","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse"],function(e,t,i,n,a,r){"use strict";function o(e,i,n){if(n=n||{},void 0===n.className)throw new Error("Missing class name.");if(this._options=t.extend({action:"upload",multiple:!1,name:"__files[]",singleFileRequests:!1,url:"index.php?ajax-upload/&t="+SECURITY_TOKEN},n),this._options.url=t.convertLegacyUrl(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),this._buttonContainer=elById(e),null===this._buttonContainer)throw new Error("Element id '"+e+"' is unknown.");if(this._target=elById(i),null===i)throw new Error("Element id '"+i+"' is unknown.");if(n.multiple&&"UL"!==this._target.nodeName&&"OL"!==this._target.nodeName&&"TBODY"!==this._target.nodeName)throw new Error("Target element has to be list or table body if uploading multiple files is supported.");this._fileElements=[],this._internalFileId=0,this._multiFileUploadIds=[],this._createButton()}return o.prototype={_createButton:function(){this._fileUpload=elCreate("input"),elAttr(this._fileUpload,"type","file"),elAttr(this._fileUpload,"name",this._options.name),this._options.multiple&&elAttr(this._fileUpload,"multiple","true"),this._fileUpload.addEventListener("change",this._upload.bind(this)),this._button=elCreate("p"),this._button.className="button uploadButton",elAttr(this._button,"role","button"),this._fileUpload.addEventListener("focus",function(){this._fileUpload.classList.contains("focus-visible")&&this._button.classList.add("active")}.bind(this)),this._fileUpload.addEventListener("blur",function(){this._button.classList.remove("active")}.bind(this));var e=elCreate("span");e.textContent=n.get("wcf.global.button.upload"),this._button.appendChild(e),a.prepend(this._fileUpload,this._button),this._insertButton(),i.trigger()},_createFileElement:function(e){var t=elCreate("progress");if(elAttr(t,"max",100),"OL"===this._target.nodeName||"UL"===this._target.nodeName){var i=elCreate("li");return i.innerText=e.name,i.appendChild(t),this._target.appendChild(i),i}if("TBODY"===this._target.nodeName)return this._createFileTableRow(e);var n=elCreate("p");return n.appendChild(t),this._target.appendChild(n),n},_createFileElements:function(e){if(e.length){var t=this._fileElements.length;this._fileElements[t]=[];for(var n=0,a=e.length;n<a;n++){var r=e[n],o=this._createFileElement(r);o.classList.contains("uploadFailed")||(elData(o,"filename",r.name),elData(o,"internal-file-id",this._internalFileId++),this._fileElements[t][n]=o)}return i.trigger(),t}return null},_createFileTableRow:function(e){throw new Error("Has to be implemented in subclass.")},_failure:function(e,t,i,n,a){return!0},_getParameters:function(){return{}},_getFormData:function(){return{}},_insertButton:function(){a.prepend(this._button,this._buttonContainer)},_progress:function(e,t){var i=Math.round(t.loaded/t.total*100);for(var n in this._fileElements[e]){var a=elByTag("PROGRESS",this._fileElements[e][n]);1===a.length&&elAttr(a[0],"value",i)}},_removeButton:function(){elRemove(this._button),i.trigger()},_success:function(e,t,i,n,a){},_upload:function(e,t,i){for(var n=r.childrenByClass(this._target,"uploadFailed"),a=0,o=n.length;a<o;a++)elRemove(n[a]);var s=null,l=[];if(t)l.push(t);else if(i){var c="";switch(i.type){case"image/jpeg":c=".jpg";break;case"image/gif":c=".gif";break;case"image/png":c=".png"}l.push({name:"pasted-from-clipboard"+c})}else l=this._fileUpload.files;if(l.length&&this.validateUpload(l))if(this._options.singleFileRequests){s=[];for(var a=0,o=l.length;a<o;a++){var d=this._uploadFiles([l[a]],i);1!==l.length&&this._multiFileUploadIds.push(d),s.push(d)}}else s=this._uploadFiles(l,i);return this._removeButton(),this._createButton(),s},validateUpload:function(e){return!0},_uploadFiles:function(t,i){var n=this._createFileElements(t);if(!this._fileElements[n].length)return null;for(var a=new FormData,r=0,o=t.length;r<o;r++)if(this._fileElements[n][r]){var s=elData(this._fileElements[n][r],"internal-file-id");i?a.append("__files["+s+"]",i,t[r].name):a.append("__files["+s+"]",t[r])}a.append("actionName",this._options.action),a.append("className",this._options.className),"upload"===this._options.action&&a.append("interfaceName","wcf\\data\\IUploadAction");var l=function(e,t){t=t||"";for(var i in e)if("object"==typeof e[i]){var n=0===t.length?i:t+"["+i+"]";l(e[i],n)}else{var r=0===t.length?i:t+"["+i+"]";a.append(r,e[i])}};return l(this._getParameters(),"parameters"),l(this._getFormData()),new e({data:a,contentType:!1,failure:this._failure.bind(this,n),silent:!0,success:this._success.bind(this,n),uploadProgress:this._progress.bind(this,n),url:this._options.url,withCredentials:!0}).sendRequest(),n},hasPendingUploads:function(){for(var e in this._fileElements)for(var t in this._fileElements[e]){var i=elByTag("PROGRESS",this._fileElements[e][t]);if(1===i.length)return!0}return!1},uploadBlob:function(e){return this._upload(null,null,e)},uploadFile:function(e){return this._upload(null,e)}},o}),define("WoltLabSuite/Core/User",[],function(){"use strict";var e,t=!1;return{getLink:function(){return e},init:function(i,n,a){if(t)throw new Error("User has already been initialized.");Object.defineProperty(this,"userId",{value:i,writable:!1}),Object.defineProperty(this,"username",{value:n,writable:!1}),e=a,t=!0}}}),define("WoltLabSuite/Core/Ajax/Jsonp",["Core"],function(e){"use strict";return{send:function(t,i,n,a){if(t="string"==typeof t?t.trim():"",0===t.length)throw new Error("Expected a non-empty string for parameter 'url'.");if("function"!=typeof i)throw new TypeError("Expected a valid callback function for parameter 'success'.");a=e.extend({parameterName:"callback",timeout:10},a||{});var r,o="wcf_jsonp_"+e.getUuid().replace(/-/g,"").substr(0,8),s=window.setTimeout(function(){"function"==typeof n&&n(),window[o]=void 0,elRemove(r)},1e3*(~~a.timeout||10));window[o]=function(){window.clearTimeout(s),i.apply(null,arguments),window[o]=void 0,elRemove(r)},t+=-1===t.indexOf("?")?"?":"&",t+=a.parameterName+"="+o,r=elCreate("script"),r.async=!0,elAttr(r,"src",t),document.head.appendChild(r)}}}),define("WoltLabSuite/Core/Ui/Notification",["Language"],function(e){"use strict";var t=!1,i=null,n=null,a=null,r=null,o=null;return{show:function(s,l,c){t||(this._init(),i="function"==typeof l?l:null,n.className=c||"success",n.textContent=e.get(s||"wcf.global.success"),t=!0,a.classList.add("active"),r=setTimeout(o,2e3))},_init:function(){null===a&&(o=this._hide.bind(this),a=elCreate("div"),a.id="systemNotification",n=elCreate("p"),n.addEventListener(WCF_CLICK_EVENT,o),a.appendChild(n),document.body.appendChild(a))},_hide:function(){clearTimeout(r),a.classList.remove("active"),null!==i&&i(),t=!1}}}),define("prism/prism-meta",[],function(){return{markup:{title:"Markup",file:"markup"},html:{title:"HTML",file:"markup"},xml:{title:"XML",file:"markup"},svg:{title:"SVG",file:"markup"},mathml:{title:"MathML",file:"markup"},css:{title:"CSS",file:"css"},clike:{title:"C-like",file:"clike"},javascript:{title:"JavaScript",file:"javascript"},abap:{title:"ABAP",file:"abap"},abnf:{title:"Augmented Backus–Naur form",file:"abnf"},actionscript:{title:"ActionScript",file:"actionscript"},ada:{title:"Ada",file:"ada"},apacheconf:{title:"Apache Configuration",file:"apacheconf"},apl:{title:"APL",file:"apl"},applescript:{title:"AppleScript",file:"applescript"},arduino:{title:"Arduino",file:"arduino"},arff:{title:"ARFF",file:"arff"},asciidoc:{title:"AsciiDoc",file:"asciidoc"},asm6502:{title:"6502 Assembly",file:"asm6502"},aspnet:{title:"ASP.NET (C#)",file:"aspnet"},autohotkey:{title:"AutoHotkey",file:"autohotkey"},autoit:{title:"AutoIt",file:"autoit"},bash:{title:"Bash",file:"bash"},basic:{title:"BASIC",file:"basic"},batch:{title:"Batch",file:"batch"},bison:{title:"Bison",file:"bison"},bnf:{title:"Backus–Naur form",file:"bnf"},brainfuck:{title:"Brainfuck",file:"brainfuck"},bro:{title:"Bro",file:"bro"},c:{title:"C",file:"c"},csharp:{title:"C#",file:"csharp"},cpp:{title:"C++",file:"cpp"},cil:{title:"CIL",file:"cil"},coffeescript:{title:"CoffeeScript",file:"coffeescript"},cmake:{title:"CMake",file:"cmake"},clojure:{title:"Clojure",file:"clojure"},crystal:{title:"Crystal",file:"crystal"},csp:{title:"Content-Security-Policy",file:"csp"},"css-extras":{title:"CSS Extras",file:"css-extras"},d:{title:"D",file:"d"},dart:{title:"Dart",file:"dart"},diff:{title:"Diff",file:"diff"},django:{title:"Django/Jinja2",file:"django"},docker:{title:"Docker",file:"docker"},ebnf:{title:"Extended Backus–Naur form",file:"ebnf"},eiffel:{title:"Eiffel",file:"eiffel"},ejs:{title:"EJS",file:"ejs"},elixir:{title:"Elixir",file:"elixir"},elm:{title:"Elm",file:"elm"},erb:{title:"ERB",file:"erb"},erlang:{title:"Erlang",file:"erlang"},fsharp:{title:"F#",file:"fsharp"},flow:{title:"Flow",file:"flow"},fortran:{title:"Fortran",file:"fortran"},gcode:{title:"G-code",file:"gcode"},gedcom:{title:"GEDCOM",file:"gedcom"},gherkin:{title:"Gherkin",file:"gherkin"},git:{title:"Git",file:"git"},glsl:{title:"GLSL",file:"glsl"},gml:{title:"GameMaker Language",file:"gml"},go:{title:"Go",file:"go"},graphql:{title:"GraphQL",file:"graphql"},groovy:{title:"Groovy",file:"groovy"},haml:{title:"Haml",file:"haml"},handlebars:{title:"Handlebars",file:"handlebars"},haskell:{title:"Haskell",file:"haskell"},haxe:{title:"Haxe",file:"haxe"},hcl:{title:"HCL",file:"hcl"},http:{title:"HTTP",file:"http"},hpkp:{title:"HTTP Public-Key-Pins",file:"hpkp"},hsts:{title:"HTTP Strict-Transport-Security",file:"hsts"},ichigojam:{title:"IchigoJam",file:"ichigojam"},icon:{title:"Icon",file:"icon"},inform7:{title:"Inform 7",file:"inform7"},ini:{title:"Ini",file:"ini"},io:{title:"Io",file:"io"},j:{title:"J",file:"j"},java:{title:"Java",file:"java"},javadoc:{title:"JavaDoc",file:"javadoc"},javadoclike:{title:"JavaDoc-like",file:"javadoclike"},javastacktrace:{title:"Java stack trace",file:"javastacktrace"},jolie:{title:"Jolie",file:"jolie"},jq:{title:"JQ",file:"jq"},jsdoc:{title:"JSDoc",file:"jsdoc"},"js-extras":{title:"JS Extras",file:"js-extras"},json:{title:"JSON",file:"json"},jsonp:{title:"JSONP",file:"jsonp"},json5:{title:"JSON5",file:"json5"},julia:{title:"Julia",file:"julia"},keyman:{title:"Keyman",file:"keyman"},kotlin:{title:"Kotlin",file:"kotlin"},latex:{title:"LaTeX",file:"latex"},tex:{title:"TeX",file:"latex"},context:{title:"ConTeXt",file:"latex"},less:{title:"Less",file:"less"},liquid:{title:"Liquid",file:"liquid"},lisp:{title:"Lisp",file:"lisp"},livescript:{title:"LiveScript",file:"livescript"},lolcode:{title:"LOLCODE",file:"lolcode"},lua:{title:"Lua",file:"lua"},makefile:{title:"Makefile",file:"makefile"},markdown:{title:"Markdown",file:"markdown"},"markup-templating":{title:"Markup templating",file:"markup-templating"},matlab:{title:"MATLAB",file:"matlab"},mel:{title:"MEL",file:"mel"},mizar:{title:"Mizar",file:"mizar"},monkey:{title:"Monkey",file:"monkey"},n1ql:{title:"N1QL",file:"n1ql"},n4js:{title:"N4JS",file:"n4js"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",file:"nand2tetris-hdl"},nasm:{title:"NASM",file:"nasm"},nginx:{title:"nginx",file:"nginx"},nim:{title:"Nim",file:"nim"},nix:{title:"Nix",file:"nix"},nsis:{title:"NSIS",file:"nsis"},objectivec:{title:"Objective-C",file:"objectivec"},ocaml:{title:"OCaml",file:"ocaml"},opencl:{title:"OpenCL",file:"opencl"},oz:{title:"Oz",file:"oz"},parigp:{title:"PARI/GP",file:"parigp"},parser:{title:"Parser",file:"parser"},pascal:{title:"Pascal",file:"pascal"},perl:{title:"Perl",file:"perl"},php:{title:"PHP",file:"php"},phpdoc:{title:"PHPDoc",file:"phpdoc"},"php-extras":{title:"PHP Extras",file:"php-extras"},plsql:{title:"PL/SQL",file:"plsql"},powershell:{title:"PowerShell",file:"powershell"},processing:{title:"Processing",file:"processing"},prolog:{title:"Prolog",file:"prolog"},properties:{title:".properties",file:"properties"},protobuf:{title:"Protocol Buffers",file:"protobuf"},pug:{title:"Pug",file:"pug"},puppet:{title:"Puppet",file:"puppet"},pure:{title:"Pure",file:"pure"},python:{title:"Python",file:"python"},q:{title:"Q (kdb+ database)",file:"q"},qore:{title:"Qore",file:"qore"},r:{title:"R",file:"r"},jsx:{title:"React JSX",file:"jsx"},tsx:{title:"React TSX",file:"tsx"},renpy:{title:"Ren'py",file:"renpy"},reason:{title:"Reason",file:"reason"},regex:{title:"Regex",file:"regex"},rest:{title:"reST (reStructuredText)",file:"rest"},rip:{title:"Rip",file:"rip"},roboconf:{title:"Roboconf",file:"roboconf"},ruby:{title:"Ruby",file:"ruby"},rust:{title:"Rust",file:"rust"},sas:{title:"SAS",file:"sas"},sass:{title:"Sass (Sass)",file:"sass"},scss:{title:"Sass (Scss)",file:"scss"},scala:{title:"Scala",file:"scala"},scheme:{title:"Scheme",file:"scheme"},"shell-session":{title:"Shell session",file:"shell-session"},smalltalk:{title:"Smalltalk",file:"smalltalk"},smarty:{title:"Smarty",file:"smarty"},sql:{title:"SQL",file:"sql"},soy:{title:"Soy (Closure Template)",file:"soy"},stylus:{title:"Stylus",file:"stylus"},swift:{title:"Swift",file:"swift"},tap:{title:"TAP",file:"tap"},tcl:{title:"Tcl",file:"tcl"},textile:{title:"Textile",file:"textile"},toml:{title:"TOML",file:"toml"},tt2:{title:"Template Toolkit 2",file:"tt2"},twig:{title:"Twig",file:"twig"},typescript:{title:"TypeScript",file:"typescript"},"t4-cs":{title:"T4 Text Templates (C#)",file:"t4-cs"},"t4-vb":{title:"T4 Text Templates (VB)",file:"t4-vb"},"t4-templating":{title:"T4 templating",file:"t4-templating"},vala:{title:"Vala",file:"vala"},vbnet:{title:"VB.Net",file:"vbnet"},velocity:{title:"Velocity",file:"velocity"},verilog:{title:"Verilog",file:"verilog"},vhdl:{title:"VHDL",file:"vhdl"},vim:{title:"vim",file:"vim"},"visual-basic":{title:"Visual Basic",file:"visual-basic"},wasm:{title:"WebAssembly",file:"wasm"},wiki:{title:"Wiki markup",file:"wiki"},xeora:{title:"Xeora",file:"xeora"},xojo:{title:"Xojo (REALbasic)",file:"xojo"},xquery:{title:"XQuery",file:"xquery"},yaml:{title:"YAML",file:"yaml"}}}),define("WoltLabSuite/Core/Bbcode/Code",["Language","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Clipboard","WoltLabSuite/Core/Prism","prism/prism-meta"],function(e,t,i,n,a){"use strict";function r(e){var t;this.container=e,this.codeContainer=elBySel(".codeBoxCode > code",this.container),this.language=null;for(var i=0;i<this.codeContainer.classList.length;i++)(t=this.codeContainer.classList[i].match(/language-(.*)/))&&(this.language=t[1])}var o=function(e){return function(){var t=arguments;return new Promise(function(i,n){var a=function(){try{i(e.apply(null,t))}catch(e){n(e)}};window.requestIdleCallback?window.requestIdleCallback(a,{timeout:5e3}):setTimeout(a,0)})}};return r.processAll=function(){elBySelAll(".codeBox:not([data-processed])",document,function(e){elData(e,"processed","1");var t=new r(e);t.language&&t.highlight(),t.createCopyButton()})},r.prototype={createCopyButton:function(){var n=elBySel(".codeBoxHeader",this.container),a=elCreate("span");a.className="icon icon24 fa-files-o pointer jsTooltip",a.setAttribute("title",e.get("wcf.message.bbcode.code.copy")),a.addEventListener("click",function(){i.copyElementTextToClipboard(this.codeContainer).then(function(){t.show(e.get("wcf.message.bbcode.code.copy.success"))})}.bind(this)),n.appendChild(a)},highlight:function(){return this.language?a[this.language]?(this.container.classList.add("highlighting"),require(["prism/components/prism-"+a[this.language].file]).then(o(function(){var e=n.languages[this.language];if(!e)throw new Error("Invalid language "+language+" given.");var t=elCreate("div");return t.innerHTML=n.highlight(this.codeContainer.textContent,e,this.language),t}.bind(this))).then(o(function(e){var t=n.wscSplitIntoLines(e),i=elBySelAll("[data-number]",t),a=elBySelAll(".codeBoxLine > span",this.codeContainer);if(i.length!==a.length)throw new Error("Unreachable");for(var r=[],s=0,l=i.length;s<l;s+=50)r.push(o(function(e){for(var t=Math.min(e+50,l),n=e;n<t;n++)a[n].parentNode.replaceChild(i[n],a[n])})(s));return Promise.all(r)}.bind(this))).then(function(){this.container.classList.remove("highlighting"),this.container.classList.add("highlighted")}.bind(this))):Promise.reject(new Error("Unknown language "+this.language)):Promise.reject(new Error("No language detected"))}},r}),define("WoltLabSuite/Core/Bbcode/Collapsible",[],function(){"use strict";var e=elByClass("jsCollapsibleBbcode");return{observe:function(){for(var t,i;e.length;)t=e[0],i=null,elBySelAll(".toggleButton:not(.jsToggleButtonEnabled)",t,function(e){e.closest(".jsCollapsibleBbcode")===t&&(i=e)}),i&&function(e,t){var i=function(i){if(e.classList.toggle("collapsed")){if(t.textContent=elData(t,"title-expand"),i instanceof Event){var n=e.getBoundingClientRect().top;if(n<0){var a=window.pageYOffset+(n-100);a<0&&(a=0),window.scrollTo(window.pageXOffset,a)}}}else t.textContent=elData(t,"title-collapse")};t.classList.add("jsToggleButtonEnabled"),t.addEventListener(WCF_CLICK_EVENT,i),0!==e.scrollTop&&i(),e.addEventListener("scroll",function(){e.classList.contains("collapsed")&&i()})}(t,i),t.classList.remove("jsCollapsibleBbcode")}}}),define("WoltLabSuite/Core/Bbcode/Spoiler",["Language"],function(e){"use strict";var t=elByClass("jsSpoilerBox");return{observe:function(){for(var e,i;t.length;)e=t[0],e.classList.remove("jsSpoilerBox"),i=elBySel(".jsSpoilerToggle",e),e=i.parentNode.nextElementSibling,i.addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this,e,i))},_onClick:function(t,i,n){n.preventDefault(),i.classList.toggle("active");var a=i.classList.contains("active");window[a?"elShow":"elHide"](t),elAttr(i,"aria-expanded",a),elAttr(t,"aria-hidden",!a),elDataBool(i,"has-custom-label")||(i.textContent=e.get(i.classList.contains("active")?"wcf.bbcode.spoiler.hide":"wcf.bbcode.spoiler.show"))}}}),define("WoltLabSuite/Core/Controller/Captcha",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if(t.has(e))throw new Error("Captcha with id '"+e+"' is already registered.");if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'callback'.");t.set(e,i)},delete:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");t.delete(e)},has:function(e){return t.has(e)},getData:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");return t.get(e)()}}}),define("WoltLabSuite/Core/Controller/Clipboard",["Ajax","Core","Dictionary","EventHandler","Language","List","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Page/Action","Ui/Screen"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p){"use strict";var f=new i,m=new i,g=new i,v=elByClass("jsClipboardContainer"),_=new o,b=new r,w={},y=new i,C=null,E=null,L=null,S='.messageCheckboxLabel > input[type="checkbox"], .message .messageClipboardCheckbox > input[type="checkbox"], .messageGroupList .columnMark > label > input[type="checkbox"]';return{setup:function(e){if(!e.pageClassName)throw new Error("Expected a non-empty string for parameter 'pageClassName'.");if(null===C)C=this._mark.bind(this),E=this._executeAction.bind(this),L=this._unmarkAll.bind(this),w=t.extend({hasMarkedItems:!1,pageClassNames:[e.pageClassName],pageObjectId:0},e),delete w.pageClassName;else{if(e.pageObjectId)throw new Error("Cannot load secondary clipboard with page object id set.");w.pageClassNames.push(e.pageClassName)}Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector),this._initContainers(),w.hasMarkedItems&&v.length&&this._loadMarkedItems(),s.add("WoltLabSuite/Core/Controller/Clipboard",this._initContainers.bind(this))},reload:function(){f.size&&this._loadMarkedItems()},_initContainers:function(){for(var e=0,t=v.length;e<t;e++){var i=v[e],n=c.identify(i),o=f.get(n);if(void 0===o){var s=elBySel(".jsClipboardMarkAll",i);if(null!==s){if(s.matches(S)){var l=s.closest("label");elAttr(l,"role","checkbox"),elAttr(l,"tabindex","0"),elAttr(l,"aria-checked",!1),elAttr(l,"aria-label",a.get("wcf.clipboard.item.markAll")),l.addEventListener("keyup",function(e){13!==e.keyCode&&32!==e.keyCode||h.click()})}elData(s,"container-id",n),s.addEventListener(WCF_CLICK_EVENT,this._markAll.bind(this))}o={checkboxes:elByClass("jsClipboardItem",i),element:i,markAll:s,markedObjectIds:new r},f.set(n,o)}for(var d=0,u=o.checkboxes.length;d<u;d++){var h=o.checkboxes[d];b.has(h)||(elData(h,"container-id",n),function(e){if(e.matches(S)){var t=e.closest("label");elAttr(t,"role","checkbox"),elAttr(t,"tabindex","0"),elAttr(t,"aria-checked",!1),elAttr(t,"aria-label",a.get("wcf.clipboard.item.mark")),t.addEventListener("keyup",function(t){13!==t.keyCode&&32!==t.keyCode||e.click()})}null===e.closest("a")?e.addEventListener(WCF_CLICK_EVENT,C):e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),window.setTimeout(function(){e.checked=!e.checked,C(null,e)},10)})}(h),b.add(h))}}},_loadMarkedItems:function(){e.api(this,{actionName:"getMarkedItems",parameters:{pageClassNames:w.pageClassNames,pageObjectID:w.pageObjectId}})},_markAll:function(e){var t=e.currentTarget,i="INPUT"!==t.nodeName||t.checked;"checkbox"===elAttr(t.parentNode,"role")&&elAttr(t.parentNode,"aria-checked",i);for(var n=[],a=elData(t,"container-id"),r=f.get(a),o=elData(r.element,"type"),s=0,c=r.checkboxes.length;s<c;s++){var d=r.checkboxes[s],u=~~elData(d,"object-id");i?d.checked||(d.checked=!0,r.markedObjectIds.add(u),n.push(u)):d.checked&&(d.checked=!1,r.markedObjectIds.delete(u),n.push(u)),"checkbox"===elAttr(d.parentNode,"role")&&elAttr(d.parentNode,"aria-checked",i);var h=l.parentByClass(t,"jsClipboardObject");null!==h&&h.classList[i?"addClass":"removeClass"]("jsMarked")}this._saveState(o,n,i)},_mark:function(e,t){t=e instanceof Event?e.currentTarget:t;var i=~~elData(t,"object-id"),n=t.checked,a=elData(t,"container-id"),r=f.get(a),o=elData(r.element,"type"),s=l.parentByClass(t,"jsClipboardObject");if(r.markedObjectIds[n?"add":"delete"](i),s.classList[n?"add":"remove"]("jsMarked"),null!==r.markAll){for(var c=!0,d=0,u=r.checkboxes.length;d<u;d++)if(!r.checkboxes[d].checked){c=!1;break}r.markAll.checked=c,"checkbox"===elAttr(r.markAll.parentNode,"role")&&elAttr(r.markAll.parentNode,"aria-checked",n)}"checkbox"===elAttr(t.parentNode,"role")&&elAttr(t.parentNode,"aria-checked",t.checked),this._saveState(o,[i],n)},_saveState:function(t,i,n){e.api(this,{actionName:n?"mark":"unmark",parameters:{pageClassNames:w.pageClassNames,pageObjectID:w.pageObjectId,objectIDs:i,objectType:t}})},_executeAction:function(e){var t=e.currentTarget,i=_.get(t);if(i.url)return void(window.location.href=i.url);var a=function(){var e=elData(t,"type");n.fire("com.woltlab.wcf.clipboard",e,{data:i,listItem:t,responseData:null})},r="string"==typeof i.internalData.confirmMessage?i.internalData.confirmMessage:"",o=!0;if("object"==typeof i.parameters&&i.parameters.actionName&&i.parameters.className){if("unmarkAll"===i.parameters.actionName||Array.isArray(i.parameters.objectIDs))if(r.length){var s="string"==typeof i.internalData.template?i.internalData.template:"";d.show({confirm:function(){var e={};if(s.length)for(var n=elBySelAll("input, select, textarea",d.getContentElement()),a=0,r=n.length;a<r;a++){var o=n[a],l=elAttr(o,"name");switch(o.nodeName){case"INPUT":("checkbox"!==o.type&&"radio"!==o.type||o.checked)&&(e[l]=elAttr(o,"value"));break;case"SELECT":e[l]=o.value;break;case"TEXTAREA":e[l]=o.value.trim()}}this._executeProxyAction(t,i,e)}.bind(this),message:r,template:s})}else this._executeProxyAction(t,i)}else r.length&&(o=!1,d.show({confirm:a,message:r}));o&&a()},_executeProxyAction:function(t,i,a){a=a||{};var r="unmarkAll"!==i.parameters.actionName?i.parameters.objectIDs:[],o={data:a};if("object"==typeof i.internalData.parameters)for(var s in i.internalData.parameters)i.internalData.parameters.hasOwnProperty(s)&&(o[s]=i.internalData.parameters[s]);e.api(this,{actionName:i.parameters.actionName,className:i.parameters.className,objectIDs:r,parameters:o},function(e){if("unmarkAll"!==i.actionName){var a=elData(t,"type");if(n.fire("com.woltlab.wcf.clipboard",a,{data:i,listItem:t,responseData:e}),y.has(a)&&-1!==y.get(a).indexOf(e.actionName))return void window.location.reload()}this._loadMarkedItems()}.bind(this))},_unmarkAll:function(t){var i=elData(t.currentTarget,"type");e.api(this,{actionName:"unmarkAll",parameters:{objectType:i}})},_ajaxSetup:function(){return{data:{className:"wcf\\data\\clipboard\\item\\ClipboardItemAction"}}},_ajaxSuccess:function(e){if("unmarkAll"===e.actionName)return void f.forEach(function(t){if(elData(t.element,"type")===e.returnValues.objectType){for(var i=elByClass("jsMarked",t.element);i.length;)i[0].classList.remove("jsMarked");null!==t.markAll&&(t.markAll.checked=!1,"checkbox"===elAttr(t.markAll.parentNode,"role")&&elAttr(t.markAll.parentNode,"aria-checked",!1));for(var n=0,a=t.checkboxes.length;n<a;n++)t.checkboxes[n].checked=!1,"checkbox"===elAttr(t.checkboxes[n].parentNode,"role")&&elAttr(t.checkboxes[n].parentNode,"aria-checked",!1);h.remove("wcfClipboard-"+e.returnValues.objectType)}}.bind(this));_=new o,y=new i,f.forEach(function(t){var i=elData(t.element,"type"),n=e.returnValues.markedItems&&e.returnValues.markedItems.hasOwnProperty(i)?e.returnValues.markedItems[i]:[];this._rebuildMarkings(t,n)}.bind(this));var t,n=[];if(e.returnValues&&e.returnValues.items)for(t in e.returnValues.items)e.returnValues.items.hasOwnProperty(t)&&n.push(t);if(m.forEach(function(e,t){-1===n.indexOf(t)&&(h.remove("wcfClipboard-"+t),g.get(t).innerHTML="")}),e.returnValues&&e.returnValues.items){var r,s,l,c,d,p,v,b,w,C,S;for(t in e.returnValues.items)if(e.returnValues.items.hasOwnProperty(t)){d=e.returnValues.items[t],y.set(t,d.reloadPageOnSuccess),s=!1,c=m.get(t),l=g.get(t),void 0===c?(s=!0,c=elCreate("a"),c.className="dropdownToggle",c.textContent=d.label,m.set(t,c),l=elCreate("ol"),l.className="dropdownMenu",g.set(t,l)):(c.textContent=d.label,l.innerHTML="");for(w in d.items)d.items.hasOwnProperty(w)&&(b=d.items[w],v=elCreate("li"),C=elCreate("span"),C.textContent=b.label,v.appendChild(C),l.appendChild(v),elData(v,"type",t),v.addEventListener(WCF_CLICK_EVENT,E),_.set(v,b));p=elCreate("li"),p.classList.add("dropdownDivider"),l.appendChild(p),S=elCreate("li"),elData(S,"type",t),C=elCreate("span"),C.textContent=a.get("wcf.clipboard.item.unmarkAll"),S.appendChild(C),S.addEventListener(WCF_CLICK_EVENT,L),l.appendChild(S),-1!==n.indexOf(t)&&(r="wcfClipboard-"+t,h.has(r)?h.show(r):h.add(r,c)),s&&(c.parentNode.classList.add("dropdown"),c.parentNode.appendChild(l),u.init(c))}}},_rebuildMarkings:function(e,t){for(var i=!0,n=0,a=e.checkboxes.length;n<a;n++){
-var r=e.checkboxes[n],o=l.parentByClass(r,"jsClipboardObject"),s=-1!==t.indexOf(~~elData(r,"object-id"));s||(i=!1),r.checked=s,o.classList[s?"add":"remove"]("jsMarked"),"checkbox"===elAttr(r.parentNode,"role")&&elAttr(r.parentNode,"aria-checked",s)}if(null!==e.markAll){e.markAll.checked=i,"checkbox"===elAttr(e.markAll.parentNode,"role")&&elAttr(e.markAll.parentNode,"aria-checked",i);for(var c=e.markAll;c=c.parentNode;)if(c instanceof Element&&c.classList.contains("columnMark")){c=c.parentNode;break}c&&c.classList[i?"add":"remove"]("jsMarked")}},hideEditor:function(e){h.remove("wcfClipboard-"+e),p.pageOverlayOpen()},showEditor:function(){this._loadMarkedItems(),p.pageOverlayClose()},unmark:function(e,t){this._saveState(e,t,!1)}}}),define("WoltLabSuite/Core/Image/ExifUtil",[],function(){"use strict";var e={SOI:216,APP0:224,APP1:225,APP2:226,APP3:227,APP4:228,APP5:229,APP6:230,APP7:231,APP8:232,APP9:233,APP10:234,APP11:235,APP12:236,APP13:237,APP14:238,COM:254};return{getExifBytesFromJpeg:function(t){return new Promise(function(i,n){if(!(t instanceof Blob||t instanceof File))return n(new TypeError("The argument must be a Blob or a File"));var a=new FileReader;a.addEventListener("error",function(){a.abort(),n(a.error)}),a.addEventListener("load",function(){var t=a.result,r=new Uint8Array(t),o=new Uint8Array;if(255!==r[0]&&r[1]!==e.SOI)return n(new Error("Not a JPEG"));for(var s=2;s<r.length&&255===r[s];){var l=2+(r[s+2]<<8|r[s+3]);if(r[s+1]===e.APP1){for(var c="",d=s+4;0!==r[d]&&d<r.length;d++)c+=String.fromCharCode(r[d]);if("Exif"===c||"http://ns.adobe.com/xap/1.0/"===c){var u=Array.prototype.slice.call(r,s,l+s),h=new Uint8Array(o.length+u.length);h.set(o),h.set(u,o.length),o=h}}s+=l}i(o)}),a.readAsArrayBuffer(t)})},removeExifData:function(t){return new Promise(function(i,n){if(!(t instanceof Blob||t instanceof File))return n(new TypeError("The argument must be a Blob or a File"));var a=new FileReader;a.addEventListener("error",function(){a.abort(),n(a.error)}),a.addEventListener("load",function(){var r=a.result,o=new Uint8Array(r);if(255!==o[0]&&o[1]!==e.SOI)return n(new Error("Not a JPEG"));for(var s=2;s<o.length&&255===o[s];){var l=2+(o[s+2]<<8|o[s+3]);if(o[s+1]===e.APP1){for(var c="",d=s+4;0!==o[d]&&d<o.length;d++)c+=String.fromCharCode(o[d]);if("Exif"===c||"http://ns.adobe.com/xap/1.0/"===c){var u=Array.prototype.slice.call(o,0,s),h=Array.prototype.slice.call(o,s+l);o=new Uint8Array(u.length+h.length),o.set(u,0),o.set(h,u.length)}else s+=l}else s+=l}i(new Blob([o],{type:t.type}))}),a.readAsArrayBuffer(t)})},setExifData:function(t,i){return this.removeExifData(t).then(function(t){return new Promise(function(n){var a=new FileReader;a.addEventListener("error",function(){a.abort(),reject(a.error)}),a.addEventListener("load",function(){var r=a.result,o=new Uint8Array(r),s=2;255===o[2]&&o[3]===e.APP0&&(s+=2+(o[4]<<8|o[5]));var l=Array.prototype.slice.call(o,0,s),c=Array.prototype.slice.call(o,s);o=new Uint8Array(l.length+i.length+c.length),o.set(l),o.set(i,s),o.set(c,s+i.length),n(new Blob([o],{type:t.type}))}),a.readAsArrayBuffer(t)})})}}}),define("WoltLabSuite/Core/Image/ImageUtil",[],function(){"use strict";return{containsTransparentPixels:function(e){for(var t=e.getContext("2d").getImageData(0,0,e.width,e.height),i=3,n=t.data.length;i<n;i+=4)if(255!==t.data[i])return!0;return!1}}}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("Pica",[],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pica=e()}}(function(){return function(){function e(t,i,n){function a(o,s){if(!i[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var d=i[o]={exports:{}};t[o][0].call(d.exports,function(e){return a(t[o][1][e]||e)},d,d.exports,e,t,i,n)}return i[o].exports}for(var r="function"==typeof require&&require,o=0;o<n.length;o++)a(n[o]);return a}return e}()({1:[function(e,t,i){"use strict";function n(e){var t=e||[],i={js:t.indexOf("js")>=0,wasm:t.indexOf("wasm")>=0};r.call(this,i),this.features={js:i.js,wasm:i.wasm&&this.has_wasm},this.use(o),this.use(s)}var a=e("inherits"),r=e("multimath"),o=e("multimath/lib/unsharp_mask"),s=e("./mm_resize");a(n,r),n.prototype.resizeAndUnsharp=function(e,t){var i=this.resize(e,t);return e.unsharpAmount&&this.unsharp_mask(i,e.toWidth,e.toHeight,e.unsharpAmount,e.unsharpRadius,e.unsharpThreshold),i},t.exports=n},{"./mm_resize":4,inherits:15,multimath:16,"multimath/lib/unsharp_mask":19}],2:[function(e,t,i){"use strict";function n(e){return e<0?0:e>255?255:e}function a(e,t,i,a,r,o){var s,l,c,d,u,h,p,f,m,g,v,_=0,b=0;for(m=0;m<a;m++){for(u=0,g=0;g<r;g++){for(h=o[u++],p=o[u++],f=_+4*h|0,s=l=c=d=0;p>0;p--)v=o[u++],d=d+v*e[f+3]|0,c=c+v*e[f+2]|0,l=l+v*e[f+1]|0,s=s+v*e[f]|0,f=f+4|0;t[b+3]=n(d+8192>>14),t[b+2]=n(c+8192>>14),t[b+1]=n(l+8192>>14),t[b]=n(s+8192>>14),b=b+4*a|0}b=4*(m+1)|0,_=(m+1)*i*4|0}}function r(e,t,i,a,r,o){var s,l,c,d,u,h,p,f,m,g,v,_=0,b=0;for(m=0;m<a;m++){for(u=0,g=0;g<r;g++){for(h=o[u++],p=o[u++],f=_+4*h|0,s=l=c=d=0;p>0;p--)v=o[u++],d=d+v*e[f+3]|0,c=c+v*e[f+2]|0,l=l+v*e[f+1]|0,s=s+v*e[f]|0,f=f+4|0;t[b+3]=n(d+8192>>14),t[b+2]=n(c+8192>>14),t[b+1]=n(l+8192>>14),t[b]=n(s+8192>>14),b=b+4*a|0}b=4*(m+1)|0,_=(m+1)*i*4|0}}t.exports={convolveHorizontally:a,convolveVertically:r}},{}],3:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQQEAXAAAAcZAghjb252b2x2ZQAACmNvbnZvbHZlSFYAAQkBAArmAwLBAwEQfwJAIANFDQAgBEUNACAFQQRqIRVBACEMQQAhDQNAIA0hDkEAIRFBACEHA0AgB0ECaiESAn8gBSAHQQF0IgdqIgZBAmouAQAiEwRAQQAhCEEAIBNrIRQgFSAHaiEPIAAgDCAGLgEAakECdGohEEEAIQlBACEKQQAhCwNAIBAoAgAiB0EYdiAPLgEAIgZsIAtqIQsgB0H/AXEgBmwgCGohCCAHQRB2Qf8BcSAGbCAKaiEKIAdBCHZB/wFxIAZsIAlqIQkgD0ECaiEPIBBBBGohECAUQQFqIhQNAAsgEiATagwBC0EAIQtBACEKQQAhCUEAIQggEgshByABIA5BAnRqIApBgMAAakEOdSIGQf8BIAZB/wFIG0EQdEGAgPwHcUEAIAZBAEobIAtBgMAAakEOdSIGQf8BIAZB/wFIG0EYdEEAIAZBAEobciAJQYDAAGpBDnUiBkH/ASAGQf8BSBtBCHRBgP4DcUEAIAZBAEobciAIQYDAAGpBDnUiBkH/ASAGQf8BSBtB/wFxQQAgBkEAShtyNgIAIA4gA2ohDiARQQFqIhEgBEcNAAsgDCACaiEMIA1BAWoiDSADRw0ACwsLIQACQEEAIAIgAyAEIAUgABAAIAJBACAEIAUgBiABEAALCw=="},{}],4:[function(e,t,i){"use strict";t.exports={name:"resize",fn:e("./resize"),wasm_fn:e("./resize_wasm"),wasm_src:e("./convolve_wasm_base64")}},{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,a=t*i*4|0;n<a;)e[n]=255,n=n+4|0}var a=e("./resize_filter_gen"),r=e("./convolve").convolveHorizontally,o=e("./convolve").convolveVertically;t.exports=function(e){var t=e.src,i=e.width,s=e.height,l=e.toWidth,c=e.toHeight,d=e.scaleX||e.toWidth/e.width,u=e.scaleY||e.toHeight/e.height,h=e.offsetX||0,p=e.offsetY||0,f=e.dest||new Uint8Array(l*c*4),m=void 0===e.quality?3:e.quality,g=e.alpha||!1,v=a(m,i,l,d,h),_=a(m,s,c,u,p),b=new Uint8Array(l*s*4);return r(t,b,i,s,l,v),o(b,f,s,l,c,_),g||n(f,l,c),f}},{"./convolve":2,"./resize_filter_gen":6}],6:[function(e,t,i){"use strict";function n(e){return Math.round(e*((1<<r)-1))}var a=e("./resize_filter_info"),r=14;t.exports=function(e,t,i,r,o){var s,l,c,d,u,h,p,f,m,g,v,_,b,w,y,C,E,L=a[e].filter,S=1/r,A=Math.min(1,r),I=a[e].win/A,D=Math.floor(2*(I+1)),x=new Int16Array((D+2)*i),T=0,B=!x.subarray||!x.set;for(s=0;s<i;s++){for(l=(s+.5)*S+o,c=Math.max(0,Math.floor(l-I)),d=Math.min(t-1,Math.ceil(l+I)),u=d-c+1,h=new Float32Array(u),p=new Int16Array(u),f=0,m=c,g=0;m<=d;m++,g++)v=L((m+.5-l)*A),f+=v,h[g]=v;for(_=0,g=0;g<h.length;g++)b=h[g]/f,_+=b,p[g]=n(b);for(p[i>>1]+=n(1-_),w=0;w<p.length&&0===p[w];)w++;if(w<p.length){for(y=p.length-1;y>0&&0===p[y];)y--;if(C=c+w,E=y-w+1,x[T++]=C,x[T++]=E,B)for(g=w;g<=y;g++)x[T++]=p[g];else x.set(p.subarray(w,y+1),T),T+=E}else x[T++]=0,x[T++]=0}return x}},{"./resize_filter_info":7}],7:[function(e,t,i){"use strict";t.exports=[{win:.5,filter:function(e){return e>=-.5&&e<.5?1:0}},{win:1,filter:function(e){if(e<=-1||e>=1)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*(.54+.46*Math.cos(t/1))}},{win:2,filter:function(e){if(e<=-2||e>=2)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/2)/(t/2)}},{win:3,filter:function(e){if(e<=-3||e>=3)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/3)/(t/3)}}]},{}],8:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,a=t*i*4|0;n<a;)e[n]=255,n=n+4|0}function a(e){return new Uint8Array(e.buffer,0,e.byteLength)}function r(e,t,i){if(s)return void t.set(a(e),i);for(var n=i,r=0;r<e.length;r++){var o=e[r];t[n++]=255&o,t[n++]=o>>8&255}}var o=e("./resize_filter_gen"),s=!0;try{s=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0]}catch(e){}t.exports=function(e){var t=e.src,i=e.width,a=e.height,s=e.toWidth,l=e.toHeight,c=e.scaleX||e.toWidth/e.width,d=e.scaleY||e.toHeight/e.height,u=e.offsetX||0,h=e.offsetY||0,p=e.dest||new Uint8Array(s*l*4),f=void 0===e.quality?3:e.quality,m=e.alpha||!1,g=o(f,i,s,c,u),v=o(f,a,l,d,h),_=this.__align(0+Math.max(t.byteLength,p.byteLength)),b=this.__align(_+a*s*4),w=this.__align(b+g.byteLength),y=w+v.byteLength,C=this.__instance("resize",y),E=new Uint8Array(this.__memory.buffer),L=new Uint32Array(this.__memory.buffer),S=new Uint32Array(t.buffer);return L.set(S),r(g,E,b),r(v,E,w),(C.exports.convolveHV||C.exports._convolveHV)(b,w,_,i,a,s,l),new Uint32Array(p.buffer).set(new Uint32Array(this.__memory.buffer,0,l*s)),m||n(p,s,l),p}},{"./resize_filter_gen":6}],9:[function(e,t,i){"use strict";function n(e,t){this.create=e,this.available=[],this.acquired={},this.lastId=1,this.timeoutId=0,this.idle=t||2e3}n.prototype.acquire=function(){var e,t=this;return 0!==this.available.length?e=this.available.pop():(e=this.create(),e.id=this.lastId++,e.release=function(){return t.release(e)}),this.acquired[e.id]=e,e},n.prototype.release=function(e){var t=this;delete this.acquired[e.id],e.lastUsed=Date.now(),this.available.push(e),0===this.timeoutId&&(this.timeoutId=setTimeout(function(){return t.gc()},100))},n.prototype.gc=function(){var e=this,t=Date.now();this.available=this.available.filter(function(i){return!(t-i.lastUsed>e.idle)||(i.destroy(),!1)}),0!==this.available.length?this.timeoutId=setTimeout(function(){return e.gc()},100):this.timeoutId=0},t.exports=n},{}],10:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,a,r){var o=i/e,s=n/t,l=(2*r+2+1)/a;if(l>.5)return[[i,n]];var c=Math.ceil(Math.log(Math.min(o,s))/Math.log(l));if(c<=1)return[[i,n]];for(var d=[],u=0;u<c;u++){var h=Math.round(Math.pow(Math.pow(e,c-u-1)*Math.pow(i,u+1),1/c)),p=Math.round(Math.pow(Math.pow(t,c-u-1)*Math.pow(n,u+1),1/c));d.push([h,p])}return d}},{}],11:[function(e,t,i){"use strict";function n(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.floor(e)}function a(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.ceil(e)}var r=1e-5;t.exports=function(e){var t=e.toWidth/e.width,i=e.toHeight/e.height,r=n(e.srcTileSize*t)-2*e.destTileBorder,o=n(e.srcTileSize*i)-2*e.destTileBorder;if(r<1||o<1)throw new Error("Internal error in pica: target tile width/height is too small.");var s,l,c,d,u,h,p,f=[];for(d=0;d<e.toHeight;d+=o)for(c=0;c<e.toWidth;c+=r)s=c-e.destTileBorder,s<0&&(s=0),u=c+r+e.destTileBorder-s,s+u>=e.toWidth&&(u=e.toWidth-s),l=d-e.destTileBorder,l<0&&(l=0),h=d+o+e.destTileBorder-l,l+h>=e.toHeight&&(h=e.toHeight-l),p={toX:s,toY:l,toWidth:u,toHeight:h,toInnerX:c,toInnerY:d,toInnerWidth:r,toInnerHeight:o,offsetX:s/t-n(s/t),offsetY:l/i-n(l/i),scaleX:t,scaleY:i,x:n(s/t),y:n(l/i),width:a(u/t),height:a(h/i)},f.push(p);return f}},{}],12:[function(e,t,i){"use strict";function n(e){return Object.prototype.toString.call(e)}t.exports.isCanvas=function(e){var t=n(e);return"[object HTMLCanvasElement]"===t||"[object Canvas]"===t},t.exports.isImage=function(e){return"[object HTMLImageElement]"===n(e)},t.exports.limiter=function(e){function t(){i<e&&n.length&&(i++,n.shift()())}var i=0,n=[];return function(e){return new Promise(function(a,r){n.push(function(){e().then(function(e){a(e),i--,t()},function(e){r(e),i--,t()})}),t()})}},t.exports.cib_quality_name=function(e){switch(e){case 0:return"pixelated";case 1:return"low";case 2:return"medium"}return"high"},t.exports.cib_support=function(){return Promise.resolve().then(function(){if("undefined"==typeof createImageBitmap||"undefined"==typeof document)return!1;var e=document.createElement("canvas");return e.width=100,e.height=100,createImageBitmap(e,0,0,100,100,{resizeWidth:10,resizeHeight:10,resizeQuality:"high"}).then(function(t){var i=10===t.width;return t.close(),e=null,i})}).catch(function(){return!1})}},{}],13:[function(e,t,i){"use strict";t.exports=function(){var t,i=e("./mathlib");onmessage=function(e){var n=e.data.opts;t||(t=new i(e.data.features));var a=t.resizeAndUnsharp(n);postMessage({result:a},[a.buffer])}}},{"./mathlib":1}],14:[function(e,t,i){function n(e){e<.5&&(e=.5);var t=Math.exp(.527076)/e,i=Math.exp(-t),n=Math.exp(-2*t),a=(1-i)*(1-i)/(1+2*t*i-n);return o=a,s=a*(t-1)*i,l=a*(t+1)*i,c=-a*n,d=2*i,u=-n,h=(o+s)/(1-d-u),p=(l+c)/(1-d-u),new Float32Array([o,s,l,c,d,u,h,p])}function a(e,t,i,n,a,r){var o,s,l,c,d,u,h,p,f,m,g,v,_,b;for(f=0;f<r;f++){for(u=f*a,h=f,p=0,o=e[u],d=o*n[6],c=d,g=n[0],v=n[1],_=n[4],b=n[5],m=0;m<a;m++)s=e[u],l=s*g+o*v+c*_+d*b,d=c,c=l,o=s,i[p]=c,p++,u++;for(u--,p--,h+=r*(a-1),o=e[u],d=o*n[7],c=d,s=o,g=n[2],v=n[3],m=a-1;m>=0;m--)l=s*g+o*v+c*_+d*b,d=c,c=l,o=s,s=e[u],t[h]=i[p]+c,u--,p--,h-=r}}function r(e,t,i,r){if(r){var o=new Uint16Array(e.length),s=new Float32Array(Math.max(t,i)),l=n(r);a(e,o,s,l,t,i,r),a(o,e,s,l,i,t,r)}}var o,s,l,c,d,u,h,p;t.exports=r},{}],15:[function(e,t,i){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}},{}],16:[function(e,t,i){"use strict";function n(e){if(!(this instanceof n))return new n(e);var t=a({},s,e||{});if(this.options=t,this.__cache={},this.has_wasm=o(),this.__init_promise=null,this.__modules=t.modules||{},this.__memory=null,this.__wasm={},this.__isLE=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0],!this.options.js&&!this.options.wasm)throw new Error('mathlib: at least "js" or "wasm" should be enabled')}var a=e("object-assign"),r=e("./lib/base64decode"),o=e("./lib/wa_detect"),s={js:!0,wasm:!0};n.prototype.use=function(e){return this.__modules[e.name]=e,this.has_wasm&&this.options.wasm&&e.wasm_fn?this[e.name]=e.wasm_fn:this[e.name]=e.fn,this},n.prototype.init=function(){if(this.__init_promise)return this.__init_promise;if(!this.options.js&&this.options.wasm&&!this.has_wasm)return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));var e=this;return this.__init_promise=Promise.all(Object.keys(e.__modules).map(function(t){var i=e.__modules[t];return e.has_wasm&&e.options.wasm&&i.wasm_fn?e.__wasm[t]?null:WebAssembly.compile(e.__base64decode(i.wasm_src)).then(function(i){e.__wasm[t]=i}):null})).then(function(){return e}),this.__init_promise},n.prototype.__base64decode=r,n.prototype.__reallocate=function(e){if(!this.__memory)return this.__memory=new WebAssembly.Memory({initial:Math.ceil(e/65536)}),this.__memory;var t=this.__memory.buffer.byteLength;return t<e&&this.__memory.grow(Math.ceil((e-t)/65536)),this.__memory},n.prototype.__instance=function(e,t,i){if(t&&this.__reallocate(t),!this.__wasm[e]){var n=this.__modules[e];this.__wasm[e]=new WebAssembly.Module(this.__base64decode(n.wasm_src))}if(!this.__cache[e]){var r={memoryBase:0,memory:this.__memory,tableBase:0,table:new WebAssembly.Table({initial:0,element:"anyfunc"})};this.__cache[e]=new WebAssembly.Instance(this.__wasm[e],{env:a(r,i||{})})}return this.__cache[e]},n.prototype.__align=function(e,t){t=t||8;var i=e%t;return e+(i?t-i:0)},t.exports=n},{"./lib/base64decode":17,"./lib/wa_detect":23,"object-assign":24}],17:[function(e,t,i){"use strict";t.exports=function(e){for(var t=e.replace(/[\r\n=]/g,""),i=t.length,n=new Uint8Array(3*i>>2),a=0,r=0,o=0;o<i;o++)o%4==0&&o&&(n[r++]=a>>16&255,n[r++]=a>>8&255,n[r++]=255&a),a=a<<6|"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t.charAt(o));var s=i%4*6;return 0===s?(n[r++]=a>>16&255,n[r++]=a>>8&255,n[r++]=255&a):18===s?(n[r++]=a>>10&255,n[r++]=a>>2&255):12===s&&(n[r++]=a>>4&255),n}},{}],18:[function(e,t,i){"use strict";t.exports=function(e,t,i){for(var n,a,r,o,s,l=t*i,c=new Uint16Array(l),d=0;d<l;d++)n=e[4*d],a=e[4*d+1],r=e[4*d+2],s=n>=a&&n>=r?n:a>=r&&a>=n?a:r,o=n<=a&&n<=r?n:a<=r&&a<=n?a:r,c[d]=257*(s+o)>>1;return c}},{}],19:[function(e,t,i){"use strict";t.exports={name:"unsharp_mask",fn:e("./unsharp_mask"),wasm_fn:e("./unsharp_mask_wasm"),wasm_src:e("./unsharp_mask_wasm_base64")}},{"./unsharp_mask":20,"./unsharp_mask_wasm":21,"./unsharp_mask_wasm_base64":22}],20:[function(e,t,i){"use strict";var n=e("glur/mono16"),a=e("./hsl_l16");t.exports=function(e,t,i,r,o,s){var l,c,d,u,h,p,f,m,g,v,_,b,w;if(!(0===r||o<.5)){o>2&&(o=2);var y=a(e,t,i),C=new Uint16Array(y);n(C,t,i,o);for(var E=r/100*4096+.5|0,L=257*s|0,S=t*i,A=0;A<S;A++)b=2*(y[A]-C[A]),Math.abs(b)>=L&&(w=4*A,l=e[w],c=e[w+1],d=e[w+2],m=l>=c&&l>=d?l:c>=l&&c>=d?c:d,f=l<=c&&l<=d?l:c<=l&&c<=d?c:d,p=257*(m+f)>>1,f===m?u=h=0:(h=p<=32767?4095*(m-f)/(m+f)|0:4095*(m-f)/(510-m-f)|0,u=l===m?65535*(c-d)/(6*(m-f))|0:c===m?21845+(65535*(d-l)/(6*(m-f))|0):43690+(65535*(l-c)/(6*(m-f))|0)),p+=E*b+2048>>12,p>65535?p=65535:p<0&&(p=0),0===h?l=c=d=p>>8:(v=p<=32767?p*(4096+h)+2048>>12:p+((65535-p)*h+2048>>12),g=2*p-v>>8,v>>=8,_=u+21845&65535,l=_>=43690?g:_>=32767?g+(6*(v-g)*(43690-_)+32768>>16):_>=10922?v:g+(6*(v-g)*_+32768>>16),_=65535&u,c=_>=43690?g:_>=32767?g+(6*(v-g)*(43690-_)+32768>>16):_>=10922?v:g+(6*(v-g)*_+32768>>16),_=u-21845&65535,d=_>=43690?g:_>=32767?g+(6*(v-g)*(43690-_)+32768>>16):_>=10922?v:g+(6*(v-g)*_+32768>>16)),e[w]=l,e[w+1]=c,e[w+2]=d)}}},{"./hsl_l16":18,"glur/mono16":14}],21:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,a,r){if(!(0===n||a<.5)){a>2&&(a=2);var o=t*i,s=4*o,l=2*o,c=2*o,d=4*Math.max(t,i),u=s,h=u+l,p=h+c,f=p+c,m=f+d,g=this.__instance("unsharp_mask",s+l+2*c+d+32,{exp:Math.exp}),v=new Uint32Array(e.buffer);new Uint32Array(this.__memory.buffer).set(v);var _=g.exports.hsl_l16||g.exports._hsl_l16;_(0,u,t,i),_=g.exports.blurMono16||g.exports._blurMono16,_(u,h,p,f,m,t,i,a),_=g.exports.unsharp||g.exports._unsharp,_(0,0,u,h,t,i,n,r),v.set(new Uint32Array(this.__memory.buffer,0,o))}}},{}],22:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABMQZgAXwBfGACfX8AYAZ/f39/f38AYAh/f39/f39/fQBgBH9/f38AYAh/f39/f39/fwACGQIDZW52A2V4cAAAA2VudgZtZW1vcnkCAAEDBgUBAgMEBQQEAXAAAAdMBRZfX2J1aWxkX2dhdXNzaWFuX2NvZWZzAAEOX19nYXVzczE2X2xpbmUAAgpibHVyTW9ubzE2AAMHaHNsX2wxNgAEB3Vuc2hhcnAABQkBAAqJEAXZAQEGfAJAIAFE24a6Q4Ia+z8gALujIgOaEAAiBCAEoCIGtjgCECABIANEAAAAAAAAAMCiEAAiBbaMOAIUIAFEAAAAAAAA8D8gBKEiAiACoiAEIAMgA6CiRAAAAAAAAPA/oCAFoaMiArY4AgAgASAEIANEAAAAAAAA8L+gIAKioiIHtjgCBCABIAQgA0QAAAAAAADwP6AgAqKiIgO2OAIIIAEgBSACoiIEtow4AgwgASACIAegIAVEAAAAAAAA8D8gBqGgIgKjtjgCGCABIAMgBKEgAqO2OAIcCwu3AwMDfwR9CHwCQCADKgIUIQkgAyoCECEKIAMqAgwhCyADKgIIIQwCQCAEQX9qIgdBAEgiCA0AIAIgAC8BALgiDSADKgIYu6IiDiAJuyIQoiAOIAq7IhGiIA0gAyoCBLsiEqIgAyoCALsiEyANoqCgoCIPtjgCACACQQRqIQIgAEECaiEAIAdFDQAgBCEGA0AgAiAOIBCiIA8iDiARoiANIBKiIBMgAC8BALgiDaKgoKAiD7Y4AgAgAkEEaiECIABBAmohACAGQX9qIgZBAUoNAAsLAkAgCA0AIAEgByAFbEEBdGogAEF+ai8BACIIuCINIAu7IhGiIA0gDLsiEqKgIA0gAyoCHLuiIg4gCrsiE6KgIA4gCbsiFKKgIg8gAkF8aioCALugqzsBACAHRQ0AIAJBeGohAiAAQXxqIQBBACAFQQF0ayEHIAEgBSAEQQF0QXxqbGohBgNAIAghAyAALwEAIQggBiANIBGiIAO4Ig0gEqKgIA8iECAToqAgDiAUoqAiDyACKgIAu6CrOwEAIAYgB2ohBiAAQX5qIQAgAkF8aiECIBAhDiAEQX9qIgRBAUoNAAsLCwvfAgIDfwZ8AkAgB0MAAAAAWw0AIARE24a6Q4Ia+z8gB0MAAAA/l7ujIgyaEAAiDSANoCIPtjgCECAEIAxEAAAAAAAAAMCiEAAiDraMOAIUIAREAAAAAAAA8D8gDaEiCyALoiANIAwgDKCiRAAAAAAAAPA/oCAOoaMiC7Y4AgAgBCANIAxEAAAAAAAA8L+gIAuioiIQtjgCBCAEIA0gDEQAAAAAAADwP6AgC6KiIgy2OAIIIAQgDiALoiINtow4AgwgBCALIBCgIA5EAAAAAAAA8D8gD6GgIgujtjgCGCAEIAwgDaEgC6O2OAIcIAYEQCAFQQF0IQogBiEJIAIhCANAIAAgCCADIAQgBSAGEAIgACAKaiEAIAhBAmohCCAJQX9qIgkNAAsLIAVFDQAgBkEBdCEIIAUhAANAIAIgASADIAQgBiAFEAIgAiAIaiECIAFBAmohASAAQX9qIgANAAsLC7wBAQV/IAMgAmwiAwRAQQAgA2shBgNAIAAoAgAiBEEIdiIHQf8BcSECAn8gBEH/AXEiAyAEQRB2IgRB/wFxIgVPBEAgAyIIIAMgAk8NARoLIAQgBCAHIAIgA0kbIAIgBUkbQf8BcQshCAJAIAMgAk0EQCADIAVNDQELIAQgByAEIAMgAk8bIAIgBUsbQf8BcSEDCyAAQQRqIQAgASADIAhqQYECbEEBdjsBACABQQJqIQEgBkEBaiIGDQALCwvTBgEKfwJAIAazQwAAgEWUQwAAyEKVu0QAAAAAAADgP6CqIQ0gBSAEbCILBEAgB0GBAmwhDgNAQQAgAi8BACADLwEAayIGQQF0IgdrIAcgBkEASBsgDk8EQCAAQQJqLQAAIQUCfyAALQAAIgYgAEEBai0AACIESSIJRQRAIAYiCCAGIAVPDQEaCyAFIAUgBCAEIAVJGyAGIARLGwshCAJ/IAYgBE0EQCAGIgogBiAFTQ0BGgsgBSAFIAQgBCAFSxsgCRsLIgogCGoiD0GBAmwiEEEBdiERQQAhDAJ/QQAiCSAIIApGDQAaIAggCmsiCUH/H2wgD0H+AyAIayAKayAQQYCABEkbbSEMIAYgCEYEQCAEIAVrQf//A2wgCUEGbG0MAQsgBSAGayAGIARrIAQgCEYiBhtB//8DbCAJQQZsbUHVqgFBqtUCIAYbagshCSARIAcgDWxBgBBqQQx1aiIGQQAgBkEAShsiBkH//wMgBkH//wNIGyEGAkACfwJAIAxB//8DcSIFBEAgBkH//wFKDQEgBUGAIGogBmxBgBBqQQx2DAILIAZBCHYiBiEFIAYhBAwCCyAFIAZB//8Dc2xBgBBqQQx2IAZqCyIFQQh2IQcgBkEBdCAFa0EIdiIGIQQCQCAJQdWqAWpB//8DcSIFQanVAksNACAFQf//AU8EQEGq1QIgBWsgByAGa2xBBmxBgIACakEQdiAGaiEEDAELIAchBCAFQanVAEsNACAFIAcgBmtsQQZsQYCAAmpBEHYgBmohBAsCfyAGIgUgCUH//wNxIghBqdUCSw0AGkGq1QIgCGsgByAGa2xBBmxBgIACakEQdiAGaiAIQf//AU8NABogByIFIAhBqdUASw0AGiAIIAcgBmtsQQZsQYCAAmpBEHYgBmoLIQUgCUGr1QJqQf//A3EiCEGp1QJLDQAgCEH//wFPBEBBqtUCIAhrIAcgBmtsQQZsQYCAAmpBEHYgBmohBgwBCyAIQanVAEsEQCAHIQYMAQsgCCAHIAZrbEEGbEGAgAJqQRB2IAZqIQYLIAEgBDoAACABQQFqIAU6AAAgAUECaiAGOgAACyADQQJqIQMgAkECaiECIABBBGohACABQQRqIQEgC0F/aiILDQALCwsL"},{}],23:[function(e,t,i){"use strict";var n;t.exports=function(){if(void 0!==n)return n;if(n=!1,"undefined"==typeof WebAssembly)return n;try{var e=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11]),t=new WebAssembly.Module(e);return 0!==new WebAssembly.Instance(t,{}).exports.test(4)&&(n=!0),n}catch(e){}return n}},{}],24:[function(e,t,i){"use strict";function n(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}var a=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;t.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},i=0;i<10;i++)t["_"+String.fromCharCode(i)]=i;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(e){n[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var i,s,l=n(e),c=1;c<arguments.length;c++){i=Object(arguments[c]);for(var d in i)r.call(i,d)&&(l[d]=i[d]);if(a){s=a(i);for(var u=0;u<s.length;u++)o.call(i,s[u])&&(l[s[u]]=i[s[u]])}}return l}},{}],25:[function(e,t,i){var n=arguments[3],a=arguments[4],r=arguments[5],o=JSON.stringify;t.exports=function(e,t){function i(e){g[e]=!0;for(var t in a[e][1]){var n=a[e][1][t];g[n]||i(n)}}for(var s,l=Object.keys(r),c=0,d=l.length;c<d;c++){var u=l[c],h=r[u].exports;if(h===e||h&&h.default===e){s=u;break}}if(!s){s=Math.floor(Math.pow(16,8)*Math.random()).toString(16);for(var p={},c=0,d=l.length;c<d;c++){var u=l[c];p[u]=u}a[s]=["function(require,module,exports){"+e+"(self); }",p]}var f=Math.floor(Math.pow(16,8)*Math.random()).toString(16),m={};m[s]=s,a[f]=["function(require,module,exports){var f = require("+o(s)+");(f.default ? f.default : f)(self);}",m];var g={};i(f);var v="("+n+")({"+Object.keys(g).map(function(e){return o(e)+":["+a[e][0]+","+o(a[e][1])+"]"}).join(",")+"},{},["+o(f)+"])",_=window.URL||window.webkitURL||window.mozURL||window.msURL,b=new Blob([v],{type:"text/javascript"});if(t&&t.bare)return b;var w=_.createObjectURL(b),y=new Worker(w);return y.objectURL=w,y}},{}],"/":[function(e,t,i){"use strict";function n(e,t){return o(e)||r(e,t)||a()}function a(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function r(e,t){var i=[],n=!0,a=!1,r=void 0;try{for(var o,s=e[Symbol.iterator]();!(n=(o=s.next()).done)&&(i.push(o.value),!t||i.length!==t);n=!0);}catch(e){a=!0,r=e}finally{try{n||null==s.return||s.return()}finally{if(a)throw r}}return i}function o(e){if(Array.isArray(e))return e}function s(){return{value:d(f),destroy:function(){if(this.value.terminate(),"undefined"!=typeof window){var e=window.URL||window.webkitURL||window.mozURL||window.msURL;e&&e.revokeObjectURL&&this.value.objectURL&&e.revokeObjectURL(this.value.objectURL)}}}}function l(e){if(!(this instanceof l))return new l(e);this.options=c({},C,e||{});var t="lk_".concat(this.options.concurrency);this.__limit=v[t]||p.limiter(this.options.concurrency),v[t]||(v[t]=this.__limit),this.features={js:!1,wasm:!1,cib:!1,ww:!1},this.__workersPool=null,this.__requested_features=[],this.__mathlib=null}var c=e("object-assign"),d=e("webworkify"),u=e("./lib/mathlib"),h=e("./lib/pool"),p=e("./lib/utils"),f=e("./lib/worker"),m=e("./lib/stepper"),g=e("./lib/tiler"),v={},_=!1;try{"undefined"!=typeof navigator&&navigator.userAgent&&(_=navigator.userAgent.indexOf("Safari")>=0)}catch(e){}var b=1;"undefined"!=typeof navigator&&(b=Math.min(navigator.hardwareConcurrency||1,4));var w,y,C={tile:1024,concurrency:b,features:["js","wasm","ww"],idle:2e3},E={quality:3,alpha:!1,unsharpAmount:0,unsharpRadius:0,unsharpThreshold:0};l.prototype.init=function(){var t=this;if(this.__initPromise)return this.__initPromise;if(!1!==w&&!0!==w&&(w=!1,"undefined"!=typeof ImageData&&"undefined"!=typeof Uint8ClampedArray))try{new ImageData(new Uint8ClampedArray(400),10,10),w=!0}catch(e){}!1!==y&&!0!==y&&(y=!1,"undefined"!=typeof ImageBitmap&&(ImageBitmap.prototype&&ImageBitmap.prototype.close?y=!0:this.debug("ImageBitmap does not support .close(), disabled")));var i=this.options.features.slice();if(i.indexOf("all")>=0&&(i=["cib","wasm","js","ww"]),this.__requested_features=i,this.__mathlib=new u(i),i.indexOf("ww")>=0&&"undefined"!=typeof window&&"Worker"in window)try{e("webworkify")(function(){}).terminate(),this.features.ww=!0;var n="wp_".concat(JSON.stringify(this.options));v[n]?this.__workersPool=v[n]:(this.__workersPool=new h(s,this.options.idle),v[n]=this.__workersPool)}catch(e){}var a,r=this.__mathlib.init().then(function(e){c(t.features,e.features)});return a=y?p.cib_support().then(function(e){if(t.features.cib&&i.indexOf("cib")<0)return void t.debug("createImageBitmap() resize supported, but disabled by config");i.indexOf("cib")>=0&&(t.features.cib=e)}):Promise.resolve(!1),this.__initPromise=Promise.all([r,a]).then(function(){return t}),this.__initPromise},l.prototype.resize=function(e,t,i){var a=this;this.debug("Start resize...");var r=c({},E);if(isNaN(i)?i&&(r=c(r,i)):r=c(r,{quality:i}),r.toWidth=t.width,r.toHeight=t.height,r.width=e.naturalWidth||e.width,r.height=e.naturalHeight||e.height,0===t.width||0===t.height)return Promise.reject(new Error("Invalid output size: ".concat(t.width,"x").concat(t.height)));r.unsharpRadius>2&&(r.unsharpRadius=2);var o=!1,s=null;r.cancelToken&&(s=r.cancelToken.then(function(e){throw o=!0,e},function(e){throw o=!0,e}));var l=Math.ceil(Math.max(3,2.5*r.unsharpRadius|0));return this.init().then(function(){if(o)return s;if(a.features.cib){var i=t.getContext("2d",{alpha:Boolean(r.alpha)});return a.debug("Resize via createImageBitmap()"),createImageBitmap(e,{resizeWidth:r.toWidth,resizeHeight:r.toHeight,resizeQuality:p.cib_quality_name(r.quality)}).then(function(e){if(o)return s;if(!r.unsharpAmount)return i.drawImage(e,0,0),e.close(),i=null,a.debug("Finished!"),t;a.debug("Unsharp result");var n=document.createElement("canvas");n.width=r.toWidth,n.height=r.toHeight;var l=n.getContext("2d",{alpha:Boolean(r.alpha)});l.drawImage(e,0,0),e.close();var c=l.getImageData(0,0,r.toWidth,r.toHeight);return a.__mathlib.unsharp(c.data,r.toWidth,r.toHeight,r.unsharpAmount,r.unsharpRadius,r.unsharpThreshold),i.putImageData(c,0,0),c=l=n=i=null,a.debug("Finished!"),t})}var d={},u=function(e){return Promise.resolve().then(function(){return a.features.ww?new Promise(function(t,i){var n=a.__workersPool.acquire();s&&s.catch(function(e){return i(e)}),n.value.onmessage=function(e){n.release(),e.data.err?i(e.data.err):t(e.data.result)},n.value.postMessage({opts:e,features:a.__requested_features,preload:{wasm_nodule:a.__mathlib.__}},[e.src.buffer])}):a.__mathlib.resizeAndUnsharp(e,d)})},h=function(e,t,i){var n,r,c,d=function(t){return a.__limit(function(){if(o)return s;var l;if(p.isCanvas(e))a.debug("Get tile pixel data"),l=n.getImageData(t.x,t.y,t.width,t.height);else{a.debug("Draw tile imageBitmap/image to temporary canvas");var d=document.createElement("canvas");d.width=t.width,d.height=t.height;var h=d.getContext("2d",{alpha:Boolean(i.alpha)});h.globalCompositeOperation="copy",h.drawImage(r||e,t.x,t.y,t.width,t.height,0,0,t.width,t.height),a.debug("Get tile pixel data"),l=h.getImageData(0,0,t.width,t.height),h=d=null}var f={src:l.data,width:t.width,height:t.height,toWidth:t.toWidth,toHeight:t.toHeight,scaleX:t.scaleX,scaleY:t.scaleY,offsetX:t.offsetX,offsetY:t.offsetY,quality:i.quality,alpha:i.alpha,unsharpAmount:i.unsharpAmount,unsharpRadius:i.unsharpRadius,unsharpThreshold:i.unsharpThreshold};return a.debug("Invoke resize math"),Promise.resolve().then(function(){return u(f)}).then(function(e){if(o)return s;l=null;var i;if(a.debug("Convert raw rgba tile result to ImageData"),w)i=new ImageData(new Uint8ClampedArray(e),t.toWidth,t.toHeight);else if(i=c.createImageData(t.toWidth,t.toHeight),i.data.set)i.data.set(e);else for(var n=i.data.length-1;n>=0;n--)i.data[n]=e[n];return a.debug("Draw tile"),_?c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth+1e-5,t.toInnerHeight+1e-5):c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth,t.toInnerHeight),null})})};return Promise.resolve().then(function(){if(c=t.getContext("2d",{alpha:Boolean(i.alpha)}),p.isCanvas(e))return n=e.getContext("2d",{alpha:Boolean(i.alpha)}),null;if(p.isImage(e))return y?(a.debug("Decode image via createImageBitmap"),createImageBitmap(e).then(function(e){r=e})):null;throw new Error('".from" should be image or canvas')}).then(function(){function e(){r&&(r.close(),r=null)}if(o)return s;a.debug("Calculate tiles");var n=g({width:i.width,height:i.height,srcTileSize:a.options.tile,toWidth:i.toWidth,toHeight:i.toHeight,destTileBorder:l}),c=n.map(function(e){return d(e)});return a.debug("Process tiles"),Promise.all(c).then(function(){return a.debug("Finished!"),e(),t},function(t){throw e(),t})})},f=m(r.width,r.height,r.toWidth,r.toHeight,a.options.tile,l);return function e(t,i,a,r){if(o)return s;var l=t.shift(),d=n(l,2),u=d[0],p=d[1],f=0===t.length;r=c({},r,{toWidth:u,toHeight:p,quality:f?r.quality:Math.min(1,r.quality)});var m;return f||(m=document.createElement("canvas"),m.width=u,m.height=p),h(i,f?a:m,r).then(function(){return f?a:(r.width=u,r.height=p,e(t,m,a,r))})}(f,e,t,r)})},l.prototype.resizeBuffer=function(e){var t=this,i=c({},E,e);return this.init().then(function(){return t.__mathlib.resizeAndUnsharp(i)})},l.prototype.toBlob=function(e,t,i){return t=t||"image/png",new Promise(function(n){if(e.toBlob)return void e.toBlob(function(e){return n(e)},t,i);for(var a=atob(e.toDataURL(t,i).split(",")[1]),r=a.length,o=new Uint8Array(r),s=0;s<r;s++)o[s]=a.charCodeAt(s);n(new Blob([o],{type:t}))})},l.prototype.debug=function(){},t.exports=l},{"./lib/mathlib":1,"./lib/pool":9,"./lib/stepper":10,"./lib/tiler":11,"./lib/utils":12,"./lib/worker":13,"object-assign":24,webworkify:25}]},{},[])("/")}),define("WoltLabSuite/Core/Image/Resizer",["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ExifUtil","Pica"],function(e,t,i){"use strict";function n(){}var a=new i({features:["js","wasm","ww"]
-});return n.prototype={maxWidth:800,maxHeight:600,quality:.8,fileType:"image/jpeg",setMaxWidth:function(e){return null==e&&(e=n.prototype.maxWidth),this.maxWidth=e,this},setMaxHeight:function(e){return null==e&&(e=n.prototype.maxHeight),this.maxHeight=e,this},setQuality:function(e){return null==e&&(e=n.prototype.quality),this.quality=e,this},setFileType:function(e){return null==e&&(e=n.prototype.fileType),this.fileType=e,this},saveFile:function(i,n,r,o){r=r||this.fileType,o=o||this.quality;var s=n.match(/(.+)(\..+?)$/);return a.toBlob(i.image,r,o).then(function(e){return"image/jpeg"===r&&void 0!==i.exif?t.setExifData(e,i.exif):e}).then(function(t){return e.blobToFile(t,s[1]+"_autoscaled")})},loadFile:function(e){var i=void 0,n=Promise.resolve(e);"image/jpeg"===e.type&&(i=t.getExifBytesFromJpeg(e),n=n.then(t.removeExifData.bind(t)));var n=n.then(function(e){return new Promise(function(t,i){var n=new FileReader,a=new Image;n.addEventListener("load",function(){a.src=n.result}),n.addEventListener("error",function(){n.abort(),i(n.error)}),a.addEventListener("error",i),a.addEventListener("load",function(){t(a)}),n.readAsDataURL(e)})});return Promise.all([i,n]).then(function(e){return{exif:e[0],image:e[1]}})},resize:function(e,t,i,n,r,o){t=t||this.maxWidth,i=i||this.maxHeight,n=n||this.quality,r=r||!1;var s=document.createElement("canvas"),l=window.createImageBitmap?createImageBitmap(e).then(function(t){if(t.height!=e.height)throw new Error("Chrome Bug #1069965")}):Promise.resolve(),c=Math.min(t,e.width),d=Math.min(i,e.height);if(e.width<=c&&e.height<=d&&!r)return Promise.resolve(void 0);var u=Math.min(c/e.width,d/e.height);s.width=Math.floor(e.width*u),s.height=Math.floor(e.height*u);var h=1;n>=.8?h=3:n>=.4&&(h=2);var p={quality:h,cancelToken:o,alpha:!0};return l.then(function(){return a.resize(e,s,p)})}},n}),define("WoltLabSuite/Core/Language/Chooser",["Core","Dictionary","Language","Dom/Traverse","Dom/Util","ObjectMap","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";var s=new t,l=!1,c=new r,d=null;return{init:function(e,t,i,n,a,r){if(!s.has(t)){var o=elById(e);if(null===o)throw new Error("Expected a valid container id, cannot find '"+t+"'.");var l=elById(t);null===l&&(l=elCreate("input"),elAttr(l,"type","hidden"),elAttr(l,"id",t),elAttr(l,"name",t),elAttr(l,"value",i),o.appendChild(l)),this._initElement(t,l,i,n,a,r)}},_setup:function(){l||(l=!0,d=this._submit.bind(this))},_initElement:function(e,t,r,l,u,h){var p;"DD"===t.parentNode.nodeName?(p=elCreate("div"),p.className="dropdown",a.prepend(p,t.parentNode)):(p=t.parentNode,p.classList.add("dropdown")),elHide(t);var f=elCreate("a");f.className="dropdownToggle dropdownIndicator boxFlag box24 inputPrefix"+("DD"===t.parentNode.nodeName?" button":""),p.appendChild(f);var m=elCreate("ul");m.className="dropdownMenu",p.appendChild(m);var g,v,_,b,w=function(t){var i=~~elData(t.currentTarget,"language-id"),a=n.childByClass(m,"active");null!==a&&a.classList.remove("active"),i&&t.currentTarget.classList.add("active"),this._select(e,i,t.currentTarget)}.bind(this);for(var y in l)if(l.hasOwnProperty(y)){var C=l[y];_=elCreate("li"),_.className="boxFlag",_.addEventListener(WCF_CLICK_EVENT,w),elData(_,"language-id",y),void 0!==C.languageCode&&elData(_,"language-code",C.languageCode),m.appendChild(_),g=elCreate("a"),g.className="box24",_.appendChild(g),v=elCreate("img"),elAttr(v,"src",C.iconPath),elAttr(v,"alt",""),v.className="iconFlag",g.appendChild(v),b=elCreate("span"),b.textContent=C.languageName,g.appendChild(b),y==r&&(f.innerHTML=_.firstChild.innerHTML)}if(h)_=elCreate("li"),_.className="dropdownDivider",m.appendChild(_),_=elCreate("li"),elData(_,"language-id",0),_.addEventListener(WCF_CLICK_EVENT,w),m.appendChild(_),g=elCreate("a"),g.textContent=i.get("wcf.global.language.noSelection"),_.appendChild(g),0===r&&(f.innerHTML=_.firstChild.innerHTML),_.addEventListener(WCF_CLICK_EVENT,w);else if(0===r){f.innerHTML=null;var E=elCreate("div");f.appendChild(E),b=elCreate("span"),b.className="icon icon24 fa-question pointer",E.appendChild(b),b=elCreate("span"),b.textContent=i.get("wcf.global.language.noSelection"),E.appendChild(b)}o.init(f),s.set(e,{callback:u,dropdownMenu:m,dropdownToggle:f,element:t});var L=n.parentByTag(t,"FORM");if(null!==L){L.addEventListener("submit",d);var S=c.get(L);void 0===S&&(S=[],c.set(L,S)),S.push(e)}},_select:function(t,i,n){var a=s.get(t);if(void 0===n){for(var r=a.dropdownMenu.childNodes,o=0,l=r.length;o<l;o++){var c=r[o];if(~~elData(c,"language-id")===i){n=c;break}}if(void 0===n)throw new Error("Cannot select unknown language id '"+i+"'")}a.element.value=i,e.triggerEvent(a.element,"change"),a.dropdownToggle.innerHTML=n.firstChild.innerHTML,s.set(t,a),"function"==typeof a.callback&&a.callback(n)},_submit:function(e){for(var t,i=c.get(e.currentTarget),n=0,a=i.length;n<a;n++)t=elCreate("input"),t.type="hidden",t.name=i[n],t.value=this.getLanguageId(i[n]),e.currentTarget.appendChild(t)},getChooser:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid language chooser input element, '"+e+"' is not i18n input field.");return t},getLanguageId:function(e){return~~this.getChooser(e).element.value},removeChooser:function(e){s.has(e)&&s.delete(e)},setLanguageId:function(e,t){if(void 0===s.get(e))throw new Error("Expected a valid  input element, '"+e+"' is not i18n input field.");this._select(e,t)}}}),define("WoltLabSuite/Core/Language/Input",["Core","Dictionary","Language","ObjectMap","StringUtil","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o,s){"use strict";var l=new t,c=!1,d=new n,u=new t,h=null,p=null;return{init:function(e,i,n,r){if(!u.has(e)){var o=elById(e);if(null===o)throw new Error("Expected a valid element id, cannot find '"+e+"'.");this._setup();var s=new t;for(var l in i)i.hasOwnProperty(l)&&s.set(~~l,a.unescapeHTML(i[l]));u.set(e,s),this._initElement(e,o,s,n,r)}},registerCallback:function(e,t,i){if(!u.has(e))throw new Error("Unknown element id '"+e+"'.");l.get(e).callbacks.set(t,i)},unregister:function(e){if(!u.has(e))throw new Error("Unknown element id '"+e+"'.");u.delete(e),l.delete(e)},_setup:function(){c||(c=!0,h=this._dropdownToggle.bind(this),p=this._submit.bind(this))},_initElement:function(e,n,a,c,u){var f=n.parentNode;if(!f.classList.contains("inputAddon")){f=elCreate("div"),f.className="inputAddon"+("TEXTAREA"===n.nodeName?" inputAddonTextarea":""),elData(f,"input-id",e);var m=document.activeElement===n;n.parentNode.insertBefore(f,n),f.appendChild(n),m&&n.focus()}f.classList.add("dropdown");var g=elCreate("span");g.className="button dropdownToggle inputPrefix";var v=elCreate("span");v.textContent=i.get("wcf.global.button.disabledI18n"),g.appendChild(v),f.insertBefore(g,n);var _=elCreate("ul");_.className="dropdownMenu",o.insertAfter(_,g);var b,w=function(t,i){var n=~~elData(t.currentTarget,"language-id"),a=r.childByClass(_,"active");null!==a&&a.classList.remove("active"),n&&t.currentTarget.classList.add("active"),this._select(e,n,i||!1)}.bind(this);for(var y in c)c.hasOwnProperty(y)&&(b=elCreate("li"),elData(b,"language-id",y),v=elCreate("span"),v.textContent=c[y],b.appendChild(v),b.addEventListener(WCF_CLICK_EVENT,w),_.appendChild(b));!0!==u&&(b=elCreate("li"),b.className="dropdownDivider",_.appendChild(b),b=elCreate("li"),elData(b,"language-id",0),v=elCreate("span"),v.textContent=i.get("wcf.global.button.disabledI18n"),b.appendChild(v),b.addEventListener(WCF_CLICK_EVENT,w),_.appendChild(b));var C=null;if(!0===u||a.size)for(var E=0,L=_.childElementCount;E<L;E++)if(~~elData(_.children[E],"language-id")===LANGUAGE_ID){C=_.children[E];break}s.init(g),s.registerCallback(f.id,h),l.set(e,{buttonLabel:g.children[0],callbacks:new t,element:n,languageId:0,isEnabled:!0,forceSelection:u});var S=r.parentByTag(n,"FORM");if(null!==S){S.addEventListener("submit",p);var A=d.get(S);void 0===A&&(A=[],d.set(S,A)),A.push(e)}null!==C&&w({currentTarget:C},!0)},_select:function(e,i,n){for(var a,r=l.get(e),o=s.getDropdownMenu(r.element.closest(".inputAddon").id),c="",d=0,h=o.childElementCount;d<h;d++){a=o.children[d];var p=elData(a,"language-id");p.length&&i===~~p&&(c=a.children[0].textContent)}if(r.languageId!==i){var f=u.get(e);r.languageId&&f.set(r.languageId,r.element.value),0===i?u.set(e,new t):(r.buttonLabel.classList.contains("active")||!0===n)&&(r.element.value=f.has(i)?f.get(i):""),r.buttonLabel.textContent=c,r.buttonLabel.classList[i?"add":"remove"]("active"),r.languageId=i}n||(r.element.blur(),r.element.focus()),r.callbacks.has("select")&&r.callbacks.get("select")(r.element)},_dropdownToggle:function(e,t){if("open"===t)for(var i,n,a=s.getDropdownMenu(e),r=elData(elById(e),"input-id"),o=l.get(r),c=u.get(r),d=0,h=a.childElementCount;d<h;d++)if(i=a.children[d],n=~~elData(i,"language-id")){var p=!1;o.languageId&&(p=n===o.languageId?""===o.element.value.trim():!c.get(n)),i.classList[p?"add":"remove"]("missingValue")}},_submit:function(e){for(var t,i,n,a,r=d.get(e.currentTarget),o=0,s=r.length;o<s;o++)i=r[o],t=l.get(i),t.isEnabled&&(a=u.get(i),t.callbacks.has("submit")&&t.callbacks.get("submit")(t.element),t.languageId&&a.set(t.languageId,t.element.value),a.size&&(a.forEach(function(t,a){n=elCreate("input"),n.type="hidden",n.name=i+"_i18n["+a+"]",n.value=t,e.currentTarget.appendChild(n)}),t.element.removeAttribute("name")))},getValues:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");var i=u.get(e);return i.set(t.languageId,t.element.value),i},setValues:function(i,n){var a=l.get(i);if(void 0===a)throw new Error("Expected a valid i18n input element, '"+i+"' is not i18n input field.");if(e.isPlainObject(n)&&(n=t.fromObject(n)),a.element.value="",n.has(0))return a.element.value=n.get(0),n.delete(0),u.set(i,n),void this._select(i,0,!0);u.set(i,n),a.languageId=0,this._select(i,LANGUAGE_ID,!0)},disable:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid element, '"+e+"' is not an i18n input field.");if(t.isEnabled){t.isEnabled=!1,elHide(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.remove("inputAddon"),i.classList.remove("dropdown")}},enable:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!t.isEnabled){t.isEnabled=!0,elShow(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.add("inputAddon"),i.classList.add("dropdown")}},isEnabled:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");return t.isEnabled},validate:function(e,t){var i=l.get(e);if(void 0===i)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!i.isEnabled)return!0;var n=u.get(e),a=s.getDropdownMenu(i.element.parentNode.id);i.languageId&&n.set(i.languageId,i.element.value);for(var r,o,c=!1,d=!1,h=0,p=a.childElementCount;h<p;h++)if(r=a.children[h],o=~~elData(r,"language-id"))if(n.has(o)&&0!==n.get(o).length){if(c)return!1;d=!0}else{if(d)return!1;c=!0}return!c||t}}}),define("WoltLabSuite/Core/Language/Text",["Core","./Input"],function(e,t){"use strict";return{init:function(e,i,n,a){var r=elById(e);if(!r||"TEXTAREA"!==r.nodeName||!r.classList.contains("wysiwygTextarea"))throw new Error('Expected <textarea class="wysiwygTextarea" /> for id \''+e+"'.");t.init(e,i,n,a),t.registerCallback(e,"select",this._callbackSelect.bind(this)),t.registerCallback(e,"submit",this._callbackSubmit.bind(this))},_callbackSelect:function(e){void 0!==window.jQuery&&window.jQuery(e).redactor("code.set",e.value)},_callbackSubmit:function(e){void 0!==window.jQuery&&(e.value=window.jQuery(e).redactor("code.get"))}}}),define("WoltLabSuite/Core/Media/Editor",["Ajax","Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Language/Chooser","WoltLabSuite/Core/Language/Input","EventKey"],function(e,t,i,n,a,r,o,s,l,c,d){"use strict";function u(e){if(this._callbackObject=e||{},this._callbackObject._editorClose&&"function"!=typeof this._callbackObject._editorClose)throw new TypeError("Callback object has no function '_editorClose'.");if(this._callbackObject._editorSuccess&&"function"!=typeof this._callbackObject._editorSuccess)throw new TypeError("Callback object has no function '_editorSuccess'.");this._media=null,this._availableLanguageCount=1,this._categoryIds=[],this._oldCategoryId=0,this._dialogs=new i}return u.prototype={_ajaxSetup:function(){return{data:{actionName:"update",className:"wcf\\data\\media\\MediaAction"}}},_ajaxSuccess:function(e){s.show(),this._callbackObject._editorSuccess&&(this._callbackObject._editorSuccess(this._media,this._oldCategoryId),this._oldCategoryId=0),o.close("mediaEditor_"+this._media.mediaID),this._media=null},_close:function(){this._media=null,this._callbackObject._editorClose&&this._callbackObject._editorClose()},_keyPress:function(e){d.Enter(e)&&(e.preventDefault(),this._saveData())},_saveData:function(){var t=o.getDialog("mediaEditor_"+this._media.mediaID).content,i=elBySel("select[name=categoryID]",t),n=elBySel("input[name=altText]",t),s=elBySel("textarea[name=caption]",t),d=elBySel("input[name=captionEnableHtml]",t),u=elBySel("input[name=title]",t),h=!1,p=!!n&&a.childByClass(n.parentNode.parentNode,"innerError"),f=!!s&&a.childByClass(s.parentNode.parentNode,"innerError"),m=a.childByClass(u.parentNode.parentNode,"innerError");if(this._oldCategoryId=this._media.categoryID,this._categoryIds.length&&(this._media.categoryID=~~i.value,-1===this._categoryIds.indexOf(this._media.categoryID)&&(this._media.categoryID=0)),this._availableLanguageCount>1?(this._media.isMultilingual=~~elBySel("input[name=isMultilingual]",t).checked,this._media.languageID=this._media.isMultilingual?null:l.getLanguageId("mediaEditor_"+this._media.mediaID+"_languageID")):this._media.languageID=LANGUAGE_ID,this._media.altText={},this._media.caption={},this._media.title={},this._availableLanguageCount>1&&this._media.isMultilingual){if(elById("altText_"+this._media.mediaID)&&!c.validate("altText_"+this._media.mediaID,!0)&&(h=!0,!p)){var g=elCreate("small");g.className="innerError",g.textContent=r.get("wcf.global.form.error.multilingual"),n.parentNode.parentNode.appendChild(g)}if(elById("caption_"+this._media.mediaID)&&!c.validate("caption_"+this._media.mediaID,!0)&&(h=!0,!f)){var g=elCreate("small");g.className="innerError",g.textContent=r.get("wcf.global.form.error.multilingual"),s.parentNode.parentNode.appendChild(g)}if(!c.validate("title_"+this._media.mediaID,!0)&&(h=!0,!m)){var g=elCreate("small");g.className="innerError",g.textContent=r.get("wcf.global.form.error.multilingual"),u.parentNode.parentNode.appendChild(g)}this._media.altText=elById("altText_"+this._media.mediaID)?c.getValues("altText_"+this._media.mediaID).toObject():"",this._media.caption=elById("caption_"+this._media.mediaID)?c.getValues("caption_"+this._media.mediaID).toObject():"",this._media.title=c.getValues("title_"+this._media.mediaID).toObject()}else this._media.altText[this._media.languageID]=n?n.value:"",this._media.caption[this._media.languageID]=s?s.value:"",this._media.title[this._media.languageID]=u.value;this._media.captionEnableHtml=d?~~d.checked:0;for(var v={allowAll:~~elById("mediaEditor_"+this._media.mediaID+"_aclAllowAll").checked,group:[],user:[]},_=elBySelAll('input[name="mediaEditor_'+this._media.mediaID+'_aclValues[group][]"]',t),b=0,w=_.length;b<w;b++)v.group.push(~~_[b].value);for(var y=elBySelAll('input[name="mediaEditor_'+this._media.mediaID+'_aclValues[user][]"]',t),b=0,w=y.length;b<w;b++)v.user.push(~~y[b].value);h||(p&&elRemove(p),f&&elRemove(f),m&&elRemove(m),e.api(this,{actionName:"update",objectIDs:[this._media.mediaID],parameters:{aclValues:v,altText:this._media.altText,caption:this._media.caption,data:{captionEnableHtml:this._media.captionEnableHtml,categoryID:this._media.categoryID,isMultilingual:this._media.isMultilingual,languageID:this._media.languageID},title:this._media.title}}))},_updateLanguageFields:function(e,t){e&&(t=e.currentTarget);var i=elById("mediaEditor_"+this._media.mediaID+"_languageIDContainer").parentNode;t.checked?(c.enable("title_"+this._media.mediaID),elById("caption_"+this._media.mediaID)&&c.enable("caption_"+this._media.mediaID),elById("altText_"+this._media.mediaID)&&c.enable("altText_"+this._media.mediaID),elHide(i)):(c.disable("title_"+this._media.mediaID),elById("caption_"+this._media.mediaID)&&c.disable("caption_"+this._media.mediaID),elById("altText_"+this._media.mediaID)&&c.disable("altText_"+this._media.mediaID),elShow(i))},edit:function(e){if("object"!=typeof e&&(e={mediaID:~~e}),null!==this._media)throw new Error("Cannot edit media with id '"+e.mediaID+"' while editing media with id '"+this._media.mediaID+"'");this._media=e,this._dialogs.has("mediaEditor_"+e.mediaID)||this._dialogs.set("mediaEditor_"+e.mediaID,{_dialogSetup:function(){return{id:"mediaEditor_"+e.mediaID,options:{backdropCloseOnClick:!1,onClose:this._close.bind(this),title:r.get("wcf.media.edit")},source:{after:function(e,t){this._availableLanguageCount=~~t.returnValues.availableLanguageCount,this._categoryIds=t.returnValues.categoryIDs.map(function(e){return~~e});t.returnValues.mediaData&&(this._media=t.returnValues.mediaData),setTimeout(function(){this._availableLanguageCount>1&&l.setLanguageId("mediaEditor_"+this._media.mediaID+"_languageID",this._media.languageID||LANGUAGE_ID),this._categoryIds.length&&(elBySel("select[name=categoryID]",e).value=~~this._media.categoryID);var t=elBySel("input[name=title]",e),a=elBySel("input[name=altText]",e),r=elBySel("textarea[name=caption]",e);if(this._availableLanguageCount>1&&this._media.isMultilingual?(elById("altText_"+this._media.mediaID)&&c.setValues("altText_"+this._media.mediaID,i.fromObject(this._media.altText||{})),elById("caption_"+this._media.mediaID)&&c.setValues("caption_"+this._media.mediaID,i.fromObject(this._media.caption||{})),c.setValues("title_"+this._media.mediaID,i.fromObject(this._media.title||{}))):(t.value=this._media.title?this._media.title[this._media.languageID||LANGUAGE_ID]:"",a&&(a.value=this._media.altText?this._media.altText[this._media.languageID||LANGUAGE_ID]:""),r&&(r.value=this._media.caption?this._media.caption[this._media.languageID||LANGUAGE_ID]:"")),this._availableLanguageCount>1){var o=elBySel("input[name=isMultilingual]",e);o.addEventListener("change",this._updateLanguageFields.bind(this)),this._updateLanguageFields(null,o)}var s=this._keyPress.bind(this);a&&a.addEventListener("keypress",s),t.addEventListener("keypress",s),elBySel("button[data-type=submit]",e).addEventListener(WCF_CLICK_EVENT,this._saveData.bind(this)),document.activeElement.blur(),elById("mediaEditor_"+this._media.mediaID).parentNode.scrollTop=0,n.trigger()}.bind(this),200)}.bind(this),data:{actionName:"getEditorDialog",className:"wcf\\data\\media\\MediaAction",objectIDs:[e.mediaID]}}}}.bind(this)}),o.open(this._dialogs.get("mediaEditor_"+e.mediaID))}},u}),define("WoltLabSuite/Core/Media/Upload",["Core","DateUtil","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","Permission","Upload","User","WoltLabSuite/Core/FileUtil"],function(e,t,i,n,a,r,o,s,l,c,d){"use strict";function u(t,i,n){n=n||{},this._elementTagSize=144,n.elementTagSize&&(this._elementTagSize=n.elementTagSize),this._mediaManager=null,n.mediaManager&&(this._mediaManager=n.mediaManager,delete n.mediaManager),this._categoryId=null,l.call(this,t,i,e.extend({className:"wcf\\data\\media\\MediaAction",multiple:!!this._mediaManager,singleFileRequests:!0},n))}return e.inherit(u,l,{_createFileElement:function(e){var n;if("OL"===this._target.nodeName||"UL"===this._target.nodeName)n=elCreate("li");else{if("TBODY"===this._target.nodeName){var r=elByTag("TR",this._target)[0],s=this._target.parentNode.parentNode;"none"===s.style.getPropertyValue("display")?(n=r,s.style.removeProperty("display"),elRemove(elById(elData(this._target,"no-items-info")))):(n=r.cloneNode(!0),n.removeAttribute("id"),a.identify(n));for(var l,u=elByTag("TD",n),h=0,p=u.length;h<p;h++)if(l=u[h],l.classList.contains("columnMark"))elBySelAll("[data-object-id]",l,elHide);else if(l.classList.contains("columnIcon"))elBySelAll("[data-object-id]",l,elHide),elByClass("mediaEditButton",l)[0].classList.add("jsMediaEditButton"),elData(elByClass("jsDeleteButton",l)[0],"confirm-message-html",o.get("wcf.media.delete.confirmMessage",{title:e.name}));else if(l.classList.contains("columnFilename")){var f=elByTag("IMG",l);f.length||(f=elByClass("icon48",l));var m=elCreate("span");m.className="icon icon48 fa-spinner mediaThumbnail",a.replaceElement(f[0],m);var g=elBySelAll(".box48 > div > p",l);g[0].textContent=e.name;var v=elByTag("A",g[1])[0];v||(v=elCreate("a"),elByTag("SMALL",g[1])[0].appendChild(v)),v.setAttribute("href",c.getLink()),v.textContent=c.username}else l.classList.contains("columnUploadTime")?(l.innerHTML="",l.appendChild(t.getTimeElement(new Date))):l.classList.contains("columnDigits")?l.textContent=d.formatFilesize(e.size):l.innerHTML="";return a.prepend(n,this._target),n}n=elCreate("p")}var _=elCreate("div");_.className="mediaThumbnail",n.appendChild(_);var b=elCreate("span");b.className="icon icon144 fa-spinner",_.appendChild(b);var w=elCreate("div");w.className="mediaInformation",n.appendChild(w);var y=elCreate("p");y.className="mediaTitle",y.textContent=e.name,w.appendChild(y);var C=elCreate("progress");return elAttr(C,"max",100),w.appendChild(C),a.prepend(n,this._target),i.trigger(),n},_getParameters:function(){var t={elementTagSize:this._elementTagSize};if(this._mediaManager){t.imagesOnly=this._mediaManager.getOption("imagesOnly");var i=this._mediaManager.getCategoryId();i&&(t.categoryID=i)}return e.extend(u._super.prototype._getParameters.call(this),t)},_replaceFileIcon:function(e,t,i){if(t.elementTag)e.outerHTML=t.elementTag;else if(t.tinyThumbnailType){var n=elCreate("img");elAttr(n,"src",t.tinyThumbnailLink),elAttr(n,"alt",""),n.style.setProperty("width",i+"px"),n.style.setProperty("height",i+"px"),a.replaceElement(e,n)}else{e.classList.remove("fa-spinner");var r=d.getIconNameByFilename(t.filename);r&&(r="-"+r),e.classList.add("fa-file"+r+"-o")}},_success:function(e,t){for(var a=this._fileElements[e],s=0,l=a.length;s<l;s++){var c=a[s],d=elData(c,"internal-file-id"),u=t.returnValues.media[d];if("TR"===c.tagName)if(u){for(var h=elBySelAll("[data-object-id]",c),s=0,l=h.length;s<l;s++)elData(h[s],"object-id",~~u.mediaID),elShow(h[s]);elByClass("columnMediaID",c)[0].textContent=u.mediaID;var p=elByClass("fa-spinner",c)[0];this._replaceFileIcon(p,u,48)}else{var f=t.returnValues.errors[d];f||(f={errorType:"uploadFailed",filename:elData(c,"filename")});var p=elByClass("fa-spinner",c)[0];p.classList.remove("fa-spinner"),p.classList.add("fa-remove"),p.classList.add("pointer"),p.classList.add("jsTooltip"),elAttr(p,"title",o.get("wcf.global.button.delete")),p.addEventListener(WCF_CLICK_EVENT,function(e){elRemove(e.currentTarget.parentNode.parentNode.parentNode),r.fire("com.woltlab.wcf.media.upload","removedErroneousUploadRow")}),c.classList.add("uploadFailed");var m=elBySelAll(".columnFilename .box48 > div > p",c)[1];elInnerError(m,o.get("wcf.media.upload.error."+f.errorType,{filename:f.filename})),elRemove(m)}else if(elRemove(n.childByTag(n.childByClass(c,"mediaInformation"),"PROGRESS")),u){var p=n.childByTag(n.childByClass(c,"mediaThumbnail"),"SPAN");this._replaceFileIcon(p,u,144),c.className="jsClipboardObject mediaFile",elData(c,"object-id",u.mediaID),this._mediaManager&&(this._mediaManager.setupMediaElement(u,c),this._mediaManager.addMedia(u,c))}else{var f=t.returnValues.errors[d];f||(f={errorType:"uploadFailed",filename:elData(c,"filename")});var p=n.childByTag(n.childByClass(c,"mediaThumbnail"),"SPAN");p.classList.remove("fa-spinner"),p.classList.add("fa-remove"),p.classList.add("pointer"),c.classList.add("uploadFailed"),c.classList.add("jsTooltip"),elAttr(c,"title",o.get("wcf.global.button.delete")),c.addEventListener(WCF_CLICK_EVENT,function(){elRemove(this)});var g=n.childByClass(n.childByClass(c,"mediaInformation"),"mediaTitle");g.innerText=o.get("wcf.media.upload.error."+f.errorType,{filename:f.filename})}i.trigger()}r.fire("com.woltlab.wcf.media.upload","success",{files:a,isMultiFileUpload:-1!==this._multiFileUploadIds.indexOf(e),media:t.returnValues.media,upload:this,uploadId:e})},_uploadFiles:function(e,t){return u._super.prototype._uploadFiles.call(this,e,t)}}),u}),define("WoltLabSuite/Core/Media/List/Upload",["Core","Dom/Util","../Upload"],function(e,t,i){"use strict";function n(e,t,n){i.call(this,e,t,n)}return e.inherit(n,i,{_createButton:function(){n._super.prototype._createButton.call(this);var e=elBySel("span",this._button),i=document.createTextNode(" ");t.prepend(i,e);var a=elCreate("span");a.className="icon icon16 fa-upload",t.prepend(a,e)},_getParameters:function(){return this._options.categoryId?e.extend(n._super.prototype._getParameters.call(this),{categoryID:this._options.categoryId}):n._super.prototype._getParameters.call(this)}}),n}),define("WoltLabSuite/Core/Media/Clipboard",["Ajax","Dom/ChangeListener","EventHandler","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,a,r,o,s,l){"use strict";var c,d=[];return{init:function(e,t,n){o.setup({hasMarkedItems:t,pageClassName:e}),c=n,i.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.media",this._clipboardAction.bind(this))},_ajaxSetup:function(){return{data:{className:"wcf\\data\\media\\MediaAction"}}},_ajaxSuccess:function(e){switch(e.actionName){case"getSetCategoryDialog":a.open(this,e.returnValues.template);break;case"setCategory":a.close(this),r.show(),o.reload()}},_dialogSetup:function(){return{id:"mediaSetCategoryDialog",options:{onSetup:function(e){elBySel("button",e).addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),this._setCategory(~~elBySel('select[name="categoryID"]',e).value),t.currentTarget.disabled=!0}.bind(this))}.bind(this),title:n.get("wcf.media.setCategory")},source:null}},_clipboardAction:function(t){var i=t.data.parameters.objectIDs;switch(t.data.actionName){case"com.woltlab.wcf.media.delete":null!==t.responseData&&c.clipboardDeleteMedia(i);break;case"com.woltlab.wcf.media.insert":c.clipboardInsertMedia(i);break;case"com.woltlab.wcf.media.setCategory":d=i,e.api(this,{actionName:"getSetCategoryDialog"})}},_setCategory:function(t){e.api(this,{actionName:"setCategory",objectIDs:d,parameters:{categoryID:t}})}}}),define("WoltLabSuite/Core/Notification/Handler",["Ajax","Core","EventHandler","StringUtil"],function(e,t,i,n){"use strict";if(!("Promise"in window&&"Notification"in window))return{setup:function(){}};var a=!1,r="",o=0,s=window.TIME_NOW,l=null,c=0;return{setup:function(e){if(e=t.extend({enableNotifications:!1,icon:"",sessionKeepAlive:0},e),r=e.icon,c=60*e.sessionKeepAlive,this._prepareNextRequest(),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this)),window.addEventListener("storage",this._onStorage.bind(this)),this._onVisibilityChange(null),e.enableNotifications)switch(window.Notification.permission){case"granted":a=!0;break;case"default":window.Notification.requestPermission(function(e){"granted"===e&&(a=!0)})}},_onVisibilityChange:function(e){if(null!==e&&!document.hidden){(Date.now()-o)/6e4>4&&(this._resetTimer(),this._dispatchRequest())}o=document.hidden?Date.now():0},_getNextDelay:function(){if(0===o)return 5;var e=~~((Date.now()-o)/6e4);return e<15?5:e<30?10:15},_resetTimer:function(){null!==l&&(window.clearTimeout(l),l=null)},_prepareNextRequest:function(){this._resetTimer();var e=Math.min(this._getNextDelay(),c);l=window.setTimeout(this._dispatchRequest.bind(this),6e4*e)},_dispatchRequest:function(){var t={};i.fire("com.woltlab.wcf.notification","beforePoll",t),t.lastRequestTimestamp=s,e.api(this,{parameters:t})},_onStorage:function(){this._prepareNextRequest();var e,n,a=!1;try{e=window.localStorage.getItem(t.getStoragePrefix()+"notification"),n=window.localStorage.getItem(t.getStoragePrefix()+"keepAliveData"),e=JSON.parse(e),n=JSON.parse(n)}catch(e){a=!0}a||i.fire("com.woltlab.wcf.notification","onStorage",{pollData:e,keepAliveData:n})},_ajaxSuccess:function(e){var n=!1,a=e.returnValues.keepAliveData,r=e.returnValues.pollData;window.WCF.System.PushNotification.executeCallbacks({returnValues:a});try{window.localStorage.setItem(t.getStoragePrefix()+"notification",JSON.stringify(r)),window.localStorage.setItem(t.getStoragePrefix()+"keepAliveData",JSON.stringify(a))}catch(e){n=!0,window.console.log(e)}n||this._prepareNextRequest(),s=e.returnValues.lastRequestTimestamp,i.fire("com.woltlab.wcf.notification","afterPoll",r),this._showNotification(r)},_showNotification:function(e){if(a&&"object"==typeof e.notification&&"string"==typeof e.notification.message){var t=new window.Notification(e.notification.title,{body:n.unescapeHTML(e.notification.message),icon:r});t.onclick=function(){window.focus(),t.close(),window.location=e.notification.link}}},_ajaxSetup:function(){return{data:{actionName:"poll",className:"wcf\\data\\session\\SessionAction"},ignoreError:!window.ENABLE_DEBUG_MODE,silent:!window.ENABLE_DEBUG_MODE}}}}),define("WoltLabSuite/Core/Ui/Redactor/DragAndDrop",["Dictionary","EventHandler","Language"],function(e,t,i){"use strict";var n=!1,a=new e,r=!1,o=!1,s=null;return{init:function(e){n||this._setup(),a.set(e.uuid,{editor:e,element:null})},_dragOver:function(e){if(e.preventDefault(),e.dataTransfer&&e.dataTransfer.types){var t=!1;for(var n in e.dataTransfer)if(e.dataTransfer.hasOwnProperty(n)&&n.match(/^moz/)){t=!0;break}if(o=!1,t)"application/x-moz-file"===e.dataTransfer.types[0]&&(o=!0);else for(var s=0;s<e.dataTransfer.types.length;s++)if("Files"===e.dataTransfer.types[s]){o=!0;break}o&&(r||(r=!0,a.forEach(function(e,t){var n=e.editor.$editor[0];if(!n.parentNode)return void a.delete(t);var r=e.element;null===r&&(r=elCreate("div"),r.className="redactorDropArea",elData(r,"element-id",e.editor.$element[0].id),elData(r,"drop-here",i.get("wcf.attachment.dragAndDrop.dropHere")),elData(r,"drop-now",i.get("wcf.attachment.dragAndDrop.dropNow")),r.addEventListener("dragover",function(){r.classList.add("active")}),r.addEventListener("dragleave",function(){r.classList.remove("active")}),r.addEventListener("drop",this._drop.bind(this)),e.element=r),n.parentNode.insertBefore(r,n),r.style.setProperty("top",n.offsetTop+"px","")}.bind(this))))}},_drop:function(e){if(o&&e.dataTransfer&&e.dataTransfer.files.length){e.preventDefault();for(var i=elData(e.currentTarget,"element-id"),n=0,a=e.dataTransfer.files.length;n<a;n++)t.fire("com.woltlab.wcf.redactor2","dragAndDrop_"+i,{file:e.dataTransfer.files[n]});this._dragLeave()}},_dragLeave:function(){r&&o&&(null!==s&&window.clearTimeout(s),s=window.setTimeout(function(){r||a.forEach(function(e){e.element&&e.element.parentNode&&(e.element.classList.remove("active"),elRemove(e.element))}),s=null},100),r=!1)},_globalDrop:function(e){if(null===e.target.closest(".redactor-layer")){var i={cancelDrop:!0,event:e};a.forEach(function(e){t.fire("com.woltlab.wcf.redactor2","dragAndDrop_globalDrop_"+e.editor.$element[0].id,i)}),i.cancelDrop&&e.preventDefault()}this._dragLeave(e)},_setup:function(){window.addEventListener("dragend",function(e){e.preventDefault()}),window.addEventListener("dragover",this._dragOver.bind(this)),window.addEventListener("dragleave",this._dragLeave.bind(this)),window.addEventListener("drop",this._globalDrop.bind(this)),n=!0}}}),define("WoltLabSuite/Core/Ui/DragAndDrop",["Core","EventHandler","WoltLabSuite/Core/Ui/Redactor/DragAndDrop"],function(e,t,i){return{register:function(n){var a=e.getUuid();n=e.extend({element:"",elementId:"",onDrop:function(e){},onGlobalDrop:function(e){}}),t.add("com.woltlab.wcf.redactor2","dragAndDrop_"+n.elementId,n.onDrop),
-t.add("com.woltlab.wcf.redactor2","dragAndDrop_globalDrop_"+n.elementId,n.onGlobalDrop),i.init({uuid:a,$editor:[n.element],$element:[{id:n.elementId}]})}}}),define("WoltLabSuite/Core/Ui/Suggestion",["Ajax","Core","Ui/SimpleDropdown"],function(e,t,i){"use strict";function n(e,t){this.init(e,t)}return n.prototype={init:function(e,i){if(this._dropdownMenu=null,this._value="",this._element=elById(e),null===this._element)throw new Error("Expected a valid element id.");if(this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction",parameters:{data:{}}},callbackSelect:null,excludedSearchValues:[],threshold:3},i),"function"!=typeof this._options.callbackSelect)throw new Error("Expected a valid callback for option 'callbackSelect'.");this._element.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),this._element.addEventListener("keydown",this._keyDown.bind(this)),this._element.addEventListener("keyup",this._keyUp.bind(this))},addExcludedValue:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedValue:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},isActive:function(){return null!==this._dropdownMenu&&i.isOpen(this._element.id)},_keyDown:function(e){if(!this.isActive())return!0;if(13!==e.keyCode&&27!==e.keyCode&&38!==e.keyCode&&40!==e.keyCode)return!0;for(var t,n=0,a=this._dropdownMenu.childElementCount;n<a&&(t=this._dropdownMenu.children[n],!t.classList.contains("active"));)n++;if(13===e.keyCode)i.close(this._element.id),this._select(t);else if(27===e.keyCode){if(!i.isOpen(this._element.id))return!0;i.close(this._element.id)}else{var r=0;38===e.keyCode?r=(0===n?a:n)-1:40===e.keyCode&&(r=n+1)===a&&(r=0),r!==n&&(t.classList.remove("active"),this._dropdownMenu.children[r].classList.add("active"))}return e.preventDefault(),!1},_select:function(e){var t=e instanceof Event;t&&(e=e.currentTarget.parentNode);var i=e.children[0];this._options.callbackSelect(this._element.id,{objectId:elData(i,"object-id"),value:e.textContent,type:elData(i,"type")}),t&&this._element.focus()},_keyUp:function(t){var n=t.currentTarget.value.trim();if(this._value!==n){if(n.length<this._options.threshold)return null!==this._dropdownMenu&&i.close(this._element.id),void(this._value=n);this._value=n,e.api(this,{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:n}}})}},_ajaxSetup:function(){return{data:this._options.ajax}},_ajaxSuccess:function(e){if(null===this._dropdownMenu?(this._dropdownMenu=elCreate("div"),this._dropdownMenu.className="dropdownMenu",i.initFragment(this._element,this._dropdownMenu)):this._dropdownMenu.innerHTML="",e.returnValues.length){for(var t,n,a,r=0,o=e.returnValues.length;r<o;r++)n=e.returnValues[r],t=elCreate("a"),n.icon?(t.className="box16",t.innerHTML=n.icon+" <span></span>",t.children[1].textContent=n.label):t.textContent=n.label,elData(t,"object-id",n.objectID),n.type&&elData(t,"type",n.type),t.addEventListener(WCF_CLICK_EVENT,this._select.bind(this)),a=elCreate("li"),0===r&&(a.className="active"),a.appendChild(t),this._dropdownMenu.appendChild(a);i.open(this._element.id,!0)}else i.close(this._element.id)}},n}),define("WoltLabSuite/Core/Ui/ItemList",["Core","Dictionary","Language","Dom/Traverse","EventKey","WoltLabSuite/Core/Ui/Suggestion","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";var s="",l=new t,c=!1,d=null,u=null,h=null,p=null,f=null,m=null;return{init:function(t,i,a){var s=elById(t);if(null===s)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(l.has(t)){var c=l.get(t);for(var d in c)if(c.hasOwnProperty(d)){var u=c[d];u instanceof Element&&u.parentNode&&elRemove(u)}o.destroy(t),l.delete(t)}a=e.extend({ajax:{actionName:"getSearchResultList",className:"",data:{}},excludedSearchValues:[],maxItems:-1,maxLength:-1,restricted:!1,isCSV:!1,callbackChange:null,callbackSubmit:null,callbackSyncShadow:null,callbackSetupValues:null,submitFieldName:""},a);var h=n.parentByTag(s,"FORM");if(null!==h)if(!1===a.isCSV){if(!a.submitFieldName.length&&"function"!=typeof a.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=l.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}var i=this.getValues(t);if(a.submitFieldName.length)for(var n,r=0,o=i.length;r<o;r++)n=elCreate("input"),n.type="hidden",n.name=a.submitFieldName.replace("{$objectId}",i[r].objectId),n.value=i[r].value,h.appendChild(n);else a.callbackSubmit(h,i)}.bind(this))}else h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=l.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}}.bind(this));this._setup();var p=this._createUI(s,a),f=new r(t,{ajax:a.ajax,callbackSelect:this._addItem.bind(this),excludedSearchValues:a.excludedSearchValues});if(l.set(t,{dropdownMenu:null,element:p.element,list:p.list,listItem:p.element.parentNode,options:a,shadow:p.shadow,suggestion:f}),i=a.callbackSetupValues?a.callbackSetupValues():p.values.length?p.values:i,Array.isArray(i))for(var m,g=0,v=i.length;g<v;g++)m=i[g],"string"==typeof m&&(m={objectId:0,value:m}),this._addItem(t,m)},getValues:function(e){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=l.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent.trim(),type:elData(e,"type")})}),i},setValues:function(e,t){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,a,r=l.get(e),o=n.childrenByClass(r.list,"item");for(i=0,a=o.length;i<a;i++)this._removeItem(null,o[i],!0);for(i=0,a=t.length;i<a;i++)this._addItem(e,t[i])},_setup:function(){c||(c=!0,d=this._keyDown.bind(this),u=this._keyPress.bind(this),h=this._keyUp.bind(this),p=this._paste.bind(this),f=this._removeItem.bind(this),m=this._blur.bind(this))},_createUI:function(e,t){var i=elCreate("ol");i.className="inputItemList"+(e.disabled?" disabled":""),elData(i,"element-id",e.id),i.addEventListener(WCF_CLICK_EVENT,function(t){t.target===i&&e.focus()});var n=elCreate("li");n.className="input",i.appendChild(n),e.addEventListener("keydown",d),e.addEventListener("keypress",u),e.addEventListener("keyup",h),e.addEventListener("paste",p);var a=e===document.activeElement;a&&e.blur(),e.addEventListener("blur",m),e.parentNode.insertBefore(i,e),n.appendChild(e),a&&window.setTimeout(function(){e.focus()},1),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var r=null,o=[];if(t.isCSV){r=elCreate("input"),r.className="itemListInputShadow",r.type="hidden",r.name=e.name,e.removeAttribute("name"),i.parentNode.insertBefore(r,i);for(var s,l=e.value.split(","),c=0,f=l.length;c<f;c++)s=l[c].trim(),s.length&&o.push(s);if("TEXTAREA"===e.nodeName){var g=elCreate("input");g.type="text",e.parentNode.insertBefore(g,e),g.id=e.id,elRemove(e),e=g}}return{element:e,list:i,shadow:r,values:o}},_acceptsNewItems:function(e){var t=l.get(e);return-1===t.options.maxItems||t.list.childElementCount-1<t.options.maxItems},_handleLimit:function(e){var t=l.get(e);this._acceptsNewItems(e)?t.element.disabled&&(t.element.disabled=!1,t.element.removeAttribute("placeholder")):t.element.disabled||(t.element.disabled=!0,elAttr(t.element,"placeholder",i.get("wcf.global.form.input.maxItems")))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;s=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(a.Enter(e)||a.Comma(e)){if(e.preventDefault(),l.get(e.currentTarget.id).options.restricted)return;var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain");var i=e.currentTarget,n=i.id,a=~~elAttr(i,"maxLength");t.split(/,/).forEach(function(e){e=e.trim(),a&&e.length>a&&(e=e.substr(0,a)),e.length>0&&this._acceptsNewItems(n)&&this._addItem(n,{objectId:0,value:e})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t){var i=l.get(e),n=elCreate("li");n.className="item";var a=elCreate("span");if(a.className="content",elData(a,"object-id",t.objectId),t.type&&elData(a,"type",t.type),a.textContent=t.value,n.appendChild(a),!i.element.disabled){var r=elCreate("a");r.className="icon icon16 fa-times",r.addEventListener(WCF_CLICK_EVENT,f),n.appendChild(r)}i.list.insertBefore(n,i.listItem),i.suggestion.addExcludedValue(t.value),i.element.value="",i.element.disabled||this._handleLimit(e);var o=this._syncShadow(i);"function"==typeof i.options.callbackChange&&(null===o&&(o=this.getValues(e)),i.options.callbackChange(e,o))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,a=elData(n,"element-id"),r=l.get(a);r.suggestion.removeExcludedValue(t.children[0].textContent),n.removeChild(t),i||r.element.focus(),this._handleLimit(a);var o=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===o&&(o=this.getValues(a)),r.options.callbackChange(a,o))},_syncShadow:function(e){if(!e.options.isCSV)return null;if("function"==typeof e.options.callbackSyncShadow)return e.options.callbackSyncShadow(e);for(var t="",i=this.getValues(e.element.id),n=0,a=i.length;n<a;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=e.currentTarget,i=l.get(t.id);if(!i.options.restricted){var n=t.value.trim();n.length&&(i.suggestion&&i.suggestion.isActive()||this._addItem(t.id,{objectId:0,value:n}))}}}}),define("WoltLabSuite/Core/Ui/Page/JumpTo",["Language","ObjectMap","Ui/Dialog"],function(e,t,i){"use strict";var n=null,a=null,r=null,o=new t,s=null;return{init:function(e,t){if(null===(t=t||null)){var i=elData(e,"link");t=i?function(e){window.location=i.replace(/pageNo=%d/,"pageNo="+e)}:function(){}}else if("function"!=typeof t)throw new TypeError("Expected a valid function for parameter 'callback'.");o.has(e)||elBySelAll(".jumpTo",e,function(i){i.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,e)),o.set(e,{callback:t})}.bind(this))},_click:function(t,a){n=t,"object"==typeof a&&a.preventDefault(),i.open(this);var o=elData(t,"pages");s.value=o,s.setAttribute("max",o),s.select(),r.textContent=e.get("wcf.page.jumpTo.description").replace(/#pages#/,o)},_keyUp:function(e){if(13===e.which&&!1===a.disabled)return void this._submit();var t=~~s.value;t<1||t>~~elAttr(s,"max")?a.disabled=!0:a.disabled=!1},_submit:function(e){o.get(n).callback(~~s.value),i.close(this)},_dialogSetup:function(){var t='<dl><dt><label for="jsPaginationPageNo">'+e.get("wcf.page.jumpTo")+'</label></dt><dd><input type="number" id="jsPaginationPageNo" value="1" min="1" max="1" class="tiny"><small></small></dd></dl><div class="formSubmit"><button class="buttonPrimary">'+e.get("wcf.global.button.submit")+"</button></div>";return{id:"paginationOverlay",options:{onSetup:function(e){s=elByTag("input",e)[0],s.addEventListener("keyup",this._keyUp.bind(this)),r=elByTag("small",e)[0],a=elByTag("button",e)[0],a.addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))}.bind(this),title:e.get("wcf.global.page.pagination")},source:t}}}}),define("WoltLabSuite/Core/Ui/Pagination",["Core","Language","ObjectMap","StringUtil","WoltLabSuite/Core/Ui/Page/JumpTo"],function(e,t,i,n,a){"use strict";function r(e,t){this.init(e,t)}return r.prototype={SHOW_LINKS:11,init:function(t,i){this._element=t,this._options=e.extend({activePage:1,maxPage:1,callbackShouldSwitch:null,callbackSwitch:null},i),"function"!=typeof this._options.callbackShouldSwitch&&(this._options.callbackShouldSwitch=null),"function"!=typeof this._options.callbackSwitch&&(this._options.callbackSwitch=null),this._element.classList.add("pagination"),this._rebuild(this._element)},_rebuild:function(){var e=!1;this._element.innerHTML="";var i,n=elCreate("ul"),r=elCreate("li");r.className="skip",n.appendChild(r);var o="icon icon24 fa-chevron-left";this._options.activePage>1?(i=elCreate("a"),i.className=o+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.previous"),i.rel="prev",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage-1))):(r.innerHTML='<span class="'+o+'"></span>',r.classList.add("disabled")),n.appendChild(this._createLink(1));var s=this.SHOW_LINKS-4,l=this._options.activePage-2;l<0&&(l=0);var c=this._options.maxPage-(this._options.activePage+1);c<0&&(c=0),this._options.activePage>1&&this._options.activePage<this._options.maxPage&&s--;var d=s/2,u=this._options.activePage,h=this._options.activePage;u<1&&(u=1),h<1&&(h=1),h>this._options.maxPage-1&&(h=this._options.maxPage-1),l>=d?u-=d:(u-=l,h+=d-l),c>=d?h+=d:(h+=c,u-=d-c),h=Math.ceil(h),u=Math.ceil(u),u<1&&(u=1),h>this._options.maxPage&&(h=this._options.maxPage);var p='<a class="jsTooltip" title="'+t.get("wcf.page.jumpTo")+'">&hellip;</a>';u>1&&(u-1<2?n.appendChild(this._createLink(2)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=p,n.appendChild(r),e=!0));for(var f=u+1;f<h;f++)n.appendChild(this._createLink(f));h<this._options.maxPage&&(this._options.maxPage-h<2?n.appendChild(this._createLink(this._options.maxPage-1)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=p,n.appendChild(r),e=!0)),n.appendChild(this._createLink(this._options.maxPage)),r=elCreate("li"),r.className="skip",n.appendChild(r),o="icon icon24 fa-chevron-right",this._options.activePage<this._options.maxPage?(i=elCreate("a"),i.className=o+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.next"),i.rel="next",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage+1))):(r.innerHTML='<span class="'+o+'"></span>',r.classList.add("disabled")),e&&(elData(n,"pages",this._options.maxPage),a.init(n,this.switchPage.bind(this))),this._element.appendChild(n)},_createLink:function(e){var i=elCreate("li");if(e!==this._options.activePage){var a=elCreate("a");a.textContent=n.addThousandsSeparator(e),a.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,e)),i.appendChild(a)}else i.classList.add("active"),i.innerHTML="<span>"+n.addThousandsSeparator(e)+'</span><span class="invisible">'+t.get("wcf.page.pagePosition",{pageNo:e,pages:this._options.maxPage})+"</span>";return i},getActivePage:function(){return this._options.activePage},getElement:function(){return this._element},getMaxPage:function(){return this._options.maxPage},switchPage:function(t,i){if("object"==typeof i&&(i.preventDefault(),i.currentTarget&&elData(i.currentTarget,"tooltip"))){var n=elById("balloonTooltip");n&&(e.triggerEvent(i.currentTarget,"mouseleave"),n.style.removeProperty("top"),n.style.removeProperty("bottom"))}if((t=~~t)>0&&this._options.activePage!==t&&t<=this._options.maxPage){if(null!==this._options.callbackShouldSwitch&&!0!==this._options.callbackShouldSwitch(t))return;this._options.activePage=t,this._rebuild(),null!==this._options.callbackSwitch&&this._options.callbackSwitch(t)}}},r}),define("WoltLabSuite/Core/Controller/Media/List",["Dom/ChangeListener","EventHandler","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,a,r){"use strict";var o,s,l=elById("mediaListTableBody");return{init:function(i){i=i||{},s=new r("uploadButton","mediaListTableBody",{categoryId:i.categoryId,multiple:!0,elementTagSize:48}),n.init("wcf\\acp\\page\\MediaListPage",i.hasMarkedItems||!1,this),t.add("com.woltlab.wcf.media.upload","removedErroneousUploadRow",this._deleteCallback.bind(this)),new WCF.Action.Delete("wcf\\data\\media\\MediaAction",".jsMediaRow").setCallback(this._deleteCallback),o=new a({_editorSuccess:function(e,t){e.categoryID!=t&&window.setTimeout(function(){window.location.reload()},500)}}),this._addButtonEventListeners(),e.add("WoltLabSuite/Core/Controller/Media/List",this._addButtonEventListeners.bind(this)),t.add("com.woltlab.wcf.media.upload","success",this._openEditorAfterUpload.bind(this))},_addButtonEventListeners:function(){for(var e,t=elByClass("jsMediaEditButton",l);t.length;)e=t[0],e.classList.remove("jsMediaEditButton"),e.addEventListener(WCF_CLICK_EVENT,this._edit.bind(this))},_deleteCallback:function(e){var t=elByTag("tr",l).length;void 0===e.length?t||window.location.reload():e.length===t?window.location.reload():i.reload.bind(i)},_edit:function(e){o.edit(elData(e.currentTarget,"object-id"))},_openEditorAfterUpload:function(e){if(e.upload===s&&!e.isMultiFileUpload&&!s.hasPendingUploads()){var t=Object.keys(e.media);t.length&&o.edit(e.media[t[0]])}},clipboardDeleteMedia:function(e){for(var t=elByClass("jsMediaRow"),i=0;i<t.length;i++){var n=t[i],a=~~elData(elByClass("jsClipboardItem",n)[0],"object-id");-1!==e.indexOf(a)&&(elRemove(n),i--)}t.length||window.location.reload()}}}),define("WoltLabSuite/Core/Controller/Notice/Dismiss",["Ajax"],function(e){"use strict";return{setup:function(){var e=elByClass("jsDismissNoticeButton");if(e.length)for(var t=this._click.bind(this),i=0,n=e.length;i<n;i++)e[i].addEventListener(WCF_CLICK_EVENT,t)},_click:function(t){var i=t.currentTarget;e.apiOnce({data:{actionName:"dismiss",className:"wcf\\data\\notice\\NoticeAction",objectIDs:[elData(i,"object-id")]},success:function(){elRemove(i.parentNode)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager",["Dictionary","Dom/ChangeListener","EventHandler","List","Dom/Util","ObjectMap"],function(e,t,i,n,a,r){"use strict";var o=!1,s=!0,l=new n,c=new e,d=new n,u=new e,h=new r;return{_hide:function(t){elHide(t),l.add(t),t.classList.contains("tabMenuContent")&&elBySelAll("li",t.parentNode.querySelector(".tabMenu"),function(e){elData(e,"name")===elData(t,"name")&&elHide(e)}),elBySelAll("[max], [maxlength], [min], [required]",t,function(t){var i=new e,n=elAttr(t,"max");n&&(i.set("max",n),t.removeAttribute("max"));var a=elAttr(t,"maxlength");a&&(i.set("maxlength",a),t.removeAttribute("maxlength"));var r=elAttr(t,"min");r&&(i.set("min",r),t.removeAttribute("min")),t.required&&(i.set("required",!0),t.removeAttribute("required")),h.set(t,i)})},_show:function(e){elShow(e),l.delete(e),e.classList.contains("tabMenuContent")&&elBySelAll("li",e.parentNode.querySelector(".tabMenu"),function(t){elData(t,"name")===elData(e,"name")&&elShow(t)}),elBySelAll("input, select",e,function(t){for(var i=t.parentNode;i!==e&&"none"!==i.style.getPropertyValue("display");)i=i.parentNode;if(i===e&&h.has(t)){var n=h.get(t);n.has("max")&&elAttr(t,"max",n.get("max")),n.has("maxlength")&&elAttr(t,"maxlength",n.get("maxlength")),n.has("min")&&elAttr(t,"min",n.get("min")),n.has("required")&&elAttr(t,"required",""),h.delete(t)}})},addDependency:function(e){var t=e.getDependentNode();u.has(t.id)?u.get(t.id).push(e):u.set(t.id,[e]);for(var i=e.getFields(),n=0,r=i.length;n<r;n++){var o=i[n],s=a.identify(o);c.has(s)||(c.set(s,o),"INPUT"!==o.tagName||"checkbox"!==o.type&&"radio"!==o.type&&"hidden"!==o.type?o.addEventListener("input",this.checkDependencies.bind(this)):o.addEventListener("change",this.checkDependencies.bind(this)))}},checkDependencies:function(){var e=[];u.forEach(function(t,i){var n=elById(i);if(null===n)return void e.push(i);for(var a=0,r=t.length;a<r;a++)if(!t[a].checkDependency())return void this._hide(n);this._show(n)}.bind(this));for(var t=0,i=e.length;t<i;t++)u.delete(e[t]);this.checkContainers()},addContainerCheckCallback:function(e){if("function"!=typeof e)throw new TypeError("Expected a valid callback for parameter 'callback'.");i.add("com.woltlab.wcf.form.builder.dependency","checkContainers",e)},checkContainers:function(){if(!0===o)return void(s=!0);o=!0,s=!1,i.fire("com.woltlab.wcf.form.builder.dependency","checkContainers"),o=!1,s&&this.checkContainers()},isHiddenByDependencies:function(e){if(l.has(e))return!0;var t=!1;return l.forEach(function(i){a.contains(i,e)&&(t=!0)}),t},register:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(d.has(t))throw new Error("Form with id '"+e+"' has already been registered.");d.add(t)},unregister:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(!d.has(t))throw new Error("Form with id '"+e+"' has not been registered.");d.delete(t),l.forEach(function(e){t.contains(e)&&l.delete(e)}),u.forEach(function(e,i){t.contains(elById(i))&&u.delete(i);for(var n=0,a=e.length;n<a;n++)for(var r=e[n].getFields(),o=0,s=r.length;o<s;o++){var l=r[o];c.delete(l.id),h.delete(l)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Field",[],function(){"use strict";function e(e){this.init(e)}return e.prototype={init:function(e){this._fieldId=e,this._readField()},_getData:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Field._getData!")},_readField:function(){if(this._field=elById(this._fieldId),null===this._field)throw new Error("Unknown field with id '"+this._fieldId+"'.")},destroy:function(){},getData:function(){return Promise.resolve(this._getData())},getId:function(){return this._fieldId}},e}),define("WoltLabSuite/Core/Form/Builder/Manager",["Core","Dictionary","EventHandler","./Field/Dependency/Manager","./Field/Field"],function(e,t,i,n,a){"use strict";var r=new t,o=new t;return{getData:function(t){if(!this.hasForm(t))throw new Error("Unknown form with id '"+t+"'.");var i=[];return r.get(t).forEach(function(e){var t=e.getData();if(!(t instanceof Promise))throw new TypeError("Data for field with id '"+e.getId()+"' is no promise.");i.push(t)}),Promise.all(i).then(function(t){for(var i={},n=0,a=t.length;n<a;n++)i=e.extend(i,t[n]);return i})},getField:function(e,t){if(!this.hasField(e,t))throw new Error("Unknown field with id '"+e+"' for form with id '"+t+"'.");return r.get(e).get(t)},getForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return o.get(e)},hasField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return r.get(e).has(t)},hasForm:function(e){return o.has(e)},registerField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");if(!(t instanceof a))throw new Error("Add field is no instance of 'WoltLabSuite/Core/Form/Builder/Field/Field'.");var n=t.getId();if(this.hasField(e,n))throw new Error("Form field with id '"+n+"' has already been registered for form with id '"+e+"'.");r.get(e).set(n,t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerField",{field:t,formId:e})},registerForm:function(e){if(this.hasForm(e))throw new Error("Form with id '"+e+"' has already been registered.");var n=elById(e);if(null===n)throw new Error("Unknown form with id '"+e+"'.");o.set(e,n),r.set(e,new t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerForm",{formId:e})},unregisterForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");i.fire("WoltLabSuite/Core/Form/Builder/Manager","beforeUnregisterForm",{formId:e}),o.delete(e),r.get(e).forEach(function(e){e.destroy()}),r.delete(e),n.unregister(e),i.fire("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",{formId:e})}}}),define("WoltLabSuite/Core/Form/Builder/Dialog",["Ajax","Core","./Manager","Ui/Dialog"],function(e,t,i,n){"use strict";function a(e,t,i,n){this.init(e,t,i,n)}return a.prototype={init:function(e,i,n,a){this._dialogId=e,this._className=i,this._actionName=n,this._options=t.extend({actionParameters:{},destroyOnClose:!1,usesDboAction:this._className.match(/\w+\\data\\/)},a),this._options.dialog=t.extend(this._options.dialog||{},{onClose:this._dialogOnClose.bind(this)}),this._formId="",this._dialogContent=""},_ajaxSetup:function(){var e={data:{actionName:this._actionName,className:this._className,parameters:this._options.actionParameters}};return this._options.usesDboAction||(e.url="index.php?ajax-invoke/&t="+SECURITY_TOKEN,e.withCredentials=!0),e},_ajaxSuccess:function(e){switch(e.actionName){case this._actionName:if(void 0===e.returnValues)throw new Error("Missing return data.");if(void 0===e.returnValues.dialog)throw new Error("Missing dialog template in return data.");if(void 0===e.returnValues.formId)throw new Error("Missing form id in return data.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog);break;case this._options.submitActionName:if(e.returnValues&&e.returnValues.formId&&e.returnValues.dialog){if(e.returnValues.formId!==this._formId)throw new Error("Mismatch between form ids: expected '"+this._formId+"' but got '"+e.returnValues.formId+"'.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog)}else this.destroy(),"function"==typeof this._options.successCallback&&this._options.successCallback(e.returnValues||{});break;default:throw new Error("Cannot handle action '"+e.actionName+"'.")}},_closeDialog:function(){n.close(this),"function"==typeof this._options.closeCallback&&this._options.closeCallback()},_dialogOnClose:function(){this._options.destroyOnClose&&this.destroy()},_dialogSetup:function(){return{id:this._dialogId,options:this._options.dialog,source:this._dialogContent}},_dialogSubmit:function(){this.getData().then(this._submitForm.bind(this))},_openDialogContent:function(e,t){this.destroy(!0),this._formId=e,this._dialogContent=t;var i=n.open(this,this._dialogContent),a=elBySel("button[data-type=cancel]",i.content);null===a||elDataBool(a,"has-event-listener")||(a.addEventListener("click",this._closeDialog.bind(this)),elData(a,"has-event-listener",1))},_submitForm:function(t){var i=elBySel("button[data-type=submit]",n.getDialog(this).content);"function"==typeof this._options.onSubmit?this._options.onSubmit(t,i):"string"==typeof this._options.submitActionName&&(i.disabled=!0,e.api(this,{actionName:this._options.submitActionName,parameters:{data:t,formId:this._formId}}))},destroy:function(e){""!==this._formId&&(i.hasForm(this._formId)&&i.unregisterForm(this._formId),!0!==e&&n.destroy(this))},getData:function(){if(""===this._formId)throw new Error("Form has not been requested yet.");return i.getData(this._formId)},open:function(){n.getDialog(this._dialogId)?n.openStatic(this._dialogId):e.api(this)}},a}),define("WoltLabSuite/Core/Media/Manager/Search",["Ajax","Core","Dom/Traverse","Dom/Util","EventKey","Language","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";function s(e){this._mediaManager=e,this._searchMode=!1,this._searchContainer=elByClass("mediaManagerSearch",e.getDialog())[0],this._input=elByClass("mediaManagerSearchField",e.getDialog())[0],this._input.addEventListener("keypress",this._keyPress.bind(this)),this._cancelButton=elByClass("mediaManagerSearchCancelButton",e.getDialog())[0],this._cancelButton.addEventListener(WCF_CLICK_EVENT,this._cancelSearch.bind(this))}return s.prototype={_ajaxSetup:function(){return{data:{actionName:"getSearchResultList",className:"wcf\\data\\media\\MediaAction",interfaceName:"wcf\\data\\ISearchAction"}}},_ajaxSuccess:function(e){this._mediaManager.setMedia(e.returnValues.media||{},e.returnValues.template||"",{pageCount:e.returnValues.pageCount||0,pageNo:e.returnValues.pageNo||0}),elByClass("dialogContent",this._mediaManager.getDialog())[0].scrollTop=0},_cancelSearch:function(){this._searchMode&&(this._searchMode=!1,this.resetSearch(),this._mediaManager.resetMedia())},_hideStringThresholdError:function(){var e=i.childByClass(this._input.parentNode.parentNode,"innerInfo");e&&elHide(e)},_keyPress:function(e){a.Enter(e)&&(e.preventDefault(),this._input.value.length>=this._mediaManager.getOption("minSearchLength")?(this._hideStringThresholdError(),this.search()):this._showStringThresholdError())},_showStringThresholdError:function(){var e=i.childByClass(this._input.parentNode.parentNode,"innerInfo");e?elShow(e):(e=elCreate("p"),e.className="innerInfo",e.textContent=r.get("wcf.media.search.info.searchStringThreshold",{minSearchLength:this._mediaManager.getOption("minSearchLength")}),n.insertAfter(e,this._input.parentNode))},hideSearch:function(){elHide(this._searchContainer)},resetSearch:function(){this._input.value=""},showSearch:function(){elShow(this._searchContainer)},search:function(t){"number"!=typeof t&&(t=1);var i=this._input.value;i&&this._input.value.length<this._mediaManager.getOption("minSearchLength")?(this._showStringThresholdError(),i=""):this._hideStringThresholdError(),this._searchMode=!0,e.api(this,{parameters:{categoryID:this._mediaManager.getCategoryId(),imagesOnly:this._mediaManager.getOption("imagesOnly"),mode:this._mediaManager.getMode(),pageNo:t,searchString:i}})}},s}),define("WoltLabSuite/Core/Media/Manager/Base",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","List","Permission","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/Upload","WoltLabSuite/Core/Media/Manager/Search","StringUtil","WoltLabSuite/Core/Ui/Pagination","WoltLabSuite/Core/Media/Clipboard"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p,f,m,g,v){"use strict";function _(n){this._options=e.extend({dialogTitle:o.get("wcf.media.manager"),imagesOnly:!1,minSearchLength:3},n),this._id="mediaManager"+b++,this._listItems=new t,this._media=new t,this._mediaManagerMediaList=null,this._search=null,this._upload=null,this._forceClipboard=!1,this._hadInitiallyMarkedItems=!1,this._pagination=null,l.get("admin.content.cms.canManageMedia")&&(this._mediaEditor=new h(this)),i.add("WoltLabSuite/Core/Media/Manager",this._addButtonEventListeners.bind(this)),r.add("com.woltlab.wcf.media.upload","success",this._openEditorAfterUpload.bind(this))}var b=0;return _.prototype={_addButtonEventListeners:function(){if(this._mediaManagerMediaList)for(var e=n.childrenByTag(this._mediaManagerMediaList,"LI"),t=0,i=e.length;t<i;t++){var a=e[t];if(l.get("admin.content.cms.canManageMedia")){var r=elByClass("jsMediaEditButton",a)[0];r&&(r.classList.remove("jsMediaEditButton"),r.addEventListener(WCF_CLICK_EVENT,this._editMedia.bind(this)))}}},_categoryChange:function(){this._search.search()},_click:function(e){e.preventDefault(),c.open(this)},_dialogClose:function(){(l.get("admin.content.cms.canManageMedia")||this._forceClipboard)&&u.hideEditor("com.woltlab.wcf.media")},_dialogInit:function(e,t){var i=t.returnValues.media||{};for(var n in i)objOwns(i,n)&&this._media.set(~~n,i[n]);this._initPagination(~~t.returnValues.pageCount),this._hadInitiallyMarkedItems=t.returnValues.hasMarkedItems},_dialogSetup:function(){return{id:this._id,options:{onClose:this._dialogClose.bind(this),onShow:this._dialogShow.bind(this),title:this._options.dialogTitle},source:{after:this._dialogInit.bind(this),data:{actionName:"getManagementDialog",className:"wcf\\data\\media\\MediaAction",parameters:{mode:this.getMode(),imagesOnly:this._options.imagesOnly}}}}},_dialogShow:function(){if(!this._mediaManagerMediaList){var e=this.getDialog();this._mediaManagerMediaList=elByClass("mediaManagerMediaList",e)[0],this._mediaCategorySelect=elBySel(".mediaManagerCategoryList > select",e),this._mediaCategorySelect&&this._mediaCategorySelect.addEventListener("change",this._categoryChange.bind(this));for(var t=n.childrenByTag(this._mediaManagerMediaList,"LI"),i=0,r=t.length;i<r;i++){var o=t[i];this._listItems.set(~~elData(o,"object-id"),o)}if(l.get("admin.content.cms.canManageMedia")){var s=elByClass("mediaManagerMediaUploadButton",c.getDialog(this).dialog)[0];this._upload=new p(a.identify(s),a.identify(this._mediaManagerMediaList),{mediaManager:this})
-;new WCF.Action.Delete("wcf\\data\\media\\MediaAction",".mediaFile")._didTriggerEffect=function(e){this.removeMedia(elData(e[0],"object-id"))}.bind(this)}l.get("admin.content.cms.canManageMedia")||this._forceClipboard?v.init("menuManagerDialog-"+this.getMode(),!!this._hadInitiallyMarkedItems,this):this._removeClipboardCheckboxes(),this._search=new f(this),t.length||this._search.hideSearch()}(l.get("admin.content.cms.canManageMedia")||this._forceClipboard)&&u.showEditor("com.woltlab.wcf.media")},_editMedia:function(e){if(!l.get("admin.content.cms.canManageMedia"))throw new Error("You are not allowed to edit media files.");c.close(this),this._mediaEditor.edit(this._media.get(~~elData(e.currentTarget,"object-id")))},_editorClose:function(){c.open(this)},_editorSuccess:function(e,t){if(this._mediaCategorySelect){var i=~~this._mediaCategorySelect.value;if(i){var n=~~e.categoryID;t==n||t!=i&&n!=i||this._search.search()}}c.open(this),this._media.set(~~e.mediaID,e);var a=this._listItems.get(~~e.mediaID),r=elByClass("mediaTitle",a)[0];e.isMultilingual?r.textContent=e.title[LANGUAGE_ID]||e.filename:r.textContent=e.title[e.languageID]||e.filename},_initPagination:function(e,t){if(void 0===t&&(t=1),e>1){var i=elCreate("div");i.className="paginationBottom jsPagination",a.replaceElement(elBySel(".jsPagination",c.getDialog(this).content),i),this._pagination=new g(i,{activePage:t,callbackSwitch:this._search.search.bind(this._search),maxPage:e})}else this._pagination&&elHide(this._pagination.getElement())},_removeClipboardCheckboxes:function(){for(var e=elByClass("mediaCheckbox",this._mediaManagerMediaList);e.length;)elRemove(e[0])},_openEditorAfterUpload:function(e){if(e.upload===this._upload&&!e.isMultiFileUpload&&!this._upload.hasPendingUploads()){var t=Object.keys(e.media);t.length&&(c.close(this),this._mediaEditor.edit(this._media.get(~~e.media[t[0]].mediaID)))}},_setMedia:function(r){e.isPlainObject(r)?this._media=t.fromObject(r):this._media=r;var s=n.nextByClass(this._mediaManagerMediaList,"info");this._media.size?s&&elHide(s):(null===s&&(s=elCreate("p"),s.className="info",s.textContent=o.get("wcf.media.search.noResults")),elShow(s),a.insertAfter(s,this._mediaManagerMediaList));for(var c=n.childrenByTag(this._mediaManagerMediaList,"LI"),d=0,h=c.length;d<h;d++){var p=c[d];this._media.has(elData(p,"object-id"))?elShow(p):elHide(p)}i.trigger(),l.get("admin.content.cms.canManageMedia")||this._forceClipboard?u.reload():this._removeClipboardCheckboxes()},addMedia:function(e,t){e.languageID||(e.isMultilingual=1),this._media.set(~~e.mediaID,e),this._listItems.set(~~e.mediaID,t),1===this._listItems.size&&this._search.showSearch()},clipboardDeleteMedia:function(e){for(var t=0,i=e.length;t<i;t++)this.removeMedia(~~e[t],!0);d.show()},getCategoryId:function(){return this._mediaCategorySelect?this._mediaCategorySelect.value:0},getDialog:function(){return c.getDialog(this).dialog},getMode:function(){return""},getOption:function(e){return this._options[e]?this._options[e]:null},removeMedia:function(e){if(this._listItems.has(e)){try{elRemove(this._listItems.get(e))}catch(e){}this._listItems.delete(e),this._media.delete(e)}},resetMedia:function(){this._search.search()},setMedia:function(e,t,i){var a=!1;for(var r in e)objOwns(e,r)&&(a=!0);if(a){var o=elCreate("ul");o.innerHTML=t;for(var s=n.childrenByTag(o,"LI"),l=0,c=s.length;l<c;l++){var d=s[l];this._listItems.has(~~elData(d,"object-id"))||(this._listItems.set(elData(d,"object-id"),d),this._mediaManagerMediaList.appendChild(d))}}this._initPagination(i.pageCount,i.pageNo),this._setMedia(e)},setupMediaElement:function(t,i){var a=n.childByClass(i,"mediaInformation"),r=elCreate("nav");r.className="jsMobileNavigation buttonGroupNavigation",a.parentNode.appendChild(r);var s=elCreate("ul");s.className="buttonList iconList",r.appendChild(s);var c=elCreate("li");c.className="mediaCheckbox",s.appendChild(c);var d=elCreate("a");c.appendChild(d);var u=elCreate("label");d.appendChild(u);var h=elCreate("input");if(h.className="jsClipboardItem",elAttr(h,"type","checkbox"),elData(h,"object-id",t.mediaID),u.appendChild(h),l.get("admin.content.cms.canManageMedia")){c=elCreate("li"),c.className="jsMediaEditButton",elData(c,"object-id",t.mediaID),s.appendChild(c),c.innerHTML='<a><span class="icon icon16 fa-pencil jsTooltip" title="'+o.get("wcf.global.button.edit")+'"></span> <span class="invisible">'+o.get("wcf.global.button.edit")+"</span></a>",c=elCreate("li"),c.className="jsDeleteButton",elData(c,"object-id",t.mediaID);var p=e.getUuid();elData(c,"confirm-message-html",m.unescapeHTML(o.get("wcf.media.delete.confirmMessage",{title:p})).replace(p,m.escapeHTML(t.filename))),s.appendChild(c),c.innerHTML='<a><span class="icon icon16 fa-times jsTooltip" title="'+o.get("wcf.global.button.delete")+'"></span> <span class="invisible">'+o.get("wcf.global.button.delete")+"</span></a>"}}},_}),define("WoltLabSuite/Core/Media/Manager/Editor",["Core","Dictionary","Dom/Traverse","EventHandler","Language","Permission","Ui/Dialog","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,a,r,o,s,l){"use strict";function c(i){i=e.extend({callbackInsert:null},i),l.call(this,i),this._forceClipboard=!0,this._activeButton=null;var a=this._options.editor?this._options.editor.core.toolbar()[0]:void 0;this._buttons=elByClass(this._options.buttonClass||"jsMediaEditorButton",a);for(var r=0,o=this._buttons.length;r<o;r++)this._buttons[r].addEventListener(WCF_CLICK_EVENT,this._click.bind(this));if(this._mediaToInsert=new t,this._mediaToInsertByClipboard=!1,this._uploadData=null,this._uploadId=null,this._options.editor&&!this._options.editor.opts.woltlab.attachments){var s=elData(this._options.editor.$editor[0],"element-id"),c=n.add("com.woltlab.wcf.redactor2","dragAndDrop_"+s,this._editorUpload.bind(this)),d=n.add("com.woltlab.wcf.redactor2","pasteFromClipboard_"+s,this._editorUpload.bind(this));n.add("com.woltlab.wcf.redactor2","destory_"+s,function(){n.remove("com.woltlab.wcf.redactor2","dragAndDrop_"+s,c),n.remove("com.woltlab.wcf.redactor2","dragAndDrop_"+s,d)}),n.add("com.woltlab.wcf.media.upload","success",this._mediaUploaded.bind(this))}}return e.inherit(c,l,{_addButtonEventListeners:function(){if(c._super.prototype._addButtonEventListeners.call(this),this._mediaManagerMediaList)for(var e=i.childrenByTag(this._mediaManagerMediaList,"LI"),t=0,n=e.length;t<n;t++){var a=e[t],r=elByClass("jsMediaInsertButton",a)[0];r&&(r.classList.remove("jsMediaInsertButton"),r.addEventListener(WCF_CLICK_EVENT,this._openInsertDialog.bind(this)))}},_buildInsertDialog:function(){for(var e="",t=this._getThumbnailSizes(),i=0,n=t.length;i<n;i++)e+='<option value="'+t[i]+'">'+a.get("wcf.media.insert.imageSize."+t[i])+"</option>";e+='<option value="original">'+a.get("wcf.media.insert.imageSize.original")+"</option>";var r='<div class="section"><dl class="thumbnailSizeSelection"><dt>'+a.get("wcf.media.insert.imageSize")+'</dt><dd><select name="thumbnailSize">'+e+'</select></dd></dl></div><div class="formSubmit"><button class="buttonPrimary">'+a.get("wcf.global.button.insert")+"</button></div>";o.open({_dialogSetup:function(){return{id:this._getInsertDialogId(),options:{onClose:this._editorClose.bind(this),onSetup:function(e){elByClass("buttonPrimary",e)[0].addEventListener(WCF_CLICK_EVENT,this._insertMedia.bind(this));var t=elBySel(".thumbnailSizeSelection",e);elShow(t)}.bind(this),title:a.get("wcf.media.insert")},source:r}}.bind(this)})},_click:function(e){this._activeButton=e.currentTarget,c._super.prototype._click.call(this,e)},_dialogShow:function(){c._super.prototype._dialogShow.call(this),this._uploadData&&(this._uploadData.file?this._upload.uploadFile(this._uploadData.file):this._uploadId=this._upload.uploadBlob(this._uploadData.blob),this._uploadData=null)},_editorUpload:function(e){this._uploadData=e,o.open(this)},_getInsertDialogId:function(){var e="mediaInsert";return this._mediaToInsert.forEach(function(t,i){e+="-"+i}),e},_getThumbnailSizes:function(){for(var e,t,i=[],n=["small","medium","large"],a=0,r=n.length;a<r;a++)e=n[a],t=!0,this._mediaToInsert.forEach(function(i){i[e+"ThumbnailType"]||(t=!1)}),t&&i.push(e);return i},_insertMedia:function(e,i,n){void 0===n&&(n=!0);if(e){o.close(this._getInsertDialogId());var a=e.currentTarget.closest(".dialogContent");i=elBySel("select[name=thumbnailSize]",a).value}if(null!==this._options.callbackInsert?this._options.callbackInsert(this._mediaToInsert,"separate",i):(this._options.editor.buffer.set(),this._mediaToInsert.forEach(this._insertMediaItem.bind(this,i))),this._mediaToInsertByClipboard){var r=[];this._mediaToInsert.forEach(function(e){r.push(e.mediaID)}),s.unmark("com.woltlab.wcf.media",r)}this._mediaToInsert=new t,this._mediaToInsertByClipboard=!1,n&&o.close(this)},_insertMediaGallery:function(){var e=[];this._mediaToInsert.forEach(function(t){e.push(t.mediaID)}),this._options.editor.buffer.set(),this._options.editor.insert.text("[wsmg='"+e.join(",")+"'][/wsmg]")},_insertMediaItem:function(e,t){if(t.isImage){for(var i,n=["small","medium","large","original"],a="",r=0;r<4&&(i=n[r],0==t[i+"ThumbnailHeight"]||(a=i,e!=i));r++);e=a,e||(e="original");var o=t.link;"original"!==e&&(o=t[e+"ThumbnailLink"]),this._options.editor.insert.html('<img src="'+o+'" class="woltlabSuiteMedia" data-media-id="'+t.mediaID+'" data-media-size="'+e+'">')}else this._options.editor.insert.text("[wsm='"+t.mediaID+"'][/wsm]")},_mediaUploaded:function(e){null!==this._uploadId&&this._upload===e.upload&&(this._uploadId===e.uploadId||Array.isArray(this._uploadId)&&-1!==this._uploadId.indexOf(e.uploadId))&&(this._mediaToInsert=t.fromObject(e.media),this._insertMedia(null,"medium",!1),this._uploadId=null)},_openInsertDialog:function(e){this.insertMedia([~~elData(e.currentTarget,"object-id")])},clipboardInsertMedia:function(e){this.insertMedia(e,!0)},insertMedia:function(e,i){this._mediaToInsert=new t,this._mediaToInsertByClipboard=i||!1;for(var n,a=!0,r=0,s=e.length;r<s;r++)n=this._media.get(e[r]),this._mediaToInsert.set(n.mediaID,n),n.isImage||(a=!1);if(a){if(this._getThumbnailSizes().length){o.close(this);var l=this._getInsertDialogId();o.getDialog(l)?o.openStatic(l):this._buildInsertDialog()}else this._insertMedia(void 0,"original")}else this._insertMedia()},getMode:function(){return"editor"},setupMediaElement:function(e,t){c._super.prototype.setupMediaElement.call(this,e,t);var i=elBySel("nav.buttonGroupNavigation > ul",t),n=elCreate("li");n.className="jsMediaInsertButton",elData(n,"object-id",e.mediaID),i.appendChild(n),n.innerHTML='<a><span class="icon icon16 fa-plus jsTooltip" title="'+a.get("wcf.media.button.insert")+'"></span> <span class="invisible">'+a.get("wcf.media.button.insert")+"</span></a>"}}),c}),define("WoltLabSuite/Core/Media/Manager/Select",["Core","Dom/Traverse","Dom/Util","Language","ObjectMap","Ui/Dialog","WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,a,r,o,s){"use strict";function l(e){s.call(this,e),this._activeButton=null,this._buttons=elByClass(this._options.buttonClass||"jsMediaSelectButton"),this._storeElements=new a;for(var t=0,n=this._buttons.length;t<n;t++){var r=this._buttons[t],o=elData(r,"store");if(o){var l=elById(o);if(l&&"INPUT"===l.tagName){this._buttons[t].addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),this._storeElements.set(r,l);var c=elCreate("p");c.className="button",i.insertAfter(c,r);var d=elCreate("span");d.className="icon icon16 fa-times",c.appendChild(d),l.value||elHide(c),c.addEventListener(WCF_CLICK_EVENT,this._removeMedia.bind(this))}}}}return e.inherit(l,s,{_addButtonEventListeners:function(){if(l._super.prototype._addButtonEventListeners.call(this),this._mediaManagerMediaList)for(var e=t.childrenByTag(this._mediaManagerMediaList,"LI"),i=0,n=e.length;i<n;i++){var a=e[i],r=elByClass("jsMediaSelectButton",a)[0];r&&(r.classList.remove("jsMediaSelectButton"),r.addEventListener(WCF_CLICK_EVENT,this._chooseMedia.bind(this)))}},_chooseMedia:function(t){if(null===this._activeButton)throw new Error("Media cannot be chosen if no button is active.");var i=this._media.get(~~elData(t.currentTarget,"object-id")),n=elById(elData(this._activeButton,"store"));n.value=i.mediaID,e.triggerEvent(n,"change");var a=elData(this._activeButton,"display");if(a){var s=elById(a);if(s)if(i.isImage)s.innerHTML='<img src="'+(i.smallThumbnailLink?i.smallThumbnailLink:i.link)+'" alt="'+(i.altText&&i.altText[LANGUAGE_ID]?i.altText[LANGUAGE_ID]:"")+'" />';else{var l=o.getIconNameByFilename(i.filename);l&&(l="-"+l),s.innerHTML='<div class="box48" style="margin-bottom: 10px;"><span class="icon icon48 fa-file'+l+'-o"></span><div class="containerHeadline"><h3>'+i.filename+"</h3><p>"+i.formattedFilesize+"</p></div></div>"}}elShow(this._activeButton.nextElementSibling),r.close(this)},_click:function(e){if(e.preventDefault(),this._activeButton=e.currentTarget,l._super.prototype._click.call(this,e),this._mediaManagerMediaList)for(var i,n=this._storeElements.get(this._activeButton),a=t.childrenByTag(this._mediaManagerMediaList,"LI"),r=0,o=a.length;r<o;r++)i=a[r],n.value&&n.value==elData(i,"object-id")?i.classList.add("jsSelected"):i.classList.remove("jsSelected")},getMode:function(){return"select"},setupMediaElement:function(e,t){l._super.prototype.setupMediaElement.call(this,e,t);var i=elBySel("nav.buttonGroupNavigation > ul",t),a=elCreate("li");a.className="jsMediaSelectButton",elData(a,"object-id",e.mediaID),i.appendChild(a),a.innerHTML='<a><span class="icon icon16 fa-check jsTooltip" title="'+n.get("wcf.media.button.select")+'"></span> <span class="invisible">'+n.get("wcf.media.button.select")+"</span></a>"},_removeMedia:function(t){t.preventDefault();var i=t.currentTarget;elHide(i);var n=i.previousElementSibling,a=elById(elData(n,"store"));a.value="",e.triggerEvent(a,"change");var r=elData(n,"display");if(r){var o=elById(r);o&&(o.innerHTML="")}}}),l}),define("WoltLabSuite/Core/Ui/Search/Input",["Ajax","Core","EventKey","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a){"use strict";function r(e,t){this.init(e,t)}return r.prototype={init:function(e,i){if(this._element=e,!(this._element instanceof Element))throw new TypeError("Expected a valid DOM element.");if("INPUT"!==this._element.nodeName||"search"!==this._element.type&&"text"!==this._element.type)throw new Error('Expected an input[type="text"].');this._activeItem=null,this._dropdownContainerId="",this._lastValue="",this._list=null,this._request=null,this._timerDelay=null,this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction"},callbackDropdownInit:null,callbackSelect:null,delay:500,excludedSearchValues:[],minLength:3,noResultPlaceholder:"",preventSubmit:!1},i),elAttr(this._element,"autocomplete","off"),this._element.addEventListener("keydown",this._keydown.bind(this)),this._element.addEventListener("keyup",this._keyup.bind(this))},addExcludedSearchValues:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedSearchValues:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},_keydown:function(e){(null!==this._activeItem&&a.isOpen(this._dropdownContainerId)||this._options.preventSubmit)&&i.Enter(e)&&e.preventDefault(),(i.ArrowUp(e)||i.ArrowDown(e)||i.Escape(e))&&e.preventDefault()},_keyup:function(e){if(null!==this._activeItem)if(a.isOpen(this._dropdownContainerId)){if(i.ArrowUp(e))return e.preventDefault(),this._keyboardPreviousItem();if(i.ArrowDown(e))return e.preventDefault(),this._keyboardNextItem();if(i.Enter(e))return e.preventDefault(),this._keyboardSelectItem()}else this._activeItem=null;if(i.Escape(e))return void a.close(this._dropdownContainerId);var t=this._element.value.trim();if(this._lastValue!==t){if(this._lastValue=t,t.length<this._options.minLength)return void(this._dropdownContainerId&&(a.close(this._dropdownContainerId),this._activeItem=null));this._options.delay?(null!==this._timerDelay&&window.clearTimeout(this._timerDelay),this._timerDelay=window.setTimeout(function(){this._search(t)}.bind(this),this._options.delay)):this._search(t)}},_search:function(t){this._request&&this._request.abortPrevious(),this._request=e.api(this,this._getParameters(t))},_getParameters:function(e){return{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:e}}}},_keyboardNextItem:function(){this._activeItem.classList.remove("active"),this._activeItem.nextElementSibling?this._activeItem=this._activeItem.nextElementSibling:this._activeItem=this._list.children[0],this._activeItem.classList.add("active")},_keyboardPreviousItem:function(){this._activeItem.classList.remove("active"),this._activeItem.previousElementSibling?this._activeItem=this._activeItem.previousElementSibling:this._activeItem=this._list.children[this._list.childElementCount-1],this._activeItem.classList.add("active")},_keyboardSelectItem:function(){this._selectItem(this._activeItem)},_clickSelectItem:function(e){this._selectItem(e.currentTarget)},_selectItem:function(e){this._options.callbackSelect&&!1===this._options.callbackSelect(e)?this._element.value="":this._element.value=elData(e,"label"),this._activeItem=null,a.close(this._dropdownContainerId)},_ajaxSuccess:function(e){var t=!1;if(null===this._list?(this._list=elCreate("ul"),this._list.className="dropdownMenu",t=!0,"function"==typeof this._options.callbackDropdownInit&&this._options.callbackDropdownInit(this._list)):this._list.innerHTML="","object"==typeof e.returnValues){var i,r=this._clickSelectItem.bind(this);for(var o in e.returnValues)e.returnValues.hasOwnProperty(o)&&(i=this._createListItem(e.returnValues[o]),i.addEventListener(WCF_CLICK_EVENT,r),this._list.appendChild(i))}t&&(n.insertAfter(this._list,this._element),a.initFragment(this._element.parentNode,this._list),this._dropdownContainerId=n.identify(this._element.parentNode)),this._dropdownContainerId&&(this._activeItem=null,this._list.childElementCount||!1!==this._handleEmptyResult()?(a.open(this._dropdownContainerId,!0),this._list.childElementCount&&~~elData(this._list.children[0],"object-id")&&(this._activeItem=this._list.children[0],this._activeItem.classList.add("active"))):a.close(this._dropdownContainerId))},_handleEmptyResult:function(){if(!this._options.noResultPlaceholder)return!1;var e=elCreate("li");e.className="dropdownText";var t=elCreate("span");return t.textContent=this._options.noResultPlaceholder,e.appendChild(t),this._list.appendChild(e),!0},_createListItem:function(e){var t=elCreate("li");elData(t,"object-id",e.objectID),elData(t,"label",e.label);var i=elCreate("span");return i.textContent=e.label,t.appendChild(i),t},_ajaxSetup:function(){return{data:this._options.ajax}}},r}),define("WoltLabSuite/Core/Ui/User/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){var a=e.isPlainObject(n)&&!0===n.includeUserGroups;n=e.extend({ajax:{className:"wcf\\data\\user\\UserAction",parameters:{data:{includeUserGroups:a?1:0}}}},n),i._super.prototype.init.call(this,t,n)},_createListItem:function(e){var t=i._super.prototype._createListItem.call(this,e);elData(t,"type",e.type);var n=elCreate("div");return n.className="box16",n.innerHTML="group"===e.type?'<span class="icon icon16 fa-users"></span>':e.icon,n.appendChild(t.children[0]),t.appendChild(n),t}}),i}),define("WoltLabSuite/Core/Ui/Acl/Simple",["Language","StringUtil","Dom/ChangeListener","WoltLabSuite/Core/Ui/User/Search/Input"],function(e,t,i,n){"use strict";function a(e,t){this.init(e,t)}return a.prototype={init:function(e,t){this._prefix=e||"",this._inputName=t||"aclValues",this._build()},_build:function(){var e=elById(this._prefix+"aclInputContainer");elById(this._prefix+"aclAllowAll").addEventListener("change",function(){elHide(e)}),elById(this._prefix+"aclAllowAll_no").addEventListener("change",function(){elShow(e)}),this._list=elById(this._prefix+"aclAccessList"),this._list.addEventListener(WCF_CLICK_EVENT,this._removeItem.bind(this));var t=[];elBySelAll(".aclLabel",this._list,function(e){t.push(e.textContent)}),this._searchInput=new n(elById(this._prefix+"aclSearchInput"),{callbackSelect:this._select.bind(this),includeUserGroups:!0,excludedSearchValues:t,preventSubmit:!0}),this._aclListContainer=elById(this._prefix+"aclListContainer"),i.trigger()},_select:function(n){var a=elData(n,"type"),r=elData(n,"label"),o='<span class="icon icon16 fa-'+("group"===a?"users":"user")+'"></span>';o+='<span class="aclLabel">'+t.escapeHTML(r)+"</span>",o+='<span class="icon icon16 fa-times pointer jsTooltip" title="'+e.get("wcf.global.button.delete")+'"></span>',o+='<input type="hidden" name="'+this._inputName+"["+a+'][]" value="'+elData(n,"object-id")+'">';var s=elCreate("li");s.innerHTML=o;var l=elBySel(".fa-user",this._list);return null===l?this._list.appendChild(s):this._list.insertBefore(s,l.parentNode),elShow(this._aclListContainer),this._searchInput.addExcludedSearchValues(r),i.trigger(),!1},_removeItem:function(e){if(e.target.classList.contains("fa-times")){var t=elBySel(".aclLabel",e.target.parentNode);this._searchInput.removeExcludedSearchValues(t.textContent),elRemove(e.target.parentNode),0===this._list.childElementCount&&elHide(this._aclListContainer)}}},a}),define("WoltLabSuite/Core/Ui/Article/MarkAllAsRead",["Ajax"],function(e){"use strict";return{init:function(){elBySelAll(".markAllAsReadButton",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this))},_click:function(t){t.preventDefault(),e.api(this)},_ajaxSuccess:function(){var e=elBySel(".mainMenu .active .badge");e&&elRemove(e),elBySelAll(".articleList .newMessageBadge",void 0,elRemove)},_ajaxSetup:function(){return{data:{actionName:"markAllAsRead",className:"wcf\\data\\article\\ArticleAction"}}}}}),define("WoltLabSuite/Core/Ui/Article/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,a,r){"use strict";var o,s,l,c=null;return{open:function(e){o=e,r.open(this)},_search:function(t){t.preventDefault();var n=c.parentNode,a=c.value.trim();if(a.length<3)return void elInnerError(n,i.get("wcf.article.search.error.tooShort"));elInnerError(n,!1),e.api(this,{parameters:{searchString:a}})},_click:function(e){e.preventDefault(),o(elData(e.currentTarget,"article-id")),r.close(this)},_ajaxSuccess:function(e){for(var t,a="",r=0,o=e.returnValues.length;r<o;r++)t=e.returnValues[r],a+='<li><div class="containerHeadline pointer" data-article-id="'+t.articleID+'"><h3>'+n.escapeHTML(t.name)+"</h3><small>"+n.escapeHTML(t.displayLink)+"</small></div></li>";l.innerHTML=a,window[a?"elShow":"elHide"](s),a?elBySelAll(".containerHeadline",l,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this)):elInnerError(c.parentNode,i.get("wcf.article.search.error.noResults"))},_ajaxSetup:function(){return{data:{actionName:"search",className:"wcf\\data\\article\\ArticleAction"}}},_dialogSetup:function(){return{id:"wcfUiArticleSearch",options:{onSetup:function(){var e=this._search.bind(this);c=elById("wcfUiArticleSearchInput"),c.addEventListener("keydown",function(i){t.Enter(i)&&e(i)}),c.nextElementSibling.addEventListener(WCF_CLICK_EVENT,e),s=elById("wcfUiArticleSearchResultContainer"),l=elById("wcfUiArticleSearchResultList")}.bind(this),onShow:function(){c.focus()},title:i.get("wcf.article.search")},source:'<div class="section"><dl><dt><label for="wcfUiArticleSearchInput">'+i.get("wcf.article.search.name")+'</label></dt><dd><div class="inputAddon"><input type="text" id="wcfUiArticleSearchInput" class="long"><a href="#" class="inputSuffix"><span class="icon icon16 fa-search"></span></a></div></dd></dl></div><section id="wcfUiArticleSearchResultContainer" class="section" style="display: none;"><header class="sectionHeader"><h2 class="sectionTitle">'+i.get("wcf.article.search.results")+'</h2></header><ol id="wcfUiArticleSearchResultList" class="containerList"></ol></section>'}}}}),define("WoltLabSuite/Core/Ui/Color/Picker",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}var i=function(e,t){if("object"==typeof window.WCF&&"function"==typeof window.WCF.ColorPicker)return(i=function(e,t){var i=new window.WCF.ColorPicker(e);return"function"==typeof t.callbackSubmit&&i.setCallbackSubmit(t.callbackSubmit),i})(e,t);0===n.length&&(window.__wcf_bc_colorPickerInit=function(){n.forEach(function(e){i(e[0],e[1])}),window.__wcf_bc_colorPickerInit=void 0,n=[]}),n.push([e,t])},n=[];return t.prototype={init:function(t,n){if(!(t instanceof Element))throw new TypeError("Expected a valid DOM element, use `UiColorPicker.fromSelector()` if you want to use a CSS selector.");this._options=e.extend({callbackSubmit:null},n),i(t,this._options)}},t.fromSelector=function(e){elBySelAll(e,void 0,function(e){new t(e)})},t}),define("WoltLabSuite/Core/Ui/Comment/Add",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function p(e){this.init(e)}return p.prototype={init:function(e){this._container=e,this._content=elBySel(".jsOuterEditorContainer",this._container),this._textarea=elBySel(".wysiwygTextarea",this._container),this._editor=null,this._loadingOverlay=null,this._content.addEventListener(WCF_CLICK_EVENT,function(e){this._content.classList.contains("collapsed")&&(e.preventDefault(),this._content.classList.remove("collapsed"),this._focusEditor())}.bind(this)),elBySel('button[data-type="save"]',this._container).addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))},_focusEditor:function(){c.element(this._container,function(){window.jQuery(this._textarea).redactor("WoltLabCaret.endOfEditor")}.bind(this))},_submitGuestDialog:function(e){if("keypress"!==e.type||d.Enter(e)){var i=elBySel("input[name=username]",e.currentTarget.closest(".dialogContent"));if(""===i.value)return elInnerError(i,n.get("wcf.global.form.error.empty")),void i.closest("dl").classList.add("formError");var a={parameters:{data:{username:i.value}}};if(h.has("commentAdd")){var r=h.getData("commentAdd");r instanceof Promise?r.then(function(e){a=t.extend(a,e),this._submit(void 0,a)}.bind(this)):(a=t.extend(a,r),this._submit(void 0,a))}else this._submit(void 0,a)}},_submit:function(n,a){if(n&&n.preventDefault(),this._validate()){this._showLoadingOverlay();var r=this._getParameters();i.fire("com.woltlab.wcf.redactor2","submit_text",r.data),u.userId||a||(r.requireGuestDialog=!0),e.api(this,t.extend({parameters:r},a))}},_getParameters:function(){var e=this._container.closest(".commentList");return{data:{message:this._getEditor().code.get(),objectID:~~elData(e,"object-id"),objectTypeID:~~elData(e,"object-type-id")}}},_validate:function(){if(elBySelAll(".innerError",this._container,elRemove),this._getEditor().utils.isEmpty())return this.throwError(this._textarea,n.get("wcf.global.form.error.empty")),!1;var e={api:this,editor:this._getEditor(),message:this._getEditor().code.get(),valid:!0};return i.fire("com.woltlab.wcf.redactor2","validate_text",e),!1!==e.valid},throwError:function(e,t){elInnerError(e,"empty"===t?n.get("wcf.global.form.error.empty"):t)},_showLoadingOverlay:function(){null===this._loadingOverlay&&(this._loadingOverlay=elCreate("div"),this._loadingOverlay.className="commentLoadingOverlay",this._loadingOverlay.innerHTML='<span class="icon icon96 fa-spinner"></span>'),this._content.classList.add("loading"),this._content.appendChild(this._loadingOverlay)},_hideLoadingOverlay:function(){this._content.classList.remove("loading");var e=elBySel(".commentLoadingOverlay",this._content);null!==e&&e.parentNode.removeChild(e)},_reset:function(){this._getEditor().code.set("<p>​</p>"),i.fire("com.woltlab.wcf.redactor2","reset_text"),document.activeElement&&document.activeElement.blur(),this._content.classList.add("collapsed")},_handleError:function(e){this.throwError(this._textarea,e.returnValues.errorType)},_getEditor:function(){if(null===this._editor){if("function"!=typeof window.jQuery)throw new Error("Unable to access editor, jQuery has not been loaded yet.");this._editor=window.jQuery(this._textarea).data("redactor")}return this._editor},_insertMessage:function(e){return r.insertHtml(e.returnValues.template,this._container,"after"),l.show(n.get("wcf.global.success.add")),a.trigger(),this._container.nextElementSibling},_ajaxSuccess:function(e){if(!u.userId&&e.returnValues.guestDialog){s.openStatic("jsDialogGuestComment",e.returnValues.guestDialog,{closable:!1,onClose:function(){h.has("commentAdd")&&h.delete("commentAdd")},title:n.get("wcf.global.confirmation.title")});var t=s.getDialog("jsDialogGuestComment");elBySel("input[type=submit]",t.content).addEventListener(WCF_CLICK_EVENT,this._submitGuestDialog.bind(this)),elBySel('button[data-type="cancel"]',t.content).addEventListener(WCF_CLICK_EVENT,this._cancelGuestDialog.bind(this)),elBySel("input[type=text]",t.content).addEventListener("keypress",this._submitGuestDialog.bind(this))}else{var i=this._insertMessage(e);u.userId||s.close("jsDialogGuestComment"),this._reset(),this._hideLoadingOverlay(),window.setTimeout(function(){c.element(i)}.bind(this),100)}},_ajaxFailure:function(e){return this._hideLoadingOverlay(),null===e||void 0===e.returnValues||void 0===e.returnValues.errorType||(this._handleError(e),!1)},_ajaxSetup:function(){return{data:{actionName:"addComment",className:"wcf\\data\\comment\\CommentAction"},silent:!0}},_cancelGuestDialog:function(){s.close("jsDialogGuestComment"),this._hideLoadingOverlay()}},p}),define("WoltLabSuite/Core/Ui/Comment/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function p(e){this.init(e)}return p.prototype={init:function(e){this._activeElement=null,this._callbackClick=null,this._comments=new o,this._container=e,this._editorContainer=null,this.rebuild(),s.add("Ui/Comment/Edit_"+c.identify(this._container),this.rebuild.bind(this))},rebuild:function(){elBySelAll(".comment",this._container,function(e){if(!this._comments.has(e)){if(elDataBool(e,"can-edit")){var t=elBySel(".jsCommentEditButton",e);null!==t&&(null===this._callbackClick&&(this._callbackClick=this._click.bind(this)),t.addEventListener(WCF_CLICK_EVENT,this._callbackClick))}this._comments.add(e)}}.bind(this))},_click:function(t){t.preventDefault(),null===this._activeElement?(this._activeElement=t.currentTarget.closest(".comment"),this._prepare(),e.api(this,{actionName:"beginEdit",objectIDs:[this._getObjectId(this._activeElement)]})):d.show("wcf.message.error.editorAlreadyInUse",null,"warning")},_prepare:function(){this._editorContainer=elCreate("div"),this._editorContainer.className="commentEditorContainer",this._editorContainer.innerHTML='<span class="icon icon48 fa-spinner"></span>';var e=elBySel(".commentContentContainer",this._activeElement);e.insertBefore(this._editorContainer,e.firstChild)},_showEditor:function(e){var t=this._getEditorId(),i=elBySel(".icon",this._editorContainer);elRemove(i);var r=elCreate("div");r.className="editorContainer",c.setInnerHtml(r,e.returnValues.template),this._editorContainer.appendChild(r);var o=elBySel(".formSubmit",r);elBySel('button[data-type="save"]',o).addEventListener(WCF_CLICK_EVENT,this._save.bind(this)),elBySel('button[data-type="cancel"]',o).addEventListener(WCF_CLICK_EVENT,this._restoreMessage.bind(this)),a.add("com.woltlab.wcf.redactor","submitEditor_"+t,function(e){e.cancel=!0,this._save()}.bind(this));var s=elById(t);"redactor"===n.editor()?window.setTimeout(function(){h.element(this._activeElement)}.bind(this),250):s.focus()},_restoreMessage:function(){this._destroyEditor(),elRemove(this._editorContainer),
-this._activeElement=null},_save:function(){var t={data:{message:""}},i=this._getEditorId();a.fire("com.woltlab.wcf.redactor2","getText_"+i,t.data),this._validate(t)&&(a.fire("com.woltlab.wcf.redactor2","submit_"+i,t),e.api(this,{actionName:"save",objectIDs:[this._getObjectId(this._activeElement)],parameters:t}),this._hideEditor())},_validate:function(e){elBySelAll(".innerError",this._activeElement,elRemove);var t=elById(this._getEditorId());if(window.jQuery(t).data("redactor").utils.isEmpty())return this.throwError(t,r.get("wcf.global.form.error.empty")),!1;var i={api:this,parameters:e,valid:!0};return a.fire("com.woltlab.wcf.redactor2","validate_"+this._getEditorId(),i),!1!==i.valid},throwError:function(e,t){elInnerError(e,t)},_showMessage:function(e){c.setInnerHtml(elBySel(".commentContent .userMessage",this._editorContainer.parentNode),e.returnValues.message),this._restoreMessage(),d.show()},_hideEditor:function(){elHide(elBySel(".editorContainer",this._editorContainer));var e=elCreate("span");e.className="icon icon48 fa-spinner",this._editorContainer.appendChild(e)},_restoreEditor:function(){var e=elBySel(".fa-spinner",this._editorContainer);elRemove(e);var t=elBySel(".editorContainer",this._editorContainer);null!==t&&elShow(t)},_destroyEditor:function(){a.fire("com.woltlab.wcf.redactor2","autosaveDestroy_"+this._getEditorId()),a.fire("com.woltlab.wcf.redactor2","destroy_"+this._getEditorId())},_getEditorId:function(){return"commentEditor"+this._getObjectId(this._activeElement)},_getObjectId:function(e){return~~elData(e,"object-id")},_ajaxFailure:function(e){var t=elBySel(".redactor-layer",this._editorContainer);return null===t?(this._restoreMessage(),!0):(this._restoreEditor(),!e||void 0===e.returnValues||void 0===e.returnValues.errorType||(elInnerError(t,e.returnValues.errorType),!1))},_ajaxSuccess:function(e){switch(e.actionName){case"beginEdit":this._showEditor(e);break;case"save":this._showMessage(e)}},_ajaxSetup:function(){return{data:{className:"wcf\\data\\comment\\CommentAction",parameters:{data:{objectTypeID:~~elData(this._container,"object-type-id")}}},silent:!0}}},p}),define("WoltLabSuite/Core/Ui/Dropdown/Builder",["Core","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!(e instanceof HTMLUListElement))throw new TypeError("Expected a reference to an <ul> element.");if(!e.classList.contains("dropdownMenu"))throw new Error("List does not appear to be a dropdown menu.")}function n(t){var i=elCreate("li");if("divider"===t)return i.className="dropdownDivider",i;"string"==typeof t.identifier&&elData(i,"identifier",t.identifier);var n=elCreate("a");if(n.href="string"==typeof t.href?t.href:"#","function"==typeof t.callback)n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),t.callback(n)});else if("#"===n.getAttribute("href"))throw new Error("Expected either a `href` value or a `callback`.");if(t.hasOwnProperty("attributes")&&e.isPlainObject(t.attributes))for(var r in t.attributes)t.attributes.hasOwnProperty(r)&&elData(n,r,t.attributes[r]);if(i.appendChild(n),void 0!==t.icon&&e.isPlainObject(t.icon)){if("string"!=typeof t.icon.name)throw new TypeError("Expected a valid icon name.");var o=16;"number"==typeof t.icon.size&&-1!==a.indexOf(~~t.icon.size)&&(o=~~t.icon.size);var s=elCreate("span");s.className="icon icon"+o+" fa-"+t.icon.name,n.appendChild(s)}var l="string"==typeof t.label?t.label.trim():"",c="string"==typeof t.labelHtml?t.labelHtml.trim():"";if(""===l&&""===c)throw new TypeError("Expected either a label or a `labelHtml`.");var d=elCreate("span");return d[l?"textContent":"innerHTML"]=l||c,n.appendChild(document.createTextNode(" ")),n.appendChild(d),i}var a=[16,24,32,48,64,96,144];return{create:function(e,t){var i=elCreate("ul");return i.className="dropdownMenu","string"==typeof t&&elData(i,"identifier",t),Array.isArray(e)&&e.length>0&&this.appendItems(i,e),i},buildItem:function(e){return n(e)},appendItem:function(e,t){i(e),e.appendChild(n(t))},appendItems:function(e,t){if(i(e),!Array.isArray(t))throw new TypeError("Expected an array of items.");var a=t.length;if(0===a)throw new Error("Expected a non-empty list of items.");if(1===a)this.appendItem(e,t[0]);else{for(var r=document.createDocumentFragment(),o=0;o<a;o++)r.appendChild(n(t[o]));e.appendChild(r)}},setItems:function(e,t){i(e),e.innerHTML="",this.appendItems(e,t)},attach:function(e,n){i(e),t.initFragment(n,e),n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),t.toggleDropdown(n.id)})},divider:function(){return"divider"}}}),define("WoltLabSuite/Core/Ui/File/Delete",["Ajax","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse","Dictionary"],function(e,t,i,n,a,r,o){"use strict";function s(e,t,i,n){if(this._isSingleImagePreview=i,this._uploadHandler=n,this._buttonContainer=elById(e),null===this._buttonContainer)throw new Error("Element id '"+e+"' is unknown.");if(this._target=elById(t),null===t)throw new Error("Element id '"+t+"' is unknown.");if(this._containers=new o,this._internalId=elData(this._target,"internal-id"),!this._internalId)throw new Error("InternalId is unknown.");this.rebuild()}return s.prototype={_createButtons:function(){for(var e,t,n,a=elBySelAll("li.uploadedFile",this._target),r=!1,o=0,s=a.length;o<s;o++)e=a[o],n=elData(e,"unique-file-id"),this._containers.has(n)||(t={uniqueFileId:n,element:e},this._containers.set(n,t),this._initDeleteButton(e,t),r=!0);r&&i.trigger()},_initDeleteButton:function(e,t){var i=elBySel(".buttonGroup",e);if(null===i)throw new Error("Button group in '"+targetId+"' is unknown.");var a=elCreate("li"),r=elCreate("span");r.classList="button jsDeleteButton small",r.textContent=n.get("wcf.global.button.delete"),a.appendChild(r),i.appendChild(a),a.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,t.uniqueFileId))},_delete:function(t){e.api(this,{uniqueFileId:t,internalId:this._internalId})},rebuild:function(){if(this._isSingleImagePreview){var e=elBySel("img",this._target);if(null!==e){var t=elData(e,"unique-file-id");if(!this._containers.has(t)){var i={uniqueFileId:t,element:e};this._containers.set(t,i),this._deleteButton=elCreate("p"),this._deleteButton.className="button deleteButton";var a=elCreate("span");a.textContent=n.get("wcf.global.button.delete"),this._deleteButton.appendChild(a),this._buttonContainer.appendChild(this._deleteButton),this._deleteButton.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,i.uniqueFileId))}}}else this._createButtons()},_ajaxSuccess:function(e){elRemove(this._containers.get(e.uniqueFileId).element),this._isSingleImagePreview&&(elRemove(this._deleteButton),this._deleteButton=null),this._uploadHandler.checkMaxFiles()},_ajaxSetup:function(){return{url:"index.php?ajax-file-delete/&t="+SECURITY_TOKEN}}},s}),define("WoltLabSuite/Core/Ui/File/Upload",["Core","Language","Dom/Util","WoltLabSuite/Core/Ui/File/Delete","Upload"],function(e,t,i,n,a){"use strict";function r(t,i,a){if(a=a||{},void 0===a.internalId)throw new Error("Missing internal id.");if(this._options=e.extend({name:"__files[]",singleFileRequests:!1,url:"index.php?ajax-file-upload/&t="+SECURITY_TOKEN,imagePreview:!1,maxFiles:null},a),this._options.multiple=null===this._options.maxFiles||this._options.maxFiles>1,0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),this._buttonContainer=elById(t),null===this._buttonContainer)throw new Error("Element id '"+t+"' is unknown.");if(this._target=elById(i),null===i)throw new Error("Element id '"+i+"' is unknown.");if(a.multiple&&"UL"!==this._target.nodeName&&"OL"!==this._target.nodeName)throw new Error("Target element has to be list or table body if uploading multiple files is supported.");this._fileElements=[],this._internalFileId=0,this._multiFileUploadIds=[],this._createButton(),this.checkMaxFiles(),this._deleteHandler=new n(t,i,this._options.imagePreview,this)}return e.inherit(r,a,{_createFileElement:function(e){var t=r._super.prototype._createFileElement.call(this,e);t.classList.add("box64","uploadedFile");var i=elBySel("progress",t),n=elCreate("span");n.className="icon icon64 fa-spinner";var a=t.textContent;t.textContent="",t.append(n);var o=elCreate("div"),s=elCreate("p");s.textContent=a;var l=elCreate("small");l.appendChild(i),o.appendChild(s),o.appendChild(l);var c=elCreate("div");c.appendChild(o);var d=elCreate("ul");return d.className="buttonGroup",c.appendChild(d),t.append(c),t},_failure:function(e,n,a,r,o){for(var s=0,l=this._fileElements[e].length;s<l;s++){this._fileElements[e][s].classList.add("uploadFailed"),elBySel("small",this._fileElements[e][s]).innerHTML="";var c=elBySel(".icon",this._fileElements[e][s]);c.classList.remove("fa-spinner"),c.classList.add("fa-ban");var d=elCreate("span");d.className="innerError",d.textContent=t.get("wcf.upload.error.uploadFailed"),i.insertAfter(d,elBySel("small",this._fileElements[e][s]))}throw new Error("Upload failed: "+n.message)},_upload:function(e,t,i){var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return n&&elRemove(n),r._super.prototype._upload.call(this,e,t,i)},_success:function(e,t,n,a,r){for(var o=0,s=this._fileElements[e].length;o<s;o++)if(void 0!==t.files[o])if(this._options.imagePreview){if(null===t.files[o].image)throw new Error("Expect image for uploaded file. None given.");if(elRemove(this._fileElements[e][o]),null!==elBySel("img.previewImage",this._target))elBySel("img.previewImage",this._target).setAttribute("src",t.files[o].image);else{var l=elCreate("img");l.classList.add("previewImage"),l.setAttribute("src",t.files[o].image),l.setAttribute("style","max-width: 100%;"),elData(l,"unique-file-id",t.files[o].uniqueFileId),this._target.appendChild(l)}}else{elData(this._fileElements[e][o],"unique-file-id",t.files[o].uniqueFileId),elBySel("small",this._fileElements[e][o]).textContent=t.files[o].filesize;var c=elBySel(".icon",this._fileElements[e][o]);c.classList.remove("fa-spinner"),c.classList.add("fa-"+t.files[o].icon)}else{if(void 0===t.error[o])throw new Error("Unknown uploaded file for uploadId "+e+".");this._fileElements[e][o].classList.add("uploadFailed"),elBySel("small",this._fileElements[e][o]).innerHTML="";var c=elBySel(".icon",this._fileElements[e][o]);if(c.classList.remove("fa-spinner"),c.classList.add("fa-ban"),null===elBySel(".innerError",this._fileElements[e][o])){var d=elCreate("span");d.className="innerError",d.textContent=t.error[o].errorMessage,i.insertAfter(d,elBySel("small",this._fileElements[e][o]))}else elBySel(".innerError",this._fileElements[e][o]).textContent=t.error[o].errorMessage}this._deleteHandler.rebuild(),this.checkMaxFiles()},_getFormData:function(){return{internalId:this._options.internalId}},validateUpload:function(e){if(null===this._options.maxFiles||e.length+this.countFiles()<=this._options.maxFiles)return!0;var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return null===n&&(n=elCreate("small"),n.className="innerError",i.insertAfter(n,this._buttonContainer)),n.textContent=t.get("wcf.upload.error.reachedRemainingLimit",{maxFiles:this._options.maxFiles-this.countFiles()}),!1},countFiles:function(){return this._options.imagePreview?null!==elBySel("img",this._target)?1:0:this._target.childElementCount},checkMaxFiles:function(){null!==this._options.maxFiles&&this.countFiles()>=this._options.maxFiles?elHide(this._button):elShow(this._button)}}),r}),define("WoltLabSuite/Core/Ui/ItemList/Filter",["Core","EventKey","Language","List","StringUtil","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";function s(e,t){this.init(e,t)}return s.prototype={init:function(n,a){this._value="",this._options=e.extend({callbackPrepareItem:void 0,enableVisibilityFilter:!0,filterPosition:"bottom"},a),"top"!==this._options.filterPosition&&(this._options.filterPosition="bottom");var r=elById(n);if(null===r)throw new Error("Expected a valid element id, '"+n+"' does not match anything.");if(!r.classList.contains("scrollableCheckboxList")&&"function"!=typeof this._options.callbackPrepareItem)throw new Error("Filter only works with elements with the CSS class 'scrollableCheckboxList'.");elData(r,"filter","showAll");var o=elCreate("div");o.className="itemListFilter",r.parentNode.insertBefore(o,r),o.appendChild(r);var s=elCreate("div");s.className="inputAddon";var l=elCreate("input");l.className="long",l.type="text",l.placeholder=i.get("wcf.global.filter.placeholder"),l.addEventListener("keydown",function(e){t.Enter(e)&&e.preventDefault()}),l.addEventListener("keyup",this._keyup.bind(this));var c=elCreate("a");if(c.href="#",c.className="button inputSuffix jsTooltip",c.title=i.get("wcf.global.filter.button.clear"),c.innerHTML='<span class="icon icon16 fa-times"></span>',c.addEventListener("click",function(e){e.preventDefault(),this.reset()}.bind(this)),s.appendChild(l),s.appendChild(c),this._options.enableVisibilityFilter){var d=elCreate("a");d.href="#",d.className="button inputSuffix jsTooltip",d.title=i.get("wcf.global.filter.button.visibility"),d.innerHTML='<span class="icon icon16 fa-eye"></span>',d.addEventListener(WCF_CLICK_EVENT,this._toggleVisibility.bind(this)),s.appendChild(d)}"bottom"===this._options.filterPosition?o.appendChild(s):o.insertBefore(s,r),this._container=o,this._dropdown=null,this._dropdownId="",this._element=r,this._input=l,this._items=null,this._fragment=null},reset:function(){this._input.value="",this._keyup()},_buildItems:function(){this._items=new n;for(var e="function"==typeof this._options.callbackPrepareItem?this._options.callbackPrepareItem:this._prepareItem.bind(this),t=0,i=this._element.childElementCount;t<i;t++)this._items.add(e(this._element.children[t]))},_prepareItem:function(e){for(var t=e.children[0],i=t.textContent.trim(),n=t.children[0];n.nextSibling;)t.removeChild(n.nextSibling);t.appendChild(document.createTextNode(" "));var a=elCreate("span");return a.textContent=i,t.appendChild(a),{item:e,span:a,text:i}},_keyup:function(){var e=this._input.value.trim();if(this._value!==e){null===this._fragment&&(this._fragment=document.createDocumentFragment(),this._element.style.setProperty("height",this._element.offsetHeight+"px","")),this._fragment.appendChild(this._element),null===this._items&&this._buildItems();var t=new RegExp("("+a.escapeRegExp(e)+")","i"),n=""===e;this._items.forEach(function(i){""===e?(i.span.textContent=i.text,elShow(i.item)):t.test(i.text)?(i.span.innerHTML=i.text.replace(t,"<u>$1</u>"),elShow(i.item),n=!0):elHide(i.item)}),"bottom"===this._options.filterPosition?this._container.insertBefore(this._fragment.firstChild,this._container.firstChild):this._container.appendChild(this._fragment.firstChild),this._value=e,elInnerError(this._container,!n&&i.get("wcf.global.filter.error.noMatches"))}},_toggleVisibility:function(e){e.preventDefault(),e.stopPropagation();var t=e.currentTarget;if(null===this._dropdown){var n=elCreate("ul");n.className="dropdownMenu",["activeOnly","highlightActive","showAll"].forEach(function(e){var t=elCreate("a");elData(t,"type",e),t.href="#",t.textContent=i.get("wcf.global.filter.visibility."+e),t.addEventListener(WCF_CLICK_EVENT,this._setVisibility.bind(this));var a=elCreate("li");if(a.appendChild(t),"showAll"===e){a.className="active";var r=elCreate("li");r.className="dropdownDivider",n.appendChild(r)}n.appendChild(a)}.bind(this)),o.initFragment(t,n),this._setupVisibilityFilter(),this._dropdown=n,this._dropdownId=t.id}o.toggleDropdown(t.id,t)},_setupVisibilityFilter:function(){var e=this._element.nextSibling,t=this._element.parentNode,i=this._element.scrollTop;document.createDocumentFragment().appendChild(this._element),elBySelAll("li",this._element,function(e){var t=elBySel('input[type="checkbox"]',e);if(t)t.checked&&e.classList.add("active"),t.addEventListener("change",function(){e.classList[t.checked?"add":"remove"]("active")});else{var i=elBySel('input[type="radio"]',e);i&&(i.checked&&e.classList.add("active"),i.addEventListener("change",function(){elBySelAll("li",this._element,function(e){e.classList.remove("active")}),e.classList[i.checked?"add":"remove"]("active")}.bind(this)))}}.bind(this)),t.insertBefore(this._element,e),this._element.scrollTop=i},_setVisibility:function(e){e.preventDefault();var t=e.currentTarget,i=elData(t,"type");if(o.close(this._dropdownId),elData(this._element,"filter")!==i){elData(this._element,"filter",i),elBySel(".active",this._dropdown).classList.remove("active"),t.parentNode.classList.add("active");var n=elById(this._dropdownId);n.classList["showAll"===i?"remove":"add"]("active");var a=elBySel(".icon",n);a.classList["showAll"===i?"add":"remove"]("fa-eye"),a.classList["showAll"===i?"remove":"add"]("fa-eye-slash")}}},s}),define("WoltLabSuite/Core/Ui/ItemList/Static",["Core","Dictionary","Language","Dom/Traverse","EventKey","Ui/SimpleDropdown"],function(e,t,i,n,a,r){"use strict";var o="",s=new t,l=!1,c=null,d=null,u=null,h=null,p=null,f=null;return{init:function(t,i,a){var o=elById(t);if(null===o)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(s.has(t)){var l=s.get(t);for(var c in l)if(l.hasOwnProperty(c)){var d=l[c];d instanceof Element&&d.parentNode&&elRemove(d)}r.destroy(t),s.delete(t)}a=e.extend({maxItems:-1,maxLength:-1,isCSV:!1,callbackChange:null,callbackSubmit:null,submitFieldName:""},a);var u=n.parentByTag(o,"FORM");if(null!==u&&!1===a.isCSV){if(!a.submitFieldName.length&&"function"!=typeof a.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");u.addEventListener("submit",function(){var e=this.getValues(t);if(a.submitFieldName.length)for(var i,n=0,r=e.length;n<r;n++)i=elCreate("input"),i.type="hidden",i.name=a.submitFieldName.replace("{$objectId}",e[n].objectId),i.value=e[n].value,u.appendChild(i);else a.callbackSubmit(u,e)}.bind(this))}this._setup();var h=this._createUI(o,a);if(s.set(t,{dropdownMenu:null,element:h.element,list:h.list,listItem:h.element.parentNode,options:a,shadow:h.shadow}),i=h.values.length?h.values:i,Array.isArray(i))for(var p,f=!h.element.disabled,m=0,g=i.length;m<g;m++)p=i[m],"string"==typeof p&&(p={objectId:0,value:p}),this._addItem(t,p,f)},getValues:function(e){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=s.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent})}),i},setValues:function(e,t){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,a,r=s.get(e),o=n.childrenByClass(r.list,"item");for(i=0,a=o.length;i<a;i++)this._removeItem(null,o[i],!0);for(i=0,a=t.length;i<a;i++)this._addItem(e,t[i])},_setup:function(){l||(l=!0,c=this._keyDown.bind(this),d=this._keyPress.bind(this),u=this._keyUp.bind(this),h=this._paste.bind(this),p=this._removeItem.bind(this),f=this._blur.bind(this))},_createUI:function(e,t){var i=elCreate("ol");i.className="inputItemList"+(e.disabled?" disabled":""),elData(i,"element-id",e.id),i.addEventListener(WCF_CLICK_EVENT,function(t){t.target===i&&e.focus()});var n=elCreate("li");n.className="input",i.appendChild(n),e.addEventListener("keydown",c),e.addEventListener("keypress",d),e.addEventListener("keyup",u),e.addEventListener("paste",h),e.addEventListener("blur",f),e.parentNode.insertBefore(i,e),n.appendChild(e),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var a=null,r=[];if(t.isCSV){a=elCreate("input"),a.className="itemListInputShadow",a.type="hidden",a.name=e.name,e.removeAttribute("name"),i.parentNode.insertBefore(a,i);for(var o,s=e.value.split(","),l=0,p=s.length;l<p;l++)o=s[l].trim(),o.length&&r.push(o);if("TEXTAREA"===e.nodeName){var m=elCreate("input");m.type="text",e.parentNode.insertBefore(m,e),m.id=e.id,elRemove(e),e=m}}return{element:e,list:i,shadow:a,values:r}},_handleLimit:function(e){var t=s.get(e);-1!==t.options.maxItems&&(t.list.childElementCount-1<t.options.maxItems?t.element.disabled&&(t.element.disabled=!1,t.element.removeAttribute("placeholder")):t.element.disabled||(t.element.disabled=!0,elAttr(t.element,"placeholder",i.get("wcf.global.form.input.maxItems"))))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;o=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(a.Enter(e)||a.Comma(e)){e.preventDefault();var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain"),t.split(/,/).forEach(function(t){t=t.trim(),0!==t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t,i){var n=s.get(e),a=elCreate("li");a.className="item";var r=elCreate("span");if(r.className="content",elData(r,"object-id",t.objectId),r.textContent=t.value,a.appendChild(r),i||!n.element.disabled){var o=elCreate("a");o.className="icon icon16 fa-times",o.addEventListener(WCF_CLICK_EVENT,p),a.appendChild(o)}n.list.insertBefore(a,n.listItem),n.element.value="",n.element.disabled||this._handleLimit(e);var l=this._syncShadow(n);"function"==typeof n.options.callbackChange&&(null===l&&(l=this.getValues(e)),n.options.callbackChange(e,l))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,a=elData(n,"element-id"),r=s.get(a);n.removeChild(t),i||r.element.focus(),this._handleLimit(a);var o=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===o&&(o=this.getValues(a)),r.options.callbackChange(a,o))},_syncShadow:function(e){if(!e.options.isCSV)return null;for(var t="",i=this.getValues(e.element.id),n=0,a=i.length;n<a;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=(s.get(e.currentTarget.id),e.currentTarget);window.setTimeout(function(){var e=t.value.trim();e.length&&this._addItem(t.id,{objectId:0,value:e})}.bind(this),100)}}}),define("WoltLabSuite/Core/Ui/ItemList/User",["WoltLabSuite/Core/Ui/ItemList"],function(e){"use strict";return{init:function(t,i){e.init(t,[],{ajax:{className:"wcf\\data\\user\\UserAction",parameters:{data:{includeUserGroups:~~i.includeUserGroups,restrictUserGroupIDs:Array.isArray(i.restrictUserGroupIDs)?i.restrictUserGroupIDs:[]}}},callbackChange:"function"==typeof i.callbackChange?i.callbackChange:null,callbackSyncShadow:i.csvPerType?this._syncShadow.bind(this):null,callbackSetupValues:"function"==typeof i.callbackSetupValues?i.callbackSetupValues:null,excludedSearchValues:Array.isArray(i.excludedSearchValues)?i.excludedSearchValues:[],isCSV:!0,maxItems:~~i.maxItems||-1,restricted:!0})},getValues:function(t){return e.getValues(t)},_syncShadow:function(e){var t=this.getValues(e.element.id),i=[],n=[];return t.forEach(function(e){e.type&&"group"===e.type?n.push(e.objectId):i.push(e.value)}),e.shadow.value=i.join(","),e._shadowGroups||(e._shadowGroups=elCreate("input"),e._shadowGroups.type="hidden",e._shadowGroups.name=e.shadow.name+"GroupIDs",e.shadow.parentNode.insertBefore(e._shadowGroups,e.shadow)),e._shadowGroups.value=n.join(","),t}}}),define("WoltLabSuite/Core/Ui/User/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination"],function(e,t,i,n,a,r){"use strict";function o(e){this.init(e)}return o.prototype={init:function(e){this._cache=new i,this._pageCount=0,this._pageNo=1,this._options=t.extend({className:"",dialogTitle:"",parameters:{}},e)},open:function(){this._pageNo=1,this._showPage()},_showPage:function(t){if("number"==typeof t&&(this._pageNo=~~t),0!==this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount))throw new RangeError("pageNo must be between 1 and "+this._pageCount+" ("+this._pageNo+" given).");if(this._cache.has(this._pageNo)){var i=a.open(this,this._cache.get(this._pageNo));if(this._pageCount>1){var n=elBySel(".jsPagination",i.content);null!==n&&new r(n,{activePage:this._pageNo,maxPage:this._pageCount,callbackSwitch:this._showPage.bind(this)});var o=i.content.parentNode;o.scrollTop>0&&(o.scrollTop=0)}}else this._options.parameters.pageNo=this._pageNo,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&(this._pageCount=~~e.returnValues.pageCount),this._cache.set(this._pageNo,e.returnValues.template),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserList",className:this._options.className,interfaceName:"wcf\\data\\IGroupedUserListAction"}}},_dialogSetup:function(){return{id:n.getUniqueId(),options:{title:this._options.dialogTitle},source:null}}},o}),define("WoltLabSuite/Core/Ui/Reaction/CountButtons",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","EventHandler"],function(e,t,i,n,a,r,o,s,l,c){"use strict";function d(e,t){this.init(e,t)}return d.prototype={init:function(e,n){if(""===n.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objects=new i,this._objectType=e,this._options=t.extend({summaryListSelector:".reactionSummaryList",containerSelector:"",isSingleItem:!1,parameters:{data:{}}},n),this.initContainers(n,e),o.add("WoltLabSuite/Core/Ui/Reaction/CountButtons-"+e,this.initContainers.bind(this))},initContainers:function(){for(var e,t,i,n=elBySelAll(this._options.containerSelector),a=!1,r=0,l=n.length;r<l;r++)if(e=n[r],!this._containers.has(s.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,summary:null,objectId:i,element:e},this._containers.set(s.identify(e),t),this._initReactionCountButtons(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),a=!0}a&&o.trigger()},updateCountButtons:function(e,t){var i=!1;this._objects.get(e).forEach(function(e){var n=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e.element);if(null!==n){for(var a={},o=elBySelAll(".reactCountButton",n),s=0,l=o.length;s<l;s++){var c=elData(o[s],"reaction-type-id");t.hasOwnProperty(c)?a[c]=o[s]:elRemove(o[s])}Object.keys(t).forEach(function(e){if(void 0!==a[e]){elBySel(".reactionCount",a[e]).innerHTML=r.shortUnit(t[e])}else if(void 0!==REACTION_TYPES[e]){var o=elCreate("span");o.className="reactCountButton",o.innerHTML=REACTION_TYPES[e].renderedIcon,elData(o,"reaction-type-id",e);var s=elCreate("span");s.className="reactionCount",s.innerHTML=r.shortUnit(t[e]),o.appendChild(s),n.appendChild(o),i=!0}},this),window[n.childElementCount>0?"elShow":"elHide"](n)}}.bind(this)),i&&o.trigger()},_initReactionCountButtons:function(e,t){var i=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e);null!==i&&i.addEventListener(WCF_CLICK_EVENT,this._showReactionOverlay.bind(this,t.objectId))},_showReactionOverlay:function(e,t){t.preventDefault(),this._currentObjectId=e,this._showOverlay()},_showOverlay:function(){this._options.parameters.data.containerID=this._objectType+"-"+this._currentObjectId,this._options.parameters.data.objectID=this._currentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){c.fire("com.woltlab.wcf.ReactionCountButtons","openDialog",e),l.open(this,e.returnValues.template),l.setTitle("userReactionOverlay-"+this._objectType,e.returnValues.title)},_ajaxSetup:function(){return{data:{actionName:"getReactionDetails",className:"\\wcf\\data\\reaction\\ReactionAction"}}},_dialogSetup:function(){return{id:"userReactionOverlay-"+this._objectType,options:{title:""},source:null}}},d}),define("WoltLabSuite/Core/Ui/Reaction/Handler",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/User/List","User","WoltLabSuite/Core/Ui/Reaction/CountButtons","Ui/Alignment","Ui/CloseOverlay"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p){"use strict";function f(e,t){this.init(e,t)}return f.prototype={init:function(e,n){if(""===n.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objectType=e,this._cache=new i,this._objects=new i,this._popoverCurrentObjectId=0,this._popover=null,this._options=t.extend({buttonSelector:".reactButton",containerSelector:"",isButtonGroupNavigation:!1,isSingleItem:!1,parameters:{data:{}}},n),this.initReactButtons(n,e),this.countButtons=new u(this._objectType,this._options),o.add("WoltLabSuite/Core/Ui/Reaction/Handler-"+e,this.initReactButtons.bind(this)),p.add("WoltLabSuite/Core/Ui/Reaction/Handler",this._closePopover.bind(this))},initReactButtons:function(){for(var e,t,i,n=elBySelAll(this._options.containerSelector),a=!1,r=0,l=n.length;r<l;r++)if(e=n[r],!this._containers.has(s.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,objectId:i,element:e},this._containers.set(s.identify(e),t),this._initReactButton(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),a=!0}a&&o.trigger()},_initReactButton:function(e,t){if(this._options.isSingleItem?t.reactButton=elBySel(this._options.buttonSelector):t.reactButton=elBySel(this._options.buttonSelector,e),null!==t.reactButton&&0!==t.reactButton.length){if(1===Object.keys(REACTION_TYPES).length){var i=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];t.reactButton.title=i.title;elBySel(".invisible",t.reactButton).innerText=i.title}t.reactButton.addEventListener(WCF_CLICK_EVENT,this._toggleReactPopover.bind(this,t.objectId,t.reactButton))}},_updateReactButton:function(e,t){this._objects.get(e).forEach(function(e){null!==e.reactButton&&(t?(e.reactButton.classList.add("active"),elData(e.reactButton,"reaction-type-id",t)):(elData(e.reactButton,"reaction-type-id",0),e.reactButton.classList.remove("active")))})},_markReactionAsActive:function(){var e=null;if(this._objects.get(this._popoverCurrentObjectId).forEach(function(t){null!==t.reactButton&&(e=~~elData(t.reactButton,"reaction-type-id"))}),null===e)throw new Error("Unable to find react button for current popover.");if(elBySelAll(".reactionTypeButton.active",this._getPopover(),function(e){e.classList.remove("active")}),e){var t=elBySel('.reactionTypeButton[data-reaction-type-id="'+e+'"]',this._getPopover());t.classList.add("active"),0==~~elData(t,"is-assignable")&&elShow(t)}},_toggleReactPopover:function(e,t,i){if(null!==i&&(i.preventDefault(),i.stopPropagation()),1===Object.keys(REACTION_TYPES).length){var n=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];this._popoverCurrentObjectId=e,this._react(n.reactionTypeID)}else 0===this._popoverCurrentObjectId||this._popoverCurrentObjectId!==e?this._openReactPopover(e,t):this._closePopover(e,t)},_openReactPopover:function(e,t){0!==this._popoverCurrentObjectId&&this._closePopover(),this._popoverCurrentObjectId=e,this._markReactionAsActive(),h.set(this._getPopover(),t,{pointer:!0,horizontal:this._options.isButtonGroupNavigation?"left":"center",vertical:"top"}),this._options.isButtonGroupNavigation&&t.closest("nav").style.setProperty("opacity","1",""),this._getPopover().classList.remove("forceHide"),this._getPopover().classList.add("active")},_getPopover:function(){if(null==this._popover){this._popover=elCreate("div"),this._popover.className="reactionPopover forceHide";var e=elCreate("div");e.className="reactionPopoverContent";var t=elCreate("ul"),i=this._getSortedReactionTypes();for(var n in i)if(i.hasOwnProperty(n)){var a=i[n],r=elCreate("li");r.className="reactionTypeButton jsTooltip",elData(r,"reaction-type-id",a.reactionTypeID),elData(r,"title",a.title),
-elData(r,"is-assignable",~~a.isAssignable),r.title=a.title;var s=elCreate("span");s.className="reactionTypeButtonTitle",s.innerHTML=a.title,r.innerHTML=a.renderedIcon,r.appendChild(s),r.addEventListener(WCF_CLICK_EVENT,this._react.bind(this,a.reactionTypeID)),a.isAssignable||elHide(r),t.appendChild(r)}e.appendChild(t),this._popover.appendChild(e);var l=elCreate("span");l.className="elementPointer",l.appendChild(elCreate("span")),this._popover.appendChild(l),document.body.appendChild(this._popover),o.trigger()}return this._popover},_getSortedReactionTypes:function(){var e=[];for(var t in REACTION_TYPES)REACTION_TYPES.hasOwnProperty(t)&&e.push(REACTION_TYPES[t]);return e.sort(function(e,t){return e.showOrder-t.showOrder}),e},_closePopover:function(){0!==this._popoverCurrentObjectId&&(this._getPopover().classList.remove("active"),elBySelAll('.reactionTypeButton[data-is-assignable="0"]',this._getPopover(),elHide),this._options.isButtonGroupNavigation&&this._objects.get(this._popoverCurrentObjectId).forEach(function(e){e.reactButton.closest("nav").style.cssText=""}),this._popoverCurrentObjectId=0)},_react:function(t){0!=~~this._popoverCurrentObjectId&&(this._options.parameters.reactionTypeID=t,this._options.parameters.data.objectID=this._popoverCurrentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters}),this._closePopover())},_ajaxSuccess:function(e){this.countButtons.updateCountButtons(e.returnValues.objectID,e.returnValues.reactions),this._updateReactButton(e.returnValues.objectID,e.returnValues.reactionTypeID)},_ajaxSetup:function(){return{data:{actionName:"react",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},f}),define("WoltLabSuite/Core/Ui/Like/Handler",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/User/List","User","WoltLabSuite/Core/Ui/Reaction/Handler"],function(e,t,i,n,a,r,o,s,l,c,d,u){"use strict";function h(e,t){this.init(e,t)}return h.prototype={init:function(e,i){if(""===i.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Like/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new a,this._details=new a,this._objectType=e,this._options=t.extend({badgeClassNames:"",isSingleItem:!1,markListItemAsActive:!1,renderAsButton:!0,summaryPrepend:!0,summaryUseIcon:!0,canDislike:!1,canLike:!1,canLikeOwnContent:!1,canViewSummary:!1,badgeContainerSelector:".messageHeader .messageStatus",buttonAppendToSelector:".messageFooter .messageFooterButtons",buttonBeforeSelector:"",containerSelector:"",summarySelector:".messageFooterGroup"},i),this.initContainers(i,e),o.add("WoltLabSuite/Core/Ui/Like/Handler-"+e,this.initContainers.bind(this)),new u(this._objectType,{containerSelector:this._options.containerSelector,summaryListSelector:".reactionSummaryList"})},initContainers:function(){for(var e,t,i=elBySelAll(this._options.containerSelector),n=!1,a=0,r=i.length;a<r;a++)e=i[a],this._containers.has(e)||(t={badge:null,dislikeButton:null,likeButton:null,summary:null,dislikes:~~elData(e,"like-dislikes"),liked:~~elData(e,"like-liked"),likes:~~elData(e,"like-likes"),objectId:~~elData(e,"object-id"),users:JSON.parse(elData(e,"like-users"))},this._containers.set(e,t),this._buildWidget(e,t),n=!0);n&&o.trigger()},_buildWidget:function(e,t){var i,n,a,o=!0;if(a=this._options.isSingleItem?elBySel(this._options.summarySelector):elBySel(this._options.summarySelector,e),null===a&&(a=this._options.isSingleItem?elBySel(this._options.badgeContainerSelector):elBySel(this._options.badgeContainerSelector,e),o=!1),null!==a){i=elCreate("ul"),i.classList.add("reactionSummaryList"),o?i.classList.add("likesSummary"):i.classList.add("reactionSummaryListTiny");for(var l in t.users)if("reactionTypeID"!==l&&REACTION_TYPES.hasOwnProperty(l)){var c=elCreate("li");c.className="reactCountButton",elData(c,"reaction-type-id",l);var u=elCreate("span");u.className="reactionCount",u.innerHTML=r.shortUnit(t.users[l]),c.appendChild(u),c.innerHTML=REACTION_TYPES[l].renderedIcon+c.innerHTML,i.appendChild(c)}o?this._options.summaryPrepend?s.prepend(i,a):a.appendChild(i):"OL"===a.nodeName||"UL"===a.nodeName?(n=elCreate("li"),n.appendChild(i),a.appendChild(n)):a.appendChild(i),t.badge=i}if(this._options.canLike&&(d.userId!=elData(e,"user-id")||this._options.canLikeOwnContent)){var h=this._options.buttonAppendToSelector?this._options.isSingleItem?elBySel(this._options.buttonAppendToSelector):elBySel(this._options.buttonAppendToSelector,e):null,p=this._options.buttonBeforeSelector?this._options.isSingleItem?elBySel(this._options.buttonBeforeSelector):elBySel(this._options.buttonBeforeSelector,e):null;if(null===p&&null===h)throw new Error("Unable to find insert location for like/dislike buttons.");t.likeButton=this._createButton(e,t.users.reactionTypeID,p,h)}},_createButton:function(e,t,i,a){var r=n.get("wcf.reactions.react"),o=elCreate("li");o.className="wcfReactButton";var s=elCreate("a");s.className="jsTooltip reactButton",this._options.renderAsButton&&s.classList.add("button"),s.href="#",s.title=r;var l=elCreate("span");l.className="icon icon16 fa-smile-o",void 0===t||0==t?elData(l,"reaction-type-id",0):(elData(s,"reaction-type-id",t),s.classList.add("active")),s.appendChild(l);var c=elCreate("span");return c.className="invisible",c.innerHTML=r,s.appendChild(document.createTextNode(" ")),s.appendChild(c),o.appendChild(s),i?i.parentNode.insertBefore(o,i):a.appendChild(o),s}},h}),define("WoltLabSuite/Core/Ui/Message/InlineEditor",["Ajax","Core","Dictionary","Environment","EventHandler","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function p(e){this.init(e)}return p.prototype={init:function(e){this._activeDropdownElement=null,this._activeElement=null,this._dropdownMenu=null,this._elements=new o,this._options=t.extend({canEditInline:!1,className:"",containerId:0,dropdownIdentifier:"",editorPrefix:"messageEditor",messageSelector:".jsMessage",quoteManager:null},e),this.rebuild(),s.add("Ui/Message/InlineEdit_"+this._options.className,this.rebuild.bind(this))},rebuild:function(){for(var e,t,i,n=elBySelAll(this._options.messageSelector),a=0,r=n.length;a<r;a++)if(i=n[a],!this._elements.has(i)){e=elBySel(".jsMessageEditButton",i),null!==e&&(t=elDataBool(i,"can-edit"),this._options.canEditInline||elDataBool(i,"can-edit-inline")?(e.addEventListener(WCF_CLICK_EVENT,this._clickDropdown.bind(this,i)),e.classList.add("jsDropdownEnabled"),t&&e.addEventListener("dblclick",this._click.bind(this,i))):t&&e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,i)));var o=elBySel(".messageBody",i),s=elBySel(".messageFooter",i),l=elBySel(".messageHeader",i);this._elements.set(i,{button:e,messageBody:o,messageBodyEditor:null,messageFooter:s,messageFooterButtons:elBySel(".messageFooterButtons",s),messageHeader:l,messageText:elBySel(".messageText",o)})}},_click:function(t,i){null===t&&(t=this._activeDropdownElement),i&&i.preventDefault(),null===this._activeElement?(this._activeElement=t,this._prepare(),e.api(this,{actionName:"beginEdit",parameters:{containerID:this._options.containerId,objectID:this._getObjectId(t)}})):d.show("wcf.message.error.editorAlreadyInUse",null,"warning")},_clickDropdown:function(e,i){i.preventDefault();var n=i.currentTarget;if(!n.classList.contains("dropdownToggle")){if(n.classList.add("dropdownToggle"),n.parentNode.classList.add("dropdown"),function(e,t){e.addEventListener(WCF_CLICK_EVENT,function(i){i.preventDefault(),i.stopPropagation(),this._activeDropdownElement=t,u.toggleDropdown(this._options.dropdownIdentifier,e)}.bind(this))}.bind(this)(n,e),null===this._dropdownMenu){this._dropdownMenu=elCreate("ul"),this._dropdownMenu.className="dropdownMenu";var r=this._dropdownGetItems();a.fire("com.woltlab.wcf.inlineEditor","dropdownInit_"+this._options.dropdownIdentifier,{items:r}),this._dropdownBuild(r),u.init(this._options.dropdownIdentifier,this._dropdownMenu),u.registerCallback(this._options.dropdownIdentifier,this._dropdownToggle.bind(this))}setTimeout(function(){t.triggerEvent(n,WCF_CLICK_EVENT)},10)}},_dropdownBuild:function(e){for(var t,i,n,a=this._clickDropdownItem.bind(this),o=0,s=e.length;o<s;o++)t=e[o],n=elCreate("li"),elData(n,"item",t.item),"divider"===t.item?n.className="dropdownDivider":(i=elCreate("span"),i.textContent=r.get(t.label),n.appendChild(i),"editItem"===t.item?n.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,null)):n.addEventListener(WCF_CLICK_EVENT,a)),this._dropdownMenu.appendChild(n)},_dropdownToggle:function(e,t){var i=this._elements.get(this._activeDropdownElement);if(i.button.parentNode.classList["open"===t?"add":"remove"]("dropdownOpen"),i.messageFooterButtons.classList["open"===t?"add":"remove"]("forceVisible"),"open"===t){var n=this._dropdownOpen();a.fire("com.woltlab.wcf.inlineEditor","dropdownOpen_"+this._options.dropdownIdentifier,{element:this._activeDropdownElement,visibility:n});for(var r,o,s=!1,l=0;l<this._dropdownMenu.childElementCount;l++)o=this._dropdownMenu.children[l],r=elData(o,"item"),"divider"===r?s?(elShow(o),s=!1):elHide(o):objOwns(n,r)&&!1===n[r]?(elHide(o),l>0&&l+1===this._dropdownMenu.childElementCount&&"divider"===elData(o.previousElementSibling,"item")&&elHide(o.previousElementSibling)):(elShow(o),s=!0)}},_dropdownGetItems:function(){},_dropdownOpen:function(){},_dropdownSelect:function(e){},_clickDropdownItem:function(e){e.preventDefault();var t=elData(e.currentTarget,"item"),i={cancel:!1,element:this._activeDropdownElement,item:t};a.fire("com.woltlab.wcf.inlineEditor","dropdownItemClick_"+this._options.dropdownIdentifier,i),!0===i.cancel?e.preventDefault():this._dropdownSelect(t)},_prepare:function(){var e=this._elements.get(this._activeElement),t=elCreate("div");t.className="messageBody editor",e.messageBodyEditor=t;var i=elCreate("span");i.className="icon icon48 fa-spinner",t.appendChild(i),c.insertAfter(t,e.messageBody),elHide(e.messageBody)},_showEditor:function(e){var t=this._getEditorId(),i=this._elements.get(this._activeElement);this._activeElement.classList.add("jsInvalidQuoteTarget");var r=l.childByClass(i.messageBodyEditor,"icon");elRemove(r);var o=i.messageBodyEditor,s=elCreate("div");s.className="editorContainer",c.setInnerHtml(s,e.returnValues.template),o.appendChild(s);var d=elBySel(".formSubmit",s);elBySel('button[data-type="save"]',d).addEventListener(WCF_CLICK_EVENT,this._save.bind(this)),elBySel('button[data-type="cancel"]',d).addEventListener(WCF_CLICK_EVENT,this._restoreMessage.bind(this)),a.add("com.woltlab.wcf.redactor","submitEditor_"+t,function(e){e.cancel=!0,this._save()}.bind(this)),elHide(i.messageHeader),elHide(i.messageFooter);var u=elById(t);"redactor"===n.editor()?window.setTimeout(function(){this._options.quoteManager&&this._options.quoteManager.setAlternativeEditor(t),h.element(this._activeElement)}.bind(this),250):u.focus()},_restoreMessage:function(){var e=this._elements.get(this._activeElement);this._destroyEditor(),elRemove(e.messageBodyEditor),e.messageBodyEditor=null,elShow(e.messageBody),elShow(e.messageFooter),elShow(e.messageHeader),this._activeElement.classList.remove("jsInvalidQuoteTarget"),this._activeElement=null,this._options.quoteManager&&this._options.quoteManager.clearAlternativeEditor()},_save:function(){var t={containerID:this._options.containerId,data:{message:""},objectID:this._getObjectId(this._activeElement),removeQuoteIDs:this._options.quoteManager?this._options.quoteManager.getQuotesMarkedForRemoval():[]},i=this._getEditorId(),n=elById("settings_"+i);n&&elBySelAll("input, select, textarea",n,function(e){if("INPUT"!==e.nodeName||"checkbox"!==e.type&&"radio"!==e.type||e.checked){var i=e.name;if(t.hasOwnProperty(i))throw new Error("Variable overshadowing, key '"+i+"' is already present.");t[i]=e.value.trim()}}),a.fire("com.woltlab.wcf.redactor2","getText_"+i,t.data);var r=this._validate(t);r instanceof Promise||(r=!1===r?Promise.reject():Promise.resolve()),r.then(function(){a.fire("com.woltlab.wcf.redactor2","submit_"+i,t),e.api(this,{actionName:"save",parameters:t}),this._hideEditor()}.bind(this),function(e){console.log("Validation of post edit failed: "+e)})},_validate:function(e){elBySelAll(".innerError",this._activeElement,elRemove);var t={api:this,parameters:e,valid:!0,promises:[]};return a.fire("com.woltlab.wcf.redactor2","validate_"+this._getEditorId(),t),t.promises.push(Promise[t.valid?"resolve":"reject"]()),Promise.all(t.promises)},throwError:function(e,t){elInnerError(e,t)},_showMessage:function(e){var t=this._activeElement,i=this._getEditorId(),n=this._elements.get(t),r=elBySelAll(".attachmentThumbnailList, .attachmentFileList",n.messageFooter);if(c.setInnerHtml(l.childByClass(n.messageBody,"messageText"),e.returnValues.message),"string"==typeof e.returnValues.attachmentList){for(var o=0,s=r.length;o<s;o++)elRemove(r[o]);var u=elCreate("div");c.setInnerHtml(u,e.returnValues.attachmentList);for(var h;u.childNodes.length;)h=u.childNodes[u.childNodes.length-1],n.messageFooter.insertBefore(h,n.messageFooter.firstChild)}if("string"==typeof e.returnValues.poll){var p=elBySel(".pollContainer",n.messageBody);null!==p&&elRemove(p.parentNode);var f=elCreate("div");f.className="jsInlineEditorHideContent",c.setInnerHtml(f,e.returnValues.poll),c.prepend(f,n.messageBody)}this._restoreMessage(),this._updateHistory(this._getHash(this._getObjectId(t))),a.fire("com.woltlab.wcf.redactor","autosaveDestroy_"+i),d.show(),this._options.quoteManager&&(this._options.quoteManager.clearAlternativeEditor(),this._options.quoteManager.countQuotes())},_hideEditor:function(){var e=this._elements.get(this._activeElement);elHide(l.childByClass(e.messageBodyEditor,"editorContainer"));var t=elCreate("span");t.className="icon icon48 fa-spinner",e.messageBodyEditor.appendChild(t)},_restoreEditor:function(){var e=this._elements.get(this._activeElement),t=elBySel(".fa-spinner",e.messageBodyEditor);elRemove(t);var i=l.childByClass(e.messageBodyEditor,"editorContainer");null!==i&&elShow(i)},_destroyEditor:function(){a.fire("com.woltlab.wcf.redactor2","autosaveDestroy_"+this._getEditorId()),a.fire("com.woltlab.wcf.redactor2","destroy_"+this._getEditorId())},_getHash:function(e){return"#message"+e},_updateHistory:function(e){window.location.hash=e},_getEditorId:function(){return this._options.editorPrefix+this._getObjectId(this._activeElement)},_getObjectId:function(e){return~~elData(e,"object-id")},_ajaxFailure:function(e){var t=this._elements.get(this._activeElement),i=elBySel(".redactor-layer",t.messageBodyEditor);return null===i?(this._restoreMessage(),!0):(this._restoreEditor(),!e||void 0===e.returnValues||void 0===e.returnValues.realErrorMessage||(elInnerError(i,e.returnValues.realErrorMessage),!1))},_ajaxSuccess:function(e){switch(e.actionName){case"beginEdit":this._showEditor(e);break;case"save":this._showMessage(e)}},_ajaxSetup:function(){return{data:{className:this._options.className,interfaceName:"wcf\\data\\IMessageInlineEditorAction"},silent:!0}},legacyEdit:function(e){this._click(elById(e),null)}},p}),define("WoltLabSuite/Core/Ui/Message/Manager",["Ajax","Core","Dictionary","Language","Dom/ChangeListener","Dom/Util"],function(e,t,i,n,a,r){"use strict";function o(e){this.init(e)}return o.prototype={init:function(e){this._elements=null,this._options=t.extend({className:"",selector:""},e),this.rebuild(),a.add("Ui/Message/Manager"+this._options.className,this.rebuild.bind(this))},rebuild:function(){this._elements=new i;for(var e,t=elBySelAll(this._options.selector),n=0,a=t.length;n<a;n++)e=t[n],this._elements.set(elData(e,"object-id"),e)},getPermission:function(e,t){t="can-"+this._getAttributeName(t);var i=this._elements.get(e);if(void 0===i)throw new Error("Unknown object id '"+e+"' for selector '"+this._options.selector+"'");return elDataBool(i,t)},getPropertyValue:function(e,t,i){var n=this._elements.get(e);if(void 0===n)throw new Error("Unknown object id '"+e+"' for selector '"+this._options.selector+"'");return window[i?"elDataBool":"elData"](n,this._getAttributeName(t))},update:function(t,i,n){e.api(this,{actionName:i,parameters:n||{},objectIDs:[t]})},updateItems:function(e,t){Array.isArray(e)||(e=[e]);for(var i,n=0,a=e.length;n<a;n++)if(void 0!==(i=this._elements.get(e[n])))for(var r in t)t.hasOwnProperty(r)&&this._update(i,r,t[r])},updateAllItems:function(e){var t=[];this._elements.forEach(function(e,i){t.push(i)}.bind(this)),this.updateItems(t,e)},setNote:function(e,t,i){var n=this._elements.get(e);if(void 0===n)throw new Error("Unknown object id '"+e+"' for selector '"+this._options.selector+"'");var a=elBySel(".messageFooterNotes",n),r=elBySel("."+t,a);i?(null===r&&(r=elCreate("p"),r.className="messageFooterNote "+t,a.appendChild(r)),r.innerHTML=i):null!==r&&elRemove(r)},_update:function(e,t,i){elData(e,this._getAttributeName(t),i);var n=1==i||!0===i||"true"===i;this._updateState(e,t,i,n)},_updateState:function(e,t,i,n){switch(t){case"isDeleted":e.classList[n?"add":"remove"]("messageDeleted"),this._toggleMessageStatus(e,"jsIconDeleted","wcf.message.status.deleted","red",n);break;case"isDisabled":e.classList[n?"add":"remove"]("messageDisabled"),this._toggleMessageStatus(e,"jsIconDisabled","wcf.message.status.disabled","green",n)}},_toggleMessageStatus:function(e,t,i,a,o){var s=elBySel(".messageStatus",e);if(null===s){var l=elBySel(".messageHeaderMetaData",e);if(null===l)return;s=elCreate("ul"),s.className="messageStatus",r.insertAfter(s,l)}var c=elBySel("."+t,s);if(o){if(null!==c)return;c=elCreate("span"),c.className="badge label "+a+" "+t,c.textContent=n.get(i);var d=elCreate("li");d.appendChild(c),s.appendChild(d)}else{if(null===c)return;elRemove(c.parentNode)}},_getAttributeName:function(e){if(-1!==e.indexOf("-"))return e;for(var t,i="",n=e.split(/([A-Z][a-z]+)/),a=0,r=n.length;a<r;a++)t=n[a],t.length&&(i.length&&(i+="-"),i+=t.toLowerCase());return i},_ajaxSuccess:function(){throw new Error("Method _ajaxSuccess() must be implemented by deriving functions.")},_ajaxSetup:function(){return{data:{className:this._options.className}}}},o}),define("WoltLabSuite/Core/Ui/Message/Reply",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function p(e){this.init(e)}return p.prototype={init:function(e){this._options=t.extend({ajax:{className:""},quoteManager:null,successMessage:"wcf.global.success.add"},e),this._container=elById("messageQuickReply"),this._content=elBySel(".messageContent",this._container),this._textarea=elById("text"),this._editor=null,this._guestDialogId="",this._loadingOverlay=null,elBySel(".message",this._container).classList.add("jsInvalidQuoteTarget");var i=this._submit.bind(this);elBySel('button[data-type="save"]',this._container).addEventListener(WCF_CLICK_EVENT,i);for(var n=elBySelAll(".jsQuickReply"),a=0,r=n.length;a<r;a++)n[a].addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this._getEditor().WoltLabReply.showEditor(),c.element(this._container,function(){this._getEditor().WoltLabCaret.endOfEditor()}.bind(this))}.bind(this))},_submitGuestDialog:function(e){if("keypress"!==e.type||d.Enter(e)){var i=elBySel("input[name=username]",e.currentTarget.closest(".dialogContent"));if(""===i.value)return elInnerError(i,n.get("wcf.global.form.error.empty")),void i.closest("dl").classList.add("formError");var a={parameters:{data:{username:i.value}}},r=elData(e.currentTarget,"captcha-id");if(h.has(r)){var o=h.getData(r);o instanceof Promise?o.then(function(e){a=t.extend(a,e),this._submit(void 0,a)}.bind(this)):(a=t.extend(a,h.getData(r)),this._submit(void 0,a))}else this._submit(void 0,a)}},_submit:function(n,a){if(n&&n.preventDefault(),(!this._content.classList.contains("loading")||this._guestDialogId&&s.isOpen(this._guestDialogId))&&this._validate()){this._showLoadingOverlay();var o=r.getDataAttributes(this._container,"data-",!0,!0);o.data={message:this._getEditor().code.get()},o.removeQuoteIDs=this._options.quoteManager?this._options.quoteManager.getQuotesMarkedForRemoval():[];var l=elById("settings_text");l&&elBySelAll("input, select, textarea",l,function(e){if("INPUT"!==e.nodeName||"checkbox"!==e.type&&"radio"!==e.type||e.checked){var t=e.name;if(o.hasOwnProperty(t))throw new Error("Variable overshadowing, key '"+t+"' is already present.");o[t]=e.value.trim()}}),i.fire("com.woltlab.wcf.redactor2","submit_text",o.data),u.userId||a||(o.requireGuestDialog=!0),e.api(this,t.extend({parameters:o},a))}},_validate:function(){if(elBySelAll(".innerError",this._container,elRemove),this._getEditor().utils.isEmpty())return this.throwError(this._textarea,n.get("wcf.global.form.error.empty")),!1;var e={api:this,editor:this._getEditor(),message:this._getEditor().code.get(),valid:!0};return i.fire("com.woltlab.wcf.redactor2","validate_text",e),!1!==e.valid},throwError:function(e,t){elInnerError(e,"empty"===t?n.get("wcf.global.form.error.empty"):t)},_showLoadingOverlay:function(){null===this._loadingOverlay&&(this._loadingOverlay=elCreate("div"),this._loadingOverlay.className="messageContentLoadingOverlay",this._loadingOverlay.innerHTML='<span class="icon icon96 fa-spinner"></span>'),this._content.classList.add("loading"),this._content.appendChild(this._loadingOverlay)},_hideLoadingOverlay:function(){this._content.classList.remove("loading");var e=elBySel(".messageContentLoadingOverlay",this._content);null!==e&&e.parentNode.removeChild(e)},_reset:function(){this._getEditor().code.set("<p>​</p>"),i.fire("com.woltlab.wcf.redactor2","reset_text")},_handleError:function(e){var t={api:this,cancel:!1,returnValues:e.returnValues};i.fire("com.woltlab.wcf.redactor2","handleError_text",t),!0!==t.cancel&&this.throwError(this._textarea,e.returnValues.realErrorMessage)},_getEditor:function(){if(null===this._editor){if("function"!=typeof window.jQuery)throw new Error("Unable to access editor, jQuery has not been loaded yet.");this._editor=window.jQuery(this._textarea).data("redactor")}return this._editor},_insertMessage:function(e){if(this._getEditor().WoltLabAutosave.reset(),e.returnValues.url)window.location==e.returnValues.url&&window.location.reload(),window.location=e.returnValues.url;else{if(e.returnValues.template){var t;if("DESC"===elData(this._container,"sort-order"))r.insertHtml(e.returnValues.template,this._container,"after"),t=r.identify(this._container.nextElementSibling);else{var i=this._container;i.previousElementSibling&&i.previousElementSibling.classList.contains("messageListPagination")&&(i=i.previousElementSibling),r.insertHtml(e.returnValues.template,i,"before"),t=r.identify(i.previousElementSibling)}elData(this._container,"last-post-time",e.returnValues.lastPostTime),window.history.replaceState(void 0,"","#"+t),c.element(elById(t))}l.show(n.get(this._options.successMessage)),this._options.quoteManager&&this._options.quoteManager.countQuotes(),a.trigger()}},_ajaxSuccess:function(e){if(!u.userId&&!e.returnValues.guestDialogID)throw new Error("Missing 'guestDialogID' return value for guest.");if(!u.userId&&e.returnValues.guestDialog){s.openStatic(e.returnValues.guestDialogID,e.returnValues.guestDialog,{closable:!1,onClose:function(){h.has(e.returnValues.guestDialogID)&&h.delete(e.returnValues.guestDialogID)},title:n.get("wcf.global.confirmation.title")});var t=s.getDialog(e.returnValues.guestDialogID);elBySel("input[type=submit]",t.content).addEventListener(WCF_CLICK_EVENT,this._submitGuestDialog.bind(this)),elBySel("input[type=text]",t.content).addEventListener("keypress",this._submitGuestDialog.bind(this)),this._guestDialogId=e.returnValues.guestDialogID}else this._insertMessage(e),u.userId||s.close(e.returnValues.guestDialogID),this._reset(),this._hideLoadingOverlay()},_ajaxFailure:function(e){return this._hideLoadingOverlay(),null===e||void 0===e.returnValues||void 0===e.returnValues.realErrorMessage||(this._handleError(e),!1)},_ajaxSetup:function(){return{data:{actionName:"quickReply",className:this._options.ajax.className,interfaceName:"wcf\\data\\IMessageQuickReplyAction"},silent:!0}}},p}),define("WoltLabSuite/Core/Ui/Message/Share",["EventHandler","StringUtil"],function(e,t){"use strict";return{_pageDescription:"",_pageUrl:"",init:function(){var i=elBySel('meta[property="og:title"]');null!==i&&(this._pageDescription=encodeURIComponent(i.content));var n=elBySel('meta[property="og:url"]');null!==n&&(this._pageUrl=encodeURIComponent(n.content)),elBySelAll(".jsMessageShareButtons",null,function(i){i.classList.remove("jsMessageShareButtons");var n=encodeURIComponent(t.unescapeHTML(elData(i,"url")||""));n||(n=this._pageUrl);var a={facebook:{link:elBySel(".jsShareFacebook",i),share:function(e){e.preventDefault(),this._share("facebook","https://www.facebook.com/sharer.php?u={pageURL}&t={text}",!0,n)}.bind(this)},google:{link:elBySel(".jsShareGoogle",i),share:function(e){e.preventDefault(),this._share("google","https://plus.google.com/share?url={pageURL}",!1,n)}.bind(this)},reddit:{link:elBySel(".jsShareReddit",i),share:function(e){e.preventDefault(),this._share("reddit","https://ssl.reddit.com/submit?url={pageURL}",!1,n)}.bind(this)},twitter:{link:elBySel(".jsShareTwitter",i),share:function(e){e.preventDefault(),this._share("twitter","https://twitter.com/share?url={pageURL}&text={text}",!1,n)}.bind(this)},linkedIn:{link:elBySel(".jsShareLinkedIn",i),share:function(e){e.preventDefault(),this._share("linkedIn","https://www.linkedin.com/cws/share?url={pageURL}",!1,n)}.bind(this)},pinterest:{link:elBySel(".jsSharePinterest",i),share:function(e){e.preventDefault(),this._share("pinterest","https://www.pinterest.com/pin/create/link/?url={pageURL}&description={text}",!1,n)}.bind(this)},xing:{link:elBySel(".jsShareXing",i),share:function(e){e.preventDefault(),this._share("xing","https://www.xing.com/social_plugins/share?url={pageURL}",!1,n)}.bind(this)},whatsApp:{link:elBySel(".jsShareWhatsApp",i),share:function(e){e.preventDefault(),window.location.href="https://api.whatsapp.com/send?text="+this._pageDescription+"%20"+this._pageUrl}.bind(this)}};e.fire("com.woltlab.wcf.message.share","shareProvider",{container:i,providers:a,pageDescription:this._pageDescription,pageUrl:this._pageUrl});for(var r in a)a.hasOwnProperty(r)&&null!==a[r].link&&a[r].link.addEventListener(WCF_CLICK_EVENT,a[r].share)}.bind(this))},_share:function(e,t,i,n){n||(n=this._pageUrl),window.open(t.replace(/\{pageURL}/,n).replace(/\{text}/,this._pageDescription+(i?"%20"+n:"")),e,"height=600,width=600")}}}),define("WoltLabSuite/Core/Ui/Page/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,a,r){"use strict";var o,s,l,c=null;return{open:function(e){o=e,r.open(this)},_search:function(t){t.preventDefault();var n=c.parentNode,a=c.value.trim();if(a.length<3)return void elInnerError(n,i.get("wcf.page.search.error.tooShort"));elInnerError(n,!1),e.api(this,{parameters:{searchString:a}})},_click:function(e){e.preventDefault();var t=e.currentTarget,i=elBySel("h3",t).textContent.replace(/['"]/g,"");o(elData(t,"page-id")+"#"+i),r.close(this)},_ajaxSuccess:function(e){for(var t,a="",r=0,o=e.returnValues.length;r<o;r++)t=e.returnValues[r],a+='<li><div class="containerHeadline pointer" data-page-id="'+t.pageID+'"><h3>'+n.escapeHTML(t.name)+"</h3><small>"+n.escapeHTML(t.displayLink)+"</small></div></li>";l.innerHTML=a,window[a?"elShow":"elHide"](s),a?elBySelAll(".containerHeadline",l,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this)):elInnerError(c.parentNode,i.get("wcf.page.search.error.noResults"))},_ajaxSetup:function(){return{data:{actionName:"search",className:"wcf\\data\\page\\PageAction"}}},_dialogSetup:function(){return{id:"wcfUiPageSearch",options:{onSetup:function(){var e=this._search.bind(this);c=elById("wcfUiPageSearchInput"),c.addEventListener("keydown",function(i){t.Enter(i)&&e(i)}),c.nextElementSibling.addEventListener(WCF_CLICK_EVENT,e),s=elById("wcfUiPageSearchResultContainer"),l=elById("wcfUiPageSearchResultList")}.bind(this),onShow:function(){c.focus()},title:i.get("wcf.page.search")},source:'<div class="section"><dl><dt><label for="wcfUiPageSearchInput">'+i.get("wcf.page.search.name")+'</label></dt><dd><div class="inputAddon"><input type="text" id="wcfUiPageSearchInput" class="long"><a href="#" class="inputSuffix"><span class="icon icon16 fa-search"></span></a></div></dd></dl></div><section id="wcfUiPageSearchResultContainer" class="section" style="display: none;"><header class="sectionHeader"><h2 class="sectionTitle">'+i.get("wcf.page.search.results")+'</h2></header><ol id="wcfUiPageSearchResultList" class="containerList"></ol></section>'}}}}),define("WoltLabSuite/Core/Ui/Sortable/List",["Core","Ui/Screen"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={init:function(i){this._options=e.extend({containerId:"",className:"",offset:0,options:{},isSimpleSorting:!1,additionalParameters:{}},i),t.on("screen-sm-md",{match:this._enable.bind(this,!0),unmatch:this._disable.bind(this),setup:this._enable.bind(this,!0)}),t.on("screen-lg",{match:this._enable.bind(this,!1),unmatch:this._disable.bind(this),setup:this._enable.bind(this,!1)})},_enable:function(e){var t=this._options.options;e&&(t.handle=".sortableNodeHandle"),new window.WCF.Sortable.List(this._options.containerId,this._options.className,this._options.offset,t,this._options.isSimpleSorting,this._options.additionalParameters)},_disable:function(){window.jQuery("#"+this._options.containerId+" .sortableList")[this._options.isSimpleSorting?"sortable":"nestedSortable"]("destroy")}},i}),define("WoltLabSuite/Core/Ui/Poll/Editor",["Core","Dom/Util","EventHandler","EventKey","Language","WoltLabSuite/Core/Date/Picker","WoltLabSuite/Core/Ui/Sortable/List"],function(e,t,i,n,a,r,o){"use strict";function s(e,t,i,n){this.init(e,t,i,n)}return s.prototype={init:function(t,n,a,r){if(this._container=elById(t),null===this._container)throw new Error("Unknown poll editor container with id '"+t+"'.");if(this._wysiwygId=a,""!==a&&null===elById(a))throw new Error("Unknown wysiwyg field with id '"+a+"'.");this.questionField=elById(this._wysiwygId+"Poll_question");var s=elByClass("sortableList",this._container);if(0===s.length)throw new Error("Cannot find poll options list for container with id '"+t+"'.");if(this.optionList=s[0],this.endTimeField=elById(this._wysiwygId+"Poll_endTime"),this.maxVotesField=elById(this._wysiwygId+"Poll_maxVotes"),this.isChangeableYesField=elById(this._wysiwygId+"Poll_isChangeable"),this.isChangeableNoField=elById(this._wysiwygId+"Poll_isChangeable_no"),this.isPublicYesField=elById(this._wysiwygId+"Poll_isPublic"),this.isPublicNoField=elById(this._wysiwygId+"Poll_isPublic_no"),this.resultsRequireVoteYesField=elById(this._wysiwygId+"Poll_resultsRequireVote"),this.resultsRequireVoteNoField=elById(this._wysiwygId+"Poll_resultsRequireVote_no"),this.sortByVotesYesField=elById(this._wysiwygId+"Poll_sortByVotes"),this.sortByVotesNoField=elById(this._wysiwygId+"Poll_sortByVotes_no"),this._optionCount=0,this._options=e.extend({isAjax:!1,maxOptions:20},r),this._createOptionList(n||[]),new o({containerId:t,options:{toleranceElement:"> div"}}),this._options.isAjax)for(var l=["handleError","reset","submit","validate"],c=0,d=l.length;c<d;c++){var u=l[c];i.add("com.woltlab.wcf.redactor2",u+"_"+this._wysiwygId,this["_"+u].bind(this))}else{var h=this._container.closest("form");if(null===h)throw new Error("Cannot find form for container with id '"+t+"'.");h.addEventListener("submit",this._submit.bind(this))}},_addOption:function(e){if(e.preventDefault(),this._optionCount===this._options.maxOptions)return!1;this._createOption(void 0,void 0,e.currentTarget.closest("li"))},_createOption:function(e,i,n){e=e||"",i=~~i||0;var r=elCreate("LI");r.className="sortableNode",elData(r,"option-id",i),
-n?t.insertAfter(r,n):this.optionList.appendChild(r);var o=elCreate("div");o.className="pollOptionInput",r.appendChild(o);var s=elCreate("span");s.className="icon icon16 fa-arrows sortableNodeHandle",o.appendChild(s);var l=elCreate("a");elAttr(l,"role","button"),elAttr(l,"href","#"),l.className="icon icon16 fa-plus jsTooltip jsAddOption pointer",elAttr(l,"title",a.get("wcf.poll.button.addOption")),l.addEventListener("click",this._addOption.bind(this)),o.appendChild(l);var c=elCreate("a");elAttr(c,"role","button"),elAttr(c,"href","#"),c.className="icon icon16 fa-times jsTooltip jsDeleteOption pointer",elAttr(c,"title",a.get("wcf.poll.button.removeOption")),c.addEventListener("click",this._removeOption.bind(this)),o.appendChild(c);var d=elCreate("input");elAttr(d,"type","text"),d.value=e,elAttr(d,"maxlength",255),d.addEventListener("keydown",this._optionInputKeyDown.bind(this)),d.addEventListener("click",function(){document.activeElement!==this&&this.focus()}),o.appendChild(d),null!==n&&d.focus(),++this._optionCount===this._options.maxOptions&&elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.remove("pointer"),e.classList.add("disabled")})},_createOptionList:function(e){for(var t=0,i=e.length;t<i;t++){var n=e[t];this._createOption(n.optionValue,n.optionID)}this._optionCount<this._options.maxOptions&&this._createOption()},_handleError:function(e){switch(e.returnValues.fieldName){case this._wysiwygId+"Poll_endTime":case this._wysiwygId+"Poll_maxVotes":var i=e.returnValues.fieldName.replace(this._wysiwygId+"Poll_",""),n=elCreate("small");n.className="innerError",n.innerHTML=a.get("wcf.poll."+i+".error."+e.returnValues.errorType);var r=elById(e.returnValues.fieldName);r.closest("dd");t.prepend(n,r.nextSibling),e.cancel=!0}},_optionInputKeyDown:function(t){n.Enter(t)&&(e.triggerEvent(elByClass("jsAddOption",t.currentTarget.parentNode)[0],"click"),t.preventDefault())},_removeOption:function(e){e.preventDefault(),elRemove(e.currentTarget.closest("li")),this._optionCount--,elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.add("pointer"),e.classList.remove("disabled")}),0===this.optionList.length&&this._createOption()},_reset:function(){this.questionField.value="",this._optionCount=0,this.optionList.innerHtml="",this._createOption(),r.clear(this.endTimeField),this.maxVotesField.value=1,this.isChangeableYesField.checked=!1,this.isChangeableNoField.checked=!0,this.isPublicYesField.checked=!1,this.isPublicNoField.checked=!0,this.resultsRequireVoteYesField.checked=!1,this.resultsRequireVoteNoField.checked=!0,this.sortByVotesYesField.checked=!1,this.sortByVotesNoField.checked=!0,i.fire("com.woltlab.wcf.poll.editor","reset",{pollEditor:this})},_submit:function(e){if(this._options.isAjax)e.poll=this.getData(),i.fire("com.woltlab.wcf.poll.editor","submit",{event:e,pollEditor:this});else for(var t=this._container.closest("form"),n=this.getOptions(),a=0,r=n.length;a<r;a++){var o=elCreate("input");elAttr(o,"type","hidden"),elAttr(o,"name",this._wysiwygId+"Poll_options["+a+"]"),o.value=n[a],t.appendChild(o)}},_validate:function(e){if(""!==this.questionField.value.trim()){for(var t=0,n=0,r=this.optionList.children.length;n<r;n++){""!==elBySel("input[type=text]",this.optionList.children[n]).value.trim()&&t++}if(0===t)e.api.throwError(this._container,a.get("wcf.global.form.error.empty")),e.valid=!1;else{var o=~~this.maxVotesField.value;o&&o>t?(e.api.throwError(this.maxVotesField.parentNode,a.get("wcf.poll.maxVotes.error.invalid")),e.valid=!1):i.fire("com.woltlab.wcf.poll.editor","validate",{data:e,pollEditor:this})}}},getData:function(){var e={};return e[this.questionField.id]=this.questionField.value,e[this._wysiwygId+"Poll_options"]=this.getOptions(),e[this.endTimeField.id]=this.endTimeField.value,e[this.maxVotesField.id]=this.maxVotesField.value,e[this.isChangeableYesField.id]=!!this.isChangeableYesField.checked,e[this.isPublicYesField.id]=!!this.isPublicYesField.checked,e[this.resultsRequireVoteYesField.id]=!!this.resultsRequireVoteYesField.checked,e[this.sortByVotesYesField.id]=!!this.sortByVotesYesField.checked,e},getOptions:function(){for(var e=[],t=0,i=this.optionList.children.length;t<i;t++){var n=this.optionList.children[t],a=elBySel("input[type=text]",n).value.trim();""!==a&&e.push(elData(n,"option-id")+"_"+a)}return e}},s}),define("WoltLabSuite/Core/Ui/Redactor/Article",["WoltLabSuite/Core/Ui/Article/Search"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(e,t){this._editor=e,t.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))},_click:function(t){t.preventDefault(),e.open(this._insert.bind(this))},_insert:function(e){this._editor.buffer.set(),this._editor.insert.text("[wsa='"+e+"'][/wsa]")}},t}),define("WoltLabSuite/Core/Ui/Redactor/Metacode",["EventHandler","Dom/Util"],function(e,t){"use strict";return{convert:function(e){e.textContent=this.convertFromHtml(e.textContent)},convertFromHtml:function(i,n){var a=elCreate("div");a.innerHTML=n;for(var r,o,s,l,c,d,u=elByTag("woltlab-metacode",a);u.length;)s=u[0],l=elData(s,"name"),r=this._parseAttributes(elData(s,"attributes")),o={attributes:r,cancel:!1,metacode:s},e.fire("com.woltlab.wcf.redactor2","metacode_"+l+"_"+i,o),!0!==o.cancel&&(d=this._getOpeningTag(l,r),c=this._getClosingTag(l),s.parentNode===a?(t.prepend(d,this._getFirstParagraph(s)),this._getLastParagraph(s).appendChild(c)):(t.prepend(d,s),s.appendChild(c)),t.unwrapChildNodes(s));for(var h,p=elByTag("kbd",a);p.length;)h=p[0],h.insertBefore(document.createTextNode("[tt]"),h.firstChild),h.appendChild(document.createTextNode("[/tt]")),t.unwrapChildNodes(h);return a.innerHTML},_getOpeningTag:function(e,t){var i="["+e;if(t.length){i+="=";for(var n=0,a=t.length;n<a;n++)n>0&&(i+=","),i+="'"+t[n]+"'"}return document.createTextNode(i+"]")},_getClosingTag:function(e){return document.createTextNode("[/"+e+"]")},_getFirstParagraph:function(e){var t,i;return 0===e.childElementCount?(i=elCreate("p"),e.appendChild(i)):(t=e.children[0],"P"===t.nodeName?i=t:(i=elCreate("p"),e.insertBefore(i,t))),i},_getLastParagraph:function(e){var t,i,n=e.childElementCount;return 0===n?(i=elCreate("p"),e.appendChild(i)):(t=e.children[n-1],"P"===t.nodeName?i=t:(i=elCreate("p"),e.appendChild(i))),i},_parseAttributes:function(e){try{e=JSON.parse(atob(e))}catch(e){}if(!Array.isArray(e))return[];for(var t,i=[],n=0,a=e.length;n<a;n++)t=e[n],"string"==typeof t&&(t=t.replace(/^'(.*)'$/,"$1")),i.push(t);return i}}}),define("WoltLabSuite/Core/Ui/Redactor/Autosave",["Core","Devtools","EventHandler","Language","Dom/Traverse","./Metacode"],function(e,t,i,n,a,r){"use strict";function o(e){this.init(e)}return o.prototype={init:function(t){this._container=null,this._metaData={},this._editor=null,this._element=t,this._isActive=!0,this._isPending=!1,this._key=e.getStoragePrefix()+elData(this._element,"autosave"),this._lastMessage="",this._originalMessage="",this._overlay=null,this._restored=!1,this._timer=null,this._cleanup(),this._element.removeAttribute("data-autosave");var n=a.parentByTag(this._element,"FORM");null!==n&&n.addEventListener("submit",this.destroy.bind(this)),i.add("com.woltlab.wcf.redactor2","getMetaData_"+this._element.id,function(e){for(var t in this._metaData)this._metaData.hasOwnProperty(t)&&(e[t]=this._metaData[t])}.bind(this)),i.add("com.woltlab.wcf.redactor2","reset_"+this._element.id,this.hideOverlay.bind(this)),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this))},_onVisibilityChange:function(){document.hidden?(this._isActive=!1,this._isPending=!0):(this._isActive=!0,this._isPending=!1)},getInitialValue:function(){if(window.ENABLE_DEVELOPER_TOOLS&&!1===t._internal_.editorAutosave())return this._element.value;var e="";try{e=window.localStorage.getItem(this._key)}catch(e){window.console.warn("Unable to access local storage: "+e.message)}try{e=JSON.parse(e)}catch(t){e=""}if(null!==e&&"object"==typeof e&&e.content){if(1e3*~~elData(this._element,"autosave-last-edit-time")<=e.timestamp){var i=elCreate("div");i.innerHTML=this._element.value;var n=elCreate("div");if(n.innerHTML=e.content,i.innerText.trim()!==n.innerText.trim())return this._originalMessage=this._element.value,this._restored=!0,this._metaData=e.meta||{},e.content}}return this._element.value},getMetaData:function(){return this._metaData},watch:function(e){if(this._editor=e,null!==this._timer)throw new Error("Autosave timer is already active.");this._timer=window.setInterval(this._saveToStorage.bind(this),15e3),this._saveToStorage(),this._isPending=!1},destroy:function(){this.clear(),this._editor=null,window.clearInterval(this._timer),this._timer=null,this._isPending=!1},clear:function(){this._metaData={},this._lastMessage="";try{window.localStorage.removeItem(this._key)}catch(e){window.console.warn("Unable to remove from local storage: "+e.message)}},createOverlay:function(){if(this._restored){var e=elCreate("div");e.className="redactorAutosaveRestored active";var t=elCreate("span");t.textContent=n.get("wcf.editor.autosave.restored"),e.appendChild(t);var i=elCreate("a");i.className="jsTooltip",i.href="#",i.title=n.get("wcf.editor.autosave.keep"),i.innerHTML='<span class="icon icon16 fa-check green"></span>',i.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.hideOverlay()}.bind(this)),e.appendChild(i),i=elCreate("a"),i.className="jsTooltip",i.href="#",i.title=n.get("wcf.editor.autosave.discard"),i.innerHTML='<span class="icon icon16 fa-times red"></span>',i.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.clear();var t=r.convertFromHtml(this._editor.core.element()[0].id,this._originalMessage);this._editor.code.start(t),this._editor.core.textarea().val(this._editor.clean.onSync(this._editor.$editor.html())),this.hideOverlay()}.bind(this)),e.appendChild(i),this._editor.core.box()[0].appendChild(e);var a=function(){this._editor.core.editor()[0].removeEventListener(WCF_CLICK_EVENT,a),this.hideOverlay()}.bind(this);this._editor.core.editor()[0].addEventListener(WCF_CLICK_EVENT,a),this._container=e}},hideOverlay:function(){null!==this._container&&(this._container.classList.remove("active"),window.setTimeout(function(){null!==this._container&&elRemove(this._container),this._container=null,this._originalMessage=""}.bind(this),1e3))},_saveToStorage:function(){if(!this._isActive){if(!this._isPending)return;this._isPending=!1}if(!window.ENABLE_DEVELOPER_TOOLS||!1!==t._internal_.editorAutosave()){var e=this._editor.code.get();if(this._editor.utils.isEmpty(e)&&(e=""),this._lastMessage!==e){if(""===e)return this.clear();try{i.fire("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._element.id,this._metaData),window.localStorage.setItem(this._key,JSON.stringify({content:e,meta:this._metaData,timestamp:Date.now()})),this._lastMessage=e}catch(e){window.console.warn("Unable to write to local storage: "+e.message)}}}},_cleanup:function(){var t,i,n,a,r=Date.now()-6048e5,o=[];for(t=0,n=window.localStorage.length;t<n;t++)if(i=window.localStorage.key(t),0===i.indexOf(e.getStoragePrefix())){try{a=window.localStorage.getItem(i)}catch(e){window.console.warn("Unable to access local storage: "+e.message)}try{a=JSON.parse(a)}catch(e){a={timestamp:0}}(!a||a.timestamp<r)&&o.push(i)}for(t=0,n=o.length;t<n;t++)try{window.localStorage.removeItem(o[t])}catch(e){window.console.warn("Unable to remove from local storage: "+e.message)}}},o}),define("WoltLabSuite/Core/Ui/Redactor/PseudoHeader",[],function(){"use strict";return{getHeight:function(e){var t=~~window.getComputedStyle(e).paddingTop.replace(/px$/,""),i=window.getComputedStyle(e,"::before");t+=~~i.paddingTop.replace(/px$/,""),t+=~~i.paddingBottom.replace(/px$/,"");var n=~~i.height.replace(/px$/,"");return 0===n&&(n=e.scrollHeight,e.classList.add("redactorCalcHeight"),n-=e.scrollHeight,e.classList.remove("redactorCalcHeight")),t+=n}}}),define("WoltLabSuite/Core/Ui/Redactor/Code",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader","prism/prism-meta"],function(e,t,i,n,a,r,o,s){"use strict";function l(e){this.init(e)}var c=0;return l.prototype={init:function(t){this._editor=t,this._elementId=this._editor.$element[0].id,this._pre=null,e.add("com.woltlab.wcf.redactor2","bbcode_code_"+this._elementId,this._bbcodeCode.bind(this)),e.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._editor.opts.activeButtonsStates.pre="code",this._callbackEdit=this._edit.bind(this),this._observeLoad()},_bbcodeCode:function(e){e.cancel=!0;var t=this._editor.selection.block();t&&"PRE"===t.nodeName&&t.classList.contains("woltlabHtml")||(this._editor.button.toggle({},"pre","func","block.format"),(t=this._editor.selection.block())&&"PRE"===t.nodeName&&!t.classList.contains("woltlabHtml")&&(1===t.childElementCount&&"BR"===t.children[0].nodeName&&t.removeChild(t.children[0]),this._setTitle(t),t.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(t)))},_observeLoad:function(){elBySelAll("pre:not(.woltlabHtml)",this._editor.$editor[0],function(e){e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)}.bind(this))},_edit:function(e){var t=e.currentTarget;0===c&&(c=o.getHeight(t));var i=a.offset(t);e.pageY>i.top&&e.pageY<i.top+c&&(e.preventDefault(),this._editor.selection.save(),this._pre=t,r.open(this))},_dialogSubmit:function(){var e="redactor-code-"+this._elementId;["file","highlighter","line"].forEach(function(t){elData(this._pre,t,elById(e+"-"+t).value)}.bind(this)),this._setTitle(this._pre),this._editor.caret.after(this._pre),r.close(this)},_setTitle:function(e){var t=elData(e,"file"),n=elData(e,"highlighter");n=-1!==this._editor.opts.woltlab.highlighters.indexOf(n)?s[n].title:"";var a=i.get("wcf.editor.code.title",{file:t,highlighter:n});elData(e,"title")!==a&&elData(e,"title",a)},_delete:function(e){e.preventDefault();var t=this._pre.nextElementSibling||this._pre.previousElementSibling;null===t&&this._pre.parentNode!==this._editor.core.editor()[0]&&(t=this._pre.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._pre),this._editor.caret.end(t)),r.close(this)},_dialogSetup:function(){var e="redactor-code-"+this._elementId,t=e+"-button-delete",a=e+"-button-save",o=e+"-file",l=e+"-highlighter",c=e+"-line";return{id:e,options:{onClose:function(){this._editor.selection.restore(),r.destroy(this)}.bind(this),onSetup:function(){elById(t).addEventListener(WCF_CLICK_EVENT,this._delete.bind(this));var e='<option value="">'+i.get("wcf.editor.code.highlighter.detect")+"</option>";e+='<option value="plain">'+i.get("wcf.editor.code.highlighter.plain")+"</option>";var a=this._editor.opts.woltlab.highlighters.map(function(e){return[e,s[e].title]});a.sort(function(e,t){return e[1]<t[1]?-1:e[1]>t[1]?1:0}),a.forEach(function(t){e+='<option value="'+t[0]+'">'+n.escapeHTML(t[1])+"</option>"}.bind(this)),elById(l).innerHTML=e}.bind(this),onShow:function(){elById(l).value=elData(this._pre,"highlighter");var e=elData(this._pre,"line");elById(c).value=""===e?1:~~e,elById(o).value=elData(this._pre,"file")}.bind(this),title:i.get("wcf.editor.code.edit")},source:'<div class="section"><dl><dt><label for="'+l+'">'+i.get("wcf.editor.code.highlighter")+'</label></dt><dd><select id="'+l+'"></select><small>'+i.get("wcf.editor.code.highlighter.description")+'</small></dd></dl><dl><dt><label for="'+c+'">'+i.get("wcf.editor.code.line")+'</label></dt><dd><input type="number" id="'+c+'" min="0" value="1" class="long" data-dialog-submit-on-enter="true"><small>'+i.get("wcf.editor.code.line.description")+'</small></dd></dl><dl><dt><label for="'+o+'">'+i.get("wcf.editor.code.file")+'</label></dt><dd><input type="text" id="'+o+'" class="long" data-dialog-submit-on-enter="true"><small>'+i.get("wcf.editor.code.file.description")+'</small></dd></dl></div><div class="formSubmit"><button id="'+a+'" class="buttonPrimary" data-type="submit">'+i.get("wcf.global.button.save")+'</button><button id="'+t+'">'+i.get("wcf.global.button.delete")+"</button></div>"}}},l}),define("WoltLabSuite/Core/Ui/Redactor/Format",["Dom/Util"],function(e){"use strict";var t=function(e){for(var t=window.getSelection().anchorNode;t;){if(t===e)return!0;t=t.parentNode}return!1};return{format:function(i,n,a){var r=window.getSelection();if(r.rangeCount){if(!t(i))return void console.error("Invalid selection, range exists outside of the editor:",r.anchorNode);var o=r.getRangeAt(0),s=null,l=null,c=null;if(o.collapsed)c=elCreate("strike"),c.textContent="​",o.insertNode(c),o=document.createRange(),o.selectNodeContents(c),r.removeAllRanges(),r.addRange(o);else{s=elCreate("mark"),l=elCreate("mark");var d=o.cloneRange();d.collapse(!0),d.insertNode(s),d=o.cloneRange(),d.collapse(!1),d.insertNode(l),o=document.createRange(),o.setStartAfter(s),o.setEndBefore(l),r.removeAllRanges(),r.addRange(o),this.removeFormat(i,n),o=document.createRange(),o.setStartAfter(s),o.setEndBefore(l),r.removeAllRanges(),r.addRange(o)}var u=["strike","strikethrough"];null===c&&(u=this._getSelectionMarker(i,r),document.execCommand(u[1]));for(var h,p,f=elBySelAll(u[0],i),m=[],g=0,v=f.length;g<v;g++)p=f[g],h=elCreate("span"),elAttr(h,"style",n+": "+a),e.replaceElement(p,h),m.push(h);var _=m.length;if(_){var b=m[0],w=m[_-1];if(null===c&&b.parentNode===w.parentNode){var y=b.parentNode;"SPAN"===y.nodeName&&""!==y.style.getPropertyValue(n)&&this._isBoundaryElement(b,y,"previous")&&this._isBoundaryElement(w,y,"next")&&e.unwrapChildNodes(y)}o=document.createRange(),o.setStart(b,0),o.setEnd(w,w.childNodes.length),r.removeAllRanges(),r.addRange(o)}null!==s&&(elRemove(s),elRemove(l))}},removeFormat:function(i,n){var a=window.getSelection();if(a.rangeCount){if(!t(i))return void console.error("Invalid selection, range exists outside of the editor:",a.anchorNode);var r=a.getRangeAt(0),o=null,s=r.collapsed;if(s){for(var l=r.startContainer,c=[l];;){var d=l.parentNode;if(d===i||"TD"===d.nodeName)break;l=d,c.push(l)}if(this._isEmpty(l.innerHTML)){var u=document.createElement("woltlab-format-marker");return r.insertNode(u),c.forEach(function(t){"SPAN"===t.nodeName&&t.style.getPropertyValue(n)&&e.unwrapChildNodes(t)}),r=document.createRange(),r.selectNode(u),r.collapse(!0),a.removeAllRanges(),a.addRange(r),void elRemove(u)}o=document.createTextNode("​"),r.insertNode(o)}for(var h=elByTag("strike",i);h.length;)e.unwrapChildNodes(h[0]);var p=this._getSelectionMarker(i,window.getSelection());if(document.execCommand(p[1]),"strike"!==p[0]&&(h=elByTag(p[0],i)),s&&null!==o&&0===h.length){document.execCommand(p[1]);var f=elCreate(p[0]);o.parentNode.insertBefore(f,o),f.appendChild(o)}for(var m,g;h.length;)g=h[0],m=this._getLastMatchingParent(g,i,n),null!==m&&this._handleParentNodes(g,m,n),elBySelAll("span",g,function(t){t.style.getPropertyValue(n)&&e.unwrapChildNodes(t)}),e.unwrapChildNodes(g);elBySelAll("span",i,function(e){e.parentNode&&!e.textContent.length&&""!==e.style.getPropertyValue(n)&&(1===e.childElementCount&&"MARK"===e.children[0].nodeName&&e.parentNode.insertBefore(e.children[0],e),0===e.childElementCount&&elRemove(e))})}},_handleParentNodes:function(t,i,n){var a;if(!e.isAtNodeStart(t,i)){a=document.createRange(),a.setStartBefore(i),a.setEndBefore(t);var r=a.extractContents();i.parentNode.insertBefore(r,i)}e.isAtNodeEnd(t,i)||(a=document.createRange(),a.setStartAfter(t),a.setEndAfter(i),r=a.extractContents(),i.parentNode.insertBefore(r,i.nextSibling)),elBySelAll("span",i,function(t){t.style.getPropertyValue(n)&&e.unwrapChildNodes(t)}),e.unwrapChildNodes(i)},_getLastMatchingParent:function(e,t,i){for(var n=e.parentNode,a=null;n!==t;)"SPAN"===n.nodeName&&""!==n.style.getPropertyValue(i)&&(a=n),n=n.parentNode;return a},_isBoundaryElement:function(e,t,i){for(var n=e;n=n[i+"Sibling"];)if(n.nodeType!==Node.TEXT_NODE||""!==n.textContent.replace(/\u200B/,""))return!1;return!0},_getSelectionMarker:function(e,t){for(var i,n,a,r=["DEL","SUB","SUP"],o=0,s=r.length;o<s;o++){if(a=r[o],n=elClosest(t.anchorNode),!(i=null!==elBySel(a.toLowerCase(),n)))for(;n&&n!==e;){if(n.nodeName===a){i=!0;break}n=n.parentNode}if(!i)break;a=void 0}return"DEL"===a||void 0===a?["strike","strikethrough"]:[a.toLowerCase(),a.toLowerCase()+"script"]},_isEmpty:function(e){return e=e.replace(/[\u200B-\u200D\uFEFF]/g,""),e=e.replace(/&nbsp;/gi,""),e=e.replace(/<\/?br\s?\/?>/g,""),e=e.replace(/\s/g,""),e=e.replace(/^<p>[^\W\w\D\d]*?<\/p>$/i,""),e=e.replace(/<iframe(.*?[^>])>$/i,"iframe"),e=e.replace(/<source(.*?[^>])>$/i,"source"),e=e.replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),e=e.replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),""===e.trim()}}}),define("WoltLabSuite/Core/Ui/Redactor/Html",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,a,r,o){"use strict";function s(e){this.init(e)}var l=0;return s.prototype={init:function(t){this._editor=t,this._elementId=this._editor.$element[0].id,this._pre=null,e.add("com.woltlab.wcf.redactor2","bbcode_woltlabHtml_"+this._elementId,this._bbcodeCode.bind(this)),e.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._editor.opts.activeButtonsStates["woltlab-html"]="woltlabHtml",this._callbackEdit=this._edit.bind(this),this._observeLoad()},_bbcodeCode:function(e){e.cancel=!0;var t=this._editor.selection.block();t&&"PRE"===t.nodeName&&!t.classList.contains("woltlabHtml")||(this._editor.button.toggle({},"pre","func","block.format"),(t=this._editor.selection.block())&&"PRE"===t.nodeName&&(t.classList.add("woltlabHtml"),1===t.childElementCount&&"BR"===t.children[0].nodeName&&t.removeChild(t.children[0]),this._setTitle(t),t.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(t)))},_observeLoad:function(){elBySelAll("pre.woltlabHtml",this._editor.$editor[0],function(e){e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)}.bind(this))},_edit:function(e){var t=e.currentTarget;0===l&&(l=o.getHeight(t));var i=a.offset(t);e.pageY>i.top&&e.pageY<i.top+l&&(e.preventDefault(),this._editor.selection.save(),this._pre=t,console.warn("should edit"))},_setTitle:function(e){["title","description"].forEach(function(t){var n=i.get("wcf.editor.html."+t);elData(e,t)!==n&&elData(e,t,n)})},_delete:function(e){console.warn("should delete"),e.preventDefault();var t=this._pre.nextElementSibling||this._pre.previousElementSibling;null===t&&this._pre.parentNode!==this._editor.core.editor()[0]&&(t=this._pre.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._pre),this._editor.caret.end(t)),r.close(this)}},s}),define("WoltLabSuite/Core/Ui/Redactor/Link",["Core","EventKey","Language","Ui/Dialog"],function(e,t,i,n){"use strict";var a=!1,r=null;return{showDialog:function(e){n.open(this),n.setTitle(this,i.get("wcf.editor.link."+(e.insert?"add":"edit")));var t=elById("redactor-modal-button-action");t.textContent=i.get("wcf.global.button."+(e.insert?"insert":"save")),r=e.submitCallback,a||(a=!0,t.addEventListener(WCF_CLICK_EVENT,this._submit.bind(this)))},_submit:function(){if(r())n.close(this);else{var e=elById("redactor-link-url");elInnerError(e,i.get(""===e.value.trim()?"wcf.global.form.error.empty":"wcf.editor.link.error.invalid"))}},_dialogSetup:function(){return{id:"redactorDialogLink",options:{onClose:function(){var e=elById("redactor-link-url"),t=e.nextElementSibling&&"SMALL"===e.nextElementSibling.nodeName?e.nextElementSibling:null;null!==t&&elRemove(t)},onSetup:function(i){var n=elBySel(".formSubmit > .buttonPrimary",i);null!==n&&elBySelAll('input[type="url"], input[type="text"]',i,function(i){i.addEventListener("keyup",function(i){t.Enter(i)&&e.triggerEvent(n,"click")})})},onShow:function(){elById("redactor-link-url").focus()}},source:'<dl><dt><label for="redactor-link-url">'+i.get("wcf.editor.link.url")+'</label></dt><dd><input type="url" id="redactor-link-url" class="long"></dd></dl><dl><dt><label for="redactor-link-url-text">'+i.get("wcf.editor.link.text")+'</label></dt><dd><input type="text" id="redactor-link-url-text" class="long"></dd></dl><div class="formSubmit"><button id="redactor-modal-button-action" class="buttonPrimary"></button></div>'}}}}),define("WoltLabSuite/Core/Ui/Redactor/Mention",["Ajax","Environment","StringUtil","Ui/CloseOverlay"],function(e,t,i,n){"use strict";function a(e){this.init(e)}var r=null;return a.prototype={init:function(e){this._active=!1,this._dropdownActive=!1,this._dropdownMenu=null,this._itemIndex=0,this._lineHeight=null,this._mentionStart="",this._redactor=e,this._timer=null,e.WoltLabEvent.register("keydown",this._keyDown.bind(this)),e.WoltLabEvent.register("keyup",this._keyUp.bind(this)),n.add("UiRedactorMention-"+e.core.element()[0].id,this._hideDropdown.bind(this))},_keyDown:function(e){if(this._dropdownActive){var t=e.event;switch(t.which){case 13:this._setUsername(null,this._dropdownMenu.children[this._itemIndex].children[0]);break;case 38:this._selectItem(-1);break;case 40:this._selectItem(1);break;default:return void this._hideDropdown()}t.preventDefault(),e.cancel=!0}},_keyUp:function(t){var i=t.event;if(13===i.which)return void(this._active=!1);if(!this._dropdownActive||(t.cancel=!0,38!==i.which&&40!==i.which)){var n=this._getTextLineInFrontOfCaret();if(n.length>0&&n.length<25){var a=n.match(/@([^,]{3,})$/);a?a.index&&!n[a.index-1].match(/\s/)||(this._mentionStart=a[1],null!==this._timer&&(window.clearTimeout(this._timer),this._timer=null),this._timer=window.setTimeout(function(){e.api(this,{parameters:{data:{searchString:this._mentionStart}}}),this._timer=null}.bind(this),500)):this._hideDropdown()}else this._hideDropdown()}},_getTextLineInFrontOfCaret:function(){var e=this._selectMention(!1);return null!==e?e.range.cloneContents().textContent.replace(/\u200B/g,"").replace(/\u00A0/g," ").trim():""},_getDropdownMenuPosition:function(){var e=this._selectMention();if(null===e)return null;this._redactor.selection.save(),e.selection.removeAllRanges(),e.selection.addRange(e.range);var t=e.selection.getRangeAt(0).getBoundingClientRect(),i={top:Math.round(t.bottom)+(window.scrollY||window.pageYOffset),left:Math.round(t.left)+document.body.scrollLeft};return null===this._lineHeight&&(this._lineHeight=Math.round(t.bottom-t.top)),this._redactor.selection.restore(),i},_setUsername:function(e,t){e&&(e.preventDefault(),t=e.currentTarget);var i=this._selectMention();if(null===i)return void this._hideDropdown();this._redactor.buffer.set(),i.selection.removeAllRanges(),i.selection.addRange(i.range);var n=getSelection().getRangeAt(0);n.deleteContents(),n.collapse(!0);var a=elData(t,"username").trim();a.split(/\s/g).length>2&&(a="'"+a.replace(/'/g,"''")+"'");var r=document.createTextNode("@"+a+" ");n.insertNode(r),n=document.createRange(),n.selectNode(r),n.collapse(!1),i.selection.removeAllRanges(),i.selection.addRange(n),this._hideDropdown()},_selectMention:function(e){var t=window.getSelection();if(!t.rangeCount||!t.isCollapsed)return null;var i=t.anchorNode;if(i.nodeType===Node.TEXT_NODE&&(i=i.parentNode),-1===i.textContent.indexOf("@"))return null;for(var n=this._redactor.core.editor()[0];i&&i!==n;){if(-1!==["PRE","WOLTLAB-QUOTE"].indexOf(i.nodeName))return null;i=i.parentNode}for(var a=t.getRangeAt(0),r=a.startContainer,o=a.startOffset;r.nodeType===Node.ELEMENT_NODE;){if(0===o&&0===r.childNodes.length)return null;r=r.childNodes[o?o-1:0],o>0&&(o=r.nodeType===Node.TEXT_NODE?r.textContent.length:r.childNodes.length)}for(var s=r,l=-1;null!==s;){if(s.nodeType!==Node.TEXT_NODE)return null;if(-1!==s.textContent.indexOf("@")){l=s.textContent.lastIndexOf("@");break}s=s.previousSibling}if(-1===l)return null;try{a=document.createRange(),a.setStart(s,l),a.setEnd(r,o)}catch(e){return window.console.debug(e),null}if(!1===e){var c="";for(l&&(c=s.textContent.substr(0,l));(s=s.previousSibling)&&s.nodeType===Node.TEXT_NODE;)c=s.textContent+c;if(c.replace(/\u200B/g,"").match(/\S$/))return null}else if(a.cloneContents().textContent.replace(/\u200B/g,"").replace(/\u00A0/g,"").trim().replace(/^@/,"")!==this._mentionStart)return null;return{range:a,selection:t}},_updateDropdownPosition:function(){var e=this._getDropdownMenuPosition();if(null===e)return void this._hideDropdown();e.top+=7,this._dropdownMenu.style.setProperty("left",e.left+"px",""),this._dropdownMenu.style.setProperty("top",e.top+"px",""),this._selectItem(0),e.top+this._dropdownMenu.offsetHeight+10>window.innerHeight+(window.scrollY||window.pageYOffset)&&this._dropdownMenu.style.setProperty("top",e.top-this._dropdownMenu.offsetHeight-2*this._lineHeight+7+"px","")},_selectItem:function(e){var t=elBySel(".active",this._dropdownMenu);null!==t&&t.classList.remove("active"),this._itemIndex+=e,this._itemIndex<0?this._itemIndex=this._dropdownMenu.childElementCount-1:this._itemIndex>=this._dropdownMenu.childElementCount&&(this._itemIndex=0),this._dropdownMenu.children[this._itemIndex].classList.add("active")},_hideDropdown:function(){null!==this._dropdownMenu&&this._dropdownMenu.classList.remove("dropdownOpen"),this._dropdownActive=!1,this._itemIndex=0},_ajaxSetup:function(){return{data:{actionName:"getSearchResultList",className:"wcf\\data\\user\\UserAction",interfaceName:"wcf\\data\\ISearchAction",parameters:{data:{includeUserGroups:!0,scope:"mention"}}},silent:!0}},_ajaxSuccess:function(e){if(!Array.isArray(e.returnValues)||!e.returnValues.length)return void this._hideDropdown();null===this._dropdownMenu&&(this._dropdownMenu=elCreate("ol"),this._dropdownMenu.className="dropdownMenu",null===r&&(r=elCreate("div"),r.className="dropdownMenuContainer",document.body.appendChild(r)),r.appendChild(this._dropdownMenu)),this._dropdownMenu.innerHTML="";for(var t,n,a,o=this._setUsername.bind(this),s=0,l=e.returnValues.length;s<l;s++)a=e.returnValues[s],n=elCreate("li"),t=elCreate("a"),t.addEventListener("mousedown",o),t.className="box16",t.innerHTML="<span>"+a.icon+"</span> <span>"+i.escapeHTML(a.label)+"</span>",elData(t,"user-id",a.objectID),elData(t,"username",a.label),n.appendChild(t),this._dropdownMenu.appendChild(n);this._dropdownMenu.classList.add("dropdownOpen"),this._dropdownActive=!0,this._updateDropdownPosition()}},a}),define("WoltLabSuite/Core/Ui/Redactor/Page",["WoltLabSuite/Core/Ui/Page/Search"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(e,t){this._editor=e,t.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))},_click:function(t){t.preventDefault(),e.open(this._insert.bind(this))},_insert:function(e){this._editor.buffer.set(),this._editor.insert.text("[wsp='"+e+"'][/wsp]")}},t}),define("WoltLabSuite/Core/Ui/Redactor/Quote",["Core","EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./Metacode","./PseudoHeader"],function(e,t,i,n,a,r,o,s,l){"use strict";function c(e,t){this.init(e,t)}var d=0;return c.prototype={init:function(e,i){this._quote=null,this._quotes=elByTag("woltlab-quote",e.$editor[0]),this._editor=e,this._elementId=this._editor.$element[0].id,t.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._editor.button.addCallback(i,this._click.bind(this)),this._callbackEdit=this._edit.bind(this),this._observeLoad(),t.add("com.woltlab.wcf.redactor2","insertQuote_"+this._elementId,this._insertQuote.bind(this))},_insertQuote:function(e){if(!this._editor.WoltLabSource.isActive()){t.fire("com.woltlab.wcf.redactor2","showEditor");var i=this._editor.core.editor()[0];this._editor.selection.restore(),this._editor.buffer.set();var n=this._editor.selection.block();for(!1===n&&(this._editor.focus.end(),n=this._editor.selection.block());n&&n.parentNode!==i;)n=n.parentNode;var r=elCreate("woltlab-quote");elData(r,"author",e.author),elData(r,"link",e.link);var o=e.content;e.isText?(o=a.escapeHTML(o),o="<p>"+o+"</p>",o=o.replace(/\n\n/g,"</p><p>"),o=o.replace(/\n/g,"<br>")):o=s.convertFromHtml(this._editor.$element[0].id,o),r.innerHTML=o,n.parentNode.insertBefore(r,n.nextSibling),
-"P"!==n.nodeName||"<br>"!==n.innerHTML&&""!==n.innerHTML.replace(/\u200B/g,"")||n.parentNode.removeChild(n);var l=r.previousElementSibling;l&&"P"!==l.nodeName&&(l=elCreate("p"),l.textContent="​",r.parentNode.insertBefore(l,r)),this._editor.WoltLabCaret.paragraphAfterBlock(r),this._editor.buffer.set()}},_click:function(){this._editor.button.toggle({},"woltlab-quote","func","block.format");var e=this._editor.selection.block();e&&"WOLTLAB-QUOTE"===e.nodeName&&(this._setTitle(e),e.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(e))},_observeLoad:function(){for(var e,t=0,i=this._quotes.length;t<i;t++)e=this._quotes[t],e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)},_edit:function(e){var t=e.currentTarget;0===d&&(d=l.getHeight(t));var i=r.offset(t);e.pageY>i.top&&e.pageY<i.top+d&&(e.preventDefault(),this._editor.selection.save(),this._quote=t,o.open(this))},_dialogSubmit:function(){var e="redactor-quote-"+this._elementId,t=elById(e+"-url"),i=t.value.replace(/\u200B/g,"").trim();if(i.length&&!/^https?:\/\/[^\/]+/.test(i))return void elInnerError(t,n.get("wcf.editor.quote.url.error.invalid"));elInnerError(t,!1),elData(this._quote,"author",elById(e+"-author").value),elData(this._quote,"link",i),this._setTitle(this._quote),this._editor.caret.after(this._quote),o.close(this)},_setTitle:function(e){var t=n.get("wcf.editor.quote.title",{author:elData(e,"author"),url:elData(e,"url")});elData(e,"title")!==t&&elData(e,"title",t)},_delete:function(e){e.preventDefault();var t=this._quote.nextElementSibling||this._quote.previousElementSibling;null===t&&this._quote.parentNode!==this._editor.core.editor()[0]&&(t=this._quote.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._quote),this._editor.caret.end(t)),o.close(this)},_dialogSetup:function(){var e="redactor-quote-"+this._elementId,t=e+"-author",i=e+"-button-delete",a=e+"-button-save",r=e+"-url";return{id:e,options:{onClose:function(){this._editor.selection.restore(),o.destroy(this)}.bind(this),onSetup:function(){elById(i).addEventListener(WCF_CLICK_EVENT,this._delete.bind(this))}.bind(this),onShow:function(){elById(t).value=elData(this._quote,"author"),elById(r).value=elData(this._quote,"link")}.bind(this),title:n.get("wcf.editor.quote.edit")},source:'<div class="section"><dl><dt><label for="'+t+'">'+n.get("wcf.editor.quote.author")+'</label></dt><dd><input type="text" id="'+t+'" class="long" data-dialog-submit-on-enter="true"></dd></dl><dl><dt><label for="'+r+'">'+n.get("wcf.editor.quote.url")+'</label></dt><dd><input type="text" id="'+r+'" class="long" data-dialog-submit-on-enter="true"><small>'+n.get("wcf.editor.quote.url.description")+'</small></dd></dl></div><div class="formSubmit"><button id="'+a+'" class="buttonPrimary" data-type="submit">'+n.get("wcf.global.button.save")+'</button><button id="'+i+'">'+n.get("wcf.global.button.delete")+"</button></div>"}}},c}),define("WoltLabSuite/Core/Ui/Redactor/Spoiler",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,a,r,o){"use strict";function s(e){this.init(e)}var l=0;return s.prototype={init:function(t){this._editor=t,this._elementId=this._editor.$element[0].id,this._spoiler=null,e.add("com.woltlab.wcf.redactor2","bbcode_spoiler_"+this._elementId,this._bbcodeSpoiler.bind(this)),e.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._callbackEdit=this._edit.bind(this),this._observeLoad()},_bbcodeSpoiler:function(e){e.cancel=!0,this._editor.button.toggle({},"woltlab-spoiler","func","block.format");var t=this._editor.selection.block();t&&("P"===t.nodeName&&(t=t.parentNode),"WOLTLAB-SPOILER"===t.nodeName&&(this._setTitle(t),t.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(t)))},_observeLoad:function(){elBySelAll("woltlab-spoiler",this._editor.$editor[0],function(e){e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)}.bind(this))},_edit:function(e){var t=e.currentTarget;0===l&&(l=o.getHeight(t));var i=a.offset(t);e.pageY>i.top&&e.pageY<i.top+l&&(e.preventDefault(),this._editor.selection.save(),this._spoiler=t,r.open(this))},_dialogSubmit:function(){elData(this._spoiler,"label",elById("redactor-spoiler-"+this._elementId+"-label").value),this._setTitle(this._spoiler),this._editor.caret.after(this._spoiler),r.close(this)},_setTitle:function(e){var t=i.get("wcf.editor.spoiler.title",{label:elData(e,"label")});elData(e,"title")!==t&&elData(e,"title",t)},_delete:function(e){e.preventDefault();var t=this._spoiler.nextElementSibling||this._spoiler.previousElementSibling;null===t&&this._spoiler.parentNode!==this._editor.core.editor()[0]&&(t=this._spoiler.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._spoiler),this._editor.caret.end(t)),r.close(this)},_dialogSetup:function(){var e="redactor-spoiler-"+this._elementId,t=e+"-button-delete",n=e+"-button-save",a=e+"-label";return{id:e,options:{onClose:function(){this._editor.selection.restore(),r.destroy(this)}.bind(this),onSetup:function(){elById(t).addEventListener(WCF_CLICK_EVENT,this._delete.bind(this))}.bind(this),onShow:function(){elById(a).value=elData(this._spoiler,"label")}.bind(this),title:i.get("wcf.editor.spoiler.edit")},source:'<div class="section"><dl><dt><label for="'+a+'">'+i.get("wcf.editor.spoiler.label")+'</label></dt><dd><input type="text" id="'+a+'" class="long" data-dialog-submit-on-enter="true"><small>'+i.get("wcf.editor.spoiler.label.description")+'</small></dd></dl></div><div class="formSubmit"><button id="'+n+'" class="buttonPrimary" data-type="submit">'+i.get("wcf.global.button.save")+'</button><button id="'+t+'">'+i.get("wcf.global.button.delete")+"</button></div>"}}},s}),define("WoltLabSuite/Core/Ui/Redactor/Table",["Language","Ui/Dialog"],function(e,t){"use strict";var i=null;return{showDialog:function(e){t.open(this),i=e.submitCallback},_dialogSubmit:function(){var e=!0;["rows","cols"].forEach(function(t){var i=elById("redactor-table-"+t);(i.value<1||i.value>100)&&(e=!1)}),e&&(i(),t.close(this))},_dialogSetup:function(){return{id:"redactorDialogTable",options:{onShow:function(){elById("redactor-table-rows").value=2,elById("redactor-table-cols").value=3},title:e.get("wcf.editor.table.insertTable")},source:'<dl><dt><label for="redactor-table-rows">'+e.get("wcf.editor.table.rows")+'</label></dt><dd><input type="number" id="redactor-table-rows" class="small" min="1" max="100" value="2" data-dialog-submit-on-enter="true"></dd></dl><dl><dt><label for="redactor-table-cols">'+e.get("wcf.editor.table.cols")+'</label></dt><dd><input type="number" id="redactor-table-cols" class="small" min="1" max="100" value="3" data-dialog-submit-on-enter="true"></dd></dl><div class="formSubmit"><button id="redactor-modal-button-action" class="buttonPrimary" data-type="submit">'+e.get("wcf.global.button.insert")+"</button></div>"}}}}),define("WoltLabSuite/Core/Ui/Search/Page",["Core","Dom/Traverse","Dom/Util","Ui/Screen","Ui/SimpleDropdown","./Input"],function(e,t,i,n,a,r){"use strict";return{init:function(o){var s=elById("pageHeaderSearchInput");new r(s,{ajax:{className:"wcf\\data\\search\\keyword\\SearchKeywordAction"},callbackDropdownInit:function(e){if(e.classList.add("dropdownMenuPageSearch"),n.is("screen-lg")){elData(e,"dropdown-alignment-horizontal","right");var t=s.clientWidth;e.style.setProperty("min-width",t+"px","");var a=s.parentNode,r=i.offset(a).left+a.clientWidth-(i.offset(s).left+t),o=i.styleAsInt(window.getComputedStyle(a),"padding-bottom");e.style.setProperty("transform","translateX(-"+Math.ceil(r)+"px) translateY(-"+o+"px)","")}},callbackSelect:function(){return setTimeout(function(){t.parentByTag(s,"FORM").submit()},1),!0}});var l=a.getDropdownMenu(i.identify(elBySel(".pageHeaderSearchType"))),c=this._click.bind(this);elBySelAll("a[data-object-type]",l,function(e){e.addEventListener(WCF_CLICK_EVENT,c)});var d=elBySel('a[data-object-type="'+o+'"]',l);e.triggerEvent(d,WCF_CLICK_EVENT)},_click:function(e){e.preventDefault();var t=elById("pageHeader");t.classList.add("searchBarForceOpen"),window.setTimeout(function(){t.classList.remove("searchBarForceOpen")},10);var i=elData(e.currentTarget,"object-type"),n=elById("pageHeaderSearchParameters");n.innerHTML="";var a=elData(e.currentTarget,"extended-link");a&&(elBySel(".pageHeaderSearchExtendedLink").href=a);var r=elData(e.currentTarget,"parameters");r=r?JSON.parse(r):{},i&&(r["types[]"]=i);for(var o in r)if(r.hasOwnProperty(o)){var s=elCreate("input");s.type="hidden",s.name=o,s.value=r[o],n.appendChild(s)}elBySel(".pageHeaderSearchType > .button > .pageHeaderSearchTypeLabel",elById("pageHeaderSearchInputContainer")).textContent=e.currentTarget.textContent}}}),define("WoltLabSuite/Core/Ui/Smiley/Insert",["EventHandler","EventKey"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={_container:null,_editorId:"",init:function(e){if(this._editorId=e,this._container=elById("smilies-"+this._editorId),!this._container&&(this._container=elById(this._editorId+"SmiliesTabContainer"),!this._container))throw new Error("Unable to find the message tab menu container containing the smilies.");this._container.addEventListener("keydown",this._keydown.bind(this)),this._container.addEventListener("mousedown",this._mousedown.bind(this))},_keydown:function(e){var i=document.activeElement;if(i.classList.contains("jsSmiley"))if(t.ArrowLeft(e)||t.ArrowRight(e)||t.Home(e)||t.End(e)){e.preventDefault();var n=Array.prototype.slice.call(elBySelAll(".jsSmiley",e.currentTarget));t.ArrowLeft(e)&&n.reverse();var a=n.indexOf(i);t.Home(e)?a=0:t.End(e)?a=n.length-1:(a+=1)===n.length&&(a=0),n[a].focus()}else(t.Enter(e)||t.Space(e))&&(e.preventDefault(),this._insert(elBySel("img",i)))},_mousedown:function(e){var t=e.target.closest("li");if(this._container.contains(t)){e.preventDefault();var i=elBySel("img",t);i&&this._insert(i)}},_insert:function(t){e.fire("com.woltlab.wcf.redactor2","insertSmiley_"+this._editorId,{img:t})}},i}),define("WoltLabSuite/Core/Ui/Style/FontAwesome",["Language","Ui/Dialog","WoltLabSuite/Core/Ui/ItemList/Filter"],function(e,t,i){"use strict";var n,a,r,o=[];return{setup:function(e){o=e},open:function(e){if(0===o.length)throw new Error("Missing icon data, please include the template before calling this method using `{include file='fontAwesomeJavaScript'}`.");n=e,t.open(this)},_click:function(e){e.preventDefault();var i=e.target.closest("li"),a=elBySel("small",i).textContent.trim();t.close(this),n(a)},_dialogSetup:function(){return{id:"fontAwesomeSelection",options:{onSetup:function(){a=elById("fontAwesomeIcons");for(var e,t="",n=0,s=o.length;n<s;n++)e=o[n],t+='<li><span class="icon icon48 fa-'+e+'"></span><small>'+e+"</small></li>";a.innerHTML=t,a.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),r=new i("fontAwesomeIcons",{callbackPrepareItem:function(e){var t=elBySel("small",e);return{item:e,span:t,text:t.textContent.trim()}},enableVisibilityFilter:!1,filterPosition:"top"})}.bind(this),onShow:function(){r.reset()},title:e.get("wcf.global.fontAwesome.selectIcon")},source:'<ul class="fontAwesomeIcons" id="fontAwesomeIcons"></ul>'}}}}),define("WoltLabSuite/Core/Ui/Toggle/Input",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(t,i){if(this._element=elBySel(t),null===this._element)throw new Error("Unable to find element by selector '"+t+"'.");var n="INPUT"===this._element.nodeName?elAttr(this._element,"type"):"";if("checkbox"!==n&&"radio"!==n)throw new Error("Illegal element, expected input[type='checkbox'] or input[type='radio'].");this._options=e.extend({hide:[],show:[]},i),["hide","show"].forEach(function(e){var t,i,n;for(i=0,n=this._options[e].length;i<n;i++)if("string"!=typeof(t=this._options[e][i])&&!(t instanceof Element))throw new TypeError("The array '"+e+"' may only contain string selectors or DOM elements.")}.bind(this)),this._element.addEventListener("change",this._change.bind(this)),this._handleElements(this._options.show,this._element.checked),this._handleElements(this._options.hide,!this._element.checked)},_change:function(e){var t=e.currentTarget.checked;this._handleElements(this._options.show,t),this._handleElements(this._options.hide,!t)},_handleElements:function(e,t){for(var i,n,a=0,r=e.length;a<r;a++){if("string"==typeof(i=e[a])){if(null===(n=elBySel(i)))throw new Error("Unable to find element by selector '"+i+"'.");e[a]=i=n}window[t?"elShow":"elHide"](i)}}},t}),define("WoltLabSuite/Core/Ui/User/Editor",["Ajax","Language","StringUtil","Dom/Util","Ui/Dialog","Ui/Notification"],function(e,t,i,n,a,r){"use strict";var o="",s=null;return{init:function(){s=elBySel(".userProfileUser"),["ban","disableAvatar","disableCoverPhoto","disableSignature","enable"].forEach(function(e){var t=elBySel(".userProfileButtonMenu .jsButtonUser"+i.ucfirst(e));t&&(elData(t,"action",e),t.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)))}.bind(this))},_click:function(t){t.preventDefault();var i=elData(t.currentTarget,"action"),n="";switch(i){case"ban":elDataBool(s,"banned")&&(n="unban");break;case"disableAvatar":elDataBool(s,"disable-avatar")&&(n="enableAvatar");break;case"disableCoverPhoto":elDataBool(s,"disable-cover-photo")&&(n="enableCoverPhoto");break;case"disableSignature":elDataBool(s,"disable-signature")&&(n="enableSignature");break;case"enable":n=elDataBool(s,"is-disabled")?"enable":"disable"}""===n?(o=i,a.open(this)):e.api(this,{actionName:n})},_submit:function(i){i.preventDefault();var n=elById("wcfUiUserEditorExpiresLabel"),a="",r="";elById("wcfUiUserEditorNeverExpires").checked||""===(a=elById("wcfUiUserEditorExpiresDatePicker").value)&&(r=t.get("wcf.global.form.error.empty")),elInnerError(n,r);var s={};s[o+"Expires"]=a,s[o+"Reason"]=elById("wcfUiUserEditorReason").value.trim(),e.api(this,{actionName:o,parameters:s})},_ajaxSuccess:function(e){switch(e.actionName){case"ban":case"unban":elData(s,"banned","ban"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserBan").textContent=t.get("wcf.user."+("ban"===e.actionName?"unban":"ban"));var i=elBySel(".contentTitle",s),n=elBySel(".jsUserBanned",i);"ban"===e.actionName?(n=elCreate("span"),n.className="icon icon24 fa-lock jsUserBanned jsTooltip",n.title=e.returnValues,i.appendChild(n)):n&&elRemove(n);break;case"disableAvatar":case"enableAvatar":elData(s,"disable-avatar","disableAvatar"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserDisableAvatar").textContent=t.get("wcf.user."+("disableAvatar"===e.actionName?"enable":"disable")+"Avatar");break;case"disableCoverPhoto":case"enableCoverPhoto":elData(s,"disable-cover-photo","disableCoverPhoto"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserDisableCoverPhoto").textContent=t.get("wcf.user."+("disableCoverPhoto"===e.actionName?"enable":"disable")+"CoverPhoto");break;case"disableSignature":case"enableSignature":elData(s,"disable-signature","disableSignature"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserDisableSignature").textContent=t.get("wcf.user."+("disableSignature"===e.actionName?"enable":"disable")+"Signature");break;case"enable":case"disable":elData(s,"is-disabled","disable"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserEnable").textContent=t.get("wcf.acp.user."+("enable"===e.actionName?"disable":"enable"))}"ban"!==e.actionName&&"disableAvatar"!==e.actionName&&"disableCoverPhoto"!==e.actionName&&"disableSignature"!==e.actionName||a.close(this),r.show()},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\UserAction",objectIDs:[elData(s,"object-id")]}}},_dialogSetup:function(){return{id:"wcfUiUserEditor",options:{onSetup:function(e){elById("wcfUiUserEditorNeverExpires").addEventListener("change",function(){window[this.checked?"elHide":"elShow"](elById("wcfUiUserEditorExpiresSettings"))}),elBySel("button.buttonPrimary",e).addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))}.bind(this),onShow:function(e){a.setTitle("wcfUiUserEditor",t.get("wcf.user."+o+".confirmMessage"));var i=elById("wcfUiUserEditorReason").nextElementSibling,n="wcf.user."+o+".reason.description";i.textContent=t.get(n),window[i.textContent===n?"elHide":"elShow"](i),i=elById("wcfUiUserEditorNeverExpires").nextElementSibling,i.textContent=t.get("wcf.user."+o+".neverExpires"),i=elBySel('label[for="wcfUiUserEditorExpires"]',e),i.textContent=t.get("wcf.user."+o+".expires"),i=elById("wcfUiUserEditorExpiresLabel"),i.textContent=t.get("wcf.user."+o+".expires.description")}},source:'<div class="section"><dl><dt><label for="wcfUiUserEditorReason">'+t.get("wcf.global.reason")+'</label></dt><dd><textarea id="wcfUiUserEditorReason" cols="40" rows="3"></textarea><small></small></dd></dl><dl><dt></dt><dd><label><input type="checkbox" id="wcfUiUserEditorNeverExpires" checked> <span></span></label></dd></dl><dl id="wcfUiUserEditorExpiresSettings" style="display: none"><dt><label for="wcfUiUserEditorExpires"></label></dt><dd><input type="date" name="wcfUiUserEditorExpires" id="wcfUiUserEditorExpires" class="medium" min="'+new Date(1e3*TIME_NOW).toISOString()+'" data-ignore-timezone="true"><small id="wcfUiUserEditorExpiresLabel"></small></dd></dl></div><div class="formSubmit"><button class="buttonPrimary">'+t.get("wcf.global.button.submit")+"</button></div>"}}}}),define("WoltLabSuite/Core/Controller/Condition/Page/Dependence",["Dom/ChangeListener","Dom/Traverse","EventHandler","ObjectMap"],function(e,t,i,n){"use strict";var a=elBySelAll('input[name="pageIDs[]"]'),r=[],o=new n,s=new n,l=!1;return{register:function(e,i){if(r.push(e),o.set(e,i),s.set(e,[]),!l){for(var n=0,c=a.length;n<c;n++)a[n].addEventListener("change",this._checkVisibility.bind(this));l=!0}t.parentByTag(e,"FORM").addEventListener("submit",function(){"none"===e.style.getPropertyValue("display")&&e.remove()}),this._checkVisibility()},_checkVisibility:function(){for(var e,t,n,s,l,c=0,d=r.length;c<d;c++){e=r[c],n=o.get(e),s=[];for(var u=0,h=a.length;u<h;u++)t=a[u],t.checked&&s.push(~~t.value);l=s.filter(function(e){return-1===n.indexOf(e)}),!s.length||l.length?this._hideDependentElement(e):this._showDependentElement(e)}i.fire("com.woltlab.wcf.pageConditionDependence","checkVisivility")},_hideDependentElement:function(e){elHide(e);for(var t=s.get(e),i=0,n=t.length;i<n;i++)elHide(t[i]);s.set(e,[])},_showDependentElement:function(e){elShow(e);for(var t=e;(t=t.parentNode)&&t instanceof Element;)"none"===t.style.getPropertyValue("display")&&s.get(e).push(t),elShow(t)}}}),define("WoltLabSuite/Core/Controller/Map/Route/Planner",["Dom/Traverse","Dom/Util","Language","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,a){function r(e,t){if(this._button=elById(e),null===this._button)throw new Error("Unknown button with id '"+e+"'");this._button.addEventListener("click",this._openDialog.bind(this)),this._destination=t}return r.prototype={_dialogSetup:function(){return{id:this._button.id+"Dialog",options:{onShow:this._initDialog.bind(this),title:i.get("wcf.map.route.planner")},source:'<div class="googleMapsDirectionsContainer" style="display: none;"><div class="googleMap"></div><div class="googleMapsDirections"></div></div><small class="googleMapsDirectionsGoogleLinkContainer"><a href="'+this._getGoogleMapsLink()+'" class="googleMapsDirectionsGoogleLink" target="_blank" style="display: none;">'+i.get("wcf.map.route.viewOnGoogleMaps")+"</a></small><dl><dt>"+i.get("wcf.map.route.origin")+'</dt><dd><input type="text" name="origin" class="long" autofocus /></dd></dl><dl style="display: none;"><dt>'+i.get("wcf.map.route.travelMode")+'</dt><dd><select name="travelMode"><option value="driving">'+i.get("wcf.map.route.travelMode.driving")+'</option><option value="walking">'+i.get("wcf.map.route.travelMode.walking")+'</option><option value="bicycling">'+i.get("wcf.map.route.travelMode.bicycling")+'</option><option value="transit">'+i.get("wcf.map.route.travelMode.transit")+"</option></select></dd></dl>"}},_calculateRoute:function(e){var t=n.getDialog(this).dialog;e.label&&(this._originInput.value=e.label),void 0===this._map&&(this._map=new google.maps.Map(elByClass("googleMap",t)[0],{disableDoubleClickZoom:WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),draggable:WCF.Location.GoogleMaps.Settings.get("draggable"),mapTypeId:google.maps.MapTypeId.ROADMAP,scaleControl:WCF.Location.GoogleMaps.Settings.get("scaleControl"),scrollwheel:WCF.Location.GoogleMaps.Settings.get("scrollwheel")}),this._directionsService=new google.maps.DirectionsService,this._directionsRenderer=new google.maps.DirectionsRenderer,this._directionsRenderer.setMap(this._map),this._directionsRenderer.setPanel(elByClass("googleMapsDirections",t)[0]),this._googleLink=elByClass("googleMapsDirectionsGoogleLink",t)[0]);var i={destination:this._destination,origin:e.location,provideRouteAlternatives:!0,travelMode:google.maps.TravelMode[this._travelMode.value.toUpperCase()]};a.show(),this._directionsService.route(i,this._setRoute.bind(this)),elAttr(this._googleLink,"href",this._getGoogleMapsLink(e.location,this._travelMode.value)),this._lastOrigin=e.location},_getGoogleMapsLink:function(e,t){if(e){var i="https://www.google.com/maps/dir/?api=1&origin="+e.lat()+","+e.lng()+"&destination="+this._destination.lat()+","+this._destination.lng();return t&&(i+="&travelmode="+t),i}return"https://www.google.com/maps/search/?api=1&query="+this._destination.lat()+","+this._destination.lng()},_initDialog:function(){if(!this._didInitDialog){var e=n.getDialog(this).dialog;this._originInput=elBySel('input[name="origin"]',e),new WCF.Location.GoogleMaps.LocationSearch(this._originInput,this._calculateRoute.bind(this)),this._travelMode=elBySel('select[name="travelMode"]',e),this._travelMode.addEventListener("change",this._updateRoute.bind(this)),this._didInitDialog=!0}},_openDialog:function(){n.open(this)},_setRoute:function(t,n){a.hide(),"OK"===n?(elShow(this._map.getDiv().parentNode),google.maps.event.trigger(this._map,"resize"),this._directionsRenderer.setDirections(t),elShow(e.parentByTag(this._travelMode,"DL")),elShow(this._googleLink),elInnerError(this._originInput,!1)):("OVER_QUERY_LIMIT"!==n&&"REQUEST_DENIED"!==n&&(n="NOT_FOUND"),elInnerError(this._originInput,i.get("wcf.map.route.error."+n.toLowerCase())))},_updateRoute:function(){this._calculateRoute({location:this._lastOrigin})}},r}),define("WoltLabSuite/Core/Controller/User/Notification/Settings",["Dictionary","Language","Dom/Traverse","Ui/SimpleDropdown"],function(e,t,i,n){"use strict";var a=new e,r=null,o=null;return{setup:function(){r=this._click.bind(this),o=this._selectType.bind(this);for(var e,t,i=elBySelAll("#notificationSettings .flexibleButtonGroup"),n=0,a=i.length;n<a;n++)e=i[n],null!==(t=elBySel(".notificationSettingsEmail",e))&&this._initGroup(e,t)},_initGroup:function(e,t){var n=~~elData(e,"object-id");elById("settings_"+n+"_disabled").addEventListener(WCF_CLICK_EVENT,function(){t.classList.remove("active")}),elById("settings_"+n+"_enabled").addEventListener(WCF_CLICK_EVENT,function(){t.classList.add("active")});var o=i.childByTag(t,"INPUT"),s=i.childByTag(t,"A");elData(s,"object-id",n),s.addEventListener(WCF_CLICK_EVENT,r),a.set(n,{button:s,dropdownMenu:null,mailSetting:t,mailValue:o})},_click:function(e){e.preventDefault();var t=e.currentTarget,r=~~elData(t,"object-id"),o=a.get(r);if(null===o.dropdownMenu)o.dropdownMenu=this._createDropdown(r,o.mailValue.value),t.parentNode.classList.add("dropdown"),t.parentNode.appendChild(o.dropdownMenu),n.init(t,e);else for(var s=i.childrenByTag(o.dropdownMenu,"LI"),l=o.mailValue.value,c=0;c<4;c++)s[c].classList[elData(s[c],"value")===l?"add":"remove"]("active")},_createDropdown:function(e,i){var n=elCreate("ul");n.className="dropdownMenu",elData(n,"object-id",e);for(var a,r,s,l=["instant","daily","divider","none"],c=0;c<4;c++)s=l[c],r=elCreate("li"),"divider"===s?r.className="dropdownDivider":(a=elCreate("a"),a.textContent=t.get("wcf.user.notification.mailNotificationType."+s),r.appendChild(a),elData(r,"value",s),r.addEventListener(WCF_CLICK_EVENT,o),i===s&&(r.className="active")),n.appendChild(r);return n},_selectType:function(e){var i=elData(e.currentTarget,"value"),n=~~elData(e.currentTarget.parentNode,"object-id"),r=a.get(n);r.mailValue.value=i,elBySel("span.title",r.mailSetting).textContent=t.get("wcf.user.notification.mailNotificationType."+i),r.button.classList["none"===i?"remove":"add"]("yellow"),r.button.classList["none"===i?"remove":"add"]("active")}}}),define("WoltLabSuite/Core/Form/Builder/Container/SuffixFormField",["EventHandler","Ui/SimpleDropdown"],function(e,t){"use strict";function i(i,n){this._formId=i,this._suffixField=elById(n),this._suffixDropdownMenu=t.getDropdownMenu(n+"_dropdown"),this._suffixDropdownToggle=elByClass("dropdownToggle",t.getDropdown(n+"_dropdown"))[0];for(var a=this._suffixDropdownMenu.children,r=0,o=a.length;r<o;r++)a[r].addEventListener("click",this._changeSuffixSelection.bind(this));e.add("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",this._destroyDropdown.bind(this))}return i.prototype={_changeSuffixSelection:function(e){if(!e.currentTarget.classList.contains("disabled")){for(var t=this._suffixDropdownMenu.children,i=0,n=t.length;i<n;i++)t[i]===e.currentTarget?t[i].classList.add("active"):t[i].classList.remove("active");this._suffixField.value=elData(e.currentTarget,"value"),this._suffixDropdownToggle.innerHTML=elData(e.currentTarget,"label")+' <span class="icon icon16 fa-caret-down pointer"></span>'}},_destroyDropdown:function(e){e.formId===this._formId&&t.destroy(this._suffixDropdownMenu.id)}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Acl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e),this._aclList=null}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._aclList.getData(),e},_readField:function(){},setAclList:function(e){this._aclList=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Captcha",["Core","./Field","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){return i.has(this._fieldId)?i.getData(this._fieldId):{}},_readField:function(){},destroy:function(){i.has(this._fieldId)&&i.delete(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Checkboxes",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=0,i=this._fields.length;t<i;t++)this._fields[t].checked&&e[this._fieldId].push(this._fields[t].value);return e},_readField:function(){this._fields=elBySelAll('input[name="'+this._fieldId+'[]"]')}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Checked",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=~~this._field.checked,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Date",["Core","WoltLabSuite/Core/Date/Picker","./Field"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{_getData:function(){var e={};return e[this._fieldId]=t.getValue(this._field),e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/ItemList",["Core","./Field","WoltLabSuite/Core/Ui/ItemList/Static"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,a=t.length;n<a;n++)t[n].objectId?e[this._fieldId][t[n].objectId]=t[n].value:e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/RadioButton",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){for(var e={},t=0,i=this._fields.length;t<i;t++)if(this._fields[t].checked){e[this._fieldId]=this._fields[t].value;break}return e},_readField:function(){this._fields=elBySelAll("input[name="+this._fieldId+"]")}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/SimpleAcl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e=[];elBySelAll('input[name="'+this._fieldId+'[group][]"]',void 0,function(t){e.push(~~t.value)});var t=[];elBySelAll('input[name="'+this._fieldId+'[user][]"]',void 0,function(e){t.push(~~e.value)});var i={};return i[this._fieldId]={group:e,user:t},i},_readField:function(){}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Tag",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,a=t.length;n<a;n++)e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/User",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){for(var e=i.getValues(this._fieldId),t=[],n=0,a=e.length;n<a;n++)t.push(e[n].value);var r={};return r[this._fieldId]=t.join(","),r}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Value",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._field.value,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/ValueI18n",["Core","./Field","WoltLabSuite/Core/Language/Input"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={},t=i.getValues(this._fieldId);return t.size>1?e[this._fieldId+"_i18n"]=t.toObject():e[this._fieldId]=t.get(0),e},destroy:function(){i.unregister(this._fieldId)}}),n}),define("WoltLabSuite/Core/Ui/Comment/Response/Add",["Core","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Notification","WoltLabSuite/Core/Ui/Comment/Add"],function(e,t,i,n,a,r,o){"use strict";function s(e,t){this.init(e,t)}return e.inherit(s,o,{init:function(t,i){s._super.prototype.init.call(this,t),this._options=e.extend({callbackInsert:null},i)},getContainer:function(){return this._isBusy?null:this._container},getContent:function(){return window.jQuery(this._textarea).redactor("code.get")},setContent:function(e){window.jQuery(this._textarea).redactor("code.set",e),window.jQuery(this._textarea).redactor("WoltLabCaret.endOfEditor");var t=elBySel(".innerError",this._textarea.parentNode);null!==t&&elRemove(t),this._content.classList.remove("collapsed"),this._focusEditor()},_getParameters:function(){var e=s._super.prototype._getParameters.call(this);return e.data.commentID=~~elData(this._container.closest(".comment"),"object-id"),e},_insertMessage:function(e){var o=a.childByClass(this._container.parentNode,"commentContent"),s=o.nextElementSibling;return null!==s&&s.classList.contains("commentResponseList")||(s=elCreate("ul"),s.className="containerList commentResponseList",elData(s,"responses",0),o.parentNode.insertBefore(s,o.nextSibling)),n.insertHtml(e.returnValues.template,s,"append"),r.show(t.get("wcf.global.success.add")),i.trigger(),window.jQuery(this._textarea).redactor("code.set",""),null!==this._options.callbackInsert&&this._options.callbackInsert(),elData(s,"responses",s.children.length),s.lastElementChild},_ajaxSetup:function(){var e=s._super.prototype._ajaxSetup.call(this);return e.data.actionName="addResponse",e}}),s}),define("WoltLabSuite/Core/Ui/Comment/Response/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll","WoltLabSuite/Core/Ui/Comment/Edit"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,p){"use strict";function f(e){this.init(e)}return t.inherit(f,p,{init:function(e){this._activeElement=null,this._callbackClick=null,this._container=e,this._editorContainer=null,this._responses=new o,this.rebuild(),
-s.add("Ui/Comment/Response/Edit_"+c.identify(this._container),this.rebuild.bind(this))},rebuild:function(){elBySelAll(".commentResponse",this._container,function(e){if(!this._responses.has(e)){if(elDataBool(e,"can-edit")){var t=elBySel(".jsCommentResponseEditButton",e);null!==t&&(null===this._callbackClick&&(this._callbackClick=this._click.bind(this)),t.addEventListener(WCF_CLICK_EVENT,this._callbackClick))}this._responses.add(e)}}.bind(this))},_click:function(t){t.preventDefault(),null===this._activeElement?(this._activeElement=t.currentTarget.closest(".commentResponse"),this._prepare(),e.api(this,{actionName:"beginEdit",objectIDs:[this._getObjectId(this._activeElement)]})):d.show("wcf.message.error.editorAlreadyInUse",null,"warning")},_prepare:function(){this._editorContainer=elCreate("div"),this._editorContainer.className="commentEditorContainer",this._editorContainer.innerHTML='<span class="icon icon48 fa-spinner"></span>';var e=elBySel(".commentResponseContent",this._activeElement);e.insertBefore(this._editorContainer,e.firstChild)},_showMessage:function(e){c.setInnerHtml(elBySel(".commentResponseContent .userMessage",this._editorContainer.parentNode),e.returnValues.message),this._restoreMessage(),d.show()},_getEditorId:function(){return"commentResponseEditor"+this._getObjectId(this._activeElement)},_ajaxSetup:function(){return{data:{className:"wcf\\data\\comment\\response\\CommentResponseAction",parameters:{data:{objectTypeID:~~elData(this._container,"object-type-id")}}},silent:!0}}}),f}),define("WoltLabSuite/Core/Ui/Page/Header/Fixed",["Core","EventHandler","Ui/Alignment","Ui/CloseOverlay","Ui/SimpleDropdown","Ui/Screen"],function(e,t,i,n,a,r){"use strict";var o,s,l,c,d,u,h,p=!1;return{init:function(){o=elById("pageHeader"),s=elById("pageHeaderContainer"),this._initSearchBar(),r.on("screen-md-down",{match:function(){p=!0},unmatch:function(){p=!1},setup:function(){p=!0}}),t.add("com.woltlab.wcf.Search","close",this._closeSearchBar.bind(this))},_initSearchBar:function(){c=elById("pageHeaderSearch"),c.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),l=elById("pageHeaderPanel"),d=elById("pageHeaderSearchInput"),u=elById("topMenu"),h=elById("userPanelSearchButton"),h.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),o.classList.contains("searchBarOpen")?this._closeSearchBar():this._openSearchBar()}.bind(this)),n.add("WoltLabSuite/Core/Ui/Page/Header/Fixed",function(){o.classList.contains("searchBarForceOpen")||this._closeSearchBar()}.bind(this)),t.add("com.woltlab.wcf.MainMenuMobile","more",function(t){"com.woltlab.wcf.search"===t.identifier&&(t.handler.close(!0),e.triggerEvent(h,WCF_CLICK_EVENT))}.bind(this))},_openSearchBar:function(){window.WCF.Dropdown.Interactive.Handler.closeAll(),o.classList.add("searchBarOpen"),h.parentNode.classList.add("open"),p||i.set(c,u,{horizontal:"right"}),c.style.setProperty("top",l.clientHeight+"px",""),d.focus(),window.setTimeout(function(){d.selectionStart=d.selectionEnd=d.value.length},1)},_closeSearchBar:function(){o.classList.remove("searchBarOpen"),h.parentNode.classList.remove("open"),["bottom","left","right","top"].forEach(function(e){c.style.removeProperty(e)}),d.blur();var e=elBySel(".pageHeaderSearchType",c);a.close(e.id)}}}),define("WoltLabSuite/Core/Ui/Page/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){if(n=e.extend({ajax:{className:"wcf\\data\\page\\PageAction"},callbackSuccess:null},n),"function"!=typeof n.callbackSuccess)throw new Error("Expected a valid callback function for 'callbackSuccess'.");i._super.prototype.init.call(this,t,n),this._pageId=0},setPageId:function(e){this._pageId=e},_getParameters:function(e){var t=i._super.prototype._getParameters.call(this,e);return t.objectIDs=[this._pageId],t},_ajaxSuccess:function(e){this._options.callbackSuccess(e)}}),i}),define("WoltLabSuite/Core/Ui/Page/Search/Handler",["Language","StringUtil","Dom/Util","Ui/Dialog","./Input"],function(e,t,i,n,a){"use strict";var r=null,o=null,s=null,l=null,c=null,d=null;return{open:function(t,i,a,o){r=a,n.open(this),n.setTitle(this,i),s.textContent=o?e.get(o):e.get("wcf.page.pageObjectID.search.terms"),this._getSearchInputHandler().setPageId(t)},_buildList:function(i){if(this._resetList(),!Array.isArray(i.returnValues)||0===i.returnValues.length)return void elInnerError(o,e.get("wcf.page.pageObjectID.search.noResults"));for(var n,a,r,s=0,l=i.returnValues.length;s<l;s++)a=i.returnValues[s],n=a.image,/^fa-/.test(n)&&(n='<span class="icon icon48 '+n+' pointer jsTooltip" title="'+e.get("wcf.global.select")+'"></span>'),r=elCreate("li"),elData(r,"object-id",a.objectID),r.innerHTML='<div class="box48">'+n+'<div><div class="containerHeadline"><h3><a href="'+t.escapeHTML(a.link)+'">'+t.escapeHTML(a.title)+"</a></h3>"+(a.description?"<p>"+a.description+"</p>":"")+"</div></div></div>",r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),c.appendChild(r);elShow(d)},_resetList:function(){elInnerError(o,!1),c.innerHTML="",elHide(d)},_getSearchInputHandler:function(){if(null===l){var e=this._buildList.bind(this);l=new a(elById("wcfUiPageSearchInput"),{callbackSuccess:e})}return l},_click:function(e){"A"!==e.target.nodeName&&(e.stopPropagation(),r(elData(e.currentTarget,"object-id")),n.close(this))},_dialogSetup:function(){return{id:"wcfUiPageSearchHandler",options:{onShow:function(){null===o&&(o=elById("wcfUiPageSearchInput"),s=o.parentNode.previousSibling.childNodes[0],c=elById("wcfUiPageSearchResultList"),d=elById("wcfUiPageSearchResultListContainer")),o.value="",elHide(d),c.innerHTML="",o.focus()},title:""},source:'<div class="section"><dl><dt><label for="wcfUiPageSearchInput">'+e.get("wcf.page.pageObjectID.search.terms")+'</label></dt><dd><input type="text" id="wcfUiPageSearchInput" class="long"></dd></dl></div><section id="wcfUiPageSearchResultListContainer" class="section sectionContainerList"><header class="sectionHeader"><h2 class="sectionTitle">'+e.get("wcf.page.pageObjectID.search.results")+'</h2></header><ul id="wcfUiPageSearchResultList" class="containerList wcfUiPageSearchResultList"></ul></section>'}}}}),define("WoltLabSuite/Core/Ui/Reaction/Profile/Loader",["Ajax","Core","Language"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){if(this._container=elById("likeList"),this._userID=e,this._reactionTypeID=null,this._targetType="received",this._options={parameters:[]},!this._userID)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'userID' given.");var t=elCreate("li");t.className="likeListMore showMore",this._noMoreEntries=elCreate("small"),this._noMoreEntries.innerHTML=i.get("wcf.like.reaction.noMoreEntries"),this._noMoreEntries.style.display="none",t.appendChild(this._noMoreEntries),this._loadButton=elCreate("button"),this._loadButton.className="small",this._loadButton.innerHTML=i.get("wcf.like.reaction.more"),this._loadButton.addEventListener(WCF_CLICK_EVENT,this._loadReactions.bind(this)),this._loadButton.style.display="none",t.appendChild(this._loadButton),this._container.appendChild(t),2===elBySel("#likeList > li").length?this._noMoreEntries.style.display="":this._loadButton.style.display="",this._setupReactionTypeButtons(),this._setupTargetTypeButtons()},_setupReactionTypeButtons:function(){for(var e,t=elBySelAll("#reactionType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeReactionTypeValue.bind(this,~~elData(e,"reaction-type-id")))},_setupTargetTypeButtons:function(){for(var e,t=elBySelAll("#likeType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeTargetType.bind(this,elData(e,"like-type")))},_changeTargetType:function(e){if("given"!==e&&"received"!==e)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'targetType' given.");e!==this._targetType&&(elBySel("#likeType .button.active").classList.remove("active"),elBySel('#likeType .button[data-like-type="'+e+'"]').classList.add("active"),this._targetType=e,this._reload())},_changeReactionTypeValue:function(e){var t=elBySel("#reactionType .button.active");t&&t.classList.remove("active"),this._reactionTypeID!==e?(elBySel('#reactionType .button[data-reaction-type-id="'+e+'"]').classList.add("active"),this._reactionTypeID=e):this._reactionTypeID=null,this._reload()},_reload:function(){for(var e=elBySelAll("#likeList > li:not(:first-child):not(:last-child)"),t=0,i=e.length;t<i;t++)this._container.removeChild(e[t]);elData(this._container,"last-like-time",0),this._loadReactions()},_loadReactions:function(){this._options.parameters.userID=this._userID,this._options.parameters.lastLikeTime=elData(this._container,"last-like-time"),this._options.parameters.targetType=this._targetType,this._options.parameters.reactionTypeID=this._reactionTypeID,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){e.returnValues.template?(elBySel("#likeList > li:nth-last-child(1)").insertAdjacentHTML("beforebegin",e.returnValues.template),elData(this._container,"last-like-time",e.returnValues.lastLikeTime),this._noMoreEntries.style.display="none",this._loadButton.style.display=""):(this._noMoreEntries.style.display="",this._loadButton.style.display="none")},_ajaxSetup:function(){return{data:{actionName:"load",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/Activity/Recent",["Ajax","Language","Dom/Util"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){this._containerId=e;var i=elById(this._containerId);this._list=elBySel(".recentActivityList",i);var n=elCreate("li");n.className="showMore",this._list.childElementCount?(n.innerHTML='<button class="small">'+t.get("wcf.user.recentActivity.more")+"</button>",n.children[0].addEventListener(WCF_CLICK_EVENT,this._showMore.bind(this))):n.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>",this._list.appendChild(n),this._showMoreItem=n,elBySelAll(".jsRecentActivitySwitchContext .button",i,function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),e.classList.contains("active")||this._switchContext()}.bind(this))}.bind(this))},_showMore:function(t){t.preventDefault(),this._showMoreItem.children[0].disabled=!0,e.api(this,{actionName:"load",parameters:{boxID:~~elData(this._list,"box-id"),filteredByFollowedUsers:elDataBool(this._list,"filtered-by-followed-users"),lastEventId:elData(this._list,"last-event-id"),lastEventTime:elData(this._list,"last-event-time"),userID:~~elData(this._list,"user-id")}})},_switchContext:function(){e.api(this,{actionName:"switchContext"},function(){window.location.hash="#"+this._containerId,window.location.reload()}.bind(this))},_ajaxSuccess:function(e){e.returnValues.template?(i.insertHtml(e.returnValues.template,this._showMoreItem,"before"),elData(this._list,"last-event-time",e.returnValues.lastEventTime),elData(this._list,"last-event-id",e.returnValues.lastEventID),this._showMoreItem.children[0].disabled=!1):this._showMoreItem.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>"},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Delete",["Ajax","EventHandler","Language","Ui/Confirmation","Ui/Notification"],function(e,t,i,n,a){"use strict";var r,o=0;return{init:function(e){r=elBySel(".jsButtonDeleteCoverPhoto"),r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),o=e,t.add("com.woltlab.wcf.user","coverPhoto",function(e){"string"==typeof e.url&&e.url.length>0&&elShow(r.parentNode)})},_click:function(t){t.preventDefault(),n.show({confirm:e.api.bind(e,this),message:i.get("wcf.user.coverPhoto.delete.confirmMessage")})},_ajaxSuccess:function(e){elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+e.returnValues.url+")",""),elHide(r.parentNode),a.show()},_ajaxSetup:function(){return{data:{actionName:"deleteCoverPhoto",className:"wcf\\data\\user\\UserProfileAction",parameters:{userID:o}}}}}}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Upload",["Core","EventHandler","Upload","Ui/Notification","Ui/Dialog"],function(e,t,i,n,a){"use strict";function r(e){i.call(this,"coverPhotoUploadButtonContainer","coverPhotoUploadPreview",{action:"uploadCoverPhoto",className:"wcf\\data\\user\\UserProfileAction"}),this._userId=e}return e.inherit(r,i,{_getParameters:function(){return{userID:this._userId}},_success:function(e,i){elInnerError(this._button,i.returnValues.errorMessage),this._target.innerHTML="",i.returnValues.url&&(elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+i.returnValues.url+")",""),a.close("userProfileCoverPhotoUpload"),n.show(),t.fire("com.woltlab.wcf.user","coverPhoto",{url:i.returnValues.url}))}}),r}),define("WoltLabSuite/Core/Ui/User/Trophy/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination","Dom/ChangeListener","List"],function(e,t,i,n,a,r,o,s){"use strict";function l(){this.init()}return l.prototype={init:function(){this._cache=new i,this._knownElements=new s,this._options={className:"wcf\\data\\user\\trophy\\UserTrophyAction",parameters:{}},this._rebuild(),o.add("WoltLabSuite/Core/Ui/User/Trophy/List",this._rebuild.bind(this))},_rebuild:function(){elBySelAll(".userTrophyOverlayList",void 0,function(e){this._knownElements.has(e)||(e.addEventListener(WCF_CLICK_EVENT,this._open.bind(this,elData(e,"user-id"))),this._knownElements.add(e))}.bind(this))},_open:function(e,t){t.preventDefault(),this._currentPageNo=1,this._currentUser=e,this._showPage()},_showPage:function(t){if(void 0!==t&&(this._currentPageNo=t),this._cache.has(this._currentUser)){if(0!==this._cache.get(this._currentUser).get("pageCount")&&(this._currentPageNo<1||this._currentPageNo>this._cache.get(this._currentUser).get("pageCount")))throw new RangeError("pageNo must be between 1 and "+this._cache.get(this._currentUser).get("pageCount")+" ("+this._currentPageNo+" given).")}else this._cache.set(this._currentUser,new i);if(this._cache.get(this._currentUser).has(this._currentPageNo)){var n=a.open(this,this._cache.get(this._currentUser).get(this._currentPageNo));if(a.setTitle("userTrophyListOverlay",this._cache.get(this._currentUser).get("title")),this._cache.get(this._currentUser).get("pageCount")>1){var o=elBySel(".jsPagination",n.content);null!==o&&new r(o,{activePage:this._currentPageNo,maxPage:this._cache.get(this._currentUser).get("pageCount"),callbackSwitch:this._showPage.bind(this)})}}else this._options.parameters.pageNo=this._currentPageNo,this._options.parameters.userID=this._currentUser,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&this._cache.get(this._currentUser).set("pageCount",~~e.returnValues.pageCount),this._cache.get(this._currentUser).set(this._currentPageNo,e.returnValues.template),this._cache.get(this._currentUser).set("title",e.returnValues.title),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserTrophyList",className:this._options.className}}},_dialogSetup:function(){return{id:"userTrophyListOverlay",options:{title:""},source:null}}},l}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Label",["Core","Dom/Util","Language","Ui/SimpleDropdown"],function(e,t,i,n){"use strict";function a(e,t,i){this.init(e,t,i)}return a.prototype={init:function(a,r,o){this._formFieldContainer=elById(a+"Container"),this._labelChooser=elByClass("labelChooser",this._formFieldContainer)[0],this._options=e.extend({forceSelection:!1,showWithoutSelection:!1},o),this._input=elCreate("input"),this._input.type="hidden",this._input.id=a,this._input.name=a,this._input.value=~~r,this._formFieldContainer.appendChild(this._input);var s=t.identify(this._labelChooser),l=n.getDropdownMenu(s);null===l&&(n.init(elByClass("dropdownToggle",this._labelChooser)[0]),l=n.getDropdownMenu(s));var c=null;if(this._options.showWithoutSelection||!this._options.forceSelection){c=elCreate("ul"),l.appendChild(c);var d=elCreate("li");d.className="dropdownDivider",c.appendChild(d)}if(this._options.showWithoutSelection){var u=elCreate("li");elData(u,"label-id",-1),this._blockScroll(u),c.appendChild(u);var h=elCreate("span");u.appendChild(h);var p=elCreate("span");p.className="badge label",p.innerHTML=i.get("wcf.label.withoutSelection"),h.appendChild(p)}if(!this._options.forceSelection){var u=elCreate("li");elData(u,"label-id",0),this._blockScroll(u),c.appendChild(u);var h=elCreate("span");u.appendChild(h);var p=elCreate("span");p.className="badge label",p.innerHTML=i.get("wcf.label.none"),h.appendChild(p)}elBySelAll("li:not(.dropdownDivider)",l,function(e){e.addEventListener("click",this._click.bind(this)),r&&~~elData(e,"label-id")===r&&this._selectLabel(e)}.bind(this))},_blockScroll:function(e){e.addEventListener("wheel",function(e){e.preventDefault()},{passive:!1})},_click:function(e){e.preventDefault(),this._selectLabel(e.currentTarget,!1)},_selectLabel:function(e){var t=elData(e,"label-id");t||(t=0);var i=elBySel("span > span",e),n=elBySel(".dropdownToggle > span",this._labelChooser);n.className=i.className,n.textContent=i.textContent,this._input.value=t}},a}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Rating",["Dictionary","Environment"],function(e,t){"use strict";function i(e,t,i,n){this.init(e,t,i,n)}return i.prototype={init:function(t,i,n,a){if(this._field=elBySel("#"+t+"Container"),null===this._field)throw new Error("Unknown field with id '"+t+"'");this._input=elCreate("input"),this._input.id=t,this._input.name=t,this._input.type="hidden",this._input.value=i,this._field.appendChild(this._input),this._activeCssClasses=n,this._defaultCssClasses=a,this._ratingElements=new e;var r=elBySel(".ratingList",this._field);r.addEventListener("mouseleave",this._restoreRating.bind(this)),elBySelAll("li",r,function(e){e.classList.contains("ratingMetaButton")?(e.addEventListener("click",this._metaButtonClick.bind(this)),e.addEventListener("mouseenter",this._restoreRating.bind(this))):(this._ratingElements.set(~~elData(e,"rating"),e),e.addEventListener("click",this._listItemClick.bind(this)),e.addEventListener("mouseenter",this._listItemMouseEnter.bind(this)),e.addEventListener("mouseleave",this._listItemMouseLeave.bind(this)))}.bind(this))},_listItemClick:function(e){this._input.value=~~elData(e.currentTarget,"rating"),"desktop"!==t.platform()&&this._restoreRating()},_listItemMouseEnter:function(e){var t=elData(e.currentTarget,"rating");this._ratingElements.forEach(function(e,i){var n=elByClass("icon",e)[0];this._toggleIcon(n,~~i<=~~t)}.bind(this))},_listItemMouseLeave:function(){this._ratingElements.forEach(function(e){var t=elByClass("icon",e)[0];this._toggleIcon(t,!1)}.bind(this))},_metaButtonClick:function(e){"removeRating"===elData(e.currentTarget,"action")&&(this._input.value="",this._listItemMouseLeave())},_restoreRating:function(){this._ratingElements.forEach(function(e,t){var i=elByClass("icon",e)[0];this._toggleIcon(i,~~t<=~~this._input.value)}.bind(this))},_toggleIcon:function(e,t){if(t=t||!1){for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.remove(this._defaultCssClasses[i]);for(var i=0;i<this._activeCssClasses.length;i++)e.classList.add(this._activeCssClasses[i])}else{for(var i=0;i<this._activeCssClasses.length;i++)e.classList.remove(this._activeCssClasses[i]);for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.add(this._defaultCssClasses[i])}}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract",["./Manager"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={checkDependency:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract.checkDependency!")},getDependentNode:function(){return this._dependentElement},getField:function(){return this._field},getFields:function(){return this._fields},init:function(t,i){if(this._dependentElement=elById(t),null===this._dependentElement)throw new Error("Unknown dependent element with container id '"+t+"Container'.");if(this._field=elById(i),null===this._field){if(this._fields=[],elBySelAll("input[type=radio][name="+i+"]",void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length&&(elBySelAll('input[type=checkbox][name="'+i+'[]"]',void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length))throw new Error("Unknown field with id '"+i+"'.")}else if(this._fields=[this._field],"INPUT"===this._field.tagName&&"radio"===this._field.type&&""!==elData(this._field,"no-input-id")){if(this._noField=elById(elData(this._field,"no-input-id")),null===this._noField)throw new Error("Cannot find 'no' input field for input field '"+i+"'");this._fields.push(this._noField)}e.addDependency(this)}},t}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Empty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!1;return!0}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return!this._field.checked;case"radio":return!(!this._noField||!this._noField.checked)||!this._field.checked;default:return 0===this._field.value.trim().length}case"SELECT":return this._field.multiple?0===elBySelAll("option:checked",this._field).length:0==this._field.value||0===this._field.value.length;case"TEXTAREA":return 0===this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/NonEmpty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!0;return!1}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return this._field.checked;case"radio":return(!this._noField||!this._noField.checked)&&this._field.checked;default:return 0!==this._field.value.trim().length}case"SELECT":return this._field.multiple?0!==elBySelAll("option:checked",this._field).length:0!=this._field.value&&0!==this._field.value.length;case"TEXTAREA":return 0!==this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Value",["./Abstract","Core","./Manager"],function(e,t,i){"use strict";function n(e,t,i){this.init(e,t),this._isNegated=!1}return t.inherit(n,e,{checkDependency:function(){if(!this._values)throw new Error("Values have not been set.");var e=[];if(this._field){if(i.isHiddenByDependencies(this._field))return!1;e.push(this._field.value)}else for(var t,n=0,a=this._fields.length;n<a;n++)if(t=this._fields[n],t.checked){if(i.isHiddenByDependencies(t))return!1;e.push(t.value)}for(var n=0,a=this._values.length;n<a;n++)for(var r=0,o=e.length;r<o;r++)if(this._values[n]==e[r])return!this._isNegated;return!!this._isNegated},negate:function(e){return this._isNegated=e,this},values:function(e){return this._values=e,this}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage",["Core","WoltLabSuite/Core/Language/Chooser","../Value"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{destroy:function(){t.removeChooser(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Attachment",["Core","../Value"],function(e,t){"use strict";function i(e){this.init(e+"_tmpHash")}return e.inherit(i,t,{}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Poll",["Core","../Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){return this._pollEditor.getData()},_readField:function(){},setPollEditor:function(e){this._pollEditor=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Abstract",["EventHandler","../Manager"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={checkContainer:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Container.checkContainer!")},init:function(e){if("string"!=typeof e)throw new TypeError("Container id has to be a string.");if(this._container=elById(e),null===this._container)throw new Error("Unknown container with id '"+e+"'.");t.addContainerCheckCallback(this.checkContainer.bind(this))}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default",["./Abstract","Core","../Manager"],function(e,t,i){"use strict";function n(e){this.init(e)}return t.inherit(n,e,{checkContainer:function(){if(!elDataBool(this._container,"ignore-dependencies")&&!i.isHiddenByDependencies(this._container)){var e=!elIsHidden(this._container),t=!1,n=this._container.children,a=0;if("H2"===this._container.children.item(0).tagName||"HEADER"===this._container.children.item(0).tagName)var a=1;for(var r=a,o=n.length;r<o;r++)if(!elIsHidden(n.item(r))){t=!0;break}e!==t&&(t?elShow(this._container):elHide(this._container),i.checkContainers())}}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Tab",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,a){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=this._container.children,o=0,s=r.length;o<s;o++)if(!elIsHidden(r.item(o))){t=!0;break}if(e!==t){var l=elBySel("#"+i.identify(this._container.parentNode)+" > nav > ul > li[data-name="+this._container.id+"]",this._container.parentNode.parentNode);if(null===l)throw new Error("Cannot find tab menu entry for tab '"+this._container.id+"'.");if(t)elShow(this._container),elShow(l);else{elHide(this._container),elHide(l);var c=a.getTabMenu(i.identify(l.closest(".tabMenuContainer")));c.getActiveTab()===l&&c.selectFirstVisible()}n.checkContainers()}}}}),r}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/TabMenu",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,a){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=elBySelAll("#"+i.identify(this._container)+" > nav > ul > li",this._container.parentNode),o=0,s=r.length;o<s;o++)if(!elIsHidden(r[o])){t=!0;break}e!==t&&(t?(elShow(this._container),a.getTabMenu(i.identify(this._container)).selectFirstVisible()):elHide(this._container),n.checkContainers())}}}),r}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Abstract",["Ajax","Dom/Util"],function(e,t){"use strict";function i(e,t){}return i.prototype={init:function(e,t){this._userId=e,this._isActive=!1!==t,this._initButton(),this._updateButton()},_initButton:function(){var e=elCreate("a");e.href="#",e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this));var i=elCreate("li");i.appendChild(e);var n=elBySel('.userProfileButtonMenu[data-menu="interaction"]');t.prepend(i,n),this._button=e,this._listItem=i},_toggle:function(t){t.preventDefault(),e.api(this,{actionName:this._getAjaxActionName(),parameters:{data:{userID:this._userId}}})},_updateButton:function(){this._button.textContent=this._getLabel(),this._listItem.classList[this._isActive?"add":"remove"]("active")},_getLabel:function(){throw new Error("Implement me!")},_getAjaxActionName:function(){throw new Error("Implement me!")},_ajaxSuccess:function(){throw new Error("Implement me!")},_ajaxSetup:function(){throw new Error("Implement me!")}},i}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Follow",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";function a(e,t){this.init(e,t)}return e.inherit(a,n,{_getLabel:function(){return t.get("wcf.user.button."+(this._isActive?"un":"")+"follow")},_getAjaxActionName:function(){return this._isActive?"unfollow":"follow"},_ajaxSuccess:function(e){this._isActive=!!e.returnValues.following,this._updateButton(),i.show()},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\follow\\UserFollowAction"}}}}),a}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Ignore",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";function a(e,t){this.init(e,t)}return e.inherit(a,n,{_getLabel:function(){return t.get("wcf.user.button."+(this._isActive?"un":"")+"ignore")},_getAjaxActionName:function(){return this._isActive?"unignore":"ignore"},_ajaxSuccess:function(e){this._isActive=!!e.returnValues.isIgnoredUser,this._updateButton(),i.show()},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\ignore\\UserIgnoreAction"}}}}),a}),function(e){e.matches=e.matches||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector,e.closest=e.closest||function(e){for(var t=this;t&&!t.matches(e);)t=t.parentElement;return t}}(Element.prototype),define("closest",function(){}),function(e){function t(){for(;n.length&&"function"==typeof n[0];)n.shift()()}var i=e.require,n=[],a=0;e.orgRequire=i,e.require=function(r,o,s){if(!Array.isArray(r))return i.apply(e,arguments);var l=new Promise(function(e,o){var s=a++;n.push(s),i(r,function(){var i=arguments;n[n.indexOf(s)]=function(){e(i)},t()},function(e){n[n.indexOf(s)]=function(){o(e)},t()})});return o&&(l=l.then(function(t){return o.apply(e,t)})),s&&l.catch(s),l},e.require.config=i.config}(window),define("require.linearExecution",function(){});
\ No newline at end of file
+var requirejs,require,define;!function(global,Promise,undef){function commentReplace(e,t){return t||""}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return e&&hasProp(e,t)&&e[t]}function obj(){return Object.create(null)}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,n){return t&&eachProp(t,function(t,a){!i&&hasProp(e,a)||(!n||"object"!=typeof t||!t||Array.isArray(t)||"function"==typeof t||t instanceof RegExp?e[a]=t:(e[a]||(e[a]={}),mixin(e[a],t,i,n)))}),e}function getGlobal(e){if(!e)return e;var t=global;return e.split(".").forEach(function(e){t=t[e]}),t}function newContext(e){function t(e){var t,i,n=e.length;for(t=0;t<n;t++)if("."===(i=e[t]))e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;t>0&&(e.splice(t-1,2),t-=2)}}function i(e,i,n){var a,r,o,s,l,c,d,u,h,f,p=i&&i.split("/"),m=p,g=k.map,v=g&&g["*"];if(e&&(e=e.split("/"),c=e.length-1,k.nodeIdCompat&&jsSuffixRegExp.test(e[c])&&(e[c]=e[c].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&p&&(m=p.slice(0,p.length-1),e=m.concat(e)),t(e),e=e.join("/")),n&&g&&(p||v)){r=e.split("/");e:for(o=r.length;o>0;o-=1){if(l=r.slice(0,o).join("/"),p)for(s=p.length;s>0;s-=1)if((a=getOwn(g,p.slice(0,s).join("/")))&&(a=getOwn(a,l))){d=a,u=o;break e}!h&&v&&getOwn(v,l)&&(h=getOwn(v,l),f=o)}!d&&h&&(d=h,u=f),d&&(r.splice(0,u,d),e=r.join("/"))}return getOwn(k.pkgs,e)||e}function n(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t}function a(e){var t,i,n,a;for(t=0;t<queue.length;t+=1){if("string"!=typeof queue[t][0]){if(!e)break;queue[t].unshift(e),e=undef}n=queue.shift(),i=n[0],t-=1,i in x||i in T||(i in M?C.apply(undef,n):T[i]=n)}e&&(a=getOwn(k.shim,e)||{},C(e,a.deps||[],a.exportsFn))}function r(e,t){var n=function(i,r,o,s){var l,c;if(t&&a(),"string"==typeof i){if(S[i])return S[i](e);if(!((l=E(i,e,!0).id)in x))throw new Error("Not loaded: "+l);return x[l]}return i&&!Array.isArray(i)&&(c=i,i=undef,Array.isArray(r)&&(i=r,r=o,o=s),t)?n.config(c)(i,r,o):(r=r||function(){return slice.call(arguments,0)},V.then(function(){return a(),C(undef,i||[],r,o,e)}))};return n.isBrowser="undefined"!=typeof document&&"undefined"!=typeof navigator,n.nameToUrl=function(e,t,i){var a,r,o,s,l,c,d,u=getOwn(k.pkgs,e);if(u&&(e=u),d=getOwn(H,e))return n.nameToUrl(d,t,i);if(urlRegExp.test(e))l=e+(t||"");else{for(a=k.paths,r=e.split("/"),o=r.length;o>0;o-=1)if(s=r.slice(0,o).join("/"),c=getOwn(a,s)){Array.isArray(c)&&(c=c[0]),r.splice(0,o,c);break}l=r.join("/"),l+=t||(/^data\:|^blob\:|\?/.test(l)||i?"":".js"),l=("/"===l.charAt(0)||l.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+l}return k.urlArgs&&!/^blob\:/.test(l)?l+k.urlArgs(e,l):l},n.toUrl=function(t){var a,r=t.lastIndexOf("."),o=t.split("/")[0],s="."===o||".."===o;return-1!==r&&(!s||r>1)&&(a=t.substring(r,t.length),t=t.substring(0,r)),n.nameToUrl(i(t,e),a,!0)},n.defined=function(t){return E(t,e,!0).id in x},n.specified=function(t){return(t=E(t,e,!0).id)in x||t in M},n}function o(e,t,i){e&&(x[e]=i,requirejs.onResourceLoad&&requirejs.onResourceLoad(D,t.map,t.deps)),t.finished=!0,t.resolve(i)}function s(e,t){e.finished=!0,e.rejected=!0,e.reject(t)}function l(e){return function(t){return i(t,e,!0)}}function c(e){e.factoryCalled=!0;var t,i=e.map.id;try{t=D.execCb(i,e.factory,e.values,x[i])}catch(t){return s(e,t)}i?t===undef&&(e.cjsModule?t=e.cjsModule.exports:e.usingExports&&(t=x[i])):N.splice(N.indexOf(e),1),o(i,e,t)}function d(e,t){this.rejected||this.depDefined[t]||(this.depDefined[t]=!0,this.depCount+=1,this.values[t]=e,this.depending||this.depCount!==this.depMax||c(this))}function u(e,t){var i={};return i.promise=new Promise(function(t,n){i.resolve=t,i.reject=function(t){e||N.splice(N.indexOf(i),1),n(t)}}),i.map=e?t||E(e):{},i.depCount=0,i.depMax=0,i.values=[],i.depDefined=[],i.depFinished=d,i.map.pr&&(i.deps=[E(i.map.pr)]),i}function h(e,t){var i;return e?(i=e in M&&M[e])||(i=M[e]=u(e,t)):(i=u(),N.push(i)),i}function f(e,t){return function(i){e.rejected||(i.dynaId||(i.dynaId="id"+(O+=1),i.requireModules=[t]),s(e,i))}}function p(e,t,i,n){i.depMax+=1,L(e,t).then(function(e){i.depFinished(e,n)},f(i,e.id)).catch(f(i,i.map.id))}function m(e){function t(t){i||o(e,h(e),t)}var i;return t.error=function(t){h(e).reject(t)},t.fromText=function(t,n){var r=h(e),o=E(E(e).n),l=o.id;i=!0,r.factory=function(e,t){return t},n&&(t=n),hasProp(k.config,e)&&(k.config[l]=k.config[e]);try{y.exec(t)}catch(e){s(r,new Error("fromText eval for "+l+" failed: "+e))}a(l),r.deps=[o],p(o,null,r,r.deps.length)},t}function g(e,t,i){e.load(t.n,r(i),m(t.id),k)}function v(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function _(e,t,i){var n=e.map.id;t[n]=!0,!e.finished&&e.deps&&e.deps.forEach(function(n){var a=n.id,r=!hasProp(S,a)&&h(a,n);!r||r.finished||i[a]||(hasProp(t,a)?e.deps.forEach(function(t,i){t.id===a&&e.depFinished(x[a],i)}):_(r,t,i))}),i[n]=!0}function b(e){var t,i,n,a=[],r=1e3*k.waitSeconds,o=r&&F+r<(new Date).getTime();if(0===P&&(e?e.finished||_(e,{},{}):N.length&&N.forEach(function(e){_(e,{},{})})),o){for(i in M)n=M[i],n.finished||a.push(n.map.id);t=new Error("Timeout for modules: "+a),t.requireModules=a,y.onError(t)}else(P||N.length)&&(A||(A=!0,setTimeout(function(){A=!1,b()},70)))}function w(e){return setTimeout(function(){e.dynaId&&W[e.dynaId]||(W[e.dynaId]=!0,y.onError(e))}),e}var y,C,E,L,S,A,I,D,x=obj(),T=obj(),k={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},B=obj(),N=[],M=obj(),U=obj(),j=obj(),P=0,F=(new Date).getTime(),O=0,W=obj(),R=obj(),H=obj(),V=Promise.resolve();return I="function"==typeof importScripts?function(e){var t=e.url;R[t]||(R[t]=!0,h(e.id),importScripts(t),a(e.id))}:function(e){var t,i=e.id,n=e.url;R[n]||(R[n]=!0,t=document.createElement("script"),t.setAttribute("data-requiremodule",i),t.type=k.scriptType||"text/javascript",t.charset="utf-8",t.async=!0,P+=1,t.addEventListener("load",function(){P-=1,a(i)},!1),t.addEventListener("error",function(){P-=1;var e,n=getOwn(k.paths,i);if(n&&Array.isArray(n)&&n.length>1){t.parentNode.removeChild(t),n.shift();var a=h(i);a.map=E(i),a.map.url=y.nameToUrl(i),I(a.map)}else e=new Error("Load failed: "+i+": "+t.src),e.requireModules=[i],h(i).reject(e)},!1),t.src=n,10===document.documentMode?asap.then(function(){document.head.appendChild(t)}):document.head.appendChild(t))},L=function(e,t){var i,n,a=e.id,r=k.shim[a];if(a in T)i=T[a],delete T[a],C.apply(undef,i);else if(!(a in M))if(e.pr){if(!(n=getOwn(H,a)))return L(E(e.pr)).then(function(i){var n=e.prn?e:E(a,t,!0),r=n.id,o=getOwn(k.shim,r);return r in j||(j[r]=!0,o&&o.deps?y(o.deps,function(){g(i,n,t)}):g(i,n,t)),h(r).promise});e.url=y.nameToUrl(n),I(e)}else r&&r.deps?y(r.deps,function(){I(e)}):I(e);return h(a).promise},E=function(e,t,n){if("string"!=typeof e)return e;var a,r,o,s,c,d,u=e+" & "+(t||"")+" & "+!!n;return o=v(e),s=o[0],e=o[1],!s&&u in B?B[u]:(s&&(s=i(s,t,n),a=s in x&&x[s]),s?a&&a.normalize?(e=a.normalize(e,l(t)),d=!0):e=-1===e.indexOf("!")?i(e,t,n):e:(e=i(e,t,n),o=v(e),s=o[0],e=o[1],r=y.nameToUrl(e)),c={id:s?s+"!"+e:e,n:e,pr:s,url:r,prn:s&&d},s||(B[u]=c),c)},S={require:function(e){return r(e)},exports:function(e){var t=x[e];return void 0!==t?t:x[e]={}},module:function(e){return{id:e,uri:"",exports:S.exports(e),config:function(){return getOwn(k.config,e)||{}}}}},C=function(e,t,i,n,a){if(e){if(e in U)return;U[e]=!0}var r=h(e);return t&&!Array.isArray(t)&&(i=t,t=[]),t=t?slice.call(t,0):null,n||(hasProp(k,"defaultErrback")?k.defaultErrback&&(n=k.defaultErrback):n=w),n&&r.promise.catch(n),a=a||e,"function"==typeof i?(!t.length&&i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t)),r.factory=i,r.deps=t,r.depending=!0,t.forEach(function(i,n){var o;t[n]=o=E(i,a,!0),i=o.id,"require"===i?r.values[n]=S.require(e):"exports"===i?(r.values[n]=S.exports(e),r.usingExports=!0):"module"===i?r.values[n]=r.cjsModule=S.module(e):void 0===i?r.values[n]=void 0:p(o,a,r,n)}),r.depending=!1,r.depCount===r.depMax&&c(r)):e&&o(e,r,i),F=(new Date).getTime(),e||b(r),r.promise},y=r(null,!0),y.config=function(t){if(t.context&&t.context!==e){var i=getOwn(contexts,t.context);return i?i.req.config(t):newContext(t.context).config(t)}if(B=obj(),t.baseUrl&&"/"!==t.baseUrl.charAt(t.baseUrl.length-1)&&(t.baseUrl+="/"),"string"==typeof t.urlArgs){var a=t.urlArgs;t.urlArgs=function(e,t){return(-1===t.indexOf("?")?"?":"&")+a}}var r=k.shim,o={paths:!0,bundles:!0,config:!0,map:!0};return eachProp(t,function(e,t){o[t]?(k[t]||(k[t]={}),mixin(k[t],e,!0,!0)):k[t]=e}),t.bundles&&eachProp(t.bundles,function(e,t){e.forEach(function(e){e!==t&&(H[e]=t)})}),t.shim&&(eachProp(t.shim,function(e,t){Array.isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=n(e)),r[t]=e}),k.shim=r),t.packages&&t.packages.forEach(function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(k.paths[i]=e.location),k.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),(t.deps||t.callback)&&y(t.deps,t.callback),y},y.onError=function(e){throw e},D={id:e,defined:x,waiting:T,config:k,deferreds:M,req:y,execCb:function(e,t,i,n){return t.apply(n,i)}},contexts[e]=D,y}if(!Promise)throw new Error("No Promise implementation available");var topReq,dataMain,src,subPath,bootstrapConfig=requirejs||require,hasOwn=Object.prototype.hasOwnProperty,contexts={},queue=[],currDirRegExp=/^\.\//,urlRegExp=/^\/|\:|\?|\.js$/,commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,slice=Array.prototype.slice;if("function"!=typeof requirejs){var asap=Promise.resolve(void 0);requirejs=topReq=newContext("_"),"function"!=typeof require&&(require=topReq),topReq.exec=function(text){return eval(text)},topReq.contexts=contexts,define=function(){queue.push(slice.call(arguments,0))},define.amd={jQuery:!0},bootstrapConfig&&topReq.config(bootstrapConfig),topReq.isBrowser&&!contexts._.config.skipDataMain&&(dataMain=document.querySelectorAll("script[data-main]")[0],(dataMain=dataMain&&dataMain.getAttribute("data-main"))&&(dataMain=dataMain.replace(jsSuffixRegExp,""),bootstrapConfig&&bootstrapConfig.baseUrl||-1!==dataMain.indexOf("!")||(src=dataMain.split("/"),dataMain=src.pop(),subPath=src.length?src.join("/")+"/":"./",topReq.config({baseUrl:subPath})),topReq([dataMain])))}}(this,"undefined"!=typeof Promise?Promise:void 0),define("requireLib",function(){}),requirejs.config({paths:{enquire:"3rdParty/enquire",favico:"3rdParty/favico","perfect-scrollbar":"3rdParty/perfect-scrollbar",Pica:"3rdParty/pica",prism:"3rdParty/prism",zxcvbn:"3rdParty/zxcvbn"},shim:{enquire:{exports:"enquire"},favico:{exports:"Favico"},"perfect-scrollbar":{exports:"PerfectScrollbar"}},map:{"*":{Ajax:"WoltLabSuite/Core/Ajax",AjaxJsonp:"WoltLabSuite/Core/Ajax/Jsonp",AjaxRequest:"WoltLabSuite/Core/Ajax/Request",CallbackList:"WoltLabSuite/Core/CallbackList",ColorUtil:"WoltLabSuite/Core/ColorUtil",Core:"WoltLabSuite/Core/Core",DateUtil:"WoltLabSuite/Core/Date/Util",Devtools:"WoltLabSuite/Core/Devtools",Dictionary:"WoltLabSuite/Core/Dictionary","Dom/ChangeListener":"WoltLabSuite/Core/Dom/Change/Listener","Dom/Traverse":"WoltLabSuite/Core/Dom/Traverse","Dom/Util":"WoltLabSuite/Core/Dom/Util",Environment:"WoltLabSuite/Core/Environment",EventHandler:"WoltLabSuite/Core/Event/Handler",EventKey:"WoltLabSuite/Core/Event/Key",Language:"WoltLabSuite/Core/Language",List:"WoltLabSuite/Core/List",ObjectMap:"WoltLabSuite/Core/ObjectMap",Permission:"WoltLabSuite/Core/Permission",StringUtil:"WoltLabSuite/Core/StringUtil","Ui/Alignment":"WoltLabSuite/Core/Ui/Alignment","Ui/CloseOverlay":"WoltLabSuite/Core/Ui/CloseOverlay","Ui/Confirmation":"WoltLabSuite/Core/Ui/Confirmation","Ui/Dialog":"WoltLabSuite/Core/Ui/Dialog","Ui/Notification":"WoltLabSuite/Core/Ui/Notification","Ui/ReusableDropdown":"WoltLabSuite/Core/Ui/Dropdown/Reusable","Ui/Screen":"WoltLabSuite/Core/Ui/Screen","Ui/Scroll":"WoltLabSuite/Core/Ui/Scroll","Ui/SimpleDropdown":"WoltLabSuite/Core/Ui/Dropdown/Simple","Ui/TabMenu":"WoltLabSuite/Core/Ui/TabMenu",Upload:"WoltLabSuite/Core/Upload",User:"WoltLabSuite/Core/User"}},waitSeconds:0}),define("jquery",[],function(){return window.jQuery}),define("require.config",function(){}),function(e,t){e.elAttr=function(e,t,i){if(void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elAttrBool=function(e,t){var i=elAttr(e,t);return"1"===i||"true"===i},e.elByClass=function(e,i){return(i||t).getElementsByClassName(e)},e.elById=function(e){return t.getElementById(e)},e.elBySel=function(e,i){return(i||t).querySelector(e)},e.elBySelAll=function(e,i,n){var a=(i||t).querySelectorAll(e);return"function"==typeof n&&Array.prototype.forEach.call(a,n),a},e.elByTag=function(e,i){return(i||t).getElementsByTagName(e)},e.elCreate=function(e){return t.createElement(e)},e.elClosest=function(e,t){if(!(e instanceof Node))throw new TypeError("Provided element is not a Node.");return e.nodeType===Node.TEXT_NODE&&null===(e=e.parentNode)?null:("string"!=typeof t&&(t=""),0===t.length?e:e.closest(t))},e.elData=function(e,t,i){if(t="data-"+t,void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elDataBool=function(e,t){var i=elData(e,t);return"1"===i||"true"===i},e.elHide=function(e){e.style.setProperty("display","none","")},e.elIsHidden=function(e){return"none"===e.style.getPropertyValue("display")},e.elInnerError=function(e,t,i){var n=e.parentNode;if(null===n)throw new Error("Only elements that have a parent element or document are valid.");if("string"!=typeof t){if(void 0!==t&&null!==t&&!1!==t)throw new TypeError("The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.");t=""}var a=e.nextElementSibling;return null!==a&&"SMALL"===a.nodeName&&a.classList.contains("innerError")||(""===t?a=null:(a=elCreate("small"),a.className="innerError",n.insertBefore(a,e.nextSibling))),""===t?null!==a&&(n.removeChild(a),a=null):a[i?"innerHTML":"textContent"]=t,a},e.elRemove=function(e){e.parentNode.removeChild(e)},e.elShow=function(e){e.style.removeProperty("display")},e.elToggle=function(e){"none"===e.style.getPropertyValue("display")?elShow(e):elHide(e)},e.forEach=function(e,t){for(var i=0,n=e.length;i<n;i++)t(e[i],i)},e.objOwns=function(e,t){return e.hasOwnProperty(t)},e.debounce=function(e,t,i){var n;return function(){var a=this,r=arguments;clearTimeout(n),n=setTimeout(function(){n=null,i||e.apply(a,r)},t),i&&!n&&e.apply(a,r)}};"touchstart"in t.documentElement||"ontouchstart"in e||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints;Object.defineProperty(e,"WCF_CLICK_EVENT",{value:"click"}),function(){function t(){e.history.state&&e.history.state.name&&"initial"!==e.history.state.name?(e.history.replaceState({name:"skip",depth:++i},""),e.history.back(),setTimeout(t,1)):e.history.replaceState({name:"initial"},"")}var i=0;t(),e.addEventListener("popstate",function(t){t.state&&t.state.name&&"skip"===t.state.name&&e.history.go(t.state.depth)})}(),e.String.prototype.hashCode=function(){var e,t=0;if(this.length)for(var i=0,n=this.length;i<n;i++)e=this.charCodeAt(i),t=(t<<5)-t+e,t&=t;return t}}(window,document),define("wcf.globalHelper",function(){}),define("WoltLabSuite/Core/Core",[],function(){"use strict";var e=function(e){return"object"==typeof e&&(Array.isArray(e)||n.isPlainObject(e))?t(e):e},t=function(t){if(!t)return null;if(Array.isArray(t))return t.slice();var i={};for(var n in t)t.hasOwnProperty(n)&&void 0!==t[n]&&(i[n]=e(t[n]));return i},i="wsc"+window.WCF_PATH.hashCode()+"-",n={clone:function(t){return e(t)},convertLegacyUrl:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){var i=t.split(/([A-Z][a-z0-9]+)/);t="";for(var n=0,a=i.length;n<a;n++){var r=i[n].trim();r.length&&(t.length&&(t+="-"),t+=r.toLowerCase())}return"index.php?"+t+"/&"})},extend:function(e){e=e||{};for(var t=this.clone(e),i=1,n=arguments.length;i<n;i++){var a=arguments[i];if(a)for(var r in a)objOwns(a,r)&&(Array.isArray(a[r])||"object"!=typeof a[r]?t[r]=a[r]:this.isPlainObject(a[r])?t[r]=this.extend(e[r],a[r]):t[r]=a[r])}return t},inherit:function(e,t,i){if(void 0===e||null===e)throw new TypeError("The constructor must not be undefined or null.");if(void 0===t||null===t)throw new TypeError("The super constructor must not be undefined or null.");if(void 0===t.prototype)throw new TypeError("The super constructor must have a prototype.");e._super=t,e.prototype=n.extend(Object.create(t.prototype,{constructor:{configurable:!0,enumerable:!1,value:e,writable:!0}}),i||{})},isPlainObject:function(e){return"object"==typeof e&&null!==e&&!e.nodeType&&Object.getPrototypeOf(e)===Object.prototype},getType:function(e){return Object.prototype.toString.call(e).replace(/^\[object (.+)\]$/,"$1")},getUuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},serialize:function(e,t){var i=[];for(var n in e)if(objOwns(e,n)){var a=t?t+"["+n+"]":n,r=e[n];"object"==typeof r?i.push(this.serialize(r,a)):i.push(encodeURIComponent(a)+"="+encodeURIComponent(r))}return i.join("&")},triggerEvent:function(e,t){if("click"===t&&e instanceof HTMLElement)return void e.click();var i;try{i=new Event(t,{bubbles:!0,cancelable:!0})}catch(e){i=document.createEvent("Event"),i.initEvent(t,!0,!0)}e.dispatchEvent(i)},getStoragePrefix:function(){return i}};return n}),define("WoltLabSuite/Core/Dictionary",["Core"],function(e){"use strict";function t(){this._dictionary=i?new Map:{}}var i=objOwns(window,"Map")&&"function"==typeof window.Map;return t.prototype={set:function(e,t){if("number"==typeof e&&(e=e.toString()),"string"!=typeof e)throw new TypeError("Only strings can be used as keys, rejected '"+e+"' ("+typeof e+").");i?this._dictionary.set(e,t):this._dictionary[e]=t},delete:function(e){"number"==typeof e&&(e=e.toString()),i?this._dictionary.delete(e):this._dictionary[e]=void 0},has:function(e){return"number"==typeof e&&(e=e.toString()),i?this._dictionary.has(e):objOwns(this._dictionary,e)&&void 0!==this._dictionary[e]},get:function(e){if("number"==typeof e&&(e=e.toString()),this.has(e))return i?this._dictionary.get(e):this._dictionary[e]},forEach:function(e){if("function"!=typeof e)throw new TypeError("forEach() expects a callback as first parameter.");if(i)this._dictionary.forEach(e);else for(var t=Object.keys(this._dictionary),n=0,a=t.length;n<a;n++)e(this._dictionary[t[n]],t[n])},merge:function(){for(var e=0,i=arguments.length;e<i;e++){var n=arguments[e];if(!(n instanceof t))throw new TypeError("Expected an object of type Dictionary, but argument "+e+" is not.");n.forEach(function(e,t){this.set(t,e)}.bind(this))}},toObject:function(){if(!i)return e.clone(this._dictionary);var t={};return this._dictionary.forEach(function(e,i){t[i]=e}),t}},t.fromObject=function(e){var i=new t;for(var n in e)objOwns(e,n)&&i.set(n,e[n]);return i},Object.defineProperty(t.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return i?this._dictionary.size:Object.keys(this._dictionary).length}}),t}),define("WoltLabSuite/Core/Template.grammar",["require"],function(e){var t=function(e,t,i,n){for(i=i||{},n=e.length;n--;i[e[n]]=t);return i},i=[2,44],n=[5,9,11,12,13,18,19,21,22,23,25,26,28,29,30,32,33,34,35,37,39,41],a=[1,25],r=[1,27],o=[1,33],s=[1,31],l=[1,32],c=[1,28],d=[1,29],u=[1,26],h=[1,35],f=[1,41],p=[1,40],m=[11,12,15,42,43,47,49,51,52,54,55],g=[9,11,12,13,18,19,21,23,26,28,30,32,33,34,35,37,39],v=[11,12,15,42,43,46,47,48,49,51,52,54,55],_=[1,64],b=[1,65],w=[18,37,39],y=[12,15],C={trace:function(){},yy:{},symbols_:{error:2,TEMPLATE:3,CHUNK_STAR:4,EOF:5,CHUNK_STAR_repetition0:6,CHUNK:7,PLAIN_ANY:8,T_LITERAL:9,COMMAND:10,T_ANY:11,T_WS:12,"{if":13,COMMAND_PARAMETERS:14,"}":15,COMMAND_repetition0:16,COMMAND_option0:17,"{/if}":18,"{include":19,COMMAND_PARAMETER_LIST:20,"{implode":21,"{/implode}":22,"{foreach":23,COMMAND_option1:24,"{/foreach}":25,"{plural":26,PLURAL_PARAMETER_LIST:27,"{lang}":28,"{/lang}":29,"{":30,VARIABLE:31,"{#":32,"{@":33,"{ldelim}":34,"{rdelim}":35,ELSE:36,"{else}":37,ELSE_IF:38,"{elseif":39,FOREACH_ELSE:40,"{foreachelse}":41,T_VARIABLE:42,T_VARIABLE_NAME:43,VARIABLE_repetition0:44,VARIABLE_SUFFIX:45,"[":46,"]":47,".":48,"(":49,VARIABLE_SUFFIX_option0:50,")":51,"=":52,COMMAND_PARAMETER_VALUE:53,T_QUOTED_STRING:54,T_DIGITS:55,COMMAND_PARAMETERS_repetition_plus0:56,COMMAND_PARAMETER:57,T_PLURAL_PARAMETER_NAME:58,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",9:"T_LITERAL",11:"T_ANY",12:"T_WS",13:"{if",15:"}",18:"{/if}",19:"{include",21:"{implode",22:"{/implode}",23:"{foreach",25:"{/foreach}",26:"{plural",28:"{lang}",29:"{/lang}",30:"{",32:"{#",33:"{@",34:"{ldelim}",35:"{rdelim}",37:"{else}",39:"{elseif",41:"{foreachelse}",42:"T_VARIABLE",43:"T_VARIABLE_NAME",46:"[",47:"]",48:".",49:"(",51:")",52:"=",54:"T_QUOTED_STRING",55:"T_DIGITS"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[8,1],[8,1],[10,7],[10,3],[10,5],[10,6],[10,3],[10,3],[10,3],[10,3],[10,3],[10,1],[10,1],[36,2],[38,4],[40,2],[31,3],[45,3],[45,2],[45,3],[20,5],[20,3],[53,1],[53,1],[53,1],[14,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,3],[27,5],[27,3],[58,1],[58,1],[6,0],[6,2],[16,0],[16,2],[17,0],[17,1],[24,0],[24,1],[44,0],[44,2],[50,0],[50,1],[56,1],[56,2]],performAction:function(e,t,i,n,a,r,o){var s=r.length-1;switch(a){case 1:return r[s-1]+";";case 2:var l=r[s].reduce(function(e,t){return t.encode&&!e[1]?e[0]+=" + '"+t.value:t.encode&&e[1]?e[0]+=t.value:!t.encode&&e[1]?e[0]+="' + "+t.value:t.encode||e[1]||(e[0]+=" + "+t.value),e[1]=t.encode,e},["''",!1]);l[1]&&(l[0]+="'"),this.$=l[0];break;case 3:case 4:this.$={encode:!0,value:r[s].replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n")};break;case 5:this.$={encode:!1,value:r[s]};break;case 8:this.$="(function() { if ("+r[s-5]+") { return "+r[s-3]+"; } "+r[s-2].join(" ")+" "+(r[s-1]||"")+" return ''; })()";break;case 9:if(!r[s-1].file)throw new Error("Missing parameter file");this.$=r[s-1].file+".fetch(v)";break;case 10:if(!r[s-3].from)throw new Error("Missing parameter from");if(!r[s-3].item)throw new Error("Missing parameter item");r[s-3].glue||(r[s-3].glue="', '"),this.$="(function() { return "+r[s-3].from+".map(function(item) { v["+r[s-3].item+"] = item; return "+r[s-1]+"; }).join("+r[s-3].glue+"); })()";break;case 11:if(!r[s-4].from)throw new Error("Missing parameter from");if(!r[s-4].item)throw new Error("Missing parameter item");this.$="(function() {var looped = false, result = '';if ("+r[s-4].from+" instanceof Array) {for (var i = 0; i < "+r[s-4].from+".length; i++) { looped = true;v["+r[s-4].key+"] = i;v["+r[s-4].item+"] = "+r[s-4].from+"[i];result += "+r[s-2]+";}} else {for (var key in "+r[s-4].from+") {if (!"+r[s-4].from+".hasOwnProperty(key)) continue;looped = true;v["+r[s-4].key+"] = key;v["+r[s-4].item+"] = "+r[s-4].from+"[key];result += "+r[s-2]+";}}return (looped ? result : "+(r[s-1]||"''")+"); })()";break;case 12:this.$="I18nPlural.getCategoryFromTemplateParameters({";var c=!1;for(var d in r[s-1])objOwns(r[s-1],d)&&(this.$+=(c?",":"")+d+": "+r[s-1][d],c=!0);this.$+="})";break;case 13:this.$="Language.get("+r[s-1]+", v)";break;case 14:this.$="StringUtil.escapeHTML("+r[s-1]+")";break;case 15:this.$="StringUtil.formatNumeric("+r[s-1]+")";break;case 16:this.$=r[s-1];break;case 17:this.$="'{'";break;case 18:this.$="'}'";break;case 19:this.$="else { return "+r[s]+"; }";break;case 20:this.$="else if ("+r[s-2]+") { return "+r[s]+"; }";break;case 21:this.$=r[s];break;case 22:this.$="v['"+r[s-1]+"']"+r[s].join("");break;case 23:this.$=r[s-2]+r[s-1]+r[s];break;case 24:this.$="['"+r[s]+"']";break;case 25:case 39:this.$=r[s-2]+(r[s-1]||"")+r[s];break;case 26:case 40:this.$=r[s],this.$[r[s-4]]=r[s-2];break;case 27:case 41:this.$={},this.$[r[s-2]]=r[s];break;case 31:this.$=r[s].join("");break;case 44:case 46:case 52:this.$=[];break;case 45:case 47:case 53:case 57:r[s-1].push(r[s]);break;case 56:this.$=[r[s]]}},table:[t([5,9,11,12,13,19,21,23,26,28,30,32,33,34,35],i,{3:1,4:2,6:3}),{1:[3]},{5:[1,4]},t([5,18,22,25,29,37,39,41],[2,2],{7:5,8:6,10:8,9:[1,7],11:[1,9],12:[1,10],13:[1,11],19:[1,12],21:[1,13],23:[1,14],26:[1,15],28:[1,16],30:[1,17],32:[1,18],33:[1,19],34:[1,20],35:[1,21]}),{1:[2,1]},t(n,[2,45]),t(n,[2,3]),t(n,[2,4]),t(n,[2,5]),t(n,[2,6]),t(n,[2,7]),{11:a,12:r,14:22,31:30,42:o,43:s,49:l,52:c,54:d,55:u,56:23,57:24},{20:34,43:h},{20:36,43:h},{20:37,43:h},{27:38,43:f,55:p,58:39},t([9,11,12,13,19,21,23,26,28,29,30,32,33,34,35],i,{6:3,4:42}),{31:43,42:o},{31:44,42:o},{31:45,42:o},t(n,[2,17]),t(n,[2,18]),{15:[1,46]},t([15,47,51],[2,31],{31:30,57:47,11:a,12:r,42:o,43:s,49:l,52:c,54:d,55:u}),t(m,[2,56]),t(m,[2,32]),t(m,[2,33]),t(m,[2,34]),t(m,[2,35]),t(m,[2,36]),t(m,[2,37]),t(m,[2,38]),{11:a,12:r,14:48,31:30,42:o,43:s,49:l,52:c,54:d,55:u,56:23,57:24},{43:[1,49]},{15:[1,50]},{52:[1,51]},{15:[1,52]},{15:[1,53]},{15:[1,54]},{52:[1,55]},{52:[2,42]},{52:[2,43]},{29:[1,56]},{15:[1,57]},{15:[1,58]},{15:[1,59]},t(g,i,{6:3,4:60}),t(m,[2,57]),{51:[1,61]},t(v,[2,52],{44:62}),t(n,[2,9]),{31:66,42:o,53:63,54:_,55:b},t([9,11,12,13,19,21,22,23,26,28,30,32,33,34,35],i,{6:3,4:67}),t([9,11,12,13,19,21,23,25,26,28,30,32,33,34,35,41],i,{6:3,4:68}),t(n,[2,12]),{31:66,42:o,53:69,54:_,55:b},t(n,[2,13]),t(n,[2,14]),t(n,[2,15]),t(n,[2,16]),t(w,[2,46],{16:70}),t(m,[2,39]),t([11,12,15,42,43,47,51,52,54,55],[2,22],{45:71,46:[1,72],48:[1,73],49:[1,74]}),{12:[1,75],15:[2,27]},t(y,[2,28]),t(y,[2,29]),t(y,[2,30]),{22:[1,76]},{24:77,25:[2,50],40:78,41:[1,79]},{12:[1,80],15:[2,41]},{17:81,18:[2,48],36:83,37:[1,85],38:82,39:[1,84]},t(v,[2,53]),{11:a,12:r,14:86,31:30,42:o,43:s,49:l,52:c,54:d,55:u,56:23,57:24},{43:[1,87]},{11:a,12:r,14:89,31:30,42:o,43:s,49:l,50:88,51:[2,54],52:c,54:d,55:u,56:23,57:24},{20:90,43:h},t(n,[2,10]),{25:[1,91]},{25:[2,51]},t([9,11,12,13,19,21,23,25,26,28,30,32,33,34,35],i,{6:3,4:92}),{27:93,43:f,55:p,58:39},{18:[1,94]},t(w,[2,47]),{18:[2,49]},{11:a,12:r,14:95,31:30,42:o,43:s,49:l,52:c,54:d,55:u,56:23,57:24},t([9,11,12,13,18,19,21,23,26,28,30,32,33,34,35],i,{6:3,4:96}),{47:[1,97]},t(v,[2,24]),{51:[1,98]},{51:[2,55]},{15:[2,26]},t(n,[2,11]),{25:[2,21]},{15:[2,40]},t(n,[2,8]),{15:[1,99]},{18:[2,19]},t(v,[2,23]),t(v,[2,25]),t(g,i,{6:3,4:100}),t(w,[2,20])],defaultActions:{4:[2,1],40:[2,42],41:[2,43],78:[2,51],83:[2,49],89:[2,55],90:[2,26],92:[2,21],93:[2,40],96:[2,19]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=this,i=[0],n=[null],a=[],r=this.table,o="",s=0,l=0,c=0,d=a.slice.call(arguments,1),u=Object.create(this.lexer),h={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(h.yy[f]=this.yy[f]);u.setInput(e,h.yy),h.yy.lexer=u,h.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var p=u.yylloc;a.push(p);var m=u.options&&u.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,v,_,b,w,y,C,E,L,S=function(){var e;return e=u.lex()||1,"number"!=typeof e&&(e=t.symbols_[e]||e),e},A={};;){if(_=i[i.length-1],this.defaultActions[_]?b=this.defaultActions[_]:(null!==g&&void 0!==g||(g=S()),b=r[_]&&r[_][g]),void 0===b||!b.length||!b[0]){var I="";L=[];for(y in r[_])this.terminals_[y]&&y>2&&L.push("'"+this.terminals_[y]+"'");I=u.showPosition?"Parse error on line "+(s+1)+":\n"+u.showPosition()+"\nExpecting "+L.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(s+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(I,{text:u.match,token:this.terminals_[g]||g,line:u.yylineno,loc:p,expected:L})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(b[0]){case 1:i.push(g),n.push(u.yytext),a.push(u.yylloc),i.push(b[1]),g=null,v?(g=v,v=null):(l=u.yyleng,o=u.yytext,s=u.yylineno,p=u.yylloc,c>0&&c--);break;case 2:if(C=this.productions_[b[1]][1],A.$=n[n.length-C],A._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},m&&(A._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(w=this.performAction.apply(A,[o,l,s,h.yy,b[1],n,a].concat(d))))return w;C&&(i=i.slice(0,-1*C*2),n=n.slice(0,-1*C),a=a.slice(0,-1*C)),i.push(this.productions_[b[1]][0]),n.push(A.$),a.push(A._$),E=r[i[i.length-2]][i[i.length-1]],i.push(E);break;case 3:return!0}}return!0}},E=function(){return{EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,n,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),n=e[0].match(/(?:\r\n?|\n).*/g),n&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,
+this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in a)this[r]=a[r];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var e,t,i,n;this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),r=0;r<a.length;r++)if((i=this._input.match(this.rules[a[r]]))&&(!t||i[0].length>t[0].length)){if(t=i,n=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,a[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,a[n]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return e=this.conditionStack.length-1-Math.abs(e||0),e>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,i,n){switch(i){case 0:break;case 1:return t.yytext=t.yytext.substring(9,t.yytext.length-10),9;case 2:case 3:return 54;case 4:return 42;case 5:return 55;case 6:return 43;case 7:return 48;case 8:return 46;case 9:return 47;case 10:return 49;case 11:return 51;case 12:return 52;case 13:return 34;case 14:return 35;case 15:return this.begin("command"),32;case 16:return this.begin("command"),33;case 17:return this.begin("command"),13;case 18:case 19:return this.begin("command"),39;case 20:return 37;case 21:return 18;case 22:return 28;case 23:return 29;case 24:return this.begin("command"),19;case 25:return this.begin("command"),21;case 26:return this.begin("command"),26;case 27:return 22;case 28:return this.begin("command"),23;case 29:return 41;case 30:return 25;case 31:return this.begin("command"),30;case 32:return this.popState(),15;case 33:return 12;case 34:return 5;case 35:return 11}},rules:[/^(?:\{\*[\s\S]*?\*\})/,/^(?:\{literal\}[\s\S]*?\{\/literal\})/,/^(?:"([^"]|\\\.)*")/,/^(?:'([^']|\\\.)*')/,/^(?:\$)/,/^(?:[0-9]+)/,/^(?:[_a-zA-Z][_a-zA-Z0-9]*)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:=)/,/^(?:\{ldelim\})/,/^(?:\{rdelim\})/,/^(?:\{#)/,/^(?:\{@)/,/^(?:\{if )/,/^(?:\{else if )/,/^(?:\{elseif )/,/^(?:\{else\})/,/^(?:\{\/if\})/,/^(?:\{lang\})/,/^(?:\{\/lang\})/,/^(?:\{include )/,/^(?:\{implode )/,/^(?:\{plural )/,/^(?:\{\/implode\})/,/^(?:\{foreach )/,/^(?:\{foreachelse\})/,/^(?:\{\/foreach\})/,/^(?:\{(?!\s))/,/^(?:\})/,/^(?:\s+)/,/^(?:$)/,/^(?:[^{])/],conditions:{command:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],inclusive:!0},INITIAL:{rules:[0,1,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35],inclusive:!0}}}}();return C.lexer=E,C}),define("WoltLabSuite/Core/NumberUtil",[],function(){"use strict";return{round:function(e,t){return void 0===t||0==+t?Math.round(e):(e=+e,t=+t,isNaN(e)||"number"!=typeof t||t%1!=0?NaN:(e=e.toString().split("e"),e=Math.round(+(e[0]+"e"+(e[1]?+e[1]-t:-t))),e=e.toString().split("e"),+(e[0]+"e"+(e[1]?+e[1]+t:t))))}}}),define("WoltLabSuite/Core/StringUtil",["Language","./NumberUtil"],function(e,t){"use strict";return{addThousandsSeparator:function(t){return void 0===e&&(e=require("Language")),String(t).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+e.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(i,n){void 0===e&&(e=require("Language")),i=String(t.round(i,n||-2));var a=i.split(".");return i=this.addThousandsSeparator(a[0]),a.length>1&&(i+=e.get("wcf.global.decimalPoint")+a[1]),i=i.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")},shortUnit:function(e){var i="";return e>=1e6?(e/=1e6,e=e>10?Math.floor(e):t.round(e,-1),i="M"):e>=1e3&&(e/=1e3,e=e>10?Math.floor(e):t.round(e,-1),i="k"),this.formatNumeric(e)+i}}}),define("WoltLabSuite/Core/I18n/Plural",["StringUtil"],function(e){"use strict";return{getCategory:function(e,t){t||(t=document.documentElement.lang),"function"!=typeof this[t]&&(t="en");var i=this[t](e);return i||"other"},getCategoryFromTemplateParameters:function(t){if(!t.value)throw new Error("Missing parameter value");if(!t.other)throw new Error("Missing parameter other");var i=t.value;Array.isArray(i)&&(i=i.length);for(var n in t)if(objOwns(t,n)&&n==~~n&&n==i)return t[n];var a=this.getCategory(i);t[a]||(a="other");var r=t[a];return-1!==r.indexOf("#")?r.replace("#",e.formatNumeric(i)):r},getF:function(e){e=e.toString();var t=e.indexOf(".");return-1===t?0:parseInt(e.substr(t+1),10)},getV:function(e){return e.toString().replace(/^[^.]*\.?/,"").length},af:function(e){if(1==e)return"one"},am:function(e){var t=Math.floor(Math.abs(e));if(1==e||0===t)return"one"},ar:function(e){if(0==e)return"zero";if(1==e)return"one";if(2==e)return"two";var t=e%100;return t>=3&&t<=10?"few":t>=11&&t<=99?"many":void 0},as:function(e){var t=Math.floor(Math.abs(e));if(1==e||0===t)return"one"},az:function(e){if(1==e)return"one"},be:function(e){var t=e%10,i=e%100;return 1==t&&11!=i?"one":t>=2&&t<=4&&!(i>=12&&i<=14)?"few":0==t||t>=5&&t<=9||i>=11&&i<=14?"many":void 0},bg:function(e){if(1==e)return"one"},bn:function(e){var t=Math.floor(Math.abs(e));if(1==e||0===t)return"one"},bo:function(e){},bs:function(e){var t=this.getV(e),i=this.getF(e),n=e%10,a=e%100,r=i%10,o=i%100;return 0==t&&1==n&&11!=a||1==r&&11!=o?"one":0==t&&n>=2&&n<=4&&a>=12&&a<=14||r>=2&&r<=4&&o>=12&&o<=14?"few":void 0},cs:function(e){var t=this.getV(e);return 1==e&&0===t?"one":e>=2&&e<=4&&0===t?"few":0===t?"many":void 0},cy:function(e){return 0==e?"zero":1==e?"one":2==e?"two":3==e?"few":6==e?"many":void 0},da:function(e){if(e>0&&e<2)return"one"},el:function(e){if(1==e)return"one"},en:function(e){if(1==e&&0===this.getV(e))return"one"},es:function(e){if(1==e)return"one"},eu:function(e){if(1==e)return"one"},fa:function(e){if(e>=0&&e<=1)return"one"},fr:function(e){if(e>=0&&e<2)return"one"},ga:function(e){return 1==e?"one":2==e?"two":3==e||4==e||5==e||6==e?"few":7==e||8==e||9==e||10==e?"many":void 0},gu:function(e){if(e>=0&&e<=1)return"one"},he:function(e){var t=this.getV(e);return 1==e&&0===t?"one":2==e&&0===t?"two":e>10&&0===t&&e%10==0?"many":void 0},hi:function(e){if(e>=0&&e<=1)return"one"},hr:function(e){return this.bs(e)},hu:function(e){if(1==e)return"one"},hy:function(e){if(e>=0&&e<2)return"one"},id:function(e){},is:function(e){var t=this.getF(e);if(0===t&&e%10==1&&e%100!=11||0!==t)return"one"},ja:function(e){},jv:function(e){},ka:function(e){if(1==e)return"one"},kk:function(e){if(1==e)return"one"},km:function(e){},kn:function(e){if(e>=0&&e<=1)return"one"},ko:function(e){},ku:function(e){if(1==e)return"one"},ky:function(e){if(1==e)return"one"},lb:function(e){if(1==e)return"one"},lo:function(e){},lt:function(e){var t=e%10,i=e%100;return 1!=t||i>=11&&i<=19?t>=2&&t<=9&&!(i>=11&&i<=19)?"few":0!=this.getF(e)?"many":void 0:"one"},lv:function(e){var t=e%10,i=e%100,n=this.getV(e),a=this.getF(e),r=a%10,o=a%100;return 0==t||i>=11&&i<=19||2==n&&o>=11&&o<=19?"zero":1==t&&11!=i||2==n&&1==r&&11!=o||2!=n&&1==r?"one":void 0},mk:function(e){var t=this.getV(e),i=this.getF(e),n=e%10,a=e%100,r=i%10,o=i%100;if(0==t&&1==n&&11!=a||1==r&&11!=o)return"one"},ml:function(e){if(1==e)return"one"},mn:function(e){if(1==e)return"one"},mr:function(e){if(1==e)return"one"},ms:function(e){},mt:function(e){var t=e%100;return 1==e?"one":0==e||t>=2&&t<=10?"few":t>=11&&t<=19?"many":void 0},my:function(e){},no:function(e){if(1==e)return"one"},ne:function(e){if(1==e)return"one"},or:function(e){if(1==e)return"one"},pa:function(e){if(1==e||0==e)return"one"},pl:function(e){var t=this.getV(e),i=e%10,n=e%100;return 1==e&&0==t?"one":0==t&&i>=2&&i<=4&&!(n>=12&&n<=14)?"few":0==t&&(1!=e&&i>=0&&i<=1||i>=5&&i<=9||n>=12&&n<=14)?"many":void 0},ps:function(e){if(1==e)return"one"},pt:function(e){if(e>=0&&e<2)return"one"},ro:function(e){var t=this.getV(e),i=e%100;return 1==e&&0===t?"one":0!=t||0==e||i>=2&&i<=19?"few":void 0},ru:function(e){var t=e%10,i=e%100;if(0==this.getV(e)){if(1==t&&11!=i)return"one";if(t>=2&&t<=4&&!(i>=12&&i<=14))return"few";if(0==t||t>=5&&t<=9||i>=11&&i<=14)return"many"}},sd:function(e){if(1==e)return"one"},si:function(e){if(0==e||1==e||0==Math.floor(e)&&1==this.getF(e))return"one"},sk:function(e){return this.cs(e)},sl:function(e){var t=this.getV(e),i=e%100;return 0==t&&1==i?"one":0==t&&2==i?"two":0==t&&(3==i||4==i)||0!=t?"few":void 0},sq:function(e){if(1==e)return"one"},sr:function(e){return this.bs(e)},ta:function(e){if(1==e)return"one"},te:function(e){if(1==e)return"one"},tg:function(e){},th:function(e){},tk:function(e){if(1==e)return"one"},tr:function(e){if(1==e)return"one"},ug:function(e){if(1==e)return"one"},uk:function(e){return this.ru(e)},uz:function(e){if(1==e)return"one"},vi:function(e){},zh:function(e){}}}),define("WoltLabSuite/Core/Template",["./Template.grammar","./StringUtil","Language","WoltLabSuite/Core/I18n/Plural"],function(e,t,i,n){"use strict";function a(){this.yy={}}function r(a){void 0===i&&(i=require("Language")),void 0===t&&(t=require("StringUtil"));try{a=e.parse(a),a="var tmp = {};\nfor (var key in v) tmp[key] = v[key];\nv = tmp;\nv.__wcf = window.WCF; v.__window = window;\nreturn "+a,this.fetch=new Function("StringUtil","Language","I18nPlural","v",a).bind(void 0,t,i,n)}catch(e){throw console.debug(e.message),e}}return a.prototype=e,e.Parser=a,e=new a,Object.defineProperty(r,"callbacks",{enumerable:!1,configurable:!1,get:function(){throw new Error("WCF.Template.callbacks is no longer supported")},set:function(e){throw new Error("WCF.Template.callbacks is no longer supported")}}),r.prototype={fetch:function(e){throw new Error("This Template is not initialized.")}},r}),define("WoltLabSuite/Core/Language",["Dictionary","./Template"],function(e,t){"use strict";var i=new e;return{addObject:function(t){i.merge(e.fromObject(t))},add:function(e,t){i.set(e,t)},get:function(e,n){n||(n={});var a=i.get(e);if(void 0===a)return e;if(void 0===t&&(t=require("WoltLabSuite/Core/Template")),"string"==typeof a){try{i.set(e,new t(a))}catch(n){i.set(e,new t("{literal}"+a.replace(/\{\/literal\}/g,"{/literal}{ldelim}/literal}{literal}")+"{/literal}"))}a=i.get(e)}return a instanceof t&&(a=a.fetch(n)),a}}}),define("WoltLabSuite/Core/CallbackList",["Dictionary"],function(e){"use strict";function t(){this._dictionary=new e}return t.prototype={add:function(e,t){if("function"!=typeof t)throw new TypeError("Expected a valid callback as second argument for identifier '"+e+"'.");this._dictionary.has(e)||this._dictionary.set(e,[]),this._dictionary.get(e).push(t)},remove:function(e){this._dictionary.delete(e)},forEach:function(e,t){if(null===e)this._dictionary.forEach(function(e,i){e.forEach(t)});else{var i=this._dictionary.get(e);void 0!==i&&i.forEach(t)}}},t}),define("WoltLabSuite/Core/Dom/Change/Listener",["CallbackList"],function(e){"use strict";var t=new e,i=!1;return{add:t.add.bind(t),remove:t.remove.bind(t),trigger:function(){if(!i)try{i=!0,t.forEach(null,function(e){e()})}finally{i=!1}}}}),define("WoltLabSuite/Core/Environment",[],function(){"use strict";var e="other",t="none",i="desktop",n=!1;return{setup:function(){if("object"==typeof window.chrome)e="chrome";else for(var a=window.getComputedStyle(document.documentElement),r=0,o=a.length;r<o;r++){var s=a[r];0===s.indexOf("-ms-")?e="microsoft":0===s.indexOf("-moz-")?e="firefox":"firefox"!==e&&0===s.indexOf("-webkit-")&&(e="safari")}var l=window.navigator.userAgent.toLowerCase();-1!==l.indexOf("crios")?(e="chrome",i="ios"):/(?:iphone|ipad|ipod)/.test(l)?(e="safari",i="ios"):-1!==l.indexOf("android")?i="android":-1!==l.indexOf("iemobile")&&(e="microsoft",i="windows"),"desktop"!==i||-1===l.indexOf("mobile")&&-1===l.indexOf("tablet")||(i="mobile"),t="redactor",n=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&window.navigator.msMaxTouchPoints>0||window.DocumentTouch&&document instanceof DocumentTouch,"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1&&(e="safari",i="ios")},browser:function(){return e},editor:function(){return t},platform:function(){return i},touch:function(){return n}}}),define("WoltLabSuite/Core/Dom/Util",["Environment","StringUtil"],function(e,t){"use strict";function i(e,t,i){if(!t.contains(e))throw new Error("Ancestor element does not contain target element.");for(var n,a=i+"Sibling";null!==e&&e!==t;){if(null!==e[i+"ElementSibling"])return!1;if(e[a])for(n=e[a];n;){if(""!==n.textContent.trim())return!1;n=n[a]}e=e.parentNode}return!0}var n=0,a={createFragmentFromHtml:function(e){var t=elCreate("div");this.setInnerHtml(t,e);for(var i=document.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return i},getUniqueId:function(){var e;do{e="wcf"+n++}while(null!==elById(e));return e},identify:function(e){if(!(e instanceof Element))throw new TypeError("Expected a valid DOM element as argument.");var t=elAttr(e,"id");return t||(t=this.getUniqueId(),elAttr(e,"id",t)),t},outerHeight:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetHeight;return i+=~~t.marginTop+~~t.marginBottom},outerWidth:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetWidth;return i+=~~t.marginLeft+~~t.marginRight},outerDimensions:function(e){var t=window.getComputedStyle(e);return{height:this.outerHeight(e,t),width:this.outerWidth(e,t)}},offset:function(e){var t=e.getBoundingClientRect();return{top:Math.round(t.top+(window.scrollY||window.pageYOffset)),left:Math.round(t.left+(window.scrollX||window.pageXOffset))}},prepend:function(e,t){0===t.childNodes.length?t.appendChild(e):t.insertBefore(e,t.childNodes[0])},insertAfter:function(e,t){null!==t.nextSibling?t.parentNode.insertBefore(e,t.nextSibling):t.parentNode.appendChild(e)},setStyles:function(e,t){var i=!1;for(var n in t)t.hasOwnProperty(n)&&(/ !important$/.test(t[n])?(i=!0,t[n]=t[n].replace(/ !important$/,"")):i=!1,"important"!==e.style.getPropertyPriority(n)||i||e.style.removeProperty(n),e.style.setProperty(n,t[n],i?"important":""))},styleAsInt:function(e,t){var i=e.getPropertyValue(t);return null===i?0:parseInt(i)},setInnerHtml:function(e,t){e.innerHTML=t;for(var i,n,a=elBySelAll("script",e),r=0,o=a.length;r<o;r++)n=a[r],i=elCreate("script"),n.src?i.src=n.src:i.textContent=n.textContent,e.appendChild(i),elRemove(n)},insertHtml:function(e,t,i){var n=elCreate("div");if(this.setInnerHtml(n,e),n.childNodes.length){var a=n.childNodes[0];switch(i){case"append":t.appendChild(a);break;case"after":this.insertAfter(a,t);break;case"prepend":this.prepend(a,t);break;case"before":t.parentNode.insertBefore(a,t);break;default:throw new Error("Unknown insert method '"+i+"'.")}for(var r;n.childNodes.length;)r=n.childNodes[0],this.insertAfter(r,a),a=r}},contains:function(e,t){for(;null!==t;)if(t=t.parentNode,e===t)return!0;return!1},getDataAttributes:function(e,i,n,a){i=i||"",/^data-/.test(i)||(i="data-"+i),n=!0===n,a=!0===a;for(var r,o,s,l={},c=0,d=e.attributes.length;c<d;c++)if(r=e.attributes[c],0===r.name.indexOf(i)){if(o=r.name.replace(new RegExp("^"+i),""),n){s=o.split("-"),o="";for(var u=0,h=s.length;u<h;u++)o.length&&(a&&"id"===s[u]?s[u]="ID":s[u]=t.ucfirst(s[u])),o+=s[u]}l[o]=r.value}return l},unwrapChildNodes:function(e){for(var t=e.parentNode;e.childNodes.length;)t.insertBefore(e.childNodes[0],e);elRemove(e)},replaceElement:function(e,t){for(;e.childNodes.length;)t.appendChild(e.childNodes[0]);e.parentNode.insertBefore(t,e),elRemove(e)},isAtNodeStart:function(e,t){return i(e,t,"previous")},isAtNodeEnd:function(e,t){return i(e,t,"next")},getFixedParent:function(e){for(;e&&e!==document.body;){if("fixed"===window.getComputedStyle(e).getPropertyValue("position"))return e;e=e.offsetParent}return null}};return window.bc_wcfDomUtil=a,a}),define("WoltLabSuite/Core/ObjectMap",[],function(){"use strict";function e(){this._map=t?new WeakMap:{key:[],value:[]}}var t=objOwns(window,"WeakMap")&&"function"==typeof window.WeakMap;return e.prototype={set:function(e,i){if("object"!=typeof e||null===e)throw new TypeError("Only objects can be used as key");if("object"!=typeof i||null===i)throw new TypeError("Only objects can be used as value");t?this._map.set(e,i):(this._map.key.push(e),this._map.value.push(i))},delete:function(e){if(t)this._map.delete(e);else{var i=this._map.key.indexOf(e);this._map.key.splice(i),this._map.value.splice(i)}},has:function(e){return t?this._map.has(e):-1!==this._map.key.indexOf(e)},get:function(e){if(t)return this._map.get(e);var i=this._map.key.indexOf(e);return-1!==i?this._map.value[i]:void 0}},e}),define("WoltLabSuite/Core/Dom/Traverse",[],function(){"use strict";var e=[function(e,t){return!0},function(e,t){return e.matches(t)},function(e,t){return e.classList.contains(t)},function(e,t){return e.nodeName===t}],t=function(t,i,n){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(var a=[],r=0;r<t.childElementCount;r++)e[i](t.children[r],n)&&a.push(t.children[r]);return a},i=function(t,i,n,a){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(t=t.parentNode;t instanceof Element;){if(t===a)return null;if(e[i](t,n))return t;t=t.parentNode}return null},n=function(t,i,n,a){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");return t instanceof Element&&null!==t[i]&&e[n](t[i],a)?t[i]:null};return{childBySel:function(e,i){return t(e,1,i)[0]||null},childByClass:function(e,i){return t(e,2,i)[0]||null},childByTag:function(e,i){return t(e,3,i)[0]||null},childrenBySel:function(e,i){return t(e,1,i)},childrenByClass:function(e,i){return t(e,2,i)},childrenByTag:function(e,i){return t(e,3,i)},parentBySel:function(e,t,n){return i(e,1,t,n)},parentByClass:function(e,t,n){return i(e,2,t,n)},parentByTag:function(e,t,n){return i(e,3,t,n)},next:function(e){return n(e,"nextElementSibling",0,null)},nextBySel:function(e,t){return n(e,"nextElementSibling",1,t)},nextByClass:function(e,t){return n(e,"nextElementSibling",2,t)},nextByTag:function(e,t){return n(e,"nextElementSibling",3,t)},prev:function(e){return n(e,"previousElementSibling",0,null)},prevBySel:function(e,t){return n(e,"previousElementSibling",1,t)},prevByClass:function(e,t){return n(e,"previousElementSibling",2,t)},prevByTag:function(e,t){return n(e,"previousElementSibling",3,t)}}}),define("WoltLabSuite/Core/Ui/Confirmation",["Core","Language","Ui/Dialog"],function(e,t,i){"use strict";var n=!1,a=null,r=null,o={},s=null;return{show:function(t){if(void 0===i&&(i=require("Ui/Dialog")),!n){if(o=e.extend({cancel:null,confirm:null,legacyCallback:null,message:"",messageIsHtml:!1,parameters:{},template:""},t),o.message="string"==typeof o.message?o.message.trim():"",!o.message.length)throw new Error("Expected a non-empty string for option 'message'.");if("function"!=typeof o.confirm&&"function"!=typeof o.legacyCallback)throw new TypeError("Expected a valid callback for option 'confirm'.");null===r&&this._createDialog(),r.innerHTML="string"==typeof o.template?o.template.trim():"",o.messageIsHtml?s.innerHTML=o.message:s.textContent=o.message,n=!0,i.open(this)}},_dialogSetup:function(){return{id:"wcfSystemConfirmation",options:{onClose:this._onClose.bind(this),onShow:this._onShow.bind(this),title:t.get("wcf.global.confirmation.title")}}},getContentElement:function(){return r},_createDialog:function(){var e=elCreate("div");elAttr(e,"id","wcfSystemConfirmation"),e.classList.add("systemConfirmation"),s=elCreate("p"),e.appendChild(s),r=elCreate("div"),elAttr(r,"id","wcfSystemConfirmationContent"),e.appendChild(r);var n=elCreate("div");n.classList.add("formSubmit"),e.appendChild(n),a=elCreate("button"),a.dataset.type="submit",a.classList.add("buttonPrimary"),a.textContent=t.get("wcf.global.confirmation.confirm"),n.appendChild(a);var o=elCreate("button");o.textContent=t.get("wcf.global.confirmation.cancel"),o.addEventListener(WCF_CLICK_EVENT,function(){i.close("wcfSystemConfirmation")}),n.appendChild(o),document.body.appendChild(e)},_confirm:function(){"function"==typeof o.legacyCallback?o.legacyCallback("confirm",o.parameters,r):o.confirm(o.parameters,r),n=!1,i.close("wcfSystemConfirmation")},_onClose:function(){n&&(a.blur(),n=!1,"function"==typeof o.legacyCallback?o.legacyCallback("cancel",o.parameters,r):"function"==typeof o.cancel&&o.cancel(o.parameters))},_onShow:function(){a.blur(),a.focus()},_dialogSubmit:function(){this._confirm()}}}),define("WoltLabSuite/Core/Ui/Screen",["Core","Dictionary","Environment"],function(e,t,i){"use strict";var n=null,a=new t,r=0,o=null,s=0,l=0,c=t.fromObject({"screen-xs":"(max-width: 544px)","screen-sm":"(min-width: 545px) and (max-width: 768px)","screen-sm-down":"(max-width: 768px)","screen-sm-up":"(min-width: 545px)","screen-sm-md":"(min-width: 545px) and (max-width: 1024px)","screen-md":"(min-width: 769px) and (max-width: 1024px)","screen-md-down":"(max-width: 1024px)","screen-md-up":"(min-width: 769px)","screen-lg":"(min-width: 1025px)","screen-lg-only":"(min-width: 1025px) and (max-width: 1280px)","screen-lg-down":"(max-width: 1280px)","screen-xl":"(min-width: 1281px)"}),d=new t;return{on:function(t,i){var n=e.getUuid(),a=this._getQueryObject(t);return"function"==typeof i.match&&a.callbacksMatch.set(n,i.match),"function"==typeof i.unmatch&&a.callbacksUnmatch.set(n,i.unmatch),"function"==typeof i.setup&&(a.mql.matches?i.setup():a.callbacksSetup.set(n,i.setup)),n},remove:function(e,t){var i=this._getQueryObject(e);i.callbacksMatch.delete(t),i.callbacksUnmatch.delete(t),i.callbacksSetup.delete(t)},is:function(e){return this._getQueryObject(e).mql.matches},scrollDisable:function(){if(0===r){s=document.body.scrollTop,o="body",s||(s=document.documentElement.scrollTop,o="documentElement");var e=elById("pageContainer");"ios"===i.platform()?(e.style.setProperty("position","relative",""),e.style.setProperty("top","-"+s+"px","")):e.style.setProperty("margin-top","-"+s+"px",""),document.documentElement.classList.add("disableScrolling")}r++},scrollEnable:function(){if(r&&0===--r){document.documentElement.classList.remove("disableScrolling");var e=elById("pageContainer");"ios"===i.platform()?(e.style.removeProperty("position"),e.style.removeProperty("top")):e.style.removeProperty("margin-top"),s&&(document[o].scrollTop=~~s)}},pageOverlayOpen:function(){0===l&&document.documentElement.classList.add("pageOverlayActive"),l++},pageOverlayClose:function(){l&&0===--l&&document.documentElement.classList.remove("pageOverlayActive")},pageOverlayIsActive:function(){return l>0},setDialogContainer:function(e){n=e},_getQueryObject:function(e){if("string"!=typeof e||""===e.trim())throw new TypeError("Expected a non-empty string for parameter 'query'.");d.has(e)&&(e=d.get(e)),c.has(e)&&(e=c.get(e));var i=a.get(e);return i||(i={callbacksMatch:new t,callbacksUnmatch:new t,callbacksSetup:new t,mql:window.matchMedia(e)},i.mql.addListener(this._mqlChange.bind(this)),a.set(e,i),e!==i.mql.media&&d.set(i.mql.media,e)),i},_mqlChange:function(e){var i=this._getQueryObject(e.media);if(e.matches)i.callbacksSetup.size?(i.callbacksSetup.forEach(function(e){e()}),i.callbacksSetup=new t):i.callbacksMatch.forEach(function(e){e()});else{if(i.callbacksSetup.size)return;i.callbacksUnmatch.forEach(function(e){e()})}}}}),define("WoltLabSuite/Core/Event/Key",[],function(){"use strict";function e(e,t,i){if(!(e instanceof Event))throw new TypeError("Expected a valid event when testing for key '"+t+"'.");return e.key===t||e.which===i}return{ArrowDown:function(t){return e(t,"ArrowDown",40)},ArrowLeft:function(t){return e(t,"ArrowLeft",37)},ArrowRight:function(t){return e(t,"ArrowRight",39)},ArrowUp:function(t){return e(t,"ArrowUp",38)},Comma:function(t){return e(t,",",44)},End:function(t){return e(t,"End",35)},Enter:function(t){return e(t,"Enter",13)},Escape:function(t){return e(t,"Escape",27)},Home:function(t){return e(t,"Home",36)},Space:function(t){return e(t,"Space",32)},Tab:function(t){return e(t,"Tab",9)}}}),define("WoltLabSuite/Core/Ui/Alignment",["Core","Language","Dom/Traverse","Dom/Util"],function(e,t,i,n){"use strict";return{set:function(a,r,o){o=e.extend({verticalOffset:0,pointer:!1,pointerClassNames:[],refDimensionsElement:null,horizontal:"left",vertical:"bottom",allowFlip:"both"},o),Array.isArray(o.pointerClassNames)&&o.pointerClassNames.length===(o.pointer?1:2)||(o.pointerClassNames=[]),-1===["left","right","center"].indexOf(o.horizontal)&&(o.horizontal="left"),"bottom"!==o.vertical&&(o.vertical="top"),-1===["both","horizontal","vertical","none"].indexOf(o.allowFlip)&&(o.allowFlip="both"),n.setStyles(a,{bottom:"auto !important",left:"0 !important",right:"auto !important",top:"0 !important",visibility:"hidden !important"});var s=n.outerDimensions(a),l=n.outerDimensions(o.refDimensionsElement instanceof Element?o.refDimensionsElement:r),c=n.offset(r),d=window.innerHeight,u=document.body.clientWidth,h={result:null},f=!1;if("center"===o.horizontal&&(f=!0,h=this._tryAlignmentHorizontal(o.horizontal,s,l,c,u),h.result||("both"===o.allowFlip||"horizontal"===o.allowFlip?o.horizontal="left":h.result=!0)),"rtl"===t.get("wcf.global.pageDirection")&&(o.horizontal="left"===o.horizontal?"right":"left"),!h.result){var p=h;if(h=this._tryAlignmentHorizontal(o.horizontal,s,l,c,u),!h.result&&("both"===o.allowFlip||"horizontal"===o.allowFlip)){var m=this._tryAlignmentHorizontal("left"===o.horizontal?"right":"left",s,l,c,u);m.result?h=m:f&&(h=p)}}var g=h.left,v=h.right,_=this._tryAlignmentVertical(o.vertical,s,l,c,d,o.verticalOffset);if(!_.result&&("both"===o.allowFlip||"vertical"===o.allowFlip)){var b=this._tryAlignmentVertical("top"===o.vertical?"bottom":"top",s,l,c,d,o.verticalOffset);b.result&&(_=b)}var w=_.bottom,y=_.top;if(o.pointer){var C=i.childrenByClass(a,"elementPointer");if(null===(C=C[0]||null))throw new Error("Expected the .elementPointer element to be a direct children.");"center"===h.align?(C.classList.add("center"),C.classList.remove("left"),C.classList.remove("right")):(C.classList.add(h.align),C.classList.remove("center"),C.classList.remove("left"===h.align?"right":"left")),"top"===_.align?C.classList.add("flipVertical"):C.classList.remove("flipVertical")}else if(2===o.pointerClassNames.length){a.classList["auto"===y?"add":"remove"](o.pointerClassNames[0]),a.classList["auto"===g?"add":"remove"](o.pointerClassNames[1])}"auto"!==w&&(w=Math.round(w)+"px"),"auto"!==g&&(g=Math.ceil(g)+"px"),"auto"!==v&&(v=Math.floor(v)+"px"),"auto"!==y&&(y=Math.round(y)+"px"),n.setStyles(a,{bottom:w,left:g,right:v,top:y}),elShow(a),a.style.removeProperty("visibility")},_tryAlignmentHorizontal:function(e,t,i,n,a){var r="auto",o="auto",s=!0;return"left"===e?(r=n.left)+t.width>a&&(s=!1):"right"===e?n.left+i.width<t.width?s=!1:(o=a-(n.left+i.width))<0&&(s=!1):(r=n.left+i.width/2-t.width/2,((r=~~r)<0||r+t.width>a)&&(s=!1)),{align:e,left:r,right:o,result:s}},_tryAlignmentVertical:function(e,t,i,n,a,r){var o="auto",s="auto",l=!0,c=50,d=elById("pageHeaderPanel");if(null!==d){var u=window.getComputedStyle(d).position;c="fixed"===u||"static"===u?d.offsetHeight:0}if("top"===e){var h=document.body.clientHeight;o=h-n.top+r,h-(o+t.height)<(window.scrollY||window.pageYOffset)+c&&(l=!1)}else(s=n.top+i.height+r)+t.height-(window.scrollY||window.pageYOffset)>a&&(l=!1);return{align:e,bottom:o,top:s,result:l}}}}),define("WoltLabSuite/Core/Ui/CloseOverlay",["CallbackList"],function(e){"use strict";var t=new e,i={setup:function(){document.body.addEventListener(WCF_CLICK_EVENT,this.execute.bind(this))},add:t.add.bind(t),remove:t.remove.bind(t),execute:function(){t.forEach(null,function(e){e()})}};return i.setup(),i}),define("WoltLabSuite/Core/Ui/Dropdown/Simple",["CallbackList","Core","Dictionary","EventKey","Ui/Alignment","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/CloseOverlay"],function(e,t,i,n,a,r,o,s,l){"use strict";var c=null,d=new e,u=!1,h=new i,f=new i,p=null,m=null,g="";return{setup:function(){u||(u=!0,p=elCreate("div"),p.className="dropdownMenuContainer",document.body.appendChild(p),c=elByClass("dropdownToggle"),this.initAll(),l.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.closeAll.bind(this)),r.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.initAll.bind(this)),document.addEventListener("scroll",this._onScroll.bind(this)),window.bc_wcfSimpleDropdown=this,m=this._dropdownMenuKeyDown.bind(this))},initAll:function(){for(var e=0,t=c.length;e<t;e++)this.init(c[e],!1)},init:function(e,i){if(this.setup(),elAttr(e,"role","button"),elAttr(e,"tabindex","0"),elAttr(e,"aria-haspopup",!0),elAttr(e,"aria-expanded",!1),e.classList.contains("jsDropdownEnabled")||elData(e,"target"))return!1;var n=o.parentByClass(e,"dropdown");if(null===n)throw new Error("Invalid dropdown passed, button '"+s.identify(e)+"' does not have a parent with .dropdown.");var a=o.nextByClass(e,"dropdownMenu");if(null===a)throw new Error("Invalid dropdown passed, button '"+s.identify(e)+"' does not have a menu as next sibling.");p.appendChild(a);var r=s.identify(n);if(!h.has(r)&&(e.classList.add("jsDropdownEnabled"),e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this)),e.addEventListener("keydown",this._handleKeyDown.bind(this)),h.set(r,n),f.set(r,a),r.match(/^wcf\d+$/)||elData(a,"source",r),a.childElementCount&&a.children[0].classList.contains("scrollableDropdownMenu"))){a=a.children[0],elData(a,"scroll-to-active",!0);var l=null,c=null;a.addEventListener("wheel",function(e){null===l&&(l=a.clientHeight),null===c&&(c=a.scrollHeight),e.deltaY<0&&0===a.scrollTop?e.preventDefault():e.deltaY>0&&a.scrollTop+l===c&&e.preventDefault()},{passive:!1})}elData(e,"target",r),i&&setTimeout(function(){elData(e,"dropdown-lazy-init",i instanceof MouseEvent),t.triggerEvent(e,WCF_CLICK_EVENT),setTimeout(function(){e.removeAttribute("data-dropdown-lazy-init")},10)},10)},initFragment:function(e,t){this.setup();var i=s.identify(e);h.has(i)||(h.set(i,e),p.appendChild(t),f.set(i,t))},registerCallback:function(e,t){d.add(e,t)},getDropdown:function(e){return h.get(e)},getDropdownMenu:function(e){return f.get(e)},toggleDropdown:function(e,t,i){this._toggle(null,e,t,i)},setAlignment:function(e,t,i){var n,r=elBySel(".dropdownToggle",e);null!==r&&r.parentNode.classList.contains("inputAddonTextarea")&&(n=r),a.set(t,i||e,{pointerClassNames:["dropdownArrowBottom","dropdownArrowRight"],refDimensionsElement:n||null,horizontal:"right"===elData(t,"dropdown-alignment-horizontal")?"right":"left",vertical:"top"===elData(t,"dropdown-alignment-vertical")?"top":"bottom",allowFlip:elData(t,"dropdown-allow-flip")||"both"})},setAlignmentById:function(e){var t=h.get(e);if(void 0===t)throw new Error("Unknown dropdown identifier '"+e+"'.");var i=f.get(e);this.setAlignment(t,i)},isOpen:function(e){var t=f.get(e);return void 0!==t&&t.classList.contains("dropdownOpen")},open:function(e,t){var i=f.get(e);void 0===i||i.classList.contains("dropdownOpen")||this.toggleDropdown(e,void 0,t)},close:function(e){var t=h.get(e);void 0!==t&&(t.classList.remove("dropdownOpen"),f.get(e).classList.remove("dropdownOpen"))},closeAll:function(){h.forEach(function(e,t){
+e.classList.contains("dropdownOpen")&&(e.classList.remove("dropdownOpen"),f.get(t).classList.remove("dropdownOpen"),this._notifyCallbacks(t,"close"))}.bind(this))},destroy:function(e){if(!h.has(e))return!1;try{this.close(e),elRemove(f.get(e))}catch(e){}return f.delete(e),h.delete(e),!0},_onDialogScroll:function(e){for(var t=e.currentTarget,i=elBySelAll(".dropdown.dropdownOpen",t),n=0,a=i.length;n<a;n++){var r=i[n],o=s.identify(r),l=s.offset(r),c=s.offset(t);l.top+r.clientHeight<=c.top?this.toggleDropdown(o):l.top>=c.top+t.offsetHeight?this.toggleDropdown(o):l.left<=c.left?this.toggleDropdown(o):l.left>=c.left+t.offsetWidth?this.toggleDropdown(o):this.setAlignment(h.get(o),f.get(o))}},_onScroll:function(){h.forEach(function(e,t){if(e.classList.contains("dropdownOpen"))if(elDataBool(e,"is-overlay-dropdown-button"))this.setAlignment(e,f.get(t));else{var i=f.get(e.id);elDataBool(i,"dropdown-ignore-page-scroll")||this.close(t)}}.bind(this))},_notifyCallbacks:function(e,t){d.forEach(e,function(i){i(e,t)})},_toggle:function(e,t,i,n){null!==e&&(e.preventDefault(),e.stopPropagation(),t=elData(e.currentTarget,"target"),void 0===n&&e instanceof MouseEvent&&(n=!0));var a=h.get(t),r=!1;if(void 0!==a){var s,l;if(e&&(s=e.currentTarget,(l=s.parentNode)!==a&&(l.classList.add("dropdown"),l.id=a.id,a.classList.remove("dropdown"),a.id="",a=l,h.set(t,l))),void 0===n&&(s=a.closest(".dropdownToggle"),s||!(s=elBySel(".dropdownToggle",a))&&a.id&&(s=elBySel('[data-target="'+a.id+'"]')),s&&elDataBool(s,"dropdown-lazy-init")&&(n=!0)),elDataBool(a,"dropdown-prevent-toggle")&&a.classList.contains("dropdownOpen")&&(r=!0),""===elData(a,"is-overlay-dropdown-button")){var c=o.parentByClass(a,"dialogContent");elData(a,"is-overlay-dropdown-button",null!==c),null!==c&&c.addEventListener("scroll",this._onDialogScroll.bind(this))}}return g="",h.forEach(function(e,a){var o=f.get(a);if(e.classList.contains("dropdownOpen"))if(!1===r){e.classList.remove("dropdownOpen"),o.classList.remove("dropdownOpen");var s=elBySel(".dropdownToggle",e);s&&elAttr(s,"aria-expanded",!1),this._notifyCallbacks(a,"close")}else g=t;else if(a===t&&o.childElementCount>0){g=t,e.classList.add("dropdownOpen"),o.classList.add("dropdownOpen");var s=elBySel(".dropdownToggle",e);if(s&&elAttr(s,"aria-expanded",!0),o.childElementCount&&elDataBool(o.children[0],"scroll-to-active")){var l=o.children[0];l.removeAttribute("data-scroll-to-active");for(var c=null,d=0,u=l.childElementCount;d<u;d++)if(l.children[d].classList.contains("active")){c=l.children[d];break}c&&(l.scrollTop=Math.max(c.offsetTop+c.clientHeight-o.clientHeight,0))}var h=elBySel(".scrollableDropdownMenu",o);null!==h&&h.classList[h.scrollHeight>h.clientHeight?"add":"remove"]("forceScrollbar"),this._notifyCallbacks(a,"open");var p=null;n||(elAttr(o,"role","menu"),elAttr(o,"tabindex",-1),o.removeEventListener("keydown",m),o.addEventListener("keydown",m),elBySelAll("li",o,function(e){e.clientHeight&&(null===p?p=e:e.classList.contains("active")&&(p=e),elAttr(e,"role","menuitem"),elAttr(e,"tabindex",-1))})),this.setAlignment(e,o,i),null!==p&&p.focus()}}.bind(this)),window.WCF.Dropdown.Interactive.Handler.closeAll(),null===e},_handleKeyDown:function(e){"INPUT"!==e.currentTarget.nodeName&&(n.Enter(e)||n.Space(e))&&(e.preventDefault(),this._toggle(e))},_dropdownMenuKeyDown:function(e){var t,i,a=document.activeElement;if("LI"===a.nodeName)if(n.ArrowDown(e)||n.ArrowUp(e)||n.End(e)||n.Home(e)){e.preventDefault();var r=Array.prototype.slice.call(elBySelAll("li",a.closest(".dropdownMenu")));(n.ArrowUp(e)||n.End(e))&&r.reverse();var o=null,s=function(e){return!e.classList.contains("dropdownDivider")&&e.clientHeight>0},l=r.indexOf(a);(n.End(e)||n.Home(e))&&(l=-1);for(var c=l+1;c<r.length;c++)if(s(r[c])){o=r[c];break}if(null===o)for(c=0;c<r.length;c++)if(s(r[c])){o=r[c];break}o.focus()}else if(n.Enter(e)||n.Space(e)){e.preventDefault();var d=a;1!==d.childElementCount||"SPAN"!==d.children[0].nodeName&&"A"!==d.children[0].nodeName||(d=d.children[0]),i=h.get(g),t=elBySel(".dropdownToggle",i),require(["Core"],function(e){var n=elData(i,"a11y-mouse-event")||"click";e.triggerEvent(d,n),t&&t.focus()})}else(n.Escape(e)||n.Tab(e))&&(e.preventDefault(),i=h.get(g),t=elBySel(".dropdownToggle",i),null!==t||i.classList.contains("dropdown")||(t=i),this._toggle(null,g),t&&t.focus())}}}),define("WoltLabSuite/Core/Devtools",[],function(){"use strict";var e={editorAutosave:!0,eventLogging:!1},t=function(){window.sessionStorage&&window.sessionStorage.setItem("__wsc_devtools_config",JSON.stringify(e))},i={help:function(){window.console.log(""),window.console.log("%cAvailable commands:","text-decoration: underline");var e=[];for(var t in i)"_internal_"!==t&&i.hasOwnProperty(t)&&e.push(t);e.sort().forEach(function(e){window.console.log("\tDevtools."+e+"()")}),window.console.log("")},toggleEditorAutosave:function(i){e.editorAutosave=!0!==i&&!e.editorAutosave,t(),window.console.log("%c\tEditor autosave "+(e.editorAutosave?"enabled":"disabled"),"font-style: italic")},toggleEventLogging:function(i){e.eventLogging=!0===i||!e.eventLogging,t(),window.console.log("%c\tEvent logging "+(e.eventLogging?"enabled":"disabled"),"font-style: italic")},_internal_:{enable:function(){if(window.Devtools=i,window.console.log("%cDevtools for WoltLab Suite loaded","font-weight: bold"),window.sessionStorage){var t=window.sessionStorage.getItem("__wsc_devtools_config");try{null!==t&&(e=JSON.parse(t))}catch(e){}e.editorAutosave||i.toggleEditorAutosave(!0),e.eventLogging&&i.toggleEventLogging(!0)}window.console.log("Settings are saved per browser session, enter `Devtools.help()` to learn more."),window.console.log("")},editorAutosave:function(){return e.editorAutosave},eventLog:function(t,i){e.eventLogging&&window.console.log("[Devtools.EventLogging] Firing event: "+i+" @ "+t)}}};return i}),define("WoltLabSuite/Core/Event/Handler",["Core","Devtools","Dictionary"],function(e,t,i){"use strict";var n=new i;return{add:function(t,a,r){if("function"!=typeof r)throw new TypeError("[WoltLabSuite/Core/Event/Handler] Expected a valid callback for '"+a+"@"+t+"'.");var o=n.get(t);void 0===o&&(o=new i,n.set(t,o));var s=o.get(a);void 0===s&&(s=new i,o.set(a,s));var l=e.getUuid();return s.set(l,r),l},fire:function(e,i,a){t._internal_.eventLog(e,i),a=a||{};var r=n.get(e);if(void 0!==r){var o=r.get(i);void 0!==o&&o.forEach(function(e){e(a)})}},remove:function(e,t,i){var a=n.get(e);if(void 0!==a){var r=a.get(t);void 0!==r&&r.delete(i)}},removeAll:function(e,t){"string"!=typeof t&&(t=void 0);var i=n.get(e);void 0!==i&&(void 0===t?n.delete(e):i.delete(t))},removeAllBySuffix:function(e,t){var i=n.get(e);if(void 0!==i){t="_"+t;var a=-1*t.length;i.forEach(function(i,n){n.substr(a)===t&&this.removeAll(e,n)}.bind(this))}}}}),define("WoltLabSuite/Core/List",[],function(){"use strict";function e(){this._set=t?new Set:[]}var t=objOwns(window,"Set")&&"function"==typeof window.Set;return e.prototype={add:function(e){t?this._set.add(e):this.has(e)||this._set.push(e)},clear:function(){t?this._set.clear():this._set=[]},delete:function(e){if(t)return this._set.delete(e);var i=this._set.indexOf(e);return-1!==i&&(this._set.splice(i,1),!0)},forEach:function(e){if(t)this._set.forEach(e);else for(var i=0,n=this._set.length;i<n;i++)e(this._set[i])},has:function(e){return t?this._set.has(e):-1!==this._set.indexOf(e)}},Object.defineProperty(e.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return t?this._set.size:this._set.length}}),e}),define("WoltLabSuite/Core/Ui/Dialog",["Ajax","Core","Dictionary","Environment","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/Screen","Ui/SimpleDropdown","EventHandler","List","EventKey"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,f,p){"use strict";var m=null,g=null,v=null,_=new i,b=!1,w=new r,y=new i,C=null,E=null,L=elByClass("jsStaticDialog"),S=["onBeforeClose","onClose","onShow"],A=["number","password","search","tel","text","url"],I=['a[href]:not([tabindex^="-"]):not([inert])','area[href]:not([tabindex^="-"]):not([inert])',"input:not([disabled]):not([inert])","select:not([disabled]):not([inert])","textarea:not([disabled]):not([inert])","button:not([disabled]):not([inert])",'iframe:not([tabindex^="-"]):not([inert])','audio:not([tabindex^="-"]):not([inert])','video:not([tabindex^="-"]):not([inert])','[contenteditable]:not([tabindex^="-"]):not([inert])','[tabindex]:not([tabindex^="-"]):not([inert])'];return{setup:function(){void 0===e&&(e=require("Ajax")),v=elCreate("div"),v.classList.add("dialogOverlay"),elAttr(v,"aria-hidden","true"),v.addEventListener("mousedown",this._closeOnBackdrop.bind(this)),v.addEventListener("wheel",function(e){e.target===v&&e.preventDefault()},{passive:!1}),elById("content").appendChild(v),E=function(e){return 27!==e.keyCode||"INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName||(this.close(m),!1)}.bind(this),d.on("screen-xs",{match:function(){b=!0},unmatch:function(){b=!1},setup:function(){b=!0}}),this._initStaticDialogs(),o.add("Ui/Dialog",this._initStaticDialogs.bind(this)),d.setDialogContainer(v),window.addEventListener("resize",function(){_.forEach(function(e){elAttrBool(e.dialog,"aria-hidden")||this.rebuild(elData(e.dialog,"id"))}.bind(this))}.bind(this))},_initStaticDialogs:function(){for(var e,t,i;L.length;)e=L[0],e.classList.remove("jsStaticDialog"),(i=elData(e,"dialog-id"))&&(t=elById(i))&&function(e,t){t.classList.remove("jsStaticDialogContent"),elData(t,"is-static-dialog",!0),elHide(t),e.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.openStatic(t.id,null,{title:elData(t,"title")})}.bind(this))}.bind(this)(e,t)},open:function(i,n){var a=w.get(i);if(t.isPlainObject(a))return this.openStatic(a.id,n);if("function"!=typeof i._dialogSetup)throw new Error("Callback object does not implement the method '_dialogSetup()'.");var r=i._dialogSetup();if(!t.isPlainObject(r))throw new Error("Expected an object literal as return value of '_dialogSetup()'.");a={id:r.id};var o=!0;if(void 0===r.source){var s=elById(r.id);if(null===s)throw new Error("Element id '"+r.id+"' is invalid and no source attribute was given. If you want to use the `html` argument instead, please add `source: null` to your dialog configuration.");r.source=document.createDocumentFragment(),r.source.appendChild(s),s.removeAttribute("id"),elShow(s)}else if(null===r.source)r.source=n;else if("function"==typeof r.source)r.source();else if(t.isPlainObject(r.source)){if("string"!=typeof n||""===n.trim())return e.api(this,r.source.data,function(e){e.returnValues&&"string"==typeof e.returnValues.template&&(this.open(i,e.returnValues.template),"function"==typeof r.source.after&&r.source.after(_.get(r.id).content,e))}.bind(this)),{};r.source=n}else{if("string"==typeof r.source){var s=elCreate("div");elAttr(s,"id",r.id),l.setInnerHtml(s,r.source),r.source=document.createDocumentFragment(),r.source.appendChild(s)}if(!r.source.nodeType||r.source.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)throw new Error("Expected at least a document fragment as 'source' attribute.");o=!1}return w.set(i,a),y.set(r.id,i),this.openStatic(r.id,r.source,r.options,o)},openStatic:function(e,i,r,o){d.pageOverlayOpen(),"desktop"!==n.platform()&&(this.isOpen(e)||d.scrollDisable()),_.has(e)?this._updateDialog(e,i):(r=t.extend({backdropCloseOnClick:!0,closable:!0,closeButtonLabel:a.get("wcf.global.button.close"),closeConfirmMessage:"",disableContentPadding:!1,title:"",onBeforeClose:null,onClose:null,onShow:null},r),r.closable||(r.backdropCloseOnClick=!1),r.closeConfirmMessage&&(r.onBeforeClose=function(e){c.show({confirm:this.close.bind(this,e),message:r.closeConfirmMessage})}.bind(this)),this._createDialog(e,i,r));var s=_.get(e);return"ios"===n.platform()&&window.setTimeout(function(){var e=elBySel("input, textarea",s.content);null!==e&&e.focus()}.bind(this),200),s},setTitle:function(e,t){e=this._getDialogId(e);var i=_.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");var n=elByClass("dialogTitle",i.dialog);n.length&&(n[0].textContent=t)},setCallback:function(e,t,i){if("object"==typeof e){var n=w.get(e);void 0!==n&&(e=n.id)}var a=_.get(e);if(void 0===a)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if(-1===S.indexOf(t))throw new Error("Invalid callback identifier, '"+t+"' is not recognized.");if("function"!=typeof i&&null!==i)throw new Error("Only functions or the 'null' value are acceptable callback values ('"+typeof i+"' given).");a[t]=i},_createDialog:function(e,t,i,n){var a=null;if(null===t&&null===(a=elById(e)))throw new Error("Expected either a HTML string or an existing element id.");var r=elCreate("div");r.classList.add("dialogContainer"),elAttr(r,"aria-hidden","true"),elAttr(r,"role","dialog"),elData(r,"id",e);var o=elCreate("header");r.appendChild(o);var s=l.getUniqueId();elAttr(r,"aria-labelledby",s);var c=elCreate("span");if(c.classList.add("dialogTitle"),c.textContent=i.title,elAttr(c,"id",s),o.appendChild(c),i.closable){var d=elCreate("a");d.className="dialogCloseButton jsTooltip",d.href="#",elAttr(d,"role","button"),elAttr(d,"tabindex","0"),elAttr(d,"title",i.closeButtonLabel),elAttr(d,"aria-label",i.closeButtonLabel),d.addEventListener(WCF_CLICK_EVENT,this._close.bind(this)),o.appendChild(d);var u=elCreate("span");u.className="icon icon24 fa-times",d.appendChild(u)}var h=elCreate("div");h.classList.add("dialogContent"),i.disableContentPadding&&h.classList.add("dialogContentNoPadding"),r.appendChild(h),h.addEventListener("wheel",function(e){for(var t,i,n,a=!1,r=e.target;;){if(t=r.clientHeight,i=r.scrollHeight,t<i){if(n=r.scrollTop,e.deltaY<0&&n>0){a=!0;break}if(e.deltaY>0&&n+t<i){a=!0;break}}if(!r||r===h)break;r=r.parentNode}!1===a&&e.preventDefault()},{passive:!1});var p;if(null===a)if("string"==typeof t)p=elCreate("div"),p.id=e,l.setInnerHtml(p,t);else{if(!(t instanceof DocumentFragment))throw new TypeError("'html' must either be a string or a DocumentFragment");for(var m,g=[],b=0,w=t.childNodes.length;b<w;b++)m=t.childNodes[b],m.nodeType===Node.ELEMENT_NODE&&g.push(m);"DIV"!==g[0].nodeName||g.length>1?(p=elCreate("div"),p.id=e,p.appendChild(t)):p=g[0]}else p=a;h.appendChild(p),"none"===p.style.getPropertyValue("display")&&elShow(p),_.set(e,{backdropCloseOnClick:i.backdropCloseOnClick,closable:i.closable,content:p,dialog:r,header:o,onBeforeClose:i.onBeforeClose,onClose:i.onClose,onShow:i.onShow,submitButton:null,inputFields:new f}),l.prepend(r,v),"function"==typeof i.onSetup&&i.onSetup(p),!0!==n&&this._updateDialog(e,null)},_updateDialog:function(e,t){var i=_.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("string"==typeof t&&l.setInnerHtml(i.content,t),"true"===elAttr(i.dialog,"aria-hidden")){u.closeAll(),window.WCF.Dropdown.Interactive.Handler.closeAll(),null===g&&(g=this._maintainFocus.bind(this),document.body.addEventListener("focus",g,{capture:!0})),i.closable&&"true"===elAttr(v,"aria-hidden")&&window.addEventListener("keyup",E),i.dialog.parentNode.insertBefore(i.dialog,i.dialog.parentNode.firstChild),elAttr(i.dialog,"aria-hidden","false"),elAttr(v,"aria-hidden","false"),elData(v,"close-on-click",i.backdropCloseOnClick?"true":"false"),m=e,C=document.activeElement;var n=elBySel(".dialogCloseButton",i.header);n&&elAttr(n,"inert",!0),this._setFocusToFirstItem(i.dialog),n&&n.removeAttribute("inert"),"function"==typeof i.onShow&&i.onShow(i.content),elDataBool(i.content,"is-static-dialog")&&h.fire("com.woltlab.wcf.dialog","openStatic",{content:i.content,id:e})}this.rebuild(e),o.trigger()},_maintainFocus:function(e){if(m){var t=_.get(m);t.dialog.contains(e.target)||e.target.closest(".dropdownMenuContainer")||e.target.closest(".datePicker")||this._setFocusToFirstItem(t.dialog,!0)}},_setFocusToFirstItem:function(e,t){var i=this._getFirstFocusableChild(e);null!==i&&(t&&("username"!==i.id&&"username"!==i.name||"safari"===n.browser()&&"ios"===n.platform()&&(i=null)),i&&setTimeout(function(){i.focus()},1))},_getFirstFocusableChild:function(e){for(var t=elBySelAll(I.join(","),e),i=0,n=t.length;i<n;i++)if(t[i].offsetWidth&&t[i].offsetHeight&&t[i].getClientRects().length)return t[i];return null},rebuild:function(e){e=this._getDialogId(e);var t=_.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("true"!==elAttr(t.dialog,"aria-hidden")){var i=t.content.parentNode,a=elBySel(".formSubmit",t.content),r=0;null!==a?(i.classList.add("dialogForm"),a.classList.add("dialogFormSubmit"),r+=l.outerHeight(a),r-=1,i.style.setProperty("margin-bottom",r+"px","")):(i.classList.remove("dialogForm"),i.style.removeProperty("margin-bottom")),r+=l.outerHeight(t.header);var o=window.innerHeight*(b?1:.8)-r;i.style.setProperty("max-height",~~o+"px",""),"chrome"!==n.browser()&&"safari"!==n.browser()||t.content.parentNode.classList.add("jsWebKitFractionalPixelFix");var s=y.get(e);if(void 0!==s&&"function"==typeof s._dialogSubmit){var c=elBySelAll('input[data-dialog-submit-on-enter="true"]',t.content),d=elBySel('.formSubmit > input[type="submit"], .formSubmit > button[data-type="submit"]',t.content);if(null===d)return void(0===c.length&&console.warn("Broken dialog, expected a submit button.",t.content));if(t.submitButton!==d){t.submitButton=d,d.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),this._submit(e)}.bind(this));for(var u,h=null,f=0,m=c.length;f<m;f++)u=c[f],t.inputFields.has(u)||(-1!==A.indexOf(u.type)?(t.inputFields.add(u),null===h&&(h=function(t){p.Enter(t)&&(t.preventDefault(),this._submit(e))}.bind(this)),u.addEventListener("keydown",h)):console.warn("Unsupported input type.",u))}}}},_submit:function(e){var t=_.get(e),i=!0;t.inputFields.forEach(function(e){e.required&&(""===e.value.trim()?(elInnerError(e,a.get("wcf.global.form.error.empty")),i=!1):elInnerError(e,!1))}),i&&y.get(e)._dialogSubmit()},_close:function(e){e.preventDefault();var t=_.get(m);if("function"==typeof t.onBeforeClose)return t.onBeforeClose(m),!1;this.close(m)},_closeOnBackdrop:function(e){if(e.target!==v)return!0;"true"===elData(v,"close-on-click")?this._close(e):e.preventDefault()},close:function(e){e=this._getDialogId(e);var t=_.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");elAttr(t.dialog,"aria-hidden","true"),document.activeElement.closest(".dialogContainer")===t.dialog&&document.activeElement.blur(),"function"==typeof t.onClose&&t.onClose(e),m=null;for(var i=0;i<v.childElementCount;i++){var a=v.children[i];if("false"===elAttr(a,"aria-hidden")){m=elData(a,"id");break}}d.pageOverlayClose(),null===m?(elAttr(v,"aria-hidden","true"),elData(v,"close-on-click","false"),t.closable&&window.removeEventListener("keyup",E)):(t=_.get(m),elData(v,"close-on-click",t.backdropCloseOnClick?"true":"false")),"desktop"!==n.platform()&&d.scrollEnable()},getDialog:function(e){return _.get(this._getDialogId(e))},isOpen:function(e){var t=this.getDialog(e);return void 0!==t&&"false"===elAttr(t.dialog,"aria-hidden")},destroy:function(e){if("object"!=typeof e||e instanceof String)throw new TypeError("Expected the callback object as parameter.");if(w.has(e)){var t=w.get(e).id;this.isOpen(t)&&this.close(t),_.has(t)&&(elRemove(_.get(t).dialog),_.delete(t)),w.delete(e)}},_getDialogId:function(e){if("object"==typeof e){var t=w.get(e);if(void 0!==t)return t.id}return e.toString()},_ajaxSetup:function(){return{}}}}),define("WoltLabSuite/Core/Ajax/Status",["Language"],function(e){"use strict";var t=0,i=null,n=null;return{_init:function(){i=elCreate("div"),i.classList.add("spinner"),elAttr(i,"role","status");var t=elCreate("span");t.className="icon icon48 fa-spinner",i.appendChild(t);var n=elCreate("span");n.textContent=e.get("wcf.global.loading"),i.appendChild(n),document.body.appendChild(i)},show:function(){null===i&&this._init(),t++,null===n&&(n=window.setTimeout(function(){t&&i.classList.add("active"),n=null},250))},hide:function(){0===--t&&(null!==n&&window.clearTimeout(n),i.classList.remove("active"))}}}),define("WoltLabSuite/Core/Ajax/Request",["Core","Language","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,a,r){"use strict";function o(e){this._data=null,this._options={},this._previousXhr=null,this._xhr=null,this._init(e)}var s=!1,l=!1;return o.prototype={_init:function(t){this._options=e.extend({data:{},contentType:"application/x-www-form-urlencoded; charset=UTF-8",responseType:"application/json",type:"POST",url:"",withCredentials:!1,autoAbort:!1,ignoreError:!1,pinData:!1,silent:!1,includeRequestedWith:!0,failure:null,finalize:null,success:null,progress:null,uploadProgress:null,callbackObject:null},t),"object"==typeof t.callbackObject&&(this._options.callbackObject=t.callbackObject),this._options.url=e.convertLegacyUrl(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),0===this._options.url.indexOf(WSC_API_URL)&&(this._options.includeRequestedWith=!0,this._options.withCredentials=!0),this._options.pinData&&(this._data=e.extend({},this._options.data)),null!==this._options.callbackObject&&("function"==typeof this._options.callbackObject._ajaxFailure&&(this._options.failure=this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxFinalize&&(this._options.finalize=this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxSuccess&&(this._options.success=this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxProgress&&(this._options.progress=this._options.callbackObject._ajaxProgress.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxUploadProgress&&(this._options.uploadProgress=this._options.callbackObject._ajaxUploadProgress.bind(this._options.callbackObject))),!1===s&&(s=!0,window.addEventListener("beforeunload",function(){l=!0}))},sendRequest:function(t){(!0===t||this._options.autoAbort)&&this.abortPrevious(),this._options.silent||r.show(),this._xhr instanceof XMLHttpRequest&&(this._previousXhr=this._xhr),this._xhr=new XMLHttpRequest,this._xhr.open(this._options.type,this._options.url,!0),this._options.contentType&&this._xhr.setRequestHeader("Content-Type",this._options.contentType),(this._options.withCredentials||this._options.includeRequestedWith)&&this._xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),this._options.withCredentials&&(this._xhr.withCredentials=!0);var i=this,n=e.clone(this._options);if(this._xhr.onload=function(){this.readyState===XMLHttpRequest.DONE&&(this.status>=200&&this.status<300||304===this.status?n.responseType&&0!==this.getResponseHeader("Content-Type").indexOf(n.responseType)?i._failure(this,n):i._success(this,n):i._failure(this,n))},this._xhr.onerror=function(){i._failure(this,n)},this._options.progress&&(this._xhr.onprogress=this._options.progress),this._options.uploadProgress&&(this._xhr.upload.onprogress=this._options.uploadProgress),"POST"===this._options.type){var a=this._options.data;"object"==typeof a&&"FormData"!==e.getType(a)&&(a=e.serialize(a)),this._xhr.send(a)}else this._xhr.send()},abortPrevious:function(){null!==this._previousXhr&&(this._previousXhr.abort(),this._previousXhr=null,this._options.silent||r.hide())},setOption:function(e,t){this._options[e]=t},getOption:function(e){return objOwns(this._options,e)?this._options[e]:null},setData:function(t){null!==this._data&&"FormData"!==e.getType(t)&&(t=e.extend(this._data,t)),this._options.data=t},_success:function(e,t){if(t.silent||r.hide(),"function"==typeof t.success){var i=null;if("application/json"===e.getResponseHeader("Content-Type").split(";",1)[0].trim()){try{i=JSON.parse(e.responseText)}catch(i){return void this._failure(e,t)}i&&i.returnValues&&void 0!==i.returnValues.template&&(i.returnValues.template=i.returnValues.template.trim()),i&&i.forceBackgroundQueuePerform&&require(["WoltLabSuite/Core/BackgroundQueue"],function(e){e.invoke()})}t.success(i,e.responseText,e,t.data)}this._finalize(t)},_failure:function(e,i){if(!l){i.silent||r.hide();var o=null;try{o=JSON.parse(e.responseText)}catch(e){}var s=!0;if("function"==typeof i.failure&&(s=i.failure(o||{},e.responseText||"",e,i.data)),!0!==i.ignoreError&&!1!==s){var c=this.getErrorHtml(o,e);c&&(void 0===a&&(a=require("Ui/Dialog")),a.openStatic(n.getUniqueId(),c,{title:t.get("wcf.global.error.title")}))}this._finalize(i)}},getErrorHtml:function(e,t){var i="",n="";if(null!==e?(e.returnValues&&e.returnValues.description&&(i+="<br><p>Description:</p><p>"+e.returnValues.description+"</p>"),e.file&&e.line&&(i+="<br><p>File:</p><p>"+e.file+" in line "+e.line+"</p>"),e.stacktrace?i+="<br><p>Stacktrace:</p><p>"+e.stacktrace+"</p>":e.exceptionID&&(i+="<br><p>Exception ID: <code>"+e.exceptionID+"</code></p>"),n=e.message,e.previous.forEach(function(e){i+="<hr><p>"+e.message+"</p>",i+="<br><p>Stacktrace</p><p>"+e.stacktrace+"</p>"})):n=t.responseText,!n||"undefined"===n){if(!ENABLE_DEBUG_MODE)return null;n="XMLHttpRequest failed without a responseText. Check your browser console."}return'<div class="ajaxDebugMessage"><p>'+n+"</p>"+i+"</div>"},_finalize:function(e){"function"==typeof e.finalize&&e.finalize(this._xhr),this._previousXhr=null,i.trigger();for(var t=elBySelAll('a[href*="#"]'),n=0,a=t.length;n<a;n++){var r=t[n],o=elAttr(r,"href");-1===o.indexOf("AJAXProxy")&&-1===o.indexOf("ajax-proxy")||(o=o.substr(o.indexOf("#")),elAttr(r,"href",document.location.toString().replace(/#.*/,"")+o))}}},o}),define("WoltLabSuite/Core/Ajax",["AjaxRequest","Core","ObjectMap"],function(e,t,i){"use strict";var n=new i;return{api:function(t,i,a,r){void 0===e&&(e=require("AjaxRequest")),"object"!=typeof i&&(i={});var o=n.get(t);if(void 0===o){if("function"!=typeof t._ajaxSetup)throw new TypeError("Callback object must implement at least _ajaxSetup().");var s=t._ajaxSetup();s.pinData=!0,s.callbackObject=t,s.url||(s.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,s.withCredentials=!0),o=new e(s),n.set(t,o)}var l=null,c=null;return"function"==typeof a&&(l=o.getOption("success"),o.setOption("success",a)),"function"==typeof r&&(c=o.getOption("failure"),o.setOption("failure",r)),o.setData(i),o.sendRequest(),null!==l&&o.setOption("success",l),null!==c&&o.setOption("failure",c),o},apiOnce:function(t){void 0===e&&(e=require("AjaxRequest")),t.pinData=!1,t.callbackObject=null,t.url||(t.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,t.withCredentials=!0),new e(t).sendRequest(!1)},getRequestObject:function(e){if(!n.has(e))throw new Error("Expected a previously used callback object, provided object is unknown.");return n.get(e)}}}),define("WoltLabSuite/Core/BackgroundQueue",["Ajax"],function(e){"use strict";var t=0,i=!1,n="";return{setUrl:function(e){n=e},invoke:function(){if(""===n)return void console.error("The background queue has not been initialized yet.");i||(i=!0,e.api(this))},_ajaxSuccess:function(e){t++,e>0&&t<5?window.setTimeout(function(){i=!1,this.invoke()}.bind(this),1e3):(i=!1,t=0)},_ajaxSetup:function(){return{url:n,ignoreError:!0,silent:!0}}}}),function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||g)return!1;try{d.clearRect(0,0,l,s),d.drawImage(e,0,0,l,s)}catch(e){}b=setTimeout(function(){t(e)},N.duration),B.setIcon(c)}function i(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,i,n){return t+t+i+i+n+n});var i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return!!i&&{r:parseInt(i[1],16),g:parseInt(i[2],16),b:parseInt(i[3],16)}}function n(e,t){var i,n={};for(i in e)n[i]=e[i];for(i in t)n[i]=t[i];return n}function a(){return w.hidden||w.msHidden||w.webkitHidden||w.mozHidden}e=e||{};var r,o,s,l,c,d,u,h,f,p,m,g,v,_,b,w,y={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1,element:null,dataUrl:!1,win:window};v={},v.ff="undefined"!=typeof InstallTrigger,v.chrome=!!window.chrome,v.opera=!!window.opera||navigator.userAgent.indexOf("Opera")>=0,v.ie=!1,v.safari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,v.supported=v.chrome||v.ff||v.opera;var C=[];m=function(){},h=g=!1;var E={};E.ready=function(){h=!0,E.reset(),m()},E.reset=function(){h&&(C=[],f=!1,p=!1,d.clearRect(0,0,l,s),d.drawImage(u,0,0,l,s),B.setIcon(c),window.clearTimeout(_),window.clearTimeout(b))},E.start=function(){if(h&&!p){var e=function(){f=C[0],p=!1,C.length>0&&(C.shift(),E.start())};if(C.length>0){p=!0;var t=function(){["type","animation","bgColor","textColor","fontFamily","fontStyle"].forEach(function(e){e in C[0].options&&(r[e]=C[0].options[e])}),N.run(C[0].options,function(){e()},!1)};f?N.run(f.options,function(){t()},!0):t()}}};var L={},S=function(e){return e.n="number"==typeof e.n?Math.abs(0|e.n):e.n,e.x=l*e.x,e.y=s*e.y,e.w=l*e.w,e.h=s*e.h,e.len=(""+e.n).length,e};L.circle=function(e){e=S(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),d.clearRect(0,0,l,s),d.drawImage(u,0,0,l,s),d.beginPath(),d.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+r.fontFamily,d.textAlign="center",t?(d.moveTo(e.x+e.w/2,e.y),d.lineTo(e.x+e.w-e.h/2,e.y),d.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),d.lineTo(e.x+e.w,e.y+e.h-e.h/2),d.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),d.lineTo(e.x+e.h/2,e.y+e.h),d.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),d.lineTo(e.x,e.y+e.h/2),d.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):d.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),d.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",d.fill(),d.closePath(),d.beginPath(),d.stroke(),d.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?d.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):d.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),d.closePath()},L.rectangle=function(e){e=S(e);2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w),d.clearRect(0,0,l,s),d.drawImage(u,0,0,l,s),d.beginPath(),d.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.9:1))+"px "+r.fontFamily,d.textAlign="center",d.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",d.fillRect(e.x,e.y,e.w,e.h),d.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?d.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):d.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),d.closePath()};var A=function(e,t){t=("string"==typeof t?{animation:t}:t)||{},m=function(){try{if("number"==typeof e?e>0:""!==e){var n={type:"badge",options:{n:e}};if("animation"in t&&N.types[""+t.animation]&&(n.options.animation=""+t.animation),"type"in t&&L[""+t.type]&&(n.options.type=""+t.type),["bgColor","textColor"].forEach(function(e){e in t&&(n.options[e]=i(t[e]))}),["fontStyle","fontFamily"].forEach(function(e){e in t&&(n.options[e]=t[e])}),C.push(n),C.length>100)throw new Error("Too many badges requests in queue.");E.start()}else E.reset()}catch(e){throw new Error("Error setting badge. Message: "+e.message)}},h&&m()},I=function(e){m=function(){try{var t=e.width,i=e.height,n=document.createElement("img"),a=t/l<i/s?t/l:i/s;n.setAttribute("crossOrigin","anonymous"),n.onload=function(){d.clearRect(0,0,l,s),d.drawImage(n,0,0,l,s),B.setIcon(c)},n.setAttribute("src",e.getAttribute("src")),n.height=i/a,n.width=t/a}catch(e){throw new Error("Error setting image. Message: "+e.message)}},h&&m()},D=function(e){m=function(){B.setIconSrc(e)},h&&m()},x=function(e){m=function(){try{if("stop"===e)return g=!0,E.reset(),void(g=!1);e.addEventListener("play",function(){t(this)},!1)}catch(e){throw new Error("Error setting video. Message: "+e.message)}
+},h&&m()},T=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),v.supported){var i=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,m=function(){try{if("stop"===e)return g=!0,E.reset(),void(g=!1);i=document.createElement("video"),i.width=l,i.height=s,navigator.getUserMedia({video:!0,audio:!1},function(e){i.src=URL.createObjectURL(e),i.play(),t(i)},function(){})}catch(e){throw new Error("Error setting webcam. Message: "+e.message)}},h&&m()}},k=function(e,t){var n=e;null==t&&"[object Object]"==Object.prototype.toString.call(e)||(n={},n[e]=t);for(var a=Object.keys(n),o=0;o<a.length;o++)"bgColor"==a[o]||"textColor"==a[o]?r[a[o]]=i(n[a[o]]):r[a[o]]=n[a[o]];C.push(f),E.start()},B={};B.getIcons=function(){var e=[];return r.element?e=[r.element]:r.elementId?(e=[w.getElementById(r.elementId)],e[0].setAttribute("href",e[0].getAttribute("src"))):(e=function(){for(var e=[],t=w.getElementsByTagName("head")[0].getElementsByTagName("link"),i=0;i<t.length;i++)/(^|\s)icon(\s|$)/i.test(t[i].getAttribute("rel"))&&e.push(t[i]);return e}(),0===e.length&&(e=[w.createElement("link")],e[0].setAttribute("rel","icon"),w.getElementsByTagName("head")[0].appendChild(e[0]))),e.forEach(function(e){e.setAttribute("type","image/png")}),e},B.setIcon=function(e){var t=e.toDataURL("image/png");B.setIconSrc(t)},B.setIconSrc=function(e){if(r.dataUrl&&r.dataUrl(e),r.element)r.element.setAttribute("href",e),r.element.setAttribute("src",e);else if(r.elementId){var t=w.getElementById(r.elementId);t.setAttribute("href",e),t.setAttribute("src",e)}else if(v.ff||v.opera){var i=o[o.length-1],n=w.createElement("link");o=[n],v.opera&&n.setAttribute("rel","icon"),n.setAttribute("rel","icon"),n.setAttribute("type","image/png"),w.getElementsByTagName("head")[0].appendChild(n),n.setAttribute("href",e),i.parentNode&&i.parentNode.removeChild(i)}else o.forEach(function(t){t.setAttribute("href",e)})};var N={};return N.duration=40,N.types={},N.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],N.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],N.run=function(e,t,i,o){var s=N.types[a()?"none":r.animation];if(o=!0===i?void 0!==o?o:s.length-1:void 0!==o?o:0,t=t||function(){},!(o<s.length&&o>=0))return void t();L[r.type](n(e,s[o])),_=setTimeout(function(){i?o-=1:o+=1,N.run(e,t,i,o)},N.duration),B.setIcon(c)},function(){r=n(y,e),r.bgColor=i(r.bgColor),r.textColor=i(r.textColor),r.position=r.position.toLowerCase(),r.animation=N.types[""+r.animation]?r.animation:y.animation,w=r.win.document;var t=r.position.indexOf("up")>-1,a=r.position.indexOf("left")>-1;if(t||a)for(var h in N.types)for(var f=0;f<N.types[h].length;f++){var p=N.types[h][f];t&&(p.y<.6?p.y=p.y-.4:p.y=p.y-2*p.y+(1-p.w)),a&&(p.x<.6?p.x=p.x-.4:p.x=p.x-2*p.x+(1-p.h)),N.types[h][f]=p}r.type=L[""+r.type]?r.type:y.type,o=B.getIcons(),c=document.createElement("canvas"),u=document.createElement("img");var m=o[o.length-1];m.hasAttribute("href")?(u.setAttribute("crossOrigin","anonymous"),u.onload=function(){s=u.height>0?u.height:32,l=u.width>0?u.width:32,c.height=s,c.width=l,d=c.getContext("2d"),E.ready()},u.setAttribute("src",m.getAttribute("href"))):(s=32,l=32,u.height=s,u.width=l,c.height=s,c.width=l,d=c.getContext("2d"),E.ready())}(),{badge:A,video:x,image:I,rawImageSrc:D,webcam:T,setOpt:k,reset:E.reset,browser:{supported:v.supported}}};void 0!==define&&define.amd?define("favico",[],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(),function(e,t,i){var n=window.matchMedia;"undefined"!=typeof module&&module.exports?module.exports=i(n):"function"==typeof define&&define.amd?define("enquire",[],function(){return t.enquire=i(n)}):t.enquire=i(n)}(0,this,function(e){"use strict";function t(e,t){var i=0,n=e.length;for(i;i<n&&!1!==t(e[i],i);i++);}function i(e){return"[object Array]"===Object.prototype.toString.apply(e)}function n(e){return"function"==typeof e}function a(e){this.options=e,!e.deferSetup&&this.setup()}function r(t,i){this.query=t,this.isUnconditional=i,this.handlers=[],this.mql=e(t);var n=this;this.listener=function(e){n.mql=e,n.assess()},this.mql.addListener(this.listener)}function o(){if(!e)throw new Error("matchMedia not present, legacy browsers require a polyfill");this.queries={},this.browserIsIncapable=!e("only all").matches}return a.prototype={setup:function(){this.options.setup&&this.options.setup(),this.initialised=!0},on:function(){!this.initialised&&this.setup(),this.options.match&&this.options.match()},off:function(){this.options.unmatch&&this.options.unmatch()},destroy:function(){this.options.destroy?this.options.destroy():this.off()},equals:function(e){return this.options===e||this.options.match===e}},r.prototype={addHandler:function(e){var t=new a(e);this.handlers.push(t),this.matches()&&t.on()},removeHandler:function(e){var i=this.handlers;t(i,function(t,n){if(t.equals(e))return t.destroy(),!i.splice(n,1)})},matches:function(){return this.mql.matches||this.isUnconditional},clear:function(){t(this.handlers,function(e){e.destroy()}),this.mql.removeListener(this.listener),this.handlers.length=0},assess:function(){var e=this.matches()?"on":"off";t(this.handlers,function(t){t[e]()})}},o.prototype={register:function(e,a,o){var s=this.queries,l=o&&this.browserIsIncapable;return s[e]||(s[e]=new r(e,l)),n(a)&&(a={match:a}),i(a)||(a=[a]),t(a,function(t){n(t)&&(t={match:t}),s[e].addHandler(t)}),this},unregister:function(e,t){var i=this.queries[e];return i&&(t?i.removeHandler(t):(i.clear(),delete this.queries[e])),this}},new o}),function e(t,i,n){function a(o,s){if(!i[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var d=i[o]={exports:{}};t[o][0].call(d.exports,function(e){var i=t[o][1][e];return a(i||e)},d,d.exports,e,t,i,n)}return i[o].exports}for(var r="function"==typeof require&&require,o=0;o<n.length;o++)a(n[o]);return a}({1:[function(e,t,i){"use strict";var n=e("../main");"function"==typeof define&&define.amd?define("perfect-scrollbar",n):(window.PerfectScrollbar=n,void 0===window.Ps&&(window.Ps=n))},{"../main":7}],2:[function(e,t,i){"use strict";function n(e,t){var i=e.className.split(" ");i.indexOf(t)<0&&i.push(t),e.className=i.join(" ")}function a(e,t){var i=e.className.split(" "),n=i.indexOf(t);n>=0&&i.splice(n,1),e.className=i.join(" ")}i.add=function(e,t){e.classList?e.classList.add(t):n(e,t)},i.remove=function(e,t){e.classList?e.classList.remove(t):a(e,t)},i.list=function(e){return e.classList?Array.prototype.slice.apply(e.classList):e.className.split(" ")}},{}],3:[function(e,t,i){"use strict";function n(e,t){return window.getComputedStyle(e)[t]}function a(e,t,i){return"number"==typeof i&&(i=i.toString()+"px"),e.style[t]=i,e}function r(e,t){for(var i in t){var n=t[i];"number"==typeof n&&(n=n.toString()+"px"),e.style[i]=n}return e}var o={};o.e=function(e,t){var i=document.createElement(e);return i.className=t,i},o.appendTo=function(e,t){return t.appendChild(e),e},o.css=function(e,t,i){return"object"==typeof t?r(e,t):void 0===i?n(e,t):a(e,t,i)},o.matches=function(e,t){return void 0!==e.matches?e.matches(t):void 0!==e.matchesSelector?e.matchesSelector(t):void 0!==e.webkitMatchesSelector?e.webkitMatchesSelector(t):void 0!==e.mozMatchesSelector?e.mozMatchesSelector(t):void 0!==e.msMatchesSelector?e.msMatchesSelector(t):void 0},o.remove=function(e){void 0!==e.remove?e.remove():e.parentNode&&e.parentNode.removeChild(e)},o.queryChildren=function(e,t){return Array.prototype.filter.call(e.childNodes,function(e){return o.matches(e,t)})},t.exports=o},{}],4:[function(e,t,i){"use strict";var n=function(e){this.element=e,this.events={}};n.prototype.bind=function(e,t){void 0===this.events[e]&&(this.events[e]=[]),this.events[e].push(t),this.element.addEventListener(e,t,!1)},n.prototype.unbind=function(e,t){var i=void 0!==t;this.events[e]=this.events[e].filter(function(n){return!(!i||n===t)||(this.element.removeEventListener(e,n,!1),!1)},this)},n.prototype.unbindAll=function(){for(var e in this.events)this.unbind(e)};var a=function(){this.eventElements=[]};a.prototype.eventElement=function(e){var t=this.eventElements.filter(function(t){return t.element===e})[0];return void 0===t&&(t=new n(e),this.eventElements.push(t)),t},a.prototype.bind=function(e,t,i){this.eventElement(e).bind(t,i)},a.prototype.unbind=function(e,t,i){this.eventElement(e).unbind(t,i)},a.prototype.unbindAll=function(){for(var e=0;e<this.eventElements.length;e++)this.eventElements[e].unbindAll()},a.prototype.once=function(e,t,i){var n=this.eventElement(e),a=function(e){n.unbind(t,a),i(e)};n.bind(t,a)},t.exports=a},{}],5:[function(e,t,i){"use strict";t.exports=function(){function e(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return e()+e()+"-"+e()+"-"+e()+"-"+e()+"-"+e()+e()+e()}}()},{}],6:[function(e,t,i){"use strict";var n=e("./class"),a=e("./dom"),r=i.toInt=function(e){return parseInt(e,10)||0},o=i.clone=function(e){if(e){if(e.constructor===Array)return e.map(o);if("object"==typeof e){var t={};for(var i in e)t[i]=o(e[i]);return t}return e}return null};i.extend=function(e,t){var i=o(e);for(var n in t)i[n]=o(t[n]);return i},i.isEditable=function(e){return a.matches(e,"input,[contenteditable]")||a.matches(e,"select,[contenteditable]")||a.matches(e,"textarea,[contenteditable]")||a.matches(e,"button,[contenteditable]")},i.removePsClasses=function(e){for(var t=n.list(e),i=0;i<t.length;i++){var a=t[i];0===a.indexOf("ps-")&&n.remove(e,a)}},i.outerWidth=function(e){return r(a.css(e,"width"))+r(a.css(e,"paddingLeft"))+r(a.css(e,"paddingRight"))+r(a.css(e,"borderLeftWidth"))+r(a.css(e,"borderRightWidth"))},i.startScrolling=function(e,t){n.add(e,"ps-in-scrolling"),void 0!==t?n.add(e,"ps-"+t):(n.add(e,"ps-x"),n.add(e,"ps-y"))},i.stopScrolling=function(e,t){n.remove(e,"ps-in-scrolling"),void 0!==t?n.remove(e,"ps-"+t):(n.remove(e,"ps-x"),n.remove(e,"ps-y"))},i.env={isWebKit:"WebkitAppearance"in document.documentElement.style,supportsTouch:"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,supportsIePointer:null!==window.navigator.msMaxTouchPoints}},{"./class":2,"./dom":3}],7:[function(e,t,i){"use strict";var n=e("./plugin/destroy"),a=e("./plugin/initialize"),r=e("./plugin/update");t.exports={initialize:a,update:r,destroy:n}},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(e,t,i){"use strict";t.exports={handlers:["click-rail","drag-scrollbar","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1,theme:"default"}},{}],9:[function(e,t,i){"use strict";var n=e("../lib/helper"),a=e("../lib/dom"),r=e("./instances");t.exports=function(e){var t=r.get(e);t&&(t.event.unbindAll(),a.remove(t.scrollbarX),a.remove(t.scrollbarY),a.remove(t.scrollbarXRail),a.remove(t.scrollbarYRail),n.removePsClasses(e),r.remove(e))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(e,t,i){"use strict";function n(e,t){function i(e){return e.getBoundingClientRect()}var n=function(e){e.stopPropagation()};t.event.bind(t.scrollbarY,"click",n),t.event.bind(t.scrollbarYRail,"click",function(n){var a=n.pageY-window.pageYOffset-i(t.scrollbarYRail).top,s=a>t.scrollbarYTop?1:-1;o(e,"top",e.scrollTop+s*t.containerHeight),r(e),n.stopPropagation()}),t.event.bind(t.scrollbarX,"click",n),t.event.bind(t.scrollbarXRail,"click",function(n){var a=n.pageX-window.pageXOffset-i(t.scrollbarXRail).left,s=a>t.scrollbarXLeft?1:-1;o(e,"left",e.scrollLeft+s*t.containerWidth),r(e),n.stopPropagation()})}var a=e("../instances"),r=e("../update-geometry"),o=e("../update-scroll");t.exports=function(e){n(e,a.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(e,t,i){"use strict";function n(e,t){function i(i){var a=n+i*t.railXRatio,o=Math.max(0,t.scrollbarXRail.getBoundingClientRect().left)+t.railXRatio*(t.railXWidth-t.scrollbarXWidth);t.scrollbarXLeft=a<0?0:a>o?o:a;var s=r.toInt(t.scrollbarXLeft*(t.contentWidth-t.containerWidth)/(t.containerWidth-t.railXRatio*t.scrollbarXWidth))-t.negativeScrollAdjustment;c(e,"left",s)}var n=null,a=null,s=function(t){i(t.pageX-a),l(e),t.stopPropagation(),t.preventDefault()},d=function(){r.stopScrolling(e,"x"),t.event.unbind(t.ownerDocument,"mousemove",s)};t.event.bind(t.scrollbarX,"mousedown",function(i){a=i.pageX,n=r.toInt(o.css(t.scrollbarX,"left"))*t.railXRatio,r.startScrolling(e,"x"),t.event.bind(t.ownerDocument,"mousemove",s),t.event.once(t.ownerDocument,"mouseup",d),i.stopPropagation(),i.preventDefault()})}function a(e,t){function i(i){var a=n+i*t.railYRatio,o=Math.max(0,t.scrollbarYRail.getBoundingClientRect().top)+t.railYRatio*(t.railYHeight-t.scrollbarYHeight);t.scrollbarYTop=a<0?0:a>o?o:a;var s=r.toInt(t.scrollbarYTop*(t.contentHeight-t.containerHeight)/(t.containerHeight-t.railYRatio*t.scrollbarYHeight));c(e,"top",s)}var n=null,a=null,s=function(t){i(t.pageY-a),l(e),t.stopPropagation(),t.preventDefault()},d=function(){r.stopScrolling(e,"y"),t.event.unbind(t.ownerDocument,"mousemove",s)};t.event.bind(t.scrollbarY,"mousedown",function(i){a=i.pageY,n=r.toInt(o.css(t.scrollbarY,"top"))*t.railYRatio,r.startScrolling(e,"y"),t.event.bind(t.ownerDocument,"mousemove",s),t.event.once(t.ownerDocument,"mouseup",d),i.stopPropagation(),i.preventDefault()})}var r=e("../../lib/helper"),o=e("../../lib/dom"),s=e("../instances"),l=e("../update-geometry"),c=e("../update-scroll");t.exports=function(e){var t=s.get(e);n(e,t),a(e,t)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var a=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===a&&n>0||a>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}var n=!1;t.event.bind(e,"mouseenter",function(){n=!0}),t.event.bind(e,"mouseleave",function(){n=!1});var o=!1;t.event.bind(t.ownerDocument,"keydown",function(c){if(!(c.isDefaultPrevented&&c.isDefaultPrevented()||c.defaultPrevented)){var d=r.matches(t.scrollbarX,":focus")||r.matches(t.scrollbarY,":focus");if(n||d){var u=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(u){if("IFRAME"===u.tagName)u=u.contentDocument.activeElement;else for(;u.shadowRoot;)u=u.shadowRoot.activeElement;if(a.isEditable(u))return}var h=0,f=0;switch(c.which){case 37:h=c.metaKey?-t.contentWidth:c.altKey?-t.containerWidth:-30;break;case 38:f=c.metaKey?t.contentHeight:c.altKey?t.containerHeight:30;break;case 39:h=c.metaKey?t.contentWidth:c.altKey?t.containerWidth:30;break;case 40:f=c.metaKey?-t.contentHeight:c.altKey?-t.containerHeight:-30;break;case 33:f=90;break;case 32:f=c.shiftKey?90:-90;break;case 34:f=-90;break;case 35:f=c.ctrlKey?-t.contentHeight:-t.containerHeight;break;case 36:f=c.ctrlKey?e.scrollTop:t.containerHeight;break;default:return}l(e,"top",e.scrollTop-f),l(e,"left",e.scrollLeft+h),s(e),o=i(h,f),o&&c.preventDefault()}}})}var a=e("../../lib/helper"),r=e("../../lib/dom"),o=e("../instances"),s=e("../update-geometry"),l=e("../update-scroll");t.exports=function(e){n(e,o.get(e))}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var a=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===a&&n>0||a>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}function n(e){var t=e.deltaX,i=-1*e.deltaY;return void 0!==t&&void 0!==i||(t=-1*e.wheelDeltaX/6,i=e.wheelDeltaY/6),e.deltaMode&&1===e.deltaMode&&(t*=10,i*=10),t!==t&&i!==i&&(t=0,i=e.wheelDelta),e.shiftKey?[-i,-t]:[t,i]}function a(t,i){var n=e.querySelector("textarea:hover, select[multiple]:hover, .ps-child:hover");if(n){if(!window.getComputedStyle(n).overflow.match(/(scroll|auto)/))return!1;var a=n.scrollHeight-n.clientHeight;if(a>0&&!(0===n.scrollTop&&i>0||n.scrollTop===a&&i<0))return!0;var r=n.scrollLeft-n.clientWidth;if(r>0&&!(0===n.scrollLeft&&t<0||n.scrollLeft===r&&t>0))return!0}return!1}function s(s){var c=n(s),d=c[0],u=c[1];a(d,u)||(l=!1,t.settings.useBothWheelAxes?t.scrollbarYActive&&!t.scrollbarXActive?(u?o(e,"top",e.scrollTop-u*t.settings.wheelSpeed):o(e,"top",e.scrollTop+d*t.settings.wheelSpeed),l=!0):t.scrollbarXActive&&!t.scrollbarYActive&&(d?o(e,"left",e.scrollLeft+d*t.settings.wheelSpeed):o(e,"left",e.scrollLeft-u*t.settings.wheelSpeed),l=!0):(o(e,"top",e.scrollTop-u*t.settings.wheelSpeed),o(e,"left",e.scrollLeft+d*t.settings.wheelSpeed)),r(e),(l=l||i(d,u))&&(s.stopPropagation(),s.preventDefault()))}var l=!1;void 0!==window.onwheel?t.event.bind(e,"wheel",s):void 0!==window.onmousewheel&&t.event.bind(e,"mousewheel",s)}var a=e("../instances"),r=e("../update-geometry"),o=e("../update-scroll");t.exports=function(e){n(e,a.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(e,t,i){"use strict";function n(e,t){t.event.bind(e,"scroll",function(){r(e)})}var a=e("../instances"),r=e("../update-geometry");t.exports=function(e){n(e,a.get(e))}},{"../instances":18,"../update-geometry":19}],15:[function(e,t,i){"use strict";function n(e,t){function i(){var e=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===e.toString().length?null:e.getRangeAt(0).commonAncestorContainer}function n(){c||(c=setInterval(function(){if(!r.get(e))return void clearInterval(c);s(e,"top",e.scrollTop+d.top),s(e,"left",e.scrollLeft+d.left),o(e)},50))}function l(){c&&(clearInterval(c),c=null),a.stopScrolling(e)}var c=null,d={top:0,left:0},u=!1;t.event.bind(t.ownerDocument,"selectionchange",function(){e.contains(i())?u=!0:(u=!1,l())}),t.event.bind(window,"mouseup",function(){u&&(u=!1,l())}),t.event.bind(window,"keyup",function(){u&&(u=!1,l())}),t.event.bind(window,"mousemove",function(t){if(u){var i={x:t.pageX,y:t.pageY},r={left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight};i.x<r.left+3?(d.left=-5,a.startScrolling(e,"x")):i.x>r.right-3?(d.left=5,a.startScrolling(e,"x")):d.left=0,i.y<r.top+3?(d.top=r.top+3-i.y<5?-5:-20,a.startScrolling(e,"y")):i.y>r.bottom-3?(d.top=i.y-r.bottom+3<5?5:20,a.startScrolling(e,"y")):d.top=0,0===d.top&&0===d.left?l():n()}})}var a=e("../../lib/helper"),r=e("../instances"),o=e("../update-geometry"),s=e("../update-scroll");t.exports=function(e){n(e,r.get(e))}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(e,t,i){"use strict";function n(e,t,i,n){function a(i,n){var a=e.scrollTop,r=e.scrollLeft,o=Math.abs(i),s=Math.abs(n);if(s>o){if(n<0&&a===t.contentHeight-t.containerHeight||n>0&&0===a)return!t.settings.swipePropagation}else if(o>s&&(i<0&&r===t.contentWidth-t.containerWidth||i>0&&0===r))return!t.settings.swipePropagation;return!0}function l(t,i){s(e,"top",e.scrollTop-i),s(e,"left",e.scrollLeft-t),o(e)}function c(){w=!0}function d(){w=!1}function u(e){return e.targetTouches?e.targetTouches[0]:e}function h(e){return!(!e.targetTouches||1!==e.targetTouches.length)||!(!e.pointerType||"mouse"===e.pointerType||e.pointerType===e.MSPOINTER_TYPE_MOUSE)}function f(e){if(h(e)){y=!0;var t=u(e);g.pageX=t.pageX,g.pageY=t.pageY,v=(new Date).getTime(),null!==b&&clearInterval(b),e.stopPropagation()}}function p(e){if(!y&&t.settings.swipePropagation&&f(e),!w&&y&&h(e)){var i=u(e),n={pageX:i.pageX,pageY:i.pageY},r=n.pageX-g.pageX,o=n.pageY-g.pageY;l(r,o),g=n;var s=(new Date).getTime(),c=s-v;c>0&&(_.x=r/c,_.y=o/c,v=s),a(r,o)&&(e.stopPropagation(),e.preventDefault())}}function m(){!w&&y&&(y=!1,clearInterval(b),b=setInterval(function(){return r.get(e)&&(_.x||_.y)?Math.abs(_.x)<.01&&Math.abs(_.y)<.01?void clearInterval(b):(l(30*_.x,30*_.y),_.x*=.8,void(_.y*=.8)):void clearInterval(b)},10))}var g={},v=0,_={},b=null,w=!1,y=!1;i?(t.event.bind(window,"touchstart",c),t.event.bind(window,"touchend",d),t.event.bind(e,"touchstart",f),t.event.bind(e,"touchmove",p),t.event.bind(e,"touchend",m)):n&&(window.PointerEvent?(t.event.bind(window,"pointerdown",c),t.event.bind(window,"pointerup",d),t.event.bind(e,"pointerdown",f),t.event.bind(e,"pointermove",p),t.event.bind(e,"pointerup",m)):window.MSPointerEvent&&(t.event.bind(window,"MSPointerDown",c),t.event.bind(window,"MSPointerUp",d),t.event.bind(e,"MSPointerDown",f),t.event.bind(e,"MSPointerMove",p),t.event.bind(e,"MSPointerUp",m)))}var a=e("../../lib/helper"),r=e("../instances"),o=e("../update-geometry"),s=e("../update-scroll");t.exports=function(e){if(a.env.supportsTouch||a.env.supportsIePointer){n(e,r.get(e),a.env.supportsTouch,a.env.supportsIePointer)}}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(e,t,i){"use strict";var n=e("../lib/helper"),a=e("../lib/class"),r=e("./instances"),o=e("./update-geometry"),s={"click-rail":e("./handler/click-rail"),"drag-scrollbar":e("./handler/drag-scrollbar"),keyboard:e("./handler/keyboard"),wheel:e("./handler/mouse-wheel"),touch:e("./handler/touch"),selection:e("./handler/selection")},l=e("./handler/native-scroll");t.exports=function(e,t){t="object"==typeof t?t:{},a.add(e,"ps-container");var i=r.add(e);i.settings=n.extend(i.settings,t),a.add(e,"ps-theme-"+i.settings.theme),i.settings.handlers.forEach(function(t){s[t](e)}),l(e),o(e)}},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(e,t,i){"use strict";function n(e){function t(){l.add(e,"ps-focus")}function i(){l.remove(e,"ps-focus")}var n=this;n.settings=s.clone(c),n.containerWidth=null,n.containerHeight=null,n.contentWidth=null,n.contentHeight=null,n.isRtl="rtl"===d.css(e,"direction"),n.isNegativeScroll=function(){var t=e.scrollLeft,i=null;return e.scrollLeft=-1,i=e.scrollLeft<0,e.scrollLeft=t,i}(),n.negativeScrollAdjustment=n.isNegativeScroll?e.scrollWidth-e.clientWidth:0,n.event=new u,n.ownerDocument=e.ownerDocument||document,n.scrollbarXRail=d.appendTo(d.e("div","ps-scrollbar-x-rail"),e),n.scrollbarX=d.appendTo(d.e("div","ps-scrollbar-x"),n.scrollbarXRail),n.scrollbarX.setAttribute("tabindex",0),n.event.bind(n.scrollbarX,"focus",t),n.event.bind(n.scrollbarX,"blur",i),n.scrollbarXActive=null,n.scrollbarXWidth=null,n.scrollbarXLeft=null,n.scrollbarXBottom=s.toInt(d.css(n.scrollbarXRail,"bottom")),n.isScrollbarXUsingBottom=n.scrollbarXBottom===n.scrollbarXBottom,n.scrollbarXTop=n.isScrollbarXUsingBottom?null:s.toInt(d.css(n.scrollbarXRail,"top")),n.railBorderXWidth=s.toInt(d.css(n.scrollbarXRail,"borderLeftWidth"))+s.toInt(d.css(n.scrollbarXRail,"borderRightWidth")),d.css(n.scrollbarXRail,"display","block"),n.railXMarginWidth=s.toInt(d.css(n.scrollbarXRail,"marginLeft"))+s.toInt(d.css(n.scrollbarXRail,"marginRight")),d.css(n.scrollbarXRail,"display",""),n.railXWidth=null,n.railXRatio=null,n.scrollbarYRail=d.appendTo(d.e("div","ps-scrollbar-y-rail"),e),n.scrollbarY=d.appendTo(d.e("div","ps-scrollbar-y"),n.scrollbarYRail),n.scrollbarY.setAttribute("tabindex",0),n.event.bind(n.scrollbarY,"focus",t),n.event.bind(n.scrollbarY,"blur",i),n.scrollbarYActive=null,n.scrollbarYHeight=null,n.scrollbarYTop=null,n.scrollbarYRight=s.toInt(d.css(n.scrollbarYRail,"right")),n.isScrollbarYUsingRight=n.scrollbarYRight===n.scrollbarYRight,n.scrollbarYLeft=n.isScrollbarYUsingRight?null:s.toInt(d.css(n.scrollbarYRail,"left")),n.scrollbarYOuterWidth=n.isRtl?s.outerWidth(n.scrollbarY):null,n.railBorderYWidth=s.toInt(d.css(n.scrollbarYRail,"borderTopWidth"))+s.toInt(d.css(n.scrollbarYRail,"borderBottomWidth")),d.css(n.scrollbarYRail,"display","block"),n.railYMarginHeight=s.toInt(d.css(n.scrollbarYRail,"marginTop"))+s.toInt(d.css(n.scrollbarYRail,"marginBottom")),d.css(n.scrollbarYRail,"display",""),n.railYHeight=null,n.railYRatio=null}function a(e){return e.getAttribute("data-ps-id")}function r(e,t){e.setAttribute("data-ps-id",t)}function o(e){e.removeAttribute("data-ps-id")}var s=e("../lib/helper"),l=e("../lib/class"),c=e("./default-setting"),d=e("../lib/dom"),u=e("../lib/event-manager"),h=e("../lib/guid"),f={};i.add=function(e){var t=h();return r(e,t),f[t]=new n(e),f[t]},i.remove=function(e){delete f[a(e)],o(e)},i.get=function(e){return f[a(e)]}},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(e,t,i){"use strict";function n(e,t){return e.settings.minScrollbarLength&&(t=Math.max(t,e.settings.minScrollbarLength)),e.settings.maxScrollbarLength&&(t=Math.min(t,e.settings.maxScrollbarLength)),t}function a(e,t){var i={width:t.railXWidth};t.isRtl?i.left=t.negativeScrollAdjustment+e.scrollLeft+t.containerWidth-t.contentWidth:i.left=e.scrollLeft,t.isScrollbarXUsingBottom?i.bottom=t.scrollbarXBottom-e.scrollTop:i.top=t.scrollbarXTop+e.scrollTop,s.css(t.scrollbarXRail,i);var n={top:e.scrollTop,height:t.railYHeight};t.isScrollbarYUsingRight?t.isRtl?n.right=t.contentWidth-(t.negativeScrollAdjustment+e.scrollLeft)-t.scrollbarYRight-t.scrollbarYOuterWidth:n.right=t.scrollbarYRight-e.scrollLeft:t.isRtl?n.left=t.negativeScrollAdjustment+e.scrollLeft+2*t.containerWidth-t.contentWidth-t.scrollbarYLeft-t.scrollbarYOuterWidth:n.left=t.scrollbarYLeft+e.scrollLeft,s.css(t.scrollbarYRail,n),s.css(t.scrollbarX,{left:t.scrollbarXLeft,width:t.scrollbarXWidth-t.railBorderXWidth}),s.css(t.scrollbarY,{top:t.scrollbarYTop,height:t.scrollbarYHeight-t.railBorderYWidth})}var r=e("../lib/helper"),o=e("../lib/class"),s=e("../lib/dom"),l=e("./instances"),c=e("./update-scroll");t.exports=function(e){var t=l.get(e);t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight;var i;e.contains(t.scrollbarXRail)||(i=s.queryChildren(e,".ps-scrollbar-x-rail"),i.length>0&&i.forEach(function(e){s.remove(e)}),s.appendTo(t.scrollbarXRail,e)),e.contains(t.scrollbarYRail)||(i=s.queryChildren(e,".ps-scrollbar-y-rail"),i.length>0&&i.forEach(function(e){s.remove(e)}),s.appendTo(t.scrollbarYRail,e)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset<t.contentWidth?(t.scrollbarXActive=!0,t.railXWidth=t.containerWidth-t.railXMarginWidth,t.railXRatio=t.containerWidth/t.railXWidth,t.scrollbarXWidth=n(t,r.toInt(t.railXWidth*t.containerWidth/t.contentWidth)),t.scrollbarXLeft=r.toInt((t.negativeScrollAdjustment+e.scrollLeft)*(t.railXWidth-t.scrollbarXWidth)/(t.contentWidth-t.containerWidth))):t.scrollbarXActive=!1,!t.settings.suppressScrollY&&t.containerHeight+t.settings.scrollYMarginOffset<t.contentHeight?(t.scrollbarYActive=!0,t.railYHeight=t.containerHeight-t.railYMarginHeight,t.railYRatio=t.containerHeight/t.railYHeight,t.scrollbarYHeight=n(t,r.toInt(t.railYHeight*t.containerHeight/t.contentHeight)),t.scrollbarYTop=r.toInt(e.scrollTop*(t.railYHeight-t.scrollbarYHeight)/(t.contentHeight-t.containerHeight))):t.scrollbarYActive=!1,t.scrollbarXLeft>=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),a(e,t),t.scrollbarXActive?o.add(e,"ps-active-x"):(o.remove(e,"ps-active-x"),t.scrollbarXWidth=0,t.scrollbarXLeft=0,c(e,"left",0)),t.scrollbarYActive?o.add(e,"ps-active-y"):(o.remove(e,"ps-active-y"),t.scrollbarYHeight=0,t.scrollbarYTop=0,c(e,"top",0))}},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(e,t,i){"use strict";var n,a,r=e("./instances"),o=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!0),t};t.exports=function(e,t,i){if(void 0===e)throw"You must provide an element to the update-scroll function";if(void 0===t)throw"You must provide an axis to the update-scroll function";if(void 0===i)throw"You must provide a value to the update-scroll function";"top"===t&&i<=0&&(e.scrollTop=i=0,e.dispatchEvent(o("ps-y-reach-start"))),"left"===t&&i<=0&&(e.scrollLeft=i=0,e.dispatchEvent(o("ps-x-reach-start")));var s=r.get(e);"top"===t&&i>=s.contentHeight-s.containerHeight&&(i=s.contentHeight-s.containerHeight,i-e.scrollTop<=1?i=e.scrollTop:e.scrollTop=i,e.dispatchEvent(o("ps-y-reach-end"))),"left"===t&&i>=s.contentWidth-s.containerWidth&&(i=s.contentWidth-s.containerWidth,i-e.scrollLeft<=1?i=e.scrollLeft:e.scrollLeft=i,e.dispatchEvent(o("ps-x-reach-end"))),n||(n=e.scrollTop),a||(a=e.scrollLeft),"top"===t&&i<n&&e.dispatchEvent(o("ps-scroll-up")),"top"===t&&i>n&&e.dispatchEvent(o("ps-scroll-down")),"left"===t&&i<a&&e.dispatchEvent(o("ps-scroll-left")),"left"===t&&i>a&&e.dispatchEvent(o("ps-scroll-right")),"top"===t&&(e.scrollTop=n=i,e.dispatchEvent(o("ps-scroll-y"))),"left"===t&&(e.scrollLeft=a=i,e.dispatchEvent(o("ps-scroll-x")))}},{"./instances":18}],21:[function(e,t,i){"use strict";var n=e("../lib/helper"),a=e("../lib/dom"),r=e("./instances"),o=e("./update-geometry"),s=e("./update-scroll");t.exports=function(e){var t=r.get(e);t&&(t.negativeScrollAdjustment=t.isNegativeScroll?e.scrollWidth-e.clientWidth:0,a.css(t.scrollbarXRail,"display","block"),a.css(t.scrollbarYRail,"display","block"),t.railXMarginWidth=n.toInt(a.css(t.scrollbarXRail,"marginLeft"))+n.toInt(a.css(t.scrollbarXRail,"marginRight")),t.railYMarginHeight=n.toInt(a.css(t.scrollbarYRail,"marginTop"))+n.toInt(a.css(t.scrollbarYRail,"marginBottom")),a.css(t.scrollbarXRail,"display","none"),a.css(t.scrollbarYRail,"display","none"),o(e),s(e,"top",e.scrollTop),s(e,"left",e.scrollLeft),a.css(t.scrollbarXRail,"display",""),a.css(t.scrollbarYRail,"display",""))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]),define("WoltLabSuite/Core/Date/Util",["Language"],function(e){"use strict";return{formatDate:function(t){return this.format(t,e.get("wcf.date.dateFormat"))},formatTime:function(t){return this.format(t,e.get("wcf.date.timeFormat"))},formatDateTime:function(t){return this.format(t,e.get("wcf.date.dateTimeFormat").replace(/%date%/,e.get("wcf.date.dateFormat")).replace(/%time%/,e.get("wcf.date.timeFormat")))},format:function(t,i){var n,a="";"c"===i&&(i="Y-m-dTH:i:sP");for(var r=0,o=i.length;r<o;r++){switch(i[r]){case"s":n=("0"+t.getSeconds().toString()).slice(-2);break;case"i":n=t.getMinutes(),n<10&&(n="0"+n);break;case"a":n=t.getHours()>11?"pm":"am";break;case"g":n=t.getHours(),0===n?n=12:n>12&&(n-=12);break;case"h":n=t.getHours(),0===n?n=12:n>12&&(n-=12),n=("0"+n.toString()).slice(-2);break
+;case"A":n=t.getHours()>11?"PM":"AM";break;case"G":n=t.getHours();break;case"H":n=t.getHours(),n=("0"+n.toString()).slice(-2);break;case"d":n=t.getDate(),n=("0"+n.toString()).slice(-2);break;case"j":n=t.getDate();break;case"l":n=e.get("__days")[t.getDay()];break;case"D":n=e.get("__daysShort")[t.getDay()];break;case"S":n="";break;case"m":n=t.getMonth()+1,n=("0"+n.toString()).slice(-2);break;case"n":n=t.getMonth()+1;break;case"F":n=e.get("__months")[t.getMonth()];break;case"M":n=e.get("__monthsShort")[t.getMonth()];break;case"y":n=t.getFullYear().toString().substr(2);break;case"Y":n=t.getFullYear();break;case"P":var s=t.getTimezoneOffset();n=s>0?"-":"+",s=Math.abs(s),n+=("0"+(~~(s/60)).toString()).slice(-2),n+=":",n+=("0"+(s%60).toString()).slice(-2);break;case"r":n=t.toString();break;case"U":n=Math.round(t.getTime()/1e3);break;case"\\":n="",r+1<o&&(n=i[++r]);break;default:n=i[r]}a+=n}return a},gmdate:function(e){return e instanceof Date||(e=new Date),Math.round(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDay(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds())/1e3)},getTimeElement:function(t){var i=elCreate("time");i.className="datetime";var n=this.formatDate(t),a=this.formatTime(t);return elAttr(i,"datetime",this.format(t,"c")),elData(i,"timestamp",(t.getTime()-t.getMilliseconds())/1e3),elData(i,"date",n),elData(i,"time",a),elData(i,"offset",60*t.getTimezoneOffset()),t.getTime()>Date.now()&&(elData(i,"is-future-date","true"),i.textContent=e.get("wcf.date.dateTimeFormat").replace("%time%",a).replace("%date%",n)),i},getTimezoneDate:function(e,t){var i=new Date(e),n=6e4*i.getTimezoneOffset();return new Date(e+n+t)}}}),define("WoltLabSuite/Core/Timer/Repeating",[],function(){"use strict";function e(e,t){if("function"!=typeof e)throw new TypeError("Expected a valid callback as first argument.");if(t<0||t>864e5)throw new RangeError("Invalid delta "+t+". Delta must be in the interval [0, 86400000].");this._callback=e.bind(void 0,this),this._delta=t,this._timer=void 0,this.restart()}return e.prototype={restart:function(){this.stop(),this._timer=setInterval(this._callback,this._delta)},stop:function(){void 0!==this._timer&&(clearInterval(this._timer),this._timer=void 0)},setDelta:function(e){this._delta=e,this.restart()}},e}),define("WoltLabSuite/Core/Date/Time/Relative",["Dom/ChangeListener","Language","WoltLabSuite/Core/Date/Util","WoltLabSuite/Core/Timer/Repeating"],function(e,t,i,n){"use strict";var a=elByTag("time"),r=!0,o=!1,s=null;return{setup:function(){new n(this._refresh.bind(this),6e4),e.add("WoltLabSuite/Core/Date/Time/Relative",this._refresh.bind(this)),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this))},_onVisibilityChange:function(){document.hidden?(r=!1,o=!1):(r=!0,o&&(this._refresh(),o=!1))},_refresh:function(){if(!r)return void(o||(o=!0));var e=new Date,n=(e.getTime()-e.getMilliseconds())/1e3;null===s&&(s=n-window.TIME_NOW);for(var l=0,c=a.length;l<c;l++){var d=a[l];if(d.classList.contains("datetime")&&!elData(d,"is-future-date")){var u=~~elData(d,"timestamp")+s,h=elData(d,"date"),f=elData(d,"time"),p=elData(d,"offset");if(elAttr(d,"title")||elAttr(d,"title",t.get("wcf.date.dateTimeFormat").replace(/%date%/,h).replace(/%time%/,f)),u>=n||n<u+60)d.textContent=t.get("wcf.date.relative.now");else if(n<u+3540){var m=Math.max(Math.round((n-u)/60),1);d.textContent=t.get("wcf.date.relative.minutes",{minutes:m})}else if(n<u+86400){var g=Math.round((n-u)/3600);d.textContent=t.get("wcf.date.relative.hours",{hours:g})}else if(n<u+518400){var v=new Date(e.getFullYear(),e.getMonth(),e.getDate()),_=Math.ceil((v/1e3-u)/86400),b=i.getTimezoneDate(1e3*u,1e3*p),w=b.getDay(),y=t.get("__days")[w];d.textContent=t.get("wcf.date.relative.pastDays",{days:_,day:y,time:f})}else d.textContent=t.get("wcf.date.shortDateTimeFormat").replace(/%date%/,h).replace(/%time%/,f)}}}}}),define("WoltLabSuite/Core/Ui/Page/Menu/Abstract",["Core","Environment","EventHandler","Language","ObjectMap","Dom/Traverse","Dom/Util","Ui/Screen"],function(e,t,i,n,a,r,o,s){"use strict";function l(e,t,i){this.init(e,t,i)}var c=elById("pageContainer"),d="";return l.prototype={init:function(e,n,r){if("packageInstallationSetup"!==elData(document.body,"template")){this._activeList=[],this._depth=0,this._enabled=!0,this._eventIdentifier=e,this._items=new a,this._menu=elById(n),this._removeActiveList=!1;var s=this.open.bind(this);this._button=elBySel(r),this._button.addEventListener(WCF_CLICK_EVENT,s),this._initItems(),this._initHeader(),i.add(this._eventIdentifier,"open",s),i.add(this._eventIdentifier,"close",this.close.bind(this)),i.add(this._eventIdentifier,"updateButtonState",this._updateButtonState.bind(this));var l,c=elByClass("menuOverlayItemList",this._menu);this._menu.addEventListener("animationend",function(){if(!this._menu.classList.contains("open"))for(var e=0,t=c.length;e<t;e++)l=c[e],l.classList.remove("active"),l.classList.remove("hidden")}.bind(this)),this._menu.children[0].addEventListener("transitionend",function(){if(this._menu.classList.add("allowScroll"),this._removeActiveList){this._removeActiveList=!1;var e=this._activeList.pop();e&&e.classList.remove("activeList")}}.bind(this));var d=elCreate("div");d.className="menuOverlayMobileBackdrop",d.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),o.insertAfter(d,this._menu),this._updateButtonState(),"android"===t.platform()&&this._initializeAndroid()}},open:function(e){return!!this._enabled&&(e instanceof Event&&e.preventDefault(),this._menu.classList.add("open"),this._menu.classList.add("allowScroll"),this._menu.children[0].classList.add("activeList"),s.scrollDisable(),c.classList.add("menuOverlay-"+this._menu.id),s.pageOverlayOpen(),!0)},close:function(e){return e instanceof Event&&e.preventDefault(),!!this._menu.classList.contains("open")&&(this._menu.classList.remove("open"),s.scrollEnable(),s.pageOverlayClose(),c.classList.remove("menuOverlay-"+this._menu.id),!0)},enable:function(){this._enabled=!0},disable:function(){this._enabled=!1,this.close(!0)},_initializeAndroid:function(){var t,i,n;switch(this._menu.id){case"pageUserMenuMobile":t="right";break;case"pageMainMenuMobile":t="left";break;default:return}i=this._menu.nextElementSibling,n=null,document.addEventListener("touchstart",function(i){var a,r,o,l;if(a=i.touches,r=this._menu.classList.contains("open"),"left"===t?(o=!r&&a[0].clientX<20,l=r&&Math.abs(this._menu.offsetWidth-a[0].clientX)<20):"right"===t&&(o=r&&Math.abs(document.body.clientWidth-this._menu.offsetWidth-a[0].clientX)<20,l=!r&&document.body.clientWidth-a[0].clientX<20),a.length>1)return void(d&&e.triggerEvent(document,"touchend"));if(!d&&(o||l)){if(s.pageOverlayIsActive()){for(var u=!1,h=0;h<c.classList.length;h++)c.classList[h]==="menuOverlay-"+this._menu.id&&(u=!0);if(!u)return}document.documentElement.classList.contains("redactorActive")||(n={x:a[0].clientX,y:a[0].clientY},o&&(d="left"),l&&(d="right"))}}.bind(this)),document.addEventListener("touchend",function(e){if(d&&null!==n){if(!this._menu.classList.contains("open"))return n=null,void(d="");var a;a=e?e.changedTouches[0].clientX:n.x,this._menu.classList.add("androidMenuTouchEnd"),this._menu.style.removeProperty("transform"),i.style.removeProperty(t),this._menu.addEventListener("transitionend",function(){this._menu.classList.remove("androidMenuTouchEnd")}.bind(this),{once:!0}),"left"===t?("left"===d&&a<n.x+100&&this.close(),"right"===d&&a<n.x-100&&this.close()):"right"===t&&("left"===d&&a>n.x+100&&this.close(),"right"===d&&a>n.x-100&&this.close()),n=null,d=""}}.bind(this)),document.addEventListener("touchmove",function(e){if(d&&null!==n){var a=e.touches,r=!1,o=!1;"left"===d&&(r=a[0].clientX>n.x+5),"right"===d&&(r=a[0].clientX<n.x-5),o=Math.abs(a[0].clientY-n.y)>20;var s=this._menu.classList.contains("open");if(s||!r||o||(this.open(),s=!0),s){var l=a[0].clientX;"right"===t&&(l=document.body.clientWidth-l),l>this._menu.offsetWidth&&(l=this._menu.offsetWidth),l<0&&(l=0),this._menu.style.setProperty("transform","translateX("+("left"===t?1:-1)*(l-this._menu.offsetWidth)+"px)"),i.style.setProperty(t,Math.min(this._menu.offsetWidth,l)+"px")}}}.bind(this))},_initItems:function(){elBySelAll(".menuOverlayItemLink",this._menu,this._initItem.bind(this))},_initItem:function(e){var t=e.parentNode,n=elData(t,"more");if(n)return void e.addEventListener(WCF_CLICK_EVENT,function(a){a.preventDefault(),a.stopPropagation(),i.fire(this._eventIdentifier,"more",{handler:this,identifier:n,item:e,parent:t})}.bind(this));var a,o=e.nextElementSibling;if(null!==o)if("OL"!==o.nodeName&&o.classList.contains("menuOverlayItemLinkIcon"))for(a=elCreate("span"),a.className="menuOverlayItemWrapper",t.insertBefore(a,e),a.appendChild(e);a.nextElementSibling;)a.appendChild(a.nextElementSibling);else{var s="#"!==elAttr(e,"href"),l=t.parentNode,c=elData(o,"title");this._items.set(e,{itemList:o,parentItemList:l}),""===c&&(c=r.childByClass(e,"menuOverlayItemTitle").textContent,elData(o,"title",c));var d=this._showItemList.bind(this,e);if(s){a=elCreate("span"),a.className="menuOverlayItemWrapper",t.insertBefore(a,e),a.appendChild(e);var u=elCreate("a");elAttr(u,"href","#"),u.className="menuOverlayItemLinkIcon"+(e.classList.contains("active")?" active":""),u.innerHTML='<span class="icon icon24 fa-angle-right"></span>',u.addEventListener(WCF_CLICK_EVENT,d),a.appendChild(u)}else e.classList.add("menuOverlayItemLinkMore"),e.addEventListener(WCF_CLICK_EVENT,d);var h=elCreate("li");h.className="menuOverlayHeader",a=elCreate("span"),a.className="menuOverlayItemWrapper";var f=elCreate("a");elAttr(f,"href","#"),f.className="menuOverlayItemLink menuOverlayBackLink",f.textContent=elData(l,"title"),f.addEventListener(WCF_CLICK_EVENT,this._hideItemList.bind(this,e));var p=elCreate("a");if(elAttr(p,"href","#"),p.className="menuOverlayItemLinkIcon",p.innerHTML='<span class="icon icon24 fa-times"></span>',p.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),a.appendChild(f),a.appendChild(p),h.appendChild(a),o.insertBefore(h,o.firstElementChild),!h.nextElementSibling.classList.contains("menuOverlayTitle")){var m=elCreate("li");m.className="menuOverlayTitle";var g=elCreate("span");g.textContent=c,m.appendChild(g),o.insertBefore(m,h.nextElementSibling)}}},_initHeader:function(){var e=elCreate("li");e.className="menuOverlayHeader";var t=elCreate("span");t.className="menuOverlayItemWrapper",e.appendChild(t);var i=elCreate("span");i.className="menuOverlayLogoWrapper",t.appendChild(i);var n=elCreate("span");n.className="menuOverlayLogo",n.style.setProperty("background-image",'url("'+elData(this._menu,"page-logo")+'")',""),i.appendChild(n);var a=elCreate("a");elAttr(a,"href","#"),a.className="menuOverlayItemLinkIcon",a.innerHTML='<span class="icon icon24 fa-times"></span>',a.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),t.appendChild(a);var o=r.childByClass(this._menu,"menuOverlayItemList");o.insertBefore(e,o.firstElementChild)},_hideItemList:function(e,t){t instanceof Event&&t.preventDefault(),this._menu.classList.remove("allowScroll"),this._removeActiveList=!0,this._items.get(e).parentItemList.classList.remove("hidden"),this._updateDepth(!1)},_showItemList:function(e,t){t instanceof Event&&t.preventDefault();var n=this._items.get(e),a=elData(n.itemList,"load");if(a&&!elDataBool(e,"loaded")){var r=t.currentTarget.firstElementChild;return r.classList.contains("fa-angle-right")&&(r.classList.remove("fa-angle-right"),r.classList.add("fa-spinner")),void i.fire(this._eventIdentifier,"load_"+a)}this._menu.classList.remove("allowScroll"),n.itemList.classList.add("activeList"),n.parentItemList.classList.add("hidden"),this._activeList.push(n.itemList),this._updateDepth(!0)},_updateDepth:function(e){this._depth+=e?1:-1;var t=-100*this._depth;"rtl"===n.get("wcf.global.pageDirection")&&(t*=-1),this._menu.children[0].style.setProperty("transform","translateX("+t+"%)","")},_updateButtonState:function(){var e=!1,t=elBySel(".menuOverlayItemList",this._menu);elBySelAll(".badgeUpdate",this._menu,function(i){~~i.textContent>0&&i.closest(".menuOverlayItemList")===t&&(e=!0)}),this._button.classList[e?"add":"remove"]("pageMenuMobileButtonHasContent")}},l}),define("WoltLabSuite/Core/Ui/Page/Menu/Main",["Core","Language","Dom/Traverse","./Abstract"],function(e,t,i,n){"use strict";function a(){this.init()}var r=null,o=null,s=null,l=null,c=null;return e.inherit(a,n,{init:function(){a._super.prototype.init.call(this,"com.woltlab.wcf.MainMenuMobile","pageMainMenuMobile","#pageHeader .mainMenu"),r=elById("pageMainMenuMobilePageOptionsTitle"),null!==r&&(s=i.childByClass(r,"menuOverlayItemList"),l=elBySel(".jsPageNavigationIcons"),c=function(e){this.close(),e.stopPropagation()}.bind(this)),elAttr(this._button,"aria-label",t.get("wcf.menu.page")),elAttr(this._button,"role","button")},open:function(e){if(!a._super.prototype.open.call(this,e))return!1;if(null===r)return!0;if(o=l&&l.childElementCount>0){for(var t,i;l.childElementCount;)t=l.children[0],t.classList.add("menuOverlayItem"),t.classList.add("menuOverlayItemOption"),t.addEventListener(WCF_CLICK_EVENT,c),i=t.children[0],i.classList.add("menuOverlayItemLink"),i.classList.add("box24"),i.children[1].classList.remove("invisible"),i.children[1].classList.add("menuOverlayItemTitle"),r.parentNode.insertBefore(t,r.nextSibling);elShow(r)}else elHide(r);return!0},close:function(e){if(!a._super.prototype.close.call(this,e))return!1;if(o){elHide(r);for(var t,i=r.nextElementSibling;i&&i.classList.contains("menuOverlayItemOption");)i.classList.remove("menuOverlayItem"),i.classList.remove("menuOverlayItemOption"),i.removeEventListener(WCF_CLICK_EVENT,c),t=i.children[0],t.classList.remove("menuOverlayItemLink"),t.classList.remove("box24"),t.children[1].classList.add("invisible"),t.children[1].classList.remove("menuOverlayItemTitle"),l.appendChild(i),i=i.nextElementSibling}return!0}}),a}),define("WoltLabSuite/Core/Ui/Page/Menu/User",["Core","EventHandler","Language","./Abstract"],function(e,t,i,n){"use strict";function a(){this.init()}return e.inherit(a,n,{init:function(){var e=elBySel("#pageUserMenuMobile > .menuOverlayItemList");if(1===e.childElementCount&&e.children[0].classList.contains("menuOverlayTitle"))return void elBySel("#pageHeader .userPanel").classList.add("hideUserPanel");a._super.prototype.init.call(this,"com.woltlab.wcf.UserMenuMobile","pageUserMenuMobile","#pageHeader .userPanel"),t.add("com.woltlab.wcf.userMenu","updateBadge",function(e){elBySelAll(".menuOverlayItemBadge",this._menu,function(t){if(elData(t,"badge-identifier")===e.identifier){var i=elBySel(".badge",t);e.count?(null===i&&(i=elCreate("span"),i.className="badge badgeUpdate",t.appendChild(i)),i.textContent=e.count):null!==i&&elRemove(i),this._updateButtonState()}}.bind(this))}.bind(this)),elAttr(this._button,"aria-label",i.get("wcf.menu.user")),elAttr(this._button,"role","button")},close:function(e){if(void 0!==this._menu){var t=WCF.Dropdown.Interactive.Handler.getOpenDropdown();t?(e.preventDefault(),e.stopPropagation(),t.close()):a._super.prototype.close.call(this,e)}}}),a}),define("WoltLabSuite/Core/Ui/Dropdown/Reusable",["Dictionary","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!n.has(e))throw new Error("Unknown dropdown identifier '"+e+"'");return n.get(e)}var n=new e,a=0;return{init:function(e,i){if(!n.has(e)){var r=elCreate("div");r.id="reusableDropdownGhost"+a++,t.initFragment(r,i),n.set(e,r.id)}},getDropdownMenu:function(e){return t.getDropdownMenu(i(e))},registerCallback:function(e,n){t.registerCallback(i(e),n)},toggleDropdown:function(e,n){t.toggleDropdown(i(e),n)}}}),define("WoltLabSuite/Core/Ui/Mobile",["Core","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Alignment","Ui/CloseOverlay","Ui/Screen","./Page/Menu/Main","./Page/Menu/User","WoltLabSuite/Core/Ui/Dropdown/Reusable"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,f){"use strict";var p=elByClass("buttonGroupNavigation"),m=null,g=null,v=null,_=!1,b=!1,w=new a,y=null,C=elByClass("message"),E=!1,L={},S=null,A=null,I=null,D=[];return{setup:function(i){L=e.extend({enableMobileMenu:!0},i),y=elById("main"),elBySelAll(".sidebar",void 0,function(e){D.push(e)}),t.touch()&&document.documentElement.classList.add("touch"),"desktop"!==t.platform()&&document.documentElement.classList.add("mobile");var n=elBySel(".messageGroupList");n&&(I=elByClass("messageGroup",n)),d.on("screen-md-down",{match:this.enable.bind(this),unmatch:this.disable.bind(this),setup:this._init.bind(this)}),d.on("screen-sm-down",{match:this.enableShadow.bind(this),unmatch:this.disableShadow.bind(this),setup:this.enableShadow.bind(this)}),d.on("screen-md-down",{match:this._enableMobileSidebar.bind(this),unmatch:this._disableMobileSidebar.bind(this),setup:this._setupMobileSidebar.bind(this)}),!t.touch()||"ios"!==t.platform()&&"android"!==t.platform()||d.on("screen-lg",{match:this._enableLGTouchNavigation.bind(this),unmatch:this._disableLGTouchNavigation.bind(this),setup:this._setupLGTouchNavigation.bind(this)})},enable:function(){_=!0,L.enableMobileMenu&&(S.enable(),A.enable())},enableShadow:function(){I&&this.rebuildShadow(I,".messageGroupLink")},disable:function(){_=!1,L.enableMobileMenu&&(S.disable(),A.disable())},disableShadow:function(){I&&this.removeShadow(I),g&&m()},_init:function(){_=!0,this._initSearchBar(),this._initButtonGroupNavigation(),this._initMessages(),this._initMobileMenu(),c.add("WoltLabSuite/Core/Ui/Mobile",this._closeAllMenus.bind(this)),r.add("WoltLabSuite/Core/Ui/Mobile",function(){this._initButtonGroupNavigation(),this._initMessages()}.bind(this))},_initSearchBar:function(){var e=elById("pageHeaderSearch"),n=elById("pageHeaderSearchInput"),a=null;i.add("com.woltlab.wcf.MainMenuMobile","more",function(i){"com.woltlab.wcf.search"===i.identifier&&(i.handler.close(!0),"ios"===t.platform()&&(a=document.body.scrollTop,d.scrollDisable()),e.style.setProperty("top",elById("pageHeader").offsetHeight+"px",""),e.classList.add("open"),n.focus(),"ios"===t.platform()&&(document.body.scrollTop=0))}),y.addEventListener(WCF_CLICK_EVENT,function(){e&&e.classList.remove("open"),"ios"===t.platform()&&null!==a&&(d.scrollEnable(),document.body.scrollTop=a,a=null)})},_initButtonGroupNavigation:function(){for(var e=0,t=p.length;e<t;e++){var i=p[e];if(!i.classList.contains("jsMobileButtonGroupNavigation")){i.classList.add("jsMobileButtonGroupNavigation");var n=elBySel(".buttonList",i);if(0!==n.childElementCount){i.parentNode.classList.add("hasMobileNavigation");var a=elCreate("a");a.className="dropdownLabel";var r=elCreate("span");r.className="icon icon24 fa-ellipsis-v",a.appendChild(r),function(e,t,i){t.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),e.classList.toggle("open")}),i.addEventListener(WCF_CLICK_EVENT,function(t){t.stopPropagation(),e.classList.remove("open")})}(i,a,n),i.insertBefore(a,i.firstChild)}}}},_initMessages:function(){Array.prototype.forEach.call(C,function(e){if(!w.has(e)){var t=elBySel(".jsMobileNavigation",e);if(t){t.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation(),window.setTimeout(function(){t.classList.remove("open")},10)});var i=elBySel(".messageQuickOptions",e);i&&t.childElementCount&&(i.classList.add("active"),i.addEventListener(WCF_CLICK_EVENT,function(n){_&&d.is("screen-sm-down")&&"LABEL"!==n.target.nodeName&&"INPUT"!==n.target.nodeName&&(n.preventDefault(),n.stopPropagation(),this._toggleMobileNavigation(e,i,t))}.bind(this)))}w.add(e)}}.bind(this))},_initMobileMenu:function(){L.enableMobileMenu&&(S=new u,A=new h)},_closeAllMenus:function(){elBySelAll(".jsMobileButtonGroupNavigation.open, .jsMobileNavigation.open",null,function(e){e.classList.remove("open")}),_&&g&&m()},rebuildShadow:function(e,t){for(var i,n,a,r=0,s=e.length;r<s;r++)i=e[r],n=i.parentNode,null===(a=o.childByClass(n,"mobileLinkShadow"))&&elBySel(t,i).href&&(a=elCreate("a"),a.className="mobileLinkShadow",a.href=elBySel(t,i).href,n.appendChild(a),n.classList.add("mobileLinkShadowContainer"))},removeShadow:function(e){for(var t,i,n,a=0,r=e.length;a<r;a++)t=e[a],i=t.parentNode,i.classList.contains("mobileLinkShadowContainer")&&(n=o.childByClass(i,"mobileLinkShadow"),null!==n&&elRemove(n),i.classList.remove("mobileLinkShadowContainer"))},_enableMobileSidebar:function(){E=!0},_disableMobileSidebar:function(){E=!1,D.forEach(function(e){e.classList.remove("open")})},_setupMobileSidebar:function(){D.forEach(function(e){e.addEventListener("mousedown",function(t){E&&t.target===e&&(t.preventDefault(),e.classList.toggle("open"))})}),E=!0},_toggleMobileNavigation:function(e,t,i){if(null===g)g=elCreate("ul"),g.className="dropdownMenu",f.init("com.woltlab.wcf.jsMobileNavigation",g),m=function(){g.classList.remove("dropdownOpen")};else if(g.classList.contains("dropdownOpen")&&(m(),v===e))return;g.innerHTML="",c.execute(),this._rebuildMobileNavigation(i);var n=i.previousElementSibling;if(n&&n.classList.contains("messageFooterButtonsExtra")){var a=elCreate("li");a.className="dropdownDivider",g.appendChild(a),this._rebuildMobileNavigation(n)}l.set(g,t,{horizontal:"right",allowFlip:"vertical"}),g.classList.add("dropdownOpen"),v=e},_setupLGTouchNavigation:function(){b=!0,elBySelAll(".boxMenuHasChildren > a",null,function(e){e.addEventListener("touchstart",function(t){b&&"false"===elAttr(e,"aria-expanded")&&(t.preventDefault(),elAttr(e,"aria-expanded","true"),e.addEventListener("touchend",function(){document.body.addEventListener("touchstart",function(){document.body.addEventListener("touchend",function(t){s.contains(e.parentNode,t.target)||t.target===e.parentNode||elAttr(e,"aria-expanded","false")},{once:!0})},{once:!0})},{once:!0}))})})},_enableLGTouchNavigation:function(){b=!0},_disableLGTouchNavigation:function(){b=!1},_rebuildMobileNavigation:function(t){elBySelAll(".button",t,function(t){if(!t.classList.contains("ignoreMobileNavigation")||t.classList.contains("reactButton")){var i=elCreate("li");t.classList.contains("active")&&(i.className="active"),i.innerHTML='<a href="#">'+elBySel("span:not(.icon)",t).textContent+"</a>",i.children[0].addEventListener(WCF_CLICK_EVENT,function(i){i.preventDefault(),i.stopPropagation(),"A"===t.nodeName?t.click():e.triggerEvent(t,WCF_CLICK_EVENT),m()}),g.appendChild(i)}})}}}),define("WoltLabSuite/Core/Ui/Scroll",["Dom/Util"],function(e){"use strict";var t=null,i=null,n=null,a=null;return{element:function(a,r){if(!(a instanceof Element))throw new TypeError("Expected a valid DOM element.");if(void 0!==r&&"function"!=typeof r)throw new TypeError("Expected a valid callback function.");if(!document.body.contains(a))throw new Error("Element must be part of the visible DOM.");if(null!==t)throw new Error("Cannot scroll to element, a concurrent request is running.");r&&(t=r,null===i&&(i=this._onScroll.bind(this)),window.addEventListener("scroll",i));var o=e.offset(a).top;if(null===n){n=50;var s=elById("pageHeaderPanel");if(null!==s){var l=window.getComputedStyle(s).position;n="fixed"===l||"static"===l?s.offsetHeight:0}}n>0&&(o<=n?o=0:o-=n);var c=window.pageYOffset;window.scrollTo({left:0,top:o,behavior:"smooth"}),window.setTimeout(function(){c===window.pageYOffset&&this._onScroll()}.bind(this),100)},_onScroll:function(){null!==a&&window.clearTimeout(a),a=window.setTimeout(function(){null!==t&&t(),window.removeEventListener("scroll",i),t=null,a=null},100)}}}),define("WoltLabSuite/Core/Ui/TabMenu/Simple",["Dictionary","Environment","EventHandler","Dom/Traverse","Dom/Util"],function(e,t,i,n,a){"use strict";function r(t){this._container=t,this._containers=new e,this._isLegacy=null,this._store=null,this._tabs=new e}return r.prototype={validate:function(){if(!this._container.classList.contains("tabMenuContainer"))return!1;var e=n.childByTag(this._container,"NAV");if(null===e)return!1;var t=elByTag("li",e);if(0===t.length)return!1;var i,r,o,s,l=n.childrenByTag(this._container,"DIV");for(o=0,s=l.length;o<s;o++)i=l[o],r=elData(i,"name"),r||(r=a.identify(i)),elData(i,"name",r),this._containers.set(r,i);var c,d=this._container.id;for(o=0,s=t.length;o<s;o++)if(c=t[o],r=this._getTabName(c)){if(this._tabs.has(r))throw new Error("Tab names must be unique, li[data-name='"+r+"'] (tab menu id: '"+d+"') exists more than once.");if(void 0===(i=this._containers.get(r)))throw new Error("Expected content element for li[data-name='"+r+"'] (tab menu id: '"+d+"').");if(i.parentNode!==this._container)throw new Error("Expected content element '"+r+"' (tab menu id: '"+d+"') to be a direct children.");if(1!==c.childElementCount||"A"!==c.children[0].nodeName)throw new Error("Expected exactly one <a> as children for li[data-name='"+r+"'] (tab menu id: '"+d+"').");this._tabs.set(r,c)}if(!this._tabs.size)throw new Error("Expected at least one tab (tab menu id: '"+d+"').");return this._isLegacy&&(elData(this._container,"is-legacy",!0),this._tabs.forEach(function(e,t){elAttr(e,"aria-controls",t)})),!0},init:function(e){e=e||null,this._tabs.forEach(function(i){if((!e||e.get(elData(i,"name"))!==i)&&(i.children[0].addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this)),"ios"===t.platform())){var n=!1;i.children[0].addEventListener("touchstart",function(){n=!0}),i.children[0].addEventListener("touchmove",function(){n=!1}),i.children[0].addEventListener("touchend",function(e){n&&(n=!1,e.preventDefault(),this._onClick(e))}.bind(this))}}.bind(this));var i=null;if(!e){var n=r.getIdentifierFromHash(),a=null;if(""!==n&&(a=this._tabs.get(n))&&this._container.parentNode.classList.contains("tabMenuContainer")&&(i=this._container),!a){var o=elData(this._container,"preselect")||elData(this._container,"active");"true"!==o&&o||(o=!0),!0===o?this._tabs.forEach(function(e){a||elIsHidden(e)||e.previousElementSibling&&!elIsHidden(e.previousElementSibling)||(a=e)}):"false"!==o&&(a=this._tabs.get(o))}a&&(this._containers.forEach(function(e){e.classList.add("hidden")}),this.select(null,a,!0));var s=elData(this._container,"store");if(s){var l=elCreate("input");l.type="hidden",l.name=s,l.value=elData(this.getActiveTab(),"name"),this._container.appendChild(l),this._store=l}}return i},select:function(e,t,n){if(!(t=t||this._tabs.get(e))){if(~~e==e){e=~~e;var a=0;this._tabs.forEach(function(i){a===e&&(t=i),a++})}if(!t)throw new Error("Expected a valid tab name, '"+e+"' given (tab menu id: '"+this._container.id+"').")}e=e||elData(t,"name");var o=this.getActiveTab(),s=null;if(o){var l=elData(o,"name");if(l===e)return;n||i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"beforeSelect",{tab:o,tabName:l}),o.classList.remove("active"),s=this._containers.get(elData(o,"name")),s.classList.remove("active"),s.classList.add("hidden"),this._isLegacy&&(o.classList.remove("ui-state-active"),s.classList.remove("ui-state-active"))}t.classList.add("active");var c=this._containers.get(e);if(c.classList.add("active"),c.classList.remove("hidden"),this._isLegacy&&(t.classList.add("ui-state-active"),c.classList.add("ui-state-active")),this._store&&(this._store.value=e),!n){i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"select",{active:t,activeName:e,previous:o,previousName:o?elData(o,"name"):null});var d=this._isLegacy&&"function"==typeof window.jQuery?window.jQuery:null;d&&d(this._container).trigger("wcftabsbeforeactivate",{newTab:d(t),oldTab:d(o),newPanel:d(c),oldPanel:d(s)});var u=window.location.href.replace(/#+[^#]*$/,"");r.getIdentifierFromHash()===e?u+=window.location.hash:u+="#"+e,window.history.replaceState(void 0,void 0,u)}require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.scrollToTab(t)})},selectFirstVisible:function(){var e;return this._tabs.forEach(function(t){e||elIsHidden(t)||(e=t)}.bind(this)),e&&this.select(void 0,e,!1),!!e},rebuild:function(){var t=new e;t.merge(this._tabs),this.validate(),this.init(t)},hasTab:function(e){return this._tabs.has(e)},_onClick:function(e){e.preventDefault(),this.select(null,e.currentTarget.parentNode)},_getTabName:function(e){var t=elData(e,"name");return t||1===e.childElementCount&&"A"===e.children[0].nodeName&&e.children[0].href.match(/#([^#]+)$/)&&(t=RegExp.$1,null===elById(t)?t=null:(this._isLegacy=!0,elData(e,"name",t))),t},getActiveTab:function(){return elBySel("#"+this._container.id+" > nav > ul > li.active")},getContainers:function(){return this._containers},getTabs:function(){return this._tabs}},r.getIdentifierFromHash=function(){return window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)?RegExp.$1:""},r}),define("WoltLabSuite/Core/Ui/TabMenu",["Dictionary","EventHandler","Dom/ChangeListener","Dom/Util","Ui/CloseOverlay","Ui/Screen","Ui/Scroll","./TabMenu/Simple"],function(e,t,i,n,a,r,o,s){"use strict";var l=null,c=!1,d=new e;return{setup:function(){this._init(),this._selectErroneousTabs(),i.add("WoltLabSuite/Core/Ui/TabMenu",this._init.bind(this)),a.add("WoltLabSuite/Core/Ui/TabMenu",function(){l&&(l.classList.remove("active"),l=null)}),r.on("screen-sm-down",{enable:this._scrollEnable.bind(this,!1),disable:this._scrollDisable.bind(this),setup:this._scrollEnable.bind(this,!0)}),window.addEventListener("hashchange",function(){var e=s.getIdentifierFromHash(),t=e?elById(e):null;null!==t&&t.classList.contains("tabMenuContent")&&d.forEach(function(t){t.hasTab(e)&&t.select(e)})});var e=s.getIdentifierFromHash();e&&window.setTimeout(function(){var t=elById(e);if(t&&t.classList.contains("tabMenuContent")){var i=window.scrollY||window.pageYOffset;if(i>0){var a=t.parentNode,r=a.offsetTop-50;if(r<0&&(r=0),i>r){var o=n.offset(a).top;o<=50?o=0:o-=50,window.scrollTo(0,o)}}}},100)},_init:function(){for(var e,t,i,a,r,c=elBySelAll(".tabMenuContainer:not(.staticTabMenuContainer)"),u=0,h=c.length;u<h;u++)if(e=c[u],t=n.identify(e),!d.has(t)&&(r=new s(e),r.validate())){a=r.init(),d.set(t,r),a instanceof Element&&(r=this.getTabMenu(a.parentNode.id),r.select(a.id,null,!0)),i=elBySel("#"+t+" > nav > ul"),function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),t.target===e?(e.classList.add("active"),l=e):(e.classList.remove("active"),l=null)})}(i),elBySelAll(".tabMenu, .menu",e,function(e){var t=this._rebuildMenuOverflow.bind(this,e),i=null;elBySel("ul",e).addEventListener("scroll",function(){null!==i&&window.clearTimeout(i),i=window.setTimeout(t,10)})}.bind(this));var f=e.closest("form");if(null!==f){var p=elBySel('input[type="submit"]',f);null!==p&&function(e,t){t.addEventListener(WCF_CLICK_EVENT,function(t){if(!t.defaultPrevented)for(var i,n=elBySelAll("input, select",e),a=0,r=n.length;a<r;a++)if(i=n[a],!i.checkValidity()){t.preventDefault();var s=this.getTabMenu(i.closest(".tabMenuContainer").id);return s.select(elData(i.closest(".tabMenuContent"),"name")),void o.element(i,function(){this.reportValidity()}.bind(i))}}.bind(this))}.bind(this)(e,p)}}},_selectErroneousTabs:function(){d.forEach(function(e){var t=!1;e.getContainers().forEach(function(i){!t&&elByClass("formError",i).length&&(t=!0,e.select(i.id))})})},getTabMenu:function(e){return d.get(e)},_scrollEnable:function(e){c=!0,d.forEach(function(t){var i=t.getActiveTab();e?this._rebuildMenuOverflow(i.closest(".menu, .tabMenu")):this.scrollToTab(i)}.bind(this))},_scrollDisable:function(){c=!1},scrollToTab:function(e){if(c){var t=e.closest("ul"),i=t.clientWidth,n=t.scrollLeft,a=t.scrollWidth;if(i!==a){var r=e.offsetLeft,o=!1;r<n&&(o=!0);var s=!1;if(!o){var l=i-(r-n),d=e.clientWidth;null!==e.nextElementSibling&&(s=!0,d+=20),l<d&&(o=!0)}o&&this._scrollMenu(t,r,n,a,i,s)}}},_scrollMenu:function(e,t,i,n,a,r){r?t-=15:t>0&&(t-=15),t=t<0?0:Math.min(t,n-a),i!==t&&(e.classList.add("enableAnimation"),i<t?e.firstElementChild.style.setProperty("margin-left",i-t+"px",""):e.style.setProperty("padding-left",i-t+"px",""),setTimeout(function(){e.classList.remove("enableAnimation"),e.firstElementChild.style.removeProperty("margin-left"),e.style.removeProperty("padding-left"),e.scrollLeft=t},300))},_rebuildMenuOverflow:function(e){if(c){var t=e.clientWidth,i=elBySel("ul",e),n=i.scrollLeft,a=i.scrollWidth,r=n>0,o=elBySel(".tabMenuOverlayLeft",e);r?(null===o&&(o=elCreate("span"),
+o.className="tabMenuOverlayLeft icon icon24 fa-angle-left",o.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft-~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.insertBefore(o,e.firstChild)),o.classList.add("active")):null!==o&&o.classList.remove("active");var s=t+n<a,l=elBySel(".tabMenuOverlayRight",e);s?(null===l&&(l=elCreate("span"),l.className="tabMenuOverlayRight icon icon24 fa-angle-right",l.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft+~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.appendChild(l)),l.classList.add("active")):null!==l&&l.classList.remove("active")}}}}),define("WoltLabSuite/Core/Ui/FlexibleMenu",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a,r){"use strict";var o=new t,s=new t,l=new t,c=new t;return{setup:function(){null!==elById("mainMenu")&&this.register("mainMenu");var e=elBySel(".navigationHeader");null!==e&&this.register(a.identify(e)),window.addEventListener("resize",this.rebuildAll.bind(this)),i.add("WoltLabSuite/Core/Ui/FlexibleMenu",this.registerTabMenus.bind(this))},register:function(e){var t=elById(e);if(null===t)throw"Expected a valid element id, '"+e+"' does not exist.";if(!o.has(e)){var i=n.childByTag(t,"UL");if(null===i)throw"Expected an <ul> element as child of container '"+e+"'.";o.set(e,t),c.set(e,i),this.rebuild(e)}},registerTabMenus:function(){for(var e=elBySelAll(".tabMenuContainer:not(.jsFlexibleMenuEnabled), .messageTabMenu:not(.jsFlexibleMenuEnabled)"),t=0,i=e.length;t<i;t++){var r=e[t],o=n.childByTag(r,"NAV");null!==o&&(r.classList.add("jsFlexibleMenuEnabled"),this.register(a.identify(o)))}},rebuildAll:function(){o.forEach(function(e,t){this.rebuild(t)}.bind(this))},rebuild:function(t){var i=o.get(t);if(void 0===i)throw"Expected a valid element id, '"+t+"' is unknown.";var d=window.getComputedStyle(i),u=i.parentNode.clientWidth;u-=a.styleAsInt(d,"margin-left"),u-=a.styleAsInt(d,"margin-right");var h=c.get(t),f=n.childrenByTag(h,"LI"),p=s.get(t),m=0;if(void 0!==p){for(var g=0,v=f.length;g<v;g++){var _=f[g];_.classList.contains("dropdown")||elShow(_)}null!==p.parentNode&&(m=a.outerWidth(p))}var b=h.scrollWidth-m,w=[];if(b>u)for(var g=f.length-1;g>=0;g--){var _=f[g];if(!(_.classList.contains("dropdown")||_.classList.contains("active")||_.classList.contains("ui-state-active"))&&(w.push(_),elHide(_),h.scrollWidth<u))break}if(w.length){var y;if(void 0===p){p=elCreate("li"),p.className="dropdown jsFlexibleMenuDropdown";var C=elCreate("a");C.className="icon icon16 fa-list",p.appendChild(C),y=elCreate("ul"),y.classList.add("dropdownMenu"),p.appendChild(y),s.set(t,p),l.set(t,y),r.init(C)}else y=l.get(t);null===p.parentNode&&h.appendChild(p);var E=document.createDocumentFragment(),L=this;w.forEach(function(i){var n=elCreate("li");n.innerHTML=i.innerHTML,n.addEventListener(WCF_CLICK_EVENT,function(n){n.preventDefault(),e.triggerEvent(elBySel("a",i),WCF_CLICK_EVENT),setTimeout(function(){L.rebuild(t)},59)}.bind(this)),E.appendChild(n)}),y.innerHTML="",y.appendChild(E)}else void 0!==p&&null!==p.parentNode&&elRemove(p)}}}),define("WoltLabSuite/Core/Ui/Tooltip",["Environment","Dom/ChangeListener","Ui/Alignment"],function(e,t,i){"use strict";var n=null,a=null,r=null,o=null,s=null,l=null;return{setup:function(){"desktop"===e.platform()&&(l=elCreate("div"),elAttr(l,"id","balloonTooltip"),l.classList.add("balloonTooltip"),l.addEventListener("transitionend",function(){l.classList.contains("active")||["bottom","left","right","top"].forEach(function(e){l.style.removeProperty(e)})}),s=elCreate("span"),elAttr(s,"id","balloonTooltipText"),l.appendChild(s),o=elCreate("span"),o.classList.add("elementPointer"),o.appendChild(elCreate("span")),l.appendChild(o),document.body.appendChild(l),r=elByClass("jsTooltip"),n=this._mouseEnter.bind(this),a=this._mouseLeave.bind(this),this.init(),t.add("WoltLabSuite/Core/Ui/Tooltip",this.init.bind(this)),window.addEventListener("scroll",this._mouseLeave.bind(this)))},init:function(){0!==r.length&&elBySelAll(".jsTooltip",void 0,function(e){e.classList.remove("jsTooltip");var t=elAttr(e,"title").trim();t.length&&(elData(e,"tooltip",t),e.removeAttribute("title"),elAttr(e,"aria-label",t),e.addEventListener("mouseenter",n),e.addEventListener("mouseleave",a),e.addEventListener(WCF_CLICK_EVENT,a))})},_mouseEnter:function(e){var t=e.currentTarget,n=elAttr(t,"title");if(n="string"==typeof n?n.trim():"",""!==n&&(elData(t,"tooltip",n),elAttr(t,"aria-label",n),t.removeAttribute("title")),n=elData(t,"tooltip"),l.style.removeProperty("top"),l.style.removeProperty("left"),!n.length)return void l.classList.remove("active");l.classList.add("active"),s.textContent=n,i.set(l,t,{horizontal:"center",verticalOffset:4,pointer:!0,pointerClassNames:["inverse"],vertical:"top"})},_mouseLeave:function(){l.classList.remove("active")}}}),define("WoltLabSuite/Core/Date/Picker",["DateUtil","Dom/Traverse","Dom/Util","EventHandler","Language","ObjectMap","Dom/ChangeListener","Ui/Alignment","WoltLabSuite/Core/Ui/CloseOverlay"],function(e,t,i,n,a,r,o,s,l){"use strict";var c=!1,d=0,u=!1,h=new r,f=null,p=0,m=0,g=[],v=null,_=null,b=null,w=null,y=null,C=null,E=null,L=null,S=null,A=null,I=null,D={init:function(){this._setup();for(var t=elBySelAll('input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)'),i=new Date,n=0,r=t.length;n<r;n++){var o=t[n];o.classList.add("inputDatePicker"),o.readOnly=!0;var s="datetime"===elAttr(o,"type"),l=s&&elDataBool(o,"time-only"),c=elDataBool(o,"disable-clear"),d=s&&elDataBool(o,"ignore-timezone"),u=o.classList.contains("birthday");elData(o,"is-date-time",s),elData(o,"is-time-only",l);var f=null,p=elAttr(o,"value"),m=/^\d+-\d+-\d+$/.test(p);if(elAttr(o,"value")){if(l){f=new Date;var g=p.split(":");f.setHours(g[0],g[1])}else{if(d||u||m){var v=new Date(p).getTimezoneOffset(),_=v>0?"-":"+";v=Math.abs(v);var b=Math.floor(v/60).toString(),w=(v%60).toString();_+=2===b.length?b:"0"+b,_+=":",_+=2===w.length?w:"0"+w,u||m?p+="T00:00:00"+_:p=p.replace(/[+-][0-9]{2}:[0-9]{2}$/,_)}f=new Date(p)}var y=f.getTime();if(isNaN(y))p="";else{elData(o,"value",y);p=e[l?"formatTime":"formatDate"+(s?"Time":"")](f)}}var C=0===p.length;if(u?(elData(o,"min-date","120"),elData(o,"max-date",(new Date).getFullYear()+"-12-31")):(o.min&&elData(o,"min-date",o.min),o.max&&elData(o,"max-date",o.max)),this._initDateRange(o,i,!0),this._initDateRange(o,i,!1),elData(o,"min-date")===elData(o,"max-date"))throw new Error("Minimum and maximum date cannot be the same (element id '"+o.id+"').");o.type="text",o.value=p,elData(o,"empty",C),elData(o,"placeholder")&&elAttr(o,"placeholder",elData(o,"placeholder"));var E=elCreate("input");if(E.id=o.id+"DatePicker",E.name=o.name,E.type="hidden",null!==f&&(E.value=l?e.format(f,"H:i"):d?e.format(f,"Y-m-dTH:i:s"):e.format(f,s?"c":"Y-m-d")),o.parentNode.insertBefore(E,o),o.removeAttribute("name"),o.addEventListener(WCF_CLICK_EVENT,A),!o.disabled){var L=elCreate("div");L.className="inputAddon";var S=elCreate("a");S.className="inputSuffix button jsTooltip",S.href="#",elAttr(S,"role","button"),elAttr(S,"tabindex","0"),elAttr(S,"title",a.get("wcf.date.datePicker")),elAttr(S,"aria-label",a.get("wcf.date.datePicker")),elAttr(S,"aria-haspopup",!0),elAttr(S,"aria-expanded",!1),S.addEventListener(WCF_CLICK_EVENT,A),L.appendChild(S);var I=elCreate("span");I.className="icon icon16 fa-calendar",S.appendChild(I),o.parentNode.insertBefore(L,o),L.insertBefore(o,S),c||(S=elCreate("a"),S.className="inputSuffix button",S.addEventListener(WCF_CLICK_EVENT,this.clear.bind(this,o)),C&&S.style.setProperty("visibility","hidden",""),L.appendChild(S),I=elCreate("span"),I.className="icon icon16 fa-times",S.appendChild(I))}for(var D=!1,x=["tiny","short","medium","long"],T=0;T<4;T++)o.classList.contains(x[T])&&(D=!0);D||o.classList.add("short"),h.set(o,{clearButton:S,shadow:E,disableClear:c,isDateTime:s,isEmpty:C,isTimeOnly:l,ignoreTimezone:d,onClose:null})}},_initDateRange:function(e,t,i){var n="data-"+(i?"min":"max")+"-date",a=e.hasAttribute(n)?elAttr(e,n).trim():"";if(a.match(/^(\d{4})-(\d{2})-(\d{2})$/))a=new Date(a).getTime();else if("now"===a)a=t.getTime();else if(a.match(/^\d{1,3}$/)){var r=new Date(t.getTime());r.setFullYear(r.getFullYear()+~~a*(i?-1:1)),a=r.getTime()}else if(a.match(/^datePicker-(.+)$/)){if(a=RegExp.$1,null===elById(a))throw new Error("Reference date picker identified by '"+a+"' does not exists (element id: '"+e.id+"').")}else a=/^\d{4}\-\d{2}\-\d{2}T/.test(a)?new Date(a).getTime():new Date(i?1902:2038,0,1).getTime();elAttr(e,n,a)},_setup:function(){c||(c=!0,d=~~a.get("wcf.date.firstDayOfTheWeek"),A=this._open.bind(this),o.add("WoltLabSuite/Core/Date/Picker",this.init.bind(this)),l.add("WoltLabSuite/Core/Date/Picker",this._close.bind(this)))},_open:function(e){e.preventDefault(),e.stopPropagation(),this._createPicker(),null===I&&(I=this._maintainFocus.bind(this),document.body.addEventListener("focus",I,{capture:!0}));var i="INPUT"===e.currentTarget.nodeName?e.currentTarget:e.currentTarget.previousElementSibling;if(i===f)return void this._close();var n=t.parentByClass(i,"dialogContent");null!==n&&(elDataBool(n,"has-datepicker-scroll-listener")||(n.addEventListener("scroll",this._onDialogScroll.bind(this)),elData(n,"has-datepicker-scroll-listener",1))),f=i;var a,r=h.get(f),o=elData(f,"value");o?(a=new Date(+o),"Invalid Date"===a.toString()&&(a=new Date)):a=new Date,m=elData(f,"min-date"),m.match(/^datePicker-(.+)$/)&&(m=elData(elById(RegExp.$1),"value")),m=new Date(+m),m.getTime()>a.getTime()&&(a=m),p=elData(f,"max-date"),p.match(/^datePicker-(.+)$/)&&(p=elData(elById(RegExp.$1),"value")),p=new Date(+p),r.isDateTime?(_.value=a.getHours(),b.value=a.getMinutes(),S.classList.add("datePickerTime")):S.classList.remove("datePickerTime"),S.classList[r.isTimeOnly?"add":"remove"]("datePickerTimeOnly"),this._renderPicker(a.getDate(),a.getMonth(),a.getFullYear()),s.set(S,f),elAttr(f.nextElementSibling,"aria-expanded",!0),u=!1},_close:function(){if(null!==S&&S.classList.contains("active")){S.classList.remove("active");var e=h.get(f);"function"==typeof e.onClose&&e.onClose(),n.fire("WoltLabSuite/Core/Date/Picker","close",{element:f}),elAttr(f.nextElementSibling,"aria-expanded",!1),f=null,m=0,p=0}},_onDialogScroll:function(e){if(null!==f){var t=e.currentTarget,n=i.offset(f),a=i.offset(t);n.top+f.clientHeight<=a.top?this._close():n.top>=a.top+t.offsetHeight?this._close():n.left<=a.left?this._close():n.left>=a.left+t.offsetWidth?this._close():s.set(S,f)}},_renderPicker:function(e,t,i){this._renderGrid(e,t,i);for(var n="",a=m.getFullYear(),r=p.getFullYear();a<=r;a++)n+='<option value="'+a+'">'+a+"</option>";L.innerHTML=n,L.value=i,w.value=t,S.classList.add("active")},_renderGrid:function(t,i,n){var a,r,o=void 0!==t,s=void 0!==i;if(t=~~t||~~elData(v,"day"),i=~~i,n=~~n,s||n){var l=0!==n,c=document.createDocumentFragment();c.appendChild(v),s||(i=~~elData(v,"month")),n=n||~~elData(v,"year");var u=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-"+("0"+t.toString()).slice(-2));for(u<m?(n=m.getFullYear(),i=m.getMonth(),t=m.getDate(),w.value=i,L.value=n,l=!0):u>p&&(n=p.getFullYear(),i=p.getMonth(),t=p.getDate(),w.value=i,L.value=n,l=!0),u=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");u.getDay()!==d;)u.setDate(u.getDate()-1);elShow(g[35].parentNode);var h,f=new Date(m.getFullYear(),m.getMonth(),m.getDate());for(r=0;r<42;r++){if(35===r&&u.getMonth()!==i){elHide(g[35].parentNode);break}a=g[r],a.textContent=u.getDate(),h=u.getMonth()===i,h&&(u<f?h=!1:u>p&&(h=!1)),a.classList[h?"remove":"add"]("otherMonth"),h&&(a.href="#",elAttr(a,"role","button"),elAttr(a,"tabindex","0"),elAttr(a,"title",e.formatDate(u)),elAttr(a,"aria-label",e.formatDate(u))),u.setDate(u.getDate()+1)}if(elData(v,"month",i),elData(v,"year",n),S.insertBefore(c,E),!o&&(u=new Date(n,i,t),u.getDate()!==t)){for(;u.getMonth()!==i;)u.setDate(u.getDate()-1);t=u.getDate()}if(l){for(r=0;r<12;r++){var _=w.children[r];_.disabled=n===m.getFullYear()&&_.value<m.getMonth()||n===p.getFullYear()&&_.value>p.getMonth()}var b=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");b.setMonth(b.getMonth()+1),y.classList[b<p?"add":"remove"]("active");var A=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");A.setDate(A.getDate()-1),C.classList[A>m?"add":"remove"]("active")}}if(t){for(r=0;r<35;r++)a=g[r],a.classList[a.classList.contains("otherMonth")||~~a.textContent!==t?"remove":"add"]("active");elData(v,"day",t)}this._formatValue()},_formatValue:function(){var e,t=h.get(f);"true"!==elData(f,"empty")&&(e=t.isDateTime?new Date(elData(v,"year"),elData(v,"month"),elData(v,"day"),_.value,b.value):new Date(elData(v,"year"),elData(v,"month"),elData(v,"day")),this.setDate(f,e))},_createPicker:function(){if(null===S){S=elCreate("div"),S.className="datePicker",S.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()});var t=elCreate("header");S.appendChild(t),C=elCreate("a"),C.className="previous jsTooltip",C.href="#",elAttr(C,"role","button"),elAttr(C,"tabindex","0"),elAttr(C,"title",a.get("wcf.date.datePicker.previousMonth")),elAttr(C,"aria-label",a.get("wcf.date.datePicker.previousMonth")),C.innerHTML='<span class="icon icon16 fa-arrow-left"></span>',C.addEventListener(WCF_CLICK_EVENT,this.previousMonth.bind(this)),t.appendChild(C);var i=elCreate("span");t.appendChild(i),w=elCreate("select"),w.className="month jsTooltip",elAttr(w,"title",a.get("wcf.date.datePicker.month")),elAttr(w,"aria-label",a.get("wcf.date.datePicker.month")),w.addEventListener("change",this._changeMonth.bind(this)),i.appendChild(w);var n,r="",o=a.get("__monthsShort");for(n=0;n<12;n++)r+='<option value="'+n+'">'+o[n]+"</option>";w.innerHTML=r,L=elCreate("select"),L.className="year jsTooltip",elAttr(L,"title",a.get("wcf.date.datePicker.year")),elAttr(L,"aria-label",a.get("wcf.date.datePicker.year")),L.addEventListener("change",this._changeYear.bind(this)),i.appendChild(L),y=elCreate("a"),y.className="next jsTooltip",y.href="#",elAttr(y,"role","button"),elAttr(y,"tabindex","0"),elAttr(y,"title",a.get("wcf.date.datePicker.nextMonth")),elAttr(y,"aria-label",a.get("wcf.date.datePicker.nextMonth")),y.innerHTML='<span class="icon icon16 fa-arrow-right"></span>',y.addEventListener(WCF_CLICK_EVENT,this.nextMonth.bind(this)),t.appendChild(y),v=elCreate("ul"),S.appendChild(v);var s=elCreate("li");s.className="weekdays",v.appendChild(s);var l,c=a.get("__daysShort");for(n=0;n<7;n++){var u=n+d;u>6&&(u-=7),l=elCreate("span"),l.textContent=c[u],s.appendChild(l)}var h,f,p=this._click.bind(this);for(n=0;n<6;n++){f=elCreate("li"),v.appendChild(f);for(var m=0;m<7;m++)h=elCreate("a"),h.addEventListener(WCF_CLICK_EVENT,p),g.push(h),f.appendChild(h)}E=elCreate("footer"),S.appendChild(E),_=elCreate("select"),_.className="hour",elAttr(_,"title",a.get("wcf.date.datePicker.hour")),elAttr(_,"aria-label",a.get("wcf.date.datePicker.hour")),_.addEventListener("change",this._formatValue.bind(this));var A="",I=new Date(2e3,0,1),D=a.get("wcf.date.timeFormat").replace(/:/,"").replace(/[isu]/g,"");for(n=0;n<24;n++)I.setHours(n),A+='<option value="'+n+'">'+e.format(I,D)+"</option>";for(_.innerHTML=A,E.appendChild(_),E.appendChild(document.createTextNode(" : ")),b=elCreate("select"),b.className="minute",elAttr(b,"title",a.get("wcf.date.datePicker.minute")),elAttr(b,"aria-label",a.get("wcf.date.datePicker.minute")),b.addEventListener("change",this._formatValue.bind(this)),A="",n=0;n<60;n++)A+='<option value="'+n+'">'+(n<10?"0"+n.toString():n)+"</option>";b.innerHTML=A,E.appendChild(b),document.body.appendChild(S)}},previousMonth:function(e){e.preventDefault(),"0"===w.value?(w.value=11,L.value=~~L.value-1):w.value=~~w.value-1,this._renderGrid(void 0,w.value,L.value)},nextMonth:function(e){e.preventDefault(),"11"===w.value?(w.value=0,L.value=1+~~L.value):w.value=1+~~w.value,this._renderGrid(void 0,w.value,L.value)},_changeMonth:function(e){this._renderGrid(void 0,e.currentTarget.value)},_changeYear:function(e){this._renderGrid(void 0,void 0,e.currentTarget.value)},_click:function(e){if(e.preventDefault(),!e.currentTarget.classList.contains("otherMonth")){elData(f,"empty",!1),this._renderGrid(e.currentTarget.textContent);h.get(f).isDateTime||this._close()}},getDate:function(e){return e=this._getElement(e),e.hasAttribute("data-value")?new Date(+elData(e,"value")):null},setDate:function(t,i){t=this._getElement(t);var n=h.get(t);elData(t,"value",i.getTime());var a,r="";n.isDateTime?n.isTimeOnly?(a=e.formatTime(i),r="H:i"):n.ignoreTimezone?(a=e.formatDateTime(i),r="Y-m-dTH:i:s"):(a=e.formatDateTime(i),r="c"):(a=e.formatDate(i),r="Y-m-d"),t.value=a,n.shadow.value=e.format(i,r),n.disableClear||n.clearButton.style.removeProperty("visibility")},getValue:function(e){e=this._getElement(e);var t=h.get(e);return t?t.shadow.value:""},clear:function(e){e=this._getElement(e);var t=h.get(e);e.removeAttribute("data-value"),e.value="",t.disableClear||t.clearButton.style.setProperty("visibility","hidden",""),t.isEmpty=!0,t.shadow.value=""},destroy:function(e){e=this._getElement(e);var t=h.get(e),i=e.parentNode;i.parentNode.insertBefore(e,i),elRemove(i),elAttr(e,"type","date"+(t.isDateTime?"time":"")),e.name=t.shadow.name,e.value=t.shadow.value,e.removeAttribute("data-value"),e.removeEventListener(WCF_CLICK_EVENT,A),elRemove(t.shadow),e.classList.remove("inputDatePicker"),e.readOnly=!1,h.delete(e)},setCloseCallback:function(e,t){e=this._getElement(e),h.get(e).onClose=t},_getElement:function(e){if("string"==typeof e&&(e=elById(e)),!(e instanceof Element&&e.classList.contains("inputDatePicker")&&h.has(e)))throw new Error("Expected a valid date picker input element or id.");return e},_maintainFocus:function(e){null!==S&&S.classList.contains("active")&&(S.contains(e.target)?u=!0:u?(f.nextElementSibling.focus(),u=!1):elBySel(".previous",S).focus())}};return window.__wcf_bc_datePicker=D,D}),define("WoltLabSuite/Core/Ui/Page/Action",["Dictionary","Language","Ui/Screen"],function(e,t,i){"use strict";var n,a,r,o=new e,s=!1,l=-1,c=window.debounce(function(){l=-1},50,!1),d=300;return{setup:function(){if(!s){s=!0,r=elCreate("div"),r.className="pageAction",n=elCreate("div"),n.className="pageActionButtons",r.appendChild(n),a=this._buildToTopButton(),r.appendChild(a),document.body.appendChild(r);var e=window.debounce(this._onScroll.bind(this),100,!1);window.addEventListener("scroll",function(){-1===l&&(l=window.pageYOffset,window.setTimeout(function(){this._onScroll(),l=window.pageYOffset}.bind(this),60)),e()}.bind(this),{passive:!0}),window.addEventListener("touchstart",function(){-1!==l&&(l=-1)},{passive:!0}),i.on("screen-sm-down",{match:function(){d=50},unmatch:function(){d=300},setup:function(){d=50}}),this._onScroll()}},_buildToTopButton:function(){var e=elCreate("a");return e.className="button buttonPrimary pageActionButtonToTop initiallyHidden jsTooltip",e.href="",elAttr(e,"title",t.get("wcf.global.scrollUp")),elAttr(e,"aria-hidden","true"),e.innerHTML='<span class="icon icon32 fa-angle-up"></span>',e.addEventListener(WCF_CLICK_EVENT,this._scrollTopTop.bind(this)),e},_onScroll:function(){if(!document.documentElement.classList.contains("disableScrolling")){var e=window.pageYOffset;if(e===l)return void c();e>=d?(a.classList.contains("initiallyHidden")&&a.classList.remove("initiallyHidden"),elAttr(a,"aria-hidden","false")):elAttr(a,"aria-hidden","true"),this._renderContainer(),-1!==l&&r.classList[e<l?"remove":"add"]("scrolledDown"),l=-1}},_scrollTopTop:function(e){e.preventDefault(),elById("top").scrollIntoView({behavior:"smooth"})},add:function(e,t,i){this.setup();var a=elCreate("div");a.className="pageActionButton",a.name=e,elAttr(a,"aria-hidden","true"),t.classList.add("button"),t.classList.add("buttonPrimary"),a.appendChild(t);var s=null;i&&void 0!==(s=o.get(i))&&(s=s.parentNode),null===s&&n.childElementCount&&(s=n.children[0]),null===s&&(s=n.firstChild),n.insertBefore(a,s),r.classList.remove("scrolledDown"),o.set(e,t),a.offsetParent,elAttr(a,"aria-hidden","false"),this._renderContainer()},has:function(e){return o.has(e)},get:function(e){return o.get(e)},remove:function(e){var t=o.get(e);if(void 0!==t){var i=t.parentNode,a=function(){try{elAttrBool(i,"aria-hidden")&&(n.removeChild(i),o.delete(e)),i.removeEventListener("transitionend",a)}catch(e){}};i.addEventListener("transitionend",a),this.hide(e)}},hide:function(e){var t=o.get(e);t&&(elAttr(t.parentNode,"aria-hidden","true"),this._renderContainer())},show:function(e){var t=o.get(e);t&&(t.parentNode.classList.contains("initiallyHidden")&&t.parentNode.classList.remove("initiallyHidden"),elAttr(t.parentNode,"aria-hidden","false"),r.classList.remove("scrolledDown"),this._renderContainer())},_renderContainer:function(){var e=!1;if(n.childElementCount)for(var t=0,i=n.childElementCount;t<i;t++)if("false"===elAttr(n.children[t],"aria-hidden")){e=!0;break}n.classList[e?"add":"remove"]("active"),e?r.classList.add("pageActionHasContextButtons"):r.classList.remove("pageActionHasContextButtons")}}}),define("WoltLabSuite/Core/Bootstrap",["favico","enquire","perfect-scrollbar","WoltLabSuite/Core/Date/Time/Relative","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Mobile","WoltLabSuite/Core/Ui/TabMenu","WoltLabSuite/Core/Ui/FlexibleMenu","Ui/Dialog","WoltLabSuite/Core/Ui/Tooltip","WoltLabSuite/Core/Language","WoltLabSuite/Core/Environment","WoltLabSuite/Core/Date/Picker","EventHandler","Core","WoltLabSuite/Core/Ui/Page/Action","Devtools","Dom/ChangeListener"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,f,p,m,g,v){"use strict";return window.Favico=e,window.enquire=t,null==window.WCF&&(window.WCF={}),null==window.WCF.Language&&(window.WCF.Language={}),window.WCF.Language.get=d.get,window.WCF.Language.add=d.add,window.WCF.Language.addObject=d.addObject,window.__wcf_bc_eventHandler=f,{setup:function(e){e=p.extend({enableMobileMenu:!0},e),window.ENABLE_DEVELOPER_TOOLS&&g._internal_.enable(),u.setup(),n.setup(),h.init(),a.setup(),r.setup({enableMobileMenu:e.enableMobileMenu}),o.setup(),l.setup(),c.setup();for(var t=elBySelAll("form[method=get]"),i=0,s=t.length;i<s;i++)t[i].setAttribute("method","post");"microsoft"===u.browser()&&(window.onbeforeunload=function(){});var d=0;d=window.setInterval(function(){"function"==typeof window.jQuery&&(window.clearInterval(d),window.jQuery(function(){m.setup()}),window.jQuery.holdReady(!1))},20),this._initA11y(),v.add("WoltLabSuite/Core/Bootstrap",this._initA11y.bind(this))},_initA11y:function(){elBySelAll("nav:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")}),elBySelAll("article:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")})}}}),define("WoltLabSuite/Core/Controller/Style/Changer",["Ajax","Language","Ui/Dialog"],function(e,t,i){"use strict";return{setup:function(){elBySelAll(".jsButtonStyleChanger",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this.showDialog.bind(this))}.bind(this))},showDialog:function(e){e.preventDefault(),i.open(this)},_dialogSetup:function(){return{id:"styleChanger",options:{disableContentPadding:!0,title:t.get("wcf.style.changeStyle")},source:{data:{actionName:"getStyleChooser",className:"wcf\\data\\style\\StyleAction"},after:function(e){for(var t=elBySelAll(".styleList > li",e),i=0,n=t.length;i<n;i++){var a=t[i];a.classList.add("pointer"),a.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}}.bind(this)}}},_click:function(t){t.preventDefault(),e.apiOnce({data:{actionName:"changeStyle",className:"wcf\\data\\style\\StyleAction",objectIDs:[elData(t.currentTarget,"style-id")]},success:function(){window.location.reload()}})}}}),define("WoltLabSuite/Core/Controller/Popover",["Ajax","Dictionary","Environment","Dom/ChangeListener","Dom/Util","Ui/Alignment"],function(e,t,i,n,a,r){"use strict";var o=null,s=new t,l=new t,c=new t,d=null,u=!1,h=null,f=null,p=null,m=null,g=null,v=null,_=null,b=null;return{_setup:function(){if(null===p){p=elCreate("div"),p.className="popover forceHide",m=elCreate("div"),m.className="popoverContent",p.appendChild(m);var e=elCreate("span");e.className="elementPointer",e.appendChild(elCreate("span")),p.appendChild(e),document.body.appendChild(p),g=this._hide.bind(this),_=this._mouseEnter.bind(this),b=this._mouseLeave.bind(this),p.addEventListener("mouseenter",this._popoverMouseEnter.bind(this)),p.addEventListener("mouseleave",b),p.addEventListener("animationend",this._clearContent.bind(this)),window.addEventListener("beforeunload",function(){u=!0,null!==h&&window.clearTimeout(h),this._hide(!0)}.bind(this)),n.add("WoltLabSuite/Core/Controller/Popover",this._init.bind(this))}},init:function(e){"desktop"===i.platform()&&(e.attributeName=e.attributeName||"data-object-id",e.legacy=!0===e.legacy,this._setup(),c.has(e.identifier)||(c.set(e.identifier,{attributeName:e.attributeName,dboAction:e.dboAction,elements:e.legacy?e.className:elByClass(e.className),legacy:e.legacy,loadCallback:e.loadCallback}),this._init(e.identifier)))},_init:function(e){"string"==typeof e&&e.length?this._initElements(c.get(e),e):c.forEach(this._initElements.bind(this))},_initElements:function(e,t){for(var i=e.legacy?elBySelAll(e.elements):e.elements,n=0,r=i.length;n<r;n++){var o=i[n],c=a.identify(o);if(s.has(c))return;if(null!==o.closest(".popover"))return void s.set(c,{content:null,state:0});var d=e.legacy?c:~~o.getAttribute(e.attributeName);if(0!==d){o.addEventListener("mouseenter",_),o.addEventListener("mouseleave",b),"A"===o.nodeName&&elAttr(o,"href")&&o.addEventListener(WCF_CLICK_EVENT,g);var u=t+"-"+d;elData(o,"cache-id",u),l.set(c,{element:o,identifier:t,objectId:d}),s.has(u)||s.set(t+"-"+d,{content:null,state:0})}}},setContent:function(e,t,i){var n=e+"-"+t,r=s.get(n);if(void 0===r)throw new Error("Unable to find element for object id '"+t+"' (identifier: '"+e+"').");var c=a.createFragmentFromHtml(i);if(c.childElementCount||(c=a.createFragmentFromHtml("<p>"+i+"</p>")),r.content=c,r.state=2,o){var d=l.get(o).element;elData(d,"cache-id")===n&&this._show()}},_mouseEnter:function(e){if(!u){null!==h&&(window.clearTimeout(h),h=null);var t=a.identify(e.currentTarget);o===t&&null!==f&&(window.clearTimeout(f),f=null),d=t,h=window.setTimeout(function(){h=null,d===t&&this._show()}.bind(this),800)}},_mouseLeave:function(){d=null,null===f&&(null===v&&(v=this._hide.bind(this)),null!==f&&window.clearTimeout(f),f=window.setTimeout(v,500))},_popoverMouseEnter:function(){null!==f&&(window.clearTimeout(f),f=null)},_show:function(){null!==f&&(window.clearTimeout(f),f=null);var e=!1;p.classList.contains("active")?o!==d&&(this._hide(),e=!0):m.childElementCount&&(e=!0),e&&(p.classList.add("forceHide"),p.offsetTop,this._clearContent(),p.classList.remove("forceHide")),o=d;var t=l.get(o);if(void 0!==t){var i=s.get(elData(t.element,"cache-id"));if(2===i.state)m.appendChild(i.content),this._rebuild(o);else if(0===i.state){i.state=1;var n=c.get(t.identifier);if(n.loadCallback)n.loadCallback(t.objectId,this,t.element);else if(n.dboAction){var a=function(e){this.setContent(t.identifier,t.objectId,e.returnValues.template)}.bind(this);this.ajaxApi({actionName:"getPopover",className:n.dboAction,interfaceName:"wcf\\data\\IPopoverAction",objectIDs:[t.objectId]},a,a)}}}},_hide:function(){null!==f&&(window.clearTimeout(f),f=null),p.classList.remove("active")},_clearContent:function(){if(o&&m.childElementCount&&!p.classList.contains("active"))for(var e=s.get(elData(l.get(o).element,"cache-id"));m.childNodes.length;)e.content.appendChild(m.childNodes[0])},_rebuild:function(){p.classList.contains("active")||(p.classList.remove("forceHide"),p.classList.add("active"),r.set(p,l.get(o).element,{pointer:!0,vertical:"top"}))},_ajaxSetup:function(){return{silent:!0}},ajaxApi:function(t,i,n){if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'success'.");e.api(this,t,i,n)}}}),define("WoltLabSuite/Core/Ui/User/Ignore",["List","Dom/ChangeListener"],function(e,t){"use strict";var i=elByClass("ignoredUserMessage"),n=null,a=new e;return{init:function(){n=this._removeClass.bind(this),this._rebuild(),t.add("WoltLabSuite/Core/Ui/User/Ignore",this._rebuild.bind(this))},_rebuild:function(){for(var e,t=0,r=i.length;t<r;t++)e=i[t],a.has(e)||(e.addEventListener(WCF_CLICK_EVENT,n),a.add(e))},_removeClass:function(e){e.preventDefault();var t=e.currentTarget;t.classList.remove("ignoredUserMessage"),t.removeEventListener(WCF_CLICK_EVENT,n),a.delete(t),window.getSelection().removeAllRanges()}}}),define("WoltLabSuite/Core/Ui/Page/Header/Menu",["Environment","Language","Ui/Screen"],function(e,t,i){"use strict";var n,a,r,o,s=!1,l=0,c=[],d=[];return{init:function(){if(o=elBySel(".mainMenu .boxMenu"),null===(r=o&&o.childElementCount?o.children[0]:null))throw new Error("Unable to find the menu.");i.on("screen-lg",{enable:this._enable.bind(this),disable:this._disable.bind(this),setup:this._setup.bind(this)})},_enable:function(){s=!0,"safari"===e.browser()?window.setTimeout(this._rebuildVisibility.bind(this),1e3):(this._rebuildVisibility(),window.setTimeout(this._rebuildVisibility.bind(this),1e3))},_disable:function(){s=!1},_showNext:function(e){if(e.preventDefault(),d.length){var t=d.slice(0,3).pop();this._setMarginLeft(o.clientWidth-(t.offsetLeft+t.clientWidth)),o.lastElementChild===t&&n.classList.remove("active"),a.classList.add("active")}},_showPrevious:function(e){if(e.preventDefault(),c.length){var t=c.slice(-3)[0];this._setMarginLeft(-1*t.offsetLeft),o.firstElementChild===t&&a.classList.remove("active"),n.classList.add("active")}},_setMarginLeft:function(e){l=Math.min(l+e,0),r.style.setProperty("margin-left",l+"px","")},_rebuildVisibility:function(){if(s){c=[],d=[];var e=o.clientWidth;if(o.scrollWidth>e||l<0)for(var t,i=0,r=o.childElementCount;i<r;i++){t=o.children[i];var u=t.offsetLeft;u<0?c.push(t):u+t.clientWidth>e&&d.push(t)}a.classList[c.length?"add":"remove"]("active"),n.classList[d.length?"add":"remove"]("active")}},_setup:function(){this._setupOverflow(),this._setupA11y()},_setupOverflow:function(){n=elCreate("a"),n.className="mainMenuShowNext",n.href="#",n.innerHTML='<span class="icon icon32 fa-angle-right"></span>',elAttr(n,"aria-hidden","true"),n.addEventListener(WCF_CLICK_EVENT,this._showNext.bind(this)),o.parentNode.appendChild(n),a=elCreate("a"),a.className="mainMenuShowPrevious",a.href="#",a.innerHTML='<span class="icon icon32 fa-angle-left"></span>',elAttr(a,"aria-hidden","true"),a.addEventListener(WCF_CLICK_EVENT,this._showPrevious.bind(this)),o.parentNode.insertBefore(a,o.parentNode.firstChild);var e=this._rebuildVisibility.bind(this);r.addEventListener("transitionend",e),window.addEventListener("resize",function(){r.style.setProperty("margin-left","0px",""),l=0,e()}),this._enable()},_setupA11y:function(){elBySelAll(".boxMenuHasChildren",o,function(e){var i=!1,n=elBySel(".boxMenuLink",e);n&&(elAttr(n,"aria-haspopup",!0),elAttr(n,"aria-expanded",i));var a=elCreate("button");a.className="visuallyHidden",a.tabindex=0,elAttr(a,"role","button"),elAttr(a,"aria-label",t.get("wcf.global.button.showMenu")),e.insertBefore(a,n.nextSibling),a.addEventListener(WCF_CLICK_EVENT,function(){i=!i,elAttr(n,"aria-expanded",i),elAttr(a,"aria-label",i?t.get("wcf.global.button.hideMenu"):t.get("wcf.global.button.showMenu"))})}.bind(this))}}}),define("WoltLabSuite/Core/User",[],function(){"use strict";var e,t=!1;return{getLink:function(){return e},init:function(i,n,a){if(t)throw new Error("User has already been initialized.");Object.defineProperty(this,"userId",{value:i,writable:!1}),Object.defineProperty(this,"username",{value:n,writable:!1}),e=a,t=!0}}}),define("WoltLabSuite/Core/Ui/Message/UserConsent",["Ajax","Core","User","Dom/ChangeListener","Dom/Util"],function(e,t,i,n,a){var r=!1,o="function"==typeof window.WeakSet?new window.WeakSet:new window.Set;return{init:function(){"all"===window.sessionStorage.getItem(t.getStoragePrefix()+"user-consent")&&(r=!0),this._registerEventListeners(),
+n.add("WoltLabSuite/Core/Ui/Message/UserConsent",this._registerEventListeners.bind(this))},_registerEventListeners:function(){r?this._enableAll():elBySelAll(".jsButtonMessageUserConsentEnable",void 0,function(e){o.has(e)||(e.addEventListener("click",this._click.bind(this)),o.add(e))}.bind(this))},_click:function(n){n.preventDefault(),r=!0,this._enableAll(),i.userId?e.apiOnce({data:{actionName:"saveUserConsent",className:"wcf\\data\\user\\UserAction"},silent:!0}):window.sessionStorage.setItem(t.getStoragePrefix()+"user-consent","all")},_enableExternalMedia:function(e){var t=atob(elData(e,"payload"));a.insertHtml(t,e,"before"),elRemove(e)},_enableAll:function(){elBySelAll(".messageUserConsent",void 0,this._enableExternalMedia.bind(this))}}}),define("WoltLabSuite/Core/BootstrapFrontend",["WoltLabSuite/Core/BackgroundQueue","WoltLabSuite/Core/Bootstrap","WoltLabSuite/Core/Controller/Style/Changer","WoltLabSuite/Core/Controller/Popover","WoltLabSuite/Core/Ui/User/Ignore","WoltLabSuite/Core/Ui/Page/Header/Menu","WoltLabSuite/Core/Ui/Message/UserConsent"],function(e,t,i,n,a,r,o){"use strict";return{setup:function(n){n.backgroundQueue.url=WSC_API_URL+n.backgroundQueue.url.substr(WCF_PATH.length),t.setup(),r.init(),n.styleChanger&&i.setup(),n.enableUserPopover&&this._initUserPopover(),e.setUrl(n.backgroundQueue.url),(Math.random()<.1||n.backgroundQueue.force)&&e.invoke(),a.init(),o.init()},_initUserPopover:function(){n.init({className:"userLink",dboAction:"wcf\\data\\user\\UserProfileAction",identifier:"com.woltlab.wcf.user"}),n.init({attributeName:"data-user-id",className:"userLink",dboAction:"wcf\\data\\user\\UserProfileAction",identifier:"com.woltlab.wcf.user.deprecated"})}}}),define("WoltLabSuite/Core/Clipboard",["Environment","Ui/Screen"],function(e,t){"use strict";return{copyTextToClipboard:function(i){if(navigator.clipboard)return navigator.clipboard.writeText(i);if(window.getSelection){var n=elCreate("textarea");n.contentEditable=!0,n.readOnly=!1;var a=!1;if("ios"===e.platform()){a=!0,t.scrollDisable();var r=~~(window.innerHeight/4)+window.pageYOffset;n.style.cssText="font-size: 16px; position: absolute; left: 1px; top: "+r+"px; width: 50px; height: 50px; overflow: hidden;border: 5px solid red;"}else n.style.cssText="position: absolute; left: -9999px; top: -9999px; width: 0; height: 0;";document.body.appendChild(n);try{n.value=i;var o=document.createRange();o.selectNodeContents(n);var s=window.getSelection();return s.removeAllRanges(),s.addRange(o),n.setSelectionRange(0,999999),document.execCommand("copy")?Promise.resolve():Promise.reject(new Error("execCommand('copy') failed"))}finally{elRemove(n),a&&t.scrollEnable()}}return Promise.reject(new Error("Neither navigator.clipboard, nor window.getSelection is supported."))},copyElementTextToClipboard:function(e){return this.copyTextToClipboard(e.textContent.replace(/\u200B/g,"").replace(/\u00A0/g," "))}}}),define("WoltLabSuite/Core/ColorUtil",[],function(){"use strict";var e={hsvToRgb:function(e,t,i){var n,a,r,o,s,l={r:0,g:0,b:0};if(n=Math.floor(e/60),a=e/60-n,t/=100,i/=100,r=i*(1-t),o=i*(1-t*a),s=i*(1-t*(1-a)),0==t)l.r=l.g=l.b=i;else switch(n){case 1:l.r=o,l.g=i,l.b=r;break;case 2:l.r=r,l.g=i,l.b=s;break;case 3:l.r=r,l.g=o,l.b=i;break;case 4:l.r=s,l.g=r,l.b=i;break;case 5:l.r=i,l.g=r,l.b=o;break;case 0:case 6:l.r=i,l.g=s,l.b=r}return{r:Math.round(255*l.r),g:Math.round(255*l.g),b:Math.round(255*l.b)}},rgbToHsv:function(e,t,i){var n,a,r,o,s,l;if(e/=255,t/=255,i/=255,o=Math.max(Math.max(e,t),i),s=Math.min(Math.min(e,t),i),l=o-s,n=0,o!==s){switch(o){case e:n=(t-i)/l*60;break;case t:n=60*(2+(i-e)/l);break;case i:n=60*(4+(e-t)/l)}n<0&&(n+=360)}return a=0===o?0:l/o,r=o,{h:Math.round(n),s:Math.round(100*a),v:Math.round(100*r)}},hexToRgb:function(e){if(/^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(e)){var t=e.split("");return"#"===t[0]&&t.shift(),3===t.length?{r:parseInt(t[0]+""+t[0],16),g:parseInt(t[1]+""+t[1],16),b:parseInt(t[2]+""+t[2],16)}:{r:parseInt(t[0]+""+t[1],16),g:parseInt(t[2]+""+t[3],16),b:parseInt(t[4]+""+t[5],16)}}return Number.NaN},rgbToHex:function(e,t,i){var n="0123456789ABCDEF";return void 0===t&&e.toString().match(/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/)&&(e=RegExp.$1,t=RegExp.$2,i=RegExp.$3),n.charAt((e-e%16)/16)+""+n.charAt(e%16)+n.charAt((t-t%16)/16)+n.charAt(t%16)+n.charAt((i-i%16)/16)+n.charAt(i%16)}};return window.__wcf_bc_colorUtil=e,e}),define("WoltLabSuite/Core/FileUtil",["Dictionary","StringUtil"],function(e,t){"use strict";var i=e.fromObject({zip:"archive",rar:"archive",tar:"archive",gz:"archive",mp3:"audio",ogg:"audio",wav:"audio",php:"code",html:"code",htm:"code",tpl:"code",js:"code",xls:"excel",ods:"excel",xlsx:"excel",gif:"image",jpg:"image",jpeg:"image",png:"image",bmp:"image",webp:"image",avi:"video",wmv:"video",mov:"video",mp4:"video",mpg:"video",mpeg:"video",flv:"video",pdf:"pdf",ppt:"powerpoint",pptx:"powerpoint",txt:"text",doc:"word",docx:"word",odt:"word"}),n=e.fromObject({"application/zip":"zip","application/x-zip-compressed":"zip","application/rar":"rar","application/vnd.rar":"rar","application/x-rar-compressed":"rar","application/x-tar":"tar","application/x-gzip":"gz","application/gzip":"gz","audio/mpeg":"mp3","audio/mp3":"mp3","audio/ogg":"ogg","audio/x-wav":"wav","application/x-php":"php","text/html":"html","application/javascript":"js","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","image/gif":"gif","image/jpeg":"jpg","image/png":"png","image/x-ms-bmp":"bmp","image/bmp":"bmp","image/webp":"webp","video/x-msvideo":"avi","video/x-ms-wmv":"wmv","video/quicktime":"mov","video/mp4":"mp4","video/mpeg":"mpg","video/x-flv":"flv","application/pdf":"pdf","application/vnd.ms-powerpoint":"ppt","application/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","text/plain":"txt","application/msword":"doc","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application/vnd.oasis.opendocument.text":"odt","public.jpeg":"jpeg","public.png":"png","com.compuserve.gif":"gif","org.webmproject.webp":"webp"});return{formatFilesize:function(e,i){void 0===i&&(i=2);var n="Byte";return e>=1e3&&(e/=1e3,n="kB"),e>=1e3&&(e/=1e3,n="MB"),e>=1e3&&(e/=1e3,n="GB"),e>=1e3&&(e/=1e3,n="TB"),t.formatNumeric(e,-i)+" "+n},getIconNameByFilename:function(e){var t=e.lastIndexOf(".");if(!1!==t){var n=e.substr(t+1);if(i.has(n))return i.get(n)}return""},getExtensionByMimeType:function(e){return n.has(e)?"."+n.get(e):""},blobToFile:function(e,t){var i=this.getExtensionByMimeType(e.type),n=window.File;try{new n([],"ie11-check")}catch(e){n=function(e,t,i){var n=Blob.call(this,e,i);return n.name=t,n.lastModifiedDate=new Date,n},n.prototype=Object.create(window.File.prototype)}return new n([e],t+i,{type:e.type})}}}),define("WoltLabSuite/Core/Permission",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if("boolean"!=typeof i)throw new TypeError("Permission value has to be boolean.");t.set(e,i)},addObject:function(e){for(var t in e)objOwns(e,t)&&this.add(t,e[t])},get:function(e){return!!t.has(e)&&t.get(e)}}});var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){function t(e,t,i,n){this.type=e,this.content=t,this.alias=i,this.length=0|(n||"").length}function i(e,n,o,s,l,c){for(var u in o)if(o.hasOwnProperty(u)&&o[u]){var h=o[u];h=Array.isArray(h)?h:[h];for(var f=0;f<h.length;++f){if(c&&c.cause==u+","+f)return;var p=h[f],m=p.inside,g=!!p.lookbehind,v=!!p.greedy,_=0,b=p.alias;if(v&&!p.pattern.global){var w=p.pattern.toString().match(/[imsuy]*$/)[0];p.pattern=RegExp(p.pattern.source,w+"g")}for(var y=p.pattern||p,C=s.next,E=l;C!==n.tail&&!(c&&E>=c.reach);E+=C.value.length,C=C.next){var L=C.value;if(n.length>e.length)return;if(!(L instanceof t)){var S=1;if(v&&C!=n.tail.prev){y.lastIndex=E;var A=y.exec(e);if(!A)break;var I=A.index+(g&&A[1]?A[1].length:0),D=A.index+A[0].length,x=E;for(x+=C.value.length;I>=x;)C=C.next,x+=C.value.length;if(x-=C.value.length,E=x,C.value instanceof t)continue;for(var T=C;T!==n.tail&&(x<D||"string"==typeof T.value);T=T.next)S++,x+=T.value.length;S--,L=e.slice(E,x),A.index-=E}else{y.lastIndex=0;var A=y.exec(L)}if(A){g&&(_=A[1]?A[1].length:0);var I=A.index+_,k=A[0].slice(_),D=I+k.length,B=L.slice(0,I),N=L.slice(D),M=E+L.length;c&&M>c.reach&&(c.reach=M);var U=C.prev;B&&(U=a(n,U,B),E+=B.length),r(n,U,S);var j=new t(u,m?d.tokenize(k,m):k,b,k);C=a(n,U,j),N&&a(n,C,N),S>1&&i(e,n,o,C.prev,E,{cause:u+","+f,reach:M})}}}}}}function n(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function a(e,t,i){var n=t.next,a={value:i,prev:t,next:n};return t.next=a,n.prev=a,e.length++,a}function r(e,t,i){for(var n=t.next,a=0;a<i&&n!==e.tail;a++)n=n.next;t.next=n,n.prev=t,e.length-=a}function o(e){for(var t=[],i=e.head.next;i!==e.tail;)t.push(i.value),i=i.next;return t}function s(){d.manual||d.highlightAll()}var l=/\blang(?:uage)?-([\w-]+)\b/i,c=0,d={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(i){return i instanceof t?new t(i.type,e(i.content),i.alias):Array.isArray(i)?i.map(e):i.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++c}),e.__id},clone:function e(t,i){i=i||{};var n,a;switch(d.util.type(t)){case"Object":if(a=d.util.objId(t),i[a])return i[a];n={},i[a]=n;for(var r in t)t.hasOwnProperty(r)&&(n[r]=e(t[r],i));return n;case"Array":return a=d.util.objId(t),i[a]?i[a]:(n=[],i[a]=n,t.forEach(function(t,a){n[a]=e(t,i)}),n);default:return t}},getLanguage:function(e){for(;e&&!l.test(e.className);)e=e.parentElement;return e?(e.className.match(l)||[,"none"])[1].toLowerCase():"none"},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(n){var e=(/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(n.stack)||[])[1];if(e){var t=document.getElementsByTagName("script");for(var i in t)if(t[i].src==e)return t[i]}return null}},isActive:function(e,t,i){for(var n="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(n))return!1;e=e.parentElement}return!!i}},languages:{extend:function(e,t){var i=d.util.clone(d.languages[e]);for(var n in t)i[n]=t[n];return i},insertBefore:function(e,t,i,n){n=n||d.languages;var a=n[e],r={};for(var o in a)if(a.hasOwnProperty(o)){if(o==t)for(var s in i)i.hasOwnProperty(s)&&(r[s]=i[s]);i.hasOwnProperty(o)||(r[o]=a[o])}var l=n[e];return n[e]=r,d.languages.DFS(d.languages,function(t,i){i===l&&t!=e&&(this[t]=r)}),r},DFS:function e(t,i,n,a){a=a||{};var r=d.util.objId;for(var o in t)if(t.hasOwnProperty(o)){i.call(t,o,t[o],n||o);var s=t[o],l=d.util.type(s);"Object"!==l||a[r(s)]?"Array"!==l||a[r(s)]||(a[r(s)]=!0,e(s,i,o,a)):(a[r(s)]=!0,e(s,i,null,a))}}},plugins:{},highlightAll:function(e,t){d.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,i){var n={callback:i,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};d.hooks.run("before-highlightall",n),n.elements=Array.prototype.slice.apply(n.container.querySelectorAll(n.selector)),d.hooks.run("before-all-elements-highlight",n);for(var a,r=0;a=n.elements[r++];)d.highlightElement(a,!0===t,n.callback)},highlightElement:function(t,i,n){function a(e){u.highlightedCode=e,d.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,d.hooks.run("after-highlight",u),d.hooks.run("complete",u),n&&n.call(u.element)}var r=d.util.getLanguage(t),o=d.languages[r];t.className=t.className.replace(l,"").replace(/\s+/g," ")+" language-"+r;var s=t.parentElement;s&&"pre"===s.nodeName.toLowerCase()&&(s.className=s.className.replace(l,"").replace(/\s+/g," ")+" language-"+r);var c=t.textContent,u={element:t,language:r,grammar:o,code:c};if(d.hooks.run("before-sanity-check",u),!u.code)return d.hooks.run("complete",u),void(n&&n.call(u.element));if(d.hooks.run("before-highlight",u),!u.grammar)return void a(d.util.encode(u.code));if(i&&e.Worker){var h=new Worker(d.filename);h.onmessage=function(e){a(e.data)},h.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else a(d.highlight(u.code,u.grammar,u.language))},highlight:function(e,i,n){var a={code:e,grammar:i,language:n};return d.hooks.run("before-tokenize",a),a.tokens=d.tokenize(a.code,a.grammar),d.hooks.run("after-tokenize",a),t.stringify(d.util.encode(a.tokens),a.language)},tokenize:function(e,t){var r=t.rest;if(r){for(var s in r)t[s]=r[s];delete t.rest}var l=new n;return a(l,l.head,e),i(e,l,t,l.head,0),o(l)},hooks:{all:{},add:function(e,t){var i=d.hooks.all;i[e]=i[e]||[],i[e].push(t)},run:function(e,t){var i=d.hooks.all[e];if(i&&i.length)for(var n,a=0;n=i[a++];)n(t)}},Token:t};if(e.Prism=d,t.stringify=function e(t,i){if("string"==typeof t)return t;if(Array.isArray(t)){var n="";return t.forEach(function(t){n+=e(t,i)}),n}var a={type:t.type,content:e(t.content,i),tag:"span",classes:["token",t.type],attributes:{},language:i},r=t.alias;r&&(Array.isArray(r)?Array.prototype.push.apply(a.classes,r):a.classes.push(r)),d.hooks.run("wrap",a);var o="";for(var s in a.attributes)o+=" "+s+'="'+(a.attributes[s]||"").replace(/"/g,"&quot;")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+o+">"+a.content+"</"+a.tag+">"},!e.document)return e.addEventListener?(d.disableWorkerMessageHandler||e.addEventListener("message",function(t){var i=JSON.parse(t.data),n=i.language,a=i.code,r=i.immediateClose;e.postMessage(d.highlight(a,d.languages[n],n)),r&&e.close()},!1),d):d;var u=d.util.currentScript();if(u&&(d.filename=u.src,u.hasAttribute("data-manual")&&(d.manual=!0)),!d.manual){var h=document.readyState;"loading"===h||"interactive"===h&&u&&u.defer?document.addEventListener("DOMContentLoaded",s):window.requestAnimationFrame?window.requestAnimationFrame(s):window.setTimeout(s,16)}return d}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),define("prism/prism",function(){}),window.Prism=window.Prism||{},window.Prism.manual=!0,define("WoltLabSuite/Core/Prism",["prism/prism"],function(){return Prism.wscSplitIntoLines=function(e){function t(){var e=elCreate("span");return elData(e,"number",o++),r.appendChild(e),e}var i,n,a,r=document.createDocumentFragment(),o=1;for(i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT,function(){return NodeFilter.FILTER_ACCEPT},!1),a=t();n=i.nextNode();)n.data.split(/\r?\n/).forEach(function(i,r){var o,s;for(r>=1&&(a.appendChild(document.createTextNode("\n")),a=t()),o=document.createTextNode(i),s=n.parentNode;s!==e;){var l=s.cloneNode(!1);l.appendChild(o),o=l,s=s.parentNode}a.appendChild(o)});return r},Prism}),define("WoltLabSuite/Core/Upload",["AjaxRequest","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse"],function(e,t,i,n,a,r){"use strict";function o(e,i,n){if(n=n||{},void 0===n.className)throw new Error("Missing class name.");if(this._options=t.extend({action:"upload",multiple:!1,acceptableFiles:null,name:"__files[]",singleFileRequests:!1,url:"index.php?ajax-upload/&t="+SECURITY_TOKEN},n),this._options.url=t.convertLegacyUrl(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),this._buttonContainer=elById(e),null===this._buttonContainer)throw new Error("Element id '"+e+"' is unknown.");if(this._target=elById(i),null===i)throw new Error("Element id '"+i+"' is unknown.");if(n.multiple&&"UL"!==this._target.nodeName&&"OL"!==this._target.nodeName&&"TBODY"!==this._target.nodeName)throw new Error("Target element has to be list or table body if uploading multiple files is supported.");this._fileElements=[],this._internalFileId=0,this._multiFileUploadIds=[],this._createButton()}return o.prototype={_createButton:function(){this._fileUpload=elCreate("input"),elAttr(this._fileUpload,"type","file"),elAttr(this._fileUpload,"name",this._options.name),this._options.multiple&&elAttr(this._fileUpload,"multiple","true"),null!==this._options.acceptableFiles&&elAttr(this._fileUpload,"accept",this._options.acceptableFiles.join(",")),this._fileUpload.addEventListener("change",this._upload.bind(this)),this._button=elCreate("p"),this._button.className="button uploadButton",elAttr(this._button,"role","button"),this._fileUpload.addEventListener("focus",function(){this._fileUpload.classList.contains("focus-visible")&&this._button.classList.add("active")}.bind(this)),this._fileUpload.addEventListener("blur",function(){this._button.classList.remove("active")}.bind(this));var e=elCreate("span");e.textContent=n.get("wcf.global.button.upload"),this._button.appendChild(e),a.prepend(this._fileUpload,this._button),this._insertButton(),i.trigger()},_createFileElement:function(e){var t=elCreate("progress");if(elAttr(t,"max",100),"OL"===this._target.nodeName||"UL"===this._target.nodeName){var i=elCreate("li");return i.innerText=e.name,i.appendChild(t),this._target.appendChild(i),i}if("TBODY"===this._target.nodeName)return this._createFileTableRow(e);var n=elCreate("p");return n.appendChild(t),this._target.appendChild(n),n},_createFileElements:function(e){if(e.length){var t=this._fileElements.length;this._fileElements[t]=[];for(var n=0,a=e.length;n<a;n++){var r=e[n],o=this._createFileElement(r);o.classList.contains("uploadFailed")||(elData(o,"filename",r.name),elData(o,"internal-file-id",this._internalFileId++),this._fileElements[t][n]=o)}return i.trigger(),t}return null},_createFileTableRow:function(e){throw new Error("Has to be implemented in subclass.")},_failure:function(e,t,i,n,a){return!0},_getParameters:function(){return{}},_getFormData:function(){return{}},_insertButton:function(){a.prepend(this._button,this._buttonContainer)},_progress:function(e,t){var i=Math.round(t.loaded/t.total*100);for(var n in this._fileElements[e]){var a=elByTag("PROGRESS",this._fileElements[e][n]);1===a.length&&elAttr(a[0],"value",i)}},_removeButton:function(){elRemove(this._button),i.trigger()},_success:function(e,t,i,n,a){},_upload:function(e,t,i){for(var n=r.childrenByClass(this._target,"uploadFailed"),a=0,o=n.length;a<o;a++)elRemove(n[a]);var s=null,l=[];if(t)l.push(t);else if(i){var c="";switch(i.type){case"image/jpeg":c=".jpg";break;case"image/gif":c=".gif";break;case"image/png":c=".png"}l.push({name:"pasted-from-clipboard"+c})}else l=this._fileUpload.files;if(l.length&&this.validateUpload(l))if(this._options.singleFileRequests){s=[];for(var a=0,o=l.length;a<o;a++){var d=this._uploadFiles([l[a]],i);1!==l.length&&this._multiFileUploadIds.push(d),s.push(d)}}else s=this._uploadFiles(l,i);return this._removeButton(),this._createButton(),s},validateUpload:function(e){return!0},_uploadFiles:function(t,i){var n=this._createFileElements(t);if(!this._fileElements[n].length)return null;for(var a=new FormData,r=0,o=t.length;r<o;r++)if(this._fileElements[n][r]){var s=elData(this._fileElements[n][r],"internal-file-id");i?a.append("__files["+s+"]",i,t[r].name):a.append("__files["+s+"]",t[r])}a.append("actionName",this._options.action),a.append("className",this._options.className),"upload"===this._options.action&&a.append("interfaceName","wcf\\data\\IUploadAction");var l=function(e,t){t=t||"";for(var i in e)if("object"==typeof e[i]){var n=0===t.length?i:t+"["+i+"]";l(e[i],n)}else{var r=0===t.length?i:t+"["+i+"]";a.append(r,e[i])}};return l(this._getParameters(),"parameters"),l(this._getFormData()),new e({data:a,contentType:!1,failure:this._failure.bind(this,n),silent:!0,success:this._success.bind(this,n),uploadProgress:this._progress.bind(this,n),url:this._options.url,withCredentials:!0}).sendRequest(),n},hasPendingUploads:function(){for(var e in this._fileElements)for(var t in this._fileElements[e]){var i=elByTag("PROGRESS",this._fileElements[e][t]);if(1===i.length)return!0}return!1},uploadBlob:function(e){return this._upload(null,null,e)},uploadFile:function(e){return this._upload(null,e)}},o}),define("WoltLabSuite/Core/Ajax/Jsonp",["Core"],function(e){"use strict";return{send:function(t,i,n,a){if(t="string"==typeof t?t.trim():"",0===t.length)throw new Error("Expected a non-empty string for parameter 'url'.");if("function"!=typeof i)throw new TypeError("Expected a valid callback function for parameter 'success'.");a=e.extend({parameterName:"callback",timeout:10},a||{});var r,o="wcf_jsonp_"+e.getUuid().replace(/-/g,"").substr(0,8),s=window.setTimeout(function(){"function"==typeof n&&n(),window[o]=void 0,elRemove(r)},1e3*(~~a.timeout||10));window[o]=function(){window.clearTimeout(s),i.apply(null,arguments),window[o]=void 0,elRemove(r)},t+=-1===t.indexOf("?")?"?":"&",t+=a.parameterName+"="+o,r=elCreate("script"),r.async=!0,elAttr(r,"src",t),document.head.appendChild(r)}}}),define("WoltLabSuite/Core/Ui/Notification",["Language"],function(e){"use strict";var t=!1,i=null,n=null,a=null,r=null,o=null;return{show:function(s,l,c){t||(this._init(),i="function"==typeof l?l:null,n.className=c||"success",n.textContent=e.get(s||"wcf.global.success"),t=!0,a.classList.add("active"),r=setTimeout(o,2e3))},_init:function(){null===a&&(o=this._hide.bind(this),a=elCreate("div"),a.id="systemNotification",n=elCreate("p"),n.addEventListener(WCF_CLICK_EVENT,o),a.appendChild(n),document.body.appendChild(a))},_hide:function(){clearTimeout(r),a.classList.remove("active"),null!==i&&i(),t=!1}}}),define("prism/prism-meta",[],function(){return{markup:{title:"Markup",file:"markup"},html:{title:"HTML",file:"markup"},xml:{title:"XML",file:"markup"},svg:{title:"SVG",file:"markup"},mathml:{title:"MathML",file:"markup"},ssml:{title:"SSML",file:"markup"},atom:{title:"Atom",file:"markup"},rss:{title:"RSS",file:"markup"},css:{title:"CSS",file:"css"},clike:{title:"C-like",file:"clike"},javascript:{title:"JavaScript",file:"javascript"},abap:{title:"ABAP",file:"abap"},abnf:{title:"ABNF",file:"abnf"},actionscript:{title:"ActionScript",file:"actionscript"},ada:{title:"Ada",file:"ada"},agda:{title:"Agda",file:"agda"},al:{title:"AL",file:"al"},antlr4:{title:"ANTLR4",file:"antlr4"},apacheconf:{title:"Apache Configuration",file:"apacheconf"},apl:{title:"APL",file:"apl"},applescript:{title:"AppleScript",file:"applescript"},aql:{title:"AQL",file:"aql"},arduino:{title:"Arduino",file:"arduino"},arff:{title:"ARFF",file:"arff"},asciidoc:{title:"AsciiDoc",file:"asciidoc"},aspnet:{title:"ASP.NET (C#)",file:"aspnet"},asm6502:{title:"6502 Assembly",file:"asm6502"},autohotkey:{title:"AutoHotkey",file:"autohotkey"},autoit:{title:"AutoIt",file:"autoit"},bash:{title:"Bash",file:"bash"},basic:{title:"BASIC",file:"basic"},batch:{title:"Batch",file:"batch"},bbcode:{title:"BBcode",file:"bbcode"},bison:{title:"Bison",file:"bison"},bnf:{title:"BNF",file:"bnf"},brainfuck:{title:"Brainfuck",file:"brainfuck"},brightscript:{title:"BrightScript",file:"brightscript"},bro:{title:"Bro",file:"bro"},c:{title:"C",file:"c"},csharp:{title:"C#",file:"csharp"},cpp:{title:"C++",file:"cpp"},cil:{title:"CIL",file:"cil"},clojure:{title:"Clojure",file:"clojure"},cmake:{title:"CMake",file:"cmake"},coffeescript:{title:"CoffeeScript",file:"coffeescript"},concurnas:{title:"Concurnas",file:"concurnas"},csp:{title:"Content-Security-Policy",file:"csp"},crystal:{title:"Crystal",file:"crystal"},"css-extras":{title:"CSS Extras",file:"css-extras"},cypher:{title:"Cypher",file:"cypher"},d:{title:"D",file:"d"},dart:{title:"Dart",file:"dart"},dax:{title:"DAX",file:"dax"},dhall:{title:"Dhall",file:"dhall"},diff:{title:"Diff",file:"diff"},django:{title:"Django/Jinja2",file:"django"},"dns-zone-file":{title:"DNS zone file",file:"dns-zone-file"},docker:{title:"Docker",file:"docker"},ebnf:{title:"EBNF",file:"ebnf"},editorconfig:{title:"EditorConfig",file:"editorconfig"},eiffel:{title:"Eiffel",file:"eiffel"},ejs:{title:"EJS",file:"ejs"},elixir:{title:"Elixir",file:"elixir"},elm:{title:"Elm",file:"elm"},etlua:{title:"Embedded Lua templating",file:"etlua"},erb:{title:"ERB",file:"erb"},erlang:{title:"Erlang",file:"erlang"},"excel-formula":{title:"Excel Formula",file:"excel-formula"},fsharp:{title:"F#",file:"fsharp"},factor:{title:"Factor",file:"factor"},"firestore-security-rules":{title:"Firestore security rules",file:"firestore-security-rules"},flow:{title:"Flow",file:"flow"},fortran:{title:"Fortran",file:"fortran"},ftl:{title:"FreeMarker Template Language",file:"ftl"},gml:{title:"GameMaker Language",file:"gml"},gcode:{title:"G-code",file:"gcode"},gdscript:{title:"GDScript",file:"gdscript"},gedcom:{title:"GEDCOM",file:"gedcom"},gherkin:{title:"Gherkin",file:"gherkin"},git:{title:"Git",file:"git"},glsl:{title:"GLSL",file:"glsl"},go:{title:"Go",file:"go"},graphql:{title:"GraphQL",file:"graphql"},groovy:{title:"Groovy",file:"groovy"},haml:{title:"Haml",file:"haml"},handlebars:{title:"Handlebars",file:"handlebars"},haskell:{title:"Haskell",file:"haskell"},haxe:{title:"Haxe",file:"haxe"},hcl:{title:"HCL",file:"hcl"},hlsl:{title:"HLSL",file:"hlsl"},http:{title:"HTTP",file:"http"},hpkp:{title:"HTTP Public-Key-Pins",file:"hpkp"},hsts:{title:"HTTP Strict-Transport-Security",file:"hsts"},ichigojam:{title:"IchigoJam",file:"ichigojam"},icon:{title:"Icon",file:"icon"},ignore:{title:".ignore",file:"ignore"},gitignore:{title:".gitignore",file:"ignore"},hgignore:{title:".hgignore",file:"ignore"},npmignore:{title:".npmignore",file:"ignore"},inform7:{title:"Inform 7",file:"inform7"},ini:{title:"Ini",file:"ini"},io:{title:"Io",file:"io"},j:{title:"J",file:"j"},java:{title:"Java",file:"java"},javadoc:{title:"JavaDoc",file:"javadoc"},javadoclike:{title:"JavaDoc-like",file:"javadoclike"},javastacktrace:{title:"Java stack trace",file:"javastacktrace"},jolie:{title:"Jolie",file:"jolie"},jq:{title:"JQ",file:"jq"},jsdoc:{title:"JSDoc",file:"jsdoc"},"js-extras":{title:"JS Extras",file:"js-extras"},json:{title:"JSON",file:"json"},json5:{title:"JSON5",file:"json5"},jsonp:{title:"JSONP",file:"jsonp"},jsstacktrace:{title:"JS stack trace",file:"jsstacktrace"},"js-templates":{title:"JS Templates",file:"js-templates"},julia:{title:"Julia",file:"julia"},keyman:{title:"Keyman",file:"keyman"},kotlin:{title:"Kotlin",file:"kotlin"},kts:{title:"Kotlin Script",file:"kotlin"},latex:{title:"LaTeX",file:"latex"},tex:{title:"TeX",file:"latex"},context:{title:"ConTeXt",file:"latex"},latte:{title:"Latte",file:"latte"},less:{title:"Less",file:"less"},lilypond:{title:"LilyPond",file:"lilypond"},liquid:{title:"Liquid",file:"liquid"},lisp:{title:"Lisp",file:"lisp"},livescript:{title:"LiveScript",file:"livescript"},llvm:{title:"LLVM IR",file:"llvm"},lolcode:{title:"LOLCODE",file:"lolcode"},lua:{title:"Lua",file:"lua"},makefile:{title:"Makefile",file:"makefile"},markdown:{title:"Markdown",file:"markdown"},"markup-templating":{title:"Markup templating",file:"markup-templating"},matlab:{title:"MATLAB",file:"matlab"},mel:{title:"MEL",file:"mel"},mizar:{title:"Mizar",file:"mizar"},monkey:{title:"Monkey",file:"monkey"},moonscript:{title:"MoonScript",file:"moonscript"},n1ql:{title:"N1QL",file:"n1ql"},n4js:{title:"N4JS",file:"n4js"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",file:"nand2tetris-hdl"},nasm:{title:"NASM",file:"nasm"},neon:{title:"NEON",file:"neon"},nginx:{title:"nginx",file:"nginx"},nim:{title:"Nim",file:"nim"},nix:{title:"Nix",file:"nix"},nsis:{title:"NSIS",file:"nsis"},objectivec:{title:"Objective-C",file:"objectivec"},ocaml:{title:"OCaml",file:"ocaml"},opencl:{title:"OpenCL",file:"opencl"},oz:{title:"Oz",file:"oz"},parigp:{title:"PARI/GP",file:"parigp"},parser:{title:"Parser",file:"parser"},pascal:{title:"Pascal",file:"pascal"},pascaligo:{title:"Pascaligo",file:"pascaligo"},pcaxis:{title:"PC-Axis",file:"pcaxis"},peoplecode:{title:"PeopleCode",file:"peoplecode"},perl:{title:"Perl",file:"perl"},php:{title:"PHP",file:"php"},phpdoc:{title:"PHPDoc",file:"phpdoc"},"php-extras":{title:"PHP Extras",file:"php-extras"},plsql:{title:"PL/SQL",file:"plsql"},powerquery:{title:"PowerQuery",file:"powerquery"},powershell:{title:"PowerShell",file:"powershell"},processing:{title:"Processing",file:"processing"},prolog:{title:"Prolog",file:"prolog"},properties:{title:".properties",file:"properties"},protobuf:{title:"Protocol Buffers",file:"protobuf"},pug:{title:"Pug",file:"pug"},puppet:{title:"Puppet",file:"puppet"},pure:{title:"Pure",file:"pure"},purebasic:{title:"PureBasic",file:"purebasic"},python:{title:"Python",file:"python"},q:{title:"Q (kdb+ database)",file:"q"},qml:{title:"QML",file:"qml"},qore:{title:"Qore",file:"qore"},r:{title:"R",file:"r"},racket:{title:"Racket",file:"racket"},jsx:{title:"React JSX",file:"jsx"},tsx:{title:"React TSX",file:"tsx"},reason:{title:"Reason",file:"reason"},regex:{title:"Regex",file:"regex"},renpy:{title:"Ren'py",file:"renpy"},rest:{title:"reST (reStructuredText)",file:"rest"},rip:{title:"Rip",file:"rip"},roboconf:{title:"Roboconf",file:"roboconf"},robotframework:{title:"Robot Framework",file:"robotframework"},ruby:{title:"Ruby",file:"ruby"},rust:{title:"Rust",file:"rust"},sas:{title:"SAS",file:"sas"},sass:{title:"Sass (Sass)",file:"sass"},scss:{title:"Sass (Scss)",file:"scss"},scala:{title:"Scala",file:"scala"},scheme:{title:"Scheme",file:"scheme"},"shell-session":{title:"Shell session",file:"shell-session"},smali:{title:"Smali",file:"smali"},smalltalk:{title:"Smalltalk",file:"smalltalk"},smarty:{title:"Smarty",file:"smarty"},solidity:{title:"Solidity (Ethereum)",file:"solidity"},"solution-file":{title:"Solution file",file:"solution-file"},soy:{title:"Soy (Closure Template)",file:"soy"},sparql:{title:"SPARQL",file:"sparql"},"splunk-spl":{title:"Splunk SPL",file:"splunk-spl"},sqf:{title:"SQF: Status Quo Function (Arma 3)",file:"sqf"},sql:{title:"SQL",file:"sql"},iecst:{title:"Structured Text (IEC 61131-3)",file:"iecst"},stylus:{title:"Stylus",file:"stylus"},swift:{title:"Swift",file:"swift"},"t4-templating":{title:"T4 templating",file:"t4-templating"},"t4-cs":{title:"T4 Text Templates (C#)",file:"t4-cs"},"t4-vb":{title:"T4 Text Templates (VB)",file:"t4-vb"},tap:{title:"TAP",file:"tap"},tcl:{title:"Tcl",file:"tcl"},tt2:{title:"Template Toolkit 2",file:"tt2"},textile:{title:"Textile",file:"textile"},toml:{title:"TOML",file:"toml"},turtle:{title:"Turtle",file:"turtle"},twig:{title:"Twig",file:"twig"},typescript:{title:"TypeScript",file:"typescript"},unrealscript:{title:"UnrealScript",file:"unrealscript"},vala:{title:"Vala",file:"vala"},vbnet:{title:"VB.Net",file:"vbnet"},velocity:{title:"Velocity",file:"velocity"},verilog:{title:"Verilog",file:"verilog"},vhdl:{title:"VHDL",file:"vhdl"},vim:{title:"vim",file:"vim"},"visual-basic":{title:"Visual Basic",file:"visual-basic"},vba:{title:"VBA",file:"visual-basic"},warpscript:{title:"WarpScript",file:"warpscript"},wasm:{title:"WebAssembly",file:"wasm"},wiki:{title:"Wiki markup",file:"wiki"},xeora:{title:"Xeora",file:"xeora"},"xml-doc":{title:"XML doc (.net)",file:"xml-doc"},xojo:{title:"Xojo (REALbasic)",file:"xojo"},xquery:{title:"XQuery",file:"xquery"},yaml:{title:"YAML",file:"yaml"},yang:{title:"YANG",file:"yang"},zig:{title:"Zig",file:"zig"}}}),define("WoltLabSuite/Core/Bbcode/Code",["Language","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Clipboard","WoltLabSuite/Core/Prism","prism/prism-meta"],function(e,t,i,n,a){"use strict";function r(e){var t;this.container=e,this.codeContainer=elBySel(".codeBoxCode > code",this.container),this.language=null;for(var i=0;i<this.codeContainer.classList.length;i++)(t=this.codeContainer.classList[i].match(/language-(.*)/))&&(this.language=t[1])}var o=function(e){return function(){var t=arguments;return new Promise(function(i,n){var a=function(){try{i(e.apply(null,t))}catch(e){n(e)}};window.requestIdleCallback?window.requestIdleCallback(a,{timeout:5e3}):setTimeout(a,0)})}};return r.processAll=function(){elBySelAll(".codeBox:not([data-processed])",document,function(e){elData(e,"processed","1");var t=new r(e)
+;t.language&&t.highlight(),t.createCopyButton()})},r.prototype={createCopyButton:function(){var n=elBySel(".codeBoxHeader",this.container),a=elCreate("span");a.className="icon icon24 fa-files-o pointer jsTooltip",a.setAttribute("title",e.get("wcf.message.bbcode.code.copy")),a.addEventListener("click",function(){i.copyElementTextToClipboard(this.codeContainer).then(function(){t.show(e.get("wcf.message.bbcode.code.copy.success"))})}.bind(this)),n.appendChild(a)},highlight:function(){return this.language?a[this.language]?(this.container.classList.add("highlighting"),require(["prism/components/prism-"+a[this.language].file]).then(o(function(){var e=n.languages[this.language];if(!e)throw new Error("Invalid language "+language+" given.");var t=elCreate("div");return t.innerHTML=n.highlight(this.codeContainer.textContent,e,this.language),t}.bind(this))).then(o(function(e){var t=n.wscSplitIntoLines(e),i=elBySelAll("[data-number]",t),a=elBySelAll(".codeBoxLine > span",this.codeContainer);if(i.length!==a.length)throw new Error("Unreachable");for(var r=[],s=0,l=i.length;s<l;s+=50)r.push(o(function(e){for(var t=Math.min(e+50,l),n=e;n<t;n++)a[n].parentNode.replaceChild(i[n],a[n])})(s));return Promise.all(r)}.bind(this))).then(function(){this.container.classList.remove("highlighting"),this.container.classList.add("highlighted")}.bind(this))):Promise.reject(new Error("Unknown language "+this.language)):Promise.reject(new Error("No language detected"))}},r}),define("WoltLabSuite/Core/Bbcode/Collapsible",[],function(){"use strict";var e=elByClass("jsCollapsibleBbcode");return{observe:function(){for(var t,i,n;e.length;)t=e[0],i=[],elBySelAll(".toggleButton:not(.jsToggleButtonEnabled)",t,function(e){e.closest(".jsCollapsibleBbcode")===t&&i.push(e)}),n=elBySel(".collapsibleBbcodeOverflow",t)||t,i.length>0&&function(e,t){var i=function(i){if(e.classList.toggle("collapsed")){if(t.forEach(function(e){e.classList.contains("icon")?(e.classList.remove("fa-compress"),e.classList.add("fa-expand"),e.title=elData(e,"title-expand")):e.textContent=elData(e,"title-expand")}),i instanceof Event){var n=e.getBoundingClientRect().top;if(n<0){var a=window.pageYOffset+(n-100);a<0&&(a=0),window.scrollTo(window.pageXOffset,a)}}}else t.forEach(function(e){e.classList.contains("icon")?(e.classList.add("fa-compress"),e.classList.remove("fa-expand"),e.title=elData(e,"title-collapse")):e.textContent=elData(e,"title-collapse")})};t.forEach(function(e){e.classList.add("jsToggleButtonEnabled"),e.addEventListener(WCF_CLICK_EVENT,i)}),0!==n.scrollTop&&(n.scrollTop=0,i()),n.addEventListener("scroll",function(){n.scrollTop=0,e.classList.contains("collapsed")&&i()})}(t,i),t.classList.remove("jsCollapsibleBbcode")}}}),define("WoltLabSuite/Core/Bbcode/Spoiler",["Language"],function(e){"use strict";var t=elByClass("jsSpoilerBox");return{observe:function(){for(var e,i;t.length;)e=t[0],e.classList.remove("jsSpoilerBox"),i=elBySel(".jsSpoilerToggle",e),e=i.parentNode.nextElementSibling,i.addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this,e,i))},_onClick:function(t,i,n){n.preventDefault(),i.classList.toggle("active");var a=i.classList.contains("active");window[a?"elShow":"elHide"](t),elAttr(i,"aria-expanded",a),elAttr(t,"aria-hidden",!a),elDataBool(i,"has-custom-label")||(i.textContent=e.get(i.classList.contains("active")?"wcf.bbcode.spoiler.hide":"wcf.bbcode.spoiler.show"))}}}),define("WoltLabSuite/Core/Controller/Captcha",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if(t.has(e))throw new Error("Captcha with id '"+e+"' is already registered.");if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'callback'.");t.set(e,i)},delete:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");t.delete(e)},has:function(e){return t.has(e)},getData:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");return t.get(e)()}}}),define("WoltLabSuite/Core/Controller/Clipboard",["Ajax","Core","Dictionary","EventHandler","Language","List","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Page/Action","Ui/Screen"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,f){"use strict";var p=new i,m=new i,g=new i,v=elByClass("jsClipboardContainer"),_=new o,b=new r,w={},y=new i,C=null,E=null,L=null,S='.messageCheckboxLabel > input[type="checkbox"], .message .messageClipboardCheckbox > input[type="checkbox"], .messageGroupList .columnMark > label > input[type="checkbox"]';return{setup:function(e){if(!e.pageClassName)throw new Error("Expected a non-empty string for parameter 'pageClassName'.");if(null===C)C=this._mark.bind(this),E=this._executeAction.bind(this),L=this._unmarkAll.bind(this),w=t.extend({hasMarkedItems:!1,pageClassNames:[e.pageClassName],pageObjectId:0},e),delete w.pageClassName;else{if(e.pageObjectId)throw new Error("Cannot load secondary clipboard with page object id set.");w.pageClassNames.push(e.pageClassName)}Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector),this._initContainers(),w.hasMarkedItems&&v.length&&this._loadMarkedItems(),s.add("WoltLabSuite/Core/Controller/Clipboard",this._initContainers.bind(this))},reload:function(){p.size&&this._loadMarkedItems()},_initContainers:function(){for(var e=0,t=v.length;e<t;e++){var i=v[e],n=c.identify(i),o=p.get(n);if(void 0===o){var s=elBySel(".jsClipboardMarkAll",i);if(null!==s){if(s.matches(S)){var l=s.closest("label");elAttr(l,"role","checkbox"),elAttr(l,"tabindex","0"),elAttr(l,"aria-checked",!1),elAttr(l,"aria-label",a.get("wcf.clipboard.item.markAll")),l.addEventListener("keyup",function(e){13!==e.keyCode&&32!==e.keyCode||h.click()})}elData(s,"container-id",n),s.addEventListener(WCF_CLICK_EVENT,this._markAll.bind(this))}o={checkboxes:elByClass("jsClipboardItem",i),element:i,markAll:s,markedObjectIds:new r},p.set(n,o)}for(var d=0,u=o.checkboxes.length;d<u;d++){var h=o.checkboxes[d];b.has(h)||(elData(h,"container-id",n),function(e){if(e.matches(S)){var t=e.closest("label");elAttr(t,"role","checkbox"),elAttr(t,"tabindex","0"),elAttr(t,"aria-checked",!1),elAttr(t,"aria-label",a.get("wcf.clipboard.item.mark")),t.addEventListener("keyup",function(t){13!==t.keyCode&&32!==t.keyCode||e.click()})}null===e.closest("a")?e.addEventListener(WCF_CLICK_EVENT,C):e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),window.setTimeout(function(){e.checked=!e.checked,C(null,e)},10)})}(h),b.add(h))}}},_loadMarkedItems:function(){e.api(this,{actionName:"getMarkedItems",parameters:{pageClassNames:w.pageClassNames,pageObjectID:w.pageObjectId}})},_markAll:function(e){var t=e.currentTarget,i="INPUT"!==t.nodeName||t.checked;"checkbox"===elAttr(t.parentNode,"role")&&elAttr(t.parentNode,"aria-checked",i);for(var n=[],a=elData(t,"container-id"),r=p.get(a),o=elData(r.element,"type"),s=0,c=r.checkboxes.length;s<c;s++){var d=r.checkboxes[s],u=~~elData(d,"object-id");i?d.checked||(d.checked=!0,r.markedObjectIds.add(u),n.push(u)):d.checked&&(d.checked=!1,r.markedObjectIds.delete(u),n.push(u)),"checkbox"===elAttr(d.parentNode,"role")&&elAttr(d.parentNode,"aria-checked",i);var h=l.parentByClass(t,"jsClipboardObject");null!==h&&h.classList[i?"addClass":"removeClass"]("jsMarked")}this._saveState(o,n,i)},_mark:function(e,t){t=e instanceof Event?e.currentTarget:t;var i=~~elData(t,"object-id"),n=t.checked,a=elData(t,"container-id"),r=p.get(a),o=elData(r.element,"type"),s=l.parentByClass(t,"jsClipboardObject");if(r.markedObjectIds[n?"add":"delete"](i),s.classList[n?"add":"remove"]("jsMarked"),null!==r.markAll){for(var c=!0,d=0,u=r.checkboxes.length;d<u;d++)if(!r.checkboxes[d].checked){c=!1;break}r.markAll.checked=c,"checkbox"===elAttr(r.markAll.parentNode,"role")&&elAttr(r.markAll.parentNode,"aria-checked",n)}"checkbox"===elAttr(t.parentNode,"role")&&elAttr(t.parentNode,"aria-checked",t.checked),this._saveState(o,[i],n)},_saveState:function(t,i,n){e.api(this,{actionName:n?"mark":"unmark",parameters:{pageClassNames:w.pageClassNames,pageObjectID:w.pageObjectId,objectIDs:i,objectType:t}})},_executeAction:function(e){var t=e.currentTarget,i=_.get(t);if(i.url)return void(window.location.href=i.url);var a=function(){var e=elData(t,"type");n.fire("com.woltlab.wcf.clipboard",e,{data:i,listItem:t,responseData:null})},r="string"==typeof i.internalData.confirmMessage?i.internalData.confirmMessage:"",o=!0;if("object"==typeof i.parameters&&i.parameters.actionName&&i.parameters.className){if("unmarkAll"===i.parameters.actionName||Array.isArray(i.parameters.objectIDs))if(r.length){var s="string"==typeof i.internalData.template?i.internalData.template:"";d.show({confirm:function(){var e={};if(s.length)for(var n=elBySelAll("input, select, textarea",d.getContentElement()),a=0,r=n.length;a<r;a++){var o=n[a],l=elAttr(o,"name");switch(o.nodeName){case"INPUT":("checkbox"!==o.type&&"radio"!==o.type||o.checked)&&(e[l]=elAttr(o,"value"));break;case"SELECT":e[l]=o.value;break;case"TEXTAREA":e[l]=o.value.trim()}}this._executeProxyAction(t,i,e)}.bind(this),message:r,template:s})}else this._executeProxyAction(t,i)}else r.length&&(o=!1,d.show({confirm:a,message:r}));o&&a()},_executeProxyAction:function(t,i,a){a=a||{};var r="unmarkAll"!==i.parameters.actionName?i.parameters.objectIDs:[],o={data:a};if("object"==typeof i.internalData.parameters)for(var s in i.internalData.parameters)i.internalData.parameters.hasOwnProperty(s)&&(o[s]=i.internalData.parameters[s]);e.api(this,{actionName:i.parameters.actionName,className:i.parameters.className,objectIDs:r,parameters:o},function(e){if("unmarkAll"!==i.actionName){var a=elData(t,"type");if(n.fire("com.woltlab.wcf.clipboard",a,{data:i,listItem:t,responseData:e}),y.has(a)&&-1!==y.get(a).indexOf(e.actionName))return void window.location.reload()}this._loadMarkedItems()}.bind(this))},_unmarkAll:function(t){var i=elData(t.currentTarget,"type");e.api(this,{actionName:"unmarkAll",parameters:{objectType:i}})},_ajaxSetup:function(){return{data:{className:"wcf\\data\\clipboard\\item\\ClipboardItemAction"}}},_ajaxSuccess:function(e){if("unmarkAll"===e.actionName)return void p.forEach(function(t){if(elData(t.element,"type")===e.returnValues.objectType){for(var i=elByClass("jsMarked",t.element);i.length;)i[0].classList.remove("jsMarked");null!==t.markAll&&(t.markAll.checked=!1,"checkbox"===elAttr(t.markAll.parentNode,"role")&&elAttr(t.markAll.parentNode,"aria-checked",!1));for(var n=0,a=t.checkboxes.length;n<a;n++)t.checkboxes[n].checked=!1,"checkbox"===elAttr(t.checkboxes[n].parentNode,"role")&&elAttr(t.checkboxes[n].parentNode,"aria-checked",!1);h.remove("wcfClipboard-"+e.returnValues.objectType)}}.bind(this));_=new o,y=new i,p.forEach(function(t){var i=elData(t.element,"type"),n=e.returnValues.markedItems&&e.returnValues.markedItems.hasOwnProperty(i)?e.returnValues.markedItems[i]:[];this._rebuildMarkings(t,n)}.bind(this));var t,n=[];if(e.returnValues&&e.returnValues.items)for(t in e.returnValues.items)e.returnValues.items.hasOwnProperty(t)&&n.push(t);if(m.forEach(function(e,t){-1===n.indexOf(t)&&(h.remove("wcfClipboard-"+t),g.get(t).innerHTML="")}),e.returnValues&&e.returnValues.items){var r,s,l,c,d,f,v,b,w,C,S;for(t in e.returnValues.items)if(e.returnValues.items.hasOwnProperty(t)){d=e.returnValues.items[t],y.set(t,d.reloadPageOnSuccess),s=!1,c=m.get(t),l=g.get(t),void 0===c?(s=!0,c=elCreate("a"),c.className="dropdownToggle",c.textContent=d.label,m.set(t,c),l=elCreate("ol"),l.className="dropdownMenu",g.set(t,l)):(c.textContent=d.label,l.innerHTML="");for(w in d.items)d.items.hasOwnProperty(w)&&(b=d.items[w],v=elCreate("li"),C=elCreate("span"),C.textContent=b.label,v.appendChild(C),l.appendChild(v),elData(v,"type",t),v.addEventListener(WCF_CLICK_EVENT,E),_.set(v,b));f=elCreate("li"),f.classList.add("dropdownDivider"),l.appendChild(f),S=elCreate("li"),elData(S,"type",t),C=elCreate("span"),C.textContent=a.get("wcf.clipboard.item.unmarkAll"),S.appendChild(C),S.addEventListener(WCF_CLICK_EVENT,L),l.appendChild(S),-1!==n.indexOf(t)&&(r="wcfClipboard-"+t,h.has(r)?h.show(r):h.add(r,c)),s&&(c.parentNode.classList.add("dropdown"),c.parentNode.appendChild(l),u.init(c))}}},_rebuildMarkings:function(e,t){for(var i=!0,n=0,a=e.checkboxes.length;n<a;n++){var r=e.checkboxes[n],o=l.parentByClass(r,"jsClipboardObject"),s=-1!==t.indexOf(~~elData(r,"object-id"));s||(i=!1),r.checked=s,o.classList[s?"add":"remove"]("jsMarked"),"checkbox"===elAttr(r.parentNode,"role")&&elAttr(r.parentNode,"aria-checked",s)}if(null!==e.markAll){e.markAll.checked=i,"checkbox"===elAttr(e.markAll.parentNode,"role")&&elAttr(e.markAll.parentNode,"aria-checked",i);for(var c=e.markAll;c=c.parentNode;)if(c instanceof Element&&c.classList.contains("columnMark")){c=c.parentNode;break}c&&c.classList[i?"add":"remove"]("jsMarked")}},hideEditor:function(e){h.remove("wcfClipboard-"+e),f.pageOverlayOpen()},showEditor:function(){this._loadMarkedItems(),f.pageOverlayClose()},unmark:function(e,t){this._saveState(e,t,!1)}}}),define("WoltLabSuite/Core/Image/ExifUtil",[],function(){"use strict";function e(e){return e===i||e===n||e===a}var t={SOI:216,APP0:224,APP1:225,APP2:226,APP3:227,APP4:228,APP5:229,APP6:230,APP7:231,APP8:232,APP9:233,APP10:234,APP11:235,APP12:236,APP13:237,APP14:238,COM:254},i="Exif",n="http://ns.adobe.com/xap/1.0/",a="http://ns.adobe.com/xmp/extension/";return{getExifBytesFromJpeg:function(i){return new Promise(function(n,a){if(!(i instanceof Blob||i instanceof File))return a(new TypeError("The argument must be a Blob or a File"));var r=new FileReader;r.addEventListener("error",function(){r.abort(),a(r.error)}),r.addEventListener("load",function(){var i=r.result,o=new Uint8Array(i),s=new Uint8Array;if(255!==o[0]&&o[1]!==t.SOI)return a(new Error("Not a JPEG"));for(var l=2;l<o.length&&255===o[l];){var c=2+(o[l+2]<<8|o[l+3]);if(o[l+1]===t.APP1){for(var d="",u=l+4;0!==o[u]&&u<o.length;u++)d+=String.fromCharCode(o[u]);if(e(d)){var h=Array.prototype.slice.call(o,l,c+l),f=new Uint8Array(s.length+h.length);f.set(s),f.set(h,s.length),s=f}}l+=c}n(s)}),r.readAsArrayBuffer(i)})},removeExifData:function(i){return new Promise(function(n,a){if(!(i instanceof Blob||i instanceof File))return a(new TypeError("The argument must be a Blob or a File"));var r=new FileReader;r.addEventListener("error",function(){r.abort(),a(r.error)}),r.addEventListener("load",function(){var o=r.result,s=new Uint8Array(o);if(255!==s[0]&&s[1]!==t.SOI)return a(new Error("Not a JPEG"));for(var l=2;l<s.length&&255===s[l];){var c=2+(s[l+2]<<8|s[l+3]);if(s[l+1]===t.APP1){for(var d="",u=l+4;0!==s[u]&&u<s.length;u++)d+=String.fromCharCode(s[u]);if(e(d)){var h=Array.prototype.slice.call(s,0,l),f=Array.prototype.slice.call(s,l+c);s=new Uint8Array(h.length+f.length),s.set(h,0),s.set(f,h.length)}else l+=c}else l+=c}n(new Blob([s],{type:i.type}))}),r.readAsArrayBuffer(i)})},setExifData:function(e,i){return this.removeExifData(e).then(function(e){return new Promise(function(n){var a=new FileReader;a.addEventListener("error",function(){a.abort(),reject(a.error)}),a.addEventListener("load",function(){var r=a.result,o=new Uint8Array(r),s=2;255===o[2]&&o[3]===t.APP0&&(s+=2+(o[4]<<8|o[5]));var l=Array.prototype.slice.call(o,0,s),c=Array.prototype.slice.call(o,s);o=new Uint8Array(l.length+i.length+c.length),o.set(l),o.set(i,s),o.set(c,s+i.length),n(new Blob([o],{type:e.type}))}),a.readAsArrayBuffer(e)})})}}}),define("WoltLabSuite/Core/Image/ImageUtil",[],function(){"use strict";return{containsTransparentPixels:function(e){for(var t=e.getContext("2d").getImageData(0,0,e.width,e.height),i=3,n=t.data.length;i<n;i+=4)if(255!==t.data[i])return!0;return!1}}}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("Pica",[],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pica=e()}}(function(){return function(){function e(t,i,n){function a(o,s){if(!i[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var d=i[o]={exports:{}};t[o][0].call(d.exports,function(e){return a(t[o][1][e]||e)},d,d.exports,e,t,i,n)}return i[o].exports}for(var r="function"==typeof require&&require,o=0;o<n.length;o++)a(n[o]);return a}return e}()({1:[function(e,t,i){"use strict";function n(e){var t=e||[],i={js:t.indexOf("js")>=0,wasm:t.indexOf("wasm")>=0};r.call(this,i),this.features={js:i.js,wasm:i.wasm&&this.has_wasm()},this.use(o),this.use(s)}var a=e("inherits"),r=e("multimath"),o=e("multimath/lib/unsharp_mask"),s=e("./mm_resize");a(n,r),n.prototype.resizeAndUnsharp=function(e,t){var i=this.resize(e,t);return e.unsharpAmount&&this.unsharp_mask(i,e.toWidth,e.toHeight,e.unsharpAmount,e.unsharpRadius,e.unsharpThreshold),i},t.exports=n},{"./mm_resize":4,inherits:15,multimath:16,"multimath/lib/unsharp_mask":19}],2:[function(e,t,i){"use strict";function n(e){return e<0?0:e>255?255:e}function a(e,t,i,a,r,o){var s,l,c,d,u,h,f,p,m,g,v,_=0,b=0;for(m=0;m<a;m++){for(u=0,g=0;g<r;g++){for(h=o[u++],f=o[u++],p=_+4*h|0,s=l=c=d=0;f>0;f--)v=o[u++],d=d+v*e[p+3]|0,c=c+v*e[p+2]|0,l=l+v*e[p+1]|0,s=s+v*e[p]|0,p=p+4|0;t[b+3]=n(d+8192>>14),t[b+2]=n(c+8192>>14),t[b+1]=n(l+8192>>14),t[b]=n(s+8192>>14),b=b+4*a|0}b=4*(m+1)|0,_=(m+1)*i*4|0}}function r(e,t,i,a,r,o){var s,l,c,d,u,h,f,p,m,g,v,_=0,b=0;for(m=0;m<a;m++){for(u=0,g=0;g<r;g++){for(h=o[u++],f=o[u++],p=_+4*h|0,s=l=c=d=0;f>0;f--)v=o[u++],d=d+v*e[p+3]|0,c=c+v*e[p+2]|0,l=l+v*e[p+1]|0,s=s+v*e[p]|0,p=p+4|0;t[b+3]=n(d+8192>>14),t[b+2]=n(c+8192>>14),t[b+1]=n(l+8192>>14),t[b]=n(s+8192>>14),b=b+4*a|0}b=4*(m+1)|0,_=(m+1)*i*4|0}}t.exports={convolveHorizontally:a,convolveVertically:r}},{}],3:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQQEAXAAAAcZAghjb252b2x2ZQAACmNvbnZvbHZlSFYAAQkBAArmAwLBAwEQfwJAIANFDQAgBEUNACAFQQRqIRVBACEMQQAhDQNAIA0hDkEAIRFBACEHA0AgB0ECaiESAn8gBSAHQQF0IgdqIgZBAmouAQAiEwRAQQAhCEEAIBNrIRQgFSAHaiEPIAAgDCAGLgEAakECdGohEEEAIQlBACEKQQAhCwNAIBAoAgAiB0EYdiAPLgEAIgZsIAtqIQsgB0H/AXEgBmwgCGohCCAHQRB2Qf8BcSAGbCAKaiEKIAdBCHZB/wFxIAZsIAlqIQkgD0ECaiEPIBBBBGohECAUQQFqIhQNAAsgEiATagwBC0EAIQtBACEKQQAhCUEAIQggEgshByABIA5BAnRqIApBgMAAakEOdSIGQf8BIAZB/wFIG0EQdEGAgPwHcUEAIAZBAEobIAtBgMAAakEOdSIGQf8BIAZB/wFIG0EYdEEAIAZBAEobciAJQYDAAGpBDnUiBkH/ASAGQf8BSBtBCHRBgP4DcUEAIAZBAEobciAIQYDAAGpBDnUiBkH/ASAGQf8BSBtB/wFxQQAgBkEAShtyNgIAIA4gA2ohDiARQQFqIhEgBEcNAAsgDCACaiEMIA1BAWoiDSADRw0ACwsLIQACQEEAIAIgAyAEIAUgABAAIAJBACAEIAUgBiABEAALCw=="},{}],4:[function(e,t,i){"use strict";t.exports={name:"resize",fn:e("./resize"),wasm_fn:e("./resize_wasm"),wasm_src:e("./convolve_wasm_base64")}},{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,a=t*i*4|0;n<a;)e[n]=255,n=n+4|0}var a=e("./resize_filter_gen"),r=e("./convolve").convolveHorizontally,o=e("./convolve").convolveVertically;t.exports=function(e){var t=e.src,i=e.width,s=e.height,l=e.toWidth,c=e.toHeight,d=e.scaleX||e.toWidth/e.width,u=e.scaleY||e.toHeight/e.height,h=e.offsetX||0,f=e.offsetY||0,p=e.dest||new Uint8Array(l*c*4),m=void 0===e.quality?3:e.quality,g=e.alpha||!1,v=a(m,i,l,d,h),_=a(m,s,c,u,f),b=new Uint8Array(l*s*4);return r(t,b,i,s,l,v),o(b,p,s,l,c,_),g||n(p,l,c),p}},{"./convolve":2,"./resize_filter_gen":6}],6:[function(e,t,i){"use strict";function n(e){return Math.round(e*((1<<r)-1))}var a=e("./resize_filter_info"),r=14;t.exports=function(e,t,i,r,o){var s,l,c,d,u,h,f,p,m,g,v,_,b,w,y,C,E,L=a[e].filter,S=1/r,A=Math.min(1,r),I=a[e].win/A,D=Math.floor(2*(I+1)),x=new Int16Array((D+2)*i),T=0,k=!x.subarray||!x.set;for(s=0;s<i;s++){for(l=(s+.5)*S+o,c=Math.max(0,Math.floor(l-I)),d=Math.min(t-1,Math.ceil(l+I)),u=d-c+1,h=new Float32Array(u),f=new Int16Array(u),p=0,m=c,g=0;m<=d;m++,g++)v=L((m+.5-l)*A),p+=v,h[g]=v;for(_=0,g=0;g<h.length;g++)b=h[g]/p,_+=b,f[g]=n(b);for(f[i>>1]+=n(1-_),w=0;w<f.length&&0===f[w];)w++;if(w<f.length){for(y=f.length-1;y>0&&0===f[y];)y--;if(C=c+w,E=y-w+1,x[T++]=C,x[T++]=E,k)for(g=w;g<=y;g++)x[T++]=f[g];else x.set(f.subarray(w,y+1),T),T+=E}else x[T++]=0,x[T++]=0}return x}},{"./resize_filter_info":7}],7:[function(e,t,i){"use strict";t.exports=[{win:.5,filter:function(e){return e>=-.5&&e<.5?1:0}},{win:1,filter:function(e){if(e<=-1||e>=1)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*(.54+.46*Math.cos(t/1))}},{win:2,filter:function(e){if(e<=-2||e>=2)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/2)/(t/2)}},{win:3,filter:function(e){if(e<=-3||e>=3)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/3)/(t/3)}}]},{}],8:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,a=t*i*4|0;n<a;)e[n]=255,n=n+4|0}function a(e){return new Uint8Array(e.buffer,0,e.byteLength)}function r(e,t,i){if(s)return void t.set(a(e),i);for(var n=i,r=0;r<e.length;r++){var o=e[r];t[n++]=255&o,t[n++]=o>>8&255}}var o=e("./resize_filter_gen"),s=!0;try{s=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0]}catch(e){}t.exports=function(e){var t=e.src,i=e.width,a=e.height,s=e.toWidth,l=e.toHeight,c=e.scaleX||e.toWidth/e.width,d=e.scaleY||e.toHeight/e.height,u=e.offsetX||0,h=e.offsetY||0,f=e.dest||new Uint8Array(s*l*4),p=void 0===e.quality?3:e.quality,m=e.alpha||!1,g=o(p,i,s,c,u),v=o(p,a,l,d,h),_=this.__align(0+Math.max(t.byteLength,f.byteLength)),b=this.__align(_+a*s*4),w=this.__align(b+g.byteLength),y=w+v.byteLength,C=this.__instance("resize",y),E=new Uint8Array(this.__memory.buffer),L=new Uint32Array(this.__memory.buffer),S=new Uint32Array(t.buffer);return L.set(S),r(g,E,b),r(v,E,w),(C.exports.convolveHV||C.exports._convolveHV)(b,w,_,i,a,s,l),new Uint32Array(f.buffer).set(new Uint32Array(this.__memory.buffer,0,l*s)),m||n(f,s,l),f}},{"./resize_filter_gen":6}],9:[function(e,t,i){"use strict";function n(e,t){this.create=e,this.available=[],this.acquired={},this.lastId=1,this.timeoutId=0,this.idle=t||2e3}n.prototype.acquire=function(){var e,t=this;return 0!==this.available.length?e=this.available.pop():(e=this.create(),e.id=this.lastId++,e.release=function(){return t.release(e)}),this.acquired[e.id]=e,e},n.prototype.release=function(e){var t=this;delete this.acquired[e.id],e.lastUsed=Date.now(),this.available.push(e),0===this.timeoutId&&(this.timeoutId=setTimeout(function(){return t.gc()},100))},n.prototype.gc=function(){var e=this,t=Date.now();this.available=this.available.filter(function(i){return!(t-i.lastUsed>e.idle)||(i.destroy(),!1)}),0!==this.available.length?this.timeoutId=setTimeout(function(){return e.gc()},100):this.timeoutId=0},t.exports=n},{}],10:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,a,r){var o=i/e,s=n/t,l=(2*r+2+1)/a;if(l>.5)return[[i,n]];var c=Math.ceil(Math.log(Math.min(o,s))/Math.log(l));if(c<=1)return[[i,n]];for(var d=[],u=0;u<c;u++){var h=Math.round(Math.pow(Math.pow(e,c-u-1)*Math.pow(i,u+1),1/c)),f=Math.round(Math.pow(Math.pow(t,c-u-1)*Math.pow(n,u+1),1/c));d.push([h,f])}return d}},{}],11:[function(e,t,i){"use strict";function n(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.floor(e)}function a(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.ceil(e)}var r=1e-5;t.exports=function(e){var t=e.toWidth/e.width,i=e.toHeight/e.height,r=n(e.srcTileSize*t)-2*e.destTileBorder,o=n(e.srcTileSize*i)-2*e.destTileBorder;if(r<1||o<1)throw new Error("Internal error in pica: target tile width/height is too small.");var s,l,c,d,u,h,f,p=[];for(d=0;d<e.toHeight;d+=o)for(c=0;c<e.toWidth;c+=r)s=c-e.destTileBorder,s<0&&(s=0),u=c+r+e.destTileBorder-s,s+u>=e.toWidth&&(u=e.toWidth-s),l=d-e.destTileBorder,l<0&&(l=0),h=d+o+e.destTileBorder-l,l+h>=e.toHeight&&(h=e.toHeight-l),f={toX:s,toY:l,toWidth:u,toHeight:h,toInnerX:c,toInnerY:d,toInnerWidth:r,toInnerHeight:o,offsetX:s/t-n(s/t),offsetY:l/i-n(l/i),scaleX:t,scaleY:i,x:n(s/t),y:n(l/i),width:a(u/t),height:a(h/i)},p.push(f);return p}},{}],12:[function(e,t,i){"use strict";function n(e){return Object.prototype.toString.call(e)}t.exports.isCanvas=function(e){var t=n(e);return"[object HTMLCanvasElement]"===t||"[object Canvas]"===t},t.exports.isImage=function(e){return"[object HTMLImageElement]"===n(e)},t.exports.limiter=function(e){function t(){i<e&&n.length&&(i++,n.shift()())}var i=0,n=[];return function(e){return new Promise(function(a,r){n.push(function(){e().then(function(e){a(e),i--,t()},function(e){r(e),i--,t()})}),t()})}},t.exports.cib_quality_name=function(e){switch(e){case 0:return"pixelated";case 1:return"low";case 2:return"medium"}return"high"},t.exports.cib_support=function(){return Promise.resolve().then(function(){if("undefined"==typeof createImageBitmap||"undefined"==typeof document)return!1;var e=document.createElement("canvas");return e.width=100,e.height=100,createImageBitmap(e,0,0,100,100,{resizeWidth:10,resizeHeight:10,resizeQuality:"high"}).then(function(t){var i=10===t.width;return t.close(),e=null,i})}).catch(function(){return!1})}},{}],13:[function(e,t,i){"use strict";t.exports=function(){var t,i=e("./mathlib");onmessage=function(e){var n=e.data.opts;t||(t=new i(e.data.features));var a=t.resizeAndUnsharp(n);postMessage({result:a},[a.buffer])}}},{"./mathlib":1}],14:[function(e,t,i){function n(e){e<.5&&(e=.5);var t=Math.exp(.527076)/e,i=Math.exp(-t),n=Math.exp(-2*t),a=(1-i)*(1-i)/(1+2*t*i-n);return o=a,s=a*(t-1)*i,l=a*(t+1)*i,c=-a*n,d=2*i,u=-n,h=(o+s)/(1-d-u),f=(l+c)/(1-d-u),new Float32Array([o,s,l,c,d,u,h,f])}function a(e,t,i,n,a,r){var o,s,l,c,d,u,h,f,p,m,g,v,_,b;for(p=0;p<r;p++){for(u=p*a,h=p,f=0,o=e[u],d=o*n[6],c=d,g=n[0],v=n[1],_=n[4],b=n[5],m=0;m<a;m++)s=e[u],l=s*g+o*v+c*_+d*b,d=c,c=l,o=s,i[f]=c,f++,u++;for(u--,f--,h+=r*(a-1),o=e[u],d=o*n[7],c=d,s=o,g=n[2],v=n[3],m=a-1;m>=0;m--)l=s*g+o*v+c*_+d*b,d=c,c=l,o=s,s=e[u],t[h]=i[f]+c,u--,f--,h-=r}}function r(e,t,i,r){if(r){var o=new Uint16Array(e.length),s=new Float32Array(Math.max(t,i)),l=n(r);a(e,o,s,l,t,i,r),a(o,e,s,l,i,t,r)}}var o,s,l,c,d,u,h,f;t.exports=r},{}],15:[function(e,t,i){"function"==typeof Object.create?t.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:t.exports=function(e,t){if(t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}}},{}],16:[function(e,t,i){"use strict";function n(e){if(!(this instanceof n))return new n(e);var t=a({},s,e||{});if(this.options=t,this.__cache={},this.__init_promise=null,this.__modules=t.modules||{},this.__memory=null,this.__wasm={},this.__isLE=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0],!this.options.js&&!this.options.wasm)throw new Error('mathlib: at least "js" or "wasm" should be enabled')}var a=e("object-assign"),r=e("./lib/base64decode"),o=e("./lib/wa_detect"),s={js:!0,wasm:!0};n.prototype.has_wasm=o,n.prototype.use=function(e){return this.__modules[e.name]=e,this.options.wasm&&this.has_wasm()&&e.wasm_fn?this[e.name]=e.wasm_fn:this[e.name]=e.fn,this},n.prototype.init=function(){if(this.__init_promise)return this.__init_promise;if(!this.options.js&&this.options.wasm&&!this.has_wasm())return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));var e=this;return this.__init_promise=Promise.all(Object.keys(e.__modules).map(function(t){var i=e.__modules[t];return e.options.wasm&&e.has_wasm()&&i.wasm_fn?e.__wasm[t]?null:WebAssembly.compile(e.__base64decode(i.wasm_src)).then(function(i){e.__wasm[t]=i}):null})).then(function(){return e}),this.__init_promise},n.prototype.__base64decode=r,n.prototype.__reallocate=function(e){if(!this.__memory)return this.__memory=new WebAssembly.Memory({initial:Math.ceil(e/65536)}),this.__memory;var t=this.__memory.buffer.byteLength;return t<e&&this.__memory.grow(Math.ceil((e-t)/65536)),this.__memory},n.prototype.__instance=function(e,t,i){if(t&&this.__reallocate(t),!this.__wasm[e]){var n=this.__modules[e];this.__wasm[e]=new WebAssembly.Module(this.__base64decode(n.wasm_src))}if(!this.__cache[e]){var r={memoryBase:0,memory:this.__memory,tableBase:0,table:new WebAssembly.Table({initial:0,element:"anyfunc"})};this.__cache[e]=new WebAssembly.Instance(this.__wasm[e],{env:a(r,i||{})})}return this.__cache[e]},n.prototype.__align=function(e,t){t=t||8;var i=e%t;return e+(i?t-i:0)},t.exports=n},{"./lib/base64decode":17,"./lib/wa_detect":23,"object-assign":24}],17:[function(e,t,i){"use strict";t.exports=function(e){for(var t=e.replace(/[\r\n=]/g,""),i=t.length,n=new Uint8Array(3*i>>2),a=0,r=0,o=0;o<i;o++)o%4==0&&o&&(n[r++]=a>>16&255,n[r++]=a>>8&255,n[r++]=255&a),a=a<<6|"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t.charAt(o));var s=i%4*6;return 0===s?(n[r++]=a>>16&255,n[r++]=a>>8&255,n[r++]=255&a):18===s?(n[r++]=a>>10&255,n[r++]=a>>2&255):12===s&&(n[r++]=a>>4&255),n}},{}],18:[function(e,t,i){"use strict";t.exports=function(e,t,i){for(var n,a,r,o,s,l=t*i,c=new Uint16Array(l),d=0;d<l;d++)n=e[4*d],a=e[4*d+1],r=e[4*d+2],s=n>=a&&n>=r?n:a>=r&&a>=n?a:r,o=n<=a&&n<=r?n:a<=r&&a<=n?a:r,c[d]=257*(s+o)>>1;return c}},{}],19:[function(e,t,i){"use strict";t.exports={name:"unsharp_mask",fn:e("./unsharp_mask"),wasm_fn:e("./unsharp_mask_wasm"),wasm_src:e("./unsharp_mask_wasm_base64")}},{"./unsharp_mask":20,"./unsharp_mask_wasm":21,"./unsharp_mask_wasm_base64":22}],20:[function(e,t,i){"use strict";var n=e("glur/mono16"),a=e("./hsl_l16");t.exports=function(e,t,i,r,o,s){var l,c,d,u,h,f,p,m,g,v,_,b,w;if(!(0===r||o<.5)){o>2&&(o=2);var y=a(e,t,i),C=new Uint16Array(y);n(C,t,i,o);for(var E=r/100*4096+.5|0,L=257*s|0,S=t*i,A=0;A<S;A++)b=2*(y[A]-C[A]),Math.abs(b)>=L&&(w=4*A,l=e[w],c=e[w+1],d=e[w+2],m=l>=c&&l>=d?l:c>=l&&c>=d?c:d,p=l<=c&&l<=d?l:c<=l&&c<=d?c:d,f=257*(m+p)>>1,p===m?u=h=0:(h=f<=32767?4095*(m-p)/(m+p)|0:4095*(m-p)/(510-m-p)|0,u=l===m?65535*(c-d)/(6*(m-p))|0:c===m?21845+(65535*(d-l)/(6*(m-p))|0):43690+(65535*(l-c)/(6*(m-p))|0)),f+=E*b+2048>>12,f>65535?f=65535:f<0&&(f=0),0===h?l=c=d=f>>8:(v=f<=32767?f*(4096+h)+2048>>12:f+((65535-f)*h+2048>>12),g=2*f-v>>8,v>>=8,_=u+21845&65535,l=_>=43690?g:_>=32767?g+(6*(v-g)*(43690-_)+32768>>16):_>=10922?v:g+(6*(v-g)*_+32768>>16),_=65535&u,c=_>=43690?g:_>=32767?g+(6*(v-g)*(43690-_)+32768>>16):_>=10922?v:g+(6*(v-g)*_+32768>>16),_=u-21845&65535,d=_>=43690?g:_>=32767?g+(6*(v-g)*(43690-_)+32768>>16):_>=10922?v:g+(6*(v-g)*_+32768>>16)),e[w]=l,e[w+1]=c,e[w+2]=d)}}},{"./hsl_l16":18,"glur/mono16":14}],21:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,a,r){if(!(0===n||a<.5)){a>2&&(a=2);var o=t*i,s=4*o,l=2*o,c=2*o,d=4*Math.max(t,i),u=s,h=u+l,f=h+c,p=f+c,m=p+d,g=this.__instance("unsharp_mask",s+l+2*c+d+32,{exp:Math.exp}),v=new Uint32Array(e.buffer);new Uint32Array(this.__memory.buffer).set(v);var _=g.exports.hsl_l16||g.exports._hsl_l16;_(0,u,t,i),_=g.exports.blurMono16||g.exports._blurMono16,_(u,h,f,p,m,t,i,a),_=g.exports.unsharp||g.exports._unsharp,_(0,0,u,h,t,i,n,r),v.set(new Uint32Array(this.__memory.buffer,0,o))}}},{}],22:[function(e,t,i){"use strict"
+;t.exports="AGFzbQEAAAABMQZgAXwBfGACfX8AYAZ/f39/f38AYAh/f39/f39/fQBgBH9/f38AYAh/f39/f39/fwACGQIDZW52A2V4cAAAA2VudgZtZW1vcnkCAAEDBgUBAgMEBQQEAXAAAAdMBRZfX2J1aWxkX2dhdXNzaWFuX2NvZWZzAAEOX19nYXVzczE2X2xpbmUAAgpibHVyTW9ubzE2AAMHaHNsX2wxNgAEB3Vuc2hhcnAABQkBAAqJEAXZAQEGfAJAIAFE24a6Q4Ia+z8gALujIgOaEAAiBCAEoCIGtjgCECABIANEAAAAAAAAAMCiEAAiBbaMOAIUIAFEAAAAAAAA8D8gBKEiAiACoiAEIAMgA6CiRAAAAAAAAPA/oCAFoaMiArY4AgAgASAEIANEAAAAAAAA8L+gIAKioiIHtjgCBCABIAQgA0QAAAAAAADwP6AgAqKiIgO2OAIIIAEgBSACoiIEtow4AgwgASACIAegIAVEAAAAAAAA8D8gBqGgIgKjtjgCGCABIAMgBKEgAqO2OAIcCwu3AwMDfwR9CHwCQCADKgIUIQkgAyoCECEKIAMqAgwhCyADKgIIIQwCQCAEQX9qIgdBAEgiCA0AIAIgAC8BALgiDSADKgIYu6IiDiAJuyIQoiAOIAq7IhGiIA0gAyoCBLsiEqIgAyoCALsiEyANoqCgoCIPtjgCACACQQRqIQIgAEECaiEAIAdFDQAgBCEGA0AgAiAOIBCiIA8iDiARoiANIBKiIBMgAC8BALgiDaKgoKAiD7Y4AgAgAkEEaiECIABBAmohACAGQX9qIgZBAUoNAAsLAkAgCA0AIAEgByAFbEEBdGogAEF+ai8BACIIuCINIAu7IhGiIA0gDLsiEqKgIA0gAyoCHLuiIg4gCrsiE6KgIA4gCbsiFKKgIg8gAkF8aioCALugqzsBACAHRQ0AIAJBeGohAiAAQXxqIQBBACAFQQF0ayEHIAEgBSAEQQF0QXxqbGohBgNAIAghAyAALwEAIQggBiANIBGiIAO4Ig0gEqKgIA8iECAToqAgDiAUoqAiDyACKgIAu6CrOwEAIAYgB2ohBiAAQX5qIQAgAkF8aiECIBAhDiAEQX9qIgRBAUoNAAsLCwvfAgIDfwZ8AkAgB0MAAAAAWw0AIARE24a6Q4Ia+z8gB0MAAAA/l7ujIgyaEAAiDSANoCIPtjgCECAEIAxEAAAAAAAAAMCiEAAiDraMOAIUIAREAAAAAAAA8D8gDaEiCyALoiANIAwgDKCiRAAAAAAAAPA/oCAOoaMiC7Y4AgAgBCANIAxEAAAAAAAA8L+gIAuioiIQtjgCBCAEIA0gDEQAAAAAAADwP6AgC6KiIgy2OAIIIAQgDiALoiINtow4AgwgBCALIBCgIA5EAAAAAAAA8D8gD6GgIgujtjgCGCAEIAwgDaEgC6O2OAIcIAYEQCAFQQF0IQogBiEJIAIhCANAIAAgCCADIAQgBSAGEAIgACAKaiEAIAhBAmohCCAJQX9qIgkNAAsLIAVFDQAgBkEBdCEIIAUhAANAIAIgASADIAQgBiAFEAIgAiAIaiECIAFBAmohASAAQX9qIgANAAsLC7wBAQV/IAMgAmwiAwRAQQAgA2shBgNAIAAoAgAiBEEIdiIHQf8BcSECAn8gBEH/AXEiAyAEQRB2IgRB/wFxIgVPBEAgAyIIIAMgAk8NARoLIAQgBCAHIAIgA0kbIAIgBUkbQf8BcQshCAJAIAMgAk0EQCADIAVNDQELIAQgByAEIAMgAk8bIAIgBUsbQf8BcSEDCyAAQQRqIQAgASADIAhqQYECbEEBdjsBACABQQJqIQEgBkEBaiIGDQALCwvTBgEKfwJAIAazQwAAgEWUQwAAyEKVu0QAAAAAAADgP6CqIQ0gBSAEbCILBEAgB0GBAmwhDgNAQQAgAi8BACADLwEAayIGQQF0IgdrIAcgBkEASBsgDk8EQCAAQQJqLQAAIQUCfyAALQAAIgYgAEEBai0AACIESSIJRQRAIAYiCCAGIAVPDQEaCyAFIAUgBCAEIAVJGyAGIARLGwshCAJ/IAYgBE0EQCAGIgogBiAFTQ0BGgsgBSAFIAQgBCAFSxsgCRsLIgogCGoiD0GBAmwiEEEBdiERQQAhDAJ/QQAiCSAIIApGDQAaIAggCmsiCUH/H2wgD0H+AyAIayAKayAQQYCABEkbbSEMIAYgCEYEQCAEIAVrQf//A2wgCUEGbG0MAQsgBSAGayAGIARrIAQgCEYiBhtB//8DbCAJQQZsbUHVqgFBqtUCIAYbagshCSARIAcgDWxBgBBqQQx1aiIGQQAgBkEAShsiBkH//wMgBkH//wNIGyEGAkACfwJAIAxB//8DcSIFBEAgBkH//wFKDQEgBUGAIGogBmxBgBBqQQx2DAILIAZBCHYiBiEFIAYhBAwCCyAFIAZB//8Dc2xBgBBqQQx2IAZqCyIFQQh2IQcgBkEBdCAFa0EIdiIGIQQCQCAJQdWqAWpB//8DcSIFQanVAksNACAFQf//AU8EQEGq1QIgBWsgByAGa2xBBmxBgIACakEQdiAGaiEEDAELIAchBCAFQanVAEsNACAFIAcgBmtsQQZsQYCAAmpBEHYgBmohBAsCfyAGIgUgCUH//wNxIghBqdUCSw0AGkGq1QIgCGsgByAGa2xBBmxBgIACakEQdiAGaiAIQf//AU8NABogByIFIAhBqdUASw0AGiAIIAcgBmtsQQZsQYCAAmpBEHYgBmoLIQUgCUGr1QJqQf//A3EiCEGp1QJLDQAgCEH//wFPBEBBqtUCIAhrIAcgBmtsQQZsQYCAAmpBEHYgBmohBgwBCyAIQanVAEsEQCAHIQYMAQsgCCAHIAZrbEEGbEGAgAJqQRB2IAZqIQYLIAEgBDoAACABQQFqIAU6AAAgAUECaiAGOgAACyADQQJqIQMgAkECaiECIABBBGohACABQQRqIQEgC0F/aiILDQALCwsL"},{}],23:[function(e,t,i){"use strict";var n;t.exports=function(){if(void 0!==n)return n;if(n=!1,"undefined"==typeof WebAssembly)return n;try{var e=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11]),t=new WebAssembly.Module(e);return 0!==new WebAssembly.Instance(t,{}).exports.test(4)&&(n=!0),n}catch(e){}return n}},{}],24:[function(e,t,i){"use strict";function n(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}var a=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;t.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},i=0;i<10;i++)t["_"+String.fromCharCode(i)]=i;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(e){n[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var i,s,l=n(e),c=1;c<arguments.length;c++){i=Object(arguments[c]);for(var d in i)r.call(i,d)&&(l[d]=i[d]);if(a){s=a(i);for(var u=0;u<s.length;u++)o.call(i,s[u])&&(l[s[u]]=i[s[u]])}}return l}},{}],25:[function(e,t,i){var n=arguments[3],a=arguments[4],r=arguments[5],o=JSON.stringify;t.exports=function(e,t){function i(e){g[e]=!0;for(var t in a[e][1]){var n=a[e][1][t];g[n]||i(n)}}for(var s,l=Object.keys(r),c=0,d=l.length;c<d;c++){var u=l[c],h=r[u].exports;if(h===e||h&&h.default===e){s=u;break}}if(!s){s=Math.floor(Math.pow(16,8)*Math.random()).toString(16);for(var f={},c=0,d=l.length;c<d;c++){var u=l[c];f[u]=u}a[s]=["function(require,module,exports){"+e+"(self); }",f]}var p=Math.floor(Math.pow(16,8)*Math.random()).toString(16),m={};m[s]=s,a[p]=["function(require,module,exports){var f = require("+o(s)+");(f.default ? f.default : f)(self);}",m];var g={};i(p);var v="("+n+")({"+Object.keys(g).map(function(e){return o(e)+":["+a[e][0]+","+o(a[e][1])+"]"}).join(",")+"},{},["+o(p)+"])",_=window.URL||window.webkitURL||window.mozURL||window.msURL,b=new Blob([v],{type:"text/javascript"});if(t&&t.bare)return b;var w=_.createObjectURL(b),y=new Worker(w);return y.objectURL=w,y}},{}],"/":[function(e,t,i){"use strict";function n(e,t){return o(e)||r(e,t)||a()}function a(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function r(e,t){var i=[],n=!0,a=!1,r=void 0;try{for(var o,s=e[Symbol.iterator]();!(n=(o=s.next()).done)&&(i.push(o.value),!t||i.length!==t);n=!0);}catch(e){a=!0,r=e}finally{try{n||null==s.return||s.return()}finally{if(a)throw r}}return i}function o(e){if(Array.isArray(e))return e}function s(){return{value:d(p),destroy:function(){if(this.value.terminate(),"undefined"!=typeof window){var e=window.URL||window.webkitURL||window.mozURL||window.msURL;e&&e.revokeObjectURL&&this.value.objectURL&&e.revokeObjectURL(this.value.objectURL)}}}}function l(e){if(!(this instanceof l))return new l(e);this.options=c({},C,e||{});var t="lk_".concat(this.options.concurrency);this.__limit=v[t]||f.limiter(this.options.concurrency),v[t]||(v[t]=this.__limit),this.features={js:!1,wasm:!1,cib:!1,ww:!1},this.__workersPool=null,this.__requested_features=[],this.__mathlib=null}var c=e("object-assign"),d=e("webworkify"),u=e("./lib/mathlib"),h=e("./lib/pool"),f=e("./lib/utils"),p=e("./lib/worker"),m=e("./lib/stepper"),g=e("./lib/tiler"),v={},_=!1;try{"undefined"!=typeof navigator&&navigator.userAgent&&(_=navigator.userAgent.indexOf("Safari")>=0)}catch(e){}var b=1;"undefined"!=typeof navigator&&(b=Math.min(navigator.hardwareConcurrency||1,4));var w,y,C={tile:1024,concurrency:b,features:["js","wasm","ww"],idle:2e3},E={quality:3,alpha:!1,unsharpAmount:0,unsharpRadius:0,unsharpThreshold:0};l.prototype.init=function(){var t=this;if(this.__initPromise)return this.__initPromise;if(!1!==w&&!0!==w&&(w=!1,"undefined"!=typeof ImageData&&"undefined"!=typeof Uint8ClampedArray))try{new ImageData(new Uint8ClampedArray(400),10,10),w=!0}catch(e){}!1!==y&&!0!==y&&(y=!1,"undefined"!=typeof ImageBitmap&&(ImageBitmap.prototype&&ImageBitmap.prototype.close?y=!0:this.debug("ImageBitmap does not support .close(), disabled")));var i=this.options.features.slice();if(i.indexOf("all")>=0&&(i=["cib","wasm","js","ww"]),this.__requested_features=i,this.__mathlib=new u(i),i.indexOf("ww")>=0&&"undefined"!=typeof window&&"Worker"in window)try{e("webworkify")(function(){}).terminate(),this.features.ww=!0;var n="wp_".concat(JSON.stringify(this.options));v[n]?this.__workersPool=v[n]:(this.__workersPool=new h(s,this.options.idle),v[n]=this.__workersPool)}catch(e){}var a,r=this.__mathlib.init().then(function(e){c(t.features,e.features)});return a=y?f.cib_support().then(function(e){if(t.features.cib&&i.indexOf("cib")<0)return void t.debug("createImageBitmap() resize supported, but disabled by config");i.indexOf("cib")>=0&&(t.features.cib=e)}):Promise.resolve(!1),this.__initPromise=Promise.all([r,a]).then(function(){return t}),this.__initPromise},l.prototype.resize=function(e,t,i){var a=this;this.debug("Start resize...");var r=c({},E);if(isNaN(i)?i&&(r=c(r,i)):r=c(r,{quality:i}),r.toWidth=t.width,r.toHeight=t.height,r.width=e.naturalWidth||e.width,r.height=e.naturalHeight||e.height,0===t.width||0===t.height)return Promise.reject(new Error("Invalid output size: ".concat(t.width,"x").concat(t.height)));r.unsharpRadius>2&&(r.unsharpRadius=2);var o=!1,s=null;r.cancelToken&&(s=r.cancelToken.then(function(e){throw o=!0,e},function(e){throw o=!0,e}));var l=Math.ceil(Math.max(3,2.5*r.unsharpRadius|0));return this.init().then(function(){if(o)return s;if(a.features.cib){var i=t.getContext("2d",{alpha:Boolean(r.alpha)});return a.debug("Resize via createImageBitmap()"),createImageBitmap(e,{resizeWidth:r.toWidth,resizeHeight:r.toHeight,resizeQuality:f.cib_quality_name(r.quality)}).then(function(e){if(o)return s;if(!r.unsharpAmount)return i.drawImage(e,0,0),e.close(),i=null,a.debug("Finished!"),t;a.debug("Unsharp result");var n=document.createElement("canvas");n.width=r.toWidth,n.height=r.toHeight;var l=n.getContext("2d",{alpha:Boolean(r.alpha)});l.drawImage(e,0,0),e.close();var c=l.getImageData(0,0,r.toWidth,r.toHeight);return a.__mathlib.unsharp_mask(c.data,r.toWidth,r.toHeight,r.unsharpAmount,r.unsharpRadius,r.unsharpThreshold),i.putImageData(c,0,0),c=l=n=i=null,a.debug("Finished!"),t})}var d={},u=function(e){return Promise.resolve().then(function(){return a.features.ww?new Promise(function(t,i){var n=a.__workersPool.acquire();s&&s.catch(function(e){return i(e)}),n.value.onmessage=function(e){n.release(),e.data.err?i(e.data.err):t(e.data.result)},n.value.postMessage({opts:e,features:a.__requested_features,preload:{wasm_nodule:a.__mathlib.__}},[e.src.buffer])}):a.__mathlib.resizeAndUnsharp(e,d)})},h=function(e,t,i){var n,r,c,d=function(t){return a.__limit(function(){if(o)return s;var l;if(f.isCanvas(e))a.debug("Get tile pixel data"),l=n.getImageData(t.x,t.y,t.width,t.height);else{a.debug("Draw tile imageBitmap/image to temporary canvas");var d=document.createElement("canvas");d.width=t.width,d.height=t.height;var h=d.getContext("2d",{alpha:Boolean(i.alpha)});h.globalCompositeOperation="copy",h.drawImage(r||e,t.x,t.y,t.width,t.height,0,0,t.width,t.height),a.debug("Get tile pixel data"),l=h.getImageData(0,0,t.width,t.height),h=d=null}var p={src:l.data,width:t.width,height:t.height,toWidth:t.toWidth,toHeight:t.toHeight,scaleX:t.scaleX,scaleY:t.scaleY,offsetX:t.offsetX,offsetY:t.offsetY,quality:i.quality,alpha:i.alpha,unsharpAmount:i.unsharpAmount,unsharpRadius:i.unsharpRadius,unsharpThreshold:i.unsharpThreshold};return a.debug("Invoke resize math"),Promise.resolve().then(function(){return u(p)}).then(function(e){if(o)return s;l=null;var i;if(a.debug("Convert raw rgba tile result to ImageData"),w)i=new ImageData(new Uint8ClampedArray(e),t.toWidth,t.toHeight);else if(i=c.createImageData(t.toWidth,t.toHeight),i.data.set)i.data.set(e);else for(var n=i.data.length-1;n>=0;n--)i.data[n]=e[n];return a.debug("Draw tile"),_?c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth+1e-5,t.toInnerHeight+1e-5):c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth,t.toInnerHeight),null})})};return Promise.resolve().then(function(){if(c=t.getContext("2d",{alpha:Boolean(i.alpha)}),f.isCanvas(e))return n=e.getContext("2d",{alpha:Boolean(i.alpha)}),null;if(f.isImage(e))return y?(a.debug("Decode image via createImageBitmap"),createImageBitmap(e).then(function(e){r=e})):null;throw new Error('".from" should be image or canvas')}).then(function(){function e(){r&&(r.close(),r=null)}if(o)return s;a.debug("Calculate tiles");var n=g({width:i.width,height:i.height,srcTileSize:a.options.tile,toWidth:i.toWidth,toHeight:i.toHeight,destTileBorder:l}),c=n.map(function(e){return d(e)});return a.debug("Process tiles"),Promise.all(c).then(function(){return a.debug("Finished!"),e(),t},function(t){throw e(),t})})},p=m(r.width,r.height,r.toWidth,r.toHeight,a.options.tile,l);return function e(t,i,a,r){if(o)return s;var l=t.shift(),d=n(l,2),u=d[0],f=d[1],p=0===t.length;r=c({},r,{toWidth:u,toHeight:f,quality:p?r.quality:Math.min(1,r.quality)});var m;return p||(m=document.createElement("canvas"),m.width=u,m.height=f),h(i,p?a:m,r).then(function(){return p?a:(r.width=u,r.height=f,e(t,m,a,r))})}(p,e,t,r)})},l.prototype.resizeBuffer=function(e){var t=this,i=c({},E,e);return this.init().then(function(){return t.__mathlib.resizeAndUnsharp(i)})},l.prototype.toBlob=function(e,t,i){return t=t||"image/png",new Promise(function(n){if(e.toBlob)return void e.toBlob(function(e){return n(e)},t,i);for(var a=atob(e.toDataURL(t,i).split(",")[1]),r=a.length,o=new Uint8Array(r),s=0;s<r;s++)o[s]=a.charCodeAt(s);n(new Blob([o],{type:t}))})},l.prototype.debug=function(){},t.exports=l},{"./lib/mathlib":1,"./lib/pool":9,"./lib/stepper":10,"./lib/tiler":11,"./lib/utils":12,"./lib/worker":13,"object-assign":24,webworkify:25}]},{},[])("/")}),define("WoltLabSuite/Core/Image/Resizer",["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ExifUtil","Pica"],function(e,t,i){"use strict";function n(){}var a=new i({features:["js","wasm","ww"]});return n.prototype={maxWidth:800,maxHeight:600,quality:.8,fileType:"image/jpeg",setMaxWidth:function(e){return null==e&&(e=n.prototype.maxWidth),this.maxWidth=e,this},setMaxHeight:function(e){return null==e&&(e=n.prototype.maxHeight),this.maxHeight=e,this},setQuality:function(e){return null==e&&(e=n.prototype.quality),this.quality=e,this},setFileType:function(e){return null==e&&(e=n.prototype.fileType),this.fileType=e,this},saveFile:function(i,n,r,o){r=r||this.fileType,o=o||this.quality;var s=n.match(/(.+)(\..+?)$/);return a.toBlob(i.image,r,o).then(function(e){return"image/jpeg"===r&&void 0!==i.exif?t.setExifData(e,i.exif):e}).then(function(t){return e.blobToFile(t,s[1])})},loadFile:function(e){var i=void 0,n=Promise.resolve(e);"image/jpeg"===e.type&&(i=t.getExifBytesFromJpeg(e),n=n.then(t.removeExifData.bind(t)));var n=n.then(function(e){return new Promise(function(t,i){var n=new FileReader,a=new Image;n.addEventListener("load",function(){a.src=n.result}),n.addEventListener("error",function(){n.abort(),i(n.error)}),a.addEventListener("error",i),a.addEventListener("load",function(){t(a)}),n.readAsDataURL(e)})});return Promise.all([i,n]).then(function(e){return{exif:e[0],image:e[1]}})},resize:function(e,t,i,n,r,o){t=t||this.maxWidth,i=i||this.maxHeight,n=n||this.quality,r=r||!1;var s=document.createElement("canvas"),l=window.createImageBitmap?createImageBitmap(e).then(function(t){if(t.height!=e.height)throw new Error("Chrome Bug #1069965")}):Promise.resolve(),c=Math.min(t,e.width),d=Math.min(i,e.height);if(e.width<=c&&e.height<=d&&!r)return Promise.resolve(void 0);var u=Math.min(c/e.width,d/e.height);s.width=Math.floor(e.width*u),s.height=Math.floor(e.height*u);var h=1;n>=.8?h=3:n>=.4&&(h=2);var f={quality:h,cancelToken:o,alpha:!0};return l.then(function(){return a.resize(e,s,f)})}},n}),define("WoltLabSuite/Core/Language/Chooser",["Core","Dictionary","Language","Dom/Traverse","Dom/Util","ObjectMap","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";var s=new t,l=!1,c=new r,d=null;return{init:function(e,t,i,n,a,r){if(!s.has(t)){var o=elById(e);if(null===o)throw new Error("Expected a valid container id, cannot find '"+t+"'.");var l=elById(t);null===l&&(l=elCreate("input"),elAttr(l,"type","hidden"),elAttr(l,"id",t),elAttr(l,"name",t),elAttr(l,"value",i),o.appendChild(l)),this._initElement(t,l,i,n,a,r)}},_setup:function(){l||(l=!0,d=this._submit.bind(this))},_initElement:function(e,t,r,l,u,h){var f;"DD"===t.parentNode.nodeName?(f=elCreate("div"),f.className="dropdown",a.prepend(f,t.parentNode)):(f=t.parentNode,f.classList.add("dropdown")),elHide(t);var p=elCreate("a");p.className="dropdownToggle dropdownIndicator boxFlag box24 inputPrefix"+("DD"===t.parentNode.nodeName?" button":""),f.appendChild(p);var m=elCreate("ul");m.className="dropdownMenu",f.appendChild(m);var g,v,_,b,w=function(t){var i=~~elData(t.currentTarget,"language-id"),a=n.childByClass(m,"active");null!==a&&a.classList.remove("active"),i&&t.currentTarget.classList.add("active"),this._select(e,i,t.currentTarget)}.bind(this);for(var y in l)if(l.hasOwnProperty(y)){var C=l[y];_=elCreate("li"),_.className="boxFlag",_.addEventListener(WCF_CLICK_EVENT,w),elData(_,"language-id",y),void 0!==C.languageCode&&elData(_,"language-code",C.languageCode),m.appendChild(_),g=elCreate("a"),g.className="box24",_.appendChild(g),v=elCreate("img"),elAttr(v,"src",C.iconPath),elAttr(v,"alt",""),v.className="iconFlag",g.appendChild(v),b=elCreate("span"),b.textContent=C.languageName,g.appendChild(b),y==r&&(p.innerHTML=_.firstChild.innerHTML)}if(h)_=elCreate("li"),_.className="dropdownDivider",m.appendChild(_),_=elCreate("li"),elData(_,"language-id",0),_.addEventListener(WCF_CLICK_EVENT,w),m.appendChild(_),g=elCreate("a"),g.textContent=i.get("wcf.global.language.noSelection"),_.appendChild(g),0===r&&(p.innerHTML=_.firstChild.innerHTML),_.addEventListener(WCF_CLICK_EVENT,w);else if(0===r){p.innerHTML=null;var E=elCreate("div");p.appendChild(E),b=elCreate("span"),b.className="icon icon24 fa-question pointer",E.appendChild(b),b=elCreate("span"),b.textContent=i.get("wcf.global.language.noSelection"),E.appendChild(b)}o.init(p),s.set(e,{callback:u,dropdownMenu:m,dropdownToggle:p,element:t});var L=n.parentByTag(t,"FORM");if(null!==L){L.addEventListener("submit",d);var S=c.get(L);void 0===S&&(S=[],c.set(L,S)),S.push(e)}},_select:function(t,i,n){var a=s.get(t);if(void 0===n){for(var r=a.dropdownMenu.childNodes,o=0,l=r.length;o<l;o++){var c=r[o];if(~~elData(c,"language-id")===i){n=c;break}}if(void 0===n)throw new Error("Cannot select unknown language id '"+i+"'")}a.element.value=i,e.triggerEvent(a.element,"change"),a.dropdownToggle.innerHTML=n.firstChild.innerHTML,s.set(t,a),"function"==typeof a.callback&&a.callback(n)},_submit:function(e){for(var t,i=c.get(e.currentTarget),n=0,a=i.length;n<a;n++)t=elCreate("input"),t.type="hidden",t.name=i[n],t.value=this.getLanguageId(i[n]),e.currentTarget.appendChild(t)},getChooser:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid language chooser input element, '"+e+"' is not i18n input field.");return t},getLanguageId:function(e){return~~this.getChooser(e).element.value},removeChooser:function(e){s.has(e)&&s.delete(e)},setLanguageId:function(e,t){if(void 0===s.get(e))throw new Error("Expected a valid  input element, '"+e+"' is not i18n input field.");this._select(e,t)}}}),define("WoltLabSuite/Core/Language/Input",["Core","Dictionary","Language","ObjectMap","StringUtil","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o,s){"use strict";var l=new t,c=!1,d=new n,u=new t,h=null,f=null;return{init:function(e,i,n,r){if(!u.has(e)){var o=elById(e);if(null===o)throw new Error("Expected a valid element id, cannot find '"+e+"'.");this._setup();var s=new t;for(var l in i)i.hasOwnProperty(l)&&s.set(~~l,a.unescapeHTML(i[l]));u.set(e,s),this._initElement(e,o,s,n,r)}},registerCallback:function(e,t,i){if(!u.has(e))throw new Error("Unknown element id '"+e+"'.");l.get(e).callbacks.set(t,i)},unregister:function(e){if(!u.has(e))throw new Error("Unknown element id '"+e+"'.");u.delete(e),l.delete(e)},_setup:function(){c||(c=!0,h=this._dropdownToggle.bind(this),f=this._submit.bind(this))},_initElement:function(e,n,a,c,u){var p=n.parentNode;if(!p.classList.contains("inputAddon")){p=elCreate("div"),p.className="inputAddon"+("TEXTAREA"===n.nodeName?" inputAddonTextarea":""),elData(p,"input-id",e);var m=document.activeElement===n;n.parentNode.insertBefore(p,n),p.appendChild(n),m&&n.focus()}p.classList.add("dropdown");var g=elCreate("span");g.className="button dropdownToggle inputPrefix";var v=elCreate("span");v.textContent=i.get("wcf.global.button.disabledI18n"),g.appendChild(v),p.insertBefore(g,n);var _=elCreate("ul");_.className="dropdownMenu",o.insertAfter(_,g);var b,w=function(t,i){var n=~~elData(t.currentTarget,"language-id"),a=r.childByClass(_,"active");null!==a&&a.classList.remove("active"),n&&t.currentTarget.classList.add("active"),this._select(e,n,i||!1)}.bind(this);for(var y in c)c.hasOwnProperty(y)&&(b=elCreate("li"),elData(b,"language-id",y),v=elCreate("span"),v.textContent=c[y],b.appendChild(v),b.addEventListener(WCF_CLICK_EVENT,w),_.appendChild(b));!0!==u&&(b=elCreate("li"),b.className="dropdownDivider",_.appendChild(b),b=elCreate("li"),elData(b,"language-id",0),v=elCreate("span"),v.textContent=i.get("wcf.global.button.disabledI18n"),b.appendChild(v),b.addEventListener(WCF_CLICK_EVENT,w),_.appendChild(b));var C=null;if(!0===u||a.size)for(var E=0,L=_.childElementCount;E<L;E++)if(~~elData(_.children[E],"language-id")===LANGUAGE_ID){C=_.children[E];break}s.init(g),s.registerCallback(p.id,h),l.set(e,{buttonLabel:g.children[0],callbacks:new t,element:n,languageId:0,isEnabled:!0,forceSelection:u});var S=r.parentByTag(n,"FORM");if(null!==S){S.addEventListener("submit",f);var A=d.get(S);void 0===A&&(A=[],d.set(S,A)),A.push(e)}null!==C&&w({currentTarget:C},!0)},_select:function(e,i,n){for(var a,r=l.get(e),o=s.getDropdownMenu(r.element.closest(".inputAddon").id),c="",d=0,h=o.childElementCount;d<h;d++){a=o.children[d];var f=elData(a,"language-id");f.length&&i===~~f&&(c=a.children[0].textContent)}if(r.languageId!==i){var p=u.get(e);r.languageId&&p.set(r.languageId,r.element.value),0===i?u.set(e,new t):(r.buttonLabel.classList.contains("active")||!0===n)&&(r.element.value=p.has(i)?p.get(i):""),r.buttonLabel.textContent=c,r.buttonLabel.classList[i?"add":"remove"]("active"),r.languageId=i}n||(r.element.blur(),r.element.focus()),r.callbacks.has("select")&&r.callbacks.get("select")(r.element)},_dropdownToggle:function(e,t){if("open"===t)for(var i,n,a=s.getDropdownMenu(e),r=elData(elById(e),"input-id"),o=l.get(r),c=u.get(r),d=0,h=a.childElementCount;d<h;d++)if(i=a.children[d],n=~~elData(i,"language-id")){var f=!1;o.languageId&&(f=n===o.languageId?""===o.element.value.trim():!c.get(n)),i.classList[f?"add":"remove"]("missingValue")}},_submit:function(e){for(var t,i,n,a,r=d.get(e.currentTarget),o=0,s=r.length;o<s;o++)i=r[o],t=l.get(i),t.isEnabled&&(a=u.get(i),t.callbacks.has("submit")&&t.callbacks.get("submit")(t.element),t.languageId&&a.set(t.languageId,t.element.value),a.size&&(a.forEach(function(t,a){n=elCreate("input"),n.type="hidden",n.name=i+"_i18n["+a+"]",n.value=t,e.currentTarget.appendChild(n)}),t.element.removeAttribute("name")))},getValues:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");var i=u.get(e);return i.set(t.languageId,t.element.value),i},setValues:function(i,n){var a=l.get(i);if(void 0===a)throw new Error("Expected a valid i18n input element, '"+i+"' is not i18n input field.");if(e.isPlainObject(n)&&(n=t.fromObject(n)),a.element.value="",n.has(0))return a.element.value=n.get(0),n.delete(0),u.set(i,n),void this._select(i,0,!0);u.set(i,n),a.languageId=0,this._select(i,LANGUAGE_ID,!0)},disable:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid element, '"+e+"' is not an i18n input field.");if(t.isEnabled){t.isEnabled=!1,elHide(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.remove("inputAddon"),i.classList.remove("dropdown")}},enable:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!t.isEnabled){t.isEnabled=!0,elShow(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.add("inputAddon"),i.classList.add("dropdown")}},isEnabled:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");return t.isEnabled},validate:function(e,t){var i=l.get(e);if(void 0===i)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!i.isEnabled)return!0;var n=u.get(e),a=s.getDropdownMenu(i.element.parentNode.id);i.languageId&&n.set(i.languageId,i.element.value);for(var r,o,c=!1,d=!1,h=0,f=a.childElementCount;h<f;h++)if(r=a.children[h],o=~~elData(r,"language-id"))if(n.has(o)&&0!==n.get(o).length){if(c)return!1;d=!0}else{if(d)return!1;c=!0}return!c||t}}}),define("WoltLabSuite/Core/Language/Text",["Core","./Input"],function(e,t){"use strict";return{init:function(e,i,n,a){var r=elById(e);if(!r||"TEXTAREA"!==r.nodeName||!r.classList.contains("wysiwygTextarea"))throw new Error('Expected <textarea class="wysiwygTextarea" /> for id \''+e+"'.");t.init(e,i,n,a),t.registerCallback(e,"select",this._callbackSelect.bind(this)),t.registerCallback(e,"submit",this._callbackSubmit.bind(this))},_callbackSelect:function(e){void 0!==window.jQuery&&window.jQuery(e).redactor("code.set",e.value)},_callbackSubmit:function(e){void 0!==window.jQuery&&(e.value=window.jQuery(e).redactor("code.get"))}}}),define("WoltLabSuite/Core/Media/Upload",["Core","DateUtil","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","Permission","Upload","User","WoltLabSuite/Core/FileUtil"],function(e,t,i,n,a,r,o,s,l,c,d){"use strict";function u(t,i,n){n=n||{},this._elementTagSize=144,n.elementTagSize&&(this._elementTagSize=n.elementTagSize),this._mediaManager=null,n.mediaManager&&(this._mediaManager=n.mediaManager,delete n.mediaManager),this._categoryId=null,l.call(this,t,i,e.extend({className:"wcf\\data\\media\\MediaAction",multiple:!!this._mediaManager,singleFileRequests:!0},n))}return e.inherit(u,l,{_createFileElement:function(e){var n;if("OL"===this._target.nodeName||"UL"===this._target.nodeName)n=elCreate("li");else{if("TBODY"===this._target.nodeName){var r=elByTag("TR",this._target)[0],s=this._target.parentNode.parentNode;"none"===s.style.getPropertyValue("display")?(n=r,s.style.removeProperty("display"),elRemove(elById(elData(this._target,"no-items-info")))):(n=r.cloneNode(!0),n.removeAttribute("id"),a.identify(n));for(var l,u=elByTag("TD",n),h=0,f=u.length;h<f;h++)if(l=u[h],l.classList.contains("columnMark"))elBySelAll("[data-object-id]",l,elHide);else if(l.classList.contains("columnIcon"))elBySelAll("[data-object-id]",l,elHide),elByClass("mediaEditButton",l)[0].classList.add("jsMediaEditButton"),elData(elByClass("jsDeleteButton",l)[0],"confirm-message-html",o.get("wcf.media.delete.confirmMessage",{title:e.name}));else if(l.classList.contains("columnFilename")){var p=elByTag("IMG",l);p.length||(p=elByClass("icon48",l));var m=elCreate("span");m.className="icon icon48 fa-spinner mediaThumbnail",a.replaceElement(p[0],m);var g=elBySelAll(".box48 > div > p",l);g[0].textContent=e.name;var v=elByTag("A",g[1])[0];v||(v=elCreate("a"),elByTag("SMALL",g[1])[0].appendChild(v)),v.setAttribute("href",c.getLink()),v.textContent=c.username}else l.classList.contains("columnUploadTime")?(l.innerHTML="",l.appendChild(t.getTimeElement(new Date))):l.classList.contains("columnDigits")?l.textContent=d.formatFilesize(e.size):l.innerHTML="";return a.prepend(n,this._target),n}n=elCreate("p")}var _=elCreate("div");_.className="mediaThumbnail",n.appendChild(_);var b=elCreate("span");b.className="icon icon144 fa-spinner",_.appendChild(b);var w=elCreate("div");w.className="mediaInformation",n.appendChild(w);var y=elCreate("p");y.className="mediaTitle",y.textContent=e.name,w.appendChild(y);var C=elCreate("progress");return elAttr(C,"max",100),w.appendChild(C),a.prepend(n,this._target),i.trigger(),n},_getParameters:function(){var t={elementTagSize:this._elementTagSize};if(this._mediaManager){t.imagesOnly=this._mediaManager.getOption("imagesOnly");var i=this._mediaManager.getCategoryId();i&&(t.categoryID=i)}return e.extend(u._super.prototype._getParameters.call(this),t)},_replaceFileIcon:function(e,t,i){if(t.elementTag)e.outerHTML=t.elementTag;else if(t.tinyThumbnailType){var n=elCreate("img");elAttr(n,"src",t.tinyThumbnailLink),elAttr(n,"alt",""),n.style.setProperty("width",i+"px"),n.style.setProperty("height",i+"px"),a.replaceElement(e,n)}else{e.classList.remove("fa-spinner");var r=d.getIconNameByFilename(t.filename);r&&(r="-"+r),e.classList.add("fa-file"+r+"-o")}},_success:function(e,t){for(var a=this._fileElements[e],s=0,l=a.length;s<l;s++){var c=a[s],d=elData(c,"internal-file-id"),u=t.returnValues.media[d];if("TR"===c.tagName)if(u){for(var h=elBySelAll("[data-object-id]",c),s=0,l=h.length;s<l;s++)elData(h[s],"object-id",~~u.mediaID),elShow(h[s]);elByClass("columnMediaID",c)[0].textContent=u.mediaID;var f=elByClass("fa-spinner",c)[0];this._replaceFileIcon(f,u,48)}else{var p=t.returnValues.errors[d];p||(p={errorType:"uploadFailed",filename:elData(c,"filename")});var f=elByClass("fa-spinner",c)[0];f.classList.remove("fa-spinner"),f.classList.add("fa-remove"),f.classList.add("pointer"),f.classList.add("jsTooltip"),elAttr(f,"title",o.get("wcf.global.button.delete")),f.addEventListener(WCF_CLICK_EVENT,function(e){elRemove(e.currentTarget.parentNode.parentNode.parentNode),r.fire("com.woltlab.wcf.media.upload","removedErroneousUploadRow")}),c.classList.add("uploadFailed");var m=elBySelAll(".columnFilename .box48 > div > p",c)[1];elInnerError(m,o.get("wcf.media.upload.error."+p.errorType,{filename:p.filename})),elRemove(m)}else if(elRemove(n.childByTag(n.childByClass(c,"mediaInformation"),"PROGRESS")),u){var f=n.childByTag(n.childByClass(c,"mediaThumbnail"),"SPAN");this._replaceFileIcon(f,u,144),c.className="jsClipboardObject mediaFile",elData(c,"object-id",u.mediaID),this._mediaManager&&(this._mediaManager.setupMediaElement(u,c),this._mediaManager.addMedia(u,c))}else{var p=t.returnValues.errors[d];p||(p={errorType:"uploadFailed",filename:elData(c,"filename")});var f=n.childByTag(n.childByClass(c,"mediaThumbnail"),"SPAN");f.classList.remove("fa-spinner"),f.classList.add("fa-remove"),f.classList.add("pointer"),c.classList.add("uploadFailed"),c.classList.add("jsTooltip"),elAttr(c,"title",o.get("wcf.global.button.delete")),c.addEventListener(WCF_CLICK_EVENT,function(){elRemove(this)});var g=n.childByClass(n.childByClass(c,"mediaInformation"),"mediaTitle");g.innerText=o.get("wcf.media.upload.error."+p.errorType,{filename:p.filename})}i.trigger()}r.fire("com.woltlab.wcf.media.upload","success",{files:a,isMultiFileUpload:-1!==this._multiFileUploadIds.indexOf(e),media:t.returnValues.media,upload:this,uploadId:e})},_uploadFiles:function(e,t){return u._super.prototype._uploadFiles.call(this,e,t)}}),u}),define("WoltLabSuite/Core/Media/Replace",["Core","Dom/ChangeListener","Dom/Util","Language","Ui/Notification","./Upload"],function(e,t,i,n,a,r){"use strict";function o(t,i,n,a){this._mediaID=t,r.call(this,i,n,e.extend(a,{action:"replaceFile"}))}return e.inherit(o,r,{_createButton:function(){r.prototype._createButton.call(this),this._button.classList.add("small"),elBySel("span",this._button).textContent=n.get("wcf.media.button.replaceFile")},_createFileElement:function(){return this._target},_getFormData:function(){return{objectIDs:[this._mediaID]}},_success:function(e,i){for(var r=this._fileElements[e],o=0,s=r.length;o<s;o++){var l=r[o],c=elData(l,"internal-file-id"),d=i.returnValues.media[c];if(d)d.isImage&&(this._target.innerHTML=d.smallThumbnailTag),elById("mediaFilename").textContent=d.filename,elById("mediaFilesize").textContent=d.formattedFilesize,d.isImage&&(elById("mediaImageDimensions").textContent=d.imageDimensions),elById("mediaUploader").innerHTML=d.userLinkElement,this._options.mediaEditor.updateData(d),elInnerError(this._buttonContainer,""),a.show();else{var u=i.returnValues.errors[c];u||(u={errorType:"uploadFailed",filename:elData(l,"filename")}),elInnerError(this._buttonContainer,n.get("wcf.media.upload.error."+u.errorType,{filename:u.filename}))}t.trigger()}}}),o}),
+define("WoltLabSuite/Core/Media/Editor",["Ajax","Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Language/Chooser","WoltLabSuite/Core/Language/Input","EventKey","WoltLabSuite/Core/Media/Replace"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function f(e){if(this._callbackObject=e||{},this._callbackObject._editorClose&&"function"!=typeof this._callbackObject._editorClose)throw new TypeError("Callback object has no function '_editorClose'.");if(this._callbackObject._editorSuccess&&"function"!=typeof this._callbackObject._editorSuccess)throw new TypeError("Callback object has no function '_editorSuccess'.");this._media=null,this._availableLanguageCount=1,this._categoryIds=[],this._oldCategoryId=0,this._dialogs=new i}return f.prototype={_ajaxSetup:function(){return{data:{actionName:"update",className:"wcf\\data\\media\\MediaAction"}}},_ajaxSuccess:function(e){l.show(),this._callbackObject._editorSuccess&&(this._callbackObject._editorSuccess(this._media,this._oldCategoryId),this._oldCategoryId=0),s.close("mediaEditor_"+this._media.mediaID),this._media=null},_close:function(){this._media=null,this._callbackObject._editorClose&&this._callbackObject._editorClose()},_initEditor:function(e,t){this._availableLanguageCount=~~t.returnValues.availableLanguageCount,this._categoryIds=t.returnValues.categoryIDs.map(function(e){return~~e});t.returnValues.mediaData&&(this._media=t.returnValues.mediaData),setTimeout(function(){this._availableLanguageCount>1&&c.setLanguageId("mediaEditor_"+this._media.mediaID+"_languageID",this._media.languageID||LANGUAGE_ID),this._categoryIds.length&&(elBySel("select[name=categoryID]",e).value=~~this._media.categoryID);var t=elBySel("input[name=title]",e),a=elBySel("input[name=altText]",e),o=elBySel("textarea[name=caption]",e);if(this._availableLanguageCount>1&&this._media.isMultilingual?(elById("altText_"+this._media.mediaID)&&d.setValues("altText_"+this._media.mediaID,i.fromObject(this._media.altText||{})),elById("caption_"+this._media.mediaID)&&d.setValues("caption_"+this._media.mediaID,i.fromObject(this._media.caption||{})),d.setValues("title_"+this._media.mediaID,i.fromObject(this._media.title||{}))):(t.value=this._media.title?this._media.title[this._media.languageID||LANGUAGE_ID]:"",a&&(a.value=this._media.altText?this._media.altText[this._media.languageID||LANGUAGE_ID]:""),o&&(o.value=this._media.caption?this._media.caption[this._media.languageID||LANGUAGE_ID]:"")),this._availableLanguageCount>1){var s=elBySel("input[name=isMultilingual]",e);s.addEventListener("change",this._updateLanguageFields.bind(this)),this._updateLanguageFields(null,s)}var l=this._keyPress.bind(this);a&&a.addEventListener("keypress",l),t.addEventListener("keypress",l),elBySel("button[data-type=submit]",e).addEventListener(WCF_CLICK_EVENT,this._saveData.bind(this)),document.activeElement.blur(),elById("mediaEditor_"+this._media.mediaID).parentNode.scrollTop=0;var u=elByClass("mediaManagerMediaReplaceButton",e)[0],f=elByClass("mediaThumbnail",e)[0];f||(f=elCreate("div"),e.appendChild(f)),new h(this._media.mediaID,r.identify(u),r.identify(f),{mediaEditor:this}),n.trigger()}.bind(this),200)},_keyPress:function(e){u.Enter(e)&&(e.preventDefault(),this._saveData())},_saveData:function(){var t=s.getDialog("mediaEditor_"+this._media.mediaID).content,i=elBySel("select[name=categoryID]",t),n=elBySel("input[name=altText]",t),r=elBySel("textarea[name=caption]",t),l=elBySel("input[name=captionEnableHtml]",t),u=elBySel("input[name=title]",t),h=!1,f=!!n&&a.childByClass(n.parentNode.parentNode,"innerError"),p=!!r&&a.childByClass(r.parentNode.parentNode,"innerError"),m=a.childByClass(u.parentNode.parentNode,"innerError");if(this._oldCategoryId=this._media.categoryID,this._categoryIds.length&&(this._media.categoryID=~~i.value,-1===this._categoryIds.indexOf(this._media.categoryID)&&(this._media.categoryID=0)),this._availableLanguageCount>1?(this._media.isMultilingual=~~elBySel("input[name=isMultilingual]",t).checked,this._media.languageID=this._media.isMultilingual?null:c.getLanguageId("mediaEditor_"+this._media.mediaID+"_languageID")):this._media.languageID=LANGUAGE_ID,this._media.altText={},this._media.caption={},this._media.title={},this._availableLanguageCount>1&&this._media.isMultilingual){if(elById("altText_"+this._media.mediaID)&&!d.validate("altText_"+this._media.mediaID,!0)&&(h=!0,!f)){var g=elCreate("small");g.className="innerError",g.textContent=o.get("wcf.global.form.error.multilingual"),n.parentNode.parentNode.appendChild(g)}if(elById("caption_"+this._media.mediaID)&&!d.validate("caption_"+this._media.mediaID,!0)&&(h=!0,!p)){var g=elCreate("small");g.className="innerError",g.textContent=o.get("wcf.global.form.error.multilingual"),r.parentNode.parentNode.appendChild(g)}if(!d.validate("title_"+this._media.mediaID,!0)&&(h=!0,!m)){var g=elCreate("small");g.className="innerError",g.textContent=o.get("wcf.global.form.error.multilingual"),u.parentNode.parentNode.appendChild(g)}this._media.altText=elById("altText_"+this._media.mediaID)?d.getValues("altText_"+this._media.mediaID).toObject():"",this._media.caption=elById("caption_"+this._media.mediaID)?d.getValues("caption_"+this._media.mediaID).toObject():"",this._media.title=d.getValues("title_"+this._media.mediaID).toObject()}else this._media.altText[this._media.languageID]=n?n.value:"",this._media.caption[this._media.languageID]=r?r.value:"",this._media.title[this._media.languageID]=u.value;this._media.captionEnableHtml=l?~~l.checked:0;for(var v={allowAll:~~elById("mediaEditor_"+this._media.mediaID+"_aclAllowAll").checked,group:[],user:[]},_=elBySelAll('input[name="mediaEditor_'+this._media.mediaID+'_aclValues[group][]"]',t),b=0,w=_.length;b<w;b++)v.group.push(~~_[b].value);for(var y=elBySelAll('input[name="mediaEditor_'+this._media.mediaID+'_aclValues[user][]"]',t),b=0,w=y.length;b<w;b++)v.user.push(~~y[b].value);h||(f&&elRemove(f),p&&elRemove(p),m&&elRemove(m),e.api(this,{actionName:"update",objectIDs:[this._media.mediaID],parameters:{aclValues:v,altText:this._media.altText,caption:this._media.caption,data:{captionEnableHtml:this._media.captionEnableHtml,categoryID:this._media.categoryID,isMultilingual:this._media.isMultilingual,languageID:this._media.languageID},title:this._media.title}}))},_updateLanguageFields:function(e,t){e&&(t=e.currentTarget);var i=elById("mediaEditor_"+this._media.mediaID+"_languageIDContainer").parentNode;t.checked?(d.enable("title_"+this._media.mediaID),elById("caption_"+this._media.mediaID)&&d.enable("caption_"+this._media.mediaID),elById("altText_"+this._media.mediaID)&&d.enable("altText_"+this._media.mediaID),elHide(i)):(d.disable("title_"+this._media.mediaID),elById("caption_"+this._media.mediaID)&&d.disable("caption_"+this._media.mediaID),elById("altText_"+this._media.mediaID)&&d.disable("altText_"+this._media.mediaID),elShow(i))},edit:function(e){if("object"!=typeof e&&(e={mediaID:~~e}),null!==this._media)throw new Error("Cannot edit media with id '"+e.mediaID+"' while editing media with id '"+this._media.mediaID+"'");this._media=e,this._dialogs.has("mediaEditor_"+e.mediaID)||this._dialogs.set("mediaEditor_"+e.mediaID,{_dialogSetup:function(){return{id:"mediaEditor_"+e.mediaID,options:{backdropCloseOnClick:!1,onClose:this._close.bind(this),title:o.get("wcf.media.edit")},source:{after:this._initEditor.bind(this),data:{actionName:"getEditorDialog",className:"wcf\\data\\media\\MediaAction",objectIDs:[e.mediaID]}}}}.bind(this)}),s.open(this._dialogs.get("mediaEditor_"+e.mediaID))},updateData:function(e){this._callbackObject._editorSuccess&&this._callbackObject._editorSuccess(e)}},f}),define("WoltLabSuite/Core/Media/List/Upload",["Core","Dom/Util","../Upload"],function(e,t,i){"use strict";function n(e,t,n){i.call(this,e,t,n)}return e.inherit(n,i,{_createButton:function(){n._super.prototype._createButton.call(this);var e=elBySel("span",this._button),i=document.createTextNode(" ");t.prepend(i,e);var a=elCreate("span");a.className="icon icon16 fa-upload",t.prepend(a,e)},_getParameters:function(){return this._options.categoryId?e.extend(n._super.prototype._getParameters.call(this),{categoryID:this._options.categoryId}):n._super.prototype._getParameters.call(this)}}),n}),define("WoltLabSuite/Core/Media/Clipboard",["Ajax","Dom/ChangeListener","EventHandler","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,a,r,o,s,l){"use strict";var c,d=[];return{init:function(e,t,n){o.setup({hasMarkedItems:t,pageClassName:e}),c=n,i.add("com.woltlab.wcf.clipboard","com.woltlab.wcf.media",this._clipboardAction.bind(this))},_ajaxSetup:function(){return{data:{className:"wcf\\data\\media\\MediaAction"}}},_ajaxSuccess:function(e){switch(e.actionName){case"getSetCategoryDialog":a.open(this,e.returnValues.template);break;case"setCategory":a.close(this),r.show(),o.reload()}},_dialogSetup:function(){return{id:"mediaSetCategoryDialog",options:{onSetup:function(e){elBySel("button",e).addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),this._setCategory(~~elBySel('select[name="categoryID"]',e).value),t.currentTarget.disabled=!0}.bind(this))}.bind(this),title:n.get("wcf.media.setCategory")},source:null}},_clipboardAction:function(t){var i=t.data.parameters.objectIDs;switch(t.data.actionName){case"com.woltlab.wcf.media.delete":null!==t.responseData&&c.clipboardDeleteMedia(i);break;case"com.woltlab.wcf.media.insert":c.clipboardInsertMedia(i);break;case"com.woltlab.wcf.media.setCategory":d=i,e.api(this,{actionName:"getSetCategoryDialog"})}},_setCategory:function(t){e.api(this,{actionName:"setCategory",objectIDs:d,parameters:{categoryID:t}})}}}),define("WoltLabSuite/Core/Notification/Handler",["Ajax","Core","EventHandler","StringUtil"],function(e,t,i,n){"use strict";if(!("Promise"in window&&"Notification"in window))return{setup:function(){}};var a=!1,r="",o=0,s=window.TIME_NOW,l=null,c=0;return{setup:function(e){if(e=t.extend({enableNotifications:!1,icon:"",sessionKeepAlive:0},e),r=e.icon,c=60*e.sessionKeepAlive,this._prepareNextRequest(),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this)),window.addEventListener("storage",this._onStorage.bind(this)),this._onVisibilityChange(null),e.enableNotifications)switch(window.Notification.permission){case"granted":a=!0;break;case"default":window.Notification.requestPermission(function(e){"granted"===e&&(a=!0)})}},_onVisibilityChange:function(e){if(null!==e&&!document.hidden){(Date.now()-o)/6e4>4&&(this._resetTimer(),this._dispatchRequest())}o=document.hidden?Date.now():0},_getNextDelay:function(){if(0===o)return 5;var e=~~((Date.now()-o)/6e4);return e<15?5:e<30?10:15},_resetTimer:function(){null!==l&&(window.clearTimeout(l),l=null)},_prepareNextRequest:function(){this._resetTimer();var e=Math.min(this._getNextDelay(),c);l=window.setTimeout(this._dispatchRequest.bind(this),6e4*e)},_dispatchRequest:function(){var t={};i.fire("com.woltlab.wcf.notification","beforePoll",t),t.lastRequestTimestamp=s,e.api(this,{parameters:t})},_onStorage:function(){this._prepareNextRequest();var e,n,a=!1;try{e=window.localStorage.getItem(t.getStoragePrefix()+"notification"),n=window.localStorage.getItem(t.getStoragePrefix()+"keepAliveData"),e=JSON.parse(e),n=JSON.parse(n)}catch(e){a=!0}a||i.fire("com.woltlab.wcf.notification","onStorage",{pollData:e,keepAliveData:n})},_ajaxSuccess:function(e){var n=!1,a=e.returnValues.keepAliveData,r=e.returnValues.pollData;window.WCF.System.PushNotification.executeCallbacks({returnValues:a});try{window.localStorage.setItem(t.getStoragePrefix()+"notification",JSON.stringify(r)),window.localStorage.setItem(t.getStoragePrefix()+"keepAliveData",JSON.stringify(a))}catch(e){n=!0,window.console.log(e)}n||this._prepareNextRequest(),s=e.returnValues.lastRequestTimestamp,i.fire("com.woltlab.wcf.notification","afterPoll",r),this._showNotification(r)},_showNotification:function(e){if(a&&"object"==typeof e.notification&&"string"==typeof e.notification.message){var t=new window.Notification(e.notification.title,{body:n.unescapeHTML(e.notification.message).replace(/&#x202F;/g," "),icon:r});t.onclick=function(){window.focus(),t.close(),window.location=e.notification.link}}},_ajaxSetup:function(){return{data:{actionName:"poll",className:"wcf\\data\\session\\SessionAction"},ignoreError:!window.ENABLE_DEBUG_MODE,silent:!window.ENABLE_DEBUG_MODE}}}}),define("WoltLabSuite/Core/Ui/Redactor/DragAndDrop",["Dictionary","EventHandler","Language"],function(e,t,i){"use strict";var n=!1,a=new e,r=!1,o=!1,s=null;return{init:function(e){n||this._setup(),a.set(e.uuid,{editor:e,element:null})},_dragOver:function(e){if(e.preventDefault(),e.dataTransfer&&e.dataTransfer.types){var t=!1;for(var n in e.dataTransfer)if(e.dataTransfer.hasOwnProperty(n)&&n.match(/^moz/)){t=!0;break}if(o=!1,t)"application/x-moz-file"===e.dataTransfer.types[0]&&(o=!0);else for(var s=0;s<e.dataTransfer.types.length;s++)if("Files"===e.dataTransfer.types[s]){o=!0;break}o&&(r||(r=!0,a.forEach(function(e,t){var n=e.editor.$editor[0];if(!n.parentNode)return void a.delete(t);var r=e.element;null===r&&(r=elCreate("div"),r.className="redactorDropArea",elData(r,"element-id",e.editor.$element[0].id),elData(r,"drop-here",i.get("wcf.attachment.dragAndDrop.dropHere")),elData(r,"drop-now",i.get("wcf.attachment.dragAndDrop.dropNow")),r.addEventListener("dragover",function(){r.classList.add("active")}),r.addEventListener("dragleave",function(){r.classList.remove("active")}),r.addEventListener("drop",this._drop.bind(this)),e.element=r),n.parentNode.insertBefore(r,n),r.style.setProperty("top",n.offsetTop+"px","")}.bind(this))))}},_drop:function(e){if(o&&e.dataTransfer&&e.dataTransfer.files.length){e.preventDefault();for(var i=elData(e.currentTarget,"element-id"),n=0,a=e.dataTransfer.files.length;n<a;n++)t.fire("com.woltlab.wcf.redactor2","dragAndDrop_"+i,{file:e.dataTransfer.files[n]});this._dragLeave()}},_dragLeave:function(){r&&o&&(null!==s&&window.clearTimeout(s),s=window.setTimeout(function(){r||a.forEach(function(e){e.element&&e.element.parentNode&&(e.element.classList.remove("active"),elRemove(e.element))}),s=null},100),r=!1)},_globalDrop:function(e){if(null===e.target.closest(".redactor-layer")){var i={cancelDrop:!0,event:e};a.forEach(function(e){t.fire("com.woltlab.wcf.redactor2","dragAndDrop_globalDrop_"+e.editor.$element[0].id,i)}),i.cancelDrop&&e.preventDefault()}this._dragLeave(e)},_setup:function(){window.addEventListener("dragend",function(e){e.preventDefault()}),window.addEventListener("dragover",this._dragOver.bind(this)),window.addEventListener("dragleave",this._dragLeave.bind(this)),window.addEventListener("drop",this._globalDrop.bind(this)),n=!0}}}),define("WoltLabSuite/Core/Ui/DragAndDrop",["Core","EventHandler","WoltLabSuite/Core/Ui/Redactor/DragAndDrop"],function(e,t,i){return{register:function(n){var a=e.getUuid();n=e.extend({element:"",elementId:"",onDrop:function(e){},onGlobalDrop:function(e){}}),t.add("com.woltlab.wcf.redactor2","dragAndDrop_"+n.elementId,n.onDrop),t.add("com.woltlab.wcf.redactor2","dragAndDrop_globalDrop_"+n.elementId,n.onGlobalDrop),i.init({uuid:a,$editor:[n.element],$element:[{id:n.elementId}]})}}}),define("WoltLabSuite/Core/Ui/Suggestion",["Ajax","Core","Ui/SimpleDropdown"],function(e,t,i){"use strict";function n(e,t){this.init(e,t)}return n.prototype={init:function(e,i){if(this._dropdownMenu=null,this._value="",this._element=elById(e),null===this._element)throw new Error("Expected a valid element id.");if(this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction",parameters:{data:{}}},callbackSelect:null,excludedSearchValues:[],threshold:3},i),"function"!=typeof this._options.callbackSelect)throw new Error("Expected a valid callback for option 'callbackSelect'.");this._element.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),this._element.addEventListener("keydown",this._keyDown.bind(this)),this._element.addEventListener("keyup",this._keyUp.bind(this))},addExcludedValue:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedValue:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},isActive:function(){return null!==this._dropdownMenu&&i.isOpen(this._element.id)},_keyDown:function(e){if(!this.isActive())return!0;if(13!==e.keyCode&&27!==e.keyCode&&38!==e.keyCode&&40!==e.keyCode)return!0;for(var t,n=0,a=this._dropdownMenu.childElementCount;n<a&&(t=this._dropdownMenu.children[n],!t.classList.contains("active"));)n++;if(13===e.keyCode)i.close(this._element.id),this._select(t);else if(27===e.keyCode){if(!i.isOpen(this._element.id))return!0;i.close(this._element.id)}else{var r=0;38===e.keyCode?r=(0===n?a:n)-1:40===e.keyCode&&(r=n+1)===a&&(r=0),r!==n&&(t.classList.remove("active"),this._dropdownMenu.children[r].classList.add("active"))}return e.preventDefault(),!1},_select:function(e){var t=e instanceof Event;t&&(e=e.currentTarget.parentNode);var i=e.children[0];this._options.callbackSelect(this._element.id,{objectId:elData(i,"object-id"),value:e.textContent,type:elData(i,"type")}),t&&this._element.focus()},_keyUp:function(t){var n=t.currentTarget.value.trim();if(this._value!==n){if(n.length<this._options.threshold)return null!==this._dropdownMenu&&i.close(this._element.id),void(this._value=n);this._value=n,e.api(this,{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:n}}})}},_ajaxSetup:function(){return{data:this._options.ajax}},_ajaxSuccess:function(e){if(null===this._dropdownMenu?(this._dropdownMenu=elCreate("div"),this._dropdownMenu.className="dropdownMenu",i.initFragment(this._element,this._dropdownMenu)):this._dropdownMenu.innerHTML="",e.returnValues.length){for(var t,n,a,r=0,o=e.returnValues.length;r<o;r++)n=e.returnValues[r],t=elCreate("a"),n.icon?(t.className="box16",t.innerHTML=n.icon+" <span></span>",t.children[1].textContent=n.label):t.textContent=n.label,elData(t,"object-id",n.objectID),n.type&&elData(t,"type",n.type),t.addEventListener(WCF_CLICK_EVENT,this._select.bind(this)),a=elCreate("li"),0===r&&(a.className="active"),a.appendChild(t),this._dropdownMenu.appendChild(a);i.open(this._element.id,!0)}else i.close(this._element.id)}},n}),define("WoltLabSuite/Core/Ui/ItemList",["Core","Dictionary","Language","Dom/Traverse","EventKey","WoltLabSuite/Core/Ui/Suggestion","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";var s="",l=new t,c=!1,d=null,u=null,h=null,f=null,p=null,m=null;return{init:function(t,i,a){var s=elById(t);if(null===s)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(l.has(t)){var c=l.get(t);for(var d in c)if(c.hasOwnProperty(d)){var u=c[d];u instanceof Element&&u.parentNode&&elRemove(u)}o.destroy(t),l.delete(t)}a=e.extend({ajax:{actionName:"getSearchResultList",className:"",data:{}},excludedSearchValues:[],maxItems:-1,maxLength:-1,restricted:!1,isCSV:!1,callbackChange:null,callbackSubmit:null,callbackSyncShadow:null,callbackSetupValues:null,submitFieldName:""},a);var h=n.parentByTag(s,"FORM");if(null!==h)if(!1===a.isCSV){if(!a.submitFieldName.length&&"function"!=typeof a.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=l.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}var i=this.getValues(t);if(a.submitFieldName.length)for(var n,r=0,o=i.length;r<o;r++)n=elCreate("input"),n.type="hidden",n.name=a.submitFieldName.replace("{$objectId}",i[r].objectId),n.value=i[r].value,h.appendChild(n);else a.callbackSubmit(h,i)}.bind(this))}else h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=l.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}}.bind(this));this._setup();var f=this._createUI(s,a),p=new r(t,{ajax:a.ajax,callbackSelect:this._addItem.bind(this),excludedSearchValues:a.excludedSearchValues});if(l.set(t,{dropdownMenu:null,element:f.element,limitReached:f.limitReached,list:f.list,listItem:f.element.parentNode,options:a,shadow:f.shadow,suggestion:p}),i=a.callbackSetupValues?a.callbackSetupValues():f.values.length?f.values:i,Array.isArray(i))for(var m,g=0,v=i.length;g<v;g++)m=i[g],"string"==typeof m&&(m={objectId:0,value:m}),this._addItem(t,m)},getValues:function(e){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=l.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent.trim(),type:elData(e,"type")})}),i},setValues:function(e,t){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,a,r=l.get(e),o=n.childrenByClass(r.list,"item");for(i=0,a=o.length;i<a;i++)this._removeItem(null,o[i],!0);for(i=0,a=t.length;i<a;i++)this._addItem(e,t[i])},_setup:function(){c||(c=!0,d=this._keyDown.bind(this),u=this._keyPress.bind(this),h=this._keyUp.bind(this),f=this._paste.bind(this),p=this._removeItem.bind(this),m=this._blur.bind(this))},_createUI:function(e,t){var n=elCreate("ol");n.className="inputItemList"+(e.disabled?" disabled":""),elData(n,"element-id",e.id),n.addEventListener(WCF_CLICK_EVENT,function(t){t.target===n&&e.focus()});var a=elCreate("li");a.className="input",n.appendChild(a),e.addEventListener("keydown",d),e.addEventListener("keypress",u),e.addEventListener("keyup",h),e.addEventListener("paste",f);var r=e===document.activeElement;r&&e.blur(),e.addEventListener("blur",m),e.parentNode.insertBefore(n,e),a.appendChild(e),r&&window.setTimeout(function(){e.focus()},1),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var o=elCreate("span");o.className="inputItemListLimitReached",o.textContent=i.get("wcf.global.form.input.maxItems"),elHide(o),a.appendChild(o);var s=null,l=[];if(t.isCSV){s=elCreate("input"),s.className="itemListInputShadow",s.type="hidden",s.name=e.name,e.removeAttribute("name"),n.parentNode.insertBefore(s,n);for(var c,p=e.value.split(","),g=0,v=p.length;g<v;g++)c=p[g].trim(),c.length&&l.push(c);if("TEXTAREA"===e.nodeName){var _=elCreate("input");_.type="text",e.parentNode.insertBefore(_,e),_.id=e.id,elRemove(e),e=_}}return{element:e,limitReached:o,list:n,shadow:s,values:l}},_acceptsNewItems:function(e){var t=l.get(e);return-1===t.options.maxItems||t.list.childElementCount-1<t.options.maxItems},_handleLimit:function(e){var t=l.get(e);this._acceptsNewItems(e)?(elShow(t.element),elHide(t.limitReached)):(elHide(t.element),elShow(t.limitReached))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;s=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(a.Enter(e)||a.Comma(e)){if(e.preventDefault(),l.get(e.currentTarget.id).options.restricted)return;var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain");var i=e.currentTarget,n=i.id,a=~~elAttr(i,"maxLength");t.split(/,/).forEach(function(e){e=e.trim(),a&&e.length>a&&(e=e.substr(0,a)),e.length>0&&this._acceptsNewItems(n)&&this._addItem(n,{objectId:0,value:e})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t){var i=l.get(e),n=elCreate("li");n.className="item";var a=elCreate("span");if(a.className="content",elData(a,"object-id",t.objectId),t.type&&elData(a,"type",t.type),a.textContent=t.value,n.appendChild(a),!i.element.disabled){var r=elCreate("a");r.className="icon icon16 fa-times",r.addEventListener(WCF_CLICK_EVENT,p),n.appendChild(r)}i.list.insertBefore(n,i.listItem),i.suggestion.addExcludedValue(t.value),i.element.value="",i.element.disabled||this._handleLimit(e);var o=this._syncShadow(i);"function"==typeof i.options.callbackChange&&(null===o&&(o=this.getValues(e)),i.options.callbackChange(e,o))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,a=elData(n,"element-id"),r=l.get(a);r.suggestion.removeExcludedValue(t.children[0].textContent),n.removeChild(t),i||r.element.focus(),this._handleLimit(a);var o=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===o&&(o=this.getValues(a)),r.options.callbackChange(a,o))},_syncShadow:function(e){if(!e.options.isCSV)return null;if("function"==typeof e.options.callbackSyncShadow)return e.options.callbackSyncShadow(e);for(var t="",i=this.getValues(e.element.id),n=0,a=i.length;n<a;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=e.currentTarget,i=l.get(t.id);if(!i.options.restricted){var n=t.value.trim();n.length&&(i.suggestion&&i.suggestion.isActive()||this._addItem(t.id,{objectId:0,value:n}))}}}}),define("WoltLabSuite/Core/Ui/Page/JumpTo",["Language","ObjectMap","Ui/Dialog"],function(e,t,i){"use strict";var n=null,a=null,r=null,o=new t,s=null;return{init:function(e,t){if(null===(t=t||null)){var i=elData(e,"link");t=i?function(e){window.location=i.replace(/pageNo=%d/,"pageNo="+e)}:function(){}}else if("function"!=typeof t)throw new TypeError("Expected a valid function for parameter 'callback'.");o.has(e)||elBySelAll(".jumpTo",e,function(i){i.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,e)),o.set(e,{callback:t})}.bind(this))},_click:function(t,a){n=t,"object"==typeof a&&a.preventDefault(),i.open(this);var o=elData(t,"pages");s.value=o,s.setAttribute("max",o),s.select(),r.textContent=e.get("wcf.page.jumpTo.description").replace(/#pages#/,o)},_keyUp:function(e){if(13===e.which&&!1===a.disabled)return void this._submit();var t=~~s.value;t<1||t>~~elAttr(s,"max")?a.disabled=!0:a.disabled=!1},_submit:function(e){o.get(n).callback(~~s.value),i.close(this)},_dialogSetup:function(){var t='<dl><dt><label for="jsPaginationPageNo">'+e.get("wcf.page.jumpTo")+'</label></dt><dd><input type="number" id="jsPaginationPageNo" value="1" min="1" max="1" class="tiny"><small></small></dd></dl><div class="formSubmit"><button class="buttonPrimary">'+e.get("wcf.global.button.submit")+"</button></div>";return{id:"paginationOverlay",options:{onSetup:function(e){s=elByTag("input",e)[0],s.addEventListener("keyup",this._keyUp.bind(this)),r=elByTag("small",e)[0],a=elByTag("button",e)[0],a.addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))}.bind(this),title:e.get("wcf.global.page.pagination")},source:t}}}}),define("WoltLabSuite/Core/Ui/Pagination",["Core","Language","ObjectMap","StringUtil","WoltLabSuite/Core/Ui/Page/JumpTo"],function(e,t,i,n,a){"use strict";function r(e,t){this.init(e,t)}return r.prototype={SHOW_LINKS:11,init:function(t,i){this._element=t,this._options=e.extend({activePage:1,maxPage:1,callbackShouldSwitch:null,callbackSwitch:null},i),"function"!=typeof this._options.callbackShouldSwitch&&(this._options.callbackShouldSwitch=null),"function"!=typeof this._options.callbackSwitch&&(this._options.callbackSwitch=null),this._element.classList.add("pagination"),this._rebuild(this._element)},_rebuild:function(){var e=!1;this._element.innerHTML="";var i,n=elCreate("ul"),r=elCreate("li");r.className="skip",n.appendChild(r);var o="icon icon24 fa-chevron-left";this._options.activePage>1?(i=elCreate("a"),i.className=o+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.previous"),i.rel="prev",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage-1))):(r.innerHTML='<span class="'+o+'"></span>',r.classList.add("disabled")),n.appendChild(this._createLink(1));var s=this.SHOW_LINKS-4,l=this._options.activePage-2;l<0&&(l=0);var c=this._options.maxPage-(this._options.activePage+1);c<0&&(c=0),this._options.activePage>1&&this._options.activePage<this._options.maxPage&&s--;var d=s/2,u=this._options.activePage,h=this._options.activePage;u<1&&(u=1),h<1&&(h=1),h>this._options.maxPage-1&&(h=this._options.maxPage-1),l>=d?u-=d:(u-=l,h+=d-l),c>=d?h+=d:(h+=c,u-=d-c),h=Math.ceil(h),u=Math.ceil(u),u<1&&(u=1),h>this._options.maxPage&&(h=this._options.maxPage);var f='<a class="jsTooltip" title="'+t.get("wcf.page.jumpTo")+'">&hellip;</a>';u>1&&(u-1<2?n.appendChild(this._createLink(2)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=f,n.appendChild(r),e=!0));for(var p=u+1;p<h;p++)n.appendChild(this._createLink(p));h<this._options.maxPage&&(this._options.maxPage-h<2?n.appendChild(this._createLink(this._options.maxPage-1)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=f,n.appendChild(r),e=!0)),n.appendChild(this._createLink(this._options.maxPage)),r=elCreate("li"),r.className="skip",n.appendChild(r),o="icon icon24 fa-chevron-right",this._options.activePage<this._options.maxPage?(i=elCreate("a"),i.className=o+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.next"),i.rel="next",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage+1))):(r.innerHTML='<span class="'+o+'"></span>',r.classList.add("disabled")),e&&(elData(n,"pages",this._options.maxPage),a.init(n,this.switchPage.bind(this))),this._element.appendChild(n)},_createLink:function(e){var i=elCreate("li");if(e!==this._options.activePage){var a=elCreate("a");a.textContent=n.addThousandsSeparator(e),a.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,e)),i.appendChild(a)}else i.classList.add("active"),i.innerHTML="<span>"+n.addThousandsSeparator(e)+'</span><span class="invisible">'+t.get("wcf.page.pagePosition",{pageNo:e,pages:this._options.maxPage})+"</span>";return i},getActivePage:function(){return this._options.activePage},getElement:function(){return this._element},getMaxPage:function(){return this._options.maxPage},switchPage:function(t,i){if("object"==typeof i&&(i.preventDefault(),i.currentTarget&&elData(i.currentTarget,"tooltip"))){var n=elById("balloonTooltip");n&&(e.triggerEvent(i.currentTarget,"mouseleave"),n.style.removeProperty("top"),n.style.removeProperty("bottom"))}if((t=~~t)>0&&this._options.activePage!==t&&t<=this._options.maxPage){if(null!==this._options.callbackShouldSwitch&&!0!==this._options.callbackShouldSwitch(t))return;this._options.activePage=t,this._rebuild(),null!==this._options.callbackSwitch&&this._options.callbackSwitch(t)}}},r}),define("WoltLabSuite/Core/Wrapper/FacebookSdk",["https://connect.facebook.net/en_US/sdk.js"],function(e){"use strict";return FB.init({version:"v7.0"}),FB}),define("WoltLabSuite/Core/Controller/Media/List",["Dom/ChangeListener","EventHandler","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,a,r){"use strict";var o,s,l=elById("mediaListTableBody");return{init:function(i){i=i||{},s=new r("uploadButton","mediaListTableBody",{categoryId:i.categoryId,multiple:!0,elementTagSize:48}),n.init("wcf\\acp\\page\\MediaListPage",i.hasMarkedItems||!1,this),t.add("com.woltlab.wcf.media.upload","removedErroneousUploadRow",this._deleteCallback.bind(this)),new WCF.Action.Delete("wcf\\data\\media\\MediaAction",".jsMediaRow").setCallback(this._deleteCallback),o=new a({_editorSuccess:function(e,t){e.categoryID!=t&&window.setTimeout(function(){window.location.reload()},500)}}),this._addButtonEventListeners(),e.add("WoltLabSuite/Core/Controller/Media/List",this._addButtonEventListeners.bind(this)),t.add("com.woltlab.wcf.media.upload","success",this._openEditorAfterUpload.bind(this))},_addButtonEventListeners:function(){for(var e,t=elByClass("jsMediaEditButton",l);t.length;)e=t[0],
+e.classList.remove("jsMediaEditButton"),e.addEventListener(WCF_CLICK_EVENT,this._edit.bind(this))},_deleteCallback:function(e){var t=elByTag("tr",l).length;void 0===e.length?t||window.location.reload():e.length===t?window.location.reload():i.reload.bind(i)},_edit:function(e){o.edit(elData(e.currentTarget,"object-id"))},_openEditorAfterUpload:function(e){if(e.upload===s&&!e.isMultiFileUpload&&!s.hasPendingUploads()){var t=Object.keys(e.media);t.length&&o.edit(e.media[t[0]])}},clipboardDeleteMedia:function(e){for(var t=elByClass("jsMediaRow"),i=0;i<t.length;i++){var n=t[i],a=~~elData(elByClass("jsClipboardItem",n)[0],"object-id");-1!==e.indexOf(a)&&(elRemove(n),i--)}t.length||window.location.reload()}}}),define("WoltLabSuite/Core/Controller/Notice/Dismiss",["Ajax"],function(e){"use strict";return{setup:function(){var e=elByClass("jsDismissNoticeButton");if(e.length)for(var t=this._click.bind(this),i=0,n=e.length;i<n;i++)e[i].addEventListener(WCF_CLICK_EVENT,t)},_click:function(t){var i=t.currentTarget;e.apiOnce({data:{actionName:"dismiss",className:"wcf\\data\\notice\\NoticeAction",objectIDs:[elData(i,"object-id")]},success:function(){elRemove(i.parentNode)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager",["Dictionary","Dom/ChangeListener","EventHandler","List","Dom/Util","ObjectMap"],function(e,t,i,n,a,r){"use strict";var o=!1,s=!0,l=new n,c=new e,d=new n,u=new e,h=new r;return{_hide:function(t){elHide(t),l.add(t),t.classList.contains("tabMenuContent")&&elBySelAll("li",t.parentNode.querySelector(".tabMenu"),function(e){elData(e,"name")===elData(t,"name")&&elHide(e)}),elBySelAll("[max], [maxlength], [min], [required]",t,function(t){var i=new e,n=elAttr(t,"max");n&&(i.set("max",n),t.removeAttribute("max"));var a=elAttr(t,"maxlength");a&&(i.set("maxlength",a),t.removeAttribute("maxlength"));var r=elAttr(t,"min");r&&(i.set("min",r),t.removeAttribute("min")),t.required&&(i.set("required",!0),t.removeAttribute("required")),h.set(t,i)})},_show:function(e){elShow(e),l.delete(e),e.classList.contains("tabMenuContent")&&elBySelAll("li",e.parentNode.querySelector(".tabMenu"),function(t){elData(t,"name")===elData(e,"name")&&elShow(t)}),elBySelAll("input, select",e,function(t){for(var i=t.parentNode;i!==e&&"none"!==i.style.getPropertyValue("display");)i=i.parentNode;if(i===e&&h.has(t)){var n=h.get(t);n.has("max")&&elAttr(t,"max",n.get("max")),n.has("maxlength")&&elAttr(t,"maxlength",n.get("maxlength")),n.has("min")&&elAttr(t,"min",n.get("min")),n.has("required")&&elAttr(t,"required",""),h.delete(t)}})},addDependency:function(e){var t=e.getDependentNode();u.has(t.id)?u.get(t.id).push(e):u.set(t.id,[e]);for(var i=e.getFields(),n=0,r=i.length;n<r;n++){var o=i[n],s=a.identify(o);c.has(s)||(c.set(s,o),"INPUT"!==o.tagName||"checkbox"!==o.type&&"radio"!==o.type&&"hidden"!==o.type?o.addEventListener("input",this.checkDependencies.bind(this)):o.addEventListener("change",this.checkDependencies.bind(this)))}},checkDependencies:function(){var e=[];u.forEach(function(t,i){var n=elById(i);if(null===n)return void e.push(i);for(var a=0,r=t.length;a<r;a++)if(!t[a].checkDependency())return void this._hide(n);this._show(n)}.bind(this));for(var t=0,i=e.length;t<i;t++)u.delete(e[t]);this.checkContainers()},addContainerCheckCallback:function(e){if("function"!=typeof e)throw new TypeError("Expected a valid callback for parameter 'callback'.");i.add("com.woltlab.wcf.form.builder.dependency","checkContainers",e)},checkContainers:function(){if(!0===o)return void(s=!0);o=!0,s=!1,i.fire("com.woltlab.wcf.form.builder.dependency","checkContainers"),o=!1,s&&this.checkContainers()},isHiddenByDependencies:function(e){if(l.has(e))return!0;var t=!1;return l.forEach(function(i){a.contains(i,e)&&(t=!0)}),t},register:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(d.has(t))throw new Error("Form with id '"+e+"' has already been registered.");d.add(t)},unregister:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(!d.has(t))throw new Error("Form with id '"+e+"' has not been registered.");d.delete(t),l.forEach(function(e){t.contains(e)&&l.delete(e)}),u.forEach(function(e,i){t.contains(elById(i))&&u.delete(i);for(var n=0,a=e.length;n<a;n++)for(var r=e[n].getFields(),o=0,s=r.length;o<s;o++){var l=r[o];c.delete(l.id),h.delete(l)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Field",[],function(){"use strict";function e(e){this.init(e)}return e.prototype={init:function(e){this._fieldId=e,this._readField()},_getData:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Field._getData!")},_readField:function(){if(this._field=elById(this._fieldId),null===this._field)throw new Error("Unknown field with id '"+this._fieldId+"'.")},destroy:function(){},getData:function(){return Promise.resolve(this._getData())},getId:function(){return this._fieldId}},e}),define("WoltLabSuite/Core/Form/Builder/Manager",["Core","Dictionary","EventHandler","./Field/Dependency/Manager","./Field/Field"],function(e,t,i,n,a){"use strict";var r=new t,o=new t;return{getData:function(t){if(!this.hasForm(t))throw new Error("Unknown form with id '"+t+"'.");var i=[];return r.get(t).forEach(function(e){var t=e.getData();if(!(t instanceof Promise))throw new TypeError("Data for field with id '"+e.getId()+"' is no promise.");i.push(t)}),Promise.all(i).then(function(t){for(var i={},n=0,a=t.length;n<a;n++)i=e.extend(i,t[n]);return i})},getField:function(e,t){if(!this.hasField(e,t))throw new Error("Unknown field with id '"+e+"' for form with id '"+t+"'.");return r.get(e).get(t)},getForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return o.get(e)},hasField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return r.get(e).has(t)},hasForm:function(e){return o.has(e)},registerField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");if(!(t instanceof a))throw new Error("Add field is no instance of 'WoltLabSuite/Core/Form/Builder/Field/Field'.");var n=t.getId();if(this.hasField(e,n))throw new Error("Form field with id '"+n+"' has already been registered for form with id '"+e+"'.");r.get(e).set(n,t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerField",{field:t,formId:e})},registerForm:function(e){if(this.hasForm(e))throw new Error("Form with id '"+e+"' has already been registered.");var n=elById(e);if(null===n)throw new Error("Unknown form with id '"+e+"'.");o.set(e,n),r.set(e,new t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerForm",{formId:e})},unregisterForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");i.fire("WoltLabSuite/Core/Form/Builder/Manager","beforeUnregisterForm",{formId:e}),o.delete(e),r.get(e).forEach(function(e){e.destroy()}),r.delete(e),n.unregister(e),i.fire("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",{formId:e})}}}),define("WoltLabSuite/Core/Form/Builder/Dialog",["Ajax","Core","./Manager","Ui/Dialog"],function(e,t,i,n){"use strict";function a(e,t,i,n){this.init(e,t,i,n)}return a.prototype={init:function(e,i,n,a){this._dialogId=e,this._className=i,this._actionName=n,this._options=t.extend({actionParameters:{},destroyOnClose:!1,usesDboAction:this._className.match(/\w+\\data\\/)},a),this._options.dialog=t.extend(this._options.dialog||{},{onClose:this._dialogOnClose.bind(this)}),this._formId="",this._dialogContent=""},_ajaxSetup:function(){var e={data:{actionName:this._actionName,className:this._className,parameters:this._options.actionParameters}};return this._options.usesDboAction||(e.url="index.php?ajax-invoke/&t="+SECURITY_TOKEN,e.withCredentials=!0),e},_ajaxSuccess:function(e){switch(e.actionName){case this._actionName:if(void 0===e.returnValues)throw new Error("Missing return data.");if(void 0===e.returnValues.dialog)throw new Error("Missing dialog template in return data.");if(void 0===e.returnValues.formId)throw new Error("Missing form id in return data.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog);break;case this._options.submitActionName:if(e.returnValues&&e.returnValues.formId&&e.returnValues.dialog){if(e.returnValues.formId!==this._formId)throw new Error("Mismatch between form ids: expected '"+this._formId+"' but got '"+e.returnValues.formId+"'.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog)}else this.destroy(),"function"==typeof this._options.successCallback&&this._options.successCallback(e.returnValues||{});break;default:throw new Error("Cannot handle action '"+e.actionName+"'.")}},_closeDialog:function(){n.close(this),"function"==typeof this._options.closeCallback&&this._options.closeCallback()},_dialogOnClose:function(){this._options.destroyOnClose&&this.destroy()},_dialogSetup:function(){return{id:this._dialogId,options:this._options.dialog,source:this._dialogContent}},_dialogSubmit:function(){this.getData().then(this._submitForm.bind(this))},_openDialogContent:function(e,t){this.destroy(!0),this._formId=e,this._dialogContent=t;var i=n.open(this,this._dialogContent),a=elBySel("button[data-type=cancel]",i.content);null===a||elDataBool(a,"has-event-listener")||(a.addEventListener("click",this._closeDialog.bind(this)),elData(a,"has-event-listener",1))},_submitForm:function(t){var i=elBySel("button[data-type=submit]",n.getDialog(this).content);"function"==typeof this._options.onSubmit?this._options.onSubmit(t,i):"string"==typeof this._options.submitActionName&&(i.disabled=!0,e.api(this,{actionName:this._options.submitActionName,parameters:{data:t,formId:this._formId}}))},destroy:function(e){""!==this._formId&&(i.hasForm(this._formId)&&i.unregisterForm(this._formId),!0!==e&&n.destroy(this))},getData:function(){if(""===this._formId)throw new Error("Form has not been requested yet.");return i.getData(this._formId)},open:function(){n.getDialog(this._dialogId)?n.openStatic(this._dialogId):e.api(this)}},a}),define("WoltLabSuite/Core/Media/Manager/Search",["Ajax","Core","Dom/Traverse","Dom/Util","EventKey","Language","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";function s(e){this._mediaManager=e,this._searchMode=!1,this._searchContainer=elByClass("mediaManagerSearch",e.getDialog())[0],this._input=elByClass("mediaManagerSearchField",e.getDialog())[0],this._input.addEventListener("keypress",this._keyPress.bind(this)),this._cancelButton=elByClass("mediaManagerSearchCancelButton",e.getDialog())[0],this._cancelButton.addEventListener(WCF_CLICK_EVENT,this._cancelSearch.bind(this))}return s.prototype={_ajaxSetup:function(){return{data:{actionName:"getSearchResultList",className:"wcf\\data\\media\\MediaAction",interfaceName:"wcf\\data\\ISearchAction"}}},_ajaxSuccess:function(e){this._mediaManager.setMedia(e.returnValues.media||{},e.returnValues.template||"",{pageCount:e.returnValues.pageCount||0,pageNo:e.returnValues.pageNo||0}),elByClass("dialogContent",this._mediaManager.getDialog())[0].scrollTop=0},_cancelSearch:function(){this._searchMode&&(this._searchMode=!1,this.resetSearch(),this._mediaManager.resetMedia())},_hideStringThresholdError:function(){var e=i.childByClass(this._input.parentNode.parentNode,"innerInfo");e&&elHide(e)},_keyPress:function(e){a.Enter(e)&&(e.preventDefault(),this._input.value.length>=this._mediaManager.getOption("minSearchLength")?(this._hideStringThresholdError(),this.search()):this._showStringThresholdError())},_showStringThresholdError:function(){var e=i.childByClass(this._input.parentNode.parentNode,"innerInfo");e?elShow(e):(e=elCreate("p"),e.className="innerInfo",e.textContent=r.get("wcf.media.search.info.searchStringThreshold",{minSearchLength:this._mediaManager.getOption("minSearchLength")}),n.insertAfter(e,this._input.parentNode))},hideSearch:function(){elHide(this._searchContainer)},resetSearch:function(){this._input.value=""},showSearch:function(){elShow(this._searchContainer)},search:function(t){"number"!=typeof t&&(t=1);var i=this._input.value;i&&this._input.value.length<this._mediaManager.getOption("minSearchLength")?(this._showStringThresholdError(),i=""):this._hideStringThresholdError(),this._searchMode=!0,e.api(this,{parameters:{categoryID:this._mediaManager.getCategoryId(),imagesOnly:this._mediaManager.getOption("imagesOnly"),mode:this._mediaManager.getMode(),pageNo:t,searchString:i}})}},s}),define("WoltLabSuite/Core/Media/Manager/Base",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","List","Permission","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/Upload","WoltLabSuite/Core/Media/Manager/Search","StringUtil","WoltLabSuite/Core/Ui/Pagination","WoltLabSuite/Core/Media/Clipboard"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,f,p,m,g,v){"use strict";function _(n){this._options=e.extend({dialogTitle:o.get("wcf.media.manager"),imagesOnly:!1,minSearchLength:3},n),this._id="mediaManager"+b++,this._listItems=new t,this._media=new t,this._mediaManagerMediaList=null,this._search=null,this._upload=null,this._forceClipboard=!1,this._hadInitiallyMarkedItems=!1,this._pagination=null,l.get("admin.content.cms.canManageMedia")&&(this._mediaEditor=new h(this)),i.add("WoltLabSuite/Core/Media/Manager",this._addButtonEventListeners.bind(this)),r.add("com.woltlab.wcf.media.upload","success",this._openEditorAfterUpload.bind(this))}var b=0;return _.prototype={_addButtonEventListeners:function(){if(this._mediaManagerMediaList)for(var e=n.childrenByTag(this._mediaManagerMediaList,"LI"),t=0,i=e.length;t<i;t++){var a=e[t];if(l.get("admin.content.cms.canManageMedia")){var r=elByClass("jsMediaEditButton",a)[0];r&&(r.classList.remove("jsMediaEditButton"),r.addEventListener(WCF_CLICK_EVENT,this._editMedia.bind(this)))}}},_categoryChange:function(){this._search.search()},_click:function(e){e.preventDefault(),c.open(this)},_dialogClose:function(){(l.get("admin.content.cms.canManageMedia")||this._forceClipboard)&&u.hideEditor("com.woltlab.wcf.media")},_dialogInit:function(e,t){var i=t.returnValues.media||{};for(var n in i)objOwns(i,n)&&this._media.set(~~n,i[n]);this._initPagination(~~t.returnValues.pageCount),this._hadInitiallyMarkedItems=t.returnValues.hasMarkedItems},_dialogSetup:function(){return{id:this._id,options:{onClose:this._dialogClose.bind(this),onShow:this._dialogShow.bind(this),title:this._options.dialogTitle},source:{after:this._dialogInit.bind(this),data:{actionName:"getManagementDialog",className:"wcf\\data\\media\\MediaAction",parameters:{mode:this.getMode(),imagesOnly:this._options.imagesOnly}}}}},_dialogShow:function(){if(!this._mediaManagerMediaList){var e=this.getDialog();this._mediaManagerMediaList=elByClass("mediaManagerMediaList",e)[0],this._mediaCategorySelect=elBySel(".mediaManagerCategoryList > select",e),this._mediaCategorySelect&&this._mediaCategorySelect.addEventListener("change",this._categoryChange.bind(this));for(var t=n.childrenByTag(this._mediaManagerMediaList,"LI"),i=0,r=t.length;i<r;i++){var o=t[i];this._listItems.set(~~elData(o,"object-id"),o)}if(l.get("admin.content.cms.canManageMedia")){var s=elByClass("mediaManagerMediaUploadButton",c.getDialog(this).dialog)[0];this._upload=new f(a.identify(s),a.identify(this._mediaManagerMediaList),{mediaManager:this});new WCF.Action.Delete("wcf\\data\\media\\MediaAction",".mediaFile")._didTriggerEffect=function(e){this.removeMedia(elData(e[0],"object-id"))}.bind(this)}l.get("admin.content.cms.canManageMedia")||this._forceClipboard?v.init("menuManagerDialog-"+this.getMode(),!!this._hadInitiallyMarkedItems,this):this._removeClipboardCheckboxes(),this._search=new p(this),t.length||this._search.hideSearch()}(l.get("admin.content.cms.canManageMedia")||this._forceClipboard)&&u.showEditor("com.woltlab.wcf.media")},_editMedia:function(e){if(!l.get("admin.content.cms.canManageMedia"))throw new Error("You are not allowed to edit media files.");c.close(this),this._mediaEditor.edit(this._media.get(~~elData(e.currentTarget,"object-id")))},_editorClose:function(){c.open(this)},_editorSuccess:function(e,t){if(this._mediaCategorySelect){var i=~~this._mediaCategorySelect.value;if(i){var n=~~e.categoryID;t==n||t!=i&&n!=i||this._search.search()}}c.open(this),this._media.set(~~e.mediaID,e);var a=this._listItems.get(~~e.mediaID),r=elByClass("mediaTitle",a)[0];e.isMultilingual?e.title&&e.title[LANGUAGE_ID]?r.textContent=e.title[LANGUAGE_ID]:r.textContent=e.filename:e.title&&e.title[e.languageID]?r.textContent=e.title[e.languageID]:r.textContent=e.filename;var o=elByClass("mediaThumbnail",a)[0];o.innerHTML=e.elementTag;var s=elByTag("img",o);s.length&&(s[0].src+="&refresh="+Date.now())},_initPagination:function(e,t){if(void 0===t&&(t=1),e>1){var i=elCreate("div");i.className="paginationBottom jsPagination",a.replaceElement(elBySel(".jsPagination",c.getDialog(this).content),i),this._pagination=new g(i,{activePage:t,callbackSwitch:this._search.search.bind(this._search),maxPage:e})}else this._pagination&&elHide(this._pagination.getElement())},_removeClipboardCheckboxes:function(){for(var e=elByClass("mediaCheckbox",this._mediaManagerMediaList);e.length;)elRemove(e[0])},_openEditorAfterUpload:function(e){if(e.upload===this._upload&&!e.isMultiFileUpload&&!this._upload.hasPendingUploads()){var t=Object.keys(e.media);t.length&&(c.close(this),this._mediaEditor.edit(this._media.get(~~e.media[t[0]].mediaID)))}},_setMedia:function(r){e.isPlainObject(r)?this._media=t.fromObject(r):this._media=r;var s=n.nextByClass(this._mediaManagerMediaList,"info");this._media.size?s&&elHide(s):(null===s&&(s=elCreate("p"),s.className="info",s.textContent=o.get("wcf.media.search.noResults")),elShow(s),a.insertAfter(s,this._mediaManagerMediaList));for(var c=n.childrenByTag(this._mediaManagerMediaList,"LI"),d=0,h=c.length;d<h;d++){var f=c[d];this._media.has(elData(f,"object-id"))?elShow(f):elHide(f)}i.trigger(),l.get("admin.content.cms.canManageMedia")||this._forceClipboard?u.reload():this._removeClipboardCheckboxes()},addMedia:function(e,t){e.languageID||(e.isMultilingual=1),this._media.set(~~e.mediaID,e),this._listItems.set(~~e.mediaID,t),1===this._listItems.size&&this._search.showSearch()},clipboardDeleteMedia:function(e){for(var t=0,i=e.length;t<i;t++)this.removeMedia(~~e[t],!0);d.show()},getCategoryId:function(){return this._mediaCategorySelect?this._mediaCategorySelect.value:0},getDialog:function(){return c.getDialog(this).dialog},getMode:function(){return""},getOption:function(e){return this._options[e]?this._options[e]:null},removeMedia:function(e){if(this._listItems.has(e)){try{elRemove(this._listItems.get(e))}catch(e){}this._listItems.delete(e),this._media.delete(e)}},resetMedia:function(){this._search.search()},setMedia:function(e,t,i){var a=!1;for(var r in e)objOwns(e,r)&&(a=!0);if(a){var o=elCreate("ul");o.innerHTML=t;for(var s=n.childrenByTag(o,"LI"),l=0,c=s.length;l<c;l++){var d=s[l];this._listItems.has(~~elData(d,"object-id"))||(this._listItems.set(elData(d,"object-id"),d),this._mediaManagerMediaList.appendChild(d))}}this._initPagination(i.pageCount,i.pageNo),this._setMedia(e)},setupMediaElement:function(t,i){var a=n.childByClass(i,"mediaInformation"),r=elCreate("nav");r.className="jsMobileNavigation buttonGroupNavigation",a.parentNode.appendChild(r);var s=elCreate("ul");s.className="buttonList iconList",r.appendChild(s);var c=elCreate("li");c.className="mediaCheckbox",s.appendChild(c);var d=elCreate("a");c.appendChild(d);var u=elCreate("label");d.appendChild(u);var h=elCreate("input");if(h.className="jsClipboardItem",elAttr(h,"type","checkbox"),elData(h,"object-id",t.mediaID),u.appendChild(h),l.get("admin.content.cms.canManageMedia")){c=elCreate("li"),c.className="jsMediaEditButton",elData(c,"object-id",t.mediaID),s.appendChild(c),c.innerHTML='<a><span class="icon icon16 fa-pencil jsTooltip" title="'+o.get("wcf.global.button.edit")+'"></span> <span class="invisible">'+o.get("wcf.global.button.edit")+"</span></a>",c=elCreate("li"),c.className="jsDeleteButton",elData(c,"object-id",t.mediaID);var f=e.getUuid();elData(c,"confirm-message-html",m.unescapeHTML(o.get("wcf.media.delete.confirmMessage",{title:f})).replace(f,m.escapeHTML(t.filename))),s.appendChild(c),c.innerHTML='<a><span class="icon icon16 fa-times jsTooltip" title="'+o.get("wcf.global.button.delete")+'"></span> <span class="invisible">'+o.get("wcf.global.button.delete")+"</span></a>"}}},_}),define("WoltLabSuite/Core/Media/Manager/Editor",["Core","Dictionary","Dom/Traverse","EventHandler","Language","Permission","Ui/Dialog","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,a,r,o,s,l){"use strict";function c(i){i=e.extend({callbackInsert:null},i),l.call(this,i),this._forceClipboard=!0,this._activeButton=null;var a=this._options.editor?this._options.editor.core.toolbar()[0]:void 0;this._buttons=elByClass(this._options.buttonClass||"jsMediaEditorButton",a);for(var r=0,o=this._buttons.length;r<o;r++)this._buttons[r].addEventListener(WCF_CLICK_EVENT,this._click.bind(this));if(this._mediaToInsert=new t,this._mediaToInsertByClipboard=!1,this._uploadData=null,this._uploadId=null,this._options.editor&&!this._options.editor.opts.woltlab.attachments){var s=elData(this._options.editor.$editor[0],"element-id"),c=n.add("com.woltlab.wcf.redactor2","dragAndDrop_"+s,this._editorUpload.bind(this)),d=n.add("com.woltlab.wcf.redactor2","pasteFromClipboard_"+s,this._editorUpload.bind(this));n.add("com.woltlab.wcf.redactor2","destory_"+s,function(){n.remove("com.woltlab.wcf.redactor2","dragAndDrop_"+s,c),n.remove("com.woltlab.wcf.redactor2","dragAndDrop_"+s,d)}),n.add("com.woltlab.wcf.media.upload","success",this._mediaUploaded.bind(this))}}return e.inherit(c,l,{_addButtonEventListeners:function(){if(c._super.prototype._addButtonEventListeners.call(this),this._mediaManagerMediaList)for(var e=i.childrenByTag(this._mediaManagerMediaList,"LI"),t=0,n=e.length;t<n;t++){var a=e[t],r=elByClass("jsMediaInsertButton",a)[0];r&&(r.classList.remove("jsMediaInsertButton"),r.addEventListener(WCF_CLICK_EVENT,this._openInsertDialog.bind(this)))}},_buildInsertDialog:function(){for(var e="",t=this._getThumbnailSizes(),i=0,n=t.length;i<n;i++)e+='<option value="'+t[i]+'">'+a.get("wcf.media.insert.imageSize."+t[i])+"</option>";e+='<option value="original">'+a.get("wcf.media.insert.imageSize.original")+"</option>";var r='<div class="section"><dl class="thumbnailSizeSelection"><dt>'+a.get("wcf.media.insert.imageSize")+'</dt><dd><select name="thumbnailSize">'+e+'</select></dd></dl></div><div class="formSubmit"><button class="buttonPrimary">'+a.get("wcf.global.button.insert")+"</button></div>";o.open({_dialogSetup:function(){return{id:this._getInsertDialogId(),options:{onClose:this._editorClose.bind(this),onSetup:function(e){elByClass("buttonPrimary",e)[0].addEventListener(WCF_CLICK_EVENT,this._insertMedia.bind(this));var t=elBySel(".thumbnailSizeSelection",e);elShow(t)}.bind(this),title:a.get("wcf.media.insert")},source:r}}.bind(this)})},_click:function(e){this._activeButton=e.currentTarget,c._super.prototype._click.call(this,e)},_dialogShow:function(){c._super.prototype._dialogShow.call(this),this._uploadData&&(this._uploadData.file?this._upload.uploadFile(this._uploadData.file):this._uploadId=this._upload.uploadBlob(this._uploadData.blob),this._uploadData=null)},_editorUpload:function(e){this._uploadData=e,o.open(this)},_getInsertDialogId:function(){var e="mediaInsert";return this._mediaToInsert.forEach(function(t,i){e+="-"+i}),e},_getThumbnailSizes:function(){for(var e,t,i=[],n=["small","medium","large"],a=0,r=n.length;a<r;a++)e=n[a],t=!0,this._mediaToInsert.forEach(function(i){i[e+"ThumbnailType"]||(t=!1)}),t&&i.push(e);return i},_insertMedia:function(e,i,n){void 0===n&&(n=!0);if(e){o.close(this._getInsertDialogId());var a=e.currentTarget.closest(".dialogContent");i=elBySel("select[name=thumbnailSize]",a).value}if(null!==this._options.callbackInsert?this._options.callbackInsert(this._mediaToInsert,"separate",i):(this._options.editor.buffer.set(),this._mediaToInsert.forEach(this._insertMediaItem.bind(this,i))),this._mediaToInsertByClipboard){var r=[];this._mediaToInsert.forEach(function(e){r.push(e.mediaID)}),s.unmark("com.woltlab.wcf.media",r)}this._mediaToInsert=new t,this._mediaToInsertByClipboard=!1,n&&o.close(this)},_insertMediaGallery:function(){var e=[];this._mediaToInsert.forEach(function(t){e.push(t.mediaID)}),this._options.editor.buffer.set(),this._options.editor.insert.text("[wsmg='"+e.join(",")+"'][/wsmg]")},_insertMediaItem:function(e,t){if(t.isImage){for(var i,n=["small","medium","large","original"],a="",r=0;r<4&&(i=n[r],0==t[i+"ThumbnailHeight"]||(a=i,e!=i));r++);e=a,e||(e="original");var o=t.link;"original"!==e&&(o=t[e+"ThumbnailLink"]),this._options.editor.insert.html('<img src="'+o+'" class="woltlabSuiteMedia" data-media-id="'+t.mediaID+'" data-media-size="'+e+'">')}else this._options.editor.insert.text("[wsm='"+t.mediaID+"'][/wsm]")},_mediaUploaded:function(e){null!==this._uploadId&&this._upload===e.upload&&(this._uploadId===e.uploadId||Array.isArray(this._uploadId)&&-1!==this._uploadId.indexOf(e.uploadId))&&(this._mediaToInsert=t.fromObject(e.media),this._insertMedia(null,"medium",!1),this._uploadId=null)},_openInsertDialog:function(e){this.insertMedia([~~elData(e.currentTarget,"object-id")])},clipboardInsertMedia:function(e){this.insertMedia(e,!0)},insertMedia:function(e,i){this._mediaToInsert=new t,this._mediaToInsertByClipboard=i||!1;for(var n,a=!0,r=0,s=e.length;r<s;r++)n=this._media.get(e[r]),this._mediaToInsert.set(n.mediaID,n),n.isImage||(a=!1);if(a){if(this._getThumbnailSizes().length){o.close(this);var l=this._getInsertDialogId();o.getDialog(l)?o.openStatic(l):this._buildInsertDialog()}else this._insertMedia(void 0,"original")}else this._insertMedia()},getMode:function(){return"editor"},setupMediaElement:function(e,t){c._super.prototype.setupMediaElement.call(this,e,t);var i=elBySel("nav.buttonGroupNavigation > ul",t),n=elCreate("li");n.className="jsMediaInsertButton",elData(n,"object-id",e.mediaID),i.appendChild(n),n.innerHTML='<a><span class="icon icon16 fa-plus jsTooltip" title="'+a.get("wcf.media.button.insert")+'"></span> <span class="invisible">'+a.get("wcf.media.button.insert")+"</span></a>"}}),c}),define("WoltLabSuite/Core/Media/Manager/Select",["Core","Dom/Traverse","Dom/Util","Language","ObjectMap","Ui/Dialog","WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,a,r,o,s){"use strict";function l(e){s.call(this,e),this._activeButton=null,this._buttons=elByClass(this._options.buttonClass||"jsMediaSelectButton"),this._storeElements=new a;for(var t=0,n=this._buttons.length;t<n;t++){var r=this._buttons[t],o=elData(r,"store");if(o){var l=elById(o);if(l&&"INPUT"===l.tagName){this._buttons[t].addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),this._storeElements.set(r,l);var c=elCreate("p");c.className="button",i.insertAfter(c,r);var d=elCreate("span");d.className="icon icon16 fa-times",c.appendChild(d),l.value||elHide(c),c.addEventListener(WCF_CLICK_EVENT,this._removeMedia.bind(this))}}}}return e.inherit(l,s,{_addButtonEventListeners:function(){if(l._super.prototype._addButtonEventListeners.call(this),this._mediaManagerMediaList)for(var e=t.childrenByTag(this._mediaManagerMediaList,"LI"),i=0,n=e.length;i<n;i++){var a=e[i],r=elByClass("jsMediaSelectButton",a)[0];r&&(r.classList.remove("jsMediaSelectButton"),r.addEventListener(WCF_CLICK_EVENT,this._chooseMedia.bind(this)))}},_chooseMedia:function(t){if(null===this._activeButton)throw new Error("Media cannot be chosen if no button is active.");var i=this._media.get(~~elData(t.currentTarget,"object-id")),n=elById(elData(this._activeButton,"store"));n.value=i.mediaID,e.triggerEvent(n,"change");var a=elData(this._activeButton,"display");if(a){var s=elById(a);if(s)if(i.isImage)s.innerHTML='<img src="'+(i.smallThumbnailLink?i.smallThumbnailLink:i.link)+'" alt="'+(i.altText&&i.altText[LANGUAGE_ID]?i.altText[LANGUAGE_ID]:"")+'" />';else{var l=o.getIconNameByFilename(i.filename);l&&(l="-"+l),s.innerHTML='<div class="box48" style="margin-bottom: 10px;"><span class="icon icon48 fa-file'+l+'-o"></span><div class="containerHeadline"><h3>'+i.filename+"</h3><p>"+i.formattedFilesize+"</p></div></div>"}}elShow(this._activeButton.nextElementSibling),r.close(this)},_click:function(e){if(e.preventDefault(),this._activeButton=e.currentTarget,l._super.prototype._click.call(this,e),this._mediaManagerMediaList)for(var i,n=this._storeElements.get(this._activeButton),a=t.childrenByTag(this._mediaManagerMediaList,"LI"),r=0,o=a.length;r<o;r++)i=a[r],n.value&&n.value==elData(i,"object-id")?i.classList.add("jsSelected"):i.classList.remove("jsSelected")},getMode:function(){return"select"},setupMediaElement:function(e,t){l._super.prototype.setupMediaElement.call(this,e,t);var i=elBySel("nav.buttonGroupNavigation > ul",t),a=elCreate("li");a.className="jsMediaSelectButton",elData(a,"object-id",e.mediaID),i.appendChild(a),a.innerHTML='<a><span class="icon icon16 fa-check jsTooltip" title="'+n.get("wcf.media.button.select")+'"></span> <span class="invisible">'+n.get("wcf.media.button.select")+"</span></a>"},_removeMedia:function(t){t.preventDefault();var i=t.currentTarget;elHide(i);var n=i.previousElementSibling,a=elById(elData(n,"store"));a.value="",e.triggerEvent(a,"change");var r=elData(n,"display");if(r){var o=elById(r);o&&(o.innerHTML="")}}}),l}),define("WoltLabSuite/Core/Ui/Search/Input",["Ajax","Core","EventKey","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a){"use strict";function r(e,t){this.init(e,t)}return r.prototype={init:function(e,i){if(this._element=e,!(this._element instanceof Element))throw new TypeError("Expected a valid DOM element.");if("INPUT"!==this._element.nodeName||"search"!==this._element.type&&"text"!==this._element.type)throw new Error('Expected an input[type="text"].');this._activeItem=null,this._dropdownContainerId="",this._lastValue="",this._list=null,this._request=null,this._timerDelay=null,this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction"},autoFocus:!0,callbackDropdownInit:null,callbackSelect:null,delay:500,excludedSearchValues:[],minLength:3,noResultPlaceholder:"",preventSubmit:!1},i),elAttr(this._element,"autocomplete","off"),this._element.addEventListener("keydown",this._keydown.bind(this)),this._element.addEventListener("keyup",this._keyup.bind(this))},addExcludedSearchValues:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedSearchValues:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},_keydown:function(e){(null!==this._activeItem&&a.isOpen(this._dropdownContainerId)||this._options.preventSubmit)&&i.Enter(e)&&e.preventDefault(),(i.ArrowUp(e)||i.ArrowDown(e)||i.Escape(e))&&e.preventDefault()},_keyup:function(e){if(null!==this._activeItem||!this._options.autoFocus)if(a.isOpen(this._dropdownContainerId)){if(i.ArrowUp(e))return e.preventDefault(),this._keyboardPreviousItem();if(i.ArrowDown(e))return e.preventDefault(),this._keyboardNextItem();if(i.Enter(e))return e.preventDefault(),this._keyboardSelectItem()}else this._activeItem=null;if(i.Escape(e))return void a.close(this._dropdownContainerId);var t=this._element.value.trim();if(this._lastValue!==t){if(this._lastValue=t,t.length<this._options.minLength)return void(this._dropdownContainerId&&(a.close(this._dropdownContainerId),this._activeItem=null));this._options.delay?(null!==this._timerDelay&&window.clearTimeout(this._timerDelay),this._timerDelay=window.setTimeout(function(){this._search(t)}.bind(this),this._options.delay)):this._search(t)}},_search:function(t){this._request&&this._request.abortPrevious(),this._request=e.api(this,this._getParameters(t))},_getParameters:function(e){return{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:e}}}},
+_keyboardNextItem:function(){var e;null!==this._activeItem&&(this._activeItem.classList.remove("active"),this._activeItem.nextElementSibling&&(e=this._activeItem.nextElementSibling)),this._activeItem=e||this._list.children[0],this._activeItem.classList.add("active")},_keyboardPreviousItem:function(){var e;null!==this._activeItem&&(this._activeItem.classList.remove("active"),this._activeItem.previousElementSibling&&(e=this._activeItem.previousElementSibling)),this._activeItem=e||this._list.children[this._list.childElementCount-1],this._activeItem.classList.add("active")},_keyboardSelectItem:function(){this._selectItem(this._activeItem)},_clickSelectItem:function(e){this._selectItem(e.currentTarget)},_selectItem:function(e){this._options.callbackSelect&&!1===this._options.callbackSelect(e)?this._element.value="":this._element.value=elData(e,"label"),this._activeItem=null,a.close(this._dropdownContainerId)},_ajaxSuccess:function(e){var t=!1;if(null===this._list?(this._list=elCreate("ul"),this._list.className="dropdownMenu",t=!0,"function"==typeof this._options.callbackDropdownInit&&this._options.callbackDropdownInit(this._list)):this._list.innerHTML="","object"==typeof e.returnValues){var i,r=this._clickSelectItem.bind(this);for(var o in e.returnValues)e.returnValues.hasOwnProperty(o)&&(i=this._createListItem(e.returnValues[o]),i.addEventListener(WCF_CLICK_EVENT,r),this._list.appendChild(i))}t&&(n.insertAfter(this._list,this._element),a.initFragment(this._element.parentNode,this._list),this._dropdownContainerId=n.identify(this._element.parentNode)),this._dropdownContainerId&&(this._activeItem=null,this._list.childElementCount||!1!==this._handleEmptyResult()?(a.open(this._dropdownContainerId,!0),this._options.autoFocus&&this._list.childElementCount&&~~elData(this._list.children[0],"object-id")&&(this._activeItem=this._list.children[0],this._activeItem.classList.add("active"))):a.close(this._dropdownContainerId))},_handleEmptyResult:function(){if(!this._options.noResultPlaceholder)return!1;var e=elCreate("li");e.className="dropdownText";var t=elCreate("span");return t.textContent=this._options.noResultPlaceholder,e.appendChild(t),this._list.appendChild(e),!0},_createListItem:function(e){var t=elCreate("li");elData(t,"object-id",e.objectID),elData(t,"label",e.label);var i=elCreate("span");return i.textContent=e.label,t.appendChild(i),t},_ajaxSetup:function(){return{data:this._options.ajax}}},r}),define("WoltLabSuite/Core/Ui/User/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){var a=e.isPlainObject(n)&&!0===n.includeUserGroups;n=e.extend({ajax:{className:"wcf\\data\\user\\UserAction",parameters:{data:{includeUserGroups:a?1:0}}}},n),i._super.prototype.init.call(this,t,n)},_createListItem:function(e){var t=i._super.prototype._createListItem.call(this,e);elData(t,"type",e.type);var n=elCreate("div");return n.className="box16",n.innerHTML="group"===e.type?'<span class="icon icon16 fa-users"></span>':e.icon,n.appendChild(t.children[0]),t.appendChild(n),t}}),i}),define("WoltLabSuite/Core/Ui/Acl/Simple",["Language","StringUtil","Dom/ChangeListener","WoltLabSuite/Core/Ui/User/Search/Input"],function(e,t,i,n){"use strict";function a(e,t){this.init(e,t)}return a.prototype={init:function(e,t){this._prefix=e||"",this._inputName=t||"aclValues",this._build()},_build:function(){var e=elById(this._prefix+"aclInputContainer");elById(this._prefix+"aclAllowAll").addEventListener("change",function(){elHide(e)}),elById(this._prefix+"aclAllowAll_no").addEventListener("change",function(){elShow(e)}),this._list=elById(this._prefix+"aclAccessList"),this._list.addEventListener(WCF_CLICK_EVENT,this._removeItem.bind(this));var t=[];elBySelAll(".aclLabel",this._list,function(e){t.push(e.textContent)}),this._searchInput=new n(elById(this._prefix+"aclSearchInput"),{callbackSelect:this._select.bind(this),includeUserGroups:!0,excludedSearchValues:t,preventSubmit:!0}),this._aclListContainer=elById(this._prefix+"aclListContainer"),i.trigger()},_select:function(n){var a=elData(n,"type"),r=elData(n,"label"),o='<span class="icon icon16 fa-'+("group"===a?"users":"user")+'"></span>';o+='<span class="aclLabel">'+t.escapeHTML(r)+"</span>",o+='<span class="icon icon16 fa-times pointer jsTooltip" title="'+e.get("wcf.global.button.delete")+'"></span>',o+='<input type="hidden" name="'+this._inputName+"["+a+'][]" value="'+elData(n,"object-id")+'">';var s=elCreate("li");s.innerHTML=o;var l=elBySel(".fa-user",this._list);return null===l?this._list.appendChild(s):this._list.insertBefore(s,l.parentNode),elShow(this._aclListContainer),this._searchInput.addExcludedSearchValues(r),i.trigger(),!1},_removeItem:function(e){if(e.target.classList.contains("fa-times")){var t=elBySel(".aclLabel",e.target.parentNode);this._searchInput.removeExcludedSearchValues(t.textContent),elRemove(e.target.parentNode),0===this._list.childElementCount&&elHide(this._aclListContainer)}}},a}),define("WoltLabSuite/Core/Ui/Article/MarkAllAsRead",["Ajax"],function(e){"use strict";return{init:function(){elBySelAll(".markAllAsReadButton",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this))},_click:function(t){t.preventDefault(),e.api(this)},_ajaxSuccess:function(){var e=elBySel(".mainMenu .active .badge");e&&elRemove(e),elBySelAll(".articleList .newMessageBadge",void 0,elRemove)},_ajaxSetup:function(){return{data:{actionName:"markAllAsRead",className:"wcf\\data\\article\\ArticleAction"}}}}}),define("WoltLabSuite/Core/Ui/Article/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,a,r){"use strict";var o,s,l,c=null;return{open:function(e){o=e,r.open(this)},_search:function(t){t.preventDefault();var n=c.parentNode,a=c.value.trim();if(a.length<3)return void elInnerError(n,i.get("wcf.article.search.error.tooShort"));elInnerError(n,!1),e.api(this,{parameters:{searchString:a}})},_click:function(e){e.preventDefault(),o(elData(e.currentTarget,"article-id")),r.close(this)},_ajaxSuccess:function(e){for(var t,a="",r=0,o=e.returnValues.length;r<o;r++)t=e.returnValues[r],a+='<li><div class="containerHeadline pointer" data-article-id="'+t.articleID+'"><h3>'+n.escapeHTML(t.name)+"</h3><small>"+n.escapeHTML(t.displayLink)+"</small></div></li>";l.innerHTML=a,window[a?"elShow":"elHide"](s),a?elBySelAll(".containerHeadline",l,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this)):elInnerError(c.parentNode,i.get("wcf.article.search.error.noResults"))},_ajaxSetup:function(){return{data:{actionName:"search",className:"wcf\\data\\article\\ArticleAction"}}},_dialogSetup:function(){return{id:"wcfUiArticleSearch",options:{onSetup:function(){var e=this._search.bind(this);c=elById("wcfUiArticleSearchInput"),c.addEventListener("keydown",function(i){t.Enter(i)&&e(i)}),c.nextElementSibling.addEventListener(WCF_CLICK_EVENT,e),s=elById("wcfUiArticleSearchResultContainer"),l=elById("wcfUiArticleSearchResultList")}.bind(this),onShow:function(){c.focus()},title:i.get("wcf.article.search")},source:'<div class="section"><dl><dt><label for="wcfUiArticleSearchInput">'+i.get("wcf.article.search.name")+'</label></dt><dd><div class="inputAddon"><input type="text" id="wcfUiArticleSearchInput" class="long"><a href="#" class="inputSuffix"><span class="icon icon16 fa-search"></span></a></div></dd></dl></div><section id="wcfUiArticleSearchResultContainer" class="section" style="display: none;"><header class="sectionHeader"><h2 class="sectionTitle">'+i.get("wcf.article.search.results")+'</h2></header><ol id="wcfUiArticleSearchResultList" class="containerList"></ol></section>'}}}}),define("WoltLabSuite/Core/Ui/Color/Picker",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}var i=function(e,t){if("object"==typeof window.WCF&&"function"==typeof window.WCF.ColorPicker)return(i=function(e,t){var i=new window.WCF.ColorPicker(e);return"function"==typeof t.callbackSubmit&&i.setCallbackSubmit(t.callbackSubmit),i})(e,t);0===n.length&&(window.__wcf_bc_colorPickerInit=function(){n.forEach(function(e){i(e[0],e[1])}),window.__wcf_bc_colorPickerInit=void 0,n=[]}),n.push([e,t])},n=[];return t.prototype={init:function(t,n){if(!(t instanceof Element))throw new TypeError("Expected a valid DOM element, use `UiColorPicker.fromSelector()` if you want to use a CSS selector.");this._options=e.extend({callbackSubmit:null},n),i(t,this._options)}},t.fromSelector=function(e){elBySelAll(e,void 0,function(e){new t(e)})},t}),define("WoltLabSuite/Core/Ui/Comment/Add",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function f(e){this.init(e)}return f.prototype={init:function(e){this._container=e,this._content=elBySel(".jsOuterEditorContainer",this._container),this._textarea=elBySel(".wysiwygTextarea",this._container),this._editor=null,this._loadingOverlay=null,this._content.addEventListener(WCF_CLICK_EVENT,function(e){this._content.classList.contains("collapsed")&&(e.preventDefault(),this._content.classList.remove("collapsed"),this._focusEditor())}.bind(this)),elBySel('button[data-type="save"]',this._container).addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))},_focusEditor:function(){c.element(this._container,function(){window.jQuery(this._textarea).redactor("WoltLabCaret.endOfEditor")}.bind(this))},_submitGuestDialog:function(e){if("keypress"!==e.type||d.Enter(e)){var i=elBySel("input[name=username]",e.currentTarget.closest(".dialogContent"));if(""===i.value)return elInnerError(i,n.get("wcf.global.form.error.empty")),void i.closest("dl").classList.add("formError");var a={parameters:{data:{username:i.value}}};if(h.has("commentAdd")){var r=h.getData("commentAdd");r instanceof Promise?r.then(function(e){a=t.extend(a,e),this._submit(void 0,a)}.bind(this)):(a=t.extend(a,r),this._submit(void 0,a))}else this._submit(void 0,a)}},_submit:function(n,a){if(n&&n.preventDefault(),this._validate()){this._showLoadingOverlay();var r=this._getParameters();i.fire("com.woltlab.wcf.redactor2","submit_text",r.data),u.userId||a||(r.requireGuestDialog=!0),e.api(this,t.extend({parameters:r},a))}},_getParameters:function(){var e=this._container.closest(".commentList");return{data:{message:this._getEditor().code.get(),objectID:~~elData(e,"object-id"),objectTypeID:~~elData(e,"object-type-id")}}},_validate:function(){if(elBySelAll(".innerError",this._container,elRemove),this._getEditor().utils.isEmpty())return this.throwError(this._textarea,n.get("wcf.global.form.error.empty")),!1;var e={api:this,editor:this._getEditor(),message:this._getEditor().code.get(),valid:!0};return i.fire("com.woltlab.wcf.redactor2","validate_text",e),!1!==e.valid},throwError:function(e,t){elInnerError(e,"empty"===t?n.get("wcf.global.form.error.empty"):t)},_showLoadingOverlay:function(){null===this._loadingOverlay&&(this._loadingOverlay=elCreate("div"),this._loadingOverlay.className="commentLoadingOverlay",this._loadingOverlay.innerHTML='<span class="icon icon96 fa-spinner"></span>'),this._content.classList.add("loading"),this._content.appendChild(this._loadingOverlay)},_hideLoadingOverlay:function(){this._content.classList.remove("loading");var e=elBySel(".commentLoadingOverlay",this._content);null!==e&&e.parentNode.removeChild(e)},_reset:function(){this._getEditor().code.set("<p>​</p>"),i.fire("com.woltlab.wcf.redactor2","reset_text"),document.activeElement&&document.activeElement.blur(),this._content.classList.add("collapsed")},_handleError:function(e){this.throwError(this._textarea,e.returnValues.errorType)},_getEditor:function(){if(null===this._editor){if("function"!=typeof window.jQuery)throw new Error("Unable to access editor, jQuery has not been loaded yet.");this._editor=window.jQuery(this._textarea).data("redactor")}return this._editor},_insertMessage:function(e){return r.insertHtml(e.returnValues.template,this._container,"after"),l.show(n.get("wcf.global.success.add")),a.trigger(),this._container.nextElementSibling},_ajaxSuccess:function(e){if(!u.userId&&e.returnValues.guestDialog){s.openStatic("jsDialogGuestComment",e.returnValues.guestDialog,{closable:!1,onClose:function(){h.has("commentAdd")&&h.delete("commentAdd")},title:n.get("wcf.global.confirmation.title")});var t=s.getDialog("jsDialogGuestComment");elBySel("input[type=submit]",t.content).addEventListener(WCF_CLICK_EVENT,this._submitGuestDialog.bind(this)),elBySel('button[data-type="cancel"]',t.content).addEventListener(WCF_CLICK_EVENT,this._cancelGuestDialog.bind(this)),elBySel("input[type=text]",t.content).addEventListener("keypress",this._submitGuestDialog.bind(this))}else{var i=this._insertMessage(e);u.userId||s.close("jsDialogGuestComment"),this._reset(),this._hideLoadingOverlay(),window.setTimeout(function(){c.element(i)}.bind(this),100)}},_ajaxFailure:function(e){return this._hideLoadingOverlay(),null===e||void 0===e.returnValues||void 0===e.returnValues.errorType||(this._handleError(e),!1)},_ajaxSetup:function(){return{data:{actionName:"addComment",className:"wcf\\data\\comment\\CommentAction"},silent:!0}},_cancelGuestDialog:function(){s.close("jsDialogGuestComment"),this._hideLoadingOverlay()}},f}),define("WoltLabSuite/Core/Ui/Comment/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function f(e){this.init(e)}return f.prototype={init:function(e){this._activeElement=null,this._callbackClick=null,this._comments=new o,this._container=e,this._editorContainer=null,this.rebuild(),s.add("Ui/Comment/Edit_"+c.identify(this._container),this.rebuild.bind(this))},rebuild:function(){elBySelAll(".comment",this._container,function(e){if(!this._comments.has(e)){if(elDataBool(e,"can-edit")){var t=elBySel(".jsCommentEditButton",e);null!==t&&(null===this._callbackClick&&(this._callbackClick=this._click.bind(this)),t.addEventListener(WCF_CLICK_EVENT,this._callbackClick))}this._comments.add(e)}}.bind(this))},_click:function(t){t.preventDefault(),null===this._activeElement?(this._activeElement=t.currentTarget.closest(".comment"),this._prepare(),e.api(this,{actionName:"beginEdit",objectIDs:[this._getObjectId(this._activeElement)]})):d.show("wcf.message.error.editorAlreadyInUse",null,"warning")},_prepare:function(){this._editorContainer=elCreate("div"),this._editorContainer.className="commentEditorContainer",this._editorContainer.innerHTML='<span class="icon icon48 fa-spinner"></span>';var e=elBySel(".commentContentContainer",this._activeElement);e.insertBefore(this._editorContainer,e.firstChild)},_showEditor:function(e){var t=this._getEditorId(),i=elBySel(".icon",this._editorContainer);elRemove(i);var r=elCreate("div");r.className="editorContainer",c.setInnerHtml(r,e.returnValues.template),this._editorContainer.appendChild(r);var o=elBySel(".formSubmit",r);elBySel('button[data-type="save"]',o).addEventListener(WCF_CLICK_EVENT,this._save.bind(this)),elBySel('button[data-type="cancel"]',o).addEventListener(WCF_CLICK_EVENT,this._restoreMessage.bind(this)),a.add("com.woltlab.wcf.redactor","submitEditor_"+t,function(e){e.cancel=!0,this._save()}.bind(this));var s=elById(t);"redactor"===n.editor()?window.setTimeout(function(){h.element(this._activeElement)}.bind(this),250):s.focus()},_restoreMessage:function(){this._destroyEditor(),elRemove(this._editorContainer),this._activeElement=null},_save:function(){var t={data:{message:""}},i=this._getEditorId();a.fire("com.woltlab.wcf.redactor2","getText_"+i,t.data),this._validate(t)&&(a.fire("com.woltlab.wcf.redactor2","submit_"+i,t),e.api(this,{actionName:"save",objectIDs:[this._getObjectId(this._activeElement)],parameters:t}),this._hideEditor())},_validate:function(e){elBySelAll(".innerError",this._activeElement,elRemove);var t=elById(this._getEditorId());if(window.jQuery(t).data("redactor").utils.isEmpty())return this.throwError(t,r.get("wcf.global.form.error.empty")),!1;var i={api:this,parameters:e,valid:!0};return a.fire("com.woltlab.wcf.redactor2","validate_"+this._getEditorId(),i),!1!==i.valid},throwError:function(e,t){elInnerError(e,t)},_showMessage:function(e){c.setInnerHtml(elBySel(".commentContent .userMessage",this._editorContainer.parentNode),e.returnValues.message),this._restoreMessage(),d.show()},_hideEditor:function(){elHide(elBySel(".editorContainer",this._editorContainer));var e=elCreate("span");e.className="icon icon48 fa-spinner",this._editorContainer.appendChild(e)},_restoreEditor:function(){var e=elBySel(".fa-spinner",this._editorContainer);elRemove(e);var t=elBySel(".editorContainer",this._editorContainer);null!==t&&elShow(t)},_destroyEditor:function(){a.fire("com.woltlab.wcf.redactor2","autosaveDestroy_"+this._getEditorId()),a.fire("com.woltlab.wcf.redactor2","destroy_"+this._getEditorId())},_getEditorId:function(){return"commentEditor"+this._getObjectId(this._activeElement)},_getObjectId:function(e){return~~elData(e,"object-id")},_ajaxFailure:function(e){var t=elBySel(".redactor-layer",this._editorContainer);return null===t?(this._restoreMessage(),!0):(this._restoreEditor(),!e||void 0===e.returnValues||void 0===e.returnValues.errorType||(elInnerError(t,e.returnValues.errorType),!1))},_ajaxSuccess:function(e){switch(e.actionName){case"beginEdit":this._showEditor(e);break;case"save":this._showMessage(e)}},_ajaxSetup:function(){return{data:{className:"wcf\\data\\comment\\CommentAction",parameters:{data:{objectTypeID:~~elData(this._container,"object-type-id")}}},silent:!0}}},f}),define("WoltLabSuite/Core/Ui/Dropdown/Builder",["Core","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!(e instanceof HTMLUListElement))throw new TypeError("Expected a reference to an <ul> element.");if(!e.classList.contains("dropdownMenu"))throw new Error("List does not appear to be a dropdown menu.")}function n(t){var i=elCreate("li");if("divider"===t)return i.className="dropdownDivider",i;"string"==typeof t.identifier&&elData(i,"identifier",t.identifier);var n=elCreate("a");if(n.href="string"==typeof t.href?t.href:"#","function"==typeof t.callback)n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),t.callback(n)});else if("#"===n.getAttribute("href"))throw new Error("Expected either a `href` value or a `callback`.");if(t.hasOwnProperty("attributes")&&e.isPlainObject(t.attributes))for(var r in t.attributes)t.attributes.hasOwnProperty(r)&&elData(n,r,t.attributes[r]);if(i.appendChild(n),void 0!==t.icon&&e.isPlainObject(t.icon)){if("string"!=typeof t.icon.name)throw new TypeError("Expected a valid icon name.");var o=16;"number"==typeof t.icon.size&&-1!==a.indexOf(~~t.icon.size)&&(o=~~t.icon.size);var s=elCreate("span");s.className="icon icon"+o+" fa-"+t.icon.name,n.appendChild(s)}var l="string"==typeof t.label?t.label.trim():"",c="string"==typeof t.labelHtml?t.labelHtml.trim():"";if(""===l&&""===c)throw new TypeError("Expected either a label or a `labelHtml`.");var d=elCreate("span");return d[l?"textContent":"innerHTML"]=l||c,n.appendChild(document.createTextNode(" ")),n.appendChild(d),i}var a=[16,24,32,48,64,96,144];return{create:function(e,t){var i=elCreate("ul");return i.className="dropdownMenu","string"==typeof t&&elData(i,"identifier",t),Array.isArray(e)&&e.length>0&&this.appendItems(i,e),i},buildItem:function(e){return n(e)},appendItem:function(e,t){i(e),e.appendChild(n(t))},appendItems:function(e,t){if(i(e),!Array.isArray(t))throw new TypeError("Expected an array of items.");var a=t.length;if(0===a)throw new Error("Expected a non-empty list of items.");if(1===a)this.appendItem(e,t[0]);else{for(var r=document.createDocumentFragment(),o=0;o<a;o++)r.appendChild(n(t[o]));e.appendChild(r)}},setItems:function(e,t){i(e),e.innerHTML="",this.appendItems(e,t)},attach:function(e,n){i(e),t.initFragment(n,e),n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),t.toggleDropdown(n.id)})},divider:function(){return"divider"}}}),define("WoltLabSuite/Core/Ui/File/Delete",["Ajax","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse","Dictionary"],function(e,t,i,n,a,r,o){"use strict";function s(e,t,i,n){if(this._isSingleImagePreview=i,this._uploadHandler=n,this._buttonContainer=elById(e),null===this._buttonContainer)throw new Error("Element id '"+e+"' is unknown.");if(this._target=elById(t),null===t)throw new Error("Element id '"+t+"' is unknown.");if(this._containers=new o,this._internalId=elData(this._target,"internal-id"),!this._internalId)throw new Error("InternalId is unknown.");this.rebuild()}return s.prototype={_createButtons:function(){for(var e,t,n,a=elBySelAll("li.uploadedFile",this._target),r=!1,o=0,s=a.length;o<s;o++)e=a[o],n=elData(e,"unique-file-id"),this._containers.has(n)||(t={uniqueFileId:n,element:e},this._containers.set(n,t),this._initDeleteButton(e,t),r=!0);r&&i.trigger()},_initDeleteButton:function(e,t){var i=elBySel(".buttonGroup",e);if(null===i)throw new Error("Button group in '"+targetId+"' is unknown.");var a=elCreate("li"),r=elCreate("span");r.classList="button jsDeleteButton small",r.textContent=n.get("wcf.global.button.delete"),a.appendChild(r),i.appendChild(a),a.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,t.uniqueFileId))},_delete:function(t){e.api(this,{uniqueFileId:t,internalId:this._internalId})},rebuild:function(){if(this._isSingleImagePreview){var e=elBySel("img",this._target);if(null!==e){var t=elData(e,"unique-file-id");if(!this._containers.has(t)){var i={uniqueFileId:t,element:e};this._containers.set(t,i),this._deleteButton=elCreate("p"),this._deleteButton.className="button deleteButton";var a=elCreate("span");a.textContent=n.get("wcf.global.button.delete"),this._deleteButton.appendChild(a),this._buttonContainer.appendChild(this._deleteButton),this._deleteButton.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,i.uniqueFileId))}}}else this._createButtons()},_ajaxSuccess:function(e){elRemove(this._containers.get(e.uniqueFileId).element),this._isSingleImagePreview&&(elRemove(this._deleteButton),this._deleteButton=null),this._uploadHandler.checkMaxFiles(),t.triggerEvent(this._target,"change")},_ajaxSetup:function(){return{url:"index.php?ajax-file-delete/&t="+SECURITY_TOKEN}}},s}),define("WoltLabSuite/Core/Ui/File/Upload",["Core","Language","Dom/Util","WoltLabSuite/Core/Ui/File/Delete","Upload"],function(e,t,i,n,a){"use strict";function r(t,i,a){if(a=a||{},void 0===a.internalId)throw new Error("Missing internal id.");if(this._options=e.extend({name:"__files[]",singleFileRequests:!1,url:"index.php?ajax-file-upload/&t="+SECURITY_TOKEN,imagePreview:!1,maxFiles:null,acceptableFiles:null},a),this._options.multiple=null===this._options.maxFiles||this._options.maxFiles>1,0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),this._buttonContainer=elById(t),null===this._buttonContainer)throw new Error("Element id '"+t+"' is unknown.");if(this._target=elById(i),null===i)throw new Error("Element id '"+i+"' is unknown.");if(a.multiple&&"UL"!==this._target.nodeName&&"OL"!==this._target.nodeName)throw new Error("Target element has to be list or table body if uploading multiple files is supported.");this._fileElements=[],this._internalFileId=0,this._multiFileUploadIds=[],this._createButton(),this.checkMaxFiles(),this._deleteHandler=new n(t,i,this._options.imagePreview,this)}return e.inherit(r,a,{_createFileElement:function(e){var t=r._super.prototype._createFileElement.call(this,e);t.classList.add("box64","uploadedFile");var i=elBySel("progress",t),n=elCreate("span");n.className="icon icon64 fa-spinner";var a=t.textContent;t.textContent="",t.append(n);var o=elCreate("div"),s=elCreate("p");s.textContent=a;var l=elCreate("small");l.appendChild(i),o.appendChild(s),o.appendChild(l);var c=elCreate("div");c.appendChild(o);var d=elCreate("ul");return d.className="buttonGroup",c.appendChild(d),t.append(c),t},_failure:function(e,n,a,r,o){for(var s=0,l=this._fileElements[e].length;s<l;s++){this._fileElements[e][s].classList.add("uploadFailed"),elBySel("small",this._fileElements[e][s]).innerHTML="";var c=elBySel(".icon",this._fileElements[e][s]);c.classList.remove("fa-spinner"),c.classList.add("fa-ban");var d=elCreate("span");d.className="innerError",d.textContent=t.get("wcf.upload.error.uploadFailed"),i.insertAfter(d,elBySel("small",this._fileElements[e][s]))}throw new Error("Upload failed: "+n.message)},_upload:function(e,t,i){var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return n&&elRemove(n),r._super.prototype._upload.call(this,e,t,i)},_success:function(t,n,a,r,o){for(var s=0,l=this._fileElements[t].length;s<l;s++)if(void 0!==n.files[s])if(this._options.imagePreview){if(null===n.files[s].image)throw new Error("Expect image for uploaded file. None given.");if(elRemove(this._fileElements[t][s]),null!==elBySel("img.previewImage",this._target))elBySel("img.previewImage",this._target).setAttribute("src",n.files[s].image);else{var c=elCreate("img");c.classList.add("previewImage"),c.setAttribute("src",n.files[s].image),c.setAttribute("style","max-width: 100%;"),elData(c,"unique-file-id",n.files[s].uniqueFileId),this._target.appendChild(c)}}else{elData(this._fileElements[t][s],"unique-file-id",n.files[s].uniqueFileId),elBySel("small",this._fileElements[t][s]).textContent=n.files[s].filesize;var d=elBySel(".icon",this._fileElements[t][s]);d.classList.remove("fa-spinner"),d.classList.add("fa-"+n.files[s].icon)}else{if(void 0===n.error[s])throw new Error("Unknown uploaded file for uploadId "+t+".");this._fileElements[t][s].classList.add("uploadFailed"),elBySel("small",this._fileElements[t][s]).innerHTML="";var d=elBySel(".icon",this._fileElements[t][s]);if(d.classList.remove("fa-spinner"),d.classList.add("fa-ban"),null===elBySel(".innerError",this._fileElements[t][s])){var u=elCreate("span");u.className="innerError",u.textContent=n.error[s].errorMessage,i.insertAfter(u,elBySel("small",this._fileElements[t][s]))}else elBySel(".innerError",this._fileElements[t][s]).textContent=n.error[s].errorMessage}this._deleteHandler.rebuild(),this.checkMaxFiles(),e.triggerEvent(this._target,"change")},_getFormData:function(){return{internalId:this._options.internalId}},validateUpload:function(e){if(null===this._options.maxFiles||e.length+this.countFiles()<=this._options.maxFiles)return!0;var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return null===n&&(n=elCreate("small"),n.className="innerError",i.insertAfter(n,this._buttonContainer)),n.textContent=t.get("wcf.upload.error.reachedRemainingLimit",{maxFiles:this._options.maxFiles-this.countFiles()}),!1},countFiles:function(){return this._options.imagePreview?null!==elBySel("img",this._target)?1:0:this._target.childElementCount},checkMaxFiles:function(){null!==this._options.maxFiles&&this.countFiles()>=this._options.maxFiles?elHide(this._button):elShow(this._button)}}),r}),define("WoltLabSuite/Core/Ui/ItemList/Filter",["Core","EventKey","Language","List","StringUtil","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,a,r,o){"use strict";function s(e,t){this.init(e,t)}return s.prototype={init:function(n,a){this._value="",this._options=e.extend({callbackPrepareItem:void 0,enableVisibilityFilter:!0,filterPosition:"bottom"},a),"top"!==this._options.filterPosition&&(this._options.filterPosition="bottom");var r=elById(n);if(null===r)throw new Error("Expected a valid element id, '"+n+"' does not match anything.");if(!r.classList.contains("scrollableCheckboxList")&&"function"!=typeof this._options.callbackPrepareItem)throw new Error("Filter only works with elements with the CSS class 'scrollableCheckboxList'.");elData(r,"filter","showAll");var o=elCreate("div");o.className="itemListFilter",r.parentNode.insertBefore(o,r),o.appendChild(r);var s=elCreate("div");s.className="inputAddon";var l=elCreate("input");l.className="long",l.type="text",l.placeholder=i.get("wcf.global.filter.placeholder"),l.addEventListener("keydown",function(e){t.Enter(e)&&e.preventDefault()}),l.addEventListener("keyup",this._keyup.bind(this));var c=elCreate("a");if(c.href="#",c.className="button inputSuffix jsTooltip",c.title=i.get("wcf.global.filter.button.clear"),c.innerHTML='<span class="icon icon16 fa-times"></span>',c.addEventListener("click",function(e){e.preventDefault(),this.reset()}.bind(this)),s.appendChild(l),s.appendChild(c),this._options.enableVisibilityFilter){var d=elCreate("a");d.href="#",d.className="button inputSuffix jsTooltip",d.title=i.get("wcf.global.filter.button.visibility"),d.innerHTML='<span class="icon icon16 fa-eye"></span>',d.addEventListener(WCF_CLICK_EVENT,this._toggleVisibility.bind(this)),s.appendChild(d)}"bottom"===this._options.filterPosition?o.appendChild(s):o.insertBefore(s,r),this._container=o,this._dropdown=null,this._dropdownId="",this._element=r,this._input=l,this._items=null,this._fragment=null},reset:function(){this._input.value="",this._keyup()},_buildItems:function(){this._items=new n;for(var e="function"==typeof this._options.callbackPrepareItem?this._options.callbackPrepareItem:this._prepareItem.bind(this),t=0,i=this._element.childElementCount;t<i;t++)this._items.add(e(this._element.children[t]))},_prepareItem:function(e){for(var t=e.children[0],i=t.textContent.trim(),n=t.children[0];n.nextSibling;)t.removeChild(n.nextSibling);t.appendChild(document.createTextNode(" "));var a=elCreate("span");return a.textContent=i,t.appendChild(a),{item:e,span:a,text:i}},_keyup:function(){var e=this._input.value.trim();if(this._value!==e){null===this._fragment&&(this._fragment=document.createDocumentFragment(),this._element.style.setProperty("height",this._element.offsetHeight+"px","")),this._fragment.appendChild(this._element),null===this._items&&this._buildItems();var t=new RegExp("("+a.escapeRegExp(e)+")","i"),n=""===e;this._items.forEach(function(i){""===e?(i.span.textContent=i.text,elShow(i.item)):t.test(i.text)?(i.span.innerHTML=i.text.replace(t,"<u>$1</u>"),elShow(i.item),n=!0):elHide(i.item)}),"bottom"===this._options.filterPosition?this._container.insertBefore(this._fragment.firstChild,this._container.firstChild):this._container.appendChild(this._fragment.firstChild),this._value=e,elInnerError(this._container,!n&&i.get("wcf.global.filter.error.noMatches"))}},_toggleVisibility:function(e){e.preventDefault(),e.stopPropagation();var t=e.currentTarget;if(null===this._dropdown){var n=elCreate("ul");n.className="dropdownMenu",["activeOnly","highlightActive","showAll"].forEach(function(e){var t=elCreate("a");elData(t,"type",e),t.href="#",t.textContent=i.get("wcf.global.filter.visibility."+e),t.addEventListener(WCF_CLICK_EVENT,this._setVisibility.bind(this));var a=elCreate("li");if(a.appendChild(t),"showAll"===e){a.className="active";var r=elCreate("li");r.className="dropdownDivider",n.appendChild(r)}n.appendChild(a)}.bind(this)),o.initFragment(t,n),this._setupVisibilityFilter(),this._dropdown=n,this._dropdownId=t.id}o.toggleDropdown(t.id,t)},_setupVisibilityFilter:function(){var e=this._element.nextSibling,t=this._element.parentNode,i=this._element.scrollTop;document.createDocumentFragment().appendChild(this._element),elBySelAll("li",this._element,function(e){var t=elBySel('input[type="checkbox"]',e);if(t)t.checked&&e.classList.add("active"),t.addEventListener("change",function(){e.classList[t.checked?"add":"remove"]("active")});else{var i=elBySel('input[type="radio"]',e);i&&(i.checked&&e.classList.add("active"),i.addEventListener("change",function(){elBySelAll("li",this._element,function(e){e.classList.remove("active")}),e.classList[i.checked?"add":"remove"]("active")}.bind(this)))}}.bind(this)),t.insertBefore(this._element,e),this._element.scrollTop=i},_setVisibility:function(e){e.preventDefault();var t=e.currentTarget,i=elData(t,"type")
+;if(o.close(this._dropdownId),elData(this._element,"filter")!==i){elData(this._element,"filter",i),elBySel(".active",this._dropdown).classList.remove("active"),t.parentNode.classList.add("active");var n=elById(this._dropdownId);n.classList["showAll"===i?"remove":"add"]("active");var a=elBySel(".icon",n);a.classList["showAll"===i?"add":"remove"]("fa-eye"),a.classList["showAll"===i?"remove":"add"]("fa-eye-slash")}}},s}),define("WoltLabSuite/Core/Ui/ItemList/Static",["Core","Dictionary","Language","Dom/Traverse","EventKey","Ui/SimpleDropdown"],function(e,t,i,n,a,r){"use strict";var o="",s=new t,l=!1,c=null,d=null,u=null,h=null,f=null,p=null;return{init:function(t,i,a){var o=elById(t);if(null===o)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(s.has(t)){var l=s.get(t);for(var c in l)if(l.hasOwnProperty(c)){var d=l[c];d instanceof Element&&d.parentNode&&elRemove(d)}r.destroy(t),s.delete(t)}a=e.extend({maxItems:-1,maxLength:-1,isCSV:!1,callbackChange:null,callbackSubmit:null,submitFieldName:""},a);var u=n.parentByTag(o,"FORM");if(null!==u&&!1===a.isCSV){if(!a.submitFieldName.length&&"function"!=typeof a.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");u.addEventListener("submit",function(){var e=this.getValues(t);if(a.submitFieldName.length)for(var i,n=0,r=e.length;n<r;n++)i=elCreate("input"),i.type="hidden",i.name=a.submitFieldName.replace("{$objectId}",e[n].objectId),i.value=e[n].value,u.appendChild(i);else a.callbackSubmit(u,e)}.bind(this))}this._setup();var h=this._createUI(o,a);if(s.set(t,{dropdownMenu:null,element:h.element,list:h.list,listItem:h.element.parentNode,options:a,shadow:h.shadow}),i=h.values.length?h.values:i,Array.isArray(i))for(var f,p=!h.element.disabled,m=0,g=i.length;m<g;m++)f=i[m],"string"==typeof f&&(f={objectId:0,value:f}),this._addItem(t,f,p)},getValues:function(e){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=s.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent})}),i},setValues:function(e,t){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,a,r=s.get(e),o=n.childrenByClass(r.list,"item");for(i=0,a=o.length;i<a;i++)this._removeItem(null,o[i],!0);for(i=0,a=t.length;i<a;i++)this._addItem(e,t[i])},_setup:function(){l||(l=!0,c=this._keyDown.bind(this),d=this._keyPress.bind(this),u=this._keyUp.bind(this),h=this._paste.bind(this),f=this._removeItem.bind(this),p=this._blur.bind(this))},_createUI:function(e,t){var i=elCreate("ol");i.className="inputItemList"+(e.disabled?" disabled":""),elData(i,"element-id",e.id),i.addEventListener(WCF_CLICK_EVENT,function(t){t.target===i&&e.focus()});var n=elCreate("li");n.className="input",i.appendChild(n),e.addEventListener("keydown",c),e.addEventListener("keypress",d),e.addEventListener("keyup",u),e.addEventListener("paste",h),e.addEventListener("blur",p),e.parentNode.insertBefore(i,e),n.appendChild(e),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var a=null,r=[];if(t.isCSV){a=elCreate("input"),a.className="itemListInputShadow",a.type="hidden",a.name=e.name,e.removeAttribute("name"),i.parentNode.insertBefore(a,i);for(var o,s=e.value.split(","),l=0,f=s.length;l<f;l++)o=s[l].trim(),o.length&&r.push(o);if("TEXTAREA"===e.nodeName){var m=elCreate("input");m.type="text",e.parentNode.insertBefore(m,e),m.id=e.id,elRemove(e),e=m}}return{element:e,list:i,shadow:a,values:r}},_handleLimit:function(e){var t=s.get(e);-1!==t.options.maxItems&&(t.list.childElementCount-1<t.options.maxItems?t.element.disabled&&(t.element.disabled=!1,t.element.removeAttribute("placeholder")):t.element.disabled||(t.element.disabled=!0,elAttr(t.element,"placeholder",i.get("wcf.global.form.input.maxItems"))))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;o=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(a.Enter(e)||a.Comma(e)){e.preventDefault();var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain"),t.split(/,/).forEach(function(t){t=t.trim(),0!==t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t,i){var n=s.get(e),a=elCreate("li");a.className="item";var r=elCreate("span");if(r.className="content",elData(r,"object-id",t.objectId),r.textContent=t.value,a.appendChild(r),i||!n.element.disabled){var o=elCreate("a");o.className="icon icon16 fa-times",o.addEventListener(WCF_CLICK_EVENT,f),a.appendChild(o)}n.list.insertBefore(a,n.listItem),n.element.value="",n.element.disabled||this._handleLimit(e);var l=this._syncShadow(n);"function"==typeof n.options.callbackChange&&(null===l&&(l=this.getValues(e)),n.options.callbackChange(e,l))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,a=elData(n,"element-id"),r=s.get(a);n.removeChild(t),i||r.element.focus(),this._handleLimit(a);var o=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===o&&(o=this.getValues(a)),r.options.callbackChange(a,o))},_syncShadow:function(e){if(!e.options.isCSV)return null;for(var t="",i=this.getValues(e.element.id),n=0,a=i.length;n<a;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=(s.get(e.currentTarget.id),e.currentTarget);window.setTimeout(function(){var e=t.value.trim();e.length&&this._addItem(t.id,{objectId:0,value:e})}.bind(this),100)}}}),define("WoltLabSuite/Core/Ui/ItemList/User",["WoltLabSuite/Core/Ui/ItemList"],function(e){"use strict";return{init:function(t,i){e.init(t,[],{ajax:{className:"wcf\\data\\user\\UserAction",parameters:{data:{includeUserGroups:~~i.includeUserGroups,restrictUserGroupIDs:Array.isArray(i.restrictUserGroupIDs)?i.restrictUserGroupIDs:[]}}},callbackChange:"function"==typeof i.callbackChange?i.callbackChange:null,callbackSyncShadow:i.csvPerType?this._syncShadow.bind(this):null,callbackSetupValues:"function"==typeof i.callbackSetupValues?i.callbackSetupValues:null,excludedSearchValues:Array.isArray(i.excludedSearchValues)?i.excludedSearchValues:[],isCSV:!0,maxItems:~~i.maxItems||-1,restricted:!0})},getValues:function(t){return e.getValues(t)},_syncShadow:function(e){var t=this.getValues(e.element.id),i=[],n=[];return t.forEach(function(e){e.type&&"group"===e.type?n.push(e.objectId):i.push(e.value)}),e.shadow.value=i.join(","),e._shadowGroups||(e._shadowGroups=elCreate("input"),e._shadowGroups.type="hidden",e._shadowGroups.name=e.shadow.name+"GroupIDs",e.shadow.parentNode.insertBefore(e._shadowGroups,e.shadow)),e._shadowGroups.value=n.join(","),t}}}),define("WoltLabSuite/Core/Ui/User/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination"],function(e,t,i,n,a,r){"use strict";function o(e){this.init(e)}return o.prototype={init:function(e){this._cache=new i,this._pageCount=0,this._pageNo=1,this._options=t.extend({className:"",dialogTitle:"",parameters:{}},e)},open:function(){this._pageNo=1,this._showPage()},_showPage:function(t){if("number"==typeof t&&(this._pageNo=~~t),0!==this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount))throw new RangeError("pageNo must be between 1 and "+this._pageCount+" ("+this._pageNo+" given).");if(this._cache.has(this._pageNo)){var i=a.open(this,this._cache.get(this._pageNo));if(this._pageCount>1){var n=elBySel(".jsPagination",i.content);null!==n&&new r(n,{activePage:this._pageNo,maxPage:this._pageCount,callbackSwitch:this._showPage.bind(this)});var o=i.content.parentNode;o.scrollTop>0&&(o.scrollTop=0)}}else this._options.parameters.pageNo=this._pageNo,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&(this._pageCount=~~e.returnValues.pageCount),this._cache.set(this._pageNo,e.returnValues.template),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserList",className:this._options.className,interfaceName:"wcf\\data\\IGroupedUserListAction"}}},_dialogSetup:function(){return{id:n.getUniqueId(),options:{title:this._options.dialogTitle},source:null}}},o}),define("WoltLabSuite/Core/Ui/Reaction/CountButtons",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","EventHandler"],function(e,t,i,n,a,r,o,s,l,c){"use strict";function d(e,t){this.init(e,t)}return d.prototype={init:function(e,n){if(""===n.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objects=new i,this._objectType=e,this._options=t.extend({summaryListSelector:".reactionSummaryList",containerSelector:"",isSingleItem:!1,parameters:{data:{}}},n),this.initContainers(n,e),o.add("WoltLabSuite/Core/Ui/Reaction/CountButtons-"+e,this.initContainers.bind(this))},initContainers:function(){for(var e,t,i,n=elBySelAll(this._options.containerSelector),a=!1,r=0,l=n.length;r<l;r++)if(e=n[r],!this._containers.has(s.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,summary:null,objectId:i,element:e},this._containers.set(s.identify(e),t),this._initReactionCountButtons(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),a=!0}a&&o.trigger()},updateCountButtons:function(e,t){var i=!1;this._objects.get(e).forEach(function(e){var n=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e.element);if(null!==n){for(var a={},o=elBySelAll(".reactCountButton",n),s=0,l=o.length;s<l;s++){var c=elData(o[s],"reaction-type-id");t.hasOwnProperty(c)?a[c]=o[s]:elRemove(o[s])}Object.keys(t).forEach(function(e){if(void 0!==a[e]){elBySel(".reactionCount",a[e]).innerHTML=r.shortUnit(t[e])}else if(void 0!==REACTION_TYPES[e]){var o=elCreate("span");o.className="reactCountButton",o.innerHTML=REACTION_TYPES[e].renderedIcon,elData(o,"reaction-type-id",e);var s=elCreate("span");s.className="reactionCount",s.innerHTML=r.shortUnit(t[e]),o.appendChild(s),n.appendChild(o),i=!0}},this),window[n.childElementCount>0?"elShow":"elHide"](n)}}.bind(this)),i&&o.trigger()},_initReactionCountButtons:function(e,t){var i=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e);null!==i&&i.addEventListener(WCF_CLICK_EVENT,this._showReactionOverlay.bind(this,t.objectId))},_showReactionOverlay:function(e,t){t.preventDefault(),this._currentObjectId=e,this._showOverlay()},_showOverlay:function(){this._options.parameters.data.containerID=this._objectType+"-"+this._currentObjectId,this._options.parameters.data.objectID=this._currentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){c.fire("com.woltlab.wcf.ReactionCountButtons","openDialog",e),l.open(this,e.returnValues.template),l.setTitle("userReactionOverlay-"+this._objectType,e.returnValues.title)},_ajaxSetup:function(){return{data:{actionName:"getReactionDetails",className:"\\wcf\\data\\reaction\\ReactionAction"}}},_dialogSetup:function(){return{id:"userReactionOverlay-"+this._objectType,options:{title:""},source:null}}},d}),define("WoltLabSuite/Core/Ui/Reaction/Handler",["Ajax","Core","Dictionary","Dom/ChangeListener","Dom/Util","Ui/Alignment","Ui/CloseOverlay","Ui/Screen","WoltLabSuite/Core/Ui/Reaction/CountButtons"],function(e,t,i,n,a,r,o,s,l){"use strict";function c(e,t){this.init(e,t)}return c.prototype={init:function(e,a){if(""===a.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objectType=e,this._cache=new i,this._objects=new i,this._popoverCurrentObjectId=0,this._popover=null,this._popoverContent=null,this._options=t.extend({buttonSelector:".reactButton",containerSelector:"",isButtonGroupNavigation:!1,isSingleItem:!1,parameters:{data:{}}},a),this.initReactButtons(a,e),this.countButtons=new l(this._objectType,this._options),n.add("WoltLabSuite/Core/Ui/Reaction/Handler-"+e,this.initReactButtons.bind(this)),o.add("WoltLabSuite/Core/Ui/Reaction/Handler",this._closePopover.bind(this))},initReactButtons:function(){for(var e,t,i,r=elBySelAll(this._options.containerSelector),o=!1,s=0,l=r.length;s<l;s++)if(e=r[s],!this._containers.has(a.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,objectId:i,element:e},this._containers.set(a.identify(e),t),this._initReactButton(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),o=!0}o&&n.trigger()},_initReactButton:function(e,t){if(this._options.isSingleItem?t.reactButton=elBySel(this._options.buttonSelector):t.reactButton=elBySel(this._options.buttonSelector,e),null!==t.reactButton&&0!==t.reactButton.length){if(1===Object.keys(REACTION_TYPES).length){var i=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];t.reactButton.title=i.title;elBySel(".invisible",t.reactButton).innerText=i.title}t.reactButton.addEventListener(WCF_CLICK_EVENT,this._toggleReactPopover.bind(this,t.objectId,t.reactButton))}},_updateReactButton:function(e,t){this._objects.get(e).forEach(function(e){null!==e.reactButton&&(t?(e.reactButton.classList.add("active"),elData(e.reactButton,"reaction-type-id",t)):(elData(e.reactButton,"reaction-type-id",0),e.reactButton.classList.remove("active")))})},_markReactionAsActive:function(){var e=null;if(this._objects.get(this._popoverCurrentObjectId).forEach(function(t){null!==t.reactButton&&(e=~~elData(t.reactButton,"reaction-type-id"))}),null===e)throw new Error("Unable to find react button for current popover.");elBySelAll(".reactionTypeButton.active",this._getPopover(),function(e){e.classList.remove("active")});var t=elBySel(".reactionPopoverContent",this._getPopover());if(e){var i=elBySel('.reactionTypeButton[data-reaction-type-id="'+e+'"]',this._getPopover());i.classList.add("active"),0==~~elData(i,"is-assignable")&&elShow(i),this._scrollReactionIntoView(t,i)}else s.is("screen-xs")&&(this._getPopover().classList.contains("inverseOrder")?t.scrollTop=0:t.scrollTop=t.scrollHeight-t.clientHeight)},_scrollReactionIntoView:function(e,t){t.offsetTop<.75*e.clientHeight?e.scrollTop=0:e.scrollTop=t.offsetTop+t.clientHeight/2-e.clientHeight/2},_toggleReactPopover:function(e,t,i){if(null!==i&&(i.preventDefault(),i.stopPropagation()),1===Object.keys(REACTION_TYPES).length){var n=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];this._popoverCurrentObjectId=e,this._react(n.reactionTypeID)}else 0===this._popoverCurrentObjectId||this._popoverCurrentObjectId!==e?this._openReactPopover(e,t):this._closePopover(e,t)},_openReactPopover:function(e,t){0!==this._popoverCurrentObjectId&&this._closePopover(),this._popoverCurrentObjectId=e,r.set(this._getPopover(),t,{pointer:!0,horizontal:this._options.isButtonGroupNavigation?"left":"center",vertical:s.is("screen-xs")?"bottom":"top"}),this._options.isButtonGroupNavigation&&t.closest("nav").style.setProperty("opacity","1","");var i=this._getPopover(),n="auto"===i.style.getPropertyValue("bottom");i.classList[n?"add":"remove"]("inverseOrder"),this._markReactionAsActive(),this._rebuildOverflowIndicator(),i.classList.remove("forceHide"),i.classList.add("active")},_getPopover:function(){if(null==this._popover){this._popover=elCreate("div"),this._popover.className="reactionPopover forceHide",this._popoverContent=elCreate("div"),this._popoverContent.className="reactionPopoverContent";var e=elCreate("ul");e.className="reactionTypeButtonList";var t=this._getSortedReactionTypes();for(var i in t)if(t.hasOwnProperty(i)){var a=t[i],r=elCreate("li");r.className="reactionTypeButton jsTooltip",elData(r,"reaction-type-id",a.reactionTypeID),elData(r,"title",a.title),elData(r,"is-assignable",~~a.isAssignable),r.title=a.title;var o=elCreate("span");o.className="reactionTypeButtonTitle",o.innerHTML=a.title,r.innerHTML=a.renderedIcon,r.appendChild(o),r.addEventListener(WCF_CLICK_EVENT,this._react.bind(this,a.reactionTypeID)),a.isAssignable||elHide(r),e.appendChild(r)}this._popoverContent.appendChild(e),this._popoverContent.addEventListener("scroll",this._rebuildOverflowIndicator.bind(this),{passive:!0}),this._popover.appendChild(this._popoverContent);var s=elCreate("span");s.className="elementPointer",s.appendChild(elCreate("span")),this._popover.appendChild(s),document.body.appendChild(this._popover),n.trigger()}return this._popover},_rebuildOverflowIndicator:function(){var e=this._popoverContent.scrollTop>0;this._popoverContent.classList[e?"add":"remove"]("overflowTop");var t=this._popoverContent.scrollTop+this._popoverContent.clientHeight<this._popoverContent.scrollHeight;this._popoverContent.classList[t?"add":"remove"]("overflowBottom")},_getSortedReactionTypes:function(){var e=[];for(var t in REACTION_TYPES)REACTION_TYPES.hasOwnProperty(t)&&e.push(REACTION_TYPES[t]);return e.sort(function(e,t){return e.showOrder-t.showOrder}),e},_closePopover:function(){0!==this._popoverCurrentObjectId&&(this._getPopover().classList.remove("active"),elBySelAll('.reactionTypeButton[data-is-assignable="0"]',this._getPopover(),elHide),this._options.isButtonGroupNavigation&&this._objects.get(this._popoverCurrentObjectId).forEach(function(e){e.reactButton.closest("nav").style.cssText=""}),this._popoverCurrentObjectId=0)},_react:function(t){0!=~~this._popoverCurrentObjectId&&(this._options.parameters.reactionTypeID=t,this._options.parameters.data.objectID=this._popoverCurrentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters}),this._closePopover())},_ajaxSuccess:function(e){this.countButtons.updateCountButtons(e.returnValues.objectID,e.returnValues.reactions),this._updateReactButton(e.returnValues.objectID,e.returnValues.reactionTypeID)},_ajaxSetup:function(){return{data:{actionName:"react",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},c}),define("WoltLabSuite/Core/Ui/Like/Handler",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/User/List","User","WoltLabSuite/Core/Ui/Reaction/Handler"],function(e,t,i,n,a,r,o,s,l,c,d,u){"use strict";function h(e,t){this.init(e,t)}return h.prototype={init:function(e,i){if(""===i.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Like/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new a,this._details=new a,this._objectType=e,this._options=t.extend({badgeClassNames:"",isSingleItem:!1,markListItemAsActive:!1,renderAsButton:!0,summaryPrepend:!0,summaryUseIcon:!0,canDislike:!1,canLike:!1,canLikeOwnContent:!1,canViewSummary:!1,badgeContainerSelector:".messageHeader .messageStatus",buttonAppendToSelector:".messageFooter .messageFooterButtons",buttonBeforeSelector:"",containerSelector:"",summarySelector:".messageFooterGroup"},i),this.initContainers(i,e),o.add("WoltLabSuite/Core/Ui/Like/Handler-"+e,this.initContainers.bind(this)),new u(this._objectType,{containerSelector:this._options.containerSelector,summaryListSelector:".reactionSummaryList"})},initContainers:function(){for(var e,t,i=elBySelAll(this._options.containerSelector),n=!1,a=0,r=i.length;a<r;a++)e=i[a],this._containers.has(e)||(t={badge:null,dislikeButton:null,likeButton:null,summary:null,dislikes:~~elData(e,"like-dislikes"),liked:~~elData(e,"like-liked"),likes:~~elData(e,"like-likes"),objectId:~~elData(e,"object-id"),users:JSON.parse(elData(e,"like-users"))},this._containers.set(e,t),this._buildWidget(e,t),n=!0);n&&o.trigger()},_buildWidget:function(e,t){var i,n,a,o=!0;if(a=this._options.isSingleItem?elBySel(this._options.summarySelector):elBySel(this._options.summarySelector,e),null===a&&(a=this._options.isSingleItem?elBySel(this._options.badgeContainerSelector):elBySel(this._options.badgeContainerSelector,e),o=!1),null!==a){i=elCreate("ul"),i.classList.add("reactionSummaryList"),o?i.classList.add("likesSummary"):i.classList.add("reactionSummaryListTiny");for(var l in t.users)if("reactionTypeID"!==l&&REACTION_TYPES.hasOwnProperty(l)){var c=elCreate("li");c.className="reactCountButton",elData(c,"reaction-type-id",l);var u=elCreate("span");u.className="reactionCount",u.innerHTML=r.shortUnit(t.users[l]),c.appendChild(u),c.innerHTML=REACTION_TYPES[l].renderedIcon+c.innerHTML,i.appendChild(c)}o?this._options.summaryPrepend?s.prepend(i,a):a.appendChild(i):"OL"===a.nodeName||"UL"===a.nodeName?(n=elCreate("li"),n.appendChild(i),a.appendChild(n)):a.appendChild(i),t.badge=i}if(this._options.canLike&&(d.userId!=elData(e,"user-id")||this._options.canLikeOwnContent)){var h=this._options.buttonAppendToSelector?this._options.isSingleItem?elBySel(this._options.buttonAppendToSelector):elBySel(this._options.buttonAppendToSelector,e):null,f=this._options.buttonBeforeSelector?this._options.isSingleItem?elBySel(this._options.buttonBeforeSelector):elBySel(this._options.buttonBeforeSelector,e):null;if(null===f&&null===h)throw new Error("Unable to find insert location for like/dislike buttons.");t.likeButton=this._createButton(e,t.users.reactionTypeID,f,h)}},_createButton:function(e,t,i,a){var r=n.get("wcf.reactions.react"),o=elCreate("li");o.className="wcfReactButton";var s=elCreate("a");s.className="jsTooltip reactButton",this._options.renderAsButton&&s.classList.add("button"),s.href="#",s.title=r;var l=elCreate("span");l.className="icon icon16 fa-smile-o",void 0===t||0==t?elData(l,"reaction-type-id",0):(elData(s,"reaction-type-id",t),s.classList.add("active")),s.appendChild(l);var c=elCreate("span");return c.className="invisible",c.innerHTML=r,s.appendChild(document.createTextNode(" ")),s.appendChild(c),o.appendChild(s),i?i.parentNode.insertBefore(o,i):a.appendChild(o),s}},h}),define("WoltLabSuite/Core/Ui/Message/InlineEditor",["Ajax","Core","Dictionary","Environment","EventHandler","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function f(e){this.init(e)}return f.prototype={init:function(e){this._activeDropdownElement=null,this._activeElement=null,this._dropdownMenu=null,this._elements=new o,this._options=t.extend({canEditInline:!1,className:"",containerId:0,dropdownIdentifier:"",editorPrefix:"messageEditor",messageSelector:".jsMessage",quoteManager:null},e),this.rebuild(),s.add("Ui/Message/InlineEdit_"+this._options.className,this.rebuild.bind(this))},rebuild:function(){for(var e,t,i,n=elBySelAll(this._options.messageSelector),a=0,r=n.length;a<r;a++)if(i=n[a],!this._elements.has(i)){e=elBySel(".jsMessageEditButton",i),null!==e&&(t=elDataBool(i,"can-edit"),this._options.canEditInline||elDataBool(i,"can-edit-inline")?(e.addEventListener(WCF_CLICK_EVENT,this._clickDropdown.bind(this,i)),e.classList.add("jsDropdownEnabled"),t&&e.addEventListener("dblclick",this._click.bind(this,i))):t&&e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,i)));var o=elBySel(".messageBody",i),s=elBySel(".messageFooter",i),l=elBySel(".messageHeader",i);this._elements.set(i,{button:e,messageBody:o,messageBodyEditor:null,messageFooter:s,messageFooterButtons:elBySel(".messageFooterButtons",s),messageHeader:l,messageText:elBySel(".messageText",o)})}},_click:function(t,i){null===t&&(t=this._activeDropdownElement),i&&i.preventDefault(),null===this._activeElement?(this._activeElement=t,this._prepare(),e.api(this,{actionName:"beginEdit",parameters:{containerID:this._options.containerId,objectID:this._getObjectId(t)}})):d.show("wcf.message.error.editorAlreadyInUse",null,"warning")},_clickDropdown:function(e,i){i.preventDefault();var n=i.currentTarget;if(!n.classList.contains("dropdownToggle")){if(n.classList.add("dropdownToggle"),n.parentNode.classList.add("dropdown"),function(e,t){e.addEventListener(WCF_CLICK_EVENT,function(i){i.preventDefault(),i.stopPropagation(),this._activeDropdownElement=t,u.toggleDropdown(this._options.dropdownIdentifier,e)}.bind(this))}.bind(this)(n,e),null===this._dropdownMenu){this._dropdownMenu=elCreate("ul"),this._dropdownMenu.className="dropdownMenu";var r=this._dropdownGetItems();a.fire("com.woltlab.wcf.inlineEditor","dropdownInit_"+this._options.dropdownIdentifier,{items:r}),this._dropdownBuild(r),u.init(this._options.dropdownIdentifier,this._dropdownMenu),u.registerCallback(this._options.dropdownIdentifier,this._dropdownToggle.bind(this))}setTimeout(function(){t.triggerEvent(n,WCF_CLICK_EVENT)},10)}},_dropdownBuild:function(e){for(var t,i,n,a=this._clickDropdownItem.bind(this),o=0,s=e.length;o<s;o++)t=e[o],n=elCreate("li"),elData(n,"item",t.item),"divider"===t.item?n.className="dropdownDivider":(i=elCreate("span"),i.textContent=r.get(t.label),n.appendChild(i),"editItem"===t.item?n.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,null)):n.addEventListener(WCF_CLICK_EVENT,a)),this._dropdownMenu.appendChild(n)},_dropdownToggle:function(e,t){var i=this._elements.get(this._activeDropdownElement);if(i.button.parentNode.classList["open"===t?"add":"remove"]("dropdownOpen"),i.messageFooterButtons.classList["open"===t?"add":"remove"]("forceVisible"),"open"===t){var n=this._dropdownOpen();a.fire("com.woltlab.wcf.inlineEditor","dropdownOpen_"+this._options.dropdownIdentifier,{element:this._activeDropdownElement,visibility:n});for(var r,o,s=!1,l=0;l<this._dropdownMenu.childElementCount;l++)o=this._dropdownMenu.children[l],r=elData(o,"item"),"divider"===r?s?(elShow(o),s=!1):elHide(o):objOwns(n,r)&&!1===n[r]?(elHide(o),l>0&&l+1===this._dropdownMenu.childElementCount&&"divider"===elData(o.previousElementSibling,"item")&&elHide(o.previousElementSibling)):(elShow(o),s=!0)}},_dropdownGetItems:function(){},_dropdownOpen:function(){},_dropdownSelect:function(e){},_clickDropdownItem:function(e){e.preventDefault();var t=elData(e.currentTarget,"item"),i={cancel:!1,element:this._activeDropdownElement,item:t};a.fire("com.woltlab.wcf.inlineEditor","dropdownItemClick_"+this._options.dropdownIdentifier,i),!0===i.cancel?e.preventDefault():this._dropdownSelect(t)},_prepare:function(){var e=this._elements.get(this._activeElement),t=elCreate("div");t.className="messageBody editor",e.messageBodyEditor=t;var i=elCreate("span");i.className="icon icon48 fa-spinner",t.appendChild(i),c.insertAfter(t,e.messageBody),elHide(e.messageBody)},_showEditor:function(e){var t=this._getEditorId(),i=this._elements.get(this._activeElement);this._activeElement.classList.add("jsInvalidQuoteTarget");var r=l.childByClass(i.messageBodyEditor,"icon");elRemove(r);var o=i.messageBodyEditor,s=elCreate("div");s.className="editorContainer",c.setInnerHtml(s,e.returnValues.template),o.appendChild(s);var d=elBySel(".formSubmit",s);elBySel('button[data-type="save"]',d).addEventListener(WCF_CLICK_EVENT,this._save.bind(this)),elBySel('button[data-type="cancel"]',d).addEventListener(WCF_CLICK_EVENT,this._restoreMessage.bind(this)),a.add("com.woltlab.wcf.redactor","submitEditor_"+t,function(e){e.cancel=!0,this._save()}.bind(this)),elHide(i.messageHeader),elHide(i.messageFooter);var u=elById(t);"redactor"===n.editor()?window.setTimeout(function(){this._options.quoteManager&&this._options.quoteManager.setAlternativeEditor(t),h.element(this._activeElement)}.bind(this),250):u.focus()},_restoreMessage:function(){var e=this._elements.get(this._activeElement);this._destroyEditor(),elRemove(e.messageBodyEditor),e.messageBodyEditor=null,elShow(e.messageBody),elShow(e.messageFooter),elShow(e.messageHeader),this._activeElement.classList.remove("jsInvalidQuoteTarget"),this._activeElement=null,this._options.quoteManager&&this._options.quoteManager.clearAlternativeEditor()},_save:function(){var t={containerID:this._options.containerId,data:{message:""},objectID:this._getObjectId(this._activeElement),removeQuoteIDs:this._options.quoteManager?this._options.quoteManager.getQuotesMarkedForRemoval():[]},i=this._getEditorId(),n=elById("settings_"+i);n&&elBySelAll("input, select, textarea",n,function(e){if("INPUT"!==e.nodeName||"checkbox"!==e.type&&"radio"!==e.type||e.checked){var i=e.name;if(t.hasOwnProperty(i))throw new Error("Variable overshadowing, key '"+i+"' is already present.");t[i]=e.value.trim()}}),a.fire("com.woltlab.wcf.redactor2","getText_"+i,t.data);var r=this._validate(t);r instanceof Promise||(r=!1===r?Promise.reject():Promise.resolve()),r.then(function(){a.fire("com.woltlab.wcf.redactor2","submit_"+i,t),e.api(this,{actionName:"save",parameters:t}),this._hideEditor()}.bind(this),function(e){console.log("Validation of post edit failed: "+e)})},_validate:function(e){elBySelAll(".innerError",this._activeElement,elRemove);var t={api:this,parameters:e,valid:!0,promises:[]};return a.fire("com.woltlab.wcf.redactor2","validate_"+this._getEditorId(),t),t.promises.push(Promise[t.valid?"resolve":"reject"]()),Promise.all(t.promises)},throwError:function(e,t){elInnerError(e,t)},_showMessage:function(e){var t=this._activeElement,i=this._getEditorId(),n=this._elements.get(t),r=elBySelAll(".attachmentThumbnailList, .attachmentFileList",n.messageFooter);if(c.setInnerHtml(l.childByClass(n.messageBody,"messageText"),e.returnValues.message),"string"==typeof e.returnValues.attachmentList){for(var o=0,s=r.length;o<s;o++)elRemove(r[o]);var u=elCreate("div");c.setInnerHtml(u,e.returnValues.attachmentList);for(var h;u.childNodes.length;)h=u.childNodes[u.childNodes.length-1],n.messageFooter.insertBefore(h,n.messageFooter.firstChild)}if("string"==typeof e.returnValues.poll){var f=elBySel(".pollContainer",n.messageBody);null!==f&&elRemove(f.parentNode);var p=elCreate("div");p.className="jsInlineEditorHideContent",c.setInnerHtml(p,e.returnValues.poll),c.prepend(p,n.messageBody)}this._restoreMessage(),this._updateHistory(this._getHash(this._getObjectId(t))),a.fire("com.woltlab.wcf.redactor","autosaveDestroy_"+i),d.show(),this._options.quoteManager&&(this._options.quoteManager.clearAlternativeEditor(),this._options.quoteManager.countQuotes())},_hideEditor:function(){var e=this._elements.get(this._activeElement);elHide(l.childByClass(e.messageBodyEditor,"editorContainer"));var t=elCreate("span");t.className="icon icon48 fa-spinner",e.messageBodyEditor.appendChild(t)},_restoreEditor:function(){var e=this._elements.get(this._activeElement),t=elBySel(".fa-spinner",e.messageBodyEditor);elRemove(t);var i=l.childByClass(e.messageBodyEditor,"editorContainer");null!==i&&elShow(i)},_destroyEditor:function(){a.fire("com.woltlab.wcf.redactor2","autosaveDestroy_"+this._getEditorId()),a.fire("com.woltlab.wcf.redactor2","destroy_"+this._getEditorId())},_getHash:function(e){return"#message"+e},_updateHistory:function(e){window.location.hash=e},_getEditorId:function(){return this._options.editorPrefix+this._getObjectId(this._activeElement)},_getObjectId:function(e){return~~elData(e,"object-id")},_ajaxFailure:function(e){var t=this._elements.get(this._activeElement),i=elBySel(".redactor-layer",t.messageBodyEditor);return null===i?(this._restoreMessage(),!0):(this._restoreEditor(),!e||void 0===e.returnValues||void 0===e.returnValues.realErrorMessage||(elInnerError(i,e.returnValues.realErrorMessage),!1))},_ajaxSuccess:function(e){switch(e.actionName){case"beginEdit":this._showEditor(e);break;case"save":this._showMessage(e)}},_ajaxSetup:function(){return{data:{className:this._options.className,interfaceName:"wcf\\data\\IMessageInlineEditorAction"},silent:!0}},legacyEdit:function(e){this._click(elById(e),null)}},f}),define("WoltLabSuite/Core/Ui/Message/Manager",["Ajax","Core","Dictionary","Language","Dom/ChangeListener","Dom/Util"],function(e,t,i,n,a,r){
+"use strict";function o(e){this.init(e)}return o.prototype={init:function(e){this._elements=null,this._options=t.extend({className:"",selector:""},e),this.rebuild(),a.add("Ui/Message/Manager"+this._options.className,this.rebuild.bind(this))},rebuild:function(){this._elements=new i;for(var e,t=elBySelAll(this._options.selector),n=0,a=t.length;n<a;n++)e=t[n],this._elements.set(elData(e,"object-id"),e)},getPermission:function(e,t){t="can-"+this._getAttributeName(t);var i=this._elements.get(e);if(void 0===i)throw new Error("Unknown object id '"+e+"' for selector '"+this._options.selector+"'");return elDataBool(i,t)},getPropertyValue:function(e,t,i){var n=this._elements.get(e);if(void 0===n)throw new Error("Unknown object id '"+e+"' for selector '"+this._options.selector+"'");return window[i?"elDataBool":"elData"](n,this._getAttributeName(t))},update:function(t,i,n){e.api(this,{actionName:i,parameters:n||{},objectIDs:[t]})},updateItems:function(e,t){Array.isArray(e)||(e=[e]);for(var i,n=0,a=e.length;n<a;n++)if(void 0!==(i=this._elements.get(e[n])))for(var r in t)t.hasOwnProperty(r)&&this._update(i,r,t[r])},updateAllItems:function(e){var t=[];this._elements.forEach(function(e,i){t.push(i)}.bind(this)),this.updateItems(t,e)},setNote:function(e,t,i){var n=this._elements.get(e);if(void 0===n)throw new Error("Unknown object id '"+e+"' for selector '"+this._options.selector+"'");var a=elBySel(".messageFooterNotes",n),r=elBySel("."+t,a);i?(null===r&&(r=elCreate("p"),r.className="messageFooterNote "+t,a.appendChild(r)),r.innerHTML=i):null!==r&&elRemove(r)},_update:function(e,t,i){elData(e,this._getAttributeName(t),i);var n=1==i||!0===i||"true"===i;this._updateState(e,t,i,n)},_updateState:function(e,t,i,n){switch(t){case"isDeleted":e.classList[n?"add":"remove"]("messageDeleted"),this._toggleMessageStatus(e,"jsIconDeleted","wcf.message.status.deleted","red",n);break;case"isDisabled":e.classList[n?"add":"remove"]("messageDisabled"),this._toggleMessageStatus(e,"jsIconDisabled","wcf.message.status.disabled","green",n)}},_toggleMessageStatus:function(e,t,i,a,o){var s=elBySel(".messageStatus",e);if(null===s){var l=elBySel(".messageHeaderMetaData",e);if(null===l)return;s=elCreate("ul"),s.className="messageStatus",r.insertAfter(s,l)}var c=elBySel("."+t,s);if(o){if(null!==c)return;c=elCreate("span"),c.className="badge label "+a+" "+t,c.textContent=n.get(i);var d=elCreate("li");d.appendChild(c),s.appendChild(d)}else{if(null===c)return;elRemove(c.parentNode)}},_getAttributeName:function(e){if(-1!==e.indexOf("-"))return e;for(var t,i="",n=e.split(/([A-Z][a-z]+)/),a=0,r=n.length;a<r;a++)t=n[a],t.length&&(i.length&&(i+="-"),i+=t.toLowerCase());return i},_ajaxSuccess:function(){throw new Error("Method _ajaxSuccess() must be implemented by deriving functions.")},_ajaxSetup:function(){return{data:{className:this._options.className}}}},o}),define("WoltLabSuite/Core/Ui/Message/Reply",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,a,r,o,s,l,c,d,u,h){"use strict";function f(e){this.init(e)}return f.prototype={init:function(e){this._options=t.extend({ajax:{className:""},quoteManager:null,successMessage:"wcf.global.success.add"},e),this._container=elById("messageQuickReply"),this._content=elBySel(".messageContent",this._container),this._textarea=elById("text"),this._editor=null,this._guestDialogId="",this._loadingOverlay=null,elBySel(".message",this._container).classList.add("jsInvalidQuoteTarget");var i=this._submit.bind(this);elBySel('button[data-type="save"]',this._container).addEventListener(WCF_CLICK_EVENT,i);for(var n=elBySelAll(".jsQuickReply"),a=0,r=n.length;a<r;a++)n[a].addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this._getEditor().WoltLabReply.showEditor(),c.element(this._container,function(){this._getEditor().WoltLabCaret.endOfEditor()}.bind(this))}.bind(this))},_submitGuestDialog:function(e){if("keypress"!==e.type||d.Enter(e)){var i=elBySel("input[name=username]",e.currentTarget.closest(".dialogContent"));if(""===i.value)return elInnerError(i,n.get("wcf.global.form.error.empty")),void i.closest("dl").classList.add("formError");var a={parameters:{data:{username:i.value}}},r=elData(e.currentTarget,"captcha-id");if(h.has(r)){var o=h.getData(r);o instanceof Promise?o.then(function(e){a=t.extend(a,e),this._submit(void 0,a)}.bind(this)):(a=t.extend(a,h.getData(r)),this._submit(void 0,a))}else this._submit(void 0,a)}},_submit:function(n,a){if(n&&n.preventDefault(),(!this._content.classList.contains("loading")||this._guestDialogId&&s.isOpen(this._guestDialogId))&&this._validate()){this._showLoadingOverlay();var o=r.getDataAttributes(this._container,"data-",!0,!0);o.data={message:this._getEditor().code.get()},o.removeQuoteIDs=this._options.quoteManager?this._options.quoteManager.getQuotesMarkedForRemoval():[];var l=elById("settings_text");l&&elBySelAll("input, select, textarea",l,function(e){if("INPUT"!==e.nodeName||"checkbox"!==e.type&&"radio"!==e.type||e.checked){var t=e.name;if(o.hasOwnProperty(t))throw new Error("Variable overshadowing, key '"+t+"' is already present.");o[t]=e.value.trim()}}),i.fire("com.woltlab.wcf.redactor2","submit_text",o.data),u.userId||a||(o.requireGuestDialog=!0),e.api(this,t.extend({parameters:o},a))}},_validate:function(){if(elBySelAll(".innerError",this._container,elRemove),this._getEditor().utils.isEmpty())return this.throwError(this._textarea,n.get("wcf.global.form.error.empty")),!1;var e={api:this,editor:this._getEditor(),message:this._getEditor().code.get(),valid:!0};return i.fire("com.woltlab.wcf.redactor2","validate_text",e),!1!==e.valid},throwError:function(e,t){elInnerError(e,"empty"===t?n.get("wcf.global.form.error.empty"):t)},_showLoadingOverlay:function(){null===this._loadingOverlay&&(this._loadingOverlay=elCreate("div"),this._loadingOverlay.className="messageContentLoadingOverlay",this._loadingOverlay.innerHTML='<span class="icon icon96 fa-spinner"></span>'),this._content.classList.add("loading"),this._content.appendChild(this._loadingOverlay)},_hideLoadingOverlay:function(){this._content.classList.remove("loading");var e=elBySel(".messageContentLoadingOverlay",this._content);null!==e&&e.parentNode.removeChild(e)},_reset:function(){this._getEditor().code.set("<p>​</p>"),i.fire("com.woltlab.wcf.redactor2","reset_text")},_handleError:function(e){var t={api:this,cancel:!1,returnValues:e.returnValues};i.fire("com.woltlab.wcf.redactor2","handleError_text",t),!0!==t.cancel&&this.throwError(this._textarea,e.returnValues.realErrorMessage)},_getEditor:function(){if(null===this._editor){if("function"!=typeof window.jQuery)throw new Error("Unable to access editor, jQuery has not been loaded yet.");this._editor=window.jQuery(this._textarea).data("redactor")}return this._editor},_insertMessage:function(e){if(this._getEditor().WoltLabAutosave.reset(),e.returnValues.url)window.location==e.returnValues.url&&window.location.reload(),window.location=e.returnValues.url;else{if(e.returnValues.template){var t;if("DESC"===elData(this._container,"sort-order"))r.insertHtml(e.returnValues.template,this._container,"after"),t=r.identify(this._container.nextElementSibling);else{var i=this._container;i.previousElementSibling&&i.previousElementSibling.classList.contains("messageListPagination")&&(i=i.previousElementSibling),r.insertHtml(e.returnValues.template,i,"before"),t=r.identify(i.previousElementSibling)}elData(this._container,"last-post-time",e.returnValues.lastPostTime),window.history.replaceState(void 0,"","#"+t),c.element(elById(t))}l.show(n.get(this._options.successMessage)),this._options.quoteManager&&this._options.quoteManager.countQuotes(),a.trigger()}},_ajaxSuccess:function(e){if(!u.userId&&!e.returnValues.guestDialogID)throw new Error("Missing 'guestDialogID' return value for guest.");if(!u.userId&&e.returnValues.guestDialog){s.openStatic(e.returnValues.guestDialogID,e.returnValues.guestDialog,{closable:!1,onClose:function(){h.has(e.returnValues.guestDialogID)&&h.delete(e.returnValues.guestDialogID)},title:n.get("wcf.global.confirmation.title")});var t=s.getDialog(e.returnValues.guestDialogID);elBySel("input[type=submit]",t.content).addEventListener(WCF_CLICK_EVENT,this._submitGuestDialog.bind(this)),elBySel("input[type=text]",t.content).addEventListener("keypress",this._submitGuestDialog.bind(this)),this._guestDialogId=e.returnValues.guestDialogID}else this._insertMessage(e),u.userId||s.close(e.returnValues.guestDialogID),this._reset(),this._hideLoadingOverlay()},_ajaxFailure:function(e){return this._hideLoadingOverlay(),null===e||void 0===e.returnValues||void 0===e.returnValues.realErrorMessage||(this._handleError(e),!1)},_ajaxSetup:function(){return{data:{actionName:"quickReply",className:this._options.ajax.className,interfaceName:"wcf\\data\\IMessageQuickReplyAction"},silent:!0}}},f}),define("WoltLabSuite/Core/Ui/Message/Share",["EventHandler","StringUtil"],function(e,t){"use strict";return{_pageDescription:"",_pageUrl:"",init:function(){var i=elBySel('meta[property="og:title"]');null!==i&&(this._pageDescription=encodeURIComponent(i.content));var n=elBySel('meta[property="og:url"]');null!==n&&(this._pageUrl=encodeURIComponent(n.content)),elBySelAll(".jsMessageShareButtons",null,function(i){i.classList.remove("jsMessageShareButtons");var n=encodeURIComponent(t.unescapeHTML(elData(i,"url")||""));n||(n=this._pageUrl);var a={facebook:{link:elBySel(".jsShareFacebook",i),share:function(e){e.preventDefault(),this._share("facebook","https://www.facebook.com/sharer.php?u={pageURL}&t={text}",!0,n)}.bind(this)},google:{link:elBySel(".jsShareGoogle",i),share:function(e){e.preventDefault(),this._share("google","https://plus.google.com/share?url={pageURL}",!1,n)}.bind(this)},reddit:{link:elBySel(".jsShareReddit",i),share:function(e){e.preventDefault(),this._share("reddit","https://ssl.reddit.com/submit?url={pageURL}",!1,n)}.bind(this)},twitter:{link:elBySel(".jsShareTwitter",i),share:function(e){e.preventDefault(),this._share("twitter","https://twitter.com/share?url={pageURL}&text={text}",!1,n)}.bind(this)},linkedIn:{link:elBySel(".jsShareLinkedIn",i),share:function(e){e.preventDefault(),this._share("linkedIn","https://www.linkedin.com/cws/share?url={pageURL}",!1,n)}.bind(this)},pinterest:{link:elBySel(".jsSharePinterest",i),share:function(e){e.preventDefault(),this._share("pinterest","https://www.pinterest.com/pin/create/link/?url={pageURL}&description={text}",!1,n)}.bind(this)},xing:{link:elBySel(".jsShareXing",i),share:function(e){e.preventDefault(),this._share("xing","https://www.xing.com/social_plugins/share?url={pageURL}",!1,n)}.bind(this)},whatsApp:{link:elBySel(".jsShareWhatsApp",i),share:function(e){e.preventDefault(),window.location.href="https://api.whatsapp.com/send?text="+this._pageDescription+"%20"+this._pageUrl}.bind(this)}};e.fire("com.woltlab.wcf.message.share","shareProvider",{container:i,providers:a,pageDescription:this._pageDescription,pageUrl:this._pageUrl});for(var r in a)a.hasOwnProperty(r)&&null!==a[r].link&&a[r].link.addEventListener(WCF_CLICK_EVENT,a[r].share)}.bind(this))},_share:function(e,t,i,n){n||(n=this._pageUrl),window.open(t.replace(/\{pageURL}/,n).replace(/\{text}/,this._pageDescription+(i?"%20"+n:"")),e,"height=600,width=600")}}}),define("WoltLabSuite/Core/Ui/Message/TwitterEmbed",["https://platform.twitter.com/widgets.js"],function(e){"use strict";var t=new Promise(function(e,t){twttr.ready(e)});return{embedTweet:function(e,i,n){return void 0===n&&(n=!1),t.then(function(){return twttr.widgets.createTweet(i,e,{dnt:!0,lang:document.documentElement.lang})}).then(function(t){if(t&&n){for(;e.lastChild;)e.removeChild(e.lastChild);e.appendChild(t)}return t})},embedAll:function(){elBySelAll("[data-wsc-twitter-tweet]",void 0,function(e){var t=elData(e,"wsc-twitter-tweet");t&&(this.embedTweet(e,t,!0),elData(e,"wsc-twitter-tweet",""))}.bind(this))}}}),define("WoltLabSuite/Core/Ui/Page/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,a,r){"use strict";var o,s,l,c=null;return{open:function(e){o=e,r.open(this)},_search:function(t){t.preventDefault();var n=c.parentNode,a=c.value.trim();if(a.length<3)return void elInnerError(n,i.get("wcf.page.search.error.tooShort"));elInnerError(n,!1),e.api(this,{parameters:{searchString:a}})},_click:function(e){e.preventDefault();var t=e.currentTarget,i=elBySel("h3",t).textContent.replace(/['"]/g,"");o(elData(t,"page-id")+"#"+i),r.close(this)},_ajaxSuccess:function(e){for(var t,a="",r=0,o=e.returnValues.length;r<o;r++)t=e.returnValues[r],a+='<li><div class="containerHeadline pointer" data-page-id="'+t.pageID+'"><h3>'+n.escapeHTML(t.name)+"</h3><small>"+n.escapeHTML(t.displayLink)+"</small></div></li>";l.innerHTML=a,window[a?"elShow":"elHide"](s),a?elBySelAll(".containerHeadline",l,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this)):elInnerError(c.parentNode,i.get("wcf.page.search.error.noResults"))},_ajaxSetup:function(){return{data:{actionName:"search",className:"wcf\\data\\page\\PageAction"}}},_dialogSetup:function(){return{id:"wcfUiPageSearch",options:{onSetup:function(){var e=this._search.bind(this);c=elById("wcfUiPageSearchInput"),c.addEventListener("keydown",function(i){t.Enter(i)&&e(i)}),c.nextElementSibling.addEventListener(WCF_CLICK_EVENT,e),s=elById("wcfUiPageSearchResultContainer"),l=elById("wcfUiPageSearchResultList")}.bind(this),onShow:function(){c.focus()},title:i.get("wcf.page.search")},source:'<div class="section"><dl><dt><label for="wcfUiPageSearchInput">'+i.get("wcf.page.search.name")+'</label></dt><dd><div class="inputAddon"><input type="text" id="wcfUiPageSearchInput" class="long"><a href="#" class="inputSuffix"><span class="icon icon16 fa-search"></span></a></div></dd></dl></div><section id="wcfUiPageSearchResultContainer" class="section" style="display: none;"><header class="sectionHeader"><h2 class="sectionTitle">'+i.get("wcf.page.search.results")+'</h2></header><ol id="wcfUiPageSearchResultList" class="containerList"></ol></section>'}}}}),define("WoltLabSuite/Core/Ui/Sortable/List",["Core","Ui/Screen"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={init:function(i){this._options=e.extend({containerId:"",className:"",offset:0,options:{},isSimpleSorting:!1,additionalParameters:{}},i),t.on("screen-sm-md",{match:this._enable.bind(this,!0),unmatch:this._disable.bind(this),setup:this._enable.bind(this,!0)}),t.on("screen-lg",{match:this._enable.bind(this,!1),unmatch:this._disable.bind(this),setup:this._enable.bind(this,!1)})},_enable:function(e){var t=this._options.options;e&&(t.handle=".sortableNodeHandle"),new window.WCF.Sortable.List(this._options.containerId,this._options.className,this._options.offset,t,this._options.isSimpleSorting,this._options.additionalParameters)},_disable:function(){window.jQuery("#"+this._options.containerId+" .sortableList")[this._options.isSimpleSorting?"sortable":"nestedSortable"]("destroy")}},i}),define("WoltLabSuite/Core/Ui/Poll/Editor",["Core","Dom/Util","EventHandler","EventKey","Language","WoltLabSuite/Core/Date/Picker","WoltLabSuite/Core/Ui/Sortable/List"],function(e,t,i,n,a,r,o){"use strict";function s(e,t,i,n){this.init(e,t,i,n)}return s.prototype={init:function(t,n,a,r){if(this._container=elById(t),null===this._container)throw new Error("Unknown poll editor container with id '"+t+"'.");if(this._wysiwygId=a,""!==a&&null===elById(a))throw new Error("Unknown wysiwyg field with id '"+a+"'.");this.questionField=elById(this._wysiwygId+"Poll_question");var s=elByClass("sortableList",this._container);if(0===s.length)throw new Error("Cannot find poll options list for container with id '"+t+"'.");if(this.optionList=s[0],this.endTimeField=elById(this._wysiwygId+"Poll_endTime"),this.maxVotesField=elById(this._wysiwygId+"Poll_maxVotes"),this.isChangeableYesField=elById(this._wysiwygId+"Poll_isChangeable"),this.isChangeableNoField=elById(this._wysiwygId+"Poll_isChangeable_no"),this.isPublicYesField=elById(this._wysiwygId+"Poll_isPublic"),this.isPublicNoField=elById(this._wysiwygId+"Poll_isPublic_no"),this.resultsRequireVoteYesField=elById(this._wysiwygId+"Poll_resultsRequireVote"),this.resultsRequireVoteNoField=elById(this._wysiwygId+"Poll_resultsRequireVote_no"),this.sortByVotesYesField=elById(this._wysiwygId+"Poll_sortByVotes"),this.sortByVotesNoField=elById(this._wysiwygId+"Poll_sortByVotes_no"),this._optionCount=0,this._options=e.extend({isAjax:!1,maxOptions:20},r),this._createOptionList(n||[]),new o({containerId:t,options:{toleranceElement:"> div"}}),this._options.isAjax)for(var l=["handleError","reset","submit","validate"],c=0,d=l.length;c<d;c++){var u=l[c];i.add("com.woltlab.wcf.redactor2",u+"_"+this._wysiwygId,this["_"+u].bind(this))}else{var h=this._container.closest("form");if(null===h)throw new Error("Cannot find form for container with id '"+t+"'.");h.addEventListener("submit",this._submit.bind(this))}},_addOption:function(e){if(e.preventDefault(),this._optionCount===this._options.maxOptions)return!1;this._createOption(void 0,void 0,e.currentTarget.closest("li"))},_createOption:function(e,i,n){e=e||"",i=~~i||0;var r=elCreate("LI");r.className="sortableNode",elData(r,"option-id",i),n?t.insertAfter(r,n):this.optionList.appendChild(r);var o=elCreate("div");o.className="pollOptionInput",r.appendChild(o);var s=elCreate("span");s.className="icon icon16 fa-arrows sortableNodeHandle",o.appendChild(s);var l=elCreate("a");elAttr(l,"role","button"),elAttr(l,"href","#"),l.className="icon icon16 fa-plus jsTooltip jsAddOption pointer",elAttr(l,"title",a.get("wcf.poll.button.addOption")),l.addEventListener("click",this._addOption.bind(this)),o.appendChild(l);var c=elCreate("a");elAttr(c,"role","button"),elAttr(c,"href","#"),c.className="icon icon16 fa-times jsTooltip jsDeleteOption pointer",elAttr(c,"title",a.get("wcf.poll.button.removeOption")),c.addEventListener("click",this._removeOption.bind(this)),o.appendChild(c);var d=elCreate("input");elAttr(d,"type","text"),d.value=e,elAttr(d,"maxlength",255),d.addEventListener("keydown",this._optionInputKeyDown.bind(this)),d.addEventListener("click",function(){document.activeElement!==this&&this.focus()}),o.appendChild(d),null!==n&&d.focus(),++this._optionCount===this._options.maxOptions&&elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.remove("pointer"),e.classList.add("disabled")})},_createOptionList:function(e){for(var t=0,i=e.length;t<i;t++){var n=e[t];this._createOption(n.optionValue,n.optionID)}this._optionCount<this._options.maxOptions&&this._createOption()},_handleError:function(e){switch(e.returnValues.fieldName){case this._wysiwygId+"Poll_endTime":case this._wysiwygId+"Poll_maxVotes":var i=e.returnValues.fieldName.replace(this._wysiwygId+"Poll_",""),n=elCreate("small");n.className="innerError",n.innerHTML=a.get("wcf.poll."+i+".error."+e.returnValues.errorType);var r=elById(e.returnValues.fieldName);r.closest("dd");t.prepend(n,r.nextSibling),e.cancel=!0}},_optionInputKeyDown:function(t){n.Enter(t)&&(e.triggerEvent(elByClass("jsAddOption",t.currentTarget.parentNode)[0],"click"),t.preventDefault())},_removeOption:function(e){e.preventDefault(),elRemove(e.currentTarget.closest("li")),this._optionCount--,elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.add("pointer"),e.classList.remove("disabled")}),0===this.optionList.length&&this._createOption()},_reset:function(){this.questionField.value="",this._optionCount=0,this.optionList.innerHtml="",this._createOption(),r.clear(this.endTimeField),this.maxVotesField.value=1,this.isChangeableYesField.checked=!1,this.isChangeableNoField.checked=!0,this.isPublicYesField.checked=!1,this.isPublicNoField.checked=!0,this.resultsRequireVoteYesField.checked=!1,this.resultsRequireVoteNoField.checked=!0,this.sortByVotesYesField.checked=!1,this.sortByVotesNoField.checked=!0,i.fire("com.woltlab.wcf.poll.editor","reset",{pollEditor:this})},_submit:function(e){if(this._options.isAjax)e.poll=this.getData(),i.fire("com.woltlab.wcf.poll.editor","submit",{event:e,pollEditor:this});else for(var t=this._container.closest("form"),n=this.getOptions(),a=0,r=n.length;a<r;a++){var o=elCreate("input");elAttr(o,"type","hidden"),elAttr(o,"name",this._wysiwygId+"Poll_options["+a+"]"),o.value=n[a],t.appendChild(o)}},_validate:function(e){if(""!==this.questionField.value.trim()){for(var t=0,n=0,r=this.optionList.children.length;n<r;n++){""!==elBySel("input[type=text]",this.optionList.children[n]).value.trim()&&t++}if(0===t)e.api.throwError(this._container,a.get("wcf.global.form.error.empty")),e.valid=!1;else{var o=~~this.maxVotesField.value;o&&o>t?(e.api.throwError(this.maxVotesField.parentNode,a.get("wcf.poll.maxVotes.error.invalid")),e.valid=!1):i.fire("com.woltlab.wcf.poll.editor","validate",{data:e,pollEditor:this})}}},getData:function(){var e={};return e[this.questionField.id]=this.questionField.value,e[this._wysiwygId+"Poll_options"]=this.getOptions(),e[this.endTimeField.id]=this.endTimeField.value,e[this.maxVotesField.id]=this.maxVotesField.value,e[this.isChangeableYesField.id]=!!this.isChangeableYesField.checked,e[this.isPublicYesField.id]=!!this.isPublicYesField.checked,e[this.resultsRequireVoteYesField.id]=!!this.resultsRequireVoteYesField.checked,e[this.sortByVotesYesField.id]=!!this.sortByVotesYesField.checked,e},getOptions:function(){for(var e=[],t=0,i=this.optionList.children.length;t<i;t++){var n=this.optionList.children[t],a=elBySel("input[type=text]",n).value.trim();""!==a&&e.push(elData(n,"option-id")+"_"+a)}return e}},s}),define("WoltLabSuite/Core/Ui/Redactor/Article",["WoltLabSuite/Core/Ui/Article/Search"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(e,t){this._editor=e,t.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))},_click:function(t){t.preventDefault(),e.open(this._insert.bind(this))},_insert:function(e){this._editor.buffer.set(),this._editor.insert.text("[wsa='"+e+"'][/wsa]")}},t}),define("WoltLabSuite/Core/Ui/Redactor/Metacode",["EventHandler","Dom/Util"],function(e,t){"use strict";return{convert:function(e){e.textContent=this.convertFromHtml(e.textContent)},convertFromHtml:function(i,n){var a=elCreate("div");a.innerHTML=n;for(var r,o,s,l,c,d,u=elByTag("woltlab-metacode",a);u.length;)s=u[0],l=elData(s,"name"),r=this._parseAttributes(elData(s,"attributes")),o={attributes:r,cancel:!1,metacode:s},e.fire("com.woltlab.wcf.redactor2","metacode_"+l+"_"+i,o),!0!==o.cancel&&(d=this._getOpeningTag(l,r),c=this._getClosingTag(l),s.parentNode===a?(t.prepend(d,this._getFirstParagraph(s)),this._getLastParagraph(s).appendChild(c)):(t.prepend(d,s),s.appendChild(c)),t.unwrapChildNodes(s));for(var h,f=elByTag("kbd",a);f.length;)h=f[0],h.insertBefore(document.createTextNode("[tt]"),h.firstChild),h.appendChild(document.createTextNode("[/tt]")),t.unwrapChildNodes(h);return a.innerHTML},_getOpeningTag:function(e,t){var i="["+e;if(t.length){i+="=";for(var n=0,a=t.length;n<a;n++)n>0&&(i+=","),i+="'"+t[n]+"'"}return document.createTextNode(i+"]")},_getClosingTag:function(e){return document.createTextNode("[/"+e+"]")},_getFirstParagraph:function(e){var t,i;return 0===e.childElementCount?(i=elCreate("p"),e.appendChild(i)):(t=e.children[0],"P"===t.nodeName?i=t:(i=elCreate("p"),e.insertBefore(i,t))),i},_getLastParagraph:function(e){var t,i,n=e.childElementCount;return 0===n?(i=elCreate("p"),e.appendChild(i)):(t=e.children[n-1],"P"===t.nodeName?i=t:(i=elCreate("p"),e.appendChild(i))),i},_parseAttributes:function(e){try{e=JSON.parse(atob(e))}catch(e){}if(!Array.isArray(e))return[];for(var t,i=[],n=0,a=e.length;n<a;n++)t=e[n],"string"==typeof t&&(t=t.replace(/^'(.*)'$/,"$1")),i.push(t);return i}}}),define("WoltLabSuite/Core/Ui/Redactor/Autosave",["Core","Devtools","EventHandler","Language","Dom/Traverse","./Metacode"],function(e,t,i,n,a,r){"use strict";function o(e){this.init(e)}return o.prototype={init:function(t){this._container=null,this._metaData={},this._editor=null,this._element=t,this._isActive=!0,this._isPending=!1,this._key=e.getStoragePrefix()+elData(this._element,"autosave"),this._lastMessage="",this._originalMessage="",this._overlay=null,this._restored=!1,this._timer=null,this._cleanup(),this._element.removeAttribute("data-autosave");var n=a.parentByTag(this._element,"FORM");null!==n&&n.addEventListener("submit",this.destroy.bind(this)),i.add("com.woltlab.wcf.redactor2","getMetaData_"+this._element.id,function(e){for(var t in this._metaData)this._metaData.hasOwnProperty(t)&&(e[t]=this._metaData[t])}.bind(this)),i.add("com.woltlab.wcf.redactor2","reset_"+this._element.id,this.hideOverlay.bind(this)),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this))},_onVisibilityChange:function(){document.hidden?(this._isActive=!1,this._isPending=!0):(this._isActive=!0,this._isPending=!1)},getInitialValue:function(){if(window.ENABLE_DEVELOPER_TOOLS&&!1===t._internal_.editorAutosave())return this._element.value;var e="";try{e=window.localStorage.getItem(this._key)}catch(e){window.console.warn("Unable to access local storage: "+e.message)}try{e=JSON.parse(e)}catch(t){e=""}if(null!==e&&"object"==typeof e&&e.content){if(1e3*~~elData(this._element,"autosave-last-edit-time")<=e.timestamp){var i=elCreate("div");i.innerHTML=this._element.value;var n=elCreate("div");if(n.innerHTML=e.content,i.innerText.trim()!==n.innerText.trim())return this._originalMessage=this._element.value,this._restored=!0,this._metaData=e.meta||{},e.content}}return this._element.value},getMetaData:function(){return this._metaData},watch:function(e){if(this._editor=e,null!==this._timer)throw new Error("Autosave timer is already active.");this._timer=window.setInterval(this._saveToStorage.bind(this),15e3),this._saveToStorage(),this._isPending=!1},destroy:function(){this.clear(),this._editor=null,window.clearInterval(this._timer),this._timer=null,this._isPending=!1},clear:function(){this._metaData={},this._lastMessage="";try{window.localStorage.removeItem(this._key)}catch(e){window.console.warn("Unable to remove from local storage: "+e.message)}},createOverlay:function(){if(this._restored){var e=elCreate("div");e.className="redactorAutosaveRestored active";var t=elCreate("span");t.textContent=n.get("wcf.editor.autosave.restored"),e.appendChild(t);var i=elCreate("a");i.className="jsTooltip",i.href="#",i.title=n.get("wcf.editor.autosave.keep"),i.innerHTML='<span class="icon icon16 fa-check green"></span>',i.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.hideOverlay()}.bind(this)),e.appendChild(i),i=elCreate("a"),i.className="jsTooltip",i.href="#",i.title=n.get("wcf.editor.autosave.discard"),i.innerHTML='<span class="icon icon16 fa-times red"></span>',i.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.clear();var t=r.convertFromHtml(this._editor.core.element()[0].id,this._originalMessage);this._editor.code.start(t),this._editor.core.textarea().val(this._editor.clean.onSync(this._editor.$editor.html())),this.hideOverlay()}.bind(this)),e.appendChild(i),this._editor.core.box()[0].appendChild(e);var a=function(){this._editor.core.editor()[0].removeEventListener(WCF_CLICK_EVENT,a),this.hideOverlay()}.bind(this);this._editor.core.editor()[0].addEventListener(WCF_CLICK_EVENT,a),this._container=e}},hideOverlay:function(){null!==this._container&&(this._container.classList.remove("active"),window.setTimeout(function(){null!==this._container&&elRemove(this._container),this._container=null,this._originalMessage=""}.bind(this),1e3))},_saveToStorage:function(){if(!this._isActive){if(!this._isPending)return;this._isPending=!1}if(!window.ENABLE_DEVELOPER_TOOLS||!1!==t._internal_.editorAutosave()){var e=this._editor.code.get();if(this._editor.utils.isEmpty(e)&&(e=""),this._lastMessage!==e){if(""===e)return this.clear();try{i.fire("com.woltlab.wcf.redactor2","autosaveMetaData_"+this._element.id,this._metaData),window.localStorage.setItem(this._key,JSON.stringify({content:e,meta:this._metaData,timestamp:Date.now()})),this._lastMessage=e}catch(e){window.console.warn("Unable to write to local storage: "+e.message)}}}},_cleanup:function(){var t,i,n,a,r=Date.now()-6048e5,o=[];for(t=0,n=window.localStorage.length;t<n;t++)if(i=window.localStorage.key(t),0===i.indexOf(e.getStoragePrefix())){try{a=window.localStorage.getItem(i)}catch(e){window.console.warn("Unable to access local storage: "+e.message)}try{a=JSON.parse(a)}catch(e){a={timestamp:0}}(!a||a.timestamp<r)&&o.push(i)}for(t=0,n=o.length;t<n;t++)try{window.localStorage.removeItem(o[t])}catch(e){window.console.warn("Unable to remove from local storage: "+e.message)}}},o}),define("WoltLabSuite/Core/Ui/Redactor/PseudoHeader",[],function(){"use strict";return{getHeight:function(e){var t=~~window.getComputedStyle(e).paddingTop.replace(/px$/,""),i=window.getComputedStyle(e,"::before");t+=~~i.paddingTop.replace(/px$/,""),t+=~~i.paddingBottom.replace(/px$/,"");var n=~~i.height.replace(/px$/,"");return 0===n&&(n=e.scrollHeight,e.classList.add("redactorCalcHeight"),n-=e.scrollHeight,e.classList.remove("redactorCalcHeight")),t+=n}}}),define("WoltLabSuite/Core/Ui/Redactor/Code",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader","prism/prism-meta"],function(e,t,i,n,a,r,o,s){"use strict";function l(e){this.init(e)}var c=0;return l.prototype={init:function(t){this._editor=t,this._elementId=this._editor.$element[0].id,this._pre=null,e.add("com.woltlab.wcf.redactor2","bbcode_code_"+this._elementId,this._bbcodeCode.bind(this)),e.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._editor.opts.activeButtonsStates.pre="code",this._callbackEdit=this._edit.bind(this),this._observeLoad()},_bbcodeCode:function(e){e.cancel=!0;var t=this._editor.selection.block();t&&"PRE"===t.nodeName&&t.classList.contains("woltlabHtml")||(this._editor.button.toggle({},"pre","func","block.format"),(t=this._editor.selection.block())&&"PRE"===t.nodeName&&!t.classList.contains("woltlabHtml")&&(1===t.childElementCount&&"BR"===t.children[0].nodeName&&t.removeChild(t.children[0]),this._setTitle(t),t.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(t)))},_observeLoad:function(){elBySelAll("pre:not(.woltlabHtml)",this._editor.$editor[0],function(e){e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)}.bind(this))},_edit:function(e){var t=e.currentTarget;0===c&&(c=o.getHeight(t));var i=a.offset(t);e.pageY>i.top&&e.pageY<i.top+c&&(e.preventDefault(),this._editor.selection.save(),this._pre=t,r.open(this))},_dialogSubmit:function(){var e="redactor-code-"+this._elementId;["file","highlighter","line"].forEach(function(t){elData(this._pre,t,elById(e+"-"+t).value)}.bind(this)),this._setTitle(this._pre),this._editor.caret.after(this._pre),r.close(this)},_setTitle:function(e){var t=elData(e,"file"),n=elData(e,"highlighter");n=-1!==this._editor.opts.woltlab.highlighters.indexOf(n)?s[n].title:"";var a=i.get("wcf.editor.code.title",{file:t,highlighter:n});elData(e,"title")!==a&&elData(e,"title",a)},_delete:function(e){e.preventDefault();var t=this._pre.nextElementSibling||this._pre.previousElementSibling;null===t&&this._pre.parentNode!==this._editor.core.editor()[0]&&(t=this._pre.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._pre),this._editor.caret.end(t)),r.close(this)},_dialogSetup:function(){var e="redactor-code-"+this._elementId,t=e+"-button-delete",a=e+"-button-save",o=e+"-file",l=e+"-highlighter",c=e+"-line";return{id:e,options:{onClose:function(){this._editor.selection.restore(),r.destroy(this)}.bind(this),onSetup:function(){elById(t).addEventListener(WCF_CLICK_EVENT,this._delete.bind(this));var e='<option value="">'+i.get("wcf.editor.code.highlighter.detect")+"</option>";e+='<option value="plain">'+i.get("wcf.editor.code.highlighter.plain")+"</option>"
+;var a=this._editor.opts.woltlab.highlighters.map(function(e){return[e,s[e].title]});a.sort(function(e,t){return e[1]<t[1]?-1:e[1]>t[1]?1:0}),a.forEach(function(t){e+='<option value="'+t[0]+'">'+n.escapeHTML(t[1])+"</option>"}.bind(this)),elById(l).innerHTML=e}.bind(this),onShow:function(){elById(l).value=elData(this._pre,"highlighter");var e=elData(this._pre,"line");elById(c).value=""===e?1:~~e,elById(o).value=elData(this._pre,"file")}.bind(this),title:i.get("wcf.editor.code.edit")},source:'<div class="section"><dl><dt><label for="'+l+'">'+i.get("wcf.editor.code.highlighter")+'</label></dt><dd><select id="'+l+'"></select><small>'+i.get("wcf.editor.code.highlighter.description")+'</small></dd></dl><dl><dt><label for="'+c+'">'+i.get("wcf.editor.code.line")+'</label></dt><dd><input type="number" id="'+c+'" min="0" value="1" class="long" data-dialog-submit-on-enter="true"><small>'+i.get("wcf.editor.code.line.description")+'</small></dd></dl><dl><dt><label for="'+o+'">'+i.get("wcf.editor.code.file")+'</label></dt><dd><input type="text" id="'+o+'" class="long" data-dialog-submit-on-enter="true"><small>'+i.get("wcf.editor.code.file.description")+'</small></dd></dl></div><div class="formSubmit"><button id="'+a+'" class="buttonPrimary" data-type="submit">'+i.get("wcf.global.button.save")+'</button><button id="'+t+'">'+i.get("wcf.global.button.delete")+"</button></div>"}}},l}),define("WoltLabSuite/Core/Ui/Redactor/Format",["Dom/Util"],function(e){"use strict";var t=function(e){for(var t=window.getSelection().anchorNode;t;){if(t===e)return!0;t=t.parentNode}return!1};return{format:function(i,n,a){var r=window.getSelection();if(r.rangeCount){if(!t(i))return void console.error("Invalid selection, range exists outside of the editor:",r.anchorNode);var o=r.getRangeAt(0),s=null,l=null,c=null;if(o.collapsed)c=elCreate("strike"),c.textContent="​",o.insertNode(c),o=document.createRange(),o.selectNodeContents(c),r.removeAllRanges(),r.addRange(o);else{s=elCreate("mark"),l=elCreate("mark");var d=o.cloneRange();d.collapse(!0),d.insertNode(s),d=o.cloneRange(),d.collapse(!1),d.insertNode(l),o=document.createRange(),o.setStartAfter(s),o.setEndBefore(l),r.removeAllRanges(),r.addRange(o),this.removeFormat(i,n),o=document.createRange(),o.setStartAfter(s),o.setEndBefore(l),r.removeAllRanges(),r.addRange(o)}var u=["strike","strikethrough"];null===c&&(u=this._getSelectionMarker(i,r),document.execCommand(u[1]));for(var h,f,p=elBySelAll(u[0],i),m=[],g=0,v=p.length;g<v;g++)f=p[g],h=elCreate("span"),elAttr(h,"style",n+": "+a),e.replaceElement(f,h),m.push(h);var _=m.length;if(_){var b=m[0],w=m[_-1];if(null===c&&b.parentNode===w.parentNode){var y=b.parentNode;"SPAN"===y.nodeName&&""!==y.style.getPropertyValue(n)&&this._isBoundaryElement(b,y,"previous")&&this._isBoundaryElement(w,y,"next")&&e.unwrapChildNodes(y)}o=document.createRange(),o.setStart(b,0),o.setEnd(w,w.childNodes.length),r.removeAllRanges(),r.addRange(o)}null!==s&&(elRemove(s),elRemove(l))}},removeFormat:function(i,n){var a=window.getSelection();if(a.rangeCount){if(!t(i))return void console.error("Invalid selection, range exists outside of the editor:",a.anchorNode);var r=a.getRangeAt(0),o=null,s=r.collapsed;if(s){for(var l=r.startContainer,c=[l];;){var d=l.parentNode;if(d===i||"TD"===d.nodeName)break;l=d,c.push(l)}if(this._isEmpty(l.innerHTML)){var u=document.createElement("woltlab-format-marker");return r.insertNode(u),c.forEach(function(t){"SPAN"===t.nodeName&&t.style.getPropertyValue(n)&&e.unwrapChildNodes(t)}),r=document.createRange(),r.selectNode(u),r.collapse(!0),a.removeAllRanges(),a.addRange(r),void elRemove(u)}o=document.createTextNode("​"),r.insertNode(o)}for(var h=elByTag("strike",i);h.length;)e.unwrapChildNodes(h[0]);var f=this._getSelectionMarker(i,window.getSelection());if(document.execCommand(f[1]),"strike"!==f[0]&&(h=elByTag(f[0],i)),s&&null!==o&&0===h.length){document.execCommand(f[1]);var p=elCreate(f[0]);o.parentNode.insertBefore(p,o),p.appendChild(o)}for(var m,g;h.length;)g=h[0],m=this._getLastMatchingParent(g,i,n),null!==m&&this._handleParentNodes(g,m,n),elBySelAll("span",g,function(t){t.style.getPropertyValue(n)&&e.unwrapChildNodes(t)}),e.unwrapChildNodes(g);elBySelAll("span",i,function(e){e.parentNode&&!e.textContent.length&&""!==e.style.getPropertyValue(n)&&(1===e.childElementCount&&"MARK"===e.children[0].nodeName&&e.parentNode.insertBefore(e.children[0],e),0===e.childElementCount&&elRemove(e))})}},_handleParentNodes:function(t,i,n){var a;if(!e.isAtNodeStart(t,i)){a=document.createRange(),a.setStartBefore(i),a.setEndBefore(t);var r=a.extractContents();i.parentNode.insertBefore(r,i)}e.isAtNodeEnd(t,i)||(a=document.createRange(),a.setStartAfter(t),a.setEndAfter(i),r=a.extractContents(),i.parentNode.insertBefore(r,i.nextSibling)),elBySelAll("span",i,function(t){t.style.getPropertyValue(n)&&e.unwrapChildNodes(t)}),e.unwrapChildNodes(i)},_getLastMatchingParent:function(e,t,i){for(var n=e.parentNode,a=null;n!==t;)"SPAN"===n.nodeName&&""!==n.style.getPropertyValue(i)&&(a=n),n=n.parentNode;return a},_isBoundaryElement:function(e,t,i){for(var n=e;n=n[i+"Sibling"];)if(n.nodeType!==Node.TEXT_NODE||""!==n.textContent.replace(/\u200B/,""))return!1;return!0},_getSelectionMarker:function(e,t){for(var i,n,a,r=["DEL","SUB","SUP"],o=0,s=r.length;o<s;o++){if(a=r[o],n=elClosest(t.anchorNode),!(i=null!==elBySel(a.toLowerCase(),n)))for(;n&&n!==e;){if(n.nodeName===a){i=!0;break}n=n.parentNode}if(!i)break;a=void 0}return"DEL"===a||void 0===a?["strike","strikethrough"]:[a.toLowerCase(),a.toLowerCase()+"script"]},_isEmpty:function(e){return e=e.replace(/[\u200B-\u200D\uFEFF]/g,""),e=e.replace(/&nbsp;/gi,""),e=e.replace(/<\/?br\s?\/?>/g,""),e=e.replace(/\s/g,""),e=e.replace(/^<p>[^\W\w\D\d]*?<\/p>$/i,""),e=e.replace(/<iframe(.*?[^>])>$/i,"iframe"),e=e.replace(/<source(.*?[^>])>$/i,"source"),e=e.replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),e=e.replace(/<[^\/>][^>]*><\/[^>]+>/gi,""),""===e.trim()}}}),define("WoltLabSuite/Core/Ui/Redactor/Html",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,a,r,o){"use strict";function s(e){this.init(e)}var l=0;return s.prototype={init:function(t){this._editor=t,this._elementId=this._editor.$element[0].id,this._pre=null,e.add("com.woltlab.wcf.redactor2","bbcode_woltlabHtml_"+this._elementId,this._bbcodeCode.bind(this)),e.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._editor.opts.activeButtonsStates["woltlab-html"]="woltlabHtml",this._callbackEdit=this._edit.bind(this),this._observeLoad()},_bbcodeCode:function(e){e.cancel=!0;var t=this._editor.selection.block();t&&"PRE"===t.nodeName&&!t.classList.contains("woltlabHtml")||(this._editor.button.toggle({},"pre","func","block.format"),(t=this._editor.selection.block())&&"PRE"===t.nodeName&&(t.classList.add("woltlabHtml"),1===t.childElementCount&&"BR"===t.children[0].nodeName&&t.removeChild(t.children[0]),this._setTitle(t),t.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(t)))},_observeLoad:function(){elBySelAll("pre.woltlabHtml",this._editor.$editor[0],function(e){e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)}.bind(this))},_edit:function(e){var t=e.currentTarget;0===l&&(l=o.getHeight(t));var i=a.offset(t);e.pageY>i.top&&e.pageY<i.top+l&&(e.preventDefault(),this._editor.selection.save(),this._pre=t,console.warn("should edit"))},_setTitle:function(e){["title","description"].forEach(function(t){var n=i.get("wcf.editor.html."+t);elData(e,t)!==n&&elData(e,t,n)})},_delete:function(e){console.warn("should delete"),e.preventDefault();var t=this._pre.nextElementSibling||this._pre.previousElementSibling;null===t&&this._pre.parentNode!==this._editor.core.editor()[0]&&(t=this._pre.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._pre),this._editor.caret.end(t)),r.close(this)}},s}),define("WoltLabSuite/Core/Ui/Redactor/Link",["Core","EventKey","Language","Ui/Dialog"],function(e,t,i,n){"use strict";var a=!1,r=null;return{showDialog:function(e){n.open(this),n.setTitle(this,i.get("wcf.editor.link."+(e.insert?"add":"edit")));var t=elById("redactor-modal-button-action");t.textContent=i.get("wcf.global.button."+(e.insert?"insert":"save")),r=e.submitCallback,a||(a=!0,t.addEventListener(WCF_CLICK_EVENT,this._submit.bind(this)))},_submit:function(){if(r())n.close(this);else{var e=elById("redactor-link-url");elInnerError(e,i.get(""===e.value.trim()?"wcf.global.form.error.empty":"wcf.editor.link.error.invalid"))}},_dialogSetup:function(){return{id:"redactorDialogLink",options:{onClose:function(){var e=elById("redactor-link-url"),t=e.nextElementSibling&&"SMALL"===e.nextElementSibling.nodeName?e.nextElementSibling:null;null!==t&&elRemove(t)},onSetup:function(i){var n=elBySel(".formSubmit > .buttonPrimary",i);null!==n&&elBySelAll('input[type="url"], input[type="text"]',i,function(i){i.addEventListener("keyup",function(i){t.Enter(i)&&e.triggerEvent(n,"click")})})},onShow:function(){elById("redactor-link-url").focus()}},source:'<dl><dt><label for="redactor-link-url">'+i.get("wcf.editor.link.url")+'</label></dt><dd><input type="url" id="redactor-link-url" class="long"></dd></dl><dl><dt><label for="redactor-link-url-text">'+i.get("wcf.editor.link.text")+'</label></dt><dd><input type="text" id="redactor-link-url-text" class="long"></dd></dl><div class="formSubmit"><button id="redactor-modal-button-action" class="buttonPrimary"></button></div>'}}}}),define("WoltLabSuite/Core/Ui/Redactor/Mention",["Ajax","Environment","StringUtil","Ui/CloseOverlay"],function(e,t,i,n){"use strict";function a(e){this.init(e)}var r=null;return a.prototype={init:function(e){this._active=!1,this._dropdownActive=!1,this._dropdownMenu=null,this._itemIndex=0,this._lineHeight=null,this._mentionStart="",this._redactor=e,this._timer=null,e.WoltLabEvent.register("keydown",this._keyDown.bind(this)),e.WoltLabEvent.register("keyup",this._keyUp.bind(this)),n.add("UiRedactorMention-"+e.core.element()[0].id,this._hideDropdown.bind(this))},_keyDown:function(e){if(this._dropdownActive){var t=e.event;switch(t.which){case 13:this._setUsername(null,this._dropdownMenu.children[this._itemIndex].children[0]);break;case 38:this._selectItem(-1);break;case 40:this._selectItem(1);break;default:return void this._hideDropdown()}t.preventDefault(),e.cancel=!0}},_keyUp:function(t){var i=t.event;if(13===i.which)return void(this._active=!1);if(!this._dropdownActive||(t.cancel=!0,38!==i.which&&40!==i.which)){var n=this._getTextLineInFrontOfCaret();if(n.length>0&&n.length<25){var a=n.match(/@([^,]{3,})$/);a?a.index&&!n[a.index-1].match(/\s/)||(this._mentionStart=a[1],null!==this._timer&&(window.clearTimeout(this._timer),this._timer=null),this._timer=window.setTimeout(function(){e.api(this,{parameters:{data:{searchString:this._mentionStart}}}),this._timer=null}.bind(this),500)):this._hideDropdown()}else this._hideDropdown()}},_getTextLineInFrontOfCaret:function(){var e=this._selectMention(!1);return null!==e?e.range.cloneContents().textContent.replace(/\u200B/g,"").replace(/\u00A0/g," ").trim():""},_getDropdownMenuPosition:function(){var e=this._selectMention();if(null===e)return null;this._redactor.selection.save(),e.selection.removeAllRanges(),e.selection.addRange(e.range);var t=e.selection.getRangeAt(0).getBoundingClientRect(),i={top:Math.round(t.bottom)+(window.scrollY||window.pageYOffset),left:Math.round(t.left)+document.body.scrollLeft};return null===this._lineHeight&&(this._lineHeight=Math.round(t.bottom-t.top)),this._redactor.selection.restore(),i},_setUsername:function(e,t){e&&(e.preventDefault(),t=e.currentTarget);var i=this._selectMention();if(null===i)return void this._hideDropdown();this._redactor.buffer.set(),i.selection.removeAllRanges(),i.selection.addRange(i.range);var n=getSelection().getRangeAt(0);n.deleteContents(),n.collapse(!0);var a=elData(t,"username").trim();a.split(/\s/g).length>2&&(a="'"+a.replace(/'/g,"''")+"'");var r=document.createTextNode("@"+a+" ");n.insertNode(r),n=document.createRange(),n.selectNode(r),n.collapse(!1),i.selection.removeAllRanges(),i.selection.addRange(n),this._hideDropdown()},_selectMention:function(e){var t=window.getSelection();if(!t.rangeCount||!t.isCollapsed)return null;var i=t.anchorNode;if(i.nodeType===Node.TEXT_NODE&&(i=i.parentNode),-1===i.textContent.indexOf("@"))return null;for(var n=this._redactor.core.editor()[0];i&&i!==n;){if(-1!==["PRE","WOLTLAB-QUOTE"].indexOf(i.nodeName))return null;i=i.parentNode}for(var a=t.getRangeAt(0),r=a.startContainer,o=a.startOffset;r.nodeType===Node.ELEMENT_NODE;){if(0===o&&0===r.childNodes.length)return null;r=r.childNodes[o?o-1:0],o>0&&(o=r.nodeType===Node.TEXT_NODE?r.textContent.length:r.childNodes.length)}for(var s=r,l=-1;null!==s;){if(s.nodeType!==Node.TEXT_NODE)return null;if(-1!==s.textContent.indexOf("@")){l=s.textContent.lastIndexOf("@");break}s=s.previousSibling}if(-1===l)return null;try{a=document.createRange(),a.setStart(s,l),a.setEnd(r,o)}catch(e){return window.console.debug(e),null}if(!1===e){var c="";for(l&&(c=s.textContent.substr(0,l));(s=s.previousSibling)&&s.nodeType===Node.TEXT_NODE;)c=s.textContent+c;if(c.replace(/\u200B/g,"").match(/\S$/))return null}else if(a.cloneContents().textContent.replace(/\u200B/g,"").replace(/\u00A0/g,"").trim().replace(/^@/,"")!==this._mentionStart)return null;return{range:a,selection:t}},_updateDropdownPosition:function(){var e=this._getDropdownMenuPosition();if(null===e)return void this._hideDropdown();e.top+=7,this._dropdownMenu.style.setProperty("left",e.left+"px",""),this._dropdownMenu.style.setProperty("top",e.top+"px",""),this._selectItem(0),e.top+this._dropdownMenu.offsetHeight+10>window.innerHeight+(window.scrollY||window.pageYOffset)&&this._dropdownMenu.style.setProperty("top",e.top-this._dropdownMenu.offsetHeight-2*this._lineHeight+7+"px","")},_selectItem:function(e){var t=elBySel(".active",this._dropdownMenu);null!==t&&t.classList.remove("active"),this._itemIndex+=e,this._itemIndex<0?this._itemIndex=this._dropdownMenu.childElementCount-1:this._itemIndex>=this._dropdownMenu.childElementCount&&(this._itemIndex=0),this._dropdownMenu.children[this._itemIndex].classList.add("active")},_hideDropdown:function(){null!==this._dropdownMenu&&this._dropdownMenu.classList.remove("dropdownOpen"),this._dropdownActive=!1,this._itemIndex=0},_ajaxSetup:function(){return{data:{actionName:"getSearchResultList",className:"wcf\\data\\user\\UserAction",interfaceName:"wcf\\data\\ISearchAction",parameters:{data:{includeUserGroups:!0,scope:"mention"}}},silent:!0}},_ajaxSuccess:function(e){if(!Array.isArray(e.returnValues)||!e.returnValues.length)return void this._hideDropdown();null===this._dropdownMenu&&(this._dropdownMenu=elCreate("ol"),this._dropdownMenu.className="dropdownMenu",null===r&&(r=elCreate("div"),r.className="dropdownMenuContainer",document.body.appendChild(r)),r.appendChild(this._dropdownMenu)),this._dropdownMenu.innerHTML="";for(var t,n,a,o=this._setUsername.bind(this),s=0,l=e.returnValues.length;s<l;s++)a=e.returnValues[s],n=elCreate("li"),t=elCreate("a"),t.addEventListener("mousedown",o),t.className="box16",t.innerHTML="<span>"+a.icon+"</span> <span>"+i.escapeHTML(a.label)+"</span>",elData(t,"user-id",a.objectID),elData(t,"username",a.label),n.appendChild(t),this._dropdownMenu.appendChild(n);this._dropdownMenu.classList.add("dropdownOpen"),this._dropdownActive=!0,this._updateDropdownPosition()}},a}),define("WoltLabSuite/Core/Ui/Redactor/Page",["WoltLabSuite/Core/Ui/Page/Search"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(e,t){this._editor=e,t.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))},_click:function(t){t.preventDefault(),e.open(this._insert.bind(this))},_insert:function(e){this._editor.buffer.set(),this._editor.insert.text("[wsp='"+e+"'][/wsp]")}},t}),define("WoltLabSuite/Core/Ui/Redactor/Quote",["Core","EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./Metacode","./PseudoHeader"],function(e,t,i,n,a,r,o,s,l){"use strict";function c(e,t){this.init(e,t)}var d=0;return c.prototype={init:function(e,i){this._quote=null,this._quotes=elByTag("woltlab-quote",e.$editor[0]),this._editor=e,this._elementId=this._editor.$element[0].id,t.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._editor.button.addCallback(i,this._click.bind(this)),this._callbackEdit=this._edit.bind(this),this._observeLoad(),t.add("com.woltlab.wcf.redactor2","insertQuote_"+this._elementId,this._insertQuote.bind(this))},_insertQuote:function(e){if(!this._editor.WoltLabSource.isActive()){t.fire("com.woltlab.wcf.redactor2","showEditor");var i=this._editor.core.editor()[0];this._editor.selection.restore(),this._editor.buffer.set();var n=this._editor.selection.block();for(!1===n&&(this._editor.focus.end(),n=this._editor.selection.block());n&&n.parentNode!==i;)n=n.parentNode;var r=elCreate("woltlab-quote");elData(r,"author",e.author),elData(r,"link",e.link);var o=e.content;e.isText?(o=a.escapeHTML(o),o="<p>"+o+"</p>",o=o.replace(/\n\n/g,"</p><p>"),o=o.replace(/\n/g,"<br>")):o=s.convertFromHtml(this._editor.$element[0].id,o),r.innerHTML=o,n.parentNode.insertBefore(r,n.nextSibling),"P"!==n.nodeName||"<br>"!==n.innerHTML&&""!==n.innerHTML.replace(/\u200B/g,"")||n.parentNode.removeChild(n);var l=r.previousElementSibling;l&&"P"!==l.nodeName&&(l=elCreate("p"),l.textContent="​",r.parentNode.insertBefore(l,r)),this._editor.WoltLabCaret.paragraphAfterBlock(r),this._editor.buffer.set()}},_click:function(){this._editor.button.toggle({},"woltlab-quote","func","block.format");var e=this._editor.selection.block();e&&"WOLTLAB-QUOTE"===e.nodeName&&(this._setTitle(e),e.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(e))},_observeLoad:function(){for(var e,t=0,i=this._quotes.length;t<i;t++)e=this._quotes[t],e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)},_edit:function(e){var t=e.currentTarget;0===d&&(d=l.getHeight(t));var i=r.offset(t);e.pageY>i.top&&e.pageY<i.top+d&&(e.preventDefault(),this._editor.selection.save(),this._quote=t,o.open(this))},_dialogSubmit:function(){var e="redactor-quote-"+this._elementId,t=elById(e+"-url"),i=t.value.replace(/\u200B/g,"").trim();if(i.length&&!/^https?:\/\/[^\/]+/.test(i))return void elInnerError(t,n.get("wcf.editor.quote.url.error.invalid"));elInnerError(t,!1),elData(this._quote,"author",elById(e+"-author").value),elData(this._quote,"link",i),this._setTitle(this._quote),this._editor.caret.after(this._quote),o.close(this)},_setTitle:function(e){var t=n.get("wcf.editor.quote.title",{author:elData(e,"author"),url:elData(e,"url")});elData(e,"title")!==t&&elData(e,"title",t)},_delete:function(e){e.preventDefault();var t=this._quote.nextElementSibling||this._quote.previousElementSibling;null===t&&this._quote.parentNode!==this._editor.core.editor()[0]&&(t=this._quote.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._quote),this._editor.caret.end(t)),o.close(this)},_dialogSetup:function(){var e="redactor-quote-"+this._elementId,t=e+"-author",i=e+"-button-delete",a=e+"-button-save",r=e+"-url";return{id:e,options:{onClose:function(){this._editor.selection.restore(),o.destroy(this)}.bind(this),onSetup:function(){elById(i).addEventListener(WCF_CLICK_EVENT,this._delete.bind(this))}.bind(this),onShow:function(){elById(t).value=elData(this._quote,"author"),elById(r).value=elData(this._quote,"link")}.bind(this),title:n.get("wcf.editor.quote.edit")},source:'<div class="section"><dl><dt><label for="'+t+'">'+n.get("wcf.editor.quote.author")+'</label></dt><dd><input type="text" id="'+t+'" class="long" data-dialog-submit-on-enter="true"></dd></dl><dl><dt><label for="'+r+'">'+n.get("wcf.editor.quote.url")+'</label></dt><dd><input type="text" id="'+r+'" class="long" data-dialog-submit-on-enter="true"><small>'+n.get("wcf.editor.quote.url.description")+'</small></dd></dl></div><div class="formSubmit"><button id="'+a+'" class="buttonPrimary" data-type="submit">'+n.get("wcf.global.button.save")+'</button><button id="'+i+'">'+n.get("wcf.global.button.delete")+"</button></div>"}}},c}),define("WoltLabSuite/Core/Ui/Redactor/Spoiler",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,a,r,o){"use strict";function s(e){this.init(e)}var l=0;return s.prototype={init:function(t){this._editor=t,this._elementId=this._editor.$element[0].id,this._spoiler=null,e.add("com.woltlab.wcf.redactor2","bbcode_spoiler_"+this._elementId,this._bbcodeSpoiler.bind(this)),e.add("com.woltlab.wcf.redactor2","observe_load_"+this._elementId,this._observeLoad.bind(this)),this._callbackEdit=this._edit.bind(this),this._observeLoad()},_bbcodeSpoiler:function(e){e.cancel=!0,this._editor.button.toggle({},"woltlab-spoiler","func","block.format");var t=this._editor.selection.block();t&&("P"===t.nodeName&&(t=t.parentNode),"WOLTLAB-SPOILER"===t.nodeName&&(this._setTitle(t),t.addEventListener(WCF_CLICK_EVENT,this._callbackEdit),this._editor.caret.end(t)))},_observeLoad:function(){elBySelAll("woltlab-spoiler",this._editor.$editor[0],function(e){e.addEventListener("mousedown",this._callbackEdit),this._setTitle(e)}.bind(this))},_edit:function(e){var t=e.currentTarget;0===l&&(l=o.getHeight(t));var i=a.offset(t);e.pageY>i.top&&e.pageY<i.top+l&&(e.preventDefault(),this._editor.selection.save(),this._spoiler=t,r.open(this))},_dialogSubmit:function(){elData(this._spoiler,"label",elById("redactor-spoiler-"+this._elementId+"-label").value),this._setTitle(this._spoiler),this._editor.caret.after(this._spoiler),r.close(this)},_setTitle:function(e){var t=i.get("wcf.editor.spoiler.title",{label:elData(e,"label")});elData(e,"title")!==t&&elData(e,"title",t)},_delete:function(e){e.preventDefault();var t=this._spoiler.nextElementSibling||this._spoiler.previousElementSibling;null===t&&this._spoiler.parentNode!==this._editor.core.editor()[0]&&(t=this._spoiler.parentNode),null===t?(this._editor.code.set(""),this._editor.focus.end()):(elRemove(this._spoiler),this._editor.caret.end(t)),r.close(this)},_dialogSetup:function(){var e="redactor-spoiler-"+this._elementId,t=e+"-button-delete",n=e+"-button-save",a=e+"-label";return{id:e,options:{onClose:function(){this._editor.selection.restore(),r.destroy(this)}.bind(this),onSetup:function(){elById(t).addEventListener(WCF_CLICK_EVENT,this._delete.bind(this))}.bind(this),onShow:function(){elById(a).value=elData(this._spoiler,"label")}.bind(this),title:i.get("wcf.editor.spoiler.edit")},source:'<div class="section"><dl><dt><label for="'+a+'">'+i.get("wcf.editor.spoiler.label")+'</label></dt><dd><input type="text" id="'+a+'" class="long" data-dialog-submit-on-enter="true"><small>'+i.get("wcf.editor.spoiler.label.description")+'</small></dd></dl></div><div class="formSubmit"><button id="'+n+'" class="buttonPrimary" data-type="submit">'+i.get("wcf.global.button.save")+'</button><button id="'+t+'">'+i.get("wcf.global.button.delete")+"</button></div>"}}},s}),define("WoltLabSuite/Core/Ui/Redactor/Table",["Language","Ui/Dialog"],function(e,t){"use strict";var i=null;return{showDialog:function(e){t.open(this),i=e.submitCallback},_dialogSubmit:function(){var e=!0;["rows","cols"].forEach(function(t){var i=elById("redactor-table-"+t);(i.value<1||i.value>100)&&(e=!1)}),e&&(i(),t.close(this))},_dialogSetup:function(){return{id:"redactorDialogTable",options:{onShow:function(){elById("redactor-table-rows").value=2,elById("redactor-table-cols").value=3},title:e.get("wcf.editor.table.insertTable")},source:'<dl><dt><label for="redactor-table-rows">'+e.get("wcf.editor.table.rows")+'</label></dt><dd><input type="number" id="redactor-table-rows" class="small" min="1" max="100" value="2" data-dialog-submit-on-enter="true"></dd></dl><dl><dt><label for="redactor-table-cols">'+e.get("wcf.editor.table.cols")+'</label></dt><dd><input type="number" id="redactor-table-cols" class="small" min="1" max="100" value="3" data-dialog-submit-on-enter="true"></dd></dl><div class="formSubmit"><button id="redactor-modal-button-action" class="buttonPrimary" data-type="submit">'+e.get("wcf.global.button.insert")+"</button></div>"}}}}),define("WoltLabSuite/Core/Ui/Search/Page",["Core","Dom/Traverse","Dom/Util","Ui/Screen","Ui/SimpleDropdown","./Input"],function(e,t,i,n,a,r){"use strict";return{init:function(o){var s=elById("pageHeaderSearchInput");new r(s,{ajax:{className:"wcf\\data\\search\\keyword\\SearchKeywordAction"},autoFocus:!1,callbackDropdownInit:function(e){if(e.classList.add("dropdownMenuPageSearch"),n.is("screen-lg")){elData(e,"dropdown-alignment-horizontal","right");var t=s.clientWidth;e.style.setProperty("min-width",t+"px","");var a=s.parentNode,r=i.offset(a).left+a.clientWidth-(i.offset(s).left+t),o=i.styleAsInt(window.getComputedStyle(a),"padding-bottom");e.style.setProperty("transform","translateX(-"+Math.ceil(r)+"px) translateY(-"+o+"px)","")}},callbackSelect:function(){return setTimeout(function(){t.parentByTag(s,"FORM").submit()},1),!0}});var l=a.getDropdownMenu(i.identify(elBySel(".pageHeaderSearchType"))),c=this._click.bind(this);elBySelAll("a[data-object-type]",l,function(e){e.addEventListener(WCF_CLICK_EVENT,c)});var d=elBySel('a[data-object-type="'+o+'"]',l);e.triggerEvent(d,WCF_CLICK_EVENT)},_click:function(e){e.preventDefault();var t=elById("pageHeader");t.classList.add("searchBarForceOpen"),window.setTimeout(function(){t.classList.remove("searchBarForceOpen")},10);var i=elData(e.currentTarget,"object-type"),n=elById("pageHeaderSearchParameters");n.innerHTML="";var a=elData(e.currentTarget,"extended-link");a&&(elBySel(".pageHeaderSearchExtendedLink").href=a);var r=elData(e.currentTarget,"parameters");r=r?JSON.parse(r):{},i&&(r["types[]"]=i);for(var o in r)if(r.hasOwnProperty(o)){var s=elCreate("input");s.type="hidden",s.name=o,s.value=r[o],n.appendChild(s)}elBySel(".pageHeaderSearchType > .button > .pageHeaderSearchTypeLabel",elById("pageHeaderSearchInputContainer")).textContent=e.currentTarget.textContent}}}),define("WoltLabSuite/Core/Ui/Smiley/Insert",["EventHandler","EventKey"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={_container:null,_editorId:"",init:function(e){if(this._editorId=e,this._container=elById("smilies-"+this._editorId),!this._container&&(this._container=elById(this._editorId+"SmiliesTabContainer"),!this._container))throw new Error("Unable to find the message tab menu container containing the smilies.");this._container.addEventListener("keydown",this._keydown.bind(this)),this._container.addEventListener("mousedown",this._mousedown.bind(this))},_keydown:function(e){var i=document.activeElement;if(i.classList.contains("jsSmiley"))if(t.ArrowLeft(e)||t.ArrowRight(e)||t.Home(e)||t.End(e)){e.preventDefault();var n=Array.prototype.slice.call(elBySelAll(".jsSmiley",e.currentTarget));t.ArrowLeft(e)&&n.reverse();var a=n.indexOf(i);t.Home(e)?a=0:t.End(e)?a=n.length-1:(a+=1)===n.length&&(a=0),n[a].focus()}else(t.Enter(e)||t.Space(e))&&(e.preventDefault(),this._insert(elBySel("img",i)))},_mousedown:function(e){var t=e.target.closest("li");if(this._container.contains(t)){e.preventDefault();var i=elBySel("img",t);i&&this._insert(i)}},_insert:function(t){e.fire("com.woltlab.wcf.redactor2","insertSmiley_"+this._editorId,{img:t})}},i}),define("WoltLabSuite/Core/Ui/Style/FontAwesome",["Language","Ui/Dialog","WoltLabSuite/Core/Ui/ItemList/Filter"],function(e,t,i){"use strict";var n,a,r,o=[];return{setup:function(e){o=e},open:function(e){if(0===o.length)throw new Error("Missing icon data, please include the template before calling this method using `{include file='fontAwesomeJavaScript'}`.");n=e,t.open(this)},_click:function(e){e.preventDefault();var i=e.target.closest("li"),a=elBySel("small",i).textContent.trim();t.close(this),n(a)},_dialogSetup:function(){return{id:"fontAwesomeSelection",options:{onSetup:function(){a=elById("fontAwesomeIcons");for(var e,t="",n=0,s=o.length;n<s;n++)e=o[n],t+='<li><span class="icon icon48 fa-'+e+'"></span><small>'+e+"</small></li>";a.innerHTML=t,a.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),r=new i("fontAwesomeIcons",{callbackPrepareItem:function(e){var t=elBySel("small",e);return{item:e,span:t,text:t.textContent.trim()}},enableVisibilityFilter:!1,filterPosition:"top"})}.bind(this),onShow:function(){r.reset()},title:e.get("wcf.global.fontAwesome.selectIcon")},source:'<ul class="fontAwesomeIcons" id="fontAwesomeIcons"></ul>'}}}}),define("WoltLabSuite/Core/Ui/Toggle/Input",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(t,i){if(this._element=elBySel(t),null===this._element)throw new Error("Unable to find element by selector '"+t+"'.");var n="INPUT"===this._element.nodeName?elAttr(this._element,"type"):"";if("checkbox"!==n&&"radio"!==n)throw new Error("Illegal element, expected input[type='checkbox'] or input[type='radio'].");this._options=e.extend({hide:[],show:[]},i),["hide","show"].forEach(function(e){var t,i,n;for(i=0,n=this._options[e].length;i<n;i++)if("string"!=typeof(t=this._options[e][i])&&!(t instanceof Element))throw new TypeError("The array '"+e+"' may only contain string selectors or DOM elements.")}.bind(this)),this._element.addEventListener("change",this._change.bind(this)),this._handleElements(this._options.show,this._element.checked),this._handleElements(this._options.hide,!this._element.checked)},_change:function(e){var t=e.currentTarget.checked;this._handleElements(this._options.show,t),this._handleElements(this._options.hide,!t)},_handleElements:function(e,t){for(var i,n,a=0,r=e.length;a<r;a++){if("string"==typeof(i=e[a])){if(null===(n=elBySel(i)))throw new Error("Unable to find element by selector '"+i+"'.");e[a]=i=n}window[t?"elShow":"elHide"](i)}}},t}),define("WoltLabSuite/Core/Ui/User/Editor",["Ajax","Language","StringUtil","Dom/Util","Ui/Dialog","Ui/Notification"],function(e,t,i,n,a,r){"use strict";var o="",s=null;return{init:function(){s=elBySel(".userProfileUser"),["ban","disableAvatar","disableCoverPhoto","disableSignature","enable"].forEach(function(e){var t=elBySel(".userProfileButtonMenu .jsButtonUser"+i.ucfirst(e));t&&(elData(t,"action",e),t.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)))}.bind(this))},_click:function(t){t.preventDefault();var i=elData(t.currentTarget,"action"),n="";switch(i){case"ban":elDataBool(s,"banned")&&(n="unban");break;case"disableAvatar":elDataBool(s,"disable-avatar")&&(n="enableAvatar");break;case"disableCoverPhoto":elDataBool(s,"disable-cover-photo")&&(n="enableCoverPhoto");break;case"disableSignature":elDataBool(s,"disable-signature")&&(n="enableSignature");break;case"enable":n=elDataBool(s,"is-disabled")?"enable":"disable"}""===n?(o=i,a.open(this)):e.api(this,{actionName:n})},_submit:function(i){i.preventDefault();var n=elById("wcfUiUserEditorExpiresLabel"),a="",r="";elById("wcfUiUserEditorNeverExpires").checked||""===(a=elById("wcfUiUserEditorExpiresDatePicker").value)&&(r=t.get("wcf.global.form.error.empty")),elInnerError(n,r);var s={};s[o+"Expires"]=a,s[o+"Reason"]=elById("wcfUiUserEditorReason").value.trim(),e.api(this,{actionName:o,parameters:s})},_ajaxSuccess:function(e){switch(e.actionName){case"ban":case"unban":elData(s,"banned","ban"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserBan").textContent=t.get("wcf.user."+("ban"===e.actionName?"unban":"ban"));var i=elBySel(".contentTitle",s),n=elBySel(".jsUserBanned",i);"ban"===e.actionName?(n=elCreate("span"),n.className="icon icon24 fa-lock jsUserBanned jsTooltip",n.title=e.returnValues,i.appendChild(n)):n&&elRemove(n);break;case"disableAvatar":case"enableAvatar":elData(s,"disable-avatar","disableAvatar"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserDisableAvatar").textContent=t.get("wcf.user."+("disableAvatar"===e.actionName?"enable":"disable")+"Avatar");break;case"disableCoverPhoto":case"enableCoverPhoto":elData(s,"disable-cover-photo","disableCoverPhoto"===e.actionName),
+elBySel(".userProfileButtonMenu .jsButtonUserDisableCoverPhoto").textContent=t.get("wcf.user."+("disableCoverPhoto"===e.actionName?"enable":"disable")+"CoverPhoto");break;case"disableSignature":case"enableSignature":elData(s,"disable-signature","disableSignature"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserDisableSignature").textContent=t.get("wcf.user."+("disableSignature"===e.actionName?"enable":"disable")+"Signature");break;case"enable":case"disable":elData(s,"is-disabled","disable"===e.actionName),elBySel(".userProfileButtonMenu .jsButtonUserEnable").textContent=t.get("wcf.acp.user."+("enable"===e.actionName?"disable":"enable"))}"ban"!==e.actionName&&"disableAvatar"!==e.actionName&&"disableCoverPhoto"!==e.actionName&&"disableSignature"!==e.actionName||a.close(this),r.show()},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\UserAction",objectIDs:[elData(s,"object-id")]}}},_dialogSetup:function(){return{id:"wcfUiUserEditor",options:{onSetup:function(e){elById("wcfUiUserEditorNeverExpires").addEventListener("change",function(){window[this.checked?"elHide":"elShow"](elById("wcfUiUserEditorExpiresSettings"))}),elBySel("button.buttonPrimary",e).addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))}.bind(this),onShow:function(e){a.setTitle("wcfUiUserEditor",t.get("wcf.user."+o+".confirmMessage"));var i=elById("wcfUiUserEditorReason").nextElementSibling,n="wcf.user."+o+".reason.description";i.textContent=t.get(n),window[i.textContent===n?"elHide":"elShow"](i),i=elById("wcfUiUserEditorNeverExpires").nextElementSibling,i.textContent=t.get("wcf.user."+o+".neverExpires"),i=elBySel('label[for="wcfUiUserEditorExpires"]',e),i.textContent=t.get("wcf.user."+o+".expires"),i=elById("wcfUiUserEditorExpiresLabel"),i.textContent=t.get("wcf.user."+o+".expires.description")}},source:'<div class="section"><dl><dt><label for="wcfUiUserEditorReason">'+t.get("wcf.global.reason")+'</label></dt><dd><textarea id="wcfUiUserEditorReason" cols="40" rows="3"></textarea><small></small></dd></dl><dl><dt></dt><dd><label><input type="checkbox" id="wcfUiUserEditorNeverExpires" checked> <span></span></label></dd></dl><dl id="wcfUiUserEditorExpiresSettings" style="display: none"><dt><label for="wcfUiUserEditorExpires"></label></dt><dd><input type="date" name="wcfUiUserEditorExpires" id="wcfUiUserEditorExpires" class="medium" min="'+new Date(1e3*TIME_NOW).toISOString()+'" data-ignore-timezone="true"><small id="wcfUiUserEditorExpiresLabel"></small></dd></dl></div><div class="formSubmit"><button class="buttonPrimary">'+t.get("wcf.global.button.submit")+"</button></div>"}}}}),define("WoltLabSuite/Core/Ui/User/PasswordStrength",["Core","Language"],function(e,t){"use strict";function i(e,t){return e.map(t).reduce(function(e,t){return e.concat(t)},[])}function n(e){return[].concat(e,e.split(/\W+/))}function a(i){var n=e.extend({},i.default_phrases);for(var a in n)if(n.hasOwnProperty(a))for(var r in n[a])if(n[a].hasOwnProperty(r)){var o="wcf.user.password.zxcvbn."+a+"."+r,s=t.get(o);s!==o&&(n[a][r]=s)}return new i(n)}function r(e,t){require(["zxcvbn"]).then(function(i){var n=i[0];this.init(n,e,t)}.bind(this))}var o=[];return elBySel('meta[property="og:site_name"]')&&o.push(elBySel('meta[property="og:site_name"]').getAttribute("content")),r.prototype={init:function(i,n,r){this._zxcvbn=i,this._input=n,this._options=e.extend({relatedInputs:[],staticDictionary:[]},r),this._options.feedbacker||(this._options.feedbacker=a(i.Feedback)),this._wrapper=elCreate("div"),this._wrapper.className="inputAddon inputAddonPasswordStrength",this._input.parentNode.insertBefore(this._wrapper,this._input),this._wrapper.appendChild(this._input);var o=elCreate("div");o.className="passwordStrengthRating";var s=elCreate("small");s.textContent=t.get("wcf.user.password.strength"),o.appendChild(s),this._score=elCreate("span"),this._score.className="passwordStrengthScore",elData(this._score,"score","-1"),o.appendChild(this._score),this._wrapper.appendChild(o),this._feedback=elCreate("div"),this._feedback.className="passwordStrengthFeedback",this._wrapper.appendChild(this._feedback),this._verdictResult=elCreate("input"),this._verdictResult.type="hidden",this._verdictResult.name=this._input.name+"_passwordStrengthVerdict",this._wrapper.parentNode.insertBefore(this._verdictResult,this._wrapper);var l=this._evaluate.bind(this);this._input.addEventListener("input",l),this._options.relatedInputs.forEach(function(e){e.addEventListener("input",l)}),""!==this._input.value.trim()&&this._evaluate()},_evaluate:function(e){var t=i(o.concat(this._options.staticDictionary,this._options.relatedInputs.map(function(e){return e.value.trim()})),n).filter(function(e){return e.length>0}),a=this._input.value.trim(),r=this._zxcvbn(a.substr(0,100),t);r.feedback=this._options.feedbacker.from_result(r),elData(this._score,"score",0===a.length?"-1":r.score),void 0!==e&&elInnerError(this._wrapper,r.feedback.warning),this._verdictResult.value=JSON.stringify(r)}},r}),define("WoltLabSuite/Core/Controller/Condition/Page/Dependence",["Dom/ChangeListener","Dom/Traverse","EventHandler","ObjectMap"],function(e,t,i,n){"use strict";var a=elBySelAll('input[name="pageIDs[]"]'),r=[],o=new n,s=new n,l=!1;return{register:function(e,i){if(r.push(e),o.set(e,i),s.set(e,[]),!l){for(var n=0,c=a.length;n<c;n++)a[n].addEventListener("change",this._checkVisibility.bind(this));l=!0}t.parentByTag(e,"FORM").addEventListener("submit",function(){"none"===e.style.getPropertyValue("display")&&e.remove()}),this._checkVisibility()},_checkVisibility:function(){for(var e,t,n,s,l,c=0,d=r.length;c<d;c++){e=r[c],n=o.get(e),s=[];for(var u=0,h=a.length;u<h;u++)t=a[u],t.checked&&s.push(~~t.value);l=s.filter(function(e){return-1===n.indexOf(e)}),!s.length||l.length?this._hideDependentElement(e):this._showDependentElement(e)}i.fire("com.woltlab.wcf.pageConditionDependence","checkVisivility")},_hideDependentElement:function(e){elHide(e);for(var t=s.get(e),i=0,n=t.length;i<n;i++)elHide(t[i]);s.set(e,[])},_showDependentElement:function(e){elShow(e);for(var t=e;(t=t.parentNode)&&t instanceof Element;)"none"===t.style.getPropertyValue("display")&&s.get(e).push(t),elShow(t)}}}),define("WoltLabSuite/Core/Controller/Map/Route/Planner",["Dom/Traverse","Dom/Util","Language","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,a){function r(e,t){if(this._button=elById(e),null===this._button)throw new Error("Unknown button with id '"+e+"'");this._button.addEventListener("click",this._openDialog.bind(this)),this._destination=t}return r.prototype={_dialogSetup:function(){return{id:this._button.id+"Dialog",options:{onShow:this._initDialog.bind(this),title:i.get("wcf.map.route.planner")},source:'<div class="googleMapsDirectionsContainer" style="display: none;"><div class="googleMap"></div><div class="googleMapsDirections"></div></div><small class="googleMapsDirectionsGoogleLinkContainer"><a href="'+this._getGoogleMapsLink()+'" class="googleMapsDirectionsGoogleLink" target="_blank" style="display: none;">'+i.get("wcf.map.route.viewOnGoogleMaps")+"</a></small><dl><dt>"+i.get("wcf.map.route.origin")+'</dt><dd><input type="text" name="origin" class="long" autofocus /></dd></dl><dl style="display: none;"><dt>'+i.get("wcf.map.route.travelMode")+'</dt><dd><select name="travelMode"><option value="driving">'+i.get("wcf.map.route.travelMode.driving")+'</option><option value="walking">'+i.get("wcf.map.route.travelMode.walking")+'</option><option value="bicycling">'+i.get("wcf.map.route.travelMode.bicycling")+'</option><option value="transit">'+i.get("wcf.map.route.travelMode.transit")+"</option></select></dd></dl>"}},_calculateRoute:function(e){var t=n.getDialog(this).dialog;e.label&&(this._originInput.value=e.label),void 0===this._map&&(this._map=new google.maps.Map(elByClass("googleMap",t)[0],{disableDoubleClickZoom:WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),draggable:WCF.Location.GoogleMaps.Settings.get("draggable"),mapTypeId:google.maps.MapTypeId.ROADMAP,scaleControl:WCF.Location.GoogleMaps.Settings.get("scaleControl"),scrollwheel:WCF.Location.GoogleMaps.Settings.get("scrollwheel")}),this._directionsService=new google.maps.DirectionsService,this._directionsRenderer=new google.maps.DirectionsRenderer,this._directionsRenderer.setMap(this._map),this._directionsRenderer.setPanel(elByClass("googleMapsDirections",t)[0]),this._googleLink=elByClass("googleMapsDirectionsGoogleLink",t)[0]);var i={destination:this._destination,origin:e.location,provideRouteAlternatives:!0,travelMode:google.maps.TravelMode[this._travelMode.value.toUpperCase()]};a.show(),this._directionsService.route(i,this._setRoute.bind(this)),elAttr(this._googleLink,"href",this._getGoogleMapsLink(e.location,this._travelMode.value)),this._lastOrigin=e.location},_getGoogleMapsLink:function(e,t){if(e){var i="https://www.google.com/maps/dir/?api=1&origin="+e.lat()+","+e.lng()+"&destination="+this._destination.lat()+","+this._destination.lng();return t&&(i+="&travelmode="+t),i}return"https://www.google.com/maps/search/?api=1&query="+this._destination.lat()+","+this._destination.lng()},_initDialog:function(){if(!this._didInitDialog){var e=n.getDialog(this).dialog;this._originInput=elBySel('input[name="origin"]',e),new WCF.Location.GoogleMaps.LocationSearch(this._originInput,this._calculateRoute.bind(this)),this._travelMode=elBySel('select[name="travelMode"]',e),this._travelMode.addEventListener("change",this._updateRoute.bind(this)),this._didInitDialog=!0}},_openDialog:function(){n.open(this)},_setRoute:function(t,n){a.hide(),"OK"===n?(elShow(this._map.getDiv().parentNode),google.maps.event.trigger(this._map,"resize"),this._directionsRenderer.setDirections(t),elShow(e.parentByTag(this._travelMode,"DL")),elShow(this._googleLink),elInnerError(this._originInput,!1)):("OVER_QUERY_LIMIT"!==n&&"REQUEST_DENIED"!==n&&(n="NOT_FOUND"),elInnerError(this._originInput,i.get("wcf.map.route.error."+n.toLowerCase())))},_updateRoute:function(){this._calculateRoute({location:this._lastOrigin})}},r}),define("WoltLabSuite/Core/Controller/User/Notification/Settings",["Language","Ui/ReusableDropdown"],function(e,t){"use strict";var i=null,n=null;return{init:function(){elBySelAll(".jsCheckboxNotificationSettingsState",void 0,function(e){e.addEventListener("change",this._stateChange.bind(this))}.bind(this)),elBySelAll(".notificationSettingsEmailType",void 0,function(e){e.addEventListener("click",this._click.bind(this))}.bind(this))},_stateChange:function(e){var t=elData(e.currentTarget,"object-id"),i=elBySel('.notificationSettingsEmailType[data-object-id="'+t+'"]');null!==i&&i.classList[e.currentTarget.checked?"remove":"add"]("disabled")},_click:function(e){e.preventDefault(),e.stopPropagation();var t=e.currentTarget;n=~~elData(t,"object-id"),this._createDropDown(),this._setCurrentEmailType(this._getEmailTypeInputElement().value),this._showDropDown(t)},_createDropDown:function(){null===i&&(i=elCreate("ul"),i.className="dropdownMenu",["instant","daily","divider","none"].forEach(function(t){var n=elCreate("li");if("divider"===t)n.className="dropdownDivider";else{var a=elCreate("a");a.href="#",a.textContent=e.get("wcf.user.notification.mailNotificationType."+t),n.appendChild(a),elData(n,"value",t),n.addEventListener(WCF_CLICK_EVENT,this._setEmailType.bind(this))}i.appendChild(n)}.bind(this)),t.init("UiNotificationSettingsEmailType",i))},_setCurrentEmailType:function(e){elBySelAll("li",i,function(t){var i=elData(t,"value");t.classList[i===e?"add":"remove"]("active")})},_showDropDown:function(e){t.toggleDropdown("UiNotificationSettingsEmailType",e)},_setEmailType:function(t){t.preventDefault();var i=elData(t.currentTarget,"value");this._getEmailTypeInputElement().value=i;var a=elBySel('.notificationSettingsEmailType[data-object-id="'+n+'"]');a.title=e.get("wcf.user.notification.mailNotificationType."+i);var r=elBySel(".jsIconNotificationSettingsEmailType",a);switch(r.classList.remove("fa-clock-o"),r.classList.remove("fa-flash"),r.classList.remove("fa-times"),r.classList.remove("green"),r.classList.remove("red"),i){case"daily":r.classList.add("fa-clock-o"),r.classList.add("green");break;case"instant":r.classList.add("fa-flash"),r.classList.add("green");break;case"none":r.classList.add("fa-times"),r.classList.add("red")}n=null},_getEmailTypeInputElement:function(){return elById("settings_"+n+"_mailNotificationType")}}}),define("WoltLabSuite/Core/Form/Builder/Container/SuffixFormField",["EventHandler","Ui/SimpleDropdown"],function(e,t){"use strict";function i(i,n){this._formId=i,this._suffixField=elById(n),this._suffixDropdownMenu=t.getDropdownMenu(n+"_dropdown"),this._suffixDropdownToggle=elByClass("dropdownToggle",t.getDropdown(n+"_dropdown"))[0];for(var a=this._suffixDropdownMenu.children,r=0,o=a.length;r<o;r++)a[r].addEventListener("click",this._changeSuffixSelection.bind(this));e.add("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",this._destroyDropdown.bind(this))}return i.prototype={_changeSuffixSelection:function(e){if(!e.currentTarget.classList.contains("disabled")){for(var t=this._suffixDropdownMenu.children,i=0,n=t.length;i<n;i++)t[i]===e.currentTarget?t[i].classList.add("active"):t[i].classList.remove("active");this._suffixField.value=elData(e.currentTarget,"value"),this._suffixDropdownToggle.innerHTML=elData(e.currentTarget,"label")+' <span class="icon icon16 fa-caret-down pointer"></span>'}},_destroyDropdown:function(e){e.formId===this._formId&&t.destroy(this._suffixDropdownMenu.id)}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Acl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e),this._aclList=null}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._aclList.getData(),e},_readField:function(){},setAclList:function(e){this._aclList=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Captcha",["Core","./Field","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){return i.has(this._fieldId)?i.getData(this._fieldId):{}},_readField:function(){},destroy:function(){i.has(this._fieldId)&&i.delete(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Checkboxes",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=0,i=this._fields.length;t<i;t++)this._fields[t].checked&&e[this._fieldId].push(this._fields[t].value);return e},_readField:function(){this._fields=elBySelAll('input[name="'+this._fieldId+'[]"]')}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Checked",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=~~this._field.checked,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Date",["Core","WoltLabSuite/Core/Date/Picker","./Field"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{_getData:function(){var e={};return e[this._fieldId]=t.getValue(this._field),e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/ItemList",["Core","./Field","WoltLabSuite/Core/Ui/ItemList/Static"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,a=t.length;n<a;n++)t[n].objectId?e[this._fieldId][t[n].objectId]=t[n].value:e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/RadioButton",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){for(var e={},t=0,i=this._fields.length;t<i;t++)if(this._fields[t].checked){e[this._fieldId]=this._fields[t].value;break}return e},_readField:function(){this._fields=elBySelAll("input[name="+this._fieldId+"]")}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/SimpleAcl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e=[];elBySelAll('input[name="'+this._fieldId+'[group][]"]',void 0,function(t){e.push(~~t.value)});var t=[];elBySelAll('input[name="'+this._fieldId+'[user][]"]',void 0,function(e){t.push(~~e.value)});var i={};return i[this._fieldId]={group:e,user:t},i},_readField:function(){}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Tag",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,a=t.length;n<a;n++)e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/User",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){for(var e=i.getValues(this._fieldId),t=[],n=0,a=e.length;n<a;n++)t.push(e[n].value);var r={};return r[this._fieldId]=t.join(","),r}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Value",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._field.value,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/ValueI18n",["Core","./Field","WoltLabSuite/Core/Language/Input"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={},t=i.getValues(this._fieldId);return t.size>1?e[this._fieldId+"_i18n"]=t.toObject():e[this._fieldId]=t.get(0),e},destroy:function(){i.unregister(this._fieldId)}}),n}),define("WoltLabSuite/Core/Ui/Comment/Response/Add",["Core","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Notification","WoltLabSuite/Core/Ui/Comment/Add"],function(e,t,i,n,a,r,o){"use strict";function s(e,t){this.init(e,t)}return e.inherit(s,o,{init:function(t,i){s._super.prototype.init.call(this,t),this._options=e.extend({callbackInsert:null},i)},getContainer:function(){return this._isBusy?null:this._container},getContent:function(){return window.jQuery(this._textarea).redactor("code.get")},setContent:function(e){window.jQuery(this._textarea).redactor("code.set",e),window.jQuery(this._textarea).redactor("WoltLabCaret.endOfEditor");var t=elBySel(".innerError",this._textarea.parentNode);null!==t&&elRemove(t),this._content.classList.remove("collapsed"),this._focusEditor()},_getParameters:function(){var e=s._super.prototype._getParameters.call(this);return e.data.commentID=~~elData(this._container.closest(".comment"),"object-id"),e},_insertMessage:function(e){var o=a.childByClass(this._container.parentNode,"commentContent"),s=o.nextElementSibling;return null!==s&&s.classList.contains("commentResponseList")||(s=elCreate("ul"),s.className="containerList commentResponseList",elData(s,"responses",0),o.parentNode.insertBefore(s,o.nextSibling)),n.insertHtml(e.returnValues.template,s,"append"),r.show(t.get("wcf.global.success.add")),i.trigger(),window.jQuery(this._textarea).redactor("code.set",""),null!==this._options.callbackInsert&&this._options.callbackInsert(),elData(s,"responses",s.children.length),s.lastElementChild},_ajaxSetup:function(){var e=s._super.prototype._ajaxSetup.call(this);return e.data.actionName="addResponse",e}}),s}),define("WoltLabSuite/Core/Ui/Comment/Response/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll","WoltLabSuite/Core/Ui/Comment/Edit"],function(e,t,i,n,a,r,o,s,l,c,d,u,h,f){"use strict";function p(e){this.init(e)}return t.inherit(p,f,{init:function(e){this._activeElement=null,this._callbackClick=null,this._container=e,this._editorContainer=null,this._responses=new o,this.rebuild(),s.add("Ui/Comment/Response/Edit_"+c.identify(this._container),this.rebuild.bind(this))},rebuild:function(){elBySelAll(".commentResponse",this._container,function(e){if(!this._responses.has(e)){if(elDataBool(e,"can-edit")){var t=elBySel(".jsCommentResponseEditButton",e);null!==t&&(null===this._callbackClick&&(this._callbackClick=this._click.bind(this)),t.addEventListener(WCF_CLICK_EVENT,this._callbackClick))}this._responses.add(e)}}.bind(this))},_click:function(t){t.preventDefault(),null===this._activeElement?(this._activeElement=t.currentTarget.closest(".commentResponse"),this._prepare(),e.api(this,{actionName:"beginEdit",objectIDs:[this._getObjectId(this._activeElement)]})):d.show("wcf.message.error.editorAlreadyInUse",null,"warning")},_prepare:function(){this._editorContainer=elCreate("div"),this._editorContainer.className="commentEditorContainer",this._editorContainer.innerHTML='<span class="icon icon48 fa-spinner"></span>';var e=elBySel(".commentResponseContent",this._activeElement);e.insertBefore(this._editorContainer,e.firstChild)},_showMessage:function(e){c.setInnerHtml(elBySel(".commentResponseContent .userMessage",this._editorContainer.parentNode),e.returnValues.message),this._restoreMessage(),d.show()},_getEditorId:function(){return"commentResponseEditor"+this._getObjectId(this._activeElement)},_ajaxSetup:function(){return{data:{className:"wcf\\data\\comment\\response\\CommentResponseAction",parameters:{data:{objectTypeID:~~elData(this._container,"object-type-id")}}},silent:!0}}}),p}),define("WoltLabSuite/Core/Ui/Page/Header/Fixed",["Core","EventHandler","Ui/Alignment","Ui/CloseOverlay","Ui/SimpleDropdown","Ui/Screen"],function(e,t,i,n,a,r){"use strict";var o,s,l,c,d,u,h,f=!1;return{init:function(){o=elById("pageHeader"),s=elById("pageHeaderContainer"),this._initSearchBar(),r.on("screen-md-down",{match:function(){f=!0},unmatch:function(){f=!1},setup:function(){f=!0}}),t.add("com.woltlab.wcf.Search","close",this._closeSearchBar.bind(this))},_initSearchBar:function(){c=elById("pageHeaderSearch"),c.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),l=elById("pageHeaderPanel"),d=elById("pageHeaderSearchInput"),u=elById("topMenu"),h=elById("userPanelSearchButton"),h.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),o.classList.contains("searchBarOpen")?this._closeSearchBar():this._openSearchBar()}.bind(this)),n.add("WoltLabSuite/Core/Ui/Page/Header/Fixed",function(){o.classList.contains("searchBarForceOpen")||this._closeSearchBar()}.bind(this)),t.add("com.woltlab.wcf.MainMenuMobile","more",function(t){"com.woltlab.wcf.search"===t.identifier&&(t.handler.close(!0),e.triggerEvent(h,WCF_CLICK_EVENT))}.bind(this))},_openSearchBar:function(){window.WCF.Dropdown.Interactive.Handler.closeAll(),o.classList.add("searchBarOpen"),h.parentNode.classList.add("open"),f||i.set(c,u,{horizontal:"right"}),c.style.setProperty("top",l.clientHeight+"px",""),d.focus(),window.setTimeout(function(){d.selectionStart=d.selectionEnd=d.value.length},1)},_closeSearchBar:function(){o.classList.remove("searchBarOpen"),h.parentNode.classList.remove("open"),["bottom","left","right","top"].forEach(function(e){c.style.removeProperty(e)}),d.blur();var e=elBySel(".pageHeaderSearchType",c);a.close(e.id)}}}),define("WoltLabSuite/Core/Ui/Page/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){if(n=e.extend({ajax:{className:"wcf\\data\\page\\PageAction"},callbackSuccess:null},n),"function"!=typeof n.callbackSuccess)throw new Error("Expected a valid callback function for 'callbackSuccess'.");i._super.prototype.init.call(this,t,n),this._pageId=0},setPageId:function(e){this._pageId=e},_getParameters:function(e){var t=i._super.prototype._getParameters.call(this,e);return t.objectIDs=[this._pageId],t},_ajaxSuccess:function(e){this._options.callbackSuccess(e)}}),i}),define("WoltLabSuite/Core/Ui/Page/Search/Handler",["Language","StringUtil","Dom/Util","Ui/Dialog","./Input"],function(e,t,i,n,a){"use strict";var r=null,o=null,s=null,l=null,c=null,d=null;return{open:function(t,i,a,o){r=a,n.open(this),n.setTitle(this,i),s.textContent=o?e.get(o):e.get("wcf.page.pageObjectID.search.terms"),this._getSearchInputHandler().setPageId(t)},_buildList:function(i){if(this._resetList(),!Array.isArray(i.returnValues)||0===i.returnValues.length)return void elInnerError(o,e.get("wcf.page.pageObjectID.search.noResults"));for(var n,a,r,s=0,l=i.returnValues.length;s<l;s++)a=i.returnValues[s],n=a.image,/^fa-/.test(n)&&(n='<span class="icon icon48 '+n+' pointer jsTooltip" title="'+e.get("wcf.global.select")+'"></span>'),r=elCreate("li"),elData(r,"object-id",a.objectID),r.innerHTML='<div class="box48">'+n+'<div><div class="containerHeadline"><h3><a href="'+t.escapeHTML(a.link)+'">'+t.escapeHTML(a.title)+"</a></h3>"+(a.description?"<p>"+a.description+"</p>":"")+"</div></div></div>",r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),c.appendChild(r);elShow(d)},_resetList:function(){elInnerError(o,!1),c.innerHTML="",elHide(d)},_getSearchInputHandler:function(){if(null===l){var e=this._buildList.bind(this);l=new a(elById("wcfUiPageSearchInput"),{callbackSuccess:e})}return l},_click:function(e){"A"!==e.target.nodeName&&(e.stopPropagation(),r(elData(e.currentTarget,"object-id")),n.close(this))},_dialogSetup:function(){return{id:"wcfUiPageSearchHandler",options:{onShow:function(){null===o&&(o=elById("wcfUiPageSearchInput"),s=o.parentNode.previousSibling.childNodes[0],c=elById("wcfUiPageSearchResultList"),d=elById("wcfUiPageSearchResultListContainer")),o.value="",elHide(d),c.innerHTML="",o.focus()},title:""},source:'<div class="section"><dl><dt><label for="wcfUiPageSearchInput">'+e.get("wcf.page.pageObjectID.search.terms")+'</label></dt><dd><input type="text" id="wcfUiPageSearchInput" class="long"></dd></dl></div><section id="wcfUiPageSearchResultListContainer" class="section sectionContainerList"><header class="sectionHeader"><h2 class="sectionTitle">'+e.get("wcf.page.pageObjectID.search.results")+'</h2></header><ul id="wcfUiPageSearchResultList" class="containerList wcfUiPageSearchResultList"></ul></section>'}}}}),define("WoltLabSuite/Core/Ui/Reaction/Profile/Loader",["Ajax","Core","Language"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){if(this._container=elById("likeList"),this._userID=e,this._reactionTypeID=null,this._targetType="received",this._options={parameters:[]},!this._userID)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'userID' given.");var t=elCreate("li");t.className="likeListMore showMore",this._noMoreEntries=elCreate("small"),this._noMoreEntries.innerHTML=i.get("wcf.like.reaction.noMoreEntries"),this._noMoreEntries.style.display="none",t.appendChild(this._noMoreEntries),this._loadButton=elCreate("button"),this._loadButton.className="small",this._loadButton.innerHTML=i.get("wcf.like.reaction.more"),this._loadButton.addEventListener(WCF_CLICK_EVENT,this._loadReactions.bind(this)),this._loadButton.style.display="none",t.appendChild(this._loadButton),this._container.appendChild(t),2===elBySel("#likeList > li").length?this._noMoreEntries.style.display="":this._loadButton.style.display="",this._setupReactionTypeButtons(),this._setupTargetTypeButtons()},_setupReactionTypeButtons:function(){for(var e,t=elBySelAll("#reactionType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeReactionTypeValue.bind(this,~~elData(e,"reaction-type-id")))},_setupTargetTypeButtons:function(){for(var e,t=elBySelAll("#likeType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeTargetType.bind(this,elData(e,"like-type")))},_changeTargetType:function(e){if("given"!==e&&"received"!==e)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'targetType' given.");e!==this._targetType&&(elBySel("#likeType .button.active").classList.remove("active"),elBySel('#likeType .button[data-like-type="'+e+'"]').classList.add("active"),this._targetType=e,this._reload())},_changeReactionTypeValue:function(e){var t=elBySel("#reactionType .button.active");t&&t.classList.remove("active"),this._reactionTypeID!==e?(elBySel('#reactionType .button[data-reaction-type-id="'+e+'"]').classList.add("active"),this._reactionTypeID=e):this._reactionTypeID=null,this._reload()},_reload:function(){for(var e=elBySelAll("#likeList > li:not(:first-child):not(:last-child)"),t=0,i=e.length;t<i;t++)this._container.removeChild(e[t]);elData(this._container,"last-like-time",0),this._loadReactions()},_loadReactions:function(){this._options.parameters.userID=this._userID,this._options.parameters.lastLikeTime=elData(this._container,"last-like-time"),this._options.parameters.targetType=this._targetType,this._options.parameters.reactionTypeID=this._reactionTypeID,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){e.returnValues.template?(elBySel("#likeList > li:nth-last-child(1)").insertAdjacentHTML("beforebegin",e.returnValues.template),elData(this._container,"last-like-time",e.returnValues.lastLikeTime),this._noMoreEntries.style.display="none",this._loadButton.style.display=""):(this._noMoreEntries.style.display="",this._loadButton.style.display="none")},_ajaxSetup:function(){return{data:{actionName:"load",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/Activity/Recent",["Ajax","Language","Dom/Util"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){this._containerId=e;var i=elById(this._containerId);this._list=elBySel(".recentActivityList",i);var n=elCreate("li");n.className="showMore",this._list.childElementCount?(n.innerHTML='<button class="small">'+t.get("wcf.user.recentActivity.more")+"</button>",n.children[0].addEventListener(WCF_CLICK_EVENT,this._showMore.bind(this))):n.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>",this._list.appendChild(n),this._showMoreItem=n,elBySelAll(".jsRecentActivitySwitchContext .button",i,function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),e.classList.contains("active")||this._switchContext()}.bind(this))}.bind(this))},_showMore:function(t){t.preventDefault(),this._showMoreItem.children[0].disabled=!0,e.api(this,{actionName:"load",parameters:{boxID:~~elData(this._list,"box-id"),filteredByFollowedUsers:elDataBool(this._list,"filtered-by-followed-users"),lastEventId:elData(this._list,"last-event-id"),lastEventTime:elData(this._list,"last-event-time"),userID:~~elData(this._list,"user-id")}})},_switchContext:function(){e.api(this,{actionName:"switchContext"},function(){window.location.hash="#"+this._containerId,window.location.reload()}.bind(this))},_ajaxSuccess:function(e){e.returnValues.template?(i.insertHtml(e.returnValues.template,this._showMoreItem,"before"),elData(this._list,"last-event-time",e.returnValues.lastEventTime),elData(this._list,"last-event-id",e.returnValues.lastEventID),this._showMoreItem.children[0].disabled=!1):this._showMoreItem.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>"},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Delete",["Ajax","EventHandler","Language","Ui/Confirmation","Ui/Notification"],function(e,t,i,n,a){"use strict";var r,o=0;return{init:function(e){r=elBySel(".jsButtonDeleteCoverPhoto"),r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),o=e,t.add("com.woltlab.wcf.user","coverPhoto",function(e){"string"==typeof e.url&&e.url.length>0&&elShow(r.parentNode)})},_click:function(t){t.preventDefault(),n.show({confirm:e.api.bind(e,this),message:i.get("wcf.user.coverPhoto.delete.confirmMessage")})},_ajaxSuccess:function(e){elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+e.returnValues.url+")",""),elHide(r.parentNode),a.show()},_ajaxSetup:function(){return{data:{actionName:"deleteCoverPhoto",className:"wcf\\data\\user\\UserProfileAction",
+parameters:{userID:o}}}}}}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Upload",["Core","EventHandler","Upload","Ui/Notification","Ui/Dialog"],function(e,t,i,n,a){"use strict";function r(e){i.call(this,"coverPhotoUploadButtonContainer","coverPhotoUploadPreview",{action:"uploadCoverPhoto",className:"wcf\\data\\user\\UserProfileAction"}),this._userId=e}return e.inherit(r,i,{_getParameters:function(){return{userID:this._userId}},_success:function(e,i){elInnerError(this._button,i.returnValues.errorMessage),this._target.innerHTML="",i.returnValues.url&&(elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+i.returnValues.url+")",""),a.close("userProfileCoverPhotoUpload"),n.show(),t.fire("com.woltlab.wcf.user","coverPhoto",{url:i.returnValues.url}))}}),r}),define("WoltLabSuite/Core/Ui/User/Trophy/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination","Dom/ChangeListener","List"],function(e,t,i,n,a,r,o,s){"use strict";function l(){this.init()}return l.prototype={init:function(){this._cache=new i,this._knownElements=new s,this._options={className:"wcf\\data\\user\\trophy\\UserTrophyAction",parameters:{}},this._rebuild(),o.add("WoltLabSuite/Core/Ui/User/Trophy/List",this._rebuild.bind(this))},_rebuild:function(){elBySelAll(".userTrophyOverlayList",void 0,function(e){this._knownElements.has(e)||(e.addEventListener(WCF_CLICK_EVENT,this._open.bind(this,elData(e,"user-id"))),this._knownElements.add(e))}.bind(this))},_open:function(e,t){t.preventDefault(),this._currentPageNo=1,this._currentUser=e,this._showPage()},_showPage:function(t){if(void 0!==t&&(this._currentPageNo=t),this._cache.has(this._currentUser)){if(0!==this._cache.get(this._currentUser).get("pageCount")&&(this._currentPageNo<1||this._currentPageNo>this._cache.get(this._currentUser).get("pageCount")))throw new RangeError("pageNo must be between 1 and "+this._cache.get(this._currentUser).get("pageCount")+" ("+this._currentPageNo+" given).")}else this._cache.set(this._currentUser,new i);if(this._cache.get(this._currentUser).has(this._currentPageNo)){var n=a.open(this,this._cache.get(this._currentUser).get(this._currentPageNo));if(a.setTitle("userTrophyListOverlay",this._cache.get(this._currentUser).get("title")),this._cache.get(this._currentUser).get("pageCount")>1){var o=elBySel(".jsPagination",n.content);null!==o&&new r(o,{activePage:this._currentPageNo,maxPage:this._cache.get(this._currentUser).get("pageCount"),callbackSwitch:this._showPage.bind(this)})}}else this._options.parameters.pageNo=this._currentPageNo,this._options.parameters.userID=this._currentUser,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&this._cache.get(this._currentUser).set("pageCount",~~e.returnValues.pageCount),this._cache.get(this._currentUser).set(this._currentPageNo,e.returnValues.template),this._cache.get(this._currentUser).set("title",e.returnValues.title),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserTrophyList",className:this._options.className}}},_dialogSetup:function(){return{id:"userTrophyListOverlay",options:{title:""},source:null}}},l}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Label",["Core","Dom/Util","Language","Ui/SimpleDropdown"],function(e,t,i,n){"use strict";function a(e,t,i){this.init(e,t,i)}return a.prototype={init:function(a,r,o){this._formFieldContainer=elById(a+"Container"),this._labelChooser=elByClass("labelChooser",this._formFieldContainer)[0],this._options=e.extend({forceSelection:!1,showWithoutSelection:!1},o),this._input=elCreate("input"),this._input.type="hidden",this._input.id=a,this._input.name=a,this._input.value=~~r,this._formFieldContainer.appendChild(this._input);var s=t.identify(this._labelChooser),l=n.getDropdownMenu(s);null===l&&(n.init(elByClass("dropdownToggle",this._labelChooser)[0]),l=n.getDropdownMenu(s));var c=null;if(this._options.showWithoutSelection||!this._options.forceSelection){c=elCreate("ul"),l.appendChild(c);var d=elCreate("li");d.className="dropdownDivider",c.appendChild(d)}if(this._options.showWithoutSelection){var u=elCreate("li");elData(u,"label-id",-1),this._blockScroll(u),c.appendChild(u);var h=elCreate("span");u.appendChild(h);var f=elCreate("span");f.className="badge label",f.innerHTML=i.get("wcf.label.withoutSelection"),h.appendChild(f)}if(!this._options.forceSelection){var u=elCreate("li");elData(u,"label-id",0),this._blockScroll(u),c.appendChild(u);var h=elCreate("span");u.appendChild(h);var f=elCreate("span");f.className="badge label",f.innerHTML=i.get("wcf.label.none"),h.appendChild(f)}elBySelAll("li:not(.dropdownDivider)",l,function(e){e.addEventListener("click",this._click.bind(this)),r&&~~elData(e,"label-id")===r&&this._selectLabel(e)}.bind(this))},_blockScroll:function(e){e.addEventListener("wheel",function(e){e.preventDefault()},{passive:!1})},_click:function(e){e.preventDefault(),this._selectLabel(e.currentTarget,!1)},_selectLabel:function(e){var t=elData(e,"label-id");t||(t=0);var i=elBySel("span > span",e),n=elBySel(".dropdownToggle > span",this._labelChooser);n.className=i.className,n.textContent=i.textContent,this._input.value=t}},a}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Rating",["Dictionary","Environment"],function(e,t){"use strict";function i(e,t,i,n){this.init(e,t,i,n)}return i.prototype={init:function(t,i,n,a){if(this._field=elBySel("#"+t+"Container"),null===this._field)throw new Error("Unknown field with id '"+t+"'");this._input=elCreate("input"),this._input.id=t,this._input.name=t,this._input.type="hidden",this._input.value=i,this._field.appendChild(this._input),this._activeCssClasses=n,this._defaultCssClasses=a,this._ratingElements=new e;var r=elBySel(".ratingList",this._field);r.addEventListener("mouseleave",this._restoreRating.bind(this)),elBySelAll("li",r,function(e){e.classList.contains("ratingMetaButton")?(e.addEventListener("click",this._metaButtonClick.bind(this)),e.addEventListener("mouseenter",this._restoreRating.bind(this))):(this._ratingElements.set(~~elData(e,"rating"),e),e.addEventListener("click",this._listItemClick.bind(this)),e.addEventListener("mouseenter",this._listItemMouseEnter.bind(this)),e.addEventListener("mouseleave",this._listItemMouseLeave.bind(this)))}.bind(this))},_listItemClick:function(e){this._input.value=~~elData(e.currentTarget,"rating"),"desktop"!==t.platform()&&this._restoreRating()},_listItemMouseEnter:function(e){var t=elData(e.currentTarget,"rating");this._ratingElements.forEach(function(e,i){var n=elByClass("icon",e)[0];this._toggleIcon(n,~~i<=~~t)}.bind(this))},_listItemMouseLeave:function(){this._ratingElements.forEach(function(e){var t=elByClass("icon",e)[0];this._toggleIcon(t,!1)}.bind(this))},_metaButtonClick:function(e){"removeRating"===elData(e.currentTarget,"action")&&(this._input.value="",this._listItemMouseLeave())},_restoreRating:function(){this._ratingElements.forEach(function(e,t){var i=elByClass("icon",e)[0];this._toggleIcon(i,~~t<=~~this._input.value)}.bind(this))},_toggleIcon:function(e,t){if(t=t||!1){for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.remove(this._defaultCssClasses[i]);for(var i=0;i<this._activeCssClasses.length;i++)e.classList.add(this._activeCssClasses[i])}else{for(var i=0;i<this._activeCssClasses.length;i++)e.classList.remove(this._activeCssClasses[i]);for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.add(this._defaultCssClasses[i])}}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract",["./Manager"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={checkDependency:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract.checkDependency!")},getDependentNode:function(){return this._dependentElement},getField:function(){return this._field},getFields:function(){return this._fields},init:function(t,i){if(this._dependentElement=elById(t),null===this._dependentElement)throw new Error("Unknown dependent element with container id '"+t+"Container'.");if(this._field=elById(i),null===this._field){if(this._fields=[],elBySelAll("input[type=radio][name="+i+"]",void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length&&(elBySelAll('input[type=checkbox][name="'+i+'[]"]',void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length))throw new Error("Unknown field with id '"+i+"'.")}else if(this._fields=[this._field],"INPUT"===this._field.tagName&&"radio"===this._field.type&&""!==elData(this._field,"no-input-id")){if(this._noField=elById(elData(this._field,"no-input-id")),null===this._noField)throw new Error("Cannot find 'no' input field for input field '"+i+"'");this._fields.push(this._noField)}e.addDependency(this)}},t}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Empty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!1;return!0}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return!this._field.checked;case"radio":return!(!this._noField||!this._noField.checked)||!this._field.checked;default:return 0===this._field.value.trim().length}case"SELECT":return this._field.multiple?0===elBySelAll("option:checked",this._field).length:0==this._field.value||0===this._field.value.length;case"TEXTAREA":return 0===this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/NonEmpty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!0;return!1}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return this._field.checked;case"radio":return(!this._noField||!this._noField.checked)&&this._field.checked;default:return 0!==this._field.value.trim().length}case"SELECT":return this._field.multiple?0!==elBySelAll("option:checked",this._field).length:0!=this._field.value&&0!==this._field.value.length;case"TEXTAREA":return 0!==this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Value",["./Abstract","Core","./Manager"],function(e,t,i){"use strict";function n(e,t,i){this.init(e,t),this._isNegated=!1}return t.inherit(n,e,{checkDependency:function(){if(!this._values)throw new Error("Values have not been set.");var e=[];if(this._field){if(i.isHiddenByDependencies(this._field))return!1;e.push(this._field.value)}else for(var t,n=0,a=this._fields.length;n<a;n++)if(t=this._fields[n],t.checked){if(i.isHiddenByDependencies(t))return!1;e.push(t.value)}for(var n=0,a=this._values.length;n<a;n++)for(var r=0,o=e.length;r<o;r++)if(this._values[n]==e[r])return!this._isNegated;return!!this._isNegated},negate:function(e){return this._isNegated=e,this},values:function(e){return this._values=e,this}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage",["Core","WoltLabSuite/Core/Language/Chooser","../Value"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{destroy:function(){t.removeChooser(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Attachment",["Core","../Value"],function(e,t){"use strict";function i(e){this.init(e+"_tmpHash")}return e.inherit(i,t,{}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Poll",["Core","../Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){return this._pollEditor.getData()},_readField:function(){},setPollEditor:function(e){this._pollEditor=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Abstract",["EventHandler","../Manager"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={checkContainer:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Container.checkContainer!")},init:function(e){if("string"!=typeof e)throw new TypeError("Container id has to be a string.");if(this._container=elById(e),null===this._container)throw new Error("Unknown container with id '"+e+"'.");t.addContainerCheckCallback(this.checkContainer.bind(this))}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default",["./Abstract","Core","../Manager"],function(e,t,i){"use strict";function n(e){this.init(e)}return t.inherit(n,e,{checkContainer:function(){if(!elDataBool(this._container,"ignore-dependencies")&&!i.isHiddenByDependencies(this._container)){var e=!elIsHidden(this._container),t=!1,n=this._container.children,a=0;if("H2"===this._container.children.item(0).tagName||"HEADER"===this._container.children.item(0).tagName)var a=1;for(var r=a,o=n.length;r<o;r++)if(!elIsHidden(n.item(r))){t=!0;break}e!==t&&(t?elShow(this._container):elHide(this._container),i.checkContainers())}}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Tab",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,a){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=this._container.children,o=0,s=r.length;o<s;o++)if(!elIsHidden(r.item(o))){t=!0;break}if(e!==t){var l=elBySel("#"+i.identify(this._container.parentNode)+" > nav > ul > li[data-name="+this._container.id+"]",this._container.parentNode.parentNode);if(null===l)throw new Error("Cannot find tab menu entry for tab '"+this._container.id+"'.");if(t)elShow(this._container),elShow(l);else{elHide(this._container),elHide(l);var c=a.getTabMenu(i.identify(l.closest(".tabMenuContainer")));c.getActiveTab()===l&&c.selectFirstVisible()}n.checkContainers()}}}}),r}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/TabMenu",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,a){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=elBySelAll("#"+i.identify(this._container)+" > nav > ul > li",this._container.parentNode),o=0,s=r.length;o<s;o++)if(!elIsHidden(r[o])){t=!0;break}e!==t&&(t?(elShow(this._container),a.getTabMenu(i.identify(this._container)).selectFirstVisible()):elHide(this._container),n.checkContainers())}}}),r}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Abstract",["Ajax","Dom/Util"],function(e,t){"use strict";function i(e,t){}return i.prototype={init:function(e,t){this._userId=e,this._isActive=!1!==t,this._initButton(),this._updateButton()},_initButton:function(){var e=elCreate("a");e.href="#",e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this));var i=elCreate("li");i.appendChild(e);var n=elBySel('.userProfileButtonMenu[data-menu="interaction"]');t.prepend(i,n),this._button=e,this._listItem=i},_toggle:function(t){t.preventDefault(),e.api(this,{actionName:this._getAjaxActionName(),parameters:{data:{userID:this._userId}}})},_updateButton:function(){this._button.textContent=this._getLabel(),this._listItem.classList[this._isActive?"add":"remove"]("active")},_getLabel:function(){throw new Error("Implement me!")},_getAjaxActionName:function(){throw new Error("Implement me!")},_ajaxSuccess:function(){throw new Error("Implement me!")},_ajaxSetup:function(){throw new Error("Implement me!")}},i}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Follow",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";function a(e,t){this.init(e,t)}return e.inherit(a,n,{_getLabel:function(){return t.get("wcf.user.button."+(this._isActive?"un":"")+"follow")},_getAjaxActionName:function(){return this._isActive?"unfollow":"follow"},_ajaxSuccess:function(e){this._isActive=!!e.returnValues.following,this._updateButton(),i.show()},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\follow\\UserFollowAction"}}}}),a}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Ignore",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";function a(e,t){this.init(e,t)}return e.inherit(a,n,{_getLabel:function(){return t.get("wcf.user.button."+(this._isActive?"un":"")+"ignore")},_getAjaxActionName:function(){return this._isActive?"unignore":"ignore"},_ajaxSuccess:function(e){this._isActive=!!e.returnValues.isIgnoredUser,this._updateButton(),i.show()},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\ignore\\UserIgnoreAction"}}}}),a}),function(e){e.matches=e.matches||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector,e.closest=e.closest||function(e){for(var t=this;t&&!t.matches(e);)t=t.parentElement;return t}}(Element.prototype),define("closest",function(){}),function(e){function t(){for(;n.length&&"function"==typeof n[0];)n.shift()()}var i=e.require,n=[],a=0;e.orgRequire=i,e.require=function(r,o,s){if(!Array.isArray(r))return i.apply(e,arguments);var l=new Promise(function(e,o){var s=a++;n.push(s),i(r,function(){var i=arguments;n[n.indexOf(s)]=function(){e(i)},t()},function(e){n[n.indexOf(s)]=function(){o(e)},t()})});return o&&(l=l.then(function(t){return o.apply(e,t)})),s&&l.catch(s),l},e.require.config=i.config}(window),define("require.linearExecution",function(){});
\ No newline at end of file
index 40ea9aa18bb97072ade522c91d8f162bcaaf50d3..d9be76e3a212859ab27a126d3593f1dddf15e11d 100644 (file)
@@ -3,16 +3,16 @@
 
 
 // WoltLabSuite.Core.tiny.min.js
-var requirejs,require,define;!function(global,Promise,undef){function commentReplace(e,t){return t||""}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return e&&hasProp(e,t)&&e[t]}function obj(){return Object.create(null)}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,n){return t&&eachProp(t,function(t,o){!i&&hasProp(e,o)||(!n||"object"!=typeof t||!t||Array.isArray(t)||"function"==typeof t||t instanceof RegExp?e[o]=t:(e[o]||(e[o]={}),mixin(e[o],t,i,n)))}),e}function getGlobal(e){if(!e)return e;var t=global;return e.split(".").forEach(function(e){t=t[e]}),t}function newContext(e){function t(e){var t,i,n=e.length;for(t=0;t<n;t++)if("."===(i=e[t]))e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;t>0&&(e.splice(t-1,2),t-=2)}}function i(e,i,n){var o,r,a,l,s,c,u,d,h,f,p=i&&i.split("/"),g=p,m=k.map,v=m&&m["*"];if(e&&(e=e.split("/"),c=e.length-1,k.nodeIdCompat&&jsSuffixRegExp.test(e[c])&&(e[c]=e[c].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&p&&(g=p.slice(0,p.length-1),e=g.concat(e)),t(e),e=e.join("/")),n&&m&&(p||v)){r=e.split("/");e:for(a=r.length;a>0;a-=1){if(s=r.slice(0,a).join("/"),p)for(l=p.length;l>0;l-=1)if((o=getOwn(m,p.slice(0,l).join("/")))&&(o=getOwn(o,s))){u=o,d=a;break e}!h&&v&&getOwn(v,s)&&(h=getOwn(v,s),f=a)}!u&&h&&(u=h,d=f),u&&(r.splice(0,d,u),e=r.join("/"))}return getOwn(k.pkgs,e)||e}function n(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t}function o(e){var t,i,n,o;for(t=0;t<queue.length;t+=1){if("string"!=typeof queue[t][0]){if(!e)break;queue[t].unshift(e),e=undef}n=queue.shift(),i=n[0],t-=1,i in D||i in T||(i in N?C.apply(undef,n):T[i]=n)}e&&(o=getOwn(k.shim,e)||{},C(e,o.deps||[],o.exportsFn))}function r(e,t){var n=function(i,r,a,l){var s,c;if(t&&o(),"string"==typeof i){if(A[i])return A[i](e);if(!((s=E(i,e,!0).id)in D))throw new Error("Not loaded: "+s);return D[s]}return i&&!Array.isArray(i)&&(c=i,i=undef,Array.isArray(r)&&(i=r,r=a,a=l),t)?n.config(c)(i,r,a):(r=r||function(){return slice.call(arguments,0)},V.then(function(){return o(),C(undef,i||[],r,a,e)}))};return n.isBrowser="undefined"!=typeof document&&"undefined"!=typeof navigator,n.nameToUrl=function(e,t,i){var o,r,a,l,s,c,u,d=getOwn(k.pkgs,e);if(d&&(e=d),u=getOwn(R,e))return n.nameToUrl(u,t,i);if(urlRegExp.test(e))s=e+(t||"");else{for(o=k.paths,r=e.split("/"),a=r.length;a>0;a-=1)if(l=r.slice(0,a).join("/"),c=getOwn(o,l)){Array.isArray(c)&&(c=c[0]),r.splice(0,a,c);break}s=r.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+s}return k.urlArgs&&!/^blob\:/.test(s)?s+k.urlArgs(e,s):s},n.toUrl=function(t){var o,r=t.lastIndexOf("."),a=t.split("/")[0],l="."===a||".."===a;return-1!==r&&(!l||r>1)&&(o=t.substring(r,t.length),t=t.substring(0,r)),n.nameToUrl(i(t,e),o,!0)},n.defined=function(t){return E(t,e,!0).id in D},n.specified=function(t){return(t=E(t,e,!0).id)in D||t in N},n}function a(e,t,i){e&&(D[e]=i,requirejs.onResourceLoad&&requirejs.onResourceLoad(I,t.map,t.deps)),t.finished=!0,t.resolve(i)}function l(e,t){e.finished=!0,e.rejected=!0,e.reject(t)}function s(e){return function(t){return i(t,e,!0)}}function c(e){e.factoryCalled=!0;var t,i=e.map.id;try{t=I.execCb(i,e.factory,e.values,D[i])}catch(t){return l(e,t)}i?t===undef&&(e.cjsModule?t=e.cjsModule.exports:e.usingExports&&(t=D[i])):M.splice(M.indexOf(e),1),a(i,e,t)}function u(e,t){this.rejected||this.depDefined[t]||(this.depDefined[t]=!0,this.depCount+=1,this.values[t]=e,this.depending||this.depCount!==this.depMax||c(this))}function d(e,t){var i={};return i.promise=new Promise(function(t,n){i.resolve=t,i.reject=function(t){e||M.splice(M.indexOf(i),1),n(t)}}),i.map=e?t||E(e):{},i.depCount=0,i.depMax=0,i.values=[],i.depDefined=[],i.depFinished=u,i.map.pr&&(i.deps=[E(i.map.pr)]),i}function h(e,t){var i;return e?(i=e in N&&N[e])||(i=N[e]=d(e,t)):(i=d(),M.push(i)),i}function f(e,t){return function(i){e.rejected||(i.dynaId||(i.dynaId="id"+(F+=1),i.requireModules=[t]),l(e,i))}}function p(e,t,i,n){i.depMax+=1,L(e,t).then(function(e){i.depFinished(e,n)},f(i,e.id)).catch(f(i,i.map.id))}function g(e){function t(t){i||a(e,h(e),t)}var i;return t.error=function(t){h(e).reject(t)},t.fromText=function(t,n){var r=h(e),a=E(E(e).n),s=a.id;i=!0,r.factory=function(e,t){return t},n&&(t=n),hasProp(k.config,e)&&(k.config[s]=k.config[e]);try{w.exec(t)}catch(e){l(r,new Error("fromText eval for "+s+" failed: "+e))}o(s),r.deps=[a],p(a,null,r,r.deps.length)},t}function m(e,t,i){e.load(t.n,r(i),g(t.id),k)}function v(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function b(e,t,i){var n=e.map.id;t[n]=!0,!e.finished&&e.deps&&e.deps.forEach(function(n){var o=n.id,r=!hasProp(A,o)&&h(o,n);!r||r.finished||i[o]||(hasProp(t,o)?e.deps.forEach(function(t,i){t.id===o&&e.depFinished(D[o],i)}):b(r,t,i))}),i[n]=!0}function _(e){var t,i,n,o=[],r=1e3*k.waitSeconds,a=r&&W+r<(new Date).getTime();if(0===j&&(e?e.finished||b(e,{},{}):M.length&&M.forEach(function(e){b(e,{},{})})),a){for(i in N)n=N[i],n.finished||o.push(n.map.id);t=new Error("Timeout for modules: "+o),t.requireModules=o,w.onError(t)}else(j||M.length)&&(S||(S=!0,setTimeout(function(){S=!1,_()},70)))}function y(e){return setTimeout(function(){e.dynaId&&O[e.dynaId]||(O[e.dynaId]=!0,w.onError(e))}),e}var w,C,E,L,A,S,x,I,D=obj(),T=obj(),k={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},B=obj(),M=[],N=obj(),U=obj(),P=obj(),j=0,W=(new Date).getTime(),F=0,O=obj(),H=obj(),R=obj(),V=Promise.resolve();return x="function"==typeof importScripts?function(e){var t=e.url;H[t]||(H[t]=!0,h(e.id),importScripts(t),o(e.id))}:function(e){var t,i=e.id,n=e.url;H[n]||(H[n]=!0,t=document.createElement("script"),t.setAttribute("data-requiremodule",i),t.type=k.scriptType||"text/javascript",t.charset="utf-8",t.async=!0,j+=1,t.addEventListener("load",function(){j-=1,o(i)},!1),t.addEventListener("error",function(){j-=1;var e,n=getOwn(k.paths,i);if(n&&Array.isArray(n)&&n.length>1){t.parentNode.removeChild(t),n.shift();var o=h(i);o.map=E(i),o.map.url=w.nameToUrl(i),x(o.map)}else e=new Error("Load failed: "+i+": "+t.src),e.requireModules=[i],h(i).reject(e)},!1),t.src=n,10===document.documentMode?asap.then(function(){document.head.appendChild(t)}):document.head.appendChild(t))},L=function(e,t){var i,n,o=e.id,r=k.shim[o];if(o in T)i=T[o],delete T[o],C.apply(undef,i);else if(!(o in N))if(e.pr){if(!(n=getOwn(R,o)))return L(E(e.pr)).then(function(i){var n=e.prn?e:E(o,t,!0),r=n.id,a=getOwn(k.shim,r);return r in P||(P[r]=!0,a&&a.deps?w(a.deps,function(){m(i,n,t)}):m(i,n,t)),h(r).promise});e.url=w.nameToUrl(n),x(e)}else r&&r.deps?w(r.deps,function(){x(e)}):x(e);return h(o).promise},E=function(e,t,n){if("string"!=typeof e)return e;var o,r,a,l,c,u,d=e+" & "+(t||"")+" & "+!!n;return a=v(e),l=a[0],e=a[1],!l&&d in B?B[d]:(l&&(l=i(l,t,n),o=l in D&&D[l]),l?o&&o.normalize?(e=o.normalize(e,s(t)),u=!0):e=-1===e.indexOf("!")?i(e,t,n):e:(e=i(e,t,n),a=v(e),l=a[0],e=a[1],r=w.nameToUrl(e)),c={id:l?l+"!"+e:e,n:e,pr:l,url:r,prn:l&&u},l||(B[d]=c),c)},A={require:function(e){return r(e)},exports:function(e){var t=D[e];return void 0!==t?t:D[e]={}},module:function(e){return{id:e,uri:"",exports:A.exports(e),config:function(){return getOwn(k.config,e)||{}}}}},C=function(e,t,i,n,o){if(e){if(e in U)return;U[e]=!0}var r=h(e);return t&&!Array.isArray(t)&&(i=t,t=[]),t=t?slice.call(t,0):null,n||(hasProp(k,"defaultErrback")?k.defaultErrback&&(n=k.defaultErrback):n=y),n&&r.promise.catch(n),o=o||e,"function"==typeof i?(!t.length&&i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t)),r.factory=i,r.deps=t,r.depending=!0,t.forEach(function(i,n){var a;t[n]=a=E(i,o,!0),i=a.id,"require"===i?r.values[n]=A.require(e):"exports"===i?(r.values[n]=A.exports(e),r.usingExports=!0):"module"===i?r.values[n]=r.cjsModule=A.module(e):void 0===i?r.values[n]=void 0:p(a,o,r,n)}),r.depending=!1,r.depCount===r.depMax&&c(r)):e&&a(e,r,i),W=(new Date).getTime(),e||_(r),r.promise},w=r(null,!0),w.config=function(t){if(t.context&&t.context!==e){var i=getOwn(contexts,t.context);return i?i.req.config(t):newContext(t.context).config(t)}if(B=obj(),t.baseUrl&&"/"!==t.baseUrl.charAt(t.baseUrl.length-1)&&(t.baseUrl+="/"),"string"==typeof t.urlArgs){var o=t.urlArgs;t.urlArgs=function(e,t){return(-1===t.indexOf("?")?"?":"&")+o}}var r=k.shim,a={paths:!0,bundles:!0,config:!0,map:!0};return eachProp(t,function(e,t){a[t]?(k[t]||(k[t]={}),mixin(k[t],e,!0,!0)):k[t]=e}),t.bundles&&eachProp(t.bundles,function(e,t){e.forEach(function(e){e!==t&&(R[e]=t)})}),t.shim&&(eachProp(t.shim,function(e,t){Array.isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=n(e)),r[t]=e}),k.shim=r),t.packages&&t.packages.forEach(function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(k.paths[i]=e.location),k.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),(t.deps||t.callback)&&w(t.deps,t.callback),w},w.onError=function(e){throw e},I={id:e,defined:D,waiting:T,config:k,deferreds:N,req:w,execCb:function(e,t,i,n){return t.apply(n,i)}},contexts[e]=I,w}if(!Promise)throw new Error("No Promise implementation available");var topReq,dataMain,src,subPath,bootstrapConfig=requirejs||require,hasOwn=Object.prototype.hasOwnProperty,contexts={},queue=[],currDirRegExp=/^\.\//,urlRegExp=/^\/|\:|\?|\.js$/,commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,slice=Array.prototype.slice;if("function"!=typeof requirejs){var asap=Promise.resolve(void 0);requirejs=topReq=newContext("_"),"function"!=typeof require&&(require=topReq),topReq.exec=function(text){return eval(text)},topReq.contexts=contexts,define=function(){queue.push(slice.call(arguments,0))},define.amd={jQuery:!0},bootstrapConfig&&topReq.config(bootstrapConfig),topReq.isBrowser&&!contexts._.config.skipDataMain&&(dataMain=document.querySelectorAll("script[data-main]")[0],(dataMain=dataMain&&dataMain.getAttribute("data-main"))&&(dataMain=dataMain.replace(jsSuffixRegExp,""),bootstrapConfig&&bootstrapConfig.baseUrl||-1!==dataMain.indexOf("!")||(src=dataMain.split("/"),dataMain=src.pop(),subPath=src.length?src.join("/")+"/":"./",topReq.config({baseUrl:subPath})),topReq([dataMain])))}}(this,"undefined"!=typeof Promise?Promise:void 0),define("requireLib",function(){}),requirejs.config({paths:{enquire:"3rdParty/enquire",favico:"3rdParty/favico","perfect-scrollbar":"3rdParty/perfect-scrollbar",Pica:"3rdParty/pica",prism:"3rdParty/prism"},shim:{enquire:{exports:"enquire"},favico:{exports:"Favico"},"perfect-scrollbar":{exports:"PerfectScrollbar"}},map:{"*":{Ajax:"WoltLabSuite/Core/Ajax",AjaxJsonp:"WoltLabSuite/Core/Ajax/Jsonp",AjaxRequest:"WoltLabSuite/Core/Ajax/Request",CallbackList:"WoltLabSuite/Core/CallbackList",ColorUtil:"WoltLabSuite/Core/ColorUtil",Core:"WoltLabSuite/Core/Core",DateUtil:"WoltLabSuite/Core/Date/Util",Devtools:"WoltLabSuite/Core/Devtools",Dictionary:"WoltLabSuite/Core/Dictionary","Dom/ChangeListener":"WoltLabSuite/Core/Dom/Change/Listener","Dom/Traverse":"WoltLabSuite/Core/Dom/Traverse","Dom/Util":"WoltLabSuite/Core/Dom/Util",Environment:"WoltLabSuite/Core/Environment",EventHandler:"WoltLabSuite/Core/Event/Handler",EventKey:"WoltLabSuite/Core/Event/Key",Language:"WoltLabSuite/Core/Language",List:"WoltLabSuite/Core/List",ObjectMap:"WoltLabSuite/Core/ObjectMap",Permission:"WoltLabSuite/Core/Permission",StringUtil:"WoltLabSuite/Core/StringUtil","Ui/Alignment":"WoltLabSuite/Core/Ui/Alignment","Ui/CloseOverlay":"WoltLabSuite/Core/Ui/CloseOverlay","Ui/Confirmation":"WoltLabSuite/Core/Ui/Confirmation","Ui/Dialog":"WoltLabSuite/Core/Ui/Dialog","Ui/Notification":"WoltLabSuite/Core/Ui/Notification","Ui/ReusableDropdown":"WoltLabSuite/Core/Ui/Dropdown/Reusable","Ui/Screen":"WoltLabSuite/Core/Ui/Screen","Ui/Scroll":"WoltLabSuite/Core/Ui/Scroll","Ui/SimpleDropdown":"WoltLabSuite/Core/Ui/Dropdown/Simple","Ui/TabMenu":"WoltLabSuite/Core/Ui/TabMenu",Upload:"WoltLabSuite/Core/Upload",User:"WoltLabSuite/Core/User"}},waitSeconds:0}),define("jquery",[],function(){return window.jQuery}),define("require.config",function(){}),function(e,t){e.elAttr=function(e,t,i){if(void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elAttrBool=function(e,t){var i=elAttr(e,t);return"1"===i||"true"===i},e.elByClass=function(e,i){return(i||t).getElementsByClassName(e)},e.elById=function(e){return t.getElementById(e)},e.elBySel=function(e,i){return(i||t).querySelector(e)},e.elBySelAll=function(e,i,n){var o=(i||t).querySelectorAll(e);return"function"==typeof n&&Array.prototype.forEach.call(o,n),o},e.elByTag=function(e,i){return(i||t).getElementsByTagName(e)},e.elCreate=function(e){return t.createElement(e)},e.elClosest=function(e,t){if(!(e instanceof Node))throw new TypeError("Provided element is not a Node.");return e.nodeType===Node.TEXT_NODE&&null===(e=e.parentNode)?null:("string"!=typeof t&&(t=""),0===t.length?e:e.closest(t))},e.elData=function(e,t,i){if(t="data-"+t,void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elDataBool=function(e,t){var i=elData(e,t);return"1"===i||"true"===i},e.elHide=function(e){e.style.setProperty("display","none","")},e.elIsHidden=function(e){return"none"===e.style.getPropertyValue("display")},e.elInnerError=function(e,t,i){var n=e.parentNode;if(null===n)throw new Error("Only elements that have a parent element or document are valid.");if("string"!=typeof t){if(void 0!==t&&null!==t&&!1!==t)throw new TypeError("The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.");t=""}var o=e.nextElementSibling;return null!==o&&"SMALL"===o.nodeName&&o.classList.contains("innerError")||(""===t?o=null:(o=elCreate("small"),o.className="innerError",n.insertBefore(o,e.nextSibling))),""===t?null!==o&&(n.removeChild(o),o=null):o[i?"innerHTML":"textContent"]=t,o},e.elRemove=function(e){e.parentNode.removeChild(e)},e.elShow=function(e){e.style.removeProperty("display")},e.elToggle=function(e){"none"===e.style.getPropertyValue("display")?elShow(e):elHide(e)},e.forEach=function(e,t){for(var i=0,n=e.length;i<n;i++)t(e[i],i)},e.objOwns=function(e,t){return e.hasOwnProperty(t)};"touchstart"in t.documentElement||"ontouchstart"in e||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints;Object.defineProperty(e,"WCF_CLICK_EVENT",{value:"click"}),function(){function t(){e.history.state&&e.history.state.name&&"initial"!==e.history.state.name?(e.history.replaceState({name:"skip",depth:++i},""),e.history.back(),setTimeout(t,1)):e.history.replaceState({name:"initial"},"")}var i=0;t(),e.addEventListener("popstate",function(t){t.state&&t.state.name&&"skip"===t.state.name&&e.history.go(t.state.depth)})}(),e.String.prototype.hashCode=function(){var e,t=0;if(this.length)for(var i=0,n=this.length;i<n;i++)e=this.charCodeAt(i),t=(t<<5)-t+e,t&=t;return t}}(window,document),define("wcf.globalHelper",function(){}),define("WoltLabSuite/Core/Core",[],function(){"use strict";var e=function(e){return"object"==typeof e&&(Array.isArray(e)||n.isPlainObject(e))?t(e):e},t=function(t){if(!t)return null;if(Array.isArray(t))return t.slice();var i={};for(var n in t)t.hasOwnProperty(n)&&void 0!==t[n]&&(i[n]=e(t[n]));return i},i="wsc"+window.WCF_PATH.hashCode()+"-",n={clone:function(t){return e(t)},convertLegacyUrl:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){var i=t.split(/([A-Z][a-z0-9]+)/);t="";for(var n=0,o=i.length;n<o;n++){var r=i[n].trim();r.length&&(t.length&&(t+="-"),t+=r.toLowerCase())}return"index.php?"+t+"/&"})},extend:function(e){e=e||{};for(var t=this.clone(e),i=1,n=arguments.length;i<n;i++){var o=arguments[i];if(o)for(var r in o)objOwns(o,r)&&(Array.isArray(o[r])||"object"!=typeof o[r]?t[r]=o[r]:this.isPlainObject(o[r])?t[r]=this.extend(e[r],o[r]):t[r]=o[r])}return t},inherit:function(e,t,i){if(void 0===e||null===e)throw new TypeError("The constructor must not be undefined or null.");if(void 0===t||null===t)throw new TypeError("The super constructor must not be undefined or null.");if(void 0===t.prototype)throw new TypeError("The super constructor must have a prototype.");e._super=t,e.prototype=n.extend(Object.create(t.prototype,{constructor:{configurable:!0,enumerable:!1,value:e,writable:!0}}),i||{})},isPlainObject:function(e){return"object"==typeof e&&null!==e&&!e.nodeType&&Object.getPrototypeOf(e)===Object.prototype},getType:function(e){return Object.prototype.toString.call(e).replace(/^\[object (.+)\]$/,"$1")},getUuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},serialize:function(e,t){var i=[];for(var n in e)if(objOwns(e,n)){var o=t?t+"["+n+"]":n,r=e[n];"object"==typeof r?i.push(this.serialize(r,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(r))}return i.join("&")},triggerEvent:function(e,t){if("click"===t&&e instanceof HTMLElement)return void e.click();var i;try{i=new Event(t,{bubbles:!0,cancelable:!0})}catch(e){i=document.createEvent("Event"),i.initEvent(t,!0,!0)}e.dispatchEvent(i)},getStoragePrefix:function(){return i}};return n}),define("WoltLabSuite/Core/Dictionary",["Core"],function(e){"use strict";function t(){this._dictionary=i?new Map:{}}var i=objOwns(window,"Map")&&"function"==typeof window.Map;return t.prototype={set:function(e,t){if("number"==typeof e&&(e=e.toString()),"string"!=typeof e)throw new TypeError("Only strings can be used as keys, rejected '"+e+"' ("+typeof e+").");i?this._dictionary.set(e,t):this._dictionary[e]=t},delete:function(e){"number"==typeof e&&(e=e.toString()),i?this._dictionary.delete(e):this._dictionary[e]=void 0},has:function(e){return"number"==typeof e&&(e=e.toString()),i?this._dictionary.has(e):objOwns(this._dictionary,e)&&void 0!==this._dictionary[e]},get:function(e){if("number"==typeof e&&(e=e.toString()),this.has(e))return i?this._dictionary.get(e):this._dictionary[e]},forEach:function(e){if("function"!=typeof e)throw new TypeError("forEach() expects a callback as first parameter.");if(i)this._dictionary.forEach(e);else for(var t=Object.keys(this._dictionary),n=0,o=t.length;n<o;n++)e(this._dictionary[t[n]],t[n])},merge:function(){for(var e=0,i=arguments.length;e<i;e++){var n=arguments[e];if(!(n instanceof t))throw new TypeError("Expected an object of type Dictionary, but argument "+e+" is not.");n.forEach(function(e,t){this.set(t,e)}.bind(this))}},toObject:function(){if(!i)return e.clone(this._dictionary);var t={};return this._dictionary.forEach(function(e,i){t[i]=e}),t}},t.fromObject=function(e){var i=new t;for(var n in e)objOwns(e,n)&&i.set(n,e[n]);return i},Object.defineProperty(t.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return i?this._dictionary.size:Object.keys(this._dictionary).length}}),t}),define("WoltLabSuite/Core/Template.grammar",["require"],function(e){var t=function(e,t,i,n){for(i=i||{},n=e.length;n--;i[e[n]]=t);return i},i=[2,37],n=[5,9,11,12,13,18,19,21,22,23,25,26,27,28,30,31,32,33,35,37,39],o=[1,24],r=[1,25],a=[1,31],l=[1,29],s=[1,30],c=[1,26],u=[1,27],d=[1,33],h=[11,12,15,40,41,45,47,49,50,52],f=[9,11,12,13,18,19,21,23,26,28,30,31,32,33,35,37],p=[11,12,15,40,41,44,45,46,47,49,50,52],g=[18,35,37],m=[12,15],v={trace:function(){},yy:{},symbols_:{error:2,TEMPLATE:3,CHUNK_STAR:4,EOF:5,CHUNK_STAR_repetition0:6,CHUNK:7,PLAIN_ANY:8,T_LITERAL:9,COMMAND:10,T_ANY:11,T_WS:12,"{if":13,COMMAND_PARAMETERS:14,"}":15,COMMAND_repetition0:16,COMMAND_option0:17,"{/if}":18,"{include":19,COMMAND_PARAMETER_LIST:20,"{implode":21,"{/implode}":22,"{foreach":23,COMMAND_option1:24,"{/foreach}":25,"{lang}":26,"{/lang}":27,"{":28,VARIABLE:29,"{#":30,"{@":31,"{ldelim}":32,"{rdelim}":33,ELSE:34,"{else}":35,ELSE_IF:36,"{elseif":37,FOREACH_ELSE:38,"{foreachelse}":39,T_VARIABLE:40,T_VARIABLE_NAME:41,VARIABLE_repetition0:42,VARIABLE_SUFFIX:43,"[":44,"]":45,".":46,"(":47,VARIABLE_SUFFIX_option0:48,")":49,"=":50,COMMAND_PARAMETER_VALUE:51,T_QUOTED_STRING:52,COMMAND_PARAMETERS_repetition_plus0:53,COMMAND_PARAMETER:54,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",9:"T_LITERAL",11:"T_ANY",12:"T_WS",13:"{if",15:"}",18:"{/if}",19:"{include",21:"{implode",22:"{/implode}",23:"{foreach",25:"{/foreach}",26:"{lang}",27:"{/lang}",28:"{",30:"{#",31:"{@",32:"{ldelim}",33:"{rdelim}",35:"{else}",37:"{elseif",39:"{foreachelse}",40:"T_VARIABLE",41:"T_VARIABLE_NAME",44:"[",45:"]",46:".",47:"(",49:")",50:"=",52:"T_QUOTED_STRING"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[8,1],[8,1],[10,7],[10,3],[10,5],[10,6],[10,3],[10,3],[10,3],[10,3],[10,1],[10,1],[34,2],[36,4],[38,2],[29,3],[43,3],[43,2],[43,3],[20,5],[20,3],[51,1],[51,1],[14,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,3],[6,0],[6,2],[16,0],[16,2],[17,0],[17,1],[24,0],[24,1],[42,0],[42,2],[48,0],[48,1],[53,1],[53,2]],performAction:function(e,t,i,n,o,r,a){var l=r.length-1;switch(o){case 1:return r[l-1]+";";case 2:var s=r[l].reduce(function(e,t){return t.encode&&!e[1]?e[0]+=" + '"+t.value:t.encode&&e[1]?e[0]+=t.value:!t.encode&&e[1]?e[0]+="' + "+t.value:t.encode||e[1]||(e[0]+=" + "+t.value),e[1]=t.encode,e},["''",!1]);s[1]&&(s[0]+="'"),this.$=s[0];break;case 3:case 4:this.$={encode:!0,value:r[l].replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n")};break;case 5:this.$={encode:!1,value:r[l]};break;case 8:this.$="(function() { if ("+r[l-5]+") { return "+r[l-3]+"; } "+r[l-2].join(" ")+" "+(r[l-1]||"")+" return ''; })()";break;case 9:if(!r[l-1].file)throw new Error("Missing parameter file");this.$=r[l-1].file+".fetch(v)";break;case 10:if(!r[l-3].from)throw new Error("Missing parameter from");if(!r[l-3].item)throw new Error("Missing parameter item");r[l-3].glue||(r[l-3].glue="', '"),this.$="(function() { return "+r[l-3].from+".map(function(item) { v["+r[l-3].item+"] = item; return "+r[l-1]+"; }).join("+r[l-3].glue+"); })()";break;case 11:if(!r[l-4].from)throw new Error("Missing parameter from");if(!r[l-4].item)throw new Error("Missing parameter item");this.$="(function() {var looped = false, result = '';if ("+r[l-4].from+" instanceof Array) {for (var i = 0; i < "+r[l-4].from+".length; i++) { looped = true;v["+r[l-4].key+"] = i;v["+r[l-4].item+"] = "+r[l-4].from+"[i];result += "+r[l-2]+";}} else {for (var key in "+r[l-4].from+") {if (!"+r[l-4].from+".hasOwnProperty(key)) continue;looped = true;v["+r[l-4].key+"] = key;v["+r[l-4].item+"] = "+r[l-4].from+"[key];result += "+r[l-2]+";}}return (looped ? result : "+(r[l-1]||"''")+"); })()";break;case 12:this.$="Language.get("+r[l-1]+", v)";break;case 13:this.$="StringUtil.escapeHTML("+r[l-1]+")";break;case 14:this.$="StringUtil.formatNumeric("+r[l-1]+")";break;case 15:this.$=r[l-1];break;case 16:this.$="'{'";break;case 17:this.$="'}'";break;case 18:this.$="else { return "+r[l]+"; }";break;case 19:this.$="else if ("+r[l-2]+") { return "+r[l]+"; }";break;case 20:this.$=r[l];break;case 21:this.$="v['"+r[l-1]+"']"+r[l].join("");break;case 22:this.$=r[l-2]+r[l-1]+r[l];break;case 23:this.$="['"+r[l]+"']";break;case 24:case 36:this.$=r[l-2]+(r[l-1]||"")+r[l];break;case 25:this.$=r[l],this.$[r[l-4]]=r[l-2];break;case 26:this.$={},this.$[r[l-2]]=r[l];break;case 29:this.$=r[l].join("");break;case 37:case 39:case 45:this.$=[];break;case 38:case 40:case 46:case 50:r[l-1].push(r[l]);break;case 49:this.$=[r[l]]}},table:[t([5,9,11,12,13,19,21,23,26,28,30,31,32,33],i,{3:1,4:2,6:3}),{1:[3]},{5:[1,4]},t([5,18,22,25,27,35,37,39],[2,2],{7:5,8:6,10:8,9:[1,7],11:[1,9],12:[1,10],13:[1,11],19:[1,12],21:[1,13],23:[1,14],26:[1,15],28:[1,16],30:[1,17],31:[1,18],32:[1,19],33:[1,20]}),{1:[2,1]},t(n,[2,38]),t(n,[2,3]),t(n,[2,4]),t(n,[2,5]),t(n,[2,6]),t(n,[2,7]),{11:o,12:r,14:21,29:28,40:a,41:l,47:s,50:c,52:u,53:22,54:23},{20:32,41:d},{20:34,41:d},{20:35,41:d},t([9,11,12,13,19,21,23,26,27,28,30,31,32,33],i,{6:3,4:36}),{29:37,40:a},{29:38,40:a},{29:39,40:a},t(n,[2,16]),t(n,[2,17]),{15:[1,40]},t([15,45,49],[2,29],{29:28,54:41,11:o,12:r,40:a,41:l,47:s,50:c,52:u}),t(h,[2,49]),t(h,[2,30]),t(h,[2,31]),t(h,[2,32]),t(h,[2,33]),t(h,[2,34]),t(h,[2,35]),{11:o,12:r,14:42,29:28,40:a,41:l,47:s,50:c,52:u,53:22,54:23},{41:[1,43]},{15:[1,44]},{50:[1,45]},{15:[1,46]},{15:[1,47]},{27:[1,48]},{15:[1,49]},{15:[1,50]},{15:[1,51]},t(f,i,{6:3,4:52}),t(h,[2,50]),{49:[1,53]},t(p,[2,45],{42:54}),t(n,[2,9]),{29:57,40:a,51:55,52:[1,56]},t([9,11,12,13,19,21,22,23,26,28,30,31,32,33],i,{6:3,4:58}),t([9,11,12,13,19,21,23,25,26,28,30,31,32,33,39],i,{6:3,4:59}),t(n,[2,12]),t(n,[2,13]),t(n,[2,14]),t(n,[2,15]),t(g,[2,39],{16:60}),t(h,[2,36]),t([11,12,15,40,41,45,49,50,52],[2,21],{43:61,44:[1,62],46:[1,63],47:[1,64]}),{12:[1,65],15:[2,26]},t(m,[2,27]),t(m,[2,28]),{22:[1,66]},{24:67,25:[2,43],38:68,39:[1,69]},{17:70,18:[2,41],34:72,35:[1,74],36:71,37:[1,73]},t(p,[2,46]),{11:o,12:r,14:75,29:28,40:a,41:l,47:s,50:c,52:u,53:22,54:23},{41:[1,76]},{11:o,12:r,14:78,29:28,40:a,41:l,47:s,48:77,49:[2,47],50:c,52:u,53:22,54:23},{20:79,41:d},t(n,[2,10]),{25:[1,80]},{25:[2,44]},t([9,11,12,13,19,21,23,25,26,28,30,31,32,33],i,{6:3,4:81}),{18:[1,82]},t(g,[2,40]),{18:[2,42]},{11:o,12:r,14:83,29:28,40:a,41:l,47:s,50:c,52:u,53:22,54:23},t([9,11,12,13,18,19,21,23,26,28,30,31,32,33],i,{6:3,4:84}),{45:[1,85]},t(p,[2,23]),{49:[1,86]},{49:[2,48]},{15:[2,25]},t(n,[2,11]),{25:[2,20]},t(n,[2,8]),{15:[1,87]},{18:[2,18]},t(p,[2,22]),t(p,[2,24]),t(f,i,{6:3,4:88}),t(g,[2,19])],defaultActions:{4:[2,1],68:[2,44],72:[2,42],78:[2,48],79:[2,25],81:[2,20],84:[2,18]},parseError:function(e,t){function i(e,t){this.message=e,this.hash=t}if(!t.recoverable)throw i.prototype=Error,new i(e,t);this.trace(e)},parse:function(e){var t=this,i=[0],n=[null],o=[],r=this.table,a="",l=0,s=0,c=0,u=o.slice.call(arguments,1),d=Object.create(this.lexer),h={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(h.yy[f]=this.yy[f]);d.setInput(e,h.yy),h.yy.lexer=d,h.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var p=d.yylloc;o.push(p);var g=d.options&&d.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,v,b,_,y,w,C,E,L,A=function(){var e;return e=d.lex()||1,"number"!=typeof e&&(e=t.symbols_[e]||e),e},S={};;){if(b=i[i.length-1],this.defaultActions[b]?_=this.defaultActions[b]:(null!==m&&void 0!==m||(m=A()),_=r[b]&&r[b][m]),void 0===_||!_.length||!_[0]){var x="";L=[];for(w in r[b])this.terminals_[w]&&w>2&&L.push("'"+this.terminals_[w]+"'");x=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+L.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[m]||m,line:d.yylineno,loc:p,expected:L})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+m);switch(_[0]){case 1:i.push(m),n.push(d.yytext),o.push(d.yylloc),i.push(_[1]),m=null,v?(m=v,v=null):(s=d.yyleng,a=d.yytext,l=d.yylineno,p=d.yylloc,c>0&&c--);break;case 2:if(C=this.productions_[_[1]][1],S.$=n[n.length-C],S._$={first_line:o[o.length-(C||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(C||1)].first_column,last_column:o[o.length-1].last_column},g&&(S._$.range=[o[o.length-(C||1)].range[0],o[o.length-1].range[1]]),void 0!==(y=this.performAction.apply(S,[a,s,l,h.yy,_[1],n,o].concat(u))))return y;C&&(i=i.slice(0,-1*C*2),n=n.slice(0,-1*C),o=o.slice(0,-1*C)),i.push(this.productions_[_[1]][0]),n.push(S.$),o.push(S._$),E=r[i[i.length-2]][i[i.length-1]],i.push(E);break;case 3:return!0}}return!0}},b=function(){return{EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var o=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[o[0],o[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,n,o;if(this.options.backtrack_lexer&&(o={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(o.yylloc.range=this.yylloc.range.slice(0))),n=e[0].match(/(?:\r\n?|\n).*/g),n&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in o)this[r]=o[r];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var e,t,i,n;this._more||(this.yytext="",this.match="");for(var o=this._currentRules(),r=0;r<o.length;r++)if((i=this._input.match(this.rules[o[r]]))&&(!t||i[0].length>t[0].length)){if(t=i,n=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,o[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,o[n]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{
-text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return e=this.conditionStack.length-1-Math.abs(e||0),e>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,i,n){switch(i){case 0:break;case 1:return t.yytext=t.yytext.substring(9,t.yytext.length-10),9;case 2:case 3:return 52;case 4:return 40;case 5:return 41;case 6:return 46;case 7:return 44;case 8:return 45;case 9:return 47;case 10:return 49;case 11:return 50;case 12:return 32;case 13:return 33;case 14:return this.begin("command"),30;case 15:return this.begin("command"),31;case 16:return this.begin("command"),13;case 17:case 18:return this.begin("command"),37;case 19:return 35;case 20:return 18;case 21:return 26;case 22:return 27;case 23:return this.begin("command"),19;case 24:return this.begin("command"),21;case 25:return 22;case 26:return this.begin("command"),23;case 27:return 39;case 28:return 25;case 29:return this.begin("command"),28;case 30:return this.popState(),15;case 31:return 12;case 32:return 5;case 33:return 11}},rules:[/^(?:\{\*[\s\S]*?\*\})/,/^(?:\{literal\}[\s\S]*?\{\/literal\})/,/^(?:"([^"]|\\\.)*")/,/^(?:'([^']|\\\.)*')/,/^(?:\$)/,/^(?:[_a-zA-Z][_a-zA-Z0-9]*)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:=)/,/^(?:\{ldelim\})/,/^(?:\{rdelim\})/,/^(?:\{#)/,/^(?:\{@)/,/^(?:\{if )/,/^(?:\{else if )/,/^(?:\{elseif )/,/^(?:\{else\})/,/^(?:\{\/if\})/,/^(?:\{lang\})/,/^(?:\{\/lang\})/,/^(?:\{include )/,/^(?:\{implode )/,/^(?:\{\/implode\})/,/^(?:\{foreach )/,/^(?:\{foreachelse\})/,/^(?:\{\/foreach\})/,/^(?:\{(?!\s))/,/^(?:\})/,/^(?:\s+)/,/^(?:$)/,/^(?:[^{])/],conditions:{command:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],inclusive:!0},INITIAL:{rules:[0,1,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,33],inclusive:!0}}}}();return v.lexer=b,v}),define("WoltLabSuite/Core/NumberUtil",[],function(){"use strict";return{round:function(e,t){return void 0===t||0==+t?Math.round(e):(e=+e,t=+t,isNaN(e)||"number"!=typeof t||t%1!=0?NaN:(e=e.toString().split("e"),e=Math.round(+(e[0]+"e"+(e[1]?+e[1]-t:-t))),e=e.toString().split("e"),+(e[0]+"e"+(e[1]?+e[1]+t:t))))}}}),define("WoltLabSuite/Core/StringUtil",["Language","./NumberUtil"],function(e,t){"use strict";return{addThousandsSeparator:function(t){return void 0===e&&(e=require("Language")),String(t).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+e.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(i,n){void 0===e&&(e=require("Language")),i=String(t.round(i,n||-2));var o=i.split(".");return i=this.addThousandsSeparator(o[0]),o.length>1&&(i+=e.get("wcf.global.decimalPoint")+o[1]),i=i.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")},shortUnit:function(e){var i="";return e>=1e6?(e/=1e6,e=e>10?Math.floor(e):t.round(e,-1),i="M"):e>=1e3&&(e/=1e3,e=e>10?Math.floor(e):t.round(e,-1),i="k"),this.formatNumeric(e)+i}}}),define("WoltLabSuite/Core/Template",["./Template.grammar","./StringUtil","Language"],function(e,t,i){"use strict";function n(){this.yy={}}function o(n){void 0===i&&(i=require("Language")),void 0===t&&(t=require("StringUtil"));try{n=e.parse(n),n="var tmp = {};\nfor (var key in v) tmp[key] = v[key];\nv = tmp;\nv.__wcf = window.WCF; v.__window = window;\nreturn "+n,this.fetch=new Function("StringUtil","Language","v",n).bind(void 0,t,i)}catch(e){throw console.debug(e.message),e}}return n.prototype=e,e.Parser=n,e=new n,Object.defineProperty(o,"callbacks",{enumerable:!1,configurable:!1,get:function(){throw new Error("WCF.Template.callbacks is no longer supported")},set:function(e){throw new Error("WCF.Template.callbacks is no longer supported")}}),o.prototype={fetch:function(e){throw new Error("This Template is not initialized.")}},o}),define("WoltLabSuite/Core/Language",["Dictionary","./Template"],function(e,t){"use strict";var i=new e;return{addObject:function(t){i.merge(e.fromObject(t))},add:function(e,t){i.set(e,t)},get:function(e,n){n||(n={});var o=i.get(e);if(void 0===o)return e;if(void 0===t&&(t=require("WoltLabSuite/Core/Template")),"string"==typeof o){try{i.set(e,new t(o))}catch(n){i.set(e,new t("{literal}"+o.replace(/\{\/literal\}/g,"{/literal}{ldelim}/literal}{literal}")+"{/literal}"))}o=i.get(e)}return o instanceof t&&(o=o.fetch(n)),o}}}),define("WoltLabSuite/Core/CallbackList",["Dictionary"],function(e){"use strict";function t(){this._dictionary=new e}return t.prototype={add:function(e,t){if("function"!=typeof t)throw new TypeError("Expected a valid callback as second argument for identifier '"+e+"'.");this._dictionary.has(e)||this._dictionary.set(e,[]),this._dictionary.get(e).push(t)},remove:function(e){this._dictionary.delete(e)},forEach:function(e,t){if(null===e)this._dictionary.forEach(function(e,i){e.forEach(t)});else{var i=this._dictionary.get(e);void 0!==i&&i.forEach(t)}}},t}),define("WoltLabSuite/Core/Dom/Change/Listener",["CallbackList"],function(e){"use strict";var t=new e,i=!1;return{add:t.add.bind(t),remove:t.remove.bind(t),trigger:function(){if(!i)try{i=!0,t.forEach(null,function(e){e()})}finally{i=!1}}}}),define("WoltLabSuite/Core/Environment",[],function(){"use strict";var e="other",t="none",i="desktop",n=!1;return{setup:function(){if("object"==typeof window.chrome)e="chrome";else for(var o=window.getComputedStyle(document.documentElement),r=0,a=o.length;r<a;r++){var l=o[r];0===l.indexOf("-ms-")?e="microsoft":0===l.indexOf("-moz-")?e="firefox":"firefox"!==e&&0===l.indexOf("-webkit-")&&(e="safari")}var s=window.navigator.userAgent.toLowerCase();-1!==s.indexOf("crios")?(e="chrome",i="ios"):/(?:iphone|ipad|ipod)/.test(s)?(e="safari",i="ios"):-1!==s.indexOf("android")?i="android":-1!==s.indexOf("iemobile")&&(e="microsoft",i="windows"),"desktop"!==i||-1===s.indexOf("mobile")&&-1===s.indexOf("tablet")||(i="mobile"),t="redactor",n=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&window.navigator.msMaxTouchPoints>0||window.DocumentTouch&&document instanceof DocumentTouch,"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1&&(e="safari",i="ios")},browser:function(){return e},editor:function(){return t},platform:function(){return i},touch:function(){return n}}}),define("WoltLabSuite/Core/Dom/Util",["Environment","StringUtil"],function(e,t){"use strict";function i(e,t,i){if(!t.contains(e))throw new Error("Ancestor element does not contain target element.");for(var n,o=i+"Sibling";null!==e&&e!==t;){if(null!==e[i+"ElementSibling"])return!1;if(e[o])for(n=e[o];n;){if(""!==n.textContent.trim())return!1;n=n[o]}e=e.parentNode}return!0}var n=0,o={createFragmentFromHtml:function(e){var t=elCreate("div");this.setInnerHtml(t,e);for(var i=document.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return i},getUniqueId:function(){var e;do{e="wcf"+n++}while(null!==elById(e));return e},identify:function(e){if(!(e instanceof Element))throw new TypeError("Expected a valid DOM element as argument.");var t=elAttr(e,"id");return t||(t=this.getUniqueId(),elAttr(e,"id",t)),t},outerHeight:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetHeight;return i+=~~t.marginTop+~~t.marginBottom},outerWidth:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetWidth;return i+=~~t.marginLeft+~~t.marginRight},outerDimensions:function(e){var t=window.getComputedStyle(e);return{height:this.outerHeight(e,t),width:this.outerWidth(e,t)}},offset:function(e){var t=e.getBoundingClientRect();return{top:Math.round(t.top+(window.scrollY||window.pageYOffset)),left:Math.round(t.left+(window.scrollX||window.pageXOffset))}},prepend:function(e,t){0===t.childNodes.length?t.appendChild(e):t.insertBefore(e,t.childNodes[0])},insertAfter:function(e,t){null!==t.nextSibling?t.parentNode.insertBefore(e,t.nextSibling):t.parentNode.appendChild(e)},setStyles:function(e,t){var i=!1;for(var n in t)t.hasOwnProperty(n)&&(/ !important$/.test(t[n])?(i=!0,t[n]=t[n].replace(/ !important$/,"")):i=!1,"important"!==e.style.getPropertyPriority(n)||i||e.style.removeProperty(n),e.style.setProperty(n,t[n],i?"important":""))},styleAsInt:function(e,t){var i=e.getPropertyValue(t);return null===i?0:parseInt(i)},setInnerHtml:function(e,t){e.innerHTML=t;for(var i,n,o=elBySelAll("script",e),r=0,a=o.length;r<a;r++)n=o[r],i=elCreate("script"),n.src?i.src=n.src:i.textContent=n.textContent,e.appendChild(i),elRemove(n)},insertHtml:function(e,t,i){var n=elCreate("div");if(this.setInnerHtml(n,e),n.childNodes.length){var o=n.childNodes[0];switch(i){case"append":t.appendChild(o);break;case"after":this.insertAfter(o,t);break;case"prepend":this.prepend(o,t);break;case"before":t.parentNode.insertBefore(o,t);break;default:throw new Error("Unknown insert method '"+i+"'.")}for(var r;n.childNodes.length;)r=n.childNodes[0],this.insertAfter(r,o),o=r}},contains:function(e,t){for(;null!==t;)if(t=t.parentNode,e===t)return!0;return!1},getDataAttributes:function(e,i,n,o){i=i||"",/^data-/.test(i)||(i="data-"+i),n=!0===n,o=!0===o;for(var r,a,l,s={},c=0,u=e.attributes.length;c<u;c++)if(r=e.attributes[c],0===r.name.indexOf(i)){if(a=r.name.replace(new RegExp("^"+i),""),n){l=a.split("-"),a="";for(var d=0,h=l.length;d<h;d++)a.length&&(o&&"id"===l[d]?l[d]="ID":l[d]=t.ucfirst(l[d])),a+=l[d]}s[a]=r.value}return s},unwrapChildNodes:function(e){for(var t=e.parentNode;e.childNodes.length;)t.insertBefore(e.childNodes[0],e);elRemove(e)},replaceElement:function(e,t){for(;e.childNodes.length;)t.appendChild(e.childNodes[0]);e.parentNode.insertBefore(t,e),elRemove(e)},isAtNodeStart:function(e,t){return i(e,t,"previous")},isAtNodeEnd:function(e,t){return i(e,t,"next")},getFixedParent:function(e){for(;e&&e!==document.body;){if("fixed"===window.getComputedStyle(e).getPropertyValue("position"))return e;e=e.offsetParent}return null}};return window.bc_wcfDomUtil=o,o}),define("WoltLabSuite/Core/ObjectMap",[],function(){"use strict";function e(){this._map=t?new WeakMap:{key:[],value:[]}}var t=objOwns(window,"WeakMap")&&"function"==typeof window.WeakMap;return e.prototype={set:function(e,i){if("object"!=typeof e||null===e)throw new TypeError("Only objects can be used as key");if("object"!=typeof i||null===i)throw new TypeError("Only objects can be used as value");t?this._map.set(e,i):(this._map.key.push(e),this._map.value.push(i))},delete:function(e){if(t)this._map.delete(e);else{var i=this._map.key.indexOf(e);this._map.key.splice(i),this._map.value.splice(i)}},has:function(e){return t?this._map.has(e):-1!==this._map.key.indexOf(e)},get:function(e){if(t)return this._map.get(e);var i=this._map.key.indexOf(e);return-1!==i?this._map.value[i]:void 0}},e}),define("WoltLabSuite/Core/Dom/Traverse",[],function(){"use strict";var e=[function(e,t){return!0},function(e,t){return e.matches(t)},function(e,t){return e.classList.contains(t)},function(e,t){return e.nodeName===t}],t=function(t,i,n){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(var o=[],r=0;r<t.childElementCount;r++)e[i](t.children[r],n)&&o.push(t.children[r]);return o},i=function(t,i,n,o){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(t=t.parentNode;t instanceof Element;){if(t===o)return null;if(e[i](t,n))return t;t=t.parentNode}return null},n=function(t,i,n,o){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");return t instanceof Element&&null!==t[i]&&e[n](t[i],o)?t[i]:null};return{childBySel:function(e,i){return t(e,1,i)[0]||null},childByClass:function(e,i){return t(e,2,i)[0]||null},childByTag:function(e,i){return t(e,3,i)[0]||null},childrenBySel:function(e,i){return t(e,1,i)},childrenByClass:function(e,i){return t(e,2,i)},childrenByTag:function(e,i){return t(e,3,i)},parentBySel:function(e,t,n){return i(e,1,t,n)},parentByClass:function(e,t,n){return i(e,2,t,n)},parentByTag:function(e,t,n){return i(e,3,t,n)},next:function(e){return n(e,"nextElementSibling",0,null)},nextBySel:function(e,t){return n(e,"nextElementSibling",1,t)},nextByClass:function(e,t){return n(e,"nextElementSibling",2,t)},nextByTag:function(e,t){return n(e,"nextElementSibling",3,t)},prev:function(e){return n(e,"previousElementSibling",0,null)},prevBySel:function(e,t){return n(e,"previousElementSibling",1,t)},prevByClass:function(e,t){return n(e,"previousElementSibling",2,t)},prevByTag:function(e,t){return n(e,"previousElementSibling",3,t)}}}),define("WoltLabSuite/Core/Ui/Confirmation",["Core","Language","Ui/Dialog"],function(e,t,i){"use strict";var n=!1,o=null,r=null,a={},l=null;return{show:function(t){if(void 0===i&&(i=require("Ui/Dialog")),!n){if(a=e.extend({cancel:null,confirm:null,legacyCallback:null,message:"",messageIsHtml:!1,parameters:{},template:""},t),a.message="string"==typeof a.message?a.message.trim():"",!a.message.length)throw new Error("Expected a non-empty string for option 'message'.");if("function"!=typeof a.confirm&&"function"!=typeof a.legacyCallback)throw new TypeError("Expected a valid callback for option 'confirm'.");null===r&&this._createDialog(),r.innerHTML="string"==typeof a.template?a.template.trim():"",a.messageIsHtml?l.innerHTML=a.message:l.textContent=a.message,n=!0,i.open(this)}},_dialogSetup:function(){return{id:"wcfSystemConfirmation",options:{onClose:this._onClose.bind(this),onShow:this._onShow.bind(this),title:t.get("wcf.global.confirmation.title")}}},getContentElement:function(){return r},_createDialog:function(){var e=elCreate("div");elAttr(e,"id","wcfSystemConfirmation"),e.classList.add("systemConfirmation"),l=elCreate("p"),e.appendChild(l),r=elCreate("div"),elAttr(r,"id","wcfSystemConfirmationContent"),e.appendChild(r);var n=elCreate("div");n.classList.add("formSubmit"),e.appendChild(n),o=elCreate("button"),o.classList.add("buttonPrimary"),o.textContent=t.get("wcf.global.confirmation.confirm"),o.addEventListener(WCF_CLICK_EVENT,this._confirm.bind(this)),n.appendChild(o);var a=elCreate("button");a.textContent=t.get("wcf.global.confirmation.cancel"),a.addEventListener(WCF_CLICK_EVENT,function(){i.close("wcfSystemConfirmation")}),n.appendChild(a),document.body.appendChild(e)},_confirm:function(){"function"==typeof a.legacyCallback?a.legacyCallback("confirm",a.parameters,r):a.confirm(a.parameters,r),n=!1,i.close("wcfSystemConfirmation")},_onClose:function(){n&&(o.blur(),n=!1,"function"==typeof a.legacyCallback?a.legacyCallback("cancel",a.parameters,r):"function"==typeof a.cancel&&a.cancel(a.parameters))},_onShow:function(){o.blur(),o.focus()}}}),define("WoltLabSuite/Core/Ui/Screen",["Core","Dictionary","Environment"],function(e,t,i){"use strict";var n=null,o=new t,r=0,a=null,l=0,s=0,c=t.fromObject({"screen-xs":"(max-width: 544px)","screen-sm":"(min-width: 545px) and (max-width: 768px)","screen-sm-down":"(max-width: 768px)","screen-sm-up":"(min-width: 545px)","screen-sm-md":"(min-width: 545px) and (max-width: 1024px)","screen-md":"(min-width: 769px) and (max-width: 1024px)","screen-md-down":"(max-width: 1024px)","screen-md-up":"(min-width: 769px)","screen-lg":"(min-width: 1025px)","screen-lg-only":"(min-width: 1025px) and (max-width: 1280px)","screen-lg-down":"(max-width: 1280px)","screen-xl":"(min-width: 1281px)"}),u=new t;return{on:function(t,i){var n=e.getUuid(),o=this._getQueryObject(t);return"function"==typeof i.match&&o.callbacksMatch.set(n,i.match),"function"==typeof i.unmatch&&o.callbacksUnmatch.set(n,i.unmatch),"function"==typeof i.setup&&(o.mql.matches?i.setup():o.callbacksSetup.set(n,i.setup)),n},remove:function(e,t){var i=this._getQueryObject(e);i.callbacksMatch.delete(t),i.callbacksUnmatch.delete(t),i.callbacksSetup.delete(t)},is:function(e){return this._getQueryObject(e).mql.matches},scrollDisable:function(){if(0===r){l=document.body.scrollTop,a="body",l||(l=document.documentElement.scrollTop,a="documentElement");var e=elById("pageContainer");"ios"===i.platform()?(e.style.setProperty("position","relative",""),e.style.setProperty("top","-"+l+"px","")):e.style.setProperty("margin-top","-"+l+"px",""),document.documentElement.classList.add("disableScrolling")}r++},scrollEnable:function(){if(r&&0===--r){document.documentElement.classList.remove("disableScrolling");var e=elById("pageContainer");"ios"===i.platform()?(e.style.removeProperty("position"),e.style.removeProperty("top")):e.style.removeProperty("margin-top"),l&&(document[a].scrollTop=~~l)}},pageOverlayOpen:function(){0===s&&document.documentElement.classList.add("pageOverlayActive"),s++},pageOverlayClose:function(){s&&0===--s&&document.documentElement.classList.remove("pageOverlayActive")},pageOverlayIsActive:function(){return s>0},setDialogContainer:function(e){n=e},_getQueryObject:function(e){if("string"!=typeof e||""===e.trim())throw new TypeError("Expected a non-empty string for parameter 'query'.");u.has(e)&&(e=u.get(e)),c.has(e)&&(e=c.get(e));var i=o.get(e);return i||(i={callbacksMatch:new t,callbacksUnmatch:new t,callbacksSetup:new t,mql:window.matchMedia(e)},i.mql.addListener(this._mqlChange.bind(this)),o.set(e,i),e!==i.mql.media&&u.set(i.mql.media,e)),i},_mqlChange:function(e){var i=this._getQueryObject(e.media);if(e.matches)i.callbacksSetup.size?(i.callbacksSetup.forEach(function(e){e()}),i.callbacksSetup=new t):i.callbacksMatch.forEach(function(e){e()});else{if(i.callbacksSetup.size)return;i.callbacksUnmatch.forEach(function(e){e()})}}}}),define("WoltLabSuite/Core/Event/Key",[],function(){"use strict";function e(e,t,i){if(!(e instanceof Event))throw new TypeError("Expected a valid event when testing for key '"+t+"'.");return e.key===t||e.which===i}return{ArrowDown:function(t){return e(t,"ArrowDown",40)},ArrowLeft:function(t){return e(t,"ArrowLeft",37)},ArrowRight:function(t){return e(t,"ArrowRight",39)},ArrowUp:function(t){return e(t,"ArrowUp",38)},Comma:function(t){return e(t,",",44)},End:function(t){return e(t,"End",35)},Enter:function(t){return e(t,"Enter",13)},Escape:function(t){return e(t,"Escape",27)},Home:function(t){return e(t,"Home",36)},Space:function(t){return e(t,"Space",32)},Tab:function(t){return e(t,"Tab",9)}}}),define("WoltLabSuite/Core/Ui/Alignment",["Core","Language","Dom/Traverse","Dom/Util"],function(e,t,i,n){"use strict";return{set:function(o,r,a){a=e.extend({verticalOffset:0,pointer:!1,pointerClassNames:[],refDimensionsElement:null,horizontal:"left",vertical:"bottom",allowFlip:"both"},a),Array.isArray(a.pointerClassNames)&&a.pointerClassNames.length===(a.pointer?1:2)||(a.pointerClassNames=[]),-1===["left","right","center"].indexOf(a.horizontal)&&(a.horizontal="left"),"bottom"!==a.vertical&&(a.vertical="top"),-1===["both","horizontal","vertical","none"].indexOf(a.allowFlip)&&(a.allowFlip="both"),n.setStyles(o,{bottom:"auto !important",left:"0 !important",right:"auto !important",top:"0 !important",visibility:"hidden !important"});var l=n.outerDimensions(o),s=n.outerDimensions(a.refDimensionsElement instanceof Element?a.refDimensionsElement:r),c=n.offset(r),u=window.innerHeight,d=document.body.clientWidth,h={result:null},f=!1;if("center"===a.horizontal&&(f=!0,h=this._tryAlignmentHorizontal(a.horizontal,l,s,c,d),h.result||("both"===a.allowFlip||"horizontal"===a.allowFlip?a.horizontal="left":h.result=!0)),"rtl"===t.get("wcf.global.pageDirection")&&(a.horizontal="left"===a.horizontal?"right":"left"),!h.result){var p=h;if(h=this._tryAlignmentHorizontal(a.horizontal,l,s,c,d),!h.result&&("both"===a.allowFlip||"horizontal"===a.allowFlip)){var g=this._tryAlignmentHorizontal("left"===a.horizontal?"right":"left",l,s,c,d);g.result?h=g:f&&(h=p)}}var m=h.left,v=h.right,b=this._tryAlignmentVertical(a.vertical,l,s,c,u,a.verticalOffset);if(!b.result&&("both"===a.allowFlip||"vertical"===a.allowFlip)){var _=this._tryAlignmentVertical("top"===a.vertical?"bottom":"top",l,s,c,u,a.verticalOffset);_.result&&(b=_)}var y=b.bottom,w=b.top;if(a.pointer){var C=i.childrenByClass(o,"elementPointer");if(null===(C=C[0]||null))throw new Error("Expected the .elementPointer element to be a direct children.");"center"===h.align?(C.classList.add("center"),C.classList.remove("left"),C.classList.remove("right")):(C.classList.add(h.align),C.classList.remove("center"),C.classList.remove("left"===h.align?"right":"left")),"top"===b.align?C.classList.add("flipVertical"):C.classList.remove("flipVertical")}else if(2===a.pointerClassNames.length){o.classList["auto"===w?"add":"remove"](a.pointerClassNames[0]),o.classList["auto"===m?"add":"remove"](a.pointerClassNames[1])}"auto"!==y&&(y=Math.round(y)+"px"),"auto"!==m&&(m=Math.ceil(m)+"px"),"auto"!==v&&(v=Math.floor(v)+"px"),"auto"!==w&&(w=Math.round(w)+"px"),n.setStyles(o,{bottom:y,left:m,right:v,top:w}),elShow(o),o.style.removeProperty("visibility")},_tryAlignmentHorizontal:function(e,t,i,n,o){var r="auto",a="auto",l=!0;return"left"===e?(r=n.left)+t.width>o&&(l=!1):"right"===e?n.left+i.width<t.width?l=!1:(a=o-(n.left+i.width))<0&&(l=!1):(r=n.left+i.width/2-t.width/2,((r=~~r)<0||r+t.width>o)&&(l=!1)),{align:e,left:r,right:a,result:l}},_tryAlignmentVertical:function(e,t,i,n,o,r){var a="auto",l="auto",s=!0,c=50,u=elById("pageHeaderPanel");if(null!==u){var d=window.getComputedStyle(u).position;c="fixed"===d||"static"===d?u.offsetHeight:0}if("top"===e){var h=document.body.clientHeight;a=h-n.top+r,h-(a+t.height)<(window.scrollY||window.pageYOffset)+c&&(s=!1)}else(l=n.top+i.height+r)+t.height-(window.scrollY||window.pageYOffset)>o&&(s=!1);return{align:e,bottom:a,top:l,result:s}}}}),define("WoltLabSuite/Core/Ui/CloseOverlay",["CallbackList"],function(e){"use strict";var t=new e,i={setup:function(){document.body.addEventListener(WCF_CLICK_EVENT,this.execute.bind(this))},add:t.add.bind(t),remove:t.remove.bind(t),execute:function(){t.forEach(null,function(e){e()})}};return i.setup(),i}),define("WoltLabSuite/Core/Ui/Dropdown/Simple",["CallbackList","Core","Dictionary","EventKey","Ui/Alignment","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/CloseOverlay"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=null,u=new e,d=!1,h=new i,f=new i,p=null,g=null,m="";return{setup:function(){d||(d=!0,p=elCreate("div"),p.className="dropdownMenuContainer",document.body.appendChild(p),c=elByClass("dropdownToggle"),this.initAll(),s.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.closeAll.bind(this)),r.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.initAll.bind(this)),document.addEventListener("scroll",this._onScroll.bind(this)),window.bc_wcfSimpleDropdown=this,g=this._dropdownMenuKeyDown.bind(this))},initAll:function(){for(var e=0,t=c.length;e<t;e++)this.init(c[e],!1)},init:function(e,i){if(this.setup(),elAttr(e,"role","button"),elAttr(e,"tabindex","0"),elAttr(e,"aria-haspopup",!0),elAttr(e,"aria-expanded",!1),e.classList.contains("jsDropdownEnabled")||elData(e,"target"))return!1;var n=a.parentByClass(e,"dropdown");if(null===n)throw new Error("Invalid dropdown passed, button '"+l.identify(e)+"' does not have a parent with .dropdown.");var o=a.nextByClass(e,"dropdownMenu");if(null===o)throw new Error("Invalid dropdown passed, button '"+l.identify(e)+"' does not have a menu as next sibling.");p.appendChild(o);var r=l.identify(n);if(!h.has(r)&&(e.classList.add("jsDropdownEnabled"),e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this)),e.addEventListener("keydown",this._handleKeyDown.bind(this)),h.set(r,n),f.set(r,o),r.match(/^wcf\d+$/)||elData(o,"source",r),o.childElementCount&&o.children[0].classList.contains("scrollableDropdownMenu"))){o=o.children[0],elData(o,"scroll-to-active",!0);var s=null,c=null;o.addEventListener("wheel",function(e){null===s&&(s=o.clientHeight),null===c&&(c=o.scrollHeight),e.deltaY<0&&0===o.scrollTop?e.preventDefault():e.deltaY>0&&o.scrollTop+s===c&&e.preventDefault()},{passive:!1})}elData(e,"target",r),i&&setTimeout(function(){elData(e,"dropdown-lazy-init",i instanceof MouseEvent),t.triggerEvent(e,WCF_CLICK_EVENT),setTimeout(function(){e.removeAttribute("data-dropdown-lazy-init")},10)},10)},initFragment:function(e,t){this.setup();var i=l.identify(e);h.has(i)||(h.set(i,e),p.appendChild(t),f.set(i,t))},registerCallback:function(e,t){u.add(e,t)},getDropdown:function(e){return h.get(e)},getDropdownMenu:function(e){return f.get(e)},toggleDropdown:function(e,t,i){this._toggle(null,e,t,i)},setAlignment:function(e,t,i){var n,r=elBySel(".dropdownToggle",e);null!==r&&r.parentNode.classList.contains("inputAddonTextarea")&&(n=r),o.set(t,i||e,{pointerClassNames:["dropdownArrowBottom","dropdownArrowRight"],refDimensionsElement:n||null,horizontal:"right"===elData(t,"dropdown-alignment-horizontal")?"right":"left",vertical:"top"===elData(t,"dropdown-alignment-vertical")?"top":"bottom",allowFlip:elData(t,"dropdown-allow-flip")||"both"})},setAlignmentById:function(e){var t=h.get(e);if(void 0===t)throw new Error("Unknown dropdown identifier '"+e+"'.");var i=f.get(e);this.setAlignment(t,i)},isOpen:function(e){var t=f.get(e);return void 0!==t&&t.classList.contains("dropdownOpen")},open:function(e,t){var i=f.get(e);void 0===i||i.classList.contains("dropdownOpen")||this.toggleDropdown(e,void 0,t)},close:function(e){var t=h.get(e);void 0!==t&&(t.classList.remove("dropdownOpen"),f.get(e).classList.remove("dropdownOpen"))},closeAll:function(){h.forEach(function(e,t){e.classList.contains("dropdownOpen")&&(e.classList.remove("dropdownOpen"),f.get(t).classList.remove("dropdownOpen"),this._notifyCallbacks(t,"close"))}.bind(this))},destroy:function(e){if(!h.has(e))return!1;try{this.close(e),elRemove(f.get(e))}catch(e){}return f.delete(e),h.delete(e),!0},_onDialogScroll:function(e){for(var t=e.currentTarget,i=elBySelAll(".dropdown.dropdownOpen",t),n=0,o=i.length;n<o;n++){var r=i[n],a=l.identify(r),s=l.offset(r),c=l.offset(t);s.top+r.clientHeight<=c.top?this.toggleDropdown(a):s.top>=c.top+t.offsetHeight?this.toggleDropdown(a):s.left<=c.left?this.toggleDropdown(a):s.left>=c.left+t.offsetWidth?this.toggleDropdown(a):this.setAlignment(h.get(a),f.get(a))}},_onScroll:function(){h.forEach(function(e,t){if(e.classList.contains("dropdownOpen"))if(elDataBool(e,"is-overlay-dropdown-button"))this.setAlignment(e,f.get(t));else{var i=f.get(e.id);elDataBool(i,"dropdown-ignore-page-scroll")||this.close(t)}}.bind(this))},_notifyCallbacks:function(e,t){u.forEach(e,function(i){i(e,t)})},_toggle:function(e,t,i,n){null!==e&&(e.preventDefault(),e.stopPropagation(),t=elData(e.currentTarget,"target"),void 0===n&&e instanceof MouseEvent&&(n=!0));var o=h.get(t),r=!1;if(void 0!==o){var l,s;if(e&&(l=e.currentTarget,(s=l.parentNode)!==o&&(s.classList.add("dropdown"),s.id=o.id,o.classList.remove("dropdown"),o.id="",o=s,h.set(t,s))),void 0===n&&(l=o.closest(".dropdownToggle"),l||!(l=elBySel(".dropdownToggle",o))&&o.id&&(l=elBySel('[data-target="'+o.id+'"]')),l&&elDataBool(l,"dropdown-lazy-init")&&(n=!0)),elDataBool(o,"dropdown-prevent-toggle")&&o.classList.contains("dropdownOpen")&&(r=!0),""===elData(o,"is-overlay-dropdown-button")){var c=a.parentByClass(o,"dialogContent");elData(o,"is-overlay-dropdown-button",null!==c),null!==c&&c.addEventListener("scroll",this._onDialogScroll.bind(this))}}return m="",h.forEach(function(e,o){var a=f.get(o);if(e.classList.contains("dropdownOpen"))if(!1===r){e.classList.remove("dropdownOpen"),a.classList.remove("dropdownOpen");var l=elBySel(".dropdownToggle",e);l&&elAttr(l,"aria-expanded",!1),this._notifyCallbacks(o,"close")}else m=t;else if(o===t&&a.childElementCount>0){m=t,e.classList.add("dropdownOpen"),a.classList.add("dropdownOpen");var l=elBySel(".dropdownToggle",e);if(l&&elAttr(l,"aria-expanded",!0),a.childElementCount&&elDataBool(a.children[0],"scroll-to-active")){var s=a.children[0];s.removeAttribute("data-scroll-to-active");for(var c=null,u=0,d=s.childElementCount;u<d;u++)if(s.children[u].classList.contains("active")){c=s.children[u];break}c&&(s.scrollTop=Math.max(c.offsetTop+c.clientHeight-a.clientHeight,0))}var h=elBySel(".scrollableDropdownMenu",a);null!==h&&h.classList[h.scrollHeight>h.clientHeight?"add":"remove"]("forceScrollbar"),this._notifyCallbacks(o,"open");var p=null;n||(elAttr(a,"role","menu"),elAttr(a,"tabindex",-1),a.removeEventListener("keydown",g),a.addEventListener("keydown",g),elBySelAll("li",a,function(e){e.clientHeight&&(null===p?p=e:e.classList.contains("active")&&(p=e),elAttr(e,"role","menuitem"),elAttr(e,"tabindex",-1))})),this.setAlignment(e,a,i),null!==p&&p.focus()}}.bind(this)),window.WCF.Dropdown.Interactive.Handler.closeAll(),null===e},_handleKeyDown:function(e){"INPUT"!==e.currentTarget.nodeName&&(n.Enter(e)||n.Space(e))&&(e.preventDefault(),this._toggle(e))},_dropdownMenuKeyDown:function(e){var t,i,o=document.activeElement;if("LI"===o.nodeName)if(n.ArrowDown(e)||n.ArrowUp(e)||n.End(e)||n.Home(e)){e.preventDefault();var r=Array.prototype.slice.call(elBySelAll("li",o.closest(".dropdownMenu")));(n.ArrowUp(e)||n.End(e))&&r.reverse();var a=null,l=function(e){return!e.classList.contains("dropdownDivider")&&e.clientHeight>0},s=r.indexOf(o);(n.End(e)||n.Home(e))&&(s=-1);for(var c=s+1;c<r.length;c++)if(l(r[c])){a=r[c];break}if(null===a)for(c=0;c<r.length;c++)if(l(r[c])){a=r[c];break}a.focus()}else if(n.Enter(e)||n.Space(e)){e.preventDefault();var u=o;1!==u.childElementCount||"SPAN"!==u.children[0].nodeName&&"A"!==u.children[0].nodeName||(u=u.children[0]),i=h.get(m),t=elBySel(".dropdownToggle",i),require(["Core"],function(e){var n=elData(i,"a11y-mouse-event")||"click";e.triggerEvent(u,n),t&&t.focus()})}else(n.Escape(e)||n.Tab(e))&&(e.preventDefault(),i=h.get(m),t=elBySel(".dropdownToggle",i),null!==t||i.classList.contains("dropdown")||(t=i),this._toggle(null,m),t&&t.focus())}}}),define("WoltLabSuite/Core/Devtools",[],function(){"use strict";return{help:function(){},toggleEditorAutosave:function(){},toggleEventLogging:function(){},_internal_:{enable:function(){},editorAutosave:function(){},eventLog:function(){}}}}),define("WoltLabSuite/Core/Event/Handler",["Core","Devtools","Dictionary"],function(e,t,i){"use strict";var n=new i;return{add:function(t,o,r){if("function"!=typeof r)throw new TypeError("[WoltLabSuite/Core/Event/Handler] Expected a valid callback for '"+o+"@"+t+"'.");var a=n.get(t);void 0===a&&(a=new i,n.set(t,a));var l=a.get(o);void 0===l&&(l=new i,a.set(o,l));var s=e.getUuid();return l.set(s,r),s},fire:function(e,i,o){t._internal_.eventLog(e,i),o=o||{};var r=n.get(e);if(void 0!==r){var a=r.get(i);void 0!==a&&a.forEach(function(e){e(o)})}},remove:function(e,t,i){var o=n.get(e);if(void 0!==o){var r=o.get(t);void 0!==r&&r.delete(i)}},removeAll:function(e,t){"string"!=typeof t&&(t=void 0);var i=n.get(e);void 0!==i&&(void 0===t?n.delete(e):i.delete(t))},removeAllBySuffix:function(e,t){var i=n.get(e);if(void 0!==i){t="_"+t;var o=-1*t.length;i.forEach(function(i,n){n.substr(o)===t&&this.removeAll(e,n)}.bind(this))}}}}),define("WoltLabSuite/Core/List",[],function(){"use strict";function e(){this._set=t?new Set:[]}var t=objOwns(window,"Set")&&"function"==typeof window.Set;return e.prototype={add:function(e){t?this._set.add(e):this.has(e)||this._set.push(e)},clear:function(){t?this._set.clear():this._set=[]},delete:function(e){if(t)return this._set.delete(e);var i=this._set.indexOf(e);return-1!==i&&(this._set.splice(i,1),!0)},forEach:function(e){
-if(t)this._set.forEach(e);else for(var i=0,n=this._set.length;i<n;i++)e(this._set[i])},has:function(e){return t?this._set.has(e):-1!==this._set.indexOf(e)}},Object.defineProperty(e.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return t?this._set.size:this._set.length}}),e}),define("WoltLabSuite/Core/Ui/Dialog",["Ajax","Core","Dictionary","Environment","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/Screen","Ui/SimpleDropdown","EventHandler","List","EventKey"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f,p){"use strict";var g=null,m=null,v=null,b=new i,_=!1,y=new r,w=new i,C=null,E=null,L=elByClass("jsStaticDialog"),A=["onBeforeClose","onClose","onShow"],S=["number","password","search","tel","text","url"],x=['a[href]:not([tabindex^="-"]):not([inert])','area[href]:not([tabindex^="-"]):not([inert])',"input:not([disabled]):not([inert])","select:not([disabled]):not([inert])","textarea:not([disabled]):not([inert])","button:not([disabled]):not([inert])",'iframe:not([tabindex^="-"]):not([inert])','audio:not([tabindex^="-"]):not([inert])','video:not([tabindex^="-"]):not([inert])','[contenteditable]:not([tabindex^="-"]):not([inert])','[tabindex]:not([tabindex^="-"]):not([inert])'];return{setup:function(){void 0===e&&(e=require("Ajax")),v=elCreate("div"),v.classList.add("dialogOverlay"),elAttr(v,"aria-hidden","true"),v.addEventListener("mousedown",this._closeOnBackdrop.bind(this)),v.addEventListener("wheel",function(e){e.target===v&&e.preventDefault()},{passive:!1}),elById("content").appendChild(v),E=function(e){return 27!==e.keyCode||"INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName||(this.close(g),!1)}.bind(this),u.on("screen-xs",{match:function(){_=!0},unmatch:function(){_=!1},setup:function(){_=!0}}),this._initStaticDialogs(),a.add("Ui/Dialog",this._initStaticDialogs.bind(this)),u.setDialogContainer(v),window.addEventListener("resize",function(){b.forEach(function(e){elAttrBool(e.dialog,"aria-hidden")||this.rebuild(elData(e.dialog,"id"))}.bind(this))}.bind(this))},_initStaticDialogs:function(){for(var e,t,i;L.length;)e=L[0],e.classList.remove("jsStaticDialog"),(i=elData(e,"dialog-id"))&&(t=elById(i))&&function(e,t){t.classList.remove("jsStaticDialogContent"),elData(t,"is-static-dialog",!0),elHide(t),e.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.openStatic(t.id,null,{title:elData(t,"title")})}.bind(this))}.bind(this)(e,t)},open:function(i,n){var o=y.get(i);if(t.isPlainObject(o))return this.openStatic(o.id,n);if("function"!=typeof i._dialogSetup)throw new Error("Callback object does not implement the method '_dialogSetup()'.");var r=i._dialogSetup();if(!t.isPlainObject(r))throw new Error("Expected an object literal as return value of '_dialogSetup()'.");o={id:r.id};var a=!0;if(void 0===r.source){var l=elById(r.id);if(null===l)throw new Error("Element id '"+r.id+"' is invalid and no source attribute was given. If you want to use the `html` argument instead, please add `source: null` to your dialog configuration.");r.source=document.createDocumentFragment(),r.source.appendChild(l),l.removeAttribute("id"),elShow(l)}else if(null===r.source)r.source=n;else if("function"==typeof r.source)r.source();else if(t.isPlainObject(r.source)){if("string"!=typeof n||""===n.trim())return e.api(this,r.source.data,function(e){e.returnValues&&"string"==typeof e.returnValues.template&&(this.open(i,e.returnValues.template),"function"==typeof r.source.after&&r.source.after(b.get(r.id).content,e))}.bind(this)),{};r.source=n}else{if("string"==typeof r.source){var l=elCreate("div");elAttr(l,"id",r.id),s.setInnerHtml(l,r.source),r.source=document.createDocumentFragment(),r.source.appendChild(l)}if(!r.source.nodeType||r.source.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)throw new Error("Expected at least a document fragment as 'source' attribute.");a=!1}return y.set(i,o),w.set(r.id,i),this.openStatic(r.id,r.source,r.options,a)},openStatic:function(e,i,r,a){u.pageOverlayOpen(),"desktop"!==n.platform()&&(this.isOpen(e)||u.scrollDisable()),b.has(e)?this._updateDialog(e,i):(r=t.extend({backdropCloseOnClick:!0,closable:!0,closeButtonLabel:o.get("wcf.global.button.close"),closeConfirmMessage:"",disableContentPadding:!1,title:"",onBeforeClose:null,onClose:null,onShow:null},r),r.closable||(r.backdropCloseOnClick=!1),r.closeConfirmMessage&&(r.onBeforeClose=function(e){c.show({confirm:this.close.bind(this,e),message:r.closeConfirmMessage})}.bind(this)),this._createDialog(e,i,r));var l=b.get(e);return"ios"===n.platform()&&window.setTimeout(function(){var e=elBySel("input, textarea",l.content);null!==e&&e.focus()}.bind(this),200),l},setTitle:function(e,t){e=this._getDialogId(e);var i=b.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");var n=elByClass("dialogTitle",i.dialog);n.length&&(n[0].textContent=t)},setCallback:function(e,t,i){if("object"==typeof e){var n=y.get(e);void 0!==n&&(e=n.id)}var o=b.get(e);if(void 0===o)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if(-1===A.indexOf(t))throw new Error("Invalid callback identifier, '"+t+"' is not recognized.");if("function"!=typeof i&&null!==i)throw new Error("Only functions or the 'null' value are acceptable callback values ('"+typeof i+"' given).");o[t]=i},_createDialog:function(e,t,i,n){var o=null;if(null===t&&null===(o=elById(e)))throw new Error("Expected either a HTML string or an existing element id.");var r=elCreate("div");r.classList.add("dialogContainer"),elAttr(r,"aria-hidden","true"),elAttr(r,"role","dialog"),elData(r,"id",e);var a=elCreate("header");r.appendChild(a);var l=s.getUniqueId();elAttr(r,"aria-labelledby",l);var c=elCreate("span");if(c.classList.add("dialogTitle"),c.textContent=i.title,elAttr(c,"id",l),a.appendChild(c),i.closable){var u=elCreate("a");u.className="dialogCloseButton jsTooltip",u.href="#",elAttr(u,"role","button"),elAttr(u,"tabindex","0"),elAttr(u,"title",i.closeButtonLabel),elAttr(u,"aria-label",i.closeButtonLabel),u.addEventListener(WCF_CLICK_EVENT,this._close.bind(this)),a.appendChild(u);var d=elCreate("span");d.className="icon icon24 fa-times",u.appendChild(d)}var h=elCreate("div");h.classList.add("dialogContent"),i.disableContentPadding&&h.classList.add("dialogContentNoPadding"),r.appendChild(h),h.addEventListener("wheel",function(e){for(var t,i,n,o=!1,r=e.target;;){if(t=r.clientHeight,i=r.scrollHeight,t<i){if(n=r.scrollTop,e.deltaY<0&&n>0){o=!0;break}if(e.deltaY>0&&n+t<i){o=!0;break}}if(!r||r===h)break;r=r.parentNode}!1===o&&e.preventDefault()},{passive:!1});var p;if(null===o)if("string"==typeof t)p=elCreate("div"),p.id=e,s.setInnerHtml(p,t);else{if(!(t instanceof DocumentFragment))throw new TypeError("'html' must either be a string or a DocumentFragment");for(var g,m=[],_=0,y=t.childNodes.length;_<y;_++)g=t.childNodes[_],g.nodeType===Node.ELEMENT_NODE&&m.push(g);"DIV"!==m[0].nodeName||m.length>1?(p=elCreate("div"),p.id=e,p.appendChild(t)):p=m[0]}else p=o;h.appendChild(p),"none"===p.style.getPropertyValue("display")&&elShow(p),b.set(e,{backdropCloseOnClick:i.backdropCloseOnClick,closable:i.closable,content:p,dialog:r,header:a,onBeforeClose:i.onBeforeClose,onClose:i.onClose,onShow:i.onShow,submitButton:null,inputFields:new f}),s.prepend(r,v),"function"==typeof i.onSetup&&i.onSetup(p),!0!==n&&this._updateDialog(e,null)},_updateDialog:function(e,t){var i=b.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("string"==typeof t&&s.setInnerHtml(i.content,t),"true"===elAttr(i.dialog,"aria-hidden")){null===m&&(m=this._maintainFocus.bind(this),document.body.addEventListener("focus",m,{capture:!0})),i.closable&&"true"===elAttr(v,"aria-hidden")&&window.addEventListener("keyup",E),i.dialog.parentNode.insertBefore(i.dialog,i.dialog.parentNode.firstChild),elAttr(i.dialog,"aria-hidden","false"),elAttr(v,"aria-hidden","false"),elData(v,"close-on-click",i.backdropCloseOnClick?"true":"false"),g=e,C=document.activeElement;var n=elBySel(".dialogCloseButton",i.header);n&&elAttr(n,"inert",!0),this._setFocusToFirstItem(i.dialog),n&&n.removeAttribute("inert"),"function"==typeof i.onShow&&i.onShow(i.content),elDataBool(i.content,"is-static-dialog")&&h.fire("com.woltlab.wcf.dialog","openStatic",{content:i.content,id:e}),d.closeAll(),window.WCF.Dropdown.Interactive.Handler.closeAll()}this.rebuild(e),a.trigger()},_maintainFocus:function(e){if(g){var t=b.get(g);t.dialog.contains(e.target)||e.target.closest(".dropdownMenuContainer")||e.target.closest(".datePicker")||this._setFocusToFirstItem(t.dialog,!0)}},_setFocusToFirstItem:function(e,t){var i=this._getFirstFocusableChild(e);null!==i&&(t&&("username"!==i.id&&"username"!==i.name||"safari"===n.browser()&&"ios"===n.platform()&&(i=null)),i&&setTimeout(function(){i.focus()},1))},_getFirstFocusableChild:function(e){for(var t=elBySelAll(x.join(","),e),i=0,n=t.length;i<n;i++)if(t[i].offsetWidth&&t[i].offsetHeight&&t[i].getClientRects().length)return t[i];return null},rebuild:function(e){e=this._getDialogId(e);var t=b.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("true"!==elAttr(t.dialog,"aria-hidden")){var i=t.content.parentNode,o=elBySel(".formSubmit",t.content),r=0;null!==o?(i.classList.add("dialogForm"),o.classList.add("dialogFormSubmit"),r+=s.outerHeight(o),r-=1,i.style.setProperty("margin-bottom",r+"px","")):(i.classList.remove("dialogForm"),i.style.removeProperty("margin-bottom")),r+=s.outerHeight(t.header);var a=window.innerHeight*(_?1:.8)-r;i.style.setProperty("max-height",~~a+"px",""),"chrome"===n.browser()&&(t.content.scrollHeight>a?t.content.style.setProperty("margin-right","-1px",""):t.content.style.removeProperty("margin-right")),"chrome"!==n.browser()&&"safari"!==n.browser()||t.content.parentNode.classList.add("jsWebKitFractionalPixelFix");var l=w.get(e);if(void 0!==l&&"function"==typeof l._dialogSubmit){var c=elBySelAll('input[data-dialog-submit-on-enter="true"]',t.content),u=elBySel('.formSubmit > input[type="submit"], .formSubmit > button[data-type="submit"]',t.content);if(null===u)return void(0===c.length&&console.warn("Broken dialog, expected a submit button.",t.content));if(t.submitButton!==u){t.submitButton=u,u.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),this._submit(e)}.bind(this));for(var d,h=null,f=0,g=c.length;f<g;f++)d=c[f],t.inputFields.has(d)||(-1!==S.indexOf(d.type)?(t.inputFields.add(d),null===h&&(h=function(t){p.Enter(t)&&(t.preventDefault(),this._submit(e))}.bind(this)),d.addEventListener("keydown",h)):console.warn("Unsupported input type.",d))}}}},_submit:function(e){var t=b.get(e),i=!0;t.inputFields.forEach(function(e){e.required&&(""===e.value.trim()?(elInnerError(e,o.get("wcf.global.form.error.empty")),i=!1):elInnerError(e,!1))}),i&&w.get(e)._dialogSubmit()},_close:function(e){e.preventDefault();var t=b.get(g);if("function"==typeof t.onBeforeClose)return t.onBeforeClose(g),!1;this.close(g)},_closeOnBackdrop:function(e){if(e.target!==v)return!0;"true"===elData(v,"close-on-click")?this._close(e):e.preventDefault()},close:function(e){e=this._getDialogId(e);var t=b.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");elAttr(t.dialog,"aria-hidden","true"),document.activeElement.closest(".dialogContainer")===t.dialog&&document.activeElement.blur(),"function"==typeof t.onClose&&t.onClose(e),g=null;for(var i=0;i<v.childElementCount;i++){var o=v.children[i];if("false"===elAttr(o,"aria-hidden")){g=elData(o,"id");break}}u.pageOverlayClose(),null===g?(elAttr(v,"aria-hidden","true"),elData(v,"close-on-click","false"),t.closable&&window.removeEventListener("keyup",E)):(t=b.get(g),elData(v,"close-on-click",t.backdropCloseOnClick?"true":"false")),"desktop"!==n.platform()&&u.scrollEnable()},getDialog:function(e){return b.get(this._getDialogId(e))},isOpen:function(e){var t=this.getDialog(e);return void 0!==t&&"false"===elAttr(t.dialog,"aria-hidden")},destroy:function(e){if("object"!=typeof e||e instanceof String)throw new TypeError("Expected the callback object as parameter.");if(y.has(e)){var t=y.get(e).id;this.isOpen(t)&&this.close(t),b.has(t)&&(elRemove(b.get(t).dialog),b.delete(t)),y.delete(e)}},_getDialogId:function(e){if("object"==typeof e){var t=y.get(e);if(void 0!==t)return t.id}return e.toString()},_ajaxSetup:function(){return{}}}}),define("WoltLabSuite/Core/Ajax/Status",["Language"],function(e){"use strict";var t=0,i=null,n=null;return{_init:function(){i=elCreate("div"),i.classList.add("spinner"),elAttr(i,"role","status");var t=elCreate("span");t.className="icon icon48 fa-spinner",i.appendChild(t);var n=elCreate("span");n.textContent=e.get("wcf.global.loading"),i.appendChild(n),document.body.appendChild(i)},show:function(){null===i&&this._init(),t++,null===n&&(n=window.setTimeout(function(){t&&i.classList.add("active"),n=null},250))},hide:function(){0===--t&&(null!==n&&window.clearTimeout(n),i.classList.remove("active"))}}}),define("WoltLabSuite/Core/Ajax/Request",["Core","Language","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,o,r){"use strict";function a(e){this._data=null,this._options={},this._previousXhr=null,this._xhr=null,this._init(e)}var l=!1,s=!1;return a.prototype={_init:function(t){this._options=e.extend({data:{},contentType:"application/x-www-form-urlencoded; charset=UTF-8",responseType:"application/json",type:"POST",url:"",withCredentials:!1,autoAbort:!1,ignoreError:!1,pinData:!1,silent:!1,includeRequestedWith:!0,failure:null,finalize:null,success:null,progress:null,uploadProgress:null,callbackObject:null},t),"object"==typeof t.callbackObject&&(this._options.callbackObject=t.callbackObject),this._options.url=e.convertLegacyUrl(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),0===this._options.url.indexOf(WSC_API_URL)&&(this._options.includeRequestedWith=!0,this._options.withCredentials=!0),this._options.pinData&&(this._data=e.extend({},this._options.data)),null!==this._options.callbackObject&&("function"==typeof this._options.callbackObject._ajaxFailure&&(this._options.failure=this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxFinalize&&(this._options.finalize=this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxSuccess&&(this._options.success=this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxProgress&&(this._options.progress=this._options.callbackObject._ajaxProgress.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxUploadProgress&&(this._options.uploadProgress=this._options.callbackObject._ajaxUploadProgress.bind(this._options.callbackObject))),!1===l&&(l=!0,window.addEventListener("beforeunload",function(){s=!0}))},sendRequest:function(t){(!0===t||this._options.autoAbort)&&this.abortPrevious(),this._options.silent||r.show(),this._xhr instanceof XMLHttpRequest&&(this._previousXhr=this._xhr),this._xhr=new XMLHttpRequest,this._xhr.open(this._options.type,this._options.url,!0),this._options.contentType&&this._xhr.setRequestHeader("Content-Type",this._options.contentType),(this._options.withCredentials||this._options.includeRequestedWith)&&this._xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),this._options.withCredentials&&(this._xhr.withCredentials=!0);var i=this,n=e.clone(this._options);if(this._xhr.onload=function(){this.readyState===XMLHttpRequest.DONE&&(this.status>=200&&this.status<300||304===this.status?n.responseType&&0!==this.getResponseHeader("Content-Type").indexOf(n.responseType)?i._failure(this,n):i._success(this,n):i._failure(this,n))},this._xhr.onerror=function(){i._failure(this,n)},this._options.progress&&(this._xhr.onprogress=this._options.progress),this._options.uploadProgress&&(this._xhr.upload.onprogress=this._options.uploadProgress),"POST"===this._options.type){var o=this._options.data;"object"==typeof o&&"FormData"!==e.getType(o)&&(o=e.serialize(o)),this._xhr.send(o)}else this._xhr.send()},abortPrevious:function(){null!==this._previousXhr&&(this._previousXhr.abort(),this._previousXhr=null,this._options.silent||r.hide())},setOption:function(e,t){this._options[e]=t},getOption:function(e){return objOwns(this._options,e)?this._options[e]:null},setData:function(t){null!==this._data&&"FormData"!==e.getType(t)&&(t=e.extend(this._data,t)),this._options.data=t},_success:function(e,t){if(t.silent||r.hide(),"function"==typeof t.success){var i=null;if("application/json"===e.getResponseHeader("Content-Type").split(";",1)[0].trim()){try{i=JSON.parse(e.responseText)}catch(i){return void this._failure(e,t)}i&&i.returnValues&&void 0!==i.returnValues.template&&(i.returnValues.template=i.returnValues.template.trim()),i&&i.forceBackgroundQueuePerform&&require(["WoltLabSuite/Core/BackgroundQueue"],function(e){e.invoke()})}t.success(i,e.responseText,e,t.data)}this._finalize(t)},_failure:function(e,i){if(!s){i.silent||r.hide();var a=null;try{a=JSON.parse(e.responseText)}catch(e){}var l=!0;if("function"==typeof i.failure&&(l=i.failure(a||{},e.responseText||"",e,i.data)),!0!==i.ignoreError&&!1!==l){var c=this.getErrorHtml(a,e);c&&(void 0===o&&(o=require("Ui/Dialog")),o.openStatic(n.getUniqueId(),c,{title:t.get("wcf.global.error.title")}))}this._finalize(i)}},getErrorHtml:function(e,t){var i="",n="";if(null!==e?(e.file&&e.line&&(i+="<br><p>File:</p><p>"+e.file+" in line "+e.line+"</p>"),e.stacktrace?i+="<br><p>Stacktrace:</p><p>"+e.stacktrace+"</p>":e.exceptionID&&(i+="<br><p>Exception ID: <code>"+e.exceptionID+"</code></p>"),n=e.message,e.previous.forEach(function(e){i+="<hr><p>"+e.message+"</p>",i+="<br><p>Stacktrace</p><p>"+e.stacktrace+"</p>"})):n=t.responseText,!n||"undefined"===n){if(!ENABLE_DEBUG_MODE)return null;n="XMLHttpRequest failed without a responseText. Check your browser console."}return'<div class="ajaxDebugMessage"><p>'+n+"</p>"+i+"</div>"},_finalize:function(e){"function"==typeof e.finalize&&e.finalize(this._xhr),this._previousXhr=null,i.trigger();for(var t=elBySelAll('a[href*="#"]'),n=0,o=t.length;n<o;n++){var r=t[n],a=elAttr(r,"href");-1===a.indexOf("AJAXProxy")&&-1===a.indexOf("ajax-proxy")||(a=a.substr(a.indexOf("#")),elAttr(r,"href",document.location.toString().replace(/#.*/,"")+a))}}},a}),define("WoltLabSuite/Core/Ajax",["AjaxRequest","Core","ObjectMap"],function(e,t,i){"use strict";var n=new i;return{api:function(t,i,o,r){void 0===e&&(e=require("AjaxRequest")),"object"!=typeof i&&(i={});var a=n.get(t);if(void 0===a){if("function"!=typeof t._ajaxSetup)throw new TypeError("Callback object must implement at least _ajaxSetup().");var l=t._ajaxSetup();l.pinData=!0,l.callbackObject=t,l.url||(l.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,l.withCredentials=!0),a=new e(l),n.set(t,a)}var s=null,c=null;return"function"==typeof o&&(s=a.getOption("success"),a.setOption("success",o)),"function"==typeof r&&(c=a.getOption("failure"),a.setOption("failure",r)),a.setData(i),a.sendRequest(),null!==s&&a.setOption("success",s),null!==c&&a.setOption("failure",c),a},apiOnce:function(t){void 0===e&&(e=require("AjaxRequest")),t.pinData=!1,t.callbackObject=null,t.url||(t.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,t.withCredentials=!0),new e(t).sendRequest(!1)},getRequestObject:function(e){if(!n.has(e))throw new Error("Expected a previously used callback object, provided object is unknown.");return n.get(e)}}}),define("WoltLabSuite/Core/BackgroundQueue",["Ajax"],function(e){"use strict";var t=0,i=!1,n="";return{setUrl:function(e){n=e},invoke:function(){if(""===n)return void console.error("The background queue has not been initialized yet.");i||(i=!0,e.api(this))},_ajaxSuccess:function(e){t++,e>0&&t<5?window.setTimeout(function(){i=!1,this.invoke()}.bind(this),1e3):(i=!1,t=0)},_ajaxSetup:function(){return{url:n,ignoreError:!0,silent:!0}}}}),function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||m)return!1;try{u.clearRect(0,0,s,l),u.drawImage(e,0,0,s,l)}catch(e){}_=setTimeout(function(){t(e)},M.duration),B.setIcon(c)}function i(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,i,n){return t+t+i+i+n+n});var i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return!!i&&{r:parseInt(i[1],16),g:parseInt(i[2],16),b:parseInt(i[3],16)}}function n(e,t){var i,n={};for(i in e)n[i]=e[i];for(i in t)n[i]=t[i];return n}function o(){return y.hidden||y.msHidden||y.webkitHidden||y.mozHidden}e=e||{};var r,a,l,s,c,u,d,h,f,p,g,m,v,b,_,y,w={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1,element:null,dataUrl:!1,win:window};v={},v.ff="undefined"!=typeof InstallTrigger,v.chrome=!!window.chrome,v.opera=!!window.opera||navigator.userAgent.indexOf("Opera")>=0,v.ie=!1,v.safari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,v.supported=v.chrome||v.ff||v.opera;var C=[];g=function(){},h=m=!1;var E={};E.ready=function(){h=!0,E.reset(),g()},E.reset=function(){h&&(C=[],f=!1,p=!1,u.clearRect(0,0,s,l),u.drawImage(d,0,0,s,l),B.setIcon(c),window.clearTimeout(b),window.clearTimeout(_))},E.start=function(){if(h&&!p){var e=function(){f=C[0],p=!1,C.length>0&&(C.shift(),E.start())};if(C.length>0){p=!0;var t=function(){["type","animation","bgColor","textColor","fontFamily","fontStyle"].forEach(function(e){e in C[0].options&&(r[e]=C[0].options[e])}),M.run(C[0].options,function(){e()},!1)};f?M.run(f.options,function(){t()},!0):t()}}};var L={},A=function(e){return e.n="number"==typeof e.n?Math.abs(0|e.n):e.n,e.x=s*e.x,e.y=l*e.y,e.w=s*e.w,e.h=l*e.h,e.len=(""+e.n).length,e};L.circle=function(e){e=A(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),u.clearRect(0,0,s,l),u.drawImage(d,0,0,s,l),u.beginPath(),u.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+r.fontFamily,u.textAlign="center",t?(u.moveTo(e.x+e.w/2,e.y),u.lineTo(e.x+e.w-e.h/2,e.y),u.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),u.lineTo(e.x+e.w,e.y+e.h-e.h/2),u.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),u.lineTo(e.x+e.h/2,e.y+e.h),u.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),u.lineTo(e.x,e.y+e.h/2),u.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):u.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),u.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",u.fill(),u.closePath(),u.beginPath(),u.stroke(),u.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?u.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):u.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),u.closePath()},L.rectangle=function(e){e=A(e);2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w),u.clearRect(0,0,s,l),u.drawImage(d,0,0,s,l),u.beginPath(),u.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.9:1))+"px "+r.fontFamily,u.textAlign="center",u.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",u.fillRect(e.x,e.y,e.w,e.h),u.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?u.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):u.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),u.closePath()};var S=function(e,t){t=("string"==typeof t?{animation:t}:t)||{},g=function(){try{if("number"==typeof e?e>0:""!==e){var n={type:"badge",options:{n:e}};if("animation"in t&&M.types[""+t.animation]&&(n.options.animation=""+t.animation),"type"in t&&L[""+t.type]&&(n.options.type=""+t.type),["bgColor","textColor"].forEach(function(e){e in t&&(n.options[e]=i(t[e]))}),["fontStyle","fontFamily"].forEach(function(e){e in t&&(n.options[e]=t[e])}),C.push(n),C.length>100)throw new Error("Too many badges requests in queue.");E.start()}else E.reset()}catch(e){throw new Error("Error setting badge. Message: "+e.message)}},h&&g()},x=function(e){g=function(){try{var t=e.width,i=e.height,n=document.createElement("img"),o=t/s<i/l?t/s:i/l;n.setAttribute("crossOrigin","anonymous"),n.onload=function(){u.clearRect(0,0,s,l),u.drawImage(n,0,0,s,l),B.setIcon(c)},n.setAttribute("src",e.getAttribute("src")),n.height=i/o,n.width=t/o}catch(e){throw new Error("Error setting image. Message: "+e.message)}},h&&g()},I=function(e){g=function(){B.setIconSrc(e)},h&&g()},D=function(e){g=function(){try{if("stop"===e)return m=!0,E.reset(),void(m=!1);e.addEventListener("play",function(){t(this)},!1)}catch(e){throw new Error("Error setting video. Message: "+e.message)}},h&&g()},T=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),v.supported){var i=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,g=function(){try{if("stop"===e)return m=!0,E.reset(),void(m=!1);i=document.createElement("video"),i.width=s,i.height=l,navigator.getUserMedia({video:!0,audio:!1},function(e){i.src=URL.createObjectURL(e),i.play(),t(i)},function(){})}catch(e){throw new Error("Error setting webcam. Message: "+e.message)}},h&&g()}},k=function(e,t){var n=e;null==t&&"[object Object]"==Object.prototype.toString.call(e)||(n={},n[e]=t);for(var o=Object.keys(n),a=0;a<o.length;a++)"bgColor"==o[a]||"textColor"==o[a]?r[o[a]]=i(n[o[a]]):r[o[a]]=n[o[a]];C.push(f),E.start()},B={};B.getIcons=function(){var e=[];return r.element?e=[r.element]:r.elementId?(e=[y.getElementById(r.elementId)],e[0].setAttribute("href",e[0].getAttribute("src"))):(e=function(){for(var e=[],t=y.getElementsByTagName("head")[0].getElementsByTagName("link"),i=0;i<t.length;i++)/(^|\s)icon(\s|$)/i.test(t[i].getAttribute("rel"))&&e.push(t[i]);return e}(),0===e.length&&(e=[y.createElement("link")],e[0].setAttribute("rel","icon"),y.getElementsByTagName("head")[0].appendChild(e[0]))),e.forEach(function(e){e.setAttribute("type","image/png")}),e},B.setIcon=function(e){var t=e.toDataURL("image/png");B.setIconSrc(t)},B.setIconSrc=function(e){if(r.dataUrl&&r.dataUrl(e),r.element)r.element.setAttribute("href",e),r.element.setAttribute("src",e);else if(r.elementId){var t=y.getElementById(r.elementId);t.setAttribute("href",e),t.setAttribute("src",e)}else if(v.ff||v.opera){var i=a[a.length-1],n=y.createElement("link");a=[n],v.opera&&n.setAttribute("rel","icon"),n.setAttribute("rel","icon"),n.setAttribute("type","image/png"),y.getElementsByTagName("head")[0].appendChild(n),n.setAttribute("href",e),i.parentNode&&i.parentNode.removeChild(i)}else a.forEach(function(t){t.setAttribute("href",e)})};var M={};return M.duration=40,M.types={},M.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],M.run=function(e,t,i,a){var l=M.types[o()?"none":r.animation];if(a=!0===i?void 0!==a?a:l.length-1:void 0!==a?a:0,t=t||function(){},!(a<l.length&&a>=0))return void t();L[r.type](n(e,l[a])),b=setTimeout(function(){i?a-=1:a+=1,M.run(e,t,i,a)},M.duration),B.setIcon(c)},function(){r=n(w,e),r.bgColor=i(r.bgColor),r.textColor=i(r.textColor),r.position=r.position.toLowerCase(),r.animation=M.types[""+r.animation]?r.animation:w.animation,y=r.win.document;var t=r.position.indexOf("up")>-1,o=r.position.indexOf("left")>-1;if(t||o)for(var h in M.types)for(var f=0;f<M.types[h].length;f++){var p=M.types[h][f];t&&(p.y<.6?p.y=p.y-.4:p.y=p.y-2*p.y+(1-p.w)),o&&(p.x<.6?p.x=p.x-.4:p.x=p.x-2*p.x+(1-p.h)),M.types[h][f]=p}r.type=L[""+r.type]?r.type:w.type,a=B.getIcons(),c=document.createElement("canvas"),d=document.createElement("img");var g=a[a.length-1];g.hasAttribute("href")?(d.setAttribute("crossOrigin","anonymous"),d.onload=function(){l=d.height>0?d.height:32,s=d.width>0?d.width:32,c.height=l,c.width=s,u=c.getContext("2d"),E.ready()},d.setAttribute("src",g.getAttribute("href"))):(l=32,s=32,d.height=l,d.width=s,c.height=l,c.width=s,u=c.getContext("2d"),E.ready())}(),{badge:S,video:D,image:x,rawImageSrc:I,webcam:T,setOpt:k,reset:E.reset,browser:{supported:v.supported}}};void 0!==define&&define.amd?define("favico",[],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(),function(e,t,i){var n=window.matchMedia;"undefined"!=typeof module&&module.exports?module.exports=i(n):"function"==typeof define&&define.amd?define("enquire",[],function(){return t.enquire=i(n)}):t.enquire=i(n)}(0,this,function(e){"use strict";function t(e,t){var i=0,n=e.length;for(i;i<n&&!1!==t(e[i],i);i++);}function i(e){return"[object Array]"===Object.prototype.toString.apply(e)}function n(e){return"function"==typeof e}function o(e){this.options=e,!e.deferSetup&&this.setup()}function r(t,i){this.query=t,this.isUnconditional=i,this.handlers=[],this.mql=e(t);var n=this;this.listener=function(e){n.mql=e,n.assess()},this.mql.addListener(this.listener)}function a(){if(!e)throw new Error("matchMedia not present, legacy browsers require a polyfill");this.queries={},this.browserIsIncapable=!e("only all").matches}return o.prototype={setup:function(){this.options.setup&&this.options.setup(),this.initialised=!0},on:function(){!this.initialised&&this.setup(),this.options.match&&this.options.match()},off:function(){this.options.unmatch&&this.options.unmatch()},destroy:function(){this.options.destroy?this.options.destroy():this.off()},equals:function(e){return this.options===e||this.options.match===e}},r.prototype={addHandler:function(e){var t=new o(e);this.handlers.push(t),this.matches()&&t.on()},removeHandler:function(e){var i=this.handlers;t(i,function(t,n){if(t.equals(e))return t.destroy(),!i.splice(n,1)})},matches:function(){return this.mql.matches||this.isUnconditional},clear:function(){t(this.handlers,function(e){e.destroy()}),this.mql.removeListener(this.listener),this.handlers.length=0},assess:function(){var e=this.matches()?"on":"off";t(this.handlers,function(t){t[e]()})}},a.prototype={register:function(e,o,a){var l=this.queries,s=a&&this.browserIsIncapable;return l[e]||(l[e]=new r(e,s)),n(o)&&(o={match:o}),i(o)||(o=[o]),t(o,function(t){n(t)&&(t={match:t}),l[e].addHandler(t)}),this},unregister:function(e,t){var i=this.queries[e];return i&&(t?i.removeHandler(t):(i.clear(),delete this.queries[e])),this}},new a}),function e(t,i,n){function o(a,l){if(!i[a]){if(!t[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(r)return r(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=i[a]={exports:{}};t[a][0].call(u.exports,function(e){var i=t[a][1][e];return o(i||e)},u,u.exports,e,t,i,n)}return i[a].exports}for(var r="function"==typeof require&&require,a=0;a<n.length;a++)o(n[a]);return o}({1:[function(e,t,i){"use strict";var n=e("../main");"function"==typeof define&&define.amd?define("perfect-scrollbar",n):(window.PerfectScrollbar=n,
-void 0===window.Ps&&(window.Ps=n))},{"../main":7}],2:[function(e,t,i){"use strict";function n(e,t){var i=e.className.split(" ");i.indexOf(t)<0&&i.push(t),e.className=i.join(" ")}function o(e,t){var i=e.className.split(" "),n=i.indexOf(t);n>=0&&i.splice(n,1),e.className=i.join(" ")}i.add=function(e,t){e.classList?e.classList.add(t):n(e,t)},i.remove=function(e,t){e.classList?e.classList.remove(t):o(e,t)},i.list=function(e){return e.classList?Array.prototype.slice.apply(e.classList):e.className.split(" ")}},{}],3:[function(e,t,i){"use strict";function n(e,t){return window.getComputedStyle(e)[t]}function o(e,t,i){return"number"==typeof i&&(i=i.toString()+"px"),e.style[t]=i,e}function r(e,t){for(var i in t){var n=t[i];"number"==typeof n&&(n=n.toString()+"px"),e.style[i]=n}return e}var a={};a.e=function(e,t){var i=document.createElement(e);return i.className=t,i},a.appendTo=function(e,t){return t.appendChild(e),e},a.css=function(e,t,i){return"object"==typeof t?r(e,t):void 0===i?n(e,t):o(e,t,i)},a.matches=function(e,t){return void 0!==e.matches?e.matches(t):void 0!==e.matchesSelector?e.matchesSelector(t):void 0!==e.webkitMatchesSelector?e.webkitMatchesSelector(t):void 0!==e.mozMatchesSelector?e.mozMatchesSelector(t):void 0!==e.msMatchesSelector?e.msMatchesSelector(t):void 0},a.remove=function(e){void 0!==e.remove?e.remove():e.parentNode&&e.parentNode.removeChild(e)},a.queryChildren=function(e,t){return Array.prototype.filter.call(e.childNodes,function(e){return a.matches(e,t)})},t.exports=a},{}],4:[function(e,t,i){"use strict";var n=function(e){this.element=e,this.events={}};n.prototype.bind=function(e,t){void 0===this.events[e]&&(this.events[e]=[]),this.events[e].push(t),this.element.addEventListener(e,t,!1)},n.prototype.unbind=function(e,t){var i=void 0!==t;this.events[e]=this.events[e].filter(function(n){return!(!i||n===t)||(this.element.removeEventListener(e,n,!1),!1)},this)},n.prototype.unbindAll=function(){for(var e in this.events)this.unbind(e)};var o=function(){this.eventElements=[]};o.prototype.eventElement=function(e){var t=this.eventElements.filter(function(t){return t.element===e})[0];return void 0===t&&(t=new n(e),this.eventElements.push(t)),t},o.prototype.bind=function(e,t,i){this.eventElement(e).bind(t,i)},o.prototype.unbind=function(e,t,i){this.eventElement(e).unbind(t,i)},o.prototype.unbindAll=function(){for(var e=0;e<this.eventElements.length;e++)this.eventElements[e].unbindAll()},o.prototype.once=function(e,t,i){var n=this.eventElement(e),o=function(e){n.unbind(t,o),i(e)};n.bind(t,o)},t.exports=o},{}],5:[function(e,t,i){"use strict";t.exports=function(){function e(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return e()+e()+"-"+e()+"-"+e()+"-"+e()+"-"+e()+e()+e()}}()},{}],6:[function(e,t,i){"use strict";var n=e("./class"),o=e("./dom"),r=i.toInt=function(e){return parseInt(e,10)||0},a=i.clone=function(e){if(e){if(e.constructor===Array)return e.map(a);if("object"==typeof e){var t={};for(var i in e)t[i]=a(e[i]);return t}return e}return null};i.extend=function(e,t){var i=a(e);for(var n in t)i[n]=a(t[n]);return i},i.isEditable=function(e){return o.matches(e,"input,[contenteditable]")||o.matches(e,"select,[contenteditable]")||o.matches(e,"textarea,[contenteditable]")||o.matches(e,"button,[contenteditable]")},i.removePsClasses=function(e){for(var t=n.list(e),i=0;i<t.length;i++){var o=t[i];0===o.indexOf("ps-")&&n.remove(e,o)}},i.outerWidth=function(e){return r(o.css(e,"width"))+r(o.css(e,"paddingLeft"))+r(o.css(e,"paddingRight"))+r(o.css(e,"borderLeftWidth"))+r(o.css(e,"borderRightWidth"))},i.startScrolling=function(e,t){n.add(e,"ps-in-scrolling"),void 0!==t?n.add(e,"ps-"+t):(n.add(e,"ps-x"),n.add(e,"ps-y"))},i.stopScrolling=function(e,t){n.remove(e,"ps-in-scrolling"),void 0!==t?n.remove(e,"ps-"+t):(n.remove(e,"ps-x"),n.remove(e,"ps-y"))},i.env={isWebKit:"WebkitAppearance"in document.documentElement.style,supportsTouch:"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,supportsIePointer:null!==window.navigator.msMaxTouchPoints}},{"./class":2,"./dom":3}],7:[function(e,t,i){"use strict";var n=e("./plugin/destroy"),o=e("./plugin/initialize"),r=e("./plugin/update");t.exports={initialize:o,update:r,destroy:n}},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(e,t,i){"use strict";t.exports={handlers:["click-rail","drag-scrollbar","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1,theme:"default"}},{}],9:[function(e,t,i){"use strict";var n=e("../lib/helper"),o=e("../lib/dom"),r=e("./instances");t.exports=function(e){var t=r.get(e);t&&(t.event.unbindAll(),o.remove(t.scrollbarX),o.remove(t.scrollbarY),o.remove(t.scrollbarXRail),o.remove(t.scrollbarYRail),n.removePsClasses(e),r.remove(e))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(e,t,i){"use strict";function n(e,t){function i(e){return e.getBoundingClientRect()}var n=function(e){e.stopPropagation()};t.event.bind(t.scrollbarY,"click",n),t.event.bind(t.scrollbarYRail,"click",function(n){var o=n.pageY-window.pageYOffset-i(t.scrollbarYRail).top,l=o>t.scrollbarYTop?1:-1;a(e,"top",e.scrollTop+l*t.containerHeight),r(e),n.stopPropagation()}),t.event.bind(t.scrollbarX,"click",n),t.event.bind(t.scrollbarXRail,"click",function(n){var o=n.pageX-window.pageXOffset-i(t.scrollbarXRail).left,l=o>t.scrollbarXLeft?1:-1;a(e,"left",e.scrollLeft+l*t.containerWidth),r(e),n.stopPropagation()})}var o=e("../instances"),r=e("../update-geometry"),a=e("../update-scroll");t.exports=function(e){n(e,o.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(e,t,i){"use strict";function n(e,t){function i(i){var o=n+i*t.railXRatio,a=Math.max(0,t.scrollbarXRail.getBoundingClientRect().left)+t.railXRatio*(t.railXWidth-t.scrollbarXWidth);t.scrollbarXLeft=o<0?0:o>a?a:o;var l=r.toInt(t.scrollbarXLeft*(t.contentWidth-t.containerWidth)/(t.containerWidth-t.railXRatio*t.scrollbarXWidth))-t.negativeScrollAdjustment;c(e,"left",l)}var n=null,o=null,l=function(t){i(t.pageX-o),s(e),t.stopPropagation(),t.preventDefault()},u=function(){r.stopScrolling(e,"x"),t.event.unbind(t.ownerDocument,"mousemove",l)};t.event.bind(t.scrollbarX,"mousedown",function(i){o=i.pageX,n=r.toInt(a.css(t.scrollbarX,"left"))*t.railXRatio,r.startScrolling(e,"x"),t.event.bind(t.ownerDocument,"mousemove",l),t.event.once(t.ownerDocument,"mouseup",u),i.stopPropagation(),i.preventDefault()})}function o(e,t){function i(i){var o=n+i*t.railYRatio,a=Math.max(0,t.scrollbarYRail.getBoundingClientRect().top)+t.railYRatio*(t.railYHeight-t.scrollbarYHeight);t.scrollbarYTop=o<0?0:o>a?a:o;var l=r.toInt(t.scrollbarYTop*(t.contentHeight-t.containerHeight)/(t.containerHeight-t.railYRatio*t.scrollbarYHeight));c(e,"top",l)}var n=null,o=null,l=function(t){i(t.pageY-o),s(e),t.stopPropagation(),t.preventDefault()},u=function(){r.stopScrolling(e,"y"),t.event.unbind(t.ownerDocument,"mousemove",l)};t.event.bind(t.scrollbarY,"mousedown",function(i){o=i.pageY,n=r.toInt(a.css(t.scrollbarY,"top"))*t.railYRatio,r.startScrolling(e,"y"),t.event.bind(t.ownerDocument,"mousemove",l),t.event.once(t.ownerDocument,"mouseup",u),i.stopPropagation(),i.preventDefault()})}var r=e("../../lib/helper"),a=e("../../lib/dom"),l=e("../instances"),s=e("../update-geometry"),c=e("../update-scroll");t.exports=function(e){var t=l.get(e);n(e,t),o(e,t)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var o=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===o&&n>0||o>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}var n=!1;t.event.bind(e,"mouseenter",function(){n=!0}),t.event.bind(e,"mouseleave",function(){n=!1});var a=!1;t.event.bind(t.ownerDocument,"keydown",function(c){if(!(c.isDefaultPrevented&&c.isDefaultPrevented()||c.defaultPrevented)){var u=r.matches(t.scrollbarX,":focus")||r.matches(t.scrollbarY,":focus");if(n||u){var d=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(d){if("IFRAME"===d.tagName)d=d.contentDocument.activeElement;else for(;d.shadowRoot;)d=d.shadowRoot.activeElement;if(o.isEditable(d))return}var h=0,f=0;switch(c.which){case 37:h=c.metaKey?-t.contentWidth:c.altKey?-t.containerWidth:-30;break;case 38:f=c.metaKey?t.contentHeight:c.altKey?t.containerHeight:30;break;case 39:h=c.metaKey?t.contentWidth:c.altKey?t.containerWidth:30;break;case 40:f=c.metaKey?-t.contentHeight:c.altKey?-t.containerHeight:-30;break;case 33:f=90;break;case 32:f=c.shiftKey?90:-90;break;case 34:f=-90;break;case 35:f=c.ctrlKey?-t.contentHeight:-t.containerHeight;break;case 36:f=c.ctrlKey?e.scrollTop:t.containerHeight;break;default:return}s(e,"top",e.scrollTop-f),s(e,"left",e.scrollLeft+h),l(e),a=i(h,f),a&&c.preventDefault()}}})}var o=e("../../lib/helper"),r=e("../../lib/dom"),a=e("../instances"),l=e("../update-geometry"),s=e("../update-scroll");t.exports=function(e){n(e,a.get(e))}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var o=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===o&&n>0||o>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}function n(e){var t=e.deltaX,i=-1*e.deltaY;return void 0!==t&&void 0!==i||(t=-1*e.wheelDeltaX/6,i=e.wheelDeltaY/6),e.deltaMode&&1===e.deltaMode&&(t*=10,i*=10),t!==t&&i!==i&&(t=0,i=e.wheelDelta),e.shiftKey?[-i,-t]:[t,i]}function o(t,i){var n=e.querySelector("textarea:hover, select[multiple]:hover, .ps-child:hover");if(n){if(!window.getComputedStyle(n).overflow.match(/(scroll|auto)/))return!1;var o=n.scrollHeight-n.clientHeight;if(o>0&&!(0===n.scrollTop&&i>0||n.scrollTop===o&&i<0))return!0;var r=n.scrollLeft-n.clientWidth;if(r>0&&!(0===n.scrollLeft&&t<0||n.scrollLeft===r&&t>0))return!0}return!1}function l(l){var c=n(l),u=c[0],d=c[1];o(u,d)||(s=!1,t.settings.useBothWheelAxes?t.scrollbarYActive&&!t.scrollbarXActive?(d?a(e,"top",e.scrollTop-d*t.settings.wheelSpeed):a(e,"top",e.scrollTop+u*t.settings.wheelSpeed),s=!0):t.scrollbarXActive&&!t.scrollbarYActive&&(u?a(e,"left",e.scrollLeft+u*t.settings.wheelSpeed):a(e,"left",e.scrollLeft-d*t.settings.wheelSpeed),s=!0):(a(e,"top",e.scrollTop-d*t.settings.wheelSpeed),a(e,"left",e.scrollLeft+u*t.settings.wheelSpeed)),r(e),(s=s||i(u,d))&&(l.stopPropagation(),l.preventDefault()))}var s=!1;void 0!==window.onwheel?t.event.bind(e,"wheel",l):void 0!==window.onmousewheel&&t.event.bind(e,"mousewheel",l)}var o=e("../instances"),r=e("../update-geometry"),a=e("../update-scroll");t.exports=function(e){n(e,o.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(e,t,i){"use strict";function n(e,t){t.event.bind(e,"scroll",function(){r(e)})}var o=e("../instances"),r=e("../update-geometry");t.exports=function(e){n(e,o.get(e))}},{"../instances":18,"../update-geometry":19}],15:[function(e,t,i){"use strict";function n(e,t){function i(){var e=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===e.toString().length?null:e.getRangeAt(0).commonAncestorContainer}function n(){c||(c=setInterval(function(){if(!r.get(e))return void clearInterval(c);l(e,"top",e.scrollTop+u.top),l(e,"left",e.scrollLeft+u.left),a(e)},50))}function s(){c&&(clearInterval(c),c=null),o.stopScrolling(e)}var c=null,u={top:0,left:0},d=!1;t.event.bind(t.ownerDocument,"selectionchange",function(){e.contains(i())?d=!0:(d=!1,s())}),t.event.bind(window,"mouseup",function(){d&&(d=!1,s())}),t.event.bind(window,"keyup",function(){d&&(d=!1,s())}),t.event.bind(window,"mousemove",function(t){if(d){var i={x:t.pageX,y:t.pageY},r={left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight};i.x<r.left+3?(u.left=-5,o.startScrolling(e,"x")):i.x>r.right-3?(u.left=5,o.startScrolling(e,"x")):u.left=0,i.y<r.top+3?(u.top=r.top+3-i.y<5?-5:-20,o.startScrolling(e,"y")):i.y>r.bottom-3?(u.top=i.y-r.bottom+3<5?5:20,o.startScrolling(e,"y")):u.top=0,0===u.top&&0===u.left?s():n()}})}var o=e("../../lib/helper"),r=e("../instances"),a=e("../update-geometry"),l=e("../update-scroll");t.exports=function(e){n(e,r.get(e))}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(e,t,i){"use strict";function n(e,t,i,n){function o(i,n){var o=e.scrollTop,r=e.scrollLeft,a=Math.abs(i),l=Math.abs(n);if(l>a){if(n<0&&o===t.contentHeight-t.containerHeight||n>0&&0===o)return!t.settings.swipePropagation}else if(a>l&&(i<0&&r===t.contentWidth-t.containerWidth||i>0&&0===r))return!t.settings.swipePropagation;return!0}function s(t,i){l(e,"top",e.scrollTop-i),l(e,"left",e.scrollLeft-t),a(e)}function c(){y=!0}function u(){y=!1}function d(e){return e.targetTouches?e.targetTouches[0]:e}function h(e){return!(!e.targetTouches||1!==e.targetTouches.length)||!(!e.pointerType||"mouse"===e.pointerType||e.pointerType===e.MSPOINTER_TYPE_MOUSE)}function f(e){if(h(e)){w=!0;var t=d(e);m.pageX=t.pageX,m.pageY=t.pageY,v=(new Date).getTime(),null!==_&&clearInterval(_),e.stopPropagation()}}function p(e){if(!w&&t.settings.swipePropagation&&f(e),!y&&w&&h(e)){var i=d(e),n={pageX:i.pageX,pageY:i.pageY},r=n.pageX-m.pageX,a=n.pageY-m.pageY;s(r,a),m=n;var l=(new Date).getTime(),c=l-v;c>0&&(b.x=r/c,b.y=a/c,v=l),o(r,a)&&(e.stopPropagation(),e.preventDefault())}}function g(){!y&&w&&(w=!1,clearInterval(_),_=setInterval(function(){return r.get(e)&&(b.x||b.y)?Math.abs(b.x)<.01&&Math.abs(b.y)<.01?void clearInterval(_):(s(30*b.x,30*b.y),b.x*=.8,void(b.y*=.8)):void clearInterval(_)},10))}var m={},v=0,b={},_=null,y=!1,w=!1;i?(t.event.bind(window,"touchstart",c),t.event.bind(window,"touchend",u),t.event.bind(e,"touchstart",f),t.event.bind(e,"touchmove",p),t.event.bind(e,"touchend",g)):n&&(window.PointerEvent?(t.event.bind(window,"pointerdown",c),t.event.bind(window,"pointerup",u),t.event.bind(e,"pointerdown",f),t.event.bind(e,"pointermove",p),t.event.bind(e,"pointerup",g)):window.MSPointerEvent&&(t.event.bind(window,"MSPointerDown",c),t.event.bind(window,"MSPointerUp",u),t.event.bind(e,"MSPointerDown",f),t.event.bind(e,"MSPointerMove",p),t.event.bind(e,"MSPointerUp",g)))}var o=e("../../lib/helper"),r=e("../instances"),a=e("../update-geometry"),l=e("../update-scroll");t.exports=function(e){if(o.env.supportsTouch||o.env.supportsIePointer){n(e,r.get(e),o.env.supportsTouch,o.env.supportsIePointer)}}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(e,t,i){"use strict";var n=e("../lib/helper"),o=e("../lib/class"),r=e("./instances"),a=e("./update-geometry"),l={"click-rail":e("./handler/click-rail"),"drag-scrollbar":e("./handler/drag-scrollbar"),keyboard:e("./handler/keyboard"),wheel:e("./handler/mouse-wheel"),touch:e("./handler/touch"),selection:e("./handler/selection")},s=e("./handler/native-scroll");t.exports=function(e,t){t="object"==typeof t?t:{},o.add(e,"ps-container");var i=r.add(e);i.settings=n.extend(i.settings,t),o.add(e,"ps-theme-"+i.settings.theme),i.settings.handlers.forEach(function(t){l[t](e)}),s(e),a(e)}},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(e,t,i){"use strict";function n(e){function t(){s.add(e,"ps-focus")}function i(){s.remove(e,"ps-focus")}var n=this;n.settings=l.clone(c),n.containerWidth=null,n.containerHeight=null,n.contentWidth=null,n.contentHeight=null,n.isRtl="rtl"===u.css(e,"direction"),n.isNegativeScroll=function(){var t=e.scrollLeft,i=null;return e.scrollLeft=-1,i=e.scrollLeft<0,e.scrollLeft=t,i}(),n.negativeScrollAdjustment=n.isNegativeScroll?e.scrollWidth-e.clientWidth:0,n.event=new d,n.ownerDocument=e.ownerDocument||document,n.scrollbarXRail=u.appendTo(u.e("div","ps-scrollbar-x-rail"),e),n.scrollbarX=u.appendTo(u.e("div","ps-scrollbar-x"),n.scrollbarXRail),n.scrollbarX.setAttribute("tabindex",0),n.event.bind(n.scrollbarX,"focus",t),n.event.bind(n.scrollbarX,"blur",i),n.scrollbarXActive=null,n.scrollbarXWidth=null,n.scrollbarXLeft=null,n.scrollbarXBottom=l.toInt(u.css(n.scrollbarXRail,"bottom")),n.isScrollbarXUsingBottom=n.scrollbarXBottom===n.scrollbarXBottom,n.scrollbarXTop=n.isScrollbarXUsingBottom?null:l.toInt(u.css(n.scrollbarXRail,"top")),n.railBorderXWidth=l.toInt(u.css(n.scrollbarXRail,"borderLeftWidth"))+l.toInt(u.css(n.scrollbarXRail,"borderRightWidth")),u.css(n.scrollbarXRail,"display","block"),n.railXMarginWidth=l.toInt(u.css(n.scrollbarXRail,"marginLeft"))+l.toInt(u.css(n.scrollbarXRail,"marginRight")),u.css(n.scrollbarXRail,"display",""),n.railXWidth=null,n.railXRatio=null,n.scrollbarYRail=u.appendTo(u.e("div","ps-scrollbar-y-rail"),e),n.scrollbarY=u.appendTo(u.e("div","ps-scrollbar-y"),n.scrollbarYRail),n.scrollbarY.setAttribute("tabindex",0),n.event.bind(n.scrollbarY,"focus",t),n.event.bind(n.scrollbarY,"blur",i),n.scrollbarYActive=null,n.scrollbarYHeight=null,n.scrollbarYTop=null,n.scrollbarYRight=l.toInt(u.css(n.scrollbarYRail,"right")),n.isScrollbarYUsingRight=n.scrollbarYRight===n.scrollbarYRight,n.scrollbarYLeft=n.isScrollbarYUsingRight?null:l.toInt(u.css(n.scrollbarYRail,"left")),n.scrollbarYOuterWidth=n.isRtl?l.outerWidth(n.scrollbarY):null,n.railBorderYWidth=l.toInt(u.css(n.scrollbarYRail,"borderTopWidth"))+l.toInt(u.css(n.scrollbarYRail,"borderBottomWidth")),u.css(n.scrollbarYRail,"display","block"),n.railYMarginHeight=l.toInt(u.css(n.scrollbarYRail,"marginTop"))+l.toInt(u.css(n.scrollbarYRail,"marginBottom")),u.css(n.scrollbarYRail,"display",""),n.railYHeight=null,n.railYRatio=null}function o(e){return e.getAttribute("data-ps-id")}function r(e,t){e.setAttribute("data-ps-id",t)}function a(e){e.removeAttribute("data-ps-id")}var l=e("../lib/helper"),s=e("../lib/class"),c=e("./default-setting"),u=e("../lib/dom"),d=e("../lib/event-manager"),h=e("../lib/guid"),f={};i.add=function(e){var t=h();return r(e,t),f[t]=new n(e),f[t]},i.remove=function(e){delete f[o(e)],a(e)},i.get=function(e){return f[o(e)]}},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(e,t,i){"use strict";function n(e,t){return e.settings.minScrollbarLength&&(t=Math.max(t,e.settings.minScrollbarLength)),e.settings.maxScrollbarLength&&(t=Math.min(t,e.settings.maxScrollbarLength)),t}function o(e,t){var i={width:t.railXWidth};t.isRtl?i.left=t.negativeScrollAdjustment+e.scrollLeft+t.containerWidth-t.contentWidth:i.left=e.scrollLeft,t.isScrollbarXUsingBottom?i.bottom=t.scrollbarXBottom-e.scrollTop:i.top=t.scrollbarXTop+e.scrollTop,l.css(t.scrollbarXRail,i);var n={top:e.scrollTop,height:t.railYHeight};t.isScrollbarYUsingRight?t.isRtl?n.right=t.contentWidth-(t.negativeScrollAdjustment+e.scrollLeft)-t.scrollbarYRight-t.scrollbarYOuterWidth:n.right=t.scrollbarYRight-e.scrollLeft:t.isRtl?n.left=t.negativeScrollAdjustment+e.scrollLeft+2*t.containerWidth-t.contentWidth-t.scrollbarYLeft-t.scrollbarYOuterWidth:n.left=t.scrollbarYLeft+e.scrollLeft,l.css(t.scrollbarYRail,n),l.css(t.scrollbarX,{left:t.scrollbarXLeft,width:t.scrollbarXWidth-t.railBorderXWidth}),l.css(t.scrollbarY,{top:t.scrollbarYTop,height:t.scrollbarYHeight-t.railBorderYWidth})}var r=e("../lib/helper"),a=e("../lib/class"),l=e("../lib/dom"),s=e("./instances"),c=e("./update-scroll");t.exports=function(e){var t=s.get(e);t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight;var i;e.contains(t.scrollbarXRail)||(i=l.queryChildren(e,".ps-scrollbar-x-rail"),i.length>0&&i.forEach(function(e){l.remove(e)}),l.appendTo(t.scrollbarXRail,e)),e.contains(t.scrollbarYRail)||(i=l.queryChildren(e,".ps-scrollbar-y-rail"),i.length>0&&i.forEach(function(e){l.remove(e)}),l.appendTo(t.scrollbarYRail,e)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset<t.contentWidth?(t.scrollbarXActive=!0,t.railXWidth=t.containerWidth-t.railXMarginWidth,t.railXRatio=t.containerWidth/t.railXWidth,t.scrollbarXWidth=n(t,r.toInt(t.railXWidth*t.containerWidth/t.contentWidth)),t.scrollbarXLeft=r.toInt((t.negativeScrollAdjustment+e.scrollLeft)*(t.railXWidth-t.scrollbarXWidth)/(t.contentWidth-t.containerWidth))):t.scrollbarXActive=!1,!t.settings.suppressScrollY&&t.containerHeight+t.settings.scrollYMarginOffset<t.contentHeight?(t.scrollbarYActive=!0,t.railYHeight=t.containerHeight-t.railYMarginHeight,t.railYRatio=t.containerHeight/t.railYHeight,t.scrollbarYHeight=n(t,r.toInt(t.railYHeight*t.containerHeight/t.contentHeight)),t.scrollbarYTop=r.toInt(e.scrollTop*(t.railYHeight-t.scrollbarYHeight)/(t.contentHeight-t.containerHeight))):t.scrollbarYActive=!1,t.scrollbarXLeft>=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),o(e,t),t.scrollbarXActive?a.add(e,"ps-active-x"):(a.remove(e,"ps-active-x"),t.scrollbarXWidth=0,t.scrollbarXLeft=0,c(e,"left",0)),t.scrollbarYActive?a.add(e,"ps-active-y"):(a.remove(e,"ps-active-y"),t.scrollbarYHeight=0,t.scrollbarYTop=0,c(e,"top",0))}},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(e,t,i){"use strict";var n,o,r=e("./instances"),a=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!0),t};t.exports=function(e,t,i){if(void 0===e)throw"You must provide an element to the update-scroll function";if(void 0===t)throw"You must provide an axis to the update-scroll function";if(void 0===i)throw"You must provide a value to the update-scroll function";"top"===t&&i<=0&&(e.scrollTop=i=0,e.dispatchEvent(a("ps-y-reach-start"))),"left"===t&&i<=0&&(e.scrollLeft=i=0,e.dispatchEvent(a("ps-x-reach-start")));var l=r.get(e);"top"===t&&i>=l.contentHeight-l.containerHeight&&(i=l.contentHeight-l.containerHeight,i-e.scrollTop<=1?i=e.scrollTop:e.scrollTop=i,e.dispatchEvent(a("ps-y-reach-end"))),"left"===t&&i>=l.contentWidth-l.containerWidth&&(i=l.contentWidth-l.containerWidth,i-e.scrollLeft<=1?i=e.scrollLeft:e.scrollLeft=i,e.dispatchEvent(a("ps-x-reach-end"))),n||(n=e.scrollTop),o||(o=e.scrollLeft),"top"===t&&i<n&&e.dispatchEvent(a("ps-scroll-up")),"top"===t&&i>n&&e.dispatchEvent(a("ps-scroll-down")),"left"===t&&i<o&&e.dispatchEvent(a("ps-scroll-left")),"left"===t&&i>o&&e.dispatchEvent(a("ps-scroll-right")),"top"===t&&(e.scrollTop=n=i,e.dispatchEvent(a("ps-scroll-y"))),"left"===t&&(e.scrollLeft=o=i,e.dispatchEvent(a("ps-scroll-x")))}},{"./instances":18}],21:[function(e,t,i){"use strict";var n=e("../lib/helper"),o=e("../lib/dom"),r=e("./instances"),a=e("./update-geometry"),l=e("./update-scroll");t.exports=function(e){var t=r.get(e);t&&(t.negativeScrollAdjustment=t.isNegativeScroll?e.scrollWidth-e.clientWidth:0,o.css(t.scrollbarXRail,"display","block"),o.css(t.scrollbarYRail,"display","block"),t.railXMarginWidth=n.toInt(o.css(t.scrollbarXRail,"marginLeft"))+n.toInt(o.css(t.scrollbarXRail,"marginRight")),t.railYMarginHeight=n.toInt(o.css(t.scrollbarYRail,"marginTop"))+n.toInt(o.css(t.scrollbarYRail,"marginBottom")),o.css(t.scrollbarXRail,"display","none"),o.css(t.scrollbarYRail,"display","none"),a(e),l(e,"top",e.scrollTop),l(e,"left",e.scrollLeft),o.css(t.scrollbarXRail,"display",""),o.css(t.scrollbarYRail,"display",""))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]),define("WoltLabSuite/Core/Date/Util",["Language"],function(e){"use strict";return{formatDate:function(t){return this.format(t,e.get("wcf.date.dateFormat"))},formatTime:function(t){return this.format(t,e.get("wcf.date.timeFormat"))},formatDateTime:function(t){return this.format(t,e.get("wcf.date.dateTimeFormat").replace(/%date%/,e.get("wcf.date.dateFormat")).replace(/%time%/,e.get("wcf.date.timeFormat")))},format:function(t,i){var n,o="";"c"===i&&(i="Y-m-dTH:i:sP");for(var r=0,a=i.length;r<a;r++){switch(i[r]){case"s":n=("0"+t.getSeconds().toString()).slice(-2);break;case"i":n=t.getMinutes(),n<10&&(n="0"+n);break;case"a":n=t.getHours()>11?"pm":"am";break;case"g":n=t.getHours(),0===n?n=12:n>12&&(n-=12);break;case"h":n=t.getHours(),0===n?n=12:n>12&&(n-=12),n=("0"+n.toString()).slice(-2);break;case"A":n=t.getHours()>11?"PM":"AM";break;case"G":n=t.getHours();break;case"H":n=t.getHours(),n=("0"+n.toString()).slice(-2);break;case"d":n=t.getDate(),n=("0"+n.toString()).slice(-2);break;case"j":n=t.getDate();break;case"l":n=e.get("__days")[t.getDay()];break;case"D":n=e.get("__daysShort")[t.getDay()];break;case"S":n="";break;case"m":n=t.getMonth()+1,n=("0"+n.toString()).slice(-2);break;case"n":n=t.getMonth()+1;break;case"F":n=e.get("__months")[t.getMonth()];break;case"M":n=e.get("__monthsShort")[t.getMonth()];break;case"y":n=t.getFullYear().toString().substr(2);break;case"Y":n=t.getFullYear();break;case"P":var l=t.getTimezoneOffset();n=l>0?"-":"+",l=Math.abs(l),n+=("0"+(~~(l/60)).toString()).slice(-2),n+=":",n+=("0"+(l%60).toString()).slice(-2);break;case"r":n=t.toString();break;case"U":n=Math.round(t.getTime()/1e3);break;case"\\":n="",r+1<a&&(n=i[++r]);break;default:n=i[r]}o+=n}return o},gmdate:function(e){return e instanceof Date||(e=new Date),Math.round(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDay(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds())/1e3)},getTimeElement:function(t){var i=elCreate("time");i.className="datetime";var n=this.formatDate(t),o=this.formatTime(t);return elAttr(i,"datetime",this.format(t,"c")),elData(i,"timestamp",(t.getTime()-t.getMilliseconds())/1e3),elData(i,"date",n),elData(i,"time",o),elData(i,"offset",60*t.getTimezoneOffset()),t.getTime()>Date.now()&&(elData(i,"is-future-date","true"),i.textContent=e.get("wcf.date.dateTimeFormat").replace("%time%",o).replace("%date%",n)),i},getTimezoneDate:function(e,t){var i=new Date(e),n=6e4*i.getTimezoneOffset();return new Date(e+n+t)}}}),define("WoltLabSuite/Core/Timer/Repeating",[],function(){"use strict";function e(e,t){if("function"!=typeof e)throw new TypeError("Expected a valid callback as first argument.");if(t<0||t>864e5)throw new RangeError("Invalid delta "+t+". Delta must be in the interval [0, 86400000].");this._callback=e.bind(void 0,this),this._delta=t,this._timer=void 0,this.restart()}return e.prototype={restart:function(){this.stop(),this._timer=setInterval(this._callback,this._delta)},stop:function(){void 0!==this._timer&&(clearInterval(this._timer),this._timer=void 0)},setDelta:function(e){this._delta=e,this.restart()}},e}),define("WoltLabSuite/Core/Date/Time/Relative",["Dom/ChangeListener","Language","WoltLabSuite/Core/Date/Util","WoltLabSuite/Core/Timer/Repeating"],function(e,t,i,n){"use strict";var o=elByTag("time"),r=!0,a=!1,l=null;return{setup:function(){new n(this._refresh.bind(this),6e4),e.add("WoltLabSuite/Core/Date/Time/Relative",this._refresh.bind(this)),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this))},_onVisibilityChange:function(){document.hidden?(r=!1,a=!1):(r=!0,a&&(this._refresh(),a=!1))},_refresh:function(){if(!r)return void(a||(a=!0));var e=new Date,n=(e.getTime()-e.getMilliseconds())/1e3;null===l&&(l=n-window.TIME_NOW);for(var s=0,c=o.length;s<c;s++){var u=o[s];if(u.classList.contains("datetime")&&!elData(u,"is-future-date")){var d=~~elData(u,"timestamp")+l,h=elData(u,"date"),f=elData(u,"time"),p=elData(u,"offset");if(elAttr(u,"title")||elAttr(u,"title",t.get("wcf.date.dateTimeFormat").replace(/%date%/,h).replace(/%time%/,f)),d>=n||n<d+60)u.textContent=t.get("wcf.date.relative.now");else if(n<d+3540){var g=Math.max(Math.round((n-d)/60),1);u.textContent=t.get("wcf.date.relative.minutes",{minutes:g})}else if(n<d+86400){var m=Math.round((n-d)/3600);u.textContent=t.get("wcf.date.relative.hours",{hours:m})}else if(n<d+518400){var v=new Date(e.getFullYear(),e.getMonth(),e.getDate()),b=Math.ceil((v/1e3-d)/86400),_=i.getTimezoneDate(1e3*d,1e3*p),y=_.getDay(),w=t.get("__days")[y];u.textContent=t.get("wcf.date.relative.pastDays",{days:b,day:w,time:f})}else u.textContent=t.get("wcf.date.shortDateTimeFormat").replace(/%date%/,h).replace(/%time%/,f)}}}}}),define("WoltLabSuite/Core/Ui/Page/Menu/Abstract",["Core","Environment","EventHandler","Language","ObjectMap","Dom/Traverse","Dom/Util","Ui/Screen"],function(e,t,i,n,o,r,a,l){"use strict";function s(e,t,i){this.init(e,t,i)}var c=elById("pageContainer"),u="";return s.prototype={init:function(e,n,r){if("packageInstallationSetup"!==elData(document.body,"template")){this._activeList=[],this._depth=0,this._enabled=!0,this._eventIdentifier=e,this._items=new o,this._menu=elById(n),this._removeActiveList=!1;var l=this.open.bind(this);this._button=elBySel(r),this._button.addEventListener(WCF_CLICK_EVENT,l),this._initItems(),this._initHeader(),i.add(this._eventIdentifier,"open",l),i.add(this._eventIdentifier,"close",this.close.bind(this)),i.add(this._eventIdentifier,"updateButtonState",this._updateButtonState.bind(this));var s,c=elByClass("menuOverlayItemList",this._menu);this._menu.addEventListener("animationend",function(){if(!this._menu.classList.contains("open"))for(var e=0,t=c.length;e<t;e++)s=c[e],s.classList.remove("active"),s.classList.remove("hidden")}.bind(this)),this._menu.children[0].addEventListener("transitionend",function(){if(this._menu.classList.add("allowScroll"),this._removeActiveList){this._removeActiveList=!1;var e=this._activeList.pop();e&&e.classList.remove("activeList")}}.bind(this));var u=elCreate("div");u.className="menuOverlayMobileBackdrop",u.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),a.insertAfter(u,this._menu),this._updateButtonState(),"android"===t.platform()&&this._initializeAndroid()}},open:function(e){return!!this._enabled&&(e instanceof Event&&e.preventDefault(),this._menu.classList.add("open"),this._menu.classList.add("allowScroll"),this._menu.children[0].classList.add("activeList"),l.scrollDisable(),c.classList.add("menuOverlay-"+this._menu.id),l.pageOverlayOpen(),!0)},close:function(e){return e instanceof Event&&e.preventDefault(),!!this._menu.classList.contains("open")&&(this._menu.classList.remove("open"),l.scrollEnable(),l.pageOverlayClose(),c.classList.remove("menuOverlay-"+this._menu.id),!0)},enable:function(){this._enabled=!0},disable:function(){this._enabled=!1,this.close(!0)},_initializeAndroid:function(){var t,i,n;switch(this._menu.id){case"pageUserMenuMobile":t="right";break;case"pageMainMenuMobile":t="left";break;default:return}i=this._menu.nextElementSibling,n=null,document.addEventListener("touchstart",function(i){var o,r,a,s;if(o=i.touches,r=this._menu.classList.contains("open"),"left"===t?(a=!r&&o[0].clientX<20,s=r&&Math.abs(this._menu.offsetWidth-o[0].clientX)<20):"right"===t&&(a=r&&Math.abs(document.body.clientWidth-this._menu.offsetWidth-o[0].clientX)<20,s=!r&&document.body.clientWidth-o[0].clientX<20),o.length>1)return void(u&&e.triggerEvent(document,"touchend"));if(!u&&(a||s)){if(l.pageOverlayIsActive()){for(var d=!1,h=0;h<c.classList.length;h++)c.classList[h]==="menuOverlay-"+this._menu.id&&(d=!0);if(!d)return}document.documentElement.classList.contains("redactorActive")||(n={x:o[0].clientX,y:o[0].clientY},a&&(u="left"),s&&(u="right"))}}.bind(this)),document.addEventListener("touchend",function(e){if(u&&null!==n){if(!this._menu.classList.contains("open"))return n=null,void(u="");var o;o=e?e.changedTouches[0].clientX:n.x,
-this._menu.classList.add("androidMenuTouchEnd"),this._menu.style.removeProperty("transform"),i.style.removeProperty(t),this._menu.addEventListener("transitionend",function(){this._menu.classList.remove("androidMenuTouchEnd")}.bind(this),{once:!0}),"left"===t?("left"===u&&o<n.x+100&&this.close(),"right"===u&&o<n.x-100&&this.close()):"right"===t&&("left"===u&&o>n.x+100&&this.close(),"right"===u&&o>n.x-100&&this.close()),n=null,u=""}}.bind(this)),document.addEventListener("touchmove",function(e){if(u&&null!==n){var o=e.touches,r=!1,a=!1;"left"===u&&(r=o[0].clientX>n.x+5),"right"===u&&(r=o[0].clientX<n.x-5),a=Math.abs(o[0].clientY-n.y)>20;var l=this._menu.classList.contains("open");if(l||!r||a||(this.open(),l=!0),l){var s=o[0].clientX;"right"===t&&(s=document.body.clientWidth-s),s>this._menu.offsetWidth&&(s=this._menu.offsetWidth),s<0&&(s=0),this._menu.style.setProperty("transform","translateX("+("left"===t?1:-1)*(s-this._menu.offsetWidth)+"px)"),i.style.setProperty(t,Math.min(this._menu.offsetWidth,s)+"px")}}}.bind(this))},_initItems:function(){elBySelAll(".menuOverlayItemLink",this._menu,this._initItem.bind(this))},_initItem:function(e){var t=e.parentNode,n=elData(t,"more");if(n)return void e.addEventListener(WCF_CLICK_EVENT,function(o){o.preventDefault(),o.stopPropagation(),i.fire(this._eventIdentifier,"more",{handler:this,identifier:n,item:e,parent:t})}.bind(this));var o,a=e.nextElementSibling;if(null!==a)if("OL"!==a.nodeName&&a.classList.contains("menuOverlayItemLinkIcon"))for(o=elCreate("span"),o.className="menuOverlayItemWrapper",t.insertBefore(o,e),o.appendChild(e);o.nextElementSibling;)o.appendChild(o.nextElementSibling);else{var l="#"!==elAttr(e,"href"),s=t.parentNode,c=elData(a,"title");this._items.set(e,{itemList:a,parentItemList:s}),""===c&&(c=r.childByClass(e,"menuOverlayItemTitle").textContent,elData(a,"title",c));var u=this._showItemList.bind(this,e);if(l){o=elCreate("span"),o.className="menuOverlayItemWrapper",t.insertBefore(o,e),o.appendChild(e);var d=elCreate("a");elAttr(d,"href","#"),d.className="menuOverlayItemLinkIcon"+(e.classList.contains("active")?" active":""),d.innerHTML='<span class="icon icon24 fa-angle-right"></span>',d.addEventListener(WCF_CLICK_EVENT,u),o.appendChild(d)}else e.classList.add("menuOverlayItemLinkMore"),e.addEventListener(WCF_CLICK_EVENT,u);var h=elCreate("li");h.className="menuOverlayHeader",o=elCreate("span"),o.className="menuOverlayItemWrapper";var f=elCreate("a");elAttr(f,"href","#"),f.className="menuOverlayItemLink menuOverlayBackLink",f.textContent=elData(s,"title"),f.addEventListener(WCF_CLICK_EVENT,this._hideItemList.bind(this,e));var p=elCreate("a");if(elAttr(p,"href","#"),p.className="menuOverlayItemLinkIcon",p.innerHTML='<span class="icon icon24 fa-times"></span>',p.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),o.appendChild(f),o.appendChild(p),h.appendChild(o),a.insertBefore(h,a.firstElementChild),!h.nextElementSibling.classList.contains("menuOverlayTitle")){var g=elCreate("li");g.className="menuOverlayTitle";var m=elCreate("span");m.textContent=c,g.appendChild(m),a.insertBefore(g,h.nextElementSibling)}}},_initHeader:function(){var e=elCreate("li");e.className="menuOverlayHeader";var t=elCreate("span");t.className="menuOverlayItemWrapper",e.appendChild(t);var i=elCreate("span");i.className="menuOverlayLogoWrapper",t.appendChild(i);var n=elCreate("span");n.className="menuOverlayLogo",n.style.setProperty("background-image",'url("'+elData(this._menu,"page-logo")+'")',""),i.appendChild(n);var o=elCreate("a");elAttr(o,"href","#"),o.className="menuOverlayItemLinkIcon",o.innerHTML='<span class="icon icon24 fa-times"></span>',o.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),t.appendChild(o);var a=r.childByClass(this._menu,"menuOverlayItemList");a.insertBefore(e,a.firstElementChild)},_hideItemList:function(e,t){t instanceof Event&&t.preventDefault(),this._menu.classList.remove("allowScroll"),this._removeActiveList=!0,this._items.get(e).parentItemList.classList.remove("hidden"),this._updateDepth(!1)},_showItemList:function(e,t){t instanceof Event&&t.preventDefault();var n=this._items.get(e),o=elData(n.itemList,"load");if(o&&!elDataBool(e,"loaded")){var r=t.currentTarget.firstElementChild;return r.classList.contains("fa-angle-right")&&(r.classList.remove("fa-angle-right"),r.classList.add("fa-spinner")),void i.fire(this._eventIdentifier,"load_"+o)}this._menu.classList.remove("allowScroll"),n.itemList.classList.add("activeList"),n.parentItemList.classList.add("hidden"),this._activeList.push(n.itemList),this._updateDepth(!0)},_updateDepth:function(e){this._depth+=e?1:-1;var t=-100*this._depth;"rtl"===n.get("wcf.global.pageDirection")&&(t*=-1),this._menu.children[0].style.setProperty("transform","translateX("+t+"%)","")},_updateButtonState:function(){var e=!1;elBySelAll(".badgeUpdate",this._menu,function(t){~~t.textContent>0&&(e=!0)}),this._button.classList[e?"add":"remove"]("pageMenuMobileButtonHasContent")}},s}),define("WoltLabSuite/Core/Ui/Page/Menu/Main",["Core","Language","Dom/Traverse","./Abstract"],function(e,t,i,n){"use strict";function o(){this.init()}var r=null,a=null,l=null,s=null,c=null;return e.inherit(o,n,{init:function(){o._super.prototype.init.call(this,"com.woltlab.wcf.MainMenuMobile","pageMainMenuMobile","#pageHeader .mainMenu"),r=elById("pageMainMenuMobilePageOptionsTitle"),null!==r&&(l=i.childByClass(r,"menuOverlayItemList"),s=elBySel(".jsPageNavigationIcons"),c=function(e){this.close(),e.stopPropagation()}.bind(this)),elAttr(this._button,"aria-label",t.get("wcf.menu.page")),elAttr(this._button,"role","button")},open:function(e){if(!o._super.prototype.open.call(this,e))return!1;if(null===r)return!0;if(a=s&&s.childElementCount>0){for(var t,i;s.childElementCount;)t=s.children[0],t.classList.add("menuOverlayItem"),t.classList.add("menuOverlayItemOption"),t.addEventListener(WCF_CLICK_EVENT,c),i=t.children[0],i.classList.add("menuOverlayItemLink"),i.classList.add("box24"),i.children[1].classList.remove("invisible"),i.children[1].classList.add("menuOverlayItemTitle"),r.parentNode.insertBefore(t,r.nextSibling);elShow(r)}else elHide(r);return!0},close:function(e){if(!o._super.prototype.close.call(this,e))return!1;if(a){elHide(r);for(var t,i=r.nextElementSibling;i&&i.classList.contains("menuOverlayItemOption");)i.classList.remove("menuOverlayItem"),i.classList.remove("menuOverlayItemOption"),i.removeEventListener(WCF_CLICK_EVENT,c),t=i.children[0],t.classList.remove("menuOverlayItemLink"),t.classList.remove("box24"),t.children[1].classList.add("invisible"),t.children[1].classList.remove("menuOverlayItemTitle"),s.appendChild(i),i=i.nextElementSibling}return!0}}),o}),define("WoltLabSuite/Core/Ui/Page/Menu/User",["Core","EventHandler","Language","./Abstract"],function(e,t,i,n){"use strict";function o(){this.init()}return e.inherit(o,n,{init:function(){var e=elBySel("#pageUserMenuMobile > .menuOverlayItemList");if(1===e.childElementCount&&e.children[0].classList.contains("menuOverlayTitle"))return void elBySel("#pageHeader .userPanel").classList.add("hideUserPanel");o._super.prototype.init.call(this,"com.woltlab.wcf.UserMenuMobile","pageUserMenuMobile","#pageHeader .userPanel"),t.add("com.woltlab.wcf.userMenu","updateBadge",function(e){elBySelAll(".menuOverlayItemBadge",this._menu,function(t){if(elData(t,"badge-identifier")===e.identifier){var i=elBySel(".badge",t);e.count?(null===i&&(i=elCreate("span"),i.className="badge badgeUpdate",t.appendChild(i)),i.textContent=e.count):null!==i&&elRemove(i),this._updateButtonState()}}.bind(this))}.bind(this)),elAttr(this._button,"aria-label",i.get("wcf.menu.user")),elAttr(this._button,"role","button")},close:function(e){if(void 0!==this._menu){var t=WCF.Dropdown.Interactive.Handler.getOpenDropdown();t?(e.preventDefault(),e.stopPropagation(),t.close()):o._super.prototype.close.call(this,e)}}}),o}),define("WoltLabSuite/Core/Ui/Dropdown/Reusable",["Dictionary","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!n.has(e))throw new Error("Unknown dropdown identifier '"+e+"'");return n.get(e)}var n=new e,o=0;return{init:function(e,i){if(!n.has(e)){var r=elCreate("div");r.id="reusableDropdownGhost"+o++,t.initFragment(r,i),n.set(e,r.id)}},getDropdownMenu:function(e){return t.getDropdownMenu(i(e))},registerCallback:function(e,n){t.registerCallback(i(e),n)},toggleDropdown:function(e,n){t.toggleDropdown(i(e),n)}}}),define("WoltLabSuite/Core/Ui/Mobile",["Core","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Alignment","Ui/CloseOverlay","Ui/Screen","./Page/Menu/Main","./Page/Menu/User","WoltLabSuite/Core/Ui/Dropdown/Reusable"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";var p=elByClass("buttonGroupNavigation"),g=null,m=null,v=null,b=!1,_=!1,y=new o,w=null,C=elByClass("message"),E={},L=null,A=null,S=null,x=[],I=!1;return{setup:function(i){E=e.extend({enableMobileMenu:!0},i),w=elById("main"),elBySelAll(".sidebar",void 0,function(e){x.push(e)}),t.touch()&&document.documentElement.classList.add("touch"),"desktop"!==t.platform()&&document.documentElement.classList.add("mobile");var n=elBySel(".messageGroupList");n&&(S=elByClass("messageGroup",n)),u.on("screen-md-down",{match:this.enable.bind(this),unmatch:this.disable.bind(this),setup:this._init.bind(this)}),u.on("screen-sm-down",{match:this.enableShadow.bind(this),unmatch:this.disableShadow.bind(this),setup:this.enableShadow.bind(this)}),u.on("screen-xs",{match:this._enableSidebarXS.bind(this),unmatch:this._disableSidebarXS.bind(this),setup:this._setupSidebarXS.bind(this)}),!t.touch()||"ios"!==t.platform()&&"android"!==t.platform()||u.on("screen-lg",{match:this._enableLGTouchNavigation.bind(this),unmatch:this._disableLGTouchNavigation.bind(this),setup:this._setupLGTouchNavigation.bind(this)})},enable:function(){b=!0,E.enableMobileMenu&&(L.enable(),A.enable())},enableShadow:function(){S&&this.rebuildShadow(S,".messageGroupLink")},disable:function(){b=!1,E.enableMobileMenu&&(L.disable(),A.disable())},disableShadow:function(){S&&this.removeShadow(S),m&&g()},_init:function(){b=!0,this._initSearchBar(),this._initButtonGroupNavigation(),this._initMessages(),this._initMobileMenu(),c.add("WoltLabSuite/Core/Ui/Mobile",this._closeAllMenus.bind(this)),r.add("WoltLabSuite/Core/Ui/Mobile",function(){this._initButtonGroupNavigation(),this._initMessages()}.bind(this))},_initSearchBar:function(){var e=elById("pageHeaderSearch"),n=elById("pageHeaderSearchInput"),o=null;i.add("com.woltlab.wcf.MainMenuMobile","more",function(i){"com.woltlab.wcf.search"===i.identifier&&(i.handler.close(!0),"ios"===t.platform()&&(o=document.body.scrollTop,u.scrollDisable()),e.style.setProperty("top",elById("pageHeader").offsetHeight+"px",""),e.classList.add("open"),n.focus(),"ios"===t.platform()&&(document.body.scrollTop=0))}),w.addEventListener(WCF_CLICK_EVENT,function(){e&&e.classList.remove("open"),"ios"===t.platform()&&null!==o&&(u.scrollEnable(),document.body.scrollTop=o,o=null)})},_initButtonGroupNavigation:function(){for(var e=0,t=p.length;e<t;e++){var i=p[e];if(!i.classList.contains("jsMobileButtonGroupNavigation")){i.classList.add("jsMobileButtonGroupNavigation");var n=elBySel(".buttonList",i);if(0!==n.childElementCount){i.parentNode.classList.add("hasMobileNavigation");var o=elCreate("a");o.className="dropdownLabel";var r=elCreate("span");r.className="icon icon24 fa-ellipsis-v",o.appendChild(r),function(e,t,i){t.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),e.classList.toggle("open")}),i.addEventListener(WCF_CLICK_EVENT,function(t){t.stopPropagation(),e.classList.remove("open")})}(i,o,n),i.insertBefore(o,i.firstChild)}}}},_initMessages:function(){Array.prototype.forEach.call(C,function(e){if(!y.has(e)){var t=elBySel(".jsMobileNavigation",e);if(t){t.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation(),window.setTimeout(function(){t.classList.remove("open")},10)});var i=elBySel(".messageQuickOptions",e);i&&t.childElementCount&&(i.classList.add("active"),i.addEventListener(WCF_CLICK_EVENT,function(n){b&&u.is("screen-sm-down")&&"LABEL"!==n.target.nodeName&&"INPUT"!==n.target.nodeName&&(n.preventDefault(),n.stopPropagation(),this._toggleMobileNavigation(e,i,t))}.bind(this)))}y.add(e)}}.bind(this))},_initMobileMenu:function(){E.enableMobileMenu&&(L=new d,A=new h)},_closeAllMenus:function(){elBySelAll(".jsMobileButtonGroupNavigation.open, .jsMobileNavigation.open",null,function(e){e.classList.remove("open")}),b&&m&&g()},rebuildShadow:function(e,t){for(var i,n,o,r=0,l=e.length;r<l;r++)i=e[r],n=i.parentNode,null===(o=a.childByClass(n,"mobileLinkShadow"))&&elBySel(t,i).href&&(o=elCreate("a"),o.className="mobileLinkShadow",o.href=elBySel(t,i).href,n.appendChild(o),n.classList.add("mobileLinkShadowContainer"))},removeShadow:function(e){for(var t,i,n,o=0,r=e.length;o<r;o++)t=e[o],i=t.parentNode,i.classList.contains("mobileLinkShadowContainer")&&(n=a.childByClass(i,"mobileLinkShadow"),null!==n&&elRemove(n),i.classList.remove("mobileLinkShadowContainer"))},_enableSidebarXS:function(){I=!0},_disableSidebarXS:function(){I=!1,x.forEach(function(e){e.classList.remove("open")})},_setupSidebarXS:function(){x.forEach(function(e){e.addEventListener("mousedown",function(t){I&&t.target===e&&(t.preventDefault(),e.classList.toggle("open"))})}),I=!0},_toggleMobileNavigation:function(e,t,i){if(null===m)m=elCreate("ul"),m.className="dropdownMenu",f.init("com.woltlab.wcf.jsMobileNavigation",m),g=function(){m.classList.remove("dropdownOpen")};else if(m.classList.contains("dropdownOpen")&&(g(),v===e))return;m.innerHTML="",c.execute(),this._rebuildMobileNavigation(i);var n=i.previousElementSibling;if(n&&n.classList.contains("messageFooterButtonsExtra")){var o=elCreate("li");o.className="dropdownDivider",m.appendChild(o),this._rebuildMobileNavigation(n)}s.set(m,t,{horizontal:"right",allowFlip:"vertical"}),m.classList.add("dropdownOpen"),v=e},_setupLGTouchNavigation:function(){_=!0,elBySelAll(".boxMenuHasChildren > a",null,function(e){e.addEventListener("touchstart",function(t){_&&"false"===elAttr(e,"aria-expanded")&&(t.preventDefault(),elAttr(e,"aria-expanded","true"),e.addEventListener("touchend",function(){document.body.addEventListener("touchstart",function(){document.body.addEventListener("touchend",function(t){l.contains(e.parentNode,t.target)||t.target===e.parentNode||elAttr(e,"aria-expanded","false")},{once:!0})},{once:!0})},{once:!0}))})})},_enableLGTouchNavigation:function(){_=!0},_disableLGTouchNavigation:function(){_=!1},_rebuildMobileNavigation:function(t){elBySelAll(".button",t,function(t){if(!t.classList.contains("ignoreMobileNavigation")||t.classList.contains("reactButton")){var i=elCreate("li");t.classList.contains("active")&&(i.className="active"),i.innerHTML='<a href="#">'+elBySel("span:not(.icon)",t).textContent+"</a>",i.children[0].addEventListener(WCF_CLICK_EVENT,function(i){i.preventDefault(),i.stopPropagation(),"A"===t.nodeName?t.click():e.triggerEvent(t,WCF_CLICK_EVENT),g()}),m.appendChild(i)}})}}}),define("WoltLabSuite/Core/Ui/Scroll",["Dom/Util"],function(e){"use strict";var t=null,i=null,n=null,o=null;return{element:function(o,r){if(!(o instanceof Element))throw new TypeError("Expected a valid DOM element.");if(void 0!==r&&"function"!=typeof r)throw new TypeError("Expected a valid callback function.");if(!document.body.contains(o))throw new Error("Element must be part of the visible DOM.");if(null!==t)throw new Error("Cannot scroll to element, a concurrent request is running.");r&&(t=r,null===i&&(i=this._onScroll.bind(this)),window.addEventListener("scroll",i));var a=e.offset(o).top;if(null===n){n=50;var l=elById("pageHeaderPanel");if(null!==l){var s=window.getComputedStyle(l).position;n="fixed"===s||"static"===s?l.offsetHeight:0}}n>0&&(a<=n?a=0:a-=n);var c=window.pageYOffset;window.scrollTo({left:0,top:a,behavior:"smooth"}),window.setTimeout(function(){c===window.pageYOffset&&this._onScroll()}.bind(this),100)},_onScroll:function(){null!==o&&window.clearTimeout(o),o=window.setTimeout(function(){null!==t&&t(),window.removeEventListener("scroll",i),t=null,o=null},100)}}}),define("WoltLabSuite/Core/Ui/TabMenu/Simple",["Dictionary","Environment","EventHandler","Dom/Traverse","Dom/Util"],function(e,t,i,n,o){"use strict";function r(t){this._container=t,this._containers=new e,this._isLegacy=null,this._store=null,this._tabs=new e}return r.prototype={validate:function(){if(!this._container.classList.contains("tabMenuContainer"))return!1;var e=n.childByTag(this._container,"NAV");if(null===e)return!1;var t=elByTag("li",e);if(0===t.length)return!1;var i,r,a,l,s=n.childrenByTag(this._container,"DIV");for(a=0,l=s.length;a<l;a++)i=s[a],r=elData(i,"name"),r||(r=o.identify(i)),elData(i,"name",r),this._containers.set(r,i);var c,u=this._container.id;for(a=0,l=t.length;a<l;a++)if(c=t[a],r=this._getTabName(c)){if(this._tabs.has(r))throw new Error("Tab names must be unique, li[data-name='"+r+"'] (tab menu id: '"+u+"') exists more than once.");if(void 0===(i=this._containers.get(r)))throw new Error("Expected content element for li[data-name='"+r+"'] (tab menu id: '"+u+"').");if(i.parentNode!==this._container)throw new Error("Expected content element '"+r+"' (tab menu id: '"+u+"') to be a direct children.");if(1!==c.childElementCount||"A"!==c.children[0].nodeName)throw new Error("Expected exactly one <a> as children for li[data-name='"+r+"'] (tab menu id: '"+u+"').");this._tabs.set(r,c)}if(!this._tabs.size)throw new Error("Expected at least one tab (tab menu id: '"+u+"').");return this._isLegacy&&(elData(this._container,"is-legacy",!0),this._tabs.forEach(function(e,t){elAttr(e,"aria-controls",t)})),!0},init:function(e){e=e||null,this._tabs.forEach(function(i){if((!e||e.get(elData(i,"name"))!==i)&&(i.children[0].addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this)),"ios"===t.platform())){var n=!1;i.children[0].addEventListener("touchstart",function(){n=!0}),i.children[0].addEventListener("touchmove",function(){n=!1}),i.children[0].addEventListener("touchend",function(e){n&&(n=!1,e.preventDefault(),this._onClick(e))}.bind(this))}}.bind(this));var i=null;if(!e){var n=r.getIdentifierFromHash(),o=null;if(""!==n&&(o=this._tabs.get(n))&&this._container.parentNode.classList.contains("tabMenuContainer")&&(i=this._container),!o){var a=elData(this._container,"preselect")||elData(this._container,"active");"true"!==a&&a||(a=!0),!0===a?this._tabs.forEach(function(e){o||elIsHidden(e)||e.previousElementSibling&&!elIsHidden(e.previousElementSibling)||(o=e)}):"false"!==a&&(o=this._tabs.get(a))}o&&(this._containers.forEach(function(e){e.classList.add("hidden")}),this.select(null,o,!0));var l=elData(this._container,"store");if(l){var s=elCreate("input");s.type="hidden",s.name=l,s.value=elData(this.getActiveTab(),"name"),this._container.appendChild(s),this._store=s}}return i},select:function(e,t,n){if(!(t=t||this._tabs.get(e))){if(~~e==e){e=~~e;var o=0;this._tabs.forEach(function(i){o===e&&(t=i),o++})}if(!t)throw new Error("Expected a valid tab name, '"+e+"' given (tab menu id: '"+this._container.id+"').")}e=e||elData(t,"name");var a=this.getActiveTab(),l=null;if(a){var s=elData(a,"name");if(s===e)return;n||i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"beforeSelect",{tab:a,tabName:s}),a.classList.remove("active"),l=this._containers.get(elData(a,"name")),l.classList.remove("active"),l.classList.add("hidden"),this._isLegacy&&(a.classList.remove("ui-state-active"),l.classList.remove("ui-state-active"))}t.classList.add("active");var c=this._containers.get(e);if(c.classList.add("active"),c.classList.remove("hidden"),this._isLegacy&&(t.classList.add("ui-state-active"),c.classList.add("ui-state-active")),this._store&&(this._store.value=e),!n){i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"select",{active:t,activeName:e,previous:a,previousName:a?elData(a,"name"):null});var u=this._isLegacy&&"function"==typeof window.jQuery?window.jQuery:null;u&&u(this._container).trigger("wcftabsbeforeactivate",{newTab:u(t),oldTab:u(a),newPanel:u(c),oldPanel:u(l)});var d=window.location.href.replace(/#+[^#]*$/,"");r.getIdentifierFromHash()===e?d+=window.location.hash:d+="#"+e,window.history.replaceState(void 0,void 0,d)}require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.scrollToTab(t)})},selectFirstVisible:function(){var e;return this._tabs.forEach(function(t){e||elIsHidden(t)||(e=t)}.bind(this)),e&&this.select(void 0,e,!1),!!e},rebuild:function(){var t=new e;t.merge(this._tabs),this.validate(),this.init(t)},hasTab:function(e){return this._tabs.has(e)},_onClick:function(e){e.preventDefault(),this.select(null,e.currentTarget.parentNode)},_getTabName:function(e){var t=elData(e,"name");return t||1===e.childElementCount&&"A"===e.children[0].nodeName&&e.children[0].href.match(/#([^#]+)$/)&&(t=RegExp.$1,null===elById(t)?t=null:(this._isLegacy=!0,elData(e,"name",t))),t},getActiveTab:function(){return elBySel("#"+this._container.id+" > nav > ul > li.active")},getContainers:function(){return this._containers},getTabs:function(){return this._tabs}},r.getIdentifierFromHash=function(){return window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)?RegExp.$1:""},r}),define("WoltLabSuite/Core/Ui/TabMenu",["Dictionary","EventHandler","Dom/ChangeListener","Dom/Util","Ui/CloseOverlay","Ui/Screen","Ui/Scroll","./TabMenu/Simple"],function(e,t,i,n,o,r,a,l){"use strict";var s=null,c=!1,u=new e;return{setup:function(){this._init(),this._selectErroneousTabs(),i.add("WoltLabSuite/Core/Ui/TabMenu",this._init.bind(this)),o.add("WoltLabSuite/Core/Ui/TabMenu",function(){s&&(s.classList.remove("active"),s=null)}),r.on("screen-sm-down",{enable:this._scrollEnable.bind(this,!1),disable:this._scrollDisable.bind(this),setup:this._scrollEnable.bind(this,!0)}),window.addEventListener("hashchange",function(){var e=l.getIdentifierFromHash(),t=e?elById(e):null;null!==t&&t.classList.contains("tabMenuContent")&&u.forEach(function(t){t.hasTab(e)&&t.select(e)})});var e=l.getIdentifierFromHash();e&&window.setTimeout(function(){var t=elById(e);if(t&&t.classList.contains("tabMenuContent")){var i=window.scrollY||window.pageYOffset;if(i>0){var o=t.parentNode,r=o.offsetTop-50;if(r<0&&(r=0),i>r){var a=n.offset(o).top;a<=50?a=0:a-=50,window.scrollTo(0,a)}}}},100)},_init:function(){for(var e,t,i,o,r,c=elBySelAll(".tabMenuContainer:not(.staticTabMenuContainer)"),d=0,h=c.length;d<h;d++)if(e=c[d],t=n.identify(e),!u.has(t)&&(r=new l(e),r.validate())){o=r.init(),u.set(t,r),o instanceof Element&&(r=this.getTabMenu(o.parentNode.id),r.select(o.id,null,!0)),i=elBySel("#"+t+" > nav > ul"),function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),t.target===e?(e.classList.add("active"),s=e):(e.classList.remove("active"),s=null)})}(i),elBySelAll(".tabMenu, .menu",e,function(e){var t=this._rebuildMenuOverflow.bind(this,e),i=null;elBySel("ul",e).addEventListener("scroll",function(){null!==i&&window.clearTimeout(i),i=window.setTimeout(t,10)})}.bind(this));var f=e.closest("form");if(null!==f){var p=elBySel('input[type="submit"]',f);null!==p&&function(e,t){t.addEventListener(WCF_CLICK_EVENT,function(t){if(!t.defaultPrevented)for(var i,n=elBySelAll("input, select",e),o=0,r=n.length;o<r;o++)if(i=n[o],!i.checkValidity()){t.preventDefault();var l=this.getTabMenu(i.closest(".tabMenuContainer").id);return l.select(elData(i.closest(".tabMenuContent"),"name")),void a.element(i,function(){this.reportValidity()}.bind(i))}}.bind(this))}.bind(this)(e,p)}}},_selectErroneousTabs:function(){u.forEach(function(e){var t=!1;e.getContainers().forEach(function(i){!t&&elByClass("formError",i).length&&(t=!0,e.select(i.id))})})},getTabMenu:function(e){return u.get(e)},_scrollEnable:function(e){c=!0,u.forEach(function(t){var i=t.getActiveTab();e?this._rebuildMenuOverflow(i.closest(".menu, .tabMenu")):this.scrollToTab(i)}.bind(this))},_scrollDisable:function(){c=!1},scrollToTab:function(e){if(c){var t=e.closest("ul"),i=t.clientWidth,n=t.scrollLeft,o=t.scrollWidth;if(i!==o){var r=e.offsetLeft,a=!1;r<n&&(a=!0);var l=!1;if(!a){var s=i-(r-n),u=e.clientWidth;null!==e.nextElementSibling&&(l=!0,u+=20),s<u&&(a=!0)}a&&this._scrollMenu(t,r,n,o,i,l)}}},_scrollMenu:function(e,t,i,n,o,r){r?t-=15:t>0&&(t-=15),t=t<0?0:Math.min(t,n-o),i!==t&&(e.classList.add("enableAnimation"),i<t?e.firstElementChild.style.setProperty("margin-left",i-t+"px",""):e.style.setProperty("padding-left",i-t+"px",""),setTimeout(function(){e.classList.remove("enableAnimation"),e.firstElementChild.style.removeProperty("margin-left"),e.style.removeProperty("padding-left"),e.scrollLeft=t},300))},_rebuildMenuOverflow:function(e){if(c){var t=e.clientWidth,i=elBySel("ul",e),n=i.scrollLeft,o=i.scrollWidth,r=n>0,a=elBySel(".tabMenuOverlayLeft",e);r?(null===a&&(a=elCreate("span"),a.className="tabMenuOverlayLeft icon icon24 fa-angle-left",a.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft-~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.insertBefore(a,e.firstChild)),a.classList.add("active")):null!==a&&a.classList.remove("active");var l=t+n<o,s=elBySel(".tabMenuOverlayRight",e);l?(null===s&&(s=elCreate("span"),s.className="tabMenuOverlayRight icon icon24 fa-angle-right",s.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft+~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.appendChild(s)),s.classList.add("active")):null!==s&&s.classList.remove("active")}}}}),define("WoltLabSuite/Core/Ui/FlexibleMenu",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o,r){"use strict";var a=new t,l=new t,s=new t,c=new t;return{setup:function(){null!==elById("mainMenu")&&this.register("mainMenu");var e=elBySel(".navigationHeader");null!==e&&this.register(o.identify(e)),window.addEventListener("resize",this.rebuildAll.bind(this)),i.add("WoltLabSuite/Core/Ui/FlexibleMenu",this.registerTabMenus.bind(this))},register:function(e){var t=elById(e);if(null===t)throw"Expected a valid element id, '"+e+"' does not exist.";if(!a.has(e)){var i=n.childByTag(t,"UL");if(null===i)throw"Expected an <ul> element as child of container '"+e+"'.";a.set(e,t),c.set(e,i),this.rebuild(e)}},registerTabMenus:function(){for(var e=elBySelAll(".tabMenuContainer:not(.jsFlexibleMenuEnabled), .messageTabMenu:not(.jsFlexibleMenuEnabled)"),t=0,i=e.length;t<i;t++){var r=e[t],a=n.childByTag(r,"NAV");null!==a&&(r.classList.add("jsFlexibleMenuEnabled"),this.register(o.identify(a)))}},rebuildAll:function(){a.forEach(function(e,t){this.rebuild(t)}.bind(this))},rebuild:function(t){var i=a.get(t);if(void 0===i)throw"Expected a valid element id, '"+t+"' is unknown.";var u=window.getComputedStyle(i),d=i.parentNode.clientWidth;d-=o.styleAsInt(u,"margin-left"),d-=o.styleAsInt(u,"margin-right");var h=c.get(t),f=n.childrenByTag(h,"LI"),p=l.get(t),g=0;if(void 0!==p){for(var m=0,v=f.length;m<v;m++){var b=f[m];b.classList.contains("dropdown")||elShow(b)}null!==p.parentNode&&(g=o.outerWidth(p))}var _=h.scrollWidth-g,y=[];if(_>d)for(var m=f.length-1;m>=0;m--){var b=f[m];if(!(b.classList.contains("dropdown")||b.classList.contains("active")||b.classList.contains("ui-state-active"))&&(y.push(b),elHide(b),h.scrollWidth<d))break}if(y.length){var w;if(void 0===p){p=elCreate("li"),p.className="dropdown jsFlexibleMenuDropdown";var C=elCreate("a");C.className="icon icon16 fa-list",p.appendChild(C),w=elCreate("ul"),w.classList.add("dropdownMenu"),p.appendChild(w),l.set(t,p),s.set(t,w),r.init(C)}else w=s.get(t);null===p.parentNode&&h.appendChild(p);var E=document.createDocumentFragment(),L=this;y.forEach(function(i){var n=elCreate("li");n.innerHTML=i.innerHTML,n.addEventListener(WCF_CLICK_EVENT,function(n){n.preventDefault(),e.triggerEvent(elBySel("a",i),WCF_CLICK_EVENT),setTimeout(function(){L.rebuild(t)},59)}.bind(this)),E.appendChild(n)}),w.innerHTML="",w.appendChild(E)}else void 0!==p&&null!==p.parentNode&&elRemove(p)}}}),define("WoltLabSuite/Core/Ui/Tooltip",["Environment","Dom/ChangeListener","Ui/Alignment"],function(e,t,i){"use strict";var n=null,o=null,r=null,a=null,l=null,s=null;return{setup:function(){"desktop"===e.platform()&&(s=elCreate("div"),elAttr(s,"id","balloonTooltip"),s.classList.add("balloonTooltip"),s.addEventListener("transitionend",function(){s.classList.contains("active")||["bottom","left","right","top"].forEach(function(e){s.style.removeProperty(e)})}),l=elCreate("span"),elAttr(l,"id","balloonTooltipText"),s.appendChild(l),a=elCreate("span"),a.classList.add("elementPointer"),a.appendChild(elCreate("span")),s.appendChild(a),document.body.appendChild(s),r=elByClass("jsTooltip"),n=this._mouseEnter.bind(this),o=this._mouseLeave.bind(this),this.init(),t.add("WoltLabSuite/Core/Ui/Tooltip",this.init.bind(this)),window.addEventListener("scroll",this._mouseLeave.bind(this)))},init:function(){0!==r.length&&elBySelAll(".jsTooltip",void 0,function(e){e.classList.remove("jsTooltip");var t=elAttr(e,"title").trim();t.length&&(elData(e,"tooltip",t),e.removeAttribute("title"),elAttr(e,"aria-label",t),e.addEventListener("mouseenter",n),e.addEventListener("mouseleave",o),e.addEventListener(WCF_CLICK_EVENT,o))})},_mouseEnter:function(e){var t=e.currentTarget,n=elAttr(t,"title");if(n="string"==typeof n?n.trim():"",""!==n&&(elData(t,"tooltip",n),t.removeAttribute("title")),n=elData(t,"tooltip"),s.style.removeProperty("top"),s.style.removeProperty("left"),!n.length)return void s.classList.remove("active");s.classList.add("active"),l.textContent=n,i.set(s,t,{horizontal:"center",verticalOffset:4,pointer:!0,pointerClassNames:["inverse"],vertical:"top"})},_mouseLeave:function(){s.classList.remove("active")}}}),define("WoltLabSuite/Core/Date/Picker",["DateUtil","Dom/Traverse","Dom/Util","EventHandler","Language","ObjectMap","Dom/ChangeListener","Ui/Alignment","WoltLabSuite/Core/Ui/CloseOverlay"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=!1,u=0,d=!1,h=new r,f=null,p=0,g=0,m=[],v=null,b=null,_=null,y=null,w=null,C=null,E=null,L=null,A=null,S=null,x=null,I={init:function(){this._setup();for(var t=elBySelAll('input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)'),i=new Date,n=0,r=t.length;n<r;n++){var a=t[n];a.classList.add("inputDatePicker"),a.readOnly=!0;var l="datetime"===elAttr(a,"type"),s=l&&elDataBool(a,"time-only"),c=elDataBool(a,"disable-clear"),u=l&&elDataBool(a,"ignore-timezone"),d=a.classList.contains("birthday");elData(a,"is-date-time",l),elData(a,"is-time-only",s);var f=null,p=elAttr(a,"value"),g=/^\d+-\d+-\d+$/.test(p);if(elAttr(a,"value")){if(s){f=new Date;var m=p.split(":");f.setHours(m[0],m[1])}else{if(u||d||g){var v=new Date(p).getTimezoneOffset(),b=v>0?"-":"+";v=Math.abs(v);var _=Math.floor(v/60).toString(),y=(v%60).toString();b+=2===_.length?_:"0"+_,b+=":",b+=2===y.length?y:"0"+y,d||g?p+="T00:00:00"+b:p=p.replace(/[+-][0-9]{2}:[0-9]{2}$/,b)}f=new Date(p)}var w=f.getTime();if(isNaN(w))p="";else{elData(a,"value",w);p=e[s?"formatTime":"formatDate"+(l?"Time":"")](f)}}var C=0===p.length;if(d?(elData(a,"min-date","120"),elData(a,"max-date",(new Date).getFullYear()+"-12-31")):(a.min&&elData(a,"min-date",a.min),a.max&&elData(a,"max-date",a.max)),this._initDateRange(a,i,!0),this._initDateRange(a,i,!1),elData(a,"min-date")===elData(a,"max-date"))throw new Error("Minimum and maximum date cannot be the same (element id '"+a.id+"').");a.type="text",a.value=p,elData(a,"empty",C),elData(a,"placeholder")&&elAttr(a,"placeholder",elData(a,"placeholder"));var E=elCreate("input");if(E.id=a.id+"DatePicker",E.name=a.name,E.type="hidden",null!==f&&(E.value=s?e.format(f,"H:i"):u?e.format(f,"Y-m-dTH:i:s"):e.format(f,l?"c":"Y-m-d")),a.parentNode.insertBefore(E,a),a.removeAttribute("name"),a.addEventListener(WCF_CLICK_EVENT,S),!a.disabled){var L=elCreate("div");L.className="inputAddon";var A=elCreate("a");A.className="inputSuffix button jsTooltip",A.href="#",elAttr(A,"role","button"),elAttr(A,"tabindex","0"),elAttr(A,"title",o.get("wcf.date.datePicker")),elAttr(A,"aria-label",o.get("wcf.date.datePicker")),
-elAttr(A,"aria-haspopup",!0),elAttr(A,"aria-expanded",!1),A.addEventListener(WCF_CLICK_EVENT,S),L.appendChild(A);var x=elCreate("span");x.className="icon icon16 fa-calendar",A.appendChild(x),a.parentNode.insertBefore(L,a),L.insertBefore(a,A),c||(A=elCreate("a"),A.className="inputSuffix button",A.addEventListener(WCF_CLICK_EVENT,this.clear.bind(this,a)),C&&A.style.setProperty("visibility","hidden",""),L.appendChild(A),x=elCreate("span"),x.className="icon icon16 fa-times",A.appendChild(x))}for(var I=!1,D=["tiny","short","medium","long"],T=0;T<4;T++)a.classList.contains(D[T])&&(I=!0);I||a.classList.add("short"),h.set(a,{clearButton:A,shadow:E,disableClear:c,isDateTime:l,isEmpty:C,isTimeOnly:s,ignoreTimezone:u,onClose:null})}},_initDateRange:function(e,t,i){var n="data-"+(i?"min":"max")+"-date",o=e.hasAttribute(n)?elAttr(e,n).trim():"";if(o.match(/^(\d{4})-(\d{2})-(\d{2})$/))o=new Date(o).getTime();else if("now"===o)o=t.getTime();else if(o.match(/^\d{1,3}$/)){var r=new Date(t.getTime());r.setFullYear(r.getFullYear()+~~o*(i?-1:1)),o=r.getTime()}else if(o.match(/^datePicker-(.+)$/)){if(o=RegExp.$1,null===elById(o))throw new Error("Reference date picker identified by '"+o+"' does not exists (element id: '"+e.id+"').")}else o=/^\d{4}\-\d{2}\-\d{2}T/.test(o)?new Date(o).getTime():new Date(i?1902:2038,0,1).getTime();elAttr(e,n,o)},_setup:function(){c||(c=!0,u=~~o.get("wcf.date.firstDayOfTheWeek"),S=this._open.bind(this),a.add("WoltLabSuite/Core/Date/Picker",this.init.bind(this)),s.add("WoltLabSuite/Core/Date/Picker",this._close.bind(this)))},_open:function(e){e.preventDefault(),e.stopPropagation(),this._createPicker(),null===x&&(x=this._maintainFocus.bind(this),document.body.addEventListener("focus",x,{capture:!0}));var i="INPUT"===e.currentTarget.nodeName?e.currentTarget:e.currentTarget.previousElementSibling;if(i===f)return void this._close();var n=t.parentByClass(i,"dialogContent");null!==n&&(elDataBool(n,"has-datepicker-scroll-listener")||(n.addEventListener("scroll",this._onDialogScroll.bind(this)),elData(n,"has-datepicker-scroll-listener",1))),f=i;var o,r=h.get(f),a=elData(f,"value");a?(o=new Date(+a),"Invalid Date"===o.toString()&&(o=new Date)):o=new Date,g=elData(f,"min-date"),g.match(/^datePicker-(.+)$/)&&(g=elData(elById(RegExp.$1),"value")),g=new Date(+g),g.getTime()>o.getTime()&&(o=g),p=elData(f,"max-date"),p.match(/^datePicker-(.+)$/)&&(p=elData(elById(RegExp.$1),"value")),p=new Date(+p),r.isDateTime?(b.value=o.getHours(),_.value=o.getMinutes(),A.classList.add("datePickerTime")):A.classList.remove("datePickerTime"),A.classList[r.isTimeOnly?"add":"remove"]("datePickerTimeOnly"),this._renderPicker(o.getDate(),o.getMonth(),o.getFullYear()),l.set(A,f),elAttr(f.nextElementSibling,"aria-expanded",!0),d=!1},_close:function(){if(null!==A&&A.classList.contains("active")){A.classList.remove("active");var e=h.get(f);"function"==typeof e.onClose&&e.onClose(),n.fire("WoltLabSuite/Core/Date/Picker","close",{element:f}),elAttr(f.nextElementSibling,"aria-expanded",!1),f=null,g=0,p=0}},_onDialogScroll:function(e){if(null!==f){var t=e.currentTarget,n=i.offset(f),o=i.offset(t);n.top+f.clientHeight<=o.top?this._close():n.top>=o.top+t.offsetHeight?this._close():n.left<=o.left?this._close():n.left>=o.left+t.offsetWidth?this._close():l.set(A,f)}},_renderPicker:function(e,t,i){this._renderGrid(e,t,i);for(var n="",o=g.getFullYear(),r=p.getFullYear();o<=r;o++)n+='<option value="'+o+'">'+o+"</option>";L.innerHTML=n,L.value=i,y.value=t,A.classList.add("active")},_renderGrid:function(t,i,n){var o,r,a=void 0!==t,l=void 0!==i;if(t=~~t||~~elData(v,"day"),i=~~i,n=~~n,l||n){var s=0!==n,c=document.createDocumentFragment();c.appendChild(v),l||(i=~~elData(v,"month")),n=n||~~elData(v,"year");var d=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-"+("0"+t.toString()).slice(-2));for(d<g?(n=g.getFullYear(),i=g.getMonth(),t=g.getDate(),y.value=i,L.value=n,s=!0):d>p&&(n=p.getFullYear(),i=p.getMonth(),t=p.getDate(),y.value=i,L.value=n,s=!0),d=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");d.getDay()!==u;)d.setDate(d.getDate()-1);elShow(m[35].parentNode);var h,f=new Date(g.getFullYear(),g.getMonth(),g.getDate());for(r=0;r<42;r++){if(35===r&&d.getMonth()!==i){elHide(m[35].parentNode);break}o=m[r],o.textContent=d.getDate(),h=d.getMonth()===i,h&&(d<f?h=!1:d>p&&(h=!1)),o.classList[h?"remove":"add"]("otherMonth"),h&&(o.href="#",elAttr(o,"role","button"),elAttr(o,"tabindex","0"),elAttr(o,"title",e.formatDate(d)),elAttr(o,"aria-label",e.formatDate(d))),d.setDate(d.getDate()+1)}if(elData(v,"month",i),elData(v,"year",n),A.insertBefore(c,E),!a&&(d=new Date(n,i,t),d.getDate()!==t)){for(;d.getMonth()!==i;)d.setDate(d.getDate()-1);t=d.getDate()}if(s){for(r=0;r<12;r++){var b=y.children[r];b.disabled=n===g.getFullYear()&&b.value<g.getMonth()||n===p.getFullYear()&&b.value>p.getMonth()}var _=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");_.setMonth(_.getMonth()+1),w.classList[_<p?"add":"remove"]("active");var S=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");S.setDate(S.getDate()-1),C.classList[S>g?"add":"remove"]("active")}}if(t){for(r=0;r<35;r++)o=m[r],o.classList[o.classList.contains("otherMonth")||~~o.textContent!==t?"remove":"add"]("active");elData(v,"day",t)}this._formatValue()},_formatValue:function(){var e,t=h.get(f);"true"!==elData(f,"empty")&&(e=t.isDateTime?new Date(elData(v,"year"),elData(v,"month"),elData(v,"day"),b.value,_.value):new Date(elData(v,"year"),elData(v,"month"),elData(v,"day")),this.setDate(f,e))},_createPicker:function(){if(null===A){A=elCreate("div"),A.className="datePicker",A.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()});var t=elCreate("header");A.appendChild(t),C=elCreate("a"),C.className="previous jsTooltip",C.href="#",elAttr(C,"role","button"),elAttr(C,"tabindex","0"),elAttr(C,"title",o.get("wcf.date.datePicker.previousMonth")),elAttr(C,"aria-label",o.get("wcf.date.datePicker.previousMonth")),C.innerHTML='<span class="icon icon16 fa-arrow-left"></span>',C.addEventListener(WCF_CLICK_EVENT,this.previousMonth.bind(this)),t.appendChild(C);var i=elCreate("span");t.appendChild(i),y=elCreate("select"),y.className="month jsTooltip",elAttr(y,"title",o.get("wcf.date.datePicker.month")),elAttr(y,"aria-label",o.get("wcf.date.datePicker.month")),y.addEventListener("change",this._changeMonth.bind(this)),i.appendChild(y);var n,r="",a=o.get("__monthsShort");for(n=0;n<12;n++)r+='<option value="'+n+'">'+a[n]+"</option>";y.innerHTML=r,L=elCreate("select"),L.className="year jsTooltip",elAttr(L,"title",o.get("wcf.date.datePicker.year")),elAttr(L,"aria-label",o.get("wcf.date.datePicker.year")),L.addEventListener("change",this._changeYear.bind(this)),i.appendChild(L),w=elCreate("a"),w.className="next jsTooltip",w.href="#",elAttr(w,"role","button"),elAttr(w,"tabindex","0"),elAttr(w,"title",o.get("wcf.date.datePicker.nextMonth")),elAttr(w,"aria-label",o.get("wcf.date.datePicker.nextMonth")),w.innerHTML='<span class="icon icon16 fa-arrow-right"></span>',w.addEventListener(WCF_CLICK_EVENT,this.nextMonth.bind(this)),t.appendChild(w),v=elCreate("ul"),A.appendChild(v);var l=elCreate("li");l.className="weekdays",v.appendChild(l);var s,c=o.get("__daysShort");for(n=0;n<7;n++){var d=n+u;d>6&&(d-=7),s=elCreate("span"),s.textContent=c[d],l.appendChild(s)}var h,f,p=this._click.bind(this);for(n=0;n<6;n++){f=elCreate("li"),v.appendChild(f);for(var g=0;g<7;g++)h=elCreate("a"),h.addEventListener(WCF_CLICK_EVENT,p),m.push(h),f.appendChild(h)}E=elCreate("footer"),A.appendChild(E),b=elCreate("select"),b.className="hour",elAttr(b,"title",o.get("wcf.date.datePicker.hour")),elAttr(b,"aria-label",o.get("wcf.date.datePicker.hour")),b.addEventListener("change",this._formatValue.bind(this));var S="",x=new Date(2e3,0,1),I=o.get("wcf.date.timeFormat").replace(/:/,"").replace(/[isu]/g,"");for(n=0;n<24;n++)x.setHours(n),S+='<option value="'+n+'">'+e.format(x,I)+"</option>";for(b.innerHTML=S,E.appendChild(b),E.appendChild(document.createTextNode(" : ")),_=elCreate("select"),_.className="minute",elAttr(_,"title",o.get("wcf.date.datePicker.minute")),elAttr(_,"aria-label",o.get("wcf.date.datePicker.minute")),_.addEventListener("change",this._formatValue.bind(this)),S="",n=0;n<60;n++)S+='<option value="'+n+'">'+(n<10?"0"+n.toString():n)+"</option>";_.innerHTML=S,E.appendChild(_),document.body.appendChild(A)}},previousMonth:function(e){e.preventDefault(),"0"===y.value?(y.value=11,L.value=~~L.value-1):y.value=~~y.value-1,this._renderGrid(void 0,y.value,L.value)},nextMonth:function(e){e.preventDefault(),"11"===y.value?(y.value=0,L.value=1+~~L.value):y.value=1+~~y.value,this._renderGrid(void 0,y.value,L.value)},_changeMonth:function(e){this._renderGrid(void 0,e.currentTarget.value)},_changeYear:function(e){this._renderGrid(void 0,void 0,e.currentTarget.value)},_click:function(e){if(e.preventDefault(),!e.currentTarget.classList.contains("otherMonth")){elData(f,"empty",!1),this._renderGrid(e.currentTarget.textContent);h.get(f).isDateTime||this._close()}},getDate:function(e){return e=this._getElement(e),e.hasAttribute("data-value")?new Date(+elData(e,"value")):null},setDate:function(t,i){t=this._getElement(t);var n=h.get(t);elData(t,"value",i.getTime());var o,r="";n.isDateTime?n.isTimeOnly?(o=e.formatTime(i),r="H:i"):n.ignoreTimezone?(o=e.formatDateTime(i),r="Y-m-dTH:i:s"):(o=e.formatDateTime(i),r="c"):(o=e.formatDate(i),r="Y-m-d"),t.value=o,n.shadow.value=e.format(i,r),n.disableClear||n.clearButton.style.removeProperty("visibility")},getValue:function(e){e=this._getElement(e);var t=h.get(e);return t?t.shadow.value:""},clear:function(e){e=this._getElement(e);var t=h.get(e);e.removeAttribute("data-value"),e.value="",t.disableClear||t.clearButton.style.setProperty("visibility","hidden",""),t.isEmpty=!0,t.shadow.value=""},destroy:function(e){e=this._getElement(e);var t=h.get(e),i=e.parentNode;i.parentNode.insertBefore(e,i),elRemove(i),elAttr(e,"type","date"+(t.isDateTime?"time":"")),e.name=t.shadow.name,e.value=t.shadow.value,e.removeAttribute("data-value"),e.removeEventListener(WCF_CLICK_EVENT,S),elRemove(t.shadow),e.classList.remove("inputDatePicker"),e.readOnly=!1,h.delete(e)},setCloseCallback:function(e,t){e=this._getElement(e),h.get(e).onClose=t},_getElement:function(e){if("string"==typeof e&&(e=elById(e)),!(e instanceof Element&&e.classList.contains("inputDatePicker")&&h.has(e)))throw new Error("Expected a valid date picker input element or id.");return e},_maintainFocus:function(e){null!==A&&A.classList.contains("active")&&(A.contains(e.target)?d=!0:d?(f.nextElementSibling.focus(),d=!1):elBySel(".previous",A).focus())}};return window.__wcf_bc_datePicker=I,I}),define("WoltLabSuite/Core/Ui/Page/Action",["Dictionary","Dom/Util"],function(e,t){"use strict";var i=new e,n=null,o=!1;return{setup:function(){o=!0,n=elCreate("ul"),n.className="pageAction",document.body.appendChild(n)},add:function(e,r,a){!1===o&&this.setup();var l=elCreate("li");if(r.classList.add("button"),r.classList.add("buttonPrimary"),l.appendChild(r),elAttr(l,"aria-hidden","toTop"===e?"true":"false"),elData(l,"name",e),"toTop"===e)l.className="toTop initiallyHidden",n.appendChild(l);else{var s=null;a&&void 0!==(s=i.get(a))&&(s=s.parentNode),null===s&&n.childElementCount&&(s=n.children[0]),null===s?t.prepend(l,n):n.insertBefore(l,s)}i.set(e,r),this._renderContainer()},has:function(e){return i.has(e)},get:function(e){return i.get(e)},remove:function(e){var t=i.get(e);if(void 0!==t){var o=t.parentNode;o.addEventListener("animationend",function(){try{n.removeChild(o),i.delete(e)}catch(e){}}),this.hide(e)}},hide:function(e){var t=i.get(e);t&&(elAttr(t.parentNode,"aria-hidden","true"),this._renderContainer())},show:function(e){var t=i.get(e);t&&(t.parentNode.classList.contains("initiallyHidden")&&t.parentNode.classList.remove("initiallyHidden"),elAttr(t.parentNode,"aria-hidden","false"),this._renderContainer())},_renderContainer:function(){var e=!1;if(n.childElementCount)for(var t=0,i=n.childElementCount;t<i;t++)if("false"===elAttr(n.children[t],"aria-hidden")){e=!0;break}n.classList[e?"add":"remove"]("active")}}}),define("WoltLabSuite/Core/Ui/Page/JumpToTop",["Environment","Language","./Action"],function(e,t,i){"use strict";function n(){this.init()}return n.prototype={init:function(){if("desktop"===e.platform()){this._callbackScrollEnd=this._afterScroll.bind(this),this._timeoutScroll=null;var n=elCreate("a");n.className="jsTooltip",n.href="#",elAttr(n,"title",t.get("wcf.global.scrollUp")),elAttr(n,"aria-hidden","true"),n.innerHTML='<span class="icon icon32 fa-angle-up"></span>',n.addEventListener(WCF_CLICK_EVENT,this._jump.bind(this)),i.add("toTop",n),window.addEventListener("scroll",this._scroll.bind(this)),this._afterScroll()}},_jump:function(e){e.preventDefault(),elById("top").scrollIntoView({behavior:"smooth"})},_scroll:function(){null!==this._timeoutScroll&&window.clearTimeout(this._timeoutScroll),this._timeoutScroll=window.setTimeout(this._callbackScrollEnd,100)},_afterScroll:function(){this._timeoutScroll=null,i[window.pageYOffset>=300?"show":"hide"]("toTop")}},n}),define("WoltLabSuite/Core/Bootstrap",["favico","enquire","perfect-scrollbar","WoltLabSuite/Core/Date/Time/Relative","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Mobile","WoltLabSuite/Core/Ui/TabMenu","WoltLabSuite/Core/Ui/FlexibleMenu","Ui/Dialog","WoltLabSuite/Core/Ui/Tooltip","WoltLabSuite/Core/Language","WoltLabSuite/Core/Environment","WoltLabSuite/Core/Date/Picker","EventHandler","Core","WoltLabSuite/Core/Ui/Page/JumpToTop","Devtools","Dom/ChangeListener"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f,p,g,m,v){"use strict";return window.Favico=e,window.enquire=t,null==window.WCF&&(window.WCF={}),null==window.WCF.Language&&(window.WCF.Language={}),window.WCF.Language.get=u.get,window.WCF.Language.add=u.add,window.WCF.Language.addObject=u.addObject,window.__wcf_bc_eventHandler=f,{setup:function(e){e=p.extend({enableMobileMenu:!0},e),window.ENABLE_DEVELOPER_TOOLS&&m._internal_.enable(),d.setup(),n.setup(),h.init(),o.setup(),r.setup({enableMobileMenu:e.enableMobileMenu}),a.setup(),s.setup(),c.setup();for(var t=elBySelAll("form[method=get]"),i=0,l=t.length;i<l;i++)t[i].setAttribute("method","post");"microsoft"===d.browser()&&(window.onbeforeunload=function(){});var u=0;u=window.setInterval(function(){"function"==typeof window.jQuery&&(window.clearInterval(u),window.jQuery(function(){new g}),window.jQuery.holdReady(!1))},20),this._initA11y(),v.add("WoltLabSuite/Core/Bootstrap",this._initA11y.bind(this))},_initA11y:function(){elBySelAll("nav:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")}),elBySelAll("article:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")})}}}),define("WoltLabSuite/Core/Controller/Style/Changer",["Ajax","Language","Ui/Dialog"],function(e,t,i){"use strict";return{setup:function(){elBySelAll(".jsButtonStyleChanger",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this.showDialog.bind(this))}.bind(this))},showDialog:function(e){e.preventDefault(),i.open(this)},_dialogSetup:function(){return{id:"styleChanger",options:{disableContentPadding:!0,title:t.get("wcf.style.changeStyle")},source:{data:{actionName:"getStyleChooser",className:"wcf\\data\\style\\StyleAction"},after:function(e){for(var t=elBySelAll(".styleList > li",e),i=0,n=t.length;i<n;i++){var o=t[i];o.classList.add("pointer"),o.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}}.bind(this)}}},_click:function(t){t.preventDefault(),e.apiOnce({data:{actionName:"changeStyle",className:"wcf\\data\\style\\StyleAction",objectIDs:[elData(t.currentTarget,"style-id")]},success:function(){window.location.reload()}})}}}),define("WoltLabSuite/Core/Controller/Popover",["Ajax","Dictionary","Environment","Dom/ChangeListener","Dom/Util","Ui/Alignment"],function(e,t,i,n,o,r){"use strict";var a=null,l=new t,s=new t,c=new t,u=null,d=!1,h=null,f=null,p=null,g=null,m=null,v=null,b=null,_=null;return{_setup:function(){if(null===p){p=elCreate("div"),p.className="popover forceHide",g=elCreate("div"),g.className="popoverContent",p.appendChild(g);var e=elCreate("span");e.className="elementPointer",e.appendChild(elCreate("span")),p.appendChild(e),document.body.appendChild(p),m=this._hide.bind(this),b=this._mouseEnter.bind(this),_=this._mouseLeave.bind(this),p.addEventListener("mouseenter",this._popoverMouseEnter.bind(this)),p.addEventListener("mouseleave",_),p.addEventListener("animationend",this._clearContent.bind(this)),window.addEventListener("beforeunload",function(){d=!0,null!==h&&window.clearTimeout(h),this._hide(!0)}.bind(this)),n.add("WoltLabSuite/Core/Controller/Popover",this._init.bind(this))}},init:function(e){"desktop"===i.platform()&&(e.attributeName=e.attributeName||"data-object-id",e.legacy=!0===e.legacy,this._setup(),c.has(e.identifier)||(c.set(e.identifier,{attributeName:e.attributeName,elements:e.legacy?e.className:elByClass(e.className),legacy:e.legacy,loadCallback:e.loadCallback}),this._init(e.identifier)))},_init:function(e){"string"==typeof e&&e.length?this._initElements(c.get(e),e):c.forEach(this._initElements.bind(this))},_initElements:function(e,t){for(var i=e.legacy?elBySelAll(e.elements):e.elements,n=0,r=i.length;n<r;n++){var a=i[n],c=o.identify(a);if(l.has(c))return;if(null!==a.closest(".popover"))return void l.set(c,{content:null,state:0});var u=e.legacy?c:~~a.getAttribute(e.attributeName);if(0!==u){a.addEventListener("mouseenter",b),a.addEventListener("mouseleave",_),"A"===a.nodeName&&elAttr(a,"href")&&a.addEventListener(WCF_CLICK_EVENT,m);var d=t+"-"+u;elData(a,"cache-id",d),s.set(c,{element:a,identifier:t,objectId:u}),l.has(d)||l.set(t+"-"+u,{content:null,state:0})}}},setContent:function(e,t,i){var n=e+"-"+t,r=l.get(n);if(void 0===r)throw new Error("Unable to find element for object id '"+t+"' (identifier: '"+e+"').");var c=o.createFragmentFromHtml(i);if(c.childElementCount||(c=o.createFragmentFromHtml("<p>"+i+"</p>")),r.content=c,r.state=2,a){var u=s.get(a).element;elData(u,"cache-id")===n&&this._show()}},_mouseEnter:function(e){if(!d){null!==h&&(window.clearTimeout(h),h=null);var t=o.identify(e.currentTarget);a===t&&null!==f&&(window.clearTimeout(f),f=null),u=t,h=window.setTimeout(function(){h=null,u===t&&this._show()}.bind(this),800)}},_mouseLeave:function(){u=null,null===f&&(null===v&&(v=this._hide.bind(this)),null!==f&&window.clearTimeout(f),f=window.setTimeout(v,500))},_popoverMouseEnter:function(){null!==f&&(window.clearTimeout(f),f=null)},_show:function(){null!==f&&(window.clearTimeout(f),f=null);var e=!1;p.classList.contains("active")?a!==u&&(this._hide(),e=!0):g.childElementCount&&(e=!0),e&&(p.classList.add("forceHide"),p.offsetTop,this._clearContent(),p.classList.remove("forceHide")),a=u;var t=s.get(a);if(void 0!==t){var i=l.get(elData(t.element,"cache-id"));2===i.state?(g.appendChild(i.content),this._rebuild(a)):0===i.state&&(i.state=1,c.get(t.identifier).loadCallback(t.objectId,this))}},_hide:function(){null!==f&&(window.clearTimeout(f),f=null),p.classList.remove("active")},_clearContent:function(){if(a&&g.childElementCount&&!p.classList.contains("active"))for(var e=l.get(elData(s.get(a).element,"cache-id"));g.childNodes.length;)e.content.appendChild(g.childNodes[0])},_rebuild:function(){p.classList.contains("active")||(p.classList.remove("forceHide"),p.classList.add("active"),r.set(p,s.get(a).element,{pointer:!0,vertical:"top"}))},_ajaxSetup:function(){return{silent:!0}},ajaxApi:function(t,i,n){if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'success'.");e.api(this,t,i,n)}}}),define("WoltLabSuite/Core/Ui/User/Ignore",["List","Dom/ChangeListener"],function(e,t){"use strict";var i=function(){};return i.prototype={init:function(){},_rebuild:function(){},_removeClass:function(){}},i}),define("WoltLabSuite/Core/Ui/Page/Header/Menu",["Environment","Language","Ui/Screen"],function(e,t,i){"use strict";var n,o,r,a,l=!1,s=0,c=[],u=[];return{init:function(){if(a=elBySel(".mainMenu .boxMenu"),null===(r=a&&a.childElementCount?a.children[0]:null))throw new Error("Unable to find the menu.");i.on("screen-lg",{enable:this._enable.bind(this),disable:this._disable.bind(this),setup:this._setup.bind(this)})},_enable:function(){l=!0,"safari"===e.browser()?window.setTimeout(this._rebuildVisibility.bind(this),1e3):(this._rebuildVisibility(),window.setTimeout(this._rebuildVisibility.bind(this),1e3))},_disable:function(){l=!1},_showNext:function(e){if(e.preventDefault(),u.length){var t=u.slice(0,3).pop();this._setMarginLeft(a.clientWidth-(t.offsetLeft+t.clientWidth)),a.lastElementChild===t&&n.classList.remove("active"),o.classList.add("active")}},_showPrevious:function(e){if(e.preventDefault(),c.length){var t=c.slice(-3)[0];this._setMarginLeft(-1*t.offsetLeft),a.firstElementChild===t&&o.classList.remove("active"),n.classList.add("active")}},_setMarginLeft:function(e){s=Math.min(s+e,0),r.style.setProperty("margin-left",s+"px","")},_rebuildVisibility:function(){if(l){c=[],u=[];var e=a.clientWidth;if(a.scrollWidth>e||s<0)for(var t,i=0,r=a.childElementCount;i<r;i++){t=a.children[i];var d=t.offsetLeft;d<0?c.push(t):d+t.clientWidth>e&&u.push(t)}o.classList[c.length?"add":"remove"]("active"),n.classList[u.length?"add":"remove"]("active")}},_setup:function(){this._setupOverflow(),this._setupA11y()},_setupOverflow:function(){n=elCreate("a"),n.className="mainMenuShowNext",n.href="#",n.innerHTML='<span class="icon icon32 fa-angle-right"></span>',elAttr(n,"aria-hidden","true"),n.addEventListener(WCF_CLICK_EVENT,this._showNext.bind(this)),a.parentNode.appendChild(n),o=elCreate("a"),o.className="mainMenuShowPrevious",o.href="#",o.innerHTML='<span class="icon icon32 fa-angle-left"></span>',elAttr(o,"aria-hidden","true"),o.addEventListener(WCF_CLICK_EVENT,this._showPrevious.bind(this)),a.parentNode.insertBefore(o,a.parentNode.firstChild);var e=this._rebuildVisibility.bind(this);r.addEventListener("transitionend",e),window.addEventListener("resize",function(){r.style.setProperty("margin-left","0px",""),s=0,e()}),this._enable()},_setupA11y:function(){elBySelAll(".boxMenuHasChildren",a,function(e){var i=!1,n=elBySel(".boxMenuLink",e);n&&(elAttr(n,"aria-haspopup",!0),elAttr(n,"aria-expanded",i));var o=elCreate("button");o.className="visuallyHidden",o.tabindex=0,elAttr(o,"role","button"),elAttr(o,"aria-label",t.get("wcf.global.button.showMenu")),e.insertBefore(o,n.nextSibling),o.addEventListener(WCF_CLICK_EVENT,function(){i=!i,elAttr(n,"aria-expanded",i),elAttr(o,"aria-label",i?t.get("wcf.global.button.hideMenu"):t.get("wcf.global.button.showMenu"))})}.bind(this))}}}),define("WoltLabSuite/Core/BootstrapFrontend",["WoltLabSuite/Core/BackgroundQueue","WoltLabSuite/Core/Bootstrap","WoltLabSuite/Core/Controller/Style/Changer","WoltLabSuite/Core/Controller/Popover","WoltLabSuite/Core/Ui/User/Ignore","WoltLabSuite/Core/Ui/Page/Header/Menu"],function(e,t,i,n,o,r){"use strict";return{setup:function(n){n.backgroundQueue.url=WSC_API_URL+n.backgroundQueue.url.substr(WCF_PATH.length),t.setup(),r.init(),n.styleChanger&&i.setup(),n.enableUserPopover&&this._initUserPopover(),e.setUrl(n.backgroundQueue.url),(Math.random()<.1||n.backgroundQueue.force)&&e.invoke()},_initUserPopover:function(){n.init({attributeName:"data-user-id",className:"userLink",identifier:"com.woltlab.wcf.user",loadCallback:function(e,t){var i=function(i){t.setContent("com.woltlab.wcf.user",e,i.returnValues.template)};t.ajaxApi({actionName:"getUserProfile",className:"wcf\\data\\user\\UserProfileAction",objectIDs:[e]},i,i)}})}}}),define("WoltLabSuite/Core/Clipboard",["Environment","Ui/Screen"],function(e,t){"use strict";return{copyTextToClipboard:function(i){if(navigator.clipboard)return navigator.clipboard.writeText(i);if(window.getSelection){var n=elCreate("textarea");n.contentEditable=!0,n.readOnly=!1;var o=!1;if("ios"===e.platform()){o=!0,t.scrollDisable();var r=~~(window.innerHeight/4)+window.pageYOffset;n.style.cssText="font-size: 16px; position: absolute; left: 1px; top: "+r+"px; width: 50px; height: 50px; overflow: hidden;border: 5px solid red;"}else n.style.cssText="position: absolute; left: -9999px; top: -9999px; width: 0; height: 0;";document.body.appendChild(n);try{n.value=i;var a=document.createRange();a.selectNodeContents(n);var l=window.getSelection();return l.removeAllRanges(),l.addRange(a),n.setSelectionRange(0,999999),document.execCommand("copy")?Promise.resolve():Promise.reject(new Error("execCommand('copy') failed"))}finally{elRemove(n),o&&t.scrollEnable()}}return Promise.reject(new Error("Neither navigator.clipboard, nor window.getSelection is supported."))},copyElementTextToClipboard:function(e){return this.copyTextToClipboard(e.textContent)}}}),define("WoltLabSuite/Core/ColorUtil",[],function(){"use strict";var e={hsvToRgb:function(e,t,i){var n,o,r,a,l,s={r:0,g:0,b:0};if(n=Math.floor(e/60),o=e/60-n,t/=100,i/=100,r=i*(1-t),a=i*(1-t*o),l=i*(1-t*(1-o)),0==t)s.r=s.g=s.b=i;else switch(n){case 1:s.r=a,s.g=i,s.b=r;break;case 2:s.r=r,s.g=i,s.b=l;break;case 3:s.r=r,s.g=a,s.b=i;break;case 4:s.r=l,s.g=r,s.b=i;break;case 5:s.r=i,s.g=r,s.b=a;break;case 0:case 6:s.r=i,s.g=l,s.b=r}return{r:Math.round(255*s.r),g:Math.round(255*s.g),b:Math.round(255*s.b)}},rgbToHsv:function(e,t,i){var n,o,r,a,l,s;if(e/=255,t/=255,i/=255,a=Math.max(Math.max(e,t),i),l=Math.min(Math.min(e,t),i),s=a-l,n=0,a!==l){switch(a){case e:n=(t-i)/s*60;break;case t:n=60*(2+(i-e)/s);break;case i:n=60*(4+(e-t)/s)}n<0&&(n+=360)}return o=0===a?0:s/a,r=a,{h:Math.round(n),s:Math.round(100*o),v:Math.round(100*r)}},hexToRgb:function(e){if(/^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(e)){var t=e.split("");return"#"===t[0]&&t.shift(),3===t.length?{r:parseInt(t[0]+""+t[0],16),g:parseInt(t[1]+""+t[1],16),b:parseInt(t[2]+""+t[2],16)}:{r:parseInt(t[0]+""+t[1],16),g:parseInt(t[2]+""+t[3],16),b:parseInt(t[4]+""+t[5],16)}}return Number.NaN},rgbToHex:function(e,t,i){var n="0123456789ABCDEF";return void 0===t&&e.toString().match(/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/)&&(e=RegExp.$1,t=RegExp.$2,i=RegExp.$3),n.charAt((e-e%16)/16)+""+n.charAt(e%16)+n.charAt((t-t%16)/16)+n.charAt(t%16)+n.charAt((i-i%16)/16)+n.charAt(i%16)}};return window.__wcf_bc_colorUtil=e,e}),define("WoltLabSuite/Core/FileUtil",["Dictionary","StringUtil"],function(e,t){"use strict";var i=e.fromObject({zip:"archive",rar:"archive",tar:"archive",gz:"archive",mp3:"audio",ogg:"audio",wav:"audio",php:"code",html:"code",htm:"code",tpl:"code",js:"code",xls:"excel",ods:"excel",xlsx:"excel",gif:"image",jpg:"image",jpeg:"image",png:"image",bmp:"image",webp:"image",avi:"video",wmv:"video",mov:"video",mp4:"video",mpg:"video",mpeg:"video",flv:"video",pdf:"pdf",ppt:"powerpoint",pptx:"powerpoint",txt:"text",doc:"word",docx:"word",odt:"word"}),n=e.fromObject({"application/zip":"zip","application/x-zip-compressed":"zip","application/rar":"rar","application/vnd.rar":"rar","application/x-rar-compressed":"rar","application/x-tar":"tar","application/x-gzip":"gz","application/gzip":"gz","audio/mpeg":"mp3","audio/mp3":"mp3","audio/ogg":"ogg","audio/x-wav":"wav","application/x-php":"php","text/html":"html","application/javascript":"js","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","image/gif":"gif","image/jpeg":"jpg","image/png":"png","image/x-ms-bmp":"bmp","image/bmp":"bmp","image/webp":"webp","video/x-msvideo":"avi","video/x-ms-wmv":"wmv","video/quicktime":"mov","video/mp4":"mp4","video/mpeg":"mpg","video/x-flv":"flv","application/pdf":"pdf","application/vnd.ms-powerpoint":"ppt","application/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","text/plain":"txt","application/msword":"doc","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application/vnd.oasis.opendocument.text":"odt"});return{formatFilesize:function(e,i){void 0===i&&(i=2);var n="Byte";return e>=1e3&&(e/=1e3,n="kB"),e>=1e3&&(e/=1e3,n="MB"),e>=1e3&&(e/=1e3,n="GB"),e>=1e3&&(e/=1e3,n="TB"),t.formatNumeric(e,-i)+" "+n},getIconNameByFilename:function(e){var t=e.lastIndexOf(".");if(!1!==t){var n=e.substr(t+1);if(i.has(n))return i.get(n)}return""},getExtensionByMimeType:function(e){return n.has(e)?"."+n.get(e):""},blobToFile:function(e,t){var i=this.getExtensionByMimeType(e.type),n=window.File;try{new n([],"ie11-check")}catch(e){n=function(e,t,i){var n=Blob.call(this,e,i);return n.name=t,n.lastModifiedDate=new Date,n},n.prototype=Object.create(window.File.prototype)}return new n([e],t+i,{type:e.type})}}}),define("WoltLabSuite/Core/Permission",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if("boolean"!=typeof i)throw new TypeError("Permission value has to be boolean.");t.set(e,i)},addObject:function(e){for(var t in e)objOwns(e,t)&&this.add(t,e[t])},get:function(e){return!!t.has(e)&&t.get(e)}}});var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){function t(e,t,i,n,o){this.type=e,this.content=t,this.alias=i,this.length=0|(n||"").length,this.greedy=!!o}var i=/\blang(?:uage)?-([\w-]+)\b/i,n=0,o={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof t?new t(e.type,o.util.encode(e.content),e.alias):Array.isArray(e)?e.map(o.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function e(t,i){var n,r,a=o.util.type(t);switch(i=i||{},a){case"Object":if(r=o.util.objId(t),i[r])return i[r];n={},i[r]=n;for(var l in t)t.hasOwnProperty(l)&&(n[l]=e(t[l],i));return n;case"Array":return r=o.util.objId(t),i[r]?i[r]:(n=[],i[r]=n,t.forEach(function(t,o){n[o]=e(t,i)}),n);default:return t}}},languages:{extend:function(e,t){var i=o.util.clone(o.languages[e]);for(var n in t)i[n]=t[n];return i},insertBefore:function(e,t,i,n){n=n||o.languages;var r=n[e],a={};for(var l in r)if(r.hasOwnProperty(l)){if(l==t)for(var s in i)i.hasOwnProperty(s)&&(a[s]=i[s]);i.hasOwnProperty(l)||(a[l]=r[l])}var c=n[e];return n[e]=a,o.languages.DFS(o.languages,function(t,i){i===c&&t!=e&&(this[t]=a)}),a},DFS:function e(t,i,n,r){r=r||{};var a=o.util.objId;for(var l in t)if(t.hasOwnProperty(l)){i.call(t,l,t[l],n||l);var s=t[l],c=o.util.type(s);"Object"!==c||r[a(s)]?"Array"!==c||r[a(s)]||(r[a(s)]=!0,e(s,i,l,r)):(r[a(s)]=!0,e(s,i,null,r))}}},plugins:{},highlightAll:function(e,t){o.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,i){var n={callback:i,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};o.hooks.run("before-highlightall",n);for(var r,a=n.elements||e.querySelectorAll(n.selector),l=0;r=a[l++];)o.highlightElement(r,!0===t,n.callback)},highlightElement:function(t,n,r){for(var a,l="none",s=t;s&&!i.test(s.className);)s=s.parentNode;s&&(l=(s.className.match(i)||[,"none"])[1].toLowerCase(),a=o.languages[l]),t.className=t.className.replace(i,"").replace(/\s+/g," ")+" language-"+l,t.parentNode&&(s=t.parentNode,/pre/i.test(s.nodeName)&&(s.className=s.className.replace(i,"").replace(/\s+/g," ")+" language-"+l));var c=t.textContent,u={element:t,language:l,grammar:a,code:c},d=function(e){u.highlightedCode=e,o.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,o.hooks.run("after-highlight",u),o.hooks.run("complete",u),r&&r.call(u.element)};if(o.hooks.run("before-sanity-check",u),!u.code)return void o.hooks.run("complete",u);if(o.hooks.run("before-highlight",u),!u.grammar)return void d(o.util.encode(u.code));if(n&&e.Worker){var h=new Worker(o.filename);h.onmessage=function(e){d(e.data)},h.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else d(o.highlight(u.code,u.grammar,u.language))},highlight:function(e,i,n){var r={code:e,grammar:i,language:n}
-;return o.hooks.run("before-tokenize",r),r.tokens=o.tokenize(r.code,r.grammar),o.hooks.run("after-tokenize",r),t.stringify(o.util.encode(r.tokens),r.language)},matchGrammar:function(e,i,n,r,a,l,s){for(var c in n)if(n.hasOwnProperty(c)&&n[c]){if(c==s)return;var u=n[c];u="Array"===o.util.type(u)?u:[u];for(var d=0;d<u.length;++d){var h=u[d],f=h.inside,p=!!h.lookbehind,g=!!h.greedy,m=0,v=h.alias;if(g&&!h.pattern.global){var b=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,b+"g")}h=h.pattern||h;for(var _=r,y=a;_<i.length;y+=i[_].length,++_){var w=i[_];if(i.length>e.length)return;if(!(w instanceof t)){if(g&&_!=i.length-1){h.lastIndex=y;var C=h.exec(e);if(!C)break;for(var E=C.index+(p?C[1].length:0),L=C.index+C[0].length,A=_,S=y,x=i.length;A<x&&(S<L||!i[A].type&&!i[A-1].greedy);++A)S+=i[A].length,E>=S&&(++_,y=S);if(i[_]instanceof t)continue;I=A-_,w=e.slice(y,S),C.index-=y}else{h.lastIndex=0;var C=h.exec(w),I=1}if(C){p&&(m=C[1]?C[1].length:0);var E=C.index+m,C=C[0].slice(m),L=E+C.length,D=w.slice(0,E),T=w.slice(L),k=[_,I];D&&(++_,y+=D.length,k.push(D));var B=new t(c,f?o.tokenize(C,f):C,v,C,g);if(k.push(B),T&&k.push(T),Array.prototype.splice.apply(i,k),1!=I&&o.matchGrammar(e,i,n,_,y,!0,c),l)break}else if(l)break}}}}},tokenize:function(e,t){var i=[e],n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}return o.matchGrammar(e,i,t,0,0,!1),i},hooks:{all:{},add:function(e,t){var i=o.hooks.all;i[e]=i[e]||[],i[e].push(t)},run:function(e,t){var i=o.hooks.all[e];if(i&&i.length)for(var n,r=0;n=i[r++];)n(t)}},Token:t};if(e.Prism=o,t.stringify=function(e,i){if("string"==typeof e)return e;if(Array.isArray(e))return e.map(function(e){return t.stringify(e,i)}).join("");var n={type:e.type,content:t.stringify(e.content,i),tag:"span",classes:["token",e.type],attributes:{},language:i};if(e.alias){var r=Array.isArray(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(n.classes,r)}o.hooks.run("wrap",n);var a=Object.keys(n.attributes).map(function(e){return e+'="'+(n.attributes[e]||"").replace(/"/g,"&quot;")+'"'}).join(" ");return"<"+n.tag+' class="'+n.classes.join(" ")+'"'+(a?" "+a:"")+">"+n.content+"</"+n.tag+">"},!e.document)return e.addEventListener?(o.disableWorkerMessageHandler||e.addEventListener("message",function(t){var i=JSON.parse(t.data),n=i.language,r=i.code,a=i.immediateClose;e.postMessage(o.highlight(r,o.languages[n],n)),a&&e.close()},!1),o):o;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(o.filename=r.src,o.manual||r.hasAttribute("data-manual")||(o.highlightAutomaticallyCallback=function(){o.manual||o.highlightAll()},"loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(o.highlightAutomaticallyCallback):window.setTimeout(o.highlightAutomaticallyCallback,16):document.addEventListener("DOMContentLoaded",o.highlightAutomaticallyCallback))),o}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),define("prism/prism",function(){}),window.Prism=window.Prism||{},window.Prism.manual=!0,define("WoltLabSuite/Core/Prism",["prism/prism"],function(){return Prism.wscSplitIntoLines=function(e){function t(){var e=elCreate("span");return elData(e,"number",a++),r.appendChild(e),e}var i,n,o,r=document.createDocumentFragment(),a=1;for(i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT,function(){return NodeFilter.FILTER_ACCEPT},!1),o=t();n=i.nextNode();)n.data.split(/\r?\n/).forEach(function(i,r){var a,l;for(r>=1&&(o.appendChild(document.createTextNode("\n")),o=t()),a=document.createTextNode(i),l=n.parentNode;l!==e;){var s=l.cloneNode(!1);s.appendChild(a),a=s,l=l.parentNode}o.appendChild(a)});return r},Prism}),define("WoltLabSuite/Core/Upload",["AjaxRequest","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={_createButton:function(){},_createFileElement:function(){},_createFileElements:function(){},_failure:function(){},_getParameters:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){},_success:function(){},_upload:function(){},_uploadFiles:function(){}},a}),define("WoltLabSuite/Core/User",[],function(){"use strict";var e,t=!1;return{getLink:function(){return e},init:function(i,n,o){if(t)throw new Error("User has already been initialized.");Object.defineProperty(this,"userId",{value:i,writable:!1}),Object.defineProperty(this,"username",{value:n,writable:!1}),e=o,t=!0}}}),define("WoltLabSuite/Core/Ajax/Jsonp",["Core"],function(e){"use strict";return{send:function(t,i,n,o){if(t="string"==typeof t?t.trim():"",0===t.length)throw new Error("Expected a non-empty string for parameter 'url'.");if("function"!=typeof i)throw new TypeError("Expected a valid callback function for parameter 'success'.");o=e.extend({parameterName:"callback",timeout:10},o||{});var r,a="wcf_jsonp_"+e.getUuid().replace(/-/g,"").substr(0,8),l=window.setTimeout(function(){"function"==typeof n&&n(),window[a]=void 0,elRemove(r)},1e3*(~~o.timeout||10));window[a]=function(){window.clearTimeout(l),i.apply(null,arguments),window[a]=void 0,elRemove(r)},t+=-1===t.indexOf("?")?"?":"&",t+=o.parameterName+"="+a,r=elCreate("script"),r.async=!0,elAttr(r,"src",t),document.head.appendChild(r)}}}),define("WoltLabSuite/Core/Ui/Notification",["Language"],function(e){"use strict";var t=!1,i=null,n=null,o=null,r=null,a=null;return{show:function(l,s,c){t||(this._init(),i="function"==typeof s?s:null,n.className=c||"success",n.textContent=e.get(l||"wcf.global.success"),t=!0,o.classList.add("active"),r=setTimeout(a,2e3))},_init:function(){null===o&&(a=this._hide.bind(this),o=elCreate("div"),o.id="systemNotification",n=elCreate("p"),n.addEventListener(WCF_CLICK_EVENT,a),o.appendChild(n),document.body.appendChild(o))},_hide:function(){clearTimeout(r),o.classList.remove("active"),null!==i&&i(),t=!1}}}),define("prism/prism-meta",[],function(){return{markup:{title:"Markup",file:"markup"},html:{title:"HTML",file:"markup"},xml:{title:"XML",file:"markup"},svg:{title:"SVG",file:"markup"},mathml:{title:"MathML",file:"markup"},css:{title:"CSS",file:"css"},clike:{title:"C-like",file:"clike"},javascript:{title:"JavaScript",file:"javascript"},abap:{title:"ABAP",file:"abap"},abnf:{title:"Augmented Backus–Naur form",file:"abnf"},actionscript:{title:"ActionScript",file:"actionscript"},ada:{title:"Ada",file:"ada"},apacheconf:{title:"Apache Configuration",file:"apacheconf"},apl:{title:"APL",file:"apl"},applescript:{title:"AppleScript",file:"applescript"},arduino:{title:"Arduino",file:"arduino"},arff:{title:"ARFF",file:"arff"},asciidoc:{title:"AsciiDoc",file:"asciidoc"},asm6502:{title:"6502 Assembly",file:"asm6502"},aspnet:{title:"ASP.NET (C#)",file:"aspnet"},autohotkey:{title:"AutoHotkey",file:"autohotkey"},autoit:{title:"AutoIt",file:"autoit"},bash:{title:"Bash",file:"bash"},basic:{title:"BASIC",file:"basic"},batch:{title:"Batch",file:"batch"},bison:{title:"Bison",file:"bison"},bnf:{title:"Backus–Naur form",file:"bnf"},brainfuck:{title:"Brainfuck",file:"brainfuck"},bro:{title:"Bro",file:"bro"},c:{title:"C",file:"c"},csharp:{title:"C#",file:"csharp"},cpp:{title:"C++",file:"cpp"},cil:{title:"CIL",file:"cil"},coffeescript:{title:"CoffeeScript",file:"coffeescript"},cmake:{title:"CMake",file:"cmake"},clojure:{title:"Clojure",file:"clojure"},crystal:{title:"Crystal",file:"crystal"},csp:{title:"Content-Security-Policy",file:"csp"},"css-extras":{title:"CSS Extras",file:"css-extras"},d:{title:"D",file:"d"},dart:{title:"Dart",file:"dart"},diff:{title:"Diff",file:"diff"},django:{title:"Django/Jinja2",file:"django"},docker:{title:"Docker",file:"docker"},ebnf:{title:"Extended Backus–Naur form",file:"ebnf"},eiffel:{title:"Eiffel",file:"eiffel"},ejs:{title:"EJS",file:"ejs"},elixir:{title:"Elixir",file:"elixir"},elm:{title:"Elm",file:"elm"},erb:{title:"ERB",file:"erb"},erlang:{title:"Erlang",file:"erlang"},fsharp:{title:"F#",file:"fsharp"},flow:{title:"Flow",file:"flow"},fortran:{title:"Fortran",file:"fortran"},gcode:{title:"G-code",file:"gcode"},gedcom:{title:"GEDCOM",file:"gedcom"},gherkin:{title:"Gherkin",file:"gherkin"},git:{title:"Git",file:"git"},glsl:{title:"GLSL",file:"glsl"},gml:{title:"GameMaker Language",file:"gml"},go:{title:"Go",file:"go"},graphql:{title:"GraphQL",file:"graphql"},groovy:{title:"Groovy",file:"groovy"},haml:{title:"Haml",file:"haml"},handlebars:{title:"Handlebars",file:"handlebars"},haskell:{title:"Haskell",file:"haskell"},haxe:{title:"Haxe",file:"haxe"},hcl:{title:"HCL",file:"hcl"},http:{title:"HTTP",file:"http"},hpkp:{title:"HTTP Public-Key-Pins",file:"hpkp"},hsts:{title:"HTTP Strict-Transport-Security",file:"hsts"},ichigojam:{title:"IchigoJam",file:"ichigojam"},icon:{title:"Icon",file:"icon"},inform7:{title:"Inform 7",file:"inform7"},ini:{title:"Ini",file:"ini"},io:{title:"Io",file:"io"},j:{title:"J",file:"j"},java:{title:"Java",file:"java"},javadoc:{title:"JavaDoc",file:"javadoc"},javadoclike:{title:"JavaDoc-like",file:"javadoclike"},javastacktrace:{title:"Java stack trace",file:"javastacktrace"},jolie:{title:"Jolie",file:"jolie"},jq:{title:"JQ",file:"jq"},jsdoc:{title:"JSDoc",file:"jsdoc"},"js-extras":{title:"JS Extras",file:"js-extras"},json:{title:"JSON",file:"json"},jsonp:{title:"JSONP",file:"jsonp"},json5:{title:"JSON5",file:"json5"},julia:{title:"Julia",file:"julia"},keyman:{title:"Keyman",file:"keyman"},kotlin:{title:"Kotlin",file:"kotlin"},latex:{title:"LaTeX",file:"latex"},tex:{title:"TeX",file:"latex"},context:{title:"ConTeXt",file:"latex"},less:{title:"Less",file:"less"},liquid:{title:"Liquid",file:"liquid"},lisp:{title:"Lisp",file:"lisp"},livescript:{title:"LiveScript",file:"livescript"},lolcode:{title:"LOLCODE",file:"lolcode"},lua:{title:"Lua",file:"lua"},makefile:{title:"Makefile",file:"makefile"},markdown:{title:"Markdown",file:"markdown"},"markup-templating":{title:"Markup templating",file:"markup-templating"},matlab:{title:"MATLAB",file:"matlab"},mel:{title:"MEL",file:"mel"},mizar:{title:"Mizar",file:"mizar"},monkey:{title:"Monkey",file:"monkey"},n1ql:{title:"N1QL",file:"n1ql"},n4js:{title:"N4JS",file:"n4js"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",file:"nand2tetris-hdl"},nasm:{title:"NASM",file:"nasm"},nginx:{title:"nginx",file:"nginx"},nim:{title:"Nim",file:"nim"},nix:{title:"Nix",file:"nix"},nsis:{title:"NSIS",file:"nsis"},objectivec:{title:"Objective-C",file:"objectivec"},ocaml:{title:"OCaml",file:"ocaml"},opencl:{title:"OpenCL",file:"opencl"},oz:{title:"Oz",file:"oz"},parigp:{title:"PARI/GP",file:"parigp"},parser:{title:"Parser",file:"parser"},pascal:{title:"Pascal",file:"pascal"},perl:{title:"Perl",file:"perl"},php:{title:"PHP",file:"php"},phpdoc:{title:"PHPDoc",file:"phpdoc"},"php-extras":{title:"PHP Extras",file:"php-extras"},plsql:{title:"PL/SQL",file:"plsql"},powershell:{title:"PowerShell",file:"powershell"},processing:{title:"Processing",file:"processing"},prolog:{title:"Prolog",file:"prolog"},properties:{title:".properties",file:"properties"},protobuf:{title:"Protocol Buffers",file:"protobuf"},pug:{title:"Pug",file:"pug"},puppet:{title:"Puppet",file:"puppet"},pure:{title:"Pure",file:"pure"},python:{title:"Python",file:"python"},q:{title:"Q (kdb+ database)",file:"q"},qore:{title:"Qore",file:"qore"},r:{title:"R",file:"r"},jsx:{title:"React JSX",file:"jsx"},tsx:{title:"React TSX",file:"tsx"},renpy:{title:"Ren'py",file:"renpy"},reason:{title:"Reason",file:"reason"},regex:{title:"Regex",file:"regex"},rest:{title:"reST (reStructuredText)",file:"rest"},rip:{title:"Rip",file:"rip"},roboconf:{title:"Roboconf",file:"roboconf"},ruby:{title:"Ruby",file:"ruby"},rust:{title:"Rust",file:"rust"},sas:{title:"SAS",file:"sas"},sass:{title:"Sass (Sass)",file:"sass"},scss:{title:"Sass (Scss)",file:"scss"},scala:{title:"Scala",file:"scala"},scheme:{title:"Scheme",file:"scheme"},"shell-session":{title:"Shell session",file:"shell-session"},smalltalk:{title:"Smalltalk",file:"smalltalk"},smarty:{title:"Smarty",file:"smarty"},sql:{title:"SQL",file:"sql"},soy:{title:"Soy (Closure Template)",file:"soy"},stylus:{title:"Stylus",file:"stylus"},swift:{title:"Swift",file:"swift"},tap:{title:"TAP",file:"tap"},tcl:{title:"Tcl",file:"tcl"},textile:{title:"Textile",file:"textile"},toml:{title:"TOML",file:"toml"},tt2:{title:"Template Toolkit 2",file:"tt2"},twig:{title:"Twig",file:"twig"},typescript:{title:"TypeScript",file:"typescript"},"t4-cs":{title:"T4 Text Templates (C#)",file:"t4-cs"},"t4-vb":{title:"T4 Text Templates (VB)",file:"t4-vb"},"t4-templating":{title:"T4 templating",file:"t4-templating"},vala:{title:"Vala",file:"vala"},vbnet:{title:"VB.Net",file:"vbnet"},velocity:{title:"Velocity",file:"velocity"},verilog:{title:"Verilog",file:"verilog"},vhdl:{title:"VHDL",file:"vhdl"},vim:{title:"vim",file:"vim"},"visual-basic":{title:"Visual Basic",file:"visual-basic"},wasm:{title:"WebAssembly",file:"wasm"},wiki:{title:"Wiki markup",file:"wiki"},xeora:{title:"Xeora",file:"xeora"},xojo:{title:"Xojo (REALbasic)",file:"xojo"},xquery:{title:"XQuery",file:"xquery"},yaml:{title:"YAML",file:"yaml"}}}),define("WoltLabSuite/Core/Bbcode/Code",["Language","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Clipboard","WoltLabSuite/Core/Prism","prism/prism-meta"],function(e,t,i,n,o){"use strict";function r(e){var t;this.container=e,this.codeContainer=elBySel(".codeBoxCode > code",this.container),this.language=null;for(var i=0;i<this.codeContainer.classList.length;i++)(t=this.codeContainer.classList[i].match(/language-(.*)/))&&(this.language=t[1])}var a=function(e){return function(){var t=arguments;return new Promise(function(i,n){var o=function(){try{i(e.apply(null,t))}catch(e){n(e)}};window.requestIdleCallback?window.requestIdleCallback(o,{timeout:5e3}):setTimeout(o,0)})}};return r.processAll=function(){elBySelAll(".codeBox:not([data-processed])",document,function(e){elData(e,"processed","1");var t=new r(e);t.language&&t.highlight(),t.createCopyButton()})},r.prototype={createCopyButton:function(){var n=elBySel(".codeBoxHeader",this.container),o=elCreate("span");o.className="icon icon24 fa-files-o pointer jsTooltip",o.setAttribute("title",e.get("wcf.message.bbcode.code.copy")),o.addEventListener("click",function(){i.copyElementTextToClipboard(this.codeContainer).then(function(){t.show(e.get("wcf.message.bbcode.code.copy.success"))})}.bind(this)),n.appendChild(o)},highlight:function(){return this.language?o[this.language]?(this.container.classList.add("highlighting"),require(["prism/components/prism-"+o[this.language].file]).then(a(function(){var e=n.languages[this.language];if(!e)throw new Error("Invalid language "+language+" given.");var t=elCreate("div");return t.innerHTML=n.highlight(this.codeContainer.textContent,e,this.language),t}.bind(this))).then(a(function(e){var t=n.wscSplitIntoLines(e),i=elBySelAll("[data-number]",t),o=elBySelAll(".codeBoxLine > span",this.codeContainer);if(i.length!==o.length)throw new Error("Unreachable");for(var r=[],l=0,s=i.length;l<s;l+=50)r.push(a(function(e){for(var t=Math.min(e+50,s),n=e;n<t;n++)o[n].parentNode.replaceChild(i[n],o[n])})(l));return Promise.all(r)}.bind(this))).then(function(){this.container.classList.remove("highlighting"),this.container.classList.add("highlighted")}.bind(this))):Promise.reject(new Error("Unknown language "+this.language)):Promise.reject(new Error("No language detected"))}},r}),define("WoltLabSuite/Core/Bbcode/Collapsible",[],function(){"use strict";var e=elByClass("jsCollapsibleBbcode");return{observe:function(){for(var t,i;e.length;)t=e[0],i=null,elBySelAll(".toggleButton:not(.jsToggleButtonEnabled)",t,function(e){e.closest(".jsCollapsibleBbcode")===t&&(i=e)}),i&&function(e,t){var i=function(i){if(e.classList.toggle("collapsed")){if(t.textContent=elData(t,"title-expand"),i instanceof Event){var n=e.getBoundingClientRect().top;if(n<0){var o=window.pageYOffset+(n-100);o<0&&(o=0),window.scrollTo(window.pageXOffset,o)}}}else t.textContent=elData(t,"title-collapse")};t.classList.add("jsToggleButtonEnabled"),t.addEventListener(WCF_CLICK_EVENT,i),0!==e.scrollTop&&i(),e.addEventListener("scroll",function(){e.classList.contains("collapsed")&&i()})}(t,i),t.classList.remove("jsCollapsibleBbcode")}}}),define("WoltLabSuite/Core/Bbcode/Spoiler",["Language"],function(e){"use strict";var t=elByClass("jsSpoilerBox");return{observe:function(){for(var e,i;t.length;)e=t[0],e.classList.remove("jsSpoilerBox"),i=elBySel(".jsSpoilerToggle",e),e=i.parentNode.nextElementSibling,i.addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this,e,i))},_onClick:function(t,i,n){n.preventDefault(),i.classList.toggle("active");var o=i.classList.contains("active");window[o?"elShow":"elHide"](t),elAttr(i,"aria-expanded",o),elAttr(t,"aria-hidden",!o),elDataBool(i,"has-custom-label")||(i.textContent=e.get(i.classList.contains("active")?"wcf.bbcode.spoiler.hide":"wcf.bbcode.spoiler.show"))}}}),define("WoltLabSuite/Core/Controller/Captcha",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if(t.has(e))throw new Error("Captcha with id '"+e+"' is already registered.");if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'callback'.");t.set(e,i)},delete:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");t.delete(e)},has:function(e){return t.has(e)},getData:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");return t.get(e)()}}}),define("WoltLabSuite/Core/Controller/Clipboard",["Ajax","Core","Dictionary","EventHandler","Language","List","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Page/Action","Ui/Screen"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";return{setup:function(){},reload:function(){},_initContainers:function(){},_loadMarkedItems:function(){},_markAll:function(){},_mark:function(){},_saveState:function(){},_executeAction:function(){},_executeProxyAction:function(){},_unmarkAll:function(){},_ajaxSetup:function(){},_ajaxSuccess:function(){},_rebuildMarkings:function(){},hideEditor:function(){},showEditor:function(){},unmark:function(){}}}),define("WoltLabSuite/Core/Image/ExifUtil",[],function(){"use strict";var e={SOI:216,APP0:224,APP1:225,APP2:226,APP3:227,APP4:228,APP5:229,APP6:230,APP7:231,APP8:232,APP9:233,APP10:234,APP11:235,APP12:236,APP13:237,APP14:238,COM:254};return{getExifBytesFromJpeg:function(t){return new Promise(function(i,n){if(!(t instanceof Blob||t instanceof File))return n(new TypeError("The argument must be a Blob or a File"));var o=new FileReader;o.addEventListener("error",function(){o.abort(),n(o.error)}),o.addEventListener("load",function(){var t=o.result,r=new Uint8Array(t),a=new Uint8Array;if(255!==r[0]&&r[1]!==e.SOI)return n(new Error("Not a JPEG"));for(var l=2;l<r.length&&255===r[l];){var s=2+(r[l+2]<<8|r[l+3]);if(r[l+1]===e.APP1){for(var c="",u=l+4;0!==r[u]&&u<r.length;u++)c+=String.fromCharCode(r[u]);if("Exif"===c||"http://ns.adobe.com/xap/1.0/"===c){var d=Array.prototype.slice.call(r,l,s+l),h=new Uint8Array(a.length+d.length);h.set(a),h.set(d,a.length),a=h}}l+=s}i(a)}),o.readAsArrayBuffer(t)})},removeExifData:function(t){return new Promise(function(i,n){if(!(t instanceof Blob||t instanceof File))return n(new TypeError("The argument must be a Blob or a File"));var o=new FileReader;o.addEventListener("error",function(){o.abort(),n(o.error)}),o.addEventListener("load",function(){var r=o.result,a=new Uint8Array(r);if(255!==a[0]&&a[1]!==e.SOI)return n(new Error("Not a JPEG"));for(var l=2;l<a.length&&255===a[l];){var s=2+(a[l+2]<<8|a[l+3]);if(a[l+1]===e.APP1){for(var c="",u=l+4;0!==a[u]&&u<a.length;u++)c+=String.fromCharCode(a[u]);if("Exif"===c||"http://ns.adobe.com/xap/1.0/"===c){var d=Array.prototype.slice.call(a,0,l),h=Array.prototype.slice.call(a,l+s);a=new Uint8Array(d.length+h.length),a.set(d,0),a.set(h,d.length)}else l+=s}else l+=s}i(new Blob([a],{type:t.type}))}),o.readAsArrayBuffer(t)})},setExifData:function(t,i){return this.removeExifData(t).then(function(t){return new Promise(function(n){var o=new FileReader;o.addEventListener("error",function(){o.abort(),reject(o.error)}),o.addEventListener("load",function(){var r=o.result,a=new Uint8Array(r),l=2;255===a[2]&&a[3]===e.APP0&&(l+=2+(a[4]<<8|a[5]));var s=Array.prototype.slice.call(a,0,l),c=Array.prototype.slice.call(a,l);a=new Uint8Array(s.length+i.length+c.length),a.set(s),a.set(i,l),a.set(c,l+i.length),n(new Blob([a],{type:t.type}))}),o.readAsArrayBuffer(t)})})}}}),define("WoltLabSuite/Core/Image/ImageUtil",[],function(){"use strict";return{containsTransparentPixels:function(e){for(var t=e.getContext("2d").getImageData(0,0,e.width,e.height),i=3,n=t.data.length;i<n;i+=4)if(255!==t.data[i])return!0;return!1}}}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("Pica",[],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pica=e()}}(function(){return function(){function e(t,i,n){function o(a,l){if(!i[a]){if(!t[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(r)return r(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=i[a]={exports:{}};t[a][0].call(u.exports,function(e){return o(t[a][1][e]||e)},u,u.exports,e,t,i,n)}return i[a].exports}for(var r="function"==typeof require&&require,a=0;a<n.length;a++)o(n[a]);return o}return e}()({1:[function(e,t,i){"use strict";function n(e){var t=e||[],i={js:t.indexOf("js")>=0,wasm:t.indexOf("wasm")>=0};r.call(this,i),this.features={js:i.js,wasm:i.wasm&&this.has_wasm},this.use(a),this.use(l)}var o=e("inherits"),r=e("multimath"),a=e("multimath/lib/unsharp_mask"),l=e("./mm_resize");o(n,r),n.prototype.resizeAndUnsharp=function(e,t){var i=this.resize(e,t);return e.unsharpAmount&&this.unsharp_mask(i,e.toWidth,e.toHeight,e.unsharpAmount,e.unsharpRadius,e.unsharpThreshold),i},t.exports=n},{"./mm_resize":4,inherits:15,multimath:16,"multimath/lib/unsharp_mask":19}],2:[function(e,t,i){"use strict";function n(e){return e<0?0:e>255?255:e}function o(e,t,i,o,r,a){var l,s,c,u,d,h,f,p,g,m,v,b=0,_=0;for(g=0;g<o;g++){for(d=0,m=0;m<r;m++){for(h=a[d++],f=a[d++],p=b+4*h|0,l=s=c=u=0;f>0;f--)v=a[d++],u=u+v*e[p+3]|0,c=c+v*e[p+2]|0,s=s+v*e[p+1]|0,l=l+v*e[p]|0,p=p+4|0;t[_+3]=n(u+8192>>14),t[_+2]=n(c+8192>>14),t[_+1]=n(s+8192>>14),t[_]=n(l+8192>>14),_=_+4*o|0}_=4*(g+1)|0,b=(g+1)*i*4|0}}function r(e,t,i,o,r,a){var l,s,c,u,d,h,f,p,g,m,v,b=0,_=0;for(g=0;g<o;g++){for(d=0,m=0;m<r;m++){for(h=a[d++],f=a[d++],p=b+4*h|0,l=s=c=u=0;f>0;f--)v=a[d++],u=u+v*e[p+3]|0,c=c+v*e[p+2]|0,s=s+v*e[p+1]|0,l=l+v*e[p]|0,p=p+4|0;t[_+3]=n(u+8192>>14),t[_+2]=n(c+8192>>14),t[_+1]=n(s+8192>>14),t[_]=n(l+8192>>14),_=_+4*o|0}_=4*(g+1)|0,b=(g+1)*i*4|0}}t.exports={convolveHorizontally:o,convolveVertically:r}},{}],3:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQQEAXAAAAcZAghjb252b2x2ZQAACmNvbnZvbHZlSFYAAQkBAArmAwLBAwEQfwJAIANFDQAgBEUNACAFQQRqIRVBACEMQQAhDQNAIA0hDkEAIRFBACEHA0AgB0ECaiESAn8gBSAHQQF0IgdqIgZBAmouAQAiEwRAQQAhCEEAIBNrIRQgFSAHaiEPIAAgDCAGLgEAakECdGohEEEAIQlBACEKQQAhCwNAIBAoAgAiB0EYdiAPLgEAIgZsIAtqIQsgB0H/AXEgBmwgCGohCCAHQRB2Qf8BcSAGbCAKaiEKIAdBCHZB/wFxIAZsIAlqIQkgD0ECaiEPIBBBBGohECAUQQFqIhQNAAsgEiATagwBC0EAIQtBACEKQQAhCUEAIQggEgshByABIA5BAnRqIApBgMAAakEOdSIGQf8BIAZB/wFIG0EQdEGAgPwHcUEAIAZBAEobIAtBgMAAakEOdSIGQf8BIAZB/wFIG0EYdEEAIAZBAEobciAJQYDAAGpBDnUiBkH/ASAGQf8BSBtBCHRBgP4DcUEAIAZBAEobciAIQYDAAGpBDnUiBkH/ASAGQf8BSBtB/wFxQQAgBkEAShtyNgIAIA4gA2ohDiARQQFqIhEgBEcNAAsgDCACaiEMIA1BAWoiDSADRw0ACwsLIQACQEEAIAIgAyAEIAUgABAAIAJBACAEIAUgBiABEAALCw=="},{}],4:[function(e,t,i){"use strict";t.exports={name:"resize",fn:e("./resize"),wasm_fn:e("./resize_wasm"),wasm_src:e("./convolve_wasm_base64")}},{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,o=t*i*4|0;n<o;)e[n]=255,n=n+4|0}var o=e("./resize_filter_gen"),r=e("./convolve").convolveHorizontally,a=e("./convolve").convolveVertically;t.exports=function(e){var t=e.src,i=e.width,l=e.height,s=e.toWidth,c=e.toHeight,u=e.scaleX||e.toWidth/e.width,d=e.scaleY||e.toHeight/e.height,h=e.offsetX||0,f=e.offsetY||0,p=e.dest||new Uint8Array(s*c*4),g=void 0===e.quality?3:e.quality,m=e.alpha||!1,v=o(g,i,s,u,h),b=o(g,l,c,d,f),_=new Uint8Array(s*l*4);return r(t,_,i,l,s,v),a(_,p,l,s,c,b),m||n(p,s,c),p}},{"./convolve":2,"./resize_filter_gen":6}],6:[function(e,t,i){"use strict";function n(e){return Math.round(e*((1<<r)-1))}var o=e("./resize_filter_info"),r=14;t.exports=function(e,t,i,r,a){var l,s,c,u,d,h,f,p,g,m,v,b,_,y,w,C,E,L=o[e].filter,A=1/r,S=Math.min(1,r),x=o[e].win/S,I=Math.floor(2*(x+1)),D=new Int16Array((I+2)*i),T=0,k=!D.subarray||!D.set;for(l=0;l<i;l++){for(s=(l+.5)*A+a,c=Math.max(0,Math.floor(s-x)),u=Math.min(t-1,Math.ceil(s+x)),d=u-c+1,h=new Float32Array(d),f=new Int16Array(d),p=0,g=c,m=0;g<=u;g++,m++)v=L((g+.5-s)*S),p+=v,h[m]=v;for(b=0,m=0;m<h.length;m++)_=h[m]/p,b+=_,f[m]=n(_);for(f[i>>1]+=n(1-b),y=0;y<f.length&&0===f[y];)y++;if(y<f.length){for(w=f.length-1;w>0&&0===f[w];)w--;if(C=c+y,E=w-y+1,D[T++]=C,D[T++]=E,k)for(m=y;m<=w;m++)D[T++]=f[m];else D.set(f.subarray(y,w+1),T),T+=E}else D[T++]=0,D[T++]=0}return D}},{"./resize_filter_info":7}],7:[function(e,t,i){"use strict";t.exports=[{win:.5,filter:function(e){return e>=-.5&&e<.5?1:0}},{win:1,filter:function(e){if(e<=-1||e>=1)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*(.54+.46*Math.cos(t/1))}},{win:2,filter:function(e){if(e<=-2||e>=2)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/2)/(t/2)}},{win:3,filter:function(e){if(e<=-3||e>=3)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/3)/(t/3)}}]},{}],8:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,o=t*i*4|0;n<o;)e[n]=255,n=n+4|0}function o(e){return new Uint8Array(e.buffer,0,e.byteLength)}function r(e,t,i){if(l)return void t.set(o(e),i);for(var n=i,r=0;r<e.length;r++){var a=e[r];t[n++]=255&a,t[n++]=a>>8&255}}var a=e("./resize_filter_gen"),l=!0;try{l=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0]}catch(e){}t.exports=function(e){var t=e.src,i=e.width,o=e.height,l=e.toWidth,s=e.toHeight,c=e.scaleX||e.toWidth/e.width,u=e.scaleY||e.toHeight/e.height,d=e.offsetX||0,h=e.offsetY||0,f=e.dest||new Uint8Array(l*s*4),p=void 0===e.quality?3:e.quality,g=e.alpha||!1,m=a(p,i,l,c,d),v=a(p,o,s,u,h),b=this.__align(0+Math.max(t.byteLength,f.byteLength)),_=this.__align(b+o*l*4),y=this.__align(_+m.byteLength),w=y+v.byteLength,C=this.__instance("resize",w),E=new Uint8Array(this.__memory.buffer),L=new Uint32Array(this.__memory.buffer),A=new Uint32Array(t.buffer);return L.set(A),r(m,E,_),r(v,E,y),(C.exports.convolveHV||C.exports._convolveHV)(_,y,b,i,o,l,s),new Uint32Array(f.buffer).set(new Uint32Array(this.__memory.buffer,0,s*l)),g||n(f,l,s),f}},{"./resize_filter_gen":6}],9:[function(e,t,i){"use strict";function n(e,t){this.create=e,this.available=[],this.acquired={},this.lastId=1,this.timeoutId=0,this.idle=t||2e3}n.prototype.acquire=function(){var e,t=this;return 0!==this.available.length?e=this.available.pop():(e=this.create(),e.id=this.lastId++,e.release=function(){return t.release(e)}),this.acquired[e.id]=e,e},n.prototype.release=function(e){var t=this;delete this.acquired[e.id],e.lastUsed=Date.now(),this.available.push(e),0===this.timeoutId&&(this.timeoutId=setTimeout(function(){return t.gc()},100))},n.prototype.gc=function(){var e=this,t=Date.now();this.available=this.available.filter(function(i){return!(t-i.lastUsed>e.idle)||(i.destroy(),!1)}),0!==this.available.length?this.timeoutId=setTimeout(function(){return e.gc()},100):this.timeoutId=0},t.exports=n},{}],10:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,o,r){var a=i/e,l=n/t,s=(2*r+2+1)/o;if(s>.5)return[[i,n]];var c=Math.ceil(Math.log(Math.min(a,l))/Math.log(s));if(c<=1)return[[i,n]];for(var u=[],d=0;d<c;d++){var h=Math.round(Math.pow(Math.pow(e,c-d-1)*Math.pow(i,d+1),1/c)),f=Math.round(Math.pow(Math.pow(t,c-d-1)*Math.pow(n,d+1),1/c));u.push([h,f])}return u}},{}],11:[function(e,t,i){"use strict";function n(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.floor(e)}function o(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.ceil(e)}var r=1e-5;t.exports=function(e){var t=e.toWidth/e.width,i=e.toHeight/e.height,r=n(e.srcTileSize*t)-2*e.destTileBorder,a=n(e.srcTileSize*i)-2*e.destTileBorder;if(r<1||a<1)throw new Error("Internal error in pica: target tile width/height is too small.");var l,s,c,u,d,h,f,p=[];for(u=0;u<e.toHeight;u+=a)for(c=0;c<e.toWidth;c+=r)l=c-e.destTileBorder,l<0&&(l=0),d=c+r+e.destTileBorder-l,l+d>=e.toWidth&&(d=e.toWidth-l),s=u-e.destTileBorder,s<0&&(s=0),h=u+a+e.destTileBorder-s,s+h>=e.toHeight&&(h=e.toHeight-s),f={toX:l,toY:s,toWidth:d,toHeight:h,toInnerX:c,toInnerY:u,toInnerWidth:r,toInnerHeight:a,offsetX:l/t-n(l/t),offsetY:s/i-n(s/i),scaleX:t,scaleY:i,x:n(l/t),y:n(s/i),width:o(d/t),height:o(h/i)},p.push(f);return p}},{}],12:[function(e,t,i){"use strict";function n(e){return Object.prototype.toString.call(e)}t.exports.isCanvas=function(e){var t=n(e);return"[object HTMLCanvasElement]"===t||"[object Canvas]"===t},t.exports.isImage=function(e){return"[object HTMLImageElement]"===n(e)},t.exports.limiter=function(e){function t(){i<e&&n.length&&(i++,n.shift()())}var i=0,n=[];return function(e){return new Promise(function(o,r){n.push(function(){e().then(function(e){o(e),i--,t()},function(e){r(e),i--,t()})}),t()})}},t.exports.cib_quality_name=function(e){switch(e){case 0:return"pixelated";case 1:return"low";case 2:return"medium"}return"high"},t.exports.cib_support=function(){return Promise.resolve().then(function(){if("undefined"==typeof createImageBitmap||"undefined"==typeof document)return!1;var e=document.createElement("canvas");return e.width=100,e.height=100,createImageBitmap(e,0,0,100,100,{resizeWidth:10,resizeHeight:10,resizeQuality:"high"}).then(function(t){var i=10===t.width;return t.close(),e=null,i})}).catch(function(){return!1})}},{}],13:[function(e,t,i){"use strict";t.exports=function(){var t,i=e("./mathlib");onmessage=function(e){var n=e.data.opts;t||(t=new i(e.data.features));var o=t.resizeAndUnsharp(n);postMessage({result:o},[o.buffer])}}},{"./mathlib":1}],14:[function(e,t,i){function n(e){e<.5&&(e=.5);var t=Math.exp(.527076)/e,i=Math.exp(-t),n=Math.exp(-2*t),o=(1-i)*(1-i)/(1+2*t*i-n);return a=o,l=o*(t-1)*i,s=o*(t+1)*i,c=-o*n,u=2*i,d=-n,h=(a+l)/(1-u-d),f=(s+c)/(1-u-d),new Float32Array([a,l,s,c,u,d,h,f])}function o(e,t,i,n,o,r){var a,l,s,c,u,d,h,f,p,g,m,v,b,_;for(p=0;p<r;p++){for(d=p*o,h=p,f=0,a=e[d],u=a*n[6],c=u,m=n[0],v=n[1],b=n[4],_=n[5],g=0;g<o;g++)l=e[d],s=l*m+a*v+c*b+u*_,u=c,c=s,a=l,i[f]=c,f++,d++;for(d--,f--,h+=r*(o-1),a=e[d],u=a*n[7],c=u,l=a,m=n[2],v=n[3],g=o-1;g>=0;g--)s=l*m+a*v+c*b+u*_,u=c,c=s,a=l,l=e[d],t[h]=i[f]+c,d--,f--,h-=r}}function r(e,t,i,r){if(r){var a=new Uint16Array(e.length),l=new Float32Array(Math.max(t,i)),s=n(r);o(e,a,l,s,t,i,r),o(a,e,l,s,i,t,r)}}var a,l,s,c,u,d,h,f;t.exports=r},{}],15:[function(e,t,i){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}},{}],16:[function(e,t,i){"use strict";function n(e){if(!(this instanceof n))return new n(e);var t=o({},l,e||{});if(this.options=t,this.__cache={},this.has_wasm=a(),this.__init_promise=null,this.__modules=t.modules||{},this.__memory=null,this.__wasm={},this.__isLE=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0],!this.options.js&&!this.options.wasm)throw new Error('mathlib: at least "js" or "wasm" should be enabled')}var o=e("object-assign"),r=e("./lib/base64decode"),a=e("./lib/wa_detect"),l={js:!0,wasm:!0};n.prototype.use=function(e){
-return this.__modules[e.name]=e,this.has_wasm&&this.options.wasm&&e.wasm_fn?this[e.name]=e.wasm_fn:this[e.name]=e.fn,this},n.prototype.init=function(){if(this.__init_promise)return this.__init_promise;if(!this.options.js&&this.options.wasm&&!this.has_wasm)return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));var e=this;return this.__init_promise=Promise.all(Object.keys(e.__modules).map(function(t){var i=e.__modules[t];return e.has_wasm&&e.options.wasm&&i.wasm_fn?e.__wasm[t]?null:WebAssembly.compile(e.__base64decode(i.wasm_src)).then(function(i){e.__wasm[t]=i}):null})).then(function(){return e}),this.__init_promise},n.prototype.__base64decode=r,n.prototype.__reallocate=function(e){if(!this.__memory)return this.__memory=new WebAssembly.Memory({initial:Math.ceil(e/65536)}),this.__memory;var t=this.__memory.buffer.byteLength;return t<e&&this.__memory.grow(Math.ceil((e-t)/65536)),this.__memory},n.prototype.__instance=function(e,t,i){if(t&&this.__reallocate(t),!this.__wasm[e]){var n=this.__modules[e];this.__wasm[e]=new WebAssembly.Module(this.__base64decode(n.wasm_src))}if(!this.__cache[e]){var r={memoryBase:0,memory:this.__memory,tableBase:0,table:new WebAssembly.Table({initial:0,element:"anyfunc"})};this.__cache[e]=new WebAssembly.Instance(this.__wasm[e],{env:o(r,i||{})})}return this.__cache[e]},n.prototype.__align=function(e,t){t=t||8;var i=e%t;return e+(i?t-i:0)},t.exports=n},{"./lib/base64decode":17,"./lib/wa_detect":23,"object-assign":24}],17:[function(e,t,i){"use strict";t.exports=function(e){for(var t=e.replace(/[\r\n=]/g,""),i=t.length,n=new Uint8Array(3*i>>2),o=0,r=0,a=0;a<i;a++)a%4==0&&a&&(n[r++]=o>>16&255,n[r++]=o>>8&255,n[r++]=255&o),o=o<<6|"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t.charAt(a));var l=i%4*6;return 0===l?(n[r++]=o>>16&255,n[r++]=o>>8&255,n[r++]=255&o):18===l?(n[r++]=o>>10&255,n[r++]=o>>2&255):12===l&&(n[r++]=o>>4&255),n}},{}],18:[function(e,t,i){"use strict";t.exports=function(e,t,i){for(var n,o,r,a,l,s=t*i,c=new Uint16Array(s),u=0;u<s;u++)n=e[4*u],o=e[4*u+1],r=e[4*u+2],l=n>=o&&n>=r?n:o>=r&&o>=n?o:r,a=n<=o&&n<=r?n:o<=r&&o<=n?o:r,c[u]=257*(l+a)>>1;return c}},{}],19:[function(e,t,i){"use strict";t.exports={name:"unsharp_mask",fn:e("./unsharp_mask"),wasm_fn:e("./unsharp_mask_wasm"),wasm_src:e("./unsharp_mask_wasm_base64")}},{"./unsharp_mask":20,"./unsharp_mask_wasm":21,"./unsharp_mask_wasm_base64":22}],20:[function(e,t,i){"use strict";var n=e("glur/mono16"),o=e("./hsl_l16");t.exports=function(e,t,i,r,a,l){var s,c,u,d,h,f,p,g,m,v,b,_,y;if(!(0===r||a<.5)){a>2&&(a=2);var w=o(e,t,i),C=new Uint16Array(w);n(C,t,i,a);for(var E=r/100*4096+.5|0,L=257*l|0,A=t*i,S=0;S<A;S++)_=2*(w[S]-C[S]),Math.abs(_)>=L&&(y=4*S,s=e[y],c=e[y+1],u=e[y+2],g=s>=c&&s>=u?s:c>=s&&c>=u?c:u,p=s<=c&&s<=u?s:c<=s&&c<=u?c:u,f=257*(g+p)>>1,p===g?d=h=0:(h=f<=32767?4095*(g-p)/(g+p)|0:4095*(g-p)/(510-g-p)|0,d=s===g?65535*(c-u)/(6*(g-p))|0:c===g?21845+(65535*(u-s)/(6*(g-p))|0):43690+(65535*(s-c)/(6*(g-p))|0)),f+=E*_+2048>>12,f>65535?f=65535:f<0&&(f=0),0===h?s=c=u=f>>8:(v=f<=32767?f*(4096+h)+2048>>12:f+((65535-f)*h+2048>>12),m=2*f-v>>8,v>>=8,b=d+21845&65535,s=b>=43690?m:b>=32767?m+(6*(v-m)*(43690-b)+32768>>16):b>=10922?v:m+(6*(v-m)*b+32768>>16),b=65535&d,c=b>=43690?m:b>=32767?m+(6*(v-m)*(43690-b)+32768>>16):b>=10922?v:m+(6*(v-m)*b+32768>>16),b=d-21845&65535,u=b>=43690?m:b>=32767?m+(6*(v-m)*(43690-b)+32768>>16):b>=10922?v:m+(6*(v-m)*b+32768>>16)),e[y]=s,e[y+1]=c,e[y+2]=u)}}},{"./hsl_l16":18,"glur/mono16":14}],21:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,o,r){if(!(0===n||o<.5)){o>2&&(o=2);var a=t*i,l=4*a,s=2*a,c=2*a,u=4*Math.max(t,i),d=l,h=d+s,f=h+c,p=f+c,g=p+u,m=this.__instance("unsharp_mask",l+s+2*c+u+32,{exp:Math.exp}),v=new Uint32Array(e.buffer);new Uint32Array(this.__memory.buffer).set(v);var b=m.exports.hsl_l16||m.exports._hsl_l16;b(0,d,t,i),b=m.exports.blurMono16||m.exports._blurMono16,b(d,h,f,p,g,t,i,o),b=m.exports.unsharp||m.exports._unsharp,b(0,0,d,h,t,i,n,r),v.set(new Uint32Array(this.__memory.buffer,0,a))}}},{}],22:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABMQZgAXwBfGACfX8AYAZ/f39/f38AYAh/f39/f39/fQBgBH9/f38AYAh/f39/f39/fwACGQIDZW52A2V4cAAAA2VudgZtZW1vcnkCAAEDBgUBAgMEBQQEAXAAAAdMBRZfX2J1aWxkX2dhdXNzaWFuX2NvZWZzAAEOX19nYXVzczE2X2xpbmUAAgpibHVyTW9ubzE2AAMHaHNsX2wxNgAEB3Vuc2hhcnAABQkBAAqJEAXZAQEGfAJAIAFE24a6Q4Ia+z8gALujIgOaEAAiBCAEoCIGtjgCECABIANEAAAAAAAAAMCiEAAiBbaMOAIUIAFEAAAAAAAA8D8gBKEiAiACoiAEIAMgA6CiRAAAAAAAAPA/oCAFoaMiArY4AgAgASAEIANEAAAAAAAA8L+gIAKioiIHtjgCBCABIAQgA0QAAAAAAADwP6AgAqKiIgO2OAIIIAEgBSACoiIEtow4AgwgASACIAegIAVEAAAAAAAA8D8gBqGgIgKjtjgCGCABIAMgBKEgAqO2OAIcCwu3AwMDfwR9CHwCQCADKgIUIQkgAyoCECEKIAMqAgwhCyADKgIIIQwCQCAEQX9qIgdBAEgiCA0AIAIgAC8BALgiDSADKgIYu6IiDiAJuyIQoiAOIAq7IhGiIA0gAyoCBLsiEqIgAyoCALsiEyANoqCgoCIPtjgCACACQQRqIQIgAEECaiEAIAdFDQAgBCEGA0AgAiAOIBCiIA8iDiARoiANIBKiIBMgAC8BALgiDaKgoKAiD7Y4AgAgAkEEaiECIABBAmohACAGQX9qIgZBAUoNAAsLAkAgCA0AIAEgByAFbEEBdGogAEF+ai8BACIIuCINIAu7IhGiIA0gDLsiEqKgIA0gAyoCHLuiIg4gCrsiE6KgIA4gCbsiFKKgIg8gAkF8aioCALugqzsBACAHRQ0AIAJBeGohAiAAQXxqIQBBACAFQQF0ayEHIAEgBSAEQQF0QXxqbGohBgNAIAghAyAALwEAIQggBiANIBGiIAO4Ig0gEqKgIA8iECAToqAgDiAUoqAiDyACKgIAu6CrOwEAIAYgB2ohBiAAQX5qIQAgAkF8aiECIBAhDiAEQX9qIgRBAUoNAAsLCwvfAgIDfwZ8AkAgB0MAAAAAWw0AIARE24a6Q4Ia+z8gB0MAAAA/l7ujIgyaEAAiDSANoCIPtjgCECAEIAxEAAAAAAAAAMCiEAAiDraMOAIUIAREAAAAAAAA8D8gDaEiCyALoiANIAwgDKCiRAAAAAAAAPA/oCAOoaMiC7Y4AgAgBCANIAxEAAAAAAAA8L+gIAuioiIQtjgCBCAEIA0gDEQAAAAAAADwP6AgC6KiIgy2OAIIIAQgDiALoiINtow4AgwgBCALIBCgIA5EAAAAAAAA8D8gD6GgIgujtjgCGCAEIAwgDaEgC6O2OAIcIAYEQCAFQQF0IQogBiEJIAIhCANAIAAgCCADIAQgBSAGEAIgACAKaiEAIAhBAmohCCAJQX9qIgkNAAsLIAVFDQAgBkEBdCEIIAUhAANAIAIgASADIAQgBiAFEAIgAiAIaiECIAFBAmohASAAQX9qIgANAAsLC7wBAQV/IAMgAmwiAwRAQQAgA2shBgNAIAAoAgAiBEEIdiIHQf8BcSECAn8gBEH/AXEiAyAEQRB2IgRB/wFxIgVPBEAgAyIIIAMgAk8NARoLIAQgBCAHIAIgA0kbIAIgBUkbQf8BcQshCAJAIAMgAk0EQCADIAVNDQELIAQgByAEIAMgAk8bIAIgBUsbQf8BcSEDCyAAQQRqIQAgASADIAhqQYECbEEBdjsBACABQQJqIQEgBkEBaiIGDQALCwvTBgEKfwJAIAazQwAAgEWUQwAAyEKVu0QAAAAAAADgP6CqIQ0gBSAEbCILBEAgB0GBAmwhDgNAQQAgAi8BACADLwEAayIGQQF0IgdrIAcgBkEASBsgDk8EQCAAQQJqLQAAIQUCfyAALQAAIgYgAEEBai0AACIESSIJRQRAIAYiCCAGIAVPDQEaCyAFIAUgBCAEIAVJGyAGIARLGwshCAJ/IAYgBE0EQCAGIgogBiAFTQ0BGgsgBSAFIAQgBCAFSxsgCRsLIgogCGoiD0GBAmwiEEEBdiERQQAhDAJ/QQAiCSAIIApGDQAaIAggCmsiCUH/H2wgD0H+AyAIayAKayAQQYCABEkbbSEMIAYgCEYEQCAEIAVrQf//A2wgCUEGbG0MAQsgBSAGayAGIARrIAQgCEYiBhtB//8DbCAJQQZsbUHVqgFBqtUCIAYbagshCSARIAcgDWxBgBBqQQx1aiIGQQAgBkEAShsiBkH//wMgBkH//wNIGyEGAkACfwJAIAxB//8DcSIFBEAgBkH//wFKDQEgBUGAIGogBmxBgBBqQQx2DAILIAZBCHYiBiEFIAYhBAwCCyAFIAZB//8Dc2xBgBBqQQx2IAZqCyIFQQh2IQcgBkEBdCAFa0EIdiIGIQQCQCAJQdWqAWpB//8DcSIFQanVAksNACAFQf//AU8EQEGq1QIgBWsgByAGa2xBBmxBgIACakEQdiAGaiEEDAELIAchBCAFQanVAEsNACAFIAcgBmtsQQZsQYCAAmpBEHYgBmohBAsCfyAGIgUgCUH//wNxIghBqdUCSw0AGkGq1QIgCGsgByAGa2xBBmxBgIACakEQdiAGaiAIQf//AU8NABogByIFIAhBqdUASw0AGiAIIAcgBmtsQQZsQYCAAmpBEHYgBmoLIQUgCUGr1QJqQf//A3EiCEGp1QJLDQAgCEH//wFPBEBBqtUCIAhrIAcgBmtsQQZsQYCAAmpBEHYgBmohBgwBCyAIQanVAEsEQCAHIQYMAQsgCCAHIAZrbEEGbEGAgAJqQRB2IAZqIQYLIAEgBDoAACABQQFqIAU6AAAgAUECaiAGOgAACyADQQJqIQMgAkECaiECIABBBGohACABQQRqIQEgC0F/aiILDQALCwsL"},{}],23:[function(e,t,i){"use strict";var n;t.exports=function(){if(void 0!==n)return n;if(n=!1,"undefined"==typeof WebAssembly)return n;try{var e=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11]),t=new WebAssembly.Module(e);return 0!==new WebAssembly.Instance(t,{}).exports.test(4)&&(n=!0),n}catch(e){}return n}},{}],24:[function(e,t,i){"use strict";function n(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}var o=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;t.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},i=0;i<10;i++)t["_"+String.fromCharCode(i)]=i;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(e){n[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var i,l,s=n(e),c=1;c<arguments.length;c++){i=Object(arguments[c]);for(var u in i)r.call(i,u)&&(s[u]=i[u]);if(o){l=o(i);for(var d=0;d<l.length;d++)a.call(i,l[d])&&(s[l[d]]=i[l[d]])}}return s}},{}],25:[function(e,t,i){var n=arguments[3],o=arguments[4],r=arguments[5],a=JSON.stringify;t.exports=function(e,t){function i(e){m[e]=!0;for(var t in o[e][1]){var n=o[e][1][t];m[n]||i(n)}}for(var l,s=Object.keys(r),c=0,u=s.length;c<u;c++){var d=s[c],h=r[d].exports;if(h===e||h&&h.default===e){l=d;break}}if(!l){l=Math.floor(Math.pow(16,8)*Math.random()).toString(16);for(var f={},c=0,u=s.length;c<u;c++){var d=s[c];f[d]=d}o[l]=["function(require,module,exports){"+e+"(self); }",f]}var p=Math.floor(Math.pow(16,8)*Math.random()).toString(16),g={};g[l]=l,o[p]=["function(require,module,exports){var f = require("+a(l)+");(f.default ? f.default : f)(self);}",g];var m={};i(p);var v="("+n+")({"+Object.keys(m).map(function(e){return a(e)+":["+o[e][0]+","+a(o[e][1])+"]"}).join(",")+"},{},["+a(p)+"])",b=window.URL||window.webkitURL||window.mozURL||window.msURL,_=new Blob([v],{type:"text/javascript"});if(t&&t.bare)return _;var y=b.createObjectURL(_),w=new Worker(y);return w.objectURL=y,w}},{}],"/":[function(e,t,i){"use strict";function n(e,t){return a(e)||r(e,t)||o()}function o(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function r(e,t){var i=[],n=!0,o=!1,r=void 0;try{for(var a,l=e[Symbol.iterator]();!(n=(a=l.next()).done)&&(i.push(a.value),!t||i.length!==t);n=!0);}catch(e){o=!0,r=e}finally{try{n||null==l.return||l.return()}finally{if(o)throw r}}return i}function a(e){if(Array.isArray(e))return e}function l(){return{value:u(p),destroy:function(){if(this.value.terminate(),"undefined"!=typeof window){var e=window.URL||window.webkitURL||window.mozURL||window.msURL;e&&e.revokeObjectURL&&this.value.objectURL&&e.revokeObjectURL(this.value.objectURL)}}}}function s(e){if(!(this instanceof s))return new s(e);this.options=c({},C,e||{});var t="lk_".concat(this.options.concurrency);this.__limit=v[t]||f.limiter(this.options.concurrency),v[t]||(v[t]=this.__limit),this.features={js:!1,wasm:!1,cib:!1,ww:!1},this.__workersPool=null,this.__requested_features=[],this.__mathlib=null}var c=e("object-assign"),u=e("webworkify"),d=e("./lib/mathlib"),h=e("./lib/pool"),f=e("./lib/utils"),p=e("./lib/worker"),g=e("./lib/stepper"),m=e("./lib/tiler"),v={},b=!1;try{"undefined"!=typeof navigator&&navigator.userAgent&&(b=navigator.userAgent.indexOf("Safari")>=0)}catch(e){}var _=1;"undefined"!=typeof navigator&&(_=Math.min(navigator.hardwareConcurrency||1,4));var y,w,C={tile:1024,concurrency:_,features:["js","wasm","ww"],idle:2e3},E={quality:3,alpha:!1,unsharpAmount:0,unsharpRadius:0,unsharpThreshold:0};s.prototype.init=function(){var t=this;if(this.__initPromise)return this.__initPromise;if(!1!==y&&!0!==y&&(y=!1,"undefined"!=typeof ImageData&&"undefined"!=typeof Uint8ClampedArray))try{new ImageData(new Uint8ClampedArray(400),10,10),y=!0}catch(e){}!1!==w&&!0!==w&&(w=!1,"undefined"!=typeof ImageBitmap&&(ImageBitmap.prototype&&ImageBitmap.prototype.close?w=!0:this.debug("ImageBitmap does not support .close(), disabled")));var i=this.options.features.slice();if(i.indexOf("all")>=0&&(i=["cib","wasm","js","ww"]),this.__requested_features=i,this.__mathlib=new d(i),i.indexOf("ww")>=0&&"undefined"!=typeof window&&"Worker"in window)try{e("webworkify")(function(){}).terminate(),this.features.ww=!0;var n="wp_".concat(JSON.stringify(this.options));v[n]?this.__workersPool=v[n]:(this.__workersPool=new h(l,this.options.idle),v[n]=this.__workersPool)}catch(e){}var o,r=this.__mathlib.init().then(function(e){c(t.features,e.features)});return o=w?f.cib_support().then(function(e){if(t.features.cib&&i.indexOf("cib")<0)return void t.debug("createImageBitmap() resize supported, but disabled by config");i.indexOf("cib")>=0&&(t.features.cib=e)}):Promise.resolve(!1),this.__initPromise=Promise.all([r,o]).then(function(){return t}),this.__initPromise},s.prototype.resize=function(e,t,i){var o=this;this.debug("Start resize...");var r=c({},E);if(isNaN(i)?i&&(r=c(r,i)):r=c(r,{quality:i}),r.toWidth=t.width,r.toHeight=t.height,r.width=e.naturalWidth||e.width,r.height=e.naturalHeight||e.height,0===t.width||0===t.height)return Promise.reject(new Error("Invalid output size: ".concat(t.width,"x").concat(t.height)));r.unsharpRadius>2&&(r.unsharpRadius=2);var a=!1,l=null;r.cancelToken&&(l=r.cancelToken.then(function(e){throw a=!0,e},function(e){throw a=!0,e}));var s=Math.ceil(Math.max(3,2.5*r.unsharpRadius|0));return this.init().then(function(){if(a)return l;if(o.features.cib){var i=t.getContext("2d",{alpha:Boolean(r.alpha)});return o.debug("Resize via createImageBitmap()"),createImageBitmap(e,{resizeWidth:r.toWidth,resizeHeight:r.toHeight,resizeQuality:f.cib_quality_name(r.quality)}).then(function(e){if(a)return l;if(!r.unsharpAmount)return i.drawImage(e,0,0),e.close(),i=null,o.debug("Finished!"),t;o.debug("Unsharp result");var n=document.createElement("canvas");n.width=r.toWidth,n.height=r.toHeight;var s=n.getContext("2d",{alpha:Boolean(r.alpha)});s.drawImage(e,0,0),e.close();var c=s.getImageData(0,0,r.toWidth,r.toHeight);return o.__mathlib.unsharp(c.data,r.toWidth,r.toHeight,r.unsharpAmount,r.unsharpRadius,r.unsharpThreshold),i.putImageData(c,0,0),c=s=n=i=null,o.debug("Finished!"),t})}var u={},d=function(e){return Promise.resolve().then(function(){return o.features.ww?new Promise(function(t,i){var n=o.__workersPool.acquire();l&&l.catch(function(e){return i(e)}),n.value.onmessage=function(e){n.release(),e.data.err?i(e.data.err):t(e.data.result)},n.value.postMessage({opts:e,features:o.__requested_features,preload:{wasm_nodule:o.__mathlib.__}},[e.src.buffer])}):o.__mathlib.resizeAndUnsharp(e,u)})},h=function(e,t,i){var n,r,c,u=function(t){return o.__limit(function(){if(a)return l;var s;if(f.isCanvas(e))o.debug("Get tile pixel data"),s=n.getImageData(t.x,t.y,t.width,t.height);else{o.debug("Draw tile imageBitmap/image to temporary canvas");var u=document.createElement("canvas");u.width=t.width,u.height=t.height;var h=u.getContext("2d",{alpha:Boolean(i.alpha)});h.globalCompositeOperation="copy",h.drawImage(r||e,t.x,t.y,t.width,t.height,0,0,t.width,t.height),o.debug("Get tile pixel data"),s=h.getImageData(0,0,t.width,t.height),h=u=null}var p={src:s.data,width:t.width,height:t.height,toWidth:t.toWidth,toHeight:t.toHeight,scaleX:t.scaleX,scaleY:t.scaleY,offsetX:t.offsetX,offsetY:t.offsetY,quality:i.quality,alpha:i.alpha,unsharpAmount:i.unsharpAmount,unsharpRadius:i.unsharpRadius,unsharpThreshold:i.unsharpThreshold};return o.debug("Invoke resize math"),Promise.resolve().then(function(){return d(p)}).then(function(e){if(a)return l;s=null;var i;if(o.debug("Convert raw rgba tile result to ImageData"),y)i=new ImageData(new Uint8ClampedArray(e),t.toWidth,t.toHeight);else if(i=c.createImageData(t.toWidth,t.toHeight),i.data.set)i.data.set(e);else for(var n=i.data.length-1;n>=0;n--)i.data[n]=e[n];return o.debug("Draw tile"),b?c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth+1e-5,t.toInnerHeight+1e-5):c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth,t.toInnerHeight),null})})};return Promise.resolve().then(function(){if(c=t.getContext("2d",{alpha:Boolean(i.alpha)}),f.isCanvas(e))return n=e.getContext("2d",{alpha:Boolean(i.alpha)}),null;if(f.isImage(e))return w?(o.debug("Decode image via createImageBitmap"),createImageBitmap(e).then(function(e){r=e})):null;throw new Error('".from" should be image or canvas')}).then(function(){function e(){r&&(r.close(),r=null)}if(a)return l;o.debug("Calculate tiles");var n=m({width:i.width,height:i.height,srcTileSize:o.options.tile,toWidth:i.toWidth,toHeight:i.toHeight,destTileBorder:s}),c=n.map(function(e){return u(e)});return o.debug("Process tiles"),Promise.all(c).then(function(){return o.debug("Finished!"),e(),t},function(t){throw e(),t})})},p=g(r.width,r.height,r.toWidth,r.toHeight,o.options.tile,s);return function e(t,i,o,r){if(a)return l;var s=t.shift(),u=n(s,2),d=u[0],f=u[1],p=0===t.length;r=c({},r,{toWidth:d,toHeight:f,quality:p?r.quality:Math.min(1,r.quality)});var g;return p||(g=document.createElement("canvas"),g.width=d,g.height=f),h(i,p?o:g,r).then(function(){return p?o:(r.width=d,r.height=f,e(t,g,o,r))})}(p,e,t,r)})},s.prototype.resizeBuffer=function(e){var t=this,i=c({},E,e);return this.init().then(function(){return t.__mathlib.resizeAndUnsharp(i)})},s.prototype.toBlob=function(e,t,i){return t=t||"image/png",new Promise(function(n){if(e.toBlob)return void e.toBlob(function(e){return n(e)},t,i);for(var o=atob(e.toDataURL(t,i).split(",")[1]),r=o.length,a=new Uint8Array(r),l=0;l<r;l++)a[l]=o.charCodeAt(l);n(new Blob([a],{type:t}))})},s.prototype.debug=function(){},t.exports=s},{"./lib/mathlib":1,"./lib/pool":9,"./lib/stepper":10,"./lib/tiler":11,"./lib/utils":12,"./lib/worker":13,"object-assign":24,webworkify:25}]},{},[])("/")}),define("WoltLabSuite/Core/Image/Resizer",["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ExifUtil","Pica"],function(e,t,i){"use strict";function n(){}var o=new i({features:["js","wasm","ww"]});return n.prototype={maxWidth:800,maxHeight:600,quality:.8,fileType:"image/jpeg",setMaxWidth:function(e){return null==e&&(e=n.prototype.maxWidth),this.maxWidth=e,this},setMaxHeight:function(e){return null==e&&(e=n.prototype.maxHeight),this.maxHeight=e,this},setQuality:function(e){return null==e&&(e=n.prototype.quality),this.quality=e,this},setFileType:function(e){return null==e&&(e=n.prototype.fileType),this.fileType=e,this},saveFile:function(i,n,r,a){r=r||this.fileType,a=a||this.quality;var l=n.match(/(.+)(\..+?)$/);return o.toBlob(i.image,r,a).then(function(e){return"image/jpeg"===r&&void 0!==i.exif?t.setExifData(e,i.exif):e}).then(function(t){return e.blobToFile(t,l[1]+"_autoscaled")})},loadFile:function(e){var i=void 0,n=Promise.resolve(e);"image/jpeg"===e.type&&(i=t.getExifBytesFromJpeg(e),n=n.then(t.removeExifData.bind(t)));var n=n.then(function(e){return new Promise(function(t,i){var n=new FileReader,o=new Image;n.addEventListener("load",function(){o.src=n.result}),n.addEventListener("error",function(){n.abort(),i(n.error)}),o.addEventListener("error",i),o.addEventListener("load",function(){t(o)}),n.readAsDataURL(e)})});return Promise.all([i,n]).then(function(e){return{exif:e[0],image:e[1]}})},resize:function(e,t,i,n,r,a){t=t||this.maxWidth,i=i||this.maxHeight,n=n||this.quality,r=r||!1;var l=document.createElement("canvas"),s=window.createImageBitmap?createImageBitmap(e).then(function(t){if(t.height!=e.height)throw new Error("Chrome Bug #1069965")}):Promise.resolve(),c=Math.min(t,e.width),u=Math.min(i,e.height);if(e.width<=c&&e.height<=u&&!r)return Promise.resolve(void 0);var d=Math.min(c/e.width,u/e.height);l.width=Math.floor(e.width*d),l.height=Math.floor(e.height*d);var h=1;n>=.8?h=3:n>=.4&&(h=2);var f={quality:h,cancelToken:a,alpha:!0};return s.then(function(){return o.resize(e,l,f)})}},n}),define("WoltLabSuite/Core/Language/Chooser",["Core","Dictionary","Language","Dom/Traverse","Dom/Util","ObjectMap","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l=new t,s=!1,c=new r,u=null;return{init:function(e,t,i,n,o,r){if(!l.has(t)){var a=elById(e);if(null===a)throw new Error("Expected a valid container id, cannot find '"+t+"'.");var s=elById(t);null===s&&(s=elCreate("input"),elAttr(s,"type","hidden"),elAttr(s,"id",t),elAttr(s,"name",t),elAttr(s,"value",i),a.appendChild(s)),this._initElement(t,s,i,n,o,r)}},_setup:function(){s||(s=!0,u=this._submit.bind(this))},_initElement:function(e,t,r,s,d,h){var f;"DD"===t.parentNode.nodeName?(f=elCreate("div"),f.className="dropdown",o.prepend(f,t.parentNode)):(f=t.parentNode,f.classList.add("dropdown")),elHide(t);var p=elCreate("a");p.className="dropdownToggle dropdownIndicator boxFlag box24 inputPrefix"+("DD"===t.parentNode.nodeName?" button":""),f.appendChild(p);var g=elCreate("ul");g.className="dropdownMenu",f.appendChild(g);var m,v,b,_,y=function(t){var i=~~elData(t.currentTarget,"language-id"),o=n.childByClass(g,"active");null!==o&&o.classList.remove("active"),i&&t.currentTarget.classList.add("active"),this._select(e,i,t.currentTarget)}.bind(this);for(var w in s)if(s.hasOwnProperty(w)){var C=s[w];b=elCreate("li"),b.className="boxFlag",b.addEventListener(WCF_CLICK_EVENT,y),elData(b,"language-id",w),void 0!==C.languageCode&&elData(b,"language-code",C.languageCode),g.appendChild(b),m=elCreate("a"),m.className="box24",b.appendChild(m),v=elCreate("img"),elAttr(v,"src",C.iconPath),elAttr(v,"alt",""),v.className="iconFlag",m.appendChild(v),_=elCreate("span"),_.textContent=C.languageName,m.appendChild(_),w==r&&(p.innerHTML=b.firstChild.innerHTML)}if(h)b=elCreate("li"),b.className="dropdownDivider",g.appendChild(b),b=elCreate("li"),elData(b,"language-id",0),b.addEventListener(WCF_CLICK_EVENT,y),g.appendChild(b),m=elCreate("a"),m.textContent=i.get("wcf.global.language.noSelection"),b.appendChild(m),0===r&&(p.innerHTML=b.firstChild.innerHTML),b.addEventListener(WCF_CLICK_EVENT,y);else if(0===r){p.innerHTML=null;var E=elCreate("div");p.appendChild(E),_=elCreate("span"),_.className="icon icon24 fa-question pointer",E.appendChild(_),_=elCreate("span"),_.textContent=i.get("wcf.global.language.noSelection"),E.appendChild(_)}a.init(p),l.set(e,{callback:d,dropdownMenu:g,dropdownToggle:p,element:t});var L=n.parentByTag(t,"FORM");if(null!==L){L.addEventListener("submit",u);var A=c.get(L);void 0===A&&(A=[],c.set(L,A)),A.push(e)}},_select:function(t,i,n){var o=l.get(t);if(void 0===n){for(var r=o.dropdownMenu.childNodes,a=0,s=r.length;a<s;a++){var c=r[a];if(~~elData(c,"language-id")===i){n=c;break}}if(void 0===n)throw new Error("Cannot select unknown language id '"+i+"'")}o.element.value=i,e.triggerEvent(o.element,"change"),o.dropdownToggle.innerHTML=n.firstChild.innerHTML,l.set(t,o),"function"==typeof o.callback&&o.callback(n)},_submit:function(e){for(var t,i=c.get(e.currentTarget),n=0,o=i.length;n<o;n++)t=elCreate("input"),t.type="hidden",t.name=i[n],t.value=this.getLanguageId(i[n]),e.currentTarget.appendChild(t)},getChooser:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid language chooser input element, '"+e+"' is not i18n input field.");return t},getLanguageId:function(e){return~~this.getChooser(e).element.value},removeChooser:function(e){l.has(e)&&l.delete(e)},setLanguageId:function(e,t){if(void 0===l.get(e))throw new Error("Expected a valid  input element, '"+e+"' is not i18n input field.");this._select(e,t)}}}),define("WoltLabSuite/Core/Language/Input",["Core","Dictionary","Language","ObjectMap","StringUtil","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a,l){"use strict";var s=new t,c=!1,u=new n,d=new t,h=null,f=null;return{init:function(e,i,n,r){if(!d.has(e)){var a=elById(e);if(null===a)throw new Error("Expected a valid element id, cannot find '"+e+"'.");this._setup();var l=new t;for(var s in i)i.hasOwnProperty(s)&&l.set(~~s,o.unescapeHTML(i[s]));d.set(e,l),this._initElement(e,a,l,n,r)}},registerCallback:function(e,t,i){if(!d.has(e))throw new Error("Unknown element id '"+e+"'.");s.get(e).callbacks.set(t,i)},unregister:function(e){if(!d.has(e))throw new Error("Unknown element id '"+e+"'.");d.delete(e),s.delete(e)},_setup:function(){c||(c=!0,h=this._dropdownToggle.bind(this),f=this._submit.bind(this))},_initElement:function(e,n,o,c,d){var p=n.parentNode;if(!p.classList.contains("inputAddon")){p=elCreate("div"),p.className="inputAddon"+("TEXTAREA"===n.nodeName?" inputAddonTextarea":""),elData(p,"input-id",e);var g=document.activeElement===n;n.parentNode.insertBefore(p,n),p.appendChild(n),g&&n.focus()}p.classList.add("dropdown");var m=elCreate("span");m.className="button dropdownToggle inputPrefix";var v=elCreate("span");v.textContent=i.get("wcf.global.button.disabledI18n"),m.appendChild(v),p.insertBefore(m,n);var b=elCreate("ul");b.className="dropdownMenu",a.insertAfter(b,m);var _,y=function(t,i){var n=~~elData(t.currentTarget,"language-id"),o=r.childByClass(b,"active");null!==o&&o.classList.remove("active"),n&&t.currentTarget.classList.add("active"),this._select(e,n,i||!1)}.bind(this);for(var w in c)c.hasOwnProperty(w)&&(_=elCreate("li"),elData(_,"language-id",w),v=elCreate("span"),v.textContent=c[w],_.appendChild(v),_.addEventListener(WCF_CLICK_EVENT,y),b.appendChild(_));!0!==d&&(_=elCreate("li"),_.className="dropdownDivider",b.appendChild(_),_=elCreate("li"),elData(_,"language-id",0),v=elCreate("span"),v.textContent=i.get("wcf.global.button.disabledI18n"),_.appendChild(v),_.addEventListener(WCF_CLICK_EVENT,y),b.appendChild(_));var C=null;if(!0===d||o.size)for(var E=0,L=b.childElementCount;E<L;E++)if(~~elData(b.children[E],"language-id")===LANGUAGE_ID){C=b.children[E];break}l.init(m),l.registerCallback(p.id,h),s.set(e,{buttonLabel:m.children[0],callbacks:new t,element:n,languageId:0,isEnabled:!0,forceSelection:d});var A=r.parentByTag(n,"FORM");if(null!==A){A.addEventListener("submit",f);var S=u.get(A);void 0===S&&(S=[],u.set(A,S)),S.push(e)}null!==C&&y({currentTarget:C},!0)},_select:function(e,i,n){for(var o,r=s.get(e),a=l.getDropdownMenu(r.element.closest(".inputAddon").id),c="",u=0,h=a.childElementCount;u<h;u++){o=a.children[u];var f=elData(o,"language-id");f.length&&i===~~f&&(c=o.children[0].textContent)}if(r.languageId!==i){var p=d.get(e);r.languageId&&p.set(r.languageId,r.element.value),0===i?d.set(e,new t):(r.buttonLabel.classList.contains("active")||!0===n)&&(r.element.value=p.has(i)?p.get(i):""),r.buttonLabel.textContent=c,r.buttonLabel.classList[i?"add":"remove"]("active"),r.languageId=i}n||(r.element.blur(),r.element.focus()),r.callbacks.has("select")&&r.callbacks.get("select")(r.element)},_dropdownToggle:function(e,t){if("open"===t)for(var i,n,o=l.getDropdownMenu(e),r=elData(elById(e),"input-id"),a=s.get(r),c=d.get(r),u=0,h=o.childElementCount;u<h;u++)if(i=o.children[u],n=~~elData(i,"language-id")){var f=!1;a.languageId&&(f=n===a.languageId?""===a.element.value.trim():!c.get(n)),i.classList[f?"add":"remove"]("missingValue")}},_submit:function(e){for(var t,i,n,o,r=u.get(e.currentTarget),a=0,l=r.length;a<l;a++)i=r[a],t=s.get(i),t.isEnabled&&(o=d.get(i),t.callbacks.has("submit")&&t.callbacks.get("submit")(t.element),t.languageId&&o.set(t.languageId,t.element.value),o.size&&(o.forEach(function(t,o){n=elCreate("input"),n.type="hidden",n.name=i+"_i18n["+o+"]",n.value=t,e.currentTarget.appendChild(n)}),t.element.removeAttribute("name")))},getValues:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");var i=d.get(e);return i.set(t.languageId,t.element.value),i},setValues:function(i,n){var o=s.get(i);if(void 0===o)throw new Error("Expected a valid i18n input element, '"+i+"' is not i18n input field.");if(e.isPlainObject(n)&&(n=t.fromObject(n)),o.element.value="",n.has(0))return o.element.value=n.get(0),n.delete(0),d.set(i,n),void this._select(i,0,!0);d.set(i,n),o.languageId=0,this._select(i,LANGUAGE_ID,!0)},disable:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid element, '"+e+"' is not an i18n input field.");if(t.isEnabled){t.isEnabled=!1,elHide(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.remove("inputAddon"),i.classList.remove("dropdown")}},enable:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!t.isEnabled){t.isEnabled=!0,elShow(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.add("inputAddon"),i.classList.add("dropdown")}},isEnabled:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");return t.isEnabled},validate:function(e,t){var i=s.get(e);if(void 0===i)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!i.isEnabled)return!0;var n=d.get(e),o=l.getDropdownMenu(i.element.parentNode.id);i.languageId&&n.set(i.languageId,i.element.value);for(var r,a,c=!1,u=!1,h=0,f=o.childElementCount;h<f;h++)if(r=o.children[h],a=~~elData(r,"language-id"))if(n.has(a)&&0!==n.get(a).length){if(c)return!1;u=!0}else{if(u)return!1;c=!0}return!c||t}}}),define("WoltLabSuite/Core/Language/Text",["Core","./Input"],function(e,t){"use strict";return{init:function(e,i,n,o){var r=elById(e);if(!r||"TEXTAREA"!==r.nodeName||!r.classList.contains("wysiwygTextarea"))throw new Error('Expected <textarea class="wysiwygTextarea" /> for id \''+e+"'.");t.init(e,i,n,o),t.registerCallback(e,"select",this._callbackSelect.bind(this)),t.registerCallback(e,"submit",this._callbackSubmit.bind(this))},_callbackSelect:function(e){void 0!==window.jQuery&&window.jQuery(e).redactor("code.set",e.value)},_callbackSubmit:function(e){void 0!==window.jQuery&&(e.value=window.jQuery(e).redactor("code.get"))}}}),define("WoltLabSuite/Core/Media/Editor",["Ajax","Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Language/Chooser","WoltLabSuite/Core/Language/Input","EventKey"],function(e,t,i,n,o,r,a,l,s,c,u){"use strict";var d=function(){};return d.prototype={_ajaxSetup:function(){},_ajaxSuccess:function(){},_close:function(){},_keyPress:function(){},_saveData:function(){},_updateLanguageFields:function(){},edit:function(){}},d}),define("WoltLabSuite/Core/Media/Upload",["Core","DateUtil","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","Permission","Upload","User","WoltLabSuite/Core/FileUtil"],function(e,t,i,n,o,r,a,l,s,c,u){"use strict";var d=function(){};return d.prototype={_createFileElement:function(){},_getParameters:function(){},_success:function(){},_uploadFiles:function(){},_createButton:function(){},_createFileElements:function(){},_failure:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){},_upload:function(){}},d}),define("WoltLabSuite/Core/Media/List/Upload",["Core","Dom/Util","../Upload"],function(e,t,i){"use strict";var n=function(){};return n.prototype={_createButton:function(){},_success:function(){},_upload:function(){},_createFileElement:function(){},_getParameters:function(){},_uploadFiles:function(){},_createFileElements:function(){},_failure:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){}},n}),define("WoltLabSuite/Core/Media/Clipboard",["Ajax","Dom/ChangeListener","EventHandler","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=function(){};return c.prototype={init:function(){},_ajaxSetup:function(){},_ajaxSuccess:function(){},_clipboardAction:function(){},_dialogSetup:function(){},_edit:function(){},_setCategory:function(){}},c}),define("WoltLabSuite/Core/Notification/Handler",["Ajax","Core","EventHandler","StringUtil"],function(e,t,i,n){"use strict";if(!("Promise"in window&&"Notification"in window))return{setup:function(){}};var o=!1,r="",a=0,l=window.TIME_NOW,s=null,c=0;return{setup:function(e){if(e=t.extend({enableNotifications:!1,icon:"",sessionKeepAlive:0},e),r=e.icon,c=60*e.sessionKeepAlive,this._prepareNextRequest(),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this)),window.addEventListener("storage",this._onStorage.bind(this)),this._onVisibilityChange(null),e.enableNotifications)switch(window.Notification.permission){case"granted":o=!0;break;case"default":window.Notification.requestPermission(function(e){"granted"===e&&(o=!0)})}},_onVisibilityChange:function(e){if(null!==e&&!document.hidden){(Date.now()-a)/6e4>4&&(this._resetTimer(),this._dispatchRequest())}
-a=document.hidden?Date.now():0},_getNextDelay:function(){if(0===a)return 5;var e=~~((Date.now()-a)/6e4);return e<15?5:e<30?10:15},_resetTimer:function(){null!==s&&(window.clearTimeout(s),s=null)},_prepareNextRequest:function(){this._resetTimer();var e=Math.min(this._getNextDelay(),c);s=window.setTimeout(this._dispatchRequest.bind(this),6e4*e)},_dispatchRequest:function(){var t={};i.fire("com.woltlab.wcf.notification","beforePoll",t),t.lastRequestTimestamp=l,e.api(this,{parameters:t})},_onStorage:function(){this._prepareNextRequest();var e,n,o=!1;try{e=window.localStorage.getItem(t.getStoragePrefix()+"notification"),n=window.localStorage.getItem(t.getStoragePrefix()+"keepAliveData"),e=JSON.parse(e),n=JSON.parse(n)}catch(e){o=!0}o||i.fire("com.woltlab.wcf.notification","onStorage",{pollData:e,keepAliveData:n})},_ajaxSuccess:function(e){var n=!1,o=e.returnValues.keepAliveData,r=e.returnValues.pollData;window.WCF.System.PushNotification.executeCallbacks({returnValues:o});try{window.localStorage.setItem(t.getStoragePrefix()+"notification",JSON.stringify(r)),window.localStorage.setItem(t.getStoragePrefix()+"keepAliveData",JSON.stringify(o))}catch(e){n=!0,window.console.log(e)}n||this._prepareNextRequest(),l=e.returnValues.lastRequestTimestamp,i.fire("com.woltlab.wcf.notification","afterPoll",r),this._showNotification(r)},_showNotification:function(e){if(o&&"object"==typeof e.notification&&"string"==typeof e.notification.message){var t=new window.Notification(e.notification.title,{body:n.unescapeHTML(e.notification.message),icon:r});t.onclick=function(){window.focus(),t.close(),window.location=e.notification.link}}},_ajaxSetup:function(){return{data:{actionName:"poll",className:"wcf\\data\\session\\SessionAction"},ignoreError:!window.ENABLE_DEBUG_MODE,silent:!window.ENABLE_DEBUG_MODE}}}}),define("WoltLabSuite/Core/Ui/Redactor/DragAndDrop",["Dictionary","EventHandler","Language"],function(e,t,i){"use strict";var n=function(){};return n.prototype={init:function(){},_dragOver:function(){},_drop:function(){},_dragLeave:function(){},_setup:function(){}},n}),define("WoltLabSuite/Core/Ui/DragAndDrop",["Core","EventHandler","WoltLabSuite/Core/Ui/Redactor/DragAndDrop"],function(e,t,i){return{register:function(n){var o=e.getUuid();n=e.extend({element:"",elementId:"",onDrop:function(e){},onGlobalDrop:function(e){}}),t.add("com.woltlab.wcf.redactor2","dragAndDrop_"+n.elementId,n.onDrop),t.add("com.woltlab.wcf.redactor2","dragAndDrop_globalDrop_"+n.elementId,n.onGlobalDrop),i.init({uuid:o,$editor:[n.element],$element:[{id:n.elementId}]})}}}),define("WoltLabSuite/Core/Ui/Suggestion",["Ajax","Core","Ui/SimpleDropdown"],function(e,t,i){"use strict";function n(e,t){this.init(e,t)}return n.prototype={init:function(e,i){if(this._dropdownMenu=null,this._value="",this._element=elById(e),null===this._element)throw new Error("Expected a valid element id.");if(this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction",parameters:{data:{}}},callbackSelect:null,excludedSearchValues:[],threshold:3},i),"function"!=typeof this._options.callbackSelect)throw new Error("Expected a valid callback for option 'callbackSelect'.");this._element.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),this._element.addEventListener("keydown",this._keyDown.bind(this)),this._element.addEventListener("keyup",this._keyUp.bind(this))},addExcludedValue:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedValue:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},isActive:function(){return null!==this._dropdownMenu&&i.isOpen(this._element.id)},_keyDown:function(e){if(!this.isActive())return!0;if(13!==e.keyCode&&27!==e.keyCode&&38!==e.keyCode&&40!==e.keyCode)return!0;for(var t,n=0,o=this._dropdownMenu.childElementCount;n<o&&(t=this._dropdownMenu.children[n],!t.classList.contains("active"));)n++;if(13===e.keyCode)i.close(this._element.id),this._select(t);else if(27===e.keyCode){if(!i.isOpen(this._element.id))return!0;i.close(this._element.id)}else{var r=0;38===e.keyCode?r=(0===n?o:n)-1:40===e.keyCode&&(r=n+1)===o&&(r=0),r!==n&&(t.classList.remove("active"),this._dropdownMenu.children[r].classList.add("active"))}return e.preventDefault(),!1},_select:function(e){var t=e instanceof Event;t&&(e=e.currentTarget.parentNode);var i=e.children[0];this._options.callbackSelect(this._element.id,{objectId:elData(i,"object-id"),value:e.textContent,type:elData(i,"type")}),t&&this._element.focus()},_keyUp:function(t){var n=t.currentTarget.value.trim();if(this._value!==n){if(n.length<this._options.threshold)return null!==this._dropdownMenu&&i.close(this._element.id),void(this._value=n);this._value=n,e.api(this,{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:n}}})}},_ajaxSetup:function(){return{data:this._options.ajax}},_ajaxSuccess:function(e){if(null===this._dropdownMenu?(this._dropdownMenu=elCreate("div"),this._dropdownMenu.className="dropdownMenu",i.initFragment(this._element,this._dropdownMenu)):this._dropdownMenu.innerHTML="",e.returnValues.length){for(var t,n,o,r=0,a=e.returnValues.length;r<a;r++)n=e.returnValues[r],t=elCreate("a"),n.icon?(t.className="box16",t.innerHTML=n.icon+" <span></span>",t.children[1].textContent=n.label):t.textContent=n.label,elData(t,"object-id",n.objectID),n.type&&elData(t,"type",n.type),t.addEventListener(WCF_CLICK_EVENT,this._select.bind(this)),o=elCreate("li"),0===r&&(o.className="active"),o.appendChild(t),this._dropdownMenu.appendChild(o);i.open(this._element.id,!0)}else i.close(this._element.id)}},n}),define("WoltLabSuite/Core/Ui/ItemList",["Core","Dictionary","Language","Dom/Traverse","EventKey","WoltLabSuite/Core/Ui/Suggestion","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l="",s=new t,c=!1,u=null,d=null,h=null,f=null,p=null,g=null;return{init:function(t,i,o){var l=elById(t);if(null===l)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(s.has(t)){var c=s.get(t);for(var u in c)if(c.hasOwnProperty(u)){var d=c[u];d instanceof Element&&d.parentNode&&elRemove(d)}a.destroy(t),s.delete(t)}o=e.extend({ajax:{actionName:"getSearchResultList",className:"",data:{}},excludedSearchValues:[],maxItems:-1,maxLength:-1,restricted:!1,isCSV:!1,callbackChange:null,callbackSubmit:null,callbackSyncShadow:null,callbackSetupValues:null,submitFieldName:""},o);var h=n.parentByTag(l,"FORM");if(null!==h)if(!1===o.isCSV){if(!o.submitFieldName.length&&"function"!=typeof o.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=s.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}var i=this.getValues(t);if(o.submitFieldName.length)for(var n,r=0,a=i.length;r<a;r++)n=elCreate("input"),n.type="hidden",n.name=o.submitFieldName.replace("{$objectId}",i[r].objectId),n.value=i[r].value,h.appendChild(n);else o.callbackSubmit(h,i)}.bind(this))}else h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=s.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}}.bind(this));this._setup();var f=this._createUI(l,o),p=new r(t,{ajax:o.ajax,callbackSelect:this._addItem.bind(this),excludedSearchValues:o.excludedSearchValues});if(s.set(t,{dropdownMenu:null,element:f.element,list:f.list,listItem:f.element.parentNode,options:o,shadow:f.shadow,suggestion:p}),i=o.callbackSetupValues?o.callbackSetupValues():f.values.length?f.values:i,Array.isArray(i))for(var g,m=0,v=i.length;m<v;m++)g=i[m],"string"==typeof g&&(g={objectId:0,value:g}),this._addItem(t,g)},getValues:function(e){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=s.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent.trim(),type:elData(e,"type")})}),i},setValues:function(e,t){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,o,r=s.get(e),a=n.childrenByClass(r.list,"item");for(i=0,o=a.length;i<o;i++)this._removeItem(null,a[i],!0);for(i=0,o=t.length;i<o;i++)this._addItem(e,t[i])},_setup:function(){c||(c=!0,u=this._keyDown.bind(this),d=this._keyPress.bind(this),h=this._keyUp.bind(this),f=this._paste.bind(this),p=this._removeItem.bind(this),g=this._blur.bind(this))},_createUI:function(e,t){var i=elCreate("ol");i.className="inputItemList"+(e.disabled?" disabled":""),elData(i,"element-id",e.id),i.addEventListener(WCF_CLICK_EVENT,function(t){t.target===i&&e.focus()});var n=elCreate("li");n.className="input",i.appendChild(n),e.addEventListener("keydown",u),e.addEventListener("keypress",d),e.addEventListener("keyup",h),e.addEventListener("paste",f);var o=e===document.activeElement;o&&e.blur(),e.addEventListener("blur",g),e.parentNode.insertBefore(i,e),n.appendChild(e),o&&window.setTimeout(function(){e.focus()},1),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var r=null,a=[];if(t.isCSV){r=elCreate("input"),r.className="itemListInputShadow",r.type="hidden",r.name=e.name,e.removeAttribute("name"),i.parentNode.insertBefore(r,i);for(var l,s=e.value.split(","),c=0,p=s.length;c<p;c++)l=s[c].trim(),l.length&&a.push(l);if("TEXTAREA"===e.nodeName){var m=elCreate("input");m.type="text",e.parentNode.insertBefore(m,e),m.id=e.id,elRemove(e),e=m}}return{element:e,list:i,shadow:r,values:a}},_acceptsNewItems:function(e){var t=s.get(e);return-1===t.options.maxItems||t.list.childElementCount-1<t.options.maxItems},_handleLimit:function(e){var t=s.get(e);this._acceptsNewItems(e)?t.element.disabled&&(t.element.disabled=!1,t.element.removeAttribute("placeholder")):t.element.disabled||(t.element.disabled=!0,elAttr(t.element,"placeholder",i.get("wcf.global.form.input.maxItems")))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;l=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(o.Enter(e)||o.Comma(e)){if(e.preventDefault(),s.get(e.currentTarget.id).options.restricted)return;var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain");var i=e.currentTarget,n=i.id,o=~~elAttr(i,"maxLength");t.split(/,/).forEach(function(e){e=e.trim(),o&&e.length>o&&(e=e.substr(0,o)),e.length>0&&this._acceptsNewItems(n)&&this._addItem(n,{objectId:0,value:e})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t){var i=s.get(e),n=elCreate("li");n.className="item";var o=elCreate("span");if(o.className="content",elData(o,"object-id",t.objectId),t.type&&elData(o,"type",t.type),o.textContent=t.value,n.appendChild(o),!i.element.disabled){var r=elCreate("a");r.className="icon icon16 fa-times",r.addEventListener(WCF_CLICK_EVENT,p),n.appendChild(r)}i.list.insertBefore(n,i.listItem),i.suggestion.addExcludedValue(t.value),i.element.value="",i.element.disabled||this._handleLimit(e);var a=this._syncShadow(i);"function"==typeof i.options.callbackChange&&(null===a&&(a=this.getValues(e)),i.options.callbackChange(e,a))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,o=elData(n,"element-id"),r=s.get(o);r.suggestion.removeExcludedValue(t.children[0].textContent),n.removeChild(t),i||r.element.focus(),this._handleLimit(o);var a=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===a&&(a=this.getValues(o)),r.options.callbackChange(o,a))},_syncShadow:function(e){if(!e.options.isCSV)return null;if("function"==typeof e.options.callbackSyncShadow)return e.options.callbackSyncShadow(e);for(var t="",i=this.getValues(e.element.id),n=0,o=i.length;n<o;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=e.currentTarget,i=s.get(t.id);if(!i.options.restricted){var n=t.value.trim();n.length&&(i.suggestion&&i.suggestion.isActive()||this._addItem(t.id,{objectId:0,value:n}))}}}}),define("WoltLabSuite/Core/Ui/Page/JumpTo",["Language","ObjectMap","Ui/Dialog"],function(e,t,i){"use strict";var n=null,o=null,r=null,a=new t,l=null;return{init:function(e,t){if(null===(t=t||null)){var i=elData(e,"link");t=i?function(e){window.location=i.replace(/pageNo=%d/,"pageNo="+e)}:function(){}}else if("function"!=typeof t)throw new TypeError("Expected a valid function for parameter 'callback'.");a.has(e)||elBySelAll(".jumpTo",e,function(i){i.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,e)),a.set(e,{callback:t})}.bind(this))},_click:function(t,o){n=t,"object"==typeof o&&o.preventDefault(),i.open(this);var a=elData(t,"pages");l.value=a,l.setAttribute("max",a),l.select(),r.textContent=e.get("wcf.page.jumpTo.description").replace(/#pages#/,a)},_keyUp:function(e){if(13===e.which&&!1===o.disabled)return void this._submit();var t=~~l.value;t<1||t>~~elAttr(l,"max")?o.disabled=!0:o.disabled=!1},_submit:function(e){a.get(n).callback(~~l.value),i.close(this)},_dialogSetup:function(){var t='<dl><dt><label for="jsPaginationPageNo">'+e.get("wcf.page.jumpTo")+'</label></dt><dd><input type="number" id="jsPaginationPageNo" value="1" min="1" max="1" class="tiny"><small></small></dd></dl><div class="formSubmit"><button class="buttonPrimary">'+e.get("wcf.global.button.submit")+"</button></div>";return{id:"paginationOverlay",options:{onSetup:function(e){l=elByTag("input",e)[0],l.addEventListener("keyup",this._keyUp.bind(this)),r=elByTag("small",e)[0],o=elByTag("button",e)[0],o.addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))}.bind(this),title:e.get("wcf.global.page.pagination")},source:t}}}}),define("WoltLabSuite/Core/Ui/Pagination",["Core","Language","ObjectMap","StringUtil","WoltLabSuite/Core/Ui/Page/JumpTo"],function(e,t,i,n,o){"use strict";function r(e,t){this.init(e,t)}return r.prototype={SHOW_LINKS:11,init:function(t,i){this._element=t,this._options=e.extend({activePage:1,maxPage:1,callbackShouldSwitch:null,callbackSwitch:null},i),"function"!=typeof this._options.callbackShouldSwitch&&(this._options.callbackShouldSwitch=null),"function"!=typeof this._options.callbackSwitch&&(this._options.callbackSwitch=null),this._element.classList.add("pagination"),this._rebuild(this._element)},_rebuild:function(){var e=!1;this._element.innerHTML="";var i,n=elCreate("ul"),r=elCreate("li");r.className="skip",n.appendChild(r);var a="icon icon24 fa-chevron-left";this._options.activePage>1?(i=elCreate("a"),i.className=a+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.previous"),i.rel="prev",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage-1))):(r.innerHTML='<span class="'+a+'"></span>',r.classList.add("disabled")),n.appendChild(this._createLink(1));var l=this.SHOW_LINKS-4,s=this._options.activePage-2;s<0&&(s=0);var c=this._options.maxPage-(this._options.activePage+1);c<0&&(c=0),this._options.activePage>1&&this._options.activePage<this._options.maxPage&&l--;var u=l/2,d=this._options.activePage,h=this._options.activePage;d<1&&(d=1),h<1&&(h=1),h>this._options.maxPage-1&&(h=this._options.maxPage-1),s>=u?d-=u:(d-=s,h+=u-s),c>=u?h+=u:(h+=c,d-=u-c),h=Math.ceil(h),d=Math.ceil(d),d<1&&(d=1),h>this._options.maxPage&&(h=this._options.maxPage);var f='<a class="jsTooltip" title="'+t.get("wcf.page.jumpTo")+'">&hellip;</a>';d>1&&(d-1<2?n.appendChild(this._createLink(2)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=f,n.appendChild(r),e=!0));for(var p=d+1;p<h;p++)n.appendChild(this._createLink(p));h<this._options.maxPage&&(this._options.maxPage-h<2?n.appendChild(this._createLink(this._options.maxPage-1)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=f,n.appendChild(r),e=!0)),n.appendChild(this._createLink(this._options.maxPage)),r=elCreate("li"),r.className="skip",n.appendChild(r),a="icon icon24 fa-chevron-right",this._options.activePage<this._options.maxPage?(i=elCreate("a"),i.className=a+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.next"),i.rel="next",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage+1))):(r.innerHTML='<span class="'+a+'"></span>',r.classList.add("disabled")),e&&(elData(n,"pages",this._options.maxPage),o.init(n,this.switchPage.bind(this))),this._element.appendChild(n)},_createLink:function(e){var i=elCreate("li");if(e!==this._options.activePage){var o=elCreate("a");o.textContent=n.addThousandsSeparator(e),o.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,e)),i.appendChild(o)}else i.classList.add("active"),i.innerHTML="<span>"+n.addThousandsSeparator(e)+'</span><span class="invisible">'+t.get("wcf.page.pagePosition",{pageNo:e,pages:this._options.maxPage})+"</span>";return i},getActivePage:function(){return this._options.activePage},getElement:function(){return this._element},getMaxPage:function(){return this._options.maxPage},switchPage:function(t,i){if("object"==typeof i&&(i.preventDefault(),i.currentTarget&&elData(i.currentTarget,"tooltip"))){var n=elById("balloonTooltip");n&&(e.triggerEvent(i.currentTarget,"mouseleave"),n.style.removeProperty("top"),n.style.removeProperty("bottom"))}if((t=~~t)>0&&this._options.activePage!==t&&t<=this._options.maxPage){if(null!==this._options.callbackShouldSwitch&&!0!==this._options.callbackShouldSwitch(t))return;this._options.activePage=t,this._rebuild(),null!==this._options.callbackSwitch&&this._options.callbackSwitch(t)}}},r}),define("WoltLabSuite/Core/Controller/Media/List",["Dom/ChangeListener","EventHandler","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},_addButtonEventListeners:function(){},_deleteCallback:function(){},_deleteMedia:function(e){},_edit:function(){}},a}),define("WoltLabSuite/Core/Controller/Notice/Dismiss",["Ajax"],function(e){"use strict";return{setup:function(){var e=elByClass("jsDismissNoticeButton");if(e.length)for(var t=this._click.bind(this),i=0,n=e.length;i<n;i++)e[i].addEventListener(WCF_CLICK_EVENT,t)},_click:function(t){var i=t.currentTarget;e.apiOnce({data:{actionName:"dismiss",className:"wcf\\data\\notice\\NoticeAction",objectIDs:[elData(i,"object-id")]},success:function(){elRemove(i.parentNode)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager",["Dictionary","Dom/ChangeListener","EventHandler","List","Dom/Util","ObjectMap"],function(e,t,i,n,o,r){"use strict";var a=!1,l=!0,s=new n,c=new e,u=new n,d=new e,h=new r;return{_hide:function(t){elHide(t),s.add(t),t.classList.contains("tabMenuContent")&&elBySelAll("li",t.parentNode.querySelector(".tabMenu"),function(e){elData(e,"name")===elData(t,"name")&&elHide(e)}),elBySelAll("[max], [maxlength], [min], [required]",t,function(t){var i=new e,n=elAttr(t,"max");n&&(i.set("max",n),t.removeAttribute("max"));var o=elAttr(t,"maxlength");o&&(i.set("maxlength",o),t.removeAttribute("maxlength"));var r=elAttr(t,"min");r&&(i.set("min",r),t.removeAttribute("min")),t.required&&(i.set("required",!0),t.removeAttribute("required")),h.set(t,i)})},_show:function(e){elShow(e),s.delete(e),e.classList.contains("tabMenuContent")&&elBySelAll("li",e.parentNode.querySelector(".tabMenu"),function(t){elData(t,"name")===elData(e,"name")&&elShow(t)}),elBySelAll("input, select",e,function(t){for(var i=t.parentNode;i!==e&&"none"!==i.style.getPropertyValue("display");)i=i.parentNode;if(i===e&&h.has(t)){var n=h.get(t);n.has("max")&&elAttr(t,"max",n.get("max")),n.has("maxlength")&&elAttr(t,"maxlength",n.get("maxlength")),n.has("min")&&elAttr(t,"min",n.get("min")),n.has("required")&&elAttr(t,"required",""),h.delete(t)}})},addDependency:function(e){var t=e.getDependentNode();d.has(t.id)?d.get(t.id).push(e):d.set(t.id,[e]);for(var i=e.getFields(),n=0,r=i.length;n<r;n++){var a=i[n],l=o.identify(a);c.has(l)||(c.set(l,a),"INPUT"!==a.tagName||"checkbox"!==a.type&&"radio"!==a.type&&"hidden"!==a.type?a.addEventListener("input",this.checkDependencies.bind(this)):a.addEventListener("change",this.checkDependencies.bind(this)))}},checkDependencies:function(){var e=[];d.forEach(function(t,i){var n=elById(i);if(null===n)return void e.push(i);for(var o=0,r=t.length;o<r;o++)if(!t[o].checkDependency())return void this._hide(n);this._show(n)}.bind(this));for(var t=0,i=e.length;t<i;t++)d.delete(e[t]);this.checkContainers()},addContainerCheckCallback:function(e){if("function"!=typeof e)throw new TypeError("Expected a valid callback for parameter 'callback'.");i.add("com.woltlab.wcf.form.builder.dependency","checkContainers",e)},checkContainers:function(){if(!0===a)return void(l=!0);a=!0,l=!1,i.fire("com.woltlab.wcf.form.builder.dependency","checkContainers"),a=!1,l&&this.checkContainers()},isHiddenByDependencies:function(e){if(s.has(e))return!0;var t=!1;return s.forEach(function(i){o.contains(i,e)&&(t=!0)}),t},register:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(u.has(t))throw new Error("Form with id '"+e+"' has already been registered.");u.add(t)},unregister:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(!u.has(t))throw new Error("Form with id '"+e+"' has not been registered.");u.delete(t),s.forEach(function(e){t.contains(e)&&s.delete(e)}),d.forEach(function(e,i){t.contains(elById(i))&&d.delete(i);for(var n=0,o=e.length;n<o;n++)for(var r=e[n].getFields(),a=0,l=r.length;a<l;a++){var s=r[a];c.delete(s.id),h.delete(s)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Field",[],function(){"use strict";function e(e){this.init(e)}return e.prototype={init:function(e){this._fieldId=e,this._readField()},_getData:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Field._getData!")},_readField:function(){if(this._field=elById(this._fieldId),null===this._field)throw new Error("Unknown field with id '"+this._fieldId+"'.")},destroy:function(){},getData:function(){return Promise.resolve(this._getData())},getId:function(){return this._fieldId}},e}),define("WoltLabSuite/Core/Form/Builder/Manager",["Core","Dictionary","EventHandler","./Field/Dependency/Manager","./Field/Field"],function(e,t,i,n,o){"use strict";var r=new t,a=new t;return{getData:function(t){if(!this.hasForm(t))throw new Error("Unknown form with id '"+t+"'.");var i=[];return r.get(t).forEach(function(e){var t=e.getData();if(!(t instanceof Promise))throw new TypeError("Data for field with id '"+e.getId()+"' is no promise.");i.push(t)}),Promise.all(i).then(function(t){for(var i={},n=0,o=t.length;n<o;n++)i=e.extend(i,t[n]);return i})},getField:function(e,t){if(!this.hasField(e,t))throw new Error("Unknown field with id '"+e+"' for form with id '"+t+"'.");return r.get(e).get(t)},getForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return a.get(e)},hasField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return r.get(e).has(t)},hasForm:function(e){return a.has(e)},registerField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");if(!(t instanceof o))throw new Error("Add field is no instance of 'WoltLabSuite/Core/Form/Builder/Field/Field'.");var n=t.getId();if(this.hasField(e,n))throw new Error("Form field with id '"+n+"' has already been registered for form with id '"+e+"'.");r.get(e).set(n,t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerField",{field:t,formId:e})},registerForm:function(e){if(this.hasForm(e))throw new Error("Form with id '"+e+"' has already been registered.");var n=elById(e);if(null===n)throw new Error("Unknown form with id '"+e+"'.");a.set(e,n),r.set(e,new t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerForm",{formId:e})},unregisterForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");i.fire("WoltLabSuite/Core/Form/Builder/Manager","beforeUnregisterForm",{formId:e}),a.delete(e),r.get(e).forEach(function(e){e.destroy()}),r.delete(e),n.unregister(e),i.fire("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",{formId:e})}}}),define("WoltLabSuite/Core/Form/Builder/Dialog",["Ajax","Core","./Manager","Ui/Dialog"],function(e,t,i,n){"use strict";function o(e,t,i,n){this.init(e,t,i,n)}return o.prototype={init:function(e,i,n,o){this._dialogId=e,this._className=i,this._actionName=n,this._options=t.extend({actionParameters:{},destroyOnClose:!1,usesDboAction:this._className.match(/\w+\\data\\/)},o),this._options.dialog=t.extend(this._options.dialog||{},{onClose:this._dialogOnClose.bind(this)}),this._formId="",this._dialogContent=""},_ajaxSetup:function(){var e={data:{actionName:this._actionName,className:this._className,parameters:this._options.actionParameters}};return this._options.usesDboAction||(e.url="index.php?ajax-invoke/&t="+SECURITY_TOKEN,e.withCredentials=!0),e},_ajaxSuccess:function(e){switch(e.actionName){case this._actionName:if(void 0===e.returnValues)throw new Error("Missing return data.");if(void 0===e.returnValues.dialog)throw new Error("Missing dialog template in return data.");if(void 0===e.returnValues.formId)throw new Error("Missing form id in return data.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog);break;case this._options.submitActionName:if(e.returnValues&&e.returnValues.formId&&e.returnValues.dialog){if(e.returnValues.formId!==this._formId)throw new Error("Mismatch between form ids: expected '"+this._formId+"' but got '"+e.returnValues.formId+"'.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog)}else this.destroy(),"function"==typeof this._options.successCallback&&this._options.successCallback(e.returnValues||{});break;default:throw new Error("Cannot handle action '"+e.actionName+"'.")}},_closeDialog:function(){n.close(this),"function"==typeof this._options.closeCallback&&this._options.closeCallback()},_dialogOnClose:function(){this._options.destroyOnClose&&this.destroy()},_dialogSetup:function(){return{id:this._dialogId,options:this._options.dialog,source:this._dialogContent}},_dialogSubmit:function(){this.getData().then(this._submitForm.bind(this))},_openDialogContent:function(e,t){this.destroy(!0),this._formId=e,this._dialogContent=t;var i=n.open(this,this._dialogContent),o=elBySel("button[data-type=cancel]",i.content);null===o||elDataBool(o,"has-event-listener")||(o.addEventListener("click",this._closeDialog.bind(this)),elData(o,"has-event-listener",1))},_submitForm:function(t){var i=elBySel("button[data-type=submit]",n.getDialog(this).content);"function"==typeof this._options.onSubmit?this._options.onSubmit(t,i):"string"==typeof this._options.submitActionName&&(i.disabled=!0,e.api(this,{actionName:this._options.submitActionName,parameters:{data:t,formId:this._formId}}))},destroy:function(e){""!==this._formId&&(i.hasForm(this._formId)&&i.unregisterForm(this._formId),!0!==e&&n.destroy(this))},getData:function(){if(""===this._formId)throw new Error("Form has not been requested yet.");return i.getData(this._formId)},open:function(){n.getDialog(this._dialogId)?n.openStatic(this._dialogId):e.api(this)}},o}),define("WoltLabSuite/Core/Media/Manager/Search",["Ajax","Core","Dom/Traverse","Dom/Util","EventKey","Language","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={_ajaxSetup:function(){},_ajaxSuccess:function(){},_cancelSearch:function(){},_keyPress:function(){},_search:function(){},hideSearch:function(){},resetSearch:function(){},showSearch:function(){}},l}),define("WoltLabSuite/Core/Media/Manager/Base",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","List","Permission","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/Upload","WoltLabSuite/Core/Media/Manager/Search","StringUtil","WoltLabSuite/Core/Ui/Pagination","WoltLabSuite/Core/Media/Clipboard"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f,p,g,m,v){"use strict";var b=function(){};return b.prototype={_addButtonEventListeners:function(){},_click:function(){},_dialogClose:function(){},_dialogInit:function(){},_dialogSetup:function(){},_dialogShow:function(){},_editMedia:function(){},_editorClose:function(){},_editorSuccess:function(){},_removeClipboardCheckboxes:function(){},_setMedia:function(){},addMedia:function(){},clipboardDeleteMedia:function(){},getDialog:function(){},getMode:function(){},getOption:function(){},removeMedia:function(){},resetMedia:function(){},setMedia:function(){},setupMediaElement:function(){}},b}),define("WoltLabSuite/Core/Media/Manager/Editor",["Core","Dictionary","Dom/Traverse","EventHandler","Language","Permission","Ui/Dialog","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=function(){};return c.prototype={_addButtonEventListeners:function(){},_buildInsertDialog:function(){},_click:function(){},_getInsertDialogId:function(){},_getThumbnailSizes:function(){},_insertMedia:function(){},_insertMediaGallery:function(){},_insertMediaItem:function(){},_openInsertDialog:function(){},insertMedia:function(){},getMode:function(){},setupMediaElement:function(){},_dialogClose:function(){},_dialogInit:function(){},_dialogSetup:function(){},_dialogShow:function(){},_editMedia:function(){},_editorClose:function(){},_editorSuccess:function(){},_removeClipboardCheckboxes:function(){},_setMedia:function(){},addMedia:function(){},clipboardInsertMedia:function(){},getDialog:function(){},getOption:function(){},removeMedia:function(){},resetMedia:function(){},setMedia:function(){}},c}),define("WoltLabSuite/Core/Media/Manager/Select",["Core","Dom/Traverse","Dom/Util","Language","ObjectMap","Ui/Dialog","WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,o,r,a,l){"use strict";var s=function(){};return s.prototype={_addButtonEventListeners:function(){},_chooseMedia:function(){},_click:function(){},getMode:function(){},setupMediaElement:function(){},_removeMedia:function(){},_clipboardAction:function(){},_dialogClose:function(){},_dialogInit:function(){},_dialogSetup:function(){},_dialogShow:function(){},_editMedia:function(){},_editorClose:function(){},_editorSuccess:function(){},_removeClipboardCheckboxes:function(){},_setMedia:function(){},addMedia:function(){},getDialog:function(){},getOption:function(){},removeMedia:function(){},resetMedia:function(){},setMedia:function(){}},s}),define("WoltLabSuite/Core/Ui/Search/Input",["Ajax","Core","EventKey","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o){"use strict";function r(e,t){this.init(e,t)}return r.prototype={init:function(e,i){if(this._element=e,!(this._element instanceof Element))throw new TypeError("Expected a valid DOM element.");if("INPUT"!==this._element.nodeName||"search"!==this._element.type&&"text"!==this._element.type)throw new Error('Expected an input[type="text"].');this._activeItem=null,this._dropdownContainerId="",this._lastValue="",this._list=null,this._request=null,this._timerDelay=null,this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction"},callbackDropdownInit:null,callbackSelect:null,delay:500,excludedSearchValues:[],minLength:3,noResultPlaceholder:"",preventSubmit:!1},i),elAttr(this._element,"autocomplete","off"),this._element.addEventListener("keydown",this._keydown.bind(this)),this._element.addEventListener("keyup",this._keyup.bind(this))},
-addExcludedSearchValues:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedSearchValues:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},_keydown:function(e){(null!==this._activeItem&&o.isOpen(this._dropdownContainerId)||this._options.preventSubmit)&&i.Enter(e)&&e.preventDefault(),(i.ArrowUp(e)||i.ArrowDown(e)||i.Escape(e))&&e.preventDefault()},_keyup:function(e){if(null!==this._activeItem)if(o.isOpen(this._dropdownContainerId)){if(i.ArrowUp(e))return e.preventDefault(),this._keyboardPreviousItem();if(i.ArrowDown(e))return e.preventDefault(),this._keyboardNextItem();if(i.Enter(e))return e.preventDefault(),this._keyboardSelectItem()}else this._activeItem=null;if(i.Escape(e))return void o.close(this._dropdownContainerId);var t=this._element.value.trim();if(this._lastValue!==t){if(this._lastValue=t,t.length<this._options.minLength)return void(this._dropdownContainerId&&(o.close(this._dropdownContainerId),this._activeItem=null));this._options.delay?(null!==this._timerDelay&&window.clearTimeout(this._timerDelay),this._timerDelay=window.setTimeout(function(){this._search(t)}.bind(this),this._options.delay)):this._search(t)}},_search:function(t){this._request&&this._request.abortPrevious(),this._request=e.api(this,this._getParameters(t))},_getParameters:function(e){return{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:e}}}},_keyboardNextItem:function(){this._activeItem.classList.remove("active"),this._activeItem.nextElementSibling?this._activeItem=this._activeItem.nextElementSibling:this._activeItem=this._list.children[0],this._activeItem.classList.add("active")},_keyboardPreviousItem:function(){this._activeItem.classList.remove("active"),this._activeItem.previousElementSibling?this._activeItem=this._activeItem.previousElementSibling:this._activeItem=this._list.children[this._list.childElementCount-1],this._activeItem.classList.add("active")},_keyboardSelectItem:function(){this._selectItem(this._activeItem)},_clickSelectItem:function(e){this._selectItem(e.currentTarget)},_selectItem:function(e){this._options.callbackSelect&&!1===this._options.callbackSelect(e)?this._element.value="":this._element.value=elData(e,"label"),this._activeItem=null,o.close(this._dropdownContainerId)},_ajaxSuccess:function(e){var t=!1;if(null===this._list?(this._list=elCreate("ul"),this._list.className="dropdownMenu",t=!0,"function"==typeof this._options.callbackDropdownInit&&this._options.callbackDropdownInit(this._list)):this._list.innerHTML="","object"==typeof e.returnValues){var i,r=this._clickSelectItem.bind(this);for(var a in e.returnValues)e.returnValues.hasOwnProperty(a)&&(i=this._createListItem(e.returnValues[a]),i.addEventListener(WCF_CLICK_EVENT,r),this._list.appendChild(i))}t&&(n.insertAfter(this._list,this._element),o.initFragment(this._element.parentNode,this._list),this._dropdownContainerId=n.identify(this._element.parentNode)),this._dropdownContainerId&&(this._activeItem=null,this._list.childElementCount||!1!==this._handleEmptyResult()?(o.open(this._dropdownContainerId,!0),this._list.childElementCount&&~~elData(this._list.children[0],"object-id")&&(this._activeItem=this._list.children[0],this._activeItem.classList.add("active"))):o.close(this._dropdownContainerId))},_handleEmptyResult:function(){if(!this._options.noResultPlaceholder)return!1;var e=elCreate("li");e.className="dropdownText";var t=elCreate("span");return t.textContent=this._options.noResultPlaceholder,e.appendChild(t),this._list.appendChild(e),!0},_createListItem:function(e){var t=elCreate("li");elData(t,"object-id",e.objectID),elData(t,"label",e.label);var i=elCreate("span");return i.textContent=e.label,t.appendChild(i),t},_ajaxSetup:function(){return{data:this._options.ajax}}},r}),define("WoltLabSuite/Core/Ui/User/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){var o=e.isPlainObject(n)&&!0===n.includeUserGroups;n=e.extend({ajax:{className:"wcf\\data\\user\\UserAction",parameters:{data:{includeUserGroups:o?1:0}}}},n),i._super.prototype.init.call(this,t,n)},_createListItem:function(e){var t=i._super.prototype._createListItem.call(this,e);elData(t,"type",e.type);var n=elCreate("div");return n.className="box16",n.innerHTML="group"===e.type?'<span class="icon icon16 fa-users"></span>':e.icon,n.appendChild(t.children[0]),t.appendChild(n),t}}),i}),define("WoltLabSuite/Core/Ui/Acl/Simple",["Language","StringUtil","Dom/ChangeListener","WoltLabSuite/Core/Ui/User/Search/Input"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={init:function(){},_build:function(){},_select:function(){},_removeItem:function(){}},o}),define("WoltLabSuite/Core/Ui/Article/MarkAllAsRead",["Ajax"],function(e){"use strict";return{init:function(){elBySelAll(".markAllAsReadButton",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this))},_click:function(t){t.preventDefault(),e.api(this)},_ajaxSuccess:function(){var e=elBySel(".mainMenu .active .badge");e&&elRemove(e),elBySelAll(".articleList .newMessageBadge",void 0,elRemove)},_ajaxSetup:function(){return{data:{actionName:"markAllAsRead",className:"wcf\\data\\article\\ArticleAction"}}}}}),define("WoltLabSuite/Core/Ui/Article/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={open:function(){},_search:function(){},_click:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},_dialogSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/Color/Picker",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}var i=function(e,t){if("object"==typeof window.WCF&&"function"==typeof window.WCF.ColorPicker)return(i=function(e,t){var i=new window.WCF.ColorPicker(e);return"function"==typeof t.callbackSubmit&&i.setCallbackSubmit(t.callbackSubmit),i})(e,t);0===n.length&&(window.__wcf_bc_colorPickerInit=function(){n.forEach(function(e){i(e[0],e[1])}),window.__wcf_bc_colorPickerInit=void 0,n=[]}),n.push([e,t])},n=[];return t.prototype={init:function(t,n){if(!(t instanceof Element))throw new TypeError("Expected a valid DOM element, use `UiColorPicker.fromSelector()` if you want to use a CSS selector.");this._options=e.extend({callbackSubmit:null},n),i(t,this._options)}},t.fromSelector=function(e){elBySelAll(e,void 0,function(e){new t(e)})},t}),define("WoltLabSuite/Core/Ui/Comment/Add",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},_submitGuestDialog:function(){},_submit:function(){},_getParameters:function(){},_validate:function(){},throwError:function(){},_showLoadingOverlay:function(){},_hideLoadingOverlay:function(){},_reset:function(){},_handleError:function(){},_getEditor:function(){},_insertMessage:function(){},_ajaxSuccess:function(){},_ajaxFailure:function(){},_ajaxSetup:function(){},_cancelGuestDialog:function(){}},f}),define("WoltLabSuite/Core/Ui/Comment/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},rebuild:function(){},_click:function(){},_prepare:function(){},_showEditor:function(){},_restoreMessage:function(){},_save:function(){},_validate:function(){},throwError:function(){},_showMessage:function(){},_hideEditor:function(){},_restoreEditor:function(){},_destroyEditor:function(){},_getEditorId:function(){},_getObjectId:function(){},_ajaxFailure:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){}},f}),define("WoltLabSuite/Core/Ui/Dropdown/Builder",["Core","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!(e instanceof HTMLUListElement))throw new TypeError("Expected a reference to an <ul> element.");if(!e.classList.contains("dropdownMenu"))throw new Error("List does not appear to be a dropdown menu.")}function n(t){var i=elCreate("li");if("divider"===t)return i.className="dropdownDivider",i;"string"==typeof t.identifier&&elData(i,"identifier",t.identifier);var n=elCreate("a");if(n.href="string"==typeof t.href?t.href:"#","function"==typeof t.callback)n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),t.callback(n)});else if("#"===n.getAttribute("href"))throw new Error("Expected either a `href` value or a `callback`.");if(t.hasOwnProperty("attributes")&&e.isPlainObject(t.attributes))for(var r in t.attributes)t.attributes.hasOwnProperty(r)&&elData(n,r,t.attributes[r]);if(i.appendChild(n),void 0!==t.icon&&e.isPlainObject(t.icon)){if("string"!=typeof t.icon.name)throw new TypeError("Expected a valid icon name.");var a=16;"number"==typeof t.icon.size&&-1!==o.indexOf(~~t.icon.size)&&(a=~~t.icon.size);var l=elCreate("span");l.className="icon icon"+a+" fa-"+t.icon.name,n.appendChild(l)}var s="string"==typeof t.label?t.label.trim():"",c="string"==typeof t.labelHtml?t.labelHtml.trim():"";if(""===s&&""===c)throw new TypeError("Expected either a label or a `labelHtml`.");var u=elCreate("span");return u[s?"textContent":"innerHTML"]=s||c,n.appendChild(document.createTextNode(" ")),n.appendChild(u),i}var o=[16,24,32,48,64,96,144];return{create:function(e,t){var i=elCreate("ul");return i.className="dropdownMenu","string"==typeof t&&elData(i,"identifier",t),Array.isArray(e)&&e.length>0&&this.appendItems(i,e),i},buildItem:function(e){return n(e)},appendItem:function(e,t){i(e),e.appendChild(n(t))},appendItems:function(e,t){if(i(e),!Array.isArray(t))throw new TypeError("Expected an array of items.");var o=t.length;if(0===o)throw new Error("Expected a non-empty list of items.");if(1===o)this.appendItem(e,t[0]);else{for(var r=document.createDocumentFragment(),a=0;a<o;a++)r.appendChild(n(t[a]));e.appendChild(r)}},setItems:function(e,t){i(e),e.innerHTML="",this.appendItems(e,t)},attach:function(e,n){i(e),t.initFragment(n,e),n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),t.toggleDropdown(n.id)})},divider:function(){return"divider"}}}),define("WoltLabSuite/Core/Ui/File/Delete",["Ajax","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse","Dictionary"],function(e,t,i,n,o,r,a){"use strict";function l(e,t,i,n){if(this._isSingleImagePreview=i,this._uploadHandler=n,this._buttonContainer=elById(e),null===this._buttonContainer)throw new Error("Element id '"+e+"' is unknown.");if(this._target=elById(t),null===t)throw new Error("Element id '"+t+"' is unknown.");if(this._containers=new a,this._internalId=elData(this._target,"internal-id"),!this._internalId)throw new Error("InternalId is unknown.");this.rebuild()}return l.prototype={_createButtons:function(){for(var e,t,n,o=elBySelAll("li.uploadedFile",this._target),r=!1,a=0,l=o.length;a<l;a++)e=o[a],n=elData(e,"unique-file-id"),this._containers.has(n)||(t={uniqueFileId:n,element:e},this._containers.set(n,t),this._initDeleteButton(e,t),r=!0);r&&i.trigger()},_initDeleteButton:function(e,t){var i=elBySel(".buttonGroup",e);if(null===i)throw new Error("Button group in '"+targetId+"' is unknown.");var o=elCreate("li"),r=elCreate("span");r.classList="button jsDeleteButton small",r.textContent=n.get("wcf.global.button.delete"),o.appendChild(r),i.appendChild(o),o.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,t.uniqueFileId))},_delete:function(t){e.api(this,{uniqueFileId:t,internalId:this._internalId})},rebuild:function(){if(this._isSingleImagePreview){var e=elBySel("img",this._target);if(null!==e){var t=elData(e,"unique-file-id");if(!this._containers.has(t)){var i={uniqueFileId:t,element:e};this._containers.set(t,i),this._deleteButton=elCreate("p"),this._deleteButton.className="button deleteButton";var o=elCreate("span");o.textContent=n.get("wcf.global.button.delete"),this._deleteButton.appendChild(o),this._buttonContainer.appendChild(this._deleteButton),this._deleteButton.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,i.uniqueFileId))}}}else this._createButtons()},_ajaxSuccess:function(e){elRemove(this._containers.get(e.uniqueFileId).element),this._isSingleImagePreview&&(elRemove(this._deleteButton),this._deleteButton=null),this._uploadHandler.checkMaxFiles()},_ajaxSetup:function(){return{url:"index.php?ajax-file-delete/&t="+SECURITY_TOKEN}}},l}),define("WoltLabSuite/Core/Ui/File/Upload",["Core","Language","Dom/Util","WoltLabSuite/Core/Ui/File/Delete","Upload"],function(e,t,i,n,o){"use strict";function r(t,i,o){if(o=o||{},void 0===o.internalId)throw new Error("Missing internal id.");if(this._options=e.extend({name:"__files[]",singleFileRequests:!1,url:"index.php?ajax-file-upload/&t="+SECURITY_TOKEN,imagePreview:!1,maxFiles:null},o),this._options.multiple=null===this._options.maxFiles||this._options.maxFiles>1,0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),this._buttonContainer=elById(t),null===this._buttonContainer)throw new Error("Element id '"+t+"' is unknown.");if(this._target=elById(i),null===i)throw new Error("Element id '"+i+"' is unknown.");if(o.multiple&&"UL"!==this._target.nodeName&&"OL"!==this._target.nodeName)throw new Error("Target element has to be list or table body if uploading multiple files is supported.");this._fileElements=[],this._internalFileId=0,this._multiFileUploadIds=[],this._createButton(),this.checkMaxFiles(),this._deleteHandler=new n(t,i,this._options.imagePreview,this)}return e.inherit(r,o,{_createFileElement:function(e){var t=r._super.prototype._createFileElement.call(this,e);t.classList.add("box64","uploadedFile");var i=elBySel("progress",t),n=elCreate("span");n.className="icon icon64 fa-spinner";var o=t.textContent;t.textContent="",t.append(n);var a=elCreate("div"),l=elCreate("p");l.textContent=o;var s=elCreate("small");s.appendChild(i),a.appendChild(l),a.appendChild(s);var c=elCreate("div");c.appendChild(a);var u=elCreate("ul");return u.className="buttonGroup",c.appendChild(u),t.append(c),t},_failure:function(e,n,o,r,a){for(var l=0,s=this._fileElements[e].length;l<s;l++){this._fileElements[e][l].classList.add("uploadFailed"),elBySel("small",this._fileElements[e][l]).innerHTML="";var c=elBySel(".icon",this._fileElements[e][l]);c.classList.remove("fa-spinner"),c.classList.add("fa-ban");var u=elCreate("span");u.className="innerError",u.textContent=t.get("wcf.upload.error.uploadFailed"),i.insertAfter(u,elBySel("small",this._fileElements[e][l]))}throw new Error("Upload failed: "+n.message)},_upload:function(e,t,i){var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return n&&elRemove(n),r._super.prototype._upload.call(this,e,t,i)},_success:function(e,t,n,o,r){for(var a=0,l=this._fileElements[e].length;a<l;a++)if(void 0!==t.files[a])if(this._options.imagePreview){if(null===t.files[a].image)throw new Error("Expect image for uploaded file. None given.");if(elRemove(this._fileElements[e][a]),null!==elBySel("img.previewImage",this._target))elBySel("img.previewImage",this._target).setAttribute("src",t.files[a].image);else{var s=elCreate("img");s.classList.add("previewImage"),s.setAttribute("src",t.files[a].image),s.setAttribute("style","max-width: 100%;"),elData(s,"unique-file-id",t.files[a].uniqueFileId),this._target.appendChild(s)}}else{elData(this._fileElements[e][a],"unique-file-id",t.files[a].uniqueFileId),elBySel("small",this._fileElements[e][a]).textContent=t.files[a].filesize;var c=elBySel(".icon",this._fileElements[e][a]);c.classList.remove("fa-spinner"),c.classList.add("fa-"+t.files[a].icon)}else{if(void 0===t.error[a])throw new Error("Unknown uploaded file for uploadId "+e+".");this._fileElements[e][a].classList.add("uploadFailed"),elBySel("small",this._fileElements[e][a]).innerHTML="";var c=elBySel(".icon",this._fileElements[e][a]);if(c.classList.remove("fa-spinner"),c.classList.add("fa-ban"),null===elBySel(".innerError",this._fileElements[e][a])){var u=elCreate("span");u.className="innerError",u.textContent=t.error[a].errorMessage,i.insertAfter(u,elBySel("small",this._fileElements[e][a]))}else elBySel(".innerError",this._fileElements[e][a]).textContent=t.error[a].errorMessage}this._deleteHandler.rebuild(),this.checkMaxFiles()},_getFormData:function(){return{internalId:this._options.internalId}},validateUpload:function(e){if(null===this._options.maxFiles||e.length+this.countFiles()<=this._options.maxFiles)return!0;var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return null===n&&(n=elCreate("small"),n.className="innerError",i.insertAfter(n,this._buttonContainer)),n.textContent=t.get("wcf.upload.error.reachedRemainingLimit",{maxFiles:this._options.maxFiles-this.countFiles()}),!1},countFiles:function(){return this._options.imagePreview?null!==elBySel("img",this._target)?1:0:this._target.childElementCount},checkMaxFiles:function(){null!==this._options.maxFiles&&this.countFiles()>=this._options.maxFiles?elHide(this._button):elShow(this._button)}}),r}),define("WoltLabSuite/Core/Ui/ItemList/Filter",["Core","EventKey","Language","List","StringUtil","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},_buildItems:function(){},_prepareItem:function(){},_keyup:function(){},_toggleVisibility:function(){},_setupVisibilityFilter:function(){},_setVisibility:function(){}},l}),define("WoltLabSuite/Core/Ui/ItemList/Static",["Core","Dictionary","Language","Dom/Traverse","EventKey","Ui/SimpleDropdown"],function(e,t,i,n,o,r){"use strict";var a="",l=new t,s=!1,c=null,u=null,d=null,h=null,f=null,p=null;return{init:function(t,i,o){var a=elById(t);if(null===a)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(l.has(t)){var s=l.get(t);for(var c in s)if(s.hasOwnProperty(c)){var u=s[c];u instanceof Element&&u.parentNode&&elRemove(u)}r.destroy(t),l.delete(t)}o=e.extend({maxItems:-1,maxLength:-1,isCSV:!1,callbackChange:null,callbackSubmit:null,submitFieldName:""},o);var d=n.parentByTag(a,"FORM");if(null!==d&&!1===o.isCSV){if(!o.submitFieldName.length&&"function"!=typeof o.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");d.addEventListener("submit",function(){var e=this.getValues(t);if(o.submitFieldName.length)for(var i,n=0,r=e.length;n<r;n++)i=elCreate("input"),i.type="hidden",i.name=o.submitFieldName.replace("{$objectId}",e[n].objectId),i.value=e[n].value,d.appendChild(i);else o.callbackSubmit(d,e)}.bind(this))}this._setup();var h=this._createUI(a,o);if(l.set(t,{dropdownMenu:null,element:h.element,list:h.list,listItem:h.element.parentNode,options:o,shadow:h.shadow}),i=h.values.length?h.values:i,Array.isArray(i))for(var f,p=!h.element.disabled,g=0,m=i.length;g<m;g++)f=i[g],"string"==typeof f&&(f={objectId:0,value:f}),this._addItem(t,f,p)},getValues:function(e){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=l.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent})}),i},setValues:function(e,t){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,o,r=l.get(e),a=n.childrenByClass(r.list,"item");for(i=0,o=a.length;i<o;i++)this._removeItem(null,a[i],!0);for(i=0,o=t.length;i<o;i++)this._addItem(e,t[i])},_setup:function(){s||(s=!0,c=this._keyDown.bind(this),u=this._keyPress.bind(this),d=this._keyUp.bind(this),h=this._paste.bind(this),f=this._removeItem.bind(this),p=this._blur.bind(this))},_createUI:function(e,t){var i=elCreate("ol");i.className="inputItemList"+(e.disabled?" disabled":""),elData(i,"element-id",e.id),i.addEventListener(WCF_CLICK_EVENT,function(t){t.target===i&&e.focus()});var n=elCreate("li");n.className="input",i.appendChild(n),e.addEventListener("keydown",c),e.addEventListener("keypress",u),e.addEventListener("keyup",d),e.addEventListener("paste",h),e.addEventListener("blur",p),e.parentNode.insertBefore(i,e),n.appendChild(e),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var o=null,r=[];if(t.isCSV){o=elCreate("input"),o.className="itemListInputShadow",o.type="hidden",o.name=e.name,e.removeAttribute("name"),i.parentNode.insertBefore(o,i);for(var a,l=e.value.split(","),s=0,f=l.length;s<f;s++)a=l[s].trim(),a.length&&r.push(a);if("TEXTAREA"===e.nodeName){var g=elCreate("input");g.type="text",e.parentNode.insertBefore(g,e),g.id=e.id,elRemove(e),e=g}}return{element:e,list:i,shadow:o,values:r}},_handleLimit:function(e){var t=l.get(e);-1!==t.options.maxItems&&(t.list.childElementCount-1<t.options.maxItems?t.element.disabled&&(t.element.disabled=!1,t.element.removeAttribute("placeholder")):t.element.disabled||(t.element.disabled=!0,elAttr(t.element,"placeholder",i.get("wcf.global.form.input.maxItems"))))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;a=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(o.Enter(e)||o.Comma(e)){e.preventDefault();var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain"),t.split(/,/).forEach(function(t){t=t.trim(),0!==t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t,i){var n=l.get(e),o=elCreate("li");o.className="item";var r=elCreate("span");if(r.className="content",elData(r,"object-id",t.objectId),r.textContent=t.value,o.appendChild(r),i||!n.element.disabled){var a=elCreate("a");a.className="icon icon16 fa-times",a.addEventListener(WCF_CLICK_EVENT,f),o.appendChild(a)}n.list.insertBefore(o,n.listItem),n.element.value="",n.element.disabled||this._handleLimit(e);var s=this._syncShadow(n);"function"==typeof n.options.callbackChange&&(null===s&&(s=this.getValues(e)),n.options.callbackChange(e,s))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,o=elData(n,"element-id"),r=l.get(o);n.removeChild(t),i||r.element.focus(),this._handleLimit(o);var a=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===a&&(a=this.getValues(o)),r.options.callbackChange(o,a))},_syncShadow:function(e){if(!e.options.isCSV)return null;for(var t="",i=this.getValues(e.element.id),n=0,o=i.length;n<o;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=(l.get(e.currentTarget.id),e.currentTarget);window.setTimeout(function(){var e=t.value.trim();e.length&&this._addItem(t.id,{objectId:0,value:e})}.bind(this),100)}}}),define("WoltLabSuite/Core/Ui/ItemList/User",["WoltLabSuite/Core/Ui/ItemList"],function(e){"use strict";var t=function(){};return t.prototype={init:function(){},getValues:function(){}},t}),define("WoltLabSuite/Core/Ui/User/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination"],function(e,t,i,n,o,r){"use strict";function a(e){this.init(e)}return a.prototype={init:function(e){this._cache=new i,this._pageCount=0,this._pageNo=1,this._options=t.extend({className:"",dialogTitle:"",parameters:{}},e)},open:function(){this._pageNo=1,this._showPage()},_showPage:function(t){if("number"==typeof t&&(this._pageNo=~~t),0!==this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount))throw new RangeError("pageNo must be between 1 and "+this._pageCount+" ("+this._pageNo+" given).");if(this._cache.has(this._pageNo)){var i=o.open(this,this._cache.get(this._pageNo));if(this._pageCount>1){var n=elBySel(".jsPagination",i.content);null!==n&&new r(n,{activePage:this._pageNo,maxPage:this._pageCount,callbackSwitch:this._showPage.bind(this)});var a=i.content.parentNode;a.scrollTop>0&&(a.scrollTop=0)}}else this._options.parameters.pageNo=this._pageNo,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&(this._pageCount=~~e.returnValues.pageCount),this._cache.set(this._pageNo,e.returnValues.template),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserList",className:this._options.className,interfaceName:"wcf\\data\\IGroupedUserListAction"}}},_dialogSetup:function(){return{id:n.getUniqueId(),options:{title:this._options.dialogTitle},source:null}}},a}),define("WoltLabSuite/Core/Ui/Reaction/CountButtons",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","EventHandler"],function(e,t,i,n,o,r,a,l,s,c){"use strict";function u(e,t){this.init(e,t)}return u.prototype={init:function(e,n){if(""===n.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objects=new i,this._objectType=e,this._options=t.extend({summaryListSelector:".reactionSummaryList",containerSelector:"",isSingleItem:!1,parameters:{data:{}}},n),this.initContainers(n,e),a.add("WoltLabSuite/Core/Ui/Reaction/CountButtons-"+e,this.initContainers.bind(this))},initContainers:function(){for(var e,t,i,n=elBySelAll(this._options.containerSelector),o=!1,r=0,s=n.length;r<s;r++)if(e=n[r],!this._containers.has(l.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,summary:null,objectId:i,element:e},this._containers.set(l.identify(e),t),this._initReactionCountButtons(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),o=!0}o&&a.trigger()},updateCountButtons:function(e,t){var i=!1;this._objects.get(e).forEach(function(e){var n=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e.element);if(null!==n){for(var o={},a=elBySelAll(".reactCountButton",n),l=0,s=a.length;l<s;l++){var c=elData(a[l],"reaction-type-id");t.hasOwnProperty(c)?o[c]=a[l]:elRemove(a[l])}Object.keys(t).forEach(function(e){if(void 0!==o[e]){elBySel(".reactionCount",o[e]).innerHTML=r.shortUnit(t[e])}else if(void 0!==REACTION_TYPES[e]){var a=elCreate("span");a.className="reactCountButton",a.innerHTML=REACTION_TYPES[e].renderedIcon,elData(a,"reaction-type-id",e);var l=elCreate("span");l.className="reactionCount",l.innerHTML=r.shortUnit(t[e]),a.appendChild(l),n.appendChild(a),i=!0}},this),window[n.childElementCount>0?"elShow":"elHide"](n)}}.bind(this)),i&&a.trigger()},_initReactionCountButtons:function(e,t){var i=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e);null!==i&&i.addEventListener(WCF_CLICK_EVENT,this._showReactionOverlay.bind(this,t.objectId))},_showReactionOverlay:function(e,t){t.preventDefault(),this._currentObjectId=e,this._showOverlay()},_showOverlay:function(){this._options.parameters.data.containerID=this._objectType+"-"+this._currentObjectId,this._options.parameters.data.objectID=this._currentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){c.fire("com.woltlab.wcf.ReactionCountButtons","openDialog",e),s.open(this,e.returnValues.template),s.setTitle("userReactionOverlay-"+this._objectType,e.returnValues.title)},_ajaxSetup:function(){return{data:{actionName:"getReactionDetails",className:"\\wcf\\data\\reaction\\ReactionAction"}}},_dialogSetup:function(){return{id:"userReactionOverlay-"+this._objectType,options:{title:""},source:null}}},u}),define("WoltLabSuite/Core/Ui/Reaction/Handler",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/User/List","User","WoltLabSuite/Core/Ui/Reaction/CountButtons","Ui/Alignment","Ui/CloseOverlay"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";function p(e,t){this.init(e,t)}return p.prototype={init:function(e,n){if(""===n.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objectType=e,this._cache=new i,this._objects=new i,this._popoverCurrentObjectId=0,this._popover=null,this._options=t.extend({buttonSelector:".reactButton",containerSelector:"",isButtonGroupNavigation:!1,isSingleItem:!1,parameters:{data:{}}},n),this.initReactButtons(n,e),this.countButtons=new d(this._objectType,this._options),a.add("WoltLabSuite/Core/Ui/Reaction/Handler-"+e,this.initReactButtons.bind(this)),f.add("WoltLabSuite/Core/Ui/Reaction/Handler",this._closePopover.bind(this))},initReactButtons:function(){for(var e,t,i,n=elBySelAll(this._options.containerSelector),o=!1,r=0,s=n.length;r<s;r++)if(e=n[r],!this._containers.has(l.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,objectId:i,element:e},this._containers.set(l.identify(e),t),this._initReactButton(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),o=!0}o&&a.trigger()},_initReactButton:function(e,t){if(this._options.isSingleItem?t.reactButton=elBySel(this._options.buttonSelector):t.reactButton=elBySel(this._options.buttonSelector,e),null!==t.reactButton&&0!==t.reactButton.length){if(1===Object.keys(REACTION_TYPES).length){var i=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];t.reactButton.title=i.title;elBySel(".invisible",t.reactButton).innerText=i.title}t.reactButton.addEventListener(WCF_CLICK_EVENT,this._toggleReactPopover.bind(this,t.objectId,t.reactButton))}},_updateReactButton:function(e,t){this._objects.get(e).forEach(function(e){null!==e.reactButton&&(t?(e.reactButton.classList.add("active"),elData(e.reactButton,"reaction-type-id",t)):(elData(e.reactButton,"reaction-type-id",0),e.reactButton.classList.remove("active")))})},_markReactionAsActive:function(){var e=null;if(this._objects.get(this._popoverCurrentObjectId).forEach(function(t){null!==t.reactButton&&(e=~~elData(t.reactButton,"reaction-type-id"))}),null===e)throw new Error("Unable to find react button for current popover.");if(elBySelAll(".reactionTypeButton.active",this._getPopover(),function(e){e.classList.remove("active")}),e){var t=elBySel('.reactionTypeButton[data-reaction-type-id="'+e+'"]',this._getPopover());t.classList.add("active"),0==~~elData(t,"is-assignable")&&elShow(t)}},_toggleReactPopover:function(e,t,i){if(null!==i&&(i.preventDefault(),i.stopPropagation()),1===Object.keys(REACTION_TYPES).length){var n=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];this._popoverCurrentObjectId=e,this._react(n.reactionTypeID)}else 0===this._popoverCurrentObjectId||this._popoverCurrentObjectId!==e?this._openReactPopover(e,t):this._closePopover(e,t)},_openReactPopover:function(e,t){0!==this._popoverCurrentObjectId&&this._closePopover(),this._popoverCurrentObjectId=e,this._markReactionAsActive(),h.set(this._getPopover(),t,{pointer:!0,horizontal:this._options.isButtonGroupNavigation?"left":"center",vertical:"top"}),this._options.isButtonGroupNavigation&&t.closest("nav").style.setProperty("opacity","1",""),this._getPopover().classList.remove("forceHide"),this._getPopover().classList.add("active")},_getPopover:function(){if(null==this._popover){this._popover=elCreate("div"),this._popover.className="reactionPopover forceHide";var e=elCreate("div");e.className="reactionPopoverContent";var t=elCreate("ul"),i=this._getSortedReactionTypes();for(var n in i)if(i.hasOwnProperty(n)){var o=i[n],r=elCreate("li")
-;r.className="reactionTypeButton jsTooltip",elData(r,"reaction-type-id",o.reactionTypeID),elData(r,"title",o.title),elData(r,"is-assignable",~~o.isAssignable),r.title=o.title;var l=elCreate("span");l.className="reactionTypeButtonTitle",l.innerHTML=o.title,r.innerHTML=o.renderedIcon,r.appendChild(l),r.addEventListener(WCF_CLICK_EVENT,this._react.bind(this,o.reactionTypeID)),o.isAssignable||elHide(r),t.appendChild(r)}e.appendChild(t),this._popover.appendChild(e);var s=elCreate("span");s.className="elementPointer",s.appendChild(elCreate("span")),this._popover.appendChild(s),document.body.appendChild(this._popover),a.trigger()}return this._popover},_getSortedReactionTypes:function(){var e=[];for(var t in REACTION_TYPES)REACTION_TYPES.hasOwnProperty(t)&&e.push(REACTION_TYPES[t]);return e.sort(function(e,t){return e.showOrder-t.showOrder}),e},_closePopover:function(){0!==this._popoverCurrentObjectId&&(this._getPopover().classList.remove("active"),elBySelAll('.reactionTypeButton[data-is-assignable="0"]',this._getPopover(),elHide),this._options.isButtonGroupNavigation&&this._objects.get(this._popoverCurrentObjectId).forEach(function(e){e.reactButton.closest("nav").style.cssText=""}),this._popoverCurrentObjectId=0)},_react:function(t){0!=~~this._popoverCurrentObjectId&&(this._options.parameters.reactionTypeID=t,this._options.parameters.data.objectID=this._popoverCurrentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters}),this._closePopover())},_ajaxSuccess:function(e){this.countButtons.updateCountButtons(e.returnValues.objectID,e.returnValues.reactions),this._updateReactButton(e.returnValues.objectID,e.returnValues.reactionTypeID)},_ajaxSetup:function(){return{data:{actionName:"react",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},p}),define("WoltLabSuite/Core/Ui/Like/Handler",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/User/List","User","WoltLabSuite/Core/Ui/Reaction/Handler"],function(e,t,i,n,o,r,a,l,s,c,u,d){"use strict";function h(e,t){this.init(e,t)}return h.prototype={init:function(e,i){if(""===i.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Like/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new o,this._details=new o,this._objectType=e,this._options=t.extend({badgeClassNames:"",isSingleItem:!1,markListItemAsActive:!1,renderAsButton:!0,summaryPrepend:!0,summaryUseIcon:!0,canDislike:!1,canLike:!1,canLikeOwnContent:!1,canViewSummary:!1,badgeContainerSelector:".messageHeader .messageStatus",buttonAppendToSelector:".messageFooter .messageFooterButtons",buttonBeforeSelector:"",containerSelector:"",summarySelector:".messageFooterGroup"},i),this.initContainers(i,e),a.add("WoltLabSuite/Core/Ui/Like/Handler-"+e,this.initContainers.bind(this)),new d(this._objectType,{containerSelector:this._options.containerSelector,summaryListSelector:".reactionSummaryList"})},initContainers:function(){for(var e,t,i=elBySelAll(this._options.containerSelector),n=!1,o=0,r=i.length;o<r;o++)e=i[o],this._containers.has(e)||(t={badge:null,dislikeButton:null,likeButton:null,summary:null,dislikes:~~elData(e,"like-dislikes"),liked:~~elData(e,"like-liked"),likes:~~elData(e,"like-likes"),objectId:~~elData(e,"object-id"),users:JSON.parse(elData(e,"like-users"))},this._containers.set(e,t),this._buildWidget(e,t),n=!0);n&&a.trigger()},_buildWidget:function(e,t){var i,n,o,a=!0;if(o=this._options.isSingleItem?elBySel(this._options.summarySelector):elBySel(this._options.summarySelector,e),null===o&&(o=this._options.isSingleItem?elBySel(this._options.badgeContainerSelector):elBySel(this._options.badgeContainerSelector,e),a=!1),null!==o){i=elCreate("ul"),i.classList.add("reactionSummaryList"),a?i.classList.add("likesSummary"):i.classList.add("reactionSummaryListTiny");for(var s in t.users)if("reactionTypeID"!==s&&REACTION_TYPES.hasOwnProperty(s)){var c=elCreate("li");c.className="reactCountButton",elData(c,"reaction-type-id",s);var d=elCreate("span");d.className="reactionCount",d.innerHTML=r.shortUnit(t.users[s]),c.appendChild(d),c.innerHTML=REACTION_TYPES[s].renderedIcon+c.innerHTML,i.appendChild(c)}a?this._options.summaryPrepend?l.prepend(i,o):o.appendChild(i):"OL"===o.nodeName||"UL"===o.nodeName?(n=elCreate("li"),n.appendChild(i),o.appendChild(n)):o.appendChild(i),t.badge=i}if(this._options.canLike&&(u.userId!=elData(e,"user-id")||this._options.canLikeOwnContent)){var h=this._options.buttonAppendToSelector?this._options.isSingleItem?elBySel(this._options.buttonAppendToSelector):elBySel(this._options.buttonAppendToSelector,e):null,f=this._options.buttonBeforeSelector?this._options.isSingleItem?elBySel(this._options.buttonBeforeSelector):elBySel(this._options.buttonBeforeSelector,e):null;if(null===f&&null===h)throw new Error("Unable to find insert location for like/dislike buttons.");t.likeButton=this._createButton(e,t.users.reactionTypeID,f,h)}},_createButton:function(e,t,i,o){var r=n.get("wcf.reactions.react"),a=elCreate("li");a.className="wcfReactButton";var l=elCreate("a");l.className="jsTooltip reactButton",this._options.renderAsButton&&l.classList.add("button"),l.href="#",l.title=r;var s=elCreate("span");s.className="icon icon16 fa-smile-o",void 0===t||0==t?elData(s,"reaction-type-id",0):(elData(l,"reaction-type-id",t),l.classList.add("active")),l.appendChild(s);var c=elCreate("span");return c.className="invisible",c.innerHTML=r,l.appendChild(document.createTextNode(" ")),l.appendChild(c),a.appendChild(l),i?i.parentNode.insertBefore(a,i):o.appendChild(a),l}},h}),define("WoltLabSuite/Core/Ui/Message/InlineEditor",["Ajax","Core","Dictionary","Environment","EventHandler","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},rebuild:function(){},_click:function(){},_clickDropdown:function(){},_dropdownBuild:function(){},_dropdownToggle:function(){},_dropdownGetItems:function(){},_dropdownOpen:function(){},_dropdownSelect:function(){},_clickDropdownItem:function(){},_prepare:function(){},_showEditor:function(){},_restoreMessage:function(){},_save:function(){},_validate:function(){},throwError:function(){},_showMessage:function(){},_hideEditor:function(){},_restoreEditor:function(){},_destroyEditor:function(){},_getHash:function(){},_updateHistory:function(){},_getEditorId:function(){},_getObjectId:function(){},_ajaxFailure:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},legacyEdit:function(){}},f}),define("WoltLabSuite/Core/Ui/Message/Manager",["Ajax","Core","Dictionary","Language","Dom/ChangeListener","Dom/Util"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},rebuild:function(){},getPermission:function(){},getPropertyValue:function(){},update:function(){},updateItems:function(){},updateAllItems:function(){},setNote:function(){},_update:function(){},_updateState:function(){},_toggleMessageStatus:function(){},_getAttributeName:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/Message/Reply",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},_submitGuestDialog:function(){},_submit:function(){},_validate:function(){},throwError:function(){},_showLoadingOverlay:function(){},_hideLoadingOverlay:function(){},_reset:function(){},_handleError:function(){},_getEditor:function(){},_insertMessage:function(){},_ajaxSuccess:function(){},_ajaxFailure:function(){},_ajaxSetup:function(){}},f}),define("WoltLabSuite/Core/Ui/Message/Share",["EventHandler","StringUtil"],function(e,t){"use strict";return{_pageDescription:"",_pageUrl:"",init:function(){var i=elBySel('meta[property="og:title"]');null!==i&&(this._pageDescription=encodeURIComponent(i.content));var n=elBySel('meta[property="og:url"]');null!==n&&(this._pageUrl=encodeURIComponent(n.content)),elBySelAll(".jsMessageShareButtons",null,function(i){i.classList.remove("jsMessageShareButtons");var n=encodeURIComponent(t.unescapeHTML(elData(i,"url")||""));n||(n=this._pageUrl);var o={facebook:{link:elBySel(".jsShareFacebook",i),share:function(e){e.preventDefault(),this._share("facebook","https://www.facebook.com/sharer.php?u={pageURL}&t={text}",!0,n)}.bind(this)},google:{link:elBySel(".jsShareGoogle",i),share:function(e){e.preventDefault(),this._share("google","https://plus.google.com/share?url={pageURL}",!1,n)}.bind(this)},reddit:{link:elBySel(".jsShareReddit",i),share:function(e){e.preventDefault(),this._share("reddit","https://ssl.reddit.com/submit?url={pageURL}",!1,n)}.bind(this)},twitter:{link:elBySel(".jsShareTwitter",i),share:function(e){e.preventDefault(),this._share("twitter","https://twitter.com/share?url={pageURL}&text={text}",!1,n)}.bind(this)},linkedIn:{link:elBySel(".jsShareLinkedIn",i),share:function(e){e.preventDefault(),this._share("linkedIn","https://www.linkedin.com/cws/share?url={pageURL}",!1,n)}.bind(this)},pinterest:{link:elBySel(".jsSharePinterest",i),share:function(e){e.preventDefault(),this._share("pinterest","https://www.pinterest.com/pin/create/link/?url={pageURL}&description={text}",!1,n)}.bind(this)},xing:{link:elBySel(".jsShareXing",i),share:function(e){e.preventDefault(),this._share("xing","https://www.xing.com/social_plugins/share?url={pageURL}",!1,n)}.bind(this)},whatsApp:{link:elBySel(".jsShareWhatsApp",i),share:function(e){e.preventDefault(),window.location.href="https://api.whatsapp.com/send?text="+this._pageDescription+"%20"+this._pageUrl}.bind(this)}};e.fire("com.woltlab.wcf.message.share","shareProvider",{container:i,providers:o,pageDescription:this._pageDescription,pageUrl:this._pageUrl});for(var r in o)o.hasOwnProperty(r)&&null!==o[r].link&&o[r].link.addEventListener(WCF_CLICK_EVENT,o[r].share)}.bind(this))},_share:function(e,t,i,n){n||(n=this._pageUrl),window.open(t.replace(/\{pageURL}/,n).replace(/\{text}/,this._pageDescription+(i?"%20"+n:"")),e,"height=600,width=600")}}}),define("WoltLabSuite/Core/Ui/Page/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={open:function(){},_search:function(){},_click:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},_dialogSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/Sortable/List",["Core","Ui/Screen"],function(e,t){"use strict";var i=function(){};return i.prototype={init:function(){},_enable:function(){},_disable:function(){}},i}),define("WoltLabSuite/Core/Ui/Poll/Editor",["Core","Dom/Util","EventHandler","EventKey","Language","WoltLabSuite/Core/Date/Picker","WoltLabSuite/Core/Ui/Sortable/List"],function(e,t,i,n,o,r,a){"use strict";function l(e,t,i,n){this.init(e,t,i,n)}return l.prototype={init:function(t,n,o,r){if(this._container=elById(t),null===this._container)throw new Error("Unknown poll editor container with id '"+t+"'.");if(this._wysiwygId=o,""!==o&&null===elById(o))throw new Error("Unknown wysiwyg field with id '"+o+"'.");this.questionField=elById(this._wysiwygId+"Poll_question");var l=elByClass("sortableList",this._container);if(0===l.length)throw new Error("Cannot find poll options list for container with id '"+t+"'.");if(this.optionList=l[0],this.endTimeField=elById(this._wysiwygId+"Poll_endTime"),this.maxVotesField=elById(this._wysiwygId+"Poll_maxVotes"),this.isChangeableYesField=elById(this._wysiwygId+"Poll_isChangeable"),this.isChangeableNoField=elById(this._wysiwygId+"Poll_isChangeable_no"),this.isPublicYesField=elById(this._wysiwygId+"Poll_isPublic"),this.isPublicNoField=elById(this._wysiwygId+"Poll_isPublic_no"),this.resultsRequireVoteYesField=elById(this._wysiwygId+"Poll_resultsRequireVote"),this.resultsRequireVoteNoField=elById(this._wysiwygId+"Poll_resultsRequireVote_no"),this.sortByVotesYesField=elById(this._wysiwygId+"Poll_sortByVotes"),this.sortByVotesNoField=elById(this._wysiwygId+"Poll_sortByVotes_no"),this._optionCount=0,this._options=e.extend({isAjax:!1,maxOptions:20},r),this._createOptionList(n||[]),new a({containerId:t,options:{toleranceElement:"> div"}}),this._options.isAjax)for(var s=["handleError","reset","submit","validate"],c=0,u=s.length;c<u;c++){var d=s[c];i.add("com.woltlab.wcf.redactor2",d+"_"+this._wysiwygId,this["_"+d].bind(this))}else{var h=this._container.closest("form");if(null===h)throw new Error("Cannot find form for container with id '"+t+"'.");h.addEventListener("submit",this._submit.bind(this))}},_addOption:function(e){if(e.preventDefault(),this._optionCount===this._options.maxOptions)return!1;this._createOption(void 0,void 0,e.currentTarget.closest("li"))},_createOption:function(e,i,n){e=e||"",i=~~i||0;var r=elCreate("LI");r.className="sortableNode",elData(r,"option-id",i),n?t.insertAfter(r,n):this.optionList.appendChild(r);var a=elCreate("div");a.className="pollOptionInput",r.appendChild(a);var l=elCreate("span");l.className="icon icon16 fa-arrows sortableNodeHandle",a.appendChild(l);var s=elCreate("a");elAttr(s,"role","button"),elAttr(s,"href","#"),s.className="icon icon16 fa-plus jsTooltip jsAddOption pointer",elAttr(s,"title",o.get("wcf.poll.button.addOption")),s.addEventListener("click",this._addOption.bind(this)),a.appendChild(s);var c=elCreate("a");elAttr(c,"role","button"),elAttr(c,"href","#"),c.className="icon icon16 fa-times jsTooltip jsDeleteOption pointer",elAttr(c,"title",o.get("wcf.poll.button.removeOption")),c.addEventListener("click",this._removeOption.bind(this)),a.appendChild(c);var u=elCreate("input");elAttr(u,"type","text"),u.value=e,elAttr(u,"maxlength",255),u.addEventListener("keydown",this._optionInputKeyDown.bind(this)),u.addEventListener("click",function(){document.activeElement!==this&&this.focus()}),a.appendChild(u),null!==n&&u.focus(),++this._optionCount===this._options.maxOptions&&elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.remove("pointer"),e.classList.add("disabled")})},_createOptionList:function(e){for(var t=0,i=e.length;t<i;t++){var n=e[t];this._createOption(n.optionValue,n.optionID)}this._optionCount<this._options.maxOptions&&this._createOption()},_handleError:function(e){switch(e.returnValues.fieldName){case this._wysiwygId+"Poll_endTime":case this._wysiwygId+"Poll_maxVotes":var i=e.returnValues.fieldName.replace(this._wysiwygId+"Poll_",""),n=elCreate("small");n.className="innerError",n.innerHTML=o.get("wcf.poll."+i+".error."+e.returnValues.errorType);var r=elById(e.returnValues.fieldName);r.closest("dd");t.prepend(n,r.nextSibling),e.cancel=!0}},_optionInputKeyDown:function(t){n.Enter(t)&&(e.triggerEvent(elByClass("jsAddOption",t.currentTarget.parentNode)[0],"click"),t.preventDefault())},_removeOption:function(e){e.preventDefault(),elRemove(e.currentTarget.closest("li")),this._optionCount--,elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.add("pointer"),e.classList.remove("disabled")}),0===this.optionList.length&&this._createOption()},_reset:function(){this.questionField.value="",this._optionCount=0,this.optionList.innerHtml="",this._createOption(),r.clear(this.endTimeField),this.maxVotesField.value=1,this.isChangeableYesField.checked=!1,this.isChangeableNoField.checked=!0,this.isPublicYesField.checked=!1,this.isPublicNoField.checked=!0,this.resultsRequireVoteYesField.checked=!1,this.resultsRequireVoteNoField.checked=!0,this.sortByVotesYesField.checked=!1,this.sortByVotesNoField.checked=!0,i.fire("com.woltlab.wcf.poll.editor","reset",{pollEditor:this})},_submit:function(e){if(this._options.isAjax)e.poll=this.getData(),i.fire("com.woltlab.wcf.poll.editor","submit",{event:e,pollEditor:this});else for(var t=this._container.closest("form"),n=this.getOptions(),o=0,r=n.length;o<r;o++){var a=elCreate("input");elAttr(a,"type","hidden"),elAttr(a,"name",this._wysiwygId+"Poll_options["+o+"]"),a.value=n[o],t.appendChild(a)}},_validate:function(e){if(""!==this.questionField.value.trim()){for(var t=0,n=0,r=this.optionList.children.length;n<r;n++){""!==elBySel("input[type=text]",this.optionList.children[n]).value.trim()&&t++}if(0===t)e.api.throwError(this._container,o.get("wcf.global.form.error.empty")),e.valid=!1;else{var a=~~this.maxVotesField.value;a&&a>t?(e.api.throwError(this.maxVotesField.parentNode,o.get("wcf.poll.maxVotes.error.invalid")),e.valid=!1):i.fire("com.woltlab.wcf.poll.editor","validate",{data:e,pollEditor:this})}}},getData:function(){var e={};return e[this.questionField.id]=this.questionField.value,e[this._wysiwygId+"Poll_options"]=this.getOptions(),e[this.endTimeField.id]=this.endTimeField.value,e[this.maxVotesField.id]=this.maxVotesField.value,e[this.isChangeableYesField.id]=!!this.isChangeableYesField.checked,e[this.isPublicYesField.id]=!!this.isPublicYesField.checked,e[this.resultsRequireVoteYesField.id]=!!this.resultsRequireVoteYesField.checked,e[this.sortByVotesYesField.id]=!!this.sortByVotesYesField.checked,e},getOptions:function(){for(var e=[],t=0,i=this.optionList.children.length;t<i;t++){var n=this.optionList.children[t],o=elBySel("input[type=text]",n).value.trim();""!==o&&e.push(elData(n,"option-id")+"_"+o)}return e}},l}),define("WoltLabSuite/Core/Ui/Redactor/Article",["WoltLabSuite/Core/Ui/Article/Search"],function(e){"use strict";var t=function(){};return t.prototype={init:function(){},_click:function(){},_insert:function(){}},t}),define("WoltLabSuite/Core/Ui/Redactor/Metacode",["EventHandler","Dom/Util"],function(e,t){"use strict";var i=function(){};return i.prototype={convert:function(){},convertFromHtml:function(){},_getOpeningTag:function(){},_getClosingTag:function(){},_getFirstParagraph:function(){},_getLastParagraph:function(){},_parseAttributes:function(){}},i}),define("WoltLabSuite/Core/Ui/Redactor/Autosave",["Core","Devtools","EventHandler","Language","Dom/Traverse","./Metacode"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},getInitialValue:function(){},getMetaData:function(){},watch:function(){},destroy:function(){},clear:function(){},createOverlay:function(){},hideOverlay:function(){},_saveToStorage:function(){},_cleanup:function(){}},a}),define("WoltLabSuite/Core/Ui/Redactor/PseudoHeader",[],function(){"use strict";var e=function(){};return e.prototype={getHeight:function(){}},e}),define("WoltLabSuite/Core/Ui/Redactor/Code",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader","prism/prism-meta"],function(e,t,i,n,o,r,a,l){"use strict";var s=function(){};return s.prototype={init:function(){},_bbcodeCode:function(){},_observeLoad:function(){},_edit:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){},_dialogSubmit:function(){}},s}),define("WoltLabSuite/Core/Ui/Redactor/Format",["Dom/Util"],function(e){"use strict";var t=function(){};return t.prototype={format:function(){},removeFormat:function(){},_handleParentNodes:function(){},_getLastMatchingParent:function(){},_isBoundaryElement:function(){},_getSelectionMarker:function(){}},t}),define("WoltLabSuite/Core/Ui/Redactor/Html",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},_bbcodeCode:function(){},_observeLoad:function(){},_edit:function(){},_save:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){}},l}),define("WoltLabSuite/Core/Ui/Redactor/Link",["Core","EventKey","Language","Ui/Dialog"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={showDialog:function(){},_submit:function(){},_dialogSetup:function(){}},o}),define("WoltLabSuite/Core/Ui/Redactor/Mention",["Ajax","Environment","StringUtil","Ui/CloseOverlay"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={init:function(){},_keyDown:function(){},_keyUp:function(){},_getTextLineInFrontOfCaret:function(){},_getDropdownMenuPosition:function(){},_setUsername:function(){},_selectMention:function(){},_updateDropdownPosition:function(){},_selectItem:function(){},_hideDropdown:function(){},_ajaxSetup:function(){},_ajaxSuccess:function(){}},o}),define("WoltLabSuite/Core/Ui/Redactor/Page",["WoltLabSuite/Core/Ui/Page/Search"],function(e){"use strict";var t=function(){};return t.prototype={init:function(){},_click:function(){},_insert:function(){}},t}),define("WoltLabSuite/Core/Ui/Redactor/Quote",["Core","EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./Metacode","./PseudoHeader"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=function(){};return c.prototype={init:function(){},_insertQuote:function(){},_click:function(){},_observeLoad:function(){},_edit:function(){},_save:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){},_dialogSubmit:function(){}},c}),define("WoltLabSuite/Core/Ui/Redactor/Spoiler",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},_bbcodeSpoiler:function(){},_observeLoad:function(){},_edit:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){},_dialogSubmit:function(){}},l}),define("WoltLabSuite/Core/Ui/Redactor/Table",["Language","Ui/Dialog"],function(e,t){"use strict";var i=function(){};return i.prototype={showDialog:function(){},_submit:function(){},_dialogSetup:function(){}},i}),define("WoltLabSuite/Core/Ui/Search/Page",["Core","Dom/Traverse","Dom/Util","Ui/Screen","Ui/SimpleDropdown","./Input"],function(e,t,i,n,o,r){"use strict";return{init:function(a){var l=elById("pageHeaderSearchInput");new r(l,{ajax:{className:"wcf\\data\\search\\keyword\\SearchKeywordAction"},callbackDropdownInit:function(e){if(e.classList.add("dropdownMenuPageSearch"),n.is("screen-lg")){elData(e,"dropdown-alignment-horizontal","right");var t=l.clientWidth;e.style.setProperty("min-width",t+"px","");var o=l.parentNode,r=i.offset(o).left+o.clientWidth-(i.offset(l).left+t),a=i.styleAsInt(window.getComputedStyle(o),"padding-bottom");e.style.setProperty("transform","translateX(-"+Math.ceil(r)+"px) translateY(-"+a+"px)","")}},callbackSelect:function(){return setTimeout(function(){t.parentByTag(l,"FORM").submit()},1),!0}});var s=o.getDropdownMenu(i.identify(elBySel(".pageHeaderSearchType"))),c=this._click.bind(this);elBySelAll("a[data-object-type]",s,function(e){e.addEventListener(WCF_CLICK_EVENT,c)});var u=elBySel('a[data-object-type="'+a+'"]',s);e.triggerEvent(u,WCF_CLICK_EVENT)},_click:function(e){e.preventDefault();var t=elById("pageHeader");t.classList.add("searchBarForceOpen"),window.setTimeout(function(){t.classList.remove("searchBarForceOpen")},10);var i=elData(e.currentTarget,"object-type"),n=elById("pageHeaderSearchParameters");n.innerHTML="";var o=elData(e.currentTarget,"extended-link");o&&(elBySel(".pageHeaderSearchExtendedLink").href=o);var r=elData(e.currentTarget,"parameters");r=r?JSON.parse(r):{},i&&(r["types[]"]=i);for(var a in r)if(r.hasOwnProperty(a)){var l=elCreate("input");l.type="hidden",l.name=a,l.value=r[a],n.appendChild(l)}elBySel(".pageHeaderSearchType > .button > .pageHeaderSearchTypeLabel",elById("pageHeaderSearchInputContainer")).textContent=e.currentTarget.textContent}}}),define("WoltLabSuite/Core/Ui/Smiley/Insert",["EventHandler","EventKey"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={_container:null,_editorId:"",init:function(e){if(this._editorId=e,this._container=elById("smilies-"+this._editorId),!this._container&&(this._container=elById(this._editorId+"SmiliesTabContainer"),!this._container))throw new Error("Unable to find the message tab menu container containing the smilies.");this._container.addEventListener("keydown",this._keydown.bind(this)),this._container.addEventListener("mousedown",this._mousedown.bind(this))},_keydown:function(e){var i=document.activeElement;if(i.classList.contains("jsSmiley"))if(t.ArrowLeft(e)||t.ArrowRight(e)||t.Home(e)||t.End(e)){e.preventDefault();var n=Array.prototype.slice.call(elBySelAll(".jsSmiley",e.currentTarget));t.ArrowLeft(e)&&n.reverse();var o=n.indexOf(i);t.Home(e)?o=0:t.End(e)?o=n.length-1:(o+=1)===n.length&&(o=0),n[o].focus()}else(t.Enter(e)||t.Space(e))&&(e.preventDefault(),this._insert(elBySel("img",i)))},_mousedown:function(e){var t=e.target.closest("li");if(this._container.contains(t)){e.preventDefault();var i=elBySel("img",t);i&&this._insert(i)}},_insert:function(t){e.fire("com.woltlab.wcf.redactor2","insertSmiley_"+this._editorId,{img:t})}},i}),define("WoltLabSuite/Core/Ui/Style/FontAwesome",["Language","Ui/Dialog","WoltLabSuite/Core/Ui/ItemList/Filter"],function(e,t,i){"use strict";var n=function(){};return n.prototype={setup:function(){},open:function(){},_click:function(){},_dialogSetup:function(){}},n}),define("WoltLabSuite/Core/Ui/Toggle/Input",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(t,i){if(this._element=elBySel(t),null===this._element)throw new Error("Unable to find element by selector '"+t+"'.");var n="INPUT"===this._element.nodeName?elAttr(this._element,"type"):"";if("checkbox"!==n&&"radio"!==n)throw new Error("Illegal element, expected input[type='checkbox'] or input[type='radio'].");this._options=e.extend({hide:[],show:[]},i),["hide","show"].forEach(function(e){var t,i,n;for(i=0,n=this._options[e].length;i<n;i++)if("string"!=typeof(t=this._options[e][i])&&!(t instanceof Element))throw new TypeError("The array '"+e+"' may only contain string selectors or DOM elements.")}.bind(this)),this._element.addEventListener("change",this._change.bind(this)),this._handleElements(this._options.show,this._element.checked),this._handleElements(this._options.hide,!this._element.checked)},_change:function(e){var t=e.currentTarget.checked;this._handleElements(this._options.show,t),this._handleElements(this._options.hide,!t)},_handleElements:function(e,t){for(var i,n,o=0,r=e.length;o<r;o++){if("string"==typeof(i=e[o])){if(null===(n=elBySel(i)))throw new Error("Unable to find element by selector '"+i+"'.");e[o]=i=n}window[t?"elShow":"elHide"](i)}}},t}),define("WoltLabSuite/Core/Ui/User/Editor",["Ajax","Language","StringUtil","Dom/Util","Ui/Dialog","Ui/Notification"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},_click:function(){},_submit:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},_dialogSetup:function(){}},a}),define("WoltLabSuite/Core/Controller/Condition/Page/Dependence",["Dom/ChangeListener","Dom/Traverse","EventHandler","ObjectMap"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={register:function(){},_checkVisibility:function(){},_hideDependentElement:function(){},_showDependentElement:function(){}},o}),define("WoltLabSuite/Core/Controller/Map/Route/Planner",["Dom/Traverse","Dom/Util","Language","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,o){function r(e,t){if(this._button=elById(e),null===this._button)throw new Error("Unknown button with id '"+e+"'");this._button.addEventListener("click",this._openDialog.bind(this)),this._destination=t}return r.prototype={_dialogSetup:function(){return{id:this._button.id+"Dialog",options:{onShow:this._initDialog.bind(this),title:i.get("wcf.map.route.planner")},source:'<div class="googleMapsDirectionsContainer" style="display: none;"><div class="googleMap"></div><div class="googleMapsDirections"></div></div><small class="googleMapsDirectionsGoogleLinkContainer"><a href="'+this._getGoogleMapsLink()+'" class="googleMapsDirectionsGoogleLink" target="_blank" style="display: none;">'+i.get("wcf.map.route.viewOnGoogleMaps")+"</a></small><dl><dt>"+i.get("wcf.map.route.origin")+'</dt><dd><input type="text" name="origin" class="long" autofocus /></dd></dl><dl style="display: none;"><dt>'+i.get("wcf.map.route.travelMode")+'</dt><dd><select name="travelMode"><option value="driving">'+i.get("wcf.map.route.travelMode.driving")+'</option><option value="walking">'+i.get("wcf.map.route.travelMode.walking")+'</option><option value="bicycling">'+i.get("wcf.map.route.travelMode.bicycling")+'</option><option value="transit">'+i.get("wcf.map.route.travelMode.transit")+"</option></select></dd></dl>"}},_calculateRoute:function(e){var t=n.getDialog(this).dialog;e.label&&(this._originInput.value=e.label),void 0===this._map&&(this._map=new google.maps.Map(elByClass("googleMap",t)[0],{disableDoubleClickZoom:WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),draggable:WCF.Location.GoogleMaps.Settings.get("draggable"),mapTypeId:google.maps.MapTypeId.ROADMAP,scaleControl:WCF.Location.GoogleMaps.Settings.get("scaleControl"),scrollwheel:WCF.Location.GoogleMaps.Settings.get("scrollwheel")}),this._directionsService=new google.maps.DirectionsService,this._directionsRenderer=new google.maps.DirectionsRenderer,this._directionsRenderer.setMap(this._map),this._directionsRenderer.setPanel(elByClass("googleMapsDirections",t)[0]),this._googleLink=elByClass("googleMapsDirectionsGoogleLink",t)[0]);var i={destination:this._destination,origin:e.location,provideRouteAlternatives:!0,travelMode:google.maps.TravelMode[this._travelMode.value.toUpperCase()]};o.show(),this._directionsService.route(i,this._setRoute.bind(this)),elAttr(this._googleLink,"href",this._getGoogleMapsLink(e.location,this._travelMode.value)),this._lastOrigin=e.location},_getGoogleMapsLink:function(e,t){if(e){var i="https://www.google.com/maps/dir/?api=1&origin="+e.lat()+","+e.lng()+"&destination="+this._destination.lat()+","+this._destination.lng();return t&&(i+="&travelmode="+t),i}return"https://www.google.com/maps/search/?api=1&query="+this._destination.lat()+","+this._destination.lng()},_initDialog:function(){if(!this._didInitDialog){var e=n.getDialog(this).dialog;this._originInput=elBySel('input[name="origin"]',e),new WCF.Location.GoogleMaps.LocationSearch(this._originInput,this._calculateRoute.bind(this)),this._travelMode=elBySel('select[name="travelMode"]',e),this._travelMode.addEventListener("change",this._updateRoute.bind(this)),this._didInitDialog=!0}},_openDialog:function(){n.open(this)},_setRoute:function(t,n){o.hide(),"OK"===n?(elShow(this._map.getDiv().parentNode),google.maps.event.trigger(this._map,"resize"),this._directionsRenderer.setDirections(t),elShow(e.parentByTag(this._travelMode,"DL")),elShow(this._googleLink),elInnerError(this._originInput,!1)):("OVER_QUERY_LIMIT"!==n&&"REQUEST_DENIED"!==n&&(n="NOT_FOUND"),elInnerError(this._originInput,i.get("wcf.map.route.error."+n.toLowerCase())))},_updateRoute:function(){this._calculateRoute({location:this._lastOrigin})}},r}),define("WoltLabSuite/Core/Controller/User/Notification/Settings",["Dictionary","Language","Dom/Traverse","Ui/SimpleDropdown"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={setup:function(){},_initGroup:function(){},_click:function(){},_createDropdown:function(){},_selectType:function(){}},o}),define("WoltLabSuite/Core/Form/Builder/Container/SuffixFormField",["EventHandler","Ui/SimpleDropdown"],function(e,t){"use strict";function i(i,n){this._formId=i,this._suffixField=elById(n),this._suffixDropdownMenu=t.getDropdownMenu(n+"_dropdown"),this._suffixDropdownToggle=elByClass("dropdownToggle",t.getDropdown(n+"_dropdown"))[0];for(var o=this._suffixDropdownMenu.children,r=0,a=o.length;r<a;r++)o[r].addEventListener("click",this._changeSuffixSelection.bind(this));e.add("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",this._destroyDropdown.bind(this))}return i.prototype={_changeSuffixSelection:function(e){if(!e.currentTarget.classList.contains("disabled")){
-for(var t=this._suffixDropdownMenu.children,i=0,n=t.length;i<n;i++)t[i]===e.currentTarget?t[i].classList.add("active"):t[i].classList.remove("active");this._suffixField.value=elData(e.currentTarget,"value"),this._suffixDropdownToggle.innerHTML=elData(e.currentTarget,"label")+' <span class="icon icon16 fa-caret-down pointer"></span>'}},_destroyDropdown:function(e){e.formId===this._formId&&t.destroy(this._suffixDropdownMenu.id)}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Acl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e),this._aclList=null}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._aclList.getData(),e},_readField:function(){},setAclList:function(e){this._aclList=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Captcha",["Core","./Field","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){return i.has(this._fieldId)?i.getData(this._fieldId):{}},_readField:function(){},destroy:function(){i.has(this._fieldId)&&i.delete(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Checkboxes",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=0,i=this._fields.length;t<i;t++)this._fields[t].checked&&e[this._fieldId].push(this._fields[t].value);return e},_readField:function(){this._fields=elBySelAll('input[name="'+this._fieldId+'[]"]')}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Checked",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=~~this._field.checked,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Date",["Core","WoltLabSuite/Core/Date/Picker","./Field"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{_getData:function(){var e={};return e[this._fieldId]=t.getValue(this._field),e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/ItemList",["Core","./Field","WoltLabSuite/Core/Ui/ItemList/Static"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,o=t.length;n<o;n++)t[n].objectId?e[this._fieldId][t[n].objectId]=t[n].value:e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/RadioButton",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){for(var e={},t=0,i=this._fields.length;t<i;t++)if(this._fields[t].checked){e[this._fieldId]=this._fields[t].value;break}return e},_readField:function(){this._fields=elBySelAll("input[name="+this._fieldId+"]")}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/SimpleAcl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e=[];elBySelAll('input[name="'+this._fieldId+'[group][]"]',void 0,function(t){e.push(~~t.value)});var t=[];elBySelAll('input[name="'+this._fieldId+'[user][]"]',void 0,function(e){t.push(~~e.value)});var i={};return i[this._fieldId]={group:e,user:t},i},_readField:function(){}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Tag",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,o=t.length;n<o;n++)e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/User",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){for(var e=i.getValues(this._fieldId),t=[],n=0,o=e.length;n<o;n++)t.push(e[n].value);var r={};return r[this._fieldId]=t.join(","),r}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Value",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._field.value,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/ValueI18n",["Core","./Field","WoltLabSuite/Core/Language/Input"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={},t=i.getValues(this._fieldId);return t.size>1?e[this._fieldId+"_i18n"]=t.toObject():e[this._fieldId]=t.get(0),e},destroy:function(){i.unregister(this._fieldId)}}),n}),define("WoltLabSuite/Core/Ui/Comment/Response/Add",["Core","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Notification","WoltLabSuite/Core/Ui/Comment/Add"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},getContainer:function(){},getContent:function(){},setContent:function(){},_submitGuestDialog:function(){},_submit:function(){},_getParameters:function(){},_validate:function(){},throwError:function(){},_showLoadingOverlay:function(){},_hideLoadingOverlay:function(){},_reset:function(){},_handleError:function(){},_getEditor:function(){},_insertMessage:function(){},_ajaxSuccess:function(){},_ajaxFailure:function(){},_ajaxSetup:function(){}},l}),define("WoltLabSuite/Core/Ui/Comment/Response/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll","WoltLabSuite/Core/Ui/Comment/Edit"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";var p=function(){};return p.prototype={init:function(){},rebuild:function(){},_click:function(){},_prepare:function(){},_showEditor:function(){},_restoreMessage:function(){},_save:function(){},_validate:function(){},throwError:function(){},_showMessage:function(){},_hideEditor:function(){},_restoreEditor:function(){},_destroyEditor:function(){},_getEditorId:function(){},_getObjectId:function(){},_ajaxFailure:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){}},p}),define("WoltLabSuite/Core/Ui/Page/Header/Fixed",["Core","EventHandler","Ui/Alignment","Ui/CloseOverlay","Ui/SimpleDropdown","Ui/Screen"],function(e,t,i,n,o,r){"use strict";var a,l,s,c,u,d,h,f=!1;return{init:function(){a=elById("pageHeader"),l=elById("pageHeaderContainer"),this._initSearchBar(),r.on("screen-md-down",{match:function(){f=!0},unmatch:function(){f=!1},setup:function(){f=!0}}),t.add("com.woltlab.wcf.Search","close",this._closeSearchBar.bind(this))},_initSearchBar:function(){c=elById("pageHeaderSearch"),c.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),s=elById("pageHeaderPanel"),u=elById("pageHeaderSearchInput"),d=elById("topMenu"),h=elById("userPanelSearchButton"),h.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),a.classList.contains("searchBarOpen")?this._closeSearchBar():this._openSearchBar()}.bind(this)),n.add("WoltLabSuite/Core/Ui/Page/Header/Fixed",function(){a.classList.contains("searchBarForceOpen")||this._closeSearchBar()}.bind(this)),t.add("com.woltlab.wcf.MainMenuMobile","more",function(t){"com.woltlab.wcf.search"===t.identifier&&(t.handler.close(!0),e.triggerEvent(h,WCF_CLICK_EVENT))}.bind(this))},_openSearchBar:function(){window.WCF.Dropdown.Interactive.Handler.closeAll(),a.classList.add("searchBarOpen"),h.parentNode.classList.add("open"),f||i.set(c,d,{horizontal:"right"}),c.style.setProperty("top",s.clientHeight+"px",""),u.focus(),window.setTimeout(function(){u.selectionStart=u.selectionEnd=u.value.length},1)},_closeSearchBar:function(){a.classList.remove("searchBarOpen"),h.parentNode.classList.remove("open"),["bottom","left","right","top"].forEach(function(e){c.style.removeProperty(e)}),u.blur();var e=elBySel(".pageHeaderSearchType",c);o.close(e.id)}}}),define("WoltLabSuite/Core/Ui/Page/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){if(n=e.extend({ajax:{className:"wcf\\data\\page\\PageAction"},callbackSuccess:null},n),"function"!=typeof n.callbackSuccess)throw new Error("Expected a valid callback function for 'callbackSuccess'.");i._super.prototype.init.call(this,t,n),this._pageId=0},setPageId:function(e){this._pageId=e},_getParameters:function(e){var t=i._super.prototype._getParameters.call(this,e);return t.objectIDs=[this._pageId],t},_ajaxSuccess:function(e){this._options.callbackSuccess(e)}}),i}),define("WoltLabSuite/Core/Ui/Page/Search/Handler",["Language","StringUtil","Dom/Util","Ui/Dialog","./Input"],function(e,t,i,n,o){"use strict";var r=null,a=null,l=null,s=null,c=null,u=null;return{open:function(t,i,o,a){r=o,n.open(this),n.setTitle(this,i),l.textContent=a?e.get(a):e.get("wcf.page.pageObjectID.search.terms"),this._getSearchInputHandler().setPageId(t)},_buildList:function(i){if(this._resetList(),!Array.isArray(i.returnValues)||0===i.returnValues.length)return void elInnerError(a,e.get("wcf.page.pageObjectID.search.noResults"));for(var n,o,r,l=0,s=i.returnValues.length;l<s;l++)o=i.returnValues[l],n=o.image,/^fa-/.test(n)&&(n='<span class="icon icon48 '+n+' pointer jsTooltip" title="'+e.get("wcf.global.select")+'"></span>'),r=elCreate("li"),elData(r,"object-id",o.objectID),r.innerHTML='<div class="box48">'+n+'<div><div class="containerHeadline"><h3><a href="'+t.escapeHTML(o.link)+'">'+t.escapeHTML(o.title)+"</a></h3>"+(o.description?"<p>"+o.description+"</p>":"")+"</div></div></div>",r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),c.appendChild(r);elShow(u)},_resetList:function(){elInnerError(a,!1),c.innerHTML="",elHide(u)},_getSearchInputHandler:function(){if(null===s){var e=this._buildList.bind(this);s=new o(elById("wcfUiPageSearchInput"),{callbackSuccess:e})}return s},_click:function(e){"A"!==e.target.nodeName&&(e.stopPropagation(),r(elData(e.currentTarget,"object-id")),n.close(this))},_dialogSetup:function(){return{id:"wcfUiPageSearchHandler",options:{onShow:function(){null===a&&(a=elById("wcfUiPageSearchInput"),l=a.parentNode.previousSibling.childNodes[0],c=elById("wcfUiPageSearchResultList"),u=elById("wcfUiPageSearchResultListContainer")),a.value="",elHide(u),c.innerHTML="",a.focus()},title:""},source:'<div class="section"><dl><dt><label for="wcfUiPageSearchInput">'+e.get("wcf.page.pageObjectID.search.terms")+'</label></dt><dd><input type="text" id="wcfUiPageSearchInput" class="long"></dd></dl></div><section id="wcfUiPageSearchResultListContainer" class="section sectionContainerList"><header class="sectionHeader"><h2 class="sectionTitle">'+e.get("wcf.page.pageObjectID.search.results")+'</h2></header><ul id="wcfUiPageSearchResultList" class="containerList wcfUiPageSearchResultList"></ul></section>'}}}}),define("WoltLabSuite/Core/Ui/Reaction/Profile/Loader",["Ajax","Core","Language"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){if(this._container=elById("likeList"),this._userID=e,this._reactionTypeID=null,this._targetType="received",this._options={parameters:[]},!this._userID)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'userID' given.");var t=elCreate("li");t.className="likeListMore showMore",this._noMoreEntries=elCreate("small"),this._noMoreEntries.innerHTML=i.get("wcf.like.reaction.noMoreEntries"),this._noMoreEntries.style.display="none",t.appendChild(this._noMoreEntries),this._loadButton=elCreate("button"),this._loadButton.className="small",this._loadButton.innerHTML=i.get("wcf.like.reaction.more"),this._loadButton.addEventListener(WCF_CLICK_EVENT,this._loadReactions.bind(this)),this._loadButton.style.display="none",t.appendChild(this._loadButton),this._container.appendChild(t),2===elBySel("#likeList > li").length?this._noMoreEntries.style.display="":this._loadButton.style.display="",this._setupReactionTypeButtons(),this._setupTargetTypeButtons()},_setupReactionTypeButtons:function(){for(var e,t=elBySelAll("#reactionType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeReactionTypeValue.bind(this,~~elData(e,"reaction-type-id")))},_setupTargetTypeButtons:function(){for(var e,t=elBySelAll("#likeType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeTargetType.bind(this,elData(e,"like-type")))},_changeTargetType:function(e){if("given"!==e&&"received"!==e)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'targetType' given.");e!==this._targetType&&(elBySel("#likeType .button.active").classList.remove("active"),elBySel('#likeType .button[data-like-type="'+e+'"]').classList.add("active"),this._targetType=e,this._reload())},_changeReactionTypeValue:function(e){var t=elBySel("#reactionType .button.active");t&&t.classList.remove("active"),this._reactionTypeID!==e?(elBySel('#reactionType .button[data-reaction-type-id="'+e+'"]').classList.add("active"),this._reactionTypeID=e):this._reactionTypeID=null,this._reload()},_reload:function(){for(var e=elBySelAll("#likeList > li:not(:first-child):not(:last-child)"),t=0,i=e.length;t<i;t++)this._container.removeChild(e[t]);elData(this._container,"last-like-time",0),this._loadReactions()},_loadReactions:function(){this._options.parameters.userID=this._userID,this._options.parameters.lastLikeTime=elData(this._container,"last-like-time"),this._options.parameters.targetType=this._targetType,this._options.parameters.reactionTypeID=this._reactionTypeID,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){e.returnValues.template?(elBySel("#likeList > li:nth-last-child(1)").insertAdjacentHTML("beforebegin",e.returnValues.template),elData(this._container,"last-like-time",e.returnValues.lastLikeTime),this._noMoreEntries.style.display="none",this._loadButton.style.display=""):(this._noMoreEntries.style.display="",this._loadButton.style.display="none")},_ajaxSetup:function(){return{data:{actionName:"load",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/Activity/Recent",["Ajax","Language","Dom/Util"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){this._containerId=e;var i=elById(this._containerId);this._list=elBySel(".recentActivityList",i);var n=elCreate("li");n.className="showMore",this._list.childElementCount?(n.innerHTML='<button class="small">'+t.get("wcf.user.recentActivity.more")+"</button>",n.children[0].addEventListener(WCF_CLICK_EVENT,this._showMore.bind(this))):n.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>",this._list.appendChild(n),this._showMoreItem=n,elBySelAll(".jsRecentActivitySwitchContext .button",i,function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),e.classList.contains("active")||this._switchContext()}.bind(this))}.bind(this))},_showMore:function(t){t.preventDefault(),this._showMoreItem.children[0].disabled=!0,e.api(this,{actionName:"load",parameters:{boxID:~~elData(this._list,"box-id"),filteredByFollowedUsers:elDataBool(this._list,"filtered-by-followed-users"),lastEventId:elData(this._list,"last-event-id"),lastEventTime:elData(this._list,"last-event-time"),userID:~~elData(this._list,"user-id")}})},_switchContext:function(){e.api(this,{actionName:"switchContext"},function(){window.location.hash="#"+this._containerId,window.location.reload()}.bind(this))},_ajaxSuccess:function(e){e.returnValues.template?(i.insertHtml(e.returnValues.template,this._showMoreItem,"before"),elData(this._list,"last-event-time",e.returnValues.lastEventTime),elData(this._list,"last-event-id",e.returnValues.lastEventID),this._showMoreItem.children[0].disabled=!1):this._showMoreItem.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>"},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Delete",["Ajax","EventHandler","Language","Ui/Confirmation","Ui/Notification"],function(e,t,i,n,o){"use strict";var r,a=0;return{init:function(e){r=elBySel(".jsButtonDeleteCoverPhoto"),r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),a=e,t.add("com.woltlab.wcf.user","coverPhoto",function(e){"string"==typeof e.url&&e.url.length>0&&elShow(r.parentNode)})},_click:function(t){t.preventDefault(),n.show({confirm:e.api.bind(e,this),message:i.get("wcf.user.coverPhoto.delete.confirmMessage")})},_ajaxSuccess:function(e){elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+e.returnValues.url+")",""),elHide(r.parentNode),o.show()},_ajaxSetup:function(){return{data:{actionName:"deleteCoverPhoto",className:"wcf\\data\\user\\UserProfileAction",parameters:{userID:a}}}}}}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Upload",["Core","EventHandler","Upload","Ui/Notification","Ui/Dialog"],function(e,t,i,n,o){"use strict";function r(e){i.call(this,"coverPhotoUploadButtonContainer","coverPhotoUploadPreview",{action:"uploadCoverPhoto",className:"wcf\\data\\user\\UserProfileAction"}),this._userId=e}return e.inherit(r,i,{_getParameters:function(){return{userID:this._userId}},_success:function(e,i){elInnerError(this._button,i.returnValues.errorMessage),this._target.innerHTML="",i.returnValues.url&&(elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+i.returnValues.url+")",""),o.close("userProfileCoverPhotoUpload"),n.show(),t.fire("com.woltlab.wcf.user","coverPhoto",{url:i.returnValues.url}))}}),r}),define("WoltLabSuite/Core/Ui/User/Trophy/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination","Dom/ChangeListener","List"],function(e,t,i,n,o,r,a,l){"use strict";function s(){this.init()}return s.prototype={init:function(){this._cache=new i,this._knownElements=new l,this._options={className:"wcf\\data\\user\\trophy\\UserTrophyAction",parameters:{}},this._rebuild(),a.add("WoltLabSuite/Core/Ui/User/Trophy/List",this._rebuild.bind(this))},_rebuild:function(){elBySelAll(".userTrophyOverlayList",void 0,function(e){this._knownElements.has(e)||(e.addEventListener(WCF_CLICK_EVENT,this._open.bind(this,elData(e,"user-id"))),this._knownElements.add(e))}.bind(this))},_open:function(e,t){t.preventDefault(),this._currentPageNo=1,this._currentUser=e,this._showPage()},_showPage:function(t){if(void 0!==t&&(this._currentPageNo=t),this._cache.has(this._currentUser)){if(0!==this._cache.get(this._currentUser).get("pageCount")&&(this._currentPageNo<1||this._currentPageNo>this._cache.get(this._currentUser).get("pageCount")))throw new RangeError("pageNo must be between 1 and "+this._cache.get(this._currentUser).get("pageCount")+" ("+this._currentPageNo+" given).")}else this._cache.set(this._currentUser,new i);if(this._cache.get(this._currentUser).has(this._currentPageNo)){var n=o.open(this,this._cache.get(this._currentUser).get(this._currentPageNo));if(o.setTitle("userTrophyListOverlay",this._cache.get(this._currentUser).get("title")),this._cache.get(this._currentUser).get("pageCount")>1){var a=elBySel(".jsPagination",n.content);null!==a&&new r(a,{activePage:this._currentPageNo,maxPage:this._cache.get(this._currentUser).get("pageCount"),callbackSwitch:this._showPage.bind(this)})}}else this._options.parameters.pageNo=this._currentPageNo,this._options.parameters.userID=this._currentUser,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&this._cache.get(this._currentUser).set("pageCount",~~e.returnValues.pageCount),this._cache.get(this._currentUser).set(this._currentPageNo,e.returnValues.template),this._cache.get(this._currentUser).set("title",e.returnValues.title),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserTrophyList",className:this._options.className}}},_dialogSetup:function(){return{id:"userTrophyListOverlay",options:{title:""},source:null}}},s}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Label",["Core","Dom/Util","Language","Ui/SimpleDropdown"],function(e,t,i,n){"use strict";function o(e,t,i){this.init(e,t,i)}return o.prototype={init:function(o,r,a){this._formFieldContainer=elById(o+"Container"),this._labelChooser=elByClass("labelChooser",this._formFieldContainer)[0],this._options=e.extend({forceSelection:!1,showWithoutSelection:!1},a),this._input=elCreate("input"),this._input.type="hidden",this._input.id=o,this._input.name=o,this._input.value=~~r,this._formFieldContainer.appendChild(this._input);var l=t.identify(this._labelChooser),s=n.getDropdownMenu(l);null===s&&(n.init(elByClass("dropdownToggle",this._labelChooser)[0]),s=n.getDropdownMenu(l));var c=null;if(this._options.showWithoutSelection||!this._options.forceSelection){c=elCreate("ul"),s.appendChild(c);var u=elCreate("li");u.className="dropdownDivider",c.appendChild(u)}if(this._options.showWithoutSelection){var d=elCreate("li");elData(d,"label-id",-1),this._blockScroll(d),c.appendChild(d);var h=elCreate("span");d.appendChild(h);var f=elCreate("span");f.className="badge label",f.innerHTML=i.get("wcf.label.withoutSelection"),h.appendChild(f)}if(!this._options.forceSelection){var d=elCreate("li");elData(d,"label-id",0),this._blockScroll(d),c.appendChild(d);var h=elCreate("span");d.appendChild(h);var f=elCreate("span");f.className="badge label",f.innerHTML=i.get("wcf.label.none"),h.appendChild(f)}elBySelAll("li:not(.dropdownDivider)",s,function(e){e.addEventListener("click",this._click.bind(this)),r&&~~elData(e,"label-id")===r&&this._selectLabel(e)}.bind(this))},_blockScroll:function(e){e.addEventListener("wheel",function(e){e.preventDefault()},{passive:!1})},_click:function(e){e.preventDefault(),this._selectLabel(e.currentTarget,!1)},_selectLabel:function(e){var t=elData(e,"label-id");t||(t=0);var i=elBySel("span > span",e),n=elBySel(".dropdownToggle > span",this._labelChooser);n.className=i.className,n.textContent=i.textContent,this._input.value=t}},o}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Rating",["Dictionary","Environment"],function(e,t){"use strict";function i(e,t,i,n){this.init(e,t,i,n)}return i.prototype={init:function(t,i,n,o){if(this._field=elBySel("#"+t+"Container"),null===this._field)throw new Error("Unknown field with id '"+t+"'");this._input=elCreate("input"),this._input.id=t,this._input.name=t,this._input.type="hidden",this._input.value=i,this._field.appendChild(this._input),this._activeCssClasses=n,this._defaultCssClasses=o,this._ratingElements=new e;var r=elBySel(".ratingList",this._field);r.addEventListener("mouseleave",this._restoreRating.bind(this)),elBySelAll("li",r,function(e){e.classList.contains("ratingMetaButton")?(e.addEventListener("click",this._metaButtonClick.bind(this)),e.addEventListener("mouseenter",this._restoreRating.bind(this))):(this._ratingElements.set(~~elData(e,"rating"),e),e.addEventListener("click",this._listItemClick.bind(this)),e.addEventListener("mouseenter",this._listItemMouseEnter.bind(this)),e.addEventListener("mouseleave",this._listItemMouseLeave.bind(this)))}.bind(this))},_listItemClick:function(e){this._input.value=~~elData(e.currentTarget,"rating"),"desktop"!==t.platform()&&this._restoreRating()},_listItemMouseEnter:function(e){var t=elData(e.currentTarget,"rating");this._ratingElements.forEach(function(e,i){var n=elByClass("icon",e)[0];this._toggleIcon(n,~~i<=~~t)}.bind(this))},_listItemMouseLeave:function(){this._ratingElements.forEach(function(e){var t=elByClass("icon",e)[0];this._toggleIcon(t,!1)}.bind(this))},_metaButtonClick:function(e){"removeRating"===elData(e.currentTarget,"action")&&(this._input.value="",this._listItemMouseLeave())},_restoreRating:function(){this._ratingElements.forEach(function(e,t){var i=elByClass("icon",e)[0];this._toggleIcon(i,~~t<=~~this._input.value)}.bind(this))},_toggleIcon:function(e,t){if(t=t||!1){for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.remove(this._defaultCssClasses[i]);for(var i=0;i<this._activeCssClasses.length;i++)e.classList.add(this._activeCssClasses[i])}else{for(var i=0;i<this._activeCssClasses.length;i++)e.classList.remove(this._activeCssClasses[i]);for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.add(this._defaultCssClasses[i])}}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract",["./Manager"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={checkDependency:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract.checkDependency!")},getDependentNode:function(){return this._dependentElement},getField:function(){return this._field},getFields:function(){return this._fields},init:function(t,i){if(this._dependentElement=elById(t),null===this._dependentElement)throw new Error("Unknown dependent element with container id '"+t+"Container'.");if(this._field=elById(i),null===this._field){if(this._fields=[],elBySelAll("input[type=radio][name="+i+"]",void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length&&(elBySelAll('input[type=checkbox][name="'+i+'[]"]',void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length))throw new Error("Unknown field with id '"+i+"'.")}else if(this._fields=[this._field],"INPUT"===this._field.tagName&&"radio"===this._field.type&&""!==elData(this._field,"no-input-id")){if(this._noField=elById(elData(this._field,"no-input-id")),null===this._noField)throw new Error("Cannot find 'no' input field for input field '"+i+"'");this._fields.push(this._noField)}e.addDependency(this)}},t}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Empty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!1;return!0}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return!this._field.checked;case"radio":return!(!this._noField||!this._noField.checked)||!this._field.checked;default:return 0===this._field.value.trim().length}case"SELECT":return this._field.multiple?0===elBySelAll("option:checked",this._field).length:0==this._field.value||0===this._field.value.length;case"TEXTAREA":return 0===this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/NonEmpty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!0;return!1}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return this._field.checked;case"radio":return(!this._noField||!this._noField.checked)&&this._field.checked;default:return 0!==this._field.value.trim().length}case"SELECT":return this._field.multiple?0!==elBySelAll("option:checked",this._field).length:0!=this._field.value&&0!==this._field.value.length;case"TEXTAREA":return 0!==this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Value",["./Abstract","Core","./Manager"],function(e,t,i){"use strict";function n(e,t,i){this.init(e,t),this._isNegated=!1}return t.inherit(n,e,{checkDependency:function(){if(!this._values)throw new Error("Values have not been set.");var e=[];if(this._field){if(i.isHiddenByDependencies(this._field))return!1;e.push(this._field.value)}else for(var t,n=0,o=this._fields.length;n<o;n++)if(t=this._fields[n],t.checked){if(i.isHiddenByDependencies(t))return!1;e.push(t.value)}for(var n=0,o=this._values.length;n<o;n++)for(var r=0,a=e.length;r<a;r++)if(this._values[n]==e[r])return!this._isNegated;return!!this._isNegated},negate:function(e){return this._isNegated=e,this},values:function(e){return this._values=e,this}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage",["Core","WoltLabSuite/Core/Language/Chooser","../Value"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{destroy:function(){t.removeChooser(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Attachment",["Core","../Value"],function(e,t){"use strict";function i(e){this.init(e+"_tmpHash")}return e.inherit(i,t,{}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Poll",["Core","../Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){return this._pollEditor.getData()},_readField:function(){},setPollEditor:function(e){this._pollEditor=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Abstract",["EventHandler","../Manager"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={checkContainer:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Container.checkContainer!")},init:function(e){if("string"!=typeof e)throw new TypeError("Container id has to be a string.");if(this._container=elById(e),null===this._container)throw new Error("Unknown container with id '"+e+"'.");t.addContainerCheckCallback(this.checkContainer.bind(this))}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default",["./Abstract","Core","../Manager"],function(e,t,i){"use strict";function n(e){this.init(e)}return t.inherit(n,e,{checkContainer:function(){if(!elDataBool(this._container,"ignore-dependencies")&&!i.isHiddenByDependencies(this._container)){var e=!elIsHidden(this._container),t=!1,n=this._container.children,o=0;if("H2"===this._container.children.item(0).tagName||"HEADER"===this._container.children.item(0).tagName)var o=1;for(var r=o,a=n.length;r<a;r++)if(!elIsHidden(n.item(r))){t=!0;break}e!==t&&(t?elShow(this._container):elHide(this._container),i.checkContainers())}}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Tab",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,o){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=this._container.children,a=0,l=r.length;a<l;a++)if(!elIsHidden(r.item(a))){t=!0;break}if(e!==t){var s=elBySel("#"+i.identify(this._container.parentNode)+" > nav > ul > li[data-name="+this._container.id+"]",this._container.parentNode.parentNode);if(null===s)throw new Error("Cannot find tab menu entry for tab '"+this._container.id+"'.");if(t)elShow(this._container),elShow(s);else{elHide(this._container),elHide(s);var c=o.getTabMenu(i.identify(s.closest(".tabMenuContainer")));c.getActiveTab()===s&&c.selectFirstVisible()}n.checkContainers()}}}}),r}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/TabMenu",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,o){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=elBySelAll("#"+i.identify(this._container)+" > nav > ul > li",this._container.parentNode),a=0,l=r.length;a<l;a++)if(!elIsHidden(r[a])){t=!0;break}e!==t&&(t?(elShow(this._container),o.getTabMenu(i.identify(this._container)).selectFirstVisible()):elHide(this._container),n.checkContainers())}}}),r}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Abstract",["Ajax","Dom/Util"],function(e,t){"use strict";function i(e,t){}return i.prototype={init:function(e,t){this._userId=e,this._isActive=!1!==t,this._initButton(),this._updateButton()},_initButton:function(){var e=elCreate("a");e.href="#",e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this));var i=elCreate("li");i.appendChild(e);var n=elBySel('.userProfileButtonMenu[data-menu="interaction"]');t.prepend(i,n),this._button=e,this._listItem=i},_toggle:function(t){t.preventDefault(),e.api(this,{actionName:this._getAjaxActionName(),parameters:{data:{userID:this._userId}}})},_updateButton:function(){
-this._button.textContent=this._getLabel(),this._listItem.classList[this._isActive?"add":"remove"]("active")},_getLabel:function(){throw new Error("Implement me!")},_getAjaxActionName:function(){throw new Error("Implement me!")},_ajaxSuccess:function(){throw new Error("Implement me!")},_ajaxSetup:function(){throw new Error("Implement me!")}},i}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Follow",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={_getLabel:function(){},_getAjaxActionName:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},init:function(){},_initButton:function(){},_toggle:function(){},_updateButton:function(){}},o}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Ignore",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={_getLabel:function(){},_getAjaxActionName:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},init:function(){},_initButton:function(){},_toggle:function(){},_updateButton:function(){}},o}),function(e){e.matches=e.matches||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector,e.closest=e.closest||function(e){for(var t=this;t&&!t.matches(e);)t=t.parentElement;return t}}(Element.prototype),define("closest",function(){}),function(e){function t(){for(;n.length&&"function"==typeof n[0];)n.shift()()}var i=e.require,n=[],o=0;e.orgRequire=i,e.require=function(r,a,l){if(!Array.isArray(r))return i.apply(e,arguments);var s=new Promise(function(e,a){var l=o++;n.push(l),i(r,function(){var i=arguments;n[n.indexOf(l)]=function(){e(i)},t()},function(e){n[n.indexOf(l)]=function(){a(e)},t()})});return a&&(s=s.then(function(t){return a.apply(e,t)})),l&&s.catch(l),s},e.require.config=i.config}(window),define("require.linearExecution",function(){});
\ No newline at end of file
+var requirejs,require,define;!function(global,Promise,undef){function commentReplace(e,t){return t||""}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return e&&hasProp(e,t)&&e[t]}function obj(){return Object.create(null)}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,n){return t&&eachProp(t,function(t,o){!i&&hasProp(e,o)||(!n||"object"!=typeof t||!t||Array.isArray(t)||"function"==typeof t||t instanceof RegExp?e[o]=t:(e[o]||(e[o]={}),mixin(e[o],t,i,n)))}),e}function getGlobal(e){if(!e)return e;var t=global;return e.split(".").forEach(function(e){t=t[e]}),t}function newContext(e){function t(e){var t,i,n=e.length;for(t=0;t<n;t++)if("."===(i=e[t]))e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;t>0&&(e.splice(t-1,2),t-=2)}}function i(e,i,n){var o,r,a,l,s,c,u,d,h,f,p=i&&i.split("/"),g=p,m=k.map,v=m&&m["*"];if(e&&(e=e.split("/"),c=e.length-1,k.nodeIdCompat&&jsSuffixRegExp.test(e[c])&&(e[c]=e[c].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&p&&(g=p.slice(0,p.length-1),e=g.concat(e)),t(e),e=e.join("/")),n&&m&&(p||v)){r=e.split("/");e:for(a=r.length;a>0;a-=1){if(s=r.slice(0,a).join("/"),p)for(l=p.length;l>0;l-=1)if((o=getOwn(m,p.slice(0,l).join("/")))&&(o=getOwn(o,s))){u=o,d=a;break e}!h&&v&&getOwn(v,s)&&(h=getOwn(v,s),f=a)}!u&&h&&(u=h,d=f),u&&(r.splice(0,d,u),e=r.join("/"))}return getOwn(k.pkgs,e)||e}function n(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t}function o(e){var t,i,n,o;for(t=0;t<queue.length;t+=1){if("string"!=typeof queue[t][0]){if(!e)break;queue[t].unshift(e),e=undef}n=queue.shift(),i=n[0],t-=1,i in D||i in T||(i in N?C.apply(undef,n):T[i]=n)}e&&(o=getOwn(k.shim,e)||{},C(e,o.deps||[],o.exportsFn))}function r(e,t){var n=function(i,r,a,l){var s,c;if(t&&o(),"string"==typeof i){if(A[i])return A[i](e);if(!((s=E(i,e,!0).id)in D))throw new Error("Not loaded: "+s);return D[s]}return i&&!Array.isArray(i)&&(c=i,i=undef,Array.isArray(r)&&(i=r,r=a,a=l),t)?n.config(c)(i,r,a):(r=r||function(){return slice.call(arguments,0)},V.then(function(){return o(),C(undef,i||[],r,a,e)}))};return n.isBrowser="undefined"!=typeof document&&"undefined"!=typeof navigator,n.nameToUrl=function(e,t,i){var o,r,a,l,s,c,u,d=getOwn(k.pkgs,e);if(d&&(e=d),u=getOwn(H,e))return n.nameToUrl(u,t,i);if(urlRegExp.test(e))s=e+(t||"");else{for(o=k.paths,r=e.split("/"),a=r.length;a>0;a-=1)if(l=r.slice(0,a).join("/"),c=getOwn(o,l)){Array.isArray(c)&&(c=c[0]),r.splice(0,a,c);break}s=r.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+s}return k.urlArgs&&!/^blob\:/.test(s)?s+k.urlArgs(e,s):s},n.toUrl=function(t){var o,r=t.lastIndexOf("."),a=t.split("/")[0],l="."===a||".."===a;return-1!==r&&(!l||r>1)&&(o=t.substring(r,t.length),t=t.substring(0,r)),n.nameToUrl(i(t,e),o,!0)},n.defined=function(t){return E(t,e,!0).id in D},n.specified=function(t){return(t=E(t,e,!0).id)in D||t in N},n}function a(e,t,i){e&&(D[e]=i,requirejs.onResourceLoad&&requirejs.onResourceLoad(I,t.map,t.deps)),t.finished=!0,t.resolve(i)}function l(e,t){e.finished=!0,e.rejected=!0,e.reject(t)}function s(e){return function(t){return i(t,e,!0)}}function c(e){e.factoryCalled=!0;var t,i=e.map.id;try{t=I.execCb(i,e.factory,e.values,D[i])}catch(t){return l(e,t)}i?t===undef&&(e.cjsModule?t=e.cjsModule.exports:e.usingExports&&(t=D[i])):M.splice(M.indexOf(e),1),a(i,e,t)}function u(e,t){this.rejected||this.depDefined[t]||(this.depDefined[t]=!0,this.depCount+=1,this.values[t]=e,this.depending||this.depCount!==this.depMax||c(this))}function d(e,t){var i={};return i.promise=new Promise(function(t,n){i.resolve=t,i.reject=function(t){e||M.splice(M.indexOf(i),1),n(t)}}),i.map=e?t||E(e):{},i.depCount=0,i.depMax=0,i.values=[],i.depDefined=[],i.depFinished=u,i.map.pr&&(i.deps=[E(i.map.pr)]),i}function h(e,t){var i;return e?(i=e in N&&N[e])||(i=N[e]=d(e,t)):(i=d(),M.push(i)),i}function f(e,t){return function(i){e.rejected||(i.dynaId||(i.dynaId="id"+(F+=1),i.requireModules=[t]),l(e,i))}}function p(e,t,i,n){i.depMax+=1,L(e,t).then(function(e){i.depFinished(e,n)},f(i,e.id)).catch(f(i,i.map.id))}function g(e){function t(t){i||a(e,h(e),t)}var i;return t.error=function(t){h(e).reject(t)},t.fromText=function(t,n){var r=h(e),a=E(E(e).n),s=a.id;i=!0,r.factory=function(e,t){return t},n&&(t=n),hasProp(k.config,e)&&(k.config[s]=k.config[e]);try{y.exec(t)}catch(e){l(r,new Error("fromText eval for "+s+" failed: "+e))}o(s),r.deps=[a],p(a,null,r,r.deps.length)},t}function m(e,t,i){e.load(t.n,r(i),g(t.id),k)}function v(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function b(e,t,i){var n=e.map.id;t[n]=!0,!e.finished&&e.deps&&e.deps.forEach(function(n){var o=n.id,r=!hasProp(A,o)&&h(o,n);!r||r.finished||i[o]||(hasProp(t,o)?e.deps.forEach(function(t,i){t.id===o&&e.depFinished(D[o],i)}):b(r,t,i))}),i[n]=!0}function _(e){var t,i,n,o=[],r=1e3*k.waitSeconds,a=r&&W+r<(new Date).getTime();if(0===j&&(e?e.finished||b(e,{},{}):M.length&&M.forEach(function(e){b(e,{},{})})),a){for(i in N)n=N[i],n.finished||o.push(n.map.id);t=new Error("Timeout for modules: "+o),t.requireModules=o,y.onError(t)}else(j||M.length)&&(S||(S=!0,setTimeout(function(){S=!1,_()},70)))}function w(e){return setTimeout(function(){e.dynaId&&O[e.dynaId]||(O[e.dynaId]=!0,y.onError(e))}),e}var y,C,E,L,A,S,x,I,D=obj(),T=obj(),k={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},B=obj(),M=[],N=obj(),U=obj(),P=obj(),j=0,W=(new Date).getTime(),F=0,O=obj(),R=obj(),H=obj(),V=Promise.resolve();return x="function"==typeof importScripts?function(e){var t=e.url;R[t]||(R[t]=!0,h(e.id),importScripts(t),o(e.id))}:function(e){var t,i=e.id,n=e.url;R[n]||(R[n]=!0,t=document.createElement("script"),t.setAttribute("data-requiremodule",i),t.type=k.scriptType||"text/javascript",t.charset="utf-8",t.async=!0,j+=1,t.addEventListener("load",function(){j-=1,o(i)},!1),t.addEventListener("error",function(){j-=1;var e,n=getOwn(k.paths,i);if(n&&Array.isArray(n)&&n.length>1){t.parentNode.removeChild(t),n.shift();var o=h(i);o.map=E(i),o.map.url=y.nameToUrl(i),x(o.map)}else e=new Error("Load failed: "+i+": "+t.src),e.requireModules=[i],h(i).reject(e)},!1),t.src=n,10===document.documentMode?asap.then(function(){document.head.appendChild(t)}):document.head.appendChild(t))},L=function(e,t){var i,n,o=e.id,r=k.shim[o];if(o in T)i=T[o],delete T[o],C.apply(undef,i);else if(!(o in N))if(e.pr){if(!(n=getOwn(H,o)))return L(E(e.pr)).then(function(i){var n=e.prn?e:E(o,t,!0),r=n.id,a=getOwn(k.shim,r);return r in P||(P[r]=!0,a&&a.deps?y(a.deps,function(){m(i,n,t)}):m(i,n,t)),h(r).promise});e.url=y.nameToUrl(n),x(e)}else r&&r.deps?y(r.deps,function(){x(e)}):x(e);return h(o).promise},E=function(e,t,n){if("string"!=typeof e)return e;var o,r,a,l,c,u,d=e+" & "+(t||"")+" & "+!!n;return a=v(e),l=a[0],e=a[1],!l&&d in B?B[d]:(l&&(l=i(l,t,n),o=l in D&&D[l]),l?o&&o.normalize?(e=o.normalize(e,s(t)),u=!0):e=-1===e.indexOf("!")?i(e,t,n):e:(e=i(e,t,n),a=v(e),l=a[0],e=a[1],r=y.nameToUrl(e)),c={id:l?l+"!"+e:e,n:e,pr:l,url:r,prn:l&&u},l||(B[d]=c),c)},A={require:function(e){return r(e)},exports:function(e){var t=D[e];return void 0!==t?t:D[e]={}},module:function(e){return{id:e,uri:"",exports:A.exports(e),config:function(){return getOwn(k.config,e)||{}}}}},C=function(e,t,i,n,o){if(e){if(e in U)return;U[e]=!0}var r=h(e);return t&&!Array.isArray(t)&&(i=t,t=[]),t=t?slice.call(t,0):null,n||(hasProp(k,"defaultErrback")?k.defaultErrback&&(n=k.defaultErrback):n=w),n&&r.promise.catch(n),o=o||e,"function"==typeof i?(!t.length&&i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t)),r.factory=i,r.deps=t,r.depending=!0,t.forEach(function(i,n){var a;t[n]=a=E(i,o,!0),i=a.id,"require"===i?r.values[n]=A.require(e):"exports"===i?(r.values[n]=A.exports(e),r.usingExports=!0):"module"===i?r.values[n]=r.cjsModule=A.module(e):void 0===i?r.values[n]=void 0:p(a,o,r,n)}),r.depending=!1,r.depCount===r.depMax&&c(r)):e&&a(e,r,i),W=(new Date).getTime(),e||_(r),r.promise},y=r(null,!0),y.config=function(t){if(t.context&&t.context!==e){var i=getOwn(contexts,t.context);return i?i.req.config(t):newContext(t.context).config(t)}if(B=obj(),t.baseUrl&&"/"!==t.baseUrl.charAt(t.baseUrl.length-1)&&(t.baseUrl+="/"),"string"==typeof t.urlArgs){var o=t.urlArgs;t.urlArgs=function(e,t){return(-1===t.indexOf("?")?"?":"&")+o}}var r=k.shim,a={paths:!0,bundles:!0,config:!0,map:!0};return eachProp(t,function(e,t){a[t]?(k[t]||(k[t]={}),mixin(k[t],e,!0,!0)):k[t]=e}),t.bundles&&eachProp(t.bundles,function(e,t){e.forEach(function(e){e!==t&&(H[e]=t)})}),t.shim&&(eachProp(t.shim,function(e,t){Array.isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=n(e)),r[t]=e}),k.shim=r),t.packages&&t.packages.forEach(function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(k.paths[i]=e.location),k.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),(t.deps||t.callback)&&y(t.deps,t.callback),y},y.onError=function(e){throw e},I={id:e,defined:D,waiting:T,config:k,deferreds:N,req:y,execCb:function(e,t,i,n){return t.apply(n,i)}},contexts[e]=I,y}if(!Promise)throw new Error("No Promise implementation available");var topReq,dataMain,src,subPath,bootstrapConfig=requirejs||require,hasOwn=Object.prototype.hasOwnProperty,contexts={},queue=[],currDirRegExp=/^\.\//,urlRegExp=/^\/|\:|\?|\.js$/,commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,slice=Array.prototype.slice;if("function"!=typeof requirejs){var asap=Promise.resolve(void 0);requirejs=topReq=newContext("_"),"function"!=typeof require&&(require=topReq),topReq.exec=function(text){return eval(text)},topReq.contexts=contexts,define=function(){queue.push(slice.call(arguments,0))},define.amd={jQuery:!0},bootstrapConfig&&topReq.config(bootstrapConfig),topReq.isBrowser&&!contexts._.config.skipDataMain&&(dataMain=document.querySelectorAll("script[data-main]")[0],(dataMain=dataMain&&dataMain.getAttribute("data-main"))&&(dataMain=dataMain.replace(jsSuffixRegExp,""),bootstrapConfig&&bootstrapConfig.baseUrl||-1!==dataMain.indexOf("!")||(src=dataMain.split("/"),dataMain=src.pop(),subPath=src.length?src.join("/")+"/":"./",topReq.config({baseUrl:subPath})),topReq([dataMain])))}}(this,"undefined"!=typeof Promise?Promise:void 0),define("requireLib",function(){}),requirejs.config({paths:{enquire:"3rdParty/enquire",favico:"3rdParty/favico","perfect-scrollbar":"3rdParty/perfect-scrollbar",Pica:"3rdParty/pica",prism:"3rdParty/prism",zxcvbn:"3rdParty/zxcvbn"},shim:{enquire:{exports:"enquire"},favico:{exports:"Favico"},"perfect-scrollbar":{exports:"PerfectScrollbar"}},map:{"*":{Ajax:"WoltLabSuite/Core/Ajax",AjaxJsonp:"WoltLabSuite/Core/Ajax/Jsonp",AjaxRequest:"WoltLabSuite/Core/Ajax/Request",CallbackList:"WoltLabSuite/Core/CallbackList",ColorUtil:"WoltLabSuite/Core/ColorUtil",Core:"WoltLabSuite/Core/Core",DateUtil:"WoltLabSuite/Core/Date/Util",Devtools:"WoltLabSuite/Core/Devtools",Dictionary:"WoltLabSuite/Core/Dictionary","Dom/ChangeListener":"WoltLabSuite/Core/Dom/Change/Listener","Dom/Traverse":"WoltLabSuite/Core/Dom/Traverse","Dom/Util":"WoltLabSuite/Core/Dom/Util",Environment:"WoltLabSuite/Core/Environment",EventHandler:"WoltLabSuite/Core/Event/Handler",EventKey:"WoltLabSuite/Core/Event/Key",Language:"WoltLabSuite/Core/Language",List:"WoltLabSuite/Core/List",ObjectMap:"WoltLabSuite/Core/ObjectMap",Permission:"WoltLabSuite/Core/Permission",StringUtil:"WoltLabSuite/Core/StringUtil","Ui/Alignment":"WoltLabSuite/Core/Ui/Alignment","Ui/CloseOverlay":"WoltLabSuite/Core/Ui/CloseOverlay","Ui/Confirmation":"WoltLabSuite/Core/Ui/Confirmation","Ui/Dialog":"WoltLabSuite/Core/Ui/Dialog","Ui/Notification":"WoltLabSuite/Core/Ui/Notification","Ui/ReusableDropdown":"WoltLabSuite/Core/Ui/Dropdown/Reusable","Ui/Screen":"WoltLabSuite/Core/Ui/Screen","Ui/Scroll":"WoltLabSuite/Core/Ui/Scroll","Ui/SimpleDropdown":"WoltLabSuite/Core/Ui/Dropdown/Simple","Ui/TabMenu":"WoltLabSuite/Core/Ui/TabMenu",Upload:"WoltLabSuite/Core/Upload",User:"WoltLabSuite/Core/User"}},waitSeconds:0}),define("jquery",[],function(){return window.jQuery}),define("require.config",function(){}),function(e,t){e.elAttr=function(e,t,i){if(void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elAttrBool=function(e,t){var i=elAttr(e,t);return"1"===i||"true"===i},e.elByClass=function(e,i){return(i||t).getElementsByClassName(e)},e.elById=function(e){return t.getElementById(e)},e.elBySel=function(e,i){return(i||t).querySelector(e)},e.elBySelAll=function(e,i,n){var o=(i||t).querySelectorAll(e);return"function"==typeof n&&Array.prototype.forEach.call(o,n),o},e.elByTag=function(e,i){return(i||t).getElementsByTagName(e)},e.elCreate=function(e){return t.createElement(e)},e.elClosest=function(e,t){if(!(e instanceof Node))throw new TypeError("Provided element is not a Node.");return e.nodeType===Node.TEXT_NODE&&null===(e=e.parentNode)?null:("string"!=typeof t&&(t=""),0===t.length?e:e.closest(t))},e.elData=function(e,t,i){if(t="data-"+t,void 0===i)return e.getAttribute(t)||"";e.setAttribute(t,i)},e.elDataBool=function(e,t){var i=elData(e,t);return"1"===i||"true"===i},e.elHide=function(e){e.style.setProperty("display","none","")},e.elIsHidden=function(e){return"none"===e.style.getPropertyValue("display")},e.elInnerError=function(e,t,i){var n=e.parentNode;if(null===n)throw new Error("Only elements that have a parent element or document are valid.");if("string"!=typeof t){if(void 0!==t&&null!==t&&!1!==t)throw new TypeError("The error message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.");t=""}var o=e.nextElementSibling;return null!==o&&"SMALL"===o.nodeName&&o.classList.contains("innerError")||(""===t?o=null:(o=elCreate("small"),o.className="innerError",n.insertBefore(o,e.nextSibling))),""===t?null!==o&&(n.removeChild(o),o=null):o[i?"innerHTML":"textContent"]=t,o},e.elRemove=function(e){e.parentNode.removeChild(e)},e.elShow=function(e){e.style.removeProperty("display")},e.elToggle=function(e){"none"===e.style.getPropertyValue("display")?elShow(e):elHide(e)},e.forEach=function(e,t){for(var i=0,n=e.length;i<n;i++)t(e[i],i)},e.objOwns=function(e,t){return e.hasOwnProperty(t)},e.debounce=function(e,t,i){var n;return function(){var o=this,r=arguments;clearTimeout(n),n=setTimeout(function(){n=null,i||e.apply(o,r)},t),i&&!n&&e.apply(o,r)}};"touchstart"in t.documentElement||"ontouchstart"in e||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints;Object.defineProperty(e,"WCF_CLICK_EVENT",{value:"click"}),function(){function t(){e.history.state&&e.history.state.name&&"initial"!==e.history.state.name?(e.history.replaceState({name:"skip",depth:++i},""),e.history.back(),setTimeout(t,1)):e.history.replaceState({name:"initial"},"")}var i=0;t(),e.addEventListener("popstate",function(t){t.state&&t.state.name&&"skip"===t.state.name&&e.history.go(t.state.depth)})}(),e.String.prototype.hashCode=function(){var e,t=0;if(this.length)for(var i=0,n=this.length;i<n;i++)e=this.charCodeAt(i),t=(t<<5)-t+e,t&=t;return t}}(window,document),define("wcf.globalHelper",function(){}),define("WoltLabSuite/Core/Core",[],function(){"use strict";var e=function(e){return"object"==typeof e&&(Array.isArray(e)||n.isPlainObject(e))?t(e):e},t=function(t){if(!t)return null;if(Array.isArray(t))return t.slice();var i={};for(var n in t)t.hasOwnProperty(n)&&void 0!==t[n]&&(i[n]=e(t[n]));return i},i="wsc"+window.WCF_PATH.hashCode()+"-",n={clone:function(t){return e(t)},convertLegacyUrl:function(e){return e.replace(/^index\.php\/(.*?)\/\?/,function(e,t){var i=t.split(/([A-Z][a-z0-9]+)/);t="";for(var n=0,o=i.length;n<o;n++){var r=i[n].trim();r.length&&(t.length&&(t+="-"),t+=r.toLowerCase())}return"index.php?"+t+"/&"})},extend:function(e){e=e||{};for(var t=this.clone(e),i=1,n=arguments.length;i<n;i++){var o=arguments[i];if(o)for(var r in o)objOwns(o,r)&&(Array.isArray(o[r])||"object"!=typeof o[r]?t[r]=o[r]:this.isPlainObject(o[r])?t[r]=this.extend(e[r],o[r]):t[r]=o[r])}return t},inherit:function(e,t,i){if(void 0===e||null===e)throw new TypeError("The constructor must not be undefined or null.");if(void 0===t||null===t)throw new TypeError("The super constructor must not be undefined or null.");if(void 0===t.prototype)throw new TypeError("The super constructor must have a prototype.");e._super=t,e.prototype=n.extend(Object.create(t.prototype,{constructor:{configurable:!0,enumerable:!1,value:e,writable:!0}}),i||{})},isPlainObject:function(e){return"object"==typeof e&&null!==e&&!e.nodeType&&Object.getPrototypeOf(e)===Object.prototype},getType:function(e){return Object.prototype.toString.call(e).replace(/^\[object (.+)\]$/,"$1")},getUuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)})},serialize:function(e,t){var i=[];for(var n in e)if(objOwns(e,n)){var o=t?t+"["+n+"]":n,r=e[n];"object"==typeof r?i.push(this.serialize(r,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(r))}return i.join("&")},triggerEvent:function(e,t){if("click"===t&&e instanceof HTMLElement)return void e.click();var i;try{i=new Event(t,{bubbles:!0,cancelable:!0})}catch(e){i=document.createEvent("Event"),i.initEvent(t,!0,!0)}e.dispatchEvent(i)},getStoragePrefix:function(){return i}};return n}),define("WoltLabSuite/Core/Dictionary",["Core"],function(e){"use strict";function t(){this._dictionary=i?new Map:{}}var i=objOwns(window,"Map")&&"function"==typeof window.Map;return t.prototype={set:function(e,t){if("number"==typeof e&&(e=e.toString()),"string"!=typeof e)throw new TypeError("Only strings can be used as keys, rejected '"+e+"' ("+typeof e+").");i?this._dictionary.set(e,t):this._dictionary[e]=t},delete:function(e){"number"==typeof e&&(e=e.toString()),i?this._dictionary.delete(e):this._dictionary[e]=void 0},has:function(e){return"number"==typeof e&&(e=e.toString()),i?this._dictionary.has(e):objOwns(this._dictionary,e)&&void 0!==this._dictionary[e]},get:function(e){if("number"==typeof e&&(e=e.toString()),this.has(e))return i?this._dictionary.get(e):this._dictionary[e]},forEach:function(e){if("function"!=typeof e)throw new TypeError("forEach() expects a callback as first parameter.");if(i)this._dictionary.forEach(e);else for(var t=Object.keys(this._dictionary),n=0,o=t.length;n<o;n++)e(this._dictionary[t[n]],t[n])},merge:function(){for(var e=0,i=arguments.length;e<i;e++){var n=arguments[e];if(!(n instanceof t))throw new TypeError("Expected an object of type Dictionary, but argument "+e+" is not.");n.forEach(function(e,t){this.set(t,e)}.bind(this))}},toObject:function(){if(!i)return e.clone(this._dictionary);var t={};return this._dictionary.forEach(function(e,i){t[i]=e}),t}},t.fromObject=function(e){var i=new t;for(var n in e)objOwns(e,n)&&i.set(n,e[n]);return i},Object.defineProperty(t.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return i?this._dictionary.size:Object.keys(this._dictionary).length}}),t}),define("WoltLabSuite/Core/Template.grammar",["require"],function(e){var t=function(e,t,i,n){for(i=i||{},n=e.length;n--;i[e[n]]=t);return i},i=[2,44],n=[5,9,11,12,13,18,19,21,22,23,25,26,28,29,30,32,33,34,35,37,39,41],o=[1,25],r=[1,27],a=[1,33],l=[1,31],s=[1,32],c=[1,28],u=[1,29],d=[1,26],h=[1,35],f=[1,41],p=[1,40],g=[11,12,15,42,43,47,49,51,52,54,55],m=[9,11,12,13,18,19,21,23,26,28,30,32,33,34,35,37,39],v=[11,12,15,42,43,46,47,48,49,51,52,54,55],b=[1,64],_=[1,65],w=[18,37,39],y=[12,15],C={trace:function(){},yy:{},symbols_:{error:2,TEMPLATE:3,CHUNK_STAR:4,EOF:5,CHUNK_STAR_repetition0:6,CHUNK:7,PLAIN_ANY:8,T_LITERAL:9,COMMAND:10,T_ANY:11,T_WS:12,"{if":13,COMMAND_PARAMETERS:14,"}":15,COMMAND_repetition0:16,COMMAND_option0:17,"{/if}":18,"{include":19,COMMAND_PARAMETER_LIST:20,"{implode":21,"{/implode}":22,"{foreach":23,COMMAND_option1:24,"{/foreach}":25,"{plural":26,PLURAL_PARAMETER_LIST:27,"{lang}":28,"{/lang}":29,"{":30,VARIABLE:31,"{#":32,"{@":33,"{ldelim}":34,"{rdelim}":35,ELSE:36,"{else}":37,ELSE_IF:38,"{elseif":39,FOREACH_ELSE:40,"{foreachelse}":41,T_VARIABLE:42,T_VARIABLE_NAME:43,VARIABLE_repetition0:44,VARIABLE_SUFFIX:45,"[":46,"]":47,".":48,"(":49,VARIABLE_SUFFIX_option0:50,")":51,"=":52,COMMAND_PARAMETER_VALUE:53,T_QUOTED_STRING:54,T_DIGITS:55,COMMAND_PARAMETERS_repetition_plus0:56,COMMAND_PARAMETER:57,T_PLURAL_PARAMETER_NAME:58,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",9:"T_LITERAL",11:"T_ANY",12:"T_WS",13:"{if",15:"}",18:"{/if}",19:"{include",21:"{implode",22:"{/implode}",23:"{foreach",25:"{/foreach}",26:"{plural",28:"{lang}",29:"{/lang}",30:"{",32:"{#",33:"{@",34:"{ldelim}",35:"{rdelim}",37:"{else}",39:"{elseif",41:"{foreachelse}",42:"T_VARIABLE",43:"T_VARIABLE_NAME",46:"[",47:"]",48:".",49:"(",51:")",52:"=",54:"T_QUOTED_STRING",55:"T_DIGITS"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[8,1],[8,1],[10,7],[10,3],[10,5],[10,6],[10,3],[10,3],[10,3],[10,3],[10,3],[10,1],[10,1],[36,2],[38,4],[40,2],[31,3],[45,3],[45,2],[45,3],[20,5],[20,3],[53,1],[53,1],[53,1],[14,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,3],[27,5],[27,3],[58,1],[58,1],[6,0],[6,2],[16,0],[16,2],[17,0],[17,1],[24,0],[24,1],[44,0],[44,2],[50,0],[50,1],[56,1],[56,2]],performAction:function(e,t,i,n,o,r,a){var l=r.length-1;switch(o){case 1:return r[l-1]+";";case 2:var s=r[l].reduce(function(e,t){return t.encode&&!e[1]?e[0]+=" + '"+t.value:t.encode&&e[1]?e[0]+=t.value:!t.encode&&e[1]?e[0]+="' + "+t.value:t.encode||e[1]||(e[0]+=" + "+t.value),e[1]=t.encode,e},["''",!1]);s[1]&&(s[0]+="'"),this.$=s[0];break;case 3:case 4:this.$={encode:!0,value:r[l].replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/(\r\n|\n|\r)/g,"\\n")};break;case 5:this.$={encode:!1,value:r[l]};break;case 8:this.$="(function() { if ("+r[l-5]+") { return "+r[l-3]+"; } "+r[l-2].join(" ")+" "+(r[l-1]||"")+" return ''; })()";break;case 9:if(!r[l-1].file)throw new Error("Missing parameter file");this.$=r[l-1].file+".fetch(v)";break;case 10:if(!r[l-3].from)throw new Error("Missing parameter from");if(!r[l-3].item)throw new Error("Missing parameter item");r[l-3].glue||(r[l-3].glue="', '"),this.$="(function() { return "+r[l-3].from+".map(function(item) { v["+r[l-3].item+"] = item; return "+r[l-1]+"; }).join("+r[l-3].glue+"); })()";break;case 11:if(!r[l-4].from)throw new Error("Missing parameter from");if(!r[l-4].item)throw new Error("Missing parameter item");this.$="(function() {var looped = false, result = '';if ("+r[l-4].from+" instanceof Array) {for (var i = 0; i < "+r[l-4].from+".length; i++) { looped = true;v["+r[l-4].key+"] = i;v["+r[l-4].item+"] = "+r[l-4].from+"[i];result += "+r[l-2]+";}} else {for (var key in "+r[l-4].from+") {if (!"+r[l-4].from+".hasOwnProperty(key)) continue;looped = true;v["+r[l-4].key+"] = key;v["+r[l-4].item+"] = "+r[l-4].from+"[key];result += "+r[l-2]+";}}return (looped ? result : "+(r[l-1]||"''")+"); })()";break;case 12:this.$="I18nPlural.getCategoryFromTemplateParameters({";var c=!1;for(var u in r[l-1])objOwns(r[l-1],u)&&(this.$+=(c?",":"")+u+": "+r[l-1][u],c=!0);this.$+="})";break;case 13:this.$="Language.get("+r[l-1]+", v)";break;case 14:this.$="StringUtil.escapeHTML("+r[l-1]+")";break;case 15:this.$="StringUtil.formatNumeric("+r[l-1]+")";break;case 16:this.$=r[l-1];break;case 17:this.$="'{'";break;case 18:this.$="'}'";break;case 19:this.$="else { return "+r[l]+"; }";break;case 20:this.$="else if ("+r[l-2]+") { return "+r[l]+"; }";break;case 21:this.$=r[l];break;case 22:this.$="v['"+r[l-1]+"']"+r[l].join("");break;case 23:this.$=r[l-2]+r[l-1]+r[l];break;case 24:this.$="['"+r[l]+"']";break;case 25:case 39:this.$=r[l-2]+(r[l-1]||"")+r[l];break;case 26:case 40:this.$=r[l],this.$[r[l-4]]=r[l-2];break;case 27:case 41:this.$={},this.$[r[l-2]]=r[l];break;case 31:this.$=r[l].join("");break;case 44:case 46:case 52:this.$=[];break;case 45:case 47:case 53:case 57:r[l-1].push(r[l]);break;case 56:this.$=[r[l]]}},table:[t([5,9,11,12,13,19,21,23,26,28,30,32,33,34,35],i,{3:1,4:2,6:3}),{1:[3]},{5:[1,4]},t([5,18,22,25,29,37,39,41],[2,2],{7:5,8:6,10:8,9:[1,7],11:[1,9],12:[1,10],13:[1,11],19:[1,12],21:[1,13],23:[1,14],26:[1,15],28:[1,16],30:[1,17],32:[1,18],33:[1,19],34:[1,20],35:[1,21]}),{1:[2,1]},t(n,[2,45]),t(n,[2,3]),t(n,[2,4]),t(n,[2,5]),t(n,[2,6]),t(n,[2,7]),{11:o,12:r,14:22,31:30,42:a,43:l,49:s,52:c,54:u,55:d,56:23,57:24},{20:34,43:h},{20:36,43:h},{20:37,43:h},{27:38,43:f,55:p,58:39},t([9,11,12,13,19,21,23,26,28,29,30,32,33,34,35],i,{6:3,4:42}),{31:43,42:a},{31:44,42:a},{31:45,42:a},t(n,[2,17]),t(n,[2,18]),{15:[1,46]},t([15,47,51],[2,31],{31:30,57:47,11:o,12:r,42:a,43:l,49:s,52:c,54:u,55:d}),t(g,[2,56]),t(g,[2,32]),t(g,[2,33]),t(g,[2,34]),t(g,[2,35]),t(g,[2,36]),t(g,[2,37]),t(g,[2,38]),{11:o,12:r,14:48,31:30,42:a,43:l,49:s,52:c,54:u,55:d,56:23,57:24},{43:[1,49]},{15:[1,50]},{52:[1,51]},{15:[1,52]},{15:[1,53]},{15:[1,54]},{52:[1,55]},{52:[2,42]},{52:[2,43]},{29:[1,56]},{15:[1,57]},{15:[1,58]},{15:[1,59]},t(m,i,{6:3,4:60}),t(g,[2,57]),{51:[1,61]},t(v,[2,52],{44:62}),t(n,[2,9]),{31:66,42:a,53:63,54:b,55:_},t([9,11,12,13,19,21,22,23,26,28,30,32,33,34,35],i,{6:3,4:67}),t([9,11,12,13,19,21,23,25,26,28,30,32,33,34,35,41],i,{6:3,4:68}),t(n,[2,12]),{31:66,42:a,53:69,54:b,55:_},t(n,[2,13]),t(n,[2,14]),t(n,[2,15]),t(n,[2,16]),t(w,[2,46],{16:70}),t(g,[2,39]),t([11,12,15,42,43,47,51,52,54,55],[2,22],{45:71,46:[1,72],48:[1,73],49:[1,74]}),{12:[1,75],15:[2,27]},t(y,[2,28]),t(y,[2,29]),t(y,[2,30]),{22:[1,76]},{24:77,25:[2,50],40:78,41:[1,79]},{12:[1,80],15:[2,41]},{17:81,18:[2,48],36:83,37:[1,85],38:82,39:[1,84]},t(v,[2,53]),{11:o,12:r,14:86,31:30,42:a,43:l,49:s,52:c,54:u,55:d,56:23,57:24},{43:[1,87]},{11:o,12:r,14:89,31:30,42:a,43:l,49:s,50:88,51:[2,54],52:c,54:u,55:d,56:23,57:24},{20:90,43:h},t(n,[2,10]),{25:[1,91]},{25:[2,51]},t([9,11,12,13,19,21,23,25,26,28,30,32,33,34,35],i,{6:3,4:92}),{27:93,43:f,55:p,58:39},{18:[1,94]},t(w,[2,47]),{18:[2,49]},{11:o,12:r,14:95,31:30,42:a,43:l,49:s,52:c,54:u,55:d,56:23,57:24},t([9,11,12,13,18,19,21,23,26,28,30,32,33,34,35],i,{6:3,4:96}),{47:[1,97]},t(v,[2,24]),{51:[1,98]},{51:[2,55]},{15:[2,26]},t(n,[2,11]),{25:[2,21]},{15:[2,40]},t(n,[2,8]),{15:[1,99]},{18:[2,19]},t(v,[2,23]),t(v,[2,25]),t(m,i,{6:3,4:100}),t(w,[2,20])],defaultActions:{4:[2,1],40:[2,42],41:[2,43],78:[2,51],83:[2,49],89:[2,55],90:[2,26],92:[2,21],93:[2,40],96:[2,19]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=this,i=[0],n=[null],o=[],r=this.table,a="",l=0,s=0,c=0,u=o.slice.call(arguments,1),d=Object.create(this.lexer),h={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(h.yy[f]=this.yy[f]);d.setInput(e,h.yy),h.yy.lexer=d,h.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var p=d.yylloc;o.push(p);var g=d.options&&d.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,v,b,_,w,y,C,E,L,A=function(){var e;return e=d.lex()||1,"number"!=typeof e&&(e=t.symbols_[e]||e),e},S={};;){if(b=i[i.length-1],this.defaultActions[b]?_=this.defaultActions[b]:(null!==m&&void 0!==m||(m=A()),_=r[b]&&r[b][m]),void 0===_||!_.length||!_[0]){var x="";L=[];for(y in r[b])this.terminals_[y]&&y>2&&L.push("'"+this.terminals_[y]+"'");x=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+L.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[m]||m,line:d.yylineno,loc:p,expected:L})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+m);switch(_[0]){case 1:i.push(m),n.push(d.yytext),o.push(d.yylloc),i.push(_[1]),m=null,v?(m=v,v=null):(s=d.yyleng,a=d.yytext,l=d.yylineno,p=d.yylloc,c>0&&c--);break;case 2:if(C=this.productions_[_[1]][1],S.$=n[n.length-C],S._$={first_line:o[o.length-(C||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(C||1)].first_column,last_column:o[o.length-1].last_column},g&&(S._$.range=[o[o.length-(C||1)].range[0],o[o.length-1].range[1]]),void 0!==(w=this.performAction.apply(S,[a,s,l,h.yy,_[1],n,o].concat(u))))return w;C&&(i=i.slice(0,-1*C*2),n=n.slice(0,-1*C),o=o.slice(0,-1*C)),i.push(this.productions_[_[1]][0]),n.push(S.$),o.push(S._$),E=r[i[i.length-2]][i[i.length-1]],i.push(E);break;case 3:return!0}}return!0}},E=function(){return{EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var o=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[o[0],o[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,n,o;if(this.options.backtrack_lexer&&(o={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(o.yylloc.range=this.yylloc.range.slice(0))),n=e[0].match(/(?:\r\n?|\n).*/g),n&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,
+this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in o)this[r]=o[r];return!1}return!1},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var e,t,i,n;this._more||(this.yytext="",this.match="");for(var o=this._currentRules(),r=0;r<o.length;r++)if((i=this._input.match(this.rules[o[r]]))&&(!t||i[0].length>t[0].length)){if(t=i,n=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,o[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,o[n]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return e=this.conditionStack.length-1-Math.abs(e||0),e>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,i,n){switch(i){case 0:break;case 1:return t.yytext=t.yytext.substring(9,t.yytext.length-10),9;case 2:case 3:return 54;case 4:return 42;case 5:return 55;case 6:return 43;case 7:return 48;case 8:return 46;case 9:return 47;case 10:return 49;case 11:return 51;case 12:return 52;case 13:return 34;case 14:return 35;case 15:return this.begin("command"),32;case 16:return this.begin("command"),33;case 17:return this.begin("command"),13;case 18:case 19:return this.begin("command"),39;case 20:return 37;case 21:return 18;case 22:return 28;case 23:return 29;case 24:return this.begin("command"),19;case 25:return this.begin("command"),21;case 26:return this.begin("command"),26;case 27:return 22;case 28:return this.begin("command"),23;case 29:return 41;case 30:return 25;case 31:return this.begin("command"),30;case 32:return this.popState(),15;case 33:return 12;case 34:return 5;case 35:return 11}},rules:[/^(?:\{\*[\s\S]*?\*\})/,/^(?:\{literal\}[\s\S]*?\{\/literal\})/,/^(?:"([^"]|\\\.)*")/,/^(?:'([^']|\\\.)*')/,/^(?:\$)/,/^(?:[0-9]+)/,/^(?:[_a-zA-Z][_a-zA-Z0-9]*)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:=)/,/^(?:\{ldelim\})/,/^(?:\{rdelim\})/,/^(?:\{#)/,/^(?:\{@)/,/^(?:\{if )/,/^(?:\{else if )/,/^(?:\{elseif )/,/^(?:\{else\})/,/^(?:\{\/if\})/,/^(?:\{lang\})/,/^(?:\{\/lang\})/,/^(?:\{include )/,/^(?:\{implode )/,/^(?:\{plural )/,/^(?:\{\/implode\})/,/^(?:\{foreach )/,/^(?:\{foreachelse\})/,/^(?:\{\/foreach\})/,/^(?:\{(?!\s))/,/^(?:\})/,/^(?:\s+)/,/^(?:$)/,/^(?:[^{])/],conditions:{command:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],inclusive:!0},INITIAL:{rules:[0,1,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35],inclusive:!0}}}}();return C.lexer=E,C}),define("WoltLabSuite/Core/NumberUtil",[],function(){"use strict";return{round:function(e,t){return void 0===t||0==+t?Math.round(e):(e=+e,t=+t,isNaN(e)||"number"!=typeof t||t%1!=0?NaN:(e=e.toString().split("e"),e=Math.round(+(e[0]+"e"+(e[1]?+e[1]-t:-t))),e=e.toString().split("e"),+(e[0]+"e"+(e[1]?+e[1]+t:t))))}}}),define("WoltLabSuite/Core/StringUtil",["Language","./NumberUtil"],function(e,t){"use strict";return{addThousandsSeparator:function(t){return void 0===e&&(e=require("Language")),String(t).replace(/(^-?\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g,"$1"+e.get("wcf.global.thousandsSeparator"))},escapeHTML:function(e){return String(e).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},escapeRegExp:function(e){return String(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},formatNumeric:function(i,n){void 0===e&&(e=require("Language")),i=String(t.round(i,n||-2));var o=i.split(".");return i=this.addThousandsSeparator(o[0]),o.length>1&&(i+=e.get("wcf.global.decimalPoint")+o[1]),i=i.replace("-","−")},lcfirst:function(e){return String(e).substring(0,1).toLowerCase()+e.substring(1)},ucfirst:function(e){return String(e).substring(0,1).toUpperCase()+e.substring(1)},unescapeHTML:function(e){return String(e).replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&gt;/g,">")},shortUnit:function(e){var i="";return e>=1e6?(e/=1e6,e=e>10?Math.floor(e):t.round(e,-1),i="M"):e>=1e3&&(e/=1e3,e=e>10?Math.floor(e):t.round(e,-1),i="k"),this.formatNumeric(e)+i}}}),define("WoltLabSuite/Core/I18n/Plural",["StringUtil"],function(e){"use strict";return{getCategory:function(e,t){t||(t=document.documentElement.lang),"function"!=typeof this[t]&&(t="en");var i=this[t](e);return i||"other"},getCategoryFromTemplateParameters:function(t){if(!t.value)throw new Error("Missing parameter value");if(!t.other)throw new Error("Missing parameter other");var i=t.value;Array.isArray(i)&&(i=i.length);for(var n in t)if(objOwns(t,n)&&n==~~n&&n==i)return t[n];var o=this.getCategory(i);t[o]||(o="other");var r=t[o];return-1!==r.indexOf("#")?r.replace("#",e.formatNumeric(i)):r},getF:function(e){e=e.toString();var t=e.indexOf(".");return-1===t?0:parseInt(e.substr(t+1),10)},getV:function(e){return e.toString().replace(/^[^.]*\.?/,"").length},af:function(e){if(1==e)return"one"},am:function(e){var t=Math.floor(Math.abs(e));if(1==e||0===t)return"one"},ar:function(e){if(0==e)return"zero";if(1==e)return"one";if(2==e)return"two";var t=e%100;return t>=3&&t<=10?"few":t>=11&&t<=99?"many":void 0},as:function(e){var t=Math.floor(Math.abs(e));if(1==e||0===t)return"one"},az:function(e){if(1==e)return"one"},be:function(e){var t=e%10,i=e%100;return 1==t&&11!=i?"one":t>=2&&t<=4&&!(i>=12&&i<=14)?"few":0==t||t>=5&&t<=9||i>=11&&i<=14?"many":void 0},bg:function(e){if(1==e)return"one"},bn:function(e){var t=Math.floor(Math.abs(e));if(1==e||0===t)return"one"},bo:function(e){},bs:function(e){var t=this.getV(e),i=this.getF(e),n=e%10,o=e%100,r=i%10,a=i%100;return 0==t&&1==n&&11!=o||1==r&&11!=a?"one":0==t&&n>=2&&n<=4&&o>=12&&o<=14||r>=2&&r<=4&&a>=12&&a<=14?"few":void 0},cs:function(e){var t=this.getV(e);return 1==e&&0===t?"one":e>=2&&e<=4&&0===t?"few":0===t?"many":void 0},cy:function(e){return 0==e?"zero":1==e?"one":2==e?"two":3==e?"few":6==e?"many":void 0},da:function(e){if(e>0&&e<2)return"one"},el:function(e){if(1==e)return"one"},en:function(e){if(1==e&&0===this.getV(e))return"one"},es:function(e){if(1==e)return"one"},eu:function(e){if(1==e)return"one"},fa:function(e){if(e>=0&&e<=1)return"one"},fr:function(e){if(e>=0&&e<2)return"one"},ga:function(e){return 1==e?"one":2==e?"two":3==e||4==e||5==e||6==e?"few":7==e||8==e||9==e||10==e?"many":void 0},gu:function(e){if(e>=0&&e<=1)return"one"},he:function(e){var t=this.getV(e);return 1==e&&0===t?"one":2==e&&0===t?"two":e>10&&0===t&&e%10==0?"many":void 0},hi:function(e){if(e>=0&&e<=1)return"one"},hr:function(e){return this.bs(e)},hu:function(e){if(1==e)return"one"},hy:function(e){if(e>=0&&e<2)return"one"},id:function(e){},is:function(e){var t=this.getF(e);if(0===t&&e%10==1&&e%100!=11||0!==t)return"one"},ja:function(e){},jv:function(e){},ka:function(e){if(1==e)return"one"},kk:function(e){if(1==e)return"one"},km:function(e){},kn:function(e){if(e>=0&&e<=1)return"one"},ko:function(e){},ku:function(e){if(1==e)return"one"},ky:function(e){if(1==e)return"one"},lb:function(e){if(1==e)return"one"},lo:function(e){},lt:function(e){var t=e%10,i=e%100;return 1!=t||i>=11&&i<=19?t>=2&&t<=9&&!(i>=11&&i<=19)?"few":0!=this.getF(e)?"many":void 0:"one"},lv:function(e){var t=e%10,i=e%100,n=this.getV(e),o=this.getF(e),r=o%10,a=o%100;return 0==t||i>=11&&i<=19||2==n&&a>=11&&a<=19?"zero":1==t&&11!=i||2==n&&1==r&&11!=a||2!=n&&1==r?"one":void 0},mk:function(e){var t=this.getV(e),i=this.getF(e),n=e%10,o=e%100,r=i%10,a=i%100;if(0==t&&1==n&&11!=o||1==r&&11!=a)return"one"},ml:function(e){if(1==e)return"one"},mn:function(e){if(1==e)return"one"},mr:function(e){if(1==e)return"one"},ms:function(e){},mt:function(e){var t=e%100;return 1==e?"one":0==e||t>=2&&t<=10?"few":t>=11&&t<=19?"many":void 0},my:function(e){},no:function(e){if(1==e)return"one"},ne:function(e){if(1==e)return"one"},or:function(e){if(1==e)return"one"},pa:function(e){if(1==e||0==e)return"one"},pl:function(e){var t=this.getV(e),i=e%10,n=e%100;return 1==e&&0==t?"one":0==t&&i>=2&&i<=4&&!(n>=12&&n<=14)?"few":0==t&&(1!=e&&i>=0&&i<=1||i>=5&&i<=9||n>=12&&n<=14)?"many":void 0},ps:function(e){if(1==e)return"one"},pt:function(e){if(e>=0&&e<2)return"one"},ro:function(e){var t=this.getV(e),i=e%100;return 1==e&&0===t?"one":0!=t||0==e||i>=2&&i<=19?"few":void 0},ru:function(e){var t=e%10,i=e%100;if(0==this.getV(e)){if(1==t&&11!=i)return"one";if(t>=2&&t<=4&&!(i>=12&&i<=14))return"few";if(0==t||t>=5&&t<=9||i>=11&&i<=14)return"many"}},sd:function(e){if(1==e)return"one"},si:function(e){if(0==e||1==e||0==Math.floor(e)&&1==this.getF(e))return"one"},sk:function(e){return this.cs(e)},sl:function(e){var t=this.getV(e),i=e%100;return 0==t&&1==i?"one":0==t&&2==i?"two":0==t&&(3==i||4==i)||0!=t?"few":void 0},sq:function(e){if(1==e)return"one"},sr:function(e){return this.bs(e)},ta:function(e){if(1==e)return"one"},te:function(e){if(1==e)return"one"},tg:function(e){},th:function(e){},tk:function(e){if(1==e)return"one"},tr:function(e){if(1==e)return"one"},ug:function(e){if(1==e)return"one"},uk:function(e){return this.ru(e)},uz:function(e){if(1==e)return"one"},vi:function(e){},zh:function(e){}}}),define("WoltLabSuite/Core/Template",["./Template.grammar","./StringUtil","Language","WoltLabSuite/Core/I18n/Plural"],function(e,t,i,n){"use strict";function o(){this.yy={}}function r(o){void 0===i&&(i=require("Language")),void 0===t&&(t=require("StringUtil"));try{o=e.parse(o),o="var tmp = {};\nfor (var key in v) tmp[key] = v[key];\nv = tmp;\nv.__wcf = window.WCF; v.__window = window;\nreturn "+o,this.fetch=new Function("StringUtil","Language","I18nPlural","v",o).bind(void 0,t,i,n)}catch(e){throw console.debug(e.message),e}}return o.prototype=e,e.Parser=o,e=new o,Object.defineProperty(r,"callbacks",{enumerable:!1,configurable:!1,get:function(){throw new Error("WCF.Template.callbacks is no longer supported")},set:function(e){throw new Error("WCF.Template.callbacks is no longer supported")}}),r.prototype={fetch:function(e){throw new Error("This Template is not initialized.")}},r}),define("WoltLabSuite/Core/Language",["Dictionary","./Template"],function(e,t){"use strict";var i=new e;return{addObject:function(t){i.merge(e.fromObject(t))},add:function(e,t){i.set(e,t)},get:function(e,n){n||(n={});var o=i.get(e);if(void 0===o)return e;if(void 0===t&&(t=require("WoltLabSuite/Core/Template")),"string"==typeof o){try{i.set(e,new t(o))}catch(n){i.set(e,new t("{literal}"+o.replace(/\{\/literal\}/g,"{/literal}{ldelim}/literal}{literal}")+"{/literal}"))}o=i.get(e)}return o instanceof t&&(o=o.fetch(n)),o}}}),define("WoltLabSuite/Core/CallbackList",["Dictionary"],function(e){"use strict";function t(){this._dictionary=new e}return t.prototype={add:function(e,t){if("function"!=typeof t)throw new TypeError("Expected a valid callback as second argument for identifier '"+e+"'.");this._dictionary.has(e)||this._dictionary.set(e,[]),this._dictionary.get(e).push(t)},remove:function(e){this._dictionary.delete(e)},forEach:function(e,t){if(null===e)this._dictionary.forEach(function(e,i){e.forEach(t)});else{var i=this._dictionary.get(e);void 0!==i&&i.forEach(t)}}},t}),define("WoltLabSuite/Core/Dom/Change/Listener",["CallbackList"],function(e){"use strict";var t=new e,i=!1;return{add:t.add.bind(t),remove:t.remove.bind(t),trigger:function(){if(!i)try{i=!0,t.forEach(null,function(e){e()})}finally{i=!1}}}}),define("WoltLabSuite/Core/Environment",[],function(){"use strict";var e="other",t="none",i="desktop",n=!1;return{setup:function(){if("object"==typeof window.chrome)e="chrome";else for(var o=window.getComputedStyle(document.documentElement),r=0,a=o.length;r<a;r++){var l=o[r];0===l.indexOf("-ms-")?e="microsoft":0===l.indexOf("-moz-")?e="firefox":"firefox"!==e&&0===l.indexOf("-webkit-")&&(e="safari")}var s=window.navigator.userAgent.toLowerCase();-1!==s.indexOf("crios")?(e="chrome",i="ios"):/(?:iphone|ipad|ipod)/.test(s)?(e="safari",i="ios"):-1!==s.indexOf("android")?i="android":-1!==s.indexOf("iemobile")&&(e="microsoft",i="windows"),"desktop"!==i||-1===s.indexOf("mobile")&&-1===s.indexOf("tablet")||(i="mobile"),t="redactor",n=!!("ontouchstart"in window)||!!("msMaxTouchPoints"in window.navigator)&&window.navigator.msMaxTouchPoints>0||window.DocumentTouch&&document instanceof DocumentTouch,"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1&&(e="safari",i="ios")},browser:function(){return e},editor:function(){return t},platform:function(){return i},touch:function(){return n}}}),define("WoltLabSuite/Core/Dom/Util",["Environment","StringUtil"],function(e,t){"use strict";function i(e,t,i){if(!t.contains(e))throw new Error("Ancestor element does not contain target element.");for(var n,o=i+"Sibling";null!==e&&e!==t;){if(null!==e[i+"ElementSibling"])return!1;if(e[o])for(n=e[o];n;){if(""!==n.textContent.trim())return!1;n=n[o]}e=e.parentNode}return!0}var n=0,o={createFragmentFromHtml:function(e){var t=elCreate("div");this.setInnerHtml(t,e);for(var i=document.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return i},getUniqueId:function(){var e;do{e="wcf"+n++}while(null!==elById(e));return e},identify:function(e){if(!(e instanceof Element))throw new TypeError("Expected a valid DOM element as argument.");var t=elAttr(e,"id");return t||(t=this.getUniqueId(),elAttr(e,"id",t)),t},outerHeight:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetHeight;return i+=~~t.marginTop+~~t.marginBottom},outerWidth:function(e,t){t=t||window.getComputedStyle(e);var i=e.offsetWidth;return i+=~~t.marginLeft+~~t.marginRight},outerDimensions:function(e){var t=window.getComputedStyle(e);return{height:this.outerHeight(e,t),width:this.outerWidth(e,t)}},offset:function(e){var t=e.getBoundingClientRect();return{top:Math.round(t.top+(window.scrollY||window.pageYOffset)),left:Math.round(t.left+(window.scrollX||window.pageXOffset))}},prepend:function(e,t){0===t.childNodes.length?t.appendChild(e):t.insertBefore(e,t.childNodes[0])},insertAfter:function(e,t){null!==t.nextSibling?t.parentNode.insertBefore(e,t.nextSibling):t.parentNode.appendChild(e)},setStyles:function(e,t){var i=!1;for(var n in t)t.hasOwnProperty(n)&&(/ !important$/.test(t[n])?(i=!0,t[n]=t[n].replace(/ !important$/,"")):i=!1,"important"!==e.style.getPropertyPriority(n)||i||e.style.removeProperty(n),e.style.setProperty(n,t[n],i?"important":""))},styleAsInt:function(e,t){var i=e.getPropertyValue(t);return null===i?0:parseInt(i)},setInnerHtml:function(e,t){e.innerHTML=t;for(var i,n,o=elBySelAll("script",e),r=0,a=o.length;r<a;r++)n=o[r],i=elCreate("script"),n.src?i.src=n.src:i.textContent=n.textContent,e.appendChild(i),elRemove(n)},insertHtml:function(e,t,i){var n=elCreate("div");if(this.setInnerHtml(n,e),n.childNodes.length){var o=n.childNodes[0];switch(i){case"append":t.appendChild(o);break;case"after":this.insertAfter(o,t);break;case"prepend":this.prepend(o,t);break;case"before":t.parentNode.insertBefore(o,t);break;default:throw new Error("Unknown insert method '"+i+"'.")}for(var r;n.childNodes.length;)r=n.childNodes[0],this.insertAfter(r,o),o=r}},contains:function(e,t){for(;null!==t;)if(t=t.parentNode,e===t)return!0;return!1},getDataAttributes:function(e,i,n,o){i=i||"",/^data-/.test(i)||(i="data-"+i),n=!0===n,o=!0===o;for(var r,a,l,s={},c=0,u=e.attributes.length;c<u;c++)if(r=e.attributes[c],0===r.name.indexOf(i)){if(a=r.name.replace(new RegExp("^"+i),""),n){l=a.split("-"),a="";for(var d=0,h=l.length;d<h;d++)a.length&&(o&&"id"===l[d]?l[d]="ID":l[d]=t.ucfirst(l[d])),a+=l[d]}s[a]=r.value}return s},unwrapChildNodes:function(e){for(var t=e.parentNode;e.childNodes.length;)t.insertBefore(e.childNodes[0],e);elRemove(e)},replaceElement:function(e,t){for(;e.childNodes.length;)t.appendChild(e.childNodes[0]);e.parentNode.insertBefore(t,e),elRemove(e)},isAtNodeStart:function(e,t){return i(e,t,"previous")},isAtNodeEnd:function(e,t){return i(e,t,"next")},getFixedParent:function(e){for(;e&&e!==document.body;){if("fixed"===window.getComputedStyle(e).getPropertyValue("position"))return e;e=e.offsetParent}return null}};return window.bc_wcfDomUtil=o,o}),define("WoltLabSuite/Core/ObjectMap",[],function(){"use strict";function e(){this._map=t?new WeakMap:{key:[],value:[]}}var t=objOwns(window,"WeakMap")&&"function"==typeof window.WeakMap;return e.prototype={set:function(e,i){if("object"!=typeof e||null===e)throw new TypeError("Only objects can be used as key");if("object"!=typeof i||null===i)throw new TypeError("Only objects can be used as value");t?this._map.set(e,i):(this._map.key.push(e),this._map.value.push(i))},delete:function(e){if(t)this._map.delete(e);else{var i=this._map.key.indexOf(e);this._map.key.splice(i),this._map.value.splice(i)}},has:function(e){return t?this._map.has(e):-1!==this._map.key.indexOf(e)},get:function(e){if(t)return this._map.get(e);var i=this._map.key.indexOf(e);return-1!==i?this._map.value[i]:void 0}},e}),define("WoltLabSuite/Core/Dom/Traverse",[],function(){"use strict";var e=[function(e,t){return!0},function(e,t){return e.matches(t)},function(e,t){return e.classList.contains(t)},function(e,t){return e.nodeName===t}],t=function(t,i,n){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(var o=[],r=0;r<t.childElementCount;r++)e[i](t.children[r],n)&&o.push(t.children[r]);return o},i=function(t,i,n,o){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");for(t=t.parentNode;t instanceof Element;){if(t===o)return null;if(e[i](t,n))return t;t=t.parentNode}return null},n=function(t,i,n,o){if(!(t instanceof Element))throw new TypeError("Expected a valid element as first argument.");return t instanceof Element&&null!==t[i]&&e[n](t[i],o)?t[i]:null};return{childBySel:function(e,i){return t(e,1,i)[0]||null},childByClass:function(e,i){return t(e,2,i)[0]||null},childByTag:function(e,i){return t(e,3,i)[0]||null},childrenBySel:function(e,i){return t(e,1,i)},childrenByClass:function(e,i){return t(e,2,i)},childrenByTag:function(e,i){return t(e,3,i)},parentBySel:function(e,t,n){return i(e,1,t,n)},parentByClass:function(e,t,n){return i(e,2,t,n)},parentByTag:function(e,t,n){return i(e,3,t,n)},next:function(e){return n(e,"nextElementSibling",0,null)},nextBySel:function(e,t){return n(e,"nextElementSibling",1,t)},nextByClass:function(e,t){return n(e,"nextElementSibling",2,t)},nextByTag:function(e,t){return n(e,"nextElementSibling",3,t)},prev:function(e){return n(e,"previousElementSibling",0,null)},prevBySel:function(e,t){return n(e,"previousElementSibling",1,t)},prevByClass:function(e,t){return n(e,"previousElementSibling",2,t)},prevByTag:function(e,t){return n(e,"previousElementSibling",3,t)}}}),define("WoltLabSuite/Core/Ui/Confirmation",["Core","Language","Ui/Dialog"],function(e,t,i){"use strict";var n=!1,o=null,r=null,a={},l=null;return{show:function(t){if(void 0===i&&(i=require("Ui/Dialog")),!n){if(a=e.extend({cancel:null,confirm:null,legacyCallback:null,message:"",messageIsHtml:!1,parameters:{},template:""},t),a.message="string"==typeof a.message?a.message.trim():"",!a.message.length)throw new Error("Expected a non-empty string for option 'message'.");if("function"!=typeof a.confirm&&"function"!=typeof a.legacyCallback)throw new TypeError("Expected a valid callback for option 'confirm'.");null===r&&this._createDialog(),r.innerHTML="string"==typeof a.template?a.template.trim():"",a.messageIsHtml?l.innerHTML=a.message:l.textContent=a.message,n=!0,i.open(this)}},_dialogSetup:function(){return{id:"wcfSystemConfirmation",options:{onClose:this._onClose.bind(this),onShow:this._onShow.bind(this),title:t.get("wcf.global.confirmation.title")}}},getContentElement:function(){return r},_createDialog:function(){var e=elCreate("div");elAttr(e,"id","wcfSystemConfirmation"),e.classList.add("systemConfirmation"),l=elCreate("p"),e.appendChild(l),r=elCreate("div"),elAttr(r,"id","wcfSystemConfirmationContent"),e.appendChild(r);var n=elCreate("div");n.classList.add("formSubmit"),e.appendChild(n),o=elCreate("button"),o.dataset.type="submit",o.classList.add("buttonPrimary"),o.textContent=t.get("wcf.global.confirmation.confirm"),n.appendChild(o);var a=elCreate("button");a.textContent=t.get("wcf.global.confirmation.cancel"),a.addEventListener(WCF_CLICK_EVENT,function(){i.close("wcfSystemConfirmation")}),n.appendChild(a),document.body.appendChild(e)},_confirm:function(){"function"==typeof a.legacyCallback?a.legacyCallback("confirm",a.parameters,r):a.confirm(a.parameters,r),n=!1,i.close("wcfSystemConfirmation")},_onClose:function(){n&&(o.blur(),n=!1,"function"==typeof a.legacyCallback?a.legacyCallback("cancel",a.parameters,r):"function"==typeof a.cancel&&a.cancel(a.parameters))},_onShow:function(){o.blur(),o.focus()},_dialogSubmit:function(){this._confirm()}}}),define("WoltLabSuite/Core/Ui/Screen",["Core","Dictionary","Environment"],function(e,t,i){"use strict";var n=null,o=new t,r=0,a=null,l=0,s=0,c=t.fromObject({"screen-xs":"(max-width: 544px)","screen-sm":"(min-width: 545px) and (max-width: 768px)","screen-sm-down":"(max-width: 768px)","screen-sm-up":"(min-width: 545px)","screen-sm-md":"(min-width: 545px) and (max-width: 1024px)","screen-md":"(min-width: 769px) and (max-width: 1024px)","screen-md-down":"(max-width: 1024px)","screen-md-up":"(min-width: 769px)","screen-lg":"(min-width: 1025px)","screen-lg-only":"(min-width: 1025px) and (max-width: 1280px)","screen-lg-down":"(max-width: 1280px)","screen-xl":"(min-width: 1281px)"}),u=new t;return{on:function(t,i){var n=e.getUuid(),o=this._getQueryObject(t);return"function"==typeof i.match&&o.callbacksMatch.set(n,i.match),"function"==typeof i.unmatch&&o.callbacksUnmatch.set(n,i.unmatch),"function"==typeof i.setup&&(o.mql.matches?i.setup():o.callbacksSetup.set(n,i.setup)),n},remove:function(e,t){var i=this._getQueryObject(e);i.callbacksMatch.delete(t),i.callbacksUnmatch.delete(t),i.callbacksSetup.delete(t)},is:function(e){return this._getQueryObject(e).mql.matches},scrollDisable:function(){if(0===r){l=document.body.scrollTop,a="body",l||(l=document.documentElement.scrollTop,a="documentElement");var e=elById("pageContainer");"ios"===i.platform()?(e.style.setProperty("position","relative",""),e.style.setProperty("top","-"+l+"px","")):e.style.setProperty("margin-top","-"+l+"px",""),document.documentElement.classList.add("disableScrolling")}r++},scrollEnable:function(){if(r&&0===--r){document.documentElement.classList.remove("disableScrolling");var e=elById("pageContainer");"ios"===i.platform()?(e.style.removeProperty("position"),e.style.removeProperty("top")):e.style.removeProperty("margin-top"),l&&(document[a].scrollTop=~~l)}},pageOverlayOpen:function(){0===s&&document.documentElement.classList.add("pageOverlayActive"),s++},pageOverlayClose:function(){s&&0===--s&&document.documentElement.classList.remove("pageOverlayActive")},pageOverlayIsActive:function(){return s>0},setDialogContainer:function(e){n=e},_getQueryObject:function(e){if("string"!=typeof e||""===e.trim())throw new TypeError("Expected a non-empty string for parameter 'query'.");u.has(e)&&(e=u.get(e)),c.has(e)&&(e=c.get(e));var i=o.get(e);return i||(i={callbacksMatch:new t,callbacksUnmatch:new t,callbacksSetup:new t,mql:window.matchMedia(e)},i.mql.addListener(this._mqlChange.bind(this)),o.set(e,i),e!==i.mql.media&&u.set(i.mql.media,e)),i},_mqlChange:function(e){var i=this._getQueryObject(e.media);if(e.matches)i.callbacksSetup.size?(i.callbacksSetup.forEach(function(e){e()}),i.callbacksSetup=new t):i.callbacksMatch.forEach(function(e){e()});else{if(i.callbacksSetup.size)return;i.callbacksUnmatch.forEach(function(e){e()})}}}}),define("WoltLabSuite/Core/Event/Key",[],function(){"use strict";function e(e,t,i){if(!(e instanceof Event))throw new TypeError("Expected a valid event when testing for key '"+t+"'.");return e.key===t||e.which===i}return{ArrowDown:function(t){return e(t,"ArrowDown",40)},ArrowLeft:function(t){return e(t,"ArrowLeft",37)},ArrowRight:function(t){return e(t,"ArrowRight",39)},ArrowUp:function(t){return e(t,"ArrowUp",38)},Comma:function(t){return e(t,",",44)},End:function(t){return e(t,"End",35)},Enter:function(t){return e(t,"Enter",13)},Escape:function(t){return e(t,"Escape",27)},Home:function(t){return e(t,"Home",36)},Space:function(t){return e(t,"Space",32)},Tab:function(t){return e(t,"Tab",9)}}}),define("WoltLabSuite/Core/Ui/Alignment",["Core","Language","Dom/Traverse","Dom/Util"],function(e,t,i,n){"use strict";return{set:function(o,r,a){a=e.extend({verticalOffset:0,pointer:!1,pointerClassNames:[],refDimensionsElement:null,horizontal:"left",vertical:"bottom",allowFlip:"both"},a),Array.isArray(a.pointerClassNames)&&a.pointerClassNames.length===(a.pointer?1:2)||(a.pointerClassNames=[]),-1===["left","right","center"].indexOf(a.horizontal)&&(a.horizontal="left"),"bottom"!==a.vertical&&(a.vertical="top"),-1===["both","horizontal","vertical","none"].indexOf(a.allowFlip)&&(a.allowFlip="both"),n.setStyles(o,{bottom:"auto !important",left:"0 !important",right:"auto !important",top:"0 !important",visibility:"hidden !important"});var l=n.outerDimensions(o),s=n.outerDimensions(a.refDimensionsElement instanceof Element?a.refDimensionsElement:r),c=n.offset(r),u=window.innerHeight,d=document.body.clientWidth,h={result:null},f=!1;if("center"===a.horizontal&&(f=!0,h=this._tryAlignmentHorizontal(a.horizontal,l,s,c,d),h.result||("both"===a.allowFlip||"horizontal"===a.allowFlip?a.horizontal="left":h.result=!0)),"rtl"===t.get("wcf.global.pageDirection")&&(a.horizontal="left"===a.horizontal?"right":"left"),!h.result){var p=h;if(h=this._tryAlignmentHorizontal(a.horizontal,l,s,c,d),!h.result&&("both"===a.allowFlip||"horizontal"===a.allowFlip)){var g=this._tryAlignmentHorizontal("left"===a.horizontal?"right":"left",l,s,c,d);g.result?h=g:f&&(h=p)}}var m=h.left,v=h.right,b=this._tryAlignmentVertical(a.vertical,l,s,c,u,a.verticalOffset);if(!b.result&&("both"===a.allowFlip||"vertical"===a.allowFlip)){var _=this._tryAlignmentVertical("top"===a.vertical?"bottom":"top",l,s,c,u,a.verticalOffset);_.result&&(b=_)}var w=b.bottom,y=b.top;if(a.pointer){var C=i.childrenByClass(o,"elementPointer");if(null===(C=C[0]||null))throw new Error("Expected the .elementPointer element to be a direct children.");"center"===h.align?(C.classList.add("center"),C.classList.remove("left"),C.classList.remove("right")):(C.classList.add(h.align),C.classList.remove("center"),C.classList.remove("left"===h.align?"right":"left")),"top"===b.align?C.classList.add("flipVertical"):C.classList.remove("flipVertical")}else if(2===a.pointerClassNames.length){o.classList["auto"===y?"add":"remove"](a.pointerClassNames[0]),o.classList["auto"===m?"add":"remove"](a.pointerClassNames[1])}"auto"!==w&&(w=Math.round(w)+"px"),"auto"!==m&&(m=Math.ceil(m)+"px"),"auto"!==v&&(v=Math.floor(v)+"px"),"auto"!==y&&(y=Math.round(y)+"px"),n.setStyles(o,{bottom:w,left:m,right:v,top:y}),elShow(o),o.style.removeProperty("visibility")},_tryAlignmentHorizontal:function(e,t,i,n,o){var r="auto",a="auto",l=!0;return"left"===e?(r=n.left)+t.width>o&&(l=!1):"right"===e?n.left+i.width<t.width?l=!1:(a=o-(n.left+i.width))<0&&(l=!1):(r=n.left+i.width/2-t.width/2,((r=~~r)<0||r+t.width>o)&&(l=!1)),{align:e,left:r,right:a,result:l}},_tryAlignmentVertical:function(e,t,i,n,o,r){var a="auto",l="auto",s=!0,c=50,u=elById("pageHeaderPanel");if(null!==u){var d=window.getComputedStyle(u).position;c="fixed"===d||"static"===d?u.offsetHeight:0}if("top"===e){var h=document.body.clientHeight;a=h-n.top+r,h-(a+t.height)<(window.scrollY||window.pageYOffset)+c&&(s=!1)}else(l=n.top+i.height+r)+t.height-(window.scrollY||window.pageYOffset)>o&&(s=!1);return{align:e,bottom:a,top:l,result:s}}}}),define("WoltLabSuite/Core/Ui/CloseOverlay",["CallbackList"],function(e){"use strict";var t=new e,i={setup:function(){document.body.addEventListener(WCF_CLICK_EVENT,this.execute.bind(this))},add:t.add.bind(t),remove:t.remove.bind(t),execute:function(){t.forEach(null,function(e){e()})}};return i.setup(),i}),define("WoltLabSuite/Core/Ui/Dropdown/Simple",["CallbackList","Core","Dictionary","EventKey","Ui/Alignment","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/CloseOverlay"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=null,u=new e,d=!1,h=new i,f=new i,p=null,g=null,m="";return{setup:function(){d||(d=!0,p=elCreate("div"),p.className="dropdownMenuContainer",document.body.appendChild(p),c=elByClass("dropdownToggle"),this.initAll(),s.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.closeAll.bind(this)),r.add("WoltLabSuite/Core/Ui/Dropdown/Simple",this.initAll.bind(this)),document.addEventListener("scroll",this._onScroll.bind(this)),window.bc_wcfSimpleDropdown=this,g=this._dropdownMenuKeyDown.bind(this))},initAll:function(){for(var e=0,t=c.length;e<t;e++)this.init(c[e],!1)},init:function(e,i){if(this.setup(),elAttr(e,"role","button"),elAttr(e,"tabindex","0"),elAttr(e,"aria-haspopup",!0),elAttr(e,"aria-expanded",!1),e.classList.contains("jsDropdownEnabled")||elData(e,"target"))return!1;var n=a.parentByClass(e,"dropdown");if(null===n)throw new Error("Invalid dropdown passed, button '"+l.identify(e)+"' does not have a parent with .dropdown.");var o=a.nextByClass(e,"dropdownMenu");if(null===o)throw new Error("Invalid dropdown passed, button '"+l.identify(e)+"' does not have a menu as next sibling.");p.appendChild(o);var r=l.identify(n);if(!h.has(r)&&(e.classList.add("jsDropdownEnabled"),e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this)),e.addEventListener("keydown",this._handleKeyDown.bind(this)),h.set(r,n),f.set(r,o),r.match(/^wcf\d+$/)||elData(o,"source",r),o.childElementCount&&o.children[0].classList.contains("scrollableDropdownMenu"))){o=o.children[0],elData(o,"scroll-to-active",!0);var s=null,c=null;o.addEventListener("wheel",function(e){null===s&&(s=o.clientHeight),null===c&&(c=o.scrollHeight),e.deltaY<0&&0===o.scrollTop?e.preventDefault():e.deltaY>0&&o.scrollTop+s===c&&e.preventDefault()},{passive:!1})}elData(e,"target",r),i&&setTimeout(function(){elData(e,"dropdown-lazy-init",i instanceof MouseEvent),t.triggerEvent(e,WCF_CLICK_EVENT),setTimeout(function(){e.removeAttribute("data-dropdown-lazy-init")},10)},10)},initFragment:function(e,t){this.setup();var i=l.identify(e);h.has(i)||(h.set(i,e),p.appendChild(t),f.set(i,t))},registerCallback:function(e,t){u.add(e,t)},getDropdown:function(e){return h.get(e)},getDropdownMenu:function(e){return f.get(e)},toggleDropdown:function(e,t,i){this._toggle(null,e,t,i)},setAlignment:function(e,t,i){var n,r=elBySel(".dropdownToggle",e);null!==r&&r.parentNode.classList.contains("inputAddonTextarea")&&(n=r),o.set(t,i||e,{pointerClassNames:["dropdownArrowBottom","dropdownArrowRight"],refDimensionsElement:n||null,horizontal:"right"===elData(t,"dropdown-alignment-horizontal")?"right":"left",vertical:"top"===elData(t,"dropdown-alignment-vertical")?"top":"bottom",allowFlip:elData(t,"dropdown-allow-flip")||"both"})},setAlignmentById:function(e){var t=h.get(e);if(void 0===t)throw new Error("Unknown dropdown identifier '"+e+"'.");var i=f.get(e);this.setAlignment(t,i)},isOpen:function(e){var t=f.get(e);return void 0!==t&&t.classList.contains("dropdownOpen")},open:function(e,t){var i=f.get(e);void 0===i||i.classList.contains("dropdownOpen")||this.toggleDropdown(e,void 0,t)},close:function(e){var t=h.get(e);void 0!==t&&(t.classList.remove("dropdownOpen"),f.get(e).classList.remove("dropdownOpen"))},closeAll:function(){h.forEach(function(e,t){
+e.classList.contains("dropdownOpen")&&(e.classList.remove("dropdownOpen"),f.get(t).classList.remove("dropdownOpen"),this._notifyCallbacks(t,"close"))}.bind(this))},destroy:function(e){if(!h.has(e))return!1;try{this.close(e),elRemove(f.get(e))}catch(e){}return f.delete(e),h.delete(e),!0},_onDialogScroll:function(e){for(var t=e.currentTarget,i=elBySelAll(".dropdown.dropdownOpen",t),n=0,o=i.length;n<o;n++){var r=i[n],a=l.identify(r),s=l.offset(r),c=l.offset(t);s.top+r.clientHeight<=c.top?this.toggleDropdown(a):s.top>=c.top+t.offsetHeight?this.toggleDropdown(a):s.left<=c.left?this.toggleDropdown(a):s.left>=c.left+t.offsetWidth?this.toggleDropdown(a):this.setAlignment(h.get(a),f.get(a))}},_onScroll:function(){h.forEach(function(e,t){if(e.classList.contains("dropdownOpen"))if(elDataBool(e,"is-overlay-dropdown-button"))this.setAlignment(e,f.get(t));else{var i=f.get(e.id);elDataBool(i,"dropdown-ignore-page-scroll")||this.close(t)}}.bind(this))},_notifyCallbacks:function(e,t){u.forEach(e,function(i){i(e,t)})},_toggle:function(e,t,i,n){null!==e&&(e.preventDefault(),e.stopPropagation(),t=elData(e.currentTarget,"target"),void 0===n&&e instanceof MouseEvent&&(n=!0));var o=h.get(t),r=!1;if(void 0!==o){var l,s;if(e&&(l=e.currentTarget,(s=l.parentNode)!==o&&(s.classList.add("dropdown"),s.id=o.id,o.classList.remove("dropdown"),o.id="",o=s,h.set(t,s))),void 0===n&&(l=o.closest(".dropdownToggle"),l||!(l=elBySel(".dropdownToggle",o))&&o.id&&(l=elBySel('[data-target="'+o.id+'"]')),l&&elDataBool(l,"dropdown-lazy-init")&&(n=!0)),elDataBool(o,"dropdown-prevent-toggle")&&o.classList.contains("dropdownOpen")&&(r=!0),""===elData(o,"is-overlay-dropdown-button")){var c=a.parentByClass(o,"dialogContent");elData(o,"is-overlay-dropdown-button",null!==c),null!==c&&c.addEventListener("scroll",this._onDialogScroll.bind(this))}}return m="",h.forEach(function(e,o){var a=f.get(o);if(e.classList.contains("dropdownOpen"))if(!1===r){e.classList.remove("dropdownOpen"),a.classList.remove("dropdownOpen");var l=elBySel(".dropdownToggle",e);l&&elAttr(l,"aria-expanded",!1),this._notifyCallbacks(o,"close")}else m=t;else if(o===t&&a.childElementCount>0){m=t,e.classList.add("dropdownOpen"),a.classList.add("dropdownOpen");var l=elBySel(".dropdownToggle",e);if(l&&elAttr(l,"aria-expanded",!0),a.childElementCount&&elDataBool(a.children[0],"scroll-to-active")){var s=a.children[0];s.removeAttribute("data-scroll-to-active");for(var c=null,u=0,d=s.childElementCount;u<d;u++)if(s.children[u].classList.contains("active")){c=s.children[u];break}c&&(s.scrollTop=Math.max(c.offsetTop+c.clientHeight-a.clientHeight,0))}var h=elBySel(".scrollableDropdownMenu",a);null!==h&&h.classList[h.scrollHeight>h.clientHeight?"add":"remove"]("forceScrollbar"),this._notifyCallbacks(o,"open");var p=null;n||(elAttr(a,"role","menu"),elAttr(a,"tabindex",-1),a.removeEventListener("keydown",g),a.addEventListener("keydown",g),elBySelAll("li",a,function(e){e.clientHeight&&(null===p?p=e:e.classList.contains("active")&&(p=e),elAttr(e,"role","menuitem"),elAttr(e,"tabindex",-1))})),this.setAlignment(e,a,i),null!==p&&p.focus()}}.bind(this)),window.WCF.Dropdown.Interactive.Handler.closeAll(),null===e},_handleKeyDown:function(e){"INPUT"!==e.currentTarget.nodeName&&(n.Enter(e)||n.Space(e))&&(e.preventDefault(),this._toggle(e))},_dropdownMenuKeyDown:function(e){var t,i,o=document.activeElement;if("LI"===o.nodeName)if(n.ArrowDown(e)||n.ArrowUp(e)||n.End(e)||n.Home(e)){e.preventDefault();var r=Array.prototype.slice.call(elBySelAll("li",o.closest(".dropdownMenu")));(n.ArrowUp(e)||n.End(e))&&r.reverse();var a=null,l=function(e){return!e.classList.contains("dropdownDivider")&&e.clientHeight>0},s=r.indexOf(o);(n.End(e)||n.Home(e))&&(s=-1);for(var c=s+1;c<r.length;c++)if(l(r[c])){a=r[c];break}if(null===a)for(c=0;c<r.length;c++)if(l(r[c])){a=r[c];break}a.focus()}else if(n.Enter(e)||n.Space(e)){e.preventDefault();var u=o;1!==u.childElementCount||"SPAN"!==u.children[0].nodeName&&"A"!==u.children[0].nodeName||(u=u.children[0]),i=h.get(m),t=elBySel(".dropdownToggle",i),require(["Core"],function(e){var n=elData(i,"a11y-mouse-event")||"click";e.triggerEvent(u,n),t&&t.focus()})}else(n.Escape(e)||n.Tab(e))&&(e.preventDefault(),i=h.get(m),t=elBySel(".dropdownToggle",i),null!==t||i.classList.contains("dropdown")||(t=i),this._toggle(null,m),t&&t.focus())}}}),define("WoltLabSuite/Core/Devtools",[],function(){"use strict";return{help:function(){},toggleEditorAutosave:function(){},toggleEventLogging:function(){},_internal_:{enable:function(){},editorAutosave:function(){},eventLog:function(){}}}}),define("WoltLabSuite/Core/Event/Handler",["Core","Devtools","Dictionary"],function(e,t,i){"use strict";var n=new i;return{add:function(t,o,r){if("function"!=typeof r)throw new TypeError("[WoltLabSuite/Core/Event/Handler] Expected a valid callback for '"+o+"@"+t+"'.");var a=n.get(t);void 0===a&&(a=new i,n.set(t,a));var l=a.get(o);void 0===l&&(l=new i,a.set(o,l));var s=e.getUuid();return l.set(s,r),s},fire:function(e,i,o){t._internal_.eventLog(e,i),o=o||{};var r=n.get(e);if(void 0!==r){var a=r.get(i);void 0!==a&&a.forEach(function(e){e(o)})}},remove:function(e,t,i){var o=n.get(e);if(void 0!==o){var r=o.get(t);void 0!==r&&r.delete(i)}},removeAll:function(e,t){"string"!=typeof t&&(t=void 0);var i=n.get(e);void 0!==i&&(void 0===t?n.delete(e):i.delete(t))},removeAllBySuffix:function(e,t){var i=n.get(e);if(void 0!==i){t="_"+t;var o=-1*t.length;i.forEach(function(i,n){n.substr(o)===t&&this.removeAll(e,n)}.bind(this))}}}}),define("WoltLabSuite/Core/List",[],function(){"use strict";function e(){this._set=t?new Set:[]}var t=objOwns(window,"Set")&&"function"==typeof window.Set;return e.prototype={add:function(e){t?this._set.add(e):this.has(e)||this._set.push(e)},clear:function(){t?this._set.clear():this._set=[]},delete:function(e){if(t)return this._set.delete(e);var i=this._set.indexOf(e);return-1!==i&&(this._set.splice(i,1),!0)},forEach:function(e){if(t)this._set.forEach(e);else for(var i=0,n=this._set.length;i<n;i++)e(this._set[i])},has:function(e){return t?this._set.has(e):-1!==this._set.indexOf(e)}},Object.defineProperty(e.prototype,"size",{enumerable:!1,configurable:!0,get:function(){return t?this._set.size:this._set.length}}),e}),define("WoltLabSuite/Core/Ui/Dialog",["Ajax","Core","Dictionary","Environment","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/Screen","Ui/SimpleDropdown","EventHandler","List","EventKey"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f,p){"use strict";var g=null,m=null,v=null,b=new i,_=!1,w=new r,y=new i,C=null,E=null,L=elByClass("jsStaticDialog"),A=["onBeforeClose","onClose","onShow"],S=["number","password","search","tel","text","url"],x=['a[href]:not([tabindex^="-"]):not([inert])','area[href]:not([tabindex^="-"]):not([inert])',"input:not([disabled]):not([inert])","select:not([disabled]):not([inert])","textarea:not([disabled]):not([inert])","button:not([disabled]):not([inert])",'iframe:not([tabindex^="-"]):not([inert])','audio:not([tabindex^="-"]):not([inert])','video:not([tabindex^="-"]):not([inert])','[contenteditable]:not([tabindex^="-"]):not([inert])','[tabindex]:not([tabindex^="-"]):not([inert])'];return{setup:function(){void 0===e&&(e=require("Ajax")),v=elCreate("div"),v.classList.add("dialogOverlay"),elAttr(v,"aria-hidden","true"),v.addEventListener("mousedown",this._closeOnBackdrop.bind(this)),v.addEventListener("wheel",function(e){e.target===v&&e.preventDefault()},{passive:!1}),elById("content").appendChild(v),E=function(e){return 27!==e.keyCode||"INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName||(this.close(g),!1)}.bind(this),u.on("screen-xs",{match:function(){_=!0},unmatch:function(){_=!1},setup:function(){_=!0}}),this._initStaticDialogs(),a.add("Ui/Dialog",this._initStaticDialogs.bind(this)),u.setDialogContainer(v),window.addEventListener("resize",function(){b.forEach(function(e){elAttrBool(e.dialog,"aria-hidden")||this.rebuild(elData(e.dialog,"id"))}.bind(this))}.bind(this))},_initStaticDialogs:function(){for(var e,t,i;L.length;)e=L[0],e.classList.remove("jsStaticDialog"),(i=elData(e,"dialog-id"))&&(t=elById(i))&&function(e,t){t.classList.remove("jsStaticDialogContent"),elData(t,"is-static-dialog",!0),elHide(t),e.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),this.openStatic(t.id,null,{title:elData(t,"title")})}.bind(this))}.bind(this)(e,t)},open:function(i,n){var o=w.get(i);if(t.isPlainObject(o))return this.openStatic(o.id,n);if("function"!=typeof i._dialogSetup)throw new Error("Callback object does not implement the method '_dialogSetup()'.");var r=i._dialogSetup();if(!t.isPlainObject(r))throw new Error("Expected an object literal as return value of '_dialogSetup()'.");o={id:r.id};var a=!0;if(void 0===r.source){var l=elById(r.id);if(null===l)throw new Error("Element id '"+r.id+"' is invalid and no source attribute was given. If you want to use the `html` argument instead, please add `source: null` to your dialog configuration.");r.source=document.createDocumentFragment(),r.source.appendChild(l),l.removeAttribute("id"),elShow(l)}else if(null===r.source)r.source=n;else if("function"==typeof r.source)r.source();else if(t.isPlainObject(r.source)){if("string"!=typeof n||""===n.trim())return e.api(this,r.source.data,function(e){e.returnValues&&"string"==typeof e.returnValues.template&&(this.open(i,e.returnValues.template),"function"==typeof r.source.after&&r.source.after(b.get(r.id).content,e))}.bind(this)),{};r.source=n}else{if("string"==typeof r.source){var l=elCreate("div");elAttr(l,"id",r.id),s.setInnerHtml(l,r.source),r.source=document.createDocumentFragment(),r.source.appendChild(l)}if(!r.source.nodeType||r.source.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)throw new Error("Expected at least a document fragment as 'source' attribute.");a=!1}return w.set(i,o),y.set(r.id,i),this.openStatic(r.id,r.source,r.options,a)},openStatic:function(e,i,r,a){u.pageOverlayOpen(),"desktop"!==n.platform()&&(this.isOpen(e)||u.scrollDisable()),b.has(e)?this._updateDialog(e,i):(r=t.extend({backdropCloseOnClick:!0,closable:!0,closeButtonLabel:o.get("wcf.global.button.close"),closeConfirmMessage:"",disableContentPadding:!1,title:"",onBeforeClose:null,onClose:null,onShow:null},r),r.closable||(r.backdropCloseOnClick=!1),r.closeConfirmMessage&&(r.onBeforeClose=function(e){c.show({confirm:this.close.bind(this,e),message:r.closeConfirmMessage})}.bind(this)),this._createDialog(e,i,r));var l=b.get(e);return"ios"===n.platform()&&window.setTimeout(function(){var e=elBySel("input, textarea",l.content);null!==e&&e.focus()}.bind(this),200),l},setTitle:function(e,t){e=this._getDialogId(e);var i=b.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");var n=elByClass("dialogTitle",i.dialog);n.length&&(n[0].textContent=t)},setCallback:function(e,t,i){if("object"==typeof e){var n=w.get(e);void 0!==n&&(e=n.id)}var o=b.get(e);if(void 0===o)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if(-1===A.indexOf(t))throw new Error("Invalid callback identifier, '"+t+"' is not recognized.");if("function"!=typeof i&&null!==i)throw new Error("Only functions or the 'null' value are acceptable callback values ('"+typeof i+"' given).");o[t]=i},_createDialog:function(e,t,i,n){var o=null;if(null===t&&null===(o=elById(e)))throw new Error("Expected either a HTML string or an existing element id.");var r=elCreate("div");r.classList.add("dialogContainer"),elAttr(r,"aria-hidden","true"),elAttr(r,"role","dialog"),elData(r,"id",e);var a=elCreate("header");r.appendChild(a);var l=s.getUniqueId();elAttr(r,"aria-labelledby",l);var c=elCreate("span");if(c.classList.add("dialogTitle"),c.textContent=i.title,elAttr(c,"id",l),a.appendChild(c),i.closable){var u=elCreate("a");u.className="dialogCloseButton jsTooltip",u.href="#",elAttr(u,"role","button"),elAttr(u,"tabindex","0"),elAttr(u,"title",i.closeButtonLabel),elAttr(u,"aria-label",i.closeButtonLabel),u.addEventListener(WCF_CLICK_EVENT,this._close.bind(this)),a.appendChild(u);var d=elCreate("span");d.className="icon icon24 fa-times",u.appendChild(d)}var h=elCreate("div");h.classList.add("dialogContent"),i.disableContentPadding&&h.classList.add("dialogContentNoPadding"),r.appendChild(h),h.addEventListener("wheel",function(e){for(var t,i,n,o=!1,r=e.target;;){if(t=r.clientHeight,i=r.scrollHeight,t<i){if(n=r.scrollTop,e.deltaY<0&&n>0){o=!0;break}if(e.deltaY>0&&n+t<i){o=!0;break}}if(!r||r===h)break;r=r.parentNode}!1===o&&e.preventDefault()},{passive:!1});var p;if(null===o)if("string"==typeof t)p=elCreate("div"),p.id=e,s.setInnerHtml(p,t);else{if(!(t instanceof DocumentFragment))throw new TypeError("'html' must either be a string or a DocumentFragment");for(var g,m=[],_=0,w=t.childNodes.length;_<w;_++)g=t.childNodes[_],g.nodeType===Node.ELEMENT_NODE&&m.push(g);"DIV"!==m[0].nodeName||m.length>1?(p=elCreate("div"),p.id=e,p.appendChild(t)):p=m[0]}else p=o;h.appendChild(p),"none"===p.style.getPropertyValue("display")&&elShow(p),b.set(e,{backdropCloseOnClick:i.backdropCloseOnClick,closable:i.closable,content:p,dialog:r,header:a,onBeforeClose:i.onBeforeClose,onClose:i.onClose,onShow:i.onShow,submitButton:null,inputFields:new f}),s.prepend(r,v),"function"==typeof i.onSetup&&i.onSetup(p),!0!==n&&this._updateDialog(e,null)},_updateDialog:function(e,t){var i=b.get(e);if(void 0===i)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("string"==typeof t&&s.setInnerHtml(i.content,t),"true"===elAttr(i.dialog,"aria-hidden")){d.closeAll(),window.WCF.Dropdown.Interactive.Handler.closeAll(),null===m&&(m=this._maintainFocus.bind(this),document.body.addEventListener("focus",m,{capture:!0})),i.closable&&"true"===elAttr(v,"aria-hidden")&&window.addEventListener("keyup",E),i.dialog.parentNode.insertBefore(i.dialog,i.dialog.parentNode.firstChild),elAttr(i.dialog,"aria-hidden","false"),elAttr(v,"aria-hidden","false"),elData(v,"close-on-click",i.backdropCloseOnClick?"true":"false"),g=e,C=document.activeElement;var n=elBySel(".dialogCloseButton",i.header);n&&elAttr(n,"inert",!0),this._setFocusToFirstItem(i.dialog),n&&n.removeAttribute("inert"),"function"==typeof i.onShow&&i.onShow(i.content),elDataBool(i.content,"is-static-dialog")&&h.fire("com.woltlab.wcf.dialog","openStatic",{content:i.content,id:e})}this.rebuild(e),a.trigger()},_maintainFocus:function(e){if(g){var t=b.get(g);t.dialog.contains(e.target)||e.target.closest(".dropdownMenuContainer")||e.target.closest(".datePicker")||this._setFocusToFirstItem(t.dialog,!0)}},_setFocusToFirstItem:function(e,t){var i=this._getFirstFocusableChild(e);null!==i&&(t&&("username"!==i.id&&"username"!==i.name||"safari"===n.browser()&&"ios"===n.platform()&&(i=null)),i&&setTimeout(function(){i.focus()},1))},_getFirstFocusableChild:function(e){for(var t=elBySelAll(x.join(","),e),i=0,n=t.length;i<n;i++)if(t[i].offsetWidth&&t[i].offsetHeight&&t[i].getClientRects().length)return t[i];return null},rebuild:function(e){e=this._getDialogId(e);var t=b.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");if("true"!==elAttr(t.dialog,"aria-hidden")){var i=t.content.parentNode,o=elBySel(".formSubmit",t.content),r=0;null!==o?(i.classList.add("dialogForm"),o.classList.add("dialogFormSubmit"),r+=s.outerHeight(o),r-=1,i.style.setProperty("margin-bottom",r+"px","")):(i.classList.remove("dialogForm"),i.style.removeProperty("margin-bottom")),r+=s.outerHeight(t.header);var a=window.innerHeight*(_?1:.8)-r;i.style.setProperty("max-height",~~a+"px",""),"chrome"!==n.browser()&&"safari"!==n.browser()||t.content.parentNode.classList.add("jsWebKitFractionalPixelFix");var l=y.get(e);if(void 0!==l&&"function"==typeof l._dialogSubmit){var c=elBySelAll('input[data-dialog-submit-on-enter="true"]',t.content),u=elBySel('.formSubmit > input[type="submit"], .formSubmit > button[data-type="submit"]',t.content);if(null===u)return void(0===c.length&&console.warn("Broken dialog, expected a submit button.",t.content));if(t.submitButton!==u){t.submitButton=u,u.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),this._submit(e)}.bind(this));for(var d,h=null,f=0,g=c.length;f<g;f++)d=c[f],t.inputFields.has(d)||(-1!==S.indexOf(d.type)?(t.inputFields.add(d),null===h&&(h=function(t){p.Enter(t)&&(t.preventDefault(),this._submit(e))}.bind(this)),d.addEventListener("keydown",h)):console.warn("Unsupported input type.",d))}}}},_submit:function(e){var t=b.get(e),i=!0;t.inputFields.forEach(function(e){e.required&&(""===e.value.trim()?(elInnerError(e,o.get("wcf.global.form.error.empty")),i=!1):elInnerError(e,!1))}),i&&y.get(e)._dialogSubmit()},_close:function(e){e.preventDefault();var t=b.get(g);if("function"==typeof t.onBeforeClose)return t.onBeforeClose(g),!1;this.close(g)},_closeOnBackdrop:function(e){if(e.target!==v)return!0;"true"===elData(v,"close-on-click")?this._close(e):e.preventDefault()},close:function(e){e=this._getDialogId(e);var t=b.get(e);if(void 0===t)throw new Error("Expected a valid dialog id, '"+e+"' does not match any active dialog.");elAttr(t.dialog,"aria-hidden","true"),document.activeElement.closest(".dialogContainer")===t.dialog&&document.activeElement.blur(),"function"==typeof t.onClose&&t.onClose(e),g=null;for(var i=0;i<v.childElementCount;i++){var o=v.children[i];if("false"===elAttr(o,"aria-hidden")){g=elData(o,"id");break}}u.pageOverlayClose(),null===g?(elAttr(v,"aria-hidden","true"),elData(v,"close-on-click","false"),t.closable&&window.removeEventListener("keyup",E)):(t=b.get(g),elData(v,"close-on-click",t.backdropCloseOnClick?"true":"false")),"desktop"!==n.platform()&&u.scrollEnable()},getDialog:function(e){return b.get(this._getDialogId(e))},isOpen:function(e){var t=this.getDialog(e);return void 0!==t&&"false"===elAttr(t.dialog,"aria-hidden")},destroy:function(e){if("object"!=typeof e||e instanceof String)throw new TypeError("Expected the callback object as parameter.");if(w.has(e)){var t=w.get(e).id;this.isOpen(t)&&this.close(t),b.has(t)&&(elRemove(b.get(t).dialog),b.delete(t)),w.delete(e)}},_getDialogId:function(e){if("object"==typeof e){var t=w.get(e);if(void 0!==t)return t.id}return e.toString()},_ajaxSetup:function(){return{}}}}),define("WoltLabSuite/Core/Ajax/Status",["Language"],function(e){"use strict";var t=0,i=null,n=null;return{_init:function(){i=elCreate("div"),i.classList.add("spinner"),elAttr(i,"role","status");var t=elCreate("span");t.className="icon icon48 fa-spinner",i.appendChild(t);var n=elCreate("span");n.textContent=e.get("wcf.global.loading"),i.appendChild(n),document.body.appendChild(i)},show:function(){null===i&&this._init(),t++,null===n&&(n=window.setTimeout(function(){t&&i.classList.add("active"),n=null},250))},hide:function(){0===--t&&(null!==n&&window.clearTimeout(n),i.classList.remove("active"))}}}),define("WoltLabSuite/Core/Ajax/Request",["Core","Language","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,o,r){"use strict";function a(e){this._data=null,this._options={},this._previousXhr=null,this._xhr=null,this._init(e)}var l=!1,s=!1;return a.prototype={_init:function(t){this._options=e.extend({data:{},contentType:"application/x-www-form-urlencoded; charset=UTF-8",responseType:"application/json",type:"POST",url:"",withCredentials:!1,autoAbort:!1,ignoreError:!1,pinData:!1,silent:!1,includeRequestedWith:!0,failure:null,finalize:null,success:null,progress:null,uploadProgress:null,callbackObject:null},t),"object"==typeof t.callbackObject&&(this._options.callbackObject=t.callbackObject),this._options.url=e.convertLegacyUrl(this._options.url),0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),0===this._options.url.indexOf(WSC_API_URL)&&(this._options.includeRequestedWith=!0,this._options.withCredentials=!0),this._options.pinData&&(this._data=e.extend({},this._options.data)),null!==this._options.callbackObject&&("function"==typeof this._options.callbackObject._ajaxFailure&&(this._options.failure=this._options.callbackObject._ajaxFailure.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxFinalize&&(this._options.finalize=this._options.callbackObject._ajaxFinalize.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxSuccess&&(this._options.success=this._options.callbackObject._ajaxSuccess.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxProgress&&(this._options.progress=this._options.callbackObject._ajaxProgress.bind(this._options.callbackObject)),"function"==typeof this._options.callbackObject._ajaxUploadProgress&&(this._options.uploadProgress=this._options.callbackObject._ajaxUploadProgress.bind(this._options.callbackObject))),!1===l&&(l=!0,window.addEventListener("beforeunload",function(){s=!0}))},sendRequest:function(t){(!0===t||this._options.autoAbort)&&this.abortPrevious(),this._options.silent||r.show(),this._xhr instanceof XMLHttpRequest&&(this._previousXhr=this._xhr),this._xhr=new XMLHttpRequest,this._xhr.open(this._options.type,this._options.url,!0),this._options.contentType&&this._xhr.setRequestHeader("Content-Type",this._options.contentType),(this._options.withCredentials||this._options.includeRequestedWith)&&this._xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),this._options.withCredentials&&(this._xhr.withCredentials=!0);var i=this,n=e.clone(this._options);if(this._xhr.onload=function(){this.readyState===XMLHttpRequest.DONE&&(this.status>=200&&this.status<300||304===this.status?n.responseType&&0!==this.getResponseHeader("Content-Type").indexOf(n.responseType)?i._failure(this,n):i._success(this,n):i._failure(this,n))},this._xhr.onerror=function(){i._failure(this,n)},this._options.progress&&(this._xhr.onprogress=this._options.progress),this._options.uploadProgress&&(this._xhr.upload.onprogress=this._options.uploadProgress),"POST"===this._options.type){var o=this._options.data;"object"==typeof o&&"FormData"!==e.getType(o)&&(o=e.serialize(o)),this._xhr.send(o)}else this._xhr.send()},abortPrevious:function(){null!==this._previousXhr&&(this._previousXhr.abort(),this._previousXhr=null,this._options.silent||r.hide())},setOption:function(e,t){this._options[e]=t},getOption:function(e){return objOwns(this._options,e)?this._options[e]:null},setData:function(t){null!==this._data&&"FormData"!==e.getType(t)&&(t=e.extend(this._data,t)),this._options.data=t},_success:function(e,t){if(t.silent||r.hide(),"function"==typeof t.success){var i=null;if("application/json"===e.getResponseHeader("Content-Type").split(";",1)[0].trim()){try{i=JSON.parse(e.responseText)}catch(i){return void this._failure(e,t)}i&&i.returnValues&&void 0!==i.returnValues.template&&(i.returnValues.template=i.returnValues.template.trim()),i&&i.forceBackgroundQueuePerform&&require(["WoltLabSuite/Core/BackgroundQueue"],function(e){e.invoke()})}t.success(i,e.responseText,e,t.data)}this._finalize(t)},_failure:function(e,i){if(!s){i.silent||r.hide();var a=null;try{a=JSON.parse(e.responseText)}catch(e){}var l=!0;if("function"==typeof i.failure&&(l=i.failure(a||{},e.responseText||"",e,i.data)),!0!==i.ignoreError&&!1!==l){var c=this.getErrorHtml(a,e);c&&(void 0===o&&(o=require("Ui/Dialog")),o.openStatic(n.getUniqueId(),c,{title:t.get("wcf.global.error.title")}))}this._finalize(i)}},getErrorHtml:function(e,t){var i="",n="";if(null!==e?(e.returnValues&&e.returnValues.description&&(i+="<br><p>Description:</p><p>"+e.returnValues.description+"</p>"),e.file&&e.line&&(i+="<br><p>File:</p><p>"+e.file+" in line "+e.line+"</p>"),e.stacktrace?i+="<br><p>Stacktrace:</p><p>"+e.stacktrace+"</p>":e.exceptionID&&(i+="<br><p>Exception ID: <code>"+e.exceptionID+"</code></p>"),n=e.message,e.previous.forEach(function(e){i+="<hr><p>"+e.message+"</p>",i+="<br><p>Stacktrace</p><p>"+e.stacktrace+"</p>"})):n=t.responseText,!n||"undefined"===n){if(!ENABLE_DEBUG_MODE)return null;n="XMLHttpRequest failed without a responseText. Check your browser console."}return'<div class="ajaxDebugMessage"><p>'+n+"</p>"+i+"</div>"},_finalize:function(e){"function"==typeof e.finalize&&e.finalize(this._xhr),this._previousXhr=null,i.trigger();for(var t=elBySelAll('a[href*="#"]'),n=0,o=t.length;n<o;n++){var r=t[n],a=elAttr(r,"href");-1===a.indexOf("AJAXProxy")&&-1===a.indexOf("ajax-proxy")||(a=a.substr(a.indexOf("#")),elAttr(r,"href",document.location.toString().replace(/#.*/,"")+a))}}},a}),define("WoltLabSuite/Core/Ajax",["AjaxRequest","Core","ObjectMap"],function(e,t,i){"use strict";var n=new i;return{api:function(t,i,o,r){void 0===e&&(e=require("AjaxRequest")),"object"!=typeof i&&(i={});var a=n.get(t);if(void 0===a){if("function"!=typeof t._ajaxSetup)throw new TypeError("Callback object must implement at least _ajaxSetup().");var l=t._ajaxSetup();l.pinData=!0,l.callbackObject=t,l.url||(l.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,l.withCredentials=!0),a=new e(l),n.set(t,a)}var s=null,c=null;return"function"==typeof o&&(s=a.getOption("success"),a.setOption("success",o)),"function"==typeof r&&(c=a.getOption("failure"),a.setOption("failure",r)),a.setData(i),a.sendRequest(),null!==s&&a.setOption("success",s),null!==c&&a.setOption("failure",c),a},apiOnce:function(t){void 0===e&&(e=require("AjaxRequest")),t.pinData=!1,t.callbackObject=null,t.url||(t.url="index.php?ajax-proxy/&t="+SECURITY_TOKEN,t.withCredentials=!0),new e(t).sendRequest(!1)},getRequestObject:function(e){if(!n.has(e))throw new Error("Expected a previously used callback object, provided object is unknown.");return n.get(e)}}}),define("WoltLabSuite/Core/BackgroundQueue",["Ajax"],function(e){"use strict";var t=0,i=!1,n="";return{setUrl:function(e){n=e},invoke:function(){if(""===n)return void console.error("The background queue has not been initialized yet.");i||(i=!0,e.api(this))},_ajaxSuccess:function(e){t++,e>0&&t<5?window.setTimeout(function(){i=!1,this.invoke()}.bind(this),1e3):(i=!1,t=0)},_ajaxSetup:function(){return{url:n,ignoreError:!0,silent:!0}}}}),function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||m)return!1;try{u.clearRect(0,0,s,l),u.drawImage(e,0,0,s,l)}catch(e){}_=setTimeout(function(){t(e)},M.duration),B.setIcon(c)}function i(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,i,n){return t+t+i+i+n+n});var i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return!!i&&{r:parseInt(i[1],16),g:parseInt(i[2],16),b:parseInt(i[3],16)}}function n(e,t){var i,n={};for(i in e)n[i]=e[i];for(i in t)n[i]=t[i];return n}function o(){return w.hidden||w.msHidden||w.webkitHidden||w.mozHidden}e=e||{};var r,a,l,s,c,u,d,h,f,p,g,m,v,b,_,w,y={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1,element:null,dataUrl:!1,win:window};v={},v.ff="undefined"!=typeof InstallTrigger,v.chrome=!!window.chrome,v.opera=!!window.opera||navigator.userAgent.indexOf("Opera")>=0,v.ie=!1,v.safari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,v.supported=v.chrome||v.ff||v.opera;var C=[];g=function(){},h=m=!1;var E={};E.ready=function(){h=!0,E.reset(),g()},E.reset=function(){h&&(C=[],f=!1,p=!1,u.clearRect(0,0,s,l),u.drawImage(d,0,0,s,l),B.setIcon(c),window.clearTimeout(b),window.clearTimeout(_))},E.start=function(){if(h&&!p){var e=function(){f=C[0],p=!1,C.length>0&&(C.shift(),E.start())};if(C.length>0){p=!0;var t=function(){["type","animation","bgColor","textColor","fontFamily","fontStyle"].forEach(function(e){e in C[0].options&&(r[e]=C[0].options[e])}),M.run(C[0].options,function(){e()},!1)};f?M.run(f.options,function(){t()},!0):t()}}};var L={},A=function(e){return e.n="number"==typeof e.n?Math.abs(0|e.n):e.n,e.x=s*e.x,e.y=l*e.y,e.w=s*e.w,e.h=l*e.h,e.len=(""+e.n).length,e};L.circle=function(e){e=A(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),u.clearRect(0,0,s,l),u.drawImage(d,0,0,s,l),u.beginPath(),u.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+r.fontFamily,u.textAlign="center",t?(u.moveTo(e.x+e.w/2,e.y),u.lineTo(e.x+e.w-e.h/2,e.y),u.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),u.lineTo(e.x+e.w,e.y+e.h-e.h/2),u.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),u.lineTo(e.x+e.h/2,e.y+e.h),u.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),u.lineTo(e.x,e.y+e.h/2),u.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):u.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),u.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",u.fill(),u.closePath(),u.beginPath(),u.stroke(),u.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?u.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):u.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),u.closePath()},L.rectangle=function(e){e=A(e);2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w),u.clearRect(0,0,s,l),u.drawImage(d,0,0,s,l),u.beginPath(),u.font=r.fontStyle+" "+Math.floor(e.h*(e.n>99?.9:1))+"px "+r.fontFamily,u.textAlign="center",u.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+e.o+")",u.fillRect(e.x,e.y,e.w,e.h),u.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?u.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):u.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),u.closePath()};var S=function(e,t){t=("string"==typeof t?{animation:t}:t)||{},g=function(){try{if("number"==typeof e?e>0:""!==e){var n={type:"badge",options:{n:e}};if("animation"in t&&M.types[""+t.animation]&&(n.options.animation=""+t.animation),"type"in t&&L[""+t.type]&&(n.options.type=""+t.type),["bgColor","textColor"].forEach(function(e){e in t&&(n.options[e]=i(t[e]))}),["fontStyle","fontFamily"].forEach(function(e){e in t&&(n.options[e]=t[e])}),C.push(n),C.length>100)throw new Error("Too many badges requests in queue.");E.start()}else E.reset()}catch(e){throw new Error("Error setting badge. Message: "+e.message)}},h&&g()},x=function(e){g=function(){try{var t=e.width,i=e.height,n=document.createElement("img"),o=t/s<i/l?t/s:i/l;n.setAttribute("crossOrigin","anonymous"),n.onload=function(){u.clearRect(0,0,s,l),u.drawImage(n,0,0,s,l),B.setIcon(c)},n.setAttribute("src",e.getAttribute("src")),n.height=i/o,n.width=t/o}catch(e){throw new Error("Error setting image. Message: "+e.message)}},h&&g()},I=function(e){g=function(){B.setIconSrc(e)},h&&g()},D=function(e){g=function(){try{if("stop"===e)return m=!0,E.reset(),void(m=!1);e.addEventListener("play",function(){t(this)},!1)}catch(e){throw new Error("Error setting video. Message: "+e.message)}},h&&g()},T=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),v.supported){var i=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,g=function(){try{if("stop"===e)return m=!0,E.reset(),void(m=!1);i=document.createElement("video"),i.width=s,i.height=l,navigator.getUserMedia({video:!0,audio:!1},function(e){i.src=URL.createObjectURL(e),i.play(),t(i)},function(){})}catch(e){throw new Error("Error setting webcam. Message: "+e.message)}},h&&g()}},k=function(e,t){var n=e;null==t&&"[object Object]"==Object.prototype.toString.call(e)||(n={},n[e]=t);for(var o=Object.keys(n),a=0;a<o.length;a++)"bgColor"==o[a]||"textColor"==o[a]?r[o[a]]=i(n[o[a]]):r[o[a]]=n[o[a]];C.push(f),E.start()},B={};B.getIcons=function(){var e=[];return r.element?e=[r.element]:r.elementId?(e=[w.getElementById(r.elementId)],e[0].setAttribute("href",e[0].getAttribute("src"))):(e=function(){for(var e=[],t=w.getElementsByTagName("head")[0].getElementsByTagName("link"),i=0;i<t.length;i++)/(^|\s)icon(\s|$)/i.test(t[i].getAttribute("rel"))&&e.push(t[i]);return e}(),
+0===e.length&&(e=[w.createElement("link")],e[0].setAttribute("rel","icon"),w.getElementsByTagName("head")[0].appendChild(e[0]))),e.forEach(function(e){e.setAttribute("type","image/png")}),e},B.setIcon=function(e){var t=e.toDataURL("image/png");B.setIconSrc(t)},B.setIconSrc=function(e){if(r.dataUrl&&r.dataUrl(e),r.element)r.element.setAttribute("href",e),r.element.setAttribute("src",e);else if(r.elementId){var t=w.getElementById(r.elementId);t.setAttribute("href",e),t.setAttribute("src",e)}else if(v.ff||v.opera){var i=a[a.length-1],n=w.createElement("link");a=[n],v.opera&&n.setAttribute("rel","icon"),n.setAttribute("rel","icon"),n.setAttribute("type","image/png"),w.getElementsByTagName("head")[0].appendChild(n),n.setAttribute("href",e),i.parentNode&&i.parentNode.removeChild(i)}else a.forEach(function(t){t.setAttribute("href",e)})};var M={};return M.duration=40,M.types={},M.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],M.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],M.run=function(e,t,i,a){var l=M.types[o()?"none":r.animation];if(a=!0===i?void 0!==a?a:l.length-1:void 0!==a?a:0,t=t||function(){},!(a<l.length&&a>=0))return void t();L[r.type](n(e,l[a])),b=setTimeout(function(){i?a-=1:a+=1,M.run(e,t,i,a)},M.duration),B.setIcon(c)},function(){r=n(y,e),r.bgColor=i(r.bgColor),r.textColor=i(r.textColor),r.position=r.position.toLowerCase(),r.animation=M.types[""+r.animation]?r.animation:y.animation,w=r.win.document;var t=r.position.indexOf("up")>-1,o=r.position.indexOf("left")>-1;if(t||o)for(var h in M.types)for(var f=0;f<M.types[h].length;f++){var p=M.types[h][f];t&&(p.y<.6?p.y=p.y-.4:p.y=p.y-2*p.y+(1-p.w)),o&&(p.x<.6?p.x=p.x-.4:p.x=p.x-2*p.x+(1-p.h)),M.types[h][f]=p}r.type=L[""+r.type]?r.type:y.type,a=B.getIcons(),c=document.createElement("canvas"),d=document.createElement("img");var g=a[a.length-1];g.hasAttribute("href")?(d.setAttribute("crossOrigin","anonymous"),d.onload=function(){l=d.height>0?d.height:32,s=d.width>0?d.width:32,c.height=l,c.width=s,u=c.getContext("2d"),E.ready()},d.setAttribute("src",g.getAttribute("href"))):(l=32,s=32,d.height=l,d.width=s,c.height=l,c.width=s,u=c.getContext("2d"),E.ready())}(),{badge:S,video:D,image:x,rawImageSrc:I,webcam:T,setOpt:k,reset:E.reset,browser:{supported:v.supported}}};void 0!==define&&define.amd?define("favico",[],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(),function(e,t,i){var n=window.matchMedia;"undefined"!=typeof module&&module.exports?module.exports=i(n):"function"==typeof define&&define.amd?define("enquire",[],function(){return t.enquire=i(n)}):t.enquire=i(n)}(0,this,function(e){"use strict";function t(e,t){var i=0,n=e.length;for(i;i<n&&!1!==t(e[i],i);i++);}function i(e){return"[object Array]"===Object.prototype.toString.apply(e)}function n(e){return"function"==typeof e}function o(e){this.options=e,!e.deferSetup&&this.setup()}function r(t,i){this.query=t,this.isUnconditional=i,this.handlers=[],this.mql=e(t);var n=this;this.listener=function(e){n.mql=e,n.assess()},this.mql.addListener(this.listener)}function a(){if(!e)throw new Error("matchMedia not present, legacy browsers require a polyfill");this.queries={},this.browserIsIncapable=!e("only all").matches}return o.prototype={setup:function(){this.options.setup&&this.options.setup(),this.initialised=!0},on:function(){!this.initialised&&this.setup(),this.options.match&&this.options.match()},off:function(){this.options.unmatch&&this.options.unmatch()},destroy:function(){this.options.destroy?this.options.destroy():this.off()},equals:function(e){return this.options===e||this.options.match===e}},r.prototype={addHandler:function(e){var t=new o(e);this.handlers.push(t),this.matches()&&t.on()},removeHandler:function(e){var i=this.handlers;t(i,function(t,n){if(t.equals(e))return t.destroy(),!i.splice(n,1)})},matches:function(){return this.mql.matches||this.isUnconditional},clear:function(){t(this.handlers,function(e){e.destroy()}),this.mql.removeListener(this.listener),this.handlers.length=0},assess:function(){var e=this.matches()?"on":"off";t(this.handlers,function(t){t[e]()})}},a.prototype={register:function(e,o,a){var l=this.queries,s=a&&this.browserIsIncapable;return l[e]||(l[e]=new r(e,s)),n(o)&&(o={match:o}),i(o)||(o=[o]),t(o,function(t){n(t)&&(t={match:t}),l[e].addHandler(t)}),this},unregister:function(e,t){var i=this.queries[e];return i&&(t?i.removeHandler(t):(i.clear(),delete this.queries[e])),this}},new a}),function e(t,i,n){function o(a,l){if(!i[a]){if(!t[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(r)return r(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=i[a]={exports:{}};t[a][0].call(u.exports,function(e){var i=t[a][1][e];return o(i||e)},u,u.exports,e,t,i,n)}return i[a].exports}for(var r="function"==typeof require&&require,a=0;a<n.length;a++)o(n[a]);return o}({1:[function(e,t,i){"use strict";var n=e("../main");"function"==typeof define&&define.amd?define("perfect-scrollbar",n):(window.PerfectScrollbar=n,void 0===window.Ps&&(window.Ps=n))},{"../main":7}],2:[function(e,t,i){"use strict";function n(e,t){var i=e.className.split(" ");i.indexOf(t)<0&&i.push(t),e.className=i.join(" ")}function o(e,t){var i=e.className.split(" "),n=i.indexOf(t);n>=0&&i.splice(n,1),e.className=i.join(" ")}i.add=function(e,t){e.classList?e.classList.add(t):n(e,t)},i.remove=function(e,t){e.classList?e.classList.remove(t):o(e,t)},i.list=function(e){return e.classList?Array.prototype.slice.apply(e.classList):e.className.split(" ")}},{}],3:[function(e,t,i){"use strict";function n(e,t){return window.getComputedStyle(e)[t]}function o(e,t,i){return"number"==typeof i&&(i=i.toString()+"px"),e.style[t]=i,e}function r(e,t){for(var i in t){var n=t[i];"number"==typeof n&&(n=n.toString()+"px"),e.style[i]=n}return e}var a={};a.e=function(e,t){var i=document.createElement(e);return i.className=t,i},a.appendTo=function(e,t){return t.appendChild(e),e},a.css=function(e,t,i){return"object"==typeof t?r(e,t):void 0===i?n(e,t):o(e,t,i)},a.matches=function(e,t){return void 0!==e.matches?e.matches(t):void 0!==e.matchesSelector?e.matchesSelector(t):void 0!==e.webkitMatchesSelector?e.webkitMatchesSelector(t):void 0!==e.mozMatchesSelector?e.mozMatchesSelector(t):void 0!==e.msMatchesSelector?e.msMatchesSelector(t):void 0},a.remove=function(e){void 0!==e.remove?e.remove():e.parentNode&&e.parentNode.removeChild(e)},a.queryChildren=function(e,t){return Array.prototype.filter.call(e.childNodes,function(e){return a.matches(e,t)})},t.exports=a},{}],4:[function(e,t,i){"use strict";var n=function(e){this.element=e,this.events={}};n.prototype.bind=function(e,t){void 0===this.events[e]&&(this.events[e]=[]),this.events[e].push(t),this.element.addEventListener(e,t,!1)},n.prototype.unbind=function(e,t){var i=void 0!==t;this.events[e]=this.events[e].filter(function(n){return!(!i||n===t)||(this.element.removeEventListener(e,n,!1),!1)},this)},n.prototype.unbindAll=function(){for(var e in this.events)this.unbind(e)};var o=function(){this.eventElements=[]};o.prototype.eventElement=function(e){var t=this.eventElements.filter(function(t){return t.element===e})[0];return void 0===t&&(t=new n(e),this.eventElements.push(t)),t},o.prototype.bind=function(e,t,i){this.eventElement(e).bind(t,i)},o.prototype.unbind=function(e,t,i){this.eventElement(e).unbind(t,i)},o.prototype.unbindAll=function(){for(var e=0;e<this.eventElements.length;e++)this.eventElements[e].unbindAll()},o.prototype.once=function(e,t,i){var n=this.eventElement(e),o=function(e){n.unbind(t,o),i(e)};n.bind(t,o)},t.exports=o},{}],5:[function(e,t,i){"use strict";t.exports=function(){function e(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return e()+e()+"-"+e()+"-"+e()+"-"+e()+"-"+e()+e()+e()}}()},{}],6:[function(e,t,i){"use strict";var n=e("./class"),o=e("./dom"),r=i.toInt=function(e){return parseInt(e,10)||0},a=i.clone=function(e){if(e){if(e.constructor===Array)return e.map(a);if("object"==typeof e){var t={};for(var i in e)t[i]=a(e[i]);return t}return e}return null};i.extend=function(e,t){var i=a(e);for(var n in t)i[n]=a(t[n]);return i},i.isEditable=function(e){return o.matches(e,"input,[contenteditable]")||o.matches(e,"select,[contenteditable]")||o.matches(e,"textarea,[contenteditable]")||o.matches(e,"button,[contenteditable]")},i.removePsClasses=function(e){for(var t=n.list(e),i=0;i<t.length;i++){var o=t[i];0===o.indexOf("ps-")&&n.remove(e,o)}},i.outerWidth=function(e){return r(o.css(e,"width"))+r(o.css(e,"paddingLeft"))+r(o.css(e,"paddingRight"))+r(o.css(e,"borderLeftWidth"))+r(o.css(e,"borderRightWidth"))},i.startScrolling=function(e,t){n.add(e,"ps-in-scrolling"),void 0!==t?n.add(e,"ps-"+t):(n.add(e,"ps-x"),n.add(e,"ps-y"))},i.stopScrolling=function(e,t){n.remove(e,"ps-in-scrolling"),void 0!==t?n.remove(e,"ps-"+t):(n.remove(e,"ps-x"),n.remove(e,"ps-y"))},i.env={isWebKit:"WebkitAppearance"in document.documentElement.style,supportsTouch:"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,supportsIePointer:null!==window.navigator.msMaxTouchPoints}},{"./class":2,"./dom":3}],7:[function(e,t,i){"use strict";var n=e("./plugin/destroy"),o=e("./plugin/initialize"),r=e("./plugin/update");t.exports={initialize:o,update:r,destroy:n}},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(e,t,i){"use strict";t.exports={handlers:["click-rail","drag-scrollbar","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1,theme:"default"}},{}],9:[function(e,t,i){"use strict";var n=e("../lib/helper"),o=e("../lib/dom"),r=e("./instances");t.exports=function(e){var t=r.get(e);t&&(t.event.unbindAll(),o.remove(t.scrollbarX),o.remove(t.scrollbarY),o.remove(t.scrollbarXRail),o.remove(t.scrollbarYRail),n.removePsClasses(e),r.remove(e))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(e,t,i){"use strict";function n(e,t){function i(e){return e.getBoundingClientRect()}var n=function(e){e.stopPropagation()};t.event.bind(t.scrollbarY,"click",n),t.event.bind(t.scrollbarYRail,"click",function(n){var o=n.pageY-window.pageYOffset-i(t.scrollbarYRail).top,l=o>t.scrollbarYTop?1:-1;a(e,"top",e.scrollTop+l*t.containerHeight),r(e),n.stopPropagation()}),t.event.bind(t.scrollbarX,"click",n),t.event.bind(t.scrollbarXRail,"click",function(n){var o=n.pageX-window.pageXOffset-i(t.scrollbarXRail).left,l=o>t.scrollbarXLeft?1:-1;a(e,"left",e.scrollLeft+l*t.containerWidth),r(e),n.stopPropagation()})}var o=e("../instances"),r=e("../update-geometry"),a=e("../update-scroll");t.exports=function(e){n(e,o.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(e,t,i){"use strict";function n(e,t){function i(i){var o=n+i*t.railXRatio,a=Math.max(0,t.scrollbarXRail.getBoundingClientRect().left)+t.railXRatio*(t.railXWidth-t.scrollbarXWidth);t.scrollbarXLeft=o<0?0:o>a?a:o;var l=r.toInt(t.scrollbarXLeft*(t.contentWidth-t.containerWidth)/(t.containerWidth-t.railXRatio*t.scrollbarXWidth))-t.negativeScrollAdjustment;c(e,"left",l)}var n=null,o=null,l=function(t){i(t.pageX-o),s(e),t.stopPropagation(),t.preventDefault()},u=function(){r.stopScrolling(e,"x"),t.event.unbind(t.ownerDocument,"mousemove",l)};t.event.bind(t.scrollbarX,"mousedown",function(i){o=i.pageX,n=r.toInt(a.css(t.scrollbarX,"left"))*t.railXRatio,r.startScrolling(e,"x"),t.event.bind(t.ownerDocument,"mousemove",l),t.event.once(t.ownerDocument,"mouseup",u),i.stopPropagation(),i.preventDefault()})}function o(e,t){function i(i){var o=n+i*t.railYRatio,a=Math.max(0,t.scrollbarYRail.getBoundingClientRect().top)+t.railYRatio*(t.railYHeight-t.scrollbarYHeight);t.scrollbarYTop=o<0?0:o>a?a:o;var l=r.toInt(t.scrollbarYTop*(t.contentHeight-t.containerHeight)/(t.containerHeight-t.railYRatio*t.scrollbarYHeight));c(e,"top",l)}var n=null,o=null,l=function(t){i(t.pageY-o),s(e),t.stopPropagation(),t.preventDefault()},u=function(){r.stopScrolling(e,"y"),t.event.unbind(t.ownerDocument,"mousemove",l)};t.event.bind(t.scrollbarY,"mousedown",function(i){o=i.pageY,n=r.toInt(a.css(t.scrollbarY,"top"))*t.railYRatio,r.startScrolling(e,"y"),t.event.bind(t.ownerDocument,"mousemove",l),t.event.once(t.ownerDocument,"mouseup",u),i.stopPropagation(),i.preventDefault()})}var r=e("../../lib/helper"),a=e("../../lib/dom"),l=e("../instances"),s=e("../update-geometry"),c=e("../update-scroll");t.exports=function(e){var t=l.get(e);n(e,t),o(e,t)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var o=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===o&&n>0||o>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}var n=!1;t.event.bind(e,"mouseenter",function(){n=!0}),t.event.bind(e,"mouseleave",function(){n=!1});var a=!1;t.event.bind(t.ownerDocument,"keydown",function(c){if(!(c.isDefaultPrevented&&c.isDefaultPrevented()||c.defaultPrevented)){var u=r.matches(t.scrollbarX,":focus")||r.matches(t.scrollbarY,":focus");if(n||u){var d=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(d){if("IFRAME"===d.tagName)d=d.contentDocument.activeElement;else for(;d.shadowRoot;)d=d.shadowRoot.activeElement;if(o.isEditable(d))return}var h=0,f=0;switch(c.which){case 37:h=c.metaKey?-t.contentWidth:c.altKey?-t.containerWidth:-30;break;case 38:f=c.metaKey?t.contentHeight:c.altKey?t.containerHeight:30;break;case 39:h=c.metaKey?t.contentWidth:c.altKey?t.containerWidth:30;break;case 40:f=c.metaKey?-t.contentHeight:c.altKey?-t.containerHeight:-30;break;case 33:f=90;break;case 32:f=c.shiftKey?90:-90;break;case 34:f=-90;break;case 35:f=c.ctrlKey?-t.contentHeight:-t.containerHeight;break;case 36:f=c.ctrlKey?e.scrollTop:t.containerHeight;break;default:return}s(e,"top",e.scrollTop-f),s(e,"left",e.scrollLeft+h),l(e),a=i(h,f),a&&c.preventDefault()}}})}var o=e("../../lib/helper"),r=e("../../lib/dom"),a=e("../instances"),l=e("../update-geometry"),s=e("../update-scroll");t.exports=function(e){n(e,a.get(e))}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(e,t,i){"use strict";function n(e,t){function i(i,n){var o=e.scrollTop;if(0===i){if(!t.scrollbarYActive)return!1;if(0===o&&n>0||o>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var r=e.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===r&&i<0||r>=t.contentWidth-t.containerWidth&&i>0)return!t.settings.wheelPropagation}return!0}function n(e){var t=e.deltaX,i=-1*e.deltaY;return void 0!==t&&void 0!==i||(t=-1*e.wheelDeltaX/6,i=e.wheelDeltaY/6),e.deltaMode&&1===e.deltaMode&&(t*=10,i*=10),t!==t&&i!==i&&(t=0,i=e.wheelDelta),e.shiftKey?[-i,-t]:[t,i]}function o(t,i){var n=e.querySelector("textarea:hover, select[multiple]:hover, .ps-child:hover");if(n){if(!window.getComputedStyle(n).overflow.match(/(scroll|auto)/))return!1;var o=n.scrollHeight-n.clientHeight;if(o>0&&!(0===n.scrollTop&&i>0||n.scrollTop===o&&i<0))return!0;var r=n.scrollLeft-n.clientWidth;if(r>0&&!(0===n.scrollLeft&&t<0||n.scrollLeft===r&&t>0))return!0}return!1}function l(l){var c=n(l),u=c[0],d=c[1];o(u,d)||(s=!1,t.settings.useBothWheelAxes?t.scrollbarYActive&&!t.scrollbarXActive?(d?a(e,"top",e.scrollTop-d*t.settings.wheelSpeed):a(e,"top",e.scrollTop+u*t.settings.wheelSpeed),s=!0):t.scrollbarXActive&&!t.scrollbarYActive&&(u?a(e,"left",e.scrollLeft+u*t.settings.wheelSpeed):a(e,"left",e.scrollLeft-d*t.settings.wheelSpeed),s=!0):(a(e,"top",e.scrollTop-d*t.settings.wheelSpeed),a(e,"left",e.scrollLeft+u*t.settings.wheelSpeed)),r(e),(s=s||i(u,d))&&(l.stopPropagation(),l.preventDefault()))}var s=!1;void 0!==window.onwheel?t.event.bind(e,"wheel",l):void 0!==window.onmousewheel&&t.event.bind(e,"mousewheel",l)}var o=e("../instances"),r=e("../update-geometry"),a=e("../update-scroll");t.exports=function(e){n(e,o.get(e))}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(e,t,i){"use strict";function n(e,t){t.event.bind(e,"scroll",function(){r(e)})}var o=e("../instances"),r=e("../update-geometry");t.exports=function(e){n(e,o.get(e))}},{"../instances":18,"../update-geometry":19}],15:[function(e,t,i){"use strict";function n(e,t){function i(){var e=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===e.toString().length?null:e.getRangeAt(0).commonAncestorContainer}function n(){c||(c=setInterval(function(){if(!r.get(e))return void clearInterval(c);l(e,"top",e.scrollTop+u.top),l(e,"left",e.scrollLeft+u.left),a(e)},50))}function s(){c&&(clearInterval(c),c=null),o.stopScrolling(e)}var c=null,u={top:0,left:0},d=!1;t.event.bind(t.ownerDocument,"selectionchange",function(){e.contains(i())?d=!0:(d=!1,s())}),t.event.bind(window,"mouseup",function(){d&&(d=!1,s())}),t.event.bind(window,"keyup",function(){d&&(d=!1,s())}),t.event.bind(window,"mousemove",function(t){if(d){var i={x:t.pageX,y:t.pageY},r={left:e.offsetLeft,right:e.offsetLeft+e.offsetWidth,top:e.offsetTop,bottom:e.offsetTop+e.offsetHeight};i.x<r.left+3?(u.left=-5,o.startScrolling(e,"x")):i.x>r.right-3?(u.left=5,o.startScrolling(e,"x")):u.left=0,i.y<r.top+3?(u.top=r.top+3-i.y<5?-5:-20,o.startScrolling(e,"y")):i.y>r.bottom-3?(u.top=i.y-r.bottom+3<5?5:20,o.startScrolling(e,"y")):u.top=0,0===u.top&&0===u.left?s():n()}})}var o=e("../../lib/helper"),r=e("../instances"),a=e("../update-geometry"),l=e("../update-scroll");t.exports=function(e){n(e,r.get(e))}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(e,t,i){"use strict";function n(e,t,i,n){function o(i,n){var o=e.scrollTop,r=e.scrollLeft,a=Math.abs(i),l=Math.abs(n);if(l>a){if(n<0&&o===t.contentHeight-t.containerHeight||n>0&&0===o)return!t.settings.swipePropagation}else if(a>l&&(i<0&&r===t.contentWidth-t.containerWidth||i>0&&0===r))return!t.settings.swipePropagation;return!0}function s(t,i){l(e,"top",e.scrollTop-i),l(e,"left",e.scrollLeft-t),a(e)}function c(){w=!0}function u(){w=!1}function d(e){return e.targetTouches?e.targetTouches[0]:e}function h(e){return!(!e.targetTouches||1!==e.targetTouches.length)||!(!e.pointerType||"mouse"===e.pointerType||e.pointerType===e.MSPOINTER_TYPE_MOUSE)}function f(e){if(h(e)){y=!0;var t=d(e);m.pageX=t.pageX,m.pageY=t.pageY,v=(new Date).getTime(),null!==_&&clearInterval(_),e.stopPropagation()}}function p(e){if(!y&&t.settings.swipePropagation&&f(e),!w&&y&&h(e)){var i=d(e),n={pageX:i.pageX,pageY:i.pageY},r=n.pageX-m.pageX,a=n.pageY-m.pageY;s(r,a),m=n;var l=(new Date).getTime(),c=l-v;c>0&&(b.x=r/c,b.y=a/c,v=l),o(r,a)&&(e.stopPropagation(),e.preventDefault())}}function g(){!w&&y&&(y=!1,clearInterval(_),_=setInterval(function(){return r.get(e)&&(b.x||b.y)?Math.abs(b.x)<.01&&Math.abs(b.y)<.01?void clearInterval(_):(s(30*b.x,30*b.y),b.x*=.8,void(b.y*=.8)):void clearInterval(_)},10))}var m={},v=0,b={},_=null,w=!1,y=!1;i?(t.event.bind(window,"touchstart",c),t.event.bind(window,"touchend",u),t.event.bind(e,"touchstart",f),t.event.bind(e,"touchmove",p),t.event.bind(e,"touchend",g)):n&&(window.PointerEvent?(t.event.bind(window,"pointerdown",c),t.event.bind(window,"pointerup",u),t.event.bind(e,"pointerdown",f),t.event.bind(e,"pointermove",p),t.event.bind(e,"pointerup",g)):window.MSPointerEvent&&(t.event.bind(window,"MSPointerDown",c),t.event.bind(window,"MSPointerUp",u),t.event.bind(e,"MSPointerDown",f),t.event.bind(e,"MSPointerMove",p),t.event.bind(e,"MSPointerUp",g)))}var o=e("../../lib/helper"),r=e("../instances"),a=e("../update-geometry"),l=e("../update-scroll");t.exports=function(e){if(o.env.supportsTouch||o.env.supportsIePointer){n(e,r.get(e),o.env.supportsTouch,o.env.supportsIePointer)}}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(e,t,i){"use strict";var n=e("../lib/helper"),o=e("../lib/class"),r=e("./instances"),a=e("./update-geometry"),l={"click-rail":e("./handler/click-rail"),"drag-scrollbar":e("./handler/drag-scrollbar"),keyboard:e("./handler/keyboard"),wheel:e("./handler/mouse-wheel"),touch:e("./handler/touch"),selection:e("./handler/selection")},s=e("./handler/native-scroll");t.exports=function(e,t){t="object"==typeof t?t:{},o.add(e,"ps-container");var i=r.add(e);i.settings=n.extend(i.settings,t),o.add(e,"ps-theme-"+i.settings.theme),i.settings.handlers.forEach(function(t){l[t](e)}),s(e),a(e)}},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(e,t,i){"use strict";function n(e){function t(){s.add(e,"ps-focus")}function i(){s.remove(e,"ps-focus")}var n=this;n.settings=l.clone(c),n.containerWidth=null,n.containerHeight=null,n.contentWidth=null,n.contentHeight=null,n.isRtl="rtl"===u.css(e,"direction"),n.isNegativeScroll=function(){var t=e.scrollLeft,i=null;return e.scrollLeft=-1,i=e.scrollLeft<0,e.scrollLeft=t,i}(),n.negativeScrollAdjustment=n.isNegativeScroll?e.scrollWidth-e.clientWidth:0,n.event=new d,n.ownerDocument=e.ownerDocument||document,n.scrollbarXRail=u.appendTo(u.e("div","ps-scrollbar-x-rail"),e),n.scrollbarX=u.appendTo(u.e("div","ps-scrollbar-x"),n.scrollbarXRail),n.scrollbarX.setAttribute("tabindex",0),n.event.bind(n.scrollbarX,"focus",t),n.event.bind(n.scrollbarX,"blur",i),n.scrollbarXActive=null,n.scrollbarXWidth=null,n.scrollbarXLeft=null,n.scrollbarXBottom=l.toInt(u.css(n.scrollbarXRail,"bottom")),n.isScrollbarXUsingBottom=n.scrollbarXBottom===n.scrollbarXBottom,n.scrollbarXTop=n.isScrollbarXUsingBottom?null:l.toInt(u.css(n.scrollbarXRail,"top")),n.railBorderXWidth=l.toInt(u.css(n.scrollbarXRail,"borderLeftWidth"))+l.toInt(u.css(n.scrollbarXRail,"borderRightWidth")),u.css(n.scrollbarXRail,"display","block"),n.railXMarginWidth=l.toInt(u.css(n.scrollbarXRail,"marginLeft"))+l.toInt(u.css(n.scrollbarXRail,"marginRight")),u.css(n.scrollbarXRail,"display",""),n.railXWidth=null,n.railXRatio=null,n.scrollbarYRail=u.appendTo(u.e("div","ps-scrollbar-y-rail"),e),n.scrollbarY=u.appendTo(u.e("div","ps-scrollbar-y"),n.scrollbarYRail),n.scrollbarY.setAttribute("tabindex",0),n.event.bind(n.scrollbarY,"focus",t),n.event.bind(n.scrollbarY,"blur",i),n.scrollbarYActive=null,n.scrollbarYHeight=null,n.scrollbarYTop=null,n.scrollbarYRight=l.toInt(u.css(n.scrollbarYRail,"right")),n.isScrollbarYUsingRight=n.scrollbarYRight===n.scrollbarYRight,n.scrollbarYLeft=n.isScrollbarYUsingRight?null:l.toInt(u.css(n.scrollbarYRail,"left")),n.scrollbarYOuterWidth=n.isRtl?l.outerWidth(n.scrollbarY):null,n.railBorderYWidth=l.toInt(u.css(n.scrollbarYRail,"borderTopWidth"))+l.toInt(u.css(n.scrollbarYRail,"borderBottomWidth")),u.css(n.scrollbarYRail,"display","block"),n.railYMarginHeight=l.toInt(u.css(n.scrollbarYRail,"marginTop"))+l.toInt(u.css(n.scrollbarYRail,"marginBottom")),u.css(n.scrollbarYRail,"display",""),n.railYHeight=null,n.railYRatio=null}function o(e){return e.getAttribute("data-ps-id")}function r(e,t){e.setAttribute("data-ps-id",t)}function a(e){e.removeAttribute("data-ps-id")}var l=e("../lib/helper"),s=e("../lib/class"),c=e("./default-setting"),u=e("../lib/dom"),d=e("../lib/event-manager"),h=e("../lib/guid"),f={};i.add=function(e){var t=h();return r(e,t),f[t]=new n(e),f[t]},i.remove=function(e){delete f[o(e)],a(e)},i.get=function(e){return f[o(e)]}},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(e,t,i){"use strict";function n(e,t){return e.settings.minScrollbarLength&&(t=Math.max(t,e.settings.minScrollbarLength)),e.settings.maxScrollbarLength&&(t=Math.min(t,e.settings.maxScrollbarLength)),t}function o(e,t){var i={width:t.railXWidth};t.isRtl?i.left=t.negativeScrollAdjustment+e.scrollLeft+t.containerWidth-t.contentWidth:i.left=e.scrollLeft,t.isScrollbarXUsingBottom?i.bottom=t.scrollbarXBottom-e.scrollTop:i.top=t.scrollbarXTop+e.scrollTop,l.css(t.scrollbarXRail,i);var n={top:e.scrollTop,height:t.railYHeight};t.isScrollbarYUsingRight?t.isRtl?n.right=t.contentWidth-(t.negativeScrollAdjustment+e.scrollLeft)-t.scrollbarYRight-t.scrollbarYOuterWidth:n.right=t.scrollbarYRight-e.scrollLeft:t.isRtl?n.left=t.negativeScrollAdjustment+e.scrollLeft+2*t.containerWidth-t.contentWidth-t.scrollbarYLeft-t.scrollbarYOuterWidth:n.left=t.scrollbarYLeft+e.scrollLeft,l.css(t.scrollbarYRail,n),l.css(t.scrollbarX,{left:t.scrollbarXLeft,width:t.scrollbarXWidth-t.railBorderXWidth}),l.css(t.scrollbarY,{top:t.scrollbarYTop,height:t.scrollbarYHeight-t.railBorderYWidth})}var r=e("../lib/helper"),a=e("../lib/class"),l=e("../lib/dom"),s=e("./instances"),c=e("./update-scroll");t.exports=function(e){var t=s.get(e);t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight;var i;e.contains(t.scrollbarXRail)||(i=l.queryChildren(e,".ps-scrollbar-x-rail"),i.length>0&&i.forEach(function(e){l.remove(e)}),l.appendTo(t.scrollbarXRail,e)),e.contains(t.scrollbarYRail)||(i=l.queryChildren(e,".ps-scrollbar-y-rail"),i.length>0&&i.forEach(function(e){l.remove(e)}),l.appendTo(t.scrollbarYRail,e)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset<t.contentWidth?(t.scrollbarXActive=!0,t.railXWidth=t.containerWidth-t.railXMarginWidth,t.railXRatio=t.containerWidth/t.railXWidth,t.scrollbarXWidth=n(t,r.toInt(t.railXWidth*t.containerWidth/t.contentWidth)),t.scrollbarXLeft=r.toInt((t.negativeScrollAdjustment+e.scrollLeft)*(t.railXWidth-t.scrollbarXWidth)/(t.contentWidth-t.containerWidth))):t.scrollbarXActive=!1,!t.settings.suppressScrollY&&t.containerHeight+t.settings.scrollYMarginOffset<t.contentHeight?(t.scrollbarYActive=!0,t.railYHeight=t.containerHeight-t.railYMarginHeight,t.railYRatio=t.containerHeight/t.railYHeight,t.scrollbarYHeight=n(t,r.toInt(t.railYHeight*t.containerHeight/t.contentHeight)),t.scrollbarYTop=r.toInt(e.scrollTop*(t.railYHeight-t.scrollbarYHeight)/(t.contentHeight-t.containerHeight))):t.scrollbarYActive=!1,t.scrollbarXLeft>=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),o(e,t),t.scrollbarXActive?a.add(e,"ps-active-x"):(a.remove(e,"ps-active-x"),t.scrollbarXWidth=0,t.scrollbarXLeft=0,c(e,"left",0)),t.scrollbarYActive?a.add(e,"ps-active-y"):(a.remove(e,"ps-active-y"),t.scrollbarYHeight=0,t.scrollbarYTop=0,c(e,"top",0))}},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(e,t,i){"use strict";var n,o,r=e("./instances"),a=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!0),t};t.exports=function(e,t,i){if(void 0===e)throw"You must provide an element to the update-scroll function";if(void 0===t)throw"You must provide an axis to the update-scroll function";if(void 0===i)throw"You must provide a value to the update-scroll function";"top"===t&&i<=0&&(e.scrollTop=i=0,e.dispatchEvent(a("ps-y-reach-start"))),"left"===t&&i<=0&&(e.scrollLeft=i=0,e.dispatchEvent(a("ps-x-reach-start")));var l=r.get(e);"top"===t&&i>=l.contentHeight-l.containerHeight&&(i=l.contentHeight-l.containerHeight,i-e.scrollTop<=1?i=e.scrollTop:e.scrollTop=i,e.dispatchEvent(a("ps-y-reach-end"))),"left"===t&&i>=l.contentWidth-l.containerWidth&&(i=l.contentWidth-l.containerWidth,i-e.scrollLeft<=1?i=e.scrollLeft:e.scrollLeft=i,e.dispatchEvent(a("ps-x-reach-end"))),n||(n=e.scrollTop),o||(o=e.scrollLeft),"top"===t&&i<n&&e.dispatchEvent(a("ps-scroll-up")),"top"===t&&i>n&&e.dispatchEvent(a("ps-scroll-down")),"left"===t&&i<o&&e.dispatchEvent(a("ps-scroll-left")),"left"===t&&i>o&&e.dispatchEvent(a("ps-scroll-right")),"top"===t&&(e.scrollTop=n=i,e.dispatchEvent(a("ps-scroll-y"))),"left"===t&&(e.scrollLeft=o=i,e.dispatchEvent(a("ps-scroll-x")))}},{"./instances":18}],21:[function(e,t,i){"use strict";var n=e("../lib/helper"),o=e("../lib/dom"),r=e("./instances"),a=e("./update-geometry"),l=e("./update-scroll");t.exports=function(e){var t=r.get(e);t&&(t.negativeScrollAdjustment=t.isNegativeScroll?e.scrollWidth-e.clientWidth:0,o.css(t.scrollbarXRail,"display","block"),o.css(t.scrollbarYRail,"display","block"),t.railXMarginWidth=n.toInt(o.css(t.scrollbarXRail,"marginLeft"))+n.toInt(o.css(t.scrollbarXRail,"marginRight")),t.railYMarginHeight=n.toInt(o.css(t.scrollbarYRail,"marginTop"))+n.toInt(o.css(t.scrollbarYRail,"marginBottom")),o.css(t.scrollbarXRail,"display","none"),o.css(t.scrollbarYRail,"display","none"),a(e),l(e,"top",e.scrollTop),l(e,"left",e.scrollLeft),o.css(t.scrollbarXRail,"display",""),o.css(t.scrollbarYRail,"display",""))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]),define("WoltLabSuite/Core/Date/Util",["Language"],function(e){"use strict";return{formatDate:function(t){return this.format(t,e.get("wcf.date.dateFormat"))},formatTime:function(t){return this.format(t,e.get("wcf.date.timeFormat"))},formatDateTime:function(t){return this.format(t,e.get("wcf.date.dateTimeFormat").replace(/%date%/,e.get("wcf.date.dateFormat")).replace(/%time%/,e.get("wcf.date.timeFormat")))},format:function(t,i){var n,o="";"c"===i&&(i="Y-m-dTH:i:sP");for(var r=0,a=i.length;r<a;r++){switch(i[r]){case"s":n=("0"+t.getSeconds().toString()).slice(-2);break;case"i":n=t.getMinutes(),n<10&&(n="0"+n);break;case"a":n=t.getHours()>11?"pm":"am";break;case"g":n=t.getHours(),0===n?n=12:n>12&&(n-=12);break;case"h":n=t.getHours(),0===n?n=12:n>12&&(n-=12),n=("0"+n.toString()).slice(-2);break;case"A":n=t.getHours()>11?"PM":"AM";break;case"G":n=t.getHours();break;case"H":n=t.getHours(),n=("0"+n.toString()).slice(-2);break;case"d":n=t.getDate(),n=("0"+n.toString()).slice(-2);break;case"j":n=t.getDate();break;case"l":n=e.get("__days")[t.getDay()];break;case"D":n=e.get("__daysShort")[t.getDay()];break;case"S":n="";break;case"m":n=t.getMonth()+1,n=("0"+n.toString()).slice(-2);break;case"n":n=t.getMonth()+1;break;case"F":n=e.get("__months")[t.getMonth()];break;case"M":n=e.get("__monthsShort")[t.getMonth()];break;case"y":n=t.getFullYear().toString().substr(2);break;case"Y":n=t.getFullYear();break;case"P":var l=t.getTimezoneOffset();n=l>0?"-":"+",l=Math.abs(l),n+=("0"+(~~(l/60)).toString()).slice(-2),n+=":",n+=("0"+(l%60).toString()).slice(-2);break;case"r":n=t.toString();break;case"U":n=Math.round(t.getTime()/1e3);break;case"\\":n="",r+1<a&&(n=i[++r]);break;default:n=i[r]}o+=n}return o},gmdate:function(e){return e instanceof Date||(e=new Date),Math.round(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDay(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds())/1e3)},getTimeElement:function(t){var i=elCreate("time");i.className="datetime";var n=this.formatDate(t),o=this.formatTime(t)
+;return elAttr(i,"datetime",this.format(t,"c")),elData(i,"timestamp",(t.getTime()-t.getMilliseconds())/1e3),elData(i,"date",n),elData(i,"time",o),elData(i,"offset",60*t.getTimezoneOffset()),t.getTime()>Date.now()&&(elData(i,"is-future-date","true"),i.textContent=e.get("wcf.date.dateTimeFormat").replace("%time%",o).replace("%date%",n)),i},getTimezoneDate:function(e,t){var i=new Date(e),n=6e4*i.getTimezoneOffset();return new Date(e+n+t)}}}),define("WoltLabSuite/Core/Timer/Repeating",[],function(){"use strict";function e(e,t){if("function"!=typeof e)throw new TypeError("Expected a valid callback as first argument.");if(t<0||t>864e5)throw new RangeError("Invalid delta "+t+". Delta must be in the interval [0, 86400000].");this._callback=e.bind(void 0,this),this._delta=t,this._timer=void 0,this.restart()}return e.prototype={restart:function(){this.stop(),this._timer=setInterval(this._callback,this._delta)},stop:function(){void 0!==this._timer&&(clearInterval(this._timer),this._timer=void 0)},setDelta:function(e){this._delta=e,this.restart()}},e}),define("WoltLabSuite/Core/Date/Time/Relative",["Dom/ChangeListener","Language","WoltLabSuite/Core/Date/Util","WoltLabSuite/Core/Timer/Repeating"],function(e,t,i,n){"use strict";var o=elByTag("time"),r=!0,a=!1,l=null;return{setup:function(){new n(this._refresh.bind(this),6e4),e.add("WoltLabSuite/Core/Date/Time/Relative",this._refresh.bind(this)),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this))},_onVisibilityChange:function(){document.hidden?(r=!1,a=!1):(r=!0,a&&(this._refresh(),a=!1))},_refresh:function(){if(!r)return void(a||(a=!0));var e=new Date,n=(e.getTime()-e.getMilliseconds())/1e3;null===l&&(l=n-window.TIME_NOW);for(var s=0,c=o.length;s<c;s++){var u=o[s];if(u.classList.contains("datetime")&&!elData(u,"is-future-date")){var d=~~elData(u,"timestamp")+l,h=elData(u,"date"),f=elData(u,"time"),p=elData(u,"offset");if(elAttr(u,"title")||elAttr(u,"title",t.get("wcf.date.dateTimeFormat").replace(/%date%/,h).replace(/%time%/,f)),d>=n||n<d+60)u.textContent=t.get("wcf.date.relative.now");else if(n<d+3540){var g=Math.max(Math.round((n-d)/60),1);u.textContent=t.get("wcf.date.relative.minutes",{minutes:g})}else if(n<d+86400){var m=Math.round((n-d)/3600);u.textContent=t.get("wcf.date.relative.hours",{hours:m})}else if(n<d+518400){var v=new Date(e.getFullYear(),e.getMonth(),e.getDate()),b=Math.ceil((v/1e3-d)/86400),_=i.getTimezoneDate(1e3*d,1e3*p),w=_.getDay(),y=t.get("__days")[w];u.textContent=t.get("wcf.date.relative.pastDays",{days:b,day:y,time:f})}else u.textContent=t.get("wcf.date.shortDateTimeFormat").replace(/%date%/,h).replace(/%time%/,f)}}}}}),define("WoltLabSuite/Core/Ui/Page/Menu/Abstract",["Core","Environment","EventHandler","Language","ObjectMap","Dom/Traverse","Dom/Util","Ui/Screen"],function(e,t,i,n,o,r,a,l){"use strict";function s(e,t,i){this.init(e,t,i)}var c=elById("pageContainer"),u="";return s.prototype={init:function(e,n,r){if("packageInstallationSetup"!==elData(document.body,"template")){this._activeList=[],this._depth=0,this._enabled=!0,this._eventIdentifier=e,this._items=new o,this._menu=elById(n),this._removeActiveList=!1;var l=this.open.bind(this);this._button=elBySel(r),this._button.addEventListener(WCF_CLICK_EVENT,l),this._initItems(),this._initHeader(),i.add(this._eventIdentifier,"open",l),i.add(this._eventIdentifier,"close",this.close.bind(this)),i.add(this._eventIdentifier,"updateButtonState",this._updateButtonState.bind(this));var s,c=elByClass("menuOverlayItemList",this._menu);this._menu.addEventListener("animationend",function(){if(!this._menu.classList.contains("open"))for(var e=0,t=c.length;e<t;e++)s=c[e],s.classList.remove("active"),s.classList.remove("hidden")}.bind(this)),this._menu.children[0].addEventListener("transitionend",function(){if(this._menu.classList.add("allowScroll"),this._removeActiveList){this._removeActiveList=!1;var e=this._activeList.pop();e&&e.classList.remove("activeList")}}.bind(this));var u=elCreate("div");u.className="menuOverlayMobileBackdrop",u.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),a.insertAfter(u,this._menu),this._updateButtonState(),"android"===t.platform()&&this._initializeAndroid()}},open:function(e){return!!this._enabled&&(e instanceof Event&&e.preventDefault(),this._menu.classList.add("open"),this._menu.classList.add("allowScroll"),this._menu.children[0].classList.add("activeList"),l.scrollDisable(),c.classList.add("menuOverlay-"+this._menu.id),l.pageOverlayOpen(),!0)},close:function(e){return e instanceof Event&&e.preventDefault(),!!this._menu.classList.contains("open")&&(this._menu.classList.remove("open"),l.scrollEnable(),l.pageOverlayClose(),c.classList.remove("menuOverlay-"+this._menu.id),!0)},enable:function(){this._enabled=!0},disable:function(){this._enabled=!1,this.close(!0)},_initializeAndroid:function(){var t,i,n;switch(this._menu.id){case"pageUserMenuMobile":t="right";break;case"pageMainMenuMobile":t="left";break;default:return}i=this._menu.nextElementSibling,n=null,document.addEventListener("touchstart",function(i){var o,r,a,s;if(o=i.touches,r=this._menu.classList.contains("open"),"left"===t?(a=!r&&o[0].clientX<20,s=r&&Math.abs(this._menu.offsetWidth-o[0].clientX)<20):"right"===t&&(a=r&&Math.abs(document.body.clientWidth-this._menu.offsetWidth-o[0].clientX)<20,s=!r&&document.body.clientWidth-o[0].clientX<20),o.length>1)return void(u&&e.triggerEvent(document,"touchend"));if(!u&&(a||s)){if(l.pageOverlayIsActive()){for(var d=!1,h=0;h<c.classList.length;h++)c.classList[h]==="menuOverlay-"+this._menu.id&&(d=!0);if(!d)return}document.documentElement.classList.contains("redactorActive")||(n={x:o[0].clientX,y:o[0].clientY},a&&(u="left"),s&&(u="right"))}}.bind(this)),document.addEventListener("touchend",function(e){if(u&&null!==n){if(!this._menu.classList.contains("open"))return n=null,void(u="");var o;o=e?e.changedTouches[0].clientX:n.x,this._menu.classList.add("androidMenuTouchEnd"),this._menu.style.removeProperty("transform"),i.style.removeProperty(t),this._menu.addEventListener("transitionend",function(){this._menu.classList.remove("androidMenuTouchEnd")}.bind(this),{once:!0}),"left"===t?("left"===u&&o<n.x+100&&this.close(),"right"===u&&o<n.x-100&&this.close()):"right"===t&&("left"===u&&o>n.x+100&&this.close(),"right"===u&&o>n.x-100&&this.close()),n=null,u=""}}.bind(this)),document.addEventListener("touchmove",function(e){if(u&&null!==n){var o=e.touches,r=!1,a=!1;"left"===u&&(r=o[0].clientX>n.x+5),"right"===u&&(r=o[0].clientX<n.x-5),a=Math.abs(o[0].clientY-n.y)>20;var l=this._menu.classList.contains("open");if(l||!r||a||(this.open(),l=!0),l){var s=o[0].clientX;"right"===t&&(s=document.body.clientWidth-s),s>this._menu.offsetWidth&&(s=this._menu.offsetWidth),s<0&&(s=0),this._menu.style.setProperty("transform","translateX("+("left"===t?1:-1)*(s-this._menu.offsetWidth)+"px)"),i.style.setProperty(t,Math.min(this._menu.offsetWidth,s)+"px")}}}.bind(this))},_initItems:function(){elBySelAll(".menuOverlayItemLink",this._menu,this._initItem.bind(this))},_initItem:function(e){var t=e.parentNode,n=elData(t,"more");if(n)return void e.addEventListener(WCF_CLICK_EVENT,function(o){o.preventDefault(),o.stopPropagation(),i.fire(this._eventIdentifier,"more",{handler:this,identifier:n,item:e,parent:t})}.bind(this));var o,a=e.nextElementSibling;if(null!==a)if("OL"!==a.nodeName&&a.classList.contains("menuOverlayItemLinkIcon"))for(o=elCreate("span"),o.className="menuOverlayItemWrapper",t.insertBefore(o,e),o.appendChild(e);o.nextElementSibling;)o.appendChild(o.nextElementSibling);else{var l="#"!==elAttr(e,"href"),s=t.parentNode,c=elData(a,"title");this._items.set(e,{itemList:a,parentItemList:s}),""===c&&(c=r.childByClass(e,"menuOverlayItemTitle").textContent,elData(a,"title",c));var u=this._showItemList.bind(this,e);if(l){o=elCreate("span"),o.className="menuOverlayItemWrapper",t.insertBefore(o,e),o.appendChild(e);var d=elCreate("a");elAttr(d,"href","#"),d.className="menuOverlayItemLinkIcon"+(e.classList.contains("active")?" active":""),d.innerHTML='<span class="icon icon24 fa-angle-right"></span>',d.addEventListener(WCF_CLICK_EVENT,u),o.appendChild(d)}else e.classList.add("menuOverlayItemLinkMore"),e.addEventListener(WCF_CLICK_EVENT,u);var h=elCreate("li");h.className="menuOverlayHeader",o=elCreate("span"),o.className="menuOverlayItemWrapper";var f=elCreate("a");elAttr(f,"href","#"),f.className="menuOverlayItemLink menuOverlayBackLink",f.textContent=elData(s,"title"),f.addEventListener(WCF_CLICK_EVENT,this._hideItemList.bind(this,e));var p=elCreate("a");if(elAttr(p,"href","#"),p.className="menuOverlayItemLinkIcon",p.innerHTML='<span class="icon icon24 fa-times"></span>',p.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),o.appendChild(f),o.appendChild(p),h.appendChild(o),a.insertBefore(h,a.firstElementChild),!h.nextElementSibling.classList.contains("menuOverlayTitle")){var g=elCreate("li");g.className="menuOverlayTitle";var m=elCreate("span");m.textContent=c,g.appendChild(m),a.insertBefore(g,h.nextElementSibling)}}},_initHeader:function(){var e=elCreate("li");e.className="menuOverlayHeader";var t=elCreate("span");t.className="menuOverlayItemWrapper",e.appendChild(t);var i=elCreate("span");i.className="menuOverlayLogoWrapper",t.appendChild(i);var n=elCreate("span");n.className="menuOverlayLogo",n.style.setProperty("background-image",'url("'+elData(this._menu,"page-logo")+'")',""),i.appendChild(n);var o=elCreate("a");elAttr(o,"href","#"),o.className="menuOverlayItemLinkIcon",o.innerHTML='<span class="icon icon24 fa-times"></span>',o.addEventListener(WCF_CLICK_EVENT,this.close.bind(this)),t.appendChild(o);var a=r.childByClass(this._menu,"menuOverlayItemList");a.insertBefore(e,a.firstElementChild)},_hideItemList:function(e,t){t instanceof Event&&t.preventDefault(),this._menu.classList.remove("allowScroll"),this._removeActiveList=!0,this._items.get(e).parentItemList.classList.remove("hidden"),this._updateDepth(!1)},_showItemList:function(e,t){t instanceof Event&&t.preventDefault();var n=this._items.get(e),o=elData(n.itemList,"load");if(o&&!elDataBool(e,"loaded")){var r=t.currentTarget.firstElementChild;return r.classList.contains("fa-angle-right")&&(r.classList.remove("fa-angle-right"),r.classList.add("fa-spinner")),void i.fire(this._eventIdentifier,"load_"+o)}this._menu.classList.remove("allowScroll"),n.itemList.classList.add("activeList"),n.parentItemList.classList.add("hidden"),this._activeList.push(n.itemList),this._updateDepth(!0)},_updateDepth:function(e){this._depth+=e?1:-1;var t=-100*this._depth;"rtl"===n.get("wcf.global.pageDirection")&&(t*=-1),this._menu.children[0].style.setProperty("transform","translateX("+t+"%)","")},_updateButtonState:function(){var e=!1,t=elBySel(".menuOverlayItemList",this._menu);elBySelAll(".badgeUpdate",this._menu,function(i){~~i.textContent>0&&i.closest(".menuOverlayItemList")===t&&(e=!0)}),this._button.classList[e?"add":"remove"]("pageMenuMobileButtonHasContent")}},s}),define("WoltLabSuite/Core/Ui/Page/Menu/Main",["Core","Language","Dom/Traverse","./Abstract"],function(e,t,i,n){"use strict";function o(){this.init()}var r=null,a=null,l=null,s=null,c=null;return e.inherit(o,n,{init:function(){o._super.prototype.init.call(this,"com.woltlab.wcf.MainMenuMobile","pageMainMenuMobile","#pageHeader .mainMenu"),r=elById("pageMainMenuMobilePageOptionsTitle"),null!==r&&(l=i.childByClass(r,"menuOverlayItemList"),s=elBySel(".jsPageNavigationIcons"),c=function(e){this.close(),e.stopPropagation()}.bind(this)),elAttr(this._button,"aria-label",t.get("wcf.menu.page")),elAttr(this._button,"role","button")},open:function(e){if(!o._super.prototype.open.call(this,e))return!1;if(null===r)return!0;if(a=s&&s.childElementCount>0){for(var t,i;s.childElementCount;)t=s.children[0],t.classList.add("menuOverlayItem"),t.classList.add("menuOverlayItemOption"),t.addEventListener(WCF_CLICK_EVENT,c),i=t.children[0],i.classList.add("menuOverlayItemLink"),i.classList.add("box24"),i.children[1].classList.remove("invisible"),i.children[1].classList.add("menuOverlayItemTitle"),r.parentNode.insertBefore(t,r.nextSibling);elShow(r)}else elHide(r);return!0},close:function(e){if(!o._super.prototype.close.call(this,e))return!1;if(a){elHide(r);for(var t,i=r.nextElementSibling;i&&i.classList.contains("menuOverlayItemOption");)i.classList.remove("menuOverlayItem"),i.classList.remove("menuOverlayItemOption"),i.removeEventListener(WCF_CLICK_EVENT,c),t=i.children[0],t.classList.remove("menuOverlayItemLink"),t.classList.remove("box24"),t.children[1].classList.add("invisible"),t.children[1].classList.remove("menuOverlayItemTitle"),s.appendChild(i),i=i.nextElementSibling}return!0}}),o}),define("WoltLabSuite/Core/Ui/Page/Menu/User",["Core","EventHandler","Language","./Abstract"],function(e,t,i,n){"use strict";function o(){this.init()}return e.inherit(o,n,{init:function(){var e=elBySel("#pageUserMenuMobile > .menuOverlayItemList");if(1===e.childElementCount&&e.children[0].classList.contains("menuOverlayTitle"))return void elBySel("#pageHeader .userPanel").classList.add("hideUserPanel");o._super.prototype.init.call(this,"com.woltlab.wcf.UserMenuMobile","pageUserMenuMobile","#pageHeader .userPanel"),t.add("com.woltlab.wcf.userMenu","updateBadge",function(e){elBySelAll(".menuOverlayItemBadge",this._menu,function(t){if(elData(t,"badge-identifier")===e.identifier){var i=elBySel(".badge",t);e.count?(null===i&&(i=elCreate("span"),i.className="badge badgeUpdate",t.appendChild(i)),i.textContent=e.count):null!==i&&elRemove(i),this._updateButtonState()}}.bind(this))}.bind(this)),elAttr(this._button,"aria-label",i.get("wcf.menu.user")),elAttr(this._button,"role","button")},close:function(e){if(void 0!==this._menu){var t=WCF.Dropdown.Interactive.Handler.getOpenDropdown();t?(e.preventDefault(),e.stopPropagation(),t.close()):o._super.prototype.close.call(this,e)}}}),o}),define("WoltLabSuite/Core/Ui/Dropdown/Reusable",["Dictionary","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!n.has(e))throw new Error("Unknown dropdown identifier '"+e+"'");return n.get(e)}var n=new e,o=0;return{init:function(e,i){if(!n.has(e)){var r=elCreate("div");r.id="reusableDropdownGhost"+o++,t.initFragment(r,i),n.set(e,r.id)}},getDropdownMenu:function(e){return t.getDropdownMenu(i(e))},registerCallback:function(e,n){t.registerCallback(i(e),n)},toggleDropdown:function(e,n){t.toggleDropdown(i(e),n)}}}),define("WoltLabSuite/Core/Ui/Mobile",["Core","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Alignment","Ui/CloseOverlay","Ui/Screen","./Page/Menu/Main","./Page/Menu/User","WoltLabSuite/Core/Ui/Dropdown/Reusable"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";var p=elByClass("buttonGroupNavigation"),g=null,m=null,v=null,b=!1,_=!1,w=new o,y=null,C=elByClass("message"),E=!1,L={},A=null,S=null,x=null,I=[];return{setup:function(i){L=e.extend({enableMobileMenu:!0},i),y=elById("main"),elBySelAll(".sidebar",void 0,function(e){I.push(e)}),t.touch()&&document.documentElement.classList.add("touch"),"desktop"!==t.platform()&&document.documentElement.classList.add("mobile");var n=elBySel(".messageGroupList");n&&(x=elByClass("messageGroup",n)),u.on("screen-md-down",{match:this.enable.bind(this),unmatch:this.disable.bind(this),setup:this._init.bind(this)}),u.on("screen-sm-down",{match:this.enableShadow.bind(this),unmatch:this.disableShadow.bind(this),setup:this.enableShadow.bind(this)}),u.on("screen-md-down",{match:this._enableMobileSidebar.bind(this),unmatch:this._disableMobileSidebar.bind(this),setup:this._setupMobileSidebar.bind(this)}),!t.touch()||"ios"!==t.platform()&&"android"!==t.platform()||u.on("screen-lg",{match:this._enableLGTouchNavigation.bind(this),unmatch:this._disableLGTouchNavigation.bind(this),setup:this._setupLGTouchNavigation.bind(this)})},enable:function(){b=!0,L.enableMobileMenu&&(A.enable(),S.enable())},enableShadow:function(){x&&this.rebuildShadow(x,".messageGroupLink")},disable:function(){b=!1,L.enableMobileMenu&&(A.disable(),S.disable())},disableShadow:function(){x&&this.removeShadow(x),m&&g()},_init:function(){b=!0,this._initSearchBar(),this._initButtonGroupNavigation(),this._initMessages(),this._initMobileMenu(),c.add("WoltLabSuite/Core/Ui/Mobile",this._closeAllMenus.bind(this)),r.add("WoltLabSuite/Core/Ui/Mobile",function(){this._initButtonGroupNavigation(),this._initMessages()}.bind(this))},_initSearchBar:function(){var e=elById("pageHeaderSearch"),n=elById("pageHeaderSearchInput"),o=null;i.add("com.woltlab.wcf.MainMenuMobile","more",function(i){"com.woltlab.wcf.search"===i.identifier&&(i.handler.close(!0),"ios"===t.platform()&&(o=document.body.scrollTop,u.scrollDisable()),e.style.setProperty("top",elById("pageHeader").offsetHeight+"px",""),e.classList.add("open"),n.focus(),"ios"===t.platform()&&(document.body.scrollTop=0))}),y.addEventListener(WCF_CLICK_EVENT,function(){e&&e.classList.remove("open"),"ios"===t.platform()&&null!==o&&(u.scrollEnable(),document.body.scrollTop=o,o=null)})},_initButtonGroupNavigation:function(){for(var e=0,t=p.length;e<t;e++){var i=p[e];if(!i.classList.contains("jsMobileButtonGroupNavigation")){i.classList.add("jsMobileButtonGroupNavigation");var n=elBySel(".buttonList",i);if(0!==n.childElementCount){i.parentNode.classList.add("hasMobileNavigation");var o=elCreate("a");o.className="dropdownLabel";var r=elCreate("span");r.className="icon icon24 fa-ellipsis-v",o.appendChild(r),function(e,t,i){t.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),e.classList.toggle("open")}),i.addEventListener(WCF_CLICK_EVENT,function(t){t.stopPropagation(),e.classList.remove("open")})}(i,o,n),i.insertBefore(o,i.firstChild)}}}},_initMessages:function(){Array.prototype.forEach.call(C,function(e){if(!w.has(e)){var t=elBySel(".jsMobileNavigation",e);if(t){t.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation(),window.setTimeout(function(){t.classList.remove("open")},10)});var i=elBySel(".messageQuickOptions",e);i&&t.childElementCount&&(i.classList.add("active"),i.addEventListener(WCF_CLICK_EVENT,function(n){b&&u.is("screen-sm-down")&&"LABEL"!==n.target.nodeName&&"INPUT"!==n.target.nodeName&&(n.preventDefault(),n.stopPropagation(),this._toggleMobileNavigation(e,i,t))}.bind(this)))}w.add(e)}}.bind(this))},_initMobileMenu:function(){L.enableMobileMenu&&(A=new d,S=new h)},_closeAllMenus:function(){elBySelAll(".jsMobileButtonGroupNavigation.open, .jsMobileNavigation.open",null,function(e){e.classList.remove("open")}),b&&m&&g()},rebuildShadow:function(e,t){for(var i,n,o,r=0,l=e.length;r<l;r++)i=e[r],n=i.parentNode,null===(o=a.childByClass(n,"mobileLinkShadow"))&&elBySel(t,i).href&&(o=elCreate("a"),o.className="mobileLinkShadow",o.href=elBySel(t,i).href,n.appendChild(o),n.classList.add("mobileLinkShadowContainer"))},removeShadow:function(e){for(var t,i,n,o=0,r=e.length;o<r;o++)t=e[o],i=t.parentNode,i.classList.contains("mobileLinkShadowContainer")&&(n=a.childByClass(i,"mobileLinkShadow"),null!==n&&elRemove(n),i.classList.remove("mobileLinkShadowContainer"))},_enableMobileSidebar:function(){E=!0},_disableMobileSidebar:function(){E=!1,I.forEach(function(e){e.classList.remove("open")})},_setupMobileSidebar:function(){I.forEach(function(e){e.addEventListener("mousedown",function(t){E&&t.target===e&&(t.preventDefault(),e.classList.toggle("open"))})}),E=!0},_toggleMobileNavigation:function(e,t,i){if(null===m)m=elCreate("ul"),m.className="dropdownMenu",f.init("com.woltlab.wcf.jsMobileNavigation",m),g=function(){m.classList.remove("dropdownOpen")};else if(m.classList.contains("dropdownOpen")&&(g(),v===e))return;m.innerHTML="",c.execute(),this._rebuildMobileNavigation(i);var n=i.previousElementSibling;if(n&&n.classList.contains("messageFooterButtonsExtra")){var o=elCreate("li");o.className="dropdownDivider",m.appendChild(o),this._rebuildMobileNavigation(n)}s.set(m,t,{horizontal:"right",allowFlip:"vertical"}),m.classList.add("dropdownOpen"),v=e},_setupLGTouchNavigation:function(){_=!0,elBySelAll(".boxMenuHasChildren > a",null,function(e){e.addEventListener("touchstart",function(t){_&&"false"===elAttr(e,"aria-expanded")&&(t.preventDefault(),elAttr(e,"aria-expanded","true"),e.addEventListener("touchend",function(){document.body.addEventListener("touchstart",function(){document.body.addEventListener("touchend",function(t){l.contains(e.parentNode,t.target)||t.target===e.parentNode||elAttr(e,"aria-expanded","false")},{once:!0})},{once:!0})},{once:!0}))})})},_enableLGTouchNavigation:function(){_=!0},_disableLGTouchNavigation:function(){_=!1},_rebuildMobileNavigation:function(t){elBySelAll(".button",t,function(t){if(!t.classList.contains("ignoreMobileNavigation")||t.classList.contains("reactButton")){var i=elCreate("li");t.classList.contains("active")&&(i.className="active"),i.innerHTML='<a href="#">'+elBySel("span:not(.icon)",t).textContent+"</a>",i.children[0].addEventListener(WCF_CLICK_EVENT,function(i){i.preventDefault(),i.stopPropagation(),"A"===t.nodeName?t.click():e.triggerEvent(t,WCF_CLICK_EVENT),g()}),m.appendChild(i)}})}}}),define("WoltLabSuite/Core/Ui/Scroll",["Dom/Util"],function(e){"use strict";var t=null,i=null,n=null,o=null;return{element:function(o,r){if(!(o instanceof Element))throw new TypeError("Expected a valid DOM element.");if(void 0!==r&&"function"!=typeof r)throw new TypeError("Expected a valid callback function.");if(!document.body.contains(o))throw new Error("Element must be part of the visible DOM.");if(null!==t)throw new Error("Cannot scroll to element, a concurrent request is running.");r&&(t=r,null===i&&(i=this._onScroll.bind(this)),window.addEventListener("scroll",i));var a=e.offset(o).top;if(null===n){n=50;var l=elById("pageHeaderPanel");if(null!==l){var s=window.getComputedStyle(l).position;n="fixed"===s||"static"===s?l.offsetHeight:0}}n>0&&(a<=n?a=0:a-=n);var c=window.pageYOffset;window.scrollTo({left:0,top:a,behavior:"smooth"}),window.setTimeout(function(){c===window.pageYOffset&&this._onScroll()}.bind(this),100)},_onScroll:function(){null!==o&&window.clearTimeout(o),o=window.setTimeout(function(){null!==t&&t(),window.removeEventListener("scroll",i),t=null,o=null},100)}}}),define("WoltLabSuite/Core/Ui/TabMenu/Simple",["Dictionary","Environment","EventHandler","Dom/Traverse","Dom/Util"],function(e,t,i,n,o){"use strict";function r(t){this._container=t,this._containers=new e,this._isLegacy=null,this._store=null,this._tabs=new e}return r.prototype={validate:function(){if(!this._container.classList.contains("tabMenuContainer"))return!1;var e=n.childByTag(this._container,"NAV");if(null===e)return!1;var t=elByTag("li",e);if(0===t.length)return!1;var i,r,a,l,s=n.childrenByTag(this._container,"DIV");for(a=0,l=s.length;a<l;a++)i=s[a],r=elData(i,"name"),r||(r=o.identify(i)),elData(i,"name",r),this._containers.set(r,i);var c,u=this._container.id;for(a=0,l=t.length;a<l;a++)if(c=t[a],r=this._getTabName(c)){if(this._tabs.has(r))throw new Error("Tab names must be unique, li[data-name='"+r+"'] (tab menu id: '"+u+"') exists more than once.");if(void 0===(i=this._containers.get(r)))throw new Error("Expected content element for li[data-name='"+r+"'] (tab menu id: '"+u+"').");if(i.parentNode!==this._container)throw new Error("Expected content element '"+r+"' (tab menu id: '"+u+"') to be a direct children.");if(1!==c.childElementCount||"A"!==c.children[0].nodeName)throw new Error("Expected exactly one <a> as children for li[data-name='"+r+"'] (tab menu id: '"+u+"').");this._tabs.set(r,c)}if(!this._tabs.size)throw new Error("Expected at least one tab (tab menu id: '"+u+"').");return this._isLegacy&&(elData(this._container,"is-legacy",!0),this._tabs.forEach(function(e,t){elAttr(e,"aria-controls",t)})),!0},init:function(e){e=e||null,this._tabs.forEach(function(i){if((!e||e.get(elData(i,"name"))!==i)&&(i.children[0].addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this)),"ios"===t.platform())){var n=!1;i.children[0].addEventListener("touchstart",function(){n=!0}),i.children[0].addEventListener("touchmove",function(){n=!1}),i.children[0].addEventListener("touchend",function(e){n&&(n=!1,e.preventDefault(),this._onClick(e))}.bind(this))}}.bind(this));var i=null;if(!e){var n=r.getIdentifierFromHash(),o=null;if(""!==n&&(o=this._tabs.get(n))&&this._container.parentNode.classList.contains("tabMenuContainer")&&(i=this._container),!o){var a=elData(this._container,"preselect")||elData(this._container,"active");"true"!==a&&a||(a=!0),!0===a?this._tabs.forEach(function(e){o||elIsHidden(e)||e.previousElementSibling&&!elIsHidden(e.previousElementSibling)||(o=e)}):"false"!==a&&(o=this._tabs.get(a))}o&&(this._containers.forEach(function(e){e.classList.add("hidden")}),this.select(null,o,!0));var l=elData(this._container,"store");if(l){var s=elCreate("input");s.type="hidden",s.name=l,s.value=elData(this.getActiveTab(),"name"),this._container.appendChild(s),this._store=s}}return i},select:function(e,t,n){if(!(t=t||this._tabs.get(e))){if(~~e==e){e=~~e;var o=0;this._tabs.forEach(function(i){o===e&&(t=i),o++})}if(!t)throw new Error("Expected a valid tab name, '"+e+"' given (tab menu id: '"+this._container.id+"').")}e=e||elData(t,"name");var a=this.getActiveTab(),l=null;if(a){var s=elData(a,"name");if(s===e)return;n||i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"beforeSelect",{tab:a,tabName:s}),a.classList.remove("active"),l=this._containers.get(elData(a,"name")),l.classList.remove("active"),l.classList.add("hidden"),this._isLegacy&&(a.classList.remove("ui-state-active"),l.classList.remove("ui-state-active"))}t.classList.add("active");var c=this._containers.get(e);if(c.classList.add("active"),c.classList.remove("hidden"),this._isLegacy&&(t.classList.add("ui-state-active"),c.classList.add("ui-state-active")),this._store&&(this._store.value=e),!n){i.fire("com.woltlab.wcf.simpleTabMenu_"+this._container.id,"select",{active:t,activeName:e,previous:a,previousName:a?elData(a,"name"):null});var u=this._isLegacy&&"function"==typeof window.jQuery?window.jQuery:null;u&&u(this._container).trigger("wcftabsbeforeactivate",{newTab:u(t),oldTab:u(a),newPanel:u(c),oldPanel:u(l)});var d=window.location.href.replace(/#+[^#]*$/,"");r.getIdentifierFromHash()===e?d+=window.location.hash:d+="#"+e,window.history.replaceState(void 0,void 0,d)}require(["WoltLabSuite/Core/Ui/TabMenu"],function(e){e.scrollToTab(t)})},selectFirstVisible:function(){var e;return this._tabs.forEach(function(t){e||elIsHidden(t)||(e=t)}.bind(this)),e&&this.select(void 0,e,!1),!!e},rebuild:function(){var t=new e;t.merge(this._tabs),this.validate(),this.init(t)},hasTab:function(e){return this._tabs.has(e)},_onClick:function(e){e.preventDefault(),this.select(null,e.currentTarget.parentNode)},_getTabName:function(e){var t=elData(e,"name");return t||1===e.childElementCount&&"A"===e.children[0].nodeName&&e.children[0].href.match(/#([^#]+)$/)&&(t=RegExp.$1,null===elById(t)?t=null:(this._isLegacy=!0,elData(e,"name",t))),t},getActiveTab:function(){return elBySel("#"+this._container.id+" > nav > ul > li.active")},getContainers:function(){return this._containers},getTabs:function(){return this._tabs}},r.getIdentifierFromHash=function(){return window.location.hash.match(/^#+([^\/]+)+(?:\/.+)?/)?RegExp.$1:""},r}),define("WoltLabSuite/Core/Ui/TabMenu",["Dictionary","EventHandler","Dom/ChangeListener","Dom/Util","Ui/CloseOverlay","Ui/Screen","Ui/Scroll","./TabMenu/Simple"],function(e,t,i,n,o,r,a,l){"use strict";var s=null,c=!1,u=new e;return{setup:function(){this._init(),this._selectErroneousTabs(),i.add("WoltLabSuite/Core/Ui/TabMenu",this._init.bind(this)),o.add("WoltLabSuite/Core/Ui/TabMenu",function(){s&&(s.classList.remove("active"),s=null)}),r.on("screen-sm-down",{enable:this._scrollEnable.bind(this,!1),disable:this._scrollDisable.bind(this),setup:this._scrollEnable.bind(this,!0)}),window.addEventListener("hashchange",function(){var e=l.getIdentifierFromHash(),t=e?elById(e):null;null!==t&&t.classList.contains("tabMenuContent")&&u.forEach(function(t){t.hasTab(e)&&t.select(e)})});var e=l.getIdentifierFromHash();e&&window.setTimeout(function(){var t=elById(e);if(t&&t.classList.contains("tabMenuContent")){var i=window.scrollY||window.pageYOffset;if(i>0){var o=t.parentNode,r=o.offsetTop-50;if(r<0&&(r=0),i>r){var a=n.offset(o).top;a<=50?a=0:a-=50,window.scrollTo(0,a)}}}},100)},_init:function(){for(var e,t,i,o,r,c=elBySelAll(".tabMenuContainer:not(.staticTabMenuContainer)"),d=0,h=c.length;d<h;d++)if(e=c[d],t=n.identify(e),!u.has(t)&&(r=new l(e),r.validate())){o=r.init(),u.set(t,r),o instanceof Element&&(r=this.getTabMenu(o.parentNode.id),r.select(o.id,null,!0)),i=elBySel("#"+t+" > nav > ul"),function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),t.stopPropagation(),t.target===e?(e.classList.add("active"),s=e):(e.classList.remove("active"),s=null)})}(i),elBySelAll(".tabMenu, .menu",e,function(e){var t=this._rebuildMenuOverflow.bind(this,e),i=null;elBySel("ul",e).addEventListener("scroll",function(){null!==i&&window.clearTimeout(i),i=window.setTimeout(t,10)})}.bind(this));var f=e.closest("form");if(null!==f){var p=elBySel('input[type="submit"]',f);null!==p&&function(e,t){t.addEventListener(WCF_CLICK_EVENT,function(t){if(!t.defaultPrevented)for(var i,n=elBySelAll("input, select",e),o=0,r=n.length;o<r;o++)if(i=n[o],!i.checkValidity()){t.preventDefault();var l=this.getTabMenu(i.closest(".tabMenuContainer").id);return l.select(elData(i.closest(".tabMenuContent"),"name")),void a.element(i,function(){this.reportValidity()}.bind(i))}}.bind(this))}.bind(this)(e,p)}}},_selectErroneousTabs:function(){u.forEach(function(e){var t=!1;e.getContainers().forEach(function(i){!t&&elByClass("formError",i).length&&(t=!0,e.select(i.id))})})},getTabMenu:function(e){return u.get(e)},_scrollEnable:function(e){c=!0,u.forEach(function(t){var i=t.getActiveTab();e?this._rebuildMenuOverflow(i.closest(".menu, .tabMenu")):this.scrollToTab(i)}.bind(this))},_scrollDisable:function(){c=!1},scrollToTab:function(e){if(c){var t=e.closest("ul"),i=t.clientWidth,n=t.scrollLeft,o=t.scrollWidth;if(i!==o){var r=e.offsetLeft,a=!1;r<n&&(a=!0);var l=!1;if(!a){var s=i-(r-n),u=e.clientWidth;null!==e.nextElementSibling&&(l=!0,u+=20),s<u&&(a=!0)}a&&this._scrollMenu(t,r,n,o,i,l)}}},_scrollMenu:function(e,t,i,n,o,r){r?t-=15:t>0&&(t-=15),t=t<0?0:Math.min(t,n-o),i!==t&&(e.classList.add("enableAnimation"),i<t?e.firstElementChild.style.setProperty("margin-left",i-t+"px",""):e.style.setProperty("padding-left",i-t+"px",""),setTimeout(function(){e.classList.remove("enableAnimation"),e.firstElementChild.style.removeProperty("margin-left"),e.style.removeProperty("padding-left"),e.scrollLeft=t},300))},_rebuildMenuOverflow:function(e){if(c){var t=e.clientWidth,i=elBySel("ul",e),n=i.scrollLeft,o=i.scrollWidth,r=n>0,a=elBySel(".tabMenuOverlayLeft",e);r?(null===a&&(a=elCreate("span"),a.className="tabMenuOverlayLeft icon icon24 fa-angle-left",a.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft-~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.insertBefore(a,e.firstChild)),a.classList.add("active")):null!==a&&a.classList.remove("active");var l=t+n<o,s=elBySel(".tabMenuOverlayRight",e);l?(null===s&&(s=elCreate("span"),s.className="tabMenuOverlayRight icon icon24 fa-angle-right",s.addEventListener(WCF_CLICK_EVENT,function(){var e=i.clientWidth;this._scrollMenu(i,i.scrollLeft+~~(e/2),i.scrollLeft,i.scrollWidth,e,0)}.bind(this)),e.appendChild(s)),s.classList.add("active")):null!==s&&s.classList.remove("active")}}}}),define("WoltLabSuite/Core/Ui/FlexibleMenu",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o,r){"use strict";var a=new t,l=new t,s=new t,c=new t;return{setup:function(){null!==elById("mainMenu")&&this.register("mainMenu");var e=elBySel(".navigationHeader");null!==e&&this.register(o.identify(e)),window.addEventListener("resize",this.rebuildAll.bind(this)),i.add("WoltLabSuite/Core/Ui/FlexibleMenu",this.registerTabMenus.bind(this))},register:function(e){var t=elById(e)
+;if(null===t)throw"Expected a valid element id, '"+e+"' does not exist.";if(!a.has(e)){var i=n.childByTag(t,"UL");if(null===i)throw"Expected an <ul> element as child of container '"+e+"'.";a.set(e,t),c.set(e,i),this.rebuild(e)}},registerTabMenus:function(){for(var e=elBySelAll(".tabMenuContainer:not(.jsFlexibleMenuEnabled), .messageTabMenu:not(.jsFlexibleMenuEnabled)"),t=0,i=e.length;t<i;t++){var r=e[t],a=n.childByTag(r,"NAV");null!==a&&(r.classList.add("jsFlexibleMenuEnabled"),this.register(o.identify(a)))}},rebuildAll:function(){a.forEach(function(e,t){this.rebuild(t)}.bind(this))},rebuild:function(t){var i=a.get(t);if(void 0===i)throw"Expected a valid element id, '"+t+"' is unknown.";var u=window.getComputedStyle(i),d=i.parentNode.clientWidth;d-=o.styleAsInt(u,"margin-left"),d-=o.styleAsInt(u,"margin-right");var h=c.get(t),f=n.childrenByTag(h,"LI"),p=l.get(t),g=0;if(void 0!==p){for(var m=0,v=f.length;m<v;m++){var b=f[m];b.classList.contains("dropdown")||elShow(b)}null!==p.parentNode&&(g=o.outerWidth(p))}var _=h.scrollWidth-g,w=[];if(_>d)for(var m=f.length-1;m>=0;m--){var b=f[m];if(!(b.classList.contains("dropdown")||b.classList.contains("active")||b.classList.contains("ui-state-active"))&&(w.push(b),elHide(b),h.scrollWidth<d))break}if(w.length){var y;if(void 0===p){p=elCreate("li"),p.className="dropdown jsFlexibleMenuDropdown";var C=elCreate("a");C.className="icon icon16 fa-list",p.appendChild(C),y=elCreate("ul"),y.classList.add("dropdownMenu"),p.appendChild(y),l.set(t,p),s.set(t,y),r.init(C)}else y=s.get(t);null===p.parentNode&&h.appendChild(p);var E=document.createDocumentFragment(),L=this;w.forEach(function(i){var n=elCreate("li");n.innerHTML=i.innerHTML,n.addEventListener(WCF_CLICK_EVENT,function(n){n.preventDefault(),e.triggerEvent(elBySel("a",i),WCF_CLICK_EVENT),setTimeout(function(){L.rebuild(t)},59)}.bind(this)),E.appendChild(n)}),y.innerHTML="",y.appendChild(E)}else void 0!==p&&null!==p.parentNode&&elRemove(p)}}}),define("WoltLabSuite/Core/Ui/Tooltip",["Environment","Dom/ChangeListener","Ui/Alignment"],function(e,t,i){"use strict";var n=null,o=null,r=null,a=null,l=null,s=null;return{setup:function(){"desktop"===e.platform()&&(s=elCreate("div"),elAttr(s,"id","balloonTooltip"),s.classList.add("balloonTooltip"),s.addEventListener("transitionend",function(){s.classList.contains("active")||["bottom","left","right","top"].forEach(function(e){s.style.removeProperty(e)})}),l=elCreate("span"),elAttr(l,"id","balloonTooltipText"),s.appendChild(l),a=elCreate("span"),a.classList.add("elementPointer"),a.appendChild(elCreate("span")),s.appendChild(a),document.body.appendChild(s),r=elByClass("jsTooltip"),n=this._mouseEnter.bind(this),o=this._mouseLeave.bind(this),this.init(),t.add("WoltLabSuite/Core/Ui/Tooltip",this.init.bind(this)),window.addEventListener("scroll",this._mouseLeave.bind(this)))},init:function(){0!==r.length&&elBySelAll(".jsTooltip",void 0,function(e){e.classList.remove("jsTooltip");var t=elAttr(e,"title").trim();t.length&&(elData(e,"tooltip",t),e.removeAttribute("title"),elAttr(e,"aria-label",t),e.addEventListener("mouseenter",n),e.addEventListener("mouseleave",o),e.addEventListener(WCF_CLICK_EVENT,o))})},_mouseEnter:function(e){var t=e.currentTarget,n=elAttr(t,"title");if(n="string"==typeof n?n.trim():"",""!==n&&(elData(t,"tooltip",n),elAttr(t,"aria-label",n),t.removeAttribute("title")),n=elData(t,"tooltip"),s.style.removeProperty("top"),s.style.removeProperty("left"),!n.length)return void s.classList.remove("active");s.classList.add("active"),l.textContent=n,i.set(s,t,{horizontal:"center",verticalOffset:4,pointer:!0,pointerClassNames:["inverse"],vertical:"top"})},_mouseLeave:function(){s.classList.remove("active")}}}),define("WoltLabSuite/Core/Date/Picker",["DateUtil","Dom/Traverse","Dom/Util","EventHandler","Language","ObjectMap","Dom/ChangeListener","Ui/Alignment","WoltLabSuite/Core/Ui/CloseOverlay"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=!1,u=0,d=!1,h=new r,f=null,p=0,g=0,m=[],v=null,b=null,_=null,w=null,y=null,C=null,E=null,L=null,A=null,S=null,x=null,I={init:function(){this._setup();for(var t=elBySelAll('input[type="date"]:not(.inputDatePicker), input[type="datetime"]:not(.inputDatePicker)'),i=new Date,n=0,r=t.length;n<r;n++){var a=t[n];a.classList.add("inputDatePicker"),a.readOnly=!0;var l="datetime"===elAttr(a,"type"),s=l&&elDataBool(a,"time-only"),c=elDataBool(a,"disable-clear"),u=l&&elDataBool(a,"ignore-timezone"),d=a.classList.contains("birthday");elData(a,"is-date-time",l),elData(a,"is-time-only",s);var f=null,p=elAttr(a,"value"),g=/^\d+-\d+-\d+$/.test(p);if(elAttr(a,"value")){if(s){f=new Date;var m=p.split(":");f.setHours(m[0],m[1])}else{if(u||d||g){var v=new Date(p).getTimezoneOffset(),b=v>0?"-":"+";v=Math.abs(v);var _=Math.floor(v/60).toString(),w=(v%60).toString();b+=2===_.length?_:"0"+_,b+=":",b+=2===w.length?w:"0"+w,d||g?p+="T00:00:00"+b:p=p.replace(/[+-][0-9]{2}:[0-9]{2}$/,b)}f=new Date(p)}var y=f.getTime();if(isNaN(y))p="";else{elData(a,"value",y);p=e[s?"formatTime":"formatDate"+(l?"Time":"")](f)}}var C=0===p.length;if(d?(elData(a,"min-date","120"),elData(a,"max-date",(new Date).getFullYear()+"-12-31")):(a.min&&elData(a,"min-date",a.min),a.max&&elData(a,"max-date",a.max)),this._initDateRange(a,i,!0),this._initDateRange(a,i,!1),elData(a,"min-date")===elData(a,"max-date"))throw new Error("Minimum and maximum date cannot be the same (element id '"+a.id+"').");a.type="text",a.value=p,elData(a,"empty",C),elData(a,"placeholder")&&elAttr(a,"placeholder",elData(a,"placeholder"));var E=elCreate("input");if(E.id=a.id+"DatePicker",E.name=a.name,E.type="hidden",null!==f&&(E.value=s?e.format(f,"H:i"):u?e.format(f,"Y-m-dTH:i:s"):e.format(f,l?"c":"Y-m-d")),a.parentNode.insertBefore(E,a),a.removeAttribute("name"),a.addEventListener(WCF_CLICK_EVENT,S),!a.disabled){var L=elCreate("div");L.className="inputAddon";var A=elCreate("a");A.className="inputSuffix button jsTooltip",A.href="#",elAttr(A,"role","button"),elAttr(A,"tabindex","0"),elAttr(A,"title",o.get("wcf.date.datePicker")),elAttr(A,"aria-label",o.get("wcf.date.datePicker")),elAttr(A,"aria-haspopup",!0),elAttr(A,"aria-expanded",!1),A.addEventListener(WCF_CLICK_EVENT,S),L.appendChild(A);var x=elCreate("span");x.className="icon icon16 fa-calendar",A.appendChild(x),a.parentNode.insertBefore(L,a),L.insertBefore(a,A),c||(A=elCreate("a"),A.className="inputSuffix button",A.addEventListener(WCF_CLICK_EVENT,this.clear.bind(this,a)),C&&A.style.setProperty("visibility","hidden",""),L.appendChild(A),x=elCreate("span"),x.className="icon icon16 fa-times",A.appendChild(x))}for(var I=!1,D=["tiny","short","medium","long"],T=0;T<4;T++)a.classList.contains(D[T])&&(I=!0);I||a.classList.add("short"),h.set(a,{clearButton:A,shadow:E,disableClear:c,isDateTime:l,isEmpty:C,isTimeOnly:s,ignoreTimezone:u,onClose:null})}},_initDateRange:function(e,t,i){var n="data-"+(i?"min":"max")+"-date",o=e.hasAttribute(n)?elAttr(e,n).trim():"";if(o.match(/^(\d{4})-(\d{2})-(\d{2})$/))o=new Date(o).getTime();else if("now"===o)o=t.getTime();else if(o.match(/^\d{1,3}$/)){var r=new Date(t.getTime());r.setFullYear(r.getFullYear()+~~o*(i?-1:1)),o=r.getTime()}else if(o.match(/^datePicker-(.+)$/)){if(o=RegExp.$1,null===elById(o))throw new Error("Reference date picker identified by '"+o+"' does not exists (element id: '"+e.id+"').")}else o=/^\d{4}\-\d{2}\-\d{2}T/.test(o)?new Date(o).getTime():new Date(i?1902:2038,0,1).getTime();elAttr(e,n,o)},_setup:function(){c||(c=!0,u=~~o.get("wcf.date.firstDayOfTheWeek"),S=this._open.bind(this),a.add("WoltLabSuite/Core/Date/Picker",this.init.bind(this)),s.add("WoltLabSuite/Core/Date/Picker",this._close.bind(this)))},_open:function(e){e.preventDefault(),e.stopPropagation(),this._createPicker(),null===x&&(x=this._maintainFocus.bind(this),document.body.addEventListener("focus",x,{capture:!0}));var i="INPUT"===e.currentTarget.nodeName?e.currentTarget:e.currentTarget.previousElementSibling;if(i===f)return void this._close();var n=t.parentByClass(i,"dialogContent");null!==n&&(elDataBool(n,"has-datepicker-scroll-listener")||(n.addEventListener("scroll",this._onDialogScroll.bind(this)),elData(n,"has-datepicker-scroll-listener",1))),f=i;var o,r=h.get(f),a=elData(f,"value");a?(o=new Date(+a),"Invalid Date"===o.toString()&&(o=new Date)):o=new Date,g=elData(f,"min-date"),g.match(/^datePicker-(.+)$/)&&(g=elData(elById(RegExp.$1),"value")),g=new Date(+g),g.getTime()>o.getTime()&&(o=g),p=elData(f,"max-date"),p.match(/^datePicker-(.+)$/)&&(p=elData(elById(RegExp.$1),"value")),p=new Date(+p),r.isDateTime?(b.value=o.getHours(),_.value=o.getMinutes(),A.classList.add("datePickerTime")):A.classList.remove("datePickerTime"),A.classList[r.isTimeOnly?"add":"remove"]("datePickerTimeOnly"),this._renderPicker(o.getDate(),o.getMonth(),o.getFullYear()),l.set(A,f),elAttr(f.nextElementSibling,"aria-expanded",!0),d=!1},_close:function(){if(null!==A&&A.classList.contains("active")){A.classList.remove("active");var e=h.get(f);"function"==typeof e.onClose&&e.onClose(),n.fire("WoltLabSuite/Core/Date/Picker","close",{element:f}),elAttr(f.nextElementSibling,"aria-expanded",!1),f=null,g=0,p=0}},_onDialogScroll:function(e){if(null!==f){var t=e.currentTarget,n=i.offset(f),o=i.offset(t);n.top+f.clientHeight<=o.top?this._close():n.top>=o.top+t.offsetHeight?this._close():n.left<=o.left?this._close():n.left>=o.left+t.offsetWidth?this._close():l.set(A,f)}},_renderPicker:function(e,t,i){this._renderGrid(e,t,i);for(var n="",o=g.getFullYear(),r=p.getFullYear();o<=r;o++)n+='<option value="'+o+'">'+o+"</option>";L.innerHTML=n,L.value=i,w.value=t,A.classList.add("active")},_renderGrid:function(t,i,n){var o,r,a=void 0!==t,l=void 0!==i;if(t=~~t||~~elData(v,"day"),i=~~i,n=~~n,l||n){var s=0!==n,c=document.createDocumentFragment();c.appendChild(v),l||(i=~~elData(v,"month")),n=n||~~elData(v,"year");var d=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-"+("0"+t.toString()).slice(-2));for(d<g?(n=g.getFullYear(),i=g.getMonth(),t=g.getDate(),w.value=i,L.value=n,s=!0):d>p&&(n=p.getFullYear(),i=p.getMonth(),t=p.getDate(),w.value=i,L.value=n,s=!0),d=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");d.getDay()!==u;)d.setDate(d.getDate()-1);elShow(m[35].parentNode);var h,f=new Date(g.getFullYear(),g.getMonth(),g.getDate());for(r=0;r<42;r++){if(35===r&&d.getMonth()!==i){elHide(m[35].parentNode);break}o=m[r],o.textContent=d.getDate(),h=d.getMonth()===i,h&&(d<f?h=!1:d>p&&(h=!1)),o.classList[h?"remove":"add"]("otherMonth"),h&&(o.href="#",elAttr(o,"role","button"),elAttr(o,"tabindex","0"),elAttr(o,"title",e.formatDate(d)),elAttr(o,"aria-label",e.formatDate(d))),d.setDate(d.getDate()+1)}if(elData(v,"month",i),elData(v,"year",n),A.insertBefore(c,E),!a&&(d=new Date(n,i,t),d.getDate()!==t)){for(;d.getMonth()!==i;)d.setDate(d.getDate()-1);t=d.getDate()}if(s){for(r=0;r<12;r++){var b=w.children[r];b.disabled=n===g.getFullYear()&&b.value<g.getMonth()||n===p.getFullYear()&&b.value>p.getMonth()}var _=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");_.setMonth(_.getMonth()+1),y.classList[_<p?"add":"remove"]("active");var S=new Date(n+"-"+("0"+(i+1).toString()).slice(-2)+"-01");S.setDate(S.getDate()-1),C.classList[S>g?"add":"remove"]("active")}}if(t){for(r=0;r<35;r++)o=m[r],o.classList[o.classList.contains("otherMonth")||~~o.textContent!==t?"remove":"add"]("active");elData(v,"day",t)}this._formatValue()},_formatValue:function(){var e,t=h.get(f);"true"!==elData(f,"empty")&&(e=t.isDateTime?new Date(elData(v,"year"),elData(v,"month"),elData(v,"day"),b.value,_.value):new Date(elData(v,"year"),elData(v,"month"),elData(v,"day")),this.setDate(f,e))},_createPicker:function(){if(null===A){A=elCreate("div"),A.className="datePicker",A.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()});var t=elCreate("header");A.appendChild(t),C=elCreate("a"),C.className="previous jsTooltip",C.href="#",elAttr(C,"role","button"),elAttr(C,"tabindex","0"),elAttr(C,"title",o.get("wcf.date.datePicker.previousMonth")),elAttr(C,"aria-label",o.get("wcf.date.datePicker.previousMonth")),C.innerHTML='<span class="icon icon16 fa-arrow-left"></span>',C.addEventListener(WCF_CLICK_EVENT,this.previousMonth.bind(this)),t.appendChild(C);var i=elCreate("span");t.appendChild(i),w=elCreate("select"),w.className="month jsTooltip",elAttr(w,"title",o.get("wcf.date.datePicker.month")),elAttr(w,"aria-label",o.get("wcf.date.datePicker.month")),w.addEventListener("change",this._changeMonth.bind(this)),i.appendChild(w);var n,r="",a=o.get("__monthsShort");for(n=0;n<12;n++)r+='<option value="'+n+'">'+a[n]+"</option>";w.innerHTML=r,L=elCreate("select"),L.className="year jsTooltip",elAttr(L,"title",o.get("wcf.date.datePicker.year")),elAttr(L,"aria-label",o.get("wcf.date.datePicker.year")),L.addEventListener("change",this._changeYear.bind(this)),i.appendChild(L),y=elCreate("a"),y.className="next jsTooltip",y.href="#",elAttr(y,"role","button"),elAttr(y,"tabindex","0"),elAttr(y,"title",o.get("wcf.date.datePicker.nextMonth")),elAttr(y,"aria-label",o.get("wcf.date.datePicker.nextMonth")),y.innerHTML='<span class="icon icon16 fa-arrow-right"></span>',y.addEventListener(WCF_CLICK_EVENT,this.nextMonth.bind(this)),t.appendChild(y),v=elCreate("ul"),A.appendChild(v);var l=elCreate("li");l.className="weekdays",v.appendChild(l);var s,c=o.get("__daysShort");for(n=0;n<7;n++){var d=n+u;d>6&&(d-=7),s=elCreate("span"),s.textContent=c[d],l.appendChild(s)}var h,f,p=this._click.bind(this);for(n=0;n<6;n++){f=elCreate("li"),v.appendChild(f);for(var g=0;g<7;g++)h=elCreate("a"),h.addEventListener(WCF_CLICK_EVENT,p),m.push(h),f.appendChild(h)}E=elCreate("footer"),A.appendChild(E),b=elCreate("select"),b.className="hour",elAttr(b,"title",o.get("wcf.date.datePicker.hour")),elAttr(b,"aria-label",o.get("wcf.date.datePicker.hour")),b.addEventListener("change",this._formatValue.bind(this));var S="",x=new Date(2e3,0,1),I=o.get("wcf.date.timeFormat").replace(/:/,"").replace(/[isu]/g,"");for(n=0;n<24;n++)x.setHours(n),S+='<option value="'+n+'">'+e.format(x,I)+"</option>";for(b.innerHTML=S,E.appendChild(b),E.appendChild(document.createTextNode(" : ")),_=elCreate("select"),_.className="minute",elAttr(_,"title",o.get("wcf.date.datePicker.minute")),elAttr(_,"aria-label",o.get("wcf.date.datePicker.minute")),_.addEventListener("change",this._formatValue.bind(this)),S="",n=0;n<60;n++)S+='<option value="'+n+'">'+(n<10?"0"+n.toString():n)+"</option>";_.innerHTML=S,E.appendChild(_),document.body.appendChild(A)}},previousMonth:function(e){e.preventDefault(),"0"===w.value?(w.value=11,L.value=~~L.value-1):w.value=~~w.value-1,this._renderGrid(void 0,w.value,L.value)},nextMonth:function(e){e.preventDefault(),"11"===w.value?(w.value=0,L.value=1+~~L.value):w.value=1+~~w.value,this._renderGrid(void 0,w.value,L.value)},_changeMonth:function(e){this._renderGrid(void 0,e.currentTarget.value)},_changeYear:function(e){this._renderGrid(void 0,void 0,e.currentTarget.value)},_click:function(e){if(e.preventDefault(),!e.currentTarget.classList.contains("otherMonth")){elData(f,"empty",!1),this._renderGrid(e.currentTarget.textContent);h.get(f).isDateTime||this._close()}},getDate:function(e){return e=this._getElement(e),e.hasAttribute("data-value")?new Date(+elData(e,"value")):null},setDate:function(t,i){t=this._getElement(t);var n=h.get(t);elData(t,"value",i.getTime());var o,r="";n.isDateTime?n.isTimeOnly?(o=e.formatTime(i),r="H:i"):n.ignoreTimezone?(o=e.formatDateTime(i),r="Y-m-dTH:i:s"):(o=e.formatDateTime(i),r="c"):(o=e.formatDate(i),r="Y-m-d"),t.value=o,n.shadow.value=e.format(i,r),n.disableClear||n.clearButton.style.removeProperty("visibility")},getValue:function(e){e=this._getElement(e);var t=h.get(e);return t?t.shadow.value:""},clear:function(e){e=this._getElement(e);var t=h.get(e);e.removeAttribute("data-value"),e.value="",t.disableClear||t.clearButton.style.setProperty("visibility","hidden",""),t.isEmpty=!0,t.shadow.value=""},destroy:function(e){e=this._getElement(e);var t=h.get(e),i=e.parentNode;i.parentNode.insertBefore(e,i),elRemove(i),elAttr(e,"type","date"+(t.isDateTime?"time":"")),e.name=t.shadow.name,e.value=t.shadow.value,e.removeAttribute("data-value"),e.removeEventListener(WCF_CLICK_EVENT,S),elRemove(t.shadow),e.classList.remove("inputDatePicker"),e.readOnly=!1,h.delete(e)},setCloseCallback:function(e,t){e=this._getElement(e),h.get(e).onClose=t},_getElement:function(e){if("string"==typeof e&&(e=elById(e)),!(e instanceof Element&&e.classList.contains("inputDatePicker")&&h.has(e)))throw new Error("Expected a valid date picker input element or id.");return e},_maintainFocus:function(e){null!==A&&A.classList.contains("active")&&(A.contains(e.target)?d=!0:d?(f.nextElementSibling.focus(),d=!1):elBySel(".previous",A).focus())}};return window.__wcf_bc_datePicker=I,I}),define("WoltLabSuite/Core/Ui/Page/Action",["Dictionary","Language","Ui/Screen"],function(e,t,i){"use strict";var n,o,r,a=new e,l=!1,s=-1,c=window.debounce(function(){s=-1},50,!1),u=300;return{setup:function(){if(!l){l=!0,r=elCreate("div"),r.className="pageAction",n=elCreate("div"),n.className="pageActionButtons",r.appendChild(n),o=this._buildToTopButton(),r.appendChild(o),document.body.appendChild(r);var e=window.debounce(this._onScroll.bind(this),100,!1);window.addEventListener("scroll",function(){-1===s&&(s=window.pageYOffset,window.setTimeout(function(){this._onScroll(),s=window.pageYOffset}.bind(this),60)),e()}.bind(this),{passive:!0}),window.addEventListener("touchstart",function(){-1!==s&&(s=-1)},{passive:!0}),i.on("screen-sm-down",{match:function(){u=50},unmatch:function(){u=300},setup:function(){u=50}}),this._onScroll()}},_buildToTopButton:function(){var e=elCreate("a");return e.className="button buttonPrimary pageActionButtonToTop initiallyHidden jsTooltip",e.href="",elAttr(e,"title",t.get("wcf.global.scrollUp")),elAttr(e,"aria-hidden","true"),e.innerHTML='<span class="icon icon32 fa-angle-up"></span>',e.addEventListener(WCF_CLICK_EVENT,this._scrollTopTop.bind(this)),e},_onScroll:function(){if(!document.documentElement.classList.contains("disableScrolling")){var e=window.pageYOffset;if(e===s)return void c();e>=u?(o.classList.contains("initiallyHidden")&&o.classList.remove("initiallyHidden"),elAttr(o,"aria-hidden","false")):elAttr(o,"aria-hidden","true"),this._renderContainer(),-1!==s&&r.classList[e<s?"remove":"add"]("scrolledDown"),s=-1}},_scrollTopTop:function(e){e.preventDefault(),elById("top").scrollIntoView({behavior:"smooth"})},add:function(e,t,i){this.setup();var o=elCreate("div");o.className="pageActionButton",o.name=e,elAttr(o,"aria-hidden","true"),t.classList.add("button"),t.classList.add("buttonPrimary"),o.appendChild(t);var l=null;i&&void 0!==(l=a.get(i))&&(l=l.parentNode),null===l&&n.childElementCount&&(l=n.children[0]),null===l&&(l=n.firstChild),n.insertBefore(o,l),r.classList.remove("scrolledDown"),a.set(e,t),o.offsetParent,elAttr(o,"aria-hidden","false"),this._renderContainer()},has:function(e){return a.has(e)},get:function(e){return a.get(e)},remove:function(e){var t=a.get(e);if(void 0!==t){var i=t.parentNode,o=function(){try{elAttrBool(i,"aria-hidden")&&(n.removeChild(i),a.delete(e)),i.removeEventListener("transitionend",o)}catch(e){}};i.addEventListener("transitionend",o),this.hide(e)}},hide:function(e){var t=a.get(e);t&&(elAttr(t.parentNode,"aria-hidden","true"),this._renderContainer())},show:function(e){var t=a.get(e);t&&(t.parentNode.classList.contains("initiallyHidden")&&t.parentNode.classList.remove("initiallyHidden"),elAttr(t.parentNode,"aria-hidden","false"),r.classList.remove("scrolledDown"),this._renderContainer())},_renderContainer:function(){var e=!1;if(n.childElementCount)for(var t=0,i=n.childElementCount;t<i;t++)if("false"===elAttr(n.children[t],"aria-hidden")){e=!0;break}n.classList[e?"add":"remove"]("active"),e?r.classList.add("pageActionHasContextButtons"):r.classList.remove("pageActionHasContextButtons")}}}),define("WoltLabSuite/Core/Bootstrap",["favico","enquire","perfect-scrollbar","WoltLabSuite/Core/Date/Time/Relative","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Mobile","WoltLabSuite/Core/Ui/TabMenu","WoltLabSuite/Core/Ui/FlexibleMenu","Ui/Dialog","WoltLabSuite/Core/Ui/Tooltip","WoltLabSuite/Core/Language","WoltLabSuite/Core/Environment","WoltLabSuite/Core/Date/Picker","EventHandler","Core","WoltLabSuite/Core/Ui/Page/Action","Devtools","Dom/ChangeListener"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f,p,g,m,v){"use strict";return window.Favico=e,window.enquire=t,null==window.WCF&&(window.WCF={}),null==window.WCF.Language&&(window.WCF.Language={}),window.WCF.Language.get=u.get,window.WCF.Language.add=u.add,window.WCF.Language.addObject=u.addObject,window.__wcf_bc_eventHandler=f,{setup:function(e){e=p.extend({enableMobileMenu:!0},e),window.ENABLE_DEVELOPER_TOOLS&&m._internal_.enable(),d.setup(),n.setup(),h.init(),o.setup(),r.setup({enableMobileMenu:e.enableMobileMenu}),a.setup(),s.setup(),c.setup();for(var t=elBySelAll("form[method=get]"),i=0,l=t.length;i<l;i++)t[i].setAttribute("method","post");"microsoft"===d.browser()&&(window.onbeforeunload=function(){});var u=0;u=window.setInterval(function(){"function"==typeof window.jQuery&&(window.clearInterval(u),window.jQuery(function(){g.setup()}),window.jQuery.holdReady(!1))},20),this._initA11y(),v.add("WoltLabSuite/Core/Bootstrap",this._initA11y.bind(this))},_initA11y:function(){elBySelAll("nav:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")}),elBySelAll("article:not([aria-label]):not([aria-labelledby]):not([role])",void 0,function(e){elAttr(e,"role","presentation")})}}}),define("WoltLabSuite/Core/Controller/Style/Changer",["Ajax","Language","Ui/Dialog"],function(e,t,i){"use strict";return{setup:function(){elBySelAll(".jsButtonStyleChanger",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this.showDialog.bind(this))}.bind(this))},showDialog:function(e){e.preventDefault(),i.open(this)},_dialogSetup:function(){return{id:"styleChanger",options:{disableContentPadding:!0,title:t.get("wcf.style.changeStyle")},source:{data:{actionName:"getStyleChooser",className:"wcf\\data\\style\\StyleAction"},after:function(e){for(var t=elBySelAll(".styleList > li",e),i=0,n=t.length;i<n;i++){var o=t[i];o.classList.add("pointer"),o.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}}.bind(this)}}},_click:function(t){t.preventDefault(),e.apiOnce({data:{actionName:"changeStyle",className:"wcf\\data\\style\\StyleAction",objectIDs:[elData(t.currentTarget,"style-id")]},success:function(){window.location.reload()}})}}}),define("WoltLabSuite/Core/Controller/Popover",["Ajax","Dictionary","Environment","Dom/ChangeListener","Dom/Util","Ui/Alignment"],function(e,t,i,n,o,r){"use strict";var a=null,l=new t,s=new t,c=new t,u=null,d=!1,h=null,f=null,p=null,g=null,m=null,v=null,b=null,_=null;return{_setup:function(){if(null===p){p=elCreate("div"),p.className="popover forceHide",g=elCreate("div"),g.className="popoverContent",p.appendChild(g);var e=elCreate("span");e.className="elementPointer",e.appendChild(elCreate("span")),p.appendChild(e),document.body.appendChild(p),m=this._hide.bind(this),b=this._mouseEnter.bind(this),_=this._mouseLeave.bind(this),p.addEventListener("mouseenter",this._popoverMouseEnter.bind(this)),p.addEventListener("mouseleave",_),p.addEventListener("animationend",this._clearContent.bind(this)),window.addEventListener("beforeunload",function(){d=!0,null!==h&&window.clearTimeout(h),this._hide(!0)}.bind(this)),n.add("WoltLabSuite/Core/Controller/Popover",this._init.bind(this))}},init:function(e){"desktop"===i.platform()&&(e.attributeName=e.attributeName||"data-object-id",e.legacy=!0===e.legacy,this._setup(),c.has(e.identifier)||(c.set(e.identifier,{attributeName:e.attributeName,dboAction:e.dboAction,elements:e.legacy?e.className:elByClass(e.className),legacy:e.legacy,loadCallback:e.loadCallback}),this._init(e.identifier)))},_init:function(e){"string"==typeof e&&e.length?this._initElements(c.get(e),e):c.forEach(this._initElements.bind(this))},_initElements:function(e,t){for(var i=e.legacy?elBySelAll(e.elements):e.elements,n=0,r=i.length;n<r;n++){var a=i[n],c=o.identify(a);if(l.has(c))return;if(null!==a.closest(".popover"))return void l.set(c,{content:null,state:0});var u=e.legacy?c:~~a.getAttribute(e.attributeName);if(0!==u){a.addEventListener("mouseenter",b),a.addEventListener("mouseleave",_),"A"===a.nodeName&&elAttr(a,"href")&&a.addEventListener(WCF_CLICK_EVENT,m);var d=t+"-"+u;elData(a,"cache-id",d),s.set(c,{element:a,identifier:t,objectId:u}),l.has(d)||l.set(t+"-"+u,{content:null,state:0})}}},setContent:function(e,t,i){var n=e+"-"+t,r=l.get(n);if(void 0===r)throw new Error("Unable to find element for object id '"+t+"' (identifier: '"+e+"').");var c=o.createFragmentFromHtml(i);if(c.childElementCount||(c=o.createFragmentFromHtml("<p>"+i+"</p>")),r.content=c,r.state=2,a){var u=s.get(a).element;elData(u,"cache-id")===n&&this._show()}},_mouseEnter:function(e){if(!d){null!==h&&(window.clearTimeout(h),h=null);var t=o.identify(e.currentTarget);a===t&&null!==f&&(window.clearTimeout(f),f=null),u=t,h=window.setTimeout(function(){h=null,u===t&&this._show()}.bind(this),800)}},_mouseLeave:function(){u=null,null===f&&(null===v&&(v=this._hide.bind(this)),null!==f&&window.clearTimeout(f),f=window.setTimeout(v,500))},_popoverMouseEnter:function(){null!==f&&(window.clearTimeout(f),f=null)},_show:function(){null!==f&&(window.clearTimeout(f),f=null);var e=!1;p.classList.contains("active")?a!==u&&(this._hide(),e=!0):g.childElementCount&&(e=!0),e&&(p.classList.add("forceHide"),p.offsetTop,this._clearContent(),p.classList.remove("forceHide")),a=u;var t=s.get(a);if(void 0!==t){var i=l.get(elData(t.element,"cache-id"));if(2===i.state)g.appendChild(i.content),this._rebuild(a);else if(0===i.state){i.state=1;var n=c.get(t.identifier);if(n.loadCallback)n.loadCallback(t.objectId,this,t.element);else if(n.dboAction){var o=function(e){this.setContent(t.identifier,t.objectId,e.returnValues.template)}.bind(this);this.ajaxApi({actionName:"getPopover",className:n.dboAction,interfaceName:"wcf\\data\\IPopoverAction",objectIDs:[t.objectId]},o,o)}}}},_hide:function(){null!==f&&(window.clearTimeout(f),f=null),p.classList.remove("active")},_clearContent:function(){if(a&&g.childElementCount&&!p.classList.contains("active"))for(var e=l.get(elData(s.get(a).element,"cache-id"));g.childNodes.length;)e.content.appendChild(g.childNodes[0])},_rebuild:function(){p.classList.contains("active")||(p.classList.remove("forceHide"),p.classList.add("active"),r.set(p,s.get(a).element,{pointer:!0,vertical:"top"}))},_ajaxSetup:function(){return{silent:!0}},ajaxApi:function(t,i,n){if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'success'.");e.api(this,t,i,n)}}}),define("WoltLabSuite/Core/Ui/User/Ignore",["List","Dom/ChangeListener"],function(e,t){"use strict";var i=function(){};return i.prototype={init:function(){},_rebuild:function(){},_removeClass:function(){}},i}),define("WoltLabSuite/Core/Ui/Page/Header/Menu",["Environment","Language","Ui/Screen"],function(e,t,i){"use strict";var n,o,r,a,l=!1,s=0,c=[],u=[];return{init:function(){if(a=elBySel(".mainMenu .boxMenu"),null===(r=a&&a.childElementCount?a.children[0]:null))throw new Error("Unable to find the menu.");i.on("screen-lg",{enable:this._enable.bind(this),disable:this._disable.bind(this),setup:this._setup.bind(this)})},_enable:function(){l=!0,"safari"===e.browser()?window.setTimeout(this._rebuildVisibility.bind(this),1e3):(this._rebuildVisibility(),window.setTimeout(this._rebuildVisibility.bind(this),1e3))},_disable:function(){l=!1},_showNext:function(e){if(e.preventDefault(),u.length){var t=u.slice(0,3).pop();this._setMarginLeft(a.clientWidth-(t.offsetLeft+t.clientWidth)),a.lastElementChild===t&&n.classList.remove("active"),o.classList.add("active")}},_showPrevious:function(e){if(e.preventDefault(),c.length){var t=c.slice(-3)[0];this._setMarginLeft(-1*t.offsetLeft),a.firstElementChild===t&&o.classList.remove("active"),n.classList.add("active")}},_setMarginLeft:function(e){s=Math.min(s+e,0),r.style.setProperty("margin-left",s+"px","")},_rebuildVisibility:function(){if(l){c=[],u=[];var e=a.clientWidth;if(a.scrollWidth>e||s<0)for(var t,i=0,r=a.childElementCount;i<r;i++){t=a.children[i];var d=t.offsetLeft;d<0?c.push(t):d+t.clientWidth>e&&u.push(t)}o.classList[c.length?"add":"remove"]("active"),n.classList[u.length?"add":"remove"]("active")}},_setup:function(){this._setupOverflow(),this._setupA11y()},_setupOverflow:function(){n=elCreate("a"),n.className="mainMenuShowNext",n.href="#",n.innerHTML='<span class="icon icon32 fa-angle-right"></span>',elAttr(n,"aria-hidden","true"),n.addEventListener(WCF_CLICK_EVENT,this._showNext.bind(this)),a.parentNode.appendChild(n),o=elCreate("a"),o.className="mainMenuShowPrevious",o.href="#",o.innerHTML='<span class="icon icon32 fa-angle-left"></span>',elAttr(o,"aria-hidden","true"),o.addEventListener(WCF_CLICK_EVENT,this._showPrevious.bind(this)),a.parentNode.insertBefore(o,a.parentNode.firstChild);var e=this._rebuildVisibility.bind(this);r.addEventListener("transitionend",e),window.addEventListener("resize",function(){r.style.setProperty("margin-left","0px",""),s=0,e()}),this._enable()},_setupA11y:function(){elBySelAll(".boxMenuHasChildren",a,function(e){var i=!1,n=elBySel(".boxMenuLink",e);n&&(elAttr(n,"aria-haspopup",!0),elAttr(n,"aria-expanded",i));var o=elCreate("button");o.className="visuallyHidden",o.tabindex=0,elAttr(o,"role","button"),elAttr(o,"aria-label",t.get("wcf.global.button.showMenu")),e.insertBefore(o,n.nextSibling),o.addEventListener(WCF_CLICK_EVENT,function(){i=!i,elAttr(n,"aria-expanded",i),elAttr(o,"aria-label",i?t.get("wcf.global.button.hideMenu"):t.get("wcf.global.button.showMenu"))})}.bind(this))}}}),define("WoltLabSuite/Core/User",[],function(){"use strict";var e,t=!1;return{getLink:function(){return e},init:function(i,n,o){if(t)throw new Error("User has already been initialized.");Object.defineProperty(this,"userId",{value:i,writable:!1}),Object.defineProperty(this,"username",{value:n,writable:!1}),e=o,t=!0}}}),define("WoltLabSuite/Core/Ui/Message/UserConsent",["Ajax","Core","User","Dom/ChangeListener","Dom/Util"],function(e,t,i,n,o){var r=!1,a="function"==typeof window.WeakSet?new window.WeakSet:new window.Set;return{init:function(){"all"===window.sessionStorage.getItem(t.getStoragePrefix()+"user-consent")&&(r=!0),this._registerEventListeners(),n.add("WoltLabSuite/Core/Ui/Message/UserConsent",this._registerEventListeners.bind(this))},_registerEventListeners:function(){r?this._enableAll():elBySelAll(".jsButtonMessageUserConsentEnable",void 0,function(e){a.has(e)||(e.addEventListener("click",this._click.bind(this)),a.add(e))}.bind(this))},_click:function(n){n.preventDefault(),r=!0,this._enableAll(),i.userId?e.apiOnce({data:{actionName:"saveUserConsent",className:"wcf\\data\\user\\UserAction"},silent:!0}):window.sessionStorage.setItem(t.getStoragePrefix()+"user-consent","all")},_enableExternalMedia:function(e){var t=atob(elData(e,"payload"));o.insertHtml(t,e,"before"),elRemove(e)},_enableAll:function(){elBySelAll(".messageUserConsent",void 0,this._enableExternalMedia.bind(this))}}}),define("WoltLabSuite/Core/BootstrapFrontend",["WoltLabSuite/Core/BackgroundQueue","WoltLabSuite/Core/Bootstrap","WoltLabSuite/Core/Controller/Style/Changer","WoltLabSuite/Core/Controller/Popover","WoltLabSuite/Core/Ui/User/Ignore","WoltLabSuite/Core/Ui/Page/Header/Menu","WoltLabSuite/Core/Ui/Message/UserConsent"],function(e,t,i,n,o,r,a){"use strict";return{setup:function(n){n.backgroundQueue.url=WSC_API_URL+n.backgroundQueue.url.substr(WCF_PATH.length),t.setup(),r.init(),n.styleChanger&&i.setup(),n.enableUserPopover&&this._initUserPopover(),e.setUrl(n.backgroundQueue.url),(Math.random()<.1||n.backgroundQueue.force)&&e.invoke(),a.init()},_initUserPopover:function(){n.init({className:"userLink",dboAction:"wcf\\data\\user\\UserProfileAction",identifier:"com.woltlab.wcf.user"}),n.init({attributeName:"data-user-id",className:"userLink",dboAction:"wcf\\data\\user\\UserProfileAction",identifier:"com.woltlab.wcf.user.deprecated"})}}
+}),define("WoltLabSuite/Core/Clipboard",["Environment","Ui/Screen"],function(e,t){"use strict";return{copyTextToClipboard:function(i){if(navigator.clipboard)return navigator.clipboard.writeText(i);if(window.getSelection){var n=elCreate("textarea");n.contentEditable=!0,n.readOnly=!1;var o=!1;if("ios"===e.platform()){o=!0,t.scrollDisable();var r=~~(window.innerHeight/4)+window.pageYOffset;n.style.cssText="font-size: 16px; position: absolute; left: 1px; top: "+r+"px; width: 50px; height: 50px; overflow: hidden;border: 5px solid red;"}else n.style.cssText="position: absolute; left: -9999px; top: -9999px; width: 0; height: 0;";document.body.appendChild(n);try{n.value=i;var a=document.createRange();a.selectNodeContents(n);var l=window.getSelection();return l.removeAllRanges(),l.addRange(a),n.setSelectionRange(0,999999),document.execCommand("copy")?Promise.resolve():Promise.reject(new Error("execCommand('copy') failed"))}finally{elRemove(n),o&&t.scrollEnable()}}return Promise.reject(new Error("Neither navigator.clipboard, nor window.getSelection is supported."))},copyElementTextToClipboard:function(e){return this.copyTextToClipboard(e.textContent.replace(/\u200B/g,"").replace(/\u00A0/g," "))}}}),define("WoltLabSuite/Core/ColorUtil",[],function(){"use strict";var e={hsvToRgb:function(e,t,i){var n,o,r,a,l,s={r:0,g:0,b:0};if(n=Math.floor(e/60),o=e/60-n,t/=100,i/=100,r=i*(1-t),a=i*(1-t*o),l=i*(1-t*(1-o)),0==t)s.r=s.g=s.b=i;else switch(n){case 1:s.r=a,s.g=i,s.b=r;break;case 2:s.r=r,s.g=i,s.b=l;break;case 3:s.r=r,s.g=a,s.b=i;break;case 4:s.r=l,s.g=r,s.b=i;break;case 5:s.r=i,s.g=r,s.b=a;break;case 0:case 6:s.r=i,s.g=l,s.b=r}return{r:Math.round(255*s.r),g:Math.round(255*s.g),b:Math.round(255*s.b)}},rgbToHsv:function(e,t,i){var n,o,r,a,l,s;if(e/=255,t/=255,i/=255,a=Math.max(Math.max(e,t),i),l=Math.min(Math.min(e,t),i),s=a-l,n=0,a!==l){switch(a){case e:n=(t-i)/s*60;break;case t:n=60*(2+(i-e)/s);break;case i:n=60*(4+(e-t)/s)}n<0&&(n+=360)}return o=0===a?0:s/a,r=a,{h:Math.round(n),s:Math.round(100*o),v:Math.round(100*r)}},hexToRgb:function(e){if(/^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(e)){var t=e.split("");return"#"===t[0]&&t.shift(),3===t.length?{r:parseInt(t[0]+""+t[0],16),g:parseInt(t[1]+""+t[1],16),b:parseInt(t[2]+""+t[2],16)}:{r:parseInt(t[0]+""+t[1],16),g:parseInt(t[2]+""+t[3],16),b:parseInt(t[4]+""+t[5],16)}}return Number.NaN},rgbToHex:function(e,t,i){var n="0123456789ABCDEF";return void 0===t&&e.toString().match(/^rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?[0-9.]+)?\)$/)&&(e=RegExp.$1,t=RegExp.$2,i=RegExp.$3),n.charAt((e-e%16)/16)+""+n.charAt(e%16)+n.charAt((t-t%16)/16)+n.charAt(t%16)+n.charAt((i-i%16)/16)+n.charAt(i%16)}};return window.__wcf_bc_colorUtil=e,e}),define("WoltLabSuite/Core/FileUtil",["Dictionary","StringUtil"],function(e,t){"use strict";var i=e.fromObject({zip:"archive",rar:"archive",tar:"archive",gz:"archive",mp3:"audio",ogg:"audio",wav:"audio",php:"code",html:"code",htm:"code",tpl:"code",js:"code",xls:"excel",ods:"excel",xlsx:"excel",gif:"image",jpg:"image",jpeg:"image",png:"image",bmp:"image",webp:"image",avi:"video",wmv:"video",mov:"video",mp4:"video",mpg:"video",mpeg:"video",flv:"video",pdf:"pdf",ppt:"powerpoint",pptx:"powerpoint",txt:"text",doc:"word",docx:"word",odt:"word"}),n=e.fromObject({"application/zip":"zip","application/x-zip-compressed":"zip","application/rar":"rar","application/vnd.rar":"rar","application/x-rar-compressed":"rar","application/x-tar":"tar","application/x-gzip":"gz","application/gzip":"gz","audio/mpeg":"mp3","audio/mp3":"mp3","audio/ogg":"ogg","audio/x-wav":"wav","application/x-php":"php","text/html":"html","application/javascript":"js","application/vnd.ms-excel":"xls","application/vnd.oasis.opendocument.spreadsheet":"ods","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","image/gif":"gif","image/jpeg":"jpg","image/png":"png","image/x-ms-bmp":"bmp","image/bmp":"bmp","image/webp":"webp","video/x-msvideo":"avi","video/x-ms-wmv":"wmv","video/quicktime":"mov","video/mp4":"mp4","video/mpeg":"mpg","video/x-flv":"flv","application/pdf":"pdf","application/vnd.ms-powerpoint":"ppt","application/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","text/plain":"txt","application/msword":"doc","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application/vnd.oasis.opendocument.text":"odt","public.jpeg":"jpeg","public.png":"png","com.compuserve.gif":"gif","org.webmproject.webp":"webp"});return{formatFilesize:function(e,i){void 0===i&&(i=2);var n="Byte";return e>=1e3&&(e/=1e3,n="kB"),e>=1e3&&(e/=1e3,n="MB"),e>=1e3&&(e/=1e3,n="GB"),e>=1e3&&(e/=1e3,n="TB"),t.formatNumeric(e,-i)+" "+n},getIconNameByFilename:function(e){var t=e.lastIndexOf(".");if(!1!==t){var n=e.substr(t+1);if(i.has(n))return i.get(n)}return""},getExtensionByMimeType:function(e){return n.has(e)?"."+n.get(e):""},blobToFile:function(e,t){var i=this.getExtensionByMimeType(e.type),n=window.File;try{new n([],"ie11-check")}catch(e){n=function(e,t,i){var n=Blob.call(this,e,i);return n.name=t,n.lastModifiedDate=new Date,n},n.prototype=Object.create(window.File.prototype)}return new n([e],t+i,{type:e.type})}}}),define("WoltLabSuite/Core/Permission",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if("boolean"!=typeof i)throw new TypeError("Permission value has to be boolean.");t.set(e,i)},addObject:function(e){for(var t in e)objOwns(e,t)&&this.add(t,e[t])},get:function(e){return!!t.has(e)&&t.get(e)}}});var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){function t(e,t,i,n){this.type=e,this.content=t,this.alias=i,this.length=0|(n||"").length}function i(e,n,a,l,s,c){for(var d in a)if(a.hasOwnProperty(d)&&a[d]){var h=a[d];h=Array.isArray(h)?h:[h];for(var f=0;f<h.length;++f){if(c&&c.cause==d+","+f)return;var p=h[f],g=p.inside,m=!!p.lookbehind,v=!!p.greedy,b=0,_=p.alias;if(v&&!p.pattern.global){var w=p.pattern.toString().match(/[imsuy]*$/)[0];p.pattern=RegExp(p.pattern.source,w+"g")}for(var y=p.pattern||p,C=l.next,E=s;C!==n.tail&&!(c&&E>=c.reach);E+=C.value.length,C=C.next){var L=C.value;if(n.length>e.length)return;if(!(L instanceof t)){var A=1;if(v&&C!=n.tail.prev){y.lastIndex=E;var S=y.exec(e);if(!S)break;var x=S.index+(m&&S[1]?S[1].length:0),I=S.index+S[0].length,D=E;for(D+=C.value.length;x>=D;)C=C.next,D+=C.value.length;if(D-=C.value.length,E=D,C.value instanceof t)continue;for(var T=C;T!==n.tail&&(D<I||"string"==typeof T.value);T=T.next)A++,D+=T.value.length;A--,L=e.slice(E,D),S.index-=E}else{y.lastIndex=0;var S=y.exec(L)}if(S){m&&(b=S[1]?S[1].length:0);var x=S.index+b,k=S[0].slice(b),I=x+k.length,B=L.slice(0,x),M=L.slice(I),N=E+L.length;c&&N>c.reach&&(c.reach=N);var U=C.prev;B&&(U=o(n,U,B),E+=B.length),r(n,U,A);var P=new t(d,g?u.tokenize(k,g):k,_,k);C=o(n,U,P),M&&o(n,C,M),A>1&&i(e,n,a,C.prev,E,{cause:d+","+f,reach:N})}}}}}}function n(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function o(e,t,i){var n=t.next,o={value:i,prev:t,next:n};return t.next=o,n.prev=o,e.length++,o}function r(e,t,i){for(var n=t.next,o=0;o<i&&n!==e.tail;o++)n=n.next;t.next=n,n.prev=t,e.length-=o}function a(e){for(var t=[],i=e.head.next;i!==e.tail;)t.push(i.value),i=i.next;return t}function l(){u.manual||u.highlightAll()}var s=/\blang(?:uage)?-([\w-]+)\b/i,c=0,u={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(i){return i instanceof t?new t(i.type,e(i.content),i.alias):Array.isArray(i)?i.map(e):i.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++c}),e.__id},clone:function e(t,i){i=i||{};var n,o;switch(u.util.type(t)){case"Object":if(o=u.util.objId(t),i[o])return i[o];n={},i[o]=n;for(var r in t)t.hasOwnProperty(r)&&(n[r]=e(t[r],i));return n;case"Array":return o=u.util.objId(t),i[o]?i[o]:(n=[],i[o]=n,t.forEach(function(t,o){n[o]=e(t,i)}),n);default:return t}},getLanguage:function(e){for(;e&&!s.test(e.className);)e=e.parentElement;return e?(e.className.match(s)||[,"none"])[1].toLowerCase():"none"},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(n){var e=(/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(n.stack)||[])[1];if(e){var t=document.getElementsByTagName("script");for(var i in t)if(t[i].src==e)return t[i]}return null}},isActive:function(e,t,i){for(var n="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(n))return!1;e=e.parentElement}return!!i}},languages:{extend:function(e,t){var i=u.util.clone(u.languages[e]);for(var n in t)i[n]=t[n];return i},insertBefore:function(e,t,i,n){n=n||u.languages;var o=n[e],r={};for(var a in o)if(o.hasOwnProperty(a)){if(a==t)for(var l in i)i.hasOwnProperty(l)&&(r[l]=i[l]);i.hasOwnProperty(a)||(r[a]=o[a])}var s=n[e];return n[e]=r,u.languages.DFS(u.languages,function(t,i){i===s&&t!=e&&(this[t]=r)}),r},DFS:function e(t,i,n,o){o=o||{};var r=u.util.objId;for(var a in t)if(t.hasOwnProperty(a)){i.call(t,a,t[a],n||a);var l=t[a],s=u.util.type(l);"Object"!==s||o[r(l)]?"Array"!==s||o[r(l)]||(o[r(l)]=!0,e(l,i,a,o)):(o[r(l)]=!0,e(l,i,null,o))}}},plugins:{},highlightAll:function(e,t){u.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,i){var n={callback:i,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};u.hooks.run("before-highlightall",n),n.elements=Array.prototype.slice.apply(n.container.querySelectorAll(n.selector)),u.hooks.run("before-all-elements-highlight",n);for(var o,r=0;o=n.elements[r++];)u.highlightElement(o,!0===t,n.callback)},highlightElement:function(t,i,n){function o(e){d.highlightedCode=e,u.hooks.run("before-insert",d),d.element.innerHTML=d.highlightedCode,u.hooks.run("after-highlight",d),u.hooks.run("complete",d),n&&n.call(d.element)}var r=u.util.getLanguage(t),a=u.languages[r];t.className=t.className.replace(s,"").replace(/\s+/g," ")+" language-"+r;var l=t.parentElement;l&&"pre"===l.nodeName.toLowerCase()&&(l.className=l.className.replace(s,"").replace(/\s+/g," ")+" language-"+r);var c=t.textContent,d={element:t,language:r,grammar:a,code:c};if(u.hooks.run("before-sanity-check",d),!d.code)return u.hooks.run("complete",d),void(n&&n.call(d.element));if(u.hooks.run("before-highlight",d),!d.grammar)return void o(u.util.encode(d.code));if(i&&e.Worker){var h=new Worker(u.filename);h.onmessage=function(e){o(e.data)},h.postMessage(JSON.stringify({language:d.language,code:d.code,immediateClose:!0}))}else o(u.highlight(d.code,d.grammar,d.language))},highlight:function(e,i,n){var o={code:e,grammar:i,language:n};return u.hooks.run("before-tokenize",o),o.tokens=u.tokenize(o.code,o.grammar),u.hooks.run("after-tokenize",o),t.stringify(u.util.encode(o.tokens),o.language)},tokenize:function(e,t){var r=t.rest;if(r){for(var l in r)t[l]=r[l];delete t.rest}var s=new n;return o(s,s.head,e),i(e,s,t,s.head,0),a(s)},hooks:{all:{},add:function(e,t){var i=u.hooks.all;i[e]=i[e]||[],i[e].push(t)},run:function(e,t){var i=u.hooks.all[e];if(i&&i.length)for(var n,o=0;n=i[o++];)n(t)}},Token:t};if(e.Prism=u,t.stringify=function e(t,i){if("string"==typeof t)return t;if(Array.isArray(t)){var n="";return t.forEach(function(t){n+=e(t,i)}),n}var o={type:t.type,content:e(t.content,i),tag:"span",classes:["token",t.type],attributes:{},language:i},r=t.alias;r&&(Array.isArray(r)?Array.prototype.push.apply(o.classes,r):o.classes.push(r)),u.hooks.run("wrap",o);var a="";for(var l in o.attributes)a+=" "+l+'="'+(o.attributes[l]||"").replace(/"/g,"&quot;")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+a+">"+o.content+"</"+o.tag+">"},!e.document)return e.addEventListener?(u.disableWorkerMessageHandler||e.addEventListener("message",function(t){var i=JSON.parse(t.data),n=i.language,o=i.code,r=i.immediateClose;e.postMessage(u.highlight(o,u.languages[n],n)),r&&e.close()},!1),u):u;var d=u.util.currentScript();if(d&&(u.filename=d.src,d.hasAttribute("data-manual")&&(u.manual=!0)),!u.manual){var h=document.readyState;"loading"===h||"interactive"===h&&d&&d.defer?document.addEventListener("DOMContentLoaded",l):window.requestAnimationFrame?window.requestAnimationFrame(l):window.setTimeout(l,16)}return u}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),define("prism/prism",function(){}),window.Prism=window.Prism||{},window.Prism.manual=!0,define("WoltLabSuite/Core/Prism",["prism/prism"],function(){return Prism.wscSplitIntoLines=function(e){function t(){var e=elCreate("span");return elData(e,"number",a++),r.appendChild(e),e}var i,n,o,r=document.createDocumentFragment(),a=1;for(i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT,function(){return NodeFilter.FILTER_ACCEPT},!1),o=t();n=i.nextNode();)n.data.split(/\r?\n/).forEach(function(i,r){var a,l;for(r>=1&&(o.appendChild(document.createTextNode("\n")),o=t()),a=document.createTextNode(i),l=n.parentNode;l!==e;){var s=l.cloneNode(!1);s.appendChild(a),a=s,l=l.parentNode}o.appendChild(a)});return r},Prism}),define("WoltLabSuite/Core/Upload",["AjaxRequest","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={_createButton:function(){},_createFileElement:function(){},_createFileElements:function(){},_failure:function(){},_getParameters:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){},_success:function(){},_upload:function(){},_uploadFiles:function(){}},a}),define("WoltLabSuite/Core/Ajax/Jsonp",["Core"],function(e){"use strict";return{send:function(t,i,n,o){if(t="string"==typeof t?t.trim():"",0===t.length)throw new Error("Expected a non-empty string for parameter 'url'.");if("function"!=typeof i)throw new TypeError("Expected a valid callback function for parameter 'success'.");o=e.extend({parameterName:"callback",timeout:10},o||{});var r,a="wcf_jsonp_"+e.getUuid().replace(/-/g,"").substr(0,8),l=window.setTimeout(function(){"function"==typeof n&&n(),window[a]=void 0,elRemove(r)},1e3*(~~o.timeout||10));window[a]=function(){window.clearTimeout(l),i.apply(null,arguments),window[a]=void 0,elRemove(r)},t+=-1===t.indexOf("?")?"?":"&",t+=o.parameterName+"="+a,r=elCreate("script"),r.async=!0,elAttr(r,"src",t),document.head.appendChild(r)}}}),define("WoltLabSuite/Core/Ui/Notification",["Language"],function(e){"use strict";var t=!1,i=null,n=null,o=null,r=null,a=null;return{show:function(l,s,c){t||(this._init(),i="function"==typeof s?s:null,n.className=c||"success",n.textContent=e.get(l||"wcf.global.success"),t=!0,o.classList.add("active"),r=setTimeout(a,2e3))},_init:function(){null===o&&(a=this._hide.bind(this),o=elCreate("div"),o.id="systemNotification",n=elCreate("p"),n.addEventListener(WCF_CLICK_EVENT,a),o.appendChild(n),document.body.appendChild(o))},_hide:function(){clearTimeout(r),o.classList.remove("active"),null!==i&&i(),t=!1}}}),define("prism/prism-meta",[],function(){return{markup:{title:"Markup",file:"markup"},html:{title:"HTML",file:"markup"},xml:{title:"XML",file:"markup"},svg:{title:"SVG",file:"markup"},mathml:{title:"MathML",file:"markup"},ssml:{title:"SSML",file:"markup"},atom:{title:"Atom",file:"markup"},rss:{title:"RSS",file:"markup"},css:{title:"CSS",file:"css"},clike:{title:"C-like",file:"clike"},javascript:{title:"JavaScript",file:"javascript"},abap:{title:"ABAP",file:"abap"},abnf:{title:"ABNF",file:"abnf"},actionscript:{title:"ActionScript",file:"actionscript"},ada:{title:"Ada",file:"ada"},agda:{title:"Agda",file:"agda"},al:{title:"AL",file:"al"},antlr4:{title:"ANTLR4",file:"antlr4"},apacheconf:{title:"Apache Configuration",file:"apacheconf"},apl:{title:"APL",file:"apl"},applescript:{title:"AppleScript",file:"applescript"},aql:{title:"AQL",file:"aql"},arduino:{title:"Arduino",file:"arduino"},arff:{title:"ARFF",file:"arff"},asciidoc:{title:"AsciiDoc",file:"asciidoc"},aspnet:{title:"ASP.NET (C#)",file:"aspnet"},asm6502:{title:"6502 Assembly",file:"asm6502"},autohotkey:{title:"AutoHotkey",file:"autohotkey"},autoit:{title:"AutoIt",file:"autoit"},bash:{title:"Bash",file:"bash"},basic:{title:"BASIC",file:"basic"},batch:{title:"Batch",file:"batch"},bbcode:{title:"BBcode",file:"bbcode"},bison:{title:"Bison",file:"bison"},bnf:{title:"BNF",file:"bnf"},brainfuck:{title:"Brainfuck",file:"brainfuck"},brightscript:{title:"BrightScript",file:"brightscript"},bro:{title:"Bro",file:"bro"},c:{title:"C",file:"c"},csharp:{title:"C#",file:"csharp"},cpp:{title:"C++",file:"cpp"},cil:{title:"CIL",file:"cil"},clojure:{title:"Clojure",file:"clojure"},cmake:{title:"CMake",file:"cmake"},coffeescript:{title:"CoffeeScript",file:"coffeescript"},concurnas:{title:"Concurnas",file:"concurnas"},csp:{title:"Content-Security-Policy",file:"csp"},crystal:{title:"Crystal",file:"crystal"},"css-extras":{title:"CSS Extras",file:"css-extras"},cypher:{title:"Cypher",file:"cypher"},d:{title:"D",file:"d"},dart:{title:"Dart",file:"dart"},dax:{title:"DAX",file:"dax"},dhall:{title:"Dhall",file:"dhall"},diff:{title:"Diff",file:"diff"},django:{title:"Django/Jinja2",file:"django"},"dns-zone-file":{title:"DNS zone file",file:"dns-zone-file"},docker:{title:"Docker",file:"docker"},ebnf:{title:"EBNF",file:"ebnf"},editorconfig:{title:"EditorConfig",file:"editorconfig"},eiffel:{title:"Eiffel",file:"eiffel"},ejs:{title:"EJS",file:"ejs"},elixir:{title:"Elixir",file:"elixir"},elm:{title:"Elm",file:"elm"},etlua:{title:"Embedded Lua templating",file:"etlua"},erb:{title:"ERB",file:"erb"},erlang:{title:"Erlang",file:"erlang"},"excel-formula":{title:"Excel Formula",file:"excel-formula"},fsharp:{title:"F#",file:"fsharp"},factor:{title:"Factor",file:"factor"},"firestore-security-rules":{title:"Firestore security rules",file:"firestore-security-rules"},flow:{title:"Flow",file:"flow"},fortran:{title:"Fortran",file:"fortran"},ftl:{title:"FreeMarker Template Language",file:"ftl"},gml:{title:"GameMaker Language",file:"gml"},gcode:{title:"G-code",file:"gcode"},gdscript:{title:"GDScript",file:"gdscript"},gedcom:{title:"GEDCOM",file:"gedcom"},gherkin:{title:"Gherkin",file:"gherkin"},git:{title:"Git",file:"git"},glsl:{title:"GLSL",file:"glsl"},go:{title:"Go",file:"go"},graphql:{title:"GraphQL",file:"graphql"},groovy:{title:"Groovy",file:"groovy"},haml:{title:"Haml",file:"haml"},handlebars:{title:"Handlebars",file:"handlebars"},haskell:{title:"Haskell",file:"haskell"},haxe:{title:"Haxe",file:"haxe"},hcl:{title:"HCL",file:"hcl"},hlsl:{title:"HLSL",file:"hlsl"},http:{title:"HTTP",file:"http"},hpkp:{title:"HTTP Public-Key-Pins",file:"hpkp"},hsts:{title:"HTTP Strict-Transport-Security",file:"hsts"},ichigojam:{title:"IchigoJam",file:"ichigojam"},icon:{title:"Icon",file:"icon"},ignore:{title:".ignore",file:"ignore"},gitignore:{title:".gitignore",file:"ignore"},hgignore:{title:".hgignore",file:"ignore"},npmignore:{title:".npmignore",file:"ignore"},inform7:{title:"Inform 7",file:"inform7"},ini:{title:"Ini",file:"ini"},io:{title:"Io",file:"io"},j:{title:"J",file:"j"},java:{title:"Java",file:"java"},javadoc:{title:"JavaDoc",file:"javadoc"},javadoclike:{title:"JavaDoc-like",file:"javadoclike"},javastacktrace:{title:"Java stack trace",file:"javastacktrace"},jolie:{title:"Jolie",file:"jolie"},jq:{title:"JQ",file:"jq"},jsdoc:{title:"JSDoc",file:"jsdoc"},"js-extras":{title:"JS Extras",file:"js-extras"},json:{title:"JSON",file:"json"},json5:{title:"JSON5",file:"json5"},jsonp:{title:"JSONP",file:"jsonp"},jsstacktrace:{title:"JS stack trace",file:"jsstacktrace"},"js-templates":{title:"JS Templates",file:"js-templates"},julia:{title:"Julia",file:"julia"},keyman:{title:"Keyman",file:"keyman"},kotlin:{title:"Kotlin",file:"kotlin"},kts:{title:"Kotlin Script",file:"kotlin"},latex:{title:"LaTeX",file:"latex"},tex:{title:"TeX",file:"latex"},context:{title:"ConTeXt",file:"latex"},latte:{title:"Latte",file:"latte"},less:{title:"Less",file:"less"},lilypond:{title:"LilyPond",file:"lilypond"},liquid:{title:"Liquid",file:"liquid"},lisp:{title:"Lisp",file:"lisp"},livescript:{title:"LiveScript",file:"livescript"},llvm:{title:"LLVM IR",file:"llvm"},lolcode:{title:"LOLCODE",file:"lolcode"},lua:{title:"Lua",file:"lua"},makefile:{title:"Makefile",file:"makefile"},markdown:{title:"Markdown",file:"markdown"},"markup-templating":{title:"Markup templating",file:"markup-templating"},matlab:{title:"MATLAB",file:"matlab"},mel:{title:"MEL",file:"mel"},mizar:{title:"Mizar",file:"mizar"},monkey:{title:"Monkey",file:"monkey"},moonscript:{title:"MoonScript",file:"moonscript"},n1ql:{title:"N1QL",file:"n1ql"},n4js:{title:"N4JS",file:"n4js"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",file:"nand2tetris-hdl"},nasm:{title:"NASM",file:"nasm"},neon:{title:"NEON",file:"neon"},nginx:{title:"nginx",file:"nginx"},nim:{title:"Nim",file:"nim"},nix:{title:"Nix",file:"nix"},nsis:{title:"NSIS",file:"nsis"},objectivec:{title:"Objective-C",file:"objectivec"},ocaml:{title:"OCaml",file:"ocaml"},opencl:{title:"OpenCL",file:"opencl"},oz:{title:"Oz",file:"oz"},parigp:{title:"PARI/GP",file:"parigp"},parser:{title:"Parser",file:"parser"},pascal:{title:"Pascal",file:"pascal"},pascaligo:{title:"Pascaligo",file:"pascaligo"},pcaxis:{title:"PC-Axis",file:"pcaxis"},peoplecode:{title:"PeopleCode",file:"peoplecode"},perl:{title:"Perl",file:"perl"},php:{title:"PHP",file:"php"},phpdoc:{title:"PHPDoc",file:"phpdoc"},"php-extras":{title:"PHP Extras",file:"php-extras"},plsql:{title:"PL/SQL",file:"plsql"},powerquery:{title:"PowerQuery",file:"powerquery"},powershell:{title:"PowerShell",file:"powershell"},processing:{title:"Processing",file:"processing"},prolog:{title:"Prolog",file:"prolog"},properties:{title:".properties",file:"properties"},protobuf:{title:"Protocol Buffers",file:"protobuf"},pug:{title:"Pug",file:"pug"},puppet:{title:"Puppet",file:"puppet"},pure:{title:"Pure",file:"pure"},purebasic:{title:"PureBasic",file:"purebasic"},python:{title:"Python",file:"python"},q:{title:"Q (kdb+ database)",file:"q"},qml:{title:"QML",file:"qml"},qore:{title:"Qore",file:"qore"},r:{title:"R",file:"r"},racket:{title:"Racket",file:"racket"},jsx:{title:"React JSX",file:"jsx"},tsx:{title:"React TSX",file:"tsx"},reason:{title:"Reason",file:"reason"},regex:{title:"Regex",file:"regex"},renpy:{title:"Ren'py",file:"renpy"},rest:{title:"reST (reStructuredText)",file:"rest"},rip:{title:"Rip",file:"rip"},roboconf:{title:"Roboconf",file:"roboconf"},robotframework:{title:"Robot Framework",file:"robotframework"},ruby:{title:"Ruby",file:"ruby"},rust:{title:"Rust",file:"rust"},sas:{title:"SAS",file:"sas"},sass:{title:"Sass (Sass)",file:"sass"},scss:{title:"Sass (Scss)",file:"scss"},scala:{title:"Scala",file:"scala"},scheme:{title:"Scheme",file:"scheme"},"shell-session":{title:"Shell session",file:"shell-session"},smali:{title:"Smali",file:"smali"},smalltalk:{title:"Smalltalk",file:"smalltalk"},smarty:{title:"Smarty",file:"smarty"},solidity:{title:"Solidity (Ethereum)",file:"solidity"},"solution-file":{title:"Solution file",file:"solution-file"},soy:{title:"Soy (Closure Template)",file:"soy"},sparql:{title:"SPARQL",file:"sparql"},"splunk-spl":{title:"Splunk SPL",file:"splunk-spl"},sqf:{title:"SQF: Status Quo Function (Arma 3)",file:"sqf"},sql:{title:"SQL",file:"sql"},iecst:{title:"Structured Text (IEC 61131-3)",file:"iecst"},stylus:{title:"Stylus",file:"stylus"},swift:{title:"Swift",file:"swift"},"t4-templating":{title:"T4 templating",file:"t4-templating"},"t4-cs":{title:"T4 Text Templates (C#)",file:"t4-cs"},"t4-vb":{title:"T4 Text Templates (VB)",file:"t4-vb"},tap:{title:"TAP",file:"tap"},tcl:{title:"Tcl",file:"tcl"},tt2:{title:"Template Toolkit 2",file:"tt2"},textile:{title:"Textile",file:"textile"},toml:{title:"TOML",file:"toml"},turtle:{title:"Turtle",file:"turtle"},twig:{title:"Twig",file:"twig"},typescript:{title:"TypeScript",file:"typescript"},unrealscript:{title:"UnrealScript",file:"unrealscript"},vala:{title:"Vala",file:"vala"},vbnet:{title:"VB.Net",file:"vbnet"},velocity:{title:"Velocity",file:"velocity"},verilog:{title:"Verilog",file:"verilog"},vhdl:{title:"VHDL",file:"vhdl"},vim:{title:"vim",file:"vim"},"visual-basic":{title:"Visual Basic",file:"visual-basic"},vba:{title:"VBA",file:"visual-basic"},warpscript:{title:"WarpScript",file:"warpscript"},wasm:{title:"WebAssembly",file:"wasm"},wiki:{title:"Wiki markup",file:"wiki"},xeora:{title:"Xeora",file:"xeora"},"xml-doc":{title:"XML doc (.net)",file:"xml-doc"},xojo:{title:"Xojo (REALbasic)",file:"xojo"},xquery:{title:"XQuery",file:"xquery"},yaml:{title:"YAML",file:"yaml"},yang:{title:"YANG",file:"yang"},zig:{title:"Zig",file:"zig"}}}),define("WoltLabSuite/Core/Bbcode/Code",["Language","WoltLabSuite/Core/Ui/Notification","WoltLabSuite/Core/Clipboard","WoltLabSuite/Core/Prism","prism/prism-meta"],function(e,t,i,n,o){"use strict";function r(e){var t;this.container=e,this.codeContainer=elBySel(".codeBoxCode > code",this.container),this.language=null;for(var i=0;i<this.codeContainer.classList.length;i++)(t=this.codeContainer.classList[i].match(/language-(.*)/))&&(this.language=t[1])}var a=function(e){return function(){var t=arguments;return new Promise(function(i,n){var o=function(){try{i(e.apply(null,t))}catch(e){n(e)}};window.requestIdleCallback?window.requestIdleCallback(o,{timeout:5e3}):setTimeout(o,0)})}};return r.processAll=function(){elBySelAll(".codeBox:not([data-processed])",document,function(e){elData(e,"processed","1");var t=new r(e);t.language&&t.highlight(),t.createCopyButton()})},r.prototype={createCopyButton:function(){var n=elBySel(".codeBoxHeader",this.container),o=elCreate("span");o.className="icon icon24 fa-files-o pointer jsTooltip",o.setAttribute("title",e.get("wcf.message.bbcode.code.copy")),o.addEventListener("click",function(){i.copyElementTextToClipboard(this.codeContainer).then(function(){t.show(e.get("wcf.message.bbcode.code.copy.success"))})}.bind(this)),n.appendChild(o)},highlight:function(){return this.language?o[this.language]?(this.container.classList.add("highlighting"),require(["prism/components/prism-"+o[this.language].file]).then(a(function(){var e=n.languages[this.language];if(!e)throw new Error("Invalid language "+language+" given.");var t=elCreate("div");return t.innerHTML=n.highlight(this.codeContainer.textContent,e,this.language),t}.bind(this))).then(a(function(e){var t=n.wscSplitIntoLines(e),i=elBySelAll("[data-number]",t),o=elBySelAll(".codeBoxLine > span",this.codeContainer);if(i.length!==o.length)throw new Error("Unreachable");for(var r=[],l=0,s=i.length;l<s;l+=50)r.push(a(function(e){for(var t=Math.min(e+50,s),n=e;n<t;n++)o[n].parentNode.replaceChild(i[n],o[n])})(l));return Promise.all(r)}.bind(this))).then(function(){this.container.classList.remove("highlighting"),this.container.classList.add("highlighted")}.bind(this))):Promise.reject(new Error("Unknown language "+this.language)):Promise.reject(new Error("No language detected"))}},r}),define("WoltLabSuite/Core/Bbcode/Collapsible",[],function(){"use strict";var e=elByClass("jsCollapsibleBbcode");return{observe:function(){for(var t,i,n;e.length;)t=e[0],i=[],elBySelAll(".toggleButton:not(.jsToggleButtonEnabled)",t,function(e){e.closest(".jsCollapsibleBbcode")===t&&i.push(e)}),n=elBySel(".collapsibleBbcodeOverflow",t)||t,i.length>0&&function(e,t){var i=function(i){if(e.classList.toggle("collapsed")){if(t.forEach(function(e){e.classList.contains("icon")?(e.classList.remove("fa-compress"),e.classList.add("fa-expand"),e.title=elData(e,"title-expand")):e.textContent=elData(e,"title-expand")}),i instanceof Event){var n=e.getBoundingClientRect().top;if(n<0){var o=window.pageYOffset+(n-100);o<0&&(o=0),window.scrollTo(window.pageXOffset,o)}}}else t.forEach(function(e){e.classList.contains("icon")?(e.classList.add("fa-compress"),e.classList.remove("fa-expand"),e.title=elData(e,"title-collapse")):e.textContent=elData(e,"title-collapse")})};t.forEach(function(e){e.classList.add("jsToggleButtonEnabled"),e.addEventListener(WCF_CLICK_EVENT,i)}),0!==n.scrollTop&&(n.scrollTop=0,i()),n.addEventListener("scroll",function(){n.scrollTop=0,e.classList.contains("collapsed")&&i()})}(t,i),t.classList.remove("jsCollapsibleBbcode")}}}),define("WoltLabSuite/Core/Bbcode/Spoiler",["Language"],function(e){"use strict";var t=elByClass("jsSpoilerBox");return{observe:function(){for(var e,i;t.length;)e=t[0],e.classList.remove("jsSpoilerBox"),i=elBySel(".jsSpoilerToggle",e),e=i.parentNode.nextElementSibling,i.addEventListener(WCF_CLICK_EVENT,this._onClick.bind(this,e,i))},_onClick:function(t,i,n){n.preventDefault(),i.classList.toggle("active");var o=i.classList.contains("active");window[o?"elShow":"elHide"](t),elAttr(i,"aria-expanded",o),elAttr(t,"aria-hidden",!o),elDataBool(i,"has-custom-label")||(i.textContent=e.get(i.classList.contains("active")?"wcf.bbcode.spoiler.hide":"wcf.bbcode.spoiler.show"))}}}),define("WoltLabSuite/Core/Controller/Captcha",["Dictionary"],function(e){"use strict";var t=new e;return{add:function(e,i){if(t.has(e))throw new Error("Captcha with id '"+e+"' is already registered.");if("function"!=typeof i)throw new TypeError("Expected a valid callback for parameter 'callback'.");t.set(e,i)},delete:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");t.delete(e)},has:function(e){return t.has(e)},getData:function(e){if(!t.has(e))throw new Error("Unknown captcha with id '"+e+"'.");return t.get(e)()}}}),define("WoltLabSuite/Core/Controller/Clipboard",["Ajax","Core","Dictionary","EventHandler","Language","List","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Confirmation","Ui/SimpleDropdown","WoltLabSuite/Core/Ui/Page/Action","Ui/Screen"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";return{setup:function(){},reload:function(){},_initContainers:function(){},_loadMarkedItems:function(){},_markAll:function(){},_mark:function(){},_saveState:function(){},_executeAction:function(){},_executeProxyAction:function(){},_unmarkAll:function(){},_ajaxSetup:function(){},_ajaxSuccess:function(){},_rebuildMarkings:function(){},hideEditor:function(){},showEditor:function(){},unmark:function(){}}}),define("WoltLabSuite/Core/Image/ExifUtil",[],function(){"use strict";function e(e){return e===i||e===n||e===o}var t={SOI:216,APP0:224,APP1:225,APP2:226,APP3:227,APP4:228,APP5:229,APP6:230,APP7:231,APP8:232,APP9:233,APP10:234,APP11:235,APP12:236,APP13:237,APP14:238,COM:254},i="Exif",n="http://ns.adobe.com/xap/1.0/",o="http://ns.adobe.com/xmp/extension/";return{getExifBytesFromJpeg:function(i){return new Promise(function(n,o){if(!(i instanceof Blob||i instanceof File))return o(new TypeError("The argument must be a Blob or a File"));var r=new FileReader;r.addEventListener("error",function(){r.abort(),o(r.error)}),r.addEventListener("load",function(){var i=r.result,a=new Uint8Array(i),l=new Uint8Array;if(255!==a[0]&&a[1]!==t.SOI)return o(new Error("Not a JPEG"));for(var s=2;s<a.length&&255===a[s];){var c=2+(a[s+2]<<8|a[s+3]);if(a[s+1]===t.APP1){for(var u="",d=s+4;0!==a[d]&&d<a.length;d++)u+=String.fromCharCode(a[d]);if(e(u)){var h=Array.prototype.slice.call(a,s,c+s),f=new Uint8Array(l.length+h.length);f.set(l),f.set(h,l.length),l=f}}s+=c}n(l)}),r.readAsArrayBuffer(i)})},removeExifData:function(i){return new Promise(function(n,o){if(!(i instanceof Blob||i instanceof File))return o(new TypeError("The argument must be a Blob or a File"));var r=new FileReader;r.addEventListener("error",function(){r.abort(),o(r.error)}),r.addEventListener("load",function(){var a=r.result,l=new Uint8Array(a);if(255!==l[0]&&l[1]!==t.SOI)return o(new Error("Not a JPEG"));for(var s=2;s<l.length&&255===l[s];){var c=2+(l[s+2]<<8|l[s+3]);if(l[s+1]===t.APP1){for(var u="",d=s+4;0!==l[d]&&d<l.length;d++)u+=String.fromCharCode(l[d]);if(e(u)){var h=Array.prototype.slice.call(l,0,s),f=Array.prototype.slice.call(l,s+c);l=new Uint8Array(h.length+f.length),l.set(h,0),l.set(f,h.length)}else s+=c
+}else s+=c}n(new Blob([l],{type:i.type}))}),r.readAsArrayBuffer(i)})},setExifData:function(e,i){return this.removeExifData(e).then(function(e){return new Promise(function(n){var o=new FileReader;o.addEventListener("error",function(){o.abort(),reject(o.error)}),o.addEventListener("load",function(){var r=o.result,a=new Uint8Array(r),l=2;255===a[2]&&a[3]===t.APP0&&(l+=2+(a[4]<<8|a[5]));var s=Array.prototype.slice.call(a,0,l),c=Array.prototype.slice.call(a,l);a=new Uint8Array(s.length+i.length+c.length),a.set(s),a.set(i,l),a.set(c,l+i.length),n(new Blob([a],{type:e.type}))}),o.readAsArrayBuffer(e)})})}}}),define("WoltLabSuite/Core/Image/ImageUtil",[],function(){"use strict";return{containsTransparentPixels:function(e){for(var t=e.getContext("2d").getImageData(0,0,e.width,e.height),i=3,n=t.data.length;i<n;i+=4)if(255!==t.data[i])return!0;return!1}}}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("Pica",[],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.pica=e()}}(function(){return function(){function e(t,i,n){function o(a,l){if(!i[a]){if(!t[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(r)return r(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=i[a]={exports:{}};t[a][0].call(u.exports,function(e){return o(t[a][1][e]||e)},u,u.exports,e,t,i,n)}return i[a].exports}for(var r="function"==typeof require&&require,a=0;a<n.length;a++)o(n[a]);return o}return e}()({1:[function(e,t,i){"use strict";function n(e){var t=e||[],i={js:t.indexOf("js")>=0,wasm:t.indexOf("wasm")>=0};r.call(this,i),this.features={js:i.js,wasm:i.wasm&&this.has_wasm()},this.use(a),this.use(l)}var o=e("inherits"),r=e("multimath"),a=e("multimath/lib/unsharp_mask"),l=e("./mm_resize");o(n,r),n.prototype.resizeAndUnsharp=function(e,t){var i=this.resize(e,t);return e.unsharpAmount&&this.unsharp_mask(i,e.toWidth,e.toHeight,e.unsharpAmount,e.unsharpRadius,e.unsharpThreshold),i},t.exports=n},{"./mm_resize":4,inherits:15,multimath:16,"multimath/lib/unsharp_mask":19}],2:[function(e,t,i){"use strict";function n(e){return e<0?0:e>255?255:e}function o(e,t,i,o,r,a){var l,s,c,u,d,h,f,p,g,m,v,b=0,_=0;for(g=0;g<o;g++){for(d=0,m=0;m<r;m++){for(h=a[d++],f=a[d++],p=b+4*h|0,l=s=c=u=0;f>0;f--)v=a[d++],u=u+v*e[p+3]|0,c=c+v*e[p+2]|0,s=s+v*e[p+1]|0,l=l+v*e[p]|0,p=p+4|0;t[_+3]=n(u+8192>>14),t[_+2]=n(c+8192>>14),t[_+1]=n(s+8192>>14),t[_]=n(l+8192>>14),_=_+4*o|0}_=4*(g+1)|0,b=(g+1)*i*4|0}}function r(e,t,i,o,r,a){var l,s,c,u,d,h,f,p,g,m,v,b=0,_=0;for(g=0;g<o;g++){for(d=0,m=0;m<r;m++){for(h=a[d++],f=a[d++],p=b+4*h|0,l=s=c=u=0;f>0;f--)v=a[d++],u=u+v*e[p+3]|0,c=c+v*e[p+2]|0,s=s+v*e[p+1]|0,l=l+v*e[p]|0,p=p+4|0;t[_+3]=n(u+8192>>14),t[_+2]=n(c+8192>>14),t[_+1]=n(s+8192>>14),t[_]=n(l+8192>>14),_=_+4*o|0}_=4*(g+1)|0,b=(g+1)*i*4|0}}t.exports={convolveHorizontally:o,convolveVertically:r}},{}],3:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQQEAXAAAAcZAghjb252b2x2ZQAACmNvbnZvbHZlSFYAAQkBAArmAwLBAwEQfwJAIANFDQAgBEUNACAFQQRqIRVBACEMQQAhDQNAIA0hDkEAIRFBACEHA0AgB0ECaiESAn8gBSAHQQF0IgdqIgZBAmouAQAiEwRAQQAhCEEAIBNrIRQgFSAHaiEPIAAgDCAGLgEAakECdGohEEEAIQlBACEKQQAhCwNAIBAoAgAiB0EYdiAPLgEAIgZsIAtqIQsgB0H/AXEgBmwgCGohCCAHQRB2Qf8BcSAGbCAKaiEKIAdBCHZB/wFxIAZsIAlqIQkgD0ECaiEPIBBBBGohECAUQQFqIhQNAAsgEiATagwBC0EAIQtBACEKQQAhCUEAIQggEgshByABIA5BAnRqIApBgMAAakEOdSIGQf8BIAZB/wFIG0EQdEGAgPwHcUEAIAZBAEobIAtBgMAAakEOdSIGQf8BIAZB/wFIG0EYdEEAIAZBAEobciAJQYDAAGpBDnUiBkH/ASAGQf8BSBtBCHRBgP4DcUEAIAZBAEobciAIQYDAAGpBDnUiBkH/ASAGQf8BSBtB/wFxQQAgBkEAShtyNgIAIA4gA2ohDiARQQFqIhEgBEcNAAsgDCACaiEMIA1BAWoiDSADRw0ACwsLIQACQEEAIAIgAyAEIAUgABAAIAJBACAEIAUgBiABEAALCw=="},{}],4:[function(e,t,i){"use strict";t.exports={name:"resize",fn:e("./resize"),wasm_fn:e("./resize_wasm"),wasm_src:e("./convolve_wasm_base64")}},{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,o=t*i*4|0;n<o;)e[n]=255,n=n+4|0}var o=e("./resize_filter_gen"),r=e("./convolve").convolveHorizontally,a=e("./convolve").convolveVertically;t.exports=function(e){var t=e.src,i=e.width,l=e.height,s=e.toWidth,c=e.toHeight,u=e.scaleX||e.toWidth/e.width,d=e.scaleY||e.toHeight/e.height,h=e.offsetX||0,f=e.offsetY||0,p=e.dest||new Uint8Array(s*c*4),g=void 0===e.quality?3:e.quality,m=e.alpha||!1,v=o(g,i,s,u,h),b=o(g,l,c,d,f),_=new Uint8Array(s*l*4);return r(t,_,i,l,s,v),a(_,p,l,s,c,b),m||n(p,s,c),p}},{"./convolve":2,"./resize_filter_gen":6}],6:[function(e,t,i){"use strict";function n(e){return Math.round(e*((1<<r)-1))}var o=e("./resize_filter_info"),r=14;t.exports=function(e,t,i,r,a){var l,s,c,u,d,h,f,p,g,m,v,b,_,w,y,C,E,L=o[e].filter,A=1/r,S=Math.min(1,r),x=o[e].win/S,I=Math.floor(2*(x+1)),D=new Int16Array((I+2)*i),T=0,k=!D.subarray||!D.set;for(l=0;l<i;l++){for(s=(l+.5)*A+a,c=Math.max(0,Math.floor(s-x)),u=Math.min(t-1,Math.ceil(s+x)),d=u-c+1,h=new Float32Array(d),f=new Int16Array(d),p=0,g=c,m=0;g<=u;g++,m++)v=L((g+.5-s)*S),p+=v,h[m]=v;for(b=0,m=0;m<h.length;m++)_=h[m]/p,b+=_,f[m]=n(_);for(f[i>>1]+=n(1-b),w=0;w<f.length&&0===f[w];)w++;if(w<f.length){for(y=f.length-1;y>0&&0===f[y];)y--;if(C=c+w,E=y-w+1,D[T++]=C,D[T++]=E,k)for(m=w;m<=y;m++)D[T++]=f[m];else D.set(f.subarray(w,y+1),T),T+=E}else D[T++]=0,D[T++]=0}return D}},{"./resize_filter_info":7}],7:[function(e,t,i){"use strict";t.exports=[{win:.5,filter:function(e){return e>=-.5&&e<.5?1:0}},{win:1,filter:function(e){if(e<=-1||e>=1)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*(.54+.46*Math.cos(t/1))}},{win:2,filter:function(e){if(e<=-2||e>=2)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/2)/(t/2)}},{win:3,filter:function(e){if(e<=-3||e>=3)return 0;if(e>-1.1920929e-7&&e<1.1920929e-7)return 1;var t=e*Math.PI;return Math.sin(t)/t*Math.sin(t/3)/(t/3)}}]},{}],8:[function(e,t,i){"use strict";function n(e,t,i){for(var n=3,o=t*i*4|0;n<o;)e[n]=255,n=n+4|0}function o(e){return new Uint8Array(e.buffer,0,e.byteLength)}function r(e,t,i){if(l)return void t.set(o(e),i);for(var n=i,r=0;r<e.length;r++){var a=e[r];t[n++]=255&a,t[n++]=a>>8&255}}var a=e("./resize_filter_gen"),l=!0;try{l=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0]}catch(e){}t.exports=function(e){var t=e.src,i=e.width,o=e.height,l=e.toWidth,s=e.toHeight,c=e.scaleX||e.toWidth/e.width,u=e.scaleY||e.toHeight/e.height,d=e.offsetX||0,h=e.offsetY||0,f=e.dest||new Uint8Array(l*s*4),p=void 0===e.quality?3:e.quality,g=e.alpha||!1,m=a(p,i,l,c,d),v=a(p,o,s,u,h),b=this.__align(0+Math.max(t.byteLength,f.byteLength)),_=this.__align(b+o*l*4),w=this.__align(_+m.byteLength),y=w+v.byteLength,C=this.__instance("resize",y),E=new Uint8Array(this.__memory.buffer),L=new Uint32Array(this.__memory.buffer),A=new Uint32Array(t.buffer);return L.set(A),r(m,E,_),r(v,E,w),(C.exports.convolveHV||C.exports._convolveHV)(_,w,b,i,o,l,s),new Uint32Array(f.buffer).set(new Uint32Array(this.__memory.buffer,0,s*l)),g||n(f,l,s),f}},{"./resize_filter_gen":6}],9:[function(e,t,i){"use strict";function n(e,t){this.create=e,this.available=[],this.acquired={},this.lastId=1,this.timeoutId=0,this.idle=t||2e3}n.prototype.acquire=function(){var e,t=this;return 0!==this.available.length?e=this.available.pop():(e=this.create(),e.id=this.lastId++,e.release=function(){return t.release(e)}),this.acquired[e.id]=e,e},n.prototype.release=function(e){var t=this;delete this.acquired[e.id],e.lastUsed=Date.now(),this.available.push(e),0===this.timeoutId&&(this.timeoutId=setTimeout(function(){return t.gc()},100))},n.prototype.gc=function(){var e=this,t=Date.now();this.available=this.available.filter(function(i){return!(t-i.lastUsed>e.idle)||(i.destroy(),!1)}),0!==this.available.length?this.timeoutId=setTimeout(function(){return e.gc()},100):this.timeoutId=0},t.exports=n},{}],10:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,o,r){var a=i/e,l=n/t,s=(2*r+2+1)/o;if(s>.5)return[[i,n]];var c=Math.ceil(Math.log(Math.min(a,l))/Math.log(s));if(c<=1)return[[i,n]];for(var u=[],d=0;d<c;d++){var h=Math.round(Math.pow(Math.pow(e,c-d-1)*Math.pow(i,d+1),1/c)),f=Math.round(Math.pow(Math.pow(t,c-d-1)*Math.pow(n,d+1),1/c));u.push([h,f])}return u}},{}],11:[function(e,t,i){"use strict";function n(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.floor(e)}function o(e){var t=Math.round(e);return Math.abs(e-t)<r?t:Math.ceil(e)}var r=1e-5;t.exports=function(e){var t=e.toWidth/e.width,i=e.toHeight/e.height,r=n(e.srcTileSize*t)-2*e.destTileBorder,a=n(e.srcTileSize*i)-2*e.destTileBorder;if(r<1||a<1)throw new Error("Internal error in pica: target tile width/height is too small.");var l,s,c,u,d,h,f,p=[];for(u=0;u<e.toHeight;u+=a)for(c=0;c<e.toWidth;c+=r)l=c-e.destTileBorder,l<0&&(l=0),d=c+r+e.destTileBorder-l,l+d>=e.toWidth&&(d=e.toWidth-l),s=u-e.destTileBorder,s<0&&(s=0),h=u+a+e.destTileBorder-s,s+h>=e.toHeight&&(h=e.toHeight-s),f={toX:l,toY:s,toWidth:d,toHeight:h,toInnerX:c,toInnerY:u,toInnerWidth:r,toInnerHeight:a,offsetX:l/t-n(l/t),offsetY:s/i-n(s/i),scaleX:t,scaleY:i,x:n(l/t),y:n(s/i),width:o(d/t),height:o(h/i)},p.push(f);return p}},{}],12:[function(e,t,i){"use strict";function n(e){return Object.prototype.toString.call(e)}t.exports.isCanvas=function(e){var t=n(e);return"[object HTMLCanvasElement]"===t||"[object Canvas]"===t},t.exports.isImage=function(e){return"[object HTMLImageElement]"===n(e)},t.exports.limiter=function(e){function t(){i<e&&n.length&&(i++,n.shift()())}var i=0,n=[];return function(e){return new Promise(function(o,r){n.push(function(){e().then(function(e){o(e),i--,t()},function(e){r(e),i--,t()})}),t()})}},t.exports.cib_quality_name=function(e){switch(e){case 0:return"pixelated";case 1:return"low";case 2:return"medium"}return"high"},t.exports.cib_support=function(){return Promise.resolve().then(function(){if("undefined"==typeof createImageBitmap||"undefined"==typeof document)return!1;var e=document.createElement("canvas");return e.width=100,e.height=100,createImageBitmap(e,0,0,100,100,{resizeWidth:10,resizeHeight:10,resizeQuality:"high"}).then(function(t){var i=10===t.width;return t.close(),e=null,i})}).catch(function(){return!1})}},{}],13:[function(e,t,i){"use strict";t.exports=function(){var t,i=e("./mathlib");onmessage=function(e){var n=e.data.opts;t||(t=new i(e.data.features));var o=t.resizeAndUnsharp(n);postMessage({result:o},[o.buffer])}}},{"./mathlib":1}],14:[function(e,t,i){function n(e){e<.5&&(e=.5);var t=Math.exp(.527076)/e,i=Math.exp(-t),n=Math.exp(-2*t),o=(1-i)*(1-i)/(1+2*t*i-n);return a=o,l=o*(t-1)*i,s=o*(t+1)*i,c=-o*n,u=2*i,d=-n,h=(a+l)/(1-u-d),f=(s+c)/(1-u-d),new Float32Array([a,l,s,c,u,d,h,f])}function o(e,t,i,n,o,r){var a,l,s,c,u,d,h,f,p,g,m,v,b,_;for(p=0;p<r;p++){for(d=p*o,h=p,f=0,a=e[d],u=a*n[6],c=u,m=n[0],v=n[1],b=n[4],_=n[5],g=0;g<o;g++)l=e[d],s=l*m+a*v+c*b+u*_,u=c,c=s,a=l,i[f]=c,f++,d++;for(d--,f--,h+=r*(o-1),a=e[d],u=a*n[7],c=u,l=a,m=n[2],v=n[3],g=o-1;g>=0;g--)s=l*m+a*v+c*b+u*_,u=c,c=s,a=l,l=e[d],t[h]=i[f]+c,d--,f--,h-=r}}function r(e,t,i,r){if(r){var a=new Uint16Array(e.length),l=new Float32Array(Math.max(t,i)),s=n(r);o(e,a,l,s,t,i,r),o(a,e,l,s,i,t,r)}}var a,l,s,c,u,d,h,f;t.exports=r},{}],15:[function(e,t,i){"function"==typeof Object.create?t.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:t.exports=function(e,t){if(t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}}},{}],16:[function(e,t,i){"use strict";function n(e){if(!(this instanceof n))return new n(e);var t=o({},l,e||{});if(this.options=t,this.__cache={},this.__init_promise=null,this.__modules=t.modules||{},this.__memory=null,this.__wasm={},this.__isLE=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0],!this.options.js&&!this.options.wasm)throw new Error('mathlib: at least "js" or "wasm" should be enabled')}var o=e("object-assign"),r=e("./lib/base64decode"),a=e("./lib/wa_detect"),l={js:!0,wasm:!0};n.prototype.has_wasm=a,n.prototype.use=function(e){return this.__modules[e.name]=e,this.options.wasm&&this.has_wasm()&&e.wasm_fn?this[e.name]=e.wasm_fn:this[e.name]=e.fn,this},n.prototype.init=function(){if(this.__init_promise)return this.__init_promise;if(!this.options.js&&this.options.wasm&&!this.has_wasm())return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));var e=this;return this.__init_promise=Promise.all(Object.keys(e.__modules).map(function(t){var i=e.__modules[t];return e.options.wasm&&e.has_wasm()&&i.wasm_fn?e.__wasm[t]?null:WebAssembly.compile(e.__base64decode(i.wasm_src)).then(function(i){e.__wasm[t]=i}):null})).then(function(){return e}),this.__init_promise},n.prototype.__base64decode=r,n.prototype.__reallocate=function(e){if(!this.__memory)return this.__memory=new WebAssembly.Memory({initial:Math.ceil(e/65536)}),this.__memory;var t=this.__memory.buffer.byteLength;return t<e&&this.__memory.grow(Math.ceil((e-t)/65536)),this.__memory},n.prototype.__instance=function(e,t,i){if(t&&this.__reallocate(t),!this.__wasm[e]){var n=this.__modules[e];this.__wasm[e]=new WebAssembly.Module(this.__base64decode(n.wasm_src))}if(!this.__cache[e]){var r={memoryBase:0,memory:this.__memory,tableBase:0,table:new WebAssembly.Table({initial:0,element:"anyfunc"})};this.__cache[e]=new WebAssembly.Instance(this.__wasm[e],{env:o(r,i||{})})}return this.__cache[e]},n.prototype.__align=function(e,t){t=t||8;var i=e%t;return e+(i?t-i:0)},t.exports=n},{"./lib/base64decode":17,"./lib/wa_detect":23,"object-assign":24}],17:[function(e,t,i){"use strict";t.exports=function(e){for(var t=e.replace(/[\r\n=]/g,""),i=t.length,n=new Uint8Array(3*i>>2),o=0,r=0,a=0;a<i;a++)a%4==0&&a&&(n[r++]=o>>16&255,n[r++]=o>>8&255,n[r++]=255&o),o=o<<6|"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(t.charAt(a));var l=i%4*6;return 0===l?(n[r++]=o>>16&255,n[r++]=o>>8&255,n[r++]=255&o):18===l?(n[r++]=o>>10&255,n[r++]=o>>2&255):12===l&&(n[r++]=o>>4&255),n}},{}],18:[function(e,t,i){"use strict";t.exports=function(e,t,i){for(var n,o,r,a,l,s=t*i,c=new Uint16Array(s),u=0;u<s;u++)n=e[4*u],o=e[4*u+1],r=e[4*u+2],l=n>=o&&n>=r?n:o>=r&&o>=n?o:r,a=n<=o&&n<=r?n:o<=r&&o<=n?o:r,c[u]=257*(l+a)>>1;return c}},{}],19:[function(e,t,i){"use strict";t.exports={name:"unsharp_mask",fn:e("./unsharp_mask"),wasm_fn:e("./unsharp_mask_wasm"),wasm_src:e("./unsharp_mask_wasm_base64")}},{"./unsharp_mask":20,"./unsharp_mask_wasm":21,"./unsharp_mask_wasm_base64":22}],20:[function(e,t,i){"use strict";var n=e("glur/mono16"),o=e("./hsl_l16");t.exports=function(e,t,i,r,a,l){var s,c,u,d,h,f,p,g,m,v,b,_,w;if(!(0===r||a<.5)){a>2&&(a=2);var y=o(e,t,i),C=new Uint16Array(y);n(C,t,i,a);for(var E=r/100*4096+.5|0,L=257*l|0,A=t*i,S=0;S<A;S++)_=2*(y[S]-C[S]),Math.abs(_)>=L&&(w=4*S,s=e[w],c=e[w+1],u=e[w+2],g=s>=c&&s>=u?s:c>=s&&c>=u?c:u,p=s<=c&&s<=u?s:c<=s&&c<=u?c:u,f=257*(g+p)>>1,p===g?d=h=0:(h=f<=32767?4095*(g-p)/(g+p)|0:4095*(g-p)/(510-g-p)|0,d=s===g?65535*(c-u)/(6*(g-p))|0:c===g?21845+(65535*(u-s)/(6*(g-p))|0):43690+(65535*(s-c)/(6*(g-p))|0)),f+=E*_+2048>>12,f>65535?f=65535:f<0&&(f=0),0===h?s=c=u=f>>8:(v=f<=32767?f*(4096+h)+2048>>12:f+((65535-f)*h+2048>>12),m=2*f-v>>8,v>>=8,b=d+21845&65535,s=b>=43690?m:b>=32767?m+(6*(v-m)*(43690-b)+32768>>16):b>=10922?v:m+(6*(v-m)*b+32768>>16),b=65535&d,c=b>=43690?m:b>=32767?m+(6*(v-m)*(43690-b)+32768>>16):b>=10922?v:m+(6*(v-m)*b+32768>>16),b=d-21845&65535,u=b>=43690?m:b>=32767?m+(6*(v-m)*(43690-b)+32768>>16):b>=10922?v:m+(6*(v-m)*b+32768>>16)),e[w]=s,e[w+1]=c,e[w+2]=u)}}},{"./hsl_l16":18,"glur/mono16":14}],21:[function(e,t,i){"use strict";t.exports=function(e,t,i,n,o,r){if(!(0===n||o<.5)){o>2&&(o=2);var a=t*i,l=4*a,s=2*a,c=2*a,u=4*Math.max(t,i),d=l,h=d+s,f=h+c,p=f+c,g=p+u,m=this.__instance("unsharp_mask",l+s+2*c+u+32,{exp:Math.exp}),v=new Uint32Array(e.buffer);new Uint32Array(this.__memory.buffer).set(v);var b=m.exports.hsl_l16||m.exports._hsl_l16;b(0,d,t,i),b=m.exports.blurMono16||m.exports._blurMono16,b(d,h,f,p,g,t,i,o),b=m.exports.unsharp||m.exports._unsharp,b(0,0,d,h,t,i,n,r),v.set(new Uint32Array(this.__memory.buffer,0,a))}}},{}],22:[function(e,t,i){"use strict";t.exports="AGFzbQEAAAABMQZgAXwBfGACfX8AYAZ/f39/f38AYAh/f39/f39/fQBgBH9/f38AYAh/f39/f39/fwACGQIDZW52A2V4cAAAA2VudgZtZW1vcnkCAAEDBgUBAgMEBQQEAXAAAAdMBRZfX2J1aWxkX2dhdXNzaWFuX2NvZWZzAAEOX19nYXVzczE2X2xpbmUAAgpibHVyTW9ubzE2AAMHaHNsX2wxNgAEB3Vuc2hhcnAABQkBAAqJEAXZAQEGfAJAIAFE24a6Q4Ia+z8gALujIgOaEAAiBCAEoCIGtjgCECABIANEAAAAAAAAAMCiEAAiBbaMOAIUIAFEAAAAAAAA8D8gBKEiAiACoiAEIAMgA6CiRAAAAAAAAPA/oCAFoaMiArY4AgAgASAEIANEAAAAAAAA8L+gIAKioiIHtjgCBCABIAQgA0QAAAAAAADwP6AgAqKiIgO2OAIIIAEgBSACoiIEtow4AgwgASACIAegIAVEAAAAAAAA8D8gBqGgIgKjtjgCGCABIAMgBKEgAqO2OAIcCwu3AwMDfwR9CHwCQCADKgIUIQkgAyoCECEKIAMqAgwhCyADKgIIIQwCQCAEQX9qIgdBAEgiCA0AIAIgAC8BALgiDSADKgIYu6IiDiAJuyIQoiAOIAq7IhGiIA0gAyoCBLsiEqIgAyoCALsiEyANoqCgoCIPtjgCACACQQRqIQIgAEECaiEAIAdFDQAgBCEGA0AgAiAOIBCiIA8iDiARoiANIBKiIBMgAC8BALgiDaKgoKAiD7Y4AgAgAkEEaiECIABBAmohACAGQX9qIgZBAUoNAAsLAkAgCA0AIAEgByAFbEEBdGogAEF+ai8BACIIuCINIAu7IhGiIA0gDLsiEqKgIA0gAyoCHLuiIg4gCrsiE6KgIA4gCbsiFKKgIg8gAkF8aioCALugqzsBACAHRQ0AIAJBeGohAiAAQXxqIQBBACAFQQF0ayEHIAEgBSAEQQF0QXxqbGohBgNAIAghAyAALwEAIQggBiANIBGiIAO4Ig0gEqKgIA8iECAToqAgDiAUoqAiDyACKgIAu6CrOwEAIAYgB2ohBiAAQX5qIQAgAkF8aiECIBAhDiAEQX9qIgRBAUoNAAsLCwvfAgIDfwZ8AkAgB0MAAAAAWw0AIARE24a6Q4Ia+z8gB0MAAAA/l7ujIgyaEAAiDSANoCIPtjgCECAEIAxEAAAAAAAAAMCiEAAiDraMOAIUIAREAAAAAAAA8D8gDaEiCyALoiANIAwgDKCiRAAAAAAAAPA/oCAOoaMiC7Y4AgAgBCANIAxEAAAAAAAA8L+gIAuioiIQtjgCBCAEIA0gDEQAAAAAAADwP6AgC6KiIgy2OAIIIAQgDiALoiINtow4AgwgBCALIBCgIA5EAAAAAAAA8D8gD6GgIgujtjgCGCAEIAwgDaEgC6O2OAIcIAYEQCAFQQF0IQogBiEJIAIhCANAIAAgCCADIAQgBSAGEAIgACAKaiEAIAhBAmohCCAJQX9qIgkNAAsLIAVFDQAgBkEBdCEIIAUhAANAIAIgASADIAQgBiAFEAIgAiAIaiECIAFBAmohASAAQX9qIgANAAsLC7wBAQV/IAMgAmwiAwRAQQAgA2shBgNAIAAoAgAiBEEIdiIHQf8BcSECAn8gBEH/AXEiAyAEQRB2IgRB/wFxIgVPBEAgAyIIIAMgAk8NARoLIAQgBCAHIAIgA0kbIAIgBUkbQf8BcQshCAJAIAMgAk0EQCADIAVNDQELIAQgByAEIAMgAk8bIAIgBUsbQf8BcSEDCyAAQQRqIQAgASADIAhqQYECbEEBdjsBACABQQJqIQEgBkEBaiIGDQALCwvTBgEKfwJAIAazQwAAgEWUQwAAyEKVu0QAAAAAAADgP6CqIQ0gBSAEbCILBEAgB0GBAmwhDgNAQQAgAi8BACADLwEAayIGQQF0IgdrIAcgBkEASBsgDk8EQCAAQQJqLQAAIQUCfyAALQAAIgYgAEEBai0AACIESSIJRQRAIAYiCCAGIAVPDQEaCyAFIAUgBCAEIAVJGyAGIARLGwshCAJ/IAYgBE0EQCAGIgogBiAFTQ0BGgsgBSAFIAQgBCAFSxsgCRsLIgogCGoiD0GBAmwiEEEBdiERQQAhDAJ/QQAiCSAIIApGDQAaIAggCmsiCUH/H2wgD0H+AyAIayAKayAQQYCABEkbbSEMIAYgCEYEQCAEIAVrQf//A2wgCUEGbG0MAQsgBSAGayAGIARrIAQgCEYiBhtB//8DbCAJQQZsbUHVqgFBqtUCIAYbagshCSARIAcgDWxBgBBqQQx1aiIGQQAgBkEAShsiBkH//wMgBkH//wNIGyEGAkACfwJAIAxB//8DcSIFBEAgBkH//wFKDQEgBUGAIGogBmxBgBBqQQx2DAILIAZBCHYiBiEFIAYhBAwCCyAFIAZB//8Dc2xBgBBqQQx2IAZqCyIFQQh2IQcgBkEBdCAFa0EIdiIGIQQCQCAJQdWqAWpB//8DcSIFQanVAksNACAFQf//AU8EQEGq1QIgBWsgByAGa2xBBmxBgIACakEQdiAGaiEEDAELIAchBCAFQanVAEsNACAFIAcgBmtsQQZsQYCAAmpBEHYgBmohBAsCfyAGIgUgCUH//wNxIghBqdUCSw0AGkGq1QIgCGsgByAGa2xBBmxBgIACakEQdiAGaiAIQf//AU8NABogByIFIAhBqdUASw0AGiAIIAcgBmtsQQZsQYCAAmpBEHYgBmoLIQUgCUGr1QJqQf//A3EiCEGp1QJLDQAgCEH//wFPBEBBqtUCIAhrIAcgBmtsQQZsQYCAAmpBEHYgBmohBgwBCyAIQanVAEsEQCAHIQYMAQsgCCAHIAZrbEEGbEGAgAJqQRB2IAZqIQYLIAEgBDoAACABQQFqIAU6AAAgAUECaiAGOgAACyADQQJqIQMgAkECaiECIABBBGohACABQQRqIQEgC0F/aiILDQALCwsL"},{}],23:[function(e,t,i){"use strict";var n;t.exports=function(){if(void 0!==n)return n;if(n=!1,"undefined"==typeof WebAssembly)return n;try{var e=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11]),t=new WebAssembly.Module(e);return 0!==new WebAssembly.Instance(t,{}).exports.test(4)&&(n=!0),n}catch(e){}return n}},{}],24:[function(e,t,i){"use strict";function n(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}var o=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;t.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},i=0;i<10;i++)t["_"+String.fromCharCode(i)]=i;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(e){n[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var i,l,s=n(e),c=1;c<arguments.length;c++){i=Object(arguments[c]);for(var u in i)r.call(i,u)&&(s[u]=i[u]);if(o){l=o(i);for(var d=0;d<l.length;d++)a.call(i,l[d])&&(s[l[d]]=i[l[d]])}}return s}},{}],25:[function(e,t,i){var n=arguments[3],o=arguments[4],r=arguments[5],a=JSON.stringify;t.exports=function(e,t){function i(e){m[e]=!0;for(var t in o[e][1]){var n=o[e][1][t];m[n]||i(n)}}for(var l,s=Object.keys(r),c=0,u=s.length;c<u;c++){var d=s[c],h=r[d].exports;if(h===e||h&&h.default===e){l=d;break}}if(!l){l=Math.floor(Math.pow(16,8)*Math.random()).toString(16);for(var f={},c=0,u=s.length;c<u;c++){var d=s[c];f[d]=d}o[l]=["function(require,module,exports){"+e+"(self); }",f]}var p=Math.floor(Math.pow(16,8)*Math.random()).toString(16),g={};g[l]=l,o[p]=["function(require,module,exports){var f = require("+a(l)+");(f.default ? f.default : f)(self);}",g];var m={};i(p);var v="("+n+")({"+Object.keys(m).map(function(e){return a(e)+":["+o[e][0]+","+a(o[e][1])+"]"}).join(",")+"},{},["+a(p)+"])",b=window.URL||window.webkitURL||window.mozURL||window.msURL,_=new Blob([v],{type:"text/javascript"});if(t&&t.bare)return _;var w=b.createObjectURL(_),y=new Worker(w);return y.objectURL=w,y}},{}],"/":[function(e,t,i){"use strict";function n(e,t){return a(e)||r(e,t)||o()}function o(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function r(e,t){var i=[],n=!0,o=!1,r=void 0;try{for(var a,l=e[Symbol.iterator]();!(n=(a=l.next()).done)&&(i.push(a.value),!t||i.length!==t);n=!0);}catch(e){o=!0,r=e}finally{try{n||null==l.return||l.return()}finally{if(o)throw r}}return i}function a(e){if(Array.isArray(e))return e}function l(){return{value:u(p),destroy:function(){if(this.value.terminate(),"undefined"!=typeof window){var e=window.URL||window.webkitURL||window.mozURL||window.msURL;e&&e.revokeObjectURL&&this.value.objectURL&&e.revokeObjectURL(this.value.objectURL)}}}}function s(e){if(!(this instanceof s))return new s(e);this.options=c({},C,e||{});var t="lk_".concat(this.options.concurrency);this.__limit=v[t]||f.limiter(this.options.concurrency),v[t]||(v[t]=this.__limit),this.features={js:!1,wasm:!1,cib:!1,ww:!1},this.__workersPool=null,this.__requested_features=[],this.__mathlib=null}var c=e("object-assign"),u=e("webworkify"),d=e("./lib/mathlib"),h=e("./lib/pool"),f=e("./lib/utils"),p=e("./lib/worker"),g=e("./lib/stepper"),m=e("./lib/tiler"),v={},b=!1;try{"undefined"!=typeof navigator&&navigator.userAgent&&(b=navigator.userAgent.indexOf("Safari")>=0)}catch(e){}var _=1;"undefined"!=typeof navigator&&(_=Math.min(navigator.hardwareConcurrency||1,4));var w,y,C={tile:1024,concurrency:_,features:["js","wasm","ww"],idle:2e3},E={quality:3,alpha:!1,unsharpAmount:0,unsharpRadius:0,unsharpThreshold:0};s.prototype.init=function(){var t=this;if(this.__initPromise)return this.__initPromise;if(!1!==w&&!0!==w&&(w=!1,"undefined"!=typeof ImageData&&"undefined"!=typeof Uint8ClampedArray))try{new ImageData(new Uint8ClampedArray(400),10,10),w=!0}catch(e){}!1!==y&&!0!==y&&(y=!1,"undefined"!=typeof ImageBitmap&&(ImageBitmap.prototype&&ImageBitmap.prototype.close?y=!0:this.debug("ImageBitmap does not support .close(), disabled")));var i=this.options.features.slice();if(i.indexOf("all")>=0&&(i=["cib","wasm","js","ww"]),this.__requested_features=i,this.__mathlib=new d(i),i.indexOf("ww")>=0&&"undefined"!=typeof window&&"Worker"in window)try{e("webworkify")(function(){}).terminate(),this.features.ww=!0;var n="wp_".concat(JSON.stringify(this.options));v[n]?this.__workersPool=v[n]:(this.__workersPool=new h(l,this.options.idle),v[n]=this.__workersPool)}catch(e){}var o,r=this.__mathlib.init().then(function(e){c(t.features,e.features)});return o=y?f.cib_support().then(function(e){if(t.features.cib&&i.indexOf("cib")<0)return void t.debug("createImageBitmap() resize supported, but disabled by config");i.indexOf("cib")>=0&&(t.features.cib=e)}):Promise.resolve(!1),this.__initPromise=Promise.all([r,o]).then(function(){return t}),this.__initPromise},s.prototype.resize=function(e,t,i){var o=this;this.debug("Start resize...");var r=c({},E);if(isNaN(i)?i&&(r=c(r,i)):r=c(r,{quality:i}),r.toWidth=t.width,r.toHeight=t.height,r.width=e.naturalWidth||e.width,r.height=e.naturalHeight||e.height,0===t.width||0===t.height)return Promise.reject(new Error("Invalid output size: ".concat(t.width,"x").concat(t.height)));r.unsharpRadius>2&&(r.unsharpRadius=2);var a=!1,l=null;r.cancelToken&&(l=r.cancelToken.then(function(e){throw a=!0,e},function(e){throw a=!0,e}));var s=Math.ceil(Math.max(3,2.5*r.unsharpRadius|0));return this.init().then(function(){if(a)return l;if(o.features.cib){var i=t.getContext("2d",{alpha:Boolean(r.alpha)});return o.debug("Resize via createImageBitmap()"),createImageBitmap(e,{resizeWidth:r.toWidth,resizeHeight:r.toHeight,resizeQuality:f.cib_quality_name(r.quality)}).then(function(e){if(a)return l;if(!r.unsharpAmount)return i.drawImage(e,0,0),e.close(),i=null,o.debug("Finished!"),t;o.debug("Unsharp result");var n=document.createElement("canvas");n.width=r.toWidth,n.height=r.toHeight;var s=n.getContext("2d",{alpha:Boolean(r.alpha)});s.drawImage(e,0,0),e.close();var c=s.getImageData(0,0,r.toWidth,r.toHeight);return o.__mathlib.unsharp_mask(c.data,r.toWidth,r.toHeight,r.unsharpAmount,r.unsharpRadius,r.unsharpThreshold),i.putImageData(c,0,0),c=s=n=i=null,o.debug("Finished!"),t})}var u={},d=function(e){return Promise.resolve().then(function(){return o.features.ww?new Promise(function(t,i){var n=o.__workersPool.acquire();l&&l.catch(function(e){return i(e)}),n.value.onmessage=function(e){n.release(),e.data.err?i(e.data.err):t(e.data.result)},n.value.postMessage({opts:e,features:o.__requested_features,preload:{wasm_nodule:o.__mathlib.__}},[e.src.buffer])}):o.__mathlib.resizeAndUnsharp(e,u)})},h=function(e,t,i){var n,r,c,u=function(t){return o.__limit(function(){if(a)return l;var s;if(f.isCanvas(e))o.debug("Get tile pixel data"),s=n.getImageData(t.x,t.y,t.width,t.height);else{o.debug("Draw tile imageBitmap/image to temporary canvas");var u=document.createElement("canvas");u.width=t.width,u.height=t.height;var h=u.getContext("2d",{alpha:Boolean(i.alpha)});h.globalCompositeOperation="copy",h.drawImage(r||e,t.x,t.y,t.width,t.height,0,0,t.width,t.height),o.debug("Get tile pixel data"),s=h.getImageData(0,0,t.width,t.height),h=u=null}var p={src:s.data,width:t.width,height:t.height,toWidth:t.toWidth,toHeight:t.toHeight,scaleX:t.scaleX,scaleY:t.scaleY,offsetX:t.offsetX,offsetY:t.offsetY,quality:i.quality,alpha:i.alpha,unsharpAmount:i.unsharpAmount,unsharpRadius:i.unsharpRadius,unsharpThreshold:i.unsharpThreshold};return o.debug("Invoke resize math"),Promise.resolve().then(function(){return d(p)}).then(function(e){if(a)return l;s=null;var i;if(o.debug("Convert raw rgba tile result to ImageData"),w)i=new ImageData(new Uint8ClampedArray(e),t.toWidth,t.toHeight);else if(i=c.createImageData(t.toWidth,t.toHeight),i.data.set)i.data.set(e);else for(var n=i.data.length-1;n>=0;n--)i.data[n]=e[n];return o.debug("Draw tile"),b?c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth+1e-5,t.toInnerHeight+1e-5):c.putImageData(i,t.toX,t.toY,t.toInnerX-t.toX,t.toInnerY-t.toY,t.toInnerWidth,t.toInnerHeight),null})})};return Promise.resolve().then(function(){if(c=t.getContext("2d",{alpha:Boolean(i.alpha)}),f.isCanvas(e))return n=e.getContext("2d",{alpha:Boolean(i.alpha)}),null;if(f.isImage(e))return y?(o.debug("Decode image via createImageBitmap"),createImageBitmap(e).then(function(e){r=e})):null;throw new Error('".from" should be image or canvas')}).then(function(){function e(){r&&(r.close(),r=null)}if(a)return l;o.debug("Calculate tiles");var n=m({width:i.width,height:i.height,srcTileSize:o.options.tile,toWidth:i.toWidth,toHeight:i.toHeight,destTileBorder:s}),c=n.map(function(e){return u(e)});return o.debug("Process tiles"),Promise.all(c).then(function(){return o.debug("Finished!"),e(),t},function(t){throw e(),t})})},p=g(r.width,r.height,r.toWidth,r.toHeight,o.options.tile,s);return function e(t,i,o,r){if(a)return l;var s=t.shift(),u=n(s,2),d=u[0],f=u[1],p=0===t.length;r=c({},r,{toWidth:d,toHeight:f,quality:p?r.quality:Math.min(1,r.quality)});var g;return p||(g=document.createElement("canvas"),g.width=d,g.height=f),h(i,p?o:g,r).then(function(){return p?o:(r.width=d,r.height=f,e(t,g,o,r))})}(p,e,t,r)})},s.prototype.resizeBuffer=function(e){var t=this,i=c({},E,e);return this.init().then(function(){return t.__mathlib.resizeAndUnsharp(i)})},s.prototype.toBlob=function(e,t,i){return t=t||"image/png",new Promise(function(n){if(e.toBlob)return void e.toBlob(function(e){return n(e)},t,i);for(var o=atob(e.toDataURL(t,i).split(",")[1]),r=o.length,a=new Uint8Array(r),l=0;l<r;l++)a[l]=o.charCodeAt(l);n(new Blob([a],{type:t}))})},s.prototype.debug=function(){},t.exports=s},{"./lib/mathlib":1,"./lib/pool":9,"./lib/stepper":10,"./lib/tiler":11,"./lib/utils":12,"./lib/worker":13,"object-assign":24,webworkify:25}]},{},[])("/")}),define("WoltLabSuite/Core/Image/Resizer",["WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Image/ExifUtil","Pica"],function(e,t,i){"use strict";function n(){}var o=new i({features:["js","wasm","ww"]});return n.prototype={maxWidth:800,maxHeight:600,quality:.8,fileType:"image/jpeg",setMaxWidth:function(e){return null==e&&(e=n.prototype.maxWidth),this.maxWidth=e,this},setMaxHeight:function(e){return null==e&&(e=n.prototype.maxHeight),this.maxHeight=e,this},setQuality:function(e){return null==e&&(e=n.prototype.quality),this.quality=e,this},setFileType:function(e){return null==e&&(e=n.prototype.fileType),this.fileType=e,this},saveFile:function(i,n,r,a){r=r||this.fileType,a=a||this.quality;var l=n.match(/(.+)(\..+?)$/);return o.toBlob(i.image,r,a).then(function(e){return"image/jpeg"===r&&void 0!==i.exif?t.setExifData(e,i.exif):e}).then(function(t){return e.blobToFile(t,l[1])})},loadFile:function(e){var i=void 0,n=Promise.resolve(e);"image/jpeg"===e.type&&(i=t.getExifBytesFromJpeg(e),n=n.then(t.removeExifData.bind(t)));var n=n.then(function(e){return new Promise(function(t,i){var n=new FileReader,o=new Image;n.addEventListener("load",function(){o.src=n.result}),n.addEventListener("error",function(){n.abort(),i(n.error)}),o.addEventListener("error",i),o.addEventListener("load",function(){t(o)}),n.readAsDataURL(e)})});return Promise.all([i,n]).then(function(e){return{exif:e[0],image:e[1]}})},resize:function(e,t,i,n,r,a){t=t||this.maxWidth,i=i||this.maxHeight,n=n||this.quality,r=r||!1;var l=document.createElement("canvas"),s=window.createImageBitmap?createImageBitmap(e).then(function(t){if(t.height!=e.height)throw new Error("Chrome Bug #1069965")}):Promise.resolve(),c=Math.min(t,e.width),u=Math.min(i,e.height);if(e.width<=c&&e.height<=u&&!r)return Promise.resolve(void 0);var d=Math.min(c/e.width,u/e.height);l.width=Math.floor(e.width*d),l.height=Math.floor(e.height*d);var h=1;n>=.8?h=3:n>=.4&&(h=2);var f={quality:h,cancelToken:a,alpha:!0};return s.then(function(){return o.resize(e,l,f)})}},n}),define("WoltLabSuite/Core/Language/Chooser",["Core","Dictionary","Language","Dom/Traverse","Dom/Util","ObjectMap","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l=new t,s=!1,c=new r,u=null;return{init:function(e,t,i,n,o,r){if(!l.has(t)){var a=elById(e);if(null===a)throw new Error("Expected a valid container id, cannot find '"+t+"'.");var s=elById(t);null===s&&(s=elCreate("input"),elAttr(s,"type","hidden"),elAttr(s,"id",t),elAttr(s,"name",t),elAttr(s,"value",i),a.appendChild(s)),this._initElement(t,s,i,n,o,r)}},_setup:function(){s||(s=!0,u=this._submit.bind(this))},_initElement:function(e,t,r,s,d,h){var f
+;"DD"===t.parentNode.nodeName?(f=elCreate("div"),f.className="dropdown",o.prepend(f,t.parentNode)):(f=t.parentNode,f.classList.add("dropdown")),elHide(t);var p=elCreate("a");p.className="dropdownToggle dropdownIndicator boxFlag box24 inputPrefix"+("DD"===t.parentNode.nodeName?" button":""),f.appendChild(p);var g=elCreate("ul");g.className="dropdownMenu",f.appendChild(g);var m,v,b,_,w=function(t){var i=~~elData(t.currentTarget,"language-id"),o=n.childByClass(g,"active");null!==o&&o.classList.remove("active"),i&&t.currentTarget.classList.add("active"),this._select(e,i,t.currentTarget)}.bind(this);for(var y in s)if(s.hasOwnProperty(y)){var C=s[y];b=elCreate("li"),b.className="boxFlag",b.addEventListener(WCF_CLICK_EVENT,w),elData(b,"language-id",y),void 0!==C.languageCode&&elData(b,"language-code",C.languageCode),g.appendChild(b),m=elCreate("a"),m.className="box24",b.appendChild(m),v=elCreate("img"),elAttr(v,"src",C.iconPath),elAttr(v,"alt",""),v.className="iconFlag",m.appendChild(v),_=elCreate("span"),_.textContent=C.languageName,m.appendChild(_),y==r&&(p.innerHTML=b.firstChild.innerHTML)}if(h)b=elCreate("li"),b.className="dropdownDivider",g.appendChild(b),b=elCreate("li"),elData(b,"language-id",0),b.addEventListener(WCF_CLICK_EVENT,w),g.appendChild(b),m=elCreate("a"),m.textContent=i.get("wcf.global.language.noSelection"),b.appendChild(m),0===r&&(p.innerHTML=b.firstChild.innerHTML),b.addEventListener(WCF_CLICK_EVENT,w);else if(0===r){p.innerHTML=null;var E=elCreate("div");p.appendChild(E),_=elCreate("span"),_.className="icon icon24 fa-question pointer",E.appendChild(_),_=elCreate("span"),_.textContent=i.get("wcf.global.language.noSelection"),E.appendChild(_)}a.init(p),l.set(e,{callback:d,dropdownMenu:g,dropdownToggle:p,element:t});var L=n.parentByTag(t,"FORM");if(null!==L){L.addEventListener("submit",u);var A=c.get(L);void 0===A&&(A=[],c.set(L,A)),A.push(e)}},_select:function(t,i,n){var o=l.get(t);if(void 0===n){for(var r=o.dropdownMenu.childNodes,a=0,s=r.length;a<s;a++){var c=r[a];if(~~elData(c,"language-id")===i){n=c;break}}if(void 0===n)throw new Error("Cannot select unknown language id '"+i+"'")}o.element.value=i,e.triggerEvent(o.element,"change"),o.dropdownToggle.innerHTML=n.firstChild.innerHTML,l.set(t,o),"function"==typeof o.callback&&o.callback(n)},_submit:function(e){for(var t,i=c.get(e.currentTarget),n=0,o=i.length;n<o;n++)t=elCreate("input"),t.type="hidden",t.name=i[n],t.value=this.getLanguageId(i[n]),e.currentTarget.appendChild(t)},getChooser:function(e){var t=l.get(e);if(void 0===t)throw new Error("Expected a valid language chooser input element, '"+e+"' is not i18n input field.");return t},getLanguageId:function(e){return~~this.getChooser(e).element.value},removeChooser:function(e){l.has(e)&&l.delete(e)},setLanguageId:function(e,t){if(void 0===l.get(e))throw new Error("Expected a valid  input element, '"+e+"' is not i18n input field.");this._select(e,t)}}}),define("WoltLabSuite/Core/Language/Input",["Core","Dictionary","Language","ObjectMap","StringUtil","Dom/Traverse","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a,l){"use strict";var s=new t,c=!1,u=new n,d=new t,h=null,f=null;return{init:function(e,i,n,r){if(!d.has(e)){var a=elById(e);if(null===a)throw new Error("Expected a valid element id, cannot find '"+e+"'.");this._setup();var l=new t;for(var s in i)i.hasOwnProperty(s)&&l.set(~~s,o.unescapeHTML(i[s]));d.set(e,l),this._initElement(e,a,l,n,r)}},registerCallback:function(e,t,i){if(!d.has(e))throw new Error("Unknown element id '"+e+"'.");s.get(e).callbacks.set(t,i)},unregister:function(e){if(!d.has(e))throw new Error("Unknown element id '"+e+"'.");d.delete(e),s.delete(e)},_setup:function(){c||(c=!0,h=this._dropdownToggle.bind(this),f=this._submit.bind(this))},_initElement:function(e,n,o,c,d){var p=n.parentNode;if(!p.classList.contains("inputAddon")){p=elCreate("div"),p.className="inputAddon"+("TEXTAREA"===n.nodeName?" inputAddonTextarea":""),elData(p,"input-id",e);var g=document.activeElement===n;n.parentNode.insertBefore(p,n),p.appendChild(n),g&&n.focus()}p.classList.add("dropdown");var m=elCreate("span");m.className="button dropdownToggle inputPrefix";var v=elCreate("span");v.textContent=i.get("wcf.global.button.disabledI18n"),m.appendChild(v),p.insertBefore(m,n);var b=elCreate("ul");b.className="dropdownMenu",a.insertAfter(b,m);var _,w=function(t,i){var n=~~elData(t.currentTarget,"language-id"),o=r.childByClass(b,"active");null!==o&&o.classList.remove("active"),n&&t.currentTarget.classList.add("active"),this._select(e,n,i||!1)}.bind(this);for(var y in c)c.hasOwnProperty(y)&&(_=elCreate("li"),elData(_,"language-id",y),v=elCreate("span"),v.textContent=c[y],_.appendChild(v),_.addEventListener(WCF_CLICK_EVENT,w),b.appendChild(_));!0!==d&&(_=elCreate("li"),_.className="dropdownDivider",b.appendChild(_),_=elCreate("li"),elData(_,"language-id",0),v=elCreate("span"),v.textContent=i.get("wcf.global.button.disabledI18n"),_.appendChild(v),_.addEventListener(WCF_CLICK_EVENT,w),b.appendChild(_));var C=null;if(!0===d||o.size)for(var E=0,L=b.childElementCount;E<L;E++)if(~~elData(b.children[E],"language-id")===LANGUAGE_ID){C=b.children[E];break}l.init(m),l.registerCallback(p.id,h),s.set(e,{buttonLabel:m.children[0],callbacks:new t,element:n,languageId:0,isEnabled:!0,forceSelection:d});var A=r.parentByTag(n,"FORM");if(null!==A){A.addEventListener("submit",f);var S=u.get(A);void 0===S&&(S=[],u.set(A,S)),S.push(e)}null!==C&&w({currentTarget:C},!0)},_select:function(e,i,n){for(var o,r=s.get(e),a=l.getDropdownMenu(r.element.closest(".inputAddon").id),c="",u=0,h=a.childElementCount;u<h;u++){o=a.children[u];var f=elData(o,"language-id");f.length&&i===~~f&&(c=o.children[0].textContent)}if(r.languageId!==i){var p=d.get(e);r.languageId&&p.set(r.languageId,r.element.value),0===i?d.set(e,new t):(r.buttonLabel.classList.contains("active")||!0===n)&&(r.element.value=p.has(i)?p.get(i):""),r.buttonLabel.textContent=c,r.buttonLabel.classList[i?"add":"remove"]("active"),r.languageId=i}n||(r.element.blur(),r.element.focus()),r.callbacks.has("select")&&r.callbacks.get("select")(r.element)},_dropdownToggle:function(e,t){if("open"===t)for(var i,n,o=l.getDropdownMenu(e),r=elData(elById(e),"input-id"),a=s.get(r),c=d.get(r),u=0,h=o.childElementCount;u<h;u++)if(i=o.children[u],n=~~elData(i,"language-id")){var f=!1;a.languageId&&(f=n===a.languageId?""===a.element.value.trim():!c.get(n)),i.classList[f?"add":"remove"]("missingValue")}},_submit:function(e){for(var t,i,n,o,r=u.get(e.currentTarget),a=0,l=r.length;a<l;a++)i=r[a],t=s.get(i),t.isEnabled&&(o=d.get(i),t.callbacks.has("submit")&&t.callbacks.get("submit")(t.element),t.languageId&&o.set(t.languageId,t.element.value),o.size&&(o.forEach(function(t,o){n=elCreate("input"),n.type="hidden",n.name=i+"_i18n["+o+"]",n.value=t,e.currentTarget.appendChild(n)}),t.element.removeAttribute("name")))},getValues:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");var i=d.get(e);return i.set(t.languageId,t.element.value),i},setValues:function(i,n){var o=s.get(i);if(void 0===o)throw new Error("Expected a valid i18n input element, '"+i+"' is not i18n input field.");if(e.isPlainObject(n)&&(n=t.fromObject(n)),o.element.value="",n.has(0))return o.element.value=n.get(0),n.delete(0),d.set(i,n),void this._select(i,0,!0);d.set(i,n),o.languageId=0,this._select(i,LANGUAGE_ID,!0)},disable:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid element, '"+e+"' is not an i18n input field.");if(t.isEnabled){t.isEnabled=!1,elHide(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.remove("inputAddon"),i.classList.remove("dropdown")}},enable:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!t.isEnabled){t.isEnabled=!0,elShow(t.buttonLabel.parentNode);var i=t.buttonLabel.parentNode.parentNode;i.classList.add("inputAddon"),i.classList.add("dropdown")}},isEnabled:function(e){var t=s.get(e);if(void 0===t)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");return t.isEnabled},validate:function(e,t){var i=s.get(e);if(void 0===i)throw new Error("Expected a valid i18n input element, '"+e+"' is not i18n input field.");if(!i.isEnabled)return!0;var n=d.get(e),o=l.getDropdownMenu(i.element.parentNode.id);i.languageId&&n.set(i.languageId,i.element.value);for(var r,a,c=!1,u=!1,h=0,f=o.childElementCount;h<f;h++)if(r=o.children[h],a=~~elData(r,"language-id"))if(n.has(a)&&0!==n.get(a).length){if(c)return!1;u=!0}else{if(u)return!1;c=!0}return!c||t}}}),define("WoltLabSuite/Core/Language/Text",["Core","./Input"],function(e,t){"use strict";return{init:function(e,i,n,o){var r=elById(e);if(!r||"TEXTAREA"!==r.nodeName||!r.classList.contains("wysiwygTextarea"))throw new Error('Expected <textarea class="wysiwygTextarea" /> for id \''+e+"'.");t.init(e,i,n,o),t.registerCallback(e,"select",this._callbackSelect.bind(this)),t.registerCallback(e,"submit",this._callbackSubmit.bind(this))},_callbackSelect:function(e){void 0!==window.jQuery&&window.jQuery(e).redactor("code.set",e.value)},_callbackSubmit:function(e){void 0!==window.jQuery&&(e.value=window.jQuery(e).redactor("code.get"))}}}),define("WoltLabSuite/Core/Media/Upload",["Core","DateUtil","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","Permission","Upload","User","WoltLabSuite/Core/FileUtil"],function(e,t,i,n,o,r,a,l,s,c,u){"use strict";var d=function(){};return d.prototype={_createFileElement:function(){},_getParameters:function(){},_success:function(){},_uploadFiles:function(){},_createButton:function(){},_createFileElements:function(){},_failure:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){},_upload:function(){}},d}),define("WoltLabSuite/Core/Media/Replace",["Core","Dom/ChangeListener","Dom/Util","Language","Ui/Notification","./Upload"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={_createButton:function(){},_success:function(){},_upload:function(){},_createFileElement:function(){},_getParameters:function(){},_uploadFiles:function(){},_createFileElements:function(){},_failure:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){}},a}),define("WoltLabSuite/Core/Media/Editor",["Ajax","Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Language/Chooser","WoltLabSuite/Core/Language/Input","EventKey","WoltLabSuite/Core/Media/Replace"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={_ajaxSetup:function(){},_ajaxSuccess:function(){},_close:function(){},_keyPress:function(){},_saveData:function(){},_updateLanguageFields:function(){},edit:function(){}},f}),define("WoltLabSuite/Core/Media/List/Upload",["Core","Dom/Util","../Upload"],function(e,t,i){"use strict";var n=function(){};return n.prototype={_createButton:function(){},_success:function(){},_upload:function(){},_createFileElement:function(){},_getParameters:function(){},_uploadFiles:function(){},_createFileElements:function(){},_failure:function(){},_insertButton:function(){},_progress:function(){},_removeButton:function(){}},n}),define("WoltLabSuite/Core/Media/Clipboard",["Ajax","Dom/ChangeListener","EventHandler","Language","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=function(){};return c.prototype={init:function(){},_ajaxSetup:function(){},_ajaxSuccess:function(){},_clipboardAction:function(){},_dialogSetup:function(){},_edit:function(){},_setCategory:function(){}},c}),define("WoltLabSuite/Core/Notification/Handler",["Ajax","Core","EventHandler","StringUtil"],function(e,t,i,n){"use strict";if(!("Promise"in window&&"Notification"in window))return{setup:function(){}};var o=!1,r="",a=0,l=window.TIME_NOW,s=null,c=0;return{setup:function(e){if(e=t.extend({enableNotifications:!1,icon:"",sessionKeepAlive:0},e),r=e.icon,c=60*e.sessionKeepAlive,this._prepareNextRequest(),document.addEventListener("visibilitychange",this._onVisibilityChange.bind(this)),window.addEventListener("storage",this._onStorage.bind(this)),this._onVisibilityChange(null),e.enableNotifications)switch(window.Notification.permission){case"granted":o=!0;break;case"default":window.Notification.requestPermission(function(e){"granted"===e&&(o=!0)})}},_onVisibilityChange:function(e){if(null!==e&&!document.hidden){(Date.now()-a)/6e4>4&&(this._resetTimer(),this._dispatchRequest())}a=document.hidden?Date.now():0},_getNextDelay:function(){if(0===a)return 5;var e=~~((Date.now()-a)/6e4);return e<15?5:e<30?10:15},_resetTimer:function(){null!==s&&(window.clearTimeout(s),s=null)},_prepareNextRequest:function(){this._resetTimer();var e=Math.min(this._getNextDelay(),c);s=window.setTimeout(this._dispatchRequest.bind(this),6e4*e)},_dispatchRequest:function(){var t={};i.fire("com.woltlab.wcf.notification","beforePoll",t),t.lastRequestTimestamp=l,e.api(this,{parameters:t})},_onStorage:function(){this._prepareNextRequest();var e,n,o=!1;try{e=window.localStorage.getItem(t.getStoragePrefix()+"notification"),n=window.localStorage.getItem(t.getStoragePrefix()+"keepAliveData"),e=JSON.parse(e),n=JSON.parse(n)}catch(e){o=!0}o||i.fire("com.woltlab.wcf.notification","onStorage",{pollData:e,keepAliveData:n})},_ajaxSuccess:function(e){var n=!1,o=e.returnValues.keepAliveData,r=e.returnValues.pollData;window.WCF.System.PushNotification.executeCallbacks({returnValues:o});try{window.localStorage.setItem(t.getStoragePrefix()+"notification",JSON.stringify(r)),window.localStorage.setItem(t.getStoragePrefix()+"keepAliveData",JSON.stringify(o))}catch(e){n=!0,window.console.log(e)}n||this._prepareNextRequest(),l=e.returnValues.lastRequestTimestamp,i.fire("com.woltlab.wcf.notification","afterPoll",r),this._showNotification(r)},_showNotification:function(e){if(o&&"object"==typeof e.notification&&"string"==typeof e.notification.message){var t=new window.Notification(e.notification.title,{body:n.unescapeHTML(e.notification.message).replace(/&#x202F;/g," "),icon:r});t.onclick=function(){window.focus(),t.close(),window.location=e.notification.link}}},_ajaxSetup:function(){return{data:{actionName:"poll",className:"wcf\\data\\session\\SessionAction"},ignoreError:!window.ENABLE_DEBUG_MODE,silent:!window.ENABLE_DEBUG_MODE}}}}),define("WoltLabSuite/Core/Ui/Redactor/DragAndDrop",["Dictionary","EventHandler","Language"],function(e,t,i){"use strict";var n=function(){};return n.prototype={init:function(){},_dragOver:function(){},_drop:function(){},_dragLeave:function(){},_setup:function(){}},n}),define("WoltLabSuite/Core/Ui/DragAndDrop",["Core","EventHandler","WoltLabSuite/Core/Ui/Redactor/DragAndDrop"],function(e,t,i){return{register:function(n){var o=e.getUuid();n=e.extend({element:"",elementId:"",onDrop:function(e){},onGlobalDrop:function(e){}}),t.add("com.woltlab.wcf.redactor2","dragAndDrop_"+n.elementId,n.onDrop),t.add("com.woltlab.wcf.redactor2","dragAndDrop_globalDrop_"+n.elementId,n.onGlobalDrop),i.init({uuid:o,$editor:[n.element],$element:[{id:n.elementId}]})}}}),define("WoltLabSuite/Core/Ui/Suggestion",["Ajax","Core","Ui/SimpleDropdown"],function(e,t,i){"use strict";function n(e,t){this.init(e,t)}return n.prototype={init:function(e,i){if(this._dropdownMenu=null,this._value="",this._element=elById(e),null===this._element)throw new Error("Expected a valid element id.");if(this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction",parameters:{data:{}}},callbackSelect:null,excludedSearchValues:[],threshold:3},i),"function"!=typeof this._options.callbackSelect)throw new Error("Expected a valid callback for option 'callbackSelect'.");this._element.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),this._element.addEventListener("keydown",this._keyDown.bind(this)),this._element.addEventListener("keyup",this._keyUp.bind(this))},addExcludedValue:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedValue:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},isActive:function(){return null!==this._dropdownMenu&&i.isOpen(this._element.id)},_keyDown:function(e){if(!this.isActive())return!0;if(13!==e.keyCode&&27!==e.keyCode&&38!==e.keyCode&&40!==e.keyCode)return!0;for(var t,n=0,o=this._dropdownMenu.childElementCount;n<o&&(t=this._dropdownMenu.children[n],!t.classList.contains("active"));)n++;if(13===e.keyCode)i.close(this._element.id),this._select(t);else if(27===e.keyCode){if(!i.isOpen(this._element.id))return!0;i.close(this._element.id)}else{var r=0;38===e.keyCode?r=(0===n?o:n)-1:40===e.keyCode&&(r=n+1)===o&&(r=0),r!==n&&(t.classList.remove("active"),this._dropdownMenu.children[r].classList.add("active"))}return e.preventDefault(),!1},_select:function(e){var t=e instanceof Event;t&&(e=e.currentTarget.parentNode);var i=e.children[0];this._options.callbackSelect(this._element.id,{objectId:elData(i,"object-id"),value:e.textContent,type:elData(i,"type")}),t&&this._element.focus()},_keyUp:function(t){var n=t.currentTarget.value.trim();if(this._value!==n){if(n.length<this._options.threshold)return null!==this._dropdownMenu&&i.close(this._element.id),void(this._value=n);this._value=n,e.api(this,{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:n}}})}},_ajaxSetup:function(){return{data:this._options.ajax}},_ajaxSuccess:function(e){if(null===this._dropdownMenu?(this._dropdownMenu=elCreate("div"),this._dropdownMenu.className="dropdownMenu",i.initFragment(this._element,this._dropdownMenu)):this._dropdownMenu.innerHTML="",e.returnValues.length){for(var t,n,o,r=0,a=e.returnValues.length;r<a;r++)n=e.returnValues[r],t=elCreate("a"),n.icon?(t.className="box16",t.innerHTML=n.icon+" <span></span>",t.children[1].textContent=n.label):t.textContent=n.label,elData(t,"object-id",n.objectID),n.type&&elData(t,"type",n.type),t.addEventListener(WCF_CLICK_EVENT,this._select.bind(this)),o=elCreate("li"),0===r&&(o.className="active"),o.appendChild(t),this._dropdownMenu.appendChild(o);i.open(this._element.id,!0)}else i.close(this._element.id)}},n}),define("WoltLabSuite/Core/Ui/ItemList",["Core","Dictionary","Language","Dom/Traverse","EventKey","WoltLabSuite/Core/Ui/Suggestion","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l="",s=new t,c=!1,u=null,d=null,h=null,f=null,p=null,g=null;return{init:function(t,i,o){var l=elById(t);if(null===l)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(s.has(t)){var c=s.get(t);for(var u in c)if(c.hasOwnProperty(u)){var d=c[u];d instanceof Element&&d.parentNode&&elRemove(d)}a.destroy(t),s.delete(t)}o=e.extend({ajax:{actionName:"getSearchResultList",className:"",data:{}},excludedSearchValues:[],maxItems:-1,maxLength:-1,restricted:!1,isCSV:!1,callbackChange:null,callbackSubmit:null,callbackSyncShadow:null,callbackSetupValues:null,submitFieldName:""},o);var h=n.parentByTag(l,"FORM");if(null!==h)if(!1===o.isCSV){if(!o.submitFieldName.length&&"function"!=typeof o.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=s.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}var i=this.getValues(t);if(o.submitFieldName.length)for(var n,r=0,a=i.length;r<a;r++)n=elCreate("input"),n.type="hidden",n.name=o.submitFieldName.replace("{$objectId}",i[r].objectId),n.value=i[r].value,h.appendChild(n);else o.callbackSubmit(h,i)}.bind(this))}else h.addEventListener("submit",function(){if(this._acceptsNewItems(t)){var e=s.get(t).element.value.trim();e.length&&this._addItem(t,{objectId:0,value:e})}}.bind(this));this._setup();var f=this._createUI(l,o),p=new r(t,{ajax:o.ajax,callbackSelect:this._addItem.bind(this),excludedSearchValues:o.excludedSearchValues});if(s.set(t,{dropdownMenu:null,element:f.element,limitReached:f.limitReached,list:f.list,listItem:f.element.parentNode,options:o,shadow:f.shadow,suggestion:p}),i=o.callbackSetupValues?o.callbackSetupValues():f.values.length?f.values:i,Array.isArray(i))for(var g,m=0,v=i.length;m<v;m++)g=i[m],"string"==typeof g&&(g={objectId:0,value:g}),this._addItem(t,g)},getValues:function(e){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=s.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent.trim(),type:elData(e,"type")})}),i},setValues:function(e,t){if(!s.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,o,r=s.get(e),a=n.childrenByClass(r.list,"item");for(i=0,o=a.length;i<o;i++)this._removeItem(null,a[i],!0);for(i=0,o=t.length;i<o;i++)this._addItem(e,t[i])},_setup:function(){c||(c=!0,u=this._keyDown.bind(this),d=this._keyPress.bind(this),h=this._keyUp.bind(this),f=this._paste.bind(this),p=this._removeItem.bind(this),g=this._blur.bind(this))},_createUI:function(e,t){var n=elCreate("ol");n.className="inputItemList"+(e.disabled?" disabled":""),elData(n,"element-id",e.id),n.addEventListener(WCF_CLICK_EVENT,function(t){t.target===n&&e.focus()});var o=elCreate("li");o.className="input",n.appendChild(o),e.addEventListener("keydown",u),e.addEventListener("keypress",d),e.addEventListener("keyup",h),e.addEventListener("paste",f);var r=e===document.activeElement;r&&e.blur(),e.addEventListener("blur",g),e.parentNode.insertBefore(n,e),o.appendChild(e),r&&window.setTimeout(function(){e.focus()},1),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var a=elCreate("span");a.className="inputItemListLimitReached",a.textContent=i.get("wcf.global.form.input.maxItems"),elHide(a),o.appendChild(a);var l=null,s=[];if(t.isCSV){l=elCreate("input"),l.className="itemListInputShadow",l.type="hidden",l.name=e.name,e.removeAttribute("name"),n.parentNode.insertBefore(l,n);for(var c,p=e.value.split(","),m=0,v=p.length;m<v;m++)c=p[m].trim(),c.length&&s.push(c);if("TEXTAREA"===e.nodeName){var b=elCreate("input");b.type="text",e.parentNode.insertBefore(b,e),b.id=e.id,elRemove(e),e=b}}return{element:e,limitReached:a,list:n,shadow:l,values:s}},_acceptsNewItems:function(e){var t=s.get(e);return-1===t.options.maxItems||t.list.childElementCount-1<t.options.maxItems},_handleLimit:function(e){var t=s.get(e);this._acceptsNewItems(e)?(elShow(t.element),elHide(t.limitReached)):(elHide(t.element),elShow(t.limitReached))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;l=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(o.Enter(e)||o.Comma(e)){if(e.preventDefault(),s.get(e.currentTarget.id).options.restricted)return;var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain");var i=e.currentTarget,n=i.id,o=~~elAttr(i,"maxLength");t.split(/,/).forEach(function(e){e=e.trim(),o&&e.length>o&&(e=e.substr(0,o)),e.length>0&&this._acceptsNewItems(n)&&this._addItem(n,{objectId:0,value:e})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t){var i=s.get(e),n=elCreate("li");n.className="item";var o=elCreate("span");if(o.className="content",elData(o,"object-id",t.objectId),t.type&&elData(o,"type",t.type),o.textContent=t.value,n.appendChild(o),!i.element.disabled){var r=elCreate("a");r.className="icon icon16 fa-times",r.addEventListener(WCF_CLICK_EVENT,p),n.appendChild(r)}i.list.insertBefore(n,i.listItem),i.suggestion.addExcludedValue(t.value),i.element.value="",i.element.disabled||this._handleLimit(e);var a=this._syncShadow(i);"function"==typeof i.options.callbackChange&&(null===a&&(a=this.getValues(e)),i.options.callbackChange(e,a))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,o=elData(n,"element-id"),r=s.get(o);r.suggestion.removeExcludedValue(t.children[0].textContent),n.removeChild(t),i||r.element.focus(),this._handleLimit(o);var a=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===a&&(a=this.getValues(o)),r.options.callbackChange(o,a))},_syncShadow:function(e){if(!e.options.isCSV)return null;if("function"==typeof e.options.callbackSyncShadow)return e.options.callbackSyncShadow(e);for(var t="",i=this.getValues(e.element.id),n=0,o=i.length;n<o;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=e.currentTarget,i=s.get(t.id);if(!i.options.restricted){var n=t.value.trim();n.length&&(i.suggestion&&i.suggestion.isActive()||this._addItem(t.id,{objectId:0,value:n}))}}}}),define("WoltLabSuite/Core/Ui/Page/JumpTo",["Language","ObjectMap","Ui/Dialog"],function(e,t,i){"use strict";var n=null,o=null,r=null,a=new t,l=null;return{init:function(e,t){if(null===(t=t||null)){var i=elData(e,"link");t=i?function(e){window.location=i.replace(/pageNo=%d/,"pageNo="+e)}:function(){}}else if("function"!=typeof t)throw new TypeError("Expected a valid function for parameter 'callback'.");a.has(e)||elBySelAll(".jumpTo",e,function(i){i.addEventListener(WCF_CLICK_EVENT,this._click.bind(this,e)),a.set(e,{callback:t})}.bind(this))},_click:function(t,o){n=t,"object"==typeof o&&o.preventDefault(),i.open(this);var a=elData(t,"pages");l.value=a,l.setAttribute("max",a),l.select(),r.textContent=e.get("wcf.page.jumpTo.description").replace(/#pages#/,a)},_keyUp:function(e){if(13===e.which&&!1===o.disabled)return void this._submit();var t=~~l.value;t<1||t>~~elAttr(l,"max")?o.disabled=!0:o.disabled=!1},_submit:function(e){a.get(n).callback(~~l.value),i.close(this)},_dialogSetup:function(){var t='<dl><dt><label for="jsPaginationPageNo">'+e.get("wcf.page.jumpTo")+'</label></dt><dd><input type="number" id="jsPaginationPageNo" value="1" min="1" max="1" class="tiny"><small></small></dd></dl><div class="formSubmit"><button class="buttonPrimary">'+e.get("wcf.global.button.submit")+"</button></div>";return{id:"paginationOverlay",options:{onSetup:function(e){l=elByTag("input",e)[0],l.addEventListener("keyup",this._keyUp.bind(this)),r=elByTag("small",e)[0],o=elByTag("button",e)[0],o.addEventListener(WCF_CLICK_EVENT,this._submit.bind(this))}.bind(this),title:e.get("wcf.global.page.pagination")},source:t}}}}),define("WoltLabSuite/Core/Ui/Pagination",["Core","Language","ObjectMap","StringUtil","WoltLabSuite/Core/Ui/Page/JumpTo"],function(e,t,i,n,o){"use strict";function r(e,t){this.init(e,t)}return r.prototype={SHOW_LINKS:11,init:function(t,i){this._element=t,this._options=e.extend({activePage:1,maxPage:1,callbackShouldSwitch:null,callbackSwitch:null},i),"function"!=typeof this._options.callbackShouldSwitch&&(this._options.callbackShouldSwitch=null),"function"!=typeof this._options.callbackSwitch&&(this._options.callbackSwitch=null),this._element.classList.add("pagination"),this._rebuild(this._element)},_rebuild:function(){var e=!1;this._element.innerHTML="";var i,n=elCreate("ul"),r=elCreate("li");r.className="skip",n.appendChild(r);var a="icon icon24 fa-chevron-left";this._options.activePage>1?(i=elCreate("a"),i.className=a+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.previous"),i.rel="prev",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage-1))):(r.innerHTML='<span class="'+a+'"></span>',r.classList.add("disabled")),n.appendChild(this._createLink(1));var l=this.SHOW_LINKS-4,s=this._options.activePage-2;s<0&&(s=0);var c=this._options.maxPage-(this._options.activePage+1);c<0&&(c=0),this._options.activePage>1&&this._options.activePage<this._options.maxPage&&l--;var u=l/2,d=this._options.activePage,h=this._options.activePage;d<1&&(d=1),h<1&&(h=1),h>this._options.maxPage-1&&(h=this._options.maxPage-1),s>=u?d-=u:(d-=s,h+=u-s),c>=u?h+=u:(h+=c,d-=u-c),h=Math.ceil(h),d=Math.ceil(d),d<1&&(d=1),h>this._options.maxPage&&(h=this._options.maxPage);var f='<a class="jsTooltip" title="'+t.get("wcf.page.jumpTo")+'">&hellip;</a>';d>1&&(d-1<2?n.appendChild(this._createLink(2)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=f,n.appendChild(r),e=!0));for(var p=d+1;p<h;p++)n.appendChild(this._createLink(p));h<this._options.maxPage&&(this._options.maxPage-h<2?n.appendChild(this._createLink(this._options.maxPage-1)):(r=elCreate("li"),r.className="jumpTo",r.innerHTML=f,n.appendChild(r),e=!0)),n.appendChild(this._createLink(this._options.maxPage)),r=elCreate("li"),r.className="skip",n.appendChild(r),a="icon icon24 fa-chevron-right",this._options.activePage<this._options.maxPage?(i=elCreate("a"),i.className=a+" jsTooltip",i.href="#",i.title=t.get("wcf.global.page.next"),i.rel="next",r.appendChild(i),i.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,this._options.activePage+1))):(r.innerHTML='<span class="'+a+'"></span>',r.classList.add("disabled")),e&&(elData(n,"pages",this._options.maxPage),o.init(n,this.switchPage.bind(this))),this._element.appendChild(n)},_createLink:function(e){var i=elCreate("li");if(e!==this._options.activePage){var o=elCreate("a");o.textContent=n.addThousandsSeparator(e),o.addEventListener(WCF_CLICK_EVENT,this.switchPage.bind(this,e)),i.appendChild(o)}else i.classList.add("active"),i.innerHTML="<span>"+n.addThousandsSeparator(e)+'</span><span class="invisible">'+t.get("wcf.page.pagePosition",{pageNo:e,pages:this._options.maxPage})+"</span>";return i},getActivePage:function(){return this._options.activePage},getElement:function(){return this._element},getMaxPage:function(){return this._options.maxPage},switchPage:function(t,i){if("object"==typeof i&&(i.preventDefault(),i.currentTarget&&elData(i.currentTarget,"tooltip"))){var n=elById("balloonTooltip");n&&(e.triggerEvent(i.currentTarget,"mouseleave"),n.style.removeProperty("top"),n.style.removeProperty("bottom"))}if((t=~~t)>0&&this._options.activePage!==t&&t<=this._options.maxPage){if(null!==this._options.callbackShouldSwitch&&!0!==this._options.callbackShouldSwitch(t))return;this._options.activePage=t,this._rebuild(),null!==this._options.callbackSwitch&&this._options.callbackSwitch(t)}}},r}),define("WoltLabSuite/Core/Wrapper/FacebookSdk",["https://connect.facebook.net/en_US/sdk.js"],function(e){"use strict";return FB.init({version:"v7.0"}),FB}),define("WoltLabSuite/Core/Controller/Media/List",["Dom/ChangeListener","EventHandler","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/List/Upload"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},_addButtonEventListeners:function(){},_deleteCallback:function(){},_deleteMedia:function(e){},_edit:function(){}},a}),define("WoltLabSuite/Core/Controller/Notice/Dismiss",["Ajax"],function(e){"use strict";return{setup:function(){var e=elByClass("jsDismissNoticeButton");if(e.length)for(var t=this._click.bind(this),i=0,n=e.length;i<n;i++)e[i].addEventListener(WCF_CLICK_EVENT,t)},_click:function(t){var i=t.currentTarget;e.apiOnce({data:{actionName:"dismiss",className:"wcf\\data\\notice\\NoticeAction",objectIDs:[elData(i,"object-id")]},success:function(){elRemove(i.parentNode)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager",["Dictionary","Dom/ChangeListener","EventHandler","List","Dom/Util","ObjectMap"],function(e,t,i,n,o,r){"use strict";var a=!1,l=!0,s=new n,c=new e,u=new n,d=new e,h=new r;return{
+_hide:function(t){elHide(t),s.add(t),t.classList.contains("tabMenuContent")&&elBySelAll("li",t.parentNode.querySelector(".tabMenu"),function(e){elData(e,"name")===elData(t,"name")&&elHide(e)}),elBySelAll("[max], [maxlength], [min], [required]",t,function(t){var i=new e,n=elAttr(t,"max");n&&(i.set("max",n),t.removeAttribute("max"));var o=elAttr(t,"maxlength");o&&(i.set("maxlength",o),t.removeAttribute("maxlength"));var r=elAttr(t,"min");r&&(i.set("min",r),t.removeAttribute("min")),t.required&&(i.set("required",!0),t.removeAttribute("required")),h.set(t,i)})},_show:function(e){elShow(e),s.delete(e),e.classList.contains("tabMenuContent")&&elBySelAll("li",e.parentNode.querySelector(".tabMenu"),function(t){elData(t,"name")===elData(e,"name")&&elShow(t)}),elBySelAll("input, select",e,function(t){for(var i=t.parentNode;i!==e&&"none"!==i.style.getPropertyValue("display");)i=i.parentNode;if(i===e&&h.has(t)){var n=h.get(t);n.has("max")&&elAttr(t,"max",n.get("max")),n.has("maxlength")&&elAttr(t,"maxlength",n.get("maxlength")),n.has("min")&&elAttr(t,"min",n.get("min")),n.has("required")&&elAttr(t,"required",""),h.delete(t)}})},addDependency:function(e){var t=e.getDependentNode();d.has(t.id)?d.get(t.id).push(e):d.set(t.id,[e]);for(var i=e.getFields(),n=0,r=i.length;n<r;n++){var a=i[n],l=o.identify(a);c.has(l)||(c.set(l,a),"INPUT"!==a.tagName||"checkbox"!==a.type&&"radio"!==a.type&&"hidden"!==a.type?a.addEventListener("input",this.checkDependencies.bind(this)):a.addEventListener("change",this.checkDependencies.bind(this)))}},checkDependencies:function(){var e=[];d.forEach(function(t,i){var n=elById(i);if(null===n)return void e.push(i);for(var o=0,r=t.length;o<r;o++)if(!t[o].checkDependency())return void this._hide(n);this._show(n)}.bind(this));for(var t=0,i=e.length;t<i;t++)d.delete(e[t]);this.checkContainers()},addContainerCheckCallback:function(e){if("function"!=typeof e)throw new TypeError("Expected a valid callback for parameter 'callback'.");i.add("com.woltlab.wcf.form.builder.dependency","checkContainers",e)},checkContainers:function(){if(!0===a)return void(l=!0);a=!0,l=!1,i.fire("com.woltlab.wcf.form.builder.dependency","checkContainers"),a=!1,l&&this.checkContainers()},isHiddenByDependencies:function(e){if(s.has(e))return!0;var t=!1;return s.forEach(function(i){o.contains(i,e)&&(t=!0)}),t},register:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(u.has(t))throw new Error("Form with id '"+e+"' has already been registered.");u.add(t)},unregister:function(e){var t=elById(e);if(null===t)throw new Error("Unknown element with id '"+e+"'");if(!u.has(t))throw new Error("Form with id '"+e+"' has not been registered.");u.delete(t),s.forEach(function(e){t.contains(e)&&s.delete(e)}),d.forEach(function(e,i){t.contains(elById(i))&&d.delete(i);for(var n=0,o=e.length;n<o;n++)for(var r=e[n].getFields(),a=0,l=r.length;a<l;a++){var s=r[a];c.delete(s.id),h.delete(s)}})}}}),define("WoltLabSuite/Core/Form/Builder/Field/Field",[],function(){"use strict";function e(e){this.init(e)}return e.prototype={init:function(e){this._fieldId=e,this._readField()},_getData:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Field._getData!")},_readField:function(){if(this._field=elById(this._fieldId),null===this._field)throw new Error("Unknown field with id '"+this._fieldId+"'.")},destroy:function(){},getData:function(){return Promise.resolve(this._getData())},getId:function(){return this._fieldId}},e}),define("WoltLabSuite/Core/Form/Builder/Manager",["Core","Dictionary","EventHandler","./Field/Dependency/Manager","./Field/Field"],function(e,t,i,n,o){"use strict";var r=new t,a=new t;return{getData:function(t){if(!this.hasForm(t))throw new Error("Unknown form with id '"+t+"'.");var i=[];return r.get(t).forEach(function(e){var t=e.getData();if(!(t instanceof Promise))throw new TypeError("Data for field with id '"+e.getId()+"' is no promise.");i.push(t)}),Promise.all(i).then(function(t){for(var i={},n=0,o=t.length;n<o;n++)i=e.extend(i,t[n]);return i})},getField:function(e,t){if(!this.hasField(e,t))throw new Error("Unknown field with id '"+e+"' for form with id '"+t+"'.");return r.get(e).get(t)},getForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return a.get(e)},hasField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");return r.get(e).has(t)},hasForm:function(e){return a.has(e)},registerField:function(e,t){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");if(!(t instanceof o))throw new Error("Add field is no instance of 'WoltLabSuite/Core/Form/Builder/Field/Field'.");var n=t.getId();if(this.hasField(e,n))throw new Error("Form field with id '"+n+"' has already been registered for form with id '"+e+"'.");r.get(e).set(n,t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerField",{field:t,formId:e})},registerForm:function(e){if(this.hasForm(e))throw new Error("Form with id '"+e+"' has already been registered.");var n=elById(e);if(null===n)throw new Error("Unknown form with id '"+e+"'.");a.set(e,n),r.set(e,new t),i.fire("WoltLabSuite/Core/Form/Builder/Manager","registerForm",{formId:e})},unregisterForm:function(e){if(!this.hasForm(e))throw new Error("Unknown form with id '"+e+"'.");i.fire("WoltLabSuite/Core/Form/Builder/Manager","beforeUnregisterForm",{formId:e}),a.delete(e),r.get(e).forEach(function(e){e.destroy()}),r.delete(e),n.unregister(e),i.fire("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",{formId:e})}}}),define("WoltLabSuite/Core/Form/Builder/Dialog",["Ajax","Core","./Manager","Ui/Dialog"],function(e,t,i,n){"use strict";function o(e,t,i,n){this.init(e,t,i,n)}return o.prototype={init:function(e,i,n,o){this._dialogId=e,this._className=i,this._actionName=n,this._options=t.extend({actionParameters:{},destroyOnClose:!1,usesDboAction:this._className.match(/\w+\\data\\/)},o),this._options.dialog=t.extend(this._options.dialog||{},{onClose:this._dialogOnClose.bind(this)}),this._formId="",this._dialogContent=""},_ajaxSetup:function(){var e={data:{actionName:this._actionName,className:this._className,parameters:this._options.actionParameters}};return this._options.usesDboAction||(e.url="index.php?ajax-invoke/&t="+SECURITY_TOKEN,e.withCredentials=!0),e},_ajaxSuccess:function(e){switch(e.actionName){case this._actionName:if(void 0===e.returnValues)throw new Error("Missing return data.");if(void 0===e.returnValues.dialog)throw new Error("Missing dialog template in return data.");if(void 0===e.returnValues.formId)throw new Error("Missing form id in return data.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog);break;case this._options.submitActionName:if(e.returnValues&&e.returnValues.formId&&e.returnValues.dialog){if(e.returnValues.formId!==this._formId)throw new Error("Mismatch between form ids: expected '"+this._formId+"' but got '"+e.returnValues.formId+"'.");this._openDialogContent(e.returnValues.formId,e.returnValues.dialog)}else this.destroy(),"function"==typeof this._options.successCallback&&this._options.successCallback(e.returnValues||{});break;default:throw new Error("Cannot handle action '"+e.actionName+"'.")}},_closeDialog:function(){n.close(this),"function"==typeof this._options.closeCallback&&this._options.closeCallback()},_dialogOnClose:function(){this._options.destroyOnClose&&this.destroy()},_dialogSetup:function(){return{id:this._dialogId,options:this._options.dialog,source:this._dialogContent}},_dialogSubmit:function(){this.getData().then(this._submitForm.bind(this))},_openDialogContent:function(e,t){this.destroy(!0),this._formId=e,this._dialogContent=t;var i=n.open(this,this._dialogContent),o=elBySel("button[data-type=cancel]",i.content);null===o||elDataBool(o,"has-event-listener")||(o.addEventListener("click",this._closeDialog.bind(this)),elData(o,"has-event-listener",1))},_submitForm:function(t){var i=elBySel("button[data-type=submit]",n.getDialog(this).content);"function"==typeof this._options.onSubmit?this._options.onSubmit(t,i):"string"==typeof this._options.submitActionName&&(i.disabled=!0,e.api(this,{actionName:this._options.submitActionName,parameters:{data:t,formId:this._formId}}))},destroy:function(e){""!==this._formId&&(i.hasForm(this._formId)&&i.unregisterForm(this._formId),!0!==e&&n.destroy(this))},getData:function(){if(""===this._formId)throw new Error("Form has not been requested yet.");return i.getData(this._formId)},open:function(){n.getDialog(this._dialogId)?n.openStatic(this._dialogId):e.api(this)}},o}),define("WoltLabSuite/Core/Media/Manager/Search",["Ajax","Core","Dom/Traverse","Dom/Util","EventKey","Language","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={_ajaxSetup:function(){},_ajaxSuccess:function(){},_cancelSearch:function(){},_keyPress:function(){},_search:function(){},hideSearch:function(){},resetSearch:function(){},showSearch:function(){}},l}),define("WoltLabSuite/Core/Media/Manager/Base",["Core","Dictionary","Dom/ChangeListener","Dom/Traverse","Dom/Util","EventHandler","Language","List","Permission","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Editor","WoltLabSuite/Core/Media/Upload","WoltLabSuite/Core/Media/Manager/Search","StringUtil","WoltLabSuite/Core/Ui/Pagination","WoltLabSuite/Core/Media/Clipboard"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f,p,g,m,v){"use strict";var b=function(){};return b.prototype={_addButtonEventListeners:function(){},_click:function(){},_dialogClose:function(){},_dialogInit:function(){},_dialogSetup:function(){},_dialogShow:function(){},_editMedia:function(){},_editorClose:function(){},_editorSuccess:function(){},_removeClipboardCheckboxes:function(){},_setMedia:function(){},addMedia:function(){},clipboardDeleteMedia:function(){},getDialog:function(){},getMode:function(){},getOption:function(){},removeMedia:function(){},resetMedia:function(){},setMedia:function(){},setupMediaElement:function(){}},b}),define("WoltLabSuite/Core/Media/Manager/Editor",["Core","Dictionary","Dom/Traverse","EventHandler","Language","Permission","Ui/Dialog","WoltLabSuite/Core/Controller/Clipboard","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=function(){};return c.prototype={_addButtonEventListeners:function(){},_buildInsertDialog:function(){},_click:function(){},_getInsertDialogId:function(){},_getThumbnailSizes:function(){},_insertMedia:function(){},_insertMediaGallery:function(){},_insertMediaItem:function(){},_openInsertDialog:function(){},insertMedia:function(){},getMode:function(){},setupMediaElement:function(){},_dialogClose:function(){},_dialogInit:function(){},_dialogSetup:function(){},_dialogShow:function(){},_editMedia:function(){},_editorClose:function(){},_editorSuccess:function(){},_removeClipboardCheckboxes:function(){},_setMedia:function(){},addMedia:function(){},clipboardInsertMedia:function(){},getDialog:function(){},getOption:function(){},removeMedia:function(){},resetMedia:function(){},setMedia:function(){}},c}),define("WoltLabSuite/Core/Media/Manager/Select",["Core","Dom/Traverse","Dom/Util","Language","ObjectMap","Ui/Dialog","WoltLabSuite/Core/FileUtil","WoltLabSuite/Core/Media/Manager/Base"],function(e,t,i,n,o,r,a,l){"use strict";var s=function(){};return s.prototype={_addButtonEventListeners:function(){},_chooseMedia:function(){},_click:function(){},getMode:function(){},setupMediaElement:function(){},_removeMedia:function(){},_clipboardAction:function(){},_dialogClose:function(){},_dialogInit:function(){},_dialogSetup:function(){},_dialogShow:function(){},_editMedia:function(){},_editorClose:function(){},_editorSuccess:function(){},_removeClipboardCheckboxes:function(){},_setMedia:function(){},addMedia:function(){},getDialog:function(){},getOption:function(){},removeMedia:function(){},resetMedia:function(){},setMedia:function(){}},s}),define("WoltLabSuite/Core/Ui/Search/Input",["Ajax","Core","EventKey","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o){"use strict";function r(e,t){this.init(e,t)}return r.prototype={init:function(e,i){if(this._element=e,!(this._element instanceof Element))throw new TypeError("Expected a valid DOM element.");if("INPUT"!==this._element.nodeName||"search"!==this._element.type&&"text"!==this._element.type)throw new Error('Expected an input[type="text"].');this._activeItem=null,this._dropdownContainerId="",this._lastValue="",this._list=null,this._request=null,this._timerDelay=null,this._options=t.extend({ajax:{actionName:"getSearchResultList",className:"",interfaceName:"wcf\\data\\ISearchAction"},autoFocus:!0,callbackDropdownInit:null,callbackSelect:null,delay:500,excludedSearchValues:[],minLength:3,noResultPlaceholder:"",preventSubmit:!1},i),elAttr(this._element,"autocomplete","off"),this._element.addEventListener("keydown",this._keydown.bind(this)),this._element.addEventListener("keyup",this._keyup.bind(this))},addExcludedSearchValues:function(e){-1===this._options.excludedSearchValues.indexOf(e)&&this._options.excludedSearchValues.push(e)},removeExcludedSearchValues:function(e){var t=this._options.excludedSearchValues.indexOf(e);-1!==t&&this._options.excludedSearchValues.splice(t,1)},_keydown:function(e){(null!==this._activeItem&&o.isOpen(this._dropdownContainerId)||this._options.preventSubmit)&&i.Enter(e)&&e.preventDefault(),(i.ArrowUp(e)||i.ArrowDown(e)||i.Escape(e))&&e.preventDefault()},_keyup:function(e){if(null!==this._activeItem||!this._options.autoFocus)if(o.isOpen(this._dropdownContainerId)){if(i.ArrowUp(e))return e.preventDefault(),this._keyboardPreviousItem();if(i.ArrowDown(e))return e.preventDefault(),this._keyboardNextItem();if(i.Enter(e))return e.preventDefault(),this._keyboardSelectItem()}else this._activeItem=null;if(i.Escape(e))return void o.close(this._dropdownContainerId);var t=this._element.value.trim();if(this._lastValue!==t){if(this._lastValue=t,t.length<this._options.minLength)return void(this._dropdownContainerId&&(o.close(this._dropdownContainerId),this._activeItem=null));this._options.delay?(null!==this._timerDelay&&window.clearTimeout(this._timerDelay),this._timerDelay=window.setTimeout(function(){this._search(t)}.bind(this),this._options.delay)):this._search(t)}},_search:function(t){this._request&&this._request.abortPrevious(),this._request=e.api(this,this._getParameters(t))},_getParameters:function(e){return{parameters:{data:{excludedSearchValues:this._options.excludedSearchValues,searchString:e}}}},_keyboardNextItem:function(){var e;null!==this._activeItem&&(this._activeItem.classList.remove("active"),this._activeItem.nextElementSibling&&(e=this._activeItem.nextElementSibling)),this._activeItem=e||this._list.children[0],this._activeItem.classList.add("active")},_keyboardPreviousItem:function(){var e;null!==this._activeItem&&(this._activeItem.classList.remove("active"),this._activeItem.previousElementSibling&&(e=this._activeItem.previousElementSibling)),this._activeItem=e||this._list.children[this._list.childElementCount-1],this._activeItem.classList.add("active")},_keyboardSelectItem:function(){this._selectItem(this._activeItem)},_clickSelectItem:function(e){this._selectItem(e.currentTarget)},_selectItem:function(e){this._options.callbackSelect&&!1===this._options.callbackSelect(e)?this._element.value="":this._element.value=elData(e,"label"),this._activeItem=null,o.close(this._dropdownContainerId)},_ajaxSuccess:function(e){var t=!1;if(null===this._list?(this._list=elCreate("ul"),this._list.className="dropdownMenu",t=!0,"function"==typeof this._options.callbackDropdownInit&&this._options.callbackDropdownInit(this._list)):this._list.innerHTML="","object"==typeof e.returnValues){var i,r=this._clickSelectItem.bind(this);for(var a in e.returnValues)e.returnValues.hasOwnProperty(a)&&(i=this._createListItem(e.returnValues[a]),i.addEventListener(WCF_CLICK_EVENT,r),this._list.appendChild(i))}t&&(n.insertAfter(this._list,this._element),o.initFragment(this._element.parentNode,this._list),this._dropdownContainerId=n.identify(this._element.parentNode)),this._dropdownContainerId&&(this._activeItem=null,this._list.childElementCount||!1!==this._handleEmptyResult()?(o.open(this._dropdownContainerId,!0),this._options.autoFocus&&this._list.childElementCount&&~~elData(this._list.children[0],"object-id")&&(this._activeItem=this._list.children[0],this._activeItem.classList.add("active"))):o.close(this._dropdownContainerId))},_handleEmptyResult:function(){if(!this._options.noResultPlaceholder)return!1;var e=elCreate("li");e.className="dropdownText";var t=elCreate("span");return t.textContent=this._options.noResultPlaceholder,e.appendChild(t),this._list.appendChild(e),!0},_createListItem:function(e){var t=elCreate("li");elData(t,"object-id",e.objectID),elData(t,"label",e.label);var i=elCreate("span");return i.textContent=e.label,t.appendChild(i),t},_ajaxSetup:function(){return{data:this._options.ajax}}},r}),define("WoltLabSuite/Core/Ui/User/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){var o=e.isPlainObject(n)&&!0===n.includeUserGroups;n=e.extend({ajax:{className:"wcf\\data\\user\\UserAction",parameters:{data:{includeUserGroups:o?1:0}}}},n),i._super.prototype.init.call(this,t,n)},_createListItem:function(e){var t=i._super.prototype._createListItem.call(this,e);elData(t,"type",e.type);var n=elCreate("div");return n.className="box16",n.innerHTML="group"===e.type?'<span class="icon icon16 fa-users"></span>':e.icon,n.appendChild(t.children[0]),t.appendChild(n),t}}),i}),define("WoltLabSuite/Core/Ui/Acl/Simple",["Language","StringUtil","Dom/ChangeListener","WoltLabSuite/Core/Ui/User/Search/Input"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={init:function(){},_build:function(){},_select:function(){},_removeItem:function(){}},o}),define("WoltLabSuite/Core/Ui/Article/MarkAllAsRead",["Ajax"],function(e){"use strict";return{init:function(){elBySelAll(".markAllAsReadButton",void 0,function(e){e.addEventListener(WCF_CLICK_EVENT,this._click.bind(this))}.bind(this))},_click:function(t){t.preventDefault(),e.api(this)},_ajaxSuccess:function(){var e=elBySel(".mainMenu .active .badge");e&&elRemove(e),elBySelAll(".articleList .newMessageBadge",void 0,elRemove)},_ajaxSetup:function(){return{data:{actionName:"markAllAsRead",className:"wcf\\data\\article\\ArticleAction"}}}}}),define("WoltLabSuite/Core/Ui/Article/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={open:function(){},_search:function(){},_click:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},_dialogSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/Color/Picker",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}var i=function(e,t){if("object"==typeof window.WCF&&"function"==typeof window.WCF.ColorPicker)return(i=function(e,t){var i=new window.WCF.ColorPicker(e);return"function"==typeof t.callbackSubmit&&i.setCallbackSubmit(t.callbackSubmit),i})(e,t);0===n.length&&(window.__wcf_bc_colorPickerInit=function(){n.forEach(function(e){i(e[0],e[1])}),window.__wcf_bc_colorPickerInit=void 0,n=[]}),n.push([e,t])},n=[];return t.prototype={init:function(t,n){if(!(t instanceof Element))throw new TypeError("Expected a valid DOM element, use `UiColorPicker.fromSelector()` if you want to use a CSS selector.");this._options=e.extend({callbackSubmit:null},n),i(t,this._options)}},t.fromSelector=function(e){elBySelAll(e,void 0,function(e){new t(e)})},t}),define("WoltLabSuite/Core/Ui/Comment/Add",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},_submitGuestDialog:function(){},_submit:function(){},_getParameters:function(){},_validate:function(){},throwError:function(){},_showLoadingOverlay:function(){},_hideLoadingOverlay:function(){},_reset:function(){},_handleError:function(){},_getEditor:function(){},_insertMessage:function(){},_ajaxSuccess:function(){},_ajaxFailure:function(){},_ajaxSetup:function(){},_cancelGuestDialog:function(){}},f}),define("WoltLabSuite/Core/Ui/Comment/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},rebuild:function(){},_click:function(){},_prepare:function(){},_showEditor:function(){},_restoreMessage:function(){},_save:function(){},_validate:function(){},throwError:function(){},_showMessage:function(){},_hideEditor:function(){},_restoreEditor:function(){},_destroyEditor:function(){},_getEditorId:function(){},_getObjectId:function(){},_ajaxFailure:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){}},f}),define("WoltLabSuite/Core/Ui/Dropdown/Builder",["Core","Ui/SimpleDropdown"],function(e,t){"use strict";function i(e){if(!(e instanceof HTMLUListElement))throw new TypeError("Expected a reference to an <ul> element.");if(!e.classList.contains("dropdownMenu"))throw new Error("List does not appear to be a dropdown menu.")}function n(t){var i=elCreate("li");if("divider"===t)return i.className="dropdownDivider",i;"string"==typeof t.identifier&&elData(i,"identifier",t.identifier);var n=elCreate("a");if(n.href="string"==typeof t.href?t.href:"#","function"==typeof t.callback)n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),t.callback(n)});else if("#"===n.getAttribute("href"))throw new Error("Expected either a `href` value or a `callback`.");if(t.hasOwnProperty("attributes")&&e.isPlainObject(t.attributes))for(var r in t.attributes)t.attributes.hasOwnProperty(r)&&elData(n,r,t.attributes[r]);if(i.appendChild(n),void 0!==t.icon&&e.isPlainObject(t.icon)){if("string"!=typeof t.icon.name)throw new TypeError("Expected a valid icon name.");var a=16;"number"==typeof t.icon.size&&-1!==o.indexOf(~~t.icon.size)&&(a=~~t.icon.size);var l=elCreate("span");l.className="icon icon"+a+" fa-"+t.icon.name,n.appendChild(l)}var s="string"==typeof t.label?t.label.trim():"",c="string"==typeof t.labelHtml?t.labelHtml.trim():"";if(""===s&&""===c)throw new TypeError("Expected either a label or a `labelHtml`.");var u=elCreate("span");return u[s?"textContent":"innerHTML"]=s||c,n.appendChild(document.createTextNode(" ")),n.appendChild(u),i}var o=[16,24,32,48,64,96,144];return{create:function(e,t){var i=elCreate("ul");return i.className="dropdownMenu","string"==typeof t&&elData(i,"identifier",t),Array.isArray(e)&&e.length>0&&this.appendItems(i,e),i},buildItem:function(e){return n(e)},appendItem:function(e,t){i(e),e.appendChild(n(t))},appendItems:function(e,t){if(i(e),!Array.isArray(t))throw new TypeError("Expected an array of items.");var o=t.length;if(0===o)throw new Error("Expected a non-empty list of items.");if(1===o)this.appendItem(e,t[0]);else{for(var r=document.createDocumentFragment(),a=0;a<o;a++)r.appendChild(n(t[a]));e.appendChild(r)}},setItems:function(e,t){i(e),e.innerHTML="",this.appendItems(e,t)},attach:function(e,n){i(e),t.initFragment(n,e),n.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),t.toggleDropdown(n.id)})},divider:function(){return"divider"}}}),define("WoltLabSuite/Core/Ui/File/Delete",["Ajax","Core","Dom/ChangeListener","Language","Dom/Util","Dom/Traverse","Dictionary"],function(e,t,i,n,o,r,a){"use strict";function l(e,t,i,n){if(this._isSingleImagePreview=i,this._uploadHandler=n,this._buttonContainer=elById(e),null===this._buttonContainer)throw new Error("Element id '"+e+"' is unknown.");if(this._target=elById(t),null===t)throw new Error("Element id '"+t+"' is unknown.");if(this._containers=new a,this._internalId=elData(this._target,"internal-id"),!this._internalId)throw new Error("InternalId is unknown.");this.rebuild()}return l.prototype={_createButtons:function(){for(var e,t,n,o=elBySelAll("li.uploadedFile",this._target),r=!1,a=0,l=o.length;a<l;a++)e=o[a],n=elData(e,"unique-file-id"),this._containers.has(n)||(t={uniqueFileId:n,element:e},this._containers.set(n,t),this._initDeleteButton(e,t),r=!0);r&&i.trigger()},_initDeleteButton:function(e,t){var i=elBySel(".buttonGroup",e);if(null===i)throw new Error("Button group in '"+targetId+"' is unknown.");var o=elCreate("li"),r=elCreate("span");r.classList="button jsDeleteButton small",r.textContent=n.get("wcf.global.button.delete"),o.appendChild(r),i.appendChild(o),o.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,t.uniqueFileId))},_delete:function(t){e.api(this,{uniqueFileId:t,internalId:this._internalId})},rebuild:function(){if(this._isSingleImagePreview){var e=elBySel("img",this._target);if(null!==e){var t=elData(e,"unique-file-id");if(!this._containers.has(t)){var i={uniqueFileId:t,element:e};this._containers.set(t,i),this._deleteButton=elCreate("p"),this._deleteButton.className="button deleteButton";var o=elCreate("span");o.textContent=n.get("wcf.global.button.delete"),this._deleteButton.appendChild(o),this._buttonContainer.appendChild(this._deleteButton),this._deleteButton.addEventListener(WCF_CLICK_EVENT,this._delete.bind(this,i.uniqueFileId))}}}else this._createButtons()},_ajaxSuccess:function(e){elRemove(this._containers.get(e.uniqueFileId).element),this._isSingleImagePreview&&(elRemove(this._deleteButton),this._deleteButton=null),this._uploadHandler.checkMaxFiles(),t.triggerEvent(this._target,"change")},_ajaxSetup:function(){return{url:"index.php?ajax-file-delete/&t="+SECURITY_TOKEN}}},l}),define("WoltLabSuite/Core/Ui/File/Upload",["Core","Language","Dom/Util","WoltLabSuite/Core/Ui/File/Delete","Upload"],function(e,t,i,n,o){"use strict";function r(t,i,o){if(o=o||{},void 0===o.internalId)throw new Error("Missing internal id.");if(this._options=e.extend({name:"__files[]",singleFileRequests:!1,url:"index.php?ajax-file-upload/&t="+SECURITY_TOKEN,imagePreview:!1,maxFiles:null,acceptableFiles:null},o),this._options.multiple=null===this._options.maxFiles||this._options.maxFiles>1,0===this._options.url.indexOf("index.php")&&(this._options.url=WSC_API_URL+this._options.url),this._buttonContainer=elById(t),null===this._buttonContainer)throw new Error("Element id '"+t+"' is unknown.");if(this._target=elById(i),null===i)throw new Error("Element id '"+i+"' is unknown.");if(o.multiple&&"UL"!==this._target.nodeName&&"OL"!==this._target.nodeName)throw new Error("Target element has to be list or table body if uploading multiple files is supported.");this._fileElements=[],this._internalFileId=0,this._multiFileUploadIds=[],this._createButton(),this.checkMaxFiles(),this._deleteHandler=new n(t,i,this._options.imagePreview,this)}return e.inherit(r,o,{_createFileElement:function(e){var t=r._super.prototype._createFileElement.call(this,e);t.classList.add("box64","uploadedFile");var i=elBySel("progress",t),n=elCreate("span");n.className="icon icon64 fa-spinner";var o=t.textContent;t.textContent="",t.append(n);var a=elCreate("div"),l=elCreate("p");l.textContent=o;var s=elCreate("small");s.appendChild(i),a.appendChild(l),a.appendChild(s);var c=elCreate("div");c.appendChild(a);var u=elCreate("ul");return u.className="buttonGroup",c.appendChild(u),t.append(c),t},_failure:function(e,n,o,r,a){for(var l=0,s=this._fileElements[e].length;l<s;l++){this._fileElements[e][l].classList.add("uploadFailed"),elBySel("small",this._fileElements[e][l]).innerHTML="";var c=elBySel(".icon",this._fileElements[e][l]);c.classList.remove("fa-spinner"),c.classList.add("fa-ban");var u=elCreate("span");u.className="innerError",u.textContent=t.get("wcf.upload.error.uploadFailed"),i.insertAfter(u,elBySel("small",this._fileElements[e][l]))}throw new Error("Upload failed: "+n.message)},_upload:function(e,t,i){var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return n&&elRemove(n),r._super.prototype._upload.call(this,e,t,i)},_success:function(t,n,o,r,a){for(var l=0,s=this._fileElements[t].length;l<s;l++)if(void 0!==n.files[l])if(this._options.imagePreview){if(null===n.files[l].image)throw new Error("Expect image for uploaded file. None given.");if(elRemove(this._fileElements[t][l]),null!==elBySel("img.previewImage",this._target))elBySel("img.previewImage",this._target).setAttribute("src",n.files[l].image);else{var c=elCreate("img");c.classList.add("previewImage"),c.setAttribute("src",n.files[l].image),c.setAttribute("style","max-width: 100%;"),elData(c,"unique-file-id",n.files[l].uniqueFileId),this._target.appendChild(c)}}else{elData(this._fileElements[t][l],"unique-file-id",n.files[l].uniqueFileId),elBySel("small",this._fileElements[t][l]).textContent=n.files[l].filesize;var u=elBySel(".icon",this._fileElements[t][l]);u.classList.remove("fa-spinner"),u.classList.add("fa-"+n.files[l].icon)}else{if(void 0===n.error[l])throw new Error("Unknown uploaded file for uploadId "+t+".");this._fileElements[t][l].classList.add("uploadFailed"),elBySel("small",this._fileElements[t][l]).innerHTML="";var u=elBySel(".icon",this._fileElements[t][l]);if(u.classList.remove("fa-spinner"),u.classList.add("fa-ban"),null===elBySel(".innerError",this._fileElements[t][l])){var d=elCreate("span");d.className="innerError",d.textContent=n.error[l].errorMessage,i.insertAfter(d,elBySel("small",this._fileElements[t][l]))}else elBySel(".innerError",this._fileElements[t][l]).textContent=n.error[l].errorMessage}this._deleteHandler.rebuild(),this.checkMaxFiles(),e.triggerEvent(this._target,"change")},_getFormData:function(){return{internalId:this._options.internalId}},validateUpload:function(e){if(null===this._options.maxFiles||e.length+this.countFiles()<=this._options.maxFiles)return!0;var n=elBySel("small.innerError:not(.innerFileError)",this._buttonContainer.parentNode);return null===n&&(n=elCreate("small"),n.className="innerError",i.insertAfter(n,this._buttonContainer)),n.textContent=t.get("wcf.upload.error.reachedRemainingLimit",{maxFiles:this._options.maxFiles-this.countFiles()}),!1},countFiles:function(){return this._options.imagePreview?null!==elBySel("img",this._target)?1:0:this._target.childElementCount},checkMaxFiles:function(){null!==this._options.maxFiles&&this.countFiles()>=this._options.maxFiles?elHide(this._button):elShow(this._button)}}),r}),define("WoltLabSuite/Core/Ui/ItemList/Filter",["Core","EventKey","Language","List","StringUtil","Dom/Util","Ui/SimpleDropdown"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},_buildItems:function(){},_prepareItem:function(){},_keyup:function(){},_toggleVisibility:function(){},_setupVisibilityFilter:function(){},_setVisibility:function(){}},l}),define("WoltLabSuite/Core/Ui/ItemList/Static",["Core","Dictionary","Language","Dom/Traverse","EventKey","Ui/SimpleDropdown"],function(e,t,i,n,o,r){"use strict";var a="",l=new t,s=!1,c=null,u=null,d=null,h=null,f=null,p=null;return{init:function(t,i,o){var a=elById(t);if(null===a)throw new Error("Expected a valid element id, '"+t+"' is invalid.");if(l.has(t)){var s=l.get(t);for(var c in s)if(s.hasOwnProperty(c)){var u=s[c];u instanceof Element&&u.parentNode&&elRemove(u)}r.destroy(t),l.delete(t)}o=e.extend({maxItems:-1,maxLength:-1,isCSV:!1,callbackChange:null,callbackSubmit:null,submitFieldName:""},o);var d=n.parentByTag(a,"FORM");if(null!==d&&!1===o.isCSV){if(!o.submitFieldName.length&&"function"!=typeof o.callbackSubmit)throw new Error("Expected a valid function for option 'callbackSubmit', a non-empty value for option 'submitFieldName' or enabling the option 'submitFieldCSV'.");d.addEventListener("submit",function(){var e=this.getValues(t);if(o.submitFieldName.length)for(var i,n=0,r=e.length;n<r;n++)i=elCreate("input"),i.type="hidden",
+i.name=o.submitFieldName.replace("{$objectId}",e[n].objectId),i.value=e[n].value,d.appendChild(i);else o.callbackSubmit(d,e)}.bind(this))}this._setup();var h=this._createUI(a,o);if(l.set(t,{dropdownMenu:null,element:h.element,list:h.list,listItem:h.element.parentNode,options:o,shadow:h.shadow}),i=h.values.length?h.values:i,Array.isArray(i))for(var f,p=!h.element.disabled,g=0,m=i.length;g<m;g++)f=i[g],"string"==typeof f&&(f={objectId:0,value:f}),this._addItem(t,f,p)},getValues:function(e){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var t=l.get(e),i=[];return elBySelAll(".item > span",t.list,function(e){i.push({objectId:~~elData(e,"object-id"),value:e.textContent})}),i},setValues:function(e,t){if(!l.has(e))throw new Error("Element id '"+e+"' is unknown.");var i,o,r=l.get(e),a=n.childrenByClass(r.list,"item");for(i=0,o=a.length;i<o;i++)this._removeItem(null,a[i],!0);for(i=0,o=t.length;i<o;i++)this._addItem(e,t[i])},_setup:function(){s||(s=!0,c=this._keyDown.bind(this),u=this._keyPress.bind(this),d=this._keyUp.bind(this),h=this._paste.bind(this),f=this._removeItem.bind(this),p=this._blur.bind(this))},_createUI:function(e,t){var i=elCreate("ol");i.className="inputItemList"+(e.disabled?" disabled":""),elData(i,"element-id",e.id),i.addEventListener(WCF_CLICK_EVENT,function(t){t.target===i&&e.focus()});var n=elCreate("li");n.className="input",i.appendChild(n),e.addEventListener("keydown",c),e.addEventListener("keypress",u),e.addEventListener("keyup",d),e.addEventListener("paste",h),e.addEventListener("blur",p),e.parentNode.insertBefore(i,e),n.appendChild(e),-1!==t.maxLength&&elAttr(e,"maxLength",t.maxLength);var o=null,r=[];if(t.isCSV){o=elCreate("input"),o.className="itemListInputShadow",o.type="hidden",o.name=e.name,e.removeAttribute("name"),i.parentNode.insertBefore(o,i);for(var a,l=e.value.split(","),s=0,f=l.length;s<f;s++)a=l[s].trim(),a.length&&r.push(a);if("TEXTAREA"===e.nodeName){var g=elCreate("input");g.type="text",e.parentNode.insertBefore(g,e),g.id=e.id,elRemove(e),e=g}}return{element:e,list:i,shadow:o,values:r}},_handleLimit:function(e){var t=l.get(e);-1!==t.options.maxItems&&(t.list.childElementCount-1<t.options.maxItems?t.element.disabled&&(t.element.disabled=!1,t.element.removeAttribute("placeholder")):t.element.disabled||(t.element.disabled=!0,elAttr(t.element,"placeholder",i.get("wcf.global.form.input.maxItems"))))},_keyDown:function(e){var t=e.currentTarget,i=t.parentNode.previousElementSibling;a=t.id,8===e.keyCode?0===t.value.length&&null!==i&&(i.classList.contains("active")?this._removeItem(null,i):i.classList.add("active")):27===e.keyCode&&null!==i&&i.classList.contains("active")&&i.classList.remove("active")},_keyPress:function(e){if(o.Enter(e)||o.Comma(e)){e.preventDefault();var t=e.currentTarget.value.trim();t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}},_paste:function(e){var t="";t="object"==typeof window.clipboardData?window.clipboardData.getData("Text"):e.clipboardData.getData("text/plain"),t.split(/,/).forEach(function(t){t=t.trim(),0!==t.length&&this._addItem(e.currentTarget.id,{objectId:0,value:t})}.bind(this)),e.preventDefault()},_keyUp:function(e){var t=e.currentTarget;if(t.value.length>0){var i=t.parentNode.previousElementSibling;null!==i&&i.classList.remove("active")}},_addItem:function(e,t,i){var n=l.get(e),o=elCreate("li");o.className="item";var r=elCreate("span");if(r.className="content",elData(r,"object-id",t.objectId),r.textContent=t.value,o.appendChild(r),i||!n.element.disabled){var a=elCreate("a");a.className="icon icon16 fa-times",a.addEventListener(WCF_CLICK_EVENT,f),o.appendChild(a)}n.list.insertBefore(o,n.listItem),n.element.value="",n.element.disabled||this._handleLimit(e);var s=this._syncShadow(n);"function"==typeof n.options.callbackChange&&(null===s&&(s=this.getValues(e)),n.options.callbackChange(e,s))},_removeItem:function(e,t,i){t=null===e?t:e.currentTarget.parentNode;var n=t.parentNode,o=elData(n,"element-id"),r=l.get(o);n.removeChild(t),i||r.element.focus(),this._handleLimit(o);var a=this._syncShadow(r);"function"==typeof r.options.callbackChange&&(null===a&&(a=this.getValues(o)),r.options.callbackChange(o,a))},_syncShadow:function(e){if(!e.options.isCSV)return null;for(var t="",i=this.getValues(e.element.id),n=0,o=i.length;n<o;n++)t+=(t.length?",":"")+i[n].value;return e.shadow.value=t,i},_blur:function(e){var t=(l.get(e.currentTarget.id),e.currentTarget);window.setTimeout(function(){var e=t.value.trim();e.length&&this._addItem(t.id,{objectId:0,value:e})}.bind(this),100)}}}),define("WoltLabSuite/Core/Ui/ItemList/User",["WoltLabSuite/Core/Ui/ItemList"],function(e){"use strict";var t=function(){};return t.prototype={init:function(){},getValues:function(){}},t}),define("WoltLabSuite/Core/Ui/User/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination"],function(e,t,i,n,o,r){"use strict";function a(e){this.init(e)}return a.prototype={init:function(e){this._cache=new i,this._pageCount=0,this._pageNo=1,this._options=t.extend({className:"",dialogTitle:"",parameters:{}},e)},open:function(){this._pageNo=1,this._showPage()},_showPage:function(t){if("number"==typeof t&&(this._pageNo=~~t),0!==this._pageCount&&(this._pageNo<1||this._pageNo>this._pageCount))throw new RangeError("pageNo must be between 1 and "+this._pageCount+" ("+this._pageNo+" given).");if(this._cache.has(this._pageNo)){var i=o.open(this,this._cache.get(this._pageNo));if(this._pageCount>1){var n=elBySel(".jsPagination",i.content);null!==n&&new r(n,{activePage:this._pageNo,maxPage:this._pageCount,callbackSwitch:this._showPage.bind(this)});var a=i.content.parentNode;a.scrollTop>0&&(a.scrollTop=0)}}else this._options.parameters.pageNo=this._pageNo,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&(this._pageCount=~~e.returnValues.pageCount),this._cache.set(this._pageNo,e.returnValues.template),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserList",className:this._options.className,interfaceName:"wcf\\data\\IGroupedUserListAction"}}},_dialogSetup:function(){return{id:n.getUniqueId(),options:{title:this._options.dialogTitle},source:null}}},a}),define("WoltLabSuite/Core/Ui/Reaction/CountButtons",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","EventHandler"],function(e,t,i,n,o,r,a,l,s,c){"use strict";function u(e,t){this.init(e,t)}return u.prototype={init:function(e,n){if(""===n.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objects=new i,this._objectType=e,this._options=t.extend({summaryListSelector:".reactionSummaryList",containerSelector:"",isSingleItem:!1,parameters:{data:{}}},n),this.initContainers(n,e),a.add("WoltLabSuite/Core/Ui/Reaction/CountButtons-"+e,this.initContainers.bind(this))},initContainers:function(){for(var e,t,i,n=elBySelAll(this._options.containerSelector),o=!1,r=0,s=n.length;r<s;r++)if(e=n[r],!this._containers.has(l.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,summary:null,objectId:i,element:e},this._containers.set(l.identify(e),t),this._initReactionCountButtons(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),o=!0}o&&a.trigger()},updateCountButtons:function(e,t){var i=!1;this._objects.get(e).forEach(function(e){var n=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e.element);if(null!==n){for(var o={},a=elBySelAll(".reactCountButton",n),l=0,s=a.length;l<s;l++){var c=elData(a[l],"reaction-type-id");t.hasOwnProperty(c)?o[c]=a[l]:elRemove(a[l])}Object.keys(t).forEach(function(e){if(void 0!==o[e]){elBySel(".reactionCount",o[e]).innerHTML=r.shortUnit(t[e])}else if(void 0!==REACTION_TYPES[e]){var a=elCreate("span");a.className="reactCountButton",a.innerHTML=REACTION_TYPES[e].renderedIcon,elData(a,"reaction-type-id",e);var l=elCreate("span");l.className="reactionCount",l.innerHTML=r.shortUnit(t[e]),a.appendChild(l),n.appendChild(a),i=!0}},this),window[n.childElementCount>0?"elShow":"elHide"](n)}}.bind(this)),i&&a.trigger()},_initReactionCountButtons:function(e,t){var i=elBySel(this._options.summaryListSelector,this._options.isSingleItem?void 0:e);null!==i&&i.addEventListener(WCF_CLICK_EVENT,this._showReactionOverlay.bind(this,t.objectId))},_showReactionOverlay:function(e,t){t.preventDefault(),this._currentObjectId=e,this._showOverlay()},_showOverlay:function(){this._options.parameters.data.containerID=this._objectType+"-"+this._currentObjectId,this._options.parameters.data.objectID=this._currentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){c.fire("com.woltlab.wcf.ReactionCountButtons","openDialog",e),s.open(this,e.returnValues.template),s.setTitle("userReactionOverlay-"+this._objectType,e.returnValues.title)},_ajaxSetup:function(){return{data:{actionName:"getReactionDetails",className:"\\wcf\\data\\reaction\\ReactionAction"}}},_dialogSetup:function(){return{id:"userReactionOverlay-"+this._objectType,options:{title:""},source:null}}},u}),define("WoltLabSuite/Core/Ui/Reaction/Handler",["Ajax","Core","Dictionary","Dom/ChangeListener","Dom/Util","Ui/Alignment","Ui/CloseOverlay","Ui/Screen","WoltLabSuite/Core/Ui/Reaction/CountButtons"],function(e,t,i,n,o,r,a,l,s){"use strict";function c(e,t){this.init(e,t)}return c.prototype={init:function(e,o){if(""===o.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new i,this._objectType=e,this._cache=new i,this._objects=new i,this._popoverCurrentObjectId=0,this._popover=null,this._popoverContent=null,this._options=t.extend({buttonSelector:".reactButton",containerSelector:"",isButtonGroupNavigation:!1,isSingleItem:!1,parameters:{data:{}}},o),this.initReactButtons(o,e),this.countButtons=new s(this._objectType,this._options),n.add("WoltLabSuite/Core/Ui/Reaction/Handler-"+e,this.initReactButtons.bind(this)),a.add("WoltLabSuite/Core/Ui/Reaction/Handler",this._closePopover.bind(this))},initReactButtons:function(){for(var e,t,i,r=elBySelAll(this._options.containerSelector),a=!1,l=0,s=r.length;l<s;l++)if(e=r[l],!this._containers.has(o.identify(e))){i=~~elData(e,"object-id"),t={reactButton:null,objectId:i,element:e},this._containers.set(o.identify(e),t),this._initReactButton(e,t);var c=[];this._objects.has(i)&&(c=this._objects.get(i)),c.push(t),this._objects.set(i,c),a=!0}a&&n.trigger()},_initReactButton:function(e,t){if(this._options.isSingleItem?t.reactButton=elBySel(this._options.buttonSelector):t.reactButton=elBySel(this._options.buttonSelector,e),null!==t.reactButton&&0!==t.reactButton.length){if(1===Object.keys(REACTION_TYPES).length){var i=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];t.reactButton.title=i.title;elBySel(".invisible",t.reactButton).innerText=i.title}t.reactButton.addEventListener(WCF_CLICK_EVENT,this._toggleReactPopover.bind(this,t.objectId,t.reactButton))}},_updateReactButton:function(e,t){this._objects.get(e).forEach(function(e){null!==e.reactButton&&(t?(e.reactButton.classList.add("active"),elData(e.reactButton,"reaction-type-id",t)):(elData(e.reactButton,"reaction-type-id",0),e.reactButton.classList.remove("active")))})},_markReactionAsActive:function(){var e=null;if(this._objects.get(this._popoverCurrentObjectId).forEach(function(t){null!==t.reactButton&&(e=~~elData(t.reactButton,"reaction-type-id"))}),null===e)throw new Error("Unable to find react button for current popover.");elBySelAll(".reactionTypeButton.active",this._getPopover(),function(e){e.classList.remove("active")});var t=elBySel(".reactionPopoverContent",this._getPopover());if(e){var i=elBySel('.reactionTypeButton[data-reaction-type-id="'+e+'"]',this._getPopover());i.classList.add("active"),0==~~elData(i,"is-assignable")&&elShow(i),this._scrollReactionIntoView(t,i)}else l.is("screen-xs")&&(this._getPopover().classList.contains("inverseOrder")?t.scrollTop=0:t.scrollTop=t.scrollHeight-t.clientHeight)},_scrollReactionIntoView:function(e,t){t.offsetTop<.75*e.clientHeight?e.scrollTop=0:e.scrollTop=t.offsetTop+t.clientHeight/2-e.clientHeight/2},_toggleReactPopover:function(e,t,i){if(null!==i&&(i.preventDefault(),i.stopPropagation()),1===Object.keys(REACTION_TYPES).length){var n=REACTION_TYPES[Object.keys(REACTION_TYPES)[0]];this._popoverCurrentObjectId=e,this._react(n.reactionTypeID)}else 0===this._popoverCurrentObjectId||this._popoverCurrentObjectId!==e?this._openReactPopover(e,t):this._closePopover(e,t)},_openReactPopover:function(e,t){0!==this._popoverCurrentObjectId&&this._closePopover(),this._popoverCurrentObjectId=e,r.set(this._getPopover(),t,{pointer:!0,horizontal:this._options.isButtonGroupNavigation?"left":"center",vertical:l.is("screen-xs")?"bottom":"top"}),this._options.isButtonGroupNavigation&&t.closest("nav").style.setProperty("opacity","1","");var i=this._getPopover(),n="auto"===i.style.getPropertyValue("bottom");i.classList[n?"add":"remove"]("inverseOrder"),this._markReactionAsActive(),this._rebuildOverflowIndicator(),i.classList.remove("forceHide"),i.classList.add("active")},_getPopover:function(){if(null==this._popover){this._popover=elCreate("div"),this._popover.className="reactionPopover forceHide",this._popoverContent=elCreate("div"),this._popoverContent.className="reactionPopoverContent";var e=elCreate("ul");e.className="reactionTypeButtonList";var t=this._getSortedReactionTypes();for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],r=elCreate("li");r.className="reactionTypeButton jsTooltip",elData(r,"reaction-type-id",o.reactionTypeID),elData(r,"title",o.title),elData(r,"is-assignable",~~o.isAssignable),r.title=o.title;var a=elCreate("span");a.className="reactionTypeButtonTitle",a.innerHTML=o.title,r.innerHTML=o.renderedIcon,r.appendChild(a),r.addEventListener(WCF_CLICK_EVENT,this._react.bind(this,o.reactionTypeID)),o.isAssignable||elHide(r),e.appendChild(r)}this._popoverContent.appendChild(e),this._popoverContent.addEventListener("scroll",this._rebuildOverflowIndicator.bind(this),{passive:!0}),this._popover.appendChild(this._popoverContent);var l=elCreate("span");l.className="elementPointer",l.appendChild(elCreate("span")),this._popover.appendChild(l),document.body.appendChild(this._popover),n.trigger()}return this._popover},_rebuildOverflowIndicator:function(){var e=this._popoverContent.scrollTop>0;this._popoverContent.classList[e?"add":"remove"]("overflowTop");var t=this._popoverContent.scrollTop+this._popoverContent.clientHeight<this._popoverContent.scrollHeight;this._popoverContent.classList[t?"add":"remove"]("overflowBottom")},_getSortedReactionTypes:function(){var e=[];for(var t in REACTION_TYPES)REACTION_TYPES.hasOwnProperty(t)&&e.push(REACTION_TYPES[t]);return e.sort(function(e,t){return e.showOrder-t.showOrder}),e},_closePopover:function(){0!==this._popoverCurrentObjectId&&(this._getPopover().classList.remove("active"),elBySelAll('.reactionTypeButton[data-is-assignable="0"]',this._getPopover(),elHide),this._options.isButtonGroupNavigation&&this._objects.get(this._popoverCurrentObjectId).forEach(function(e){e.reactButton.closest("nav").style.cssText=""}),this._popoverCurrentObjectId=0)},_react:function(t){0!=~~this._popoverCurrentObjectId&&(this._options.parameters.reactionTypeID=t,this._options.parameters.data.objectID=this._popoverCurrentObjectId,this._options.parameters.data.objectType=this._objectType,e.api(this,{parameters:this._options.parameters}),this._closePopover())},_ajaxSuccess:function(e){this.countButtons.updateCountButtons(e.returnValues.objectID,e.returnValues.reactions),this._updateReactButton(e.returnValues.objectID,e.returnValues.reactionTypeID)},_ajaxSetup:function(){return{data:{actionName:"react",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},c}),define("WoltLabSuite/Core/Ui/Like/Handler",["Ajax","Core","Dictionary","Language","ObjectMap","StringUtil","Dom/ChangeListener","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/User/List","User","WoltLabSuite/Core/Ui/Reaction/Handler"],function(e,t,i,n,o,r,a,l,s,c,u,d){"use strict";function h(e,t){this.init(e,t)}return h.prototype={init:function(e,i){if(""===i.containerSelector)throw new Error("[WoltLabSuite/Core/Ui/Like/Handler] Expected a non-empty string for option 'containerSelector'.");this._containers=new o,this._details=new o,this._objectType=e,this._options=t.extend({badgeClassNames:"",isSingleItem:!1,markListItemAsActive:!1,renderAsButton:!0,summaryPrepend:!0,summaryUseIcon:!0,canDislike:!1,canLike:!1,canLikeOwnContent:!1,canViewSummary:!1,badgeContainerSelector:".messageHeader .messageStatus",buttonAppendToSelector:".messageFooter .messageFooterButtons",buttonBeforeSelector:"",containerSelector:"",summarySelector:".messageFooterGroup"},i),this.initContainers(i,e),a.add("WoltLabSuite/Core/Ui/Like/Handler-"+e,this.initContainers.bind(this)),new d(this._objectType,{containerSelector:this._options.containerSelector,summaryListSelector:".reactionSummaryList"})},initContainers:function(){for(var e,t,i=elBySelAll(this._options.containerSelector),n=!1,o=0,r=i.length;o<r;o++)e=i[o],this._containers.has(e)||(t={badge:null,dislikeButton:null,likeButton:null,summary:null,dislikes:~~elData(e,"like-dislikes"),liked:~~elData(e,"like-liked"),likes:~~elData(e,"like-likes"),objectId:~~elData(e,"object-id"),users:JSON.parse(elData(e,"like-users"))},this._containers.set(e,t),this._buildWidget(e,t),n=!0);n&&a.trigger()},_buildWidget:function(e,t){var i,n,o,a=!0;if(o=this._options.isSingleItem?elBySel(this._options.summarySelector):elBySel(this._options.summarySelector,e),null===o&&(o=this._options.isSingleItem?elBySel(this._options.badgeContainerSelector):elBySel(this._options.badgeContainerSelector,e),a=!1),null!==o){i=elCreate("ul"),i.classList.add("reactionSummaryList"),a?i.classList.add("likesSummary"):i.classList.add("reactionSummaryListTiny");for(var s in t.users)if("reactionTypeID"!==s&&REACTION_TYPES.hasOwnProperty(s)){var c=elCreate("li");c.className="reactCountButton",elData(c,"reaction-type-id",s);var d=elCreate("span");d.className="reactionCount",d.innerHTML=r.shortUnit(t.users[s]),c.appendChild(d),c.innerHTML=REACTION_TYPES[s].renderedIcon+c.innerHTML,i.appendChild(c)}a?this._options.summaryPrepend?l.prepend(i,o):o.appendChild(i):"OL"===o.nodeName||"UL"===o.nodeName?(n=elCreate("li"),n.appendChild(i),o.appendChild(n)):o.appendChild(i),t.badge=i}if(this._options.canLike&&(u.userId!=elData(e,"user-id")||this._options.canLikeOwnContent)){var h=this._options.buttonAppendToSelector?this._options.isSingleItem?elBySel(this._options.buttonAppendToSelector):elBySel(this._options.buttonAppendToSelector,e):null,f=this._options.buttonBeforeSelector?this._options.isSingleItem?elBySel(this._options.buttonBeforeSelector):elBySel(this._options.buttonBeforeSelector,e):null;if(null===f&&null===h)throw new Error("Unable to find insert location for like/dislike buttons.");t.likeButton=this._createButton(e,t.users.reactionTypeID,f,h)}},_createButton:function(e,t,i,o){var r=n.get("wcf.reactions.react"),a=elCreate("li");a.className="wcfReactButton";var l=elCreate("a");l.className="jsTooltip reactButton",this._options.renderAsButton&&l.classList.add("button"),l.href="#",l.title=r;var s=elCreate("span");s.className="icon icon16 fa-smile-o",void 0===t||0==t?elData(s,"reaction-type-id",0):(elData(l,"reaction-type-id",t),l.classList.add("active")),l.appendChild(s);var c=elCreate("span");return c.className="invisible",c.innerHTML=r,l.appendChild(document.createTextNode(" ")),l.appendChild(c),a.appendChild(l),i?i.parentNode.insertBefore(a,i):o.appendChild(a),l}},h}),define("WoltLabSuite/Core/Ui/Message/InlineEditor",["Ajax","Core","Dictionary","Environment","EventHandler","Language","ObjectMap","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},rebuild:function(){},_click:function(){},_clickDropdown:function(){},_dropdownBuild:function(){},_dropdownToggle:function(){},_dropdownGetItems:function(){},_dropdownOpen:function(){},_dropdownSelect:function(){},_clickDropdownItem:function(){},_prepare:function(){},_showEditor:function(){},_restoreMessage:function(){},_save:function(){},_validate:function(){},throwError:function(){},_showMessage:function(){},_hideEditor:function(){},_restoreEditor:function(){},_destroyEditor:function(){},_getHash:function(){},_updateHistory:function(){},_getEditorId:function(){},_getObjectId:function(){},_ajaxFailure:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},legacyEdit:function(){}},f}),define("WoltLabSuite/Core/Ui/Message/Manager",["Ajax","Core","Dictionary","Language","Dom/ChangeListener","Dom/Util"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},rebuild:function(){},getPermission:function(){},getPropertyValue:function(){},update:function(){},updateItems:function(){},updateAllItems:function(){},setNote:function(){},_update:function(){},_updateState:function(){},_toggleMessageStatus:function(){},_getAttributeName:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/Message/Reply",["Ajax","Core","EventHandler","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Dialog","Ui/Notification","WoltLabSuite/Core/Ui/Scroll","EventKey","User","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i,n,o,r,a,l,s,c,u,d,h){"use strict";var f=function(){};return f.prototype={init:function(){},_submitGuestDialog:function(){},_submit:function(){},_validate:function(){},throwError:function(){},_showLoadingOverlay:function(){},_hideLoadingOverlay:function(){},_reset:function(){},_handleError:function(){},_getEditor:function(){},_insertMessage:function(){},_ajaxSuccess:function(){},_ajaxFailure:function(){},_ajaxSetup:function(){}},f}),define("WoltLabSuite/Core/Ui/Message/Share",["EventHandler","StringUtil"],function(e,t){"use strict";return{_pageDescription:"",_pageUrl:"",init:function(){var i=elBySel('meta[property="og:title"]');null!==i&&(this._pageDescription=encodeURIComponent(i.content));var n=elBySel('meta[property="og:url"]');null!==n&&(this._pageUrl=encodeURIComponent(n.content)),elBySelAll(".jsMessageShareButtons",null,function(i){i.classList.remove("jsMessageShareButtons");var n=encodeURIComponent(t.unescapeHTML(elData(i,"url")||""));n||(n=this._pageUrl);var o={facebook:{link:elBySel(".jsShareFacebook",i),share:function(e){e.preventDefault(),this._share("facebook","https://www.facebook.com/sharer.php?u={pageURL}&t={text}",!0,n)}.bind(this)},google:{link:elBySel(".jsShareGoogle",i),share:function(e){e.preventDefault(),this._share("google","https://plus.google.com/share?url={pageURL}",!1,n)}.bind(this)},reddit:{link:elBySel(".jsShareReddit",i),share:function(e){e.preventDefault(),this._share("reddit","https://ssl.reddit.com/submit?url={pageURL}",!1,n)}.bind(this)},twitter:{link:elBySel(".jsShareTwitter",i),share:function(e){e.preventDefault(),this._share("twitter","https://twitter.com/share?url={pageURL}&text={text}",!1,n)}.bind(this)},linkedIn:{link:elBySel(".jsShareLinkedIn",i),share:function(e){e.preventDefault(),this._share("linkedIn","https://www.linkedin.com/cws/share?url={pageURL}",!1,n)}.bind(this)},pinterest:{link:elBySel(".jsSharePinterest",i),share:function(e){e.preventDefault(),this._share("pinterest","https://www.pinterest.com/pin/create/link/?url={pageURL}&description={text}",!1,n)}.bind(this)},xing:{link:elBySel(".jsShareXing",i),share:function(e){e.preventDefault(),this._share("xing","https://www.xing.com/social_plugins/share?url={pageURL}",!1,n)}.bind(this)},whatsApp:{link:elBySel(".jsShareWhatsApp",i),share:function(e){e.preventDefault(),window.location.href="https://api.whatsapp.com/send?text="+this._pageDescription+"%20"+this._pageUrl}.bind(this)}};e.fire("com.woltlab.wcf.message.share","shareProvider",{container:i,providers:o,pageDescription:this._pageDescription,pageUrl:this._pageUrl});for(var r in o)o.hasOwnProperty(r)&&null!==o[r].link&&o[r].link.addEventListener(WCF_CLICK_EVENT,o[r].share)}.bind(this))},_share:function(e,t,i,n){n||(n=this._pageUrl),window.open(t.replace(/\{pageURL}/,n).replace(/\{text}/,this._pageDescription+(i?"%20"+n:"")),e,"height=600,width=600")}}}),define("WoltLabSuite/Core/Ui/Message/TwitterEmbed",["https://platform.twitter.com/widgets.js"],function(e){"use strict";var t=new Promise(function(e,t){twttr.ready(e)});return{embedTweet:function(e,i,n){return void 0===n&&(n=!1),t.then(function(){return twttr.widgets.createTweet(i,e,{dnt:!0,lang:document.documentElement.lang})}).then(function(t){if(t&&n){for(;e.lastChild;)e.removeChild(e.lastChild);e.appendChild(t)}return t})},embedAll:function(){elBySelAll("[data-wsc-twitter-tweet]",void 0,function(e){var t=elData(e,"wsc-twitter-tweet");t&&(this.embedTweet(e,t,!0),elData(e,"wsc-twitter-tweet",""))}.bind(this))}}}),define("WoltLabSuite/Core/Ui/Page/Search",["Ajax","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={open:function(){},_search:function(){},_click:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},_dialogSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/Sortable/List",["Core","Ui/Screen"],function(e,t){"use strict";var i=function(){};return i.prototype={init:function(){},_enable:function(){},_disable:function(){}},i}),define("WoltLabSuite/Core/Ui/Poll/Editor",["Core","Dom/Util","EventHandler","EventKey","Language","WoltLabSuite/Core/Date/Picker","WoltLabSuite/Core/Ui/Sortable/List"],function(e,t,i,n,o,r,a){"use strict";function l(e,t,i,n){this.init(e,t,i,n)}return l.prototype={init:function(t,n,o,r){if(this._container=elById(t),null===this._container)throw new Error("Unknown poll editor container with id '"+t+"'.");if(this._wysiwygId=o,""!==o&&null===elById(o))throw new Error("Unknown wysiwyg field with id '"+o+"'.");this.questionField=elById(this._wysiwygId+"Poll_question");var l=elByClass("sortableList",this._container);if(0===l.length)throw new Error("Cannot find poll options list for container with id '"+t+"'.");if(this.optionList=l[0],this.endTimeField=elById(this._wysiwygId+"Poll_endTime"),this.maxVotesField=elById(this._wysiwygId+"Poll_maxVotes"),this.isChangeableYesField=elById(this._wysiwygId+"Poll_isChangeable"),this.isChangeableNoField=elById(this._wysiwygId+"Poll_isChangeable_no"),this.isPublicYesField=elById(this._wysiwygId+"Poll_isPublic"),this.isPublicNoField=elById(this._wysiwygId+"Poll_isPublic_no"),this.resultsRequireVoteYesField=elById(this._wysiwygId+"Poll_resultsRequireVote"),this.resultsRequireVoteNoField=elById(this._wysiwygId+"Poll_resultsRequireVote_no"),this.sortByVotesYesField=elById(this._wysiwygId+"Poll_sortByVotes"),this.sortByVotesNoField=elById(this._wysiwygId+"Poll_sortByVotes_no"),this._optionCount=0,this._options=e.extend({isAjax:!1,maxOptions:20},r),this._createOptionList(n||[]),new a({containerId:t,options:{toleranceElement:"> div"}}),this._options.isAjax)for(var s=["handleError","reset","submit","validate"],c=0,u=s.length;c<u;c++){var d=s[c];i.add("com.woltlab.wcf.redactor2",d+"_"+this._wysiwygId,this["_"+d].bind(this))}else{var h=this._container.closest("form");if(null===h)throw new Error("Cannot find form for container with id '"+t+"'.");h.addEventListener("submit",this._submit.bind(this))}},_addOption:function(e){if(e.preventDefault(),this._optionCount===this._options.maxOptions)return!1;this._createOption(void 0,void 0,e.currentTarget.closest("li"))},_createOption:function(e,i,n){e=e||"",i=~~i||0;var r=elCreate("LI");r.className="sortableNode",elData(r,"option-id",i),n?t.insertAfter(r,n):this.optionList.appendChild(r);var a=elCreate("div");a.className="pollOptionInput",r.appendChild(a);var l=elCreate("span");l.className="icon icon16 fa-arrows sortableNodeHandle",a.appendChild(l);var s=elCreate("a");elAttr(s,"role","button"),elAttr(s,"href","#"),s.className="icon icon16 fa-plus jsTooltip jsAddOption pointer",elAttr(s,"title",o.get("wcf.poll.button.addOption")),s.addEventListener("click",this._addOption.bind(this)),a.appendChild(s);var c=elCreate("a");elAttr(c,"role","button"),elAttr(c,"href","#"),c.className="icon icon16 fa-times jsTooltip jsDeleteOption pointer",elAttr(c,"title",o.get("wcf.poll.button.removeOption")),c.addEventListener("click",this._removeOption.bind(this)),a.appendChild(c);var u=elCreate("input");elAttr(u,"type","text"),u.value=e,elAttr(u,"maxlength",255),u.addEventListener("keydown",this._optionInputKeyDown.bind(this)),u.addEventListener("click",function(){document.activeElement!==this&&this.focus()}),a.appendChild(u),null!==n&&u.focus(),++this._optionCount===this._options.maxOptions&&elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.remove("pointer"),e.classList.add("disabled")})},_createOptionList:function(e){for(var t=0,i=e.length;t<i;t++){var n=e[t];this._createOption(n.optionValue,n.optionID)}this._optionCount<this._options.maxOptions&&this._createOption()},_handleError:function(e){switch(e.returnValues.fieldName){case this._wysiwygId+"Poll_endTime":case this._wysiwygId+"Poll_maxVotes":var i=e.returnValues.fieldName.replace(this._wysiwygId+"Poll_",""),n=elCreate("small");n.className="innerError",n.innerHTML=o.get("wcf.poll."+i+".error."+e.returnValues.errorType);var r=elById(e.returnValues.fieldName);r.closest("dd");t.prepend(n,r.nextSibling),e.cancel=!0}},_optionInputKeyDown:function(t){n.Enter(t)&&(e.triggerEvent(elByClass("jsAddOption",t.currentTarget.parentNode)[0],"click"),t.preventDefault())},_removeOption:function(e){e.preventDefault(),elRemove(e.currentTarget.closest("li")),this._optionCount--,elBySelAll("span.jsAddOption",this.optionList,function(e){e.classList.add("pointer"),e.classList.remove("disabled")}),0===this.optionList.length&&this._createOption()},_reset:function(){this.questionField.value="",this._optionCount=0,this.optionList.innerHtml="",this._createOption(),r.clear(this.endTimeField),this.maxVotesField.value=1,this.isChangeableYesField.checked=!1,this.isChangeableNoField.checked=!0,this.isPublicYesField.checked=!1,this.isPublicNoField.checked=!0,this.resultsRequireVoteYesField.checked=!1,this.resultsRequireVoteNoField.checked=!0,this.sortByVotesYesField.checked=!1,this.sortByVotesNoField.checked=!0,i.fire("com.woltlab.wcf.poll.editor","reset",{pollEditor:this})},_submit:function(e){if(this._options.isAjax)e.poll=this.getData(),i.fire("com.woltlab.wcf.poll.editor","submit",{event:e,pollEditor:this});else for(var t=this._container.closest("form"),n=this.getOptions(),o=0,r=n.length;o<r;o++){var a=elCreate("input");elAttr(a,"type","hidden"),elAttr(a,"name",this._wysiwygId+"Poll_options["+o+"]"),a.value=n[o],t.appendChild(a)}},_validate:function(e){if(""!==this.questionField.value.trim()){for(var t=0,n=0,r=this.optionList.children.length;n<r;n++){""!==elBySel("input[type=text]",this.optionList.children[n]).value.trim()&&t++}if(0===t)e.api.throwError(this._container,o.get("wcf.global.form.error.empty")),e.valid=!1;else{var a=~~this.maxVotesField.value;a&&a>t?(e.api.throwError(this.maxVotesField.parentNode,o.get("wcf.poll.maxVotes.error.invalid")),e.valid=!1):i.fire("com.woltlab.wcf.poll.editor","validate",{data:e,pollEditor:this})}}},getData:function(){var e={};return e[this.questionField.id]=this.questionField.value,e[this._wysiwygId+"Poll_options"]=this.getOptions(),e[this.endTimeField.id]=this.endTimeField.value,e[this.maxVotesField.id]=this.maxVotesField.value,e[this.isChangeableYesField.id]=!!this.isChangeableYesField.checked,e[this.isPublicYesField.id]=!!this.isPublicYesField.checked,e[this.resultsRequireVoteYesField.id]=!!this.resultsRequireVoteYesField.checked,e[this.sortByVotesYesField.id]=!!this.sortByVotesYesField.checked,e},getOptions:function(){
+for(var e=[],t=0,i=this.optionList.children.length;t<i;t++){var n=this.optionList.children[t],o=elBySel("input[type=text]",n).value.trim();""!==o&&e.push(elData(n,"option-id")+"_"+o)}return e}},l}),define("WoltLabSuite/Core/Ui/Redactor/Article",["WoltLabSuite/Core/Ui/Article/Search"],function(e){"use strict";var t=function(){};return t.prototype={init:function(){},_click:function(){},_insert:function(){}},t}),define("WoltLabSuite/Core/Ui/Redactor/Metacode",["EventHandler","Dom/Util"],function(e,t){"use strict";var i=function(){};return i.prototype={convert:function(){},convertFromHtml:function(){},_getOpeningTag:function(){},_getClosingTag:function(){},_getFirstParagraph:function(){},_getLastParagraph:function(){},_parseAttributes:function(){}},i}),define("WoltLabSuite/Core/Ui/Redactor/Autosave",["Core","Devtools","EventHandler","Language","Dom/Traverse","./Metacode"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},getInitialValue:function(){},getMetaData:function(){},watch:function(){},destroy:function(){},clear:function(){},createOverlay:function(){},hideOverlay:function(){},_saveToStorage:function(){},_cleanup:function(){}},a}),define("WoltLabSuite/Core/Ui/Redactor/PseudoHeader",[],function(){"use strict";var e=function(){};return e.prototype={getHeight:function(){}},e}),define("WoltLabSuite/Core/Ui/Redactor/Code",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader","prism/prism-meta"],function(e,t,i,n,o,r,a,l){"use strict";var s=function(){};return s.prototype={init:function(){},_bbcodeCode:function(){},_observeLoad:function(){},_edit:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){},_dialogSubmit:function(){}},s}),define("WoltLabSuite/Core/Ui/Redactor/Format",["Dom/Util"],function(e){"use strict";var t=function(){};return t.prototype={format:function(){},removeFormat:function(){},_handleParentNodes:function(){},_getLastMatchingParent:function(){},_isBoundaryElement:function(){},_getSelectionMarker:function(){}},t}),define("WoltLabSuite/Core/Ui/Redactor/Html",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},_bbcodeCode:function(){},_observeLoad:function(){},_edit:function(){},_save:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){}},l}),define("WoltLabSuite/Core/Ui/Redactor/Link",["Core","EventKey","Language","Ui/Dialog"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={showDialog:function(){},_submit:function(){},_dialogSetup:function(){}},o}),define("WoltLabSuite/Core/Ui/Redactor/Mention",["Ajax","Environment","StringUtil","Ui/CloseOverlay"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={init:function(){},_keyDown:function(){},_keyUp:function(){},_getTextLineInFrontOfCaret:function(){},_getDropdownMenuPosition:function(){},_setUsername:function(){},_selectMention:function(){},_updateDropdownPosition:function(){},_selectItem:function(){},_hideDropdown:function(){},_ajaxSetup:function(){},_ajaxSuccess:function(){}},o}),define("WoltLabSuite/Core/Ui/Redactor/Page",["WoltLabSuite/Core/Ui/Page/Search"],function(e){"use strict";var t=function(){};return t.prototype={init:function(){},_click:function(){},_insert:function(){}},t}),define("WoltLabSuite/Core/Ui/Redactor/Quote",["Core","EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./Metacode","./PseudoHeader"],function(e,t,i,n,o,r,a,l,s){"use strict";var c=function(){};return c.prototype={init:function(){},_insertQuote:function(){},_click:function(){},_observeLoad:function(){},_edit:function(){},_save:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){},_dialogSubmit:function(){}},c}),define("WoltLabSuite/Core/Ui/Redactor/Spoiler",["EventHandler","EventKey","Language","StringUtil","Dom/Util","Ui/Dialog","./PseudoHeader"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},_bbcodeSpoiler:function(){},_observeLoad:function(){},_edit:function(){},_setTitle:function(){},_delete:function(){},_dialogSetup:function(){},_dialogSubmit:function(){}},l}),define("WoltLabSuite/Core/Ui/Redactor/Table",["Language","Ui/Dialog"],function(e,t){"use strict";var i=function(){};return i.prototype={showDialog:function(){},_submit:function(){},_dialogSetup:function(){}},i}),define("WoltLabSuite/Core/Ui/Search/Page",["Core","Dom/Traverse","Dom/Util","Ui/Screen","Ui/SimpleDropdown","./Input"],function(e,t,i,n,o,r){"use strict";return{init:function(a){var l=elById("pageHeaderSearchInput");new r(l,{ajax:{className:"wcf\\data\\search\\keyword\\SearchKeywordAction"},autoFocus:!1,callbackDropdownInit:function(e){if(e.classList.add("dropdownMenuPageSearch"),n.is("screen-lg")){elData(e,"dropdown-alignment-horizontal","right");var t=l.clientWidth;e.style.setProperty("min-width",t+"px","");var o=l.parentNode,r=i.offset(o).left+o.clientWidth-(i.offset(l).left+t),a=i.styleAsInt(window.getComputedStyle(o),"padding-bottom");e.style.setProperty("transform","translateX(-"+Math.ceil(r)+"px) translateY(-"+a+"px)","")}},callbackSelect:function(){return setTimeout(function(){t.parentByTag(l,"FORM").submit()},1),!0}});var s=o.getDropdownMenu(i.identify(elBySel(".pageHeaderSearchType"))),c=this._click.bind(this);elBySelAll("a[data-object-type]",s,function(e){e.addEventListener(WCF_CLICK_EVENT,c)});var u=elBySel('a[data-object-type="'+a+'"]',s);e.triggerEvent(u,WCF_CLICK_EVENT)},_click:function(e){e.preventDefault();var t=elById("pageHeader");t.classList.add("searchBarForceOpen"),window.setTimeout(function(){t.classList.remove("searchBarForceOpen")},10);var i=elData(e.currentTarget,"object-type"),n=elById("pageHeaderSearchParameters");n.innerHTML="";var o=elData(e.currentTarget,"extended-link");o&&(elBySel(".pageHeaderSearchExtendedLink").href=o);var r=elData(e.currentTarget,"parameters");r=r?JSON.parse(r):{},i&&(r["types[]"]=i);for(var a in r)if(r.hasOwnProperty(a)){var l=elCreate("input");l.type="hidden",l.name=a,l.value=r[a],n.appendChild(l)}elBySel(".pageHeaderSearchType > .button > .pageHeaderSearchTypeLabel",elById("pageHeaderSearchInputContainer")).textContent=e.currentTarget.textContent}}}),define("WoltLabSuite/Core/Ui/Smiley/Insert",["EventHandler","EventKey"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={_container:null,_editorId:"",init:function(e){if(this._editorId=e,this._container=elById("smilies-"+this._editorId),!this._container&&(this._container=elById(this._editorId+"SmiliesTabContainer"),!this._container))throw new Error("Unable to find the message tab menu container containing the smilies.");this._container.addEventListener("keydown",this._keydown.bind(this)),this._container.addEventListener("mousedown",this._mousedown.bind(this))},_keydown:function(e){var i=document.activeElement;if(i.classList.contains("jsSmiley"))if(t.ArrowLeft(e)||t.ArrowRight(e)||t.Home(e)||t.End(e)){e.preventDefault();var n=Array.prototype.slice.call(elBySelAll(".jsSmiley",e.currentTarget));t.ArrowLeft(e)&&n.reverse();var o=n.indexOf(i);t.Home(e)?o=0:t.End(e)?o=n.length-1:(o+=1)===n.length&&(o=0),n[o].focus()}else(t.Enter(e)||t.Space(e))&&(e.preventDefault(),this._insert(elBySel("img",i)))},_mousedown:function(e){var t=e.target.closest("li");if(this._container.contains(t)){e.preventDefault();var i=elBySel("img",t);i&&this._insert(i)}},_insert:function(t){e.fire("com.woltlab.wcf.redactor2","insertSmiley_"+this._editorId,{img:t})}},i}),define("WoltLabSuite/Core/Ui/Style/FontAwesome",["Language","Ui/Dialog","WoltLabSuite/Core/Ui/ItemList/Filter"],function(e,t,i){"use strict";var n=function(){};return n.prototype={setup:function(){},open:function(){},_click:function(){},_dialogSetup:function(){}},n}),define("WoltLabSuite/Core/Ui/Toggle/Input",["Core"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={init:function(t,i){if(this._element=elBySel(t),null===this._element)throw new Error("Unable to find element by selector '"+t+"'.");var n="INPUT"===this._element.nodeName?elAttr(this._element,"type"):"";if("checkbox"!==n&&"radio"!==n)throw new Error("Illegal element, expected input[type='checkbox'] or input[type='radio'].");this._options=e.extend({hide:[],show:[]},i),["hide","show"].forEach(function(e){var t,i,n;for(i=0,n=this._options[e].length;i<n;i++)if("string"!=typeof(t=this._options[e][i])&&!(t instanceof Element))throw new TypeError("The array '"+e+"' may only contain string selectors or DOM elements.")}.bind(this)),this._element.addEventListener("change",this._change.bind(this)),this._handleElements(this._options.show,this._element.checked),this._handleElements(this._options.hide,!this._element.checked)},_change:function(e){var t=e.currentTarget.checked;this._handleElements(this._options.show,t),this._handleElements(this._options.hide,!t)},_handleElements:function(e,t){for(var i,n,o=0,r=e.length;o<r;o++){if("string"==typeof(i=e[o])){if(null===(n=elBySel(i)))throw new Error("Unable to find element by selector '"+i+"'.");e[o]=i=n}window[t?"elShow":"elHide"](i)}}},t}),define("WoltLabSuite/Core/Ui/User/Editor",["Ajax","Language","StringUtil","Dom/Util","Ui/Dialog","Ui/Notification"],function(e,t,i,n,o,r){"use strict";var a=function(){};return a.prototype={init:function(){},_click:function(){},_submit:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},_dialogSetup:function(){}},a}),define("WoltLabSuite/Core/Ui/User/PasswordStrength",["Core","Language"],function(e,t){"use strict";function i(e,t){return e.map(t).reduce(function(e,t){return e.concat(t)},[])}function n(e){return[].concat(e,e.split(/\W+/))}function o(i){var n=e.extend({},i.default_phrases);for(var o in n)if(n.hasOwnProperty(o))for(var r in n[o])if(n[o].hasOwnProperty(r)){var a="wcf.user.password.zxcvbn."+o+"."+r,l=t.get(a);l!==a&&(n[o][r]=l)}return new i(n)}function r(e,t){require(["zxcvbn"]).then(function(i){var n=i[0];this.init(n,e,t)}.bind(this))}var a=[];return elBySel('meta[property="og:site_name"]')&&a.push(elBySel('meta[property="og:site_name"]').getAttribute("content")),r.prototype={init:function(i,n,r){this._zxcvbn=i,this._input=n,this._options=e.extend({relatedInputs:[],staticDictionary:[]},r),this._options.feedbacker||(this._options.feedbacker=o(i.Feedback)),this._wrapper=elCreate("div"),this._wrapper.className="inputAddon inputAddonPasswordStrength",this._input.parentNode.insertBefore(this._wrapper,this._input),this._wrapper.appendChild(this._input);var a=elCreate("div");a.className="passwordStrengthRating";var l=elCreate("small");l.textContent=t.get("wcf.user.password.strength"),a.appendChild(l),this._score=elCreate("span"),this._score.className="passwordStrengthScore",elData(this._score,"score","-1"),a.appendChild(this._score),this._wrapper.appendChild(a),this._feedback=elCreate("div"),this._feedback.className="passwordStrengthFeedback",this._wrapper.appendChild(this._feedback),this._verdictResult=elCreate("input"),this._verdictResult.type="hidden",this._verdictResult.name=this._input.name+"_passwordStrengthVerdict",this._wrapper.parentNode.insertBefore(this._verdictResult,this._wrapper);var s=this._evaluate.bind(this);this._input.addEventListener("input",s),this._options.relatedInputs.forEach(function(e){e.addEventListener("input",s)}),""!==this._input.value.trim()&&this._evaluate()},_evaluate:function(e){var t=i(a.concat(this._options.staticDictionary,this._options.relatedInputs.map(function(e){return e.value.trim()})),n).filter(function(e){return e.length>0}),o=this._input.value.trim(),r=this._zxcvbn(o.substr(0,100),t);r.feedback=this._options.feedbacker.from_result(r),elData(this._score,"score",0===o.length?"-1":r.score),void 0!==e&&elInnerError(this._wrapper,r.feedback.warning),this._verdictResult.value=JSON.stringify(r)}},r}),define("WoltLabSuite/Core/Controller/Condition/Page/Dependence",["Dom/ChangeListener","Dom/Traverse","EventHandler","ObjectMap"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={register:function(){},_checkVisibility:function(){},_hideDependentElement:function(){},_showDependentElement:function(){}},o}),define("WoltLabSuite/Core/Controller/Map/Route/Planner",["Dom/Traverse","Dom/Util","Language","Ui/Dialog","WoltLabSuite/Core/Ajax/Status"],function(e,t,i,n,o){function r(e,t){if(this._button=elById(e),null===this._button)throw new Error("Unknown button with id '"+e+"'");this._button.addEventListener("click",this._openDialog.bind(this)),this._destination=t}return r.prototype={_dialogSetup:function(){return{id:this._button.id+"Dialog",options:{onShow:this._initDialog.bind(this),title:i.get("wcf.map.route.planner")},source:'<div class="googleMapsDirectionsContainer" style="display: none;"><div class="googleMap"></div><div class="googleMapsDirections"></div></div><small class="googleMapsDirectionsGoogleLinkContainer"><a href="'+this._getGoogleMapsLink()+'" class="googleMapsDirectionsGoogleLink" target="_blank" style="display: none;">'+i.get("wcf.map.route.viewOnGoogleMaps")+"</a></small><dl><dt>"+i.get("wcf.map.route.origin")+'</dt><dd><input type="text" name="origin" class="long" autofocus /></dd></dl><dl style="display: none;"><dt>'+i.get("wcf.map.route.travelMode")+'</dt><dd><select name="travelMode"><option value="driving">'+i.get("wcf.map.route.travelMode.driving")+'</option><option value="walking">'+i.get("wcf.map.route.travelMode.walking")+'</option><option value="bicycling">'+i.get("wcf.map.route.travelMode.bicycling")+'</option><option value="transit">'+i.get("wcf.map.route.travelMode.transit")+"</option></select></dd></dl>"}},_calculateRoute:function(e){var t=n.getDialog(this).dialog;e.label&&(this._originInput.value=e.label),void 0===this._map&&(this._map=new google.maps.Map(elByClass("googleMap",t)[0],{disableDoubleClickZoom:WCF.Location.GoogleMaps.Settings.get("disableDoubleClickZoom"),draggable:WCF.Location.GoogleMaps.Settings.get("draggable"),mapTypeId:google.maps.MapTypeId.ROADMAP,scaleControl:WCF.Location.GoogleMaps.Settings.get("scaleControl"),scrollwheel:WCF.Location.GoogleMaps.Settings.get("scrollwheel")}),this._directionsService=new google.maps.DirectionsService,this._directionsRenderer=new google.maps.DirectionsRenderer,this._directionsRenderer.setMap(this._map),this._directionsRenderer.setPanel(elByClass("googleMapsDirections",t)[0]),this._googleLink=elByClass("googleMapsDirectionsGoogleLink",t)[0]);var i={destination:this._destination,origin:e.location,provideRouteAlternatives:!0,travelMode:google.maps.TravelMode[this._travelMode.value.toUpperCase()]};o.show(),this._directionsService.route(i,this._setRoute.bind(this)),elAttr(this._googleLink,"href",this._getGoogleMapsLink(e.location,this._travelMode.value)),this._lastOrigin=e.location},_getGoogleMapsLink:function(e,t){if(e){var i="https://www.google.com/maps/dir/?api=1&origin="+e.lat()+","+e.lng()+"&destination="+this._destination.lat()+","+this._destination.lng();return t&&(i+="&travelmode="+t),i}return"https://www.google.com/maps/search/?api=1&query="+this._destination.lat()+","+this._destination.lng()},_initDialog:function(){if(!this._didInitDialog){var e=n.getDialog(this).dialog;this._originInput=elBySel('input[name="origin"]',e),new WCF.Location.GoogleMaps.LocationSearch(this._originInput,this._calculateRoute.bind(this)),this._travelMode=elBySel('select[name="travelMode"]',e),this._travelMode.addEventListener("change",this._updateRoute.bind(this)),this._didInitDialog=!0}},_openDialog:function(){n.open(this)},_setRoute:function(t,n){o.hide(),"OK"===n?(elShow(this._map.getDiv().parentNode),google.maps.event.trigger(this._map,"resize"),this._directionsRenderer.setDirections(t),elShow(e.parentByTag(this._travelMode,"DL")),elShow(this._googleLink),elInnerError(this._originInput,!1)):("OVER_QUERY_LIMIT"!==n&&"REQUEST_DENIED"!==n&&(n="NOT_FOUND"),elInnerError(this._originInput,i.get("wcf.map.route.error."+n.toLowerCase())))},_updateRoute:function(){this._calculateRoute({location:this._lastOrigin})}},r}),define("WoltLabSuite/Core/Controller/User/Notification/Settings",["Language","Ui/ReusableDropdown"],function(e,t){"use strict";return function(){}}),define("WoltLabSuite/Core/Form/Builder/Container/SuffixFormField",["EventHandler","Ui/SimpleDropdown"],function(e,t){"use strict";function i(i,n){this._formId=i,this._suffixField=elById(n),this._suffixDropdownMenu=t.getDropdownMenu(n+"_dropdown"),this._suffixDropdownToggle=elByClass("dropdownToggle",t.getDropdown(n+"_dropdown"))[0];for(var o=this._suffixDropdownMenu.children,r=0,a=o.length;r<a;r++)o[r].addEventListener("click",this._changeSuffixSelection.bind(this));e.add("WoltLabSuite/Core/Form/Builder/Manager","afterUnregisterForm",this._destroyDropdown.bind(this))}return i.prototype={_changeSuffixSelection:function(e){if(!e.currentTarget.classList.contains("disabled")){for(var t=this._suffixDropdownMenu.children,i=0,n=t.length;i<n;i++)t[i]===e.currentTarget?t[i].classList.add("active"):t[i].classList.remove("active");this._suffixField.value=elData(e.currentTarget,"value"),this._suffixDropdownToggle.innerHTML=elData(e.currentTarget,"label")+' <span class="icon icon16 fa-caret-down pointer"></span>'}},_destroyDropdown:function(e){e.formId===this._formId&&t.destroy(this._suffixDropdownMenu.id)}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Acl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e),this._aclList=null}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._aclList.getData(),e},_readField:function(){},setAclList:function(e){this._aclList=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Captcha",["Core","./Field","WoltLabSuite/Core/Controller/Captcha"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){return i.has(this._fieldId)?i.getData(this._fieldId):{}},_readField:function(){},destroy:function(){i.has(this._fieldId)&&i.delete(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Checkboxes",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=0,i=this._fields.length;t<i;t++)this._fields[t].checked&&e[this._fieldId].push(this._fields[t].value);return e},_readField:function(){this._fields=elBySelAll('input[name="'+this._fieldId+'[]"]')}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Checked",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=~~this._field.checked,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Date",["Core","WoltLabSuite/Core/Date/Picker","./Field"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{_getData:function(){var e={};return e[this._fieldId]=t.getValue(this._field),e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/ItemList",["Core","./Field","WoltLabSuite/Core/Ui/ItemList/Static"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,o=t.length;n<o;n++)t[n].objectId?e[this._fieldId][t[n].objectId]=t[n].value:e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/RadioButton",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){for(var e={},t=0,i=this._fields.length;t<i;t++)if(this._fields[t].checked){e[this._fieldId]=this._fields[t].value;break}return e},_readField:function(){this._fields=elBySelAll("input[name="+this._fieldId+"]")}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/SimpleAcl",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e=[];elBySelAll('input[name="'+this._fieldId+'[group][]"]',void 0,function(t){e.push(~~t.value)});var t=[];elBySelAll('input[name="'+this._fieldId+'[user][]"]',void 0,function(e){t.push(~~e.value)});var i={};return i[this._fieldId]={group:e,user:t},i},_readField:function(){}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Tag",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={};e[this._fieldId]=[];for(var t=i.getValues(this._fieldId),n=0,o=t.length;n<o;n++)e[this._fieldId].push(t[n].value);return e}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/User",["Core","./Field","WoltLabSuite/Core/Ui/ItemList"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){for(var e=i.getValues(this._fieldId),t=[],n=0,o=e.length;n<o;n++)t.push(e[n].value);var r={};return r[this._fieldId]=t.join(","),r}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Value",["Core","./Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){var e={};return e[this._fieldId]=this._field.value,e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/ValueI18n",["Core","./Field","WoltLabSuite/Core/Language/Input"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,t,{_getData:function(){var e={},t=i.getValues(this._fieldId);return t.size>1?e[this._fieldId+"_i18n"]=t.toObject():e[this._fieldId]=t.get(0),e},destroy:function(){i.unregister(this._fieldId)}}),n}),define("WoltLabSuite/Core/Ui/Comment/Response/Add",["Core","Language","Dom/ChangeListener","Dom/Util","Dom/Traverse","Ui/Notification","WoltLabSuite/Core/Ui/Comment/Add"],function(e,t,i,n,o,r,a){"use strict";var l=function(){};return l.prototype={init:function(){},getContainer:function(){},getContent:function(){},setContent:function(){},_submitGuestDialog:function(){},_submit:function(){},_getParameters:function(){},_validate:function(){},throwError:function(){},_showLoadingOverlay:function(){},_hideLoadingOverlay:function(){},_reset:function(){},_handleError:function(){},_getEditor:function(){},_insertMessage:function(){},_ajaxSuccess:function(){},_ajaxFailure:function(){},_ajaxSetup:function(){}},l}),define("WoltLabSuite/Core/Ui/Comment/Response/Edit",["Ajax","Core","Dictionary","Environment","EventHandler","Language","List","Dom/ChangeListener","Dom/Traverse","Dom/Util","Ui/Notification","Ui/ReusableDropdown","WoltLabSuite/Core/Ui/Scroll","WoltLabSuite/Core/Ui/Comment/Edit"],function(e,t,i,n,o,r,a,l,s,c,u,d,h,f){"use strict";var p=function(){};return p.prototype={init:function(){},rebuild:function(){},_click:function(){},_prepare:function(){},_showEditor:function(){},_restoreMessage:function(){},_save:function(){},_validate:function(){},throwError:function(){},_showMessage:function(){},_hideEditor:function(){},_restoreEditor:function(){},_destroyEditor:function(){},_getEditorId:function(){},_getObjectId:function(){},_ajaxFailure:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){}},p}),define("WoltLabSuite/Core/Ui/Page/Header/Fixed",["Core","EventHandler","Ui/Alignment","Ui/CloseOverlay","Ui/SimpleDropdown","Ui/Screen"],function(e,t,i,n,o,r){"use strict";var a,l,s,c,u,d,h,f=!1;return{init:function(){a=elById("pageHeader"),l=elById("pageHeaderContainer"),this._initSearchBar(),r.on("screen-md-down",{match:function(){f=!0},unmatch:function(){f=!1},setup:function(){f=!0}}),t.add("com.woltlab.wcf.Search","close",this._closeSearchBar.bind(this))},_initSearchBar:function(){c=elById("pageHeaderSearch"),c.addEventListener(WCF_CLICK_EVENT,function(e){e.stopPropagation()}),s=elById("pageHeaderPanel"),u=elById("pageHeaderSearchInput"),d=elById("topMenu"),h=elById("userPanelSearchButton"),h.addEventListener(WCF_CLICK_EVENT,function(e){e.preventDefault(),e.stopPropagation(),a.classList.contains("searchBarOpen")?this._closeSearchBar():this._openSearchBar()}.bind(this)),n.add("WoltLabSuite/Core/Ui/Page/Header/Fixed",function(){a.classList.contains("searchBarForceOpen")||this._closeSearchBar()}.bind(this)),t.add("com.woltlab.wcf.MainMenuMobile","more",function(t){"com.woltlab.wcf.search"===t.identifier&&(t.handler.close(!0),e.triggerEvent(h,WCF_CLICK_EVENT))}.bind(this))},_openSearchBar:function(){window.WCF.Dropdown.Interactive.Handler.closeAll(),a.classList.add("searchBarOpen"),h.parentNode.classList.add("open"),f||i.set(c,d,{horizontal:"right"}),c.style.setProperty("top",s.clientHeight+"px",""),u.focus(),window.setTimeout(function(){u.selectionStart=u.selectionEnd=u.value.length},1)},_closeSearchBar:function(){a.classList.remove("searchBarOpen"),h.parentNode.classList.remove("open"),["bottom","left","right","top"].forEach(function(e){c.style.removeProperty(e)}),u.blur();var e=elBySel(".pageHeaderSearchType",c);o.close(e.id)}}}),define("WoltLabSuite/Core/Ui/Page/Search/Input",["Core","WoltLabSuite/Core/Ui/Search/Input"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return e.inherit(i,t,{init:function(t,n){if(n=e.extend({ajax:{className:"wcf\\data\\page\\PageAction"},callbackSuccess:null},n),"function"!=typeof n.callbackSuccess)throw new Error("Expected a valid callback function for 'callbackSuccess'.");i._super.prototype.init.call(this,t,n),this._pageId=0},setPageId:function(e){this._pageId=e},_getParameters:function(e){var t=i._super.prototype._getParameters.call(this,e);return t.objectIDs=[this._pageId],t},_ajaxSuccess:function(e){this._options.callbackSuccess(e)}}),i}),define("WoltLabSuite/Core/Ui/Page/Search/Handler",["Language","StringUtil","Dom/Util","Ui/Dialog","./Input"],function(e,t,i,n,o){"use strict";var r=null,a=null,l=null,s=null,c=null,u=null;return{open:function(t,i,o,a){r=o,n.open(this),n.setTitle(this,i),l.textContent=a?e.get(a):e.get("wcf.page.pageObjectID.search.terms"),this._getSearchInputHandler().setPageId(t)},_buildList:function(i){if(this._resetList(),!Array.isArray(i.returnValues)||0===i.returnValues.length)return void elInnerError(a,e.get("wcf.page.pageObjectID.search.noResults"));for(var n,o,r,l=0,s=i.returnValues.length;l<s;l++)o=i.returnValues[l],n=o.image,/^fa-/.test(n)&&(n='<span class="icon icon48 '+n+' pointer jsTooltip" title="'+e.get("wcf.global.select")+'"></span>'),r=elCreate("li"),elData(r,"object-id",o.objectID),r.innerHTML='<div class="box48">'+n+'<div><div class="containerHeadline"><h3><a href="'+t.escapeHTML(o.link)+'">'+t.escapeHTML(o.title)+"</a></h3>"+(o.description?"<p>"+o.description+"</p>":"")+"</div></div></div>",r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),c.appendChild(r);elShow(u)},_resetList:function(){elInnerError(a,!1),c.innerHTML="",elHide(u)},_getSearchInputHandler:function(){if(null===s){var e=this._buildList.bind(this);s=new o(elById("wcfUiPageSearchInput"),{callbackSuccess:e})}return s},_click:function(e){"A"!==e.target.nodeName&&(e.stopPropagation(),r(elData(e.currentTarget,"object-id")),n.close(this))},_dialogSetup:function(){return{id:"wcfUiPageSearchHandler",options:{onShow:function(){null===a&&(a=elById("wcfUiPageSearchInput"),l=a.parentNode.previousSibling.childNodes[0],c=elById("wcfUiPageSearchResultList"),u=elById("wcfUiPageSearchResultListContainer")),a.value="",elHide(u),c.innerHTML="",a.focus()},title:""},source:'<div class="section"><dl><dt><label for="wcfUiPageSearchInput">'+e.get("wcf.page.pageObjectID.search.terms")+'</label></dt><dd><input type="text" id="wcfUiPageSearchInput" class="long"></dd></dl></div><section id="wcfUiPageSearchResultListContainer" class="section sectionContainerList"><header class="sectionHeader"><h2 class="sectionTitle">'+e.get("wcf.page.pageObjectID.search.results")+'</h2></header><ul id="wcfUiPageSearchResultList" class="containerList wcfUiPageSearchResultList"></ul></section>'}}}}),define("WoltLabSuite/Core/Ui/Reaction/Profile/Loader",["Ajax","Core","Language"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){if(this._container=elById("likeList"),this._userID=e,this._reactionTypeID=null,this._targetType="received",this._options={parameters:[]},!this._userID)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'userID' given.");var t=elCreate("li");t.className="likeListMore showMore",this._noMoreEntries=elCreate("small"),this._noMoreEntries.innerHTML=i.get("wcf.like.reaction.noMoreEntries"),this._noMoreEntries.style.display="none",t.appendChild(this._noMoreEntries),this._loadButton=elCreate("button"),this._loadButton.className="small",this._loadButton.innerHTML=i.get("wcf.like.reaction.more"),this._loadButton.addEventListener(WCF_CLICK_EVENT,this._loadReactions.bind(this)),this._loadButton.style.display="none",t.appendChild(this._loadButton),this._container.appendChild(t),2===elBySel("#likeList > li").length?this._noMoreEntries.style.display="":this._loadButton.style.display="",this._setupReactionTypeButtons(),this._setupTargetTypeButtons()},_setupReactionTypeButtons:function(){for(var e,t=elBySelAll("#reactionType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeReactionTypeValue.bind(this,~~elData(e,"reaction-type-id")))},_setupTargetTypeButtons:function(){for(var e,t=elBySelAll("#likeType .button"),i=0,n=t.length;i<n;i++)e=t[i],e.addEventListener(WCF_CLICK_EVENT,this._changeTargetType.bind(this,elData(e,"like-type")))},_changeTargetType:function(e){if("given"!==e&&"received"!==e)throw new Error("[WoltLabSuite/Core/Ui/Reaction/Profile/Loader] Invalid parameter 'targetType' given.");e!==this._targetType&&(elBySel("#likeType .button.active").classList.remove("active"),elBySel('#likeType .button[data-like-type="'+e+'"]').classList.add("active"),this._targetType=e,this._reload())},_changeReactionTypeValue:function(e){var t=elBySel("#reactionType .button.active");t&&t.classList.remove("active"),this._reactionTypeID!==e?(elBySel('#reactionType .button[data-reaction-type-id="'+e+'"]').classList.add("active"),this._reactionTypeID=e):this._reactionTypeID=null,this._reload()},_reload:function(){for(var e=elBySelAll("#likeList > li:not(:first-child):not(:last-child)"),t=0,i=e.length;t<i;t++)this._container.removeChild(e[t]);elData(this._container,"last-like-time",0),this._loadReactions()},_loadReactions:function(){this._options.parameters.userID=this._userID,this._options.parameters.lastLikeTime=elData(this._container,"last-like-time"),this._options.parameters.targetType=this._targetType,this._options.parameters.reactionTypeID=this._reactionTypeID,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){e.returnValues.template?(elBySel("#likeList > li:nth-last-child(1)").insertAdjacentHTML("beforebegin",e.returnValues.template),elData(this._container,"last-like-time",e.returnValues.lastLikeTime),this._noMoreEntries.style.display="none",this._loadButton.style.display=""):(this._noMoreEntries.style.display="",this._loadButton.style.display="none")},_ajaxSetup:function(){return{data:{actionName:"load",className:"\\wcf\\data\\reaction\\ReactionAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/Activity/Recent",["Ajax","Language","Dom/Util"],function(e,t,i){"use strict";function n(e){this.init(e)}return n.prototype={init:function(e){this._containerId=e;var i=elById(this._containerId);this._list=elBySel(".recentActivityList",i);var n=elCreate("li");n.className="showMore",this._list.childElementCount?(n.innerHTML='<button class="small">'+t.get("wcf.user.recentActivity.more")+"</button>",n.children[0].addEventListener(WCF_CLICK_EVENT,this._showMore.bind(this))):n.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>",this._list.appendChild(n),this._showMoreItem=n,elBySelAll(".jsRecentActivitySwitchContext .button",i,function(e){e.addEventListener(WCF_CLICK_EVENT,function(t){t.preventDefault(),e.classList.contains("active")||this._switchContext()}.bind(this))}.bind(this))},_showMore:function(t){t.preventDefault(),this._showMoreItem.children[0].disabled=!0,e.api(this,{actionName:"load",parameters:{boxID:~~elData(this._list,"box-id"),
+filteredByFollowedUsers:elDataBool(this._list,"filtered-by-followed-users"),lastEventId:elData(this._list,"last-event-id"),lastEventTime:elData(this._list,"last-event-time"),userID:~~elData(this._list,"user-id")}})},_switchContext:function(){e.api(this,{actionName:"switchContext"},function(){window.location.hash="#"+this._containerId,window.location.reload()}.bind(this))},_ajaxSuccess:function(e){e.returnValues.template?(i.insertHtml(e.returnValues.template,this._showMoreItem,"before"),elData(this._list,"last-event-time",e.returnValues.lastEventTime),elData(this._list,"last-event-id",e.returnValues.lastEventID),this._showMoreItem.children[0].disabled=!1):this._showMoreItem.innerHTML="<small>"+t.get("wcf.user.recentActivity.noMoreEntries")+"</small>"},_ajaxSetup:function(){return{data:{className:"wcf\\data\\user\\activity\\event\\UserActivityEventAction"}}}},n}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Delete",["Ajax","EventHandler","Language","Ui/Confirmation","Ui/Notification"],function(e,t,i,n,o){"use strict";var r,a=0;return{init:function(e){r=elBySel(".jsButtonDeleteCoverPhoto"),r.addEventListener(WCF_CLICK_EVENT,this._click.bind(this)),a=e,t.add("com.woltlab.wcf.user","coverPhoto",function(e){"string"==typeof e.url&&e.url.length>0&&elShow(r.parentNode)})},_click:function(t){t.preventDefault(),n.show({confirm:e.api.bind(e,this),message:i.get("wcf.user.coverPhoto.delete.confirmMessage")})},_ajaxSuccess:function(e){elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+e.returnValues.url+")",""),elHide(r.parentNode),o.show()},_ajaxSetup:function(){return{data:{actionName:"deleteCoverPhoto",className:"wcf\\data\\user\\UserProfileAction",parameters:{userID:a}}}}}}),define("WoltLabSuite/Core/Ui/User/CoverPhoto/Upload",["Core","EventHandler","Upload","Ui/Notification","Ui/Dialog"],function(e,t,i,n,o){"use strict";function r(e){i.call(this,"coverPhotoUploadButtonContainer","coverPhotoUploadPreview",{action:"uploadCoverPhoto",className:"wcf\\data\\user\\UserProfileAction"}),this._userId=e}return e.inherit(r,i,{_getParameters:function(){return{userID:this._userId}},_success:function(e,i){elInnerError(this._button,i.returnValues.errorMessage),this._target.innerHTML="",i.returnValues.url&&(elBySel(".userProfileCoverPhoto").style.setProperty("background-image","url("+i.returnValues.url+")",""),o.close("userProfileCoverPhotoUpload"),n.show(),t.fire("com.woltlab.wcf.user","coverPhoto",{url:i.returnValues.url}))}}),r}),define("WoltLabSuite/Core/Ui/User/Trophy/List",["Ajax","Core","Dictionary","Dom/Util","Ui/Dialog","WoltLabSuite/Core/Ui/Pagination","Dom/ChangeListener","List"],function(e,t,i,n,o,r,a,l){"use strict";function s(){this.init()}return s.prototype={init:function(){this._cache=new i,this._knownElements=new l,this._options={className:"wcf\\data\\user\\trophy\\UserTrophyAction",parameters:{}},this._rebuild(),a.add("WoltLabSuite/Core/Ui/User/Trophy/List",this._rebuild.bind(this))},_rebuild:function(){elBySelAll(".userTrophyOverlayList",void 0,function(e){this._knownElements.has(e)||(e.addEventListener(WCF_CLICK_EVENT,this._open.bind(this,elData(e,"user-id"))),this._knownElements.add(e))}.bind(this))},_open:function(e,t){t.preventDefault(),this._currentPageNo=1,this._currentUser=e,this._showPage()},_showPage:function(t){if(void 0!==t&&(this._currentPageNo=t),this._cache.has(this._currentUser)){if(0!==this._cache.get(this._currentUser).get("pageCount")&&(this._currentPageNo<1||this._currentPageNo>this._cache.get(this._currentUser).get("pageCount")))throw new RangeError("pageNo must be between 1 and "+this._cache.get(this._currentUser).get("pageCount")+" ("+this._currentPageNo+" given).")}else this._cache.set(this._currentUser,new i);if(this._cache.get(this._currentUser).has(this._currentPageNo)){var n=o.open(this,this._cache.get(this._currentUser).get(this._currentPageNo));if(o.setTitle("userTrophyListOverlay",this._cache.get(this._currentUser).get("title")),this._cache.get(this._currentUser).get("pageCount")>1){var a=elBySel(".jsPagination",n.content);null!==a&&new r(a,{activePage:this._currentPageNo,maxPage:this._cache.get(this._currentUser).get("pageCount"),callbackSwitch:this._showPage.bind(this)})}}else this._options.parameters.pageNo=this._currentPageNo,this._options.parameters.userID=this._currentUser,e.api(this,{parameters:this._options.parameters})},_ajaxSuccess:function(e){void 0!==e.returnValues.pageCount&&this._cache.get(this._currentUser).set("pageCount",~~e.returnValues.pageCount),this._cache.get(this._currentUser).set(this._currentPageNo,e.returnValues.template),this._cache.get(this._currentUser).set("title",e.returnValues.title),this._showPage()},_ajaxSetup:function(){return{data:{actionName:"getGroupedUserTrophyList",className:this._options.className}}},_dialogSetup:function(){return{id:"userTrophyListOverlay",options:{title:""},source:null}}},s}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Label",["Core","Dom/Util","Language","Ui/SimpleDropdown"],function(e,t,i,n){"use strict";function o(e,t,i){this.init(e,t,i)}return o.prototype={init:function(o,r,a){this._formFieldContainer=elById(o+"Container"),this._labelChooser=elByClass("labelChooser",this._formFieldContainer)[0],this._options=e.extend({forceSelection:!1,showWithoutSelection:!1},a),this._input=elCreate("input"),this._input.type="hidden",this._input.id=o,this._input.name=o,this._input.value=~~r,this._formFieldContainer.appendChild(this._input);var l=t.identify(this._labelChooser),s=n.getDropdownMenu(l);null===s&&(n.init(elByClass("dropdownToggle",this._labelChooser)[0]),s=n.getDropdownMenu(l));var c=null;if(this._options.showWithoutSelection||!this._options.forceSelection){c=elCreate("ul"),s.appendChild(c);var u=elCreate("li");u.className="dropdownDivider",c.appendChild(u)}if(this._options.showWithoutSelection){var d=elCreate("li");elData(d,"label-id",-1),this._blockScroll(d),c.appendChild(d);var h=elCreate("span");d.appendChild(h);var f=elCreate("span");f.className="badge label",f.innerHTML=i.get("wcf.label.withoutSelection"),h.appendChild(f)}if(!this._options.forceSelection){var d=elCreate("li");elData(d,"label-id",0),this._blockScroll(d),c.appendChild(d);var h=elCreate("span");d.appendChild(h);var f=elCreate("span");f.className="badge label",f.innerHTML=i.get("wcf.label.none"),h.appendChild(f)}elBySelAll("li:not(.dropdownDivider)",s,function(e){e.addEventListener("click",this._click.bind(this)),r&&~~elData(e,"label-id")===r&&this._selectLabel(e)}.bind(this))},_blockScroll:function(e){e.addEventListener("wheel",function(e){e.preventDefault()},{passive:!1})},_click:function(e){e.preventDefault(),this._selectLabel(e.currentTarget,!1)},_selectLabel:function(e){var t=elData(e,"label-id");t||(t=0);var i=elBySel("span > span",e),n=elBySel(".dropdownToggle > span",this._labelChooser);n.className=i.className,n.textContent=i.textContent,this._input.value=t}},o}),define("WoltLabSuite/Core/Form/Builder/Field/Controller/Rating",["Dictionary","Environment"],function(e,t){"use strict";function i(e,t,i,n){this.init(e,t,i,n)}return i.prototype={init:function(t,i,n,o){if(this._field=elBySel("#"+t+"Container"),null===this._field)throw new Error("Unknown field with id '"+t+"'");this._input=elCreate("input"),this._input.id=t,this._input.name=t,this._input.type="hidden",this._input.value=i,this._field.appendChild(this._input),this._activeCssClasses=n,this._defaultCssClasses=o,this._ratingElements=new e;var r=elBySel(".ratingList",this._field);r.addEventListener("mouseleave",this._restoreRating.bind(this)),elBySelAll("li",r,function(e){e.classList.contains("ratingMetaButton")?(e.addEventListener("click",this._metaButtonClick.bind(this)),e.addEventListener("mouseenter",this._restoreRating.bind(this))):(this._ratingElements.set(~~elData(e,"rating"),e),e.addEventListener("click",this._listItemClick.bind(this)),e.addEventListener("mouseenter",this._listItemMouseEnter.bind(this)),e.addEventListener("mouseleave",this._listItemMouseLeave.bind(this)))}.bind(this))},_listItemClick:function(e){this._input.value=~~elData(e.currentTarget,"rating"),"desktop"!==t.platform()&&this._restoreRating()},_listItemMouseEnter:function(e){var t=elData(e.currentTarget,"rating");this._ratingElements.forEach(function(e,i){var n=elByClass("icon",e)[0];this._toggleIcon(n,~~i<=~~t)}.bind(this))},_listItemMouseLeave:function(){this._ratingElements.forEach(function(e){var t=elByClass("icon",e)[0];this._toggleIcon(t,!1)}.bind(this))},_metaButtonClick:function(e){"removeRating"===elData(e.currentTarget,"action")&&(this._input.value="",this._listItemMouseLeave())},_restoreRating:function(){this._ratingElements.forEach(function(e,t){var i=elByClass("icon",e)[0];this._toggleIcon(i,~~t<=~~this._input.value)}.bind(this))},_toggleIcon:function(e,t){if(t=t||!1){for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.remove(this._defaultCssClasses[i]);for(var i=0;i<this._activeCssClasses.length;i++)e.classList.add(this._activeCssClasses[i])}else{for(var i=0;i<this._activeCssClasses.length;i++)e.classList.remove(this._activeCssClasses[i]);for(var i=0;i<this._defaultCssClasses.length;i++)e.classList.add(this._defaultCssClasses[i])}}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract",["./Manager"],function(e){"use strict";function t(e,t){this.init(e,t)}return t.prototype={checkDependency:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract.checkDependency!")},getDependentNode:function(){return this._dependentElement},getField:function(){return this._field},getFields:function(){return this._fields},init:function(t,i){if(this._dependentElement=elById(t),null===this._dependentElement)throw new Error("Unknown dependent element with container id '"+t+"Container'.");if(this._field=elById(i),null===this._field){if(this._fields=[],elBySelAll("input[type=radio][name="+i+"]",void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length&&(elBySelAll('input[type=checkbox][name="'+i+'[]"]',void 0,function(e){this._fields.push(e)}.bind(this)),!this._fields.length))throw new Error("Unknown field with id '"+i+"'.")}else if(this._fields=[this._field],"INPUT"===this._field.tagName&&"radio"===this._field.type&&""!==elData(this._field,"no-input-id")){if(this._noField=elById(elData(this._field,"no-input-id")),null===this._noField)throw new Error("Cannot find 'no' input field for input field '"+i+"'");this._fields.push(this._noField)}e.addDependency(this)}},t}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Empty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!1;return!0}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return!this._field.checked;case"radio":return!(!this._noField||!this._noField.checked)||!this._field.checked;default:return 0===this._field.value.trim().length}case"SELECT":return this._field.multiple?0===elBySelAll("option:checked",this._field).length:0==this._field.value||0===this._field.value.length;case"TEXTAREA":return 0===this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/NonEmpty",["./Abstract","Core"],function(e,t){"use strict";function i(e,t){this.init(e,t)}return t.inherit(i,e,{checkDependency:function(){if(null===this._field){for(var e=0,t=this._fields.length;e<t;e++)if(this._fields[e].checked)return!0;return!1}switch(this._field.tagName){case"INPUT":switch(this._field.type){case"checkbox":return this._field.checked;case"radio":return(!this._noField||!this._noField.checked)&&this._field.checked;default:return 0!==this._field.value.trim().length}case"SELECT":return this._field.multiple?0!==elBySelAll("option:checked",this._field).length:0!=this._field.value&&0!==this._field.value.length;case"TEXTAREA":return 0!==this._field.value.trim().length}}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Value",["./Abstract","Core","./Manager"],function(e,t,i){"use strict";function n(e,t,i){this.init(e,t),this._isNegated=!1}return t.inherit(n,e,{checkDependency:function(){if(!this._values)throw new Error("Values have not been set.");var e=[];if(this._field){if(i.isHiddenByDependencies(this._field))return!1;e.push(this._field.value)}else for(var t,n=0,o=this._fields.length;n<o;n++)if(t=this._fields[n],t.checked){if(i.isHiddenByDependencies(t))return!1;e.push(t.value)}for(var n=0,o=this._values.length;n<o;n++)for(var r=0,a=e.length;r<a;r++)if(this._values[n]==e[r])return!this._isNegated;return!!this._isNegated},negate:function(e){return this._isNegated=e,this},values:function(e){return this._values=e,this}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Language/ContentLanguage",["Core","WoltLabSuite/Core/Language/Chooser","../Value"],function(e,t,i){"use strict";function n(e){this.init(e)}return e.inherit(n,i,{destroy:function(){t.removeChooser(this._fieldId)}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Attachment",["Core","../Value"],function(e,t){"use strict";function i(e){this.init(e+"_tmpHash")}return e.inherit(i,t,{}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Poll",["Core","../Field"],function(e,t){"use strict";function i(e){this.init(e)}return e.inherit(i,t,{_getData:function(){return this._pollEditor.getData()},_readField:function(){},setPollEditor:function(e){this._pollEditor=e}}),i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Abstract",["EventHandler","../Manager"],function(e,t){"use strict";function i(e){this.init(e)}return i.prototype={checkContainer:function(){throw new Error("Missing implementation of WoltLabSuite/Core/Form/Builder/Field/Dependency/Container.checkContainer!")},init:function(e){if("string"!=typeof e)throw new TypeError("Container id has to be a string.");if(this._container=elById(e),null===this._container)throw new Error("Unknown container with id '"+e+"'.");t.addContainerCheckCallback(this.checkContainer.bind(this))}},i}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default",["./Abstract","Core","../Manager"],function(e,t,i){"use strict";function n(e){this.init(e)}return t.inherit(n,e,{checkContainer:function(){if(!elDataBool(this._container,"ignore-dependencies")&&!i.isHiddenByDependencies(this._container)){var e=!elIsHidden(this._container),t=!1,n=this._container.children,o=0;if("H2"===this._container.children.item(0).tagName||"HEADER"===this._container.children.item(0).tagName)var o=1;for(var r=o,a=n.length;r<a;r++)if(!elIsHidden(n.item(r))){t=!0;break}e!==t&&(t?elShow(this._container):elHide(this._container),i.checkContainers())}}}),n}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Tab",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,o){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=this._container.children,a=0,l=r.length;a<l;a++)if(!elIsHidden(r.item(a))){t=!0;break}if(e!==t){var s=elBySel("#"+i.identify(this._container.parentNode)+" > nav > ul > li[data-name="+this._container.id+"]",this._container.parentNode.parentNode);if(null===s)throw new Error("Cannot find tab menu entry for tab '"+this._container.id+"'.");if(t)elShow(this._container),elShow(s);else{elHide(this._container),elHide(s);var c=o.getTabMenu(i.identify(s.closest(".tabMenuContainer")));c.getActiveTab()===s&&c.selectFirstVisible()}n.checkContainers()}}}}),r}),define("WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/TabMenu",["./Abstract","Core","Dom/Util","../Manager","Ui/TabMenu"],function(e,t,i,n,o){"use strict";function r(e){this.init(e)}return t.inherit(r,e,{checkContainer:function(){if(!n.isHiddenByDependencies(this._container)){for(var e=!elIsHidden(this._container),t=!1,r=elBySelAll("#"+i.identify(this._container)+" > nav > ul > li",this._container.parentNode),a=0,l=r.length;a<l;a++)if(!elIsHidden(r[a])){t=!0;break}e!==t&&(t?(elShow(this._container),o.getTabMenu(i.identify(this._container)).selectFirstVisible()):elHide(this._container),n.checkContainers())}}}),r}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Abstract",["Ajax","Dom/Util"],function(e,t){"use strict";function i(e,t){}return i.prototype={init:function(e,t){this._userId=e,this._isActive=!1!==t,this._initButton(),this._updateButton()},_initButton:function(){var e=elCreate("a");e.href="#",e.addEventListener(WCF_CLICK_EVENT,this._toggle.bind(this));var i=elCreate("li");i.appendChild(e);var n=elBySel('.userProfileButtonMenu[data-menu="interaction"]');t.prepend(i,n),this._button=e,this._listItem=i},_toggle:function(t){t.preventDefault(),e.api(this,{actionName:this._getAjaxActionName(),parameters:{data:{userID:this._userId}}})},_updateButton:function(){this._button.textContent=this._getLabel(),this._listItem.classList[this._isActive?"add":"remove"]("active")},_getLabel:function(){throw new Error("Implement me!")},_getAjaxActionName:function(){throw new Error("Implement me!")},_ajaxSuccess:function(){throw new Error("Implement me!")},_ajaxSetup:function(){throw new Error("Implement me!")}},i}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Follow",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={_getLabel:function(){},_getAjaxActionName:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},init:function(){},_initButton:function(){},_toggle:function(){},_updateButton:function(){}},o}),define("WoltLabSuite/Core/Ui/User/Profile/Menu/Item/Ignore",["Core","Language","Ui/Notification","./Abstract"],function(e,t,i,n){"use strict";var o=function(){};return o.prototype={_getLabel:function(){},_getAjaxActionName:function(){},_ajaxSuccess:function(){},_ajaxSetup:function(){},init:function(){},_initButton:function(){},_toggle:function(){},_updateButton:function(){}},o}),function(e){e.matches=e.matches||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector,e.closest=e.closest||function(e){for(var t=this;t&&!t.matches(e);)t=t.parentElement;return t}}(Element.prototype),define("closest",function(){}),function(e){function t(){for(;n.length&&"function"==typeof n[0];)n.shift()()}var i=e.require,n=[],o=0;e.orgRequire=i,e.require=function(r,a,l){if(!Array.isArray(r))return i.apply(e,arguments);var s=new Promise(function(e,a){var l=o++;n.push(l),i(r,function(){var i=arguments;n[n.indexOf(l)]=function(){e(i)},t()},function(e){n[n.indexOf(l)]=function(){a(e)},t()})});return a&&(s=s.then(function(t){return a.apply(e,t)})),l&&s.catch(l),s},e.require.config=i.config}(window),define("require.linearExecution",function(){});
\ No newline at end of file
index 0c2a10d855ac8cc7ea29dcbd5d4aa59c387cb7e7..dcbfd07372fb73817b2b7c8558b7021f687ecb41 100644 (file)
@@ -254,6 +254,10 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                 */
                _triggerDelete: function(articleId) {
                        var article = _articles.get(articleId);
+                       if (!article) {
+                               // The affected article might be hidden by the filter settings.
+                               return;
+                       }
                        
                        if (article.isArticleEdit) {
                                window.location = this._options.redirectUrl;
@@ -275,6 +279,10 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                 */
                _triggerPublish: function(articleId) {
                        var article = _articles.get(articleId);
+                       if (!article) {
+                               // The affected article might be hidden by the filter settings.
+                               return;
+                       }
                        
                        if (article.isArticleEdit) {
                                // unsupported
@@ -291,6 +299,10 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                 */
                _triggerRestore: function(articleId) {
                        var article = _articles.get(articleId);
+                       if (!article) {
+                               // The affected article might be hidden by the filter settings.
+                               return;
+                       }
                        
                        elHide(article.buttons.delete);
                        elHide(article.buttons.restore);
@@ -311,6 +323,10 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                 */
                _triggerTrash: function(articleId) {
                        var article = _articles.get(articleId);
+                       if (!article) {
+                               // The affected article might be hidden by the filter settings.
+                               return;
+                       }
                        
                        elShow(article.buttons.delete);
                        elShow(article.buttons.restore);
@@ -336,6 +352,10 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Language', 'U
                 */
                _triggerUnpublish: function(articleId) {
                        var article = _articles.get(articleId);
+                       if (!article) {
+                               // The affected article might be hidden by the filter settings.
+                               return;
+                       }
                        
                        if (article.isArticleEdit) {
                                // unsupported
index 71fbb77898db91416eb3fe8096fc365e2ca5a818..47de858f879971c19850fcd76badbd39d5b03aee 100644 (file)
@@ -1,4 +1,4 @@
-define(['Ajax', 'Dictionary', 'Language', 'Ui/Dialog'], function (Ajax, Dictionary, Language, UiDialog) {
+define(['Ajax', 'Dictionary', 'Language', 'Ui/Dialog', 'Ui/Notification'], function (Ajax, Dictionary, Language, UiDialog, UiNotification) {
        "use strict";
        
        var _buttons = new Dictionary();
@@ -142,7 +142,8 @@ define(['Ajax', 'Dictionary', 'Language', 'Ui/Dialog'], function (Ajax, Dictiona
                        if (_queue.length === 0) {
                                _buttonSyncAll.classList.remove('disabled');
                                
-                               // TODO: do stuff
+                               UiNotification.show();
+                               
                                return;
                        }
                        
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Delete.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Delete.js
deleted file mode 100644 (file)
index 075f52f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Deletes the current style's default cover photo.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Delete
- */
-define(['Ajax', 'Language', 'Ui/Confirmation', 'Ui/Notification'], function (Ajax, Language, UiConfirmation, UiNotification) {
-       "use strict";
-       
-       var _button, _styleId;
-       
-       /**
-        * @exports     WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Delete
-        */
-       return {
-               /**
-                * Initializes the delete handler and enables the delete button on upload.
-                * 
-                * @param       {int}           styleId
-                */
-               init: function (styleId) {
-                       _styleId = styleId;
-                       
-                       _button = elBySel('.jsButtonDeleteCoverPhoto');
-                       _button.addEventListener(WCF_CLICK_EVENT, this._click.bind(this));
-               },
-               
-               /**
-                * Handles clicks on the delete button.
-                * 
-                * @param       {Event}         event
-                * @protected
-                */
-               _click: function (event) {
-                       event.preventDefault();
-                       
-                       UiConfirmation.show({
-                               confirm: Ajax.api.bind(Ajax, this),
-                               message: Language.get('wcf.acp.style.coverPhoto.delete.confirmMessage')
-                       });
-               },
-               
-               _ajaxSuccess: function (data) {
-                       elById('coverPhotoPreview').style.setProperty('background-image', 'url(' + data.returnValues.url + ')', '');
-                       
-                       elHide(_button);
-                       
-                       UiNotification.show();
-               },
-               
-               _ajaxSetup: function () {
-                       return {
-                               data: {
-                                       actionName: 'deleteCoverPhoto',
-                                       className: 'wcf\\data\\style\\StyleAction',
-                                       objectIDs: [_styleId]
-                               }
-                       };
-               }
-       };
-});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Upload.js
deleted file mode 100644 (file)
index 9122e32..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Handles uploading the style's cover photo.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Acp/Ui/Style/CoverPhoto/Upload
- */
-define(['Core', 'Dom/Traverse', 'Language', 'Ui/Notification', 'Upload'], function(Core, DomTraverse, Language, UiNotification, Upload) {
-       "use strict";
-       
-       /**
-        * @constructor
-        */
-       function AcpUiStyleCoverPhotoUpload(styleId) {
-               this._styleId = ~~styleId;
-               
-               Upload.call(this, 'uploadCoverPhoto', 'coverPhotoPreview', {
-                       action: 'uploadCoverPhoto',
-                       className: 'wcf\\data\\style\\StyleAction'
-               });
-       }
-       Core.inherit(AcpUiStyleCoverPhotoUpload, Upload, {
-               /**
-                * @see WoltLabSuite/Core/Upload#_createFileElement
-                */
-               _createFileElement: function(file) {
-                       return this._target;
-               },
-               
-               /**
-                * @see WoltLabSuite/Core/Upload#_getParameters
-                */
-               _getParameters: function() {
-                       return {
-                               styleID: this._styleId
-                       };
-               },
-               
-               /**
-                * @see WoltLabSuite/Core/Upload#_success
-                */
-               _success: function(uploadId, data) {
-                       var errorMessage = '';
-                       if (data.returnValues.url) {
-                               this._target.style.setProperty('background-image', 'url(' + data.returnValues.url + '?timestamp=' + Date.now() + ')', '');
-                               
-                               UiNotification.show();
-                       }
-                       else if (data.returnValues.errorType) {
-                               errorMessage = Language.get('wcf.user.coverPhoto.upload.error.' + data.returnValues.errorType);
-                       }
-                       
-                       elInnerError(this._button, errorMessage);
-               }
-       });
-       
-       return AcpUiStyleCoverPhotoUpload;
-});
index 7f3819cf549670a80c122fb85c0c4491d72b0590..78f2b30f5e158bf67c2f9d3a3a80a2591ff6d0f0 100644 (file)
@@ -183,6 +183,7 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                }
                        };
                        
+                       var apiVersions = elBySel('.spSidebarBox[data-category="apiVersion"]', container);
                        var element;
                        var callbackChange = function() {
                                element = elBySel('.spSidebarBox[data-category="' + lastValue + '"]', container);
@@ -192,6 +193,9 @@ define(['Ajax', 'Core', 'Dictionary', 'Dom/Util', 'EventHandler', 'Ui/Screen'],
                                element = elBySel('.spSidebarBox[data-category="' + lastValue + '"]', container);
                                elShow(element);
                                
+                               var showCompatibilityNotice = elBySel('.spApiVersion', element) !== null;
+                               window[showCompatibilityNotice ? 'elShow' : 'elHide'](apiVersions);
+                               
                                // set region marker
                                _updateRegionMarker();
                        };
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Favicon/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Favicon/Upload.js
deleted file mode 100644 (file)
index 51779b7..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Handles uploading the style favicon.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Acp/Ui/Style/Favicon/Upload
- */
-define(['Core', 'Dom/Traverse', 'Language', 'Ui/Notification', 'Upload'], function(Core, DomTraverse, Language, UiNotification, Upload) {
-       "use strict";
-       
-       /**
-        * @constructor
-        */
-       function AcpUiStyleImageUpload(styleId) {
-               this._styleId = ~~styleId;
-               
-               Upload.call(this, 'uploadFavicon', 'faviconImage', {
-                       action: 'uploadFavicon',
-                       className: 'wcf\\data\\style\\StyleAction'
-               });
-       }
-       Core.inherit(AcpUiStyleImageUpload, Upload, {
-               /**
-                * @see WoltLabSuite/Core/Upload#_createFileElement
-                */
-               _createFileElement: function(file) {
-                       return this._target;
-               },
-               
-               /**
-                * @see WoltLabSuite/Core/Upload#_getParameters
-                */
-               _getParameters: function() {
-                       return {
-                               styleID: this._styleId
-                       };
-               },
-               
-               /**
-                * @see WoltLabSuite/Core/Upload#_success
-                */
-               _success: function(uploadId, data) {
-                       var errorMessage = '';
-                       if (data.returnValues.url) {
-                               elAttr(this._target, 'src', data.returnValues.url + '?timestamp=' + Date.now());
-                               
-                               UiNotification.show();
-                       }
-                       else if (data.returnValues.errorType) {
-                               errorMessage = Language.get('wcf.acp.style.favicon.error.' + data.returnValues.errorType);
-                       }
-                       
-                       elInnerError(this._button, errorMessage);
-               }
-       });
-       
-       return AcpUiStyleImageUpload;
-});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Image/Upload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Style/Image/Upload.js
deleted file mode 100644 (file)
index fc71cc8..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Handles uploading style preview images.
- * 
- * @author     Matthias Schmidt
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Acp/Ui/Style/Image/Upload
- */
-define(['Core', 'Dom/Traverse', 'Language', 'Ui/Notification', 'Upload'], function(Core, DomTraverse, Language, UiNotification, Upload) {
-       "use strict";
-       
-       /**
-        * @constructor
-        */
-       function AcpUiStyleImageUpload(styleId, tmpHash, is2x) {
-               this._is2x = (is2x === true);
-               this._styleId = ~~styleId;
-               this._tmpHash = tmpHash;
-               
-               Upload.call(this, 'uploadImage' + (this._is2x ? '2x' : ''), 'styleImage' + (this._is2x ? '2x' : ''), {
-                       className: 'wcf\\data\\style\\StyleAction'
-               });
-       }
-       Core.inherit(AcpUiStyleImageUpload, Upload, {
-               /**
-                * @see WoltLabSuite/Core/Upload#_createFileElement
-                */
-               _createFileElement: function(file) {
-                       return this._target;
-               },
-               
-               /**
-                * @see WoltLabSuite/Core/Upload#_getParameters
-                */
-               _getParameters: function() {
-                       return {
-                               is2x: this._is2x,
-                               styleId: this._styleId,
-                               tmpHash: this._tmpHash
-                       };
-               },
-               
-               /**
-                * @see WoltLabSuite/Core/Upload#_success
-                */
-               _success: function(uploadId, data) {
-                       var errorMessage = '';
-                       if (data.returnValues.url) {
-                               elAttr(this._target, 'src', data.returnValues.url + '?timestamp=' + Date.now());
-                               
-                               UiNotification.show();
-                       }
-                       else if (data.returnValues.errorType) {
-                               errorMessage = Language.get('wcf.acp.style.image.error.' + data.returnValues.errorType);
-                       }
-                       
-                       elInnerError(this._button, errorMessage);
-               }
-       });
-       
-       return AcpUiStyleImageUpload;
-});
index 8322fd650704697418779daace5e966f68352d5f..ce1b9bb697b8948ff40d7cb6238ee095daeb29a1 100644 (file)
@@ -7,7 +7,7 @@
  * @module     WoltLabSuite/Core/Acp/Ui/User/Editor
  * @since       3.1
  */
-define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/SimpleDropdown', 'WoltLabSuite/Core/Acp/Ui/User/Content/Remove/Handler'], function(Ajax, Core, EventHandler, Language, UiSimpleDropdown, RemoveContentHandler) {
+define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/Notification', 'Ui/SimpleDropdown', 'WoltLabSuite/Core/Acp/Ui/User/Content/Remove/Handler'], function(Ajax, Core, EventHandler, Language, UiNotification, UiSimpleDropdown, RemoveContentHandler) {
        "use strict";
        
        /**
@@ -80,6 +80,49 @@ define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/SimpleDropdown', 'WoltLa
                        if (deleteContent !== null) {
                                new RemoveContentHandler(deleteContent, userId);
                        }
+                       
+                       var toggleConfirmEmail = elBySel('.jsConfirmEmailToggle', dropdownMenu);
+                       if (toggleConfirmEmail !== null) {
+                               toggleConfirmEmail.addEventListener(WCF_CLICK_EVENT, function (event) {
+                                       event.preventDefault();
+                                       
+                                       Ajax.api({
+                                               _ajaxSetup: function () {
+                                                       return {
+                                                               data: {
+                                                                       actionName: (elDataBool(userRow, 'email-confirmed') ? 'un' : '') + 'confirmEmail',
+                                                                       className: 'wcf\\data\\user\\UserAction',
+                                                                       objectIDs: [userId]
+                                                               }
+                                                       };
+                                               }
+                                       }, null, function (data) {
+                                               elBySelAll('.jsUserRow', undefined, function(userRow) {
+                                                       var userId = parseInt(elData(userRow, 'object-id'));
+                                                       if (data.objectIDs.indexOf(userId) !== -1) {
+                                                               var confirmEmailButton = elBySel('.jsConfirmEmailToggle', UiSimpleDropdown.getDropdownMenu('userListDropdown' + userId));
+                                                               
+                                                               switch (data.actionName) {
+                                                                       case 'confirmEmail':
+                                                                               elData(userRow, 'email-confirmed', 'true');
+                                                                               confirmEmailButton.textContent = elData(confirmEmailButton, 'unconfirm-email-message');
+                                                                               break;
+                                                                       
+                                                                       case 'unconfirmEmail':
+                                                                               elData(userRow, 'email-confirmed', 'false');
+                                                                               confirmEmailButton.textContent = elData(confirmEmailButton, 'confirm-email-message');
+                                                                               break;
+                                                                               
+                                                                       default: 
+                                                                               throw new Error("Unreachable");
+                                                               }
+                                                       }
+                                               });
+                                               
+                                               UiNotification.show();
+                                       });
+                               });
+                       }
                },
                
                /**
index 9dcd6837ecf1940b686cadf99064048b8249ed19..e9fad9cb17cf875b429c21b20548c980c1f45dcc 100644 (file)
@@ -314,6 +314,10 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt
                        var message = '';
                        
                        if (data !== null) {
+                               if (data.returnValues && data.returnValues.description) {
+                                       details += '<br><p>Description:</p><p>' + data.returnValues.description + '</p>';
+                               }
+                               
                                if (data.file && data.line) {
                                        details += '<br><p>File:</p><p>' + data.file + ' in line ' + data.line + '</p>';
                                }
index 8002ae63db66d1b16090e40c9f50af9f7e52bdbe..20b0d5d595590081db73810eff114fb3cc3ddd67 100644 (file)
@@ -16,24 +16,34 @@ define([], function() {
         */
        return {
                observe: function() {
-                       var container, toggleButton;
+                       var container, toggleButtons, overflowContainer;
                        while (_containers.length) {
                                container = _containers[0];
                                
                                // find the matching toggle button
-                               toggleButton = null;
+                               toggleButtons = [];
                                elBySelAll('.toggleButton:not(.jsToggleButtonEnabled)', container, function (button) {
                                        //noinspection JSReferencingMutableVariableFromClosure
                                        if (button.closest('.jsCollapsibleBbcode') === container) {
-                                               toggleButton = button;
+                                               toggleButtons.push(button);
                                        }
                                });
+                               overflowContainer = elBySel('.collapsibleBbcodeOverflow', container) || container;
                                
-                               if (toggleButton) {
-                                       (function (container, toggleButton) {
+                               if (toggleButtons.length > 0) {
+                                       (function (container, toggleButtons) {
                                                var toggle = function (event) {
                                                        if (container.classList.toggle('collapsed')) {
-                                                               toggleButton.textContent = elData(toggleButton, 'title-expand');
+                                                               toggleButtons.forEach(function (toggleButton) {
+                                                                       if (toggleButton.classList.contains('icon')) {
+                                                                               toggleButton.classList.remove('fa-compress');
+                                                                               toggleButton.classList.add('fa-expand');
+                                                                               toggleButton.title = elData(toggleButton, 'title-expand');
+                                                                       }
+                                                                       else {
+                                                                               toggleButton.textContent = elData(toggleButton, 'title-expand');
+                                                                       }
+                                                               });
                                                                
                                                                if (event instanceof Event) {
                                                                        // negative top value means the upper boundary is not within the viewport
@@ -46,23 +56,36 @@ define([], function() {
                                                                }
                                                        }
                                                        else {
-                                                               toggleButton.textContent = elData(toggleButton, 'title-collapse');
+                                                               toggleButtons.forEach(function (toggleButton) {
+                                                                       if (toggleButton.classList.contains('icon')) {
+                                                                               toggleButton.classList.add('fa-compress');
+                                                                               toggleButton.classList.remove('fa-expand');
+                                                                               toggleButton.title = elData(toggleButton, 'title-collapse');
+                                                                       }
+                                                                       else {
+                                                                               toggleButton.textContent = elData(toggleButton, 'title-collapse');
+                                                                       }
+                                                               });
                                                        }
                                                };
                                                
-                                               toggleButton.classList.add('jsToggleButtonEnabled');
-                                               toggleButton.addEventListener(WCF_CLICK_EVENT, toggle);
+                                               toggleButtons.forEach(function (toggleButton) {
+                                                       toggleButton.classList.add('jsToggleButtonEnabled');
+                                                       toggleButton.addEventListener(WCF_CLICK_EVENT, toggle);
+                                               });
                                                
                                                // expand boxes that are initially scrolled
-                                               if (container.scrollTop !== 0) {
+                                               if (overflowContainer.scrollTop !== 0) {
+                                                       overflowContainer.scrollTop = 0;
                                                        toggle();
                                                }
-                                               container.addEventListener('scroll', function () {
+                                               overflowContainer.addEventListener('scroll', function () {
+                                                       overflowContainer.scrollTop = 0;
                                                        if (container.classList.contains('collapsed')) {
                                                                toggle();
                                                        }
                                                });
-                                       })(container, toggleButton);
+                                       })(container, toggleButtons);
                                }
                                
                                container.classList.remove('jsCollapsibleBbcode');
index 54f204e61c2e36b0efc549ef39a8b08eaefa44ab..cd59626d77c7c9bf304f8655c8e9b8b0c677e68b 100644 (file)
@@ -13,14 +13,14 @@ define(
                'favico',                  'enquire',                'perfect-scrollbar',      'WoltLabSuite/Core/Date/Time/Relative',
                'Ui/SimpleDropdown',       'WoltLabSuite/Core/Ui/Mobile',  'WoltLabSuite/Core/Ui/TabMenu', 'WoltLabSuite/Core/Ui/FlexibleMenu',
                'Ui/Dialog',               'WoltLabSuite/Core/Ui/Tooltip', 'WoltLabSuite/Core/Language',   'WoltLabSuite/Core/Environment',
-               'WoltLabSuite/Core/Date/Picker', 'EventHandler',           'Core',                   'WoltLabSuite/Core/Ui/Page/JumpToTop',
+               'WoltLabSuite/Core/Date/Picker', 'EventHandler',           'Core',                   'WoltLabSuite/Core/Ui/Page/Action',
                'Devtools', 'Dom/ChangeListener'
        ], 
        function(
                 favico,                   enquire,                  perfectScrollbar,         DateTimeRelative,
                 UiSimpleDropdown,         UiMobile,                 UiTabMenu,                UiFlexibleMenu,
                 UiDialog,                 UiTooltip,                Language,                 Environment,
-                DatePicker,               EventHandler,             Core,                     UiPageJumpToTop,
+                DatePicker,               EventHandler,             Core,                     UiPageAction,
                 Devtools, DomChangeListener
        )
 {
@@ -91,7 +91,7 @@ define(
                                        // putting it at the end of the jQuery queue avoids trashing the
                                        // layout too early and thus delaying the page initialization
                                        window.jQuery(function() {
-                                               new UiPageJumpToTop();
+                                               UiPageAction.setup();
                                        });
                                        
                                        window.jQuery.holdReady(false);
index 7b46625bdcdf93c668a5078bb2c4b81ec4c1f67e..6a0b64e4d694e108d3d81f39034fe0c47ca0ad2d 100644 (file)
@@ -9,11 +9,13 @@
 define(
        [
                'WoltLabSuite/Core/BackgroundQueue', 'WoltLabSuite/Core/Bootstrap', 'WoltLabSuite/Core/Controller/Style/Changer',
-               'WoltLabSuite/Core/Controller/Popover', 'WoltLabSuite/Core/Ui/User/Ignore', 'WoltLabSuite/Core/Ui/Page/Header/Menu'
+               'WoltLabSuite/Core/Controller/Popover', 'WoltLabSuite/Core/Ui/User/Ignore', 'WoltLabSuite/Core/Ui/Page/Header/Menu',
+               'WoltLabSuite/Core/Ui/Message/UserConsent'
        ],
        function(
                BackgroundQueue, Bootstrap, ControllerStyleChanger,
-               ControllerPopover, UiUserIgnore, UiPageHeaderMenu
+               ControllerPopover, UiUserIgnore, UiPageHeaderMenu,
+               UiMessageUserConsent
        )
 {
        "use strict";
@@ -52,27 +54,26 @@ define(
                        if (COMPILER_TARGET_DEFAULT) {
                                UiUserIgnore.init();
                        }
+                       
+                       UiMessageUserConsent.init();
                },
                
                /**
                 * Initializes user profile popover.
                 */
                _initUserPopover: function() {
+                       ControllerPopover.init({
+                               className: 'userLink',
+                               dboAction: 'wcf\\data\\user\\UserProfileAction',
+                               identifier: 'com.woltlab.wcf.user'
+                       });
+                       
+                       // @deprecated since 5.3
                        ControllerPopover.init({
                                attributeName: 'data-user-id',
                                className: 'userLink',
-                               identifier: 'com.woltlab.wcf.user',
-                               loadCallback: function(objectId, popover) {
-                                       var callback = function(data) {
-                                               popover.setContent('com.woltlab.wcf.user', objectId, data.returnValues.template);
-                                       };
-                                       
-                                       popover.ajaxApi({
-                                               actionName: 'getUserProfile',
-                                               className: 'wcf\\data\\user\\UserProfileAction',
-                                               objectIDs: [ objectId ]
-                                       }, callback, callback);
-                               }
+                               dboAction: 'wcf\\data\\user\\UserProfileAction',
+                               identifier: 'com.woltlab.wcf.user.deprecated'
                        });
                }
        };
index fc35381cc872e3d83aaa497f3a1f3dc25dae41f6..592988e0d3b978ff8e7bdb3f4bd67afa810841cb 100644 (file)
@@ -60,7 +60,7 @@ define(['Environment', 'Ui/Screen'], function(Environment, UiScreen) {
                },
                
                copyElementTextToClipboard: function (element) {
-                       return this.copyTextToClipboard(element.textContent);
+                       return this.copyTextToClipboard(element.textContent.replace(/\u200B/g, '').replace(/\u00A0/g, ' '));
                }
        };
 });
index 82a4769de5e1aa7445c411a5a1b65d77e28e0b5d..e90798f123497ac93eae464b598a4762e28b7323 100644 (file)
@@ -118,6 +118,7 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                        
                        _handlers.set(options.identifier, {
                                attributeName: options.attributeName,
+                               dboAction: options.dboAction,
                                elements: options.legacy ? options.className : elByClass(options.className),
                                legacy: options.legacy,
                                loadCallback: options.loadCallback
@@ -336,7 +337,26 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', '
                        else if (data.state === STATE_NONE) {
                                data.state = STATE_LOADING;
                                
-                               _handlers.get(elementData.identifier).loadCallback(elementData.objectId, this);
+                               var handler = _handlers.get(elementData.identifier);
+                               if (handler.loadCallback) {
+                                       handler.loadCallback(elementData.objectId, this, elementData.element);
+                               }
+                               else if (handler.dboAction) {
+                                       var callback = function(data) {
+                                               this.setContent(
+                                                       elementData.identifier,
+                                                       elementData.objectId,
+                                                       data.returnValues.template
+                                               );
+                                       }.bind(this);
+                                       
+                                       this.ajaxApi({
+                                               actionName: 'getPopover',
+                                               className: handler.dboAction,
+                                               interfaceName: 'wcf\\data\\IPopoverAction',
+                                               objectIDs: [ elementData.objectId ]
+                                       }, callback, callback);
+                               }
                        }
                },
                
index 0afac53be570da1079a2cf7906ce128fccb1fdd3..f97800d10259a527c887622ad15c1633fddc8400 100644 (file)
 /**
  * Handles email notification type for user notification settings.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Controller/User/Notification/Settings
+ *
+ * @author      Alexander Ebert
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module      WoltLabSuite/Core/Controller/User/Notification/Settings
  */
-define(['Dictionary', 'Language', 'Dom/Traverse', 'Ui/SimpleDropdown'], function(Dictionary, Language, DomTraverse, UiSimpleDropdown) {
-       "use strict";
+define(['Language', 'Ui/ReusableDropdown'], function (Language, UiReusableDropdown) {
+       'use strict';
        
        if (!COMPILER_TARGET_DEFAULT) {
-               var Fake = function() {};
-               Fake.prototype = {
-                       setup: function() {},
-                       _initGroup: function() {},
-                       _click: function() {},
-                       _createDropdown: function() {},
-                       _selectType: function() {}
-               };
-               return Fake;
+               return function () {};
        }
        
-       var _data = new Dictionary();
-       
-       var _callbackClick = null;
-       var _callbackSelectType = null;
+       var _dropDownMenu = null;
+       var _objectId = null;
        
        /**
         * @exports     WoltLabSuite/Core/Controller/User/Notification/Settings
         */
-       var ControllerUserNotificationSettings = {
+       return {
                /**
                 * Binds event listeners for all notifications supporting emails.
                 */
-               setup: function() {
-                       _callbackClick = this._click.bind(this);
-                       _callbackSelectType = this._selectType.bind(this);
+               init: function () {
+                       elBySelAll('.jsCheckboxNotificationSettingsState', undefined, (function (checkbox) {
+                               checkbox.addEventListener('change', this._stateChange.bind(this));
+                       }).bind(this));
                        
-                       var group, mailSetting, groups = elBySelAll('#notificationSettings .flexibleButtonGroup');
-                       for (var i = 0, length = groups.length; i < length; i++) {
-                               group = groups[i];
-                               
-                               mailSetting = elBySel('.notificationSettingsEmail', group);
-                               if (mailSetting === null) {
-                                       continue;
-                               }
-                               
-                               this._initGroup(group, mailSetting);
-                       }
+                       elBySelAll('.notificationSettingsEmailType', undefined, (function (button) {
+                               button.addEventListener('click', this._click.bind(this));
+                       }).bind(this));
                },
                
                /**
-                * Initializes a setting.
-                * 
-                * @param       {Element}       group           button group element
-                * @param       {Element}       mailSetting     mail settings element
+                * @param {Event} event
                 */
-               _initGroup: function(group, mailSetting) {
-                       var groupId = ~~elData(group, 'object-id');
-                       
-                       var disabledNotification = elById('settings_' + groupId + '_disabled');
-                       disabledNotification.addEventListener(WCF_CLICK_EVENT, function() { mailSetting.classList.remove('active'); });
-                       var enabledNotification = elById('settings_' + groupId + '_enabled');
-                       enabledNotification.addEventListener(WCF_CLICK_EVENT, function() { mailSetting.classList.add('active'); });
-                       
-                       var mailValue = DomTraverse.childByTag(mailSetting, 'INPUT');
-                       
-                       var button = DomTraverse.childByTag(mailSetting, 'A');
-                       elData(button, 'object-id', groupId);
-                       button.addEventListener(WCF_CLICK_EVENT, _callbackClick);
-                       
-                       _data.set(groupId, {
-                               button: button,
-                               dropdownMenu: null,
-                               mailSetting: mailSetting,
-                               mailValue: mailValue
-                       });
+               _stateChange: function (event) {
+                       var objectId = elData(event.currentTarget, 'object-id');
+                       var emailSettingsType = elBySel('.notificationSettingsEmailType[data-object-id="' + objectId + '"]');
+                       if (emailSettingsType !== null) {
+                               emailSettingsType.classList[event.currentTarget.checked ? 'remove' : 'add']('disabled');
+                       }
                },
                
                /**
-                * Creates and displays the email type dropdown.
-                * 
-                * @param       {Object}        event           event object
+                * @param       {Event} event           event object
                 */
-               _click: function(event) {
+               _click: function (event) {
                        event.preventDefault();
+                       event.stopPropagation();
                        
                        var button = event.currentTarget;
-                       var objectId = ~~elData(button, 'object-id');
-                       var data = _data.get(objectId);
-                       if (data.dropdownMenu === null) {
-                               data.dropdownMenu = this._createDropdown(objectId, data.mailValue.value);
-                               
-                               button.parentNode.classList.add('dropdown');
-                               button.parentNode.appendChild(data.dropdownMenu);
-                               
-                               UiSimpleDropdown.init(button, event);
-                       }
-                       else {
-                               var items = DomTraverse.childrenByTag(data.dropdownMenu, 'LI'), value = data.mailValue.value;
-                               for (var i = 0; i < 4; i++) {
-                                       items[i].classList[(elData(items[i], 'value') === value) ? 'add' : 'remove']('active');
-                               }
-                       }
+                       _objectId = ~~elData(button, 'object-id');
+                       
+                       this._createDropDown();
+                       
+                       this._setCurrentEmailType(this._getEmailTypeInputElement().value);
+                       
+                       this._showDropDown(button);
                },
                
-               /**
-                * Creates the email type dropdown.
-                * 
-                * @param       {int}           objectId        notification event id
-                * @param       {string}        initialValue    initial email type
-                * @returns     {Element}       dropdown menu object
-                */
-               _createDropdown: function(objectId, initialValue) {
-                       var dropdownMenu = elCreate('ul');
-                       dropdownMenu.className = 'dropdownMenu';
-                       elData(dropdownMenu, 'object-id', objectId);
+               _createDropDown: function () {
+                       if (_dropDownMenu !== null) {
+                               return;
+                       }
                        
-                       var link, listItem, value, items = ['instant', 'daily', 'divider', 'none'];
-                       for (var i = 0; i < 4; i++) {
-                               value = items[i];
-                               
-                               listItem = elCreate('li');
+                       _dropDownMenu = elCreate('ul');
+                       _dropDownMenu.className = 'dropdownMenu';
+                       
+                       ['instant', 'daily', 'divider', 'none'].forEach((function (value) {
+                               var listItem = elCreate('li');
                                if (value === 'divider') {
                                        listItem.className = 'dropdownDivider';
                                }
                                else {
-                                       link = elCreate('a');
+                                       var link = elCreate('a');
+                                       link.href = '#';
                                        link.textContent = Language.get('wcf.user.notification.mailNotificationType.' + value);
                                        listItem.appendChild(link);
                                        elData(listItem, 'value', value);
-                                       listItem.addEventListener(WCF_CLICK_EVENT, _callbackSelectType);
-                                       
-                                       if (initialValue === value) {
-                                               listItem.className = 'active';
-                                       }
+                                       listItem.addEventListener(WCF_CLICK_EVENT, this._setEmailType.bind(this));
                                }
                                
-                               dropdownMenu.appendChild(listItem);
-                       }
+                               _dropDownMenu.appendChild(listItem);
+                       }).bind(this));
                        
-                       return dropdownMenu;
+                       UiReusableDropdown.init('UiNotificationSettingsEmailType', _dropDownMenu);
+               },
+               
+               _setCurrentEmailType: function (currentValue) {
+                       elBySelAll('li', _dropDownMenu, function (button) {
+                               var value = elData(button, 'value');
+                               button.classList[(value === currentValue) ? 'add' : 'remove']('active');
+                       });
+               },
+               
+               _showDropDown: function (referenceElement) {
+                       UiReusableDropdown.toggleDropdown('UiNotificationSettingsEmailType', referenceElement);
                },
                
                /**
-                * Sets the selected email notification type.
-                * 
-                * @param       {Object}        event           event object
+                * @param       {Event} event           event object
                 */
-               _selectType: function(event) {
+               _setEmailType: function (event) {
+                       event.preventDefault();
+                       
                        var value = elData(event.currentTarget, 'value');
-                       var groupId = ~~elData(event.currentTarget.parentNode, 'object-id');
                        
-                       var data = _data.get(groupId);
-                       data.mailValue.value = value;
-                       elBySel('span.title', data.mailSetting).textContent = Language.get('wcf.user.notification.mailNotificationType.' + value);
+                       this._getEmailTypeInputElement().value = value;
+                       
+                       var button = elBySel('.notificationSettingsEmailType[data-object-id="' + _objectId + '"]');
+                       button.title = Language.get('wcf.user.notification.mailNotificationType.' + value);
                        
-                       data.button.classList[(value === 'none') ? 'remove' : 'add']('yellow');
-                       data.button.classList[(value === 'none') ? 'remove' : 'add']('active');
+                       var icon = elBySel('.jsIconNotificationSettingsEmailType', button);
+                       icon.classList.remove('fa-clock-o');
+                       icon.classList.remove('fa-flash');
+                       icon.classList.remove('fa-times');
+                       icon.classList.remove('green');
+                       icon.classList.remove('red');
+                       
+                       switch (value) {
+                               case 'daily':
+                                       icon.classList.add('fa-clock-o');
+                                       icon.classList.add('green');
+                                       break;
+                               
+                               case 'instant':
+                                       icon.classList.add('fa-flash');
+                                       icon.classList.add('green');
+                                       break;
+                               
+                               case 'none':
+                                       icon.classList.add('fa-times');
+                                       icon.classList.add('red');
+                                       break;
+                       }
+                       
+                       _objectId = null;
+               },
+               
+               /**
+                * @return {HTMLInputElement}
+                */
+               _getEmailTypeInputElement: function () {
+                       return elById('settings_' + _objectId + '_mailNotificationType');
                }
        };
-       
-       return ControllerUserNotificationSettings;
 });
index 676a0f58bd119fdcfecdfded49ca907eae26ec79..c75ba0f23f8152f1032889479bf8f0bcf36398e9 100644 (file)
@@ -165,6 +165,7 @@ define(['Environment', 'StringUtil'], function(Environment, StringUtil) {
                 * 
                 * @param       {Element}       el              element to prepend
                 * @param       {Element}       parentEl        future containing element
+                * @deprecated 5.3 Use `parentEl.insertBefore(el, parentEl.firstChild)` instead.
                 */
                prepend: function(el, parentEl) {
                        if (parentEl.childNodes.length === 0) {
@@ -180,6 +181,7 @@ define(['Environment', 'StringUtil'], function(Environment, StringUtil) {
                 * 
                 * @param       {Element}       newEl           element to insert
                 * @param       {Element}       el              reference element
+                * @deprecated 5.3 Use `el.parentNode.insertBefore(newEl, el.nextSibling)` instead.
                 */
                insertAfter: function(newEl, el) {
                        if (el.nextSibling !== null) {
index a7390b3cedfe9a3d7417920ff10d6d275f4bff7f..d356f98914cc3b6de37219007864a845a2faa0ec 100644 (file)
@@ -122,7 +122,13 @@ define(['Dictionary', 'StringUtil'], function(Dictionary, StringUtil) {
                // word
                'application/msword': 'doc',
                'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
-               'application/vnd.oasis.opendocument.text': 'odt'
+               'application/vnd.oasis.opendocument.text': 'odt',
+
+               // iOS
+               'public.jpeg': 'jpeg',
+               'public.png': 'png',
+               'com.compuserve.gif': 'gif',
+               'org.webmproject.webp': 'webp'
        });
        
        return {
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js b/wcfsetup/install/files/js/WoltLabSuite/Core/I18n/Plural.js
new file mode 100644 (file)
index 0000000..adf440f
--- /dev/null
@@ -0,0 +1,553 @@
+/**
+ * Generates plural phrases for the `plural` template plugin.
+ * 
+ * @author     Matthias Schmidt, Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/I18n/Plural
+ */
+define(['StringUtil'], function(StringUtil) {
+       "use strict";
+       
+       var PLURAL_FEW = 'few';
+       var PLURAL_MANY = 'many';
+       var PLURAL_ONE = 'one';
+       var PLURAL_OTHER = 'other';
+       var PLURAL_TWO = 'two';
+       var PLURAL_ZERO = 'zero';
+       
+       return {
+               /**
+                * Returns the plural category for the given value.
+                *
+                * @param       {number}        value
+                * @param       {?string}       languageCode
+                * @return      string
+                */
+               getCategory: function(value, languageCode) {
+                       if (!languageCode) {
+                               languageCode = document.documentElement.lang;
+                       }
+                       
+                       // Fallback: handle unknown languages as English
+                       if (typeof this[languageCode] !== 'function') {
+                               languageCode = 'en';
+                       }
+                       
+                       var category = this[languageCode](value);
+                       if (category) {
+                               return category;
+                       }
+                       
+                       return PLURAL_OTHER;
+               },
+               
+               /**
+                * Returns the value for a `plural` element used in the template.
+                * 
+                * @param       {object}        parameters
+                * @see         wcf\system\template\plugin\PluralFunctionTemplatePlugin::execute()
+                */
+               getCategoryFromTemplateParameters: function(parameters) {
+                       if (!parameters['value'] ) {
+                               throw new Error('Missing parameter value');
+                       }
+                       if (!parameters['other']) {
+                               throw new Error('Missing parameter other');
+                       }
+                       
+                       var value = parameters['value'];
+                       if (Array.isArray(value)) {
+                               value = value.length;
+                       }
+                       
+                       // handle numeric attributes
+                       for (var key in parameters) {
+                               if (objOwns(parameters, key) && key == ~~key && key == value) {
+                                       return parameters[key];
+                               }
+                       }
+                       
+                       var category = this.getCategory(value);
+                       if (!parameters[category]) {
+                               category = PLURAL_OTHER;
+                       }
+                       
+                       var string = parameters[category];
+                       if (string.indexOf('#') !== -1) {
+                               return string.replace('#', StringUtil.formatNumeric(value));
+                       }
+                       
+                       return string;
+               },
+               
+               /**
+                * `f` is the fractional number as a whole number (1.234 yields 234)
+                * 
+                * @param       {number}        n
+                * @return      {integer}
+                */
+               getF: function(n) {
+                       n = n.toString();
+                       var pos = n.indexOf('.');
+                       if (pos === -1) {
+                               return 0;
+                       }
+                       
+                       return parseInt(n.substr(pos + 1), 10);
+               },
+               
+               /**
+                * `v` represents the number of digits of the fractional part (1.234 yields 3)
+                * 
+                * @param       {number}        n
+                * @return      {integer}
+                */
+               getV: function(n) {
+                       return n.toString().replace(/^[^.]*\.?/, '').length;
+               },
+               
+               // Afrikaans
+               af: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Amharic
+               am: function(n) {
+                       var i = Math.floor(Math.abs(n));
+                       if (n == 1 || i === 0) return PLURAL_ONE;
+               },
+               
+               // Arabic
+               ar: function(n) {
+                       if (n == 0) return PLURAL_ZERO;
+                       if (n == 1) return PLURAL_ONE;
+                       if (n == 2) return PLURAL_TWO;
+                       
+                       var mod100 = n % 100;
+                       if (mod100 >= 3 && mod100 <= 10) return PLURAL_FEW;
+                       if (mod100 >= 11 && mod100 <= 99) return PLURAL_MANY;
+               },
+               
+               // Assamese
+               as: function(n) {
+                       var i = Math.floor(Math.abs(n));
+                       if (n == 1 || i === 0) return PLURAL_ONE;
+               },
+               
+               // Azerbaijani
+               az: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Belarusian
+               be: function(n) {
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+                       
+                       if (mod10 == 1 && mod100 != 11) return PLURAL_ONE;
+                       if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return PLURAL_FEW;
+                       if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) return PLURAL_MANY;
+               },
+               
+               // Bulgarian
+               bg: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Bengali
+               bn: function(n) {
+                       var i = Math.floor(Math.abs(n));
+                       if (n == 1 || i === 0) return PLURAL_ONE;
+               },
+               
+               // Tibetan
+               bo: function(n) {},
+               
+               // Bosnian
+               bs: function(n) {
+                       var v = this.getV(n);
+                       var f = this.getF(n);
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+                       var fMod10 = f % 10;
+                       var fMod100 = f % 100;
+                       
+                       if ((v == 0 && mod10 == 1 && mod100 != 11) || (fMod10 == 1 && fMod100 != 11)) return PLURAL_ONE;
+                       if ((v == 0 && mod10 >= 2 && mod10 <= 4 && mod100 >= 12 && mod100 <= 14)
+                               || (fMod10 >= 2 && fMod10 <= 4 && fMod100 >= 12 && fMod100 <= 14)) return PLURAL_FEW;
+               },
+               
+               // Czech
+               cs: function(n) {
+                       var v = this.getV(n);
+                       
+                       if (n == 1 && v === 0) return PLURAL_ONE;
+                       if (n >= 2 && n <= 4 && v === 0) return PLURAL_FEW;
+                       if (v === 0) return PLURAL_MANY;
+               },
+               
+               // Welsh
+               cy: function(n) {
+                       if (n == 0) return PLURAL_ZERO;
+                       if (n == 1) return PLURAL_ONE;
+                       if (n == 2) return PLURAL_TWO;
+                       if (n == 3) return PLURAL_FEW;
+                       if (n == 6) return PLURAL_MANY;
+               },
+               
+               // Danish
+               da: function(n) {
+                       if (n > 0 && n < 2) return PLURAL_ONE;
+               },
+               
+               // Greek
+               el: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Catalan (ca)
+               // German (de)
+               // English (en)
+               // Estonian (et)
+               // Finnish (fi)
+               // Italian (it)
+               // Dutch (nl)
+               // Swedish (sv)
+               // Swahili (sw)
+               // Urdu (ur)
+               en: function(n) {
+                       if (n == 1 && this.getV(n) === 0) return PLURAL_ONE;
+               },
+               
+               // Spanish
+               es: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Basque
+               eu: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Persian
+               fa: function(n) {
+                       if (n >= 0 && n <= 1) return PLURAL_ONE;
+               },
+               
+               // French
+               fr: function(n) {
+                       if (n >= 0 && n < 2) return PLURAL_ONE;
+               },
+               
+               // Irish
+               ga: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+                       if (n == 2) return PLURAL_TWO;
+                       if (n == 3 || n == 4 || n == 5 || n == 6) return PLURAL_FEW;
+                       if (n == 7 || n == 8 || n == 9 || n == 10) return PLURAL_MANY;
+               },
+               
+               // Gujarati
+               gu: function(n) {
+                       if (n >= 0 && n <= 1) return PLURAL_ONE;
+               },
+               
+               // Hebrew
+               he: function(n) {
+                       var v = this.getV(n);
+       
+                       if (n == 1 && v === 0) return PLURAL_ONE;
+                       if (n == 2 && v === 0) return PLURAL_TWO;
+                       if (n > 10 && v === 0 && n % 10 == 0) return PLURAL_MANY;
+               },
+               
+               // Hindi
+               hi: function(n) {
+                       if (n >= 0 && n <= 1) return PLURAL_ONE;
+               },
+               
+               // Croatian
+               hr: function(n) {
+                       // same as Bosnian
+                       return this.bs(n);
+               },
+               
+               // Hungarian
+               hu: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Armenian
+               hy: function(n) {
+                       if (n >= 0 && n < 2) return PLURAL_ONE;
+               },
+               
+               // Indonesian
+               id: function(n) {},
+               
+               // Icelandic
+               is: function(n) {
+                       var f = this.getF(n);
+                       
+                       if (f === 0 && n % 10 === 1 && !(n % 100 === 11) || !(f === 0)) return PLURAL_ONE;
+               },
+               
+               // Japanese
+               ja: function(n) {},
+               
+               // Javanese
+               jv: function(n) {},
+               
+               // Georgian
+               ka: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Kazakh
+               kk: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Khmer
+               km: function(n) {},
+               
+               // Kannada
+               kn: function(n) {
+                       if (n >= 0 && n <= 1) return PLURAL_ONE;
+               },
+               
+               // Korean
+               ko: function(n) {},
+               
+               // Kurdish
+               ku: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Kyrgyz
+               ky: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Luxembourgish
+               lb: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Lao
+               lo: function(n) {},
+               
+               // Lithuanian
+               lt: function(n) {
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+                       
+                       if (mod10 == 1 && !(mod100 >= 11 && mod100 <= 19)) return PLURAL_ONE;
+                       if (mod10 >= 2 && mod10 <= 9 && !(mod100 >= 11 && mod100 <= 19)) return PLURAL_FEW;
+                       if (this.getF(n) != 0) return PLURAL_MANY;
+               },
+               
+               // Latvian
+               lv: function(n) {
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+                       var v = this.getV(n);
+                       var f = this.getF(n);
+                       var fMod10 = f % 10;
+                       var fMod100 = f % 100;
+                       
+                       if (mod10 == 0 || (mod100 >= 11 && mod100 <= 19) || (v == 2 && fMod100 >= 11 && fMod100 <= 19)) return PLURAL_ZERO;
+                       if ((mod10 == 1 && mod100 != 11) || (v == 2 && fMod10 == 1 && fMod100 != 11) || (v != 2 && fMod10 == 1)) return PLURAL_ONE;
+               },
+               
+               // Macedonian
+               mk: function(n) {
+                       var v = this.getV(n);
+                       var f = this.getF(n);
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+                       var fMod10 = f % 10;
+                       var fMod100 = f % 100;
+                       
+                       if ((v == 0 && mod10 == 1 && mod100 != 11) || (fMod10 == 1 && fMod100 != 11)) return PLURAL_ONE;
+               },
+               
+               // Malayalam
+               ml: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Mongolian 
+               mn: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Marathi 
+               mr: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Malay 
+               ms: function(n) {},
+               
+               // Maltese 
+               mt: function(n) {
+                       var mod100 = n % 100;
+                       
+                       if (n == 1) return PLURAL_ONE;
+                       if (n == 0 || (mod100 >= 2 && mod100 <= 10)) return PLURAL_FEW;
+                       if (mod100 >= 11 && mod100 <= 19) return PLURAL_MANY;
+               },
+               
+               // Burmese
+               my: function(n) {},
+               
+               // Norwegian
+               no: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Nepali
+               ne: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Odia
+               or: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Punjabi
+               pa: function(n) {
+                       if (n == 1 || n == 0) return PLURAL_ONE;
+               },
+               
+               // Polish
+               pl: function(n) {
+                       var v = this.getV(n);
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+       
+                       if (n == 1 && v == 0) return PLURAL_ONE;
+                       if (v == 0 && mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return PLURAL_FEW;
+                       if (v == 0 && ((n != 1 && mod10 >= 0 && mod10 <= 1) || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 12 && mod100 <= 14))) return PLURAL_MANY;
+               },
+               
+               // Pashto
+               ps: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Portuguese
+               pt: function(n) {
+                       if (n >= 0 && n < 2) return PLURAL_ONE;
+               },
+               
+               // Romanian
+               ro: function(n) {
+                       var v = this.getV(n);
+                       var mod100 = n % 100;
+                       
+                       if (n == 1 && v === 0) return PLURAL_ONE;
+                       if (v != 0 || n == 0 || (mod100 >= 2 && mod100 <= 19)) return PLURAL_FEW;
+               },
+               
+               // Russian
+               ru: function(n) {
+                       var mod10 = n % 10;
+                       var mod100 = n % 100;
+                       
+                       if (this.getV(n) == 0) {
+                               if (mod10 == 1 && mod100 != 11) return PLURAL_ONE;
+                               if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return PLURAL_FEW;
+                               if (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)) return PLURAL_MANY;
+                       }
+               },
+               
+               // Sindhi
+               sd: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Sinhala
+               si: function(n) {
+                       if (n == 0 || n == 1 || (Math.floor(n) == 0 && this.getF(n) == 1)) return PLURAL_ONE;
+               },
+               
+               // Slovak
+               sk: function(n) {
+                       // same as Czech
+                       return this.cs(n);
+               },
+               
+               // Slovenian
+               sl: function(n) {
+                       var v = this.getV(n);
+                       var mod100 = n % 100;
+                       
+                       if (v == 0 && mod100 == 1) return PLURAL_ONE;
+                       if (v == 0 && mod100 == 2) return PLURAL_TWO;
+                       if ((v == 0 && (mod100 == 3 || mod100 == 4)) || v != 0) return PLURAL_FEW;
+               },
+               
+               // Albanian
+               sq: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Serbian
+               sr: function(n) {
+                       // same as Bosnian
+                       return this.bs(n);
+               },
+               
+               // Tamil
+               ta: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Telugu
+               te: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Tajik
+               tg: function(n) {},
+               
+               // Thai
+               th: function(n) {},
+               
+               // Turkmen
+               tk: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Turkish
+               tr: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Uyghur
+               ug: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Ukrainian
+               uk: function(n) {
+                       // same as Russian
+                       return this.ru(n);
+               },
+               
+               // Uzbek
+               uz: function(n) {
+                       if (n == 1) return PLURAL_ONE;
+               },
+               
+               // Vietnamese
+               vi: function(n) {},
+               
+               // Chinese
+               zh: function(n) {}
+       };
+});
index cc6f5a01624d9ee1bfcb042e54f45cae0d1e2c3f..c4846ec452c4893d9c7e9901904b759ce8bf87f9 100644 (file)
@@ -32,6 +32,11 @@ define([], function() {
        // Known sequence signatures
        var _signatureEXIF = 'Exif';
        var _signatureXMP  = 'http://ns.adobe.com/xap/1.0/';
+       var _signatureXMPExtension = 'http://ns.adobe.com/xmp/extension/';
+       
+       function isExifSignature(signature) {
+               return signature === _signatureEXIF || signature === _signatureXMP || signature === _signatureXMPExtension;
+       }
        
        return {
                /**
@@ -76,7 +81,7 @@ define([], function() {
                                                        }
                                                        
                                                        // Only copy Exif and XMP data
-                                                       if (signature === _signatureEXIF || signature === _signatureXMP) {
+                                                       if (isExifSignature(signature)) {
                                                                // append the found EXIF sequence, usually only a single EXIF (APP1) sequence should be defined
                                                                var sequence = Array.prototype.slice.call(bytes, i, length + i); // IE11 does not have slice in the Uint8Array prototype
                                                                var concat = new Uint8Array(exif.length + sequence.length);
@@ -137,8 +142,8 @@ define([], function() {
                                                                signature += String.fromCharCode(bytes[j]);
                                                        }
                                                        
-                                                       // Only remove Exif and XMP data
-                                                       if (signature === _signatureEXIF || signature === _signatureXMP) {
+                                                       // Only remove known signatures
+                                                       if (isExifSignature(signature)) {
                                                                var start = Array.prototype.slice.call(bytes, 0, i);
                                                                var end = Array.prototype.slice.call(bytes, i + length);
                                                                bytes = new Uint8Array(start.length + end.length);
index 24985c5f12816f118bc92f6cad7d11c3aa14a4ae..8b7448f309bd7c69832b302adcb68cf79e9d5bd7 100644 (file)
@@ -101,7 +101,7 @@ define([
                                        return blob;
                                })
                                .then(function (blob) {
-                                       return FileUtil.blobToFile(blob, basename[1] + '_autoscaled');
+                                       return FileUtil.blobToFile(blob, basename[1]);
                                });
                },
                
index 56f0db76d1fc7cabd6d7b9283241ec48fbdb6b5a..da5f85b473a014ac866fcdb79a7fa5048d078a61 100644 (file)
@@ -8,14 +8,34 @@
  */
 define(
        [
-               'Ajax',                         'Core',                       'Dictionary',          'Dom/ChangeListener',
-               'Dom/Traverse',                 'Language',                   'Ui/Dialog',           'Ui/Notification',
-               'WoltLabSuite/Core/Language/Chooser', 'WoltLabSuite/Core/Language/Input', 'EventKey'
+               'Ajax',
+               'Core',
+               'Dictionary',
+               'Dom/ChangeListener',
+               'Dom/Traverse',
+               'Dom/Util',
+               'Language',
+               'Ui/Dialog',
+               'Ui/Notification',
+               'WoltLabSuite/Core/Language/Chooser',
+               'WoltLabSuite/Core/Language/Input',
+               'EventKey',
+               'WoltLabSuite/Core/Media/Replace'
        ],
        function(
-               Ajax,                            Core,                         Dictionary,            DomChangeListener,
-               DomTraverse,                     Language,                     UiDialog,              UiNotification,
-               LanguageChooser,                 LanguageInput,                EventKey
+               Ajax,
+               Core,
+               Dictionary,
+               DomChangeListener,
+               DomTraverse,
+               DomUtil,
+               Language,
+               UiDialog,
+               UiNotification,
+               LanguageChooser,
+               LanguageInput,
+               EventKey,
+               MediaReplace
        )
 {
        "use strict";
@@ -98,6 +118,90 @@ define(
                        }
                },
                
+               /**
+                * Initializes the editor dialog.
+                * 
+                * @param       {HTMLElement}           content
+                * @param       {object}                data
+                * @since       5.3
+                */
+               _initEditor: function(content, data) {
+                       this._availableLanguageCount = ~~data.returnValues.availableLanguageCount;
+                       this._categoryIds = data.returnValues.categoryIDs.map(function(number) {
+                               return ~~number;
+                       });
+                       
+                       var didLoadMediaData = false;
+                       if (data.returnValues.mediaData) {
+                               this._media = data.returnValues.mediaData;
+                               
+                               didLoadMediaData = true;
+                       }
+                       
+                       // make sure that the language chooser is initialized first
+                       setTimeout(function() {
+                               if (this._availableLanguageCount > 1) {
+                                       LanguageChooser.setLanguageId('mediaEditor_' + this._media.mediaID + '_languageID', this._media.languageID || LANGUAGE_ID);
+                               }
+                               
+                               if (this._categoryIds.length) {
+                                       elBySel('select[name=categoryID]', content).value = ~~this._media.categoryID;
+                               }
+                               
+                               var title = elBySel('input[name=title]', content);
+                               var altText = elBySel('input[name=altText]', content);
+                               var caption = elBySel('textarea[name=caption]', content);
+                               
+                               if (this._availableLanguageCount > 1 && this._media.isMultilingual) {
+                                       if (elById('altText_' + this._media.mediaID)) LanguageInput.setValues('altText_' + this._media.mediaID, Dictionary.fromObject(this._media.altText || { }));
+                                       if (elById('caption_' + this._media.mediaID)) LanguageInput.setValues('caption_' + this._media.mediaID, Dictionary.fromObject(this._media.caption || { }));
+                                       LanguageInput.setValues('title_' + this._media.mediaID, Dictionary.fromObject(this._media.title || { }));
+                               }
+                               else {
+                                       title.value = this._media.title ? this._media.title[this._media.languageID || LANGUAGE_ID] : '';
+                                       if (altText) altText.value = this._media.altText ? this._media.altText[this._media.languageID || LANGUAGE_ID] : '';
+                                       if (caption) caption.value = this._media.caption ? this._media.caption[this._media.languageID || LANGUAGE_ID] : '';
+                               }
+                               
+                               if (this._availableLanguageCount > 1) {
+                                       var isMultilingual = elBySel('input[name=isMultilingual]', content);
+                                       isMultilingual.addEventListener('change', this._updateLanguageFields.bind(this));
+                                       
+                                       this._updateLanguageFields(null, isMultilingual);
+                               }
+                               
+                               var keyPress = this._keyPress.bind(this);
+                               if (altText) altText.addEventListener('keypress', keyPress);
+                               title.addEventListener('keypress', keyPress);
+                               
+                               elBySel('button[data-type=submit]', content).addEventListener(WCF_CLICK_EVENT, this._saveData.bind(this));
+                               
+                               // remove focus from input elements and scroll dialog to top
+                               document.activeElement.blur();
+                               elById('mediaEditor_' + this._media.mediaID).parentNode.scrollTop = 0;
+                               
+                               // Initialize button to replace media file.
+                               var uploadButton = elByClass('mediaManagerMediaReplaceButton', content)[0];
+                               var target = elByClass('mediaThumbnail', content)[0];
+                               if (!target) {
+                                       target = elCreate('div');
+                                       content.appendChild(target);
+                               }
+                               new MediaReplace(
+                                       this._media.mediaID,
+                                       DomUtil.identify(uploadButton),
+                                       // Pass an anonymous element for non-images which is required internally
+                                       // but not needed in this case.
+                                       DomUtil.identify(target),
+                                       {
+                                               mediaEditor: this
+                                       }
+                               );
+                               
+                               DomChangeListener.trigger();
+                       }.bind(this), 200);
+               },
+               
                /**
                 * Handles the `[ENTER]` key to submit the form.
                 * 
@@ -289,64 +393,7 @@ define(
                                                                title: Language.get('wcf.media.edit')
                                                        },
                                                        source: {
-                                                               after: (function(content, data) {
-                                                                       this._availableLanguageCount = ~~data.returnValues.availableLanguageCount;
-                                                                       this._categoryIds = data.returnValues.categoryIDs.map(function(number) {
-                                                                               return ~~number;
-                                                                       });
-                                                                       
-                                                                       var didLoadMediaData = false;
-                                                                       if (data.returnValues.mediaData) {
-                                                                               this._media = data.returnValues.mediaData;
-                                                                               
-                                                                               didLoadMediaData = true;
-                                                                       }
-                                                                       
-                                                                       // make sure that the language chooser is initialized first
-                                                                       setTimeout(function() {
-                                                                               if (this._availableLanguageCount > 1) {
-                                                                                       LanguageChooser.setLanguageId('mediaEditor_' + this._media.mediaID + '_languageID', this._media.languageID || LANGUAGE_ID);
-                                                                               }
-                                                                               
-                                                                               if (this._categoryIds.length) {
-                                                                                       elBySel('select[name=categoryID]', content).value = ~~this._media.categoryID;
-                                                                               }
-                                                                               
-                                                                               var title = elBySel('input[name=title]', content);
-                                                                               var altText = elBySel('input[name=altText]', content);
-                                                                               var caption = elBySel('textarea[name=caption]', content);
-                                                                               
-                                                                               if (this._availableLanguageCount > 1 && this._media.isMultilingual) {
-                                                                                       if (elById('altText_' + this._media.mediaID)) LanguageInput.setValues('altText_' + this._media.mediaID, Dictionary.fromObject(this._media.altText || { }));
-                                                                                       if (elById('caption_' + this._media.mediaID)) LanguageInput.setValues('caption_' + this._media.mediaID, Dictionary.fromObject(this._media.caption || { }));
-                                                                                       LanguageInput.setValues('title_' + this._media.mediaID, Dictionary.fromObject(this._media.title || { }));
-                                                                               }
-                                                                               else {
-                                                                                       title.value = this._media.title ? this._media.title[this._media.languageID || LANGUAGE_ID] : ''; 
-                                                                                       if (altText) altText.value = this._media.altText ? this._media.altText[this._media.languageID || LANGUAGE_ID] : '';
-                                                                                       if (caption) caption.value = this._media.caption ? this._media.caption[this._media.languageID || LANGUAGE_ID] : '';
-                                                                               }
-                                                                               
-                                                                               if (this._availableLanguageCount > 1) {
-                                                                                       var isMultilingual = elBySel('input[name=isMultilingual]', content);
-                                                                                       isMultilingual.addEventListener('change', this._updateLanguageFields.bind(this));
-                                                                                       
-                                                                                       this._updateLanguageFields(null, isMultilingual);
-                                                                               }
-                                                                               
-                                                                               var keyPress = this._keyPress.bind(this);
-                                                                               if (altText) altText.addEventListener('keypress', keyPress);
-                                                                               title.addEventListener('keypress', keyPress);
-                                                                               
-                                                                               elBySel('button[data-type=submit]', content).addEventListener(WCF_CLICK_EVENT, this._saveData.bind(this));
-                                                                               
-                                                                               // remove focus from input elements and scroll dialog to top
-                                                                               document.activeElement.blur();
-                                                                               elById('mediaEditor_' + this._media.mediaID).parentNode.scrollTop = 0;
-                                                                               
-                                                                               DomChangeListener.trigger();
-                                                                       }.bind(this), 200);
-                                                               }).bind(this),
+                                                               after: this._initEditor.bind(this),
                                                                data: {
                                                                        actionName: 'getEditorDialog',
                                                                        className: 'wcf\\data\\media\\MediaAction',
@@ -359,6 +406,18 @@ define(
                        }
                        
                        UiDialog.open(this._dialogs.get('mediaEditor_' + media.mediaID));
+               },
+               
+               /**
+                * Updates the data of the currently edited media file.
+                * 
+                * @param       {object}        data
+                * @since       5.3
+                */
+               updateData: function(data) {
+                       if (this._callbackObject._editorSuccess) {
+                               this._callbackObject._editorSuccess(data);
+                       }
                }
        };
        
index 5f811a6ff6c85c2a35ab07e175a61b8713fb7e80..b290ffc880a7ce04e4df40c1457d1c3739f23c8e 100644 (file)
@@ -288,10 +288,28 @@ define(
                        var listItem = this._listItems.get(~~media.mediaID);
                        var p = elByClass('mediaTitle', listItem)[0];
                        if (media.isMultilingual) {
-                               p.textContent = media.title[LANGUAGE_ID] || media.filename;
+                               if (media.title && media.title[LANGUAGE_ID]) {
+                                       p.textContent = media.title[LANGUAGE_ID];
+                               }
+                               else {
+                                       p.textContent = media.filename;
+                               }
                        }
                        else {
-                               p.textContent = media.title[media.languageID] || media.filename;
+                               if (media.title && media.title[media.languageID]) {
+                                       p.textContent = media.title[media.languageID];
+                               }
+                               else {
+                                       p.textContent = media.filename;
+                               }
+                       }
+                       
+                       var thumbnail = elByClass('mediaThumbnail', listItem)[0];
+                       thumbnail.innerHTML = media.elementTag;
+                       // Bust browser cache by adding additional parameter.
+                       var imgs = elByTag('img', thumbnail);
+                       if (imgs.length) {
+                               imgs[0].src += '&refresh=' + Date.now();
                        }
                },
                
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Replace.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Media/Replace.js
new file mode 100644 (file)
index 0000000..c77c8c1
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ * Uploads replacemnts for media files.
+ *
+ * @author      Matthias Schmidt
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module      WoltLabSuite/Core/Media/Upload
+ * @since       5.3
+ */
+define(
+       [
+               'Core',
+               'Dom/ChangeListener',
+               'Dom/Util',
+               'Language',
+               'Ui/Notification',
+               './Upload'
+       ],
+       function(
+               Core,
+               DomChangeListener,
+               DomUtil,
+               Language,
+               UiNotification,
+               MediaUpload
+       )
+       {
+               "use strict";
+               
+               if (!COMPILER_TARGET_DEFAULT) {
+                       var Fake = function() {};
+                       Fake.prototype = {
+                               _createButton: function() {},
+                               _success: function() {},
+                               _upload: function() {},
+                               _createFileElement: function() {},
+                               _getParameters: function() {},
+                               _uploadFiles: function() {},
+                               _createFileElements: function() {},
+                               _failure: function() {},
+                               _insertButton: function() {},
+                               _progress: function() {},
+                               _removeButton: function() {}
+                       };
+                       return Fake;
+               }
+               
+               /**
+                * @constructor
+                */
+               function MediaReplace(mediaID, buttonContainerId, targetId, options) {
+                       this._mediaID = mediaID;
+                       
+                       MediaUpload.call(this, buttonContainerId, targetId, Core.extend(options, {
+                               action: 'replaceFile'
+                       }));
+               }
+               Core.inherit(MediaReplace, MediaUpload, {
+                       /**
+                        * @see WoltLabSuite/Core/Upload#_createButton
+                        */
+                       _createButton: function() {
+                               MediaUpload.prototype._createButton.call(this);
+                               
+                               this._button.classList.add('small');
+                               
+                               var span = elBySel('span', this._button);
+                               span.textContent = Language.get('wcf.media.button.replaceFile');
+                       },
+                       
+                       /**
+                        * @see WoltLabSuite/Core/Upload#_createFileElement
+                        */
+                       _createFileElement: function() {
+                               return this._target;
+                       },
+                       
+                       /**
+                        * @see WoltLabSuite/Core/Upload#_getFormData
+                        */
+                       _getFormData: function() {
+                               return {
+                                       objectIDs: [this._mediaID]
+                               };
+                       },
+                       
+                       /**
+                        * @see WoltLabSuite/Core/Upload#_success
+                        */
+                       _success: function(uploadId, data) {
+                               var files = this._fileElements[uploadId];
+                               
+                               for (var i = 0, length = files.length; i < length; i++) {
+                                       var file = files[i];
+                                       var internalFileId = elData(file, 'internal-file-id');
+                                       var media = data.returnValues.media[internalFileId];
+                                       
+                                       if (media) {
+                                               if (media.isImage) {
+                                                       this._target.innerHTML = media.smallThumbnailTag;
+                                               }
+                                               
+                                               elById('mediaFilename').textContent = media.filename;
+                                               elById('mediaFilesize').textContent = media.formattedFilesize;
+                                               if (media.isImage) {
+                                                       elById('mediaImageDimensions').textContent = media.imageDimensions;
+                                               }
+                                               elById('mediaUploader').innerHTML = media.userLinkElement;
+                                               
+                                               this._options.mediaEditor.updateData(media);
+                                               
+                                               // Remove existing error messages.
+                                               elInnerError(this._buttonContainer, '');
+                                               
+                                               UiNotification.show();
+                                       }
+                                       else {
+                                               var error = data.returnValues.errors[internalFileId];
+                                               if (!error) {
+                                                       error = {
+                                                               errorType: 'uploadFailed',
+                                                               filename: elData(file, 'filename')
+                                                       };
+                                               }
+                                               
+                                               elInnerError(this._buttonContainer, Language.get('wcf.media.upload.error.' + error.errorType, {
+                                                       filename: error.filename
+                                               }));
+                                       }
+                                       
+                                       DomChangeListener.trigger();
+                               }
+                       },
+               });
+               
+               return MediaReplace;
+       }
+);
index 2dfe96eade836d7a6d7759b7c9f091c8bc2d182b..d2fe020820a3015d2a032c53f2b3e44895c43d4e 100644 (file)
@@ -225,7 +225,7 @@ define(['Ajax', 'Core', 'EventHandler', 'StringUtil'], function(Ajax, Core, Even
                        if (typeof pollData.notification === 'object' && typeof pollData.notification.message ===  'string') {
                                //noinspection JSUnresolvedVariable
                                var notification = new window.Notification(pollData.notification.title, {
-                                       body: StringUtil.unescapeHTML(pollData.notification.message),
+                                       body: StringUtil.unescapeHTML(pollData.notification.message).replace(/&#x202F;/g, "\u202F"),
                                        icon: _icon
                                });
                                notification.onclick = function () {
index accb016437b5718de83a425a3f183ac707871944..2087181326faf8c28d0c2a923ac91f0774ef1a7e 100644 (file)
@@ -20,6 +20,7 @@
 <command>\"([^"]|\\\.)*\" return 'T_QUOTED_STRING';
 <command>\'([^']|\\\.)*\' return 'T_QUOTED_STRING';
 <command>\$ return 'T_VARIABLE';
+<command>[0-9]+ { return 'T_DIGITS'; }
 <command>[_a-zA-Z][_a-zA-Z0-9]* { return 'T_VARIABLE_NAME'; }
 <command>"."    return '.';
 <command>"["    return '[';
@@ -40,6 +41,7 @@
 "{/lang}"   return '{/lang}';
 "{include " { this.begin('command'); return '{include'; }
 "{implode " { this.begin('command'); return '{implode'; }
+"{plural " { this.begin('command'); return '{plural'; }
 "{/implode}" return '{/implode}';
 "{foreach "  { this.begin('command'); return '{foreach'; }
 "{foreachelse}"  return '{foreachelse}';
@@ -122,6 +124,17 @@ COMMAND:
                + "}"
                + "return (looped ? result : " + ($5 || "''") + "); })()"
        }
+|      '{plural' PLURAL_PARAMETER_LIST '}' {
+               $$ = "I18nPlural.getCategoryFromTemplateParameters({"
+               var needsComma = false;
+               for (var key in $2) {
+                       if (objOwns($2, key)) {
+                               $$ += (needsComma ? ',' : '') + key + ': ' + $2[key];
+                               needsComma = true;
+                       }
+               }
+               $$ += "})";
+       }
 |      '{lang}' CHUNK_STAR '{/lang}' -> "Language.get(" + $2 + ", v)"
 |      '{' VARIABLE '}'  -> "StringUtil.escapeHTML(" + $2 + ")"
 |      '{#' VARIABLE '}' -> "StringUtil.formatNumeric(" + $2 + ")"
@@ -154,11 +167,18 @@ COMMAND_PARAMETER_LIST:
 |      T_VARIABLE_NAME '=' COMMAND_PARAMETER_VALUE { $$ = {}; $$[$1] = $3; }
 ;
 
-COMMAND_PARAMETER_VALUE: T_QUOTED_STRING | VARIABLE;
+COMMAND_PARAMETER_VALUE: T_QUOTED_STRING | T_DIGITS | VARIABLE;
 
 // COMMAND_PARAMETERS parses anything that is valid between a command name and the closing brace
 COMMAND_PARAMETERS: COMMAND_PARAMETER+ -> $1.join('')
 ;
-COMMAND_PARAMETER: T_ANY | T_WS | '=' | T_QUOTED_STRING | VARIABLE | T_VARIABLE_NAME
+COMMAND_PARAMETER: T_ANY | T_DIGITS | T_WS | '=' | T_QUOTED_STRING | VARIABLE | T_VARIABLE_NAME
 |      '(' COMMAND_PARAMETERS ')' -> $1 + ($2 || '') + $3
 ;
+
+PLURAL_PARAMETER_LIST:
+       T_PLURAL_PARAMETER_NAME '=' COMMAND_PARAMETER_VALUE T_WS PLURAL_PARAMETER_LIST { $$ = $5; $$[$1] = $3; }
+|      T_PLURAL_PARAMETER_NAME '=' COMMAND_PARAMETER_VALUE { $$ = {}; $$[$1] = $3; }
+;
+
+T_PLURAL_PARAMETER_NAME: T_DIGITS | T_VARIABLE_NAME;
index 5ccb6e73f204f08fbee18c1dbbed7b80a43b5acd..876e292cc83a6d28cd1ce8291ed5c70373936aff 100644 (file)
@@ -1,12 +1,12 @@
 
 
 define(function(require){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,37],$V1=[5,9,11,12,13,18,19,21,22,23,25,26,27,28,30,31,32,33,35,37,39],$V2=[1,24],$V3=[1,25],$V4=[1,31],$V5=[1,29],$V6=[1,30],$V7=[1,26],$V8=[1,27],$V9=[1,33],$Va=[11,12,15,40,41,45,47,49,50,52],$Vb=[9,11,12,13,18,19,21,23,26,28,30,31,32,33,35,37],$Vc=[11,12,15,40,41,44,45,46,47,49,50,52],$Vd=[18,35,37],$Ve=[12,15];
-var parser = {trace: function trace() { },
+var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,44],$V1=[5,9,11,12,13,18,19,21,22,23,25,26,28,29,30,32,33,34,35,37,39,41],$V2=[1,25],$V3=[1,27],$V4=[1,33],$V5=[1,31],$V6=[1,32],$V7=[1,28],$V8=[1,29],$V9=[1,26],$Va=[1,35],$Vb=[1,41],$Vc=[1,40],$Vd=[11,12,15,42,43,47,49,51,52,54,55],$Ve=[9,11,12,13,18,19,21,23,26,28,30,32,33,34,35,37,39],$Vf=[11,12,15,42,43,46,47,48,49,51,52,54,55],$Vg=[1,64],$Vh=[1,65],$Vi=[18,37,39],$Vj=[12,15];
+var parser = {trace: function trace () { },
 yy: {},
-symbols_: {"error":2,"TEMPLATE":3,"CHUNK_STAR":4,"EOF":5,"CHUNK_STAR_repetition0":6,"CHUNK":7,"PLAIN_ANY":8,"T_LITERAL":9,"COMMAND":10,"T_ANY":11,"T_WS":12,"{if":13,"COMMAND_PARAMETERS":14,"}":15,"COMMAND_repetition0":16,"COMMAND_option0":17,"{/if}":18,"{include":19,"COMMAND_PARAMETER_LIST":20,"{implode":21,"{/implode}":22,"{foreach":23,"COMMAND_option1":24,"{/foreach}":25,"{lang}":26,"{/lang}":27,"{":28,"VARIABLE":29,"{#":30,"{@":31,"{ldelim}":32,"{rdelim}":33,"ELSE":34,"{else}":35,"ELSE_IF":36,"{elseif":37,"FOREACH_ELSE":38,"{foreachelse}":39,"T_VARIABLE":40,"T_VARIABLE_NAME":41,"VARIABLE_repetition0":42,"VARIABLE_SUFFIX":43,"[":44,"]":45,".":46,"(":47,"VARIABLE_SUFFIX_option0":48,")":49,"=":50,"COMMAND_PARAMETER_VALUE":51,"T_QUOTED_STRING":52,"COMMAND_PARAMETERS_repetition_plus0":53,"COMMAND_PARAMETER":54,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"EOF",9:"T_LITERAL",11:"T_ANY",12:"T_WS",13:"{if",15:"}",18:"{/if}",19:"{include",21:"{implode",22:"{/implode}",23:"{foreach",25:"{/foreach}",26:"{lang}",27:"{/lang}",28:"{",30:"{#",31:"{@",32:"{ldelim}",33:"{rdelim}",35:"{else}",37:"{elseif",39:"{foreachelse}",40:"T_VARIABLE",41:"T_VARIABLE_NAME",44:"[",45:"]",46:".",47:"(",49:")",50:"=",52:"T_QUOTED_STRING"},
-productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[8,1],[8,1],[10,7],[10,3],[10,5],[10,6],[10,3],[10,3],[10,3],[10,3],[10,1],[10,1],[34,2],[36,4],[38,2],[29,3],[43,3],[43,2],[43,3],[20,5],[20,3],[51,1],[51,1],[14,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,1],[54,3],[6,0],[6,2],[16,0],[16,2],[17,0],[17,1],[24,0],[24,1],[42,0],[42,2],[48,0],[48,1],[53,1],[53,2]],
+symbols_: {"error":2,"TEMPLATE":3,"CHUNK_STAR":4,"EOF":5,"CHUNK_STAR_repetition0":6,"CHUNK":7,"PLAIN_ANY":8,"T_LITERAL":9,"COMMAND":10,"T_ANY":11,"T_WS":12,"{if":13,"COMMAND_PARAMETERS":14,"}":15,"COMMAND_repetition0":16,"COMMAND_option0":17,"{/if}":18,"{include":19,"COMMAND_PARAMETER_LIST":20,"{implode":21,"{/implode}":22,"{foreach":23,"COMMAND_option1":24,"{/foreach}":25,"{plural":26,"PLURAL_PARAMETER_LIST":27,"{lang}":28,"{/lang}":29,"{":30,"VARIABLE":31,"{#":32,"{@":33,"{ldelim}":34,"{rdelim}":35,"ELSE":36,"{else}":37,"ELSE_IF":38,"{elseif":39,"FOREACH_ELSE":40,"{foreachelse}":41,"T_VARIABLE":42,"T_VARIABLE_NAME":43,"VARIABLE_repetition0":44,"VARIABLE_SUFFIX":45,"[":46,"]":47,".":48,"(":49,"VARIABLE_SUFFIX_option0":50,")":51,"=":52,"COMMAND_PARAMETER_VALUE":53,"T_QUOTED_STRING":54,"T_DIGITS":55,"COMMAND_PARAMETERS_repetition_plus0":56,"COMMAND_PARAMETER":57,"T_PLURAL_PARAMETER_NAME":58,"$accept":0,"$end":1},
+terminals_: {2:"error",5:"EOF",9:"T_LITERAL",11:"T_ANY",12:"T_WS",13:"{if",15:"}",18:"{/if}",19:"{include",21:"{implode",22:"{/implode}",23:"{foreach",25:"{/foreach}",26:"{plural",28:"{lang}",29:"{/lang}",30:"{",32:"{#",33:"{@",34:"{ldelim}",35:"{rdelim}",37:"{else}",39:"{elseif",41:"{foreachelse}",42:"T_VARIABLE",43:"T_VARIABLE_NAME",46:"[",47:"]",48:".",49:"(",51:")",52:"=",54:"T_QUOTED_STRING",55:"T_DIGITS"},
+productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[8,1],[8,1],[10,7],[10,3],[10,5],[10,6],[10,3],[10,3],[10,3],[10,3],[10,3],[10,1],[10,1],[36,2],[38,4],[40,2],[31,3],[45,3],[45,2],[45,3],[20,5],[20,3],[53,1],[53,1],[53,1],[14,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,1],[57,3],[27,5],[27,3],[58,1],[58,1],[6,0],[6,2],[16,0],[16,2],[17,0],[17,1],[24,0],[24,1],[44,0],[44,2],[50,0],[50,1],[56,1],[56,2]],
 performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
 /* this == yyval */
 
@@ -84,77 +84,86 @@ case 11:
        
 break;
 case 12:
-this.$ = "Language.get(" + $$[$0-1] + ", v)";
+
+               this.$ = "I18nPlural.getCategoryFromTemplateParameters({"
+               var needsComma = false;
+               for (var key in $$[$0-1]) {
+                       if (objOwns($$[$0-1], key)) {
+                               this.$ += (needsComma ? ',' : '') + key + ': ' + $$[$0-1][key];
+                               needsComma = true;
+                       }
+               }
+               this.$ += "})";
+       
 break;
 case 13:
-this.$ = "StringUtil.escapeHTML(" + $$[$0-1] + ")";
+this.$ = "Language.get(" + $$[$0-1] + ", v)";
 break;
 case 14:
-this.$ = "StringUtil.formatNumeric(" + $$[$0-1] + ")";
+this.$ = "StringUtil.escapeHTML(" + $$[$0-1] + ")";
 break;
 case 15:
-this.$ = $$[$0-1];
+this.$ = "StringUtil.formatNumeric(" + $$[$0-1] + ")";
 break;
 case 16:
-this.$ = "'{'";
+this.$ = $$[$0-1];
 break;
 case 17:
-this.$ = "'}'";
+this.$ = "'{'";
 break;
 case 18:
-this.$ = "else { return " + $$[$0] + "; }";
+this.$ = "'}'";
 break;
 case 19:
-this.$ = "else if (" + $$[$0-2] + ") { return " + $$[$0] + "; }";
+this.$ = "else { return " + $$[$0] + "; }";
 break;
 case 20:
-this.$ = $$[$0];
+this.$ = "else if (" + $$[$0-2] + ") { return " + $$[$0] + "; }";
 break;
 case 21:
-this.$ = "v['" + $$[$0-1] + "']" + $$[$0].join('');;
+this.$ = $$[$0];
 break;
 case 22:
-this.$ = $$[$0-2] + $$[$0-1] + $$[$0];
+this.$ = "v['" + $$[$0-1] + "']" + $$[$0].join('');;
 break;
 case 23:
+this.$ = $$[$0-2] + $$[$0-1] + $$[$0];
+break;
+case 24:
 this.$ = "['" + $$[$0] + "']";
 break;
-case 24: case 36:
+case 25: case 39:
 this.$ = $$[$0-2] + ($$[$0-1] || '') + $$[$0];
 break;
-case 25:
+case 26: case 40:
  this.$ = $$[$0]; this.$[$$[$0-4]] = $$[$0-2]; 
 break;
-case 26:
+case 27: case 41:
  this.$ = {}; this.$[$$[$0-2]] = $$[$0]; 
 break;
-case 29:
+case 31:
 this.$ = $$[$0].join('');
 break;
-case 37: case 39: case 45:
+case 44: case 46: case 52:
 this.$ = [];
 break;
-case 38: case 40: case 46: case 50:
+case 45: case 47: case 53: case 57:
 $$[$0-1].push($$[$0]);
 break;
-case 49:
+case 56:
 this.$ = [$$[$0]];
 break;
 }
 },
-table: [o([5,9,11,12,13,19,21,23,26,28,30,31,32,33],$V0,{3:1,4:2,6:3}),{1:[3]},{5:[1,4]},o([5,18,22,25,27,35,37,39],[2,2],{7:5,8:6,10:8,9:[1,7],11:[1,9],12:[1,10],13:[1,11],19:[1,12],21:[1,13],23:[1,14],26:[1,15],28:[1,16],30:[1,17],31:[1,18],32:[1,19],33:[1,20]}),{1:[2,1]},o($V1,[2,38]),o($V1,[2,3]),o($V1,[2,4]),o($V1,[2,5]),o($V1,[2,6]),o($V1,[2,7]),{11:$V2,12:$V3,14:21,29:28,40:$V4,41:$V5,47:$V6,50:$V7,52:$V8,53:22,54:23},{20:32,41:$V9},{20:34,41:$V9},{20:35,41:$V9},o([9,11,12,13,19,21,23,26,27,28,30,31,32,33],$V0,{6:3,4:36}),{29:37,40:$V4},{29:38,40:$V4},{29:39,40:$V4},o($V1,[2,16]),o($V1,[2,17]),{15:[1,40]},o([15,45,49],[2,29],{29:28,54:41,11:$V2,12:$V3,40:$V4,41:$V5,47:$V6,50:$V7,52:$V8}),o($Va,[2,49]),o($Va,[2,30]),o($Va,[2,31]),o($Va,[2,32]),o($Va,[2,33]),o($Va,[2,34]),o($Va,[2,35]),{11:$V2,12:$V3,14:42,29:28,40:$V4,41:$V5,47:$V6,50:$V7,52:$V8,53:22,54:23},{41:[1,43]},{15:[1,44]},{50:[1,45]},{15:[1,46]},{15:[1,47]},{27:[1,48]},{15:[1,49]},{15:[1,50]},{15:[1,51]},o($Vb,$V0,{6:3,4:52}),o($Va,[2,50]),{49:[1,53]},o($Vc,[2,45],{42:54}),o($V1,[2,9]),{29:57,40:$V4,51:55,52:[1,56]},o([9,11,12,13,19,21,22,23,26,28,30,31,32,33],$V0,{6:3,4:58}),o([9,11,12,13,19,21,23,25,26,28,30,31,32,33,39],$V0,{6:3,4:59}),o($V1,[2,12]),o($V1,[2,13]),o($V1,[2,14]),o($V1,[2,15]),o($Vd,[2,39],{16:60}),o($Va,[2,36]),o([11,12,15,40,41,45,49,50,52],[2,21],{43:61,44:[1,62],46:[1,63],47:[1,64]}),{12:[1,65],15:[2,26]},o($Ve,[2,27]),o($Ve,[2,28]),{22:[1,66]},{24:67,25:[2,43],38:68,39:[1,69]},{17:70,18:[2,41],34:72,35:[1,74],36:71,37:[1,73]},o($Vc,[2,46]),{11:$V2,12:$V3,14:75,29:28,40:$V4,41:$V5,47:$V6,50:$V7,52:$V8,53:22,54:23},{41:[1,76]},{11:$V2,12:$V3,14:78,29:28,40:$V4,41:$V5,47:$V6,48:77,49:[2,47],50:$V7,52:$V8,53:22,54:23},{20:79,41:$V9},o($V1,[2,10]),{25:[1,80]},{25:[2,44]},o([9,11,12,13,19,21,23,25,26,28,30,31,32,33],$V0,{6:3,4:81}),{18:[1,82]},o($Vd,[2,40]),{18:[2,42]},{11:$V2,12:$V3,14:83,29:28,40:$V4,41:$V5,47:$V6,50:$V7,52:$V8,53:22,54:23},o([9,11,12,13,18,19,21,23,26,28,30,31,32,33],$V0,{6:3,4:84}),{45:[1,85]},o($Vc,[2,23]),{49:[1,86]},{49:[2,48]},{15:[2,25]},o($V1,[2,11]),{25:[2,20]},o($V1,[2,8]),{15:[1,87]},{18:[2,18]},o($Vc,[2,22]),o($Vc,[2,24]),o($Vb,$V0,{6:3,4:88}),o($Vd,[2,19])],
-defaultActions: {4:[2,1],68:[2,44],72:[2,42],78:[2,48],79:[2,25],81:[2,20],84:[2,18]},
-parseError: function parseError(str, hash) {
+table: [o([5,9,11,12,13,19,21,23,26,28,30,32,33,34,35],$V0,{3:1,4:2,6:3}),{1:[3]},{5:[1,4]},o([5,18,22,25,29,37,39,41],[2,2],{7:5,8:6,10:8,9:[1,7],11:[1,9],12:[1,10],13:[1,11],19:[1,12],21:[1,13],23:[1,14],26:[1,15],28:[1,16],30:[1,17],32:[1,18],33:[1,19],34:[1,20],35:[1,21]}),{1:[2,1]},o($V1,[2,45]),o($V1,[2,3]),o($V1,[2,4]),o($V1,[2,5]),o($V1,[2,6]),o($V1,[2,7]),{11:$V2,12:$V3,14:22,31:30,42:$V4,43:$V5,49:$V6,52:$V7,54:$V8,55:$V9,56:23,57:24},{20:34,43:$Va},{20:36,43:$Va},{20:37,43:$Va},{27:38,43:$Vb,55:$Vc,58:39},o([9,11,12,13,19,21,23,26,28,29,30,32,33,34,35],$V0,{6:3,4:42}),{31:43,42:$V4},{31:44,42:$V4},{31:45,42:$V4},o($V1,[2,17]),o($V1,[2,18]),{15:[1,46]},o([15,47,51],[2,31],{31:30,57:47,11:$V2,12:$V3,42:$V4,43:$V5,49:$V6,52:$V7,54:$V8,55:$V9}),o($Vd,[2,56]),o($Vd,[2,32]),o($Vd,[2,33]),o($Vd,[2,34]),o($Vd,[2,35]),o($Vd,[2,36]),o($Vd,[2,37]),o($Vd,[2,38]),{11:$V2,12:$V3,14:48,31:30,42:$V4,43:$V5,49:$V6,52:$V7,54:$V8,55:$V9,56:23,57:24},{43:[1,49]},{15:[1,50]},{52:[1,51]},{15:[1,52]},{15:[1,53]},{15:[1,54]},{52:[1,55]},{52:[2,42]},{52:[2,43]},{29:[1,56]},{15:[1,57]},{15:[1,58]},{15:[1,59]},o($Ve,$V0,{6:3,4:60}),o($Vd,[2,57]),{51:[1,61]},o($Vf,[2,52],{44:62}),o($V1,[2,9]),{31:66,42:$V4,53:63,54:$Vg,55:$Vh},o([9,11,12,13,19,21,22,23,26,28,30,32,33,34,35],$V0,{6:3,4:67}),o([9,11,12,13,19,21,23,25,26,28,30,32,33,34,35,41],$V0,{6:3,4:68}),o($V1,[2,12]),{31:66,42:$V4,53:69,54:$Vg,55:$Vh},o($V1,[2,13]),o($V1,[2,14]),o($V1,[2,15]),o($V1,[2,16]),o($Vi,[2,46],{16:70}),o($Vd,[2,39]),o([11,12,15,42,43,47,51,52,54,55],[2,22],{45:71,46:[1,72],48:[1,73],49:[1,74]}),{12:[1,75],15:[2,27]},o($Vj,[2,28]),o($Vj,[2,29]),o($Vj,[2,30]),{22:[1,76]},{24:77,25:[2,50],40:78,41:[1,79]},{12:[1,80],15:[2,41]},{17:81,18:[2,48],36:83,37:[1,85],38:82,39:[1,84]},o($Vf,[2,53]),{11:$V2,12:$V3,14:86,31:30,42:$V4,43:$V5,49:$V6,52:$V7,54:$V8,55:$V9,56:23,57:24},{43:[1,87]},{11:$V2,12:$V3,14:89,31:30,42:$V4,43:$V5,49:$V6,50:88,51:[2,54],52:$V7,54:$V8,55:$V9,56:23,57:24},{20:90,43:$Va},o($V1,[2,10]),{25:[1,91]},{25:[2,51]},o([9,11,12,13,19,21,23,25,26,28,30,32,33,34,35],$V0,{6:3,4:92}),{27:93,43:$Vb,55:$Vc,58:39},{18:[1,94]},o($Vi,[2,47]),{18:[2,49]},{11:$V2,12:$V3,14:95,31:30,42:$V4,43:$V5,49:$V6,52:$V7,54:$V8,55:$V9,56:23,57:24},o([9,11,12,13,18,19,21,23,26,28,30,32,33,34,35],$V0,{6:3,4:96}),{47:[1,97]},o($Vf,[2,24]),{51:[1,98]},{51:[2,55]},{15:[2,26]},o($V1,[2,11]),{25:[2,21]},{15:[2,40]},o($V1,[2,8]),{15:[1,99]},{18:[2,19]},o($Vf,[2,23]),o($Vf,[2,25]),o($Ve,$V0,{6:3,4:100}),o($Vi,[2,20])],
+defaultActions: {4:[2,1],40:[2,42],41:[2,43],78:[2,51],83:[2,49],89:[2,55],90:[2,26],92:[2,21],93:[2,40],96:[2,19]},
+parseError: function parseError (str, hash) {
     if (hash.recoverable) {
         this.trace(str);
     } else {
-        function _parseError (msg, hash) {
-            this.message = msg;
-            this.hash = hash;
-        }
-        _parseError.prototype = Error;
-
-        throw new _parseError(str, hash);
+        var error = new Error(str);
+        error.hash = hash;
+        throw error;
     }
 },
 parse: function parse(input) {
@@ -437,7 +446,7 @@ showPosition:function () {
     },
 
 // test the lexed token: return FALSE when not a match, otherwise return token
-test_match:function (match, indexed_rule) {
+test_match:function(match, indexed_rule) {
         var token,
             lines,
             backup;
@@ -567,7 +576,7 @@ next:function () {
     },
 
 // return next match that has a token
-lex:function lex() {
+lex:function lex () {
         var r = this.next();
         if (r) {
             return r;
@@ -577,12 +586,12 @@ lex:function lex() {
     },
 
 // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
-begin:function begin(condition) {
+begin:function begin (condition) {
         this.conditionStack.push(condition);
     },
 
 // pop the previously active lexer condition state off the condition stack
-popState:function popState() {
+popState:function popState () {
         var n = this.conditionStack.length - 1;
         if (n > 0) {
             return this.conditionStack.pop();
@@ -592,7 +601,7 @@ popState:function popState() {
     },
 
 // produce the lexer rule set which is active for the currently active lexer condition state
-_currentRules:function _currentRules() {
+_currentRules:function _currentRules () {
         if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
             return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
         } else {
@@ -601,7 +610,7 @@ _currentRules:function _currentRules() {
     },
 
 // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
-topState:function topState(n) {
+topState:function topState (n) {
         n = this.conditionStack.length - 1 - Math.abs(n || 0);
         if (n >= 0) {
             return this.conditionStack[n];
@@ -611,7 +620,7 @@ topState:function topState(n) {
     },
 
 // alias for begin(condition)
-pushState:function pushState(condition) {
+pushState:function pushState (condition) {
         this.begin(condition);
     },
 
@@ -627,74 +636,78 @@ case 0:/* comment */
 break;
 case 1: yy_.yytext = yy_.yytext.substring(9, yy_.yytext.length - 10); return 9; 
 break;
-case 2:return 52;
+case 2:return 54;
 break;
-case 3:return 52;
+case 3:return 54;
 break;
-case 4:return 40;
+case 4:return 42;
 break;
-case 5: return 41
+case 5: return 55
 break;
-case 6:return 46;
+case 6: return 43; 
 break;
-case 7:return 44;
+case 7:return 48;
 break;
-case 8:return 45;
+case 8:return 46;
 break;
 case 9:return 47;
 break;
 case 10:return 49;
 break;
-case 11:return 50;
+case 11:return 51;
+break;
+case 12:return 52;
+break;
+case 13:return 34;
 break;
-case 12:return 32;
+case 14:return 35;
 break;
-case 13:return 33;
+case 15: this.begin('command'); return 32; 
 break;
-case 14: this.begin('command'); return 30
+case 16: this.begin('command'); return 33
 break;
-case 15: this.begin('command'); return 31
+case 17: this.begin('command'); return 13
 break;
-case 16: this.begin('command'); return 13
+case 18: this.begin('command'); return 39
 break;
-case 17: this.begin('command'); return 37
+case 19: this.begin('command'); return 39
 break;
-case 18: this.begin('command'); return 37; 
+case 20:return 37;
 break;
-case 19:return 35;
+case 21:return 18;
 break;
-case 20:return 18;
+case 22:return 28;
 break;
-case 21:return 26;
+case 23:return 29;
 break;
-case 22:return 27;
+case 24: this.begin('command'); return 19; 
 break;
-case 23: this.begin('command'); return 19
+case 25: this.begin('command'); return 21
 break;
-case 24: this.begin('command'); return 21
+case 26: this.begin('command'); return 26
 break;
-case 25:return 22;
+case 27:return 22;
 break;
-case 26: this.begin('command'); return 23; 
+case 28: this.begin('command'); return 23; 
 break;
-case 27:return 39;
+case 29:return 41;
 break;
-case 28:return 25;
+case 30:return 25;
 break;
-case 29: this.begin('command'); return 28
+case 31: this.begin('command'); return 30
 break;
-case 30: this.popState(); return 15;
+case 32: this.popState(); return 15;
 break;
-case 31:return 12;
+case 33:return 12;
 break;
-case 32:return 5;
+case 34:return 5;
 break;
-case 33:return 11;
+case 35:return 11;
 break;
 }
 },
-rules: [/^(?:\{\*[\s\S]*?\*\})/,/^(?:\{literal\}[\s\S]*?\{\/literal\})/,/^(?:"([^"]|\\\.)*")/,/^(?:'([^']|\\\.)*')/,/^(?:\$)/,/^(?:[_a-zA-Z][_a-zA-Z0-9]*)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:=)/,/^(?:\{ldelim\})/,/^(?:\{rdelim\})/,/^(?:\{#)/,/^(?:\{@)/,/^(?:\{if )/,/^(?:\{else if )/,/^(?:\{elseif )/,/^(?:\{else\})/,/^(?:\{\/if\})/,/^(?:\{lang\})/,/^(?:\{\/lang\})/,/^(?:\{include )/,/^(?:\{implode )/,/^(?:\{\/implode\})/,/^(?:\{foreach )/,/^(?:\{foreachelse\})/,/^(?:\{\/foreach\})/,/^(?:\{(?!\s))/,/^(?:\})/,/^(?:\s+)/,/^(?:$)/,/^(?:[^{])/],
-conditions: {"command":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"inclusive":true},"INITIAL":{"rules":[0,1,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,33],"inclusive":true}}
+rules: [/^(?:\{\*[\s\S]*?\*\})/,/^(?:\{literal\}[\s\S]*?\{\/literal\})/,/^(?:"([^"]|\\\.)*")/,/^(?:'([^']|\\\.)*')/,/^(?:\$)/,/^(?:[0-9]+)/,/^(?:[_a-zA-Z][_a-zA-Z0-9]*)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:=)/,/^(?:\{ldelim\})/,/^(?:\{rdelim\})/,/^(?:\{#)/,/^(?:\{@)/,/^(?:\{if )/,/^(?:\{else if )/,/^(?:\{elseif )/,/^(?:\{else\})/,/^(?:\{\/if\})/,/^(?:\{lang\})/,/^(?:\{\/lang\})/,/^(?:\{include )/,/^(?:\{implode )/,/^(?:\{plural )/,/^(?:\{\/implode\})/,/^(?:\{foreach )/,/^(?:\{foreachelse\})/,/^(?:\{\/foreach\})/,/^(?:\{(?!\s))/,/^(?:\})/,/^(?:\s+)/,/^(?:$)/,/^(?:[^{])/],
+conditions: {"command":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"inclusive":true},"INITIAL":{"rules":[0,1,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35],"inclusive":true}}
 });
 return lexer;
 })();
index cefa552da9b128adc51159b152789d7d7bf99f7d..1efce33b5ec94a61e96785bf23522d7b5b003efb 100644 (file)
@@ -9,7 +9,7 @@
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLabSuite/Core/Template
  */
-define(['./Template.grammar', './StringUtil', 'Language'], function(parser, StringUtil, Language) {
+define(['./Template.grammar', './StringUtil', 'Language', 'WoltLabSuite/Core/I18n/Plural'], function(parser, StringUtil, Language, I18nPlural) {
        "use strict";
        
        // work around bug in AMD module generation of Jison
@@ -39,7 +39,7 @@ define(['./Template.grammar', './StringUtil', 'Language'], function(parser, Stri
                        + "v.__wcf = window.WCF; v.__window = window;\n"
                        + "return " + template;
                        
-                       this.fetch = new Function("StringUtil", "Language", "v", template).bind(undefined, StringUtil, Language);
+                       this.fetch = new Function("StringUtil", "Language", "I18nPlural", "v", template).bind(undefined, StringUtil, Language, I18nPlural);
                }
                catch (e) {
                        console.debug(e.message);
index 055bb9f84c2ba10c6ee534beefe884f68bf84af5..444b782fe806087348ee9fdc2e34d84c2cf2bc5c 100644 (file)
@@ -114,9 +114,9 @@ define(['Core', 'Language', 'Ui/Dialog'], function(Core, Language, UiDialog) {
                        dialog.appendChild(formSubmit);
                        
                        _confirmButton = elCreate('button');
+                       _confirmButton.dataset.type = "submit";
                        _confirmButton.classList.add('buttonPrimary');
                        _confirmButton.textContent = Language.get('wcf.global.confirmation.confirm');
-                       _confirmButton.addEventListener(WCF_CLICK_EVENT, this._confirm.bind(this));
                        formSubmit.appendChild(_confirmButton);
                        
                        var cancelButton = elCreate('button');
@@ -165,6 +165,10 @@ define(['Core', 'Language', 'Ui/Dialog'], function(Core, Language, UiDialog) {
                _onShow: function() {
                        _confirmButton.blur();
                        _confirmButton.focus();
+               },
+
+               _dialogSubmit: function() {
+                       this._confirm();
                }
        };
 });
index 0fe311d1f1db0c06f096241e71bdc26fd959a4b6..4af7aa99f3117dc3f0ae99e41f7a0595aadd617f 100644 (file)
@@ -511,6 +511,10 @@ define(
                        }
                        
                        if (elAttr(data.dialog, 'aria-hidden') === 'true') {
+                               // close existing dropdowns
+                               UiSimpleDropdown.closeAll();
+                               window.WCF.Dropdown.Interactive.Handler.closeAll();
+                               
                                if (_callbackFocus === null) {
                                        _callbackFocus = this._maintainFocus.bind(this);
                                        document.body.addEventListener('focus', _callbackFocus, { capture: true });
@@ -548,10 +552,6 @@ define(
                                                id: id
                                        });
                                }
-                               
-                               // close existing dropdowns
-                               UiSimpleDropdown.closeAll();
-                               window.WCF.Dropdown.Interactive.Handler.closeAll();
                        }
                        
                        this.rebuild(id);
@@ -593,7 +593,7 @@ define(
                                        // causing it to pop out from below and immediately vanish.
                                        // 
                                        // iOS will only show the keyboard if an input element is focused *and* the
-                                       // focus is an immediate result of an user interaction. This method must be
+                                       // focus is an immediate result of a user interaction. This method must be
                                        // assumed to be called from within a click event, but we want to set the
                                        // focus without triggering the keyboard.
                                        // 
@@ -667,16 +667,6 @@ define(
                        var maximumHeight = (window.innerHeight * (_dialogFullHeight ? 1 : 0.8)) - unavailableHeight;
                        contentContainer.style.setProperty('max-height', ~~maximumHeight + 'px', '');
                        
-                       // fix for a calculation bug in Chrome causing the scrollbar to overlap the border
-                       if (Environment.browser() === 'chrome') {
-                               if (data.content.scrollHeight > maximumHeight) {
-                                       data.content.style.setProperty('margin-right', '-1px', '');
-                               }
-                               else {
-                                       data.content.style.removeProperty('margin-right');
-                               }
-                       }
-                       
                        // Chrome and Safari use heavy anti-aliasing when the dialog's width
                        // cannot be evenly divided, causing the whole text to become blurry
                        if (Environment.browser() === 'chrome' || Environment.browser() === 'safari') {
index 46a1fb72a14376e502cf64fe4b6f9a548aa23510..520966758e8b3e170d45dd55780347e38ecf2250 100644 (file)
@@ -146,6 +146,7 @@ define(['Ajax', 'Core', 'Dom/ChangeListener', 'Language', 'Dom/Util', 'Dom/Trave
                        }
                        
                        this._uploadHandler.checkMaxFiles();
+                       Core.triggerEvent(this._target, 'change');
                },
                
                _ajaxSetup: function () {
index 1832bf2121e8529ca14c88854af6d07c527e4fb4..59b48a95dd73e827d9c698d736ccb8183367e7cf 100644 (file)
@@ -31,7 +31,9 @@ define(['Core', 'Language', 'Dom/Util', 'WoltLabSuite/Core/Ui/File/Delete', 'Upl
                        // image preview
                        imagePreview: false,
                        // max files
-                       maxFiles: null
+                       maxFiles: null,
+                       // array of acceptable file types, null if any file type is acceptable
+                       acceptableFiles: null,
                }, options);
                
                this._options.multiple = this._options.maxFiles === null || this._options.maxFiles > 1; 
@@ -184,6 +186,7 @@ define(['Core', 'Language', 'Dom/Util', 'WoltLabSuite/Core/Ui/File/Delete', 'Upl
                        // create delete buttons
                        this._deleteHandler.rebuild();
                        this.checkMaxFiles();
+                       Core.triggerEvent(this._target, 'change');
                },
                
                _getFormData: function() {
index 9509b07b28709816ba92efb375665f43ea6642d5..a570555eda981cc95c58825751426f33651aea9e 100644 (file)
@@ -146,6 +146,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'EventKey', 'WoltLabSu
                        _data.set(elementId, {
                                dropdownMenu: null,
                                element: data.element,
+                               limitReached: data.limitReached,
                                list: data.list,
                                listItem: data.element.parentNode,
                                options: options,
@@ -286,6 +287,12 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'EventKey', 'WoltLabSu
                                elAttr(element, 'maxLength', options.maxLength);
                        }
                        
+                       var limitReached = elCreate('span');
+                       limitReached.className = 'inputItemListLimitReached';
+                       limitReached.textContent = Language.get('wcf.global.form.input.maxItems');
+                       elHide(limitReached);
+                       listItem.appendChild(limitReached);
+                       
                        var shadow = null, values = [];
                        if (options.isCSV) {
                                shadow = elCreate('input');
@@ -319,6 +326,7 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'EventKey', 'WoltLabSu
                        
                        return {
                                element: element,
+                               limitReached: limitReached,
                                list: list,
                                shadow: shadow,
                                values: values
@@ -349,14 +357,12 @@ define(['Core', 'Dictionary', 'Language', 'Dom/Traverse', 'EventKey', 'WoltLabSu
                _handleLimit: function(elementId) {
                        var data = _data.get(elementId);
                        if (this._acceptsNewItems(elementId)) {
-                               if (data.element.disabled) {
-                                       data.element.disabled = false;
-                                       data.element.removeAttribute('placeholder');
-                               }
+                               elShow(data.element);
+                               elHide(data.limitReached);
                        }
-                       else if (!data.element.disabled) {
-                               data.element.disabled = true;
-                               elAttr(data.element, 'placeholder', Language.get('wcf.global.form.input.maxItems'));
+                       else {
+                               elHide(data.element);
+                               elShow(data.limitReached);
                        }
                },
                
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/TwitterEmbed.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/TwitterEmbed.js
new file mode 100644 (file)
index 0000000..3c45916
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * Wrapper around Twitter's createTweet API.
+ *
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/Ui/Message/TwitterEmbed
+ */
+define(['https://platform.twitter.com/widgets.js'], function(Widgets) {
+       "use strict";
+       
+       var twitterReady = new Promise(function(resolve, reject) {
+               twttr.ready(resolve);
+       });
+       
+       /**
+        * @exports     WoltLabSuite/Core/Ui/Message/TwitterEmbed
+        */
+       return {
+               /**
+                * Embed the tweet identified by the given tweetId into the given container.
+                * 
+                * @param {HTMLElement} container
+                * @param {string} tweetId
+                * @param {boolean} removeChildren Whether to remove existing children of the given container after embedding the tweet.
+                * @return {HTMLElement} The Tweet element created by Twitter.
+                */
+               embedTweet: function(container, tweetId, removeChildren) {
+                       if (removeChildren === undefined) removeChildren = false;
+                       
+                       return twitterReady.then(function() {
+                               return twttr.widgets.createTweet(tweetId, container, {
+                                       dnt: true,
+                                       lang: document.documentElement.lang,
+                               });
+                       }).then(function(tweet) {
+                               if (tweet && removeChildren) {
+                                       while (container.lastChild) {
+                                               container.removeChild(container.lastChild);
+                                       }
+                                       container.appendChild(tweet);
+                               }
+                               
+                               return tweet;
+                       });
+               },
+               
+               /**
+                * Embeds tweets into all elements with a data-wsc-twitter-tweet attribute, removing
+                * existing children.
+                */
+               embedAll: function() {
+                       elBySelAll("[data-wsc-twitter-tweet]", undefined, function(container) {
+                               var tweetId = elData(container, "wsc-twitter-tweet");
+                               if (tweetId) {
+                                       this.embedTweet(container, tweetId, true);
+                                       elData(container, "wsc-twitter-tweet", "");
+                               }
+                       }.bind(this))
+               }
+       };
+});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/UserConsent.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Message/UserConsent.js
new file mode 100644 (file)
index 0000000..59c10ce
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * Prompts the user for their consent before displaying external media.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module      WoltLabSuite/Core/Ui/Message/UserConsent
+ */
+define(['Ajax', 'Core', 'User', 'Dom/ChangeListener', 'Dom/Util'], function (Ajax, Core, User, DomChangeListener, DomUtil) {
+       var _enableAll = false;
+       var _knownButtons = (typeof window.WeakSet === 'function') ? new window.WeakSet() : new window.Set();
+       
+       return {
+               init: function () {
+                       if (window.sessionStorage.getItem(Core.getStoragePrefix() + 'user-consent') === 'all') {
+                               _enableAll = true;
+                       }
+                       
+                       this._registerEventListeners();
+                       
+                       DomChangeListener.add(
+                               'WoltLabSuite/Core/Ui/Message/UserConsent',
+                               this._registerEventListeners.bind(this)
+                       );
+               },
+               
+               _registerEventListeners: function () {
+                       if (_enableAll) {
+                               this._enableAll();
+                       }
+                       else {
+                               elBySelAll('.jsButtonMessageUserConsentEnable', undefined, (function (button) {
+                                       if (!_knownButtons.has(button)) {
+                                               button.addEventListener('click', this._click.bind(this));
+                                               _knownButtons.add(button);
+                                       }
+                               }).bind(this));
+                       }
+               },
+               
+               /**
+                * @param {Event} event
+                */
+               _click: function (event) {
+                       event.preventDefault();
+                       
+                       _enableAll = true;
+                       
+                       this._enableAll();
+                       
+                       if (User.userId) {
+                               Ajax.apiOnce({
+                                       data: {
+                                               actionName: 'saveUserConsent',
+                                               className: 'wcf\\data\\user\\UserAction'
+                                       },
+                                       silent: true
+                               });
+                       }
+                       else {
+                               window.sessionStorage.setItem(Core.getStoragePrefix() + 'user-consent', 'all');
+                       }
+               },
+               
+               /**
+                * @param {Element} container
+                */
+               _enableExternalMedia: function (container) {
+                       var payload = atob(elData(container, 'payload'));
+                       
+                       DomUtil.insertHtml(payload, container, 'before');
+                       elRemove(container);
+               },
+               
+               _enableAll: function () {
+                       elBySelAll('.messageUserConsent', undefined, this._enableExternalMedia.bind(this));
+               }
+       };
+});
index 340ec766848e4c140fd80ca4951a1f6a9f0fe757..a26f6a424d2c9d2225facf46271b4ee45f571cc5 100644 (file)
@@ -21,12 +21,12 @@ define(
        var _knownMessages = new List();
        var _main = null;
        var _messages = elByClass('message');
+       var _mobileSidebarEnabled = false;
        var _options = {};
        var _pageMenuMain = null;
        var _pageMenuUser = null;
        var _messageGroups = null;
        var _sidebars = [];
-       var _sidebarXsEnabled = false;
        
        /**
         * @exports     WoltLabSuite/Core/Ui/Mobile
@@ -71,10 +71,10 @@ define(
                                setup: this.enableShadow.bind(this)
                        });
                        
-                       UiScreen.on('screen-xs', {
-                               match: this._enableSidebarXS.bind(this),
-                               unmatch: this._disableSidebarXS.bind(this),
-                               setup: this._setupSidebarXS.bind(this)
+                       UiScreen.on('screen-md-down', {
+                               match: this._enableMobileSidebar.bind(this),
+                               unmatch: this._disableMobileSidebar.bind(this),
+                               setup: this._setupMobileSidebar.bind(this)
                        });
                        
                        // On the large tablets (e.g. iPad Pro) the navigation is not usable, because there is not the mobile
@@ -310,22 +310,22 @@ define(
                        }
                },
                
-               _enableSidebarXS: function() {
-                       _sidebarXsEnabled = true;
+               _enableMobileSidebar: function() {
+                       _mobileSidebarEnabled = true;
                },
                
-               _disableSidebarXS: function() {
-                       _sidebarXsEnabled = false;
+               _disableMobileSidebar: function() {
+                       _mobileSidebarEnabled = false;
                        
                        _sidebars.forEach(function (sidebar) {
                                sidebar.classList.remove('open');
                        });
                },
                
-               _setupSidebarXS: function() {
+               _setupMobileSidebar: function() {
                        _sidebars.forEach(function (sidebar) {
                                sidebar.addEventListener('mousedown', function(event) {
-                                       if (_sidebarXsEnabled && event.target === sidebar) {
+                                       if (_mobileSidebarEnabled && event.target === sidebar) {
                                                event.preventDefault();
                                                
                                                sidebar.classList.toggle('open');
@@ -333,7 +333,7 @@ define(
                                });
                        });
                        
-                       _sidebarXsEnabled = true;
+                       _mobileSidebarEnabled = true;
                },
                
                _toggleMobileNavigation: function (message, quickOptions, navigation) {
index e9ffa17c2435adeb9d601b54130092d3197fd991..b1d8eeb71472c17254c18629f529c03cee61a514 100644 (file)
@@ -1,18 +1,35 @@
 /**
  * Provides page actions such as "jump to top" and clipboard actions.
- * 
+ *
  * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module     WoltLabSuite/Core/Ui/Page/Action
  */
-define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
-       "use strict";
+define(['Dictionary', 'Language', 'Ui/Screen'], function (Dictionary, Language, UiScreen) {
+       'use strict';
        
        var _buttons = new Dictionary();
-       var _container = null;
+       
+       /** @var {Element} */
+       var _container;
+       
        var _didInit = false;
        
+       var _lastPosition = -1;
+       
+       /** @var {Element} */
+       var _toTopButton;
+       
+       /** @var {Element} */
+       var _wrapper;
+       
+       var _resetLastPosition = window.debounce(function () {
+               _lastPosition = -1;
+       }, 50, false);
+
+       var _toTopButtonThreshold = 300;
+       
        /**
         * @exports     WoltLabSuite/Core/Ui/Page/Action
         */
@@ -20,66 +37,182 @@ define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
                /**
                 * Initializes the page action container.
                 */
-               setup: function() {
+               setup: function () {
+                       if (_didInit) {
+                               return;
+                       }
+                       
                        _didInit = true;
                        
-                       _container = elCreate('ul');
-                       _container.className = 'pageAction';
-                       document.body.appendChild(_container);
+                       _wrapper = elCreate('div');
+                       _wrapper.className = 'pageAction';
+                       
+                       _container = elCreate('div');
+                       _container.className = 'pageActionButtons';
+                       _wrapper.appendChild(_container);
+                       
+                       _toTopButton = this._buildToTopButton();
+                       _wrapper.appendChild(_toTopButton);
+                       
+                       document.body.appendChild(_wrapper);
+                       
+                       var debounce = window.debounce(this._onScroll.bind(this), 100, false);
+                       window.addEventListener(
+                               "scroll",
+                               function () {
+                                       if (_lastPosition === -1) {
+                                               _lastPosition = window.pageYOffset;
+                                               
+                                               // Invoke the scroll handler once to immediately respond to
+                                               // the user action before debouncing all further calls.
+                                               window.setTimeout(function () {
+                                                       this._onScroll();
+                                                       
+                                                       _lastPosition = window.pageYOffset;
+                                               }.bind(this), 60);
+                                       }
+
+                                       debounce();
+                               }.bind(this),
+                               {passive: true}
+                       );
+                       
+                       window.addEventListener("touchstart", function () {
+                               // Force a reset of the scroll position to trigger an immediate reaction
+                               // when the user touches the display again.
+                               if (_lastPosition !== -1) {
+                                       _lastPosition = -1;
+                               }
+                       }, {passive: true});
+
+                       UiScreen.on('screen-sm-down', {
+                               match: function() {
+                                       _toTopButtonThreshold = 50;
+                               },
+                               unmatch: function() {
+                                       _toTopButtonThreshold = 300;
+                               },
+                               setup: function() {
+                                       _toTopButtonThreshold = 50;
+                               }
+                       });
+                       
+                       this._onScroll();
+               },
+               
+               _buildToTopButton: function () {
+                       var button = elCreate('a');
+                       button.className = 'button buttonPrimary pageActionButtonToTop initiallyHidden jsTooltip';
+                       button.href = '';
+                       elAttr(button, 'title', Language.get('wcf.global.scrollUp'));
+                       elAttr(button, 'aria-hidden', 'true');
+                       button.innerHTML = '<span class="icon icon32 fa-angle-up"></span>';
+                       
+                       button.addEventListener(WCF_CLICK_EVENT, this._scrollTopTop.bind(this));
+                       
+                       return button;
+               },
+               
+               _onScroll: function () {
+                       if (document.documentElement.classList.contains('disableScrolling')) {
+                               // Ignore any scroll events that take place while body scrolling is disabled,
+                               // because it messes up the scroll offsets.
+                               return;
+                       }
+                       
+                       var offset = window.pageYOffset;
+                       if (offset === _lastPosition) {
+                               // Ignore any scroll event that is fired but without a position change. This can
+                               // happen after closing a dialog that prevented the body from being scrolled.
+                               _resetLastPosition();
+                               return;
+                       }
+                       
+                       if (offset >= _toTopButtonThreshold) {
+                               if (_toTopButton.classList.contains('initiallyHidden')) {
+                                       _toTopButton.classList.remove('initiallyHidden');
+                               }
+                               
+                               elAttr(_toTopButton, 'aria-hidden', 'false');
+                       }
+                       else {
+                               elAttr(_toTopButton, 'aria-hidden', 'true');
+                       }
+                       
+                       this._renderContainer();
+                       
+                       if (_lastPosition !== -1) {
+                               _wrapper.classList[offset < _lastPosition ? 'remove' : 'add']('scrolledDown');
+                       }
+                       
+                       _lastPosition = -1;
+               },
+               
+               /**
+                * @param {Event} event
+                */
+               _scrollTopTop: function (event) {
+                       event.preventDefault();
+                       
+                       elById('top').scrollIntoView({behavior: 'smooth'});
                },
                
                /**
                 * Adds a button to the page action list. You can optionally provide a button name to
                 * insert the button right before it. Unmatched button names or empty value will cause
                 * the button to be prepended to the list.
-                * 
+                *
                 * @param       {string}        buttonName              unique identifier
                 * @param       {Element}       button                  button element, must not be wrapped in a <li>
                 * @param       {string=}       insertBeforeButton      insert button before element identified by provided button name
                 */
-               add: function(buttonName, button, insertBeforeButton) {
-                       if (_didInit === false) this.setup();
+               add: function (buttonName, button, insertBeforeButton) {
+                       this.setup();
+                       
+                       // The wrapper is required for backwards compatibility, because some implementations rely on a
+                       // dedicated parent element to insert elements, for example, for drop-down menus.
+                       var wrapper = elCreate('div');
+                       wrapper.className = 'pageActionButton';
+                       wrapper.name = buttonName;
+                       elAttr(wrapper, 'aria-hidden', 'true');
                        
-                       var listItem = elCreate('li');
                        button.classList.add('button');
                        button.classList.add('buttonPrimary');
-                       listItem.appendChild(button);
-                       elAttr(listItem, 'aria-hidden', (buttonName === 'toTop' ? 'true' : 'false'));
-                       elData(listItem, 'name', buttonName);
-                       
-                       // force 'to top' button to be always at the most outer position
-                       if (buttonName === 'toTop') {
-                               listItem.className = 'toTop initiallyHidden';
-                               _container.appendChild(listItem);
-                       }
-                       else {
-                               var insertBefore = null;
-                               if (insertBeforeButton) {
-                                       insertBefore = _buttons.get(insertBeforeButton);
-                                       if (insertBefore !== undefined) {
-                                               insertBefore = insertBefore.parentNode;
-                                       }
-                               }
-                               
-                               if (insertBefore === null && _container.childElementCount) {
-                                       insertBefore = _container.children[0];
-                               }
-                               
-                               if (insertBefore === null) {
-                                       DomUtil.prepend(listItem, _container);
-                               }
-                               else {
-                                       _container.insertBefore(listItem, insertBefore);
+                       wrapper.appendChild(button);
+                       
+                       var insertBefore = null;
+                       if (insertBeforeButton) {
+                               insertBefore = _buttons.get(insertBeforeButton);
+                               if (insertBefore !== undefined) {
+                                       insertBefore = insertBefore.parentNode;
                                }
                        }
                        
+                       if (insertBefore === null && _container.childElementCount) {
+                               insertBefore = _container.children[0];
+                       }
+                       if (insertBefore === null) {
+                               insertBefore = _container.firstChild;
+                       }
+                       
+                       _container.insertBefore(wrapper, insertBefore);
+                       _wrapper.classList.remove('scrolledDown');
+                       
                        _buttons.set(buttonName, button);
+                       
+                       // Query a layout related property to force a reflow, otherwise the transition is optimized away.
+                       // noinspection BadExpressionStatementJS
+                       wrapper.offsetParent;
+                       
+                       // Toggle the visibility to force the transition to be applied.
+                       elAttr(wrapper, 'aria-hidden', 'false');
+                       
                        this._renderContainer();
                },
                
                /**
                 * Returns true if there is a registered button with the provided name.
-                * 
+                *
                 * @param       {string}        buttonName      unique identifier
                 * @return      {boolean}       true if there is a registered button with this name
                 */
@@ -89,32 +222,38 @@ define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
                
                /**
                 * Returns the stored button by name or undefined.
-                * 
+                *
                 * @param       {string}        buttonName      unique identifier
                 * @return      {Element}       button element or undefined
                 */
-               get: function(buttonName) {
+               get: function (buttonName) {
                        return _buttons.get(buttonName);
                },
                
                /**
                 * Removes a button by its button name.
-                * 
+                *
                 * @param       {string}        buttonName      unique identifier
                 */
-               remove: function(buttonName) {
+               remove: function (buttonName) {
                        var button = _buttons.get(buttonName);
                        if (button !== undefined) {
                                var listItem = button.parentNode;
-                               listItem.addEventListener('animationend', function () {
+                               var callback = function () {
                                        try {
-                                               _container.removeChild(listItem);
-                                               _buttons.delete(buttonName);
+                                               if (elAttrBool(listItem, 'aria-hidden')) {
+                                                       _container.removeChild(listItem);
+                                                       _buttons.delete(buttonName);
+                                               }
+                                               
+                                               listItem.removeEventListener('transitionend', callback);
                                        }
                                        catch (e) {
                                                // ignore errors if the element has already been removed
                                        }
-                               });
+                               };
+                               
+                               listItem.addEventListener('transitionend', callback);
                                
                                this.hide(buttonName);
                        }
@@ -122,10 +261,10 @@ define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
                
                /**
                 * Hides a button by its button name.
-                * 
+                *
                 * @param       {string}        buttonName      unique identifier
                 */
-               hide: function(buttonName) {
+               hide: function (buttonName) {
                        var button = _buttons.get(buttonName);
                        if (button) {
                                elAttr(button.parentNode, 'aria-hidden', 'true');
@@ -135,10 +274,10 @@ define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
                
                /**
                 * Shows a button by its button name.
-                * 
+                *
                 * @param       {string}        buttonName      unique identifier
                 */
-               show: function(buttonName) {
+               show: function (buttonName) {
                        var button = _buttons.get(buttonName);
                        if (button) {
                                if (button.parentNode.classList.contains('initiallyHidden')) {
@@ -146,16 +285,17 @@ define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
                                }
                                
                                elAttr(button.parentNode, 'aria-hidden', 'false');
+                               _wrapper.classList.remove('scrolledDown');
                                this._renderContainer();
                        }
                },
                
                /**
                 * Toggles the container's visibility.
-                * 
+                *
                 * @protected
                 */
-               _renderContainer: function() {
+               _renderContainer: function () {
                        var hasVisibleItems = false;
                        if (_container.childElementCount) {
                                for (var i = 0, length = _container.childElementCount; i < length; i++) {
@@ -167,6 +307,13 @@ define(['Dictionary', 'Dom/Util'], function(Dictionary, DomUtil) {
                        }
                        
                        _container.classList[(hasVisibleItems ? 'add' : 'remove')]('active');
+
+                       if (hasVisibleItems) {
+                               _wrapper.classList.add("pageActionHasContextButtons");
+                       }
+                       else {
+                               _wrapper.classList.remove("pageActionHasContextButtons");
+                       }
                }
        };
 });
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/JumpToTop.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/JumpToTop.js
deleted file mode 100644 (file)
index 27e6d9d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Provides a link to scroll to top once the page is scrolled by at least 50% the height of the window.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Ui/Page/JumpToTop
- */
-define(['Environment', 'Language', './Action'], function(Environment, Language, PageAction) {
-       "use strict";
-       
-       /**
-        * @constructor
-        */
-       function JumpToTop() { this.init(); }
-       JumpToTop.prototype = {
-               /**
-                * Initializes the top link for desktop browsers only.
-                */
-               init: function() {
-                       // top link is not available on smartphones and tablets (they have a built-in function to accomplish this)
-                       if (Environment.platform() !== 'desktop') {
-                               return;
-                       }
-                       
-                       this._callbackScrollEnd = this._afterScroll.bind(this);
-                       this._timeoutScroll = null;
-                       
-                       var button = elCreate('a');
-                       button.className = 'jsTooltip';
-                       button.href = '#';
-                       elAttr(button, 'title', Language.get('wcf.global.scrollUp'));
-                       elAttr(button, 'aria-hidden', 'true');
-                       button.innerHTML = '<span class="icon icon32 fa-angle-up"></span>';
-                       
-                       button.addEventListener(WCF_CLICK_EVENT, this._jump.bind(this));
-                       
-                       PageAction.add('toTop', button);
-                       
-                       window.addEventListener('scroll', this._scroll.bind(this));
-                       
-                       // invoke callback on page load
-                       this._afterScroll();
-               },
-               
-               /**
-                * Handles clicks on the top link.
-                * 
-                * @param       {Event}         event   event object
-                * @protected
-                */
-               _jump: function(event) {
-                       event.preventDefault();
-                       
-                       elById('top').scrollIntoView({ behavior: 'smooth' });
-               },
-               
-               /**
-                * Callback executed whenever the window is being scrolled.
-                * 
-                * @protected
-                */
-               _scroll: function() {
-                       if (this._timeoutScroll !== null) {
-                               window.clearTimeout(this._timeoutScroll);
-                       }
-                       
-                       this._timeoutScroll = window.setTimeout(this._callbackScrollEnd, 100);
-               },
-               
-               /**
-                * Delayed callback executed once the page has not been scrolled for a certain amount of time.
-                * 
-                * @protected
-                */
-               _afterScroll: function() {
-                       this._timeoutScroll = null;
-                       
-                       PageAction[(window.pageYOffset >= 300) ? 'show' : 'hide']('toTop');
-               }
-       };
-       
-       return JumpToTop;
-});
index e07e7d37ad3eccb3645fd5dd2633064ee307c517..9418ee8c963c5bb9bb2f5cba63b000b28fe29e31 100644 (file)
@@ -550,8 +550,9 @@ define(['Core', 'Environment', 'EventHandler', 'Language', 'ObjectMap', 'Dom/Tra
                
                _updateButtonState: function() {
                        var hasNewContent = false;
+                       var itemList = elBySel('.menuOverlayItemList', this._menu);
                        elBySelAll('.badgeUpdate', this._menu, function (badge) {
-                               if (~~badge.textContent > 0) {
+                               if (~~badge.textContent > 0 && badge.closest('.menuOverlayItemList') === itemList) {
                                        hasNewContent = true;
                                }
                        });
index 7e0a60363cc42369cb1992b50444fd4add17f66b..c4a978f4ea20af227ff01fe73d9f830a749d9f1e 100644 (file)
@@ -9,18 +9,27 @@
  */
 define(
        [
-               'Ajax',      'Core',                            'Dictionary',           'Language',
-               'ObjectMap', 'StringUtil',                      'Dom/ChangeListener',   'Dom/Util',
-               'Ui/Dialog', 'WoltLabSuite/Core/Ui/User/List',  'User',                 'WoltLabSuite/Core/Ui/Reaction/CountButtons',
-               'Ui/Alignment', 'Ui/CloseOverlay'
+               'Ajax',
+               'Core',
+               'Dictionary',           
+               'Dom/ChangeListener',
+               'Dom/Util',
+               'Ui/Alignment',
+               'Ui/CloseOverlay',
+               'Ui/Screen',
+               'WoltLabSuite/Core/Ui/Reaction/CountButtons',
        ],
        function(
-               Ajax,        Core,              Dictionary,             Language,
-               ObjectMap,   StringUtil,        DomChangeListener,      DomUtil,
-               UiDialog,    UiUserList,        User,                   CountButtons,
-               UiAlignment, UiCloseOverlay
-       )
-       {
+               Ajax,
+               Core,
+               Dictionary,             
+               DomChangeListener,
+               DomUtil,
+               UiAlignment,
+               UiCloseOverlay,
+               UiScreen,
+               CountButtons
+       ) {
                "use strict";
                
                /**
@@ -47,6 +56,7 @@ define(
                                this._popoverCurrentObjectId = 0;
                                
                                this._popover = null;
+                               this._popoverContent = null;
                                
                                this._options = Core.extend({
                                        // selectors
@@ -119,7 +129,7 @@ define(
                                        elementData.reactButton = elBySel(this._options.buttonSelector, element);
                                }
                                
-                               if (elementData.reactButton === null || elementData.reactButton.length === 0) {
+                               if (elementData.reactButton === null || elementData.reactButton.length === 0) {
                                        // The element may have no react button. 
                                        return;
                                }
@@ -168,6 +178,7 @@ define(
                                        element.classList.remove('active');
                                });
                                
+                               var scrollableContainer = elBySel('.reactionPopoverContent', this._getPopover());
                                if (reactionTypeID) {
                                        var reactionTypeButton = elBySel('.reactionTypeButton[data-reaction-type-id="' + reactionTypeID + '"]', this._getPopover());
                                        reactionTypeButton.classList.add('active');
@@ -175,6 +186,35 @@ define(
                                        if (~~elData(reactionTypeButton, 'is-assignable') === 0) {
                                                elShow(reactionTypeButton);
                                        }
+                                       
+                                       this._scrollReactionIntoView(scrollableContainer, reactionTypeButton);
+                               }
+                               else {
+                                       // The "first" reaction is positioned as close as possible to the toggle button,
+                                       // which means that we need to scroll the list to the bottom if the popover is
+                                       // displayed above the toggle button.
+                                       if (UiScreen.is('screen-xs')) {
+                                               if (this._getPopover().classList.contains('inverseOrder')) {
+                                                       scrollableContainer.scrollTop = 0;
+                                               }
+                                               else {
+                                                       scrollableContainer.scrollTop = scrollableContainer.scrollHeight - scrollableContainer.clientHeight;
+                                               }
+                                       }
+                               }
+                       },
+                       
+                       _scrollReactionIntoView: function (scrollableContainer, reactionTypeButton) {
+                               // Do not scroll if the button is located in the upper 75%.
+                               if (reactionTypeButton.offsetTop < scrollableContainer.clientHeight * 0.75) {
+                                       scrollableContainer.scrollTop = 0;
+                               }
+                               else {
+                                       // `Element.scrollTop` permits arbitrary values and will always clamp them to
+                                       // the maximum possible offset value. We can abuse this behavior by calculating
+                                       // the values to place the selected reaction in the center of the popover,
+                                       // regardless of the offset being out of range.
+                                       scrollableContainer.scrollTop = reactionTypeButton.offsetTop + reactionTypeButton.clientHeight / 2 - scrollableContainer.clientHeight / 2;
                                }
                        },
                        
@@ -221,20 +261,32 @@ define(
                                }
                                
                                this._popoverCurrentObjectId = objectId;
-                               this._markReactionAsActive();
                                
                                UiAlignment.set(this._getPopover(), element, {
                                        pointer: true,
-                                       horizontal: (this._options.isButtonGroupNavigation) ? 'left' :'center',
-                                       vertical: 'top'
+                                       horizontal: (this._options.isButtonGroupNavigation) ? 'left' : 'center',
+                                       vertical: UiScreen.is('screen-xs') ? 'bottom' : 'top'
                                });
                                
                                if (this._options.isButtonGroupNavigation) {
                                        element.closest('nav').style.setProperty('opacity', '1', '');
                                }
                                
-                               this._getPopover().classList.remove('forceHide');
-                               this._getPopover().classList.add('active');
+                               var popover = this._getPopover();
+                               
+                               // The popover could be rendered below the input field on mobile, in which case
+                               // the "first" button is displayed at the bottom and thus farthest away. Reversing
+                               // the display order will restore the logic by placing the "first" button as close
+                               // to the react button as possible.
+                               var inverseOrder = popover.style.getPropertyValue('bottom') === 'auto';
+                               popover.classList[inverseOrder ? 'add' : 'remove']('inverseOrder');
+                               
+                               this._markReactionAsActive();
+                               
+                               this._rebuildOverflowIndicator();
+                               
+                               popover.classList.remove('forceHide');
+                               popover.classList.add('active');
                        },
                        
                        /**
@@ -247,10 +299,11 @@ define(
                                        this._popover = elCreate('div');
                                        this._popover.className = 'reactionPopover forceHide';
                                        
-                                       var _popoverContent = elCreate('div');
-                                       _popoverContent.className = 'reactionPopoverContent';
+                                       this._popoverContent = elCreate('div');
+                                       this._popoverContent.className = 'reactionPopoverContent';
                                        
                                        var popoverContentHTML = elCreate('ul');
+                                       popoverContentHTML.className = 'reactionTypeButtonList';
                                        
                                        var sortedReactionTypes = this._getSortedReactionTypes();
                                        
@@ -285,8 +338,10 @@ define(
                                                popoverContentHTML.appendChild(reactionTypeItem);
                                        }
                                        
-                                       _popoverContent.appendChild(popoverContentHTML);
-                                       this._popover.appendChild(_popoverContent);
+                                       this._popoverContent.appendChild(popoverContentHTML);
+                                       this._popoverContent.addEventListener('scroll', this._rebuildOverflowIndicator.bind(this), {passive: true});
+                                       
+                                       this._popover.appendChild(this._popoverContent);
                                        
                                        var pointer = elCreate('span');
                                        pointer.className = 'elementPointer';
@@ -301,6 +356,14 @@ define(
                                return this._popover;
                        },
                        
+                       _rebuildOverflowIndicator: function () {
+                               var hasTopOverflow = this._popoverContent.scrollTop > 0;
+                               this._popoverContent.classList[hasTopOverflow ? 'add' : 'remove']('overflowTop');
+                               
+                               var hasBottomOverflow = this._popoverContent.scrollTop + this._popoverContent.clientHeight < this._popoverContent.scrollHeight;
+                               this._popoverContent.classList[hasBottomOverflow ? 'add' : 'remove']('overflowBottom');
+                       },
+                       
                        /**
                         * Sort the reaction types by the showOrder field.
                         * 
index 0abfac00d1df1c18fd5f3f08bf358b5cd4b9d046..245824f03da7ecbef032138ccd5658851a3817b6 100644 (file)
@@ -44,6 +44,7 @@ define(['Ajax', 'Core', 'EventKey', 'Dom/Util', 'Ui/SimpleDropdown'], function(A
                                        className: '',
                                        interfaceName: 'wcf\\data\\ISearchAction'
                                },
+                               autoFocus: true,
                                callbackDropdownInit: null,
                                callbackSelect: null,
                                delay: 500,
@@ -109,7 +110,7 @@ define(['Ajax', 'Core', 'EventKey', 'Dom/Util', 'Ui/SimpleDropdown'], function(A
                 */
                _keyup: function(event) {
                        // handle dropdown keyboard navigation
-                       if (this._activeItem !== null) {
+                       if (this._activeItem !== null || !this._options.autoFocus) {
                                if (UiSimpleDropdown.isOpen(this._dropdownContainerId)) {
                                        if (EventKey.ArrowUp(event)) {
                                                event.preventDefault();
@@ -210,15 +211,17 @@ define(['Ajax', 'Core', 'EventKey', 'Dom/Util', 'Ui/SimpleDropdown'], function(A
                 * @protected
                 */
                _keyboardNextItem: function() {
-                       this._activeItem.classList.remove('active');
+                       var nextItem;
                        
-                       if (this._activeItem.nextElementSibling) {
-                               this._activeItem = this._activeItem.nextElementSibling;
-                       }
-                       else {
-                               this._activeItem = this._list.children[0];
+                       if (this._activeItem !== null) {
+                               this._activeItem.classList.remove('active');
+                               
+                               if (this._activeItem.nextElementSibling) {
+                                       nextItem = this._activeItem.nextElementSibling;
+                               }
                        }
                        
+                       this._activeItem = nextItem || this._list.children[0];
                        this._activeItem.classList.add('active');
                },
                
@@ -228,15 +231,17 @@ define(['Ajax', 'Core', 'EventKey', 'Dom/Util', 'Ui/SimpleDropdown'], function(A
                 * @protected
                 */
                _keyboardPreviousItem: function() {
-                       this._activeItem.classList.remove('active');
+                       var nextItem;
                        
-                       if (this._activeItem.previousElementSibling) {
-                               this._activeItem = this._activeItem.previousElementSibling;
-                       }
-                       else {
-                               this._activeItem = this._list.children[this._list.childElementCount - 1];
+                       if (this._activeItem !== null) {
+                               this._activeItem.classList.remove('active');
+                               
+                               if (this._activeItem.previousElementSibling) {
+                                       nextItem = this._activeItem.previousElementSibling;
+                               }
                        }
                        
+                       this._activeItem = nextItem || this._list.children[this._list.childElementCount - 1];
                        this._activeItem.classList.add('active');
                },
                
@@ -330,7 +335,7 @@ define(['Ajax', 'Core', 'EventKey', 'Dom/Util', 'Ui/SimpleDropdown'], function(A
                                        UiSimpleDropdown.open(this._dropdownContainerId, true);
                                        
                                        // mark first item as active
-                                       if (this._list.childElementCount && ~~elData(this._list.children[0], 'object-id')) {
+                                       if (this._options.autoFocus && this._list.childElementCount && ~~elData(this._list.children[0], 'object-id')) {
                                                this._activeItem = this._list.children[0];
                                                this._activeItem.classList.add('active');
                                        }
index 7617509f0898244799fd1f9405f1b139804156f9..3822bec94267e4adcd143f9e91f3d8e5595c1e9c 100644 (file)
@@ -9,6 +9,7 @@ define(['Core', 'Dom/Traverse', 'Dom/Util', 'Ui/Screen', 'Ui/SimpleDropdown', '.
                                ajax: {
                                        className: 'wcf\\data\\search\\keyword\\SearchKeywordAction'
                                },
+                               autoFocus: false,
                                callbackDropdownInit: function(dropdownMenu) {
                                        dropdownMenu.classList.add('dropdownMenuPageSearch');
                                        
index 3cdb58fed4315c86d7b688068a9d5026f9d53cfb..24adf15d0b1b9c0691b9260602336f51db5f053b 100644 (file)
@@ -97,6 +97,7 @@ define(['Environment', 'Dom/ChangeListener', 'Ui/Alignment'], function(Environme
                        
                        if (title !== '') {
                                elData(element, 'tooltip', title);
+                               elAttr(element, 'aria-label', title);
                                element.removeAttribute('title');
                        }
                        
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/PasswordStrength.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/User/PasswordStrength.js
new file mode 100644 (file)
index 0000000..00a4087
--- /dev/null
@@ -0,0 +1,145 @@
+/**
+ * Adds a password strength meter to a password input and exposes
+ * zxcbn's verdict as sibling input.
+ *
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/Ui/User/PasswordStrength
+ */
+define(['Core', 'Language'], function (Core, Language) {
+       'use strict';
+       
+       var STATIC_DICTIONARY = [];
+       if (elBySel('meta[property="og:site_name"]')) {
+               STATIC_DICTIONARY.push(elBySel('meta[property="og:site_name"]').getAttribute('content'));
+       }
+       
+       function flatMap(array, callback) {
+               return array.map(callback).reduce(function (carry, item) {
+                       return carry.concat(item);
+               }, []);
+       }
+       
+       function splitIntoWords(value) {
+               return [].concat(value, value.split(/\W+/));
+       }
+       
+       function initializeFeedbacker(Feedback) {
+               var phrases = Core.extend({}, Feedback.default_phrases);
+               for (var type in phrases) {
+                       if (phrases.hasOwnProperty(type)) {
+                               for (var phrase in phrases[type]) {
+                                       if (phrases[type].hasOwnProperty(phrase)) {
+                                               var languageItem = 'wcf.user.password.zxcvbn.' + type + '.' + phrase;
+                                               var value = Language.get(languageItem);
+                                               if (value !== languageItem) {
+                                                       phrases[type][phrase] = value;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return new Feedback(phrases);
+       }
+       
+       /**
+        * @constructor
+        */
+       function PasswordStrength(input, options) {
+               require(['zxcvbn']).then(function (modules) {
+                       var zxcvbn = modules[0];
+                       this.init(zxcvbn, input, options);
+               }.bind(this));
+       }
+       
+       PasswordStrength.prototype = {
+               /**
+                * @param       {*}             zxcvbn
+                * @param       {Element}       input
+                * @param       {object}        options
+                */
+               init: function (zxcvbn, input, options) {
+                       this._zxcvbn = zxcvbn;
+                       this._input = input;
+                       
+                       this._options = Core.extend({
+                               relatedInputs: [],
+                               staticDictionary: []
+                       }, options);
+                       
+                       if (!this._options.feedbacker) {
+                               this._options.feedbacker = initializeFeedbacker(zxcvbn.Feedback);
+                       }
+                       
+                       this._wrapper = elCreate('div');
+                       this._wrapper.className = 'inputAddon inputAddonPasswordStrength';
+                       this._input.parentNode.insertBefore(this._wrapper, this._input);
+                       this._wrapper.appendChild(this._input);
+                       
+                       var rating = elCreate('div');
+                       rating.className = 'passwordStrengthRating';
+                       
+                       var ratingLabel = elCreate('small');
+                       ratingLabel.textContent = Language.get('wcf.user.password.strength');
+                       rating.appendChild(ratingLabel);
+                       
+                       this._score = elCreate('span');
+                       this._score.className = 'passwordStrengthScore';
+                       elData(this._score, 'score', '-1');
+                       rating.appendChild(this._score);
+                       
+                       this._wrapper.appendChild(rating);
+                       
+                       this._feedback = elCreate('div');
+                       this._feedback.className = 'passwordStrengthFeedback';
+                       this._wrapper.appendChild(this._feedback);
+                       
+                       this._verdictResult = elCreate('input');
+                       this._verdictResult.type = 'hidden';
+                       this._verdictResult.name = this._input.name + '_passwordStrengthVerdict';
+                       this._wrapper.parentNode.insertBefore(this._verdictResult, this._wrapper);
+                       
+                       var callback = this._evaluate.bind(this);
+                       this._input.addEventListener('input', callback);
+                       this._options.relatedInputs.forEach(function (input) {
+                               input.addEventListener('input', callback);
+                       });
+                       
+                       if (this._input.value.trim() !== '') {
+                               this._evaluate();
+                       }
+               },
+               
+               /**
+                * @param {Event=} event
+                */
+               _evaluate: function (event) {
+                       var dictionary = flatMap(STATIC_DICTIONARY.concat(this._options.staticDictionary,
+                               this._options.relatedInputs.map(function (input) {
+                                       return input.value.trim();
+                               })
+                       ), splitIntoWords).filter(function (value) {
+                               return value.length > 0;
+                       });
+                       
+                       var value = this._input.value.trim();
+                       
+                       // To bound runtime latency for really long passwords, consider sending zxcvbn() only
+                       // the first 100 characters or so of user input.
+                       var verdict = this._zxcvbn(value.substr(0, 100), dictionary);
+                       verdict.feedback = this._options.feedbacker.from_result(verdict);
+                       
+                       elData(this._score, 'score', value.length === 0 ? '-1' : verdict.score);
+                       
+                       if (event !== undefined) {
+                               // Do not overwrite the value on page load.
+                               elInnerError(this._wrapper, verdict.feedback.warning);
+                       }
+                       
+                       this._verdictResult.value = JSON.stringify(verdict);
+               }
+       };
+       
+       return PasswordStrength;
+});
index 4b0254c85ada97e558748c04164fa5bd241ab05a..2c4b551650e130cdd6df349c5a2d53d5193d0fbf 100644 (file)
@@ -44,6 +44,8 @@ define(['AjaxRequest', 'Core', 'Dom/ChangeListener', 'Language', 'Dom/Util', 'Do
                        action: 'upload',
                        // is true if multiple files can be uploaded at once
                        multiple: false,
+                       // array of acceptable file types, null if any file type is acceptable
+                       acceptableFiles: null,
                        // name if the upload field
                        name: '__files[]',
                        // is true if every file from a multi-file selection is uploaded in its own request
@@ -89,6 +91,9 @@ define(['AjaxRequest', 'Core', 'Dom/ChangeListener', 'Language', 'Dom/Util', 'Do
                        if (this._options.multiple) {
                                elAttr(this._fileUpload, 'multiple', 'true');
                        }
+                       if (this._options.acceptableFiles !== null) {
+                               elAttr(this._fileUpload, 'accept', this._options.acceptableFiles.join(','));
+                       }
                        this._fileUpload.addEventListener('change', this._upload.bind(this));
                        
                        this._button = elCreate('p');
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Wrapper/FacebookSdk.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Wrapper/FacebookSdk.js
new file mode 100644 (file)
index 0000000..4c389b7
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * Handles loading and initialization of Facebook's JavaScript SDK.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLabSuite/Core/Wrapper/FacebookSdk
+ */
+define(['https://connect.facebook.net/en_US/sdk.js'], function(_dummy) {
+       "use strict";
+       
+       // see: https://developers.facebook.com/docs/javascript/reference/FB.init/v7.0
+       FB.init({
+               version: 'v7.0'
+       });
+       
+       return FB;
+});
index 1af435138ce5b42e900166ae9993388ff4d02e47..a779de0d1ba1ad9da2c3107d605ca54a0af04661 100644 (file)
@@ -6,6 +6,7 @@ requirejs.config({
                'perfect-scrollbar': '3rdParty/perfect-scrollbar',
                'Pica': '3rdParty/pica',
                prism: '3rdParty/prism',
+               zxcvbn: '3rdParty/zxcvbn',
        },
        shim: {
                enquire: { exports: 'enquire' },
index c3aa1615c1f88f37eff75ba143f08743f2bc7fd9..c4c7009a98baaaf0922178633a1fb3d5b7f9b42e 100644 (file)
                return obj.hasOwnProperty(property);
        };
        
+       /**
+        * Returns a function, that, as long as it continues to be invoked, will not
+        * be triggered. The function will be called after it stops being called for
+        * N milliseconds. If `immediate` is passed, trigger the function on the
+        * leading edge, instead of the trailing.
+        * 
+        * @param {function} func
+        * @param {number} wait
+        * @param {boolean} immediate
+        * @return function
+        * @see https://davidwalsh.name/javascript-debounce-function
+        */
+       window.debounce = function (func, wait, immediate) {
+               var timeout;
+               
+               return function() {
+                       var context = this;
+                       var args = arguments;
+                       
+                       clearTimeout(timeout);
+                       
+                       timeout = setTimeout(function() {
+                               timeout = null;
+                               
+                               if (!immediate) {
+                                       func.apply(context, args)
+                               }
+                       }, wait);
+                       
+                       if (immediate && !timeout) {
+                               func.apply(context, args)
+                       }
+               };
+       };
+       
        /* assigns a global constant defining the proper 'click' event depending on the browser,
           enforcing 'touchstart' on mobile devices for a better UX. We're using defineProperty()
           here because at the time of writing Safari does not support 'const'. Thanks Safari.
index a6262ef889bb63701efd5f40af1668c9b3164756..03326d3ecfb3d1a03a97f69d46c57d97ed6a70d9 100644 (file)
@@ -15,7 +15,7 @@ use wcf\system\WCF;
 use wcf\util\UserUtil;
 
 /**
- * Exports the stored data of an user in compliance with Art. 20 "Right to data portability" of the
+ * Exports the stored data of a user in compliance with Art. 20 "Right to data portability" of the
  * the General Data Protection Regulation (GDPR) of the European Union.
  *
  * The file formats XML, JSON and CSV are explicitly listed as being a structured
index 3883185b1c5961c1edd0dff5a55e21337517050f..2f38de8fc317a734eb94cbb8d6a434b65000d503 100644 (file)
@@ -2,6 +2,8 @@
 namespace wcf\acp\action;
 use wcf\data\search\SearchEditor;
 use wcf\action\AbstractAction;
+use wcf\data\user\User;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\NamedUserException;
 use wcf\system\menu\acp\ACPMenu;
 use wcf\system\request\LinkHandler;
@@ -126,6 +128,26 @@ class UserQuickSearchAction extends AbstractAction {
                                $this->matches = $statement->fetchAll(\PDO::FETCH_COLUMN);
                                break;
                        
+                       case 'pendingActivation':
+                               $conditionBuilder = new PreparedStatementConditionBuilder();
+                               $conditionBuilder->add('activationCode <> ?', [0]);
+                               if (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER) {
+                                       $conditionBuilder->add('emailConfirmed IS NULL');
+                               }
+                               
+                               $this->sortField = 'registrationDate';
+                               $this->sortOrder = 'DESC';
+                               $sql = "SELECT          user_table.userID
+                                       FROM            wcf".WCF_N."_user user_table
+                                       LEFT JOIN       wcf".WCF_N."_user_option_value option_value
+                                       ON              (option_value.userID = user_table.userID)
+                                       ". $conditionBuilder ."
+                                       ORDER BY        user_table.registrationDate DESC";
+                               $statement = WCF::getDB()->prepareStatement($sql, $this->maxResults);
+                               $statement->execute($conditionBuilder->getParameters());
+                               $this->matches = $statement->fetchAll(\PDO::FETCH_COLUMN);
+                               break;
+                               
                        case 'disabledAvatars':
                                $sql = "SELECT          user_table.userID
                                        FROM            wcf".WCF_N."_user user_table
index a4827be93e1ad365436a4a03f40a89a7eea86a38..6bf891e2427958fa20fe5762ea529cf88254c499 100644 (file)
@@ -8,6 +8,7 @@ use wcf\system\ad\AdHandler;
 use wcf\system\ad\location\IAdLocation;
 use wcf\system\condition\ConditionHandler;
 use wcf\system\exception\UserInputException;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -216,7 +217,10 @@ class AdAddForm extends AbstractForm {
                        $condition->getProcessor()->reset();
                }
                
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(AdEditForm::class, ['id' => $returnValues['returnValues']->adID]),
+               ]);
        }
        
        /**
index ac1f7dc9910ecdbbdc46f7d46375d8c48d31db31..6d3ef2b182478dd98ec564c73a02701b93d89281 100644 (file)
@@ -114,6 +114,18 @@ class ArticleAddForm extends AbstractForm {
         */
        public $title = [];
        
+       /**
+        * article meta titles
+        * @var string[]
+        */
+       public $metaTitle = [];
+       
+       /**
+        * article meta descriptions
+        * @var string[]
+        */
+       public $metaDescription = [];
+       
        /**
         * tags
         * @var string[][]
@@ -244,6 +256,8 @@ class ArticleAddForm extends AbstractForm {
                        $this->publicationDateObj = \DateTime::createFromFormat('Y-m-d\TH:i:sP', $this->publicationDate);
                }
                if (isset($_POST['title']) && is_array($_POST['title'])) $this->title = ArrayUtil::trim($_POST['title']);
+               if (isset($_POST['metaTitle']) && is_array($_POST['metaTitle'])) $this->metaTitle = ArrayUtil::trim($_POST['metaTitle']);
+               if (isset($_POST['metaDescription']) && is_array($_POST['metaDescription'])) $this->metaDescription = ArrayUtil::trim($_POST['metaDescription']);
                if (MODULE_TAGGING && isset($_POST['tags']) && is_array($_POST['tags'])) $this->tags = ArrayUtil::trim($_POST['tags']);
                if (isset($_POST['teaser']) && is_array($_POST['teaser'])) $this->teaser = ArrayUtil::trim($_POST['teaser']);
                if (isset($_POST['content']) && is_array($_POST['content'])) $this->content = ArrayUtil::trim($_POST['content']);
@@ -410,6 +424,8 @@ class ArticleAddForm extends AbstractForm {
                                        'htmlInputProcessor' => isset($this->htmlInputProcessors[$language->languageID]) ? $this->htmlInputProcessors[$language->languageID] : null,
                                        'imageID' => !empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null,
                                        'teaserImageID' => !empty($this->teaserImageID[$language->languageID]) ? $this->teaserImageID[$language->languageID] : null,
+                                       'metaTitle' => !empty($this->metaTitle[$language->languageID]) ? $this->metaTitle[$language->languageID] : '',
+                                       'metaDescription' => !empty($this->metaDescription[$language->languageID]) ? $this->metaDescription[$language->languageID] : '',
                                ];
                        }
                }
@@ -422,6 +438,8 @@ class ArticleAddForm extends AbstractForm {
                                'htmlInputProcessor' => isset($this->htmlInputProcessors[0]) ? $this->htmlInputProcessors[0] : null,
                                'imageID' => !empty($this->imageID[0]) ? $this->imageID[0] : null,
                                'teaserImageID' => !empty($this->teaserImageID[0]) ? $this->teaserImageID[0] : null,
+                               'metaTitle' => !empty($this->metaTitle[0]) ? $this->metaTitle[0] : '',
+                               'metaDescription' => !empty($this->metaDescription[0]) ? $this->metaDescription[0] : '',
                        ];
                }
                
@@ -454,7 +472,10 @@ class ArticleAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(ArticleEditForm::class, ['id' => $article->getObjectID()]),
+               ]);
                
                // reset variables
                $this->publicationDate = '';
@@ -478,6 +499,16 @@ class ArticleAddForm extends AbstractForm {
                if (empty($_POST)) {
                        $this->setDefaultValues();
                }
+               
+               // init tags
+               if (!$this->isMultilingual) {
+                       if (!isset($this->tags[0])) $this->tags[0] = [];
+               }
+               else {
+                       foreach ($this->availableLanguages as $language) {
+                               if (!isset($this->tags[$language->languageID])) $this->tags[$language->languageID] = [];
+                       }
+               }
        }
        
        /**
@@ -517,6 +548,8 @@ class ArticleAddForm extends AbstractForm {
                        'teaserImages' => $this->teaserImages,
                        'tags' => $this->tags,
                        'title' => $this->title,
+                       'metaTitle' => $this->metaTitle,
+                       'metaDescription' => $this->metaDescription,
                        'teaser' => $this->teaser,
                        'content' => $this->content,
                        'availableLanguages' => $this->availableLanguages,
index d08f2615f8d5dfaa41654d70ee0510772fc6a632..230f4dfc99a32561fb441eff684b9ec3a07e7fa4 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\acp\form;
 use wcf\system\exception\UserInputException;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -84,6 +85,10 @@ class ArticleCategoryAddForm extends AbstractCategoryAddForm {
                
                parent::save();
                
+               WCF::getTPL()->assign([
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(ArticleCategoryEditForm::class, ['id' => $this->objectAction->getReturnValues()['returnValues']->categoryID]),
+               ]);
+               
                $this->sortField = 'publicationDate';
                $this->sortOrder = 'DESC';
        }
index d7f1790f298d38100354c6b0501c39a5bbcec732..db5305cc61830fb88463f0e3ad3480625a5ba334 100644 (file)
@@ -89,7 +89,9 @@ class ArticleEditForm extends ArticleAddForm {
                                        'content' => !empty($this->content[$language->languageID]) ? $this->content[$language->languageID] : '',
                                        'htmlInputProcessor' => isset($this->htmlInputProcessors[$language->languageID]) ? $this->htmlInputProcessors[$language->languageID] : null,
                                        'imageID' => !empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null,
-                                       'teaserImageID' => !empty($this->teaserImageID[$language->languageID]) ? $this->teaserImageID[$language->languageID] : null
+                                       'teaserImageID' => !empty($this->teaserImageID[$language->languageID]) ? $this->teaserImageID[$language->languageID] : null,
+                                       'metaTitle' => !empty($this->metaTitle[$language->languageID]) ? $this->metaTitle[$language->languageID] : '',
+                                       'metaDescription' => !empty($this->metaDescription[$language->languageID]) ? $this->metaDescription[$language->languageID] : '',
                                ];
                        }
                }
@@ -101,7 +103,9 @@ class ArticleEditForm extends ArticleAddForm {
                                'content' => !empty($this->content[0]) ? $this->content[0] : '',
                                'htmlInputProcessor' => isset($this->htmlInputProcessors[0]) ? $this->htmlInputProcessors[0] : null,
                                'imageID' => !empty($this->imageID[0]) ? $this->imageID[0] : null,
-                               'teaserImageID' => !empty($this->teaserImageID[0]) ? $this->teaserImageID[0] : null
+                               'teaserImageID' => !empty($this->teaserImageID[0]) ? $this->teaserImageID[0] : null,
+                               'metaTitle' => !empty($this->metaTitle[0]) ? $this->metaTitle[0] : '',
+                               'metaDescription' => !empty($this->metaDescription[0]) ? $this->metaDescription[0] : '',
                        ];
                }
                
@@ -161,6 +165,8 @@ class ArticleEditForm extends ArticleAddForm {
                                $this->content[$languageID] = $content->content;
                                $this->imageID[$languageID] = $content->imageID;
                                $this->teaserImageID[$languageID] = $content->teaserImageID;
+                               $this->metaTitle[$languageID] = $content->metaTitle;
+                               $this->metaDescription[$languageID] = $content->metaDescription;
                                
                                // get tags
                                if (MODULE_TAGGING) {
index e9c8cd7fbe368e6efaca3c04ff49632356efed80..dcf057b03b609862068b82b682a9020b339f000c 100644 (file)
@@ -8,6 +8,7 @@ use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -269,7 +270,10 @@ class BBCodeAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(BBCodeEditForm::class, ['id' => $returnValues['returnValues']->bbcodeID]),
+               ]);
        }
        
        /**
index 323109321c421bd8ae2de791de6ea70cc3349699..f269d8dea1b018ddb38c9b1bb876a959dcebf22c 100644 (file)
@@ -6,6 +6,7 @@ use wcf\data\bbcode\media\provider\BBCodeMediaProviderEditor;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -133,7 +134,10 @@ class BBCodeMediaProviderAddForm extends AbstractForm {
                $this->title = $this->regex = $this->html = $this->className = '';
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(BBCodeMediaProviderEditForm::class, ['id' => $provider->providerID]),
+               ]);
        }
        
        /**
index 2c36e1f543733d7025d487eb96033814d017f100..800ecb2940315e8b8395dc5552112c5d0391daf8 100644 (file)
@@ -562,7 +562,10 @@ class BoxAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(BoxEditForm::class, ['id' => $box->getObjectID()]),
+               ]);
                
                // reset variables
                $this->cssClassName = $this->name = '';
index 3820b04e32e751c8ec3171c0379443d8ae111612..9dba861bd2c2a90e8eebe0214dfc0e301619f827 100644 (file)
@@ -6,6 +6,7 @@ use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -117,7 +118,10 @@ class CaptchaQuestionAddForm extends AbstractForm {
                $this->isDisabled = 0;
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(CaptchaQuestionEditForm::class, ['id' => $questionID]),
+               ]);
        }
        
        /**
index 4da4864fc6a448c48b52959f68e9aaae23b8df20..867254ca80862c0d6fb4c2ded10530599b047467 100644 (file)
@@ -3,6 +3,8 @@ namespace wcf\acp\form;
 use wcf\data\contact\option\ContactOption;
 use wcf\data\contact\option\ContactOptionAction;
 use wcf\data\contact\option\ContactOptionEditor;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
 
 /**
  * Shows the contact option add form.
@@ -61,4 +63,15 @@ class ContactOptionAddForm extends AbstractCustomOptionForm {
                $this->getI18nValue('optionTitle')->setLanguageItem('wcf.contact.option', 'wcf.contact', 'com.woltlab.wcf');
                $this->getI18nValue('optionDescription')->setLanguageItem('wcf.contact.optionDescription', 'wcf.contact', 'com.woltlab.wcf');
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               WCF::getTPL()->assign([
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(ContactOptionEditForm::class, ['id' => $this->objectAction->getReturnValues()['returnValues']->getObjectID()]),
+               ]);
+       }
 }
index b712f2f615eb3567148287bb2cd2296841203198..f4ee58c7d9685582c616c314a528b25266393998 100644 (file)
@@ -15,4 +15,11 @@ class ContactOptionEditForm extends ContactOptionAddForm {
         * @inheritDoc
         */
        public $action = 'edit';
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               AbstractCustomOptionForm::save();
+       }
 }
index bdd31f6a62975916363ffc037370ae7c99597c9f..97735ac81f74fa6909f806c161a7d6317af2f8c7 100644 (file)
@@ -7,6 +7,7 @@ use wcf\form\AbstractForm;
 use wcf\system\email\Mailbox;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 
 /**
@@ -155,7 +156,10 @@ class ContactRecipientAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(ContactRecipientEditForm::class, ['id' => $recipientID]),
+               ]);
                
                // reset values
                $this->email = $this->name = 0;
index c91fba1f39dbff55885a402c89cb074044db53d6..f1050903d0ccd009ea99bc7e918e98da57161781 100755 (executable)
@@ -7,6 +7,7 @@ use wcf\form\AbstractForm;
 use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\CronjobUtil;
 use wcf\util\StringUtil;
@@ -188,7 +189,10 @@ class CronjobAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(CronjobEditForm::class, ['id' => $cronjobID]),
+               ]);
        }
        
        /**
index 85b221cf42f3782a1a21a65973e4604809ab86ad..a0f6170252cc0efaab08310d720c79f067298558 100644 (file)
@@ -107,12 +107,6 @@ class DataImportForm extends AbstractForm {
         */
        public $fileSystemPath = '';
        
-       /**
-        * display a warning if InnoDB uses a slow configuration
-        * @var boolean
-        */
-       public $showInnoDBWarning = false;
-       
        /**
         * display notice for existing import mappings
         * @var boolean
@@ -280,14 +274,6 @@ class DataImportForm extends AbstractForm {
                                }
                        }
                }
-               
-               $sql = "SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute();
-               $row = $statement->fetchArray();
-               if ($row && $row['Value'] == 1) {
-                       $this->showInnoDBWarning = true;
-               }
        }
        
        /**
@@ -310,9 +296,8 @@ class DataImportForm extends AbstractForm {
                        'dbPrefix' => $this->dbPrefix,
                        'fileSystemPath' => $this->fileSystemPath,
                        'userMergeMode' => $this->userMergeMode,
-                       'showInnoDBWarning' => $this->showInnoDBWarning,
                        'showMappingNotice' => $this->showMappingNotice,
-                       'additionalData' => $this->additionalData
+                       'additionalData' => $this->additionalData,
                ]);
        }
 }
index 28b23f667e208b028e0d2153643a2642585559c4..fe23827af25a0bd44af32ebf53a560a04dbfe133 100644 (file)
@@ -41,6 +41,7 @@ class FirstTimeSetupForm extends AbstractOptionListForm {
                'mail_from_address',
                'mail_admin_address',
                'image_allow_external_source',
+               'message_enable_user_consent',
                'module_contact_form',
                'log_ip_address',
                'package_server_auth_code',
index 30edd88d495e786405c1d4a4da641701dae8cd80..4ca80af12b2f90f5348a25e9105d9be8ae7b3649 100644 (file)
@@ -8,6 +8,7 @@ use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -173,10 +174,10 @@ class LabelAddForm extends AbstractForm {
                        'showOrder' => $this->showOrder
                ])]);
                $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->getReturnValues();
+               $labelID = $returnValues['returnValues']->labelID;
                
                if (!I18nHandler::getInstance()->isPlainValue('label')) {
-                       $returnValues = $this->objectAction->getReturnValues();
-                       $labelID = $returnValues['returnValues']->labelID;
                        I18nHandler::getInstance()->save('label', 'wcf.acp.label.label'.$labelID, 'wcf.acp.label', 1);
                        
                        // update group name
@@ -200,7 +201,10 @@ class LabelAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(LabelEditForm::class, ['id' => $labelID]),
+               ]);
        }
        
        /**
index db8a8c68d6c2003e0b4bcf8abc6bc04237a376c1..b2be3a9419e97a6c2974097436f5832c2b4a7327 100644 (file)
@@ -9,6 +9,7 @@ use wcf\system\exception\UserInputException;
 use wcf\system\label\object\type\ILabelObjectTypeHandler;
 use wcf\system\label\object\type\LabelObjectTypeContainer;
 use wcf\system\language\I18nHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -197,7 +198,10 @@ class LabelGroupAddForm extends AbstractForm {
                $this->setObjectTypeRelations();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(LabelGroupEditForm::class, ['id' => $returnValues['returnValues']->groupID]),
+               ]);
                
                I18nHandler::getInstance()->reset();
        }
index 2a690913e385fb8066094ca0bc09a025562a2442..48963368915a370ce8f2b0fb3aa988f7d61a3adf 100644 (file)
@@ -5,6 +5,7 @@ use wcf\data\language\LanguageEditor;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\LanguageFactory;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -155,7 +156,10 @@ class LanguageAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(LanguageEditForm::class, ['id' => $this->language->languageID]),
+               ]);
                
                // reset values
                $this->countryCode = $this->languageCode = $this->languageName = '';
index 292d2753fe9eb4932896e5c846a9cb8e9825f1c4..eb039cbbf075beb8fb9c80df8814f6334f2d6eef 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\acp\form;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
 
 /**
  * Shows the media category add form.
@@ -20,4 +22,15 @@ class MediaCategoryAddForm extends AbstractCategoryAddForm {
         * @inheritDoc
         */
        public $objectTypeName = 'com.woltlab.wcf.media.category';
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               WCF::getTPL()->assign([
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(MediaCategoryEditForm::class, ['id' => $this->objectAction->getReturnValues()['returnValues']->categoryID]),
+               ]);
+       }
 }
index ff9080b2bf0e247903946f0771980f3cc4cd7a4a..f03c4bd9fd88b68bc4ff25505b264f4b3a9d8cdf 100644 (file)
@@ -10,6 +10,7 @@ use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\language\LanguageFactory;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
 use wcf\util\StringUtil;
@@ -210,7 +211,10 @@ class MenuAddForm extends AbstractForm {
                $this->pageIDs = $this->aclValues = [];
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(MenuEditForm::class, ['id' => $menuEditor->menuID]),
+               ]);
                
                I18nHandler::getInstance()->reset();
        }
index dec77ce5476ade815914956229f78c9c1471ace6..b7ec2df95fb74ef07f7b8ea88e390a9a15561323 100644 (file)
@@ -12,6 +12,7 @@ use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\page\handler\ILookupPageHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -269,7 +270,10 @@ class MenuItemAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(MenuItemEditForm::class, ['id' => $menuItem->itemID]),
+               ]);
                
                // reset variables
                $this->isInternalLink = true;
index f94907456ef0032c6ebe5447e6be24621808cc9c..e1deea4f1def63508947becd4fe215a7aef68426 100644 (file)
@@ -9,6 +9,7 @@ use wcf\system\condition\ConditionHandler;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -240,7 +241,10 @@ class NoticeAddForm extends AbstractForm {
                        $condition->getProcessor()->reset();
                }
                
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(NoticeEditForm::class, ['id' => $returnValues['returnValues']->noticeID]),
+               ]);
        }
        
        /**
index 576b0c7e83aaf225c4f7ff5c6b87f2fba0906dcf..c3ab55c86833ee6577083fbdcb6d62dfc39426ed 100755 (executable)
@@ -2,11 +2,14 @@
 namespace wcf\acp\form;
 use wcf\data\package\update\server\PackageUpdateServer;
 use wcf\data\package\update\server\PackageUpdateServerAction;
+use wcf\data\package\update\server\PackageUpdateServerList;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\system\WCFACP;
 use wcf\util\StringUtil;
+use wcf\util\Url;
 
 /**
  * Shows the server add form.
@@ -62,6 +65,15 @@ class PackageUpdateServerAddForm extends AbstractForm {
        public function validate() {
                parent::validate();
                
+               $this->validateServerURL();
+       }
+       
+       /**
+        * Validates the server URL.
+        * 
+        * @since       5.3
+        */
+       protected function validateServerURL() {
                if (empty($this->serverURL)) {
                        throw new UserInputException('serverURL');
                }
@@ -69,6 +81,33 @@ class PackageUpdateServerAddForm extends AbstractForm {
                if (!PackageUpdateServer::isValidServerURL($this->serverURL)) {
                        throw new UserInputException('serverURL', 'invalid');
                }
+               
+               if (StringUtil::endsWith(Url::parse($this->serverURL)['host'], '.woltlab.com', true)) {
+                       throw new UserInputException('serverURL', 'woltlab');
+               }
+               
+               if (($duplicate = $this->findDuplicateServer())) {
+                       throw new UserInputException('serverURL', [
+                               'duplicate' => $duplicate,
+                       ]);
+               }
+       }
+       
+       /**
+        * Returns the first package update server with a matching serverURL.
+        * 
+        * @since       5.3
+        */
+       protected function findDuplicateServer() {
+               $packageServerList = new PackageUpdateServerList();
+               $packageServerList->readObjects();
+               foreach ($packageServerList as $packageServer) {
+                       if ($packageServer->serverURL == $this->serverURL) {
+                               return $packageServer;
+                       }
+               }
+               
+               return null;
        }
        
        /**
@@ -83,14 +122,17 @@ class PackageUpdateServerAddForm extends AbstractForm {
                        'loginUsername' => $this->loginUsername,
                        'loginPassword' => $this->loginPassword
                ])]);
-               $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->executeAction();
                $this->saved();
                
                // reset values
                $this->serverURL = $this->loginUsername = $this->loginPassword = '';
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(PackageUpdateServerEditForm::class, ['id' => $returnValues['returnValues']->packageUpdateServerID]),
+               ]);
        }
        
        /**
index 53c5965dbcc288adc69a6923dd408d3c1f09d492..2af28a4159547b2be8c6cdddb743b59ae7d38fa2 100755 (executable)
@@ -45,18 +45,29 @@ class PackageUpdateServerEditForm extends PackageUpdateServerAddForm {
                }
        }
        
+       /**
+        * Does nothing.
+        * 
+        * @since       5.3
+        */
+       public function validateServerURL() {
+               // The server URL cannot be modified, thus we do not need to validate it.
+       }
+       
        /**
         * @inheritDoc
         */
        public function save() {
                AbstractForm::save();
                
+               $data = [];
+               if ($this->loginUsername != $this->updateServer->loginUsername || $this->loginPassword) {
+                       $data['loginUsername'] = $this->loginUsername;
+                       $data['loginPassword'] = $this->loginPassword;
+               }
+               
                // save server
-               $this->objectAction = new PackageUpdateServerAction([$this->packageUpdateServerID], 'update', ['data' => array_merge($this->additionalFields, [
-                       'serverURL' => $this->serverURL,
-                       'loginUsername' => $this->loginUsername,
-                       'loginPassword' => $this->loginPassword
-               ])]);
+               $this->objectAction = new PackageUpdateServerAction([$this->packageUpdateServerID], 'update', ['data' => array_merge($this->additionalFields, $data)]);
                $this->objectAction->executeAction();
                $this->saved();
                
@@ -70,10 +81,9 @@ class PackageUpdateServerEditForm extends PackageUpdateServerAddForm {
        public function readData() {
                parent::readData();
                
+               $this->serverURL = $this->updateServer->serverURL;
                if (empty($_POST)) {
-                       $this->serverURL = $this->updateServer->serverURL;
                        $this->loginUsername = $this->updateServer->loginUsername;
-                       $this->loginPassword = $this->updateServer->loginPassword;
                }
        }
        
index 1cdac321f9e00c5dec06acedbc703372140c0d99..285550278e94d3444281aeaf346acf57ff03d714 100644 (file)
@@ -636,7 +636,10 @@ class PageAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(PageEditForm::class, ['id' => $page->pageID]),
+               ]);
                
                // reset variables
                $this->parentPageID = $this->isDisabled = $this->isLandingPage = $this->availableDuringOfflineMode = $this->enableShareButtons = $this->addPageToMainMenu = 0;
index dfa94ac193e76c0bd8874176a7f1897fb71fddc3..7a48e72286aad3db1a4eaeaf17728f3f4f1154c1 100644 (file)
@@ -10,6 +10,7 @@ use wcf\system\exception\NamedUserException;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\payment\method\PaymentMethodHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
 
@@ -142,7 +143,7 @@ class PaidSubscriptionAddForm extends AbstractForm {
                I18nHandler::getInstance()->register('title');
                
                // get available user groups
-               $this->availableUserGroups = UserGroup::getAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS]);
+               $this->availableUserGroups = UserGroup::getSortedAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS]);
                
                if (!count(PaymentMethodHandler::getInstance()->getPaymentMethods())) {
                        throw new NamedUserException(WCF::getLanguage()->get('wcf.acp.paidSubscription.error.noPaymentMethods'));
@@ -283,7 +284,10 @@ class PaidSubscriptionAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(PaidSubscriptionEditForm::class, ['id' => $returnValues['returnValues']->subscriptionID]),
+               ]);
        }
        
        /**
index 9def60650096107587e449879ecf53983f1c5221..3ebe24818b223138827465953a09a85c98d88437 100644 (file)
@@ -44,6 +44,11 @@ class ReactionTypeAddForm extends AbstractFormBuilderForm {
         */
        public $neededModules = ['MODULE_LIKE'];
        
+       /**
+        * @inheritDoc
+        */
+       public $objectEditLinkController = ReactionTypeEditForm::class;
+               
        /**
         * @inheritDoc
         */
index 37b1af79338d2f568a8a28dd54e9a7fd356b5d7c..e51e7d70317684d5582ba4810a56216d9be9a20e 100755 (executable)
@@ -1,12 +1,13 @@
 <?php
 namespace wcf\acp\form;
 use wcf\data\object\type\ObjectType;
-use wcf\data\object\type\ObjectTypeAction;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\form\AbstractForm;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
+use wcf\system\registry\RegistryHandler;
 use wcf\system\WCF;
+use wcf\system\worker\SitemapRebuildWorker;
 
 /**
  * Shows the sitemap edit form.
@@ -105,10 +106,21 @@ class SitemapEditForm extends AbstractForm {
                parent::readData();
                
                if (empty($_POST)) {
-                       if ($this->objectType->priority !== null) $this->priority = $this->objectType->priority; 
-                       if ($this->objectType->changeFreq !== null) $this->changeFreq = $this->objectType->changeFreq; 
-                       if ($this->objectType->rebuildTime !== null) $this->rebuildTime = $this->objectType->rebuildTime; 
-                       if ($this->objectType->isDisabled !== null) $this->isDisabled = $this->objectType->isDisabled;
+                       $sitemapData = RegistryHandler::getInstance()->get('com.woltlab.wcf', SitemapRebuildWorker::REGISTRY_PREFIX . $this->objectTypeName);
+                       $sitemapData = @unserialize($sitemapData);
+                       
+                       if (is_array($sitemapData)) {
+                               $this->priority = $sitemapData['priority'];
+                               $this->changeFreq = $sitemapData['changeFreq'];
+                               $this->rebuildTime = $sitemapData['rebuildTime'];
+                               $this->isDisabled = $sitemapData['isDisabled'];
+                       }
+                       else {
+                               if ($this->objectType->priority !== null) $this->priority = $this->objectType->priority;
+                               if ($this->objectType->changeFreq !== null) $this->changeFreq = $this->objectType->changeFreq;
+                               if ($this->objectType->rebuildTime !== null) $this->rebuildTime = $this->objectType->rebuildTime;
+                               if ($this->objectType->isDisabled !== null) $this->isDisabled = $this->objectType->isDisabled;
+                       }
                }
        }
        
@@ -145,19 +157,12 @@ class SitemapEditForm extends AbstractForm {
        public function save() {
                parent::save();
                
-               $data = array_merge($this->objectType->additionalData, [
+               RegistryHandler::getInstance()->set('com.woltlab.wcf', SitemapRebuildWorker::REGISTRY_PREFIX . $this->objectTypeName, serialize([
                        'priority' => $this->priority,
                        'changeFreq' => $this->changeFreq,
                        'rebuildTime' => $this->rebuildTime,
-                       'isDisabled' => $this->isDisabled
-               ]);
-               
-               $this->objectAction = new ObjectTypeAction([$this->objectType], 'update', [
-                       'data' => [
-                               'additionalData' => serialize($data)
-                       ]
-               ]);
-               $this->objectAction->executeAction();
+                       'isDisabled' => $this->isDisabled,
+               ]));
                
                $this->saved();
                
index 16ad4615cbadce9774a9c292dc387e97ea2424c7..b277cd7d5dd4fd8621e1eae7d967bc78ee7ed474 100644 (file)
@@ -8,6 +8,7 @@ use wcf\form\AbstractForm;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
 use wcf\util\ImageUtil;
@@ -224,7 +225,10 @@ class SmileyAddForm extends AbstractForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(SmileyEditForm::class, ['id' => $smileyID]),
+               ]);
        }
        
        /**
index fe98b3b637b6a819c227c16a6da83ebc1544b54b..35f45571322efe224c60c2a412f40e3202d59eef 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\acp\form;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
 
 /**
  * Shows the smiley category add form.
@@ -29,4 +31,15 @@ class SmileyCategoryAddForm extends AbstractCategoryAddForm {
         * @inheritDoc
         */
        public $neededModules = ['MODULE_SMILEY'];
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               WCF::getTPL()->assign([
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(SmileyCategoryEditForm::class, ['id' => $this->objectAction->getReturnValues()['returnValues']->categoryID]),
+               ]);
+       }
 }
index 0f8e20924b3c8ac373159584ef509417cf82b060..65a81562a6a1480d79a346589b89cc4ddc2213e0 100644 (file)
@@ -5,14 +5,22 @@ use wcf\data\style\Style;
 use wcf\data\style\StyleAction;
 use wcf\data\style\StyleEditor;
 use wcf\data\template\group\TemplateGroup;
-use wcf\data\template\group\TemplateGroupList;
+use wcf\data\user\cover\photo\UserCoverPhoto;
 use wcf\form\AbstractForm;
 use wcf\system\event\EventHandler;
 use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
+use wcf\system\file\upload\UploadField;
+use wcf\system\file\upload\UploadHandler;
+use wcf\system\image\ImageHandler;
 use wcf\system\language\I18nHandler;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
+use wcf\system\style\StyleCompiler;
+use wcf\system\style\exception\FontDownloadFailed;
+use wcf\system\style\FontManager;
 use wcf\system\WCF;
+use wcf\util\ArrayUtil;
 use wcf\util\DateUtil;
 use wcf\util\FileUtil;
 use wcf\util\StringUtil;
@@ -105,12 +113,6 @@ class StyleAddForm extends AbstractForm {
         */
        public $globals = [];
        
-       /**
-        * image path
-        * @var string
-        */
-       public $imagePath = 'images/';
-       
        /**
         * tainted style
         * @var boolean
@@ -188,6 +190,11 @@ class StyleAddForm extends AbstractForm {
         */
        public $tmpHash = '';
        
+       /**
+        * @var string
+        */
+       public $styleTestFileDir;
+       
        /**
         * list of variables and their value
         * @var string[]
@@ -200,6 +207,36 @@ class StyleAddForm extends AbstractForm {
         */
        public $specialVariables = [];
        
+       /**
+        * current scroll offsets before submitting the form
+        * @var integer[]
+        */
+       public $scrollOffsets = [];
+       
+       /**
+        * @var (null|UploadField)[]
+        * @since 5.3
+        */
+       public $uploads = [];
+       
+       /**
+        * @var (null|UploadField)[]
+        * @since 5.3
+        */
+       public $removedUploads = [];
+       
+       /**
+        * @var UploadField[]
+        * @since 5.3
+        */
+       public $customAssets = [];
+       
+       public $supportedApiVersionsCompatibility = [
+               '3.0' => '3.0',
+               '3.1' => '3.1',
+               '5.2' => '5.2 / 5.3',
+       ];
+       
        /**
         * @inheritDoc
         */
@@ -209,15 +246,14 @@ class StyleAddForm extends AbstractForm {
                I18nHandler::getInstance()->register('styleDescription');
                
                $this->setVariables();
+               
+               $this->rebuildUploadFields();
+               
                if (empty($_POST)) {
                        $this->readStyleVariables();
                }
                
-               $templateGroupList = new TemplateGroupList();
-               $templateGroupList->sqlOrderBy = "templateGroupName";
-               $templateGroupList->getConditionBuilder()->add('templateGroupFolderName <> ?', ['_wcf_email/']);
-               $templateGroupList->readObjects();
-               $this->availableTemplateGroups = $templateGroupList->getObjects();
+               $this->availableTemplateGroups = TemplateGroup::getSelectList([-1], 1);
                
                if (isset($_REQUEST['tmpHash'])) {
                        $this->tmpHash = StringUtil::trim($_REQUEST['tmpHash']);
@@ -227,6 +263,79 @@ class StyleAddForm extends AbstractForm {
                }
        }
        
+       /**
+        * @since       5.3
+        */
+       protected function getUploadFields() {
+               return [
+                       'image' => [
+                               'size' => [
+                                       'maxWidth' => Style::PREVIEW_IMAGE_MAX_WIDTH,
+                                       'maxHeight' => Style::PREVIEW_IMAGE_MAX_WIDTH,
+                                       'preserveAspectRatio' => false,
+                               ],
+                       ],
+                       'image2x' => [
+                               'size' => [
+                                       'maxWidth' => 2 * Style::PREVIEW_IMAGE_MAX_WIDTH,
+                                       'maxHeight' => 2 * Style::PREVIEW_IMAGE_MAX_WIDTH,
+                                       'preserveAspectRatio' => false,
+                               ],
+                       ],
+                       'pageLogo' => [
+                               'allowSvgImage' => true,
+                       ],
+                       'pageLogoMobile' => [
+                               'allowSvgImage' => true,
+                       ],
+                       'coverPhoto' => [
+                               'size' => [
+                                       'minWidth' => UserCoverPhoto::MIN_WIDTH,
+                                       'minHeight' => UserCoverPhoto::MIN_HEIGHT,
+                               ]
+                       ],
+                       'favicon' => [
+                               'size' => [
+                                       'resize' => false,
+                                       'minWidth' => Style::FAVICON_IMAGE_WIDTH,
+                                       'maxWidth' => Style::FAVICON_IMAGE_WIDTH,
+                                       'minHeight' => Style::FAVICON_IMAGE_HEIGHT,
+                                       'maxHeight' => Style::FAVICON_IMAGE_HEIGHT,
+                               ]
+                       ],
+               ];
+       }
+       
+       /**
+        * @since       5.3
+        */
+       protected function rebuildUploadFields() {
+               $handler = UploadHandler::getInstance();
+               foreach ($this->getUploadFields() as $name => $options) {
+                       if ($handler->isRegisteredFieldId($name)) {
+                               $handler->unregisterUploadField($name);
+                       }
+                       $field = new UploadField($name);
+                       $field->setImageOnly(true);
+                       if (isset($options['allowSvgImage'])) {
+                               $field->setAllowSvgImage($options['allowSvgImage']);
+                       }
+                       $field->maxFiles = 1;
+                       $handler->registerUploadField($field);
+               }
+               
+               // This field is special cased, because it may contain arbitrary data.
+               $name = 'customAssets';
+               if ($handler->isRegisteredFieldId($name)) {
+                       $handler->unregisterUploadField($name);
+               }
+               $field = new UploadField($name);
+               $field->setImageOnly(true);
+               $field->setAllowSvgImage(true);
+               $field->maxFiles = null;
+               $handler->registerUploadField($field);
+       }
+       
        /**
         * @inheritDoc
         */
@@ -271,13 +380,11 @@ class StyleAddForm extends AbstractForm {
                        }
                }
                $this->variables['useFluidLayout'] = isset($_POST['useFluidLayout']) ? 1 : 0;
-               $this->variables['useGoogleFont'] = isset($_POST['useGoogleFont']) ? 1 : 0;
                
                // style data
                if (isset($_POST['authorName'])) $this->authorName = StringUtil::trim($_POST['authorName']);
                if (isset($_POST['authorURL'])) $this->authorURL = StringUtil::trim($_POST['authorURL']);
                if (isset($_POST['copyright'])) $this->copyright = StringUtil::trim($_POST['copyright']);
-               if (isset($_POST['imagePath'])) $this->imagePath = StringUtil::trim($_POST['imagePath']);
                if (isset($_POST['license'])) $this->license = StringUtil::trim($_POST['license']);
                if (isset($_POST['packageName'])) $this->packageName = StringUtil::trim($_POST['packageName']);
                if (isset($_POST['styleDate'])) $this->styleDate = StringUtil::trim($_POST['styleDate']);
@@ -286,6 +393,45 @@ class StyleAddForm extends AbstractForm {
                if (isset($_POST['styleVersion'])) $this->styleVersion = StringUtil::trim($_POST['styleVersion']);
                if (isset($_POST['templateGroupID'])) $this->templateGroupID = intval($_POST['templateGroupID']);
                if (isset($_POST['apiVersion']) && in_array($_POST['apiVersion'], Style::$supportedApiVersions)) $this->apiVersion = $_POST['apiVersion'];
+               
+               // codemirror scroll offset
+               if (isset($_POST['scrollOffsets']) && is_array($_POST['scrollOffsets'])) $this->scrollOffsets = ArrayUtil::toIntegerArray($_POST['scrollOffsets']); 
+               
+               $this->uploads = $this->removedUploads = [];
+               foreach (array_keys($this->getUploadFields()) as $field) {
+                       $removedFiles = UploadHandler::getInstance()->getRemovedFiledByFieldId($field);
+                       if (!empty($removedFiles)) {
+                               $this->removedUploads = array_merge($this->removedUploads, $removedFiles);
+                       }
+                       
+                       $files = UploadHandler::getInstance()->getFilesByFieldId($field);
+                       if (!empty($files)) {
+                               $this->uploads[$field] = $files[0];
+                       }
+               }
+               
+               $this->customAssets = [
+                       'removed' => UploadHandler::getInstance()->getRemovedFiledByFieldId('customAssets'),
+                       'added' => UploadHandler::getInstance()->getFilesByFieldId('customAssets'),
+               ];
+       }
+       
+       /**
+        * @since       5.3
+        */
+       protected function downloadGoogleFont() {
+               $fontManager = FontManager::getInstance();
+               $family = $this->variables['wcfFontFamilyGoogle'];
+               if ($family) {
+                       if (!$fontManager->isFamilyDownloaded($family)) {
+                               try {
+                                       $fontManager->downloadFamily($family);
+                               }
+                               catch (FontDownloadFailed $e) {
+                                       throw new UserInputException('wcfFontFamilyGoogle', 'downloadFailed'.($e->getReason() ? '.'.$e->getReason() : ''));
+                               }
+                       }
+               }
        }
        
        /**
@@ -339,19 +485,39 @@ class StyleAddForm extends AbstractForm {
                        }
                }
                
-               // ensure image path is below WCF_DIR/images/
-               if ($this->imagePath) {
-                       $relativePath = FileUtil::unifyDirSeparator(FileUtil::getRelativePath(WCF_DIR.'images/', WCF_DIR.$this->imagePath));
-                       if (strpos($relativePath, '../') !== false) {
-                               throw new UserInputException('imagePath', 'invalid');
-                       }
-               }
-               
                if (!empty($this->variables['overrideScss'])) {
                        $this->parseOverrides();
                }
                
+               $this->downloadGoogleFont();
+               
+               $this->validateIndividualScss();
+               
                $this->validateApiVersion();
+               
+               $this->validateUploads();
+       }
+       
+       /**
+        * Validates the individual scss.
+        * @throws      UserInputException
+        * @since       5.3
+        */
+       public function validateIndividualScss() {
+               $variables = array_merge(StyleCompiler::getDefaultVariables(), $this->variables);
+               
+               $this->styleTestFileDir = FileUtil::getTemporaryFilename('style_');
+               FileUtil::makePath($this->styleTestFileDir);
+               
+               $result = StyleCompiler::getInstance()->testStyle($this->styleTestFileDir, $this->styleName, $this->apiVersion, false, $variables);
+               
+               if ($result !== null) {
+                       rmdir($this->styleTestFileDir);
+                       
+                       throw new UserInputException('individualScss', [
+                               'message' => $result->getMessage(),
+                       ]);
+               }
        }
        
        /**
@@ -378,6 +544,73 @@ class StyleAddForm extends AbstractForm {
                }
        }
        
+       /**
+        * @since       5.3
+        */
+       protected function validateUploads() {
+               foreach ($this->getUploadFields() as $field => $options) {
+                       $files = UploadHandler::getInstance()->getFilesByFieldId($field);
+                       if (count($files) > 1) {
+                               throw new UserInputException($field, 'invalid');
+                       }
+                       if (empty($files)) continue;
+                       
+                       if (isset($options['size'])) {
+                               $fileLocation = $files[0]->getLocation();
+                               if (($imageData = getimagesize($fileLocation)) === false) {
+                                       throw new UserInputException($field, 'invalid');
+                               }
+                               switch ($imageData[2]) {
+                                       case IMAGETYPE_PNG:
+                                       case IMAGETYPE_JPEG:
+                                       case IMAGETYPE_GIF:
+                                               // fine
+                                       break;
+                                       default:
+                                               throw new UserInputException($field, 'invalid');
+                               }
+                               
+                               $maxWidth = $options['size']['maxWidth'] ?? PHP_INT_MAX;
+                               $maxHeight = $options['size']['maxHeight'] ?? PHP_INT_MAX;
+                               $minWidth = $options['size']['minWidth'] ?? 0;
+                               $minHeight = $options['size']['minHeight'] ?? 0;
+                               
+                               if ($options['size']['resize'] ?? true) {
+                                       if ($imageData[0] > $maxWidth || $imageData[1] > $maxHeight) {
+                                               $adapter = ImageHandler::getInstance()->getAdapter();
+                                               $adapter->loadFile($fileLocation);
+                                               $thumbnail = $adapter->createThumbnail(
+                                                       $maxWidth,
+                                                       $maxHeight,
+                                                       $options['size']['preserveAspectRatio'] ?? true
+                                               );
+                                               $adapter->writeImage($thumbnail, $fileLocation);
+                                               // Clear thumbnail as soon as possible to free up the memory.
+                                               $thumbnail = null;
+                                       }
+                                       
+                                       // Check again after scaling
+                                       if (($imageData = getimagesize($fileLocation)) === false) {
+                                               throw new UserInputException($field, 'invalid');
+                                       }
+                               }
+                               
+                               if ($imageData[0] > $maxWidth) {
+                                       throw new UserInputException($field, 'maxWidth');
+                               }
+                               if ($imageData[0] > $maxHeight) {
+                                       throw new UserInputException($field, 'maxHeight');
+                               }
+                               if ($imageData[0] < $minWidth) {
+                                       throw new UserInputException($field, 'minWidth');
+                               }
+                               if ($imageData[0] < $minHeight) {
+                                       throw new UserInputException($field, 'minHeight');
+                               }
+                       }
+               }
+       }
+       
        /**
         * Validates LESS-variable overrides.
         * 
@@ -542,12 +775,9 @@ class StyleAddForm extends AbstractForm {
                $this->specialVariables = [
                        'individualScss',
                        'overrideScss',
-                       'pageLogo',
                        'pageLogoWidth',
                        'pageLogoHeight',
-                       'pageLogoMobile',
                        'useFluidLayout',
-                       'useGoogleFont',
                        'wcfFontFamilyGoogle',
                        'wcfFontFamilyFallback'
                ];
@@ -585,15 +815,17 @@ class StyleAddForm extends AbstractForm {
                                'styleDescription' => '',
                                'styleVersion' => $this->styleVersion,
                                'styleDate' => $this->styleDate,
-                               'imagePath' => $this->imagePath,
                                'copyright' => $this->copyright,
                                'license' => $this->license,
                                'authorName' => $this->authorName,
                                'authorURL' => $this->authorURL,
                                'apiVersion' => $this->apiVersion
                        ]),
+                       'uploads' => $this->uploads,
+                       'removedUploads' => $this->removedUploads,
+                       'customAssets' => $this->customAssets,
                        'tmpHash' => $this->tmpHash,
-                       'variables' => $this->variables
+                       'variables' => $this->variables,
                ]);
                $returnValues = $this->objectAction->executeAction();
                $style = $returnValues['returnValues'];
@@ -606,6 +838,14 @@ class StyleAddForm extends AbstractForm {
                        'styleDescription' => 'wcf.style.styleDescription'.$style->styleID
                ]);
                
+               // Do not save the compiled style, because the image path was unknown during the style generation. 
+               if ($this->styleTestFileDir && file_exists($this->styleTestFileDir . '/style.css') && file_exists($this->styleTestFileDir . '/style-rtl.css')) {
+                       unlink($this->styleTestFileDir . '/style.css');
+                       unlink($this->styleTestFileDir . '/style-rtl.css');
+                       
+                       rmdir($this->styleTestFileDir);
+               }
+               
                // call saved event
                $this->saved();
                
@@ -613,16 +853,20 @@ class StyleAddForm extends AbstractForm {
                $this->authorName = $this->authorURL = $this->copyright = $this->packageName = '';
                $this->license = $this->styleDate = $this->styleDescription = $this->styleName = $this->styleVersion = '';
                $this->setDefaultValues();
-               $this->imagePath = 'images/';
                $this->isTainted = true;
                $this->templateGroupID = 0;
+               $this->styleTestFileDir = null;
+               $this->rebuildUploadFields();
                
                I18nHandler::getInstance()->reset();
                
                // reload variables
                $this->readStyleVariables();
                
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(StyleEditForm::class, ['id' => $style->styleID]),
+               ]);
        }
        
        /**
@@ -644,7 +888,6 @@ class StyleAddForm extends AbstractForm {
                        'colorCategories' => $this->colorCategories,
                        'colors' => $this->colors,
                        'copyright' => $this->copyright,
-                       'imagePath' => $this->imagePath,
                        'isTainted' => $this->isTainted,
                        'license' => $this->license,
                        'packageName' => $this->packageName,
@@ -657,7 +900,11 @@ class StyleAddForm extends AbstractForm {
                        'tmpHash' => $this->tmpHash,
                        'variables' => $this->variables,
                        'supportedApiVersions' => Style::$supportedApiVersions,
-                       'newVariables' => $this->newVariables
+                       'supportedApiVersionsCompatibility' => $this->supportedApiVersionsCompatibility,
+                       'newVariables' => $this->newVariables,
+                       'scrollOffsets' => $this->scrollOffsets,
+                       'coverPhotoMinHeight' => UserCoverPhoto::MIN_HEIGHT,
+                       'coverPhotoMinWidth' => UserCoverPhoto::MIN_WIDTH,
                ]);
        }
        
index ddbf303cbb905c0e4a339ea71aa8c3c95eaa51cb..8f0ffe20ee9efe68ed2e86d07b4d6016107d6ec1 100644 (file)
@@ -2,11 +2,15 @@
 namespace wcf\acp\form;
 use wcf\data\style\Style;
 use wcf\data\style\StyleAction;
-use wcf\data\user\cover\photo\UserCoverPhoto;
 use wcf\form\AbstractForm;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\UserInputException;
+use wcf\system\file\upload\UploadFile;
+use wcf\system\file\upload\UploadHandler;
 use wcf\system\language\I18nHandler;
+use wcf\system\style\StyleCompiler;
 use wcf\system\WCF;
+use wcf\util\FileUtil;
 
 /**
  * Shows the style edit form.
@@ -58,6 +62,35 @@ class StyleEditForm extends StyleAddForm {
                }
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function validateIndividualScss() {
+               $variables = $this->variables;
+               if (!$this->style->isTainted) {
+                       $variables['individualScss'] = Style::joinLessVariables($variables['individualScss'], $variables['individualScssCustom']);
+                       $variables['overrideScss'] = Style::joinLessVariables($variables['overrideScss'], $variables['overrideScssCustom']);
+                       
+                       unset($variables['individualScssCustom']);
+                       unset($variables['overrideScssCustom']);
+               }
+               
+               $variables = array_merge(StyleCompiler::getDefaultVariables(), $variables);
+               
+               $this->styleTestFileDir = FileUtil::getTemporaryFilename('style_');
+               FileUtil::makePath($this->styleTestFileDir);
+               
+               $result = StyleCompiler::getInstance()->testStyle($this->styleTestFileDir, $this->styleName, $this->apiVersion, $this->style->imagePath, $variables);
+               
+               if ($result !== null) {
+                       rmdir($this->styleTestFileDir);
+                       
+                       throw new UserInputException('individualScss', [
+                               'message' => $result->getMessage(),
+                       ]);
+               }
+       }
+       
        /**
         * @inheritDoc
         */
@@ -102,6 +135,19 @@ class StyleEditForm extends StyleAddForm {
                        $this->variables['overrideScss'] = $tmp['preset'];
                        $this->variables['overrideScssCustom'] = $tmp['custom'];
                }
+               
+               if ($this->variables['pageLogo'] && file_exists($this->style->getAssetPath().$this->variables['pageLogo'])) {
+                       $file = new UploadFile($this->style->getAssetPath().$this->variables['pageLogo'], basename($this->variables['pageLogo']), true, true, true);
+                       UploadHandler::getInstance()->registerFilesByField('pageLogo', [
+                               $file,
+                       ]);
+               }
+               if ($this->variables['pageLogoMobile'] && file_exists($this->style->getAssetPath().$this->variables['pageLogoMobile'])) {
+                       $file = new UploadFile($this->style->getAssetPath().$this->variables['pageLogoMobile'], basename($this->variables['pageLogoMobile']), true, true, true);
+                       UploadHandler::getInstance()->registerFilesByField('pageLogoMobile', [
+                               $file,
+                       ]);
+               }
        }
        
        /**
@@ -129,7 +175,6 @@ class StyleEditForm extends StyleAddForm {
                        $this->authorName = $this->style->authorName;
                        $this->authorURL = $this->style->authorURL;
                        $this->copyright = $this->style->copyright;
-                       $this->imagePath = $this->style->imagePath;
                        $this->isTainted = $this->style->isTainted;
                        $this->license = $this->style->license;
                        $this->packageName = $this->style->packageName;
@@ -138,6 +183,40 @@ class StyleEditForm extends StyleAddForm {
                        $this->styleName = $this->style->styleName;
                        $this->styleVersion = $this->style->styleVersion;
                        $this->templateGroupID = $this->style->templateGroupID;
+                       if ($this->style->image && file_exists(WCF_DIR.'images/'.$this->style->image)) {
+                               $file = new UploadFile(WCF_DIR.'images/'.$this->style->image, $this->style->image, true, true, false);
+                               UploadHandler::getInstance()->registerFilesByField('image', [
+                                       $file,
+                               ]);
+                       }
+                       if ($this->style->image2x && file_exists(WCF_DIR.'images/'.$this->style->image2x)) {
+                               $file = new UploadFile(WCF_DIR.'images/'.$this->style->image2x, $this->style->image2x, true, true, false);
+                               UploadHandler::getInstance()->registerFilesByField('image2x', [
+                                       $file,
+                               ]);
+                       }
+                       if ($this->style->coverPhotoExtension && file_exists($this->style->getCoverPhotoLocation())) {
+                               $file = new UploadFile($this->style->getCoverPhotoLocation(), $this->style->getCoverPhoto(), true, true, false);
+                               UploadHandler::getInstance()->registerFilesByField('coverPhoto', [
+                                       $file,
+                               ]);
+                       }
+                       if ($this->style->hasFavicon) {
+                               foreach (['png', 'jpg', 'gif'] as $extension) {
+                                       $filename = "favicon-template.".$extension;
+                                       if (file_exists($this->style->getAssetPath().$filename)) {
+                                               $file = new UploadFile($this->style->getAssetPath().$filename, $filename, true, true, false);
+                                               UploadHandler::getInstance()->registerFilesByField('favicon', [
+                                                       $file,
+                                               ]);
+                                               break;
+                                       }
+                               }
+                       }
+                       
+                       UploadHandler::getInstance()->registerFilesByField('customAssets', array_map(function ($filename) {
+                               return new UploadFile($filename, basename($filename), false, true, true);
+                       }, glob($this->style->getAssetPath().'custom/*')));
                }
        }
        
@@ -164,7 +243,6 @@ class StyleEditForm extends StyleAddForm {
                                'templateGroupID' => $this->templateGroupID,
                                'styleVersion' => $this->styleVersion,
                                'styleDate' => $this->styleDate,
-                               'imagePath' => $this->imagePath,
                                'copyright' => $this->copyright,
                                'packageName' => $this->packageName,
                                'license' => $this->license,
@@ -172,11 +250,23 @@ class StyleEditForm extends StyleAddForm {
                                'authorURL' => $this->authorURL,
                                'apiVersion' => $this->apiVersion
                        ]),
+                       'uploads' => $this->uploads,
+                       'removedUploads' => $this->removedUploads,
+                       'customAssets' => $this->customAssets,
                        'tmpHash' => $this->tmpHash,
-                       'variables' => $this->variables
+                       'variables' => $this->variables,
                ]);
                $this->objectAction->executeAction();
                
+               // save compiled style
+               if ($this->styleTestFileDir && file_exists($this->styleTestFileDir . '/style.css') && file_exists($this->styleTestFileDir . '/style-rtl.css')) {
+                       $styleFilename = StyleCompiler::getFilenameForStyle($this->style);
+                       rename($this->styleTestFileDir . '/style.css', $styleFilename . '.css');
+                       rename($this->styleTestFileDir . '/style-rtl.css', $styleFilename . '-rtl.css');
+                       
+                       rmdir($this->styleTestFileDir);
+               }
+               
                // save description
                I18nHandler::getInstance()->save('styleDescription', $this->style->styleDescription, 'wcf.style');
                
@@ -212,8 +302,6 @@ class StyleEditForm extends StyleAddForm {
                        'isTainted' => $this->style->isTainted,
                        'style' => $this->style,
                        'styleID' => $this->styleID,
-                       'coverPhotoMinHeight' => UserCoverPhoto::MIN_HEIGHT,
-                       'coverPhotoMinWidth' => UserCoverPhoto::MIN_WIDTH
                ]);
        }
 }
index 705e8c7bf9eb7c91a6f9668411949b2ada085eae..dd46bb32d4cd8d18111d7165d5378372031d0f38 100644 (file)
@@ -38,12 +38,6 @@ class StyleExportForm extends AbstractForm {
         */
        public $exportAsPackage = false;
        
-       /**
-        * true, if images should be exported
-        * @var boolean
-        */
-       public $exportImages = false;
-       
        /**
         * true, if templates should be exported
         * @var boolean
@@ -79,7 +73,6 @@ class StyleExportForm extends AbstractForm {
                        throw new IllegalLinkException();
                }
                
-               if ($this->style->imagePath && $this->style->imagePath != 'images/') $this->canExportImages = true;
                if ($this->style->templateGroupID) $this->canExportTemplates = true;
        }
        
@@ -89,7 +82,6 @@ class StyleExportForm extends AbstractForm {
        public function readFormParameters() {
                parent::readFormParameters();
                
-               if ($this->canExportImages && isset($_POST['exportImages'])) $this->exportImages = true;
                if ($this->canExportTemplates && isset($_POST['exportTemplates'])) $this->exportTemplates = true;
                
                if ($this->style->packageName && isset($_POST['exportAsPackage'])) {
@@ -118,7 +110,7 @@ class StyleExportForm extends AbstractForm {
                
                // export style
                $styleEditor = new StyleEditor($this->style);
-               $styleEditor->export($this->exportTemplates, $this->exportImages, ($this->exportAsPackage ? $this->style->packageName : ''));
+               $styleEditor->export($this->exportTemplates, true, ($this->exportAsPackage ? $this->style->packageName : ''));
                
                // call saved event
                $this->saved();
@@ -133,10 +125,8 @@ class StyleExportForm extends AbstractForm {
                parent::assignVariables();
                
                WCF::getTPL()->assign([
-                       'canExportImages' => $this->canExportImages,
                        'canExportTemplates' => $this->canExportTemplates,
                        'exportAsPackage' => $this->exportAsPackage,
-                       'exportImages' => $this->exportImages,
                        'exportTemplates' => $this->exportTemplates,
                        'style' => $this->style,
                        'styleID' => $this->styleID
index 491d76b578ea49d5ba958c3b8cedb543b5a60680..507eaef40493b233a18622ab8df921b568a145e6 100644 (file)
@@ -1,10 +1,12 @@
 <?php
 namespace wcf\acp\form;
 use wcf\form\AbstractForm;
+use wcf\system\exception\UserInputException;
 use wcf\system\registry\RegistryHandler;
 use wcf\system\style\StyleCompiler;
 use wcf\system\style\StyleHandler;
 use wcf\system\WCF;
+use wcf\util\FileUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -26,6 +28,17 @@ class StyleGlobalValuesForm extends AbstractForm {
         * @var string
         */
        public $styles = '';
+
+       /**
+        * current scroll offset before submitting the form
+        * @var integer
+        */
+       public $stylesScrollOffset = 0;
+       
+       /**
+        * @var string
+        */
+       public $styleTestFileDir;
        
        /**
         * @inheritDoc
@@ -36,6 +49,9 @@ class StyleGlobalValuesForm extends AbstractForm {
                if (isset($_POST['styles'])) {
                        $this->styles = StringUtil::unifyNewlines(StringUtil::trim($_POST['styles']));
                }
+               if (isset($_POST['stylesScrollOffset'])) {
+                       $this->stylesScrollOffset = intval($_POST['stylesScrollOffset']);
+               }
        }
        
        /**
@@ -49,6 +65,39 @@ class StyleGlobalValuesForm extends AbstractForm {
                }
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               parent::validate();
+               
+               $tmpFile = FileUtil::getTemporaryFilename('styleGlobalValues_', '.scss');
+               file_put_contents($tmpFile, $this->styles);
+               
+               try {
+                       // Due to performance issues we can only compile the default style and check, 
+                       // whether there are syntax issues. 
+                       $defaultStyle = StyleHandler::getInstance()->getDefaultStyle();
+                       if ($defaultStyle !== null) {
+                               $this->styleTestFileDir = FileUtil::getTemporaryFilename('style_');
+                               FileUtil::makePath($this->styleTestFileDir);
+                               
+                               $errorMessage = StyleCompiler::getInstance()->testStyle($this->styleTestFileDir, $defaultStyle->styleName, $defaultStyle->apiVersion, $defaultStyle->imagePath, $defaultStyle->getVariables(), $tmpFile);
+                               
+                               if ($errorMessage !== null) {
+                                       rmdir($this->styleTestFileDir);
+                                       
+                                       throw new UserInputException('styles', [
+                                               'message' => str_replace($tmpFile, '', $errorMessage->getMessage()),
+                                       ]);
+                               }
+                       }
+               }
+               finally {
+                       unlink($tmpFile);
+               }
+       }
+       
        /**
         * @inheritDoc
         */
@@ -74,6 +123,16 @@ class StyleGlobalValuesForm extends AbstractForm {
                // reset stylesheets
                StyleHandler::resetStylesheets(false);
                
+               // save compiled style
+               $defaultStyle = StyleHandler::getInstance()->getDefaultStyle();
+               if ($defaultStyle !== null && $this->styleTestFileDir && file_exists($this->styleTestFileDir . '/style.css') && file_exists($this->styleTestFileDir . '/style-rtl.css')) {
+                       $styleFilename = StyleCompiler::getFilenameForStyle($defaultStyle);
+                       rename($this->styleTestFileDir . '/style.css', $styleFilename . '.css');
+                       rename($this->styleTestFileDir . '/style-rtl.css', $styleFilename . '-rtl.css');
+                       
+                       rmdir($this->styleTestFileDir);
+               }
+               
                WCF::getTPL()->assign('success', true);
        }
        
@@ -84,7 +143,8 @@ class StyleGlobalValuesForm extends AbstractForm {
                parent::assignVariables();
                
                WCF::getTPL()->assign([
-                       'styles' => $this->styles
+                       'styles' => $this->styles,
+                       'stylesScrollOffset' => $this->stylesScrollOffset,
                ]);
        }
 }
index 7e0f3157ec2c7f73650b5b1ce626c79124c2a8f4..ca7ba2b9439662a5f7cc89349cf800d769709784 100644 (file)
@@ -6,6 +6,7 @@ use wcf\data\tag\TagEditor;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\LanguageFactory;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
 use wcf\util\StringUtil;
@@ -179,7 +180,10 @@ class TagAddForm extends AbstractForm {
                $this->synonyms = [];
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(TagEditForm::class, ['id' => $returnValues['returnValues']->tagID]),
+               ]);
        }
        
        /**
index 0e1c12ed6cd1180129294c9d90f115bd8a1baadc..0d2e48905909a84a0c84115cdf73d7c72f1cf7a6 100644 (file)
@@ -9,6 +9,7 @@ use wcf\form\AbstractForm;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -196,7 +197,7 @@ class TemplateAddForm extends AbstractForm {
                        'packageID' => $this->packageID,
                        'templateGroupID' => $this->templateGroupID
                ]), 'source' => $this->templateSource]);
-               $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->executeAction();
                $this->saved();
                
                // reset values
@@ -204,7 +205,10 @@ class TemplateAddForm extends AbstractForm {
                $this->templateGroupID = 0;
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(TemplateEditForm::class, ['id' => $returnValues['returnValues']->templateID]),
+               ]);
        }
        
        /**
index 761428def49587b3fa9b6503b3841243c599bd3c..031e1e20df3439e105b0536c320e831e81f2c7e9 100644 (file)
@@ -4,6 +4,7 @@ use wcf\data\template\group\TemplateGroup;
 use wcf\data\template\group\TemplateGroupAction;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
 use wcf\util\StringUtil;
@@ -132,7 +133,7 @@ class TemplateGroupAddForm extends AbstractForm {
                        'templateGroupFolderName' => $this->templateGroupFolderName,
                        'parentTemplateGroupID' => $this->parentTemplateGroupID ?: null
                ])]);
-               $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->executeAction();
                $this->saved();
                
                // reset values
@@ -140,7 +141,10 @@ class TemplateGroupAddForm extends AbstractForm {
                $this->parentTemplateGroupID = 0;
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(TemplateGroupEditForm::class, ['id' => $returnValues['returnValues']->templateGroupID]),
+               ]);
        }
        
        /**
index 4dd41d99651c562c13dd5fc01086c32963620f01..8fb49e083327a4ea979e048ee8c0532460638286 100644 (file)
@@ -9,6 +9,7 @@ use wcf\data\trophy\TrophyEditor;
 use wcf\system\condition\ConditionHandler;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nValue;
+use wcf\system\request\LinkHandler;
 use wcf\system\trophy\condition\TrophyConditionHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
@@ -308,9 +309,9 @@ class TrophyAddForm extends AbstractAcpForm {
                        ]),
                        'tmpHash' => $this->tmpHash
                ]);
-               $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->executeAction();
                
-               $this->saveI18n($this->objectAction->getReturnValues()['returnValues'], TrophyEditor::class);
+               $this->saveI18n($returnValues['returnValues'], TrophyEditor::class);
                
                // transform conditions array into one-dimensional array
                $conditions = [];
@@ -325,9 +326,13 @@ class TrophyAddForm extends AbstractAcpForm {
                        }
                }
                
-               ConditionHandler::getInstance()->createConditions($this->objectAction->getReturnValues()['returnValues']->trophyID, $conditions);
+               ConditionHandler::getInstance()->createConditions($returnValues['returnValues']->trophyID, $conditions);
                
                $this->reset();
+               
+               WCF::getTPL()->assign([
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(TrophyEditForm::class, ['id' => $returnValues['returnValues']->trophyID]),
+               ]);
        }
        
        /**
index 56a3e7d453033cdd618c12acc0036b4dd33e1911..0c598d66fddbf01bc9d0e4b1ce4a190c5034996b 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\acp\form;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
 
 /**
  * Represents the trophy category add form.
@@ -30,4 +32,15 @@ class TrophyCategoryAddForm extends AbstractCategoryAddForm {
         * @inheritDoc
         */
        public $neededPermissions = ['admin.trophy.canManageTrophy'];
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               WCF::getTPL()->assign([
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(TrophyCategoryEditForm::class, ['id' => $this->objectAction->getReturnValues()['returnValues']->categoryID]),
+               ]);
+       }
 }
index 696f4e759dda094add24a77c5ae56e811b5cb015..23f5984dbd20d958585b5d380eb8495f44189f1b 100644 (file)
@@ -8,6 +8,7 @@ use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\UserInputException;
 use wcf\system\html\input\HtmlInputProcessor;
 use wcf\system\language\LanguageFactory;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
 use wcf\util\StringUtil;
@@ -269,12 +270,13 @@ class UserAddForm extends UserOptionListForm {
                }
                
                $this->objectAction = new UserAction([], 'create', $data);
-               $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->executeAction();
                $this->saved();
                
                // show empty add form
                WCF::getTPL()->assign([
-                       'success' => true
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(UserEditForm::class, ['id' => $returnValues['returnValues']->userID]),
                ]);
                
                // reset values
index 79e2306b9fa78e5e35e78904d49c5b9e45c8b6d2..f592a868c35c720230348dd26f199e39a2f4dfe6 100755 (executable)
@@ -184,6 +184,6 @@ class UserAssignToGroupForm extends AbstractForm {
         * Get a list of available groups.
         */
        protected function readGroups() {
-               $this->groups = UserGroup::getAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS]);
+               $this->groups = UserGroup::getSortedAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::USERS]);
        }
 }
index ec7b904ae84a5202060001a867fcd5fe7362a645..ac99ae5531c978a8e7aef9cad5f9b471cfd93452 100755 (executable)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\acp\form;
+use wcf\data\style\Style;
 use wcf\data\user\avatar\Gravatar;
 use wcf\data\user\avatar\UserAvatar;
 use wcf\data\user\avatar\UserAvatarAction;
@@ -15,6 +16,7 @@ use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\exception\UserInputException;
 use wcf\system\moderation\queue\ModerationQueueManager;
+use wcf\system\style\StyleHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -22,7 +24,7 @@ use wcf\util\StringUtil;
  * Shows the user edit form.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Acp\Form
  */
@@ -133,6 +135,20 @@ class UserEditForm extends UserAddForm {
         */
        public $disconnect3rdParty = 0;
        
+       /**
+        * list of available styles for the edited user
+        * @var         Style[]
+        * @since       5.3
+        */
+       public $availableStyles = [];
+       
+       /**
+        * id of the used style
+        * @var         int
+        * @since       5.3
+        */
+       public $styleID = 0;
+       
        /**
         * @inheritDoc
         */
@@ -175,6 +191,7 @@ class UserEditForm extends UserAddForm {
                }
                
                if (isset($_POST['avatarType'])) $this->avatarType = $_POST['avatarType'];
+               if (isset($_POST['styleID'])) $this->styleID = intval($_POST['styleID']);
                
                if (WCF::getSession()->getPermission('admin.user.canDisableAvatar')) {
                        if (!empty($_POST['disableAvatar'])) $this->disableAvatar = 1;
@@ -208,6 +225,13 @@ class UserEditForm extends UserAddForm {
                        $this->readDefaultValues();
                }
                
+               $userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->userID);
+               foreach (StyleHandler::getInstance()->getStyles() as $style) {
+                       if (!$style->isDisabled || $userProfile->getPermission('admin.style.canUseDisabledStyle')) {
+                               $this->availableStyles[$style->styleID] = $style;
+                       }
+               }
+               
                parent::readData();
                
                // get the avatar object
@@ -217,8 +241,6 @@ class UserEditForm extends UserAddForm {
                
                // get the user cover photo object
                if ($this->user->coverPhotoHash) {
-                       $userProfile = UserProfileRuntimeCache::getInstance()->getObject($this->userID);
-                       
                        // If the editing user lacks the permissions to view the cover photo, the system
                        // will try to load the default cover photo. However, the default cover photo depends
                        // on the style, eventually triggering a change to the template group which will
@@ -248,6 +270,7 @@ class UserEditForm extends UserAddForm {
                $this->banReason = $this->user->banReason;
                $this->banExpires = $this->user->banExpires;
                $this->userTitle = $this->user->userTitle;
+               $this->styleID = $this->user->styleID;
                
                $this->signature = $this->user->signature;
                $this->disableSignature = $this->user->disableSignature;
@@ -292,6 +315,8 @@ class UserEditForm extends UserAddForm {
                        'disableCoverPhotoExpires' => $this->disableCoverPhotoExpires,
                        'deleteCoverPhoto' => $this->deleteCoverPhoto,
                        'ownerGroupID' => UserGroup::getOwnerGroupID(),
+                       'availableStyles' => $this->availableStyles,
+                       'styleID' => $this->styleID,
                ]);
        }
        
@@ -351,7 +376,7 @@ class UserEditForm extends UserAddForm {
                
                // save user
                $saveOptions = $this->optionHandler->save();
-
+               
                $data = [
                        'data' => array_merge($this->additionalFields, [
                                'username' => $this->username,
@@ -359,13 +384,19 @@ class UserEditForm extends UserAddForm {
                                'password' => $this->password,
                                'languageID' => $this->languageID,
                                'userTitle' => $this->userTitle,
-                               'signature' => $this->htmlInputProcessor->getHtml()
+                               'signature' => $this->htmlInputProcessor->getHtml(),
+                               'styleID' => $this->styleID,
                        ]),
                        'groups' => $this->groupIDs,
                        'languageIDs' => $this->visibleLanguages,
-                       'options' => $saveOptions
+                       'options' => $saveOptions,
                ];
-
+               // handle changed username
+               if (mb_strtolower($this->username) != mb_strtolower($this->user->username)) {
+                       $data['data']['lastUsernameChange'] = TIME_NOW;
+                       $data['data']['oldUsername'] = $this->user->username;
+               }
+               
                // handle ban
                if (WCF::getSession()->getPermission('admin.user.canBanUser')) {
                        $data['data']['banned'] = $this->banned;
@@ -515,5 +546,9 @@ class UserEditForm extends UserAddForm {
                $this->validateAvatar();
                
                parent::validate();
+               
+               if (!isset($this->availableStyles[$this->styleID])) {
+                       $this->styleID = 0;
+               }
        }
 }
index a2e74ecdb78657b4c3c11aff54432ad3ae7c2a1a..df7eb775a13be8eb052a043dfbd6e20577eb1ed4 100755 (executable)
@@ -5,6 +5,7 @@ use wcf\data\user\group\UserGroupEditor;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\option\user\group\UserGroupOptionHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\system\WCFACP;
 use wcf\util\StringUtil;
@@ -188,7 +189,10 @@ class UserGroupAddForm extends AbstractOptionListForm {
                $this->saved();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(UserGroupEditForm::class, ['id' => $groupID]),
+               ]);
                
                // reset values
                $this->groupName = '';
index 5a33b512720a32ddb43920ef83e7fc594dfcc68c..fb3b0e304d6236e04d3f9e572f1ee5cf1f56c752 100644 (file)
@@ -6,6 +6,7 @@ use wcf\data\user\group\UserGroup;
 use wcf\form\AbstractForm;
 use wcf\system\condition\ConditionHandler;
 use wcf\system\exception\UserInputException;
+use wcf\system\request\LinkHandler;
 use wcf\system\user\group\assignment\UserGroupAssignmentHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
@@ -79,7 +80,7 @@ class UserGroupAssignmentAddForm extends AbstractForm {
         * @inheritDoc
         */
        public function readData() {
-               $this->userGroups = UserGroup::getGroupsByType([], [
+               $this->userGroups = UserGroup::getSortedGroupsByType([], [
                        UserGroup::EVERYONE,
                        UserGroup::GUESTS,
                        UserGroup::OWNER,
@@ -91,10 +92,6 @@ class UserGroupAssignmentAddForm extends AbstractForm {
                        }
                }
                
-               uasort($this->userGroups, function(UserGroup $groupA, UserGroup $groupB) {
-                       return strcmp($groupA->getName(), $groupB->getName());
-               });
-               
                $this->conditions = UserGroupAssignmentHandler::getInstance()->getGroupedObjectTypes();
                
                parent::readData();
@@ -154,7 +151,10 @@ class UserGroupAssignmentAddForm extends AbstractForm {
                        }
                }
                
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(UserGroupAssignmentEditForm::class, ['id' => $returnValues['returnValues']->assignmentID]),
+               ]);
        }
        
        /**
index 69a4f5a8bc381cf307936aeba361d70351ce1dfe..09586ea774d45cda26577b6dbcfa4e2801e48391 100644 (file)
@@ -14,7 +14,6 @@ use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\option\user\group\IUserGroupGroupOptionType;
 use wcf\system\option\user\group\IUserGroupOptionType;
-use wcf\system\option\user\group\UserGroupOptionHandler;
 use wcf\system\WCF;
 use wcf\system\WCFACP;
 
@@ -22,7 +21,7 @@ use wcf\system\WCFACP;
  * Shows the user group option form to edit a single option.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Acp\Form
  */
@@ -118,7 +117,7 @@ class UserGroupOptionForm extends AbstractForm {
                }
                
                // read accessible groups
-               $this->groups = UserGroup::getAccessibleGroups();
+               $this->groups = UserGroup::getSortedAccessibleGroups();
                if ($this->userGroupOption->usersOnly) {
                        $guestGroup = UserGroup::getGroupByType(UserGroup::GUESTS);
                        if (isset($this->groups[$guestGroup->groupID])) {
index 15f6527348b490d9baaec1c525424165f138931e..010e02b5e368ea190b200d2044cd83027163c06f 100644 (file)
@@ -48,19 +48,15 @@ class UserGroupPromoteOwnerForm extends AbstractFormBuilderForm {
                        throw new IllegalLinkException();
                }
                
-               $this->groups = UserGroup::getGroupsByType([UserGroup::OTHER]);
+               $this->groups = UserGroup::getSortedGroupsByType([UserGroup::OTHER]);
                $this->groups = array_filter($this->groups, function (UserGroup $group) {
                        return $group->isAdminGroup();
                });
                
                if (empty($this->groups)) {
                        // fallback for broken installations without an admin group
-                       $this->groups = UserGroup::getGroupsByType([UserGroup::OTHER]);
+                       $this->groups = UserGroup::getSortedGroupsByType([UserGroup::OTHER]);
                }
-               
-               uasort($this->groups, function(UserGroup $a, UserGroup $b) {
-                       return $a->getName() <=> $b->getName();
-               });
        }
        
        /**
index e51e0635674b8e288d61da1c79dcbee7d55bd66c..d258d8bc87d3fff4c65815f83ed437d28abd4f4b 100755 (executable)
@@ -209,7 +209,7 @@ class UserMailForm extends AbstractForm {
                        $this->userList->readObjects();
                }
                
-               $this->groups = UserGroup::getAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE]);
+               $this->groups = UserGroup::getSortedAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE]);
        }
        
        /**
index 0acc822adeaad2f612514c50f160f98ec678d94f..fc6e6f3c63a07cbd2058e1ace7c7574ee3d50f1b 100644 (file)
@@ -8,6 +8,7 @@ use wcf\data\user\option\UserOptionEditor;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -331,7 +332,10 @@ class UserOptionAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(UserOptionEditForm::class, ['id' => $userOption->optionID]),
+               ]);
        }
        
        /**
index d8d081ff99d7f64e8992852061ff7f2498530fc9..bd6f461b4cc0bd1191cae933e58333b0fc786f0f 100644 (file)
@@ -5,6 +5,7 @@ use wcf\data\user\option\category\UserOptionCategoryEditor;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 
 /**
@@ -101,7 +102,10 @@ class UserOptionCategoryAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(UserOptionCategoryEditForm::class, ['id' => $categoryID]),
+               ]);
        }
        
        /**
index 338846c41070ea1987abe94d499203406b8d9f7f..155a88f83220a6c7a3d3a0bd663b3d571bdafcde 100644 (file)
@@ -3,10 +3,12 @@ namespace wcf\acp\form;
 use wcf\data\user\group\UserGroup;
 use wcf\data\user\rank\UserRankAction;
 use wcf\data\user\rank\UserRankEditor;
+use wcf\data\user\UserProfile;
 use wcf\form\AbstractForm;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\I18nHandler;
 use wcf\system\Regex;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -174,7 +176,7 @@ class UserRankAddForm extends AbstractForm {
                }
                
                // required gender
-               if ($this->requiredGender < 0 || $this->requiredGender > 2) {
+               if ($this->requiredGender < 0 || $this->requiredGender > UserProfile::GENDER_OTHER) {
                        $this->requiredGender = 0;
                }
                
@@ -200,11 +202,10 @@ class UserRankAddForm extends AbstractForm {
                        'requiredGender' => $this->requiredGender,
                        'hideTitle' => ($this->hideTitle ? 1 : 0)
                ])]);
-               $this->objectAction->executeAction();
+               $returnValues = $this->objectAction->executeAction();
+               $rankID = $returnValues['returnValues']->rankID;
                
                if (!I18nHandler::getInstance()->isPlainValue('rankTitle')) {
-                       $returnValues = $this->objectAction->getReturnValues();
-                       $rankID = $returnValues['returnValues']->rankID;
                        I18nHandler::getInstance()->save('rankTitle', 'wcf.user.rank.userRank'.$rankID, 'wcf.user', 1);
                        
                        // update name
@@ -223,7 +224,10 @@ class UserRankAddForm extends AbstractForm {
                I18nHandler::getInstance()->reset();
                
                // show success message
-               WCF::getTPL()->assign('success', true);
+               WCF::getTPL()->assign([
+                       'success' => true,
+                       'objectEditLink' => LinkHandler::getInstance()->getControllerLink(UserRankEditForm::class, ['id' => $rankID]),
+               ]);
        }
        
        /**
@@ -241,7 +245,7 @@ class UserRankAddForm extends AbstractForm {
                        'customCssClassName' => $this->customCssClassName,
                        'groupID' => $this->groupID,
                        'rankTitle' => $this->rankTitle,
-                       'availableGroups' => UserGroup::getGroupsByType([], [UserGroup::GUESTS, UserGroup::EVERYONE]),
+                       'availableGroups' => UserGroup::getSortedGroupsByType([], [UserGroup::GUESTS, UserGroup::EVERYONE]),
                        'requiredPoints' => $this->requiredPoints,
                        'rankImage' => $this->rankImage,
                        'repeatImage' => $this->repeatImage,
index 8f3239d3c473bbdeea43a1453783e9476ec2d910..efc22200eee1ad28d2d3f7f1430b6c8e6ac17965 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 namespace wcf\acp\page;
-use wcf\data\cronjob\CronjobList;
+use wcf\data\cronjob\I18nCronjobList;
 use wcf\page\SortablePage;
 
 /**
@@ -11,7 +11,7 @@ use wcf\page\SortablePage;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Acp\Page
  * 
- * @property   CronjobList     $objectList
+ * @property   I18nCronjobList $objectList
  */
 class CronjobListPage extends SortablePage {
        /**
@@ -27,7 +27,7 @@ class CronjobListPage extends SortablePage {
        /**
         * @inheritDoc
         */
-       public $defaultSortField = 'cronjobID';
+       public $defaultSortField = 'descriptionI18n';
        
        /**
         * @inheritDoc
@@ -37,12 +37,12 @@ class CronjobListPage extends SortablePage {
        /**
         * @inheritDoc
         */
-       public $validSortFields = ['cronjobID', 'nextExec', 'startMinute', 'startHour', 'startDom', 'startMonth', 'startDow'];
+       public $validSortFields = ['cronjobID', 'nextExec', 'startMinute', 'startHour', 'startDom', 'startMonth', 'startDow', 'descriptionI18n'];
        
        /**
         * @inheritDoc
         */
-       public $objectListClassName = CronjobList::class;
+       public $objectListClassName = I18nCronjobList::class;
        
        /**
         * @inheritDoc
index a459262c6168733f32da8e486f867457c0caca25..05df8b3e3a9381e332694d1f9f6cf66018fd4e36 100755 (executable)
@@ -1,7 +1,10 @@
 <?php
 namespace wcf\acp\page;
+use wcf\data\cronjob\CronjobList;
+use wcf\data\cronjob\I18nCronjobList;
 use wcf\data\cronjob\log\CronjobLogList;
 use wcf\page\SortablePage;
+use wcf\system\WCF;
 
 /**
  * Shows cronjob log information.
@@ -49,6 +52,31 @@ class CronjobLogListPage extends SortablePage {
         */
        public $objectListClassName = CronjobLogList::class;
        
+       /**
+        * @var integer
+        */
+       public $cronjobID = 0;
+       
+       /**
+        * @var integer
+        */
+       public $success = -1;
+       
+       /**
+        * @var CronjobList
+        */
+       public $availableCronjobs;
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               if (!empty($_REQUEST['cronjobID'])) $this->cronjobID = intval($_REQUEST['cronjobID']);
+               if (isset($_REQUEST['success'])) $this->success = intval($_REQUEST['success']);
+       }
+       
        /**
         * @inheritDoc
         */
@@ -57,6 +85,13 @@ class CronjobLogListPage extends SortablePage {
                
                $this->objectList->sqlSelects = "cronjob.*";
                $this->objectList->sqlJoins = "LEFT JOIN wcf".WCF_N."_cronjob cronjob ON (cronjob.cronjobID = cronjob_log.cronjobID)";
+               
+               if ($this->cronjobID) {
+                       $this->objectList->getConditionBuilder()->add('cronjob_log.cronjobID = ?', [$this->cronjobID]);
+               }
+               if ($this->success != -1) {
+                       $this->objectList->getConditionBuilder()->add('cronjob_log.success = ?', [$this->success]);
+               }
        }
        
        /**
@@ -67,4 +102,28 @@ class CronjobLogListPage extends SortablePage {
                
                parent::readObjects();
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readData() {
+               parent::readData();
+               
+               $this->availableCronjobs = new I18nCronjobList();
+               $this->availableCronjobs->sqlOrderBy = 'descriptionI18n';
+               $this->availableCronjobs->readObjects();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'cronjobID' => $this->cronjobID,
+                       'success' => $this->success,
+                       'availableCronjobs' => $this->availableCronjobs,
+               ]);
+       }
 }
diff --git a/wcfsetup/install/files/lib/acp/page/DevtoolsMissingLanguageItemListPage.class.php b/wcfsetup/install/files/lib/acp/page/DevtoolsMissingLanguageItemListPage.class.php
new file mode 100644 (file)
index 0000000..0d5fb2f
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+namespace wcf\acp\page;
+use wcf\data\devtools\missing\language\item\DevtoolsMissingLanguageItemList;
+use wcf\page\SortablePage;
+
+/**
+ * Shows the list of missing language item log entries.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Acp\Page
+ * @since      5.3
+ */
+class DevtoolsMissingLanguageItemListPage extends SortablePage {
+       /**
+        * @inheritDoc
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.devtools.missingLanguageItem.list';
+       
+       /**
+        * @inheritDoc
+        */
+       public $defaultSortField = 'lastTime';
+       
+       /**
+        * @inheritDoc
+        */
+       public $defaultSortOrder = 'DESC';
+       
+       /**
+        * @inheritDoc
+        */
+       public $itemsPerPage = 50;
+       
+       /**
+        * @inheritDoc
+        */
+       public $objectListClassName = DevtoolsMissingLanguageItemList::class;
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededModules = ['ENABLE_DEVELOPER_TOOLS'];
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['admin.configuration.package.canInstallPackage'];
+       
+       /**
+        * @inheritDoc
+        */
+       public $validSortFields = ['itemID', 'languageID', 'languageItem', 'lastTime'];
+}
index a6e8447a08db9900da5303f0f87f89a992924c8e..38ce4eb580b2e6cc4feca9e61e6ed48f5c2edcdb 100644 (file)
@@ -141,15 +141,22 @@ class ExceptionLogViewPage extends MultipleLinkPage {
                $this->calculateNumberOfPages();
                
                $i = 0;
-               
+               $seenHashes = [];
                foreach ($this->exceptions as $key => $val) {
                        $i++;
+                       
+                       $parsed = ExceptionLogUtil::parseException($val);
+                       if (isset($seenHashes[$parsed['stackHash']])) {
+                               $parsed['collapsed'] = true;
+                       }
+                       $seenHashes[$parsed['stackHash']] = true;
+                       
                        if ($i < $this->startIndex || $i > $this->endIndex) {
                                unset($this->exceptions[$key]);
                                continue;
                        }
                        try {
-                               $this->exceptions[$key] = ExceptionLogUtil::parseException($val);
+                               $this->exceptions[$key] = $parsed;
                        }
                        catch (\InvalidArgumentException $e) {
                                unset($this->exceptions[$key]);
index daa34c18964b7e9118f28559e126566a92869b2e..c56966fe962e8aec09639af13b6e967e075c04a6 100755 (executable)
@@ -1,19 +1,21 @@
 <?php
 namespace wcf\acp\page;
+use wcf\data\user\User;
+use wcf\data\devtools\missing\language\item\DevtoolsMissingLanguageItemList;
 use wcf\page\AbstractPage;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\cache\builder\OptionCacheBuilder;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\io\RemoteFile;
 use wcf\system\package\PackageInstallationDispatcher;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
-use wcf\util\StringUtil;
 
 /**
  * Shows the welcome page in admin control panel.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Acp\Page
  */
@@ -30,6 +32,15 @@ class IndexPage extends AbstractPage {
        public function readData() {
                parent::readData();
                
+               $sql = "SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute();
+               $row = $statement->fetchArray();
+               $innodbFlushLogAtTrxCommit = false;
+               if ($row !== false) {
+                       $innodbFlushLogAtTrxCommit = $row['Value'];
+               }
+               
                $this->server = [
                        'os' => PHP_OS,
                        'webserver' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '',
@@ -38,7 +49,8 @@ class IndexPage extends AbstractPage {
                        'memoryLimit' => @ini_get('memory_limit'),
                        'upload_max_filesize' => @ini_get('upload_max_filesize'),
                        'postMaxSize' => @ini_get('post_max_size'),
-                       'sslSupport' => RemoteFile::supportsSSL()
+                       'sslSupport' => RemoteFile::supportsSSL(),
+                       'innodbFlushLogAtTrxCommit' => $innodbFlushLogAtTrxCommit,
                ];
                
                // get load
@@ -57,12 +69,18 @@ class IndexPage extends AbstractPage {
                parent::assignVariables();
                
                $usersAwaitingApproval = 0;
-               if (REGISTER_ACTIVATION_METHOD == 2) {
+               if (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN) {
+                       $conditionBuilder = new PreparedStatementConditionBuilder();
+                       $conditionBuilder->add('activationCode <> ?', [0]);
+                       if (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER) {
+                               $conditionBuilder->add('emailConfirmed IS NULL');
+                       }
+                       
                        $sql = "SELECT  COUNT(*)
-                               FROM    wcf".WCF_N."_user
-                               WHERE   activationCode <> 0";
+                               FROM    wcf".WCF_N."_user ".
+                               $conditionBuilder;
                        $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute();
+                       $statement->execute($conditionBuilder->getParameters());
                        $usersAwaitingApproval = $statement->fetchSingleColumn();
                }
                
@@ -84,6 +102,10 @@ class IndexPage extends AbstractPage {
                
                $evaluationExpired = $evaluationPending = [];
                foreach (ApplicationHandler::getInstance()->getApplications() as $application) {
+                       if ($application->isTainted) {
+                               continue;
+                       }
+                       
                        if ($application->getPackage()->package === 'com.woltlab.wcf') {
                                continue;
                        }
@@ -115,13 +137,16 @@ class IndexPage extends AbstractPage {
                }
                
                $missingLanguageItemsMTime = 0;
-               if (
-                       ENABLE_DEBUG_MODE
-                       && ENABLE_DEVELOPER_TOOLS
-                       && file_exists(WCF_DIR . 'log/missingLanguageItems.txt')
-                       && filesize(WCF_DIR . 'log/missingLanguageItems.txt') > 0
-               ) {
-                       $missingLanguageItemsMTime = filemtime(WCF_DIR . 'log/missingLanguageItems.txt');
+               if (ENABLE_DEBUG_MODE && ENABLE_DEVELOPER_TOOLS) {
+                       $logList = new DevtoolsMissingLanguageItemList();
+                       $logList->sqlOrderBy = 'lastTime DESC';
+                       $logList->sqlLimit = 1;
+                       $logList->readObjects();
+                       $logEntry = $logList->getSingleObject();
+                       
+                       if ($logEntry !== null) {
+                               $missingLanguageItemsMTime = $logEntry->lastTime;
+                       }
                }
                
                WCF::getTPL()->assign([
index 819327399331629d1098d3588b1f3f960997b821..1087cc8e7a97a8527cc5509a6701e7b2771025fe 100644 (file)
@@ -1,7 +1,13 @@
 <?php
 namespace wcf\acp\page;
 use wcf\data\label\group\LabelGroupList;
+use wcf\data\language\item\LanguageItemList;
 use wcf\page\SortablePage;
+use wcf\system\language\LanguageFactory;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
+use wcf\util\HeaderUtil;
+use wcf\util\StringUtil;
 
 /**
  * Lists available label groups.
@@ -27,7 +33,12 @@ class LabelGroupListPage extends SortablePage {
        /**
         * @inheritDoc
         */
-       public $validSortFields = ['groupID', 'groupName', 'groupDescription', 'showOrder'];
+       public $itemsPerPage = 50;
+       
+       /**
+        * @inheritDoc
+        */
+       public $validSortFields = ['groupID', 'groupName', 'groupDescription', 'showOrder', 'labels'];
        
        /**
         * @inheritDoc
@@ -38,4 +49,81 @@ class LabelGroupListPage extends SortablePage {
         * @inheritDoc
         */
        public $objectListClassName = LabelGroupList::class;
+       
+       /**
+        * @var string
+        */
+       public $groupName = '';
+       
+       /**
+        * @var string
+        */
+       public $groupDescription = '';
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               if (!empty($_POST)) {
+                       $parameters = [];
+                       if (!empty($_POST['groupName'])) $parameters['groupName'] = StringUtil::trim($_POST['groupName']);
+                       if (!empty($_POST['groupDescription'])) $parameters['groupDescription'] = StringUtil::trim($_POST['groupDescription']);
+                       
+                       if (!empty($parameters)) {
+                               HeaderUtil::redirect(LinkHandler::getInstance()->getLink('LabelGroupList', $parameters));
+                               exit;
+                       }
+               }
+               
+               if (isset($_REQUEST['groupName'])) $this->groupName = StringUtil::trim($_REQUEST['groupName']);
+               if (isset($_REQUEST['groupDescription'])) $this->groupDescription = StringUtil::trim($_REQUEST['groupDescription']);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected function initObjectList() {
+               parent::initObjectList();
+               
+               $this->objectList->sqlSelects .= '(SELECT COUNT(*) FROM wcf'.WCF_N.'_label WHERE groupID = label_group.groupID) AS labels';
+               
+               if ($this->groupName) {
+                       $languageItemList = new LanguageItemList();
+                       $languageItemList->getConditionBuilder()->add('languageCategoryID = ?', [LanguageFactory::getInstance()->getCategory('wcf.acp.label')->languageCategoryID]);
+                       $languageItemList->getConditionBuilder()->add('languageID = ?', [WCF::getLanguage()->languageID]);
+                       $languageItemList->getConditionBuilder()->add('languageItem LIKE ?', ['wcf.acp.label.group%']);
+                       $languageItemList->getConditionBuilder()->add('languageItemValue LIKE ?', ['%'.addcslashes($this->groupName, '_%').'%']);
+                       $languageItemList->readObjects();
+                       
+                       $labelIDs = [];
+                       foreach ($languageItemList as $languageItem) {
+                               $labelIDs[] = str_replace('wcf.acp.label.group', '', $languageItem->languageItem);
+                       }
+                       
+                       if (!empty($labelIDs)) {
+                               $this->objectList->getConditionBuilder()->add('(groupName LIKE ? OR groupID IN (?))', ['%'.addcslashes($this->groupName, '_%').'%', $labelIDs]);
+                       }
+                       else {
+                               $this->objectList->getConditionBuilder()->add('groupName LIKE ?', ['%'.addcslashes($this->groupName, '_%').'%']);
+                       }
+               }
+               
+               if ($this->groupDescription) {
+                       $this->objectList->getConditionBuilder()->add('label_group.groupDescription LIKE ?', ['%'.addcslashes($this->groupDescription, '_%').'%']);
+               }
+       }
+               
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'groupName' => $this->groupName,
+                       'groupDescription' => $this->groupDescription,
+               ]);
+       }
 }
index f6843a8df62e7674f990d238613ecadb0c07c292..7f23616d031f9303b349fe936fb64be9dd5c84b8 100644 (file)
@@ -33,6 +33,11 @@ class LabelListPage extends SortablePage {
         */
        public $defaultSortField = 'label';
        
+       /**
+        * @inheritDoc
+        */
+       public $itemsPerPage = 50;
+       
        /**
         * @inheritDoc
         */
index 9b1b9a75aa6c7a5354975aa634f0db478b8d9e5b..4c8ff59619b5e1e6a544ffbf99b948de5b167543 100755 (executable)
@@ -32,7 +32,7 @@ class PackageUpdateServerListPage extends SortablePage {
        /**
         * @inheritDoc
         */
-       public $validSortFields = ['packageUpdateServerID', 'serverURL', 'status', 'errorMessage', 'lastUpdateTime', 'packages'];
+       public $validSortFields = ['packageUpdateServerID', 'serverURL', 'loginUsername', 'status', 'errorMessage', 'lastUpdateTime', 'packages'];
        
        /**
         * @inheritDoc
index b09c9d4af61cacf0954aa795d5d1c26b39a700d0..e6314272d4cc7958603d3dce58ab2d7d3d4f7176 100644 (file)
@@ -27,6 +27,8 @@ class PluginStorePurchasedItemsPage extends AbstractPage {
         */
        public $neededPermissions = ['admin.configuration.package.canUpdatePackage', 'admin.configuration.package.canUninstallPackage'];
        
+       public $fetchedPackageServers = false;
+       
        /**
         * list of purchased products grouped by WCF major release
         * @var array<array>
@@ -74,24 +76,18 @@ class PluginStorePurchasedItemsPage extends AbstractPage {
        public function readData() {
                parent::readData();
                
-               $serverList = new PackageUpdateServerList();
-               $serverList->readObjects();
-               foreach ($serverList as $server) {
-                       if (preg_match('~https?://store.woltlab.com/(?P<wcfMajorRelease>[a-z]+)/~', $server->serverURL, $matches)) {
-                               $this->updateServers[$matches['wcfMajorRelease']] = $server;
+               foreach (PackageUpdateServer::getActiveUpdateServers() as $packageUpdateServer) {
+                       if ($packageUpdateServer->isWoltLabUpdateServer() || $packageUpdateServer->isWoltLabStoreServer()) {
+                               $this->fetchedPackageServers = $packageUpdateServer->lastUpdateTime > 0;
+                               break;
                        }
                }
                
                foreach ($this->products as $packageUpdateID => $product) {
-                       $wcfMajorRelease = $product['wcfMajorRelease'];
-                       if (!isset($this->productData[$wcfMajorRelease])) {
-                               $this->productData[$wcfMajorRelease] = [];
-                       }
-                       
                        $languageCode = WCF::getLanguage()->languageCode;
                        $packageName = isset($product['packageName'][$languageCode]) ? $product['packageName'][$languageCode] : $product['packageName']['en'];
                        
-                       $this->productData[$wcfMajorRelease][$packageUpdateID] = [
+                       $this->productData[$packageUpdateID] = [
                                'author' => $product['author'],
                                'authorURL' => $product['authorURL'],
                                'package' => $product['package'],
@@ -101,25 +97,29 @@ class PluginStorePurchasedItemsPage extends AbstractPage {
                                        'available' => $product['lastVersion'],
                                        'installed' => ''
                                ],
-                               'status' => isset($this->updateServers[$wcfMajorRelease]) ? 'install' : 'unavailable'
+                               'status' => 'install',
                        ];
                        
                        $package = PackageCache::getInstance()->getPackageByIdentifier($product['package']);
                        if ($package !== null) {
-                               $this->productData[$wcfMajorRelease][$packageUpdateID]['version']['installed'] = $package->packageVersion;
+                               $this->productData[$packageUpdateID]['version']['installed'] = $package->packageVersion;
                                
                                if (Package::compareVersion($product['lastVersion'], $package->packageVersion, '>')) {
-                                       $this->productData[$wcfMajorRelease][$packageUpdateID]['status'] = 'update';
+                                       $this->productData[$packageUpdateID]['status'] = 'update';
                                }
                                else if (Package::compareVersion($product['lastVersion'], $package->packageVersion, '<=')) {
-                                       $this->productData[$wcfMajorRelease][$packageUpdateID]['status'] = 'upToDate';
+                                       $this->productData[$packageUpdateID]['status'] = 'upToDate';
                                }
                        }
                        
-                       if (isset($this->updateServers[$wcfMajorRelease]) && $this->updateServers[$wcfMajorRelease]->lastUpdateTime == 0) {
-                               $this->productData[$wcfMajorRelease][$packageUpdateID]['status'] = 'requireUpdate';
+                       if (!$this->fetchedPackageServers) {
+                               $this->productData[$packageUpdateID]['status'] = 'requireUpdate';
                        }
                }
+               
+               uasort($this->productData, function (array $a, array $b) {
+                       return strcasecmp($a['packageName'], $b['packageName']);
+               });
        }
        
        /**
@@ -129,9 +129,8 @@ class PluginStorePurchasedItemsPage extends AbstractPage {
                parent::assignVariables();
                
                WCF::getTPL()->assign([
+                       'fetchedPackageServers' => $this->fetchedPackageServers,
                        'productData' => $this->productData,
-                       'updateServers' => $this->updateServers,
-                       'wcfMajorReleases' => $this->wcfMajorReleases
                ]);
        }
 }
index 0f6dfd6d3e3aa4211c44a67e2f644607f9e3c3ec..392c23b394320d9e1f58abe177494e215d69105e 100644 (file)
@@ -35,12 +35,6 @@ class RebuildDataPage extends AbstractPage {
         */
        public $objectTypes = [];
        
-       /**
-        * display a warning if InnoDB uses a slow configuration
-        * @var boolean
-        */
-       public $showInnoDBWarning = false;
-       
        /**
         * @inheritDoc
         */
@@ -65,14 +59,6 @@ class RebuildDataPage extends AbstractPage {
                        return 0;
                });
                
-               $sql = "SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute();
-               $row = $statement->fetchArray();
-               if ($row && $row['Value'] == 1) {
-                       $this->showInnoDBWarning = true;
-               }
-               
                // We're disallowing rebuilding any other data unless the
                // database encoding has been converted to utf8mb4. The
                // user_storage table is used as a reference, as it is the
@@ -102,7 +88,6 @@ class RebuildDataPage extends AbstractPage {
                WCF::getTPL()->assign([
                        'convertEncoding' => $this->convertEncoding,
                        'objectTypes' => $this->objectTypes,
-                       'showInnoDBWarning' => $this->showInnoDBWarning
                ]);
        }
 }
index 94efdb3809464d27f38372668cc6473f10b0ddf8..3509086dad014c8015ae4311fdaf18e325a1ef21 100755 (executable)
@@ -4,6 +4,7 @@ use wcf\data\object\type\ObjectType;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\page\AbstractPage;
 use wcf\system\WCF;
+use wcf\system\worker\SitemapRebuildWorker;
 
 /**
  * Shows a list of sitemap object types. 
@@ -37,6 +38,10 @@ class SitemapListPage extends AbstractPage {
                parent::readData();
                
                $this->sitemapObjectTypes = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.sitemap.object');
+               
+               foreach ($this->sitemapObjectTypes as $sitemapObjectType) {
+                       SitemapRebuildWorker::prepareSitemapObject($sitemapObjectType);
+               }
        }
        
        /**
index e21129cc1cc20699febca45b9907f51327a68732..f61595a05b42f8f840ec1a34ceafd53c0fc344a2 100644 (file)
@@ -92,33 +92,33 @@ class SystemCheckPage extends AbstractPage {
                'wcf'. WCF_N .'_user' => [
                        'avatarID' => [
                                'referenceTable' => 'wcf'. WCF_N .'_user_avatar',
-                               'referenceColumn' => 'avatarID'
-                       ]
+                               'referenceColumn' => 'avatarID',
+                       ],
                ],
                'wcf'. WCF_N .'_comment' => [
                        'userID' => [
                                'referenceTable' => 'wcf'. WCF_N .'_user',
-                               'referenceColumn' => 'userID'
+                               'referenceColumn' => 'userID',
                        ],
                        'objectTypeID' => [
                                'referenceTable' => 'wcf'. WCF_N .'_object_type',
-                               'referenceColumn' => 'objectTypeID'
-                       ]
+                               'referenceColumn' => 'objectTypeID',
+                       ],
                ],
                'wcf'. WCF_N .'_moderation_queue' => [
                        'objectTypeID' => [
                                'referenceTable' => 'wcf'. WCF_N .'_object_type',
-                               'referenceColumn' => 'objectTypeID'
+                               'referenceColumn' => 'objectTypeID',
                        ],
                        'assignedUserID' => [
                                'referenceTable' => 'wcf'. WCF_N .'_user',
-                               'referenceColumn' => 'userID'
+                               'referenceColumn' => 'userID',
                        ],
                        'userID' => [
                                'referenceTable' => 'wcf'. WCF_N .'_user',
-                               'referenceColumn' => 'userID'
-                       ]
-               ]
+                               'referenceColumn' => 'userID',
+                       ],
+               ],
        ];
        
        public $results = [
@@ -131,10 +131,15 @@ class SystemCheckPage extends AbstractPage {
                        'foreignKeys' => false,
                        'searchEngine' => [
                                'result' => false, 
-                               'incorrectTables' => []
+                               'incorrectTables' => [],
                        ],
                ],
                'php' => [
+                       'gd' => [
+                               'jpeg' => false,
+                               'png' => false,
+                               'result' => false,
+                       ],
                        'extension' => [],
                        'memoryLimit' => [
                                'required' => '0',
@@ -181,6 +186,7 @@ class SystemCheckPage extends AbstractPage {
                $this->validatePhpExtensions();
                $this->validatePhpMemoryLimit();
                $this->validatePhpVersion();
+               $this->validatePhpGdSupport();
                $this->validateWritableDirectories();
        }
        
@@ -382,6 +388,21 @@ class SystemCheckPage extends AbstractPage {
                $this->results['status']['php'] = $this->results['status']['php'] && ($this->results['php']['version']['result'] !== 'unsupported');
        }
        
+       protected function validatePhpGdSupport() {
+               if (!function_exists('\gd_info')) {
+                       $this->results['status']['php'] = false;
+                       return;
+               }
+               
+               $gdInfo = \gd_info();
+               $this->results['php']['gd']['jpeg'] = !empty($gdInfo['JPEG Support']);
+               $this->results['php']['gd']['png'] = !empty($gdInfo['PNG Support']);
+               
+               $this->results['php']['gd']['result'] = $this->results['php']['gd']['jpeg'] && $this->results['php']['gd']['png'];
+               
+               $this->results['status']['php'] = $this->results['status']['php'] && $this->results['php']['gd']['result'];
+       }
+       
        protected function validateWritableDirectories() {
                foreach ($this->directories as $abbreviation => $directories) {
                        $basePath = Application::getDirectory($abbreviation);
index 19ebab30270e3e8b17540ee6d06bd8fc5e0d350d..cfba6300a987fa6d35439fecfe1a639ebda7d2b1 100644 (file)
@@ -6,6 +6,7 @@ use wcf\system\file\upload\UploadFile;
 use wcf\system\file\upload\UploadHandler;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
+use wcf\util\ImageUtil;
 use wcf\util\JSON;
 
 /**
@@ -87,7 +88,7 @@ class AJAXFileUploadAction extends AbstractSecureAction {
                $field = UploadHandler::getInstance()->getFieldByInternalId($this->internalId);
                
                foreach ($_FILES['__files']['tmp_name'] as $id => $tmpName) {
-                       if ($field->isImageOnly() && !UploadHandler::isValidImage($tmpName, $_FILES['__files']['name'][$id], $field->svgImageAllowed())) {
+                       if ($field->isImageOnly() && !ImageUtil::isImage($tmpName, $_FILES['__files']['name'][$id], $field->svgImageAllowed())) {
                                $response['error'][$i++] = [
                                        'filename' => $_FILES['__files']['name'][$id],
                                        'errorMessage' => WCF::getLanguage()->get('wcf.upload.error.noImage')
index 47e6fd46db20d7719ecc6bb165c85843d91ad2dc..23026f9d29ccbe7537e30d482bdec251861b9df0 100644 (file)
@@ -1,15 +1,18 @@
 <?php
 namespace wcf\action;
+use GuzzleHttp\Exception\TransferException;
+use GuzzleHttp\Psr7\Request;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\SystemException;
+use wcf\system\io\File;
+use wcf\system\io\HttpFactory;
 use wcf\system\WCF;
 use wcf\util\exception\CryptoException;
-use wcf\util\exception\HTTPException;
 use wcf\util\CryptoUtil;
 use wcf\util\FileUtil;
 use wcf\util\HeaderUtil;
-use wcf\util\HTTPRequest;
 use wcf\util\StringUtil;
+use wcf\util\Url;
 
 /**
  * Proxies requests for embedded images.
@@ -32,6 +35,11 @@ class ImageProxyAction extends AbstractAction {
         */
        public $key = '';
        
+       /**
+        * 10 Mebibyte
+        */
+       const MAX_SIZE = (10 * (1 << 20));
+       
        /**
         * @inheritDoc
         */
@@ -71,47 +79,55 @@ class ImageProxyAction extends AbstractAction {
                        }
                        
                        if ($fileLocation === null) {
+                               $tmp = FileUtil::getTemporaryFilename('image_proxy_');
+                               
                                try {
                                        // rewrite schemaless URLs to https
-                                       $scheme = parse_url($url, PHP_URL_SCHEME);
+                                       $scheme = Url::parse($url)['scheme'];
                                        if (!$scheme) {
                                                if (StringUtil::startsWith($url, '//')) {
                                                        $url = 'https:'.$url;
                                                }
                                                else {
-                                                       throw new \DomainException();
+                                                       throw new \DomainException("Refusing to proxy a schemaless URL that does not start with //");
                                                }
                                        }
                                        
+                                       if (Url::parse($url)['port']) {
+                                               throw new \DomainException("Refusing to proxy non-standard ports.");
+                                       }
+                                       
                                        // download image
                                        try {
-                                               $request = new HTTPRequest($url, [
-                                                       'maxLength' => 10 * (1 << 20) // download at most 10 MiB
+                                               $client = HttpFactory::makeClient([
+                                                       'timeout' => 10,
+                                                       'stream' => true,
                                                ]);
-                                               $request->addHeader('Via', '1.1 wsc');
-                                               $request->addHeader('Accept', 'image/*');
-                                               $request->execute();
-                                       }
-                                       catch (\Exception $e) {
-                                               $chain = $e;
-                                               do {
-                                                       if ($chain instanceof HTTPException) {
-                                                               throw new \DomainException();
-                                                       }
-                                                       // TODO: This is the Exception thrown by RemoteFile.
-                                                       //       Update if RemoteFile switches to a proper subclass in the future.
-                                                       if (strpos($chain->getMessage(), 'Can not connect to') === 0) {
-                                                               throw new \DomainException();
+                                               $request = new Request('GET', $url, [
+                                                       'via' => '1.1 wsc',
+                                                       'accept' => 'image/*',
+                                                       'range' => 'bytes=0-'.(self::MAX_SIZE - 1),
+                                               ]);
+                                               $response = $client->send($request);
+                                               
+                                               $file = new File($tmp);
+                                               while (!$response->getBody()->eof()) {
+                                                       $file->write($response->getBody()->read(8192));
+                                                       
+                                                       if ($response->getBody()->tell() >= self::MAX_SIZE) {
+                                                               break;
                                                        }
                                                }
-                                               while ($chain = $chain->getPrevious());
-                                               
-                                               throw $e;
+                                               $response->getBody()->close();
+                                               $file->flush();
+                                               $file->close();
+                                       }
+                                       catch (TransferException $e) {
+                                               throw new \DomainException('Failed to request', 0, $e);
                                        }
-                                       $image = $request->getReply()['body'];
                                        
                                        // check file type
-                                       $imageData = @getimagesizefromstring($image);
+                                       $imageData = @getimagesize($tmp);
                                        if (!$imageData) throw new \DomainException();
                                        
                                        switch ($imageData[2]) {
@@ -131,13 +147,13 @@ class ImageProxyAction extends AbstractAction {
                                catch (\DomainException $e) {
                                        // save a dummy image in case the server sent us junk, otherwise we might try to download the file over and over and over again.
                                        // taken from the public domain gif at https://commons.wikimedia.org/wiki/File%3aBlank.gif
-                                       $image = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x21\xF9\x04\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3B";
+                                       file_put_contents($tmp, "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x21\xF9\x04\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3B");
                                        $extension = 'gif';
                                }
                                
                                $fileLocation = $dir.'/'.$fileName.'.'.$extension;
                                
-                               file_put_contents($fileLocation, $image);
+                               rename($tmp, $fileLocation);
                                
                                // update mtime for correct expiration calculation
                                @touch($fileLocation);
index c7adcdf48dad7fdb50e4bfda92c600469e5eaa71..101e7f4be114cf99755b9f600719a46ff663b734 100644 (file)
@@ -1,10 +1,7 @@
 <?php
 namespace wcf\action;
-use wcf\data\user\notification\event\UserNotificationEvent;
-use wcf\data\user\User;
-use wcf\system\exception\IllegalLinkException;
+use wcf\form\NotificationUnsubscribeForm;
 use wcf\system\request\LinkHandler;
-use wcf\system\WCF;
 use wcf\util\HeaderUtil;
 use wcf\util\StringUtil;
 
@@ -15,6 +12,7 @@ use wcf\util\StringUtil;
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Action
+ * @deprecated 5.3 Replaced by NotificationUnsubscribeForm
  */
 class NotificationDisableAction extends AbstractAction {
        /**
@@ -23,24 +21,12 @@ class NotificationDisableAction extends AbstractAction {
         */
        public $eventID = 0;
        
-       /**
-        * notification event
-        * @var UserNotificationEvent
-        */
-       public $event = null;
-       
        /**
         * user id
         * @var integer
         */
        public $userID = 0;
        
-       /**
-        * user object
-        * @var User
-        */
-       public $user = null;
-       
        /**
         * security token
         * @var string
@@ -53,60 +39,15 @@ class NotificationDisableAction extends AbstractAction {
        public function readParameters() {
                parent::readParameters();
                
-               if (isset($_REQUEST['eventID'])) {
-                       $this->eventID = intval($_REQUEST['eventID']);
-                       
-                       $this->event = new UserNotificationEvent($this->eventID);
-                       if (!$this->event->eventID) {
-                               throw new IllegalLinkException();
-                       }
-               }
-               
+               if (isset($_REQUEST['eventID'])) $this->eventID = intval($_REQUEST['eventID']);
                if (isset($_REQUEST['userID'])) $this->userID = intval($_REQUEST['userID']);
-               $this->user = new User($this->userID);
-               if (!$this->user->userID) {
-                       throw new IllegalLinkException();
-               }
-               
                if (isset($_REQUEST['token'])) $this->token = StringUtil::trim($_REQUEST['token']);
-               if (empty($this->token) || !\hash_equals($this->user->notificationMailToken, $this->token)) {
-                       throw new IllegalLinkException();
-               }
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function execute() {
-               parent::execute();
-               
-               if ($this->event !== null) {
-                       $sql = "UPDATE  wcf".WCF_N."_user_notification_event_to_user
-                               SET     mailNotificationType = ?
-                               WHERE   userID = ?
-                                       AND eventID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute([
-                               'none',
-                               $this->userID,
-                               $this->eventID
-                       ]);
-               }
-               else {
-                       $sql = "UPDATE  wcf".WCF_N."_user_notification_event_to_user
-                               SET     mailNotificationType = ?
-                               WHERE   userID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute([
-                               'none',
-                               $this->userID
-                       ]);
-               }
-               
-               $this->executed();
-               
-               // redirect to url
-               HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->get('wcf.user.notification.mail.disabled'));
+
+               HeaderUtil::redirect(LinkHandler::getInstance()->getControllerLink(NotificationUnsubscribeForm::class, [
+                       'userID' => $this->userID,
+                       'eventID' => $this->eventID,
+                       'token' => $this->token,
+               ]));
                exit;
        }
 }
index 3c05b13b055fafd69ef59fba91679f205ba7814c..ac588e1646c4b19f7a1696232a6cf372444e2b19 100644 (file)
@@ -201,5 +201,7 @@ class PollAction extends AJAXProxyAction {
                }
                
                $returnValues['canVote'] = $this->poll->isChangeable ? 1 : 0;
+               $returnValues['totalVotes'] = $this->poll->votes;
+               $returnValues['totalVotesTooltip'] = WCF::getLanguage()->getDynamicVariable('wcf.poll.totalVotes', ['poll' => $this->poll]);
        }
 }
index e8652bff1f87d51c1ff67032b05a733b8f6effc1..a290eafef7f4048bfe3213714d44485a23ceb145 100644 (file)
@@ -5,6 +5,7 @@ use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\InvalidSecurityTokenException;
 use wcf\system\exception\NamedUserException;
 use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\exception\ValidateActionException;
 use wcf\system\WCF;
@@ -99,14 +100,19 @@ trait TAJAXException {
                        );
                }
                else {
+                       $returnValues = [
+                               'file' => $e->getFile(),
+                               'line' => $e->getLine(),
+                       ];
+                       if ($e instanceof SystemException && $e->getDescription()) {
+                               $returnValues['description'] = $e->getDescription();
+                       }
+                       
                        throw new AJAXException(
                                $e->getMessage(),
                                AJAXException::INTERNAL_ERROR,
                                $e->getTraceAsString(),
-                               [
-                                       'file' => $e->getFile(),
-                                       'line' => $e->getLine()
-                               ],
+                               $returnValues,
                                \wcf\functions\exception\logThrowable($e),
                                $e->getPrevious()
                        );
index 2f9d54f196822c489127f474db07261a57eab44c..c3485c6104dd15809d711f6262aa63d8343c07dd 100644 (file)
@@ -17,6 +17,16 @@ namespace {
        // set autoload function
        spl_autoload_register([WCF::class, 'autoload']);
        
+       spl_autoload_register(function ($className) {
+               /**
+                * @deprecated 5.3 This file is a compatibility layer mapping from Leafo\\ to ScssPhp\\
+                */
+               $leafo = 'Leafo\\';
+               if (substr($className, 0, strlen($leafo)) === $leafo) {
+                       class_alias('ScssPhp\\'.substr($className, strlen($leafo)), $className, true);
+               }
+       });
+       
        /**
         * Escapes a string for use in sql query.
         * 
@@ -103,6 +113,10 @@ namespace wcf {
                
                return $_SERVER[WCF_REQUEST_ID_HEADER] ?? '';
        }
+       
+       function getMinorVersion() {
+               return preg_replace('/^(\d+\.\d+)\..*$/', '\\1', WCF_VERSION);
+       }
 }
 
 namespace wcf\functions\exception {
@@ -127,12 +141,12 @@ namespace wcf\functions\exception {
                        return str_replace("\n", ' ', $item);
                };
                
-               // don't forget to update ExceptionLogViewPage, when changing the log file format
+               // don't forget to update ExceptionLogUtil / ExceptionLogViewPage, when changing the log file format
                $message = gmdate('r', TIME_NOW)."\n".
                        'Message: '.$stripNewlines($e->getMessage())."\n".
                        'PHP version: '.phpversion()."\n".
                        'WoltLab Suite version: '.WCF_VERSION."\n".
-                       'Request URI: '.$stripNewlines($_SERVER['REQUEST_URI'] ?? '').(\wcf\getRequestId() ? ' ('.\wcf\getRequestId().')' : '')."\n".
+                       'Request URI: '.$stripNewlines(($_SERVER['REQUEST_METHOD'] ?? '').' '.($_SERVER['REQUEST_URI'] ?? '')).(\wcf\getRequestId() ? ' ('.\wcf\getRequestId().')' : '')."\n".
                        'Referrer: '.$stripNewlines($_SERVER['HTTP_REFERER'] ?? '')."\n".
                        'User Agent: '.$stripNewlines($_SERVER['HTTP_USER_AGENT'] ?? '')."\n".
                        'Peak Memory Usage: '.memory_get_peak_usage().'/'.FileUtil::getMemoryLimit()."\n";
@@ -141,7 +155,7 @@ namespace wcf\functions\exception {
                        $message .= "======\n".
                        'Error Class: '.get_class($prev)."\n".
                        'Error Message: '.$stripNewlines($prev->getMessage())."\n".
-                       'Error Code: '.intval($prev->getCode())."\n".
+                       'Error Code: '.$stripNewlines($prev->getCode())."\n".
                        'File: '.$stripNewlines($prev->getFile()).' ('.$prev->getLine().')'."\n".
                        'Extra Information: '.($prev instanceof IExtraInformationException ? base64_encode(serialize($prev->getExtraInformation())) : '-')."\n".
                        'Stack Trace: '.json_encode(array_map(function ($item) {
@@ -457,7 +471,7 @@ EXPLANATION;
                                                        </li>
                                                        <li class="exceptionSystemInformation2">
                                                                <p class="exceptionFieldTitle">Request URI<span class="exceptionColon">:</span></p>
-                                                               <p class="exceptionFieldValue"><?php if (isset($_SERVER['REQUEST_URI'])) echo StringUtil::encodeHTML($_SERVER['REQUEST_URI']); ?></p>
+                                                               <p class="exceptionFieldValue"><?php if (isset($_SERVER['REQUEST_METHOD'])) echo StringUtil::encodeHTML($_SERVER['REQUEST_METHOD']); ?> <?php if (isset($_SERVER['REQUEST_URI'])) echo StringUtil::encodeHTML($_SERVER['REQUEST_URI']); ?></p>
                                                        </li>
                                                        <li class="exceptionSystemInformation4">
                                                                <p class="exceptionFieldTitle">Referrer<span class="exceptionColon">:</span></p>
@@ -499,7 +513,7 @@ EXPLANATION;
                                                        <?php if ($e->getCode()) { ?>
                                                                <li>
                                                                        <p class="exceptionFieldTitle">Error Code<span class="exceptionColon">:</span></p>
-                                                                       <p class="exceptionFieldValue"><?php echo intval($e->getCode()); ?></p>
+                                                                       <p class="exceptionFieldValue"><?php echo StringUtil::encodeHTML($e->getCode()); ?></p>
                                                                </li>
                                                        <?php } ?>
                                                        <li>
index 8cb29708a3b0d13f4f79d82df787fb7bc1000da3..8c8b7525377e247b4814406fb2339c3f09f2e60a 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 namespace wcf\data;
-use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\event\EventHandler;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\exception\SystemException;
@@ -15,7 +14,7 @@ use wcf\util\StringUtil;
  * Default implementation for DatabaseObject-related actions.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Data
  */
@@ -403,7 +402,7 @@ abstract class AbstractDatabaseObjectAction implements IDatabaseObjectAction, ID
        }
        
        /**
-        * Returns a single object and throws an UserInputException if no or more than one object is given.
+        * Returns a single object and throws a UserInputException if no or more than one object is given.
         * 
         * @return      DatabaseObject
         * @throws      UserInputException
@@ -564,7 +563,7 @@ abstract class AbstractDatabaseObjectAction implements IDatabaseObjectAction, ID
                                else {
                                        if ($structure === self::STRUCT_FLAT) {
                                                $target[$variableName] = StringUtil::trim($target[$variableName]);
-                                               if (!$allowEmpty && empty($target[$variableName])) {
+                                               if (!$allowEmpty && $target[$variableName] === '') {
                                                        throw new UserInputException($variableName);
                                                }
                                        }
@@ -575,7 +574,7 @@ abstract class AbstractDatabaseObjectAction implements IDatabaseObjectAction, ID
                                                }
                                                
                                                for ($i = 0, $length = count($target[$variableName]); $i < $length; $i++) {
-                                                       if (empty($target[$variableName][$i])) {
+                                                       if ($target[$variableName][$i] === '') {
                                                                throw new UserInputException($variableName);
                                                        }
                                                }
index 19cea93519119114ee2363d7b242f70d38e37cd8..107e989ad5f48ac378204bb0cc027667685134aa 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data;
+use wcf\system\database\exception\DatabaseQueryExecutionException;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\WCF;
 
@@ -123,4 +124,25 @@ abstract class DatabaseObjectEditor extends DatabaseObjectDecorator implements I
                
                return $affectedCount;
        }
+       
+       /**
+        * Creates a new object, returns null if the row already exists.
+        *
+        * @param       array   $parameters
+        * @return      IStorableObject|null
+        * @since       5.3
+        */
+       public static function createOrIgnore(array $parameters = []) {
+               try {
+                       return static::create($parameters);
+               }
+               catch (DatabaseQueryExecutionException $e) {
+                       // Error code 23000 = duplicate key
+                       if ($e->getCode() == '23000' && $e->getDriverCode() == '1062') {
+                               return null;
+                       }
+                       
+                       throw $e;
+               }
+       }
 }
index 3078a0caf20f1e98a27b9cded6056374e3f9e332..3879c6f8836877cd8fceea0d3746274ec9cd1158 100644 (file)
@@ -252,6 +252,16 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                return $this->conditionBuilder;
        }
        
+       /**
+        * Sets the condition builder dynamically.
+        * 
+        * @param       PreparedStatementConditionBuilder $conditionBuilder
+        * @since       5.3
+        */
+       public function setConditionBuilder(PreparedStatementConditionBuilder $conditionBuilder) {
+               $this->conditionBuilder = $conditionBuilder;
+       }
+       
        /**
         * Returns the name of the database table.
         * 
@@ -359,4 +369,22 @@ abstract class DatabaseObjectList implements \Countable, ITraversableObject {
                        return null;
                }
        }
+       
+       /**
+        * Returns the only object in this list or `null` if the list is empty.
+        * 
+        * @return      DatabaseObject|null
+        * @throws      \BadMethodCallException         if list contains more than one object
+        */
+       public function getSingleObject() {
+               if (count($this->objects) > 1) {
+                       throw new \BadMethodCallException("Cannot get a single object when the list contains " . count($this->objects) . " objects.");
+               }
+               
+               if (empty($this->objects)) {
+                       return null;
+               }
+               
+               return reset($this->objects);
+       }
 }
diff --git a/wcfsetup/install/files/lib/data/IPopoverAction.class.php b/wcfsetup/install/files/lib/data/IPopoverAction.class.php
new file mode 100644 (file)
index 0000000..2992e0b
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+namespace wcf\data;
+
+/**
+ * Every object action that provides popover previews for database objects has to implement this interface.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Data
+ * @since      5.3
+ */
+interface IPopoverAction {
+       /**
+        * Validates the `getPopover` action.
+        */
+       public function validateGetPopover();
+       
+       /**
+        * Returns the requested popover for a specific object.
+        * 
+        * Return value:
+        *      [
+        *              'template' => '...'
+        *      ]
+        * 
+        * @return      string[]
+        */
+       public function getPopover();
+}
diff --git a/wcfsetup/install/files/lib/data/IPopoverObject.class.php b/wcfsetup/install/files/lib/data/IPopoverObject.class.php
new file mode 100644 (file)
index 0000000..b3404a8
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace wcf\data;
+
+/**
+ * Database objects that support links with preview popovers via `WoltLabSuite/Core/Controller/Popover`
+ * can implement this interface so that when the `anchor` template plugin is used and the CSS class name
+ * returned by `getPopoverLinkClass()` is given, the `data-object-id` attribute is automatically added
+ * to support the preview popover.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Data
+ * @since      5.3
+ */
+interface IPopoverObject extends IIDObject, ITitledLinkObject {
+       /**
+        * Returns the CSS class that objects of this type use for popover links.
+        * 
+        * @return      string
+        */
+       public function getPopoverLinkClass();
+}
index e19f16eb0c63d3bf9528a5a018b7c8d721441fe9..d44c02325cfa5d675090e9b210a0edc12d4b3a98 100644 (file)
@@ -104,7 +104,9 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                                        'teaser' => $content['teaser'],
                                        'content' => $content['content'],
                                        'imageID' => $content['imageID'],
-                                       'teaserImageID' => $content['teaserImageID']
+                                       'teaserImageID' => $content['teaserImageID'],
+                                       'metaTitle' => $content['metaTitle'] ?? '',
+                                       'metaDescription' => $content['metaDescription'] ?? '',
                                ]);
                                $articleContentEditor = new ArticleContentEditor($articleContent);
                                
@@ -191,7 +193,9 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                                                        'teaser' => $content['teaser'],
                                                        'content' => $content['content'],
                                                        'imageID' => ($isRevert) ? $articleContent->imageID : $content['imageID'],
-                                                       'teaserImageID' => ($isRevert) ? $articleContent->teaserImageID : $content['teaserImageID']
+                                                       'teaserImageID' => ($isRevert) ? $articleContent->teaserImageID : $content['teaserImageID'],
+                                                       'metaTitle' => $content['metaTitle'] ?? '',
+                                                       'metaDescription' => $content['metaDescription'] ?? '',
                                                ]);
                                                
                                                $versionData[] = $articleContent;
@@ -213,7 +217,9 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                                                        'teaser' => $content['teaser'],
                                                        'content' => $content['content'],
                                                        'imageID' => ($isRevert) ? null : $content['imageID'],
-                                                       'teaserImageID' => ($isRevert) ? null : $content['teaserImageID']
+                                                       'teaserImageID' => ($isRevert) ? null : $content['teaserImageID'],
+                                                       'metaTitle' => $content['metaTitle'] ?? '',
+                                                       'metaDescription' => $content['metaDescription'] ?? '',
                                                ]);
                                                $articleContentEditor = new ArticleContentEditor($articleContent);
                                                
@@ -313,6 +319,22 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                                ArticleEditor::updateArticleCounter($usersToArticles);
                        }
                }
+               
+               // update author in recent activities
+               if (isset($this->parameters['data']['userID'])) {
+                       $sql = "UPDATE wcf".WCF_N."_user_activity_event SET userID = ? WHERE objectTypeID = ? AND objectID = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       
+                       foreach ($this->objects as $articleEditor) {
+                               if ($articleEditor->userID != $this->parameters['data']['userID']) {
+                                       $statement->execute([
+                                               $this->parameters['data']['userID'],
+                                               UserActivityEventHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.article.recentActivityEvent'),
+                                               $articleEditor->articleID,
+                                       ]);
+                               }
+                       }
+               }
        }
        
        /**
index 1661cc337ba76d688ba1efc4c8797bce51ba5318..c0be84f5130afb808cfeaee718c815848f8e2903 100644 (file)
@@ -1,6 +1,11 @@
 <?php
 namespace wcf\data\article;
+use wcf\data\like\Like;
 use wcf\data\like\object\AbstractLikeObject;
+use wcf\data\reaction\object\IReactionObject;
+use wcf\system\user\notification\object\LikeUserNotificationObject;
+use wcf\system\user\notification\UserNotificationHandler;
+use wcf\system\WCF;
 
 /**
  * Likeable object implementation for cms articles.
@@ -14,7 +19,7 @@ use wcf\data\like\object\AbstractLikeObject;
  * @method     Article getDecoratedObject()
  * @mixin      Article
  */
-class LikeableArticle extends AbstractLikeObject {
+class LikeableArticle extends AbstractLikeObject implements IReactionObject {
        /**
         * @inheritDoc
         */
@@ -65,4 +70,20 @@ class LikeableArticle extends AbstractLikeObject {
        public function getLanguageID() {
                return null;
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function sendNotification(Like $like) {
+               if ($this->getDecoratedObject()->userID != WCF::getUser()->userID) {
+                       $notificationObject = new LikeUserNotificationObject($like);
+                       UserNotificationHandler::getInstance()->fireEvent(
+                               'like',
+                               'com.woltlab.wcf.likeableArticle.notification',
+                               $notificationObject,
+                               [$this->getDecoratedObject()->userID],
+                               ['objectID' => $this->getDecoratedObject()->entryID]
+                       );
+               }
+       }
 }
index 88e3bdfafb7b5b49ac631078ba737874edeb98e5..4eea05fccf490bc3a3dc2cc2d3e71fafa36f7cb8 100644 (file)
@@ -71,7 +71,9 @@ class LikeableArticleProvider extends AbstractObjectTypeProvider implements ILik
                                // short output
                                $text = WCF::getLanguage()->getDynamicVariable('wcf.like.title.com.woltlab.wcf.likeableArticle', [
                                        'article' => $article,
-                                       'like' => $like
+                                       'reaction' => $like,
+                                       // @deprecated 5.3 Use `$reaction` instead
+                                       'like' => $like,
                                ]);
                                $like->setTitle($text);
                                
index 448bf072d830d3e14266bb565fa1bddc08cc098a..1984151c1ca9fab8464dedd3c1c8ab49452bb1da 100644 (file)
@@ -84,9 +84,8 @@ class ViewableArticle extends DatabaseObjectDecorator {
                $list->enableContentLoading($enableContentLoading);
                $list->setObjectIDs([$articleID]);
                $list->readObjects();
-               $objects = $list->getObjects();
-               if (isset($objects[$articleID])) return $objects[$articleID];
-               return null;
+               
+               return $list->getSingleObject();
        }
        
        /**
index da65861685c1dcc60a96832cee1f96af214809d0..cd83d7b7e0e3a27318d9b958153eef822d698753 100644 (file)
@@ -30,6 +30,8 @@ use wcf\util\StringUtil;
  * @property-read      integer|null    $imageID                id of the (image) media object used as article image for the associated language or `null` if no image is used
  * @property-read      integer|null    $teaserImageID          id of the (image) media object used as article teaser image for the associated language or `null` if no image is used                                      
  * @property-read      integer         $hasEmbeddedObjects     is `1` if there are embedded objects in the article content, otherwise `0`
+ * @property-read       string          $metaTitle              title of the article used in the title tag
+ * @property-read       string          $metaDescription        meta description of the article
  */
 class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteController {
        /**
@@ -61,7 +63,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
        }
        
        /**
-        * Returns the article's unformatted content.
+        * Returns the article's unformatted teaser.
         *
         * @return      string
         */
@@ -70,7 +72,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
        }
        
        /**
-        * Returns the article's formatted content.
+        * Returns the article's formatted teaser.
         *
         * @return      string
         */
@@ -81,6 +83,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
                else {
                        $htmlOutputProcessor = new HtmlOutputProcessor();
                        $htmlOutputProcessor->setOutputType('text/plain');
+                       $htmlOutputProcessor->enableUgc = false;
                        $htmlOutputProcessor->process($this->content, 'com.woltlab.wcf.article.content', $this->articleContentID, false, $this->languageID);
                        
                        return nl2br(StringUtil::encodeHTML(StringUtil::truncate($htmlOutputProcessor->getHtml(), 500)), false);
@@ -94,6 +97,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
         */
        public function getFormattedContent() {
                $processor = new HtmlOutputProcessor();
+               $processor->enableUgc = false;
                $processor->process($this->content, 'com.woltlab.wcf.article.content', $this->articleContentID, false, $this->languageID);
                
                return $processor->getHtml();
@@ -106,6 +110,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
         */
        public function getAmpFormattedContent() {
                $processor = new AmpHtmlOutputProcessor();
+               $processor->enableUgc = false;
                $processor->process($this->content, 'com.woltlab.wcf.article.content', $this->articleContentID);
                
                return $processor->getHtml();
@@ -149,6 +154,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
                        case 'text/plain':
                                $processor = new HtmlOutputProcessor();
                                $processor->setOutputType('text/plain');
+                               $processor->enableUgc = false;
                                $processor->process($this->content, 'com.woltlab.wcf.article.content', $this->articleContentID);
                                
                                return $processor->getHtml();
@@ -156,6 +162,7 @@ class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteCo
                                // parse and return message
                                $processor = new HtmlOutputProcessor();
                                $processor->setOutputType('text/simplified-html');
+                               $processor->enableUgc = false;
                                $processor->process($this->content, 'com.woltlab.wcf.article.content', $this->articleContentID);
                                
                                return $processor->getHtml();
index f7bae162cb77a8f1d1d2e3bf943dcbc33eee7b68..bc2f61ab06c87cc4bbe6b2d5a8949e984ba65867 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\attachment;
+use wcf\data\ILinkableObject;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\data\DatabaseObject;
 use wcf\data\IThumbnailFile;
@@ -42,7 +43,7 @@ use wcf\util\StringUtil;
  * @property-read      integer         $uploadTime             timestamp at which the attachment has been uploaded
  * @property-read      integer         $showOrder              position of the attachment in relation to the other attachment to the same message
  */
-class Attachment extends DatabaseObject implements IRouteController, IThumbnailFile {
+class Attachment extends DatabaseObject implements ILinkableObject, IRouteController, IThumbnailFile {
        /**
         * indicates if the attachment is embedded
         * @var boolean
@@ -55,6 +56,17 @@ class Attachment extends DatabaseObject implements IRouteController, IThumbnailF
         */
        protected $permissions = [];
        
+       /**
+        * @inheritDoc
+        */
+       public function getLink() {
+               // Do not use `LinkHandler::getControllerLink()` or `forceFrontend` as attachment
+               // links can be opened in the frontend and in the ACP.
+               return LinkHandler::getInstance()->getLink('Attachment', [
+                       'object' => $this,
+               ]);
+       }
+       
        /**
         * Returns true if a user has the permission to download this attachment.
         * 
@@ -197,6 +209,9 @@ class Attachment extends DatabaseObject implements IRouteController, IThumbnailF
                if ($size == 'tiny') {
                        $parameters['tiny'] = 1;
                }
+               else if ($size == 'thumbnail') {
+                       $parameters['thumbnail'] = 1;
+               }
                
                return LinkHandler::getInstance()->getLink('Attachment', $parameters);
        }
@@ -231,7 +246,7 @@ class Attachment extends DatabaseObject implements IRouteController, IThumbnailF
         */
        public function showAsImage() {
                if ($this->isImage) {
-                       if (ATTACHMENT_ENABLE_THUMBNAILS && !$this->hasThumbnail() && ($this->width > ATTACHMENT_THUMBNAIL_WIDTH || $this->height > ATTACHMENT_THUMBNAIL_HEIGHT)) return false;
+                       if (!$this->hasThumbnail() && ($this->width > ATTACHMENT_THUMBNAIL_WIDTH || $this->height > ATTACHMENT_THUMBNAIL_HEIGHT)) return false;
                        
                        if ($this->canDownload()) return true;
                        
index ab45a063f3789268ed22cb88dae2698b916896c6..d7b5b08884fa95cf745d733aeba050c884d432b3 100644 (file)
@@ -9,7 +9,6 @@ use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\event\EventHandler;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\exception\UserInputException;
-use wcf\system\request\LinkHandler;
 use wcf\system\upload\DefaultUploadFileSaveStrategy;
 use wcf\system\upload\DefaultUploadFileValidationStrategy;
 use wcf\system\upload\UploadFile;
@@ -116,7 +115,7 @@ class AttachmentAction extends AbstractDatabaseObjectAction implements ISortable
                $handler = new AttachmentHandler($this->parameters['objectType'], intval($this->parameters['objectID']), $this->parameters['tmpHash']);
                /** @noinspection PhpUndefinedMethodInspection */
                if ($handler->count() + count($this->parameters['__files']->getFiles()) > $processor->getMaxCount()) {
-                       throw new UserInputException('files', 'exceededQuota', [
+                       throw new UserInputException('files', 'reachedLimit', [
                                'current' => $handler->count(),
                                'quota' => $processor->getMaxCount()
                        ]);
@@ -136,7 +135,7 @@ class AttachmentAction extends AbstractDatabaseObjectAction implements ISortable
                
                // save files
                $saveStrategy = new DefaultUploadFileSaveStrategy(self::class, [
-                       'generateThumbnails' => ATTACHMENT_ENABLE_THUMBNAILS,
+                       'generateThumbnails' => true,
                        'rotateImages' => true
                ], [
                        'objectID' => intval($this->parameters['objectID']),
@@ -172,9 +171,9 @@ class AttachmentAction extends AbstractDatabaseObjectAction implements ISortable
                                        'formattedFilesize' => FileUtil::formatFilesize($attachment->filesize),
                                        'isImage' => $attachment->isImage,
                                        'attachmentID' => $attachment->attachmentID,
-                                       'tinyURL' => $attachment->tinyThumbnailType ? LinkHandler::getInstance()->getLink('Attachment', ['object' => $attachment], 'tiny=1') : '',
-                                       'thumbnailURL' => $attachment->thumbnailType ? LinkHandler::getInstance()->getLink('Attachment', ['object' => $attachment], 'thumbnail=1') : '',
-                                       'url' => LinkHandler::getInstance()->getLink('Attachment', ['object' => $attachment]),
+                                       'tinyURL' => $attachment->tinyThumbnailType ? $attachment->getThumbnailLink('tiny') : '',
+                                       'thumbnailURL' => $attachment->thumbnailType ? $attachment->getThumbnailLink('thumbnail') : '',
+                                       'url' => $attachment->getLink(),
                                        'height' => $attachment->height,
                                        'width' => $attachment->width,
                                        'iconName' => $attachment->getIconName()
index f920be955b55fa49ac2dfe2e47863ba292023857..9d74756472372729d647c20a800a1ac378c607f7 100644 (file)
@@ -5,13 +5,15 @@ use wcf\system\bbcode\media\provider\IBBCodeMediaProvider;
 use wcf\system\cache\builder\BBCodeMediaProviderCacheBuilder;
 use wcf\system\request\IRouteController;
 use wcf\system\Regex;
+use wcf\system\WCF;
 use wcf\util\StringUtil;
+use wcf\util\Url;
 
 /**
  * Represents a BBCode media provider.
  * 
  * @author     Tim Duesterhus
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Data\Bbcode\Media\Provider
  *
@@ -98,14 +100,14 @@ class BBCodeMediaProvider extends DatabaseObject implements IRouteController {
                        if (!$regex->match($url)) continue;
                        
                        if ($this->getCallback() !== null) {
-                               return $this->getCallback()->parse($url, $regex->getMatches());
+                               return $this->getOutputForUserConsent($url, $this->getCallback()->parse($url, $regex->getMatches()));
                        }
                        else {
                                $output = $this->html;
                                foreach ($regex->getMatches() as $name => $value) {
                                        $output = str_replace('{$' . $name . '}', $value, $output);
                                }
-                               return $output;
+                               return $this->getOutputForUserConsent($url, $output);
                        }
                }
                
@@ -133,4 +135,27 @@ class BBCodeMediaProvider extends DatabaseObject implements IRouteController {
                
                return $this->callback;
        }
+       
+       /**
+        * Replaces embedded media with an approval dialog.
+        * 
+        * @param string $url
+        * @param string $html
+        * @return string
+        */
+       protected function getOutputForUserConsent($url, $html) {
+               if (!MESSAGE_ENABLE_USER_CONSENT) {
+                       return $html;
+               }
+               
+               if (WCF::getUser()->userID && WCF::getUser()->getUserOption('enableEmbeddedMedia')) {
+                       return $html;
+               }
+               
+               return WCF::getTPL()->fetch('messageUserConsent', 'wcf', [
+                       'host' => Url::parse($url)['host'],
+                       'payload' => base64_encode($html),
+                       'url' => $url,
+               ]);
+       }
 }
index c09ae8ec2a56ed790aadfb6f165a87074f12b3d8..eb46f3b1bb4bbb2c7b6d24209277c97a213c8070 100644 (file)
@@ -103,6 +103,7 @@ class BoxContent extends DatabaseObject {
         */
        public function getFormattedContent() {
                $processor = new HtmlOutputProcessor();
+               $processor->enableUgc = false;
                $processor->process($this->content, 'com.woltlab.wcf.box.content', $this->boxContentID);
                
                return $processor->getHtml();
index c253d224c26b488c3d06da8b1b1c88132fe8f5c9..062c8575e6f522e1b352e89759a53926a0600b42 100644 (file)
@@ -58,8 +58,7 @@ class ViewableComment extends DatabaseObjectDecorator {
                $list = new ViewableCommentList();
                $list->setObjectIDs([$commentID]);
                $list->readObjects();
-               $objects = $list->getObjects();
-               if (isset($objects[$commentID])) return $objects[$commentID];
-               return null;
+               
+               return $list->getSingleObject();
        }
 }
index dd803ade89ef7f2d4683ff9abbcd135cead819d7..9e98895d7f73fa26e1d1118fba3cce30c8204a05 100644 (file)
@@ -58,8 +58,7 @@ class ViewableCommentResponse extends DatabaseObjectDecorator {
                $list = new ViewableCommentResponseList();
                $list->setObjectIDs([$responseID]);
                $list->readObjects();
-               $objects = $list->getObjects();
-               if (isset($objects[$responseID])) return $objects[$responseID];
-               return null;
+               
+               return $list->getSingleObject();
        }
 }
index 042990c0910a306d1280a2c4d32569f5f4e4b200..21ecda03bab4908cef9fefd78a1cbf481f522f43 100644 (file)
@@ -111,7 +111,7 @@ class ContactOptionAction extends CustomOptionAction implements ISortableAction
                
                // build mail
                $email = new Email();
-               $email->addRecipient(new Mailbox($recipient->email));
+               $email->addRecipient($recipient->getMailbox());
                $email->setSubject($defaultLanguage->get('wcf.contact.mail.subject'));
                $email->setBody(new MimePartFacade([
                        new RecipientAwareTextMimePart('text/html', 'email_contact', 'wcf', $messageData),
index 457c26cf4f36fd49ccd3e90a23cee8a4159a591e..c4cd24a1027ded0e98228c4f40d19cce1216324a 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\data\contact\recipient;
 use wcf\data\DatabaseObject;
+use wcf\system\email\Mailbox;
 use wcf\system\WCF;
 
 /**
@@ -37,7 +38,7 @@ class ContactRecipient extends DatabaseObject {
         * @inheritDoc
         */
        public function __toString() {
-               return WCF::getLanguage()->get($this->name);
+               return $this->getName();
        }
        
        /**
@@ -49,4 +50,34 @@ class ContactRecipient extends DatabaseObject {
                        $this->data['isAdministrator'] = MAIL_ADMIN_ADDRESS;
                }
        }
+       
+       /**
+        * Returns the localized name of this recipient.
+        * 
+        * @since 5.3
+        */
+       public function getName() {
+               return WCF::getLanguage()->get($this->name);
+       }
+       
+       /**
+        * Returns the localized email address of this recipient.
+        * 
+        * @since 5.3
+        */
+       public function getEmail() {
+               return WCF::getLanguage()->get($this->email);
+       }
+       
+       /**
+        * Returns a localized Mailbox for this recipient.
+        * 
+        * @since 5.3
+        */
+       public function getMailbox() {
+               return new Mailbox(
+                       $this->getEmail(),
+                       $this->getName()
+               );
+       }
 }
diff --git a/wcfsetup/install/files/lib/data/cronjob/I18nCronjobList.class.php b/wcfsetup/install/files/lib/data/cronjob/I18nCronjobList.class.php
new file mode 100644 (file)
index 0000000..8e59a9d
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+namespace wcf\data\cronjob;
+use wcf\data\I18nDatabaseObjectList;
+
+/**
+ * I18n implementation of cronjob list.
+ *
+ * @author     Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Data\Cronjob
+ * @since       5.3
+ *
+ * @method     Cronjob         current()
+ * @method     Cronjob[]       getObjects()
+ * @method     Cronjob|null    search($objectID)
+ * @property   Cronjob[]       $objects
+ */
+class I18nCronjobList extends I18nDatabaseObjectList {
+       /**
+        * @inheritDoc
+        */
+       public $i18nFields = ['description' => 'descriptionI18n'];
+       
+       /**
+        * @inheritDoc
+        */
+       public $className = Cronjob::class;
+}
index 9db43c0a83e06b504aa50911832274391daa5a9d..33e764db14a6d56b463982a274ce7d995d4c8e0f 100644 (file)
@@ -177,7 +177,7 @@ abstract class CustomOption extends Option implements ITitledObject {
                        
                        /** @noinspection PhpMissingBreakStatementInspection */
                        case 'URL':
-                               if (!$forcePlaintext) return StringUtil::getAnchorTag($this->optionValue);
+                               if (!$forcePlaintext) return StringUtil::getAnchorTag($this->optionValue, '', true, true);
                                // fallthrough
                                
                        default:
diff --git a/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItem.class.php b/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItem.class.php
new file mode 100644 (file)
index 0000000..243582f
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+namespace wcf\data\devtools\missing\language\item;
+use wcf\data\DatabaseObject;
+use wcf\data\language\Language;
+use wcf\system\language\LanguageFactory;
+use wcf\system\WCF;
+use wcf\util\JSON;
+
+/**
+ * Represents a missing language item log entry.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Devtools\Missing\Language\Item
+ * @since      5.3
+ * 
+ * @property-read      integer         $itemID         unique id of the missing language item log entry
+ * @property-read      integer         $languageID     id of the language the missing language item was requested for
+ * @property-read      string          $languageItem   name of the missing language item
+ * @property-read      integer         $lastTime       timestamp of the last time the missing language item was requested
+ * @property-read      string          $stackTrace     stack trace of how the missing language item was requested for the last time
+ */
+class DevtoolsMissingLanguageItem extends DatabaseObject {
+       /**
+        * Returns the language the missing language item was requested for or `null` if the language
+        * does not exist anymore.
+        * 
+        * @return      null|Language
+        */
+       public function getLanguage() {
+               if ($this->languageID === null) {
+                       return null;
+               }
+               
+               return LanguageFactory::getInstance()->getLanguage($this->languageID);
+       }
+       
+       /**
+        * Returns the formatted stack trace of how the missing language item was requested for the
+        * last time.
+        * 
+        * @return      string
+        */
+       public function getStackTrace() {
+               $stackTrace = JSON::decode($this->stackTrace);
+               foreach ($stackTrace as &$stackEntry) {
+                       foreach ($stackEntry['args'] as &$stackEntryArg) {
+                               if (gettype($stackEntryArg) === 'string') {
+                                       $stackEntryArg = str_replace(["\n", "\t"], ['\n', '\t'], $stackEntryArg);
+                               }
+                       }
+                       unset($stackEntryArg);
+               }
+               unset($stackEntry);
+               
+               return WCF::getTPL()->fetch('__devtoolsMissingLanguageItemStackTrace', 'wcf', [
+                       'stackTrace' => $stackTrace,
+               ]);
+       }
+}
diff --git a/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemAction.class.php b/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemAction.class.php
new file mode 100644 (file)
index 0000000..afc3865
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+namespace wcf\data\devtools\missing\language\item;
+use wcf\data\AbstractDatabaseObjectAction;
+use wcf\data\IDeleteAction;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\WCF;
+use wcf\util\JSON;
+use function wcf\functions\exception\sanitizeStacktrace;
+
+/**
+ * Executes missing language item log entry-related actions.
+ *
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Devtools\Missing\Language\Item
+ * @since      5.3
+ * 
+ * @method     DevtoolsMissingLanguageItemEditor[]     getObjects()
+ * @method     DevtoolsMissingLanguageItemEditor       getSingleObject()
+ */
+class DevtoolsMissingLanguageItemAction extends AbstractDatabaseObjectAction implements IDeleteAction {
+       /**
+        * @inheritDoc
+        */
+       protected $permissionsDelete = ['admin.configuration.package.canInstallPackage'];
+       
+       /**
+        * Logs a missing language item.
+        */
+       public function logLanguageItem() {
+               $stackTraceData = sanitizeStacktrace(new \Exception(), true);
+               // Remove stack entries related to logging.
+               array_shift($stackTraceData);
+               array_shift($stackTraceData);
+               array_shift($stackTraceData);
+               $stackTrace = JSON::encode($stackTraceData);
+               
+               $sql = "INSERT INTO             wcf" . WCF_N . "_devtools_missing_language_item
+                                               (languageID, languageItem, lastTime, stackTrace)
+                       VALUES                  (?, ?, ?, ?)
+                       ON DUPLICATE KEY
+                       UPDATE                  lastTime = ?,
+                                               stackTrace = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute([
+                       $this->parameters['language']->languageID,
+                       $this->parameters['languageItem'],
+                       TIME_NOW,
+                       $stackTrace,
+                       
+                       TIME_NOW,
+                       $stackTrace,
+               ]);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validateDelete() {
+               if (!ENABLE_DEVELOPER_TOOLS || !LOG_MISSING_LANGUAGE_ITEMS) {
+                       throw new IllegalLinkException();
+               }
+               
+               parent::validateDelete();
+       }
+       
+       /**
+        * Validates the `clearLog` action.
+        */
+       public function validateClearLog() {
+               if (!ENABLE_DEVELOPER_TOOLS || !LOG_MISSING_LANGUAGE_ITEMS) {
+                       throw new IllegalLinkException();
+               }
+               
+               WCF::getSession()->checkPermissions(['admin.configuration.package.canInstallPackage']);
+       }
+       
+       /**
+        * Removes all entries from the missing language item log.
+        */
+       public function clearLog() {
+               $sql = "DELETE FROM     wcf" . WCF_N . "_devtools_missing_language_item";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute();
+       }
+}
diff --git a/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemEditor.class.php b/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemEditor.class.php
new file mode 100644 (file)
index 0000000..4204723
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace wcf\data\devtools\missing\language\item;
+use wcf\data\DatabaseObjectEditor;
+
+/**
+ * Provides functions to edit missing language item log entry.
+ *
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Devtools\Missing\Language\Item
+ * @since      5.3
+ *
+ * @method static      DevtoolsMissingLanguageItem     create(array $parameters = [])
+ * @method             DevtoolsMissingLanguageItem     getDecoratedObject()
+ * @mixin              DevtoolsMissingLanguageItem
+ */
+class DevtoolsMissingLanguageItemEditor extends DatabaseObjectEditor {
+       /**
+        * @inheritDoc
+        */
+       protected static $baseClass = DevtoolsMissingLanguageItem::class;
+}
diff --git a/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemList.class.php b/wcfsetup/install/files/lib/data/devtools/missing/language/item/DevtoolsMissingLanguageItemList.class.php
new file mode 100644 (file)
index 0000000..bd53415
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+namespace wcf\data\devtools\missing\language\item;
+use wcf\data\DatabaseObjectList;
+
+/**
+ * Represents a list of missing language item log entries.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Devtools\Missing\Language\Item
+ * @since      5.3
+ * 
+ * @method     DevtoolsMissingLanguageItem             current()
+ * @method     DevtoolsMissingLanguageItem[]           getObjects()
+ * @method     DevtoolsMissingLanguageItem             getSingleObject()
+ * @method     DevtoolsMissingLanguageItem|null        search($objectID)
+ * @property   DevtoolsMissingLanguageItem[]           $objects
+ */
+class DevtoolsMissingLanguageItemList extends DatabaseObjectList {}
index c21077b3b916914e7b08958b4555d0f2ad14900a..b5d745b1e342043fd7827c6135052ee242a0d6a5 100644 (file)
@@ -14,7 +14,7 @@ use wcf\data\TDatabaseObjectPermissions;
  *
  * @property-read      integer         $listenerID             unique id of the event listener
  * @property-read      integer         $packageID              id of the package which delivers the event listener
- * @property-read      string          $environment            environment in which the event listener is executed, possible values: 'user' or 'admin'
+ * @property-read      string          $environment            environment in which the event listener is executed, possible values: 'all', 'user' or 'admin'
  * @property-read      string          $listenerName           name and textual identifier of the event listener
  * @property-read      string          $eventClassName         name of the class in which the listened event is fired
  * @property-read      string          $eventName              name of the listened event
index 2d63925f876bbd4296e31ad304e3eec8e9722c7a..dbfbe56584709b85b45219fe66c28dcf9362113e 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\data\label;
 use wcf\data\DatabaseObject;
 use wcf\system\request\IRouteController;
 use wcf\system\WCF;
+use wcf\util\StringUtil;
 
 /**
  * Represents a label.
@@ -48,4 +49,17 @@ class Label extends DatabaseObject implements IRouteController {
                
                return $this->cssClassName;
        }
+       
+       /**
+        * Returns the HTML representation of the label.
+        * 
+        * @param       string          $additionalClasses
+        * @return      string
+        * @since       5.3
+        */
+       public function render($additionalClasses = '') {
+               return '<span class="badge label' . ($this->getClassNames() ? ' ' . $this->getClassNames() : '')
+                       . ($additionalClasses ? ' ' . $additionalClasses : '') . '">'
+                       . StringUtil::encodeHTML($this->getTitle()) . '</span>';
+       }
 }
index 448bac6df079523ef5702a77674503244b479f4a..2e8a8379454a69b0c259a3e8b87ba42de91d519e 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\data\language;
 use wcf\data\DatabaseObject;
+use wcf\data\devtools\missing\language\item\DevtoolsMissingLanguageItemAction;
 use wcf\system\language\LanguageFactory;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
@@ -46,6 +47,12 @@ class Language extends DatabaseObject {
         */
        public $packageID = PACKAGE_ID;
        
+       /**
+        * contains categories currently being loaded as array keys
+        * @var bool[]
+        */
+       protected $categoriesBeingLoaded = [];
+       
        /**
         * Returns the name of this language.
         * 
@@ -123,11 +130,10 @@ class Language extends DatabaseObject {
                        LOG_MISSING_LANGUAGE_ITEMS &&
                        preg_match('~^([a-zA-Z0-9-_]+\.)+[a-zA-Z0-9-_]+$~', $item)
                ) {
-                       $logFile = WCF_DIR . 'log/missingLanguageItems.txt';
-                       \wcf\functions\exception\logThrowable(
-                               new \Exception("Missing language item '{$item}'."),
-                               $logFile
-                       );
+                       (new DevtoolsMissingLanguageItemAction([], 'logLanguageItem', [
+                               'language' => $this,
+                               'languageItem' => $item,
+                       ]))->executeAction();
                }
                
                // return plain input
@@ -161,11 +167,10 @@ class Language extends DatabaseObject {
                        $staticItem === $item &&
                        preg_match('~^([a-zA-Z0-9-_]+\.)+[a-zA-Z0-9-_]+$~', $item)
                ) {
-                       $logFile = WCF_DIR . 'log/missingLanguageItems.txt';
-                       \wcf\functions\exception\logThrowable(
-                               new \Exception("Missing language item '{$item}'."),
-                               $logFile
-                       );
+                       (new DevtoolsMissingLanguageItemAction([], 'logLanguageItem', [
+                               'language' => $this,
+                               'languageItem' => $item,
+                       ]))->executeAction();
                }
                
                return $staticItem;
@@ -210,6 +215,10 @@ class Language extends DatabaseObject {
                // search language file
                $filename = WCF_DIR.'language/'.$this->languageID.'_'.$category.'.php';
                if (!@file_exists($filename)) {
+                       if (isset($this->categoriesBeingLoaded[$category])) {
+                               throw new \LogicException("Circular dependency detected! Cannot load category '{$category}' while it is already being loaded.");
+                       }
+                       
                        if ($this->editor === null) {
                                $this->editor = new LanguageEditor($this);
                        }
@@ -220,7 +229,11 @@ class Language extends DatabaseObject {
                                return false;
                        }
                        
+                       $this->categoriesBeingLoaded[$category] = true;
+                       
                        $this->editor->updateCategory($languageCategory);
+                       
+                       unset($this->categoriesBeingLoaded[$category]);
                }
                
                // include language file
index fa1bd3f10ca31e4fe5a252b898578a71b9adcf86..0ae36115a4e6e4f63e85bec72a3fa2a9e021d352 100644 (file)
@@ -328,6 +328,10 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje
                                                ));
                                        }
                                        
+                                       if (StringUtil::trim($itemName) !== $itemName) {
+                                               throw new \InvalidArgumentException("The name '{$itemName}' contains leading or trailing whitespaces.");
+                                       }
+                                       
                                        $itemValue = $element->nodeValue;
                                        
                                        $itemData[] = $this->languageID;
index 1adcfc2a9b64fc0fe1cbe7f3d49c6bf4fab22104..7f7038467525d811808d357ff130fe3e69dba9a5 100644 (file)
@@ -4,6 +4,7 @@ use wcf\data\reaction\type\ReactionType;
 use wcf\data\reaction\type\ReactionTypeCache;
 use wcf\data\DatabaseObject;
 use wcf\system\WCF;
+use wcf\util\StringUtil;
 
 /**
  * Represents a like of an object.
@@ -35,6 +36,26 @@ class Like extends DatabaseObject {
         */
        const DISLIKE = -1;
        
+       /**
+        * Returns the title of the associated reaction type.
+        * 
+        * @return      string
+        * @since       5.3
+        */
+       public function __toString() {
+               return $this->getReactionType()->getTitle();
+       }
+       
+       /**
+        * Renders the like by showing the associated reaction type's icon.
+        * 
+        * @return      string
+        * @since       5.3
+        */
+       public function render() {
+               return '<span title="' . StringUtil::encodeHTML($this) . '" class="jsTooltip">' . $this->getReactionType()->renderIcon() . '</span>';
+       }
+       
        /**
         * Returns the like with given type, object id and user id.
         * 
index 65a888a26070d6c4c96b83d03f1a4cca781ba11c..3a4b32ea01c7d954ccf4374b89b8550fdb659855 100644 (file)
@@ -24,6 +24,7 @@ use wcf\system\WCF;
  * @property-read      string          $fileType               type of the physical media file
  * @property-read      string          $fileHash               hash of the physical media file
  * @property-read      integer         $uploadTime             timestamp at which the media file has been uploaded
+ * @property-read       int             $fileUpdateTime         timestamp at which the media file was updated the last or `0` if it has not been updated
  * @property-read      integer|null    $userID                 id of the user who uploaded the media file or null if the user does not exist anymore
  * @property-read      string          $username               name of the user who uploaded the media file
  * @property-read      integer|null    $languageID             id of the language associated with the media file or null if the media file is multilingual or if the language has been deleted
index 101d36c0f7f753f506153f996bd0d90a623fa739..11e5e2402b53b21c08ca27817736fb24823bb79d 100644 (file)
@@ -15,6 +15,7 @@ use wcf\system\language\I18nHandler;
 use wcf\system\language\LanguageFactory;
 use wcf\system\request\LinkHandler;
 use wcf\system\upload\DefaultUploadFileSaveStrategy;
+use wcf\system\upload\MediaReplaceUploadFileValidationStrategy;
 use wcf\system\upload\MediaUploadFileValidationStrategy;
 use wcf\system\upload\UploadFile;
 use wcf\system\WCF;
@@ -148,6 +149,7 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction,
                        'captionEnableHtml' => $media->captionEnableHtml,
                        'categoryID' => $media->categoryID,
                        'elementTag' => $media instanceof ViewableMedia ? $media->getElementTag($this->parameters['elementTagSize'] ?? 144) : '',
+                       'elementTag48' => $media instanceof ViewableMedia ? $media->getElementTag(48) : '',
                        'fileHash' => $media->fileHash,
                        'filename' => $media->filename,
                        'filesize' => $media->filesize,
@@ -155,6 +157,9 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction,
                        'fileType' => $media->fileType,
                        'height' => $media->height,
                        'languageID' => $media->languageID,
+                       'imageDimensions' => $media->isImage ? WCF::getLanguage()->getDynamicVariable('wcf.media.imageDimensions.value', [
+                               'media' => $media,
+                       ]) : '',
                        'isImage' => $media->isImage,
                        'isMultilingual' => $media->isMultilingual,
                        'largeThumbnailHeight' => $media->largeThumbnailHeight,
@@ -169,6 +174,7 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction,
                        'mediumThumbnailWidth' => $media->mediumThumbnailWidth,
                        'smallThumbnailHeight' => $media->smallThumbnailHeight,
                        'smallThumbnailLink' => $media->smallThumbnailType ? $media->getThumbnailLink('small') : '',
+                       'smallThumbnailTag' => $media->smallThumbnailType ? $media->getThumbnailTag('small') : '',
                        'smallThumbnailType' => $media->smallThumbnailType,
                        'smallThumbnailWidth' => $media->smallThumbnailWidth,
                        'tinyThumbnailHeight' => $media->tinyThumbnailHeight,
@@ -182,6 +188,10 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction,
                                'id' => $media->userID,
                                'title' => $media->username
                        ]) : '',
+                       'userLinkElement' => $media instanceof ViewableMedia ? WCF::getTPL()->fetchString(
+                               WCF::getTPL()->getCompiler()->compileString('userLink', '{user object=$userProfile}')['template'],
+                               ['userProfile' => $media->getUserProfile()]
+                       ) : '',
                        'username' => $media->username,
                        'width' => $media->width
                ];
@@ -677,4 +687,87 @@ class MediaAction extends AbstractDatabaseObjectAction implements ISearchAction,
                
                $this->unmarkItems();
        }
+       
+       /**
+        * Validates the `replaceFile` action.
+        * 
+        * @since       5.3
+        */
+       public function validateReplaceFile() {
+               WCF::getSession()->checkPermissions(['admin.content.cms.canManageMedia']);
+               
+               $this->getSingleObject();
+               
+               /** @noinspection PhpUndefinedMethodInspection */
+               $this->parameters['__files']->validateFiles(
+                       new MediaReplaceUploadFileValidationStrategy($this->getSingleObject()->getDecoratedObject())
+               );
+       }
+       
+       /**
+        * Replaces the actual file of a media file.
+        * 
+        * @return      array
+        * @since       5.3
+        */
+       public function replaceFile() {
+               $saveStrategy = new DefaultUploadFileSaveStrategy(static::class, [
+                       'action' => 'update',
+                       'generateThumbnails' => true,
+                       'object' => $this->getSingleObject()->getDecoratedObject(),
+                       'rotateImages' => true,
+               ], [
+                       'fileUpdateTime' => TIME_NOW,
+                       'userID' => $this->getSingleObject()->userID,
+                       'username' => $this->getSingleObject()->username,
+               ]);
+               
+               /** @noinspection PhpUndefinedMethodInspection */
+               $this->parameters['__files']->saveFiles($saveStrategy);
+               
+               /** @var Media[] $mediaFiles */
+               $mediaFiles = $saveStrategy->getObjects();
+               
+               $result = [
+                       'errors' => [],
+                       'media' => []
+               ];
+               
+               if (!empty($mediaFiles)) {
+                       $mediaIDs = $mediaToFileID = [];
+                       foreach ($mediaFiles as $internalFileID => $media) {
+                               $mediaIDs[] = $media->mediaID;
+                               $mediaToFileID[$media->mediaID] = $internalFileID;
+                       }
+                       
+                       // fetch media objects from database
+                       $mediaList = new ViewableMediaList();
+                       $mediaList->setObjectIDs($mediaIDs);
+                       $mediaList->readObjects();
+                       
+                       foreach ($mediaList as $media) {
+                               $result['media'][$mediaToFileID[$media->mediaID]] = $this->getMediaData($media);
+                       }
+               }
+               
+               /** @var UploadFile[] $files */
+               /** @noinspection PhpUndefinedMethodInspection */
+               $files = $this->parameters['__files']->getFiles();
+               foreach ($files as $file) {
+                       if ($file->getValidationErrorType()) {
+                               $result['errors'][$file->getInternalFileID()] = [
+                                       'filename' => $file->getFilename(),
+                                       'filesize' => $file->getFilesize(),
+                                       'errorType' => $file->getValidationErrorType()
+                               ];
+                       }
+               }
+               
+               // Delete *old* files using the non-updated local media editor object.
+               if (empty($result['errors'])) {
+                       $this->getSingleObject()->deleteFiles();
+               }
+               
+               return $result;
+       }
 }
index ae8b51333696c21203b4a2c1822f26fbc1a2ea13..8ca88788d373ce1973db6d49b8b58ac8a84ab12d 100644 (file)
@@ -7,7 +7,6 @@ use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\exception\UserInputException;
 use wcf\system\moderation\queue\ModerationQueueManager;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\storage\UserStorageHandler;
 use wcf\system\visitTracker\VisitTracker;
 use wcf\system\WCF;
@@ -16,7 +15,7 @@ use wcf\system\WCF;
  * Executes moderation queue-related actions.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Data\Moderation\Queue
  * 
@@ -265,7 +264,7 @@ class ModerationQueueAction extends AbstractDatabaseObjectAction {
                $username = $this->user->userID ? $this->user->username : WCF::getLanguage()->get('wcf.moderation.assignedUser.nobody');
                $link = '';
                if ($this->user->userID) {
-                       $link = LinkHandler::getInstance()->getLink('User', ['object' => $this->user]);
+                       $link = $this->user->getLink();
                }
                
                $newStatus = '';
index 871cd590662ab7de9ca88adc3df1eb9127dbd373..b9618a0202dada6e1a93434728ecb1aa4240103f 100644 (file)
@@ -157,9 +157,8 @@ class ViewableModerationQueue extends DatabaseObjectDecorator implements ILinkab
                $queueList->getConditionBuilder()->add("moderation_queue.queueID = ?", [$queueID]);
                $queueList->sqlLimit = 1;
                $queueList->readObjects();
-               $queues = $queueList->getObjects();
                
-               return (isset($queues[$queueID]) ? $queues[$queueID] : null);
+               return $queueList->getSingleObject();
        }
        
        /**
index cffcc44f8df5df7514e7d8552749accbced08d82..f99a95a9f8e1d1c0a8d60824d6761b01693c3619 100644 (file)
@@ -2,7 +2,9 @@
 namespace wcf\data\object\type;
 use wcf\data\IToggleAction;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\registry\RegistryHandler;
 use wcf\system\WCF;
+use wcf\system\worker\SitemapRebuildWorker;
 
 /**
  * Executes sitemap object type-related actions.
@@ -33,9 +35,22 @@ class SitemapObjectTypeAction extends ObjectTypeAction implements IToggleAction
         */
        public function toggle() {
                foreach ($this->getObjects() as $objectEditor) {
-                       $objectEditor->update([
-                               'additionalData' => serialize(array_merge($objectEditor->additionalData, ['isDisabled' => !$objectEditor->isDisabled ? 1 : 0]))
-                       ]);
+                       $sitemapData = RegistryHandler::getInstance()->get('com.woltlab.wcf', SitemapRebuildWorker::REGISTRY_PREFIX . $objectEditor->objectType);
+                       $sitemapData = @unserialize($sitemapData);
+                       
+                       if (is_array($sitemapData)) {
+                               $sitemapData['isDisabled'] = $sitemapData['isDisabled'] ? 0 : 1;
+                       }
+                       else {
+                               $sitemapData = [
+                                       'priority' => $objectEditor->priority,
+                                       'changeFreq' => $objectEditor->changeFreq,
+                                       'rebuildTime' => $objectEditor->rebuildTime,
+                                       'isDisabled' => $objectEditor->isDisabled ? 0 : 1,
+                               ];
+                       }
+                       
+                       RegistryHandler::getInstance()->set('com.woltlab.wcf', SitemapRebuildWorker::REGISTRY_PREFIX . $objectEditor->objectType, serialize($sitemapData));
                }
        }
        
index 9c5d9e0c42753617d782624e00c530466fbf9213..ebfc10b50d2ffd89956bf1d09ee48b57135bda75 100644 (file)
@@ -1,7 +1,11 @@
 <?php
 namespace wcf\data\package;
+use wcf\acp\page\PackagePage;
 use wcf\data\DatabaseObject;
+use wcf\data\ILinkableObject;
 use wcf\system\package\PackageInstallationDispatcher;
+use wcf\system\request\IRouteController;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
 
@@ -27,7 +31,7 @@ use wcf\util\FileUtil;
  * @property-read      string          $author                 author of the package
  * @property-read      string          $authorURL              external url to the website of the package author
  */
-class Package extends DatabaseObject {
+class Package extends DatabaseObject implements ILinkableObject, IRouteController {
        /**
         * recursive list of packages that were given as required packages during installation
         * @var         Package[]
@@ -71,6 +75,22 @@ class Package extends DatabaseObject {
         */
        protected static $requirements = null;
        
+       /**
+        * @inheritDoc
+        */
+       public function getLink() {
+               return LinkHandler::getInstance()->getControllerLink(PackagePage::class, [
+                       'object' => $this,
+               ]);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getTitle() {
+               return $this->getName();
+       }
+       
        /**
         * Returns true if this package is required by other packages.
         * 
index 222e8aa1cffaba2d4db96f60d200efddd8c3d369..dbf70fb30fa22be8098abf812082a8f1d9013444 100644 (file)
@@ -109,11 +109,6 @@ class PackageInstallationPluginAction extends AbstractDatabaseObjectAction {
                        throw new \RuntimeException("PIP '{$this->packageInstallationPlugin->pluginName}' is not allowed to throw a 'SplitNodeException'.");
                }
                
-               // clear cache
-               
-               // TODO: use a central method instead!
-               
-               // create search index tables
                SearchIndexManager::getInstance()->createSearchIndices();
                
                VersionTracker::getInstance()->createStorageTables();
index 0e857fe7d299bb42658e1f71caf5aca907c3a58e..de7e6b7e14469ac23a8f3f7f8868ccf6b5d1e0d1 100644 (file)
@@ -66,6 +66,7 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                // there are no available package update servers
                if (empty($availableUpdateServers)) {
                        WCF::getTPL()->assign([
+                               'officialPackages' => [],
                                'thirdPartySources' => [],
                                'trustedSources' => [],
                        ]);
@@ -96,6 +97,7 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                // no matches found
                if (empty($packageUpdateIDs)) {
                        WCF::getTPL()->assign([
+                               'officialPackages' => [],
                                'thirdPartySources' => [],
                                'trustedSources' => [],
                        ]);
@@ -134,6 +136,7 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                // no matches found
                if (empty($packageUpdates)) {
                        WCF::getTPL()->assign([
+                               'officialPackages' => [],
                                'thirdPartySources' => [],
                                'trustedSources' => [],
                        ]);
@@ -459,10 +462,11 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                
                // assign versions
                /**
+                * @var ViewablePackageUpdate[] $officialPackages
                 * @var ViewablePackageUpdate[] $thirdPartySources
                 * @var ViewablePackageUpdate[] $trustedSources
                 */
-               $thirdPartySources = $trustedSources = [];
+               $officialPackages = $thirdPartySources = $trustedSources = [];
                /**
                 * @var int $packageUpdateID
                 * @var ViewablePackageUpdate $packageUpdate
@@ -473,7 +477,10 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                        $packageUpdate->setLatestVersion($updateVersions[$versionIDs['existing']]);
                        $packageUpdate->setUpdateServer($updateServers[$packageUpdate->packageUpdateServerID]);
                        
-                       if ($packageUpdate->getUpdateServer()->isTrustedServer() || $packageUpdate->getUpdateServer()->isWoltLabStoreServer()) {
+                       if ($packageUpdate->getUpdateServer()->isWoltLabUpdateServer()) {
+                               $officialPackages[] = $packageUpdate;
+                       }
+                       else if ($packageUpdate->getUpdateServer()->isTrustedServer() || $packageUpdate->getUpdateServer()->isWoltLabStoreServer()) {
                                $trustedSources[] = $packageUpdate;
                        }
                        else {
@@ -481,6 +488,9 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                        }
                }
                
+               uasort($officialPackages, function(ViewablePackageUpdate $a, ViewablePackageUpdate $b) {
+                       return strnatcasecmp($a->getName(), $b->getName());
+               });
                uasort($thirdPartySources, function(ViewablePackageUpdate $a, ViewablePackageUpdate $b) {
                        return strnatcasecmp($a->getName(), $b->getName());
                });
@@ -489,12 +499,13 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
                });
                
                WCF::getTPL()->assign([
+                       'officialPackages' => $officialPackages,
                        'thirdPartySources' => $thirdPartySources,
                        'trustedSources' => $trustedSources,
                ]);
                
                return [
-                       'count' => count($thirdPartySources) + count($trustedSources),
+                       'count' => count($officialPackages) + count($thirdPartySources) + count($trustedSources),
                        'template' => WCF::getTPL()->fetch('packageSearchResultList'),
                ];
        }
index 5cd2294177f2af63fa205432deb66ce5a3d167c7..bc00b3e095631b14ebfb9b85142d3213541b6a62 100644 (file)
@@ -52,6 +52,17 @@ class PackageUpdateServer extends DatabaseObject {
                }
                
                parent::handleData($data);
+               
+               $prefix = ENABLE_ENTERPRISE_MODE ? 'cloud/' : '';
+               if ($this->isWoltLabUpdateServer()) {
+                       $this->data['serverURL'] = 'http://update.woltlab.com/'.$prefix.\wcf\getMinorVersion().'/';
+               }
+               if ($this->isWoltLabStoreServer()) {
+                       $this->data['serverURL'] = 'http://store.woltlab.com/'.$prefix.\wcf\getMinorVersion().'/';
+               }
+               if ($this->isWoltLabUpdateServer() || $this->isWoltLabStoreServer()) {
+                       $this->data['isDisabled'] = 0;
+               }
        }
        
        /**
@@ -61,20 +72,50 @@ class PackageUpdateServer extends DatabaseObject {
         * @return      PackageUpdateServer[]
         */
        public static final function getActiveUpdateServers(array $packageUpdateServerIDs = []) {
-               $list = new PackageUpdateServerList();
-               $list->getConditionBuilder()->add("isDisabled = ?", [0]);
                if (!empty($packageUpdateServerIDs)) {
-                       $list->getConditionBuilder()->add("packageUpdateServerID IN (?)", [$packageUpdateServerIDs]);
+                       throw new \InvalidArgumentException("Filtering package update servers by ID is no longer supported.");
                }
+               
+               $list = new PackageUpdateServerList();
                $list->readObjects();
                
+               $woltlabUpdateServer = null;
+               $woltlabStoreServer = null;
+               $results = [];
+               foreach ($list as $packageServer) {
+                       if ($packageServer->isWoltLabUpdateServer()) {
+                               $woltlabUpdateServer = $packageServer;
+                       }
+                       else if ($packageServer->isWoltLabStoreServer()) {
+                               $woltlabStoreServer = $packageServer;
+                       }
+                       else if ($packageServer->isDisabled) {
+                               continue;
+                       }
+                       
+                       $results[$packageServer->packageUpdateServerID] = $packageServer;
+               }
+               
+               if (!$woltlabUpdateServer) {
+                       $packageServer = PackageUpdateServerEditor::create([
+                               'serverURL' => 'http://update.woltlab.com/'.\wcf\getMinorVersion().'/',
+                       ]);
+                       $results[$packageServer->packageUpdateServerID] = $packageServer;
+               }
+               if (!$woltlabStoreServer) {
+                       $packageServer = PackageUpdateServerEditor::create([
+                               'serverURL' => 'http://store.woltlab.com/'.\wcf\getMinorVersion().'/',
+                       ]);
+                       $results[$packageServer->packageUpdateServerID] = $packageServer;
+               }
+               
                if (ENABLE_ENTERPRISE_MODE) {
-                       return array_filter($list->getObjects(), function (PackageUpdateServer $server) {
+                       return array_filter($results, function (PackageUpdateServer $server) {
                                return $server->isWoltLabStoreServer() || $server->isTrustedServer();
                        });
                }
                
-               return $list->getObjects();
+               return $results;
        }
        
        /**
@@ -238,6 +279,26 @@ class PackageUpdateServer extends DatabaseObject {
                return false;
        }
        
+       /**
+        * Returns whether the current user may delete this update server.
+        * 
+        * @return      boolean
+        * @since       5.3
+        */
+       public final function canDelete() {
+               return !$this->isWoltLabUpdateServer() && !$this->isWoltLabStoreServer();
+       }
+       
+       /**
+        * Returns whether the current user may disable this update server.
+        * 
+        * @return      boolean
+        * @since       5.3
+        */
+       public final function canDisable() {
+               return !$this->isWoltLabUpdateServer() && !$this->isWoltLabStoreServer();
+       }
+       
        /**
         * Returns true if the host is `update.woltlab.com`.
         * 
index 897ef73de3435aabb6d774c27eced36eefc1bbfe..5d8ae5cce78061f93c3c8a86e611695b1f5ce7ac 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\data\package\update\server;
 use wcf\data\AbstractDatabaseObjectAction;
 use wcf\data\IToggleAction;
 use wcf\data\TDatabaseObjectToggle;
+use wcf\system\exception\PermissionDeniedException;
 
 /**
  * Executes package update server-related actions.
@@ -17,7 +18,9 @@ use wcf\data\TDatabaseObjectToggle;
  * @method     PackageUpdateServerEditor       getSingleObject()
  */
 class PackageUpdateServerAction extends AbstractDatabaseObjectAction implements IToggleAction {
-       use TDatabaseObjectToggle;
+       use TDatabaseObjectToggle {
+               validateToggle as traitValidateToggle;
+       }
        
        /**
         * @inheritDoc
@@ -43,4 +46,29 @@ class PackageUpdateServerAction extends AbstractDatabaseObjectAction implements
         * @inheritDoc
         */
        protected $requireACP = ['create', 'delete', 'toggle', 'update'];
+       
+       /**
+        * @inheritDoc
+        */
+       public function validateDelete() {
+               parent::validateDelete();
+               
+               /** @var PackageUpdateServer $updateServer */
+               foreach ($this->getObjects() as $updateServer) {
+                       if (!$updateServer->canDelete()) throw new PermissionDeniedException();
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validateToggle() {
+               $this->traitValidateToggle();
+               
+               /** @var PackageUpdateServer $updateServer */
+               foreach ($this->getObjects() as $updateServer) {
+                       if (!$updateServer->canDisable()) throw new PermissionDeniedException();
+               }
+       }
+       
 }
index 482c259ed777ab3af812625f205394b4e2c9388c..aa98e0b67f1d543e3ae549d53bf5308784c83a66 100644 (file)
@@ -13,6 +13,7 @@ use wcf\system\cache\builder\ApplicationCacheBuilder;
 use wcf\system\cache\builder\RoutingCacheBuilder;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\SystemException;
+use wcf\system\language\LanguageFactory;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 
@@ -78,6 +79,12 @@ class Page extends DatabaseObject implements ILinkableObject, ITitledObject {
         */
        public $pageContents;
        
+       /**
+        * @var PageLanguage[]
+        * @since 5.3
+        */
+       public $pageLanguages;
+       
        /**
         * Returns true if the active user can delete this page.
         * 
@@ -345,19 +352,23 @@ class Page extends DatabaseObject implements ILinkableObject, ITitledObject {
         * @return PageLanguage[]
         */
        public function getPageLanguages() {
-               $pageLanguages = [];
-               if ($this->isMultilingual) {
-                       $sql = "SELECT  languageID
+               if ($this->pageLanguages === null) {
+                       $this->pageLanguages = [];
+                       if ($this->isMultilingual) {
+                               $sql = "SELECT  languageID
                                FROM    wcf" . WCF_N . "_page_content
                                WHERE   pageID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute([$this->pageID]);
-                       while ($languageID = $statement->fetchColumn()) {
-                               $pageLanguages[] = new PageLanguage($this->pageID, $languageID);
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               $statement->execute([$this->pageID]);
+                               while ($languageID = $statement->fetchColumn()) {
+                                       if (LanguageFactory::getInstance()->getLanguage($languageID) !== null) {
+                                               $this->pageLanguages[] = new PageLanguage($this->pageID, $languageID);
+                                       }
+                               }
                        }
                }
                
-               return $pageLanguages;
+               return $this->pageLanguages;
        }
        
        /**
index 4434f93e48c000eacabeb92416a16e6c8287709f..95a22998266fe55e23aec792304559ff3f959c31 100644 (file)
@@ -47,6 +47,7 @@ class PageContent extends DatabaseObject implements ILinkableObject {
                MessageEmbeddedObjectManager::getInstance()->loadObjects('com.woltlab.wcf.page.content', [$this->pageContentID]);
                
                $processor = new HtmlOutputProcessor();
+               $processor->enableUgc = false;
                $processor->process($this->content, 'com.woltlab.wcf.page.content', $this->pageContentID);
                
                return $processor->getHtml();
index d17c7a97f136a95c4b53100c145b34190847777e..d8ace46aaef8f4e981c80821dfdd02e70157e3dc 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\data\style;
 use wcf\data\DatabaseObject;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\WCF;
+use wcf\util\FileUtil;
 
 /**
  * Represents a style.
@@ -55,6 +56,8 @@ class Style extends DatabaseObject {
        const FAVICON_IMAGE_HEIGHT = 256;
        const FAVICON_IMAGE_WIDTH = 256;
        
+       const BASE_ASSET_PATH = WCF_DIR.'images/';
+       
        /**
         * Returns the name of this style.
         * 
@@ -64,6 +67,16 @@ class Style extends DatabaseObject {
                return $this->styleName;
        }
        
+       /**
+        * Returns the absolute path to the style's asset folder.
+        * 
+        * @return      string
+        * @since       5.3
+        */
+       public function getAssetPath() {
+               return FileUtil::addTrailingSlash(static::BASE_ASSET_PATH . 'style-' . $this->styleID);
+       }
+       
        /**
         * Returns the styles variables of this style.
         * 
@@ -221,7 +234,7 @@ class Style extends DatabaseObject {
         */
        public function getCoverPhoto() {
                if ($this->coverPhotoExtension) {
-                       return $this->styleID . '.' . $this->coverPhotoExtension;
+                       return 'coverPhoto.'.$this->coverPhotoExtension;
                }
                
                return 'default.jpg';
@@ -232,7 +245,10 @@ class Style extends DatabaseObject {
         * @since 5.2
         */
        public function getCoverPhotoLocation() {
-               return WCF_DIR . 'images/coverPhotos/' . $this->getCoverPhoto();
+               if ($this->coverPhotoExtension) {
+                       return $this->getAssetPath().'coverPhoto.'.$this->coverPhotoExtension;
+               }
+               return WCF_DIR . 'images/coverPhotos/default.jpg';
        }
        
        /**
@@ -240,6 +256,9 @@ class Style extends DatabaseObject {
         * @since 5.2
         */
        public function getCoverPhotoUrl() {
+               if ($this->coverPhotoExtension) {
+                       return WCF::getPath() . FileUtil::getRelativePath(WCF_DIR, $this->getAssetPath()).'coverPhoto.'.$this->coverPhotoExtension;
+               }
                return WCF::getPath() . 'images/coverPhotos/' . $this->getCoverPhoto();
        }
        
@@ -257,7 +276,13 @@ class Style extends DatabaseObject {
                        }
                }
                
-               $path = 'images/favicon/'. ($this->hasFavicon ? $this->styleID : 'default') . ".{$filename}";
+               if ($this->hasFavicon) {
+                       $path = FileUtil::getRelativePath(WCF_DIR, $this->getAssetPath()).$filename;
+               }
+               else {
+                       $path = 'images/favicon/default.'.$filename;
+               }
+               
                if ($absolutePath) {
                        return WCF::getPath() . $path;
                }
index e314baf4c625543173439db6210dff389d9e6ef5..e7801c92c68418f5bd115bd28d05e20c469f324f 100644 (file)
@@ -1,26 +1,20 @@
 <?php
 namespace wcf\data\style;
 use wcf\data\TDatabaseObjectToggle;
-use wcf\data\user\cover\photo\UserCoverPhoto;
 use wcf\data\user\UserAction;
 use wcf\data\AbstractDatabaseObjectAction;
 use wcf\data\IToggleAction;
-use wcf\data\IUploadAction;
 use wcf\system\cache\builder\StyleCacheBuilder;
-use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\PermissionDeniedException;
-use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\image\ImageHandler;
 use wcf\system\language\LanguageFactory;
 use wcf\system\request\LinkHandler;
 use wcf\system\style\StyleHandler;
-use wcf\system\upload\DefaultUploadFileValidationStrategy;
-use wcf\system\upload\UploadFile;
-use wcf\system\upload\UploadHandler;
 use wcf\system\Regex;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
+use wcf\util\ImageUtil;
 
 /**
  * Executes style-related actions.
@@ -33,7 +27,7 @@ use wcf\util\FileUtil;
  * @method     StyleEditor[]   getObjects()
  * @method     StyleEditor     getSingleObject()
  */
-class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction, IUploadAction {
+class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction {
        use TDatabaseObjectToggle;
        
        /**
@@ -59,7 +53,7 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
        /**
         * @inheritDoc
         */
-       protected $requireACP = ['copy', 'delete', 'deleteCoverPhoto', 'markAsTainted', 'setAsDefault', 'toggle', 'update', 'upload', 'uploadCoverPhoto', 'uploadLogo', 'uploadLogoMobile'];
+       protected $requireACP = ['copy', 'delete', 'markAsTainted', 'setAsDefault', 'toggle', 'update', 'upload',];
        
        /**
         * style object
@@ -87,6 +81,15 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
                // handle style preview image
                $this->updateStylePreviewImage($style);
                
+               // create favicon data
+               $this->updateFavicons($style);
+               
+               // handle the cover photo
+               $this->updateCoverPhoto($style);
+                       
+               // handle custom assets
+               $this->updateCustomAssets($style);
+               
                return $style;
        }
        
@@ -109,6 +112,9 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
                        // handle the cover photo
                        $this->updateCoverPhoto($style->getDecoratedObject());
                        
+                       // handle custom assets
+                       $this->updateCustomAssets($style->getDecoratedObject());
+                       
                        // reset stylesheet
                        StyleHandler::getInstance()->resetStylesheet($style->getDecoratedObject());
                }
@@ -172,6 +178,37 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
                        return;
                }
                
+               $style->loadVariables();
+               foreach (['pageLogo', 'pageLogoMobile'] as $type) {
+                       if (array_key_exists($type, $this->parameters['uploads'])) {
+                               /** @var \wcf\system\file\upload\UploadFile $file */
+                               $file = $this->parameters['uploads'][$type];
+                               
+                               // Only save file, if it is not proccessed. 
+                               if ($file !== null && !$file->isProcessed()) {
+                                       $fileLocation = $file->getLocation();
+                                       $extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION);
+                                       $newName = $type.'-'.\bin2hex(\random_bytes(4)).'.'.$extension;
+                                       $newLocation = $style->getAssetPath().$newName;
+                                       rename($fileLocation, $newLocation);
+                                       $this->parameters['variables'][$type] = $newName;
+                                       $file->setProcessed($newLocation);
+                               }
+                               else if ($file === null) {
+                                       $this->parameters['variables'][$type] = '';
+                               }
+                               else {
+                                       $this->parameters['variables'][$type] = basename($file->getLocation());
+                               }
+                       }
+               }
+               
+               foreach ($this->parameters['removedUploads'] as $removedUpload) {
+                       if (file_exists($removedUpload->getLocation())) {
+                               unlink($removedUpload->getLocation());
+                       }
+               }
+               
                $sql = "SELECT  variableID, variableName, defaultValue
                        FROM    wcf".WCF_N."_style_variable";
                $statement = WCF::getDB()->prepareStatement($sql);
@@ -224,51 +261,43 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
         * @param       Style           $style
         */
        protected function updateStylePreviewImage(Style $style) {
-               if (!isset($this->parameters['tmpHash'])) {
-                       return;
-               }
-               
-               foreach (['', '@2x'] as $type) {
-                       $fileExtension = WCF::getSession()->getVar('stylePreview-' . $this->parameters['tmpHash'] . $type);
-                       if ($fileExtension !== null) {
-                               $oldFilename = WCF_DIR . 'images/stylePreview-' . $this->parameters['tmpHash'] . $type . '.' . $fileExtension;
-                               if (file_exists($oldFilename)) {
-                                       $filename = 'stylePreview-' . $style->styleID . $type . '.' . $fileExtension;
-                                       if (@rename($oldFilename, WCF_DIR . 'images/' . $filename)) {
-                                               // delete old file if it has a different file extension
-                                               if ($type === '') {
-                                                       if ($style->image != $filename) {
-                                                               @unlink(WCF_DIR . 'images/' . $style->image);
-                                                               
-                                                               // update filename in database
-                                                               $sql = "UPDATE  wcf" . WCF_N . "_style
-                                                                       SET     image = ?
-                                                                       WHERE   styleID = ?";
-                                                               $statement = WCF::getDB()->prepareStatement($sql);
-                                                               $statement->execute([
-                                                                       $filename, $style->styleID
-                                                               ]);
-                                                       }
-                                               }
-                                               else {
-                                                       if ($style->image2x != $filename) {
-                                                               @unlink(WCF_DIR . 'images/' . $style->image2x);
-                                                               
-                                                               // update filename in database
-                                                               $sql = "UPDATE  wcf" . WCF_N . "_style
-                                                                       SET     image2x = ?
-                                                                       WHERE   styleID = ?";
-                                                               $statement = WCF::getDB()->prepareStatement($sql);
-                                                               $statement->execute([
-                                                                       $filename, $style->styleID
-                                                               ]);
-                                                       }
-                                               }
+               foreach (['image', 'image2x'] as $type) {
+                       if (array_key_exists($type, $this->parameters['uploads'])) {
+                               /** @var \wcf\system\file\upload\UploadFile $file */
+                               $file = $this->parameters['uploads'][$type];
+                               
+                               if ($style->{$type} && file_exists($style->getAssetPath().basename($style->{$type}))) {
+                                       if (!$file || $style->getAssetPath().basename($style->{$type}) !== $file->getLocation()) {
+                                               unlink($style->getAssetPath().basename($style->{$type}));
+                                       }
+                               }
+                               if ($file !== null) {
+                                       $fileLocation = $file->getLocation();
+                                       if (($imageData = getimagesize($fileLocation)) === false) {
+                                               throw new \InvalidArgumentException('The given '.$type.' is not an image');
+                                       }
+                                       $extension = ImageUtil::getExtensionByMimeType($imageData['mime']);
+                                       if ($type === 'image') {
+                                               $newName = 'stylePreview.'.$extension;
+                                       }
+                                       else if ($type === 'image2x') {
+                                               $newName = 'stylePreview@2x.'.$extension;
                                        }
                                        else {
-                                               // remove temp file
-                                               @unlink($oldFilename);
+                                               throw new \LogicException('Unreachable');
                                        }
+                                       $newLocation = $style->getAssetPath().$newName;
+                                       rename($fileLocation, $newLocation);
+                                       (new StyleEditor($style))->update([
+                                               $type => FileUtil::getRelativePath(WCF_DIR.'images/', $style->getAssetPath()).$newName,
+                                       ]);
+                                       
+                                       $file->setProcessed($newLocation);
+                               }
+                               else {
+                                       (new StyleEditor($style))->update([
+                                               $type => '',
+                                       ]);
                                }
                        }
                }
@@ -281,37 +310,68 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
         * @since       3.1
         */
        protected function updateFavicons(Style $style) {
-               $styleID = $style->styleID;
-               $fileExtension = WCF::getSession()->getVar('styleFavicon-template-'.$styleID);
-               $hasFavicon = (bool)$style->hasFavicon;
-               if ($fileExtension) {
-                       $template = WCF_DIR . "images/favicon/{$styleID}.favicon-template.{$fileExtension}";
-                       $images = [
-                               'android-chrome-192x192.png' => 192,
-                               'android-chrome-256x256.png' => 256,
-                               'apple-touch-icon.png' => 180,
-                               'mstile-150x150.png' => 150
-                       ];
+               $images = [
+                       'android-chrome-192x192.png' => 192,
+                       'android-chrome-256x256.png' => 256,
+                       'apple-touch-icon.png' => 180,
+                       'mstile-150x150.png' => 150
+               ];
+               
+               $hasFavicon = $style->hasFavicon;
+               if (array_key_exists('favicon', $this->parameters['uploads'])) {
+                       /** @var \wcf\system\file\upload\UploadFile $file */
+                       $file = $this->parameters['uploads']['favicon'];
                        
-                       $adapter = ImageHandler::getInstance()->getAdapter();
-                       $adapter->loadFile($template);
-                       foreach ($images as $filename => $length) {
-                               $thumbnail = $adapter->createThumbnail($length, $length);
-                               $adapter->writeImage($thumbnail, WCF_DIR."images/favicon/{$styleID}.{$filename}");
+                       if ($file !== null && !$file->isProcessed()) {
+                               $fileLocation = $file->getLocation();
+                               if (($imageData = getimagesize($fileLocation)) === false) {
+                                       throw new \InvalidArgumentException('The given favicon is not an image');
+                               }
+                               $extension = ImageUtil::getExtensionByMimeType($imageData['mime']);
+                               $newName = "favicon-template.".$extension;
+                               $newLocation = $style->getAssetPath().$newName;
+                               rename($fileLocation, $newLocation);
+                               
+                               // Create browser specific files.
+                               $adapter = ImageHandler::getInstance()->getAdapter();
+                               $adapter->loadFile($newLocation);
+                               foreach ($images as $filename => $length) {
+                                       $thumbnail = $adapter->createThumbnail($length, $length);
+                                       $adapter->writeImage($thumbnail, $style->getAssetPath().$filename);
+                                       // Clear thumbnail as soon as possible to free up the memory.
+                                       $thumbnail = null;
+                               }
+                               
+                               // Create ICO file.
+                               require(WCF_DIR . 'lib/system/api/chrisjean/php-ico/class-php-ico.php');
+                               (new \PHP_ICO($newLocation, [
+                                       [16, 16],
+                                       [32, 32]
+                               ]))->save_ico($style->getAssetPath()."favicon.ico");
+                               
+                               (new StyleEditor($style))->update([
+                                       'hasFavicon' => 1,
+                               ]);
+                               
+                               $file->setProcessed($newLocation);
+                               $hasFavicon = true;
+                       }
+                       else if ($file === null) {
+                               foreach ($images as $filename => $length) {
+                                       unlink($style->getAssetPath().$filename);
+                               }
+                               unlink($style->getAssetPath()."favicon.ico");
+                               foreach (['png', 'jpg', 'gif'] as $extension) {
+                                       if (file_exists($style->getAssetPath()."favicon-template.".$extension)) {
+                                               unlink($style->getAssetPath()."favicon-template.".$extension);
+                                       }
+                               }
+                               (new StyleEditor($style))->update([
+                                       'hasFavicon' => 0,
+                               ]);
+                               
+                               $hasFavicon = false;
                        }
-                       
-                       // create ico
-                       require(WCF_DIR . 'lib/system/api/chrisjean/php-ico/class-php-ico.php');
-                       $phpIco = new \PHP_ICO($template, [
-                               [16, 16],
-                               [32, 32]
-                       ]);
-                       $phpIco->save_ico(WCF_DIR . "images/favicon/{$styleID}.favicon.ico");
-                       
-                       $hasFavicon = true;
-                       
-                       (new StyleEditor($style))->update(['hasFavicon' => 1]);
-                       WCF::getSession()->unregister('styleFavicon-template-'.$style->styleID);
                }
                
                if ($hasFavicon) {
@@ -321,12 +381,12 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
     "name": "",
     "icons": [
         {
-            "src": "{$styleID}.android-chrome-192x192.png",
+            "src": "android-chrome-192x192.png",
             "sizes": "192x192",
             "type": "image/png"
         },
         {
-            "src": "{$styleID}.android-chrome-256x256.png",
+            "src": "android-chrome-256x256.png",
             "sizes": "256x256",
             "type": "image/png"
         }
@@ -336,7 +396,7 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction,
     "display": "standalone"
 }
 MANIFEST;
-                       file_put_contents(WCF_DIR . "images/favicon/{$styleID}.manifest.json", $manifest);
+                       file_put_contents($style->getAssetPath()."manifest.json", $manifest);
                        
                        $style->loadVariables();
                        $tileColor = $style->getVariable('wcfHeaderBackground', true);
@@ -347,13 +407,13 @@ MANIFEST;
 <browserconfig>
     <msapplication>
         <tile>
-            <square150x150logo src="{$styleID}.mstile-150x150.png"/>
+            <square150x150logo src="mstile-150x150.png"/>
             <TileColor>{$tileColor}</TileColor>
         </tile>
     </msapplication>
 </browserconfig>
 BROWSERCONFIG;
-                       file_put_contents(WCF_DIR . "images/favicon/{$styleID}.browserconfig.xml", $browserconfig);
+                       file_put_contents($style->getAssetPath()."browserconfig.xml", $browserconfig);
                }
        }
        
@@ -364,419 +424,65 @@ BROWSERCONFIG;
         * @since       3.1
         */
        protected function updateCoverPhoto(Style $style) {
-               $styleID = $style->styleID;
-               $fileExtension = WCF::getSession()->getVar('styleCoverPhoto-'.$styleID);
-               if ($fileExtension) {
-                       // remove old image
-                       if ($style->coverPhotoExtension) {
-                               @unlink(WCF_DIR . 'images/coverPhotos/' . $style->getCoverPhoto());
-                       }
-                       
-                       rename(
-                               WCF_DIR . 'images/coverPhotos/' . $styleID . '.tmp.' . $fileExtension,
-                               WCF_DIR . 'images/coverPhotos/' . $styleID . '.' . $fileExtension
-                       );
+               if (array_key_exists('coverPhoto', $this->parameters['uploads'])) {
+                       /** @var \wcf\system\file\upload\UploadFile $file */
+                       $file = $this->parameters['uploads']['coverPhoto'];
                        
-                       (new StyleEditor($style))->update(['coverPhotoExtension' => $fileExtension]);
-                       WCF::getSession()->unregister('styleCoverPhoto-'.$style->styleID);
-               }
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function validateUpload() {
-               // check upload permissions
-               if (!WCF::getSession()->getPermission('admin.style.canManageStyle')) {
-                       throw new PermissionDeniedException();
-               }
-               
-               $this->readBoolean('is2x', true);
-               $this->readString('tmpHash');
-               $this->readInteger('styleID', true);
-               
-               if ($this->parameters['styleID']) {
-                       $styles = StyleHandler::getInstance()->getStyles();
-                       if (!isset($styles[$this->parameters['styleID']])) {
-                               throw new UserInputException('styleID');
+                       if ($style->coverPhotoExtension && file_exists($style->getCoverPhotoLocation())) {
+                               if (!$file || $style->getCoverPhotoLocation() !== $file->getLocation()) {
+                                       unlink($style->getCoverPhotoLocation());
+                               }
                        }
-                       
-                       $this->style = $styles[$this->parameters['styleID']];
-               }
-               
-               /** @var UploadHandler $uploadHandler */
-               $uploadHandler = $this->parameters['__files'];
-               
-               if (count($uploadHandler->getFiles()) != 1) {
-                       throw new IllegalLinkException();
-               }
-               
-               // check max filesize, allowed file extensions etc.
-               $uploadHandler->validateFiles(new DefaultUploadFileValidationStrategy(PHP_INT_MAX, ['jpg', 'jpeg', 'png', 'gif', 'svg']));
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function upload() {
-               // save files
-               /** @noinspection PhpUndefinedMethodInspection */
-               /** @var UploadFile[] $files */
-               $files = $this->parameters['__files']->getFiles();
-               $file = $files[0];
-               
-               $multiplier = ($this->parameters['is2x']) ? 2 : 1;
-               
-               try {
-                       if (!$file->getValidationErrorType()) {
-                               // shrink preview image if necessary
+                       if ($file !== null) {
                                $fileLocation = $file->getLocation();
-                               try {
-                                       if (($imageData = getimagesize($fileLocation)) === false) {
-                                               throw new UserInputException('image');
-                                       }
-                                       switch ($imageData[2]) {
-                                               case IMAGETYPE_PNG:
-                                               case IMAGETYPE_JPEG:
-                                               case IMAGETYPE_GIF:
-                                                       // fine
-                                               break;
-                                               default:
-                                                       throw new UserInputException('image');
-                                       }
-                                       
-                                       if ($imageData[0] > (Style::PREVIEW_IMAGE_MAX_WIDTH * $multiplier) || $imageData[1] > (Style::PREVIEW_IMAGE_MAX_HEIGHT * $multiplier)) {
-                                               $adapter = ImageHandler::getInstance()->getAdapter();
-                                               $adapter->loadFile($fileLocation);
-                                               $fileLocation = FileUtil::getTemporaryFilename();
-                                               $thumbnail = $adapter->createThumbnail(Style::PREVIEW_IMAGE_MAX_WIDTH * $multiplier, Style::PREVIEW_IMAGE_MAX_HEIGHT * $multiplier, false);
-                                               $adapter->writeImage($thumbnail, $fileLocation);
-                                       }
-                               }
-                               catch (SystemException $e) {
-                                       throw new UserInputException('image');
+                               if (($imageData = getimagesize($fileLocation)) === false) {
+                                       throw new \InvalidArgumentException('The given coverPhoto is not an image');
                                }
+                               $extension = ImageUtil::getExtensionByMimeType($imageData['mime']);
+                               $newLocation = $style->getAssetPath().'coverPhoto.'.$extension;
+                               rename($fileLocation, $newLocation);
+                               (new StyleEditor($style))->update([
+                                       'coverPhotoExtension' => $extension,
+                               ]);
                                
-                               // move uploaded file
-                               if (@copy($fileLocation, WCF_DIR.'images/stylePreview-'.$this->parameters['tmpHash'].($this->parameters['is2x'] ? '@2x' : '').'.'.$file->getFileExtension())) {
-                                       @unlink($fileLocation);
-                                       
-                                       // store extension within session variables
-                                       WCF::getSession()->register('stylePreview-'.$this->parameters['tmpHash'].($this->parameters['is2x'] ? '@2x' : ''), $file->getFileExtension());
-                                       
-                                       if ($this->parameters['styleID']) {
-                                               $this->updateStylePreviewImage($this->style);
-                                               
-                                               return [
-                                                       'url' => WCF::getPath().'images/stylePreview-'.$this->parameters['styleID'].($this->parameters['is2x'] ? '@2x' : '').'.'.$file->getFileExtension()
-                                               ];
-                                       }
-                                       
-                                       // return result
-                                       return [
-                                               'url' => WCF::getPath().'images/stylePreview-'.$this->parameters['tmpHash'].($this->parameters['is2x'] ? '@2x' : '').'.'.$file->getFileExtension()
-                                       ];
-                               }
-                               else {
-                                       throw new UserInputException('image', 'uploadFailed');
-                               }
+                               $file->setProcessed($newLocation);
                        }
-               }
-               catch (UserInputException $e) {
-                       $file->setValidationErrorType($e->getType());
-               }
-               
-               return ['errorType' => $file->getValidationErrorType()];
-       }
-       
-       /**
-        * Validates parameters to update a logo.
-        */
-       public function validateUploadLogo() {
-               $this->validateUpload();
-       }
-       
-       /**
-        * Handles logo upload.
-        * 
-        * @return      string[]
-        */
-       public function uploadLogo() {
-               // save files
-               /** @noinspection PhpUndefinedMethodInspection */
-               /** @var UploadFile[] $files */
-               $files = $this->parameters['__files']->getFiles();
-               $file = $files[0];
-               
-               try {
-                       if (!$file->getValidationErrorType()) {
-                               // shrink avatar if necessary
-                               $fileLocation = $file->getLocation();
-                               
-                               // move uploaded file
-                               if (@copy($fileLocation, WCF_DIR.'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension())) {
-                                       @unlink($fileLocation);
-                                       
-                                       // store extension within session variables
-                                       WCF::getSession()->register('styleLogo-'.$this->parameters['tmpHash'], $file->getFileExtension());
-                                       
-                                       // get logo size
-                                       list($width, $height) = getimagesize(WCF_DIR.'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension());
-                                       
-                                       // return result
-                                       return [
-                                               'url' => WCF::getPath().'images/styleLogo-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension(),
-                                               'width' => $width,
-                                               'height' => $height
-                                       ];
-                               }
-                               else {
-                                       throw new UserInputException('image', 'uploadFailed');
-                               }
+                       else {
+                               (new StyleEditor($style))->update([
+                                       'coverPhotoExtension' => '',
+                               ]);
                        }
                }
-               catch (UserInputException $e) {
-                       $file->setValidationErrorType($e->getType());
+               else if ($style->coverPhotoExtension) {
+                       (new StyleEditor($style))->update([
+                               'coverPhotoExtension' => '',
+                       ]);
                }
-               
-               return ['errorType' => $file->getValidationErrorType()];
-       }
-       
-       /**
-        * Validates parameters to update a mobile logo.
-        */
-       public function validateUploadLogoMobile() {
-               $this->validateUpload();
        }
        
        /**
-        * Handles mobile logo upload.
-        *
-        * @return      string[]
+        * @since       5.2
         */
-       public function uploadLogoMobile() {
-               // save files
-               /** @noinspection PhpUndefinedMethodInspection */
-               /** @var UploadFile[] $files */
-               $files = $this->parameters['__files']->getFiles();
-               $file = $files[0];
+       protected function updateCustomAssets(Style $style) {
+               $customAssetPath = $style->getAssetPath().'custom/';
                
-               try {
-                       if (!$file->getValidationErrorType()) {
-                               // shrink avatar if necessary
-                               $fileLocation = $file->getLocation();
-                               
-                               // move uploaded file
-                               if (@copy($fileLocation, WCF_DIR.'images/styleLogo-mobile-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension())) {
-                                       @unlink($fileLocation);
-                                       
-                                       // store extension within session variables
-                                       WCF::getSession()->register('styleLogo-mobile-'.$this->parameters['tmpHash'], $file->getFileExtension());
-                                       
-                                       // return result
-                                       return [
-                                               'url' => WCF::getPath().'images/styleLogo-mobile-'.$this->parameters['tmpHash'].'.'.$file->getFileExtension()
-                                       ];
-                               }
-                               else {
-                                       throw new UserInputException('image', 'uploadFailed');
-                               }
+               if (!empty($this->parameters['customAssets']['removed'])) {
+                       /** @var \wcf\system\file\upload\UploadFile $file */
+                       foreach ($this->parameters['customAssets']['removed'] as $file) {
+                               unlink($file->getLocation());
                        }
                }
-               catch (UserInputException $e) {
-                       $file->setValidationErrorType($e->getType());
-               }
-               
-               return ['errorType' => $file->getValidationErrorType()];
-       }
-       
-       /**
-        * Validates parameters to upload a favicon.
-        * 
-        * @since       3.1
-        */
-       public function validateUploadFavicon() {
-               // ignore tmp hash, uploading is supported for existing styles only
-               // and files will be finally processed on form submit
-               $this->parameters['tmpHash'] = '@@@WCF_INVALID_TMP_HASH@@@';
-               
-               $this->validateUpload();
-       }
-       
-       /**
-        * Handles favicon upload.
-        *
-        * @return      string[]
-        * @since       3.1
-        */
-       public function uploadFavicon() {
-               // save files
-               /** @noinspection PhpUndefinedMethodInspection */
-               /** @var UploadFile[] $files */
-               $files = $this->parameters['__files']->getFiles();
-               $file = $files[0];
-               
-               try {
-                       if (!$file->getValidationErrorType()) {
-                               $fileLocation = $file->getLocation();
-                               try {
-                                       if (($imageData = getimagesize($fileLocation)) === false) {
-                                               throw new UserInputException('favicon');
-                                       }
-                                       switch ($imageData[2]) {
-                                               case IMAGETYPE_PNG:
-                                               case IMAGETYPE_JPEG:
-                                               case IMAGETYPE_GIF:
-                                                       // fine
-                                                       break;
-                                               default:
-                                                       throw new UserInputException('favicon');
-                                       }
-                                       
-                                       if ($imageData[0] != Style::FAVICON_IMAGE_WIDTH || $imageData[1] != Style::FAVICON_IMAGE_HEIGHT) {
-                                               throw new UserInputException('favicon', 'dimensions');
-                                       }
-                               }
-                               catch (SystemException $e) {
-                                       throw new UserInputException('favicon');
-                               }
-                               
-                               // move uploaded file
-                               if (@copy($fileLocation, WCF_DIR.'images/favicon/'.$this->style->styleID.'.favicon-template.'.$file->getFileExtension())) {
-                                       @unlink($fileLocation);
-                                       
-                                       // store extension within session variables
-                                       WCF::getSession()->register('styleFavicon-template-'.$this->style->styleID, $file->getFileExtension());
-                                       
-                                       // return result
-                                       return [
-                                               'url' => WCF::getPath().'images/favicon/'.$this->style->styleID.'.favicon-template.'.$file->getFileExtension()
-                                       ];
-                               }
-                               else {
-                                       throw new UserInputException('favicon', 'uploadFailed');
-                               }
+               if (!empty($this->parameters['customAssets']['added'])) {
+                       if (!is_dir($customAssetPath)) {
+                               FileUtil::makePath($customAssetPath);
                        }
-               }
-               catch (UserInputException $e) {
-                       $file->setValidationErrorType($e->getType());
-               }
-               
-               return ['errorType' => $file->getValidationErrorType()];
-       }
-       
-       /**
-        * Validates parameters to upload a cover photo.
-        *
-        * @since       3.1
-        */
-       public function validateUploadCoverPhoto() {
-               if (!MODULE_USER_COVER_PHOTO) {
-                       throw new PermissionDeniedException();
-               }
-               
-               // ignore tmp hash, uploading is supported for existing styles only
-               // and files will be finally processed on form submit
-               $this->parameters['tmpHash'] = '@@@WCF_INVALID_TMP_HASH@@@';
-               
-               $this->validateUpload();
-       }
-       
-       /**
-        * Handles the cover photo upload.
-        *
-        * @return      string[]
-        * @since       3.1
-        */
-       public function uploadCoverPhoto() {
-               // save files
-               /** @noinspection PhpUndefinedMethodInspection */
-               /** @var UploadFile[] $files */
-               $files = $this->parameters['__files']->getFiles();
-               $file = $files[0];
-               
-               try {
-                       if (!$file->getValidationErrorType()) {
-                               $fileLocation = $file->getLocation();
-                               try {
-                                       if (($imageData = getimagesize($fileLocation)) === false) {
-                                               throw new UserInputException('coverPhoto');
-                                       }
-                                       switch ($imageData[2]) {
-                                               case IMAGETYPE_PNG:
-                                               case IMAGETYPE_JPEG:
-                                               case IMAGETYPE_GIF:
-                                                       // fine
-                                                       break;
-                                               default:
-                                                       throw new UserInputException('coverPhoto');
-                                       }
-                                       
-                                       if ($imageData[0] < UserCoverPhoto::MIN_WIDTH) {
-                                               throw new UserInputException('coverPhoto', 'minWidth');
-                                       }
-                                       else if ($imageData[1] < UserCoverPhoto::MIN_HEIGHT) {
-                                               throw new UserInputException('coverPhoto', 'minHeight');
-                                       }
-                               }
-                               catch (SystemException $e) {
-                                       throw new UserInputException('coverPhoto');
-                               }
-                               
-                               // move uploaded file
-                               if (@copy($fileLocation, WCF_DIR.'images/coverPhotos/'.$this->style->styleID.'.tmp.'.$file->getFileExtension())) {
-                                       @unlink($fileLocation);
-                                       
-                                       // store extension within session variables
-                                       WCF::getSession()->register('styleCoverPhoto-'.$this->style->styleID, $file->getFileExtension());
-                                       
-                                       // return result
-                                       return [
-                                               'url' => WCF::getPath().'images/coverPhotos/'.$this->style->styleID.'.tmp.'.$file->getFileExtension()
-                                       ];
-                               }
-                               else {
-                                       throw new UserInputException('coverPhoto', 'uploadFailed');
-                               }
+                       
+                       /** @var \wcf\system\file\upload\UploadFile $file */
+                       foreach ($this->parameters['customAssets']['added'] as $file) {
+                               rename($file->getLocation(), $customAssetPath.$file->getFilename());
+                               $file->setProcessed($customAssetPath.$file->getFilename());
                        }
                }
-               catch (UserInputException $e) {
-                       $file->setValidationErrorType($e->getType());
-               }
-               
-               return ['errorType' => $file->getValidationErrorType()];
-       }
-       
-       /**
-        * Validates the parameters to delete a style's default cover photo.
-        * 
-        * @throws      PermissionDeniedException
-        * @throws      UserInputException
-        * @since       3.1
-        */
-       public function validateDeleteCoverPhoto() {
-               if (!MODULE_USER_COVER_PHOTO) {
-                       throw new PermissionDeniedException();
-               }
-               
-               $this->styleEditor = $this->getSingleObject();
-               if (!$this->styleEditor->coverPhotoExtension) {
-                       throw new UserInputException('objectIDs');
-               }
-       }
-       
-       /**
-        * Deletes a style's default cover photo.
-        * 
-        * @return      string[]
-        * @since       3.1
-        */
-       public function deleteCoverPhoto() {
-               $this->styleEditor->deleteCoverPhoto();
-               
-               return [
-                       'url' => WCF::getPath().'images/coverPhotos/'.(new Style($this->styleEditor->styleID))->getCoverPhoto()
-               ];
        }
        
        /**
@@ -865,8 +571,12 @@ BROWSERCONFIG;
                        'authorName' => $this->styleEditor->authorName,
                        'authorURL' => $this->styleEditor->authorURL,
                        'imagePath' => $this->styleEditor->imagePath,
-                       'apiVersion' => $this->styleEditor->apiVersion
+                       'apiVersion' => $this->styleEditor->apiVersion,
+                       
+                       'coverPhotoExtension' => $this->styleEditor->coverPhotoExtension,
+                       'hasFavicon' => $this->styleEditor->hasFavicon,
                ]);
+               $styleEditor = new StyleEditor($newStyle);
                
                // check if style description uses i18n
                if (preg_match('~^wcf.style.styleDescription\d+$~', $newStyle->styleDescription)) {
@@ -888,7 +598,6 @@ BROWSERCONFIG;
                        $statement->execute([$newStyle->styleDescription]);
                        
                        // update style description
-                       $styleEditor = new StyleEditor($newStyle);
                        $styleEditor->update([
                                'styleDescription' => $styleDescription
                        ]);
@@ -909,94 +618,36 @@ BROWSERCONFIG;
                foreach (['image', 'image2x'] as $imageType) {
                        $image = $this->styleEditor->{$imageType};
                        if ($image) {
-                               // get extension
-                               $fileExtension = mb_substr($image, mb_strrpos($image, '.'));
-                               
-                               // copy existing preview image
-                               if (@copy(WCF_DIR . 'images/' . $image, WCF_DIR . 'images/stylePreview-' . $newStyle->styleID . $fileExtension)) {
-                                       // bypass StyleEditor::update() to avoid scaling of already fitting image
-                                       $sql = "UPDATE  wcf" . WCF_N . "_style
-                                               SET     ".$imageType." = ?
-                                               WHERE   styleID = ?";
-                                       $statement = WCF::getDB()->prepareStatement($sql);
-                                       $statement->execute([
-                                               'stylePreview-' . $newStyle->styleID . $fileExtension,
-                                               $newStyle->styleID
-                                       ]);
-                               }
-                       }
-               }
-               
-               // copy cover photo
-               if ($this->styleEditor->coverPhotoExtension) {
-                       if (@copy(WCF_DIR . "images/coverPhotos/{$this->styleEditor->styleID}.{$this->styleEditor->coverPhotoExtension}", WCF_DIR . "images/coverPhotos/{$newStyle->styleID}.{$this->styleEditor->coverPhotoExtension}")) {
-                               $sql = "UPDATE  wcf" . WCF_N . "_style
-                                       SET     coverPhotoExtension = ?
-                                       WHERE   styleID = ?";
-                               $statement = WCF::getDB()->prepareStatement($sql);
-                               $statement->execute([
-                                       $this->styleEditor->coverPhotoExtension,
-                                       $newStyle->styleID
+                               $styleEditor->update([
+                                       $imageType => preg_replace('/^style-\d+/', 'style-'.$styleEditor->styleID, $image),
                                ]);
                        }
                }
                
-               // copy favicon
-               if ($this->styleEditor->hasFavicon) {
-                       $path = WCF_DIR . 'images/favicon/';
-                       foreach (glob($path . "{$this->styleEditor->styleID}.*") as $filepath) {
-                               @copy($filepath, $path . preg_replace('~^\d+\.~', "{$newStyle->styleID}.", basename($filepath)));
+               // Copy asset path
+               $iterator = new \RecursiveIteratorIterator(
+                       new \RecursiveDirectoryIterator(
+                               $this->styleEditor->getAssetPath(),
+                               \FilesystemIterator::SKIP_DOTS
+                       ), 
+                       \RecursiveIteratorIterator::SELF_FIRST
+               );
+               foreach ($iterator as $file) {
+                       /** @var \SplFileInfo $file */
+                       if ($file->isDir()) {
+                               $relativePath = FileUtil::getRelativePath($this->styleEditor->getAssetPath(), $file->getPathname());
                        }
-                       
-                       $sql = "UPDATE  wcf" . WCF_N . "_style
-                               SET     hasFavicon = ?
-                               WHERE   styleID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute([
-                               1,
-                               $newStyle->styleID
-                       ]);
-               }
-               
-               // copy images
-               if ($this->styleEditor->imagePath && is_dir(WCF_DIR . $this->styleEditor->imagePath)) {
-                       $path = FileUtil::removeTrailingSlash($this->styleEditor->imagePath);
-                       $newPath = '';
-                       $i = 2;
-                       while (true) {
-                               $newPath = "{$path}-{$i}/";
-                               if (!file_exists(WCF_DIR . $newPath)) {
-                                       break;
-                               }
-                               
-                               $i++;
+                       else if ($file->isFile()) {
+                               $relativePath = FileUtil::getRelativePath($this->styleEditor->getAssetPath(), $file->getPath());
                        }
-                       
-                       if (!FileUtil::makePath(WCF_DIR . $newPath)) {
-                               $newPath = '';
+                       else {
+                               throw new \LogicException('Unreachable');
                        }
-                       
-                       if ($newPath) {
-                               $src = FileUtil::addTrailingSlash(WCF_DIR . $this->styleEditor->imagePath);
-                               $dst = WCF_DIR . $newPath;
-                               
-                               $dir = opendir($src);
-                               while (($file = readdir($dir)) !== false) {
-                                       if ($file != '.' && $file != '..' && !is_dir($file)) {
-                                               @copy($src . $file, $dst . $file);
-                                       }
-                               }
-                               closedir($dir);
+                       $targetFolder = $newStyle->getAssetPath().$relativePath;
+                       FileUtil::makePath($targetFolder);
+                       if ($file->isFile()) {
+                               copy($file->getPathname(), $targetFolder.$file->getFilename());
                        }
-                       
-                       $sql = "UPDATE  wcf".WCF_N."_style
-                               SET     imagePath = ?
-                               WHERE   styleID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute([
-                               $newPath,
-                               $newStyle->styleID
-                       ]);
                }
                
                StyleCacheBuilder::getInstance()->reset();
index c3a4c1fb705bb70d8f2f46131c4a3ec7094ae68a..25cdd75360d03a86cf78581161f988a963b5b3e2 100644 (file)
@@ -13,7 +13,6 @@ use wcf\data\IEditableCachedObject;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\cache\builder\StyleCacheBuilder;
 use wcf\system\exception\SystemException;
-use wcf\system\image\ImageHandler;
 use wcf\system\io\Tar;
 use wcf\system\io\TarWriter;
 use wcf\system\language\LanguageFactory;
@@ -21,6 +20,8 @@ use wcf\system\package\PackageArchive;
 use wcf\system\style\StyleCompiler;
 use wcf\system\style\StyleHandler;
 use wcf\system\Regex;
+use wcf\system\style\exception\FontDownloadFailed;
+use wcf\system\style\FontManager;
 use wcf\system\WCF;
 use wcf\util\DateUtil;
 use wcf\util\FileUtil;
@@ -42,7 +43,7 @@ use wcf\util\XMLWriter;
 class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject {
        const EXCLUDE_WCF_VERSION = '6.0.0 Alpha 1';
        const INFO_FILE = 'style.xml';
-       const VALID_IMAGE_EXTENSIONS = ['.gif', '.jpg', '.jpeg', '.png', '.svg'];
+       const VALID_IMAGE_EXTENSIONS = ['gif', 'jpg', 'jpeg', 'png', 'svg', 'xml', 'json'];
        
        /**
         * list of compatible API versions
@@ -73,11 +74,6 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                if ($variables !== null) {
                        $this->setVariables($variables);
                }
-               
-               // scale preview image
-               if (!empty($parameters['image']) && $parameters['image'] != $this->image) {
-                       self::scalePreviewImage($parameters['image']);
-               }
        }
        
        /**
@@ -86,12 +82,6 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
        public function delete() {
                parent::delete();
                
-               // delete variables
-               $sql = "DELETE FROM     wcf".WCF_N."_style_variable_value
-                       WHERE           styleID = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([$this->styleID]);
-               
                // delete style files
                $files = @glob(WCF_DIR.'style/style-'.$this->styleID.'*.css');
                if (is_array($files)) {
@@ -360,9 +350,10 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
         * @param       string          $filename
         * @param       integer         $packageID
         * @param       StyleEditor     $style
+        * @param       boolean         $skipFontDownload
         * @return      StyleEditor
         */
-       public static function import($filename, $packageID = 1, StyleEditor $style = null) {
+       public static function import($filename, $packageID = 1, StyleEditor $style = null, $skipFontDownload = false) {
                // open file
                $tar = new Tar($filename);
                
@@ -387,39 +378,6 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        $style = StyleHandler::getInstance()->getStyleByName($styleData['packageName'], true);
                }
                
-               // import images
-               if (!empty($data['images']) && $data['imagesPath'] != 'images/') {
-                       // create images folder if necessary
-                       $imagesLocation = self::getFileLocation($data['imagesPath']);
-                       $styleData['imagePath'] = FileUtil::getRelativePath(WCF_DIR, $imagesLocation);
-                       
-                       $index = $tar->getIndexByFilename($data['images']);
-                       if ($index !== false) {
-                               // extract images tar
-                               $destination = FileUtil::getTemporaryFilename('images_');
-                               $tar->extract($index, $destination);
-                               
-                               // open images tar
-                               $imagesTar = new Tar($destination);
-                               $contentList = $imagesTar->getContentList();
-                               foreach ($contentList as $key => $val) {
-                                       if ($val['type'] == 'file') {
-                                               $fileExtension = mb_substr($val['filename'], mb_strrpos($val['filename'], '.'));
-                                               if (!in_array($fileExtension, self::VALID_IMAGE_EXTENSIONS)) {
-                                                       continue;
-                                               }
-                                               
-                                               $imagesTar->extract($key, $imagesLocation.basename($val['filename']));
-                                               FileUtil::makeWritable($imagesLocation.basename($val['filename']));
-                                       }
-                               }
-                               
-                               // delete tmp file
-                               $imagesTar->close();
-                               @unlink($destination);
-                       }
-               }
-               
                // handle templates
                if (!empty($data['templates'])) {
                        $templateGroupFolderName = '';
@@ -554,6 +512,13 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        }
                }
                
+               $duplicateLogo = false;
+               // duplicate logo if logo matches mobile logo
+               if (!empty($styleData['variables']['pageLogo']) && !empty($styleData['variables']['pageLogoMobile']) && $styleData['variables']['pageLogo'] == $styleData['variables']['pageLogoMobile']) {
+                       $styleData['variables']['pageLogoMobile'] = 'm-'.basename($styleData['variables']['pageLogo']);
+                       $duplicateLogo = true;
+               }
+               
                // save style
                if ($style === null) {
                        $styleData['packageID'] = $packageID;
@@ -597,17 +562,62 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        $style->update($styleData);
                }
                
+               // import images
+               if (!empty($data['images'])) {
+                       $index = $tar->getIndexByFilename($data['images']);
+                       if ($index !== false) {
+                               // extract images tar
+                               $destination = FileUtil::getTemporaryFilename('images_');
+                               $tar->extract($index, $destination);
+                               
+                               // open images tar
+                               $imagesTar = new Tar($destination);
+                               $contentList = $imagesTar->getContentList();
+                               foreach ($contentList as $key => $val) {
+                                       if ($val['type'] == 'file') {
+                                               $path = FileUtil::getRealPath($val['filename']);
+                                               $fileExtension = pathinfo($path, PATHINFO_EXTENSION);
+
+                                               if (!in_array($fileExtension, self::VALID_IMAGE_EXTENSIONS)) {
+                                                       continue;
+                                               }
+                                               
+                                               if (strpos($path, '../') !== false) {
+                                                       continue;
+                                               }
+                                               
+                                               $targetFile = FileUtil::getRealPath($style->getAssetPath().$path);
+                                               if (strpos(FileUtil::getRelativePath($style->getAssetPath(), $targetFile), '../') !== false) {
+                                                       continue;
+                                               }
+                                               
+                                               // duplicate pageLogo for mobile version
+                                               if ($duplicateLogo && $val['filename'] == $styleData['variables']['pageLogo']) {
+                                                       $imagesTar->extract($key, $style->getAssetPath().'m-'.basename($targetFile));
+                                               }
+                                               
+                                               $imagesTar->extract($key, $targetFile);
+                                               FileUtil::makeWritable($targetFile);
+                                       }
+                               }
+                               
+                               // delete tmp file
+                               $imagesTar->close();
+                               @unlink($destination);
+                       }
+               }
+               
                // import preview image
                foreach (['image', 'image2x'] as $type) {
                        if (!empty($data[$type])) {
-                               $fileExtension = mb_substr($data[$type], mb_strrpos($data[$type], '.'));
+                               $fileExtension = pathinfo($data[$type], PATHINFO_EXTENSION);
                                if (!in_array($fileExtension, self::VALID_IMAGE_EXTENSIONS)) {
                                        continue;
                                }
                                
                                $index = $tar->getIndexByFilename($data[$type]);
                                if ($index !== false) {
-                                       $filename = WCF_DIR . 'images/stylePreview-' . $style->styleID . ($type === 'image2x' ? '@2x' : '') . $fileExtension;
+                                       $filename = $style->getAssetPath().'stylePreview' . ($type === 'image2x' ? '@2x' : '') . '.' . $fileExtension;
                                        $tar->extract($index, $filename);
                                        FileUtil::makeWritable($filename);
                                        
@@ -618,7 +628,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                                                                        case IMAGETYPE_PNG:
                                                                        case IMAGETYPE_JPEG:
                                                                        case IMAGETYPE_GIF:
-                                                                               $style->update([$type => 'stylePreview-' . $style->styleID . ($type === 'image2x' ? '@2x' : '') . $fileExtension]);
+                                                                               $style->update([$type => 'style-' . $style->styleID . '/stylePreview' . ($type === 'image2x' ? '@2x' : '') . '.' . $fileExtension]);
                                                                }
                                                        }
                                                }
@@ -632,10 +642,10 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                
                // import cover photo
                if (!empty($data['coverPhoto'])) {
-                       $fileExtension = mb_substr($data['coverPhoto'], mb_strrpos($data['coverPhoto'], '.'));
+                       $fileExtension = pathinfo($data['coverPhoto'], PATHINFO_EXTENSION);
                        $index = $tar->getIndexByFilename($data['coverPhoto']);
                        if ($index !== false && in_array($fileExtension, self::VALID_IMAGE_EXTENSIONS)) {
-                               $filename = WCF_DIR . 'images/coverPhotos/' . $style->styleID . $fileExtension;
+                               $filename = $style->getAssetPath().'coverPhoto.' . $fileExtension;
                                $tar->extract($index, $filename);
                                FileUtil::makeWritable($filename);
                                
@@ -646,7 +656,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                                                                case IMAGETYPE_PNG:
                                                                case IMAGETYPE_JPEG:
                                                                case IMAGETYPE_GIF:
-                                                                       $style->update(['coverPhotoExtension' => mb_substr($fileExtension, 1)]);
+                                                                       $style->update(['coverPhotoExtension' => $fileExtension]);
                                                        }
                                                }
                                        }
@@ -657,6 +667,18 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        }
                }
                
+               if (!$skipFontDownload) {
+                       // download google fonts
+                       $fontManager = FontManager::getInstance();
+                       $family = $style->getVariable('wcfFontFamilyGoogle');
+                       try {
+                               $fontManager->downloadFamily($family);
+                       }
+                       catch (FontDownloadFailed $e) {
+                               // ignore
+                       }
+               }
+
                $tar->close();
                
                return $style;
@@ -758,7 +780,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                }
                
                // append cover photo
-               $coverPhoto = ($this->coverPhotoExtension) ? WCF_DIR.'images/coverPhotos/'.$this->styleID.'.'.$this->coverPhotoExtension : '';
+               $coverPhoto = ($this->coverPhotoExtension) ? $this->getAssetPath().'coverPhoto.'.$this->coverPhotoExtension : '';
                if ($coverPhoto && @file_exists($coverPhoto)) {
                        $styleTar->add($coverPhoto, '', FileUtil::addTrailingSlash(dirname($coverPhoto)));
                }
@@ -790,8 +812,8 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                $xml->writeElement('date', $this->styleDate);
                $xml->writeElement('version', $this->styleVersion);
                $xml->writeElement('apiVersion', $this->apiVersion);
-               if ($this->image) $xml->writeElement('image', $this->image);
-               if ($this->image2x) $xml->writeElement('image2x', $this->image2x);
+               if ($this->image) $xml->writeElement('image', basename($this->image));
+               if ($this->image2x) $xml->writeElement('image2x', basename($this->image2x));
                if ($coverPhoto) $xml->writeElement('coverPhoto', basename(FileUtil::unifyDirSeparator($coverPhoto)));
                if ($this->copyright) $xml->writeElement('copyright', $this->copyright);
                if ($this->license) $xml->writeElement('license', $this->license);
@@ -876,25 +898,31 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        @unlink($templatesTarName);
                }
                
-               if ($images && ($this->imagePath && $this->imagePath != 'images/')) {
+               if ($images) {
                        // create images tar
                        $imagesTarName = FileUtil::getTemporaryFilename('images_', '.tar');
                        $imagesTar = new TarWriter($imagesTarName);
                        FileUtil::makeWritable($imagesTarName);
                        
-                       // append images to tar
-                       $path = FileUtil::addTrailingSlash(WCF_DIR.$this->imagePath);
-                       if (file_exists($path) && is_dir($path)) {
-                               $handle = opendir($path);
-                               
-                               $regEx = new Regex('\.(jpg|jpeg|gif|png|svg)$', Regex::CASE_INSENSITIVE);
-                               while (($file = readdir($handle)) !== false) {
-                                       if (is_file($path.$file) && $regEx->match($file)) {
-                                               $imagesTar->add($path.$file, '', $path);
-                                       }
-                               }
+                       $regEx = new Regex('\.(jpg|jpeg|gif|png|svg|ico|json|xml|txt)$', Regex::CASE_INSENSITIVE);
+                       $iterator = new \RecursiveIteratorIterator(
+                               new \RecursiveDirectoryIterator(
+                                       $this->getAssetPath(),
+                                       \FilesystemIterator::SKIP_DOTS
+                               ), 
+                               \RecursiveIteratorIterator::SELF_FIRST
+                       );
+                       foreach ($iterator as $file) {
+                               /** @var \SplFileInfo $file */
+                               if (!$file->isFile()) continue;
+                               if (!$regEx->match($file->getPathName())) continue;
+                               // Skip preview images and cover photos.
+                               if ($this->image && FileUtil::unifyDirSeparator($file->getPathname()) === FileUtil::unifyDirSeparator(WCF_DIR.'images/'.$this->image)) continue;
+                               if ($this->image2x && FileUtil::unifyDirSeparator($file->getPathname()) === FileUtil::unifyDirSeparator(WCF_DIR.'images/'.$this->image2x)) continue;
+                               if ($coverPhoto && FileUtil::unifyDirSeparator($file->getPathname()) === FileUtil::unifyDirSeparator($coverPhoto)) continue;
+
+                               $imagesTar->add($file->getPathName(), '', $this->getAssetPath());
                        }
-                       
                        // append images tar to style tar
                        $imagesTar->create();
                        $styleTar->add($imagesTarName, 'images.tar', $imagesTarName);
@@ -1059,16 +1087,19 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                $style = parent::create($parameters);
                $styleEditor = new StyleEditor($style);
                
+               // create asset path
+               FileUtil::makePath($style->getAssetPath());
+               
+               $styleEditor->update([
+                       'imagePath' => FileUtil::getRelativePath(WCF_DIR, $style->getAssetPath()),
+               ]);
+               $styleEditor = new StyleEditor(new Style($style->styleID));
+               
                // save variables
                if ($variables !== null) {
                        $styleEditor->setVariables($variables);
                }
                
-               // scale preview image
-               if (!empty($parameters['image'])) {
-                       self::scalePreviewImage(WCF_DIR.$parameters['image']);
-               }
-               
                return $style;
        }
        
@@ -1078,16 +1109,4 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
        public static function resetCache() {
                StyleCacheBuilder::getInstance()->reset();
        }
-       
-       /**
-        * Scales the style preview image.
-        * 
-        * @param       string          $filename
-        */
-       public static function scalePreviewImage($filename) {
-               $adapter = ImageHandler::getInstance()->getAdapter();
-               $adapter->loadFile(WCF_DIR.'images/'.$filename);
-               $thumbnail = $adapter->createThumbnail(Style::PREVIEW_IMAGE_MAX_WIDTH, Style::PREVIEW_IMAGE_MAX_HEIGHT);
-               $adapter->writeImage($thumbnail, WCF_DIR.'images/'.$filename);
-       }
 }
index 645a205d9ab14b3632403d46792966b98e27e4ba..46938316157eda7b235a6c2c6a7bde870dc8f61a 100644 (file)
@@ -54,6 +54,16 @@ class Trophy extends DatabaseObject implements ITitledLinkObject, IRouteControll
         */
        const DEFAULT_SIZE = 32;
        
+       /**
+        * Returns the title of the trophy.
+        * 
+        * @return      string
+        * @since       5.3
+        */
+       public function __toString() {
+               return $this->getTitle();
+       }
+       
        /**
         * @inheritDoc
         */
index 5898034e1ff75fe8cfc8af159dd11f53246d662e..d745216d199f999e0114695644e559cd93b1bf62 100644 (file)
@@ -88,7 +88,13 @@ class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction
                
                $userTrophyAction = new UserTrophyAction($userTrophyList->getObjects(), 'delete');
                $userTrophyAction->executeAction();
-               
+
+               foreach ($this->getObjects() as $trophy) {
+                       if ($trophy->iconFile) {
+                               @unlink(WCF_DIR . 'images/trophy/' . $trophy->iconFile);
+                       }
+               }
+
                $returnValues = parent::delete();
                
                UserStorageHandler::getInstance()->resetAll('specialTrophies');
@@ -105,7 +111,7 @@ class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction
                if (isset($this->parameters['data']['type']) && $this->parameters['data']['type'] === Trophy::TYPE_IMAGE) {
                        foreach ($this->getObjects() as $trophy) {
                                if (isset($this->parameters['tmpHash'])) {
-                                       $this->updateTrophyImage($trophy);
+                                       $this->updateTrophyImage($trophy->getDecoratedObject());
                                }
                        }
                }
index ace53a093df3bccb75d81806b885a1bbf0713f59..6293a2d59d0ebe1253cf5203118527d94fd36ce2 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\user;
+use wcf\data\IPopoverObject;
 use wcf\data\language\Language;
 use wcf\data\user\group\UserGroup;
 use wcf\data\DatabaseObject;
@@ -34,7 +35,8 @@ use wcf\util\UserUtil;
  * @property-read      integer         $banned                         is `1` if the user is banned, otherwise `0`
  * @property-read      string          $banReason                      reason why the user is banned
  * @property-read      integer         $banExpires                     timestamp at which the banned user is automatically unbanned
- * @property-read      integer         $activationCode                 code sent to the user's email address used for account activation
+ * @property-read      integer         $activationCode                 flag which determines, whether the user is activated (for legacy reasons an random integer, if the user is *not* activated)
+ * @property-read      string          $emailConfirmed                 code sent to the user's email address used for account activation or null if the email is confirmed
  * @property-read      integer         $lastLostPasswordRequestTime    timestamp at which the user has reported that they lost their password or 0 if password has not been reported as lost
  * @property-read      string          $lostPasswordKey                code used for authenticating setting new password after password loss or empty if password has not been reported as lost
  * @property-read      integer         $lastUsernameChange             timestamp at which the user changed their name the last time or 0 if username has not been changed
@@ -71,7 +73,7 @@ use wcf\util\UserUtil;
  * @property-read      integer         $articles                       number of articles written by the user
  * @property-read       string          $blacklistMatches               JSON string of an array with all matches in the blacklist, otherwise an empty string 
  */
-final class User extends DatabaseObject implements IRouteController, IUserContent {
+final class User extends DatabaseObject implements IPopoverObject, IRouteController, IUserContent {
        /**
         * list of group ids
         * @var integer[]
@@ -102,6 +104,11 @@ final class User extends DatabaseObject implements IRouteController, IUserConten
         */
        protected static $userOptions;
        
+       const REGISTER_ACTIVATION_NONE = 0;
+       const REGISTER_ACTIVATION_USER = 1;
+       const REGISTER_ACTIVATION_ADMIN = 2;
+       const REGISTER_ACTIVATION_USER_AND_ADMIN = self::REGISTER_ACTIVATION_USER | self::REGISTER_ACTIVATION_ADMIN;
+       
        /** @noinspection PhpMissingParentConstructorInspection */
        /**
         * @inheritDoc
@@ -402,6 +409,16 @@ final class User extends DatabaseObject implements IRouteController, IUserConten
                return 0;
        }
        
+       /**
+        * Returns true if the email is confirmed.
+        *
+        * @return      boolean
+        * @since       5.3
+        */
+       public function isEmailConfirmed() {
+               return $this->emailConfirmed === null;
+       }
+       
        /**
         * Returns the time zone of this user.
         * 
@@ -584,7 +601,7 @@ final class User extends DatabaseObject implements IRouteController, IUserConten
         * @return      boolean
         */
        public function canPurchasePaidSubscriptions() {
-               return WCF::getUser()->userID && WCF::getUser()->activationCode == 0;
+               return WCF::getUser()->userID && !$this->pendingActivation();
        }
        
        /**
@@ -595,7 +612,7 @@ final class User extends DatabaseObject implements IRouteController, IUserConten
         * @since 5.2
         */
        public function getBlacklistMatches() {
-               if ($this->activationCode && $this->blacklistMatches) {
+               if ($this->pendingActivation() && $this->blacklistMatches) {
                        $matches = JSON::decode($this->blacklistMatches);
                        if (is_array($matches)) {
                                return $matches;
@@ -619,4 +636,61 @@ final class User extends DatabaseObject implements IRouteController, IUserConten
                        return WCF::getLanguage()->get('wcf.user.' . $field);
                }, $this->getBlacklistMatches());
        }
+       
+       /**
+        * Returns true if this user is not activated.
+        *
+        * @return      boolean
+        * @since       5.3
+        */
+       public function pendingActivation() {
+               return $this->activationCode != 0;
+       }
+       
+       /**
+        * Returns true if this user requires activation by the user.
+        *
+        * @return      boolean
+        * @since       5.3
+        */
+       public function requiresEmailActivation() {
+               return REGISTER_ACTIVATION_METHOD & self::REGISTER_ACTIVATION_USER && $this->pendingActivation() && !$this->isEmailConfirmed();
+       }
+       
+       /**
+        * Returns true if this user requires the activation by an admin.
+        *
+        * @return      boolean
+        * @since       5.3
+        */
+       public function requiresAdminActivation() {
+               return REGISTER_ACTIVATION_METHOD & self::REGISTER_ACTIVATION_ADMIN && $this->pendingActivation();
+       }
+       
+       /**
+        * Returns true if this user can confirm the email themself.
+        *
+        * @return      boolean
+        * @since       5.3
+        */
+       public function canEmailConfirm() {
+               return REGISTER_ACTIVATION_METHOD & self::REGISTER_ACTIVATION_USER && !$this->isEmailConfirmed();
+       }
+       
+       /**
+        * Returns true, if the user must confirm his email by themself. 
+        * 
+        * @return      boolean
+        * @since       5.3
+        */
+       public function mustSelfEmailConfirm() {
+               return REGISTER_ACTIVATION_METHOD & self::REGISTER_ACTIVATION_USER;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getPopoverLinkClass() {
+               return 'userLink';
+       }
 }
index f8cea74a7f0987af8821d6d8f4e1cdd81d0ef5ab..e2de2fe17e1c142b26069002ddf8b877af203474 100644 (file)
@@ -618,17 +618,77 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                $this->validateEnable();
        }
        
+       /**
+        * Validates the confirm email action.
+        * @since       5.3
+        */
+       public function validateConfirmEmail() {
+               $this->validateEnable();
+       }
+       
+       /**
+        * Validates the unconfirm email action.
+        * @since       5.3
+        */
+       public function validateUnconfirmEmail() {
+               $this->validateEnable();
+       }
+       
+       /**
+        * Marks the email address as confirmed. It also enables the user, iff the register method is user activation only.
+        * @since       5.3
+        */
+       public function confirmEmail() {
+               if (empty($this->objects)) $this->readObjects();
+               
+               (new UserAction($this->objects, 'update', [
+                       'data' => [
+                               'emailConfirmed' => null,
+                       ]
+               ]))->executeAction();
+               
+               if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN)) {
+                       $this->enable();
+               }
+               
+               $this->unmarkItems();
+       }
+       
+       /**
+        * Marks the email address as unconfirmed.
+        * @since       5.3
+        */
+       public function unconfirmEmail() {
+               if (empty($this->objects)) $this->readObjects();
+               
+               foreach ($this->objects as $object) {
+                       (new UserAction([$object], 'update', [
+                               'data' => [
+                                       'emailConfirmed' => bin2hex(\random_bytes(20))
+                               ]
+                       ]))->executeAction();
+               }
+               
+               $this->unmarkItems();
+       }
+       
        /**
         * Enables users.
         */
        public function enable() {
                if (empty($this->objects)) $this->readObjects();
                
+               $data = [
+                       'activationCode' => 0,
+                       'blacklistMatches' => '',
+               ];
+               
+               if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
+                       $data['emailConfirmed'] = null;
+               }
+               
                $action = new UserAction($this->objects, 'update', [
-                       'data' => [
-                               'activationCode' => 0,
-                               'blacklistMatches' => '',
-                       ],
+                       'data' => $data,
                        'removeGroups' => UserGroup::getGroupIDsByType([UserGroup::GUESTS])
                ]);
                $action->executeAction();
@@ -668,9 +728,14 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
        public function disable() {
                if (empty($this->objects)) $this->readObjects();
                
+               // We reset the activationCode (which indicates, that the user is not enabled) AND disable the email
+               // confirm status, because if the user can enable himself by an email confirmation and we do not reset 
+               // the email confirmed status, the behavior is undefined, because a user exists, which is not enabled
+               // but has a valid email address (Which doesn't usually happen). 
                $action = new UserAction($this->objects, 'update', [
                        'data' => [
-                               'activationCode' => UserRegistrationUtil::getActivationCode()
+                               'activationCode' => UserRegistrationUtil::getActivationCode(),
+                               'emailConfirmed' => bin2hex(\random_bytes(20)),
                        ],
                        'removeGroups' => UserGroup::getGroupIDsByType([UserGroup::USERS])
                ]);
@@ -989,6 +1054,21 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                // does nothing
        }
        
+       /**
+        * @since 5.3
+        */
+       public function validateSaveUserConsent() {}
+       
+       /**
+        * @since 5.3
+        */
+       public function saveUserConsent() {
+               $userEditor = new UserEditor(WCF::getUser());
+               $userEditor->updateUserOptions([
+                       User::getUserOptionID('enableEmbeddedMedia') => 1,
+               ]);
+       }
+       
        /**
         * Validates the 'resendActivationMail' action.
         * 
@@ -1004,12 +1084,13 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                        throw new PermissionDeniedException();
                }
                
-               if (REGISTER_ACTIVATION_METHOD != 1) {
+               if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
                        throw new IllegalLinkException();
                }  
                
                foreach ($this->objects as $object) {
-                       if (!$object->activationCode) {
+                       /** @var UserEditor $object */
+                       if (!$object->canEmailConfirm()) {
                                throw new UserInputException('objectIDs');
                        }
                }
@@ -1024,7 +1105,7 @@ class UserAction extends AbstractDatabaseObjectAction implements IClipboardActio
                foreach ($this->objects as $object) {
                        $action = new UserAction([$object], 'update', [
                                'data' => [
-                                       'activationCode' => UserRegistrationUtil::getActivationCode()
+                                       'emailConfirmed' => bin2hex(\random_bytes(20))
                                ]
                        ]);
                        $action->executeAction();
index 0a14ca3e52c0df4c047a78a4aa18d89c13351968..4b51a744f41741ba696c58b6c7b58d1e3cf1ba04 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\user;
+use wcf\data\DatabaseObject;
 use wcf\data\user\option\UserOption;
 use wcf\data\IGroupedUserListAction;
 use wcf\system\cache\builder\UserOptionCacheBuilder;
@@ -27,10 +28,22 @@ class UserBirthdayAction extends UserProfileAction implements IGroupedUserListAc
         */
        public function validateGetGroupedUserList() {
                $this->readString('date');
+               $this->readString('sortField', true);
+               $this->readString('sortOrder', true);
                
                if (!preg_match('/\d{4}-\d{2}-\d{2}/', $this->parameters['date'])) {
                        throw new UserInputException();
                }
+               
+               if ($this->parameters['sortField'] && $this->parameters['sortOrder']) {
+                       if (!in_array($this->parameters['sortField'], ['username', 'activityPoints', 'registrationDate'])) {
+                               throw new UserInputException('sortField');
+                       }
+                       
+                       if (!in_array($this->parameters['sortOrder'], ['ASC', 'DESC'])) {
+                               throw new UserInputException('sortOrder');
+                       }
+               }
        }
        
        /**
@@ -62,6 +75,10 @@ class UserBirthdayAction extends UserProfileAction implements IGroupedUserListAc
                        }
                }
                
+               if ($this->parameters['sortField'] && $this->parameters['sortOrder']) {
+                       DatabaseObject::sort($users, $this->parameters['sortField'], $this->parameters['sortOrder']);
+               }
+               
                WCF::getTPL()->assign([
                        'users' => $users,
                        'year' => $year
index 2af52f43d99c18182a1e09fe8b32254421b1c1d8..cd0bf855cd8c300340a166a50be202370e87bd49 100644 (file)
@@ -105,6 +105,7 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
        
        const GENDER_MALE = 1;
        const GENDER_FEMALE = 2;
+       const GENDER_OTHER = 3;
        
        const ACCESS_EVERYONE = 0;
        const ACCESS_REGISTERED = 1;
@@ -406,7 +407,10 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
         * @return      boolean
         */
        public function canViewOnlineStatus() {
-               return (WCF::getUser()->userID == $this->userID || WCF::getSession()->getPermission('admin.user.canViewInvisible') || $this->isAccessible('canViewOnlineStatus'));
+               return WCF::getUser()->userID == $this->userID
+                       || WCF::getSession()->getPermission('admin.user.canViewInvisible')
+                       || !$this->getPermission('user.profile.canHideOnlineStatus')
+                       || $this->isAccessible('canViewOnlineStatus');
        }
        
        /**
@@ -426,7 +430,7 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
        }
        
        /**
-        * Returns the special trophies for the user. 
+        * Returns the special trophies for the user.
         *
         * @return      Trophy[]
         */
@@ -459,14 +463,14 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
                        $conditionBuilder->add('trophyID IN (?)', [$trophyDeleteIDs]);
                        
                        // reset the user special trophies 
-                       $sql = "DELETE FROM wcf".WCF_N."_user_special_trophy ".$conditionBuilder; 
+                       $sql = "DELETE FROM wcf".WCF_N."_user_special_trophy ".$conditionBuilder;
                        $statement = WCF::getDB()->prepareStatement($sql);
                        $statement->execute($conditionBuilder->getParameters());
                        
                        UserStorageHandler::getInstance()->update($this->userID, 'specialTrophies', serialize($specialTrophies));
                }
                $trophies = TrophyCache::getInstance()->getTrophiesByID($specialTrophies);
-               Trophy::sort($trophies, 'showOrder'); 
+               Trophy::sort($trophies, 'showOrder');
                
                return $trophies;
        }
@@ -881,7 +885,7 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
         * @return      boolean
         */
        public function canEditOwnProfile() {
-               if ($this->activationCode || !$this->getPermission('user.profile.canEditUserProfile')) {
+               if ($this->pendingActivation() || !$this->getPermission('user.profile.canEditUserProfile')) {
                        return false;
                }
                
@@ -1018,7 +1022,7 @@ class UserProfile extends DatabaseObjectDecorator implements ITitledLinkObject {
         * @return      string
         */
        public function getAnchorTag() {
-               return '<a href="'.$this->getLink().'" class="userLink" data-user-id="'.$this->userID.'">'.StringUtil::encodeHTML($this->username).'</a>';
+               return '<a href="'.$this->getLink().'" class="userLink" data-object-id="'.$this->userID.'">'.StringUtil::encodeHTML($this->username).'</a>';
        }
        
        /**
index 38c5765724e52df5091d2a67e37b24a055763cc6..36420cd9b8747a5def45fc21721e1a1d0f72b633 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\user;
+use wcf\data\IPopoverAction;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\data\user\group\UserGroup;
 use wcf\system\bbcode\BBCodeHandler;
@@ -30,11 +31,11 @@ use wcf\util\StringUtil;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Data\User
  */
-class UserProfileAction extends UserAction {
+class UserProfileAction extends UserAction implements IPopoverAction {
        /**
         * @inheritDoc
         */
-       protected $allowGuestAccess = ['getUserProfile', 'getDetailedActivityPointList'];
+       protected $allowGuestAccess = ['getUserProfile', 'getDetailedActivityPointList', 'getPopover'];
        
        /**
         * @var User
@@ -93,8 +94,28 @@ class UserProfileAction extends UserAction {
         * Validates user profile preview.
         * 
         * @throws      UserInputException
+        * @deprecated  since 5.3, use `validateGetPopover()`
         */
        public function validateGetUserProfile() {
+               $this->validateGetPopover();
+       }
+       
+       /**
+        * Returns user profile preview.
+        * 
+        * @return      array
+        * @deprecated  since 5.3, use `getPopover()`
+        */
+       public function getUserProfile() {
+               return array_merge($this->getPopover(), [
+                       'userID' => reset($this->objectIDs),
+               ]);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validateGetPopover() {
                WCF::getSession()->checkPermissions(['user.profile.canViewUserProfile']);
                
                if (count($this->objectIDs) != 1) {
@@ -103,24 +124,18 @@ class UserProfileAction extends UserAction {
        }
        
        /**
-        * Returns user profile preview.
-        * 
-        * @return      array
+        * @inheritDoc
         */
-       public function getUserProfile() {
+       public function getPopover() {
                $userID = reset($this->objectIDs);
                
                if ($userID) {
-                       $userProfileList = new UserProfileList();
-                       $userProfileList->getConditionBuilder()->add("user_table.userID = ?", [$userID]);
-                       $userProfileList->readObjects();
-                       $userProfiles = $userProfileList->getObjects();
-                       
-                       if (empty($userProfiles)) {
-                               WCF::getTPL()->assign('unknownUser', true);
+                       $userProfile = UserProfileRuntimeCache::getInstance()->getObject($userID);
+                       if ($userProfile) {
+                               WCF::getTPL()->assign('user', $userProfile);
                        }
                        else {
-                               WCF::getTPL()->assign('user', reset($userProfiles));
+                               WCF::getTPL()->assign('unknownUser', true);
                        }
                }
                else {
@@ -129,7 +144,6 @@ class UserProfileAction extends UserAction {
                
                return [
                        'template' => WCF::getTPL()->fetch('userProfilePreview'),
-                       'userID' => $userID
                ];
        }
        
@@ -414,7 +428,7 @@ class UserProfileAction extends UserAction {
                                $fixUserGroupIDs[$user->userID] = [UserGroup::EVERYONE];
                                $groupIDs[] = UserGroup::EVERYONE;
                        }
-                       if ($user->activationCode) {
+                       if ($user->pendingActivation()) {
                                if (!in_array(UserGroup::GUESTS, $groupIDs)) {
                                        if (!isset($fixUserGroupIDs[$user->userID])) $fixUserGroupIDs[$user->userID] = [];
                                        $fixUserGroupIDs[$user->userID][] = UserGroup::GUESTS;
index 0a44b0e8a3e174c507e0071c8004d0ca8bcbc1ff..5d8280d821069aaba6efbea0356e2d2eea566d92 100644 (file)
@@ -33,6 +33,8 @@ class UserRegistrationAction extends UserAction {
        
        /**
         * Validates the validate password function.
+        * 
+        * @deprecated 5.3
         */
        public function validateValidatePassword() {
                $this->readString('password');
@@ -89,18 +91,9 @@ class UserRegistrationAction extends UserAction {
        }
        
        /**
-        * Validates given password.
-        * 
-        * @return      array
+        * @deprecated  5.3 - Always returns isValid = true.
         */
        public function validatePassword() {
-               if (!UserRegistrationUtil::isSecurePassword($this->parameters['password'])) {
-                       return [
-                               'isValid' => false,
-                               'error' => 'notSecure'
-                       ];
-               }
-               
                return [
                        'isValid' => true
                ];
index e63fac3b3b28dfc0d5c6e9e86b7a0c32150809e1..9097c1a9c3e87e04e67fe7d6fe0b1f59dfad1aa1 100644 (file)
@@ -160,7 +160,7 @@ class UserAvatarAction extends AbstractDatabaseObjectAction {
                }
                
                $data = [
-                       'avatarName' => $tmp['basename'],
+                       'avatarName' => mb_substr($tmp['basename'], 0, 255),
                        'avatarExtension' => $tmp['extension'],
                        'width' => $imageData[0],
                        'height' => $imageData[1],
index 3021c05f141d2b9c0397a380937f936519c89739..e1fbb86cedcc7d1830c4a6ec3f7996c5df47679a 100644 (file)
@@ -65,21 +65,19 @@ class UserFollowAction extends AbstractDatabaseObjectAction implements IGroupedU
        }
        
        /**
-        * Follows an user.
+        * Follows a user.
         * 
         * @return      array
         */
        public function follow() {
-               $follow = UserFollow::getFollow(WCF::getUser()->userID, $this->parameters['data']['userID']);
+               /** @var UserFollow $follow */
+               $follow = UserFollowEditor::createOrIgnore([
+                       'userID' => WCF::getUser()->userID,
+                       'followUserID' => $this->parameters['data']['userID'],
+                       'time' => TIME_NOW,
+               ]);
                
-               // not following right now
-               if (!$follow->followID) {
-                       $follow = UserFollowEditor::create([
-                               'userID' => WCF::getUser()->userID,
-                               'followUserID' => $this->parameters['data']['userID'],
-                               'time' => TIME_NOW
-                       ]);
-                       
+               if ($follow !== null) {
                        // send notification
                        UserNotificationHandler::getInstance()->fireEvent(
                                'following',
@@ -109,7 +107,7 @@ class UserFollowAction extends AbstractDatabaseObjectAction implements IGroupedU
        }
        
        /**
-        * Stops following an user.
+        * Stops following a user.
         * 
         * @return      array
         */
index d9b9313785fdc0a7f2ef1a72094a9166565f6536..c0382946e4a57d5764f54827a88a2bf8e3e8737c 100644 (file)
@@ -125,6 +125,22 @@ class UserGroup extends DatabaseObject implements ITitledObject {
                return $groups;
        }
        
+       /**
+        * Returns a sorted list of groups filtered by given type.
+        *
+        * @param       integer[]       $types
+        * @param       integer[]       $invalidGroupTypes
+        * @return      UserGroup[]
+        * @since       5.3
+        */
+       public static function getSortedGroupsByType(array $types = [], array $invalidGroupTypes = []) {
+               $userGroups = self::getGroupsByType($types, $invalidGroupTypes);
+               
+               self::sortGroups($userGroups);
+               
+               return $userGroups;
+       }
+       
        /**
         * Returns unique group by given type. Only works for the default user groups.
         * 
@@ -211,13 +227,23 @@ class UserGroup extends DatabaseObject implements ITitledObject {
        /**
         * Returns true if this is the 'Owner' group.
         * 
-        * @return bool
-        * @since 5.2
+        * @return      bool
+        * @since       5.2
         */
        public function isOwner() {
                return $this->groupType == self::OWNER;
        }
        
+       /**
+        * Returns `true` if the active user can copy this user group.
+        * 
+        * @return      bool
+        * @since       5.3
+        */
+       public function canCopy() {
+               return WCF::getSession()->getPermission('admin.user.canAddGroup') && $this->isAccessible();
+       }
+       
        /**
         * Returns true if the given groups are accessible for the active user.
         * 
@@ -270,9 +296,7 @@ class UserGroup extends DatabaseObject implements ITitledObject {
        public static function getSortedAccessibleGroups(array $groupTypes = [], array $invalidGroupTypes = []) {
                $userGroups = self::getAccessibleGroups($groupTypes, $invalidGroupTypes);
                
-               uasort($userGroups, function(UserGroup $groupA, UserGroup $groupB) {
-                       return strcasecmp($groupA->getName(), $groupB->getName());
-               });
+               self::sortGroups($userGroups);
                
                return $userGroups;
        }
@@ -545,4 +569,16 @@ class UserGroup extends DatabaseObject implements ITitledObject {
                
                return self::$ownerGroup ? self::$ownerGroup->groupID : null;
        }
+       
+       /**
+        * Sorts the given user groups alphabetically.
+        * 
+        * @param       UserGroup[]     $userGroups
+        * @since       5.3
+        */
+       public static function sortGroups(array &$userGroups) {
+               uasort($userGroups, function(UserGroup $groupA, UserGroup $groupB) {
+                       return strcasecmp($groupA->getName(), $groupB->getName());
+               });
+       }
 }
index 5d24644c3367d126ecd5e00cd4e838bae63b61c4..30d03db4a6391f5e6ee8f6f5a807b6f73ed6f865 100644 (file)
@@ -94,7 +94,7 @@ class UserGroupAction extends AbstractDatabaseObjectAction {
                $this->readBoolean('copyUserGroupOptions');
                
                $this->groupEditor = $this->getSingleObject();
-               if (!$this->groupEditor->isAccessible() || $this->groupEditor->groupType != UserGroup::OTHER) {
+               if (!$this->groupEditor->canCopy()) {
                        throw new PermissionDeniedException();
                }
        }
@@ -120,18 +120,25 @@ class UserGroupAction extends AbstractDatabaseObjectAction {
                
                $optionValues = $statement->fetchMap('optionID', 'optionValue');
                
-               $groupAction = new UserGroupAction([], 'create', [
+               $groupType = $this->groupEditor->groupType;
+               // When copying special user groups of which only one may exist,
+               // change the group type to 'other'.
+               if (in_array($groupType, [UserGroup::EVERYONE, UserGroup::GUESTS, UserGroup::USERS, UserGroup::OWNER])) {
+                       $groupType = UserGroup::OTHER;
+               }
+               
+               /** @var UserGroup $group */
+               $group = (new UserGroupAction([], 'create', [
                        'data' => [
                                'groupName' => $this->groupEditor->groupName,
                                'groupDescription' => $this->groupEditor->groupDescription,
                                'priority' => $this->groupEditor->priority,
                                'userOnlineMarking' => $this->groupEditor->userOnlineMarking,
-                               'showOnTeamPage' => $this->groupEditor->showOnTeamPage
+                               'showOnTeamPage' => $this->groupEditor->showOnTeamPage,
+                               'groupType' => $groupType,
                        ],
-                       'options' => $optionValues
-               ]);
-               $returnValues = $groupAction->executeAction();
-               $group = $returnValues['returnValues'];
+                       'options' => $optionValues,
+               ]))->executeAction()['returnValues'];
                $groupEditor = new UserGroupEditor($group);
                
                // update group name
@@ -169,7 +176,7 @@ class UserGroupAction extends AbstractDatabaseObjectAction {
                
                $groupEditor->update([
                        'groupDescription' => $groupDescription,
-                       'groupName' => $groupName
+                       'groupName' => $groupName,
                ]);
                
                // copy members
@@ -209,8 +216,8 @@ class UserGroupAction extends AbstractDatabaseObjectAction {
                return [
                        'groupID' => $group->groupID,
                        'redirectURL' => LinkHandler::getInstance()->getLink('UserGroupEdit', [
-                               'id' => $group->groupID
-                       ])
+                               'id' => $group->groupID,
+                       ]),
                ];
        }
        
index f534d0f346f5a1f35712ee113c64111fc96066e6..38509a1ef1e33146e040c6b304635d8aee3ee535 100644 (file)
@@ -2,6 +2,7 @@
 namespace wcf\data\user\group\option;
 use wcf\data\user\group\UserGroupEditor;
 use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\WCF;
 
 /**
@@ -26,15 +27,21 @@ class UserGroupOptionAction extends AbstractDatabaseObjectAction {
         * Updates option values for given option id.
         */
        public function updateValues() {
+               /** @var UserGroupOption $option */
                $option = current($this->objects);
                
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add("optionID = ?", [$option->optionID]);
+               if (!empty($this->parameters['values'])) {
+                       $groupIDs = array_keys($this->parameters['values']);
+                       $conditions->add("groupID IN (?)", [$groupIDs]);
+               }
+               
                // remove old values
                $sql = "DELETE FROM     wcf".WCF_N."_user_group_option_value
-                       WHERE           optionID = ?";
+                       ".$conditions;
                $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([
-                       $option->optionID
-               ]);
+               $statement->execute($conditions->getParameters());
                
                if (!empty($this->parameters['values'])) {
                        $sql = "INSERT INTO     wcf".WCF_N."_user_group_option_value
index ea3f6a9a0ac4356132954fee2b55970d30240a16..f42b299c3aa33ced2b5519ab4def67d901236159 100644 (file)
@@ -41,20 +41,19 @@ class UserIgnoreAction extends AbstractDatabaseObjectAction {
        }
        
        /**
-        * Ignores an user.
+        * Ignores a user.
         * 
         * @return      array
         */
        public function ignore() {
-               $ignore = UserIgnore::getIgnore($this->parameters['data']['userID']);
+               /** @var UserIgnore $ignore */
+               $ignore = UserIgnoreEditor::createOrIgnore([
+                       'ignoreUserID' => $this->parameters['data']['userID'],
+                       'time' => TIME_NOW,
+                       'userID' => WCF::getUser()->userID,
+               ]);
                
-               if (!$ignore->ignoreID) {
-                       UserIgnoreEditor::create([
-                               'ignoreUserID' => $this->parameters['data']['userID'],
-                               'time' => TIME_NOW,
-                               'userID' => WCF::getUser()->userID
-                       ]);
-                       
+               if ($ignore !== null) {
                        UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'ignoredUserIDs');
                        UserStorageHandler::getInstance()->reset([$this->parameters['data']['userID']], 'ignoredByUserIDs');
                        
@@ -98,7 +97,7 @@ class UserIgnoreAction extends AbstractDatabaseObjectAction {
        }
        
        /**
-        * Unignores an user.
+        * Unignores a user.
         * 
         * @return      array
         */
index 147602ff9d11bc5cebb6a4fec92cbd65d38f4ca1..95914e0af3ad842ffffc44f9c44364a19bb59d0e 100644 (file)
@@ -10,7 +10,7 @@ use wcf\system\Regex;
 use wcf\system\WCF;
 
 /**
- * Represents an user menu item.
+ * Represents a user menu item.
  * 
  * @author     Alexander Ebert
  * @copyright  2001-2019 WoltLab GmbH
index f0eacae03efb6ac04c42634089c558f8500a9862..db1d7a55aab914eee4fe3242012e2296993faad9 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\data\user\notification;
 use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\PermissionDeniedException;
 use wcf\system\user\notification\UserNotificationHandler;
 use wcf\system\user\storage\UserStorageHandler;
@@ -232,23 +233,53 @@ class UserNotificationAction extends AbstractDatabaseObjectAction {
         * @return      boolean[]
         */
        public function markAllAsConfirmed() {
-               // remove notifications for this user
-               $sql = "UPDATE  wcf".WCF_N."_user_notification
-                       SET     confirmTime = ?
-                       WHERE   userID = ?";
+               // Step 1) Find the IDs of the unread notifications.
+               // This is done in a separate step, because this allows the UPDATE query to
+               // leverage fine-grained locking of exact rows based off the PRIMARY KEY.
+               // Simply updating all notifications belonging to a specific user will need
+               // to prevent concurrent threads from inserting new notifications for proper
+               // consistency, possibly leading to deadlocks.
+               $sql = "SELECT  notificationID
+                       FROM    wcf".WCF_N."_user_notification
+                       WHERE   userID = ?
+                           AND confirmTime = ?
+                           AND time < ?";
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute([
+                       WCF::getUser()->userID,
+                       0,
                        TIME_NOW,
-                       WCF::getUser()->userID
                ]);
+               $notificationIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
                
-               // delete notification_to_user assignments (mimic legacy notification system)
-               $sql = "DELETE FROM     wcf".WCF_N."_user_notification_to_user
-                       WHERE           userID = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([WCF::getUser()->userID]);
+               if (!empty($notificationIDs)) {
+                       // Step 2) Mark the notifications as read.
+                       $condition = new PreparedStatementConditionBuilder();
+                       $condition->add('notificationID IN (?)', [$notificationIDs]);
+                       
+                       $sql = "UPDATE  wcf".WCF_N."_user_notification
+                               SET     confirmTime = ?
+                               {$condition}";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute(\array_merge(
+                               [TIME_NOW],
+                               $condition->getParameters()
+                       ));
+                       
+                       // Step 3) Delete notification_to_user assignments (mimic legacy notification system)
+                       
+                       // This conditions technically is not required, because notificationIDs are unique.
+                       // As this is not enforced at the database layer we play safe until this legacy table
+                       // finally is removed.
+                       $condition->add('userID = ?', [WCF::getUser()->userID]);
+                       
+                       $sql = "DELETE FROM     wcf".WCF_N."_user_notification_to_user
+                               {$condition}";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute($condition->getParameters());
+               }
                
-               // reset notification count
+               // Step 4) Clear cached values.
                UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'userNotificationCount');
                
                return [
index d8e7366d652c771ff3d75281c4c4abca96a6d8b3..c45c4098503b2897dda9ce44a71c21e7a31676ab 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\data\user\notification\event;
+use wcf\data\object\type\ObjectType;
+use wcf\data\object\type\ObjectTypeCache;
 use wcf\data\ProcessibleDatabaseObject;
 use wcf\data\TDatabaseObjectOptions;
 use wcf\data\TDatabaseObjectPermissions;
@@ -31,4 +33,14 @@ class UserNotificationEvent extends ProcessibleDatabaseObject {
         * @inheritDoc
         */
        protected static $processorInterface = IUserNotificationEvent::class;
+       
+       /**
+        * Returns the object type of this event.
+        *
+        * @return      ObjectType
+        * @since 5.3
+        */
+       public function getObjectType() {
+               return ObjectTypeCache::getInstance()->getObjectType($this->objectTypeID);
+       }
 }
index 910ee331570b86b671268445e4271f5ddb3d9e57..ed5f390283b95423de58a79adf99f25947b6869e 100644 (file)
@@ -99,7 +99,6 @@ class UserNotificationEventAction extends AbstractDatabaseObjectAction {
                $getRenderedException = function($e) {
                        \wcf\functions\exception\logThrowable($e);
                        
-                       // TODO: output could/should be improved in the future
                        return $e->getMessage();
                };
                
index aa3031ca52f5594ad0375e79e71c507ff2424072..77ce4ade08d7a142aaf52543758123c20873f138 100644 (file)
@@ -87,7 +87,7 @@ class UserObjectWatchAction extends AbstractDatabaseObjectAction {
                if ($this->parameters['subscribe']) {
                        // newly subscribed
                        if ($this->userObjectWatch === null) {
-                               UserObjectWatchEditor::create([
+                               UserObjectWatchEditor::createOrIgnore([
                                        'notification' => $this->parameters['enableNotification'] ? 1 : 0,
                                        'objectID' => $this->parameters['objectID'],
                                        'objectTypeID' => $this->objectType->objectTypeID,
index eba14df0f42503ac261d490750bd134913027e8e..c478d8c7610f3dc2d5df5000704d71fe0237fdca 100644 (file)
@@ -48,7 +48,7 @@ class UserOnline extends UserProfile {
                        $username = str_replace('%s', $username, $this->userOnlineMarking);
                }
                
-               if ($this->canViewOnlineStatus == 3) {
+               if ($this->canViewOnlineStatus == UserProfile::ACCESS_NOBODY) {
                        $username .= WCF::getLanguage()->get('wcf.user.usersOnline.invisible');
                }
                
index 1069985dd710511df8a2a344550c1a44c07fc88c..f41dd21bdf41849694218bf07f5f0a85dfc038d9 100644 (file)
@@ -4,6 +4,7 @@ use wcf\data\option\OptionAction;
 use wcf\data\session\SessionList;
 use wcf\data\user\group\UserGroup;
 use wcf\data\user\User;
+use wcf\data\user\UserProfile;
 use wcf\system\event\EventHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
@@ -72,7 +73,7 @@ class UsersOnlineList extends SessionList {
                
                foreach ($objects as $object) {
                        $object = new UserOnline(new User(null, null, $object));
-                       if (!$object->userID || self::isVisible($object->userID, $object->canViewOnlineStatus)) {
+                       if (!$object->userID || self::isVisibleUser($object)) {
                                $this->objects[$object->sessionID] = $object;
                                $this->indexToObject[] = $object->sessionID;
                        }
@@ -95,19 +96,27 @@ class UsersOnlineList extends SessionList {
                        ".$conditionBuilder;
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute($conditionBuilder->getParameters());
+               
+               $users = $userIDs = [];
                while ($row = $statement->fetchArray()) {
                        $this->stats['total']++;
-                       if ($row['userID']) {
+                       
+                       $user = new UserOnline(new User(null, $row));
+                       if ($user->userID) {
                                $this->stats['members']++;
-                               
-                               if ($row['canViewOnlineStatus'] && !self::isVisible($row['userID'], $row['canViewOnlineStatus'])) {
-                                       $this->stats['invisible']++;
-                               }
+                               $users[] = $user;
+                               $userIDs[] = $user->userID;
                        }
                        else {
                                $this->stats['guests']++;
                        }
                }
+               
+               foreach ($users as $user) {
+                       if ($user->canViewOnlineStatus && !self::isVisibleUser($user)) {
+                               $this->stats['invisible']++;
+                       }
+               }
        }
        
        /**
@@ -155,20 +164,29 @@ class UsersOnlineList extends SessionList {
         * @param       integer         $userID
         * @param       integer         $canViewOnlineStatus
         * @return      boolean
+        * @deprecated  5.3             Use `isVisibleUser` instead
         */
        public static function isVisible($userID, $canViewOnlineStatus) {
-               if (WCF::getSession()->getPermission('admin.user.canViewInvisible') || $userID == WCF::getUser()->userID) return true;
-
-               $data = ['result' => false, 'userID' => $userID, 'canViewOnlineStatus' => $canViewOnlineStatus];
+               if (WCF::getSession()->getPermission('admin.user.canViewInvisible') || $userID == WCF::getUser()->userID) {
+                       return true;
+               }
+               
+               $data = [
+                       'result' => false,
+                       'userID' => $userID,
+                       'canViewOnlineStatus' => $canViewOnlineStatus,
+               ];
                
                switch ($canViewOnlineStatus) {
-                       case 0: // everyone
+                       case UserProfile::ACCESS_EVERYONE:
                                $data['result'] = true;
                                break;
-                       case 1: // registered
+                               
+                       case UserProfile::ACCESS_REGISTERED:
                                if (WCF::getUser()->userID) $data['result'] = true;
                                break;
-                       case 2: // following
+                               
+                       case UserProfile::ACCESS_FOLLOWING:
                                /** @noinspection PhpUndefinedMethodInspection */
                                if (WCF::getUserProfileHandler()->isFollower($userID)) $data['result'] = true;
                                break;
@@ -178,4 +196,41 @@ class UsersOnlineList extends SessionList {
                
                return $data['result'];
        }
+       
+       /**
+        * Checks the 'canViewOnlineStatus' setting for the given user.
+        * 
+        * @param       UserOnline      $userOnline
+        * @return      boolean
+        * @since       5.3
+        */
+       public static function isVisibleUser(UserOnline $userOnline) {
+               if (WCF::getSession()->getPermission('admin.user.canViewInvisible') || $userOnline->userID == WCF::getUser()->userID) {
+                       return true;
+               }
+               
+               $data = [
+                       'result' => false,
+                       'userOnline' => $userOnline,
+               ];
+               
+               switch ($userOnline->canViewOnlineStatus) {
+                       case UserProfile::ACCESS_EVERYONE:
+                               $data['result'] = true;
+                               break;
+                       
+                       case UserProfile::ACCESS_REGISTERED:
+                               if (WCF::getUser()->userID) $data['result'] = true;
+                               break;
+                       
+                       case UserProfile::ACCESS_FOLLOWING:
+                               /** @noinspection PhpUndefinedMethodInspection */
+                               if (WCF::getUserProfileHandler()->isFollower($userOnline->userID)) $data['result'] = true;
+                               break;
+               }
+               
+               EventHandler::getInstance()->fireAction(get_called_class(), 'isVisibleUser', $data);
+               
+               return $data['result'];
+       }
 }
index ee4609885964958a268faa8f913e850b636a887f..339c1940d4fdbf93d153b7b2f829b566eff887e8 100644 (file)
@@ -11,7 +11,7 @@ use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 
 /**
- * Represents an user profile menu item.
+ * Represents a user profile menu item.
  * 
  * @author     Alexander Ebert
  * @copyright  2001-2019 WoltLab GmbH
index 49e8f6802789eb6b3d06f5a7c96bcf5ace2c6d72..7fbbacec5cc60338547933c81e6257c3a46d11b2 100644 (file)
@@ -14,7 +14,7 @@ use wcf\system\WCF;
  * Abstract implementation of a form using the form builder API.
  * 
  * @author     Matthias Schmidt
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Form
  * @since      5.2
@@ -25,7 +25,7 @@ abstract class AbstractFormBuilderForm extends AbstractForm {
         * @var IFormDocument
         */
        public $form;
-
+       
        /**
         * name of the form document class
         * @var string
@@ -58,6 +58,20 @@ abstract class AbstractFormBuilderForm extends AbstractForm {
         */
        public $objectActionClass;
        
+       /**
+        * name of the controller for the link to the edit form
+        * @var string
+        * @since 5.3
+        */
+       public $objectEditLinkController = '';
+       
+       /**
+        * name of the application for the link to the edit form
+        * @var string
+        * @since 5.3
+        */
+       public $objectEditLinkApplication = 'wcf';
+       
        /**
         * @inheritDoc
         */
@@ -166,6 +180,13 @@ abstract class AbstractFormBuilderForm extends AbstractForm {
                $this->saved();
                
                WCF::getTPL()->assign('success', true);
+               
+               if ($this->formAction === 'create' && $this->objectEditLinkController) {
+                       WCF::getTPL()->assign('objectEditLink', LinkHandler::getInstance()->getControllerLink($this->objectEditLinkController, [
+                               'application' => $this->objectEditLinkApplication,
+                               'id' => $this->objectAction->getReturnValues()['returnValues']->getObjectID(),
+                       ]));
+               }
        }
        
        /**
@@ -213,10 +234,10 @@ abstract class AbstractFormBuilderForm extends AbstractForm {
        /**
         * @inheritDoc
         */
-       public function show() {
-               $this->buildForm();
+       public function checkPermissions() {
+               parent::checkPermissions();
                
-               parent::show();
+               $this->buildForm();
        }
        
        /**
index acf2169b7e8e977c100ccd401562915f437c69bb..88a246a47a35ba14de4272b6338a8e37a07e59ac 100644 (file)
@@ -7,10 +7,12 @@ use wcf\system\email\mime\MimePartFacade;
 use wcf\system\email\mime\RecipientAwareTextMimePart;
 use wcf\system\email\Email;
 use wcf\system\email\UserMailbox;
+use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\menu\user\UserMenu;
 use wcf\system\WCF;
 use wcf\util\HeaderUtil;
+use wcf\util\JSON;
 use wcf\util\PasswordUtil;
 use wcf\util\StringUtil;
 use wcf\util\UserRegistrationUtil;
@@ -54,6 +56,11 @@ class AccountManagementForm extends AbstractForm {
         */
        public $newPassword = '';
        
+       /**
+        * @var mixed[]
+        */
+       public $newPasswordStrengthVerdict = [];
+       
        /**
         * confirmed new password
         * @var string
@@ -151,6 +158,14 @@ class AccountManagementForm extends AbstractForm {
                if (isset($_POST['email'])) $this->email = $_POST['email'];
                if (isset($_POST['confirmEmail'])) $this->confirmEmail = $_POST['confirmEmail'];
                if (isset($_POST['newPassword'])) $this->newPassword = $_POST['newPassword'];
+               if (isset($_POST['newPassword_passwordStrengthVerdict'])) {
+                       try {
+                               $this->newPasswordStrengthVerdict = JSON::decode($_POST['newPassword_passwordStrengthVerdict']);
+                       }
+                       catch (SystemException $e) {
+                               // ignore
+                       }
+               }
                if (isset($_POST['confirmNewPassword'])) $this->confirmNewPassword = $_POST['confirmNewPassword'];
                if (isset($_POST['username'])) $this->username = StringUtil::trim($_POST['username']);
                if (isset($_POST['quit'])) $this->quit = intval($_POST['quit']);
@@ -215,7 +230,7 @@ class AccountManagementForm extends AbstractForm {
                                        throw new UserInputException('confirmNewPassword');
                                }
                                
-                               if (!UserRegistrationUtil::isSecurePassword($this->newPassword)) {
+                               if (($this->newPasswordStrengthVerdict['score'] ?? 4) < PASSWORD_MIN_SCORE) {
                                        throw new UserInputException('newPassword', 'notSecure');
                                }
                                
@@ -338,12 +353,12 @@ class AccountManagementForm extends AbstractForm {
                
                // email
                if (WCF::getSession()->getPermission('user.profile.canChangeEmail') && $this->email != WCF::getUser()->email && $this->email != WCF::getUser()->newEmail) {
-                       if (REGISTER_ACTIVATION_METHOD == 0 || REGISTER_ACTIVATION_METHOD == 2 || mb_strtolower($this->email) == mb_strtolower(WCF::getUser()->email)) {
+                       if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
                                // update email
                                $updateParameters['email'] = $this->email;
                                $success[] = 'wcf.user.changeEmail.success';
                        }
-                       else if (REGISTER_ACTIVATION_METHOD == 1) {
+                       else if (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER) {
                                // get reactivation code
                                $activationCode = UserRegistrationUtil::getActivationCode();
                                
index 96a3480587b4389179c5a5ab67c2045fc8eced1f..71b37a847b9e14e46a095f350b82fc32cf9c3bdc 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\form;
 use wcf\data\article\Article;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\HeaderUtil;
 
@@ -35,5 +36,11 @@ class ArticleAddForm extends \wcf\acp\form\ArticleAddForm {
                        HeaderUtil::redirect($article->getLink());
                        exit;
                }
+               else {
+                       WCF::getTPL()->assign([
+                               // We need to reassign the link here because otherwise it will lead to the admin panel.
+                               'objectEditLink' => LinkHandler::getInstance()->getControllerLink(ArticleEditForm::class, ['id' => $article->getObjectID()]),
+                       ]);
+               }
        }
 }
index ced589073477996e1c20fdfa6a25c5c7640eacd2..17b31bbd6b89f1a860a18031bf343ba4e87bfdc0 100644 (file)
@@ -97,15 +97,20 @@ class EmailActivationForm extends AbstractForm {
                        'newEmail' => '',
                        'reactivationCode' => 0
                ];
-               if ($this->user->activationCode != 0 && REGISTER_ACTIVATION_METHOD == 1) {
-                       $data['activationCode'] = 0;
-               }
                
                // enable new email
                $this->objectAction = new UserAction([$this->user], 'update', [
                        'data' => array_merge($this->additionalFields, $data)
                ]);
                $this->objectAction->executeAction();
+               
+               // confirm email
+               if (!$this->user->isEmailConfirmed() && empty($this->user->blacklistMatches)) {
+                       // enable new email
+                       $this->objectAction = new UserAction([$this->user], 'confirmEmail');
+                       $this->objectAction->executeAction();
+               }
+               
                $this->saved();
                
                // forward to index page
@@ -129,7 +134,7 @@ class EmailActivationForm extends AbstractForm {
         * @inheritDoc
         */
        public function show() {
-               if (REGISTER_ACTIVATION_METHOD != 1) {
+               if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
                        throw new IllegalLinkException();
                }
                
diff --git a/wcfsetup/install/files/lib/form/MailForm.class.php b/wcfsetup/install/files/lib/form/MailForm.class.php
deleted file mode 100644 (file)
index b78f626..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-<?php
-namespace wcf\form;
-use wcf\data\user\UserProfile;
-use wcf\system\cache\runtime\UserProfileRuntimeCache;
-use wcf\system\email\mime\MimePartFacade;
-use wcf\system\email\mime\RecipientAwareTextMimePart;
-use wcf\system\email\Email;
-use wcf\system\email\Mailbox;
-use wcf\system\email\UserMailbox;
-use wcf\system\exception\IllegalLinkException;
-use wcf\system\exception\PermissionDeniedException;
-use wcf\system\exception\UserInputException;
-use wcf\system\page\PageLocationManager;
-use wcf\system\request\LinkHandler;
-use wcf\system\WCF;
-use wcf\util\HeaderUtil;
-use wcf\util\StringUtil;
-use wcf\util\UserUtil;
-
-/**
- * Shows the user mail form.
- * 
- * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\Form
- */
-class MailForm extends AbstractCaptchaForm {
-       /**
-        * @inheritDoc
-        */
-       public $useCaptcha = PROFILE_MAIL_USE_CAPTCHA;
-       
-       /**
-        * @inheritDoc
-        */
-       public $forceCaptcha = true;
-       
-       /**
-        * recipient's user id
-        * @var integer
-        */
-       public $userID = 0;
-       
-       /**
-        * recipient's user object
-        * @var UserProfile
-        */
-       public $user = null;
-       
-       /**
-        * true to add the reply-to header
-        * @var boolean
-        */
-       public $showAddress = true;
-       
-       /**
-        * email subject
-        * @var string
-        */
-       public $subject = '';
-       
-       /**
-        * email message
-        * @var string
-        */
-       public $message = '';
-       
-       /**
-        * sender's email address
-        * @var string
-        */
-       public $email = '';
-       
-       /**
-        * @inheritDoc
-        */
-       public $neededPermissions = ['user.profile.canMail'];
-       
-       /**
-        * @inheritDoc
-        */
-       public function readParameters() {
-               parent::readParameters();
-               
-               if (isset($_REQUEST['id'])) $this->userID = intval($_REQUEST['id']);
-               $this->user = UserProfileRuntimeCache::getInstance()->getObject($this->userID);
-               if ($this->user === null) {
-                       throw new IllegalLinkException();
-               }
-               // validate ignore status
-               if (WCF::getUser()->userID && $this->user->isIgnoredUser(WCF::getUser()->userID)) {
-                       throw new PermissionDeniedException();
-               }
-               
-               $this->canonicalURL = LinkHandler::getInstance()->getLink('Mail', ['object' => $this->user->getDecoratedObject()]);
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function readFormParameters() {
-               parent::readFormParameters();
-               
-               $this->showAddress = 0;
-               if (isset($_POST['message'])) $this->message = StringUtil::trim($_POST['message']);
-               if (isset($_POST['subject'])) $this->subject = StringUtil::trim($_POST['subject']);
-               if (isset($_POST['email'])) $this->email = StringUtil::trim($_POST['email']);
-               if (isset($_POST['showAddress'])) $this->showAddress = intval($_POST['showAddress']);
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function validate() {
-               if (!WCF::getUser()->userID) {
-                       if (empty($this->email)) {
-                               throw new UserInputException('email');
-                       }
-                       
-                       if (!UserUtil::isValidEmail($this->email)) {
-                               throw new UserInputException('email', 'invalid');
-                       }
-               }
-               
-               if (empty($this->subject)) {
-                       throw new UserInputException('subject');
-               }
-               
-               if (empty($this->message)) {
-                       throw new UserInputException('message');
-               }
-               
-               parent::validate();
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function save() {
-               parent::save();
-               
-               // build message data
-               $messageData = [
-                       'message' => $this->message,
-                       'username' => WCF::getUser()->userID ? WCF::getUser()->username : $this->email
-               ];
-               
-               // build mail
-               $email = new Email();
-               $email->addRecipient(new UserMailbox($this->user->getDecoratedObject()));
-               $email->setSubject($this->user->getLanguage()->getDynamicVariable('wcf.user.mail.mail.subject', [
-                       'username' => WCF::getUser()->userID ? WCF::getUser()->username : $this->email,
-                       'subject' => $this->subject
-               ]));
-               $email->setBody(new MimePartFacade([
-                       new RecipientAwareTextMimePart('text/html', 'email_mail', 'wcf', $messageData),
-                       new RecipientAwareTextMimePart('text/plain', 'email_mail', 'wcf', $messageData)
-               ]));
-               
-               // add reply-to tag
-               if (WCF::getUser()->userID) {
-                       if ($this->showAddress) {
-                               $email->setReplyTo(new UserMailbox(WCF::getUser()));
-                       }
-               }
-               else {
-                       $email->setReplyTo(new Mailbox($this->email));
-               }
-               
-               // send mail
-               $email->send();
-               $this->saved();
-               
-               // forward to profile page
-               HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink('User', ['object' => $this->user]), WCF::getLanguage()->getDynamicVariable('wcf.user.mail.sent', ['user' => $this->user]));
-               exit;
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function readData() {
-               parent::readData();
-               
-               PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.User', $this->user->userID, $this->user);
-               if (MODULE_MEMBERS_LIST) PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.MembersList');
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function assignVariables() {
-               parent::assignVariables();
-               
-               WCF::getTPL()->assign([
-                       'user' => $this->user,
-                       'showAddress' => $this->showAddress,
-                       'message' => $this->message,
-                       'subject' => $this->subject,
-                       'email' => $this->email
-               ]);
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function show() {
-               if (!$this->user->isAccessible('canMail')) {
-                       throw new PermissionDeniedException();
-               }
-               
-               parent::show();
-       }
-}
index 4f4b376a73dc74a07e31ca1ec7483f8d9a0032ea..cec85658747eb4e02b5568411e340754ddc8633d 100644 (file)
@@ -270,7 +270,7 @@ abstract class MessageForm extends AbstractCaptchaForm {
         */
        public function readData() {
                // get attachments
-               if (MODULE_ATTACHMENT && $this->attachmentObjectType) {
+               if ($this->attachmentObjectType) {
                        $this->attachmentHandler = new AttachmentHandler($this->attachmentObjectType, $this->attachmentObjectID, $this->tmpHash, $this->attachmentParentObjectID);
                }
                
index c6a7a85c2e1bf019b1cbf9c96438d7076b7144dc..0df3a42a04f272d707998841c975f463638e954e 100644 (file)
@@ -5,10 +5,12 @@ use wcf\data\user\UserAction;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\NamedUserException;
 use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\HeaderUtil;
+use wcf\util\JSON;
 use wcf\util\StringUtil;
 use wcf\util\UserRegistrationUtil;
 
@@ -47,6 +49,11 @@ class NewPasswordForm extends AbstractForm {
         */
        public $newPassword = '';
        
+       /**
+        * @var mixed[]
+        */
+       public $newPasswordStrengthVerdict = [];
+       
        /**
         * confirmed new password
         * @var string
@@ -102,6 +109,14 @@ class NewPasswordForm extends AbstractForm {
                parent::readFormParameters();
                
                if (isset($_POST['newPassword'])) $this->newPassword = $_POST['newPassword'];
+               if (isset($_POST['newPassword_passwordStrengthVerdict'])) {
+                       try {
+                               $this->newPasswordStrengthVerdict = JSON::decode($_POST['newPassword_passwordStrengthVerdict']);
+                       }
+                       catch (SystemException $e) {
+                               // ignore
+                       }
+               }
                if (isset($_POST['confirmNewPassword'])) $this->confirmNewPassword = $_POST['confirmNewPassword'];
        }
        
@@ -119,7 +134,7 @@ class NewPasswordForm extends AbstractForm {
                        throw new UserInputException('confirmNewPassword');
                }
                
-               if (!UserRegistrationUtil::isSecurePassword($this->newPassword)) {
+               if (($this->newPasswordStrengthVerdict['score'] ?? 4) < PASSWORD_MIN_SCORE) {
                        throw new UserInputException('newPassword', 'notSecure');
                }
                
diff --git a/wcfsetup/install/files/lib/form/NotificationUnsubscribeForm.class.php b/wcfsetup/install/files/lib/form/NotificationUnsubscribeForm.class.php
new file mode 100644 (file)
index 0000000..e0490c5
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+namespace wcf\form;
+
+use wcf\data\user\notification\event\UserNotificationEvent;
+use wcf\data\user\User;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
+use wcf\util\HeaderUtil;
+use wcf\util\StringUtil;
+
+/**
+ * Represents the notification unsubscribe form.
+ *
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\Form
+ * @since      5.3
+ */
+class NotificationUnsubscribeForm extends AbstractForm {
+       /**
+        * @var User
+        */
+       public $user;
+       
+       /**
+        * user provided verification token
+        * @var string
+        */
+       public $token = '';
+       
+       /**
+        * @var boolean
+        */
+       public $isOneClick = false;
+       
+       /**
+        * notification event to unsubscribe
+        * @var UserNotificationEvent
+        */
+       public $event;
+       
+       /**
+        * Disable security token validation.
+        */
+       protected function validateSecurityToken() {
+               // Do not validate the security token, the request is authenticated by
+               // the mail token.
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               if (isset($_REQUEST['userID'])) {
+                       $this->user = new User(intval($_REQUEST['userID']));
+                       if (!$this->user->userID) {
+                               throw new IllegalLinkException();
+                       }
+               }
+               else {
+                       throw new IllegalLinkException();
+               }
+               
+               if (isset($_REQUEST['token'])) {
+                       $this->token = StringUtil::trim($_REQUEST['token']);
+               }
+               else {
+                       throw new IllegalLinkException();
+               }
+               
+               if (!empty($_REQUEST['eventID'])) {
+                       $this->event = new UserNotificationEvent(intval($_REQUEST['eventID']));
+                       if (!$this->event->eventID) {
+                               throw new IllegalLinkException();
+                       }
+               }
+               
+               if (!hash_equals($this->user->notificationMailToken, $this->token)) {
+                       throw new IllegalLinkException();
+               }
+               
+               $this->isOneClick = (isset($_POST['List-Unsubscribe']) && $_POST['List-Unsubscribe'] === 'One-Click');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               if ($this->event !== null) {
+                       $sql = "UPDATE  wcf".WCF_N."_user_notification_event_to_user
+                               SET     mailNotificationType = ?
+                               WHERE   userID = ?
+                                       AND eventID = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               'none',
+                               $this->user->userID,
+                               $this->event->eventID
+                       ]);
+               }
+               else {
+                       $sql = "UPDATE  wcf".WCF_N."_user_notification_event_to_user
+                               SET     mailNotificationType = ?
+                               WHERE   userID = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               'none',
+                               $this->user->userID
+                       ]);
+               }
+               
+               $this->saved();
+               
+               if ($this->isOneClick) {
+                       // One-Click unsubscriptions are sent by the recipient's MUA upon clicking a button.
+                       // No additional information except the URI are available and specifically no user interaction can happen.
+                       // Just send a lightweight 204 No Content response, instead of kilobytes of HTML to save on resources.
+                       header('HTTP/1.0 204 No Content');
+                       exit;
+               }
+               else {
+                       // redirect to url
+                       HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->get('wcf.user.notification.mail.disabled'));
+                       exit;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'user' => $this->user,
+                       'token' => $this->token,
+                       'event' => $this->event,
+               ]);
+       }
+}
index ea72f12487e7415f2795bdafb10bec615f7dfb67..5a12caa2ae5069c71868732799871246c3e41957 100644 (file)
@@ -29,7 +29,7 @@ class RegisterActivationForm extends AbstractForm {
        
        /**
         * activation code
-        * @var integer
+        * @var string
         */
        public $activationCode = '';
        
@@ -50,7 +50,7 @@ class RegisterActivationForm extends AbstractForm {
                        $this->user = new User($userID);
                        if ($this->user->userID) $this->username = $this->user->username;
                }
-               if (!empty($_GET['a'])) $this->activationCode = intval($_GET['a']);
+               if (!empty($_GET['a'])) $this->activationCode = StringUtil::trim($_GET['a']);
        }
        
        /**
@@ -63,7 +63,7 @@ class RegisterActivationForm extends AbstractForm {
                        $this->username = StringUtil::trim($_POST['username']);
                        $this->user = User::getUserByUsername($this->username);
                }
-               if (isset($_POST['activationCode'])) $this->activationCode = intval($_POST['activationCode']);
+               if (isset($_POST['activationCode'])) $this->activationCode = StringUtil::trim($_POST['activationCode']);
        }
        
        /**
@@ -77,13 +77,13 @@ class RegisterActivationForm extends AbstractForm {
                        throw new UserInputException('username', 'notFound');
                }
                
-               // user is already enabled
-               if ($this->user->activationCode == 0) {
+               // user email is already confirmed
+               if ($this->user->isEmailConfirmed()) {
                        throw new NamedUserException(WCF::getLanguage()->get('wcf.user.registerActivation.error.userAlreadyEnabled'));
                }
                
                // check given activation code
-               if ($this->user->activationCode != $this->activationCode) {
+               if (!\hash_equals($this->user->emailConfirmed, $this->activationCode)) {
                        throw new UserInputException('activationCode', 'invalid');
                }
                
@@ -99,12 +99,19 @@ class RegisterActivationForm extends AbstractForm {
                parent::save();
                
                // enable user
-               $this->objectAction = new UserAction([$this->user], 'enable', ['skipNotification' => true]);
+               $this->objectAction = new UserAction([$this->user], 'confirmEmail', ['skipNotification' => true]);
                $this->objectAction->executeAction();
                $this->saved();
                
                // forward to index page
-               HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->getDynamicVariable('wcf.user.registerActivation.success'), 10);
+               if ($this->user->requiresAdminActivation()) {
+                       $redirectText = WCF::getLanguage()->getDynamicVariable('wcf.user.registerActivation.success.awaitAdminActivation');
+               }
+               else {
+                       $redirectText = WCF::getLanguage()->getDynamicVariable('wcf.user.registerActivation.success');
+               }
+               
+               HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), $redirectText, 10);
                exit;
        }
        
@@ -124,7 +131,7 @@ class RegisterActivationForm extends AbstractForm {
         * @inheritDoc
         */
        public function show() {
-               if (REGISTER_ACTIVATION_METHOD != 1) {
+               if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
                        throw new IllegalLinkException();
                }
                
index 5a64e1a09200d6c1409f2b07edb2a097edb4826e..8880750bf0ff42b80029c871d69c59280892b57e 100644 (file)
@@ -99,6 +99,11 @@ class RegisterForm extends UserAddForm {
         */
        public static $minRegistrationTime = 10;
        
+       /**
+        * @var mixed[]
+        */
+       public $passwordStrengthVerdict = [];
+       
        /**
         * @inheritDoc
         */
@@ -145,6 +150,14 @@ class RegisterForm extends UserAddForm {
                if (isset($_POST[$this->randomFieldNames['email']])) $this->email = StringUtil::trim($_POST[$this->randomFieldNames['email']]);
                if (isset($_POST[$this->randomFieldNames['confirmEmail']])) $this->confirmEmail = StringUtil::trim($_POST[$this->randomFieldNames['confirmEmail']]);
                if (isset($_POST[$this->randomFieldNames['password']])) $this->password = $_POST[$this->randomFieldNames['password']];
+               if (isset($_POST[$this->randomFieldNames['password'].'_passwordStrengthVerdict'])) {
+                       try {
+                               $this->passwordStrengthVerdict = JSON::decode($_POST[$this->randomFieldNames['password'].'_passwordStrengthVerdict']);
+                       }
+                       catch (SystemException $e) {
+                               // ignore
+                       }
+               }
                if (isset($_POST[$this->randomFieldNames['confirmPassword']])) $this->confirmPassword = $_POST[$this->randomFieldNames['confirmPassword']];
                
                $this->groupIDs = [];
@@ -295,7 +308,7 @@ class RegisterForm extends UserAddForm {
                        parent::validatePassword($password, $confirmPassword);
                        
                        // check security of the given password
-                       if (!UserRegistrationUtil::isSecurePassword($password)) {
+                       if (($this->passwordStrengthVerdict['score'] ?? 4) < PASSWORD_MIN_SCORE) {
                                throw new UserInputException('password', 'notSecure');
                        }
                }
@@ -438,9 +451,11 @@ class RegisterForm extends UserAddForm {
                
                // generate activation code
                $addDefaultGroups = true;
-               if (!empty($this->blacklistMatches) || (REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty) || REGISTER_ACTIVATION_METHOD == 2) {
+               if (!empty($this->blacklistMatches) || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && !$registerVia3rdParty) || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN)) {
                        $activationCode = UserRegistrationUtil::getActivationCode();
+                       $emailConfirmCode = bin2hex(\random_bytes(20));
                        $this->additionalFields['activationCode'] = $activationCode;
+                       $this->additionalFields['emailConfirmed'] = $emailConfirmCode;
                        $addDefaultGroups = false;
                        $this->groupIDs = UserGroup::getGroupIDsByType([UserGroup::EVERYONE, UserGroup::GUESTS]);
                }
@@ -483,12 +498,12 @@ class RegisterForm extends UserAddForm {
                }
                
                // activation management
-               if (REGISTER_ACTIVATION_METHOD == 0 && empty($this->blacklistMatches)) {
+               if (REGISTER_ACTIVATION_METHOD == User::REGISTER_ACTIVATION_NONE && empty($this->blacklistMatches)) {
                        $this->message = 'wcf.user.register.success';
                        
                        UserGroupAssignmentHandler::getInstance()->checkUsers([$user->userID]);
                }
-               else if (REGISTER_ACTIVATION_METHOD == 1 && empty($this->blacklistMatches)) {
+               else if (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && empty($this->blacklistMatches)) {
                        // registering via 3rdParty leads to instant activation
                        if ($registerVia3rdParty) {
                                $this->message = 'wcf.user.register.success';
@@ -505,7 +520,7 @@ class RegisterForm extends UserAddForm {
                                $this->message = 'wcf.user.register.success.needActivation';
                        }
                }
-               else if (REGISTER_ACTIVATION_METHOD == 2 || !empty($this->blacklistMatches)) {
+               else if (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN || !empty($this->blacklistMatches)) {
                        $this->message = 'wcf.user.register.success.awaitActivation';
                }
                
index 1be7e8b42eecf153d6bc5bfbb077ea611b9f9909..36be3ecfd13a9f6dd673859d82555766feeae4cf 100644 (file)
@@ -89,7 +89,7 @@ class RegisterNewActivationCodeForm extends AbstractForm {
                        throw new UserInputException('username', 'notFound');
                }
                
-               if ($this->user->activationCode == 0) {
+               if ($this->user->isEmailConfirmed()) {
                        throw new UserInputException('username', 'alreadyEnabled');
                }
                
@@ -198,7 +198,7 @@ class RegisterNewActivationCodeForm extends AbstractForm {
         * @inheritDoc
         */
        public function show() {
-               if (REGISTER_ACTIVATION_METHOD != 1) {
+               if (!(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
                        throw new IllegalLinkException();
                }
                
index 966fb83e7282d333e43946dd7329e779545786b7..c2b099970dd6014b059a5550cbca0c73cd1be294 100644 (file)
@@ -130,6 +130,9 @@ class SettingsForm extends AbstractForm {
                        
                        Trophy::sort($this->availableTrophies, 'showOrder');
                }
+               else if (!$this->optionHandler->countCategoryOptions('settings.'.$this->category)) {
+                       throw new IllegalLinkException();
+               }
        }
        
        /**
index 72204717680074addffbc9a5fdff0cf4411b28aa..9583b960a35fac33d397d4e778498eb741911887 100644 (file)
@@ -175,7 +175,7 @@ class UserSearchForm extends UserOptionListForm {
                }
                
                // do search
-               $statement = WCF::getDB()->prepareStatement($sql.$this->conditions, $this->maxResults);
+               $statement = WCF::getDB()->prepareStatement($sql."\n".$this->conditions, $this->maxResults);
                $statement->execute($this->conditions->getParameters());
                $this->matches = $statement->fetchAll(\PDO::FETCH_COLUMN);
        }
index fdcb05187b4679fa16caba85e131c8d60e2ae196..f36838e12d6949a4f455ee2e5a1696883d09dd6e 100644 (file)
@@ -7,6 +7,7 @@ use wcf\data\article\ArticleAction;
 use wcf\data\article\ArticleEditor;
 use wcf\data\article\ViewableArticle;
 use wcf\data\tag\Tag;
+use wcf\system\cache\runtime\ViewableArticleRuntimeCache;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\PermissionDeniedException;
@@ -83,7 +84,7 @@ abstract class AbstractArticlePage extends AbstractPage {
                        throw new IllegalLinkException();
                }
                
-               $this->article = ViewableArticle::getArticle($this->articleContent->articleID, false);
+               $this->article = ViewableArticleRuntimeCache::getInstance()->getObject($this->articleContent->articleID);
                $this->article->getDiscussionProvider()->setArticleContent($this->articleContent->getDecoratedObject());
                $this->category = $this->article->getCategory();
                
@@ -137,28 +138,28 @@ abstract class AbstractArticlePage extends AbstractPage {
                if (MODULE_TAGGING && ARTICLE_RELATED_ARTICLES) {
                        if (!empty($this->tags)) {
                                $conditionBuilder = new PreparedStatementConditionBuilder();
-                               $conditionBuilder->add('objectTypeID = ?', [TagEngine::getInstance()->getObjectTypeID('com.woltlab.wcf.article')]);
-                               $conditionBuilder->add('tagID IN (?)', [array_keys($this->tags)]);
-                               $conditionBuilder->add('objectID <> ?', [$this->articleContentID]);
-                               $sql = "SELECT          objectID, COUNT(*) AS count
-                                       FROM            wcf" . WCF_N . "_tag_to_object
+                               $conditionBuilder->add('tag_to_object.objectTypeID = ?', [TagEngine::getInstance()->getObjectTypeID('com.woltlab.wcf.article')]);
+                               $conditionBuilder->add('tag_to_object.tagID IN (?)', [array_keys($this->tags)]);
+                               $conditionBuilder->add('tag_to_object.objectID <> ?', [$this->articleContentID]);
+                               $sql = "SELECT          MAX(article.articleID), COUNT(*) AS count
+                                       FROM            wcf" . WCF_N . "_tag_to_object tag_to_object
+                                       INNER JOIN      wcf" . WCF_N . "_article_content article_content
+                                       ON              tag_to_object.objectID = article_content.articleContentID
+                                       INNER JOIN      wcf" . WCF_N . "_article article
+                                       ON              article_content.articleID = article.articleID
                                        " . $conditionBuilder . "
-                                       GROUP BY        objectID
+                                       GROUP BY        tag_to_object.objectID
                                        HAVING          COUNT(*) >= " . round(count($this->tags) * ARTICLE_RELATED_ARTICLES_MATCH_THRESHOLD / 100) . "
-                                       ORDER BY        count DESC";
-                               $statement = WCF::getDB()->prepareStatement($sql, ARTICLE_RELATED_ARTICLES);
+                                       ORDER BY        count DESC, MAX(article.time) DESC";
+                               $statement = WCF::getDB()->prepareStatement($sql, ARTICLE_RELATED_ARTICLES * 4);
                                $statement->execute($conditionBuilder->getParameters());
-                               $articleContentIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
+                               $articleIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
                                
-                               if (!empty($articleContentIDs)) {
-                                       $conditionBuilder = new PreparedStatementConditionBuilder();
-                                       $conditionBuilder->add('articleContentID IN (?)', [$articleContentIDs]);
-                                       $sql = "SELECT          articleID
-                                               FROM            wcf" . WCF_N . "_article_content
-                                               " . $conditionBuilder;
-                                       $statement = WCF::getDB()->prepareStatement($sql);
-                                       $statement->execute($conditionBuilder->getParameters());
-                                       $articleIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
+                               if (!empty($articleIDs)) {
+                                       if (count($articleIDs) > ARTICLE_RELATED_ARTICLES) {
+                                               shuffle($articleIDs);
+                                               $articleIDs = array_slice($articleIDs, 0, ARTICLE_RELATED_ARTICLES);
+                                       }
                                        
                                        $this->relatedArticles = new AccessibleArticleList();
                                        $this->relatedArticles->getConditionBuilder()->add('article.articleID IN (?)', [$articleIDs]);
index 86ec3056f45dd256c9e2df41b0337e9cafaefc6c..5c3b1dafc8ac0c1d9c5baddfb016fe4ef87b4937 100644 (file)
@@ -4,14 +4,13 @@ use wcf\data\user\User;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\session\SessionHandler;
 use wcf\system\WCF;
-use wcf\util\StringUtil;
 
 /**
  * Automatically authes the user for the current request via an access-token.
  * A missing token will be ignored, an invalid token results in a throw of a IllegalLinkException.
  * 
  * @author     Tim Duesterhus
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Page
  */
index 05eca840ee2138482267ffdb5f0c2be6b813daea..093ca704f51ea26dc9b7cbf9f9f7634effe2c686 100644 (file)
@@ -20,6 +20,11 @@ class ArticleAmpPage extends AbstractArticlePage {
         */
        public $templateName = 'ampArticle';
        
+       /**
+        * @inheritDoc
+        */
+       public $neededModules = ['MODULE_ARTICLE', 'MODULE_AMP'];
+       
        /**
         * list of additional articles
         * @var ViewableArticle[]
index 4cf8bec2d91beca2cae8a76e1090f467821c275f..231a10e5ca9f18c4c7143b3c9512bf054cc0f954 100644 (file)
@@ -7,7 +7,6 @@ use wcf\data\like\object\LikeObject;
 use wcf\system\comment\manager\ICommentManager;
 use wcf\system\comment\CommentHandler;
 use wcf\system\reaction\ReactionHandler;
-use wcf\system\request\LinkHandler;
 use wcf\system\MetaTagHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
@@ -105,9 +104,12 @@ class ArticlePage extends AbstractArticlePage {
                
                // add meta/og tags
                MetaTagHandler::getInstance()->addTag('og:title', 'og:title', $this->articleContent->getTitle() . ' - ' . WCF::getLanguage()->get(PAGE_TITLE), true);
-               MetaTagHandler::getInstance()->addTag('og:url', 'og:url', LinkHandler::getInstance()->getLink('Article', ['object' => $this->articleContent]), true);
+               MetaTagHandler::getInstance()->addTag('og:url', 'og:url', $this->articleContent->getLink(), true);
                MetaTagHandler::getInstance()->addTag('og:type', 'og:type', 'article', true);
                MetaTagHandler::getInstance()->addTag('og:description', 'og:description', ($this->articleContent->teaser ?: StringUtil::decodeHTML(StringUtil::stripHTML($this->articleContent->getFormattedTeaser()))), true);
+               if ($this->articleContent->metaDescription) {
+                       MetaTagHandler::getInstance()->addTag('description', 'description', $this->articleContent->metaDescription);
+               }
                
                if ($this->articleContent->getTeaserImage() && $this->articleContent->getTeaserImage()->width >= 200 && $this->articleContent->getTeaserImage()->height >= 200) {
                        MetaTagHandler::getInstance()->addTag('og:image', 'og:image', $this->articleContent->getTeaserImage()->getLink(), true);
index b2b129668e0efc4aa94e287abaf23671b57f41db..1cf566137a4e88a2f5435e05ceb27f55df86d6d5 100644 (file)
@@ -61,6 +61,7 @@ class CategoryTrophyListPage extends TrophyListPage {
        protected function initObjectList() {
                MultipleLinkPage::initObjectList();
                
+               $this->objectList->sqlSelects = '(SELECT COUNT(*) FROM wcf'.WCF_N.'_user_trophy WHERE trophyID = trophy.trophyID) AS awarded';
                $this->objectList->getConditionBuilder()->add('isDisabled = ?', [0]);
                $this->objectList->getConditionBuilder()->add('categoryID = ?', [$this->categoryID]);
        }
index 7d247b1bbd0853d196c3243b6c9fadadb1b6f111..6d7e1c2a7cab2a7f58932a5214bb6f3d5289cf35 100644 (file)
@@ -17,6 +17,8 @@ use wcf\util\StringUtil;
  * @since      3.0
  */
 class MediaPage extends AbstractPage {
+       const AVAILABLE_DURING_OFFLINE_MODE = true;
+       
        /**
         * etag for the media file
         * @var string
@@ -85,16 +87,19 @@ class MediaPage extends AbstractPage {
                        $this->eTag = $this->mediaID;
                }
                
+               $this->eTag .= '_' . $this->media->fileHash;
+               
                // init file reader
+               $maxAge = 3600;
                $this->fileReader = new FileReader($location, [
                        'filename' => $this->media->filename,
                        'mimeType' => $mimeType,
                        'filesize' => $filesize,
                        'showInline' => in_array($mimeType, self::$inlineMimeTypes),
                        'enableRangeSupport' => $this->thumbnail ? true : false,
-                       'lastModificationTime' => $this->media->uploadTime,
-                       'expirationDate' => TIME_NOW + 31536000,
-                       'maxAge' => 31536000
+                       'lastModificationTime' => $this->media->fileUpdateTime ?? $this->media->uploadTime,
+                       'expirationDate' => TIME_NOW + $maxAge,
+                       'maxAge' => $maxAge,
                ]);
                
                if ($this->eTag !== null) {
index 1bc3162856ae172ee06ba7212fb673e85fb82ae1..1bf0d8b26c2c92d39801165e28b82dd2b3fbd8d2 100644 (file)
@@ -4,7 +4,9 @@ use wcf\data\moderation\queue\ModerationQueue;
 use wcf\data\moderation\queue\ViewableModerationQueueList;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\moderation\queue\ModerationQueueManager;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
+use wcf\util\HeaderUtil;
 
 /**
  * List of moderation queue entries.
@@ -69,7 +71,13 @@ class ModerationListPage extends SortablePage {
        /**
         * @inheritDoc
         */
-       public $validSortFields = ['assignedUsername', 'lastChangeTime', 'queueID', 'time', 'username', 'comments'];
+       public $validSortFields = ['username', 'time', 'comments', 'assignedUsername', 'lastChangeTime'];
+       
+       /**
+        * indicates if any filter is being used
+        * @var bool
+        */
+       public $hasActiveFilter = false;
        
        /**
         * @inheritDoc
@@ -87,6 +95,16 @@ class ModerationListPage extends SortablePage {
                                throw new IllegalLinkException();
                        }
                }
+               
+               if ($this->assignedUserID !== -1 || $this->status !== -1 || $this->definitionID !== 0) {
+                       $this->hasActiveFilter = true;
+               }
+               
+               if (!empty($_POST)) {
+                       $url = http_build_query($_POST, '', '&');
+                       HeaderUtil::redirect(LinkHandler::getInstance()->getControllerLink(static::class, [], $url));
+                       exit;
+               }
        }
        
        /**
@@ -128,7 +146,9 @@ class ModerationListPage extends SortablePage {
                        'assignedUserID' => $this->assignedUserID,
                        'availableDefinitions' => $this->availableDefinitions,
                        'definitionID' => $this->definitionID,
-                       'status' => $this->status
+                       'status' => $this->status,
+                       'validSortFields' => $this->validSortFields,
+                       'hasActiveFilter' => $this->hasActiveFilter,
                ]);
        }
 }
index f8fde99e0715c5c3dd432b464a2413c6e0e1d058..5e2fe27e1efbf29a0bc54741dde6115d61366c32 100644 (file)
@@ -25,6 +25,11 @@ class PaidSubscriptionListPage extends AbstractPage {
         */
        public $neededModules = ['MODULE_PAID_SUBSCRIPTION'];
        
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['user.profile.payment.canBuyPaidSubscription'];
+       
        /**
         * list of available paid subscriptions
         * @var array
@@ -43,7 +48,7 @@ class PaidSubscriptionListPage extends AbstractPage {
        public function checkPermissions() {
                parent::checkPermissions();
                
-               if (WCF::getUser()->activationCode != 0) {
+               if (WCF::getUser()->pendingActivation()) {
                        throw new PermissionDeniedException();
                }
        }
index fc16fa6deefee3e5bbc18ac027c068cd66f24c5e..9049b99ff0c2deb64a3e37557271b8edd5fb07db 100644 (file)
@@ -83,6 +83,7 @@ class TrophyListPage extends MultipleLinkPage {
        protected function initObjectList() {
                parent::initObjectList();
                
+               $this->objectList->sqlSelects = '(SELECT COUNT(*) FROM wcf'.WCF_N.'_user_trophy WHERE trophyID = trophy.trophyID) AS awarded';
                $this->objectList->getConditionBuilder()->add('isDisabled = ?', [0]);
                $this->objectList->getConditionBuilder()->add('categoryID IN (?)', [array_map(function ($category) {
                        return $category->categoryID;
index 072232effe430070d70743348a59a5af03ac4974..478b8198a65c2b91ea51235eff6c91261f174c90 100644 (file)
@@ -94,7 +94,7 @@ class UserPage extends AbstractPage {
                
                if (isset($_REQUEST['editOnInit'])) $this->editOnInit = true;
                
-               $this->canonicalURL = LinkHandler::getInstance()->getLink('User', ['object' => $this->user]);
+               $this->canonicalURL = $this->user->getLink();
        }
        
        /**
@@ -163,7 +163,8 @@ class UserPage extends AbstractPage {
                        'visitors' => $this->visitorList !== null ? $this->visitorList->getObjects() : [],
                        'visitorCount' => $this->visitorList !== null ? $this->visitorList->countObjects() : 0,
                        'isAccessible' => UserGroup::isAccessibleGroup($this->user->getGroupIDs()),
-                       'coverPhotoDimensions' => UserCoverPhoto::getCoverPhotoDimensions()
+                       'coverPhotoDimensions' => UserCoverPhoto::getCoverPhotoDimensions(),
+                       'specialTrophyCount' => (MODULE_TROPHY ? count($this->user->getSpecialTrophies()) : 0),
                ]);
        }
        
index 6edc754bbd4f661240a4e35df8b68a87e7c5c460..ba7a3f30c94cddda82ae192e9a8a509f331d9954 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system;
 use phpline\console\ConsoleReader;
 use phpline\internal\Log;
 use phpline\TerminalFactory;
+use wcf\data\session\SessionEditor;
 use wcf\system\cli\command\CLICommandHandler;
 use wcf\system\cli\command\CLICommandNameCompleter;
 use wcf\system\cli\DatabaseCLICommandHistory;
@@ -30,7 +31,7 @@ set_exception_handler([CLIWCF::class, 'handleCLIException']);
  * Extends WCF class with functions for CLI.
  * 
  * @author     Tim Duesterhus
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System
  */
@@ -64,13 +65,6 @@ class CLIWCF extends WCF {
                $zendLoader = new ZendLoader([ZendLoader::AUTOREGISTER_ZF => true]);
                $zendLoader->register();
                
-               $argv = new ArgvParser([
-                       'packageID=i' => ''
-               ]);
-               $argv->setOption(ArgvParser::CONFIG_FREEFORM_FLAGS, true);
-               $argv->parse();
-               define('PACKAGE_ID', $argv->packageID ?: 1);
-               
                // disable benchmark
                define('ENABLE_BENCHMARK', 0);
                
@@ -97,15 +91,20 @@ class CLIWCF extends WCF {
         * @inheritDoc
         */
        public static function destruct() {
-               if (self::getReader() !== null && self::getReader()->getHistory() instanceof DatabaseCLICommandHistory) {
-                       /** @var DatabaseCLICommandHistory $history */
-                       $history = self::getReader()->getHistory();
-                       
-                       $history->save();
-                       $history->autoSave = false;
+               // Giving WCF_SESSION_ID disables saving of the command history.
+               if (empty($_ENV['WCF_SESSION_ID'])) {
+                       if (self::getReader() !== null && self::getReader()->getHistory() instanceof DatabaseCLICommandHistory) {
+                               /** @var DatabaseCLICommandHistory $history */
+                               $history = self::getReader()->getHistory();
+                               
+                               $history->save();
+                               $history->autoSave = false;
+                       }
                }
                
-               self::getSession()->delete();
+               if (empty($_ENV['WCF_SESSION_ID'])) {
+                       self::getSession()->delete();
+               }
        }
        
        /**
@@ -128,7 +127,6 @@ class CLIWCF extends WCF {
                        'version' => WCF::getLanguage()->get('wcf.cli.help.version'),
                        'disableUpdateCheck' => WCF::getLanguage()->get('wcf.cli.help.disableUpdateCheck'),
                        'exitOnFail' => WCF::getLanguage()->get('wcf.cli.help.exitOnFail'),
-                       'packageID=i' => WCF::getLanguage()->get('wcf.cli.help.packageID')
                ]);
                self::getArgvParser()->setOptions([
                        ArgvParser::CONFIG_CUMULATIVE_FLAGS => true,
@@ -230,29 +228,39 @@ class CLIWCF extends WCF {
         * Does the user authentification.
         */
        protected function initAuth() {
-               do {
-                       $line = self::getReader()->readLine(WCF::getLanguage()->get('wcf.user.username').'> ');
-                       if ($line === null) exit;
-                       $username = StringUtil::trim($line);
-               }
-               while ($username === '');
-               
-               do {
-                       $line = self::getReader()->readLine(WCF::getLanguage()->get('wcf.user.password').'> ', '*');
-                       if ($line === null) exit;
-                       $password = StringUtil::trim($line);
-               }
-               while ($password === '');
-               
-               // check credentials and switch user
-               try {
-                       $user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($username, $password);
-                       WCF::getSession()->changeUser($user);
+               if (!empty($_ENV['WCF_SESSION_ID'])) {
+                       self::getSession()->delete();
+                       self::getSession()->load(SessionEditor::class, $_ENV['WCF_SESSION_ID']);
+                       if (!self::getUser()->userID) {
+                               self::getReader()->println('Invalid sessionID');
+                               exit(1);
+                       }
                }
-               catch (UserInputException $e) {
-                       $message = WCF::getLanguage()->getDynamicVariable('wcf.user.'.$e->getField().'.error.'.$e->getType(), ['username' => $username]);
-                       self::getReader()->println($message);
-                       exit(1);
+               else {
+                       do {
+                               $line = self::getReader()->readLine(WCF::getLanguage()->get('wcf.user.username').'> ');
+                               if ($line === null) exit;
+                               $username = StringUtil::trim($line);
+                       }
+                       while ($username === '');
+                       
+                       do {
+                               $line = self::getReader()->readLine(WCF::getLanguage()->get('wcf.user.password').'> ', '*');
+                               if ($line === null) exit;
+                               $password = StringUtil::trim($line);
+                       }
+                       while ($password === '');
+                       
+                       // check credentials and switch user
+                       try {
+                               $user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($username, $password);
+                               WCF::getSession()->changeUser($user);
+                       }
+                       catch (UserInputException $e) {
+                               $message = WCF::getLanguage()->getDynamicVariable('wcf.user.'.$e->getField().'.error.'.$e->getType(), ['username' => $username]);
+                               self::getReader()->println($message);
+                               exit(1);
+                       }
                }
                
                // initialize history
index f04462001e094dfe67cb1bfc25fda99726644ade..a3f9a1b2ceae5d6fb026e1d0a182519415328f99 100644 (file)
@@ -51,7 +51,7 @@ if (!@ini_get('date.timezone')) {
 }
 
 // define current woltlab suite version
-define('WCF_VERSION', '5.2.14');
+define('WCF_VERSION', '5.3.7');
 
 // define current API version
 // @deprecated 5.2
@@ -370,6 +370,26 @@ class WCF {
                define('LIKE_ALLOW_FOR_OWN_CONTENT', 0);
                define('LIKE_ENABLE_DISLIKE', 0);
                
+               // Thumbnails for attachments are already enabled since 5.3.
+               // https://github.com/WoltLab/WCF/pull/3444
+               define('ATTACHMENT_ENABLE_THUMBNAILS', 1);
+               
+               // User markings are always applied in sidebars since 5.3.
+               // https://github.com/WoltLab/WCF/issues/3330
+               define('MESSAGE_SIDEBAR_ENABLE_USER_ONLINE_MARKING', 1);
+               
+               // Password strength configuration is deprecated since 5.3.
+               define('REGISTER_ENABLE_PASSWORD_SECURITY_CHECK', 0);
+               define('REGISTER_PASSWORD_MIN_LENGTH', 0);
+               define('REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE', 8);
+               define('REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE', 0);
+               define('REGISTER_PASSWORD_MUST_CONTAIN_DIGIT', 0);
+               define('REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR', 0);
+
+               // rel=nofollow is always applied to external link since 5.3
+               // https://github.com/WoltLab/WCF/issues/3339
+               define('EXTERNAL_LINK_REL_NOFOLLOW', 1);
+               
                $filename = WCF_DIR.'options.inc.php';
                
                // create options file if doesn't exist
@@ -726,7 +746,7 @@ class WCF {
                        $wcf = new TemplateScriptingCore($wcf);
                }
                
-               self::getTPL()->registerPrefilter(['event', 'hascontent', 'lang']);
+               self::getTPL()->registerPrefilter(['event', 'hascontent', 'lang', 'jslang']);
                self::getTPL()->assign([
                        '__wcf' => $wcf,
                        '__wcfVersion' => LAST_UPDATE_TIME // @deprecated 2.1, use LAST_UPDATE_TIME directly
@@ -744,7 +764,7 @@ class WCF {
                        }
                }
                
-               EmailTemplateEngine::getInstance()->registerPrefilter(['event', 'hascontent', 'lang']);
+               EmailTemplateEngine::getInstance()->registerPrefilter(['event', 'hascontent', 'lang', 'jslang']);
                EmailTemplateEngine::getInstance()->assign([
                        '__wcf' => $wcf
                ]);
index 9aa4bf6c007d972dbcf2704d0fe87402a40d322f..d42caacfec4d443dbbf5bea19618620ac113dd29 100644 (file)
@@ -19,6 +19,7 @@ use wcf\system\io\File;
 use wcf\system\io\Tar;
 use wcf\system\language\LanguageFactory;
 use wcf\system\package\PackageArchive;
+use wcf\system\request\RouteHandler;
 use wcf\system\session\ACPSessionFactory;
 use wcf\system\session\SessionHandler;
 use wcf\system\setup\Installer;
@@ -225,6 +226,8 @@ class WCFSetup extends WCF {
                if (isset($_REQUEST['step'])) $step = $_REQUEST['step'];
                else $step = 'selectSetupLanguage';
                
+               header('set-cookie: wcfsetup_cookietest='.TMP_FILE_PREFIX.'; domain=' . str_replace(RouteHandler::getProtocol(), '', RouteHandler::getHost()) . (RouteHandler::secureConnection() ? '; secure' : ''));
+               
                // execute current step
                switch ($step) {
                        /** @noinspection PhpMissingBreakStatementInspection */
@@ -384,6 +387,19 @@ class WCFSetup extends WCF {
                // openssl extension
                $system['openssl']['result'] = @extension_loaded('openssl');
                
+               // curl
+               $system['curl']['result'] = @extension_loaded('curl');
+               
+               // misconfigured reverse proxy / cookies
+               $system['hostname']['result'] = true;
+               list($system['hostname']['value']) = explode(':', $_SERVER['HTTP_HOST'], 2);
+               if (!empty($_SERVER['HTTP_REFERER'])) {
+                       $refererHostname = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
+                       $system['hostname']['result'] = $_SERVER['HTTP_HOST'] == $refererHostname;
+               }
+               
+               $system['cookie']['result'] = !empty($_COOKIE['wcfsetup_cookietest']) && $_COOKIE['wcfsetup_cookietest'] == TMP_FILE_PREFIX;
+               
                WCF::getTPL()->assign([
                        'system' => $system,
                        'nextStep' => 'configureDirectories'
@@ -1268,7 +1284,7 @@ class WCFSetup extends WCF {
                        $useRandomCookiePrefix = false;
                }
                
-               $prefix = 'wsc52_';
+               $prefix = 'wsc_';
                if ($useRandomCookiePrefix) {
                        $cookieNames = array_keys($_COOKIE);
                        while (true) {
index 0ba15eede3216abec716bc3989a2ae5cf1f8de58..0663dcdf3091d88b663b075d36f5e125d2e8d3f3 100644 (file)
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab::getLoader();
+return ComposerAutoloaderInitf07e6bf6487a19c1ad4a7f66aa2be118::getLoader();
index f6316f90ce174d1e58d662f6ba6e2336abd8f059..d08fca2ff6d8193e66fe6d02d1b688708f589341 120000 (symlink)
@@ -1,14 +1 @@
-#!/usr/bin/env sh
-
-dir=$(cd "${0%[/\\]*}" > /dev/null; cd "../leafo/scssphp/bin" && pwd)
-
-if [ -d /proc/cygdrive ]; then
-    case $(which php) in
-        $(readlink -n /proc/cygdrive)/*)
-            # We are in Cygwin using Windows php, so the path must be translated
-            dir=$(cygpath -m "$dir");
-            ;;
-    esac
-fi
-
-"${dir}/pscss" "$@"
+../scssphp/scssphp/bin/pscss
\ No newline at end of file
diff --git a/wcfsetup/install/files/lib/system/api/bin/pscss.bat b/wcfsetup/install/files/lib/system/api/bin/pscss.bat
deleted file mode 100644 (file)
index cadaeea..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-@ECHO OFF
-setlocal DISABLEDELAYEDEXPANSION
-SET BIN_TARGET=%~dp0/../leafo/scssphp/bin/pscss
-php "%BIN_TARGET%" %*
index f1171d35c8267fc862dc43fee0ff9aa4cdc63182..5cde75ff521c8f509d49abbe3011983029c09ae6 100644 (file)
-PHP ICO - The PHP ICO Generator
-
-Copyright 2011-2016 Chris Jean
-
-PHP ICO is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-PHP ICO is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with PHP ICO; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                            NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
+PHP ICO - The PHP ICO Generator\r
+\r
+Copyright 2011-2016 Chris Jean\r
+\r
+PHP ICO is free software; you can redistribute it and/or modify\r
+it under the terms of the GNU General Public License as published by\r
+the Free Software Foundation; either version 2 of the License, or\r
+(at your option) any later version.\r
+\r
+PHP ICO is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+GNU General Public License for more details.\r
+\r
+You should have received a copy of the GNU General Public License\r
+along with PHP ICO; if not, write to the Free Software\r
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
+\r
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+                    GNU GENERAL PUBLIC LICENSE\r
+                       Version 2, June 1991\r
+\r
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+                            Preamble\r
+\r
+  The licenses for most software are designed to take away your\r
+freedom to share and change it.  By contrast, the GNU General Public\r
+License is intended to guarantee your freedom to share and change free\r
+software--to make sure the software is free for all its users.  This\r
+General Public License applies to most of the Free Software\r
+Foundation's software and to any other program whose authors commit to\r
+using it.  (Some other Free Software Foundation software is covered by\r
+the GNU Lesser General Public License instead.)  You can apply it to\r
+your programs, too.\r
+\r
+  When we speak of free software, we are referring to freedom, not\r
+price.  Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+this service if you wish), that you receive source code or can get it\r
+if you want it, that you can change the software or use pieces of it\r
+in new free programs; and that you know you can do these things.\r
+\r
+  To protect your rights, we need to make restrictions that forbid\r
+anyone to deny you these rights or to ask you to surrender the rights.\r
+These restrictions translate to certain responsibilities for you if you\r
+distribute copies of the software, or if you modify it.\r
+\r
+  For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must give the recipients all the rights that\r
+you have.  You must make sure that they, too, receive or can get the\r
+source code.  And you must show them these terms so they know their\r
+rights.\r
+\r
+  We protect your rights with two steps: (1) copyright the software, and\r
+(2) offer you this license which gives you legal permission to copy,\r
+distribute and/or modify the software.\r
+\r
+  Also, for each author's protection and ours, we want to make certain\r
+that everyone understands that there is no warranty for this free\r
+software.  If the software is modified by someone else and passed on, we\r
+want its recipients to know that what they have is not the original, so\r
+that any problems introduced by others will not reflect on the original\r
+authors' reputations.\r
+\r
+  Finally, any free program is threatened constantly by software\r
+patents.  We wish to avoid the danger that redistributors of a free\r
+program will individually obtain patent licenses, in effect making the\r
+program proprietary.  To prevent this, we have made it clear that any\r
+patent must be licensed for everyone's free use or not licensed at all.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\r
+                    GNU GENERAL PUBLIC LICENSE\r
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+  0. This License applies to any program or other work which contains\r
+a notice placed by the copyright holder saying it may be distributed\r
+under the terms of this General Public License.  The "Program", below,\r
+refers to any such program or work, and a "work based on the Program"\r
+means either the Program or any derivative work under copyright law:\r
+that is to say, a work containing the Program or a portion of it,\r
+either verbatim or with modifications and/or translated into another\r
+language.  (Hereinafter, translation is included without limitation in\r
+the term "modification".)  Each licensee is addressed as "you".\r
+\r
+Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope.  The act of\r
+running the Program is not restricted, and the output from the Program\r
+is covered only if its contents constitute a work based on the\r
+Program (independent of having been made by running the Program).\r
+Whether that is true depends on what the Program does.\r
+\r
+  1. You may copy and distribute verbatim copies of the Program's\r
+source code as you receive it, in any medium, provided that you\r
+conspicuously and appropriately publish on each copy an appropriate\r
+copyright notice and disclaimer of warranty; keep intact all the\r
+notices that refer to this License and to the absence of any warranty;\r
+and give any other recipients of the Program a copy of this License\r
+along with the Program.\r
+\r
+You may charge a fee for the physical act of transferring a copy, and\r
+you may at your option offer warranty protection in exchange for a fee.\r
+\r
+  2. You may modify your copy or copies of the Program or any portion\r
+of it, thus forming a work based on the Program, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+    a) You must cause the modified files to carry prominent notices\r
+    stating that you changed the files and the date of any change.\r
+\r
+    b) You must cause any work that you distribute or publish, that in\r
+    whole or in part contains or is derived from the Program or any\r
+    part thereof, to be licensed as a whole at no charge to all third\r
+    parties under the terms of this License.\r
+\r
+    c) If the modified program normally reads commands interactively\r
+    when run, you must cause it, when started running for such\r
+    interactive use in the most ordinary way, to print or display an\r
+    announcement including an appropriate copyright notice and a\r
+    notice that there is no warranty (or else, saying that you provide\r
+    a warranty) and that users may redistribute the program under\r
+    these conditions, and telling the user how to view a copy of this\r
+    License.  (Exception: if the Program itself is interactive but\r
+    does not normally print such an announcement, your work based on\r
+    the Program is not required to print an announcement.)\r
+\r
+These requirements apply to the modified work as a whole.  If\r
+identifiable sections of that work are not derived from the Program,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works.  But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Program, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Program.\r
+\r
+In addition, mere aggregation of another work not based on the Program\r
+with the Program (or with a work based on the Program) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+  3. You may copy and distribute the Program (or a work based on it,\r
+under Section 2) in object code or executable form under the terms of\r
+Sections 1 and 2 above provided that you also do one of the following:\r
+\r
+    a) Accompany it with the complete corresponding machine-readable\r
+    source code, which must be distributed under the terms of Sections\r
+    1 and 2 above on a medium customarily used for software interchange; or,\r
+\r
+    b) Accompany it with a written offer, valid for at least three\r
+    years, to give any third party, for a charge no more than your\r
+    cost of physically performing source distribution, a complete\r
+    machine-readable copy of the corresponding source code, to be\r
+    distributed under the terms of Sections 1 and 2 above on a medium\r
+    customarily used for software interchange; or,\r
+\r
+    c) Accompany it with the information you received as to the offer\r
+    to distribute corresponding source code.  (This alternative is\r
+    allowed only for noncommercial distribution and only if you\r
+    received the program in object code or executable form with such\r
+    an offer, in accord with Subsection b above.)\r
+\r
+The source code for a work means the preferred form of the work for\r
+making modifications to it.  For an executable work, complete source\r
+code means all the source code for all modules it contains, plus any\r
+associated interface definition files, plus the scripts used to\r
+control compilation and installation of the executable.  However, as a\r
+special exception, the source code distributed need not include\r
+anything that is normally distributed (in either source or binary\r
+form) with the major components (compiler, kernel, and so on) of the\r
+operating system on which the executable runs, unless that component\r
+itself accompanies the executable.\r
+\r
+If distribution of executable or object code is made by offering\r
+access to copy from a designated place, then offering equivalent\r
+access to copy the source code from the same place counts as\r
+distribution of the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\r
+  4. You may not copy, modify, sublicense, or distribute the Program\r
+except as expressly provided under this License.  Any attempt\r
+otherwise to copy, modify, sublicense or distribute the Program is\r
+void, and will automatically terminate your rights under this License.\r
+However, parties who have received copies, or rights, from you under\r
+this License will not have their licenses terminated so long as such\r
+parties remain in full compliance.\r
+\r
+  5. You are not required to accept this License, since you have not\r
+signed it.  However, nothing else grants you permission to modify or\r
+distribute the Program or its derivative works.  These actions are\r
+prohibited by law if you do not accept this License.  Therefore, by\r
+modifying or distributing the Program (or any work based on the\r
+Program), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Program or works based on it.\r
+\r
+  6. Each time you redistribute the Program (or any work based on the\r
+Program), the recipient automatically receives a license from the\r
+original licensor to copy, distribute or modify the Program subject to\r
+these terms and conditions.  You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties to\r
+this License.\r
+\r
+  7. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License.  If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Program at all.  For example, if a patent\r
+license would not permit royalty-free redistribution of the Program by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Program.\r
+\r
+If any portion of this section is held invalid or unenforceable under\r
+any particular circumstance, the balance of the section is intended to\r
+apply and the section as a whole is intended to apply in other\r
+circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system, which is\r
+implemented by public license practices.  Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\r
+  8. If the distribution and/or use of the Program is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Program under this License\r
+may add an explicit geographical distribution limitation excluding\r
+those countries, so that distribution is permitted only in or among\r
+countries not thus excluded.  In such case, this License incorporates\r
+the limitation as if written in the body of this License.\r
+\r
+  9. The Free Software Foundation may publish revised and/or new versions\r
+of the General Public License from time to time.  Such new versions will\r
+be similar in spirit to the present version, but may differ in detail to\r
+address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number.  If the Program\r
+specifies a version number of this License which applies to it and "any\r
+later version", you have the option of following the terms and conditions\r
+either of that version or of any later version published by the Free\r
+Software Foundation.  If the Program does not specify a version number of\r
+this License, you may choose any version ever published by the Free Software\r
+Foundation.\r
+\r
+  10. If you wish to incorporate parts of the Program into other free\r
+programs whose distribution conditions are different, write to the author\r
+to ask for permission.  For software which is copyrighted by the Free\r
+Software Foundation, write to the Free Software Foundation; we sometimes\r
+make exceptions for this.  Our decision will be guided by the two goals\r
+of preserving the free status of all derivatives of our free software and\r
+of promoting the sharing and reuse of software generally.\r
+\r
+                            NO WARRANTY\r
+\r
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
+REPAIR OR CORRECTION.\r
+\r
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGES.\r
+\r
+                     END OF TERMS AND CONDITIONS\r
+\r
+            How to Apply These Terms to Your New Programs\r
+\r
+  If you develop a new program, and you want it to be of the greatest\r
+possible use to the public, the best way to achieve this is to make it\r
+free software which everyone can redistribute and change under these terms.\r
+\r
+  To do so, attach the following notices to the program.  It is safest\r
+to attach them to the start of each source file to most effectively\r
+convey the exclusion of warranty; and each file should have at least\r
+the "copyright" line and a pointer to where the full notice is found.\r
+\r
+    <one line to give the program's name and a brief idea of what it does.>\r
+    Copyright (C) <year>  <name of author>\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License along\r
+    with this program; if not, write to the Free Software Foundation, Inc.,\r
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+\r
+Also add information on how to contact you by electronic and paper mail.\r
+\r
+If the program is interactive, make it output a short notice like this\r
+when it starts in an interactive mode:\r
+\r
+    Gnomovision version 69, Copyright (C) year name of author\r
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r
+    This is free software, and you are welcome to redistribute it\r
+    under certain conditions; type `show c' for details.\r
+\r
+The hypothetical commands `show w' and `show c' should show the appropriate\r
+parts of the General Public License.  Of course, the commands you use may\r
+be called something other than `show w' and `show c'; they could even be\r
+mouse-clicks or menu items--whatever suits your program.\r
+\r
+You should also get your employer (if you work as a programmer) or your\r
+school, if any, to sign a "copyright disclaimer" for the program, if\r
+necessary.  Here is a sample; alter the names:\r
+\r
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\r
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.\r
+\r
+  <signature of Ty Coon>, 1 April 1989\r
+  Ty Coon, President of Vice\r
+\r
+This General Public License does not permit incorporating your program into\r
+proprietary programs.  If your program is a subroutine library, you may\r
+consider it more useful to permit linking proprietary applications with the\r
+library.  If this is what you want to do, use the GNU Lesser General\r
+Public License instead of this License.\r
index 8170b339600e8e45c594fa28d1c6385d2a8a7d19..da977f942c90a9e6a1ed67429eb5594513750d78 100644 (file)
         "chrisjean/php-ico": "1.0.*",
         "true/punycode": "~2.0",
         "pear/net_idna2": "^0.2.0",
-        "leafo/scssphp": "^0.7.7"
-    }
+        "scssphp/scssphp": "^1.3",
+        "guzzlehttp/guzzle": "dev-6.5-woltlab"
+    },
+    "repositories": [
+        {
+            "type": "vcs",
+            "url": "https://github.com/WoltLab/guzzle",
+            "no-api": true
+        }
+    ]
 }
index 9d53f215e63fd1ea2d0d8690bfc4767a30531573..42f21211ffe955cfb613f25a2661dcd363ca5bed 100644 (file)
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "0b588fa9bae7b0d713b4dadff7fbe829",
+    "content-hash": "e4709905ac8ea201053fb79a4a25e0da",
     "packages": [
         {
             "name": "chrisjean/php-ico",
         },
         {
             "name": "erusev/parsedown",
-            "version": "1.7.3",
+            "version": "1.7.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/erusev/parsedown.git",
-                "reference": "6d893938171a817f4e9bc9e86f2da1e370b7bcd7"
+                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/erusev/parsedown/zipball/6d893938171a817f4e9bc9e86f2da1e370b7bcd7",
-                "reference": "6d893938171a817f4e9bc9e86f2da1e370b7bcd7",
+                "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
                 "shasum": ""
             },
             "require": {
@@ -93,7 +93,7 @@
                 "markdown",
                 "parser"
             ],
-            "time": "2019-03-17T18:48:37+00:00"
+            "time": "2019-12-30T22:54:17+00:00"
         },
         {
             "name": "ezyang/htmlpurifier",
             "time": "2019-10-28T03:44:26+00:00"
         },
         {
-            "name": "leafo/scssphp",
-            "version": "v0.7.8",
+            "name": "guzzlehttp/guzzle",
+            "version": "dev-6.5-woltlab",
             "source": {
                 "type": "git",
-                "url": "https://github.com/leafo/scssphp.git",
-                "reference": "a384906af3d078e98b089d7d36f6ceab8703f7ff"
+                "url": "https://github.com/WoltLab/guzzle",
+                "reference": "6298db12d08c3c65c80971bb1b9f6f98e8a43c35"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/leafo/scssphp/zipball/a384906af3d078e98b089d7d36f6ceab8703f7ff",
-                "reference": "a384906af3d078e98b089d7d36f6ceab8703f7ff",
+                "url": "https://api.github.com/repos/WoltLab/guzzle/zipball/6298db12d08c3c65c80971bb1b9f6f98e8a43c35",
+                "reference": "6298db12d08c3c65c80971bb1b9f6f98e8a43c35",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.4.0"
+                "ext-json": "*",
+                "guzzlehttp/promises": "^1.0",
+                "guzzlehttp/psr7": "^1.6.1",
+                "php": ">=5.5",
+                "symfony/polyfill-intl-idn": "^1.17.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "~4.6",
-                "squizlabs/php_codesniffer": "~2.5"
+                "ext-curl": "*",
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+                "psr/log": "^1.1"
             },
-            "bin": [
-                "bin/pscss"
+            "suggest": {
+                "psr/log": "Required for using the Log middleware"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.5-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "autoload-dev": {
+                "psr-4": {
+                    "GuzzleHttp\\Tests\\": "tests/"
+                }
+            },
+            "license": [
+                "MIT"
             ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                }
+            ],
+            "description": "Guzzle is a PHP HTTP client library",
+            "homepage": "http://guzzlephp.org/",
+            "keywords": [
+                "HTTP client",
+                "client",
+                "curl",
+                "framework",
+                "http",
+                "rest",
+                "web service"
+            ],
+            "time": "2021-02-01T09:42:51+00:00"
+        },
+        {
+            "name": "guzzlehttp/promises",
+            "version": "v1.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/promises.git",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.0"
+            },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4-dev"
+                }
+            },
             "autoload": {
                 "psr-4": {
-                    "Leafo\\ScssPhp\\": "src/"
+                    "GuzzleHttp\\Promise\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
                 }
+            ],
+            "description": "Guzzle promises library",
+            "keywords": [
+                "promise"
+            ],
+            "time": "2016-12-20T10:07:11+00:00"
+        },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "1.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0",
+                "psr/http-message": "~1.0",
+                "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+            },
+            "provide": {
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "ext-zlib": "*",
+                "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+            },
+            "suggest": {
+                "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
             ],
             "authors": [
                 {
-                    "name": "Leaf Corcoran",
-                    "email": "leafot@gmail.com",
-                    "homepage": "http://leafo.net"
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "homepage": "https://github.com/Tobion"
                 }
             ],
-            "description": "scssphp is a compiler for SCSS written in PHP.",
-            "homepage": "http://leafo.github.io/scssphp/",
+            "description": "PSR-7 message implementation that also provides common utility methods",
             "keywords": [
-                "css",
-                "less",
-                "sass",
-                "scss",
-                "stylesheet"
+                "http",
+                "message",
+                "psr-7",
+                "request",
+                "response",
+                "stream",
+                "uri",
+                "url"
             ],
-            "time": "2019-04-24T18:10:10+00:00"
+            "time": "2019-07-01T23:21:34+00:00"
         },
         {
             "name": "pear/net_idna2",
         },
         {
             "name": "pear/pear_exception",
-            "version": "v1.0.0",
+            "version": "v1.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/pear/PEAR_Exception.git",
-                "reference": "8c18719fdae000b690e3912be401c76e406dd13b"
+                "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b",
-                "reference": "8c18719fdae000b690e3912be401c76e406dd13b",
+                "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7",
+                "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7",
                 "shasum": ""
             },
             "require": {
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "PEAR": ""
-                }
+                "classmap": [
+                    "PEAR/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "include-path": [
             "keywords": [
                 "exception"
             ],
-            "time": "2015-02-10T20:07:52+00:00"
+            "time": "2019-12-10T10:24:42+00:00"
         },
         {
             "name": "pelago/emogrifier",
             ],
             "time": "2018-12-10T10:36:30+00:00"
         },
+        {
+            "name": "psr/http-message",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-message.git",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP messages",
+            "homepage": "https://github.com/php-fig/http-message",
+            "keywords": [
+                "http",
+                "http-message",
+                "psr",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "time": "2016-08-06T14:39:51+00:00"
+        },
+        {
+            "name": "ralouphie/getallheaders",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ralouphie/getallheaders.git",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.1",
+                "phpunit/phpunit": "^5 || ^6.5"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/getallheaders.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ralph Khattar",
+                    "email": "ralph.khattar@gmail.com"
+                }
+            ],
+            "description": "A polyfill for getallheaders.",
+            "time": "2019-03-08T08:55:37+00:00"
+        },
+        {
+            "name": "scssphp/scssphp",
+            "version": "1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/scssphp/scssphp.git",
+                "reference": "261cd018025d5790e135a1e5b694d6af186e6bca"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/scssphp/scssphp/zipball/261cd018025d5790e135a1e5b694d6af186e6bca",
+                "reference": "261cd018025d5790e135a1e5b694d6af186e6bca",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-json": "*",
+                "php": ">=5.6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3 || ^9.4",
+                "sass/sass-spec": "2020.08.10",
+                "squizlabs/php_codesniffer": "~3.5",
+                "twbs/bootstrap": "~4.3",
+                "zurb/foundation": "~6.5"
+            },
+            "bin": [
+                "bin/pscss"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "ScssPhp\\ScssPhp\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Anthon Pang",
+                    "email": "apang@softwaredevelopment.ca",
+                    "homepage": "https://github.com/robocoder"
+                },
+                {
+                    "name": "Cédric Morin",
+                    "email": "cedric@yterium.com",
+                    "homepage": "https://github.com/Cerdic"
+                }
+            ],
+            "description": "scssphp is a compiler for SCSS written in PHP.",
+            "homepage": "http://scssphp.github.io/scssphp/",
+            "keywords": [
+                "css",
+                "less",
+                "sass",
+                "scss",
+                "stylesheet"
+            ],
+            "time": "2020-10-29T11:09:57+00:00"
+        },
         {
             "name": "symfony/css-selector",
-            "version": "v3.4.35",
+            "version": "v3.4.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "f819f71ae3ba6f396b4c015bd5895de7d2f1f85f"
+                "reference": "9ccf6e78077a3fc1596e6c7b5958008965a11518"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/f819f71ae3ba6f396b4c015bd5895de7d2f1f85f",
-                "reference": "f819f71ae3ba6f396b4c015bd5895de7d2f1f85f",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/9ccf6e78077a3fc1596e6c7b5958008965a11518",
+                "reference": "9ccf6e78077a3fc1596e6c7b5958008965a11518",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony CssSelector Component",
             "homepage": "https://symfony.com",
-            "time": "2019-10-01T11:57:37+00:00"
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-03-16T08:31:04+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-idn",
+            "version": "v1.17.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-idn.git",
+                "reference": "a57f8161502549a742a63c09f0a604997bf47027"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a57f8161502549a742a63c09f0a604997bf47027",
+                "reference": "a57f8161502549a742a63c09f0a604997bf47027",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "symfony/polyfill-mbstring": "^1.3",
+                "symfony/polyfill-php72": "^1.10"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.17-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Idn\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Laurent Bassin",
+                    "email": "laurent@bassin.info"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "idn",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-06-06T08:46:27+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.12.0",
+            "version": "v1.17.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
+                "reference": "7110338d81ce1cbc3e273136e4574663627037a7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
-                "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7",
+                "reference": "7110338d81ce1cbc3e273136e4574663627037a7",
                 "shasum": ""
             },
             "require": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.12-dev"
+                    "dev-master": "1.17-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
                 }
             },
             "autoload": {
                 "portable",
                 "shim"
             ],
-            "time": "2019-08-06T08:03:45+00:00"
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-06-06T08:46:27+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php72",
+            "version": "v1.17.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php72.git",
+                "reference": "f048e612a3905f34931127360bdd2def19a5e582"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582",
+                "reference": "f048e612a3905f34931127360bdd2def19a5e582",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.17-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php72\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-05-12T16:47:27+00:00"
         },
         {
             "name": "true/punycode",
     "packages-dev": [],
     "aliases": [],
     "minimum-stability": "stable",
-    "stability-flags": [],
+    "stability-flags": {
+        "guzzlehttp/guzzle": 20
+    },
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": [],
     "platform-overrides": {
         "php": "7.0.22",
         "ext-gd": "0"
-    }
+    },
+    "plugin-api-version": "2.0.0"
 }
index fce8549f0781bafdc7da2301b84d048286757445..1a58957d25d4a5fd00be8d9f086a4ece3bf8371e 100644 (file)
@@ -37,8 +37,8 @@ namespace Composer\Autoload;
  *
  * @author Fabien Potencier <fabien@symfony.com>
  * @author Jordi Boggiano <j.boggiano@seld.be>
- * @see    http://www.php-fig.org/psr/psr-0/
- * @see    http://www.php-fig.org/psr/psr-4/
+ * @see    https://www.php-fig.org/psr/psr-0/
+ * @see    https://www.php-fig.org/psr/psr-4/
  */
 class ClassLoader
 {
@@ -60,7 +60,7 @@ class ClassLoader
     public function getPrefixes()
     {
         if (!empty($this->prefixesPsr0)) {
-            return call_user_func_array('array_merge', $this->prefixesPsr0);
+            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
         }
 
         return array();
diff --git a/wcfsetup/install/files/lib/system/api/composer/InstalledVersions.php b/wcfsetup/install/files/lib/system/api/composer/InstalledVersions.php
new file mode 100644 (file)
index 0000000..d497987
--- /dev/null
@@ -0,0 +1,369 @@
+<?php
+
+namespace Composer;
+
+use Composer\Semver\VersionParser;
+
+
+
+
+
+
+class InstalledVersions
+{
+private static $installed = array (
+  'root' => 
+  array (
+    'pretty_version' => '1.0.0+no-version-set',
+    'version' => '1.0.0.0',
+    'aliases' => 
+    array (
+    ),
+    'reference' => NULL,
+    'name' => '__root__',
+  ),
+  'versions' => 
+  array (
+    '__root__' => 
+    array (
+      'pretty_version' => '1.0.0+no-version-set',
+      'version' => '1.0.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => NULL,
+    ),
+    'chrisjean/php-ico' => 
+    array (
+      'pretty_version' => '1.0.4',
+      'version' => '1.0.4.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6',
+    ),
+    'erusev/parsedown' => 
+    array (
+      'pretty_version' => '1.7.4',
+      'version' => '1.7.4.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'cb17b6477dfff935958ba01325f2e8a2bfa6dab3',
+    ),
+    'ezyang/htmlpurifier' => 
+    array (
+      'pretty_version' => 'v4.12.0',
+      'version' => '4.12.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a617e55bc62a87eec73bd456d146d134ad716f03',
+    ),
+    'guzzlehttp/guzzle' => 
+    array (
+      'pretty_version' => 'dev-6.5-woltlab',
+      'version' => 'dev-6.5-woltlab',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '6298db12d08c3c65c80971bb1b9f6f98e8a43c35',
+    ),
+    'guzzlehttp/promises' => 
+    array (
+      'pretty_version' => 'v1.3.1',
+      'version' => '1.3.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a59da6cf61d80060647ff4d3eb2c03a2bc694646',
+    ),
+    'guzzlehttp/psr7' => 
+    array (
+      'pretty_version' => '1.6.1',
+      'version' => '1.6.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '239400de7a173fe9901b9ac7c06497751f00727a',
+    ),
+    'pear/net_idna2' => 
+    array (
+      'pretty_version' => 'v0.2.0',
+      'version' => '0.2.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '51734eaf8be2df58e8aad5835b9966459b2fb37c',
+    ),
+    'pear/pear_exception' => 
+    array (
+      'pretty_version' => 'v1.0.1',
+      'version' => '1.0.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7',
+    ),
+    'pelago/emogrifier' => 
+    array (
+      'pretty_version' => 'v2.1.1',
+      'version' => '2.1.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '8ee7fb5ad772915451ed3415c1992bd3697d4983',
+    ),
+    'psr/http-message' => 
+    array (
+      'pretty_version' => '1.0.1',
+      'version' => '1.0.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
+    ),
+    'psr/http-message-implementation' => 
+    array (
+      'provided' => 
+      array (
+        0 => '1.0',
+      ),
+    ),
+    'ralouphie/getallheaders' => 
+    array (
+      'pretty_version' => '3.0.3',
+      'version' => '3.0.3.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '120b605dfeb996808c31b6477290a714d356e822',
+    ),
+    'scssphp/scssphp' => 
+    array (
+      'pretty_version' => '1.3',
+      'version' => '1.3.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '261cd018025d5790e135a1e5b694d6af186e6bca',
+    ),
+    'symfony/css-selector' => 
+    array (
+      'pretty_version' => 'v3.4.42',
+      'version' => '3.4.42.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '9ccf6e78077a3fc1596e6c7b5958008965a11518',
+    ),
+    'symfony/polyfill-intl-idn' => 
+    array (
+      'pretty_version' => 'v1.17.1',
+      'version' => '1.17.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a57f8161502549a742a63c09f0a604997bf47027',
+    ),
+    'symfony/polyfill-mbstring' => 
+    array (
+      'pretty_version' => 'v1.17.1',
+      'version' => '1.17.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '7110338d81ce1cbc3e273136e4574663627037a7',
+    ),
+    'symfony/polyfill-php72' => 
+    array (
+      'pretty_version' => 'v1.17.0',
+      'version' => '1.17.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'f048e612a3905f34931127360bdd2def19a5e582',
+    ),
+    'true/punycode' => 
+    array (
+      'pretty_version' => 'v2.1.1',
+      'version' => '2.1.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a4d0c11a36dd7f4e7cd7096076cab6d3378a071e',
+    ),
+  ),
+);
+
+
+
+
+
+
+
+public static function getInstalledPackages()
+{
+return array_keys(self::$installed['versions']);
+}
+
+
+
+
+
+
+
+
+
+public static function isInstalled($packageName)
+{
+return isset(self::$installed['versions'][$packageName]);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function satisfies(VersionParser $parser, $packageName, $constraint)
+{
+$constraint = $parser->parseConstraints($constraint);
+$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+return $provided->matches($constraint);
+}
+
+
+
+
+
+
+
+
+
+
+public static function getVersionRanges($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+$ranges = array();
+if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
+$ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
+}
+if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
+}
+if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
+}
+if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
+}
+
+return implode(' || ', $ranges);
+}
+
+
+
+
+
+public static function getVersion($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+if (!isset(self::$installed['versions'][$packageName]['version'])) {
+return null;
+}
+
+return self::$installed['versions'][$packageName]['version'];
+}
+
+
+
+
+
+public static function getPrettyVersion($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
+return null;
+}
+
+return self::$installed['versions'][$packageName]['pretty_version'];
+}
+
+
+
+
+
+public static function getReference($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+if (!isset(self::$installed['versions'][$packageName]['reference'])) {
+return null;
+}
+
+return self::$installed['versions'][$packageName]['reference'];
+}
+
+
+
+
+
+public static function getRootPackage()
+{
+return self::$installed['root'];
+}
+
+
+
+
+
+
+
+public static function getRawData()
+{
+return self::$installed;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function reload($data)
+{
+self::$installed = $data;
+}
+}
index 063ce1fa712957e4ba13c41b60e6fd120c3c7c3c..33a49c649b1200e79521a135fa99f7c227afcbaa 100644 (file)
@@ -6,5 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
 $baseDir = $vendorDir;
 
 return array(
+    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+    'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php',
     'PHP_ICO' => $vendorDir . '/chrisjean/php-ico/class-php-ico.php',
 );
index ba2ac6cbeca974dac1e6a966bdcb7a68c506147e..4910210bebd3b857cb28f59ca1d58b29fafc596f 100644 (file)
@@ -7,5 +7,11 @@ $baseDir = $vendorDir;
 
 return array(
     '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
+    '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
+    '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
+    'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
+    'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
+    'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
     '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
+    '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
 );
index c197b6be79009b020dfb99095d832e493618b0ff..67a9a9a041f1961ca89cc0e5e2390e1d2b49d912 100644 (file)
@@ -7,7 +7,6 @@ $baseDir = $vendorDir;
 
 return array(
     'Parsedown' => array($vendorDir . '/erusev/parsedown'),
-    'PEAR' => array($vendorDir . '/pear/pear_exception'),
     'Net' => array($vendorDir . '/pear/net_idna2'),
     'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
 );
index 1cae62ff682cfcede40cf75740f2a63ef3052da5..0ebcaa804d9572e751dc575256bbe3e9d2e7291e 100644 (file)
@@ -7,8 +7,14 @@ $baseDir = $vendorDir;
 
 return array(
     'TrueBV\\' => array($vendorDir . '/true/punycode/src'),
+    'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
     'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
+    'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
     'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
+    'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
+    'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
     'Pelago\\' => array($vendorDir . '/pelago/emogrifier/src'),
-    'Leafo\\ScssPhp\\' => array($vendorDir . '/leafo/scssphp/src'),
+    'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
+    'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
+    'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
 );
index 9ec7c39aadfe39997b533e191dfdcb83fb43c82d..7cc25acda310ef10cd53d3fa6ea4cc83bc24403f 100644 (file)
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab
+class ComposerAutoloaderInitf07e6bf6487a19c1ad4a7f66aa2be118
 {
     private static $loader;
 
@@ -13,15 +13,20 @@ class ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab
         }
     }
 
+    /**
+     * @return \Composer\Autoload\ClassLoader
+     */
     public static function getLoader()
     {
         if (null !== self::$loader) {
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab', 'loadClassLoader'), true, false);
+        require __DIR__ . '/platform_check.php';
+
+        spl_autoload_register(array('ComposerAutoloaderInitf07e6bf6487a19c1ad4a7f66aa2be118', 'loadClassLoader'), true, false);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInitf07e6bf6487a19c1ad4a7f66aa2be118', 'loadClassLoader'));
 
         $includePaths = require __DIR__ . '/include_paths.php';
         $includePaths[] = get_include_path();
@@ -29,9 +34,9 @@ class ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab
 
         $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
         if ($useStaticLoader) {
-            require_once __DIR__ . '/autoload_static.php';
+            require __DIR__ . '/autoload_static.php';
 
-            call_user_func(\Composer\Autoload\ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab::getInitializer($loader));
+            call_user_func(\Composer\Autoload\ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118::getInitializer($loader));
         } else {
             $map = require __DIR__ . '/autoload_namespaces.php';
             foreach ($map as $namespace => $path) {
@@ -52,19 +57,19 @@ class ComposerAutoloaderInit4a4e0e985ef68770d710dc260edc44ab
         $loader->register(false);
 
         if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab::$files;
+            $includeFiles = Composer\Autoload\ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequire4a4e0e985ef68770d710dc260edc44ab($fileIdentifier, $file);
+            composerRequiref07e6bf6487a19c1ad4a7f66aa2be118($fileIdentifier, $file);
         }
 
         return $loader;
     }
 }
 
-function composerRequire4a4e0e985ef68770d710dc260edc44ab($fileIdentifier, $file)
+function composerRequiref07e6bf6487a19c1ad4a7f66aa2be118($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         require $file;
index acad2076063c537b4e73fa2dee31af32b6775142..9144259f89bbf40def7ea274e66f6a77c6803a61 100644 (file)
@@ -4,11 +4,17 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab
+class ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118
 {
     public static $files = array (
         '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
+        '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
+        '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
+        'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
+        'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
+        'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
         '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
+        '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
     );
 
     public static $prefixLengthsPsr4 = array (
@@ -18,16 +24,22 @@ class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab
         ),
         'S' => 
         array (
+            'Symfony\\Polyfill\\Php72\\' => 23,
             'Symfony\\Polyfill\\Mbstring\\' => 26,
+            'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
             'Symfony\\Component\\CssSelector\\' => 30,
+            'ScssPhp\\ScssPhp\\' => 16,
         ),
         'P' => 
         array (
+            'Psr\\Http\\Message\\' => 17,
             'Pelago\\' => 7,
         ),
-        'L' => 
+        'G' => 
         array (
-            'Leafo\\ScssPhp\\' => 14,
+            'GuzzleHttp\\Psr7\\' => 16,
+            'GuzzleHttp\\Promise\\' => 19,
+            'GuzzleHttp\\' => 11,
         ),
     );
 
@@ -36,21 +48,45 @@ class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab
         array (
             0 => __DIR__ . '/..' . '/true/punycode/src',
         ),
+        'Symfony\\Polyfill\\Php72\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
+        ),
         'Symfony\\Polyfill\\Mbstring\\' => 
         array (
             0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
         ),
+        'Symfony\\Polyfill\\Intl\\Idn\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
+        ),
         'Symfony\\Component\\CssSelector\\' => 
         array (
             0 => __DIR__ . '/..' . '/symfony/css-selector',
         ),
+        'ScssPhp\\ScssPhp\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
+        ),
+        'Psr\\Http\\Message\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/http-message/src',
+        ),
         'Pelago\\' => 
         array (
             0 => __DIR__ . '/..' . '/pelago/emogrifier/src',
         ),
-        'Leafo\\ScssPhp\\' => 
+        'GuzzleHttp\\Psr7\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
+        ),
+        'GuzzleHttp\\Promise\\' => 
         array (
-            0 => __DIR__ . '/..' . '/leafo/scssphp/src',
+            0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
+        ),
+        'GuzzleHttp\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
         ),
     );
 
@@ -61,10 +97,6 @@ class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab
             array (
                 0 => __DIR__ . '/..' . '/erusev/parsedown',
             ),
-            'PEAR' => 
-            array (
-                0 => __DIR__ . '/..' . '/pear/pear_exception',
-            ),
         ),
         'N' => 
         array (
@@ -83,16 +115,18 @@ class ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab
     );
 
     public static $classMap = array (
+        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+        'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php',
         'PHP_ICO' => __DIR__ . '/..' . '/chrisjean/php-ico/class-php-ico.php',
     );
 
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab::$prefixDirsPsr4;
-            $loader->prefixesPsr0 = ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab::$prefixesPsr0;
-            $loader->classMap = ComposerStaticInit4a4e0e985ef68770d710dc260edc44ab::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118::$prefixDirsPsr4;
+            $loader->prefixesPsr0 = ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118::$prefixesPsr0;
+            $loader->classMap = ComposerStaticInitf07e6bf6487a19c1ad4a7f66aa2be118::$classMap;
 
         }, null, ClassLoader::class);
     }
index 0372fce88dc7403c959387c1a474bbb452de88fc..eb791ec8488960c7a44940f39e2c0dd23176bb13 100644 (file)
-[
-    {
-        "name": "chrisjean/php-ico",
-        "version": "1.0.4",
-        "version_normalized": "1.0.4.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/chrisbliss18/php-ico.git",
-            "reference": "ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/chrisbliss18/php-ico/zipball/ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6",
-            "reference": "ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6",
-            "shasum": ""
-        },
-        "require": {
-            "ext-gd": "*",
-            "php": ">=5.2.4"
-        },
-        "time": "2016-09-27T22:00:56+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "class-php-ico.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "GPL-2.0+"
-        ],
-        "authors": [
-            {
-                "name": "Chris Jean",
-                "homepage": "https://chrisjean.com",
-                "role": "Developer"
-            }
-        ],
-        "description": "An easy-to-use library to generate valid ICO files.",
-        "homepage": "https://github.com/chrisbliss18/php-ico",
-        "keywords": [
-            "favicon",
-            "ico"
-        ]
-    },
-    {
-        "name": "erusev/parsedown",
-        "version": "1.7.3",
-        "version_normalized": "1.7.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/erusev/parsedown.git",
-            "reference": "6d893938171a817f4e9bc9e86f2da1e370b7bcd7"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/erusev/parsedown/zipball/6d893938171a817f4e9bc9e86f2da1e370b7bcd7",
-            "reference": "6d893938171a817f4e9bc9e86f2da1e370b7bcd7",
-            "shasum": ""
-        },
-        "require": {
-            "ext-mbstring": "*",
-            "php": ">=5.3.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^4.8.35"
-        },
-        "time": "2019-03-17T18:48:37+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Parsedown": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Emanuil Rusev",
-                "email": "hello@erusev.com",
-                "homepage": "http://erusev.com"
-            }
-        ],
-        "description": "Parser for Markdown.",
-        "homepage": "http://parsedown.org",
-        "keywords": [
-            "markdown",
-            "parser"
-        ]
-    },
-    {
-        "name": "ezyang/htmlpurifier",
-        "version": "v4.12.0",
-        "version_normalized": "4.12.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/ezyang/htmlpurifier.git",
-            "reference": "a617e55bc62a87eec73bd456d146d134ad716f03"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/a617e55bc62a87eec73bd456d146d134ad716f03",
-            "reference": "a617e55bc62a87eec73bd456d146d134ad716f03",
-            "shasum": ""
-        },
-        "require": {
-            "php": ">=5.2"
-        },
-        "require-dev": {
-            "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
-        },
-        "time": "2019-10-28T03:44:26+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "HTMLPurifier": "library/"
-            },
-            "files": [
-                "library/HTMLPurifier.composer.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "LGPL-2.1-or-later"
-        ],
-        "authors": [
-            {
-                "name": "Edward Z. Yang",
-                "email": "admin@htmlpurifier.org",
-                "homepage": "http://ezyang.com"
-            }
-        ],
-        "description": "Standards compliant HTML filter written in PHP",
-        "homepage": "http://htmlpurifier.org/",
-        "keywords": [
-            "html"
-        ]
-    },
-    {
-        "name": "leafo/scssphp",
-        "version": "v0.7.8",
-        "version_normalized": "0.7.8.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/leafo/scssphp.git",
-            "reference": "a384906af3d078e98b089d7d36f6ceab8703f7ff"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/leafo/scssphp/zipball/a384906af3d078e98b089d7d36f6ceab8703f7ff",
-            "reference": "a384906af3d078e98b089d7d36f6ceab8703f7ff",
-            "shasum": ""
-        },
-        "require": {
-            "php": ">=5.4.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "~4.6",
-            "squizlabs/php_codesniffer": "~2.5"
-        },
-        "time": "2019-04-24T18:10:10+00:00",
-        "bin": [
-            "bin/pscss"
-        ],
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Leafo\\ScssPhp\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Leaf Corcoran",
-                "email": "leafot@gmail.com",
-                "homepage": "http://leafo.net"
-            }
-        ],
-        "description": "scssphp is a compiler for SCSS written in PHP.",
-        "homepage": "http://leafo.github.io/scssphp/",
-        "keywords": [
-            "css",
-            "less",
-            "sass",
-            "scss",
-            "stylesheet"
-        ]
-    },
-    {
-        "name": "pear/net_idna2",
-        "version": "v0.2.0",
-        "version_normalized": "0.2.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/pear/Net_IDNA2.git",
-            "reference": "51734eaf8be2df58e8aad5835b9966459b2fb37c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/pear/Net_IDNA2/zipball/51734eaf8be2df58e8aad5835b9966459b2fb37c",
-            "reference": "51734eaf8be2df58e8aad5835b9966459b2fb37c",
-            "shasum": ""
-        },
-        "require": {
-            "pear/pear_exception": "@stable"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^4"
-        },
-        "time": "2017-03-06T20:46:41+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Net": "./"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "include-path": [
-            "./"
-        ],
-        "license": [
-            "LGPL"
-        ],
-        "authors": [
-            {
-                "name": "Stefan Neufeind",
-                "email": "pear.neufeind@speedpartner.de",
-                "role": "Lead"
-            },
-            {
-                "name": "Daniel O'Connor",
-                "email": "daniel.oconnor@gmail.com",
-                "role": "Lead"
-            }
-        ],
-        "description": "More info available on: https://pear.php.net/package/Net_IDNA2"
-    },
-    {
-        "name": "pear/pear_exception",
-        "version": "v1.0.0",
-        "version_normalized": "1.0.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/pear/PEAR_Exception.git",
-            "reference": "8c18719fdae000b690e3912be401c76e406dd13b"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b",
-            "reference": "8c18719fdae000b690e3912be401c76e406dd13b",
-            "shasum": ""
-        },
-        "require": {
-            "php": ">=4.4.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "*"
-        },
-        "time": "2015-02-10T20:07:52+00:00",
-        "type": "class",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "PEAR": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "include-path": [
-            "."
-        ],
-        "license": [
-            "BSD-2-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Helgi Thormar",
-                "email": "dufuz@php.net"
-            },
-            {
-                "name": "Greg Beaver",
-                "email": "cellog@php.net"
-            }
-        ],
-        "description": "The PEAR Exception base class.",
-        "homepage": "https://github.com/pear/PEAR_Exception",
-        "keywords": [
-            "exception"
-        ]
-    },
-    {
-        "name": "pelago/emogrifier",
-        "version": "v2.1.1",
-        "version_normalized": "2.1.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/MyIntervals/emogrifier.git",
-            "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8ee7fb5ad772915451ed3415c1992bd3697d4983",
-            "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983",
-            "shasum": ""
-        },
-        "require": {
-            "ext-dom": "*",
-            "ext-libxml": "*",
-            "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0",
-            "symfony/css-selector": "^3.4.0 || ^4.0.0"
-        },
-        "require-dev": {
-            "friendsofphp/php-cs-fixer": "^2.2.0",
-            "phpmd/phpmd": "^2.6.0",
-            "phpunit/phpunit": "^4.8.0",
-            "squizlabs/php_codesniffer": "^3.3.2"
-        },
-        "time": "2018-12-10T10:36:30+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.1.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Pelago\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "John Reeve",
-                "email": "jreeve@pelagodesign.com"
-            },
-            {
-                "name": "Cameron Brooks"
-            },
-            {
-                "name": "Jaime Prado"
-            },
-            {
-                "name": "Oliver Klee",
-                "email": "github@oliverklee.de"
-            },
-            {
-                "name": "Zoli Szabó",
-                "email": "zoli.szabo+github@gmail.com"
-            },
-            {
-                "name": "Jake Hotson",
-                "email": "jake@qzdesign.co.uk"
-            }
-        ],
-        "description": "Converts CSS styles into inline style attributes in your HTML code",
-        "homepage": "https://www.myintervals.com/emogrifier.php",
-        "keywords": [
-            "css",
-            "email",
-            "pre-processing"
-        ]
-    },
-    {
-        "name": "symfony/css-selector",
-        "version": "v3.4.35",
-        "version_normalized": "3.4.35.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/css-selector.git",
-            "reference": "f819f71ae3ba6f396b4c015bd5895de7d2f1f85f"
+{
+    "packages": [
+        {
+            "name": "chrisjean/php-ico",
+            "version": "1.0.4",
+            "version_normalized": "1.0.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/chrisbliss18/php-ico.git",
+                "reference": "ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/chrisbliss18/php-ico/zipball/ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6",
+                "reference": "ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6",
+                "shasum": ""
+            },
+            "require": {
+                "ext-gd": "*",
+                "php": ">=5.2.4"
+            },
+            "time": "2016-09-27T22:00:56+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "class-php-ico.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "GPL-2.0+"
+            ],
+            "authors": [
+                {
+                    "name": "Chris Jean",
+                    "homepage": "https://chrisjean.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "An easy-to-use library to generate valid ICO files.",
+            "homepage": "https://github.com/chrisbliss18/php-ico",
+            "keywords": [
+                "favicon",
+                "ico"
+            ],
+            "install-path": "../chrisjean/php-ico"
         },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/css-selector/zipball/f819f71ae3ba6f396b4c015bd5895de7d2f1f85f",
-            "reference": "f819f71ae3ba6f396b4c015bd5895de7d2f1f85f",
-            "shasum": ""
+        {
+            "name": "erusev/parsedown",
+            "version": "1.7.4",
+            "version_normalized": "1.7.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/erusev/parsedown.git",
+                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+                "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "php": ">=5.3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35"
+            },
+            "time": "2019-12-30T22:54:17+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Parsedown": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Emanuil Rusev",
+                    "email": "hello@erusev.com",
+                    "homepage": "http://erusev.com"
+                }
+            ],
+            "description": "Parser for Markdown.",
+            "homepage": "http://parsedown.org",
+            "keywords": [
+                "markdown",
+                "parser"
+            ],
+            "install-path": "../erusev/parsedown"
         },
-        "require": {
-            "php": "^5.5.9|>=7.0.8"
+        {
+            "name": "ezyang/htmlpurifier",
+            "version": "v4.12.0",
+            "version_normalized": "4.12.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ezyang/htmlpurifier.git",
+                "reference": "a617e55bc62a87eec73bd456d146d134ad716f03"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/a617e55bc62a87eec73bd456d146d134ad716f03",
+                "reference": "a617e55bc62a87eec73bd456d146d134ad716f03",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.2"
+            },
+            "require-dev": {
+                "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
+            },
+            "time": "2019-10-28T03:44:26+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "HTMLPurifier": "library/"
+                },
+                "files": [
+                    "library/HTMLPurifier.composer.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "LGPL-2.1-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "Edward Z. Yang",
+                    "email": "admin@htmlpurifier.org",
+                    "homepage": "http://ezyang.com"
+                }
+            ],
+            "description": "Standards compliant HTML filter written in PHP",
+            "homepage": "http://htmlpurifier.org/",
+            "keywords": [
+                "html"
+            ],
+            "install-path": "../ezyang/htmlpurifier"
         },
-        "time": "2019-10-01T11:57:37+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.4-dev"
-            }
+        {
+            "name": "guzzlehttp/guzzle",
+            "version": "dev-6.5-woltlab",
+            "version_normalized": "dev-6.5-woltlab",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/WoltLab/guzzle",
+                "reference": "6298db12d08c3c65c80971bb1b9f6f98e8a43c35"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/WoltLab/guzzle/zipball/6298db12d08c3c65c80971bb1b9f6f98e8a43c35",
+                "reference": "6298db12d08c3c65c80971bb1b9f6f98e8a43c35",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "guzzlehttp/promises": "^1.0",
+                "guzzlehttp/psr7": "^1.6.1",
+                "php": ">=5.5",
+                "symfony/polyfill-intl-idn": "^1.17.0"
+            },
+            "require-dev": {
+                "ext-curl": "*",
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+                "psr/log": "^1.1"
+            },
+            "suggest": {
+                "psr/log": "Required for using the Log middleware"
+            },
+            "time": "2021-02-01T09:42:51+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.5-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "autoload-dev": {
+                "psr-4": {
+                    "GuzzleHttp\\Tests\\": "tests/"
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                }
+            ],
+            "description": "Guzzle is a PHP HTTP client library",
+            "homepage": "http://guzzlephp.org/",
+            "keywords": [
+                "HTTP client",
+                "client",
+                "curl",
+                "framework",
+                "http",
+                "rest",
+                "web service"
+            ],
+            "install-path": "../guzzlehttp/guzzle"
         },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\CssSelector\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
+        {
+            "name": "guzzlehttp/promises",
+            "version": "v1.3.1",
+            "version_normalized": "1.3.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/promises.git",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.0"
+            },
+            "time": "2016-12-20T10:07:11+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Promise\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                }
+            ],
+            "description": "Guzzle promises library",
+            "keywords": [
+                "promise"
+            ],
+            "install-path": "../guzzlehttp/promises"
         },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Jean-François Simon",
-                "email": "jeanfrancois.simon@sensiolabs.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony CssSelector Component",
-        "homepage": "https://symfony.com"
-    },
-    {
-        "name": "symfony/polyfill-mbstring",
-        "version": "v1.12.0",
-        "version_normalized": "1.12.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-mbstring.git",
-            "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "1.6.1",
+            "version_normalized": "1.6.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0",
+                "psr/http-message": "~1.0",
+                "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+            },
+            "provide": {
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "ext-zlib": "*",
+                "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+            },
+            "suggest": {
+                "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
+            },
+            "time": "2019-07-01T23:21:34+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.6-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "homepage": "https://github.com/Tobion"
+                }
+            ],
+            "description": "PSR-7 message implementation that also provides common utility methods",
+            "keywords": [
+                "http",
+                "message",
+                "psr-7",
+                "request",
+                "response",
+                "stream",
+                "uri",
+                "url"
+            ],
+            "install-path": "../guzzlehttp/psr7"
         },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
-            "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
-            "shasum": ""
+        {
+            "name": "pear/net_idna2",
+            "version": "v0.2.0",
+            "version_normalized": "0.2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pear/Net_IDNA2.git",
+                "reference": "51734eaf8be2df58e8aad5835b9966459b2fb37c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pear/Net_IDNA2/zipball/51734eaf8be2df58e8aad5835b9966459b2fb37c",
+                "reference": "51734eaf8be2df58e8aad5835b9966459b2fb37c",
+                "shasum": ""
+            },
+            "require": {
+                "pear/pear_exception": "@stable"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4"
+            },
+            "time": "2017-03-06T20:46:41+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Net": "./"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                "./"
+            ],
+            "license": [
+                "LGPL"
+            ],
+            "authors": [
+                {
+                    "name": "Stefan Neufeind",
+                    "email": "pear.neufeind@speedpartner.de",
+                    "role": "Lead"
+                },
+                {
+                    "name": "Daniel O'Connor",
+                    "email": "daniel.oconnor@gmail.com",
+                    "role": "Lead"
+                }
+            ],
+            "description": "More info available on: https://pear.php.net/package/Net_IDNA2",
+            "install-path": "../pear/net_idna2"
         },
-        "require": {
-            "php": ">=5.3.3"
+        {
+            "name": "pear/pear_exception",
+            "version": "v1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pear/PEAR_Exception.git",
+                "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7",
+                "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=4.4.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "*"
+            },
+            "time": "2019-12-10T10:24:42+00:00",
+            "type": "class",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "PEAR/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "include-path": [
+                "."
+            ],
+            "license": [
+                "BSD-2-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Helgi Thormar",
+                    "email": "dufuz@php.net"
+                },
+                {
+                    "name": "Greg Beaver",
+                    "email": "cellog@php.net"
+                }
+            ],
+            "description": "The PEAR Exception base class.",
+            "homepage": "https://github.com/pear/PEAR_Exception",
+            "keywords": [
+                "exception"
+            ],
+            "install-path": "../pear/pear_exception"
         },
-        "suggest": {
-            "ext-mbstring": "For best performance"
+        {
+            "name": "pelago/emogrifier",
+            "version": "v2.1.1",
+            "version_normalized": "2.1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MyIntervals/emogrifier.git",
+                "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8ee7fb5ad772915451ed3415c1992bd3697d4983",
+                "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-libxml": "*",
+                "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0",
+                "symfony/css-selector": "^3.4.0 || ^4.0.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^2.2.0",
+                "phpmd/phpmd": "^2.6.0",
+                "phpunit/phpunit": "^4.8.0",
+                "squizlabs/php_codesniffer": "^3.3.2"
+            },
+            "time": "2018-12-10T10:36:30+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Pelago\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "John Reeve",
+                    "email": "jreeve@pelagodesign.com"
+                },
+                {
+                    "name": "Cameron Brooks"
+                },
+                {
+                    "name": "Jaime Prado"
+                },
+                {
+                    "name": "Oliver Klee",
+                    "email": "github@oliverklee.de"
+                },
+                {
+                    "name": "Zoli Szabó",
+                    "email": "zoli.szabo+github@gmail.com"
+                },
+                {
+                    "name": "Jake Hotson",
+                    "email": "jake@qzdesign.co.uk"
+                }
+            ],
+            "description": "Converts CSS styles into inline style attributes in your HTML code",
+            "homepage": "https://www.myintervals.com/emogrifier.php",
+            "keywords": [
+                "css",
+                "email",
+                "pre-processing"
+            ],
+            "install-path": "../pelago/emogrifier"
         },
-        "time": "2019-08-06T08:03:45+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.12-dev"
-            }
+        {
+            "name": "psr/http-message",
+            "version": "1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-message.git",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2016-08-06T14:39:51+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP messages",
+            "homepage": "https://github.com/php-fig/http-message",
+            "keywords": [
+                "http",
+                "http-message",
+                "psr",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "install-path": "../psr/http-message"
         },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Mbstring\\": ""
-            },
-            "files": [
-                "bootstrap.php"
-            ]
+        {
+            "name": "ralouphie/getallheaders",
+            "version": "3.0.3",
+            "version_normalized": "3.0.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ralouphie/getallheaders.git",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.1",
+                "phpunit/phpunit": "^5 || ^6.5"
+            },
+            "time": "2019-03-08T08:55:37+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "src/getallheaders.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ralph Khattar",
+                    "email": "ralph.khattar@gmail.com"
+                }
+            ],
+            "description": "A polyfill for getallheaders.",
+            "install-path": "../ralouphie/getallheaders"
         },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill for the Mbstring extension",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "mbstring",
-            "polyfill",
-            "portable",
-            "shim"
-        ]
-    },
-    {
-        "name": "true/punycode",
-        "version": "v2.1.1",
-        "version_normalized": "2.1.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/true/php-punycode.git",
-            "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e"
+        {
+            "name": "scssphp/scssphp",
+            "version": "1.3",
+            "version_normalized": "1.3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/scssphp/scssphp.git",
+                "reference": "261cd018025d5790e135a1e5b694d6af186e6bca"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/scssphp/scssphp/zipball/261cd018025d5790e135a1e5b694d6af186e6bca",
+                "reference": "261cd018025d5790e135a1e5b694d6af186e6bca",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-json": "*",
+                "php": ">=5.6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3 || ^9.4",
+                "sass/sass-spec": "2020.08.10",
+                "squizlabs/php_codesniffer": "~3.5",
+                "twbs/bootstrap": "~4.3",
+                "zurb/foundation": "~6.5"
+            },
+            "time": "2020-10-29T11:09:57+00:00",
+            "bin": [
+                "bin/pscss"
+            ],
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "ScssPhp\\ScssPhp\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Anthon Pang",
+                    "email": "apang@softwaredevelopment.ca",
+                    "homepage": "https://github.com/robocoder"
+                },
+                {
+                    "name": "Cédric Morin",
+                    "email": "cedric@yterium.com",
+                    "homepage": "https://github.com/Cerdic"
+                }
+            ],
+            "description": "scssphp is a compiler for SCSS written in PHP.",
+            "homepage": "http://scssphp.github.io/scssphp/",
+            "keywords": [
+                "css",
+                "less",
+                "sass",
+                "scss",
+                "stylesheet"
+            ],
+            "install-path": "../scssphp/scssphp"
         },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/true/php-punycode/zipball/a4d0c11a36dd7f4e7cd7096076cab6d3378a071e",
-            "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e",
-            "shasum": ""
+        {
+            "name": "symfony/css-selector",
+            "version": "v3.4.42",
+            "version_normalized": "3.4.42.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/css-selector.git",
+                "reference": "9ccf6e78077a3fc1596e6c7b5958008965a11518"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/9ccf6e78077a3fc1596e6c7b5958008965a11518",
+                "reference": "9ccf6e78077a3fc1596e6c7b5958008965a11518",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.5.9|>=7.0.8"
+            },
+            "time": "2020-03-16T08:31:04+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.4-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\CssSelector\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Jean-François Simon",
+                    "email": "jeanfrancois.simon@sensiolabs.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony CssSelector Component",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/css-selector"
         },
-        "require": {
-            "php": ">=5.3.0",
-            "symfony/polyfill-mbstring": "^1.3"
+        {
+            "name": "symfony/polyfill-intl-idn",
+            "version": "v1.17.1",
+            "version_normalized": "1.17.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-idn.git",
+                "reference": "a57f8161502549a742a63c09f0a604997bf47027"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a57f8161502549a742a63c09f0a604997bf47027",
+                "reference": "a57f8161502549a742a63c09f0a604997bf47027",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "symfony/polyfill-mbstring": "^1.3",
+                "symfony/polyfill-php72": "^1.10"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "time": "2020-06-06T08:46:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.17-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Idn\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Laurent Bassin",
+                    "email": "laurent@bassin.info"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "idn",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-intl-idn"
         },
-        "require-dev": {
-            "phpunit/phpunit": "~4.7",
-            "squizlabs/php_codesniffer": "~2.0"
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.17.1",
+            "version_normalized": "1.17.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "7110338d81ce1cbc3e273136e4574663627037a7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7",
+                "reference": "7110338d81ce1cbc3e273136e4574663627037a7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
+            "time": "2020-06-06T08:46:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.17-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-mbstring"
         },
-        "time": "2016-11-16T10:37:54+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "TrueBV\\": "src/"
-            }
+        {
+            "name": "symfony/polyfill-php72",
+            "version": "v1.17.0",
+            "version_normalized": "1.17.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php72.git",
+                "reference": "f048e612a3905f34931127360bdd2def19a5e582"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582",
+                "reference": "f048e612a3905f34931127360bdd2def19a5e582",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "time": "2020-05-12T16:47:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.17-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php72\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-php72"
         },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Renan Gonçalves",
-                "email": "renan.saddam@gmail.com"
-            }
-        ],
-        "description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)",
-        "homepage": "https://github.com/true/php-punycode",
-        "keywords": [
-            "idna",
-            "punycode"
-        ]
-    }
-]
+        {
+            "name": "true/punycode",
+            "version": "v2.1.1",
+            "version_normalized": "2.1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/true/php-punycode.git",
+                "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/true/php-punycode/zipball/a4d0c11a36dd7f4e7cd7096076cab6d3378a071e",
+                "reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0",
+                "symfony/polyfill-mbstring": "^1.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.7",
+                "squizlabs/php_codesniffer": "~2.0"
+            },
+            "time": "2016-11-16T10:37:54+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "TrueBV\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Renan Gonçalves",
+                    "email": "renan.saddam@gmail.com"
+                }
+            ],
+            "description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)",
+            "homepage": "https://github.com/true/php-punycode",
+            "keywords": [
+                "idna",
+                "punycode"
+            ],
+            "install-path": "../true/punycode"
+        }
+    ],
+    "dev": false,
+    "dev-package-names": []
+}
diff --git a/wcfsetup/install/files/lib/system/api/composer/installed.php b/wcfsetup/install/files/lib/system/api/composer/installed.php
new file mode 100644 (file)
index 0000000..c5bcebb
--- /dev/null
@@ -0,0 +1,184 @@
+<?php return array (
+  'root' => 
+  array (
+    'pretty_version' => '1.0.0+no-version-set',
+    'version' => '1.0.0.0',
+    'aliases' => 
+    array (
+    ),
+    'reference' => NULL,
+    'name' => '__root__',
+  ),
+  'versions' => 
+  array (
+    '__root__' => 
+    array (
+      'pretty_version' => '1.0.0+no-version-set',
+      'version' => '1.0.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => NULL,
+    ),
+    'chrisjean/php-ico' => 
+    array (
+      'pretty_version' => '1.0.4',
+      'version' => '1.0.4.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6',
+    ),
+    'erusev/parsedown' => 
+    array (
+      'pretty_version' => '1.7.4',
+      'version' => '1.7.4.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'cb17b6477dfff935958ba01325f2e8a2bfa6dab3',
+    ),
+    'ezyang/htmlpurifier' => 
+    array (
+      'pretty_version' => 'v4.12.0',
+      'version' => '4.12.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a617e55bc62a87eec73bd456d146d134ad716f03',
+    ),
+    'guzzlehttp/guzzle' => 
+    array (
+      'pretty_version' => 'dev-6.5-woltlab',
+      'version' => 'dev-6.5-woltlab',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '6298db12d08c3c65c80971bb1b9f6f98e8a43c35',
+    ),
+    'guzzlehttp/promises' => 
+    array (
+      'pretty_version' => 'v1.3.1',
+      'version' => '1.3.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a59da6cf61d80060647ff4d3eb2c03a2bc694646',
+    ),
+    'guzzlehttp/psr7' => 
+    array (
+      'pretty_version' => '1.6.1',
+      'version' => '1.6.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '239400de7a173fe9901b9ac7c06497751f00727a',
+    ),
+    'pear/net_idna2' => 
+    array (
+      'pretty_version' => 'v0.2.0',
+      'version' => '0.2.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '51734eaf8be2df58e8aad5835b9966459b2fb37c',
+    ),
+    'pear/pear_exception' => 
+    array (
+      'pretty_version' => 'v1.0.1',
+      'version' => '1.0.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7',
+    ),
+    'pelago/emogrifier' => 
+    array (
+      'pretty_version' => 'v2.1.1',
+      'version' => '2.1.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '8ee7fb5ad772915451ed3415c1992bd3697d4983',
+    ),
+    'psr/http-message' => 
+    array (
+      'pretty_version' => '1.0.1',
+      'version' => '1.0.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
+    ),
+    'psr/http-message-implementation' => 
+    array (
+      'provided' => 
+      array (
+        0 => '1.0',
+      ),
+    ),
+    'ralouphie/getallheaders' => 
+    array (
+      'pretty_version' => '3.0.3',
+      'version' => '3.0.3.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '120b605dfeb996808c31b6477290a714d356e822',
+    ),
+    'scssphp/scssphp' => 
+    array (
+      'pretty_version' => '1.3',
+      'version' => '1.3.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '261cd018025d5790e135a1e5b694d6af186e6bca',
+    ),
+    'symfony/css-selector' => 
+    array (
+      'pretty_version' => 'v3.4.42',
+      'version' => '3.4.42.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '9ccf6e78077a3fc1596e6c7b5958008965a11518',
+    ),
+    'symfony/polyfill-intl-idn' => 
+    array (
+      'pretty_version' => 'v1.17.1',
+      'version' => '1.17.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a57f8161502549a742a63c09f0a604997bf47027',
+    ),
+    'symfony/polyfill-mbstring' => 
+    array (
+      'pretty_version' => 'v1.17.1',
+      'version' => '1.17.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '7110338d81ce1cbc3e273136e4574663627037a7',
+    ),
+    'symfony/polyfill-php72' => 
+    array (
+      'pretty_version' => 'v1.17.0',
+      'version' => '1.17.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'f048e612a3905f34931127360bdd2def19a5e582',
+    ),
+    'true/punycode' => 
+    array (
+      'pretty_version' => 'v2.1.1',
+      'version' => '2.1.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'a4d0c11a36dd7f4e7cd7096076cab6d3378a071e',
+    ),
+  ),
+);
diff --git a/wcfsetup/install/files/lib/system/api/composer/platform_check.php b/wcfsetup/install/files/lib/system/api/composer/platform_check.php
new file mode 100644 (file)
index 0000000..8b379f4
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 50600)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+        } elseif (!headers_sent()) {
+            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+        }
+    }
+    trigger_error(
+        'Composer detected issues in your platform: ' . implode(' ', $issues),
+        E_USER_ERROR
+    );
+}
index a34b44f0f061bb2e7f1768e2cb12878df5fb0993..1b9d6d5bc2c044a2e1115dda3f001874f5891789 100644 (file)
@@ -17,7 +17,7 @@ class Parsedown
 {
     # ~
 
-    const version = '1.7.3';
+    const version = '1.7.4';
 
     # ~
 
@@ -1489,22 +1489,41 @@ class Parsedown
             }
         }
 
+        $permitRawHtml = false;
+
         if (isset($Element['text']))
+        {
+            $text = $Element['text'];
+        }
+        // very strongly consider an alternative if you're writing an
+        // extension
+        elseif (isset($Element['rawHtml']))
+        {
+            $text = $Element['rawHtml'];
+            $allowRawHtmlInSafeMode = isset($Element['allowRawHtmlInSafeMode']) && $Element['allowRawHtmlInSafeMode'];
+            $permitRawHtml = !$this->safeMode || $allowRawHtmlInSafeMode;
+        }
+
+        if (isset($text))
         {
             $markup .= '>';
 
-            if (!isset($Element['nonNestables'])) 
+            if (!isset($Element['nonNestables']))
             {
                 $Element['nonNestables'] = array();
             }
 
             if (isset($Element['handler']))
             {
-                $markup .= $this->{$Element['handler']}($Element['text'], $Element['nonNestables']);
+                $markup .= $this->{$Element['handler']}($text, $Element['nonNestables']);
+            }
+            elseif (!$permitRawHtml)
+            {
+                $markup .= self::escape($text, true);
             }
             else
             {
-                $markup .= self::escape($Element['text'], true);
+                $markup .= $text;
             }
 
             $markup .= '</'.$Element['name'].'>';
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/.php_cs b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/.php_cs
new file mode 100644 (file)
index 0000000..2dd5036
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+$config = PhpCsFixer\Config::create()
+    ->setRiskyAllowed(true)
+    ->setRules([
+        '@PSR2' => true,
+        'array_syntax' => ['syntax' => 'short'],
+        'declare_strict_types' => false,
+        'concat_space' => ['spacing'=>'one'],
+        'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
+        'ordered_imports' => true,
+        // 'phpdoc_align' => ['align'=>'vertical'],
+        // 'native_function_invocation' => true,
+    ])
+    ->setFinder(
+        PhpCsFixer\Finder::create()
+            ->in(__DIR__.'/src')
+            ->in(__DIR__.'/tests')
+            ->name('*.php')
+    )
+;
+
+return $config;
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/CHANGELOG.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/CHANGELOG.md
new file mode 100644 (file)
index 0000000..464cf1c
--- /dev/null
@@ -0,0 +1,1338 @@
+# Change Log
+
+## 6.5.5 - 2020-06-16
+
+* Unpin version constraint for `symfony/polyfill-intl-idn` [#2678](https://github.com/guzzle/guzzle/pull/2678)
+
+## 6.5.4 - 2020-05-25
+
+* Fix various intl icu issues [#2626](https://github.com/guzzle/guzzle/pull/2626)
+
+## 6.5.3 - 2020-04-18
+
+* Use Symfony intl-idn polyfill [#2550](https://github.com/guzzle/guzzle/pull/2550)
+* Remove use of internal functions [#2548](https://github.com/guzzle/guzzle/pull/2548)
+
+## 6.5.2 - 2019-12-23
+
+* idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489)
+
+## 6.5.1 - 2019-12-21
+
+* Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454)
+* IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424)
+
+## 6.5.0 - 2019-12-07
+
+* Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143)
+* Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287)
+* Fix: Gracefully handle passing `null` to the `header` option. [#2132](https://github.com/guzzle/guzzle/pull/2132)
+* Fix: `RetryMiddleware` did not do exponential delay between retries due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132)
+  Previously, `RetryMiddleware` would sleep for 1 millisecond, then 2 milliseconds, then 4 milliseconds.
+  **After this change, `RetryMiddleware` will sleep for 1 second, then 2 seconds, then 4 seconds.**
+  `Middleware::retry()` accepts a second callback parameter to override the default timeouts if needed.
+* Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348)
+* Deprecated `ClientInterface::VERSION`
+
+## 6.4.1 - 2019-10-23
+
+* No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that 
+* Added `parent::__construct()` to `FileCookieJar` and `SessionCookieJar`
+
+## 6.4.0 - 2019-10-23
+
+* Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108)
+* Fix: Test if response is readable before returning a summary in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081)
+* Fix: Add support for GUZZLE_CURL_SELECT_TIMEOUT environment variable [#2161](https://github.com/guzzle/guzzle/pull/2161)
+* Improvement: Added `GuzzleHttp\Exception\InvalidArgumentException` [#2163](https://github.com/guzzle/guzzle/pull/2163)
+* Improvement: Added `GuzzleHttp\_current_time()` to use `hrtime()` if that function exists. [#2242](https://github.com/guzzle/guzzle/pull/2242)
+* Improvement: Added curl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284)
+* Improvement: Make GuzzleException extend Throwable wherever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273)
+* Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335)
+* Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362)
+
+## 6.3.3 - 2018-04-22
+
+* Fix: Default headers when decode_content is specified
+
+
+## 6.3.2 - 2018-03-26
+
+* Fix: Release process
+
+
+## 6.3.1 - 2018-03-26
+
+* Bug fix: Parsing 0 epoch expiry times in cookies [#2014](https://github.com/guzzle/guzzle/pull/2014)
+* Improvement: Better ConnectException detection [#2012](https://github.com/guzzle/guzzle/pull/2012)
+* Bug fix: Malformed domain that contains a "/" [#1999](https://github.com/guzzle/guzzle/pull/1999)
+* Bug fix: Undefined offset when a cookie has no first key-value pair [#1998](https://github.com/guzzle/guzzle/pull/1998)
+* Improvement: Support PHPUnit 6 [#1953](https://github.com/guzzle/guzzle/pull/1953)
+* Bug fix: Support empty headers [#1915](https://github.com/guzzle/guzzle/pull/1915)
+* Bug fix: Ignore case during header modifications [#1916](https://github.com/guzzle/guzzle/pull/1916)
+
++ Minor code cleanups, documentation fixes and clarifications.
+
+
+## 6.3.0 - 2017-06-22
+
+* Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659)
+* Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621)
+* Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580)
+* Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609)
+* Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641)
+* Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611)
+* Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811)
+* Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642)
+* Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569)
+* Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711)
+* Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745)
+* Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721)
+* Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318)
+* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684)
+* Improvement:         Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827)
+
+
++ Minor code cleanups, documentation fixes and clarifications.
+
+## 6.2.3 - 2017-02-28
+
+* Fix deprecations with guzzle/psr7 version 1.4
+
+## 6.2.2 - 2016-10-08
+
+* Allow to pass nullable Response to delay callable
+* Only add scheme when host is present
+* Fix drain case where content-length is the literal string zero
+* Obfuscate in-URL credentials in exceptions
+
+## 6.2.1 - 2016-07-18
+
+* Address HTTP_PROXY security vulnerability, CVE-2016-5385:
+  https://httpoxy.org/
+* Fixing timeout bug with StreamHandler:
+  https://github.com/guzzle/guzzle/pull/1488
+* Only read up to `Content-Length` in PHP StreamHandler to avoid timeouts when
+  a server does not honor `Connection: close`.
+* Ignore URI fragment when sending requests.
+
+## 6.2.0 - 2016-03-21
+
+* Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`.
+  https://github.com/guzzle/guzzle/pull/1389
+* Bug fix: Fix sleep calculation when waiting for delayed requests.
+  https://github.com/guzzle/guzzle/pull/1324
+* Feature: More flexible history containers.
+  https://github.com/guzzle/guzzle/pull/1373
+* Bug fix: defer sink stream opening in StreamHandler.
+  https://github.com/guzzle/guzzle/pull/1377
+* Bug fix: do not attempt to escape cookie values.
+  https://github.com/guzzle/guzzle/pull/1406
+* Feature: report original content encoding and length on decoded responses.
+  https://github.com/guzzle/guzzle/pull/1409
+* Bug fix: rewind seekable request bodies before dispatching to cURL.
+  https://github.com/guzzle/guzzle/pull/1422
+* Bug fix: provide an empty string to `http_build_query` for HHVM workaround.
+  https://github.com/guzzle/guzzle/pull/1367
+
+## 6.1.1 - 2015-11-22
+
+* Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler
+  https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4
+* Feature: HandlerStack is now more generic.
+  https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e
+* Bug fix: setting verify to false in the StreamHandler now disables peer
+  verification. https://github.com/guzzle/guzzle/issues/1256
+* Feature: Middleware now uses an exception factory, including more error
+  context. https://github.com/guzzle/guzzle/pull/1282
+* Feature: better support for disabled functions.
+  https://github.com/guzzle/guzzle/pull/1287
+* Bug fix: fixed regression where MockHandler was not using `sink`.
+  https://github.com/guzzle/guzzle/pull/1292
+
+## 6.1.0 - 2015-09-08
+
+* Feature: Added the `on_stats` request option to provide access to transfer
+  statistics for requests. https://github.com/guzzle/guzzle/pull/1202
+* Feature: Added the ability to persist session cookies in CookieJars.
+  https://github.com/guzzle/guzzle/pull/1195
+* Feature: Some compatibility updates for Google APP Engine
+  https://github.com/guzzle/guzzle/pull/1216
+* Feature: Added support for NO_PROXY to prevent the use of a proxy based on
+  a simple set of rules. https://github.com/guzzle/guzzle/pull/1197
+* Feature: Cookies can now contain square brackets.
+  https://github.com/guzzle/guzzle/pull/1237
+* Bug fix: Now correctly parsing `=` inside of quotes in Cookies.
+  https://github.com/guzzle/guzzle/pull/1232
+* Bug fix: Cusotm cURL options now correctly override curl options of the
+  same name. https://github.com/guzzle/guzzle/pull/1221
+* Bug fix: Content-Type header is now added when using an explicitly provided
+  multipart body. https://github.com/guzzle/guzzle/pull/1218
+* Bug fix: Now ignoring Set-Cookie headers that have no name.
+* Bug fix: Reason phrase is no longer cast to an int in some cases in the
+  cURL handler. https://github.com/guzzle/guzzle/pull/1187
+* Bug fix: Remove the Authorization header when redirecting if the Host
+  header changes. https://github.com/guzzle/guzzle/pull/1207
+* Bug fix: Cookie path matching fixes
+  https://github.com/guzzle/guzzle/issues/1129
+* Bug fix: Fixing the cURL `body_as_string` setting
+  https://github.com/guzzle/guzzle/pull/1201
+* Bug fix: quotes are no longer stripped when parsing cookies.
+  https://github.com/guzzle/guzzle/issues/1172
+* Bug fix: `form_params` and `query` now always uses the `&` separator.
+  https://github.com/guzzle/guzzle/pull/1163
+* Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set.
+  https://github.com/guzzle/guzzle/pull/1189
+
+## 6.0.2 - 2015-07-04
+
+* Fixed a memory leak in the curl handlers in which references to callbacks
+  were not being removed by `curl_reset`.
+* Cookies are now extracted properly before redirects.
+* Cookies now allow more character ranges.
+* Decoded Content-Encoding responses are now modified to correctly reflect
+  their state if the encoding was automatically removed by a handler. This
+  means that the `Content-Encoding` header may be removed an the
+  `Content-Length` modified to reflect the message size after removing the
+  encoding.
+* Added a more explicit error message when trying to use `form_params` and
+  `multipart` in the same request.
+* Several fixes for HHVM support.
+* Functions are now conditionally required using an additional level of
+  indirection to help with global Composer installations.
+
+## 6.0.1 - 2015-05-27
+
+* Fixed a bug with serializing the `query` request option where the `&`
+  separator was missing.
+* Added a better error message for when `body` is provided as an array. Please
+  use `form_params` or `multipart` instead.
+* Various doc fixes.
+
+## 6.0.0 - 2015-05-26
+
+* See the UPGRADING.md document for more information.
+* Added `multipart` and `form_params` request options.
+* Added `synchronous` request option.
+* Added the `on_headers` request option.
+* Fixed `expect` handling.
+* No longer adding default middlewares in the client ctor. These need to be
+  present on the provided handler in order to work.
+* Requests are no longer initiated when sending async requests with the
+  CurlMultiHandler. This prevents unexpected recursion from requests completing
+  while ticking the cURL loop.
+* Removed the semantics of setting `default` to `true`. This is no longer
+  required now that the cURL loop is not ticked for async requests.
+* Added request and response logging middleware.
+* No longer allowing self signed certificates when using the StreamHandler.
+* Ensuring that `sink` is valid if saving to a file.
+* Request exceptions now include a "handler context" which provides handler
+  specific contextual information.
+* Added `GuzzleHttp\RequestOptions` to allow request options to be applied
+  using constants.
+* `$maxHandles` has been removed from CurlMultiHandler.
+* `MultipartPostBody` is now part of the `guzzlehttp/psr7` package.
+
+## 5.3.0 - 2015-05-19
+
+* Mock now supports `save_to`
+* Marked `AbstractRequestEvent::getTransaction()` as public.
+* Fixed a bug in which multiple headers using different casing would overwrite
+  previous headers in the associative array.
+* Added `Utils::getDefaultHandler()`
+* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated.
+* URL scheme is now always lowercased.
+
+## 6.0.0-beta.1
+
+* Requires PHP >= 5.5
+* Updated to use PSR-7
+  * Requires immutable messages, which basically means an event based system
+    owned by a request instance is no longer possible.
+  * Utilizing the [Guzzle PSR-7 package](https://github.com/guzzle/psr7).
+  * Removed the dependency on `guzzlehttp/streams`. These stream abstractions
+    are available in the `guzzlehttp/psr7` package under the `GuzzleHttp\Psr7`
+    namespace.
+* Added middleware and handler system
+  * Replaced the Guzzle event and subscriber system with a middleware system.
+  * No longer depends on RingPHP, but rather places the HTTP handlers directly
+    in Guzzle, operating on PSR-7 messages.
+  * Retry logic is now encapsulated in `GuzzleHttp\Middleware::retry`, which
+    means the `guzzlehttp/retry-subscriber` is now obsolete.
+  * Mocking responses is now handled using `GuzzleHttp\Handler\MockHandler`.
+* Asynchronous responses
+  * No longer supports the `future` request option to send an async request.
+    Instead, use one of the `*Async` methods of a client (e.g., `requestAsync`,
+    `getAsync`, etc.).
+  * Utilizing `GuzzleHttp\Promise` instead of React's promise library to avoid
+    recursion required by chaining and forwarding react promises. See
+    https://github.com/guzzle/promises
+  * Added `requestAsync` and `sendAsync` to send request asynchronously.
+  * Added magic methods for `getAsync()`, `postAsync()`, etc. to send requests
+    asynchronously.
+* Request options
+  * POST and form updates
+    * Added the `form_fields` and `form_files` request options.
+    * Removed the `GuzzleHttp\Post` namespace.
+    * The `body` request option no longer accepts an array for POST requests.
+  * The `exceptions` request option has been deprecated in favor of the
+    `http_errors` request options.
+  * The `save_to` request option has been deprecated in favor of `sink` request
+    option.
+* Clients no longer accept an array of URI template string and variables for
+  URI variables. You will need to expand URI templates before passing them
+  into a client constructor or request method.
+* Client methods `get()`, `post()`, `put()`, `patch()`, `options()`, etc. are
+  now magic methods that will send synchronous requests.
+* Replaced `Utils.php` with plain functions in `functions.php`.
+* Removed `GuzzleHttp\Collection`.
+* Removed `GuzzleHttp\BatchResults`. Batched pool results are now returned as
+  an array.
+* Removed `GuzzleHttp\Query`. Query string handling is now handled using an
+  associative array passed into the `query` request option. The query string
+  is serialized using PHP's `http_build_query`. If you need more control, you
+  can pass the query string in as a string.
+* `GuzzleHttp\QueryParser` has been replaced with the
+  `GuzzleHttp\Psr7\parse_query`.
+
+## 5.2.0 - 2015-01-27
+
+* Added `AppliesHeadersInterface` to make applying headers to a request based
+  on the body more generic and not specific to `PostBodyInterface`.
+* Reduced the number of stack frames needed to send requests.
+* Nested futures are now resolved in the client rather than the RequestFsm
+* Finishing state transitions is now handled in the RequestFsm rather than the
+  RingBridge.
+* Added a guard in the Pool class to not use recursion for request retries.
+
+## 5.1.0 - 2014-12-19
+
+* Pool class no longer uses recursion when a request is intercepted.
+* The size of a Pool can now be dynamically adjusted using a callback.
+  See https://github.com/guzzle/guzzle/pull/943.
+* Setting a request option to `null` when creating a request with a client will
+  ensure that the option is not set. This allows you to overwrite default
+  request options on a per-request basis.
+  See https://github.com/guzzle/guzzle/pull/937.
+* Added the ability to limit which protocols are allowed for redirects by
+  specifying a `protocols` array in the `allow_redirects` request option.
+* Nested futures due to retries are now resolved when waiting for synchronous
+  responses. See https://github.com/guzzle/guzzle/pull/947.
+* `"0"` is now an allowed URI path. See
+  https://github.com/guzzle/guzzle/pull/935.
+* `Query` no longer typehints on the `$query` argument in the constructor,
+  allowing for strings and arrays.
+* Exceptions thrown in the `end` event are now correctly wrapped with Guzzle
+  specific exceptions if necessary.
+
+## 5.0.3 - 2014-11-03
+
+This change updates query strings so that they are treated as un-encoded values
+by default where the value represents an un-encoded value to send over the
+wire. A Query object then encodes the value before sending over the wire. This
+means that even value query string values (e.g., ":") are url encoded. This
+makes the Query class match PHP's http_build_query function. However, if you
+want to send requests over the wire using valid query string characters that do
+not need to be encoded, then you can provide a string to Url::setQuery() and
+pass true as the second argument to specify that the query string is a raw
+string that should not be parsed or encoded (unless a call to getQuery() is
+subsequently made, forcing the query-string to be converted into a Query
+object).
+
+## 5.0.2 - 2014-10-30
+
+* Added a trailing `\r\n` to multipart/form-data payloads. See
+  https://github.com/guzzle/guzzle/pull/871
+* Added a `GuzzleHttp\Pool::send()` convenience method to match the docs.
+* Status codes are now returned as integers. See
+  https://github.com/guzzle/guzzle/issues/881
+* No longer overwriting an existing `application/x-www-form-urlencoded` header
+  when sending POST requests, allowing for customized headers. See
+  https://github.com/guzzle/guzzle/issues/877
+* Improved path URL serialization.
+
+  * No longer double percent-encoding characters in the path or query string if
+    they are already encoded.
+  * Now properly encoding the supplied path to a URL object, instead of only
+    encoding ' ' and '?'.
+  * Note: This has been changed in 5.0.3 to now encode query string values by
+    default unless the `rawString` argument is provided when setting the query
+    string on a URL: Now allowing many more characters to be present in the
+    query string without being percent encoded. See http://tools.ietf.org/html/rfc3986#appendix-A
+
+## 5.0.1 - 2014-10-16
+
+Bugfix release.
+
+* Fixed an issue where connection errors still returned response object in
+  error and end events event though the response is unusable. This has been
+  corrected so that a response is not returned in the `getResponse` method of
+  these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867
+* Fixed an issue where transfer statistics were not being populated in the
+  RingBridge. https://github.com/guzzle/guzzle/issues/866
+
+## 5.0.0 - 2014-10-12
+
+Adding support for non-blocking responses and some minor API cleanup.
+
+### New Features
+
+* Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`.
+* Added a public API for creating a default HTTP adapter.
+* Updated the redirect plugin to be non-blocking so that redirects are sent
+  concurrently. Other plugins like this can now be updated to be non-blocking.
+* Added a "progress" event so that you can get upload and download progress
+  events.
+* Added `GuzzleHttp\Pool` which implements FutureInterface and transfers
+  requests concurrently using a capped pool size as efficiently as possible.
+* Added `hasListeners()` to EmitterInterface.
+* Removed `GuzzleHttp\ClientInterface::sendAll` and marked
+  `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the
+  recommended way).
+
+### Breaking changes
+
+The breaking changes in this release are relatively minor. The biggest thing to
+look out for is that request and response objects no longer implement fluent
+interfaces.
+
+* Removed the fluent interfaces (i.e., `return $this`) from requests,
+  responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`,
+  `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and
+  `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of
+  why I did this: http://ocramius.github.io/blog/fluent-interfaces-are-evil/.
+  This also makes the Guzzle message interfaces compatible with the current
+  PSR-7 message proposal.
+* Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except
+  for the HTTP request functions from function.php, these functions are now
+  implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode`
+  moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to
+  `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to
+  `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be
+  `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php
+  caused problems for many users: they aren't PSR-4 compliant, require an
+  explicit include, and needed an if-guard to ensure that the functions are not
+  declared multiple times.
+* Rewrote adapter layer.
+    * Removing all classes from `GuzzleHttp\Adapter`, these are now
+      implemented as callables that are stored in `GuzzleHttp\Ring\Client`.
+    * Removed the concept of "parallel adapters". Sending requests serially or
+      concurrently is now handled using a single adapter.
+    * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The
+      Transaction object now exposes the request, response, and client as public
+      properties. The getters and setters have been removed.
+* Removed the "headers" event. This event was only useful for changing the
+  body a response once the headers of the response were known. You can implement
+  a similar behavior in a number of ways. One example might be to use a
+  FnStream that has access to the transaction being sent. For example, when the
+  first byte is written, you could check if the response headers match your
+  expectations, and if so, change the actual stream body that is being
+  written to.
+* Removed the `asArray` parameter from
+  `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header
+  value as an array, then use the newly added `getHeaderAsArray()` method of
+  `MessageInterface`. This change makes the Guzzle interfaces compatible with
+  the PSR-7 interfaces.
+* `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add
+  custom request options using double-dispatch (this was an implementation
+  detail). Instead, you should now provide an associative array to the
+  constructor which is a mapping of the request option name mapping to a
+  function that applies the option value to a request.
+* Removed the concept of "throwImmediately" from exceptions and error events.
+  This control mechanism was used to stop a transfer of concurrent requests
+  from completing. This can now be handled by throwing the exception or by
+  cancelling a pool of requests or each outstanding future request individually.
+* Updated to "GuzzleHttp\Streams" 3.0.
+    * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a
+      `maxLen` parameter. This update makes the Guzzle streams project
+      compatible with the current PSR-7 proposal.
+    * `GuzzleHttp\Stream\Stream::__construct`,
+      `GuzzleHttp\Stream\Stream::factory`, and
+      `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second
+      argument. They now accept an associative array of options, including the
+      "size" key and "metadata" key which can be used to provide custom metadata.
+
+## 4.2.2 - 2014-09-08
+
+* Fixed a memory leak in the CurlAdapter when reusing cURL handles.
+* No longer using `request_fulluri` in stream adapter proxies.
+* Relative redirects are now based on the last response, not the first response.
+
+## 4.2.1 - 2014-08-19
+
+* Ensuring that the StreamAdapter does not always add a Content-Type header
+* Adding automated github releases with a phar and zip
+
+## 4.2.0 - 2014-08-17
+
+* Now merging in default options using a case-insensitive comparison.
+  Closes https://github.com/guzzle/guzzle/issues/767
+* Added the ability to automatically decode `Content-Encoding` response bodies
+  using the `decode_content` request option. This is set to `true` by default
+  to decode the response body if it comes over the wire with a
+  `Content-Encoding`. Set this value to `false` to disable decoding the
+  response content, and pass a string to provide a request `Accept-Encoding`
+  header and turn on automatic response decoding. This feature now allows you
+  to pass an `Accept-Encoding` header in the headers of a request but still
+  disable automatic response decoding.
+  Closes https://github.com/guzzle/guzzle/issues/764
+* Added the ability to throw an exception immediately when transferring
+  requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760
+* Updating guzzlehttp/streams dependency to ~2.1
+* No longer utilizing the now deprecated namespaced methods from the stream
+  package.
+
+## 4.1.8 - 2014-08-14
+
+* Fixed an issue in the CurlFactory that caused setting the `stream=false`
+  request option to throw an exception.
+  See: https://github.com/guzzle/guzzle/issues/769
+* TransactionIterator now calls rewind on the inner iterator.
+  See: https://github.com/guzzle/guzzle/pull/765
+* You can now set the `Content-Type` header to `multipart/form-data`
+  when creating POST requests to force multipart bodies.
+  See https://github.com/guzzle/guzzle/issues/768
+
+## 4.1.7 - 2014-08-07
+
+* Fixed an error in the HistoryPlugin that caused the same request and response
+  to be logged multiple times when an HTTP protocol error occurs.
+* Ensuring that cURL does not add a default Content-Type when no Content-Type
+  has been supplied by the user. This prevents the adapter layer from modifying
+  the request that is sent over the wire after any listeners may have already
+  put the request in a desired state (e.g., signed the request).
+* Throwing an exception when you attempt to send requests that have the
+  "stream" set to true in parallel using the MultiAdapter.
+* Only calling curl_multi_select when there are active cURL handles. This was
+  previously changed and caused performance problems on some systems due to PHP
+  always selecting until the maximum select timeout.
+* Fixed a bug where multipart/form-data POST fields were not correctly
+  aggregated (e.g., values with "&").
+
+## 4.1.6 - 2014-08-03
+
+* Added helper methods to make it easier to represent messages as strings,
+  including getting the start line and getting headers as a string.
+
+## 4.1.5 - 2014-08-02
+
+* Automatically retrying cURL "Connection died, retrying a fresh connect"
+  errors when possible.
+* cURL implementation cleanup
+* Allowing multiple event subscriber listeners to be registered per event by
+  passing an array of arrays of listener configuration.
+
+## 4.1.4 - 2014-07-22
+
+* Fixed a bug that caused multi-part POST requests with more than one field to
+  serialize incorrectly.
+* Paths can now be set to "0"
+* `ResponseInterface::xml` now accepts a `libxml_options` option and added a
+  missing default argument that was required when parsing XML response bodies.
+* A `save_to` stream is now created lazily, which means that files are not
+  created on disk unless a request succeeds.
+
+## 4.1.3 - 2014-07-15
+
+* Various fixes to multipart/form-data POST uploads
+* Wrapping function.php in an if-statement to ensure Guzzle can be used
+  globally and in a Composer install
+* Fixed an issue with generating and merging in events to an event array
+* POST headers are only applied before sending a request to allow you to change
+  the query aggregator used before uploading
+* Added much more robust query string parsing
+* Fixed various parsing and normalization issues with URLs
+* Fixing an issue where multi-valued headers were not being utilized correctly
+  in the StreamAdapter
+
+## 4.1.2 - 2014-06-18
+
+* Added support for sending payloads with GET requests
+
+## 4.1.1 - 2014-06-08
+
+* Fixed an issue related to using custom message factory options in subclasses
+* Fixed an issue with nested form fields in a multi-part POST
+* Fixed an issue with using the `json` request option for POST requests
+* Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar`
+
+## 4.1.0 - 2014-05-27
+
+* Added a `json` request option to easily serialize JSON payloads.
+* Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON.
+* Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`.
+* Added the ability to provide an emitter to a client in the client constructor.
+* Added the ability to persist a cookie session using $_SESSION.
+* Added a trait that can be used to add event listeners to an iterator.
+* Removed request method constants from RequestInterface.
+* Fixed warning when invalid request start-lines are received.
+* Updated MessageFactory to work with custom request option methods.
+* Updated cacert bundle to latest build.
+
+4.0.2 (2014-04-16)
+------------------
+
+* Proxy requests using the StreamAdapter now properly use request_fulluri (#632)
+* Added the ability to set scalars as POST fields (#628)
+
+## 4.0.1 - 2014-04-04
+
+* The HTTP status code of a response is now set as the exception code of
+  RequestException objects.
+* 303 redirects will now correctly switch from POST to GET requests.
+* The default parallel adapter of a client now correctly uses the MultiAdapter.
+* HasDataTrait now initializes the internal data array as an empty array so
+  that the toArray() method always returns an array.
+
+## 4.0.0 - 2014-03-29
+
+* For more information on the 4.0 transition, see:
+  http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/
+* For information on changes and upgrading, see:
+  https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40
+* Added `GuzzleHttp\batch()` as a convenience function for sending requests in
+  parallel without needing to write asynchronous code.
+* Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`.
+  You can now pass a callable or an array of associative arrays where each
+  associative array contains the "fn", "priority", and "once" keys.
+
+## 4.0.0.rc-2 - 2014-03-25
+
+* Removed `getConfig()` and `setConfig()` from clients to avoid confusion
+  around whether things like base_url, message_factory, etc. should be able to
+  be retrieved or modified.
+* Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface
+* functions.php functions were renamed using snake_case to match PHP idioms
+* Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and
+  `GUZZLE_CURL_SELECT_TIMEOUT` environment variables
+* Added the ability to specify custom `sendAll()` event priorities
+* Added the ability to specify custom stream context options to the stream
+  adapter.
+* Added a functions.php function for `get_path()` and `set_path()`
+* CurlAdapter and MultiAdapter now use a callable to generate curl resources
+* MockAdapter now properly reads a body and emits a `headers` event
+* Updated Url class to check if a scheme and host are set before adding ":"
+  and "//". This allows empty Url (e.g., "") to be serialized as "".
+* Parsing invalid XML no longer emits warnings
+* Curl classes now properly throw AdapterExceptions
+* Various performance optimizations
+* Streams are created with the faster `Stream\create()` function
+* Marked deprecation_proxy() as internal
+* Test server is now a collection of static methods on a class
+
+## 4.0.0-rc.1 - 2014-03-15
+
+* See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40
+
+## 3.8.1 - 2014-01-28
+
+* Bug: Always using GET requests when redirecting from a 303 response
+* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in
+  `Guzzle\Http\ClientInterface::setSslVerification()`
+* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL
+* Bug: The body of a request can now be set to `"0"`
+* Sending PHP stream requests no longer forces `HTTP/1.0`
+* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of
+  each sub-exception
+* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than
+  clobbering everything).
+* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators)
+* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`.
+  For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`.
+* Now properly escaping the regular expression delimiter when matching Cookie domains.
+* Network access is now disabled when loading XML documents
+
+## 3.8.0 - 2013-12-05
+
+* Added the ability to define a POST name for a file
+* JSON response parsing now properly walks additionalProperties
+* cURL error code 18 is now retried automatically in the BackoffPlugin
+* Fixed a cURL error when URLs contain fragments
+* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were
+  CurlExceptions
+* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e)
+* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS`
+* Fixed a bug that was encountered when parsing empty header parameters
+* UriTemplate now has a `setRegex()` method to match the docs
+* The `debug` request parameter now checks if it is truthy rather than if it exists
+* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin
+* Added the ability to combine URLs using strict RFC 3986 compliance
+* Command objects can now return the validation errors encountered by the command
+* Various fixes to cache revalidation (#437 and 29797e5)
+* Various fixes to the AsyncPlugin
+* Cleaned up build scripts
+
+## 3.7.4 - 2013-10-02
+
+* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430)
+* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp
+  (see https://github.com/aws/aws-sdk-php/issues/147)
+* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots
+* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420)
+* Updated the bundled cacert.pem (#419)
+* OauthPlugin now supports adding authentication to headers or query string (#425)
+
+## 3.7.3 - 2013-09-08
+
+* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and
+  `CommandTransferException`.
+* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description
+* Schemas are only injected into response models when explicitly configured.
+* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of
+  an EntityBody.
+* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator.
+* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`.
+* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody()
+* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin
+* Bug fix: Visiting XML attributes first before visiting XML children when serializing requests
+* Bug fix: Properly parsing headers that contain commas contained in quotes
+* Bug fix: mimetype guessing based on a filename is now case-insensitive
+
+## 3.7.2 - 2013-08-02
+
+* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander
+  See https://github.com/guzzle/guzzle/issues/371
+* Bug fix: Cookie domains are now matched correctly according to RFC 6265
+  See https://github.com/guzzle/guzzle/issues/377
+* Bug fix: GET parameters are now used when calculating an OAuth signature
+* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted
+* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched
+* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input.
+  See https://github.com/guzzle/guzzle/issues/379
+* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See
+  https://github.com/guzzle/guzzle/pull/380
+* cURL multi cleanup and optimizations
+
+## 3.7.1 - 2013-07-05
+
+* Bug fix: Setting default options on a client now works
+* Bug fix: Setting options on HEAD requests now works. See #352
+* Bug fix: Moving stream factory before send event to before building the stream. See #353
+* Bug fix: Cookies no longer match on IP addresses per RFC 6265
+* Bug fix: Correctly parsing header parameters that are in `<>` and quotes
+* Added `cert` and `ssl_key` as request options
+* `Host` header can now diverge from the host part of a URL if the header is set manually
+* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter
+* OAuth parameters are only added via the plugin if they aren't already set
+* Exceptions are now thrown when a URL cannot be parsed
+* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails
+* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin
+
+## 3.7.0 - 2013-06-10
+
+* See UPGRADING.md for more information on how to upgrade.
+* Requests now support the ability to specify an array of $options when creating a request to more easily modify a
+  request. You can pass a 'request.options' configuration setting to a client to apply default request options to
+  every request created by a client (e.g. default query string variables, headers, curl options, etc.).
+* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
+  See `Guzzle\Http\StaticClient::mount`.
+* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
+      created by a command (e.g. custom headers, query string variables, timeout settings, etc.).
+* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
+  headers of a response
+* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
+  (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`)
+* ServiceBuilders now support storing and retrieving arbitrary data
+* CachePlugin can now purge all resources for a given URI
+* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource
+* CachePlugin now uses the Vary header to determine if a resource is a cache hit
+* `Guzzle\Http\Message\Response` now implements `\Serializable`
+* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters
+* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable
+* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()`
+* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size
+* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message
+* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older
+  Symfony users can still use the old version of Monolog.
+* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`.
+  Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`.
+* Several performance improvements to `Guzzle\Common\Collection`
+* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
+  createRequest, head, delete, put, patch, post, options, prepareRequest
+* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
+* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
+* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
+  `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
+  resource, string, or EntityBody into the $options parameter to specify the download location of the response.
+* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
+  default `array()`
+* Added `Guzzle\Stream\StreamInterface::isRepeatable`
+* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
+  $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
+  $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`.
+* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`.
+* Removed `Guzzle\Http\ClientInterface::expandTemplate()`
+* Removed `Guzzle\Http\ClientInterface::setRequestFactory()`
+* Removed `Guzzle\Http\ClientInterface::getCurlMulti()`
+* Removed `Guzzle\Http\Message\RequestInterface::canCache`
+* Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`
+* Removed `Guzzle\Http\Message\RequestInterface::isRedirect`
+* Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
+* You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting
+  `Guzzle\Common\Version::$emitWarnings` to true.
+* Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use
+      `$request->getResponseBody()->isRepeatable()` instead.
+* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
+  `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
+* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
+  `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
+* Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
+* Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
+* Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
+* Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand.
+  These will work through Guzzle 4.0
+* Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params].
+* Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
+* Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`.
+* Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`.
+* Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
+* Marked `Guzzle\Common\Collection::inject()` as deprecated.
+* Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');`
+* CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
+  CacheStorageInterface. These two objects and interface will be removed in a future version.
+* Always setting X-cache headers on cached responses
+* Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
+* `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
+  $request, Response $response);`
+* `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
+* `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
+* Added `CacheStorageInterface::purge($url)`
+* `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
+  $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
+  CanCacheStrategyInterface $canCache = null)`
+* Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
+
+## 3.6.0 - 2013-05-29
+
+* ServiceDescription now implements ToArrayInterface
+* Added command.hidden_params to blacklist certain headers from being treated as additionalParameters
+* Guzzle can now correctly parse incomplete URLs
+* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
+* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
+* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
+* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
+  HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
+  CacheControl header implementation.
+* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
+* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
+* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
+  Guzzle\Http\Curl\RequestMediator
+* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
+* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
+* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
+* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
+* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
+* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
+* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
+  directly via interfaces
+* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
+  but are a no-op until removed.
+* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
+  `Guzzle\Service\Command\ArrayCommandInterface`.
+* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
+  on a request while the request is still being transferred
+* The ability to case-insensitively search for header values
+* Guzzle\Http\Message\Header::hasExactHeader
+* Guzzle\Http\Message\Header::raw. Use getAll()
+* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
+  instead.
+* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
+* Added the ability to cast Model objects to a string to view debug information.
+
+## 3.5.0 - 2013-05-13
+
+* Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times
+* Bug: Better cleanup of one-time events across the board (when an event is meant to fire once, it will now remove
+  itself from the EventDispatcher)
+* Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values
+* Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too
+* Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a
+  non-existent key
+* Bug: All __call() method arguments are now required (helps with mocking frameworks)
+* Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference
+  to help with refcount based garbage collection of resources created by sending a request
+* Deprecating ZF1 cache and log adapters. These will be removed in the next major version.
+* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it's deprecated). Use the
+  HistoryPlugin for a history.
+* Added a `responseBody` alias for the `response_body` location
+* Refactored internals to no longer rely on Response::getRequest()
+* HistoryPlugin can now be cast to a string
+* HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests
+  and responses that are sent over the wire
+* Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects
+
+## 3.4.3 - 2013-04-30
+
+* Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response
+* Added a check to re-extract the temp cacert bundle from the phar before sending each request
+
+## 3.4.2 - 2013-04-29
+
+* Bug fix: Stream objects now work correctly with "a" and "a+" modes
+* Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present
+* Bug fix: AsyncPlugin no longer forces HEAD requests
+* Bug fix: DateTime timezones are now properly handled when using the service description schema formatter
+* Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails
+* Setting a response on a request will write to the custom request body from the response body if one is specified
+* LogPlugin now writes to php://output when STDERR is undefined
+* Added the ability to set multiple POST files for the same key in a single call
+* application/x-www-form-urlencoded POSTs now use the utf-8 charset by default
+* Added the ability to queue CurlExceptions to the MockPlugin
+* Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send)
+* Configuration loading now allows remote files
+
+## 3.4.1 - 2013-04-16
+
+* Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti
+  handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost.
+* Exceptions are now properly grouped when sending requests in parallel
+* Redirects are now properly aggregated when a multi transaction fails
+* Redirects now set the response on the original object even in the event of a failure
+* Bug fix: Model names are now properly set even when using $refs
+* Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax
+* Added support for oauth_callback in OAuth signatures
+* Added support for oauth_verifier in OAuth signatures
+* Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection
+
+## 3.4.0 - 2013-04-11
+
+* Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289
+* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
+* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
+* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
+* Bug fix: Added `number` type to service descriptions.
+* Bug fix: empty parameters are removed from an OAuth signature
+* Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header
+* Bug fix: Fixed "array to string" error when validating a union of types in a service description
+* Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream
+* Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin.
+* Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs.
+* The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections.
+* Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if
+  the Content-Type can be determined based on the entity body or the path of the request.
+* Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder.
+* Added support for a PSR-3 LogAdapter.
+* Added a `command.after_prepare` event
+* Added `oauth_callback` parameter to the OauthPlugin
+* Added the ability to create a custom stream class when using a stream factory
+* Added a CachingEntityBody decorator
+* Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized.
+* The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar.
+* You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies
+* POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This
+  means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use
+  POST fields or files (the latter is only used when emulating a form POST in the browser).
+* Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest
+
+## 3.3.1 - 2013-03-10
+
+* Added the ability to create PHP streaming responses from HTTP requests
+* Bug fix: Running any filters when parsing response headers with service descriptions
+* Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing
+* Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across
+  response location visitors.
+* Bug fix: Removed the possibility of creating configuration files with circular dependencies
+* RequestFactory::create() now uses the key of a POST file when setting the POST file name
+* Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set
+
+## 3.3.0 - 2013-03-03
+
+* A large number of performance optimizations have been made
+* Bug fix: Added 'wb' as a valid write mode for streams
+* Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned
+* Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()`
+* BC: Removed `Guzzle\Http\Utils` class
+* BC: Setting a service description on a client will no longer modify the client's command factories.
+* BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using
+  the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
+* BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to
+  lowercase
+* Operation parameter objects are now lazy loaded internally
+* Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses
+* Added support for instantiating responseType=class responseClass classes. Classes must implement
+  `Guzzle\Service\Command\ResponseClassInterface`
+* Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These
+  additional properties also support locations and can be used to parse JSON responses where the outermost part of the
+  JSON is an array
+* Added support for nested renaming of JSON models (rename sentAs to name)
+* CachePlugin
+    * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error
+    * Debug headers can now added to cached response in the CachePlugin
+
+## 3.2.0 - 2013-02-14
+
+* CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients.
+* URLs with no path no longer contain a "/" by default
+* Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url.
+* BadResponseException no longer includes the full request and response message
+* Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface
+* Adding getResponseBody() to Guzzle\Http\Message\RequestInterface
+* Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription
+* Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list
+* xmlEncoding can now be customized for the XML declaration of a XML service description operation
+* Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value
+  aggregation and no longer uses callbacks
+* The URL encoding implementation of Guzzle\Http\QueryString can now be customized
+* Bug fix: Filters were not always invoked for array service description parameters
+* Bug fix: Redirects now use a target response body rather than a temporary response body
+* Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded
+* Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives
+
+## 3.1.2 - 2013-01-27
+
+* Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the
+  response body. For example, the XmlVisitor now parses the XML response into an array in the before() method.
+* Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent
+* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444)
+* Fixed a bug where redirect responses were not chained correctly using getPreviousResponse()
+* Setting default headers on a client after setting the user-agent will not erase the user-agent setting
+
+## 3.1.1 - 2013-01-20
+
+* Adding wildcard support to Guzzle\Common\Collection::getPath()
+* Adding alias support to ServiceBuilder configs
+* Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface
+
+## 3.1.0 - 2013-01-12
+
+* BC: CurlException now extends from RequestException rather than BadResponseException
+* BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse()
+* Added getData to ServiceDescriptionInterface
+* Added context array to RequestInterface::setState()
+* Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http
+* Bug: Adding required content-type when JSON request visitor adds JSON to a command
+* Bug: Fixing the serialization of a service description with custom data
+* Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing
+  an array of successful and failed responses
+* Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection
+* Added Guzzle\Http\IoEmittingEntityBody
+* Moved command filtration from validators to location visitors
+* Added `extends` attributes to service description parameters
+* Added getModels to ServiceDescriptionInterface
+
+## 3.0.7 - 2012-12-19
+
+* Fixing phar detection when forcing a cacert to system if null or true
+* Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()`
+* Cleaning up `Guzzle\Common\Collection::inject` method
+* Adding a response_body location to service descriptions
+
+## 3.0.6 - 2012-12-09
+
+* CurlMulti performance improvements
+* Adding setErrorResponses() to Operation
+* composer.json tweaks
+
+## 3.0.5 - 2012-11-18
+
+* Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin
+* Bug: Response body can now be a string containing "0"
+* Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert
+* Bug: QueryString::fromString now properly parses query string parameters that contain equal signs
+* Added support for XML attributes in service description responses
+* DefaultRequestSerializer now supports array URI parameter values for URI template expansion
+* Added better mimetype guessing to requests and post files
+
+## 3.0.4 - 2012-11-11
+
+* Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value
+* Bug: Cookies can now be added that have a name, domain, or value set to "0"
+* Bug: Using the system cacert bundle when using the Phar
+* Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures
+* Enhanced cookie jar de-duplication
+* Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added
+* Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies
+* Added the ability to create any sort of hash for a stream rather than just an MD5 hash
+
+## 3.0.3 - 2012-11-04
+
+* Implementing redirects in PHP rather than cURL
+* Added PECL URI template extension and using as default parser if available
+* Bug: Fixed Content-Length parsing of Response factory
+* Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams.
+* Adding ToArrayInterface throughout library
+* Fixing OauthPlugin to create unique nonce values per request
+
+## 3.0.2 - 2012-10-25
+
+* Magic methods are enabled by default on clients
+* Magic methods return the result of a command
+* Service clients no longer require a base_url option in the factory
+* Bug: Fixed an issue with URI templates where null template variables were being expanded
+
+## 3.0.1 - 2012-10-22
+
+* Models can now be used like regular collection objects by calling filter, map, etc.
+* Models no longer require a Parameter structure or initial data in the constructor
+* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
+
+## 3.0.0 - 2012-10-15
+
+* Rewrote service description format to be based on Swagger
+    * Now based on JSON schema
+    * Added nested input structures and nested response models
+    * Support for JSON and XML input and output models
+    * Renamed `commands` to `operations`
+    * Removed dot class notation
+    * Removed custom types
+* Broke the project into smaller top-level namespaces to be more component friendly
+* Removed support for XML configs and descriptions. Use arrays or JSON files.
+* Removed the Validation component and Inspector
+* Moved all cookie code to Guzzle\Plugin\Cookie
+* Magic methods on a Guzzle\Service\Client now return the command un-executed.
+* Calling getResult() or getResponse() on a command will lazily execute the command if needed.
+* Now shipping with cURL's CA certs and using it by default
+* Added previousResponse() method to response objects
+* No longer sending Accept and Accept-Encoding headers on every request
+* Only sending an Expect header by default when a payload is greater than 1MB
+* Added/moved client options:
+    * curl.blacklist to curl.option.blacklist
+    * Added ssl.certificate_authority
+* Added a Guzzle\Iterator component
+* Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin
+* Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin)
+* Added a more robust caching plugin
+* Added setBody to response objects
+* Updating LogPlugin to use a more flexible MessageFormatter
+* Added a completely revamped build process
+* Cleaning up Collection class and removing default values from the get method
+* Fixed ZF2 cache adapters
+
+## 2.8.8 - 2012-10-15
+
+* Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did
+
+## 2.8.7 - 2012-09-30
+
+* Bug: Fixed config file aliases for JSON includes
+* Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests
+* Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload
+* Bug: Hardening request and response parsing to account for missing parts
+* Bug: Fixed PEAR packaging
+* Bug: Fixed Request::getInfo
+* Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail
+* Adding the ability for the namespace Iterator factory to look in multiple directories
+* Added more getters/setters/removers from service descriptions
+* Added the ability to remove POST fields from OAuth signatures
+* OAuth plugin now supports 2-legged OAuth
+
+## 2.8.6 - 2012-09-05
+
+* Added the ability to modify and build service descriptions
+* Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command
+* Added a `json` parameter location
+* Now allowing dot notation for classes in the CacheAdapterFactory
+* Using the union of two arrays rather than an array_merge when extending service builder services and service params
+* Ensuring that a service is a string before doing strpos() checks on it when substituting services for references
+  in service builder config files.
+* Services defined in two different config files that include one another will by default replace the previously
+  defined service, but you can now create services that extend themselves and merge their settings over the previous
+* The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like
+  '_default' with a default JSON configuration file.
+
+## 2.8.5 - 2012-08-29
+
+* Bug: Suppressed empty arrays from URI templates
+* Bug: Added the missing $options argument from ServiceDescription::factory to enable caching
+* Added support for HTTP responses that do not contain a reason phrase in the start-line
+* AbstractCommand commands are now invokable
+* Added a way to get the data used when signing an Oauth request before a request is sent
+
+## 2.8.4 - 2012-08-15
+
+* Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin
+* Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable.
+* Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream
+* Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream
+* Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5())
+* Added additional response status codes
+* Removed SSL information from the default User-Agent header
+* DELETE requests can now send an entity body
+* Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries
+* Added the ability of the MockPlugin to consume mocked request bodies
+* LogPlugin now exposes request and response objects in the extras array
+
+## 2.8.3 - 2012-07-30
+
+* Bug: Fixed a case where empty POST requests were sent as GET requests
+* Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body
+* Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new
+* Added multiple inheritance to service description commands
+* Added an ApiCommandInterface and added `getParamNames()` and `hasParam()`
+* Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything
+* Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles
+
+## 2.8.2 - 2012-07-24
+
+* Bug: Query string values set to 0 are no longer dropped from the query string
+* Bug: A Collection object is no longer created each time a call is made to `Guzzle\Service\Command\AbstractCommand::getRequestHeaders()`
+* Bug: `+` is now treated as an encoded space when parsing query strings
+* QueryString and Collection performance improvements
+* Allowing dot notation for class paths in filters attribute of a service descriptions
+
+## 2.8.1 - 2012-07-16
+
+* Loosening Event Dispatcher dependency
+* POST redirects can now be customized using CURLOPT_POSTREDIR
+
+## 2.8.0 - 2012-07-15
+
+* BC: Guzzle\Http\Query
+    * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl)
+    * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding()
+    * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool)
+    * Changed the aggregation functions of QueryString to be static methods
+    * Can now use fromString() with querystrings that have a leading ?
+* cURL configuration values can be specified in service descriptions using `curl.` prefixed parameters
+* Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body
+* Cookies are no longer URL decoded by default
+* Bug: URI template variables set to null are no longer expanded
+
+## 2.7.2 - 2012-07-02
+
+* BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser.
+* BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty()
+* CachePlugin now allows for a custom request parameter function to check if a request can be cached
+* Bug fix: CachePlugin now only caches GET and HEAD requests by default
+* Bug fix: Using header glue when transferring headers over the wire
+* Allowing deeply nested arrays for composite variables in URI templates
+* Batch divisors can now return iterators or arrays
+
+## 2.7.1 - 2012-06-26
+
+* Minor patch to update version number in UA string
+* Updating build process
+
+## 2.7.0 - 2012-06-25
+
+* BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes.
+* BC: Removed magic setX methods from commands
+* BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method
+* Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable.
+* Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity)
+* Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace
+* Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin
+* Added the ability to set POST fields and files in a service description
+* Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method
+* Adding a command.before_prepare event to clients
+* Added BatchClosureTransfer and BatchClosureDivisor
+* BatchTransferException now includes references to the batch divisor and transfer strategies
+* Fixed some tests so that they pass more reliably
+* Added Guzzle\Common\Log\ArrayLogAdapter
+
+## 2.6.6 - 2012-06-10
+
+* BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin
+* BC: Removing Guzzle\Service\Command\CommandSet
+* Adding generic batching system (replaces the batch queue plugin and command set)
+* Updating ZF cache and log adapters and now using ZF's composer repository
+* Bug: Setting the name of each ApiParam when creating through an ApiCommand
+* Adding result_type, result_doc, deprecated, and doc_url to service descriptions
+* Bug: Changed the default cookie header casing back to 'Cookie'
+
+## 2.6.5 - 2012-06-03
+
+* BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource()
+* BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from
+* BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data
+* BC: Renaming methods in the CookieJarInterface
+* Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations
+* Making the default glue for HTTP headers ';' instead of ','
+* Adding a removeValue to Guzzle\Http\Message\Header
+* Adding getCookies() to request interface.
+* Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber()
+
+## 2.6.4 - 2012-05-30
+
+* BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class.
+* BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand
+* Bug: Fixing magic method command calls on clients
+* Bug: Email constraint only validates strings
+* Bug: Aggregate POST fields when POST files are present in curl handle
+* Bug: Fixing default User-Agent header
+* Bug: Only appending or prepending parameters in commands if they are specified
+* Bug: Not requiring response reason phrases or status codes to match a predefined list of codes
+* Allowing the use of dot notation for class namespaces when using instance_of constraint
+* Added any_match validation constraint
+* Added an AsyncPlugin
+* Passing request object to the calculateWait method of the ExponentialBackoffPlugin
+* Allowing the result of a command object to be changed
+* Parsing location and type sub values when instantiating a service description rather than over and over at runtime
+
+## 2.6.3 - 2012-05-23
+
+* [BC] Guzzle\Common\FromConfigInterface no longer requires any config options.
+* [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields.
+* You can now use an array of data when creating PUT request bodies in the request factory.
+* Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable.
+* [Http] Adding support for Content-Type in multipart POST uploads per upload
+* [Http] Added support for uploading multiple files using the same name (foo[0], foo[1])
+* Adding more POST data operations for easier manipulation of POST data.
+* You can now set empty POST fields.
+* The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files.
+* Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate.
+* CS updates
+
+## 2.6.2 - 2012-05-19
+
+* [Http] Better handling of nested scope requests in CurlMulti.  Requests are now always prepares in the send() method rather than the addRequest() method.
+
+## 2.6.1 - 2012-05-19
+
+* [BC] Removing 'path' support in service descriptions.  Use 'uri'.
+* [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache.
+* [BC] Removing Guzzle\Common\NullObject.  Use https://github.com/mtdowling/NullObject if you need it.
+* [BC] Removing Guzzle\Common\XmlElement.
+* All commands, both dynamic and concrete, have ApiCommand objects.
+* Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits.
+* Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored.
+* Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible.
+
+## 2.6.0 - 2012-05-15
+
+* [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder
+* [BC] Executing a Command returns the result of the command rather than the command
+* [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed.
+* [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args.
+* [BC] Moving ResourceIterator* to Guzzle\Service\Resource
+* [BC] Completely refactored ResourceIterators to iterate over a cloned command object
+* [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate
+* [BC] Guzzle\Guzzle is now deprecated
+* Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject
+* Adding Guzzle\Version class to give version information about Guzzle
+* Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate()
+* Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data
+* ServiceDescription and ServiceBuilder are now cacheable using similar configs
+* Changing the format of XML and JSON service builder configs.  Backwards compatible.
+* Cleaned up Cookie parsing
+* Trimming the default Guzzle User-Agent header
+* Adding a setOnComplete() method to Commands that is called when a command completes
+* Keeping track of requests that were mocked in the MockPlugin
+* Fixed a caching bug in the CacheAdapterFactory
+* Inspector objects can be injected into a Command object
+* Refactoring a lot of code and tests to be case insensitive when dealing with headers
+* Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL
+* Adding the ability to set global option overrides to service builder configs
+* Adding the ability to include other service builder config files from within XML and JSON files
+* Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method.
+
+## 2.5.0 - 2012-05-08
+
+* Major performance improvements
+* [BC] Simplifying Guzzle\Common\Collection.  Please check to see if you are using features that are now deprecated.
+* [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component.
+* [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates.  Use "{}"
+* Added the ability to passed parameters to all requests created by a client
+* Added callback functionality to the ExponentialBackoffPlugin
+* Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies.
+* Rewinding request stream bodies when retrying requests
+* Exception is thrown when JSON response body cannot be decoded
+* Added configurable magic method calls to clients and commands.  This is off by default.
+* Fixed a defect that added a hash to every parsed URL part
+* Fixed duplicate none generation for OauthPlugin.
+* Emitting an event each time a client is generated by a ServiceBuilder
+* Using an ApiParams object instead of a Collection for parameters of an ApiCommand
+* cache.* request parameters should be renamed to params.cache.*
+* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle.
+* Added the ability to disable type validation of service descriptions
+* ServiceDescriptions and ServiceBuilders are now Serializable
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/Dockerfile b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/Dockerfile
new file mode 100644 (file)
index 0000000..f6a0952
--- /dev/null
@@ -0,0 +1,18 @@
+FROM composer:latest as setup
+
+RUN mkdir /guzzle
+
+WORKDIR /guzzle
+
+RUN set -xe \
+    && composer init --name=guzzlehttp/test --description="Simple project for testing Guzzle scripts" --author="Márk Sági-Kazár <mark.sagikazar@gmail.com>" --no-interaction \
+    && composer require guzzlehttp/guzzle
+
+
+FROM php:7.3
+
+RUN mkdir /guzzle
+
+WORKDIR /guzzle
+
+COPY --from=setup /guzzle /guzzle
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/LICENSE b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/LICENSE
new file mode 100644 (file)
index 0000000..50a177b
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/README.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/README.md
new file mode 100644 (file)
index 0000000..5fdb6c5
--- /dev/null
@@ -0,0 +1,90 @@
+Guzzle, PHP HTTP client
+=======================
+
+[![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases)
+[![Build Status](https://img.shields.io/travis/guzzle/guzzle.svg?style=flat-square)](https://travis-ci.org/guzzle/guzzle)
+[![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle)
+
+Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and
+trivial to integrate with web services.
+
+- Simple interface for building query strings, POST requests, streaming large
+  uploads, streaming large downloads, using HTTP cookies, uploading JSON data,
+  etc...
+- Can send both synchronous and asynchronous requests using the same interface.
+- Uses PSR-7 interfaces for requests, responses, and streams. This allows you
+  to utilize other PSR-7 compatible libraries with Guzzle.
+- Abstracts away the underlying HTTP transport, allowing you to write
+  environment and transport agnostic code; i.e., no hard dependency on cURL,
+  PHP streams, sockets, or non-blocking event loops.
+- Middleware system allows you to augment and compose client behavior.
+
+```php
+$client = new \GuzzleHttp\Client();
+$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
+
+echo $response->getStatusCode(); # 200
+echo $response->getHeaderLine('content-type'); # 'application/json; charset=utf8'
+echo $response->getBody(); # '{"id": 1420053, "name": "guzzle", ...}'
+
+# Send an asynchronous request.
+$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
+$promise = $client->sendAsync($request)->then(function ($response) {
+    echo 'I completed! ' . $response->getBody();
+});
+
+$promise->wait();
+```
+
+## Help and docs
+
+- [Documentation](http://guzzlephp.org/)
+- [Stack Overflow](http://stackoverflow.com/questions/tagged/guzzle)
+- [Gitter](https://gitter.im/guzzle/guzzle)
+
+
+## Installing Guzzle
+
+The recommended way to install Guzzle is through
+[Composer](http://getcomposer.org).
+
+```bash
+# Install Composer
+curl -sS https://getcomposer.org/installer | php
+```
+
+Next, run the Composer command to install the latest stable version of Guzzle:
+
+```bash
+composer require guzzlehttp/guzzle
+```
+
+After installing, you need to require Composer's autoloader:
+
+```php
+require 'vendor/autoload.php';
+```
+
+You can then later update Guzzle using composer:
+
+ ```bash
+composer update
+ ```
+
+
+## Version Guidance
+
+| Version | Status     | Packagist           | Namespace    | Repo                | Docs                | PSR-7 | PHP Version |
+|---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------|
+| 3.x     | EOL        | `guzzle/guzzle`     | `Guzzle`     | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No    | >= 5.3.3    |
+| 4.x     | EOL        | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A                 | No    | >= 5.4      |
+| 5.x     | EOL        | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No    | >= 5.4      |
+| 6.x     | Latest     | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes   | >= 5.5      |
+
+[guzzle-3-repo]: https://github.com/guzzle/guzzle3
+[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x
+[guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3
+[guzzle-6-repo]: https://github.com/guzzle/guzzle
+[guzzle-3-docs]: http://guzzle3.readthedocs.org
+[guzzle-5-docs]: http://guzzle.readthedocs.org/en/5.3/
+[guzzle-6-docs]: http://guzzle.readthedocs.org/en/latest/
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/UPGRADING.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/UPGRADING.md
new file mode 100644 (file)
index 0000000..91d1dcc
--- /dev/null
@@ -0,0 +1,1203 @@
+Guzzle Upgrade Guide
+====================
+
+5.0 to 6.0
+----------
+
+Guzzle now uses [PSR-7](http://www.php-fig.org/psr/psr-7/) for HTTP messages.
+Due to the fact that these messages are immutable, this prompted a refactoring
+of Guzzle to use a middleware based system rather than an event system. Any
+HTTP message interaction (e.g., `GuzzleHttp\Message\Request`) need to be
+updated to work with the new immutable PSR-7 request and response objects. Any
+event listeners or subscribers need to be updated to become middleware
+functions that wrap handlers (or are injected into a
+`GuzzleHttp\HandlerStack`).
+
+- Removed `GuzzleHttp\BatchResults`
+- Removed `GuzzleHttp\Collection`
+- Removed `GuzzleHttp\HasDataTrait`
+- Removed `GuzzleHttp\ToArrayInterface`
+- The `guzzlehttp/streams` dependency has been removed. Stream functionality
+  is now present in the `GuzzleHttp\Psr7` namespace provided by the
+  `guzzlehttp/psr7` package.
+- Guzzle no longer uses ReactPHP promises and now uses the
+  `guzzlehttp/promises` library. We use a custom promise library for three
+  significant reasons:
+  1. React promises (at the time of writing this) are recursive. Promise
+     chaining and promise resolution will eventually blow the stack. Guzzle
+     promises are not recursive as they use a sort of trampolining technique.
+     Note: there has been movement in the React project to modify promises to
+     no longer utilize recursion.
+  2. Guzzle needs to have the ability to synchronously block on a promise to
+     wait for a result. Guzzle promises allows this functionality (and does
+     not require the use of recursion).
+  3. Because we need to be able to wait on a result, doing so using React
+     promises requires wrapping react promises with RingPHP futures. This
+     overhead is no longer needed, reducing stack sizes, reducing complexity,
+     and improving performance.
+- `GuzzleHttp\Mimetypes` has been moved to a function in
+  `GuzzleHttp\Psr7\mimetype_from_extension` and
+  `GuzzleHttp\Psr7\mimetype_from_filename`.
+- `GuzzleHttp\Query` and `GuzzleHttp\QueryParser` have been removed. Query
+  strings must now be passed into request objects as strings, or provided to
+  the `query` request option when creating requests with clients. The `query`
+  option uses PHP's `http_build_query` to convert an array to a string. If you
+  need a different serialization technique, you will need to pass the query
+  string in as a string. There are a couple helper functions that will make
+  working with query strings easier: `GuzzleHttp\Psr7\parse_query` and
+  `GuzzleHttp\Psr7\build_query`.
+- Guzzle no longer has a dependency on RingPHP. Due to the use of a middleware
+  system based on PSR-7, using RingPHP and it's middleware system as well adds
+  more complexity than the benefits it provides. All HTTP handlers that were
+  present in RingPHP have been modified to work directly with PSR-7 messages
+  and placed in the `GuzzleHttp\Handler` namespace. This significantly reduces
+  complexity in Guzzle, removes a dependency, and improves performance. RingPHP
+  will be maintained for Guzzle 5 support, but will no longer be a part of
+  Guzzle 6.
+- As Guzzle now uses a middleware based systems the event system and RingPHP
+  integration has been removed. Note: while the event system has been removed,
+  it is possible to add your own type of event system that is powered by the
+  middleware system.
+  - Removed the `Event` namespace.
+  - Removed the `Subscriber` namespace.
+  - Removed `Transaction` class
+  - Removed `RequestFsm`
+  - Removed `RingBridge`
+  - `GuzzleHttp\Subscriber\Cookie` is now provided by
+    `GuzzleHttp\Middleware::cookies`
+  - `GuzzleHttp\Subscriber\HttpError` is now provided by
+    `GuzzleHttp\Middleware::httpError`
+  - `GuzzleHttp\Subscriber\History` is now provided by
+    `GuzzleHttp\Middleware::history`
+  - `GuzzleHttp\Subscriber\Mock` is now provided by
+    `GuzzleHttp\Handler\MockHandler`
+  - `GuzzleHttp\Subscriber\Prepare` is now provided by
+    `GuzzleHttp\PrepareBodyMiddleware`
+  - `GuzzleHttp\Subscriber\Redirect` is now provided by
+    `GuzzleHttp\RedirectMiddleware`
+- Guzzle now uses `Psr\Http\Message\UriInterface` (implements in
+  `GuzzleHttp\Psr7\Uri`) for URI support. `GuzzleHttp\Url` is now gone.
+- Static functions in `GuzzleHttp\Utils` have been moved to namespaced
+  functions under the `GuzzleHttp` namespace. This requires either a Composer
+  based autoloader or you to include functions.php.
+- `GuzzleHttp\ClientInterface::getDefaultOption` has been renamed to
+  `GuzzleHttp\ClientInterface::getConfig`.
+- `GuzzleHttp\ClientInterface::setDefaultOption` has been removed.
+- The `json` and `xml` methods of response objects has been removed. With the
+  migration to strictly adhering to PSR-7 as the interface for Guzzle messages,
+  adding methods to message interfaces would actually require Guzzle messages
+  to extend from PSR-7 messages rather then work with them directly.
+
+## Migrating to middleware
+
+The change to PSR-7 unfortunately required significant refactoring to Guzzle
+due to the fact that PSR-7 messages are immutable. Guzzle 5 relied on an event
+system from plugins. The event system relied on mutability of HTTP messages and
+side effects in order to work. With immutable messages, you have to change your
+workflow to become more about either returning a value (e.g., functional
+middlewares) or setting a value on an object. Guzzle v6 has chosen the
+functional middleware approach.
+
+Instead of using the event system to listen for things like the `before` event,
+you now create a stack based middleware function that intercepts a request on
+the way in and the promise of the response on the way out. This is a much
+simpler and more predictable approach than the event system and works nicely
+with PSR-7 middleware. Due to the use of promises, the middleware system is
+also asynchronous.
+
+v5:
+
+```php
+use GuzzleHttp\Event\BeforeEvent;
+$client = new GuzzleHttp\Client();
+// Get the emitter and listen to the before event.
+$client->getEmitter()->on('before', function (BeforeEvent $e) {
+    // Guzzle v5 events relied on mutation
+    $e->getRequest()->setHeader('X-Foo', 'Bar');
+});
+```
+
+v6:
+
+In v6, you can modify the request before it is sent using the `mapRequest`
+middleware. The idiomatic way in v6 to modify the request/response lifecycle is
+to setup a handler middleware stack up front and inject the handler into a
+client.
+
+```php
+use GuzzleHttp\Middleware;
+// Create a handler stack that has all of the default middlewares attached
+$handler = GuzzleHttp\HandlerStack::create();
+// Push the handler onto the handler stack
+$handler->push(Middleware::mapRequest(function (RequestInterface $request) {
+    // Notice that we have to return a request object
+    return $request->withHeader('X-Foo', 'Bar');
+}));
+// Inject the handler into the client
+$client = new GuzzleHttp\Client(['handler' => $handler]);
+```
+
+## POST Requests
+
+This version added the [`form_params`](http://guzzle.readthedocs.org/en/latest/request-options.html#form_params)
+and `multipart` request options. `form_params` is an associative array of
+strings or array of strings and is used to serialize an
+`application/x-www-form-urlencoded` POST request. The
+[`multipart`](http://guzzle.readthedocs.org/en/latest/request-options.html#multipart)
+option is now used to send a multipart/form-data POST request.
+
+`GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add
+POST files to a multipart/form-data request.
+
+The `body` option no longer accepts an array to send POST requests. Please use
+`multipart` or `form_params` instead.
+
+The `base_url` option has been renamed to `base_uri`.
+
+4.x to 5.0
+----------
+
+## Rewritten Adapter Layer
+
+Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send
+HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor
+is still supported, but it has now been renamed to `handler`. Instead of
+passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP
+`callable` that follows the RingPHP specification.
+
+## Removed Fluent Interfaces
+
+[Fluent interfaces were removed](http://ocramius.github.io/blog/fluent-interfaces-are-evil)
+from the following classes:
+
+- `GuzzleHttp\Collection`
+- `GuzzleHttp\Url`
+- `GuzzleHttp\Query`
+- `GuzzleHttp\Post\PostBody`
+- `GuzzleHttp\Cookie\SetCookie`
+
+## Removed functions.php
+
+Removed "functions.php", so that Guzzle is truly PSR-4 compliant. The following
+functions can be used as replacements.
+
+- `GuzzleHttp\json_decode` -> `GuzzleHttp\Utils::jsonDecode`
+- `GuzzleHttp\get_path` -> `GuzzleHttp\Utils::getPath`
+- `GuzzleHttp\Utils::setPath` -> `GuzzleHttp\set_path`
+- `GuzzleHttp\Pool::batch` -> `GuzzleHttp\batch`. This function is, however,
+  deprecated in favor of using `GuzzleHttp\Pool::batch()`.
+
+The "procedural" global client has been removed with no replacement (e.g.,
+`GuzzleHttp\get()`, `GuzzleHttp\post()`, etc.). Use a `GuzzleHttp\Client`
+object as a replacement.
+
+## `throwImmediately` has been removed
+
+The concept of "throwImmediately" has been removed from exceptions and error
+events. This control mechanism was used to stop a transfer of concurrent
+requests from completing. This can now be handled by throwing the exception or
+by cancelling a pool of requests or each outstanding future request
+individually.
+
+## headers event has been removed
+
+Removed the "headers" event. This event was only useful for changing the
+body a response once the headers of the response were known. You can implement
+a similar behavior in a number of ways. One example might be to use a
+FnStream that has access to the transaction being sent. For example, when the
+first byte is written, you could check if the response headers match your
+expectations, and if so, change the actual stream body that is being
+written to.
+
+## Updates to HTTP Messages
+
+Removed the `asArray` parameter from
+`GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header
+value as an array, then use the newly added `getHeaderAsArray()` method of
+`MessageInterface`. This change makes the Guzzle interfaces compatible with
+the PSR-7 interfaces.
+
+3.x to 4.0
+----------
+
+## Overarching changes:
+
+- Now requires PHP 5.4 or greater.
+- No longer requires cURL to send requests.
+- Guzzle no longer wraps every exception it throws. Only exceptions that are
+  recoverable are now wrapped by Guzzle.
+- Various namespaces have been removed or renamed.
+- No longer requiring the Symfony EventDispatcher. A custom event dispatcher
+  based on the Symfony EventDispatcher is
+  now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant
+  speed and functionality improvements).
+
+Changes per Guzzle 3.x namespace are described below.
+
+## Batch
+
+The `Guzzle\Batch` namespace has been removed. This is best left to
+third-parties to implement on top of Guzzle's core HTTP library.
+
+## Cache
+
+The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement
+has been implemented yet, but hoping to utilize a PSR cache interface).
+
+## Common
+
+- Removed all of the wrapped exceptions. It's better to use the standard PHP
+  library for unrecoverable exceptions.
+- `FromConfigInterface` has been removed.
+- `Guzzle\Common\Version` has been removed. The VERSION constant can be found
+  at `GuzzleHttp\ClientInterface::VERSION`.
+
+### Collection
+
+- `getAll` has been removed. Use `toArray` to convert a collection to an array.
+- `inject` has been removed.
+- `keySearch` has been removed.
+- `getPath` no longer supports wildcard expressions. Use something better like
+  JMESPath for this.
+- `setPath` now supports appending to an existing array via the `[]` notation.
+
+### Events
+
+Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses
+`GuzzleHttp\Event\Emitter`.
+
+- `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by
+  `GuzzleHttp\Event\EmitterInterface`.
+- `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by
+  `GuzzleHttp\Event\Emitter`.
+- `Symfony\Component\EventDispatcher\Event` is replaced by
+  `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in
+  `GuzzleHttp\Event\EventInterface`.
+- `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and
+  `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the
+  event emitter of a request, client, etc. now uses the `getEmitter` method
+  rather than the `getDispatcher` method.
+
+#### Emitter
+
+- Use the `once()` method to add a listener that automatically removes itself
+  the first time it is invoked.
+- Use the `listeners()` method to retrieve a list of event listeners rather than
+  the `getListeners()` method.
+- Use `emit()` instead of `dispatch()` to emit an event from an emitter.
+- Use `attach()` instead of `addSubscriber()` and `detach()` instead of
+  `removeSubscriber()`.
+
+```php
+$mock = new Mock();
+// 3.x
+$request->getEventDispatcher()->addSubscriber($mock);
+$request->getEventDispatcher()->removeSubscriber($mock);
+// 4.x
+$request->getEmitter()->attach($mock);
+$request->getEmitter()->detach($mock);
+```
+
+Use the `on()` method to add a listener rather than the `addListener()` method.
+
+```php
+// 3.x
+$request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } );
+// 4.x
+$request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } );
+```
+
+## Http
+
+### General changes
+
+- The cacert.pem certificate has been moved to `src/cacert.pem`.
+- Added the concept of adapters that are used to transfer requests over the
+  wire.
+- Simplified the event system.
+- Sending requests in parallel is still possible, but batching is no longer a
+  concept of the HTTP layer. Instead, you must use the `complete` and `error`
+  events to asynchronously manage parallel request transfers.
+- `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`.
+- `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`.
+- QueryAggregators have been rewritten so that they are simply callable
+  functions.
+- `GuzzleHttp\StaticClient` has been removed. Use the functions provided in
+  `functions.php` for an easy to use static client instance.
+- Exceptions in `GuzzleHttp\Exception` have been updated to all extend from
+  `GuzzleHttp\Exception\TransferException`.
+
+### Client
+
+Calling methods like `get()`, `post()`, `head()`, etc. no longer create and
+return a request, but rather creates a request, sends the request, and returns
+the response.
+
+```php
+// 3.0
+$request = $client->get('/');
+$response = $request->send();
+
+// 4.0
+$response = $client->get('/');
+
+// or, to mirror the previous behavior
+$request = $client->createRequest('GET', '/');
+$response = $client->send($request);
+```
+
+`GuzzleHttp\ClientInterface` has changed.
+
+- The `send` method no longer accepts more than one request. Use `sendAll` to
+  send multiple requests in parallel.
+- `setUserAgent()` has been removed. Use a default request option instead. You
+  could, for example, do something like:
+  `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`.
+- `setSslVerification()` has been removed. Use default request options instead,
+  like `$client->setConfig('defaults/verify', true)`.
+
+`GuzzleHttp\Client` has changed.
+
+- The constructor now accepts only an associative array. You can include a
+  `base_url` string or array to use a URI template as the base URL of a client.
+  You can also specify a `defaults` key that is an associative array of default
+  request options. You can pass an `adapter` to use a custom adapter,
+  `batch_adapter` to use a custom adapter for sending requests in parallel, or
+  a `message_factory` to change the factory used to create HTTP requests and
+  responses.
+- The client no longer emits a `client.create_request` event.
+- Creating requests with a client no longer automatically utilize a URI
+  template. You must pass an array into a creational method (e.g.,
+  `createRequest`, `get`, `put`, etc.) in order to expand a URI template.
+
+### Messages
+
+Messages no longer have references to their counterparts (i.e., a request no
+longer has a reference to it's response, and a response no loger has a
+reference to its request). This association is now managed through a
+`GuzzleHttp\Adapter\TransactionInterface` object. You can get references to
+these transaction objects using request events that are emitted over the
+lifecycle of a request.
+
+#### Requests with a body
+
+- `GuzzleHttp\Message\EntityEnclosingRequest` and
+  `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The
+  separation between requests that contain a body and requests that do not
+  contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface`
+  handles both use cases.
+- Any method that previously accepts a `GuzzleHttp\Response` object now accept a
+  `GuzzleHttp\Message\ResponseInterface`.
+- `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to
+  `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create
+  both requests and responses and is implemented in
+  `GuzzleHttp\Message\MessageFactory`.
+- POST field and file methods have been removed from the request object. You
+  must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface`
+  to control the format of a POST body. Requests that are created using a
+  standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use
+  a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if
+  the method is POST and no body is provided.
+
+```php
+$request = $client->createRequest('POST', '/');
+$request->getBody()->setField('foo', 'bar');
+$request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r')));
+```
+
+#### Headers
+
+- `GuzzleHttp\Message\Header` has been removed. Header values are now simply
+  represented by an array of values or as a string. Header values are returned
+  as a string by default when retrieving a header value from a message. You can
+  pass an optional argument of `true` to retrieve a header value as an array
+  of strings instead of a single concatenated string.
+- `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to
+  `GuzzleHttp\Post`. This interface has been simplified and now allows the
+  addition of arbitrary headers.
+- Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most
+  of the custom headers are now handled separately in specific
+  subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has
+  been updated to properly handle headers that contain parameters (like the
+  `Link` header).
+
+#### Responses
+
+- `GuzzleHttp\Message\Response::getInfo()` and
+  `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event
+  system to retrieve this type of information.
+- `GuzzleHttp\Message\Response::getRawHeaders()` has been removed.
+- `GuzzleHttp\Message\Response::getMessage()` has been removed.
+- `GuzzleHttp\Message\Response::calculateAge()` and other cache specific
+  methods have moved to the CacheSubscriber.
+- Header specific helper functions like `getContentMd5()` have been removed.
+  Just use `getHeader('Content-MD5')` instead.
+- `GuzzleHttp\Message\Response::setRequest()` and
+  `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event
+  system to work with request and response objects as a transaction.
+- `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the
+  Redirect subscriber instead.
+- `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have
+  been removed. Use `getStatusCode()` instead.
+
+#### Streaming responses
+
+Streaming requests can now be created by a client directly, returning a
+`GuzzleHttp\Message\ResponseInterface` object that contains a body stream
+referencing an open PHP HTTP stream.
+
+```php
+// 3.0
+use Guzzle\Stream\PhpStreamRequestFactory;
+$request = $client->get('/');
+$factory = new PhpStreamRequestFactory();
+$stream = $factory->fromRequest($request);
+$data = $stream->read(1024);
+
+// 4.0
+$response = $client->get('/', ['stream' => true]);
+// Read some data off of the stream in the response body
+$data = $response->getBody()->read(1024);
+```
+
+#### Redirects
+
+The `configureRedirects()` method has been removed in favor of a
+`allow_redirects` request option.
+
+```php
+// Standard redirects with a default of a max of 5 redirects
+$request = $client->createRequest('GET', '/', ['allow_redirects' => true]);
+
+// Strict redirects with a custom number of redirects
+$request = $client->createRequest('GET', '/', [
+    'allow_redirects' => ['max' => 5, 'strict' => true]
+]);
+```
+
+#### EntityBody
+
+EntityBody interfaces and classes have been removed or moved to
+`GuzzleHttp\Stream`. All classes and interfaces that once required
+`GuzzleHttp\EntityBodyInterface` now require
+`GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no
+longer uses `GuzzleHttp\EntityBody::factory` but now uses
+`GuzzleHttp\Stream\Stream::factory` or even better:
+`GuzzleHttp\Stream\create()`.
+
+- `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface`
+- `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream`
+- `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream`
+- `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream`
+- `Guzzle\Http\IoEmittyinEntityBody` has been removed.
+
+#### Request lifecycle events
+
+Requests previously submitted a large number of requests. The number of events
+emitted over the lifecycle of a request has been significantly reduced to make
+it easier to understand how to extend the behavior of a request. All events
+emitted during the lifecycle of a request now emit a custom
+`GuzzleHttp\Event\EventInterface` object that contains context providing
+methods and a way in which to modify the transaction at that specific point in
+time (e.g., intercept the request and set a response on the transaction).
+
+- `request.before_send` has been renamed to `before` and now emits a
+  `GuzzleHttp\Event\BeforeEvent`
+- `request.complete` has been renamed to `complete` and now emits a
+  `GuzzleHttp\Event\CompleteEvent`.
+- `request.sent` has been removed. Use `complete`.
+- `request.success` has been removed. Use `complete`.
+- `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`.
+- `request.exception` has been removed. Use `error`.
+- `request.receive.status_line` has been removed.
+- `curl.callback.progress` has been removed. Use a custom `StreamInterface` to
+  maintain a status update.
+- `curl.callback.write` has been removed. Use a custom `StreamInterface` to
+  intercept writes.
+- `curl.callback.read` has been removed. Use a custom `StreamInterface` to
+  intercept reads.
+
+`headers` is a new event that is emitted after the response headers of a
+request have been received before the body of the response is downloaded. This
+event emits a `GuzzleHttp\Event\HeadersEvent`.
+
+You can intercept a request and inject a response using the `intercept()` event
+of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and
+`GuzzleHttp\Event\ErrorEvent` event.
+
+See: http://docs.guzzlephp.org/en/latest/events.html
+
+## Inflection
+
+The `Guzzle\Inflection` namespace has been removed. This is not a core concern
+of Guzzle.
+
+## Iterator
+
+The `Guzzle\Iterator` namespace has been removed.
+
+- `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and
+  `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of
+  Guzzle itself.
+- `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent
+  class is shipped with PHP 5.4.
+- `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because
+  it's easier to just wrap an iterator in a generator that maps values.
+
+For a replacement of these iterators, see https://github.com/nikic/iter
+
+## Log
+
+The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The
+`Guzzle\Log` namespace has been removed. Guzzle now relies on
+`Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been
+moved to `GuzzleHttp\Subscriber\Log\Formatter`.
+
+## Parser
+
+The `Guzzle\Parser` namespace has been removed. This was previously used to
+make it possible to plug in custom parsers for cookies, messages, URI
+templates, and URLs; however, this level of complexity is not needed in Guzzle
+so it has been removed.
+
+- Cookie: Cookie parsing logic has been moved to
+  `GuzzleHttp\Cookie\SetCookie::fromString`.
+- Message: Message parsing logic for both requests and responses has been moved
+  to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only
+  used in debugging or deserializing messages, so it doesn't make sense for
+  Guzzle as a library to add this level of complexity to parsing messages.
+- UriTemplate: URI template parsing has been moved to
+  `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL
+  URI template library if it is installed.
+- Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously
+  it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary,
+  then developers are free to subclass `GuzzleHttp\Url`.
+
+## Plugin
+
+The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`.
+Several plugins are shipping with the core Guzzle library under this namespace.
+
+- `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar
+  code has moved to `GuzzleHttp\Cookie`.
+- `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin.
+- `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is
+  received.
+- `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin.
+- `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before
+  sending. This subscriber is attached to all requests by default.
+- `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin.
+
+The following plugins have been removed (third-parties are free to re-implement
+these if needed):
+
+- `GuzzleHttp\Plugin\Async` has been removed.
+- `GuzzleHttp\Plugin\CurlAuth` has been removed.
+- `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This
+  functionality should instead be implemented with event listeners that occur
+  after normal response parsing occurs in the guzzle/command package.
+
+The following plugins are not part of the core Guzzle package, but are provided
+in separate repositories:
+
+- `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be much simpler
+  to build custom retry policies using simple functions rather than various
+  chained classes. See: https://github.com/guzzle/retry-subscriber
+- `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to
+  https://github.com/guzzle/cache-subscriber
+- `Guzzle\Http\Plugin\Log\LogPlugin` has moved to
+  https://github.com/guzzle/log-subscriber
+- `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to
+  https://github.com/guzzle/message-integrity-subscriber
+- `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to
+  `GuzzleHttp\Subscriber\MockSubscriber`.
+- `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to
+  https://github.com/guzzle/oauth-subscriber
+
+## Service
+
+The service description layer of Guzzle has moved into two separate packages:
+
+- http://github.com/guzzle/command Provides a high level abstraction over web
+  services by representing web service operations using commands.
+- http://github.com/guzzle/guzzle-services Provides an implementation of
+  guzzle/command that provides request serialization and response parsing using
+  Guzzle service descriptions.
+
+## Stream
+
+Stream have moved to a separate package available at
+https://github.com/guzzle/streams.
+
+`Guzzle\Stream\StreamInterface` has been given a large update to cleanly take
+on the responsibilities of `Guzzle\Http\EntityBody` and
+`Guzzle\Http\EntityBodyInterface` now that they have been removed. The number
+of methods implemented by the `StreamInterface` has been drastically reduced to
+allow developers to more easily extend and decorate stream behavior.
+
+## Removed methods from StreamInterface
+
+- `getStream` and `setStream` have been removed to better encapsulate streams.
+- `getMetadata` and `setMetadata` have been removed in favor of
+  `GuzzleHttp\Stream\MetadataStreamInterface`.
+- `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been
+  removed. This data is accessible when
+  using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`.
+- `rewind` has been removed. Use `seek(0)` for a similar behavior.
+
+## Renamed methods
+
+- `detachStream` has been renamed to `detach`.
+- `feof` has been renamed to `eof`.
+- `ftell` has been renamed to `tell`.
+- `readLine` has moved from an instance method to a static class method of
+  `GuzzleHttp\Stream\Stream`.
+
+## Metadata streams
+
+`GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams
+that contain additional metadata accessible via `getMetadata()`.
+`GuzzleHttp\Stream\StreamInterface::getMetadata` and
+`GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed.
+
+## StreamRequestFactory
+
+The entire concept of the StreamRequestFactory has been removed. The way this
+was used in Guzzle 3 broke the actual interface of sending streaming requests
+(instead of getting back a Response, you got a StreamInterface). Streaming
+PHP requests are now implemented through the `GuzzleHttp\Adapter\StreamAdapter`.
+
+3.6 to 3.7
+----------
+
+### Deprecations
+
+- You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.:
+
+```php
+\Guzzle\Common\Version::$emitWarnings = true;
+```
+
+The following APIs and options have been marked as deprecated:
+
+- Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead.
+- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
+- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
+- Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
+- Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
+- Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
+- Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
+- Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
+- Marked `Guzzle\Common\Collection::inject()` as deprecated.
+- Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use
+  `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or
+  `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));`
+
+3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational
+request methods. When paired with a client's configuration settings, these options allow you to specify default settings
+for various aspects of a request. Because these options make other previous configuration options redundant, several
+configuration options and methods of a client and AbstractCommand have been deprecated.
+
+- Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`.
+- Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`.
+- Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')`
+- Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0
+
+        $command = $client->getCommand('foo', array(
+            'command.headers' => array('Test' => '123'),
+            'command.response_body' => '/path/to/file'
+        ));
+
+        // Should be changed to:
+
+        $command = $client->getCommand('foo', array(
+            'command.request_options' => array(
+                'headers' => array('Test' => '123'),
+                'save_as' => '/path/to/file'
+            )
+        ));
+
+### Interface changes
+
+Additions and changes (you will need to update any implementations or subclasses you may have created):
+
+- Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
+  createRequest, head, delete, put, patch, post, options, prepareRequest
+- Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
+- Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
+- Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
+  `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
+  resource, string, or EntityBody into the $options parameter to specify the download location of the response.
+- Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
+  default `array()`
+- Added `Guzzle\Stream\StreamInterface::isRepeatable`
+- Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
+
+The following methods were removed from interfaces. All of these methods are still available in the concrete classes
+that implement them, but you should update your code to use alternative methods:
+
+- Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
+  `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
+  `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or
+  `$client->setDefaultOption('headers/{header_name}', 'value')`. or
+  `$client->setDefaultOption('headers', array('header_name' => 'value'))`.
+- Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`.
+- Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail.
+- Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail.
+- Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail.
+- Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin.
+- Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin.
+- Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin.
+
+### Cache plugin breaking changes
+
+- CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
+  CacheStorageInterface. These two objects and interface will be removed in a future version.
+- Always setting X-cache headers on cached responses
+- Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
+- `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
+  $request, Response $response);`
+- `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
+- `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
+- Added `CacheStorageInterface::purge($url)`
+- `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
+  $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
+  CanCacheStrategyInterface $canCache = null)`
+- Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
+
+3.5 to 3.6
+----------
+
+* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
+* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
+* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
+  For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader().
+  Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request.
+* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
+  HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
+  CacheControl header implementation.
+* Moved getLinks() from Response to just be used on a Link header object.
+
+If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
+HeaderInterface (e.g. toArray(), getAll(), etc.).
+
+### Interface changes
+
+* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
+* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
+* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
+  Guzzle\Http\Curl\RequestMediator
+* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
+* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
+* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
+
+### Removed deprecated functions
+
+* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
+* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
+
+### Deprecations
+
+* The ability to case-insensitively search for header values
+* Guzzle\Http\Message\Header::hasExactHeader
+* Guzzle\Http\Message\Header::raw. Use getAll()
+* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
+  instead.
+
+### Other changes
+
+* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
+* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
+  directly via interfaces
+* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
+  but are a no-op until removed.
+* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
+  `Guzzle\Service\Command\ArrayCommandInterface`.
+* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
+  on a request while the request is still being transferred
+* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
+
+3.3 to 3.4
+----------
+
+Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
+
+3.2 to 3.3
+----------
+
+### Response::getEtag() quote stripping removed
+
+`Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header
+
+### Removed `Guzzle\Http\Utils`
+
+The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
+
+### Stream wrapper and type
+
+`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase.
+
+### curl.emit_io became emit_io
+
+Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the
+'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
+
+3.1 to 3.2
+----------
+
+### CurlMulti is no longer reused globally
+
+Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added
+to a single client can pollute requests dispatched from other clients.
+
+If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the
+ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is
+created.
+
+```php
+$multi = new Guzzle\Http\Curl\CurlMulti();
+$builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json');
+$builder->addListener('service_builder.create_client', function ($event) use ($multi) {
+    $event['client']->setCurlMulti($multi);
+}
+});
+```
+
+### No default path
+
+URLs no longer have a default path value of '/' if no path was specified.
+
+Before:
+
+```php
+$request = $client->get('http://www.foo.com');
+echo $request->getUrl();
+// >> http://www.foo.com/
+```
+
+After:
+
+```php
+$request = $client->get('http://www.foo.com');
+echo $request->getUrl();
+// >> http://www.foo.com
+```
+
+### Less verbose BadResponseException
+
+The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and
+response information. You can, however, get access to the request and response object by calling `getRequest()` or
+`getResponse()` on the exception object.
+
+### Query parameter aggregation
+
+Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a
+setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is
+responsible for handling the aggregation of multi-valued query string variables into a flattened hash.
+
+2.8 to 3.x
+----------
+
+### Guzzle\Service\Inspector
+
+Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig`
+
+**Before**
+
+```php
+use Guzzle\Service\Inspector;
+
+class YourClient extends \Guzzle\Service\Client
+{
+    public static function factory($config = array())
+    {
+        $default = array();
+        $required = array('base_url', 'username', 'api_key');
+        $config = Inspector::fromConfig($config, $default, $required);
+
+        $client = new self(
+            $config->get('base_url'),
+            $config->get('username'),
+            $config->get('api_key')
+        );
+        $client->setConfig($config);
+
+        $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
+
+        return $client;
+    }
+```
+
+**After**
+
+```php
+use Guzzle\Common\Collection;
+
+class YourClient extends \Guzzle\Service\Client
+{
+    public static function factory($config = array())
+    {
+        $default = array();
+        $required = array('base_url', 'username', 'api_key');
+        $config = Collection::fromConfig($config, $default, $required);
+
+        $client = new self(
+            $config->get('base_url'),
+            $config->get('username'),
+            $config->get('api_key')
+        );
+        $client->setConfig($config);
+
+        $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
+
+        return $client;
+    }
+```
+
+### Convert XML Service Descriptions to JSON
+
+**Before**
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<client>
+    <commands>
+        <!-- Groups -->
+        <command name="list_groups" method="GET" uri="groups.json">
+            <doc>Get a list of groups</doc>
+        </command>
+        <command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'>
+            <doc>Uses a search query to get a list of groups</doc>
+            <param name="query" type="string" required="true" />
+        </command>
+        <command name="create_group" method="POST" uri="groups.json">
+            <doc>Create a group</doc>
+            <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
+            <param name="Content-Type" location="header" static="application/json"/>
+        </command>
+        <command name="delete_group" method="DELETE" uri="groups/{{id}}.json">
+            <doc>Delete a group by ID</doc>
+            <param name="id" type="integer" required="true"/>
+        </command>
+        <command name="get_group" method="GET" uri="groups/{{id}}.json">
+            <param name="id" type="integer" required="true"/>
+        </command>
+        <command name="update_group" method="PUT" uri="groups/{{id}}.json">
+            <doc>Update a group</doc>
+            <param name="id" type="integer" required="true"/>
+            <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
+            <param name="Content-Type" location="header" static="application/json"/>
+        </command>
+    </commands>
+</client>
+```
+
+**After**
+
+```json
+{
+    "name":       "Zendesk REST API v2",
+    "apiVersion": "2012-12-31",
+    "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users",
+    "operations": {
+        "list_groups":  {
+            "httpMethod":"GET",
+            "uri":       "groups.json",
+            "summary":   "Get a list of groups"
+        },
+        "search_groups":{
+            "httpMethod":"GET",
+            "uri":       "search.json?query=\"{query} type:group\"",
+            "summary":   "Uses a search query to get a list of groups",
+            "parameters":{
+                "query":{
+                    "location":   "uri",
+                    "description":"Zendesk Search Query",
+                    "type":       "string",
+                    "required":   true
+                }
+            }
+        },
+        "create_group": {
+            "httpMethod":"POST",
+            "uri":       "groups.json",
+            "summary":   "Create a group",
+            "parameters":{
+                "data":        {
+                    "type":       "array",
+                    "location":   "body",
+                    "description":"Group JSON",
+                    "filters":    "json_encode",
+                    "required":   true
+                },
+                "Content-Type":{
+                    "type":    "string",
+                    "location":"header",
+                    "static":  "application/json"
+                }
+            }
+        },
+        "delete_group": {
+            "httpMethod":"DELETE",
+            "uri":       "groups/{id}.json",
+            "summary":   "Delete a group",
+            "parameters":{
+                "id":{
+                    "location":   "uri",
+                    "description":"Group to delete by ID",
+                    "type":       "integer",
+                    "required":   true
+                }
+            }
+        },
+        "get_group":    {
+            "httpMethod":"GET",
+            "uri":       "groups/{id}.json",
+            "summary":   "Get a ticket",
+            "parameters":{
+                "id":{
+                    "location":   "uri",
+                    "description":"Group to get by ID",
+                    "type":       "integer",
+                    "required":   true
+                }
+            }
+        },
+        "update_group": {
+            "httpMethod":"PUT",
+            "uri":       "groups/{id}.json",
+            "summary":   "Update a group",
+            "parameters":{
+                "id":          {
+                    "location":   "uri",
+                    "description":"Group to update by ID",
+                    "type":       "integer",
+                    "required":   true
+                },
+                "data":        {
+                    "type":       "array",
+                    "location":   "body",
+                    "description":"Group JSON",
+                    "filters":    "json_encode",
+                    "required":   true
+                },
+                "Content-Type":{
+                    "type":    "string",
+                    "location":"header",
+                    "static":  "application/json"
+                }
+            }
+        }
+}
+```
+
+### Guzzle\Service\Description\ServiceDescription
+
+Commands are now called Operations
+
+**Before**
+
+```php
+use Guzzle\Service\Description\ServiceDescription;
+
+$sd = new ServiceDescription();
+$sd->getCommands();     // @returns ApiCommandInterface[]
+$sd->hasCommand($name);
+$sd->getCommand($name); // @returns ApiCommandInterface|null
+$sd->addCommand($command); // @param ApiCommandInterface $command
+```
+
+**After**
+
+```php
+use Guzzle\Service\Description\ServiceDescription;
+
+$sd = new ServiceDescription();
+$sd->getOperations();           // @returns OperationInterface[]
+$sd->hasOperation($name);
+$sd->getOperation($name);       // @returns OperationInterface|null
+$sd->addOperation($operation);  // @param OperationInterface $operation
+```
+
+### Guzzle\Common\Inflection\Inflector
+
+Namespace is now `Guzzle\Inflection\Inflector`
+
+### Guzzle\Http\Plugin
+
+Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below.
+
+### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log
+
+Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively.
+
+**Before**
+
+```php
+use Guzzle\Common\Log\ClosureLogAdapter;
+use Guzzle\Http\Plugin\LogPlugin;
+
+/** @var \Guzzle\Http\Client */
+$client;
+
+// $verbosity is an integer indicating desired message verbosity level
+$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE);
+```
+
+**After**
+
+```php
+use Guzzle\Log\ClosureLogAdapter;
+use Guzzle\Log\MessageFormatter;
+use Guzzle\Plugin\Log\LogPlugin;
+
+/** @var \Guzzle\Http\Client */
+$client;
+
+// $format is a string indicating desired message format -- @see MessageFormatter
+$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT);
+```
+
+### Guzzle\Http\Plugin\CurlAuthPlugin
+
+Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`.
+
+### Guzzle\Http\Plugin\ExponentialBackoffPlugin
+
+Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes.
+
+**Before**
+
+```php
+use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
+
+$backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge(
+        ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429)
+    ));
+
+$client->addSubscriber($backoffPlugin);
+```
+
+**After**
+
+```php
+use Guzzle\Plugin\Backoff\BackoffPlugin;
+use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
+
+// Use convenient factory method instead -- see implementation for ideas of what
+// you can do with chaining backoff strategies
+$backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge(
+        HttpBackoffStrategy::getDefaultFailureCodes(), array(429)
+    ));
+$client->addSubscriber($backoffPlugin);
+```
+
+### Known Issues
+
+#### [BUG] Accept-Encoding header behavior changed unintentionally.
+
+(See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e)
+
+In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to
+properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen.
+See issue #217 for a workaround, or use a version containing the fix.
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/composer.json b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/composer.json
new file mode 100644 (file)
index 0000000..c01864f
--- /dev/null
@@ -0,0 +1,59 @@
+{
+    "name": "guzzlehttp/guzzle",
+    "type": "library",
+    "description": "Guzzle is a PHP HTTP client library",
+    "keywords": [
+        "framework",
+        "http",
+        "rest",
+        "web service",
+        "curl",
+        "client",
+        "HTTP client"
+    ],
+    "homepage": "http://guzzlephp.org/",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Michael Dowling",
+            "email": "mtdowling@gmail.com",
+            "homepage": "https://github.com/mtdowling"
+        }
+    ],
+    "require": {
+        "php": ">=5.5",
+        "ext-json": "*",
+        "symfony/polyfill-intl-idn": "^1.17.0",
+        "guzzlehttp/promises": "^1.0",
+        "guzzlehttp/psr7": "^1.6.1"
+    },
+    "require-dev": {
+        "ext-curl": "*",
+        "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+        "psr/log": "^1.1"
+    },
+    "suggest": {
+        "psr/log": "Required for using the Log middleware"
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "6.5-dev"
+        }
+    },
+    "autoload": {
+        "psr-4": {
+            "GuzzleHttp\\": "src/"
+        },
+        "files": [
+            "src/functions_include.php"
+        ]
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "GuzzleHttp\\Tests\\": "tests/"
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Client.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Client.php
new file mode 100644 (file)
index 0000000..315a022
--- /dev/null
@@ -0,0 +1,501 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Cookie\CookieJar;
+use GuzzleHttp\Exception\GuzzleException;
+use GuzzleHttp\Promise;
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * @method ResponseInterface get(string|UriInterface $uri, array $options = [])
+ * @method ResponseInterface head(string|UriInterface $uri, array $options = [])
+ * @method ResponseInterface put(string|UriInterface $uri, array $options = [])
+ * @method ResponseInterface post(string|UriInterface $uri, array $options = [])
+ * @method ResponseInterface patch(string|UriInterface $uri, array $options = [])
+ * @method ResponseInterface delete(string|UriInterface $uri, array $options = [])
+ * @method Promise\PromiseInterface getAsync(string|UriInterface $uri, array $options = [])
+ * @method Promise\PromiseInterface headAsync(string|UriInterface $uri, array $options = [])
+ * @method Promise\PromiseInterface putAsync(string|UriInterface $uri, array $options = [])
+ * @method Promise\PromiseInterface postAsync(string|UriInterface $uri, array $options = [])
+ * @method Promise\PromiseInterface patchAsync(string|UriInterface $uri, array $options = [])
+ * @method Promise\PromiseInterface deleteAsync(string|UriInterface $uri, array $options = [])
+ */
+class Client implements ClientInterface
+{
+    /** @var array Default request options */
+    private $config;
+
+    /**
+     * Clients accept an array of constructor parameters.
+     *
+     * Here's an example of creating a client using a base_uri and an array of
+     * default request options to apply to each request:
+     *
+     *     $client = new Client([
+     *         'base_uri'        => 'http://www.foo.com/1.0/',
+     *         'timeout'         => 0,
+     *         'allow_redirects' => false,
+     *         'proxy'           => '192.168.16.1:10'
+     *     ]);
+     *
+     * Client configuration settings include the following options:
+     *
+     * - handler: (callable) Function that transfers HTTP requests over the
+     *   wire. The function is called with a Psr7\Http\Message\RequestInterface
+     *   and array of transfer options, and must return a
+     *   GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
+     *   Psr7\Http\Message\ResponseInterface on success.
+     *   If no handler is provided, a default handler will be created
+     *   that enables all of the request options below by attaching all of the
+     *   default middleware to the handler.
+     * - base_uri: (string|UriInterface) Base URI of the client that is merged
+     *   into relative URIs. Can be a string or instance of UriInterface.
+     * - **: any request option
+     *
+     * @param array $config Client configuration settings.
+     *
+     * @see \GuzzleHttp\RequestOptions for a list of available request options.
+     */
+    public function __construct(array $config = [])
+    {
+        if (!isset($config['handler'])) {
+            $config['handler'] = HandlerStack::create();
+        } elseif (!is_callable($config['handler'])) {
+            throw new \InvalidArgumentException('handler must be a callable');
+        }
+
+        // Convert the base_uri to a UriInterface
+        if (isset($config['base_uri'])) {
+            $config['base_uri'] = Psr7\uri_for($config['base_uri']);
+        }
+
+        $this->configureDefaults($config);
+    }
+
+    /**
+     * @param string $method
+     * @param array  $args
+     *
+     * @return Promise\PromiseInterface
+     */
+    public function __call($method, $args)
+    {
+        if (count($args) < 1) {
+            throw new \InvalidArgumentException('Magic request methods require a URI and optional options array');
+        }
+
+        $uri = $args[0];
+        $opts = isset($args[1]) ? $args[1] : [];
+
+        return substr($method, -5) === 'Async'
+            ? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
+            : $this->request($method, $uri, $opts);
+    }
+
+    /**
+     * Asynchronously send an HTTP request.
+     *
+     * @param array $options Request options to apply to the given
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
+     *
+     * @return Promise\PromiseInterface
+     */
+    public function sendAsync(RequestInterface $request, array $options = [])
+    {
+        // Merge the base URI into the request URI if needed.
+        $options = $this->prepareDefaults($options);
+
+        return $this->transfer(
+            $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
+            $options
+        );
+    }
+
+    /**
+     * Send an HTTP request.
+     *
+     * @param array $options Request options to apply to the given
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
+     *
+     * @return ResponseInterface
+     * @throws GuzzleException
+     */
+    public function send(RequestInterface $request, array $options = [])
+    {
+        $options[RequestOptions::SYNCHRONOUS] = true;
+        return $this->sendAsync($request, $options)->wait();
+    }
+
+    /**
+     * Create and send an asynchronous HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string              $method  HTTP method
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
+     *
+     * @return Promise\PromiseInterface
+     */
+    public function requestAsync($method, $uri = '', array $options = [])
+    {
+        $options = $this->prepareDefaults($options);
+        // Remove request modifying parameter because it can be done up-front.
+        $headers = isset($options['headers']) ? $options['headers'] : [];
+        $body = isset($options['body']) ? $options['body'] : null;
+        $version = isset($options['version']) ? $options['version'] : '1.1';
+        // Merge the URI into the base URI.
+        $uri = $this->buildUri($uri, $options);
+        if (is_array($body)) {
+            $this->invalidBody();
+        }
+        $request = new Psr7\Request($method, $uri, $headers, $body, $version);
+        // Remove the option so that they are not doubly-applied.
+        unset($options['headers'], $options['body'], $options['version']);
+
+        return $this->transfer($request, $options);
+    }
+
+    /**
+     * Create and send an HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string              $method  HTTP method.
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
+     *
+     * @return ResponseInterface
+     * @throws GuzzleException
+     */
+    public function request($method, $uri = '', array $options = [])
+    {
+        $options[RequestOptions::SYNCHRONOUS] = true;
+        return $this->requestAsync($method, $uri, $options)->wait();
+    }
+
+    /**
+     * Get a client configuration option.
+     *
+     * These options include default request options of the client, a "handler"
+     * (if utilized by the concrete client), and a "base_uri" if utilized by
+     * the concrete client.
+     *
+     * @param string|null $option The config option to retrieve.
+     *
+     * @return mixed
+     */
+    public function getConfig($option = null)
+    {
+        return $option === null
+            ? $this->config
+            : (isset($this->config[$option]) ? $this->config[$option] : null);
+    }
+
+    /**
+     * @param  string|null $uri
+     *
+     * @return UriInterface
+     */
+    private function buildUri($uri, array $config)
+    {
+        // for BC we accept null which would otherwise fail in uri_for
+        $uri = Psr7\uri_for($uri === null ? '' : $uri);
+
+        if (isset($config['base_uri'])) {
+            $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
+        }
+
+        if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
+            $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion'];
+            $uri = Utils::idnUriConvert($uri, $idnOptions);
+        }
+
+        return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
+    }
+
+    /**
+     * Configures the default options for a client.
+     *
+     * @param array $config
+     * @return void
+     */
+    private function configureDefaults(array $config)
+    {
+        $defaults = [
+            'allow_redirects' => RedirectMiddleware::$defaultSettings,
+            'http_errors'     => true,
+            'decode_content'  => true,
+            'verify'          => true,
+            'cookies'         => false,
+            'idn_conversion'  => true,
+        ];
+
+        // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
+
+        // We can only trust the HTTP_PROXY environment variable in a CLI
+        // process due to the fact that PHP has no reliable mechanism to
+        // get environment variables that start with "HTTP_".
+        if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) {
+            $defaults['proxy']['http'] = getenv('HTTP_PROXY');
+        }
+
+        if ($proxy = getenv('HTTPS_PROXY')) {
+            $defaults['proxy']['https'] = $proxy;
+        }
+
+        if ($noProxy = getenv('NO_PROXY')) {
+            $cleanedNoProxy = str_replace(' ', '', $noProxy);
+            $defaults['proxy']['no'] = explode(',', $cleanedNoProxy);
+        }
+
+        $this->config = $config + $defaults;
+
+        if (!empty($config['cookies']) && $config['cookies'] === true) {
+            $this->config['cookies'] = new CookieJar();
+        }
+
+        // Add the default user-agent header.
+        if (!isset($this->config['headers'])) {
+            $this->config['headers'] = ['User-Agent' => default_user_agent()];
+        } else {
+            // Add the User-Agent header if one was not already set.
+            foreach (array_keys($this->config['headers']) as $name) {
+                if (strtolower($name) === 'user-agent') {
+                    return;
+                }
+            }
+            $this->config['headers']['User-Agent'] = default_user_agent();
+        }
+    }
+
+    /**
+     * Merges default options into the array.
+     *
+     * @param array $options Options to modify by reference
+     *
+     * @return array
+     */
+    private function prepareDefaults(array $options)
+    {
+        $defaults = $this->config;
+
+        if (!empty($defaults['headers'])) {
+            // Default headers are only added if they are not present.
+            $defaults['_conditional'] = $defaults['headers'];
+            unset($defaults['headers']);
+        }
+
+        // Special handling for headers is required as they are added as
+        // conditional headers and as headers passed to a request ctor.
+        if (array_key_exists('headers', $options)) {
+            // Allows default headers to be unset.
+            if ($options['headers'] === null) {
+                $defaults['_conditional'] = [];
+                unset($options['headers']);
+            } elseif (!is_array($options['headers'])) {
+                throw new \InvalidArgumentException('headers must be an array');
+            }
+        }
+
+        // Shallow merge defaults underneath options.
+        $result = $options + $defaults;
+
+        // Remove null values.
+        foreach ($result as $k => $v) {
+            if ($v === null) {
+                unset($result[$k]);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Transfers the given request and applies request options.
+     *
+     * The URI of the request is not modified and the request options are used
+     * as-is without merging in default options.
+     *
+     * @param array $options See \GuzzleHttp\RequestOptions.
+     *
+     * @return Promise\PromiseInterface
+     */
+    private function transfer(RequestInterface $request, array $options)
+    {
+        // save_to -> sink
+        if (isset($options['save_to'])) {
+            $options['sink'] = $options['save_to'];
+            unset($options['save_to']);
+        }
+
+        // exceptions -> http_errors
+        if (isset($options['exceptions'])) {
+            $options['http_errors'] = $options['exceptions'];
+            unset($options['exceptions']);
+        }
+
+        $request = $this->applyOptions($request, $options);
+        /** @var HandlerStack $handler */
+        $handler = $options['handler'];
+
+        try {
+            return Promise\promise_for($handler($request, $options));
+        } catch (\Exception $e) {
+            return Promise\rejection_for($e);
+        }
+    }
+
+    /**
+     * Applies the array of request options to a request.
+     *
+     * @param RequestInterface $request
+     * @param array            $options
+     *
+     * @return RequestInterface
+     */
+    private function applyOptions(RequestInterface $request, array &$options)
+    {
+        $modify = [
+            'set_headers' => [],
+        ];
+
+        if (isset($options['headers'])) {
+            $modify['set_headers'] = $options['headers'];
+            unset($options['headers']);
+        }
+
+        if (isset($options['form_params'])) {
+            if (isset($options['multipart'])) {
+                throw new \InvalidArgumentException('You cannot use '
+                    . 'form_params and multipart at the same time. Use the '
+                    . 'form_params option if you want to send application/'
+                    . 'x-www-form-urlencoded requests, and the multipart '
+                    . 'option to send multipart/form-data requests.');
+            }
+            $options['body'] = http_build_query($options['form_params'], '', '&');
+            unset($options['form_params']);
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
+            $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
+        }
+
+        if (isset($options['multipart'])) {
+            $options['body'] = new Psr7\MultipartStream($options['multipart']);
+            unset($options['multipart']);
+        }
+
+        if (isset($options['json'])) {
+            $options['body'] = \GuzzleHttp\json_encode($options['json']);
+            unset($options['json']);
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
+            $options['_conditional']['Content-Type'] = 'application/json';
+        }
+
+        if (!empty($options['decode_content'])
+            && $options['decode_content'] !== true
+        ) {
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']);
+            $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
+        }
+
+        if (isset($options['body'])) {
+            if (is_array($options['body'])) {
+                $this->invalidBody();
+            }
+            $modify['body'] = Psr7\stream_for($options['body']);
+            unset($options['body']);
+        }
+
+        if (!empty($options['auth']) && is_array($options['auth'])) {
+            $value = $options['auth'];
+            $type = isset($value[2]) ? strtolower($value[2]) : 'basic';
+            switch ($type) {
+                case 'basic':
+                    // Ensure that we don't have the header in different case and set the new value.
+                    $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']);
+                    $modify['set_headers']['Authorization'] = 'Basic '
+                        . base64_encode("$value[0]:$value[1]");
+                    break;
+                case 'digest':
+                    // @todo: Do not rely on curl
+                    $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
+                    $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
+                    break;
+                case 'ntlm':
+                    $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
+                    $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
+                    break;
+            }
+        }
+
+        if (isset($options['query'])) {
+            $value = $options['query'];
+            if (is_array($value)) {
+                $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
+            }
+            if (!is_string($value)) {
+                throw new \InvalidArgumentException('query must be a string or array');
+            }
+            $modify['query'] = $value;
+            unset($options['query']);
+        }
+
+        // Ensure that sink is not an invalid value.
+        if (isset($options['sink'])) {
+            // TODO: Add more sink validation?
+            if (is_bool($options['sink'])) {
+                throw new \InvalidArgumentException('sink must not be a boolean');
+            }
+        }
+
+        $request = Psr7\modify_request($request, $modify);
+        if ($request->getBody() instanceof Psr7\MultipartStream) {
+            // Use a multipart/form-data POST if a Content-Type is not set.
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
+            $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
+                . $request->getBody()->getBoundary();
+        }
+
+        // Merge in conditional headers if they are not present.
+        if (isset($options['_conditional'])) {
+            // Build up the changes so it's in a single clone of the message.
+            $modify = [];
+            foreach ($options['_conditional'] as $k => $v) {
+                if (!$request->hasHeader($k)) {
+                    $modify['set_headers'][$k] = $v;
+                }
+            }
+            $request = Psr7\modify_request($request, $modify);
+            // Don't pass this internal value along to middleware/handlers.
+            unset($options['_conditional']);
+        }
+
+        return $request;
+    }
+
+    /**
+     * Throw Exception with pre-set message.
+     * @return void
+     * @throws \InvalidArgumentException Invalid body.
+     */
+    private function invalidBody()
+    {
+        throw new \InvalidArgumentException('Passing in the "body" request '
+            . 'option as an array to send a POST request has been deprecated. '
+            . 'Please use the "form_params" request option to send a '
+            . 'application/x-www-form-urlencoded request, or the "multipart" '
+            . 'request option to send a multipart/form-data request.');
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/ClientInterface.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/ClientInterface.php
new file mode 100644 (file)
index 0000000..638b75d
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\GuzzleException;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Client interface for sending HTTP requests.
+ */
+interface ClientInterface
+{
+    /**
+     * @deprecated Will be removed in Guzzle 7.0.0
+     */
+    const VERSION = '6.5.5';
+
+    /**
+     * Send an HTTP request.
+     *
+     * @param RequestInterface $request Request to send
+     * @param array            $options Request options to apply to the given
+     *                                  request and to the transfer.
+     *
+     * @return ResponseInterface
+     * @throws GuzzleException
+     */
+    public function send(RequestInterface $request, array $options = []);
+
+    /**
+     * Asynchronously send an HTTP request.
+     *
+     * @param RequestInterface $request Request to send
+     * @param array            $options Request options to apply to the given
+     *                                  request and to the transfer.
+     *
+     * @return PromiseInterface
+     */
+    public function sendAsync(RequestInterface $request, array $options = []);
+
+    /**
+     * Create and send an HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string              $method  HTTP method.
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @return ResponseInterface
+     * @throws GuzzleException
+     */
+    public function request($method, $uri, array $options = []);
+
+    /**
+     * Create and send an asynchronous HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string              $method  HTTP method
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @return PromiseInterface
+     */
+    public function requestAsync($method, $uri, array $options = []);
+
+    /**
+     * Get a client configuration option.
+     *
+     * These options include default request options of the client, a "handler"
+     * (if utilized by the concrete client), and a "base_uri" if utilized by
+     * the concrete client.
+     *
+     * @param string|null $option The config option to retrieve.
+     *
+     * @return mixed
+     */
+    public function getConfig($option = null);
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/CookieJar.php
new file mode 100644 (file)
index 0000000..38f98ad
--- /dev/null
@@ -0,0 +1,316 @@
+<?php
+namespace GuzzleHttp\Cookie;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Cookie jar that stores cookies as an array
+ */
+class CookieJar implements CookieJarInterface
+{
+    /** @var SetCookie[] Loaded cookie data */
+    private $cookies = [];
+
+    /** @var bool */
+    private $strictMode;
+
+    /**
+     * @param bool $strictMode   Set to true to throw exceptions when invalid
+     *                           cookies are added to the cookie jar.
+     * @param array $cookieArray Array of SetCookie objects or a hash of
+     *                           arrays that can be used with the SetCookie
+     *                           constructor
+     */
+    public function __construct($strictMode = false, $cookieArray = [])
+    {
+        $this->strictMode = $strictMode;
+
+        foreach ($cookieArray as $cookie) {
+            if (!($cookie instanceof SetCookie)) {
+                $cookie = new SetCookie($cookie);
+            }
+            $this->setCookie($cookie);
+        }
+    }
+
+    /**
+     * Create a new Cookie jar from an associative array and domain.
+     *
+     * @param array  $cookies Cookies to create the jar from
+     * @param string $domain  Domain to set the cookies to
+     *
+     * @return self
+     */
+    public static function fromArray(array $cookies, $domain)
+    {
+        $cookieJar = new self();
+        foreach ($cookies as $name => $value) {
+            $cookieJar->setCookie(new SetCookie([
+                'Domain'  => $domain,
+                'Name'    => $name,
+                'Value'   => $value,
+                'Discard' => true
+            ]));
+        }
+
+        return $cookieJar;
+    }
+
+    /**
+     * @deprecated
+     */
+    public static function getCookieValue($value)
+    {
+        return $value;
+    }
+
+    /**
+     * Evaluate if this cookie should be persisted to storage
+     * that survives between requests.
+     *
+     * @param SetCookie $cookie Being evaluated.
+     * @param bool $allowSessionCookies If we should persist session cookies
+     * @return bool
+     */
+    public static function shouldPersist(
+        SetCookie $cookie,
+        $allowSessionCookies = false
+    ) {
+        if ($cookie->getExpires() || $allowSessionCookies) {
+            if (!$cookie->getDiscard()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Finds and returns the cookie based on the name
+     *
+     * @param string $name cookie name to search for
+     * @return SetCookie|null cookie that was found or null if not found
+     */
+    public function getCookieByName($name)
+    {
+        // don't allow a non string name
+        if ($name === null || !is_scalar($name)) {
+            return null;
+        }
+        foreach ($this->cookies as $cookie) {
+            if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
+                return $cookie;
+            }
+        }
+
+        return null;
+    }
+
+    public function toArray()
+    {
+        return array_map(function (SetCookie $cookie) {
+            return $cookie->toArray();
+        }, $this->getIterator()->getArrayCopy());
+    }
+
+    public function clear($domain = null, $path = null, $name = null)
+    {
+        if (!$domain) {
+            $this->cookies = [];
+            return;
+        } elseif (!$path) {
+            $this->cookies = array_filter(
+                $this->cookies,
+                function (SetCookie $cookie) use ($domain) {
+                    return !$cookie->matchesDomain($domain);
+                }
+            );
+        } elseif (!$name) {
+            $this->cookies = array_filter(
+                $this->cookies,
+                function (SetCookie $cookie) use ($path, $domain) {
+                    return !($cookie->matchesPath($path) &&
+                        $cookie->matchesDomain($domain));
+                }
+            );
+        } else {
+            $this->cookies = array_filter(
+                $this->cookies,
+                function (SetCookie $cookie) use ($path, $domain, $name) {
+                    return !($cookie->getName() == $name &&
+                        $cookie->matchesPath($path) &&
+                        $cookie->matchesDomain($domain));
+                }
+            );
+        }
+    }
+
+    public function clearSessionCookies()
+    {
+        $this->cookies = array_filter(
+            $this->cookies,
+            function (SetCookie $cookie) {
+                return !$cookie->getDiscard() && $cookie->getExpires();
+            }
+        );
+    }
+
+    public function setCookie(SetCookie $cookie)
+    {
+        // If the name string is empty (but not 0), ignore the set-cookie
+        // string entirely.
+        $name = $cookie->getName();
+        if (!$name && $name !== '0') {
+            return false;
+        }
+
+        // Only allow cookies with set and valid domain, name, value
+        $result = $cookie->validate();
+        if ($result !== true) {
+            if ($this->strictMode) {
+                throw new \RuntimeException('Invalid cookie: ' . $result);
+            } else {
+                $this->removeCookieIfEmpty($cookie);
+                return false;
+            }
+        }
+
+        // Resolve conflicts with previously set cookies
+        foreach ($this->cookies as $i => $c) {
+
+            // Two cookies are identical, when their path, and domain are
+            // identical.
+            if ($c->getPath() != $cookie->getPath() ||
+                $c->getDomain() != $cookie->getDomain() ||
+                $c->getName() != $cookie->getName()
+            ) {
+                continue;
+            }
+
+            // The previously set cookie is a discard cookie and this one is
+            // not so allow the new cookie to be set
+            if (!$cookie->getDiscard() && $c->getDiscard()) {
+                unset($this->cookies[$i]);
+                continue;
+            }
+
+            // If the new cookie's expiration is further into the future, then
+            // replace the old cookie
+            if ($cookie->getExpires() > $c->getExpires()) {
+                unset($this->cookies[$i]);
+                continue;
+            }
+
+            // If the value has changed, we better change it
+            if ($cookie->getValue() !== $c->getValue()) {
+                unset($this->cookies[$i]);
+                continue;
+            }
+
+            // The cookie exists, so no need to continue
+            return false;
+        }
+
+        $this->cookies[] = $cookie;
+
+        return true;
+    }
+
+    public function count()
+    {
+        return count($this->cookies);
+    }
+
+    public function getIterator()
+    {
+        return new \ArrayIterator(array_values($this->cookies));
+    }
+
+    public function extractCookies(
+        RequestInterface $request,
+        ResponseInterface $response
+    ) {
+        if ($cookieHeader = $response->getHeader('Set-Cookie')) {
+            foreach ($cookieHeader as $cookie) {
+                $sc = SetCookie::fromString($cookie);
+                if (!$sc->getDomain()) {
+                    $sc->setDomain($request->getUri()->getHost());
+                }
+                if (0 !== strpos($sc->getPath(), '/')) {
+                    $sc->setPath($this->getCookiePathFromRequest($request));
+                }
+                $this->setCookie($sc);
+            }
+        }
+    }
+
+    /**
+     * Computes cookie path following RFC 6265 section 5.1.4
+     *
+     * @link https://tools.ietf.org/html/rfc6265#section-5.1.4
+     *
+     * @param RequestInterface $request
+     * @return string
+     */
+    private function getCookiePathFromRequest(RequestInterface $request)
+    {
+        $uriPath = $request->getUri()->getPath();
+        if (''  === $uriPath) {
+            return '/';
+        }
+        if (0 !== strpos($uriPath, '/')) {
+            return '/';
+        }
+        if ('/' === $uriPath) {
+            return '/';
+        }
+        if (0 === $lastSlashPos = strrpos($uriPath, '/')) {
+            return '/';
+        }
+
+        return substr($uriPath, 0, $lastSlashPos);
+    }
+
+    public function withCookieHeader(RequestInterface $request)
+    {
+        $values = [];
+        $uri = $request->getUri();
+        $scheme = $uri->getScheme();
+        $host = $uri->getHost();
+        $path = $uri->getPath() ?: '/';
+
+        foreach ($this->cookies as $cookie) {
+            if ($cookie->matchesPath($path) &&
+                $cookie->matchesDomain($host) &&
+                !$cookie->isExpired() &&
+                (!$cookie->getSecure() || $scheme === 'https')
+            ) {
+                $values[] = $cookie->getName() . '='
+                    . $cookie->getValue();
+            }
+        }
+
+        return $values
+            ? $request->withHeader('Cookie', implode('; ', $values))
+            : $request;
+    }
+
+    /**
+     * If a cookie already exists and the server asks to set it again with a
+     * null value, the cookie must be deleted.
+     *
+     * @param SetCookie $cookie
+     */
+    private function removeCookieIfEmpty(SetCookie $cookie)
+    {
+        $cookieValue = $cookie->getValue();
+        if ($cookieValue === null || $cookieValue === '') {
+            $this->clear(
+                $cookie->getDomain(),
+                $cookie->getPath(),
+                $cookie->getName()
+            );
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php
new file mode 100644 (file)
index 0000000..6ee1188
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+namespace GuzzleHttp\Cookie;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Stores HTTP cookies.
+ *
+ * It extracts cookies from HTTP requests, and returns them in HTTP responses.
+ * CookieJarInterface instances automatically expire contained cookies when
+ * necessary. Subclasses are also responsible for storing and retrieving
+ * cookies from a file, database, etc.
+ *
+ * @link http://docs.python.org/2/library/cookielib.html Inspiration
+ */
+interface CookieJarInterface extends \Countable, \IteratorAggregate
+{
+    /**
+     * Create a request with added cookie headers.
+     *
+     * If no matching cookies are found in the cookie jar, then no Cookie
+     * header is added to the request and the same request is returned.
+     *
+     * @param RequestInterface $request Request object to modify.
+     *
+     * @return RequestInterface returns the modified request.
+     */
+    public function withCookieHeader(RequestInterface $request);
+
+    /**
+     * Extract cookies from an HTTP response and store them in the CookieJar.
+     *
+     * @param RequestInterface  $request  Request that was sent
+     * @param ResponseInterface $response Response that was received
+     */
+    public function extractCookies(
+        RequestInterface $request,
+        ResponseInterface $response
+    );
+
+    /**
+     * Sets a cookie in the cookie jar.
+     *
+     * @param SetCookie $cookie Cookie to set.
+     *
+     * @return bool Returns true on success or false on failure
+     */
+    public function setCookie(SetCookie $cookie);
+
+    /**
+     * Remove cookies currently held in the cookie jar.
+     *
+     * Invoking this method without arguments will empty the whole cookie jar.
+     * If given a $domain argument only cookies belonging to that domain will
+     * be removed. If given a $domain and $path argument, cookies belonging to
+     * the specified path within that domain are removed. If given all three
+     * arguments, then the cookie with the specified name, path and domain is
+     * removed.
+     *
+     * @param string|null $domain Clears cookies matching a domain
+     * @param string|null $path   Clears cookies matching a domain and path
+     * @param string|null $name   Clears cookies matching a domain, path, and name
+     *
+     * @return CookieJarInterface
+     */
+    public function clear($domain = null, $path = null, $name = null);
+
+    /**
+     * Discard all sessions cookies.
+     *
+     * Removes cookies that don't have an expire field or a have a discard
+     * field set to true. To be called when the user agent shuts down according
+     * to RFC 2965.
+     */
+    public function clearSessionCookies();
+
+    /**
+     * Converts the cookie jar to an array.
+     *
+     * @return array
+     */
+    public function toArray();
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php
new file mode 100644 (file)
index 0000000..3fb8600
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+namespace GuzzleHttp\Cookie;
+
+/**
+ * Persists non-session cookies using a JSON formatted file
+ */
+class FileCookieJar extends CookieJar
+{
+    /** @var string filename */
+    private $filename;
+
+    /** @var bool Control whether to persist session cookies or not. */
+    private $storeSessionCookies;
+
+    /**
+     * Create a new FileCookieJar object
+     *
+     * @param string $cookieFile        File to store the cookie data
+     * @param bool $storeSessionCookies Set to true to store session cookies
+     *                                  in the cookie jar.
+     *
+     * @throws \RuntimeException if the file cannot be found or created
+     */
+    public function __construct($cookieFile, $storeSessionCookies = false)
+    {
+        parent::__construct();
+        $this->filename = $cookieFile;
+        $this->storeSessionCookies = $storeSessionCookies;
+
+        if (file_exists($cookieFile)) {
+            $this->load($cookieFile);
+        }
+    }
+
+    /**
+     * Saves the file when shutting down
+     */
+    public function __destruct()
+    {
+        $this->save($this->filename);
+    }
+
+    /**
+     * Saves the cookies to a file.
+     *
+     * @param string $filename File to save
+     * @throws \RuntimeException if the file cannot be found or created
+     */
+    public function save($filename)
+    {
+        $json = [];
+        foreach ($this as $cookie) {
+            /** @var SetCookie $cookie */
+            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
+                $json[] = $cookie->toArray();
+            }
+        }
+
+        $jsonStr = \GuzzleHttp\json_encode($json);
+        if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) {
+            throw new \RuntimeException("Unable to save file {$filename}");
+        }
+    }
+
+    /**
+     * Load cookies from a JSON formatted file.
+     *
+     * Old cookies are kept unless overwritten by newly loaded ones.
+     *
+     * @param string $filename Cookie file to load.
+     * @throws \RuntimeException if the file cannot be loaded.
+     */
+    public function load($filename)
+    {
+        $json = file_get_contents($filename);
+        if (false === $json) {
+            throw new \RuntimeException("Unable to load file {$filename}");
+        } elseif ($json === '') {
+            return;
+        }
+
+        $data = \GuzzleHttp\json_decode($json, true);
+        if (is_array($data)) {
+            foreach (json_decode($json, true) as $cookie) {
+                $this->setCookie(new SetCookie($cookie));
+            }
+        } elseif (strlen($data)) {
+            throw new \RuntimeException("Invalid cookie file: {$filename}");
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php
new file mode 100644 (file)
index 0000000..0224a24
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+namespace GuzzleHttp\Cookie;
+
+/**
+ * Persists cookies in the client session
+ */
+class SessionCookieJar extends CookieJar
+{
+    /** @var string session key */
+    private $sessionKey;
+    
+    /** @var bool Control whether to persist session cookies or not. */
+    private $storeSessionCookies;
+
+    /**
+     * Create a new SessionCookieJar object
+     *
+     * @param string $sessionKey        Session key name to store the cookie
+     *                                  data in session
+     * @param bool $storeSessionCookies Set to true to store session cookies
+     *                                  in the cookie jar.
+     */
+    public function __construct($sessionKey, $storeSessionCookies = false)
+    {
+        parent::__construct();
+        $this->sessionKey = $sessionKey;
+        $this->storeSessionCookies = $storeSessionCookies;
+        $this->load();
+    }
+
+    /**
+     * Saves cookies to session when shutting down
+     */
+    public function __destruct()
+    {
+        $this->save();
+    }
+
+    /**
+     * Save cookies to the client session
+     */
+    public function save()
+    {
+        $json = [];
+        foreach ($this as $cookie) {
+            /** @var SetCookie $cookie */
+            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
+                $json[] = $cookie->toArray();
+            }
+        }
+
+        $_SESSION[$this->sessionKey] = json_encode($json);
+    }
+
+    /**
+     * Load the contents of the client session into the data array
+     */
+    protected function load()
+    {
+        if (!isset($_SESSION[$this->sessionKey])) {
+            return;
+        }
+        $data = json_decode($_SESSION[$this->sessionKey], true);
+        if (is_array($data)) {
+            foreach ($data as $cookie) {
+                $this->setCookie(new SetCookie($cookie));
+            }
+        } elseif (strlen($data)) {
+            throw new \RuntimeException("Invalid cookie data");
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Cookie/SetCookie.php
new file mode 100644 (file)
index 0000000..3d776a7
--- /dev/null
@@ -0,0 +1,403 @@
+<?php
+namespace GuzzleHttp\Cookie;
+
+/**
+ * Set-Cookie object
+ */
+class SetCookie
+{
+    /** @var array */
+    private static $defaults = [
+        'Name'     => null,
+        'Value'    => null,
+        'Domain'   => null,
+        'Path'     => '/',
+        'Max-Age'  => null,
+        'Expires'  => null,
+        'Secure'   => false,
+        'Discard'  => false,
+        'HttpOnly' => false
+    ];
+
+    /** @var array Cookie data */
+    private $data;
+
+    /**
+     * Create a new SetCookie object from a string
+     *
+     * @param string $cookie Set-Cookie header string
+     *
+     * @return self
+     */
+    public static function fromString($cookie)
+    {
+        // Create the default return array
+        $data = self::$defaults;
+        // Explode the cookie string using a series of semicolons
+        $pieces = array_filter(array_map('trim', explode(';', $cookie)));
+        // The name of the cookie (first kvp) must exist and include an equal sign.
+        if (empty($pieces[0]) || !strpos($pieces[0], '=')) {
+            return new self($data);
+        }
+
+        // Add the cookie pieces into the parsed data array
+        foreach ($pieces as $part) {
+            $cookieParts = explode('=', $part, 2);
+            $key = trim($cookieParts[0]);
+            $value = isset($cookieParts[1])
+                ? trim($cookieParts[1], " \n\r\t\0\x0B")
+                : true;
+
+            // Only check for non-cookies when cookies have been found
+            if (empty($data['Name'])) {
+                $data['Name'] = $key;
+                $data['Value'] = $value;
+            } else {
+                foreach (array_keys(self::$defaults) as $search) {
+                    if (!strcasecmp($search, $key)) {
+                        $data[$search] = $value;
+                        continue 2;
+                    }
+                }
+                $data[$key] = $value;
+            }
+        }
+
+        return new self($data);
+    }
+
+    /**
+     * @param array $data Array of cookie data provided by a Cookie parser
+     */
+    public function __construct(array $data = [])
+    {
+        $this->data = array_replace(self::$defaults, $data);
+        // Extract the Expires value and turn it into a UNIX timestamp if needed
+        if (!$this->getExpires() && $this->getMaxAge()) {
+            // Calculate the Expires date
+            $this->setExpires(time() + $this->getMaxAge());
+        } elseif ($this->getExpires() && !is_numeric($this->getExpires())) {
+            $this->setExpires($this->getExpires());
+        }
+    }
+
+    public function __toString()
+    {
+        $str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
+        foreach ($this->data as $k => $v) {
+            if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
+                if ($k === 'Expires') {
+                    $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
+                } else {
+                    $str .= ($v === true ? $k : "{$k}={$v}") . '; ';
+                }
+            }
+        }
+
+        return rtrim($str, '; ');
+    }
+
+    public function toArray()
+    {
+        return $this->data;
+    }
+
+    /**
+     * Get the cookie name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->data['Name'];
+    }
+
+    /**
+     * Set the cookie name
+     *
+     * @param string $name Cookie name
+     */
+    public function setName($name)
+    {
+        $this->data['Name'] = $name;
+    }
+
+    /**
+     * Get the cookie value
+     *
+     * @return string
+     */
+    public function getValue()
+    {
+        return $this->data['Value'];
+    }
+
+    /**
+     * Set the cookie value
+     *
+     * @param string $value Cookie value
+     */
+    public function setValue($value)
+    {
+        $this->data['Value'] = $value;
+    }
+
+    /**
+     * Get the domain
+     *
+     * @return string|null
+     */
+    public function getDomain()
+    {
+        return $this->data['Domain'];
+    }
+
+    /**
+     * Set the domain of the cookie
+     *
+     * @param string $domain
+     */
+    public function setDomain($domain)
+    {
+        $this->data['Domain'] = $domain;
+    }
+
+    /**
+     * Get the path
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->data['Path'];
+    }
+
+    /**
+     * Set the path of the cookie
+     *
+     * @param string $path Path of the cookie
+     */
+    public function setPath($path)
+    {
+        $this->data['Path'] = $path;
+    }
+
+    /**
+     * Maximum lifetime of the cookie in seconds
+     *
+     * @return int|null
+     */
+    public function getMaxAge()
+    {
+        return $this->data['Max-Age'];
+    }
+
+    /**
+     * Set the max-age of the cookie
+     *
+     * @param int $maxAge Max age of the cookie in seconds
+     */
+    public function setMaxAge($maxAge)
+    {
+        $this->data['Max-Age'] = $maxAge;
+    }
+
+    /**
+     * The UNIX timestamp when the cookie Expires
+     *
+     * @return mixed
+     */
+    public function getExpires()
+    {
+        return $this->data['Expires'];
+    }
+
+    /**
+     * Set the unix timestamp for which the cookie will expire
+     *
+     * @param int $timestamp Unix timestamp
+     */
+    public function setExpires($timestamp)
+    {
+        $this->data['Expires'] = is_numeric($timestamp)
+            ? (int) $timestamp
+            : strtotime($timestamp);
+    }
+
+    /**
+     * Get whether or not this is a secure cookie
+     *
+     * @return bool|null
+     */
+    public function getSecure()
+    {
+        return $this->data['Secure'];
+    }
+
+    /**
+     * Set whether or not the cookie is secure
+     *
+     * @param bool $secure Set to true or false if secure
+     */
+    public function setSecure($secure)
+    {
+        $this->data['Secure'] = $secure;
+    }
+
+    /**
+     * Get whether or not this is a session cookie
+     *
+     * @return bool|null
+     */
+    public function getDiscard()
+    {
+        return $this->data['Discard'];
+    }
+
+    /**
+     * Set whether or not this is a session cookie
+     *
+     * @param bool $discard Set to true or false if this is a session cookie
+     */
+    public function setDiscard($discard)
+    {
+        $this->data['Discard'] = $discard;
+    }
+
+    /**
+     * Get whether or not this is an HTTP only cookie
+     *
+     * @return bool
+     */
+    public function getHttpOnly()
+    {
+        return $this->data['HttpOnly'];
+    }
+
+    /**
+     * Set whether or not this is an HTTP only cookie
+     *
+     * @param bool $httpOnly Set to true or false if this is HTTP only
+     */
+    public function setHttpOnly($httpOnly)
+    {
+        $this->data['HttpOnly'] = $httpOnly;
+    }
+
+    /**
+     * Check if the cookie matches a path value.
+     *
+     * A request-path path-matches a given cookie-path if at least one of
+     * the following conditions holds:
+     *
+     * - The cookie-path and the request-path are identical.
+     * - The cookie-path is a prefix of the request-path, and the last
+     *   character of the cookie-path is %x2F ("/").
+     * - The cookie-path is a prefix of the request-path, and the first
+     *   character of the request-path that is not included in the cookie-
+     *   path is a %x2F ("/") character.
+     *
+     * @param string $requestPath Path to check against
+     *
+     * @return bool
+     */
+    public function matchesPath($requestPath)
+    {
+        $cookiePath = $this->getPath();
+
+        // Match on exact matches or when path is the default empty "/"
+        if ($cookiePath === '/' || $cookiePath == $requestPath) {
+            return true;
+        }
+
+        // Ensure that the cookie-path is a prefix of the request path.
+        if (0 !== strpos($requestPath, $cookiePath)) {
+            return false;
+        }
+
+        // Match if the last character of the cookie-path is "/"
+        if (substr($cookiePath, -1, 1) === '/') {
+            return true;
+        }
+
+        // Match if the first character not included in cookie path is "/"
+        return substr($requestPath, strlen($cookiePath), 1) === '/';
+    }
+
+    /**
+     * Check if the cookie matches a domain value
+     *
+     * @param string $domain Domain to check against
+     *
+     * @return bool
+     */
+    public function matchesDomain($domain)
+    {
+        // Remove the leading '.' as per spec in RFC 6265.
+        // http://tools.ietf.org/html/rfc6265#section-5.2.3
+        $cookieDomain = ltrim($this->getDomain(), '.');
+
+        // Domain not set or exact match.
+        if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) {
+            return true;
+        }
+
+        // Matching the subdomain according to RFC 6265.
+        // http://tools.ietf.org/html/rfc6265#section-5.1.3
+        if (filter_var($domain, FILTER_VALIDATE_IP)) {
+            return false;
+        }
+
+        return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/', $domain);
+    }
+
+    /**
+     * Check if the cookie is expired
+     *
+     * @return bool
+     */
+    public function isExpired()
+    {
+        return $this->getExpires() !== null && time() > $this->getExpires();
+    }
+
+    /**
+     * Check if the cookie is valid according to RFC 6265
+     *
+     * @return bool|string Returns true if valid or an error message if invalid
+     */
+    public function validate()
+    {
+        // Names must not be empty, but can be 0
+        $name = $this->getName();
+        if (empty($name) && !is_numeric($name)) {
+            return 'The cookie name must not be empty';
+        }
+
+        // Check if any of the invalid characters are present in the cookie name
+        if (preg_match(
+            '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/',
+            $name
+        )) {
+            return 'Cookie name must not contain invalid characters: ASCII '
+                . 'Control characters (0-31;127), space, tab and the '
+                . 'following characters: ()<>@,;:\"/?={}';
+        }
+
+        // Value must not be empty, but can be 0
+        $value = $this->getValue();
+        if (empty($value) && !is_numeric($value)) {
+            return 'The cookie value must not be empty';
+        }
+
+        // Domains must not be empty, but can be 0
+        // A "0" is not a valid internet domain, but may be used as server name
+        // in a private network.
+        $domain = $this->getDomain();
+        if (empty($domain) && !is_numeric($domain)) {
+            return 'The cookie domain must not be empty';
+        }
+
+        return true;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/BadResponseException.php
new file mode 100644 (file)
index 0000000..427d896
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Exception when an HTTP error occurs (4xx or 5xx error)
+ */
+class BadResponseException extends RequestException
+{
+    public function __construct(
+        $message,
+        RequestInterface $request,
+        ResponseInterface $response = null,
+        \Exception $previous = null,
+        array $handlerContext = []
+    ) {
+        if (null === $response) {
+            @trigger_error(
+                'Instantiating the ' . __CLASS__ . ' class without a Response is deprecated since version 6.3 and will be removed in 7.0.',
+                E_USER_DEPRECATED
+            );
+        }
+        parent::__construct($message, $request, $response, $previous, $handlerContext);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ClientException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ClientException.php
new file mode 100644 (file)
index 0000000..4cfd393
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+/**
+ * Exception when a client error is encountered (4xx codes)
+ */
+class ClientException extends BadResponseException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ConnectException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ConnectException.php
new file mode 100644 (file)
index 0000000..d33b0cc
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Exception thrown when a connection cannot be established.
+ *
+ * Note that no response is present for a ConnectException
+ */
+class ConnectException extends RequestException
+{
+    public function __construct(
+        $message,
+        RequestInterface $request,
+        \Exception $previous = null,
+        array $handlerContext = []
+    ) {
+        parent::__construct($message, $request, null, $previous, $handlerContext);
+    }
+
+    /**
+     * @return null
+     */
+    public function getResponse()
+    {
+        return null;
+    }
+
+    /**
+     * @return bool
+     */
+    public function hasResponse()
+    {
+        return false;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/GuzzleException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/GuzzleException.php
new file mode 100644 (file)
index 0000000..27b2722
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+use Throwable;
+
+if (interface_exists(Throwable::class)) {
+    interface GuzzleException extends Throwable
+    {
+    }
+} else {
+    /**
+     * @method string getMessage()
+     * @method \Throwable|null getPrevious()
+     * @method mixed getCode()
+     * @method string getFile()
+     * @method int getLine()
+     * @method array getTrace()
+     * @method string getTraceAsString()
+     */
+    interface GuzzleException
+    {
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php
new file mode 100644 (file)
index 0000000..bfd20e2
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+final class InvalidArgumentException extends \InvalidArgumentException implements GuzzleException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/RequestException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/RequestException.php
new file mode 100644 (file)
index 0000000..12dd081
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * HTTP Request exception
+ */
+class RequestException extends TransferException
+{
+    /** @var RequestInterface */
+    private $request;
+
+    /** @var ResponseInterface|null */
+    private $response;
+
+    /** @var array */
+    private $handlerContext;
+
+    public function __construct(
+        $message,
+        RequestInterface $request,
+        ResponseInterface $response = null,
+        \Exception $previous = null,
+        array $handlerContext = []
+    ) {
+        // Set the code of the exception if the response is set and not future.
+        $code = $response && !($response instanceof PromiseInterface)
+            ? $response->getStatusCode()
+            : 0;
+        parent::__construct($message, $code, $previous);
+        $this->request = $request;
+        $this->response = $response;
+        $this->handlerContext = $handlerContext;
+    }
+
+    /**
+     * Wrap non-RequestExceptions with a RequestException
+     *
+     * @param RequestInterface $request
+     * @param \Exception       $e
+     *
+     * @return RequestException
+     */
+    public static function wrapException(RequestInterface $request, \Exception $e)
+    {
+        return $e instanceof RequestException
+            ? $e
+            : new RequestException($e->getMessage(), $request, null, $e);
+    }
+
+    /**
+     * Factory method to create a new exception with a normalized error message
+     *
+     * @param RequestInterface  $request  Request
+     * @param ResponseInterface $response Response received
+     * @param \Exception        $previous Previous exception
+     * @param array             $ctx      Optional handler context.
+     *
+     * @return self
+     */
+    public static function create(
+        RequestInterface $request,
+        ResponseInterface $response = null,
+        \Exception $previous = null,
+        array $ctx = []
+    ) {
+        if (!$response) {
+            return new self(
+                'Error completing request',
+                $request,
+                null,
+                $previous,
+                $ctx
+            );
+        }
+
+        $level = (int) floor($response->getStatusCode() / 100);
+        if ($level === 4) {
+            $label = 'Client error';
+            $className = ClientException::class;
+        } elseif ($level === 5) {
+            $label = 'Server error';
+            $className = ServerException::class;
+        } else {
+            $label = 'Unsuccessful request';
+            $className = __CLASS__;
+        }
+
+        $uri = $request->getUri();
+        $uri = static::obfuscateUri($uri);
+
+        // Client Error: `GET /` resulted in a `404 Not Found` response:
+        // <html> ... (truncated)
+        $message = sprintf(
+            '%s: `%s %s` resulted in a `%s %s` response',
+            $label,
+            $request->getMethod(),
+            $uri,
+            $response->getStatusCode(),
+            $response->getReasonPhrase()
+        );
+
+        $summary = static::getResponseBodySummary($response);
+
+        if ($summary !== null) {
+            $message .= ":\n{$summary}\n";
+        }
+
+        return new $className($message, $request, $response, $previous, $ctx);
+    }
+
+    /**
+     * Get a short summary of the response
+     *
+     * Will return `null` if the response is not printable.
+     *
+     * @param ResponseInterface $response
+     *
+     * @return string|null
+     */
+    public static function getResponseBodySummary(ResponseInterface $response)
+    {
+        return \GuzzleHttp\Psr7\get_message_body_summary($response);
+    }
+
+    /**
+     * Obfuscates URI if there is a username and a password present
+     *
+     * @param UriInterface $uri
+     *
+     * @return UriInterface
+     */
+    private static function obfuscateUri(UriInterface $uri)
+    {
+        $userInfo = $uri->getUserInfo();
+
+        if (false !== ($pos = strpos($userInfo, ':'))) {
+            return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
+        }
+
+        return $uri;
+    }
+
+    /**
+     * Get the request that caused the exception
+     *
+     * @return RequestInterface
+     */
+    public function getRequest()
+    {
+        return $this->request;
+    }
+
+    /**
+     * Get the associated response
+     *
+     * @return ResponseInterface|null
+     */
+    public function getResponse()
+    {
+        return $this->response;
+    }
+
+    /**
+     * Check if a response was received
+     *
+     * @return bool
+     */
+    public function hasResponse()
+    {
+        return $this->response !== null;
+    }
+
+    /**
+     * Get contextual information about the error from the underlying handler.
+     *
+     * The contents of this array will vary depending on which handler you are
+     * using. It may also be just an empty array. Relying on this data will
+     * couple you to a specific handler, but can give more debug information
+     * when needed.
+     *
+     * @return array
+     */
+    public function getHandlerContext()
+    {
+        return $this->handlerContext;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/SeekException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/SeekException.php
new file mode 100644 (file)
index 0000000..a77c289
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Exception thrown when a seek fails on a stream.
+ */
+class SeekException extends \RuntimeException implements GuzzleException
+{
+    private $stream;
+
+    public function __construct(StreamInterface $stream, $pos = 0, $msg = '')
+    {
+        $this->stream = $stream;
+        $msg = $msg ?: 'Could not seek the stream to position ' . $pos;
+        parent::__construct($msg);
+    }
+
+    /**
+     * @return StreamInterface
+     */
+    public function getStream()
+    {
+        return $this->stream;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ServerException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/ServerException.php
new file mode 100644 (file)
index 0000000..127094c
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+/**
+ * Exception when a server error is encountered (5xx codes)
+ */
+class ServerException extends BadResponseException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php
new file mode 100644 (file)
index 0000000..fff0525
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+class TooManyRedirectsException extends RequestException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/TransferException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Exception/TransferException.php
new file mode 100644 (file)
index 0000000..7c11db3
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+namespace GuzzleHttp\Exception;
+
+class TransferException extends \RuntimeException implements GuzzleException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlFactory.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlFactory.php
new file mode 100644 (file)
index 0000000..4bcbb35
--- /dev/null
@@ -0,0 +1,583 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Exception\ConnectException;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Promise\FulfilledPromise;
+use GuzzleHttp\Psr7\LazyOpenStream;
+use GuzzleHttp\TransferStats;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Creates curl resources from a request
+ */
+class CurlFactory implements CurlFactoryInterface
+{
+    const CURL_VERSION_STR = 'curl_version';
+    const LOW_CURL_VERSION_NUMBER = '7.21.2';
+
+    /** @var array */
+    private $handles = [];
+
+    /** @var int Total number of idle handles to keep in cache */
+    private $maxHandles;
+
+    /**
+     * @param int $maxHandles Maximum number of idle handles.
+     */
+    public function __construct($maxHandles)
+    {
+        $this->maxHandles = $maxHandles;
+    }
+
+    public function create(RequestInterface $request, array $options)
+    {
+        if (isset($options['curl']['body_as_string'])) {
+            $options['_body_as_string'] = $options['curl']['body_as_string'];
+            unset($options['curl']['body_as_string']);
+        }
+
+        $easy = new EasyHandle;
+        $easy->request = $request;
+        $easy->options = $options;
+        $conf = $this->getDefaultConf($easy);
+        $this->applyMethod($easy, $conf);
+        $this->applyHandlerOptions($easy, $conf);
+        $this->applyHeaders($easy, $conf);
+        unset($conf['_headers']);
+
+        // Add handler options from the request configuration options
+        if (isset($options['curl'])) {
+            $conf = array_replace($conf, $options['curl']);
+        }
+
+        $conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
+        $easy->handle = $this->handles
+            ? array_pop($this->handles)
+            : curl_init();
+        curl_setopt_array($easy->handle, $conf);
+
+        return $easy;
+    }
+
+    public function release(EasyHandle $easy)
+    {
+        $resource = $easy->handle;
+        unset($easy->handle);
+
+        if (count($this->handles) >= $this->maxHandles) {
+            curl_close($resource);
+        } else {
+            // Remove all callback functions as they can hold onto references
+            // and are not cleaned up by curl_reset. Using curl_setopt_array
+            // does not work for some reason, so removing each one
+            // individually.
+            curl_setopt($resource, CURLOPT_HEADERFUNCTION, null);
+            curl_setopt($resource, CURLOPT_READFUNCTION, null);
+            curl_setopt($resource, CURLOPT_WRITEFUNCTION, null);
+            curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null);
+            curl_reset($resource);
+            $this->handles[] = $resource;
+        }
+    }
+
+    /**
+     * Completes a cURL transaction, either returning a response promise or a
+     * rejected promise.
+     *
+     * @param callable             $handler
+     * @param EasyHandle           $easy
+     * @param CurlFactoryInterface $factory Dictates how the handle is released
+     *
+     * @return \GuzzleHttp\Promise\PromiseInterface
+     */
+    public static function finish(
+        callable $handler,
+        EasyHandle $easy,
+        CurlFactoryInterface $factory
+    ) {
+        if (isset($easy->options['on_stats'])) {
+            self::invokeStats($easy);
+        }
+
+        if (!$easy->response || $easy->errno) {
+            return self::finishError($handler, $easy, $factory);
+        }
+
+        // Return the response if it is present and there is no error.
+        $factory->release($easy);
+
+        // Rewind the body of the response if possible.
+        $body = $easy->response->getBody();
+        if ($body->isSeekable()) {
+            $body->rewind();
+        }
+
+        return new FulfilledPromise($easy->response);
+    }
+
+    private static function invokeStats(EasyHandle $easy)
+    {
+        $curlStats = curl_getinfo($easy->handle);
+        $curlStats['appconnect_time'] = curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME);
+        $stats = new TransferStats(
+            $easy->request,
+            $easy->response,
+            $curlStats['total_time'],
+            $easy->errno,
+            $curlStats
+        );
+        call_user_func($easy->options['on_stats'], $stats);
+    }
+
+    private static function finishError(
+        callable $handler,
+        EasyHandle $easy,
+        CurlFactoryInterface $factory
+    ) {
+        // Get error information and release the handle to the factory.
+        $ctx = [
+            'errno' => $easy->errno,
+            'error' => curl_error($easy->handle),
+            'appconnect_time' => curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME),
+        ] + curl_getinfo($easy->handle);
+        $ctx[self::CURL_VERSION_STR] = curl_version()['version'];
+        $factory->release($easy);
+
+        // Retry when nothing is present or when curl failed to rewind.
+        if (empty($easy->options['_err_message'])
+            && (!$easy->errno || $easy->errno == 65)
+        ) {
+            return self::retryFailedRewind($handler, $easy, $ctx);
+        }
+
+        return self::createRejection($easy, $ctx);
+    }
+
+    private static function createRejection(EasyHandle $easy, array $ctx)
+    {
+        static $connectionErrors = [
+            CURLE_OPERATION_TIMEOUTED  => true,
+            CURLE_COULDNT_RESOLVE_HOST => true,
+            CURLE_COULDNT_CONNECT      => true,
+            CURLE_SSL_CONNECT_ERROR    => true,
+            CURLE_GOT_NOTHING          => true,
+        ];
+
+        // If an exception was encountered during the onHeaders event, then
+        // return a rejected promise that wraps that exception.
+        if ($easy->onHeadersException) {
+            return \GuzzleHttp\Promise\rejection_for(
+                new RequestException(
+                    'An error was encountered during the on_headers event',
+                    $easy->request,
+                    $easy->response,
+                    $easy->onHeadersException,
+                    $ctx
+                )
+            );
+        }
+        if (version_compare($ctx[self::CURL_VERSION_STR], self::LOW_CURL_VERSION_NUMBER)) {
+            $message = sprintf(
+                'cURL error %s: %s (%s)',
+                $ctx['errno'],
+                $ctx['error'],
+                'see https://curl.haxx.se/libcurl/c/libcurl-errors.html'
+            );
+        } else {
+            $message = sprintf(
+                'cURL error %s: %s (%s) for %s',
+                $ctx['errno'],
+                $ctx['error'],
+                'see https://curl.haxx.se/libcurl/c/libcurl-errors.html',
+                $easy->request->getUri()
+            );
+        }
+
+        // Create a connection exception if it was a specific error code.
+        $error = isset($connectionErrors[$easy->errno])
+            ? new ConnectException($message, $easy->request, null, $ctx)
+            : new RequestException($message, $easy->request, $easy->response, null, $ctx);
+
+        return \GuzzleHttp\Promise\rejection_for($error);
+    }
+
+    private function getDefaultConf(EasyHandle $easy)
+    {
+        $conf = [
+            '_headers'             => $easy->request->getHeaders(),
+            CURLOPT_CUSTOMREQUEST  => $easy->request->getMethod(),
+            CURLOPT_URL            => (string) $easy->request->getUri()->withFragment(''),
+            CURLOPT_RETURNTRANSFER => false,
+            CURLOPT_HEADER         => false,
+            CURLOPT_CONNECTTIMEOUT => 150,
+        ];
+
+        if (defined('CURLOPT_PROTOCOLS')) {
+            $conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS;
+        }
+
+        $version = $easy->request->getProtocolVersion();
+        if ($version == 1.1) {
+            $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
+        } elseif ($version == 2.0) {
+            $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
+        } else {
+            $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
+        }
+
+        return $conf;
+    }
+
+    private function applyMethod(EasyHandle $easy, array &$conf)
+    {
+        $body = $easy->request->getBody();
+        $size = $body->getSize();
+
+        if ($size === null || $size > 0) {
+            $this->applyBody($easy->request, $easy->options, $conf);
+            return;
+        }
+
+        $method = $easy->request->getMethod();
+        if ($method === 'PUT' || $method === 'POST') {
+            // See http://tools.ietf.org/html/rfc7230#section-3.3.2
+            if (!$easy->request->hasHeader('Content-Length')) {
+                $conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
+            }
+        } elseif ($method === 'HEAD') {
+            $conf[CURLOPT_NOBODY] = true;
+            unset(
+                $conf[CURLOPT_WRITEFUNCTION],
+                $conf[CURLOPT_READFUNCTION],
+                $conf[CURLOPT_FILE],
+                $conf[CURLOPT_INFILE]
+            );
+        }
+    }
+
+    private function applyBody(RequestInterface $request, array $options, array &$conf)
+    {
+        $size = $request->hasHeader('Content-Length')
+            ? (int) $request->getHeaderLine('Content-Length')
+            : null;
+
+        // Send the body as a string if the size is less than 1MB OR if the
+        // [curl][body_as_string] request value is set.
+        if (($size !== null && $size < 1000000) ||
+            !empty($options['_body_as_string'])
+        ) {
+            $conf[CURLOPT_POSTFIELDS] = (string) $request->getBody();
+            // Don't duplicate the Content-Length header
+            $this->removeHeader('Content-Length', $conf);
+            $this->removeHeader('Transfer-Encoding', $conf);
+        } else {
+            $conf[CURLOPT_UPLOAD] = true;
+            if ($size !== null) {
+                $conf[CURLOPT_INFILESIZE] = $size;
+                $this->removeHeader('Content-Length', $conf);
+            }
+            $body = $request->getBody();
+            if ($body->isSeekable()) {
+                $body->rewind();
+            }
+            $conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) {
+                return $body->read($length);
+            };
+        }
+
+        // If the Expect header is not present, prevent curl from adding it
+        if (!$request->hasHeader('Expect')) {
+            $conf[CURLOPT_HTTPHEADER][] = 'Expect:';
+        }
+
+        // cURL sometimes adds a content-type by default. Prevent this.
+        if (!$request->hasHeader('Content-Type')) {
+            $conf[CURLOPT_HTTPHEADER][] = 'Content-Type:';
+        }
+    }
+
+    private function applyHeaders(EasyHandle $easy, array &$conf)
+    {
+        foreach ($conf['_headers'] as $name => $values) {
+            foreach ($values as $value) {
+                $value = (string) $value;
+                if ($value === '') {
+                    // cURL requires a special format for empty headers.
+                    // See https://github.com/guzzle/guzzle/issues/1882 for more details.
+                    $conf[CURLOPT_HTTPHEADER][] = "$name;";
+                } else {
+                    $conf[CURLOPT_HTTPHEADER][] = "$name: $value";
+                }
+            }
+        }
+
+        // Remove the Accept header if one was not set
+        if (!$easy->request->hasHeader('Accept')) {
+            $conf[CURLOPT_HTTPHEADER][] = 'Accept:';
+        }
+    }
+
+    /**
+     * Remove a header from the options array.
+     *
+     * @param string $name    Case-insensitive header to remove
+     * @param array  $options Array of options to modify
+     */
+    private function removeHeader($name, array &$options)
+    {
+        foreach (array_keys($options['_headers']) as $key) {
+            if (!strcasecmp($key, $name)) {
+                unset($options['_headers'][$key]);
+                return;
+            }
+        }
+    }
+
+    private function applyHandlerOptions(EasyHandle $easy, array &$conf)
+    {
+        $options = $easy->options;
+        if (isset($options['verify'])) {
+            if ($options['verify'] === false) {
+                unset($conf[CURLOPT_CAINFO]);
+                $conf[CURLOPT_SSL_VERIFYHOST] = 0;
+                $conf[CURLOPT_SSL_VERIFYPEER] = false;
+            } else {
+                $conf[CURLOPT_SSL_VERIFYHOST] = 2;
+                $conf[CURLOPT_SSL_VERIFYPEER] = true;
+                if (is_string($options['verify'])) {
+                    // Throw an error if the file/folder/link path is not valid or doesn't exist.
+                    if (!file_exists($options['verify'])) {
+                        throw new \InvalidArgumentException(
+                            "SSL CA bundle not found: {$options['verify']}"
+                        );
+                    }
+                    // If it's a directory or a link to a directory use CURLOPT_CAPATH.
+                    // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
+                    if (is_dir($options['verify']) ||
+                        (is_link($options['verify']) && is_dir(readlink($options['verify'])))) {
+                        $conf[CURLOPT_CAPATH] = $options['verify'];
+                    } else {
+                        $conf[CURLOPT_CAINFO] = $options['verify'];
+                    }
+                }
+            }
+        }
+
+        if (!empty($options['decode_content'])) {
+            $accept = $easy->request->getHeaderLine('Accept-Encoding');
+            if ($accept) {
+                $conf[CURLOPT_ENCODING] = $accept;
+            } else {
+                $conf[CURLOPT_ENCODING] = '';
+                // Don't let curl send the header over the wire
+                $conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
+            }
+        }
+
+        if (!isset($options['sink'])) {
+            // Use a default temp stream if no sink was set.
+            $options['sink'] = \fopen('php://temp', 'w+');
+        }
+        $sink = $options['sink'];
+        if (!is_string($sink)) {
+            $sink = \GuzzleHttp\Psr7\stream_for($sink);
+        } elseif (!is_dir(dirname($sink))) {
+            // Ensure that the directory exists before failing in curl.
+            throw new \RuntimeException(sprintf(
+                'Directory %s does not exist for sink value of %s',
+                dirname($sink),
+                $sink
+            ));
+        } else {
+            $sink = new LazyOpenStream($sink, 'w+');
+        }
+        $easy->sink = $sink;
+        $conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) {
+            return $sink->write($write);
+        };
+
+        $timeoutRequiresNoSignal = false;
+        if (isset($options['timeout'])) {
+            $timeoutRequiresNoSignal |= $options['timeout'] < 1;
+            $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
+        }
+
+        // CURL default value is CURL_IPRESOLVE_WHATEVER
+        if (isset($options['force_ip_resolve'])) {
+            if ('v4' === $options['force_ip_resolve']) {
+                $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;
+            } elseif ('v6' === $options['force_ip_resolve']) {
+                $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6;
+            }
+        }
+
+        if (isset($options['connect_timeout'])) {
+            $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
+            $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
+        }
+
+        if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
+            $conf[CURLOPT_NOSIGNAL] = true;
+        }
+
+        if (isset($options['proxy'])) {
+            if (!is_array($options['proxy'])) {
+                $conf[CURLOPT_PROXY] = $options['proxy'];
+            } else {
+                $scheme = $easy->request->getUri()->getScheme();
+                if (isset($options['proxy'][$scheme])) {
+                    $host = $easy->request->getUri()->getHost();
+                    if (!isset($options['proxy']['no']) ||
+                        !\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no'])
+                    ) {
+                        $conf[CURLOPT_PROXY] = $options['proxy'][$scheme];
+                    }
+                }
+            }
+        }
+
+        if (isset($options['cert'])) {
+            $cert = $options['cert'];
+            if (is_array($cert)) {
+                $conf[CURLOPT_SSLCERTPASSWD] = $cert[1];
+                $cert = $cert[0];
+            }
+            if (!file_exists($cert)) {
+                throw new \InvalidArgumentException(
+                    "SSL certificate not found: {$cert}"
+                );
+            }
+            $conf[CURLOPT_SSLCERT] = $cert;
+        }
+
+        if (isset($options['ssl_key'])) {
+            if (is_array($options['ssl_key'])) {
+                if (count($options['ssl_key']) === 2) {
+                    list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key'];
+                } else {
+                    list($sslKey) = $options['ssl_key'];
+                }
+            }
+
+            $sslKey = isset($sslKey) ? $sslKey: $options['ssl_key'];
+
+            if (!file_exists($sslKey)) {
+                throw new \InvalidArgumentException(
+                    "SSL private key not found: {$sslKey}"
+                );
+            }
+            $conf[CURLOPT_SSLKEY] = $sslKey;
+        }
+
+        if (isset($options['progress'])) {
+            $progress = $options['progress'];
+            if (!is_callable($progress)) {
+                throw new \InvalidArgumentException(
+                    'progress client option must be callable'
+                );
+            }
+            $conf[CURLOPT_NOPROGRESS] = false;
+            $conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) {
+                $args = func_get_args();
+                // PHP 5.5 pushed the handle onto the start of the args
+                if (is_resource($args[0])) {
+                    array_shift($args);
+                }
+                call_user_func_array($progress, $args);
+            };
+        }
+
+        if (!empty($options['debug'])) {
+            $conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']);
+            $conf[CURLOPT_VERBOSE] = true;
+        }
+    }
+
+    /**
+     * This function ensures that a response was set on a transaction. If one
+     * was not set, then the request is retried if possible. This error
+     * typically means you are sending a payload, curl encountered a
+     * "Connection died, retrying a fresh connect" error, tried to rewind the
+     * stream, and then encountered a "necessary data rewind wasn't possible"
+     * error, causing the request to be sent through curl_multi_info_read()
+     * without an error status.
+     */
+    private static function retryFailedRewind(
+        callable $handler,
+        EasyHandle $easy,
+        array $ctx
+    ) {
+        try {
+            // Only rewind if the body has been read from.
+            $body = $easy->request->getBody();
+            if ($body->tell() > 0) {
+                $body->rewind();
+            }
+        } catch (\RuntimeException $e) {
+            $ctx['error'] = 'The connection unexpectedly failed without '
+                . 'providing an error. The request would have been retried, '
+                . 'but attempting to rewind the request body failed. '
+                . 'Exception: ' . $e;
+            return self::createRejection($easy, $ctx);
+        }
+
+        // Retry no more than 3 times before giving up.
+        if (!isset($easy->options['_curl_retries'])) {
+            $easy->options['_curl_retries'] = 1;
+        } elseif ($easy->options['_curl_retries'] == 2) {
+            $ctx['error'] = 'The cURL request was retried 3 times '
+                . 'and did not succeed. The most likely reason for the failure '
+                . 'is that cURL was unable to rewind the body of the request '
+                . 'and subsequent retries resulted in the same error. Turn on '
+                . 'the debug option to see what went wrong. See '
+                . 'https://bugs.php.net/bug.php?id=47204 for more information.';
+            return self::createRejection($easy, $ctx);
+        } else {
+            $easy->options['_curl_retries']++;
+        }
+
+        return $handler($easy->request, $easy->options);
+    }
+
+    private function createHeaderFn(EasyHandle $easy)
+    {
+        if (isset($easy->options['on_headers'])) {
+            $onHeaders = $easy->options['on_headers'];
+
+            if (!is_callable($onHeaders)) {
+                throw new \InvalidArgumentException('on_headers must be callable');
+            }
+        } else {
+            $onHeaders = null;
+        }
+
+        return function ($ch, $h) use (
+            $onHeaders,
+            $easy,
+            &$startingResponse
+        ) {
+            $value = trim($h);
+            if ($value === '') {
+                $startingResponse = true;
+                $easy->createResponse();
+                if ($onHeaders !== null) {
+                    try {
+                        $onHeaders($easy->response);
+                    } catch (\Exception $e) {
+                        // Associate the exception with the handle and trigger
+                        // a curl header write error by returning 0.
+                        $easy->onHeadersException = $e;
+                        return -1;
+                    }
+                }
+            } elseif ($startingResponse) {
+                $startingResponse = false;
+                $easy->headers = [$value];
+            } else {
+                $easy->headers[] = $value;
+            }
+            return strlen($h);
+        };
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php
new file mode 100644 (file)
index 0000000..b0fc236
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use Psr\Http\Message\RequestInterface;
+
+interface CurlFactoryInterface
+{
+    /**
+     * Creates a cURL handle resource.
+     *
+     * @param RequestInterface $request Request
+     * @param array            $options Transfer options
+     *
+     * @return EasyHandle
+     * @throws \RuntimeException when an option cannot be applied
+     */
+    public function create(RequestInterface $request, array $options);
+
+    /**
+     * Release an easy handle, allowing it to be reused or closed.
+     *
+     * This function must call unset on the easy handle's "handle" property.
+     *
+     * @param EasyHandle $easy
+     */
+    public function release(EasyHandle $easy);
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlHandler.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlHandler.php
new file mode 100644 (file)
index 0000000..43577da
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * HTTP handler that uses cURL easy handles as a transport layer.
+ *
+ * When using the CurlHandler, custom curl options can be specified as an
+ * associative array of curl option constants mapping to values in the
+ * **curl** key of the "client" key of the request.
+ */
+class CurlHandler
+{
+    /** @var CurlFactoryInterface */
+    private $factory;
+
+    /**
+     * Accepts an associative array of options:
+     *
+     * - factory: Optional curl factory used to create cURL handles.
+     *
+     * @param array $options Array of options to use with the handler
+     */
+    public function __construct(array $options = [])
+    {
+        $this->factory = isset($options['handle_factory'])
+            ? $options['handle_factory']
+            : new CurlFactory(3);
+    }
+
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        if (isset($options['delay'])) {
+            usleep($options['delay'] * 1000);
+        }
+
+        $easy = $this->factory->create($request, $options);
+        curl_exec($easy->handle);
+        $easy->errno = curl_errno($easy->handle);
+
+        return CurlFactory::finish($this, $easy, $this->factory);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php
new file mode 100644 (file)
index 0000000..564c95f
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\Promise;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Returns an asynchronous response using curl_multi_* functions.
+ *
+ * When using the CurlMultiHandler, custom curl options can be specified as an
+ * associative array of curl option constants mapping to values in the
+ * **curl** key of the provided request options.
+ *
+ * @property resource $_mh Internal use only. Lazy loaded multi-handle.
+ */
+class CurlMultiHandler
+{
+    /** @var CurlFactoryInterface */
+    private $factory;
+    private $selectTimeout;
+    private $active;
+    private $handles = [];
+    private $delays = [];
+    private $options = [];
+
+    /**
+     * This handler accepts the following options:
+     *
+     * - handle_factory: An optional factory  used to create curl handles
+     * - select_timeout: Optional timeout (in seconds) to block before timing
+     *   out while selecting curl handles. Defaults to 1 second.
+     * - options: An associative array of CURLMOPT_* options and
+     *   corresponding values for curl_multi_setopt()
+     *
+     * @param array $options
+     */
+    public function __construct(array $options = [])
+    {
+        $this->factory = isset($options['handle_factory'])
+            ? $options['handle_factory'] : new CurlFactory(50);
+
+        if (isset($options['select_timeout'])) {
+            $this->selectTimeout = $options['select_timeout'];
+        } elseif ($selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT')) {
+            $this->selectTimeout = $selectTimeout;
+        } else {
+            $this->selectTimeout = 1;
+        }
+
+        $this->options = isset($options['options']) ? $options['options'] : [];
+    }
+
+    public function __get($name)
+    {
+        if ($name === '_mh') {
+            $this->_mh = curl_multi_init();
+
+            foreach ($this->options as $option => $value) {
+                // A warning is raised in case of a wrong option.
+                curl_multi_setopt($this->_mh, $option, $value);
+            }
+
+            // Further calls to _mh will return the value directly, without entering the
+            // __get() method at all.
+            return $this->_mh;
+        }
+
+        throw new \BadMethodCallException();
+    }
+
+    public function __destruct()
+    {
+        if (isset($this->_mh)) {
+            curl_multi_close($this->_mh);
+            unset($this->_mh);
+        }
+    }
+
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        $easy = $this->factory->create($request, $options);
+        $id = (int) $easy->handle;
+
+        $promise = new Promise(
+            [$this, 'execute'],
+            function () use ($id) {
+                return $this->cancel($id);
+            }
+        );
+
+        $this->addRequest(['easy' => $easy, 'deferred' => $promise]);
+
+        return $promise;
+    }
+
+    /**
+     * Ticks the curl event loop.
+     */
+    public function tick()
+    {
+        // Add any delayed handles if needed.
+        if ($this->delays) {
+            $currentTime = Utils::currentTime();
+            foreach ($this->delays as $id => $delay) {
+                if ($currentTime >= $delay) {
+                    unset($this->delays[$id]);
+                    curl_multi_add_handle(
+                        $this->_mh,
+                        $this->handles[$id]['easy']->handle
+                    );
+                }
+            }
+        }
+
+        // Step through the task queue which may add additional requests.
+        P\queue()->run();
+
+        if ($this->active &&
+            curl_multi_select($this->_mh, $this->selectTimeout) === -1
+        ) {
+            // Perform a usleep if a select returns -1.
+            // See: https://bugs.php.net/bug.php?id=61141
+            usleep(250);
+        }
+
+        while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM);
+
+        $this->processMessages();
+    }
+
+    /**
+     * Runs until all outstanding connections have completed.
+     */
+    public function execute()
+    {
+        $queue = P\queue();
+
+        while ($this->handles || !$queue->isEmpty()) {
+            // If there are no transfers, then sleep for the next delay
+            if (!$this->active && $this->delays) {
+                usleep($this->timeToNext());
+            }
+            $this->tick();
+        }
+    }
+
+    private function addRequest(array $entry)
+    {
+        $easy = $entry['easy'];
+        $id = (int) $easy->handle;
+        $this->handles[$id] = $entry;
+        if (empty($easy->options['delay'])) {
+            curl_multi_add_handle($this->_mh, $easy->handle);
+        } else {
+            $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000);
+        }
+    }
+
+    /**
+     * Cancels a handle from sending and removes references to it.
+     *
+     * @param int $id Handle ID to cancel and remove.
+     *
+     * @return bool True on success, false on failure.
+     */
+    private function cancel($id)
+    {
+        // Cannot cancel if it has been processed.
+        if (!isset($this->handles[$id])) {
+            return false;
+        }
+
+        $handle = $this->handles[$id]['easy']->handle;
+        unset($this->delays[$id], $this->handles[$id]);
+        curl_multi_remove_handle($this->_mh, $handle);
+        curl_close($handle);
+
+        return true;
+    }
+
+    private function processMessages()
+    {
+        while ($done = curl_multi_info_read($this->_mh)) {
+            $id = (int) $done['handle'];
+            curl_multi_remove_handle($this->_mh, $done['handle']);
+
+            if (!isset($this->handles[$id])) {
+                // Probably was cancelled.
+                continue;
+            }
+
+            $entry = $this->handles[$id];
+            unset($this->handles[$id], $this->delays[$id]);
+            $entry['easy']->errno = $done['result'];
+            $entry['deferred']->resolve(
+                CurlFactory::finish(
+                    $this,
+                    $entry['easy'],
+                    $this->factory
+                )
+            );
+        }
+    }
+
+    private function timeToNext()
+    {
+        $currentTime = Utils::currentTime();
+        $nextTime = PHP_INT_MAX;
+        foreach ($this->delays as $time) {
+            if ($time < $nextTime) {
+                $nextTime = $time;
+            }
+        }
+
+        return max(0, $nextTime - $currentTime) * 1000000;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/EasyHandle.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/EasyHandle.php
new file mode 100644 (file)
index 0000000..7754e91
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Psr7\Response;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Represents a cURL easy handle and the data it populates.
+ *
+ * @internal
+ */
+final class EasyHandle
+{
+    /** @var resource cURL resource */
+    public $handle;
+
+    /** @var StreamInterface Where data is being written */
+    public $sink;
+
+    /** @var array Received HTTP headers so far */
+    public $headers = [];
+
+    /** @var ResponseInterface Received response (if any) */
+    public $response;
+
+    /** @var RequestInterface Request being sent */
+    public $request;
+
+    /** @var array Request options */
+    public $options = [];
+
+    /** @var int cURL error number (if any) */
+    public $errno = 0;
+
+    /** @var \Exception Exception during on_headers (if any) */
+    public $onHeadersException;
+
+    /**
+     * Attach a response to the easy handle based on the received headers.
+     *
+     * @throws \RuntimeException if no headers have been received.
+     */
+    public function createResponse()
+    {
+        if (empty($this->headers)) {
+            throw new \RuntimeException('No headers have been received');
+        }
+
+        // HTTP-version SP status-code SP reason-phrase
+        $startLine = explode(' ', array_shift($this->headers), 3);
+        $headers = \GuzzleHttp\headers_from_lines($this->headers);
+        $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
+
+        if (!empty($this->options['decode_content'])
+            && isset($normalizedKeys['content-encoding'])
+        ) {
+            $headers['x-encoded-content-encoding']
+                = $headers[$normalizedKeys['content-encoding']];
+            unset($headers[$normalizedKeys['content-encoding']]);
+            if (isset($normalizedKeys['content-length'])) {
+                $headers['x-encoded-content-length']
+                    = $headers[$normalizedKeys['content-length']];
+
+                $bodyLength = (int) $this->sink->getSize();
+                if ($bodyLength) {
+                    $headers[$normalizedKeys['content-length']] = $bodyLength;
+                } else {
+                    unset($headers[$normalizedKeys['content-length']]);
+                }
+            }
+        }
+
+        // Attach a response to the easy handle with the parsed headers.
+        $this->response = new Response(
+            $startLine[1],
+            $headers,
+            $this->sink,
+            substr($startLine[0], 5),
+            isset($startLine[2]) ? (string) $startLine[2] : null
+        );
+    }
+
+    public function __get($name)
+    {
+        $msg = $name === 'handle'
+            ? 'The EasyHandle has been released'
+            : 'Invalid property: ' . $name;
+        throw new \BadMethodCallException($msg);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/MockHandler.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/MockHandler.php
new file mode 100644 (file)
index 0000000..5b312bc
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\HandlerStack;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Promise\RejectedPromise;
+use GuzzleHttp\TransferStats;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Handler that returns responses or throw exceptions from a queue.
+ */
+class MockHandler implements \Countable
+{
+    private $queue = [];
+    private $lastRequest;
+    private $lastOptions;
+    private $onFulfilled;
+    private $onRejected;
+
+    /**
+     * Creates a new MockHandler that uses the default handler stack list of
+     * middlewares.
+     *
+     * @param array $queue Array of responses, callables, or exceptions.
+     * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
+     * @param callable $onRejected  Callback to invoke when the return value is rejected.
+     *
+     * @return HandlerStack
+     */
+    public static function createWithMiddleware(
+        array $queue = null,
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    ) {
+        return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
+    }
+
+    /**
+     * The passed in value must be an array of
+     * {@see Psr7\Http\Message\ResponseInterface} objects, Exceptions,
+     * callables, or Promises.
+     *
+     * @param array $queue
+     * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
+     * @param callable $onRejected  Callback to invoke when the return value is rejected.
+     */
+    public function __construct(
+        array $queue = null,
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    ) {
+        $this->onFulfilled = $onFulfilled;
+        $this->onRejected = $onRejected;
+
+        if ($queue) {
+            call_user_func_array([$this, 'append'], $queue);
+        }
+    }
+
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        if (!$this->queue) {
+            throw new \OutOfBoundsException('Mock queue is empty');
+        }
+
+        if (isset($options['delay']) && is_numeric($options['delay'])) {
+            usleep($options['delay'] * 1000);
+        }
+
+        $this->lastRequest = $request;
+        $this->lastOptions = $options;
+        $response = array_shift($this->queue);
+
+        if (isset($options['on_headers'])) {
+            if (!is_callable($options['on_headers'])) {
+                throw new \InvalidArgumentException('on_headers must be callable');
+            }
+            try {
+                $options['on_headers']($response);
+            } catch (\Exception $e) {
+                $msg = 'An error was encountered during the on_headers event';
+                $response = new RequestException($msg, $request, $response, $e);
+            }
+        }
+
+        if (is_callable($response)) {
+            $response = call_user_func($response, $request, $options);
+        }
+
+        $response = $response instanceof \Exception
+            ? \GuzzleHttp\Promise\rejection_for($response)
+            : \GuzzleHttp\Promise\promise_for($response);
+
+        return $response->then(
+            function ($value) use ($request, $options) {
+                $this->invokeStats($request, $options, $value);
+                if ($this->onFulfilled) {
+                    call_user_func($this->onFulfilled, $value);
+                }
+                if (isset($options['sink'])) {
+                    $contents = (string) $value->getBody();
+                    $sink = $options['sink'];
+
+                    if (is_resource($sink)) {
+                        fwrite($sink, $contents);
+                    } elseif (is_string($sink)) {
+                        file_put_contents($sink, $contents);
+                    } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
+                        $sink->write($contents);
+                    }
+                }
+
+                return $value;
+            },
+            function ($reason) use ($request, $options) {
+                $this->invokeStats($request, $options, null, $reason);
+                if ($this->onRejected) {
+                    call_user_func($this->onRejected, $reason);
+                }
+                return \GuzzleHttp\Promise\rejection_for($reason);
+            }
+        );
+    }
+
+    /**
+     * Adds one or more variadic requests, exceptions, callables, or promises
+     * to the queue.
+     */
+    public function append()
+    {
+        foreach (func_get_args() as $value) {
+            if ($value instanceof ResponseInterface
+                || $value instanceof \Exception
+                || $value instanceof PromiseInterface
+                || is_callable($value)
+            ) {
+                $this->queue[] = $value;
+            } else {
+                throw new \InvalidArgumentException('Expected a response or '
+                    . 'exception. Found ' . \GuzzleHttp\describe_type($value));
+            }
+        }
+    }
+
+    /**
+     * Get the last received request.
+     *
+     * @return RequestInterface
+     */
+    public function getLastRequest()
+    {
+        return $this->lastRequest;
+    }
+
+    /**
+     * Get the last received request options.
+     *
+     * @return array
+     */
+    public function getLastOptions()
+    {
+        return $this->lastOptions;
+    }
+
+    /**
+     * Returns the number of remaining items in the queue.
+     *
+     * @return int
+     */
+    public function count()
+    {
+        return count($this->queue);
+    }
+
+    public function reset()
+    {
+        $this->queue = [];
+    }
+
+    private function invokeStats(
+        RequestInterface $request,
+        array $options,
+        ResponseInterface $response = null,
+        $reason = null
+    ) {
+        if (isset($options['on_stats'])) {
+            $transferTime = isset($options['transfer_time']) ? $options['transfer_time'] : 0;
+            $stats = new TransferStats($request, $response, $transferTime, $reason);
+            call_user_func($options['on_stats'], $stats);
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/Proxy.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/Proxy.php
new file mode 100644 (file)
index 0000000..f8b00be
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\RequestOptions;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Provides basic proxies for handlers.
+ */
+class Proxy
+{
+    /**
+     * Sends synchronous requests to a specific handler while sending all other
+     * requests to another handler.
+     *
+     * @param callable $default Handler used for normal responses
+     * @param callable $sync    Handler used for synchronous responses.
+     *
+     * @return callable Returns the composed handler.
+     */
+    public static function wrapSync(
+        callable $default,
+        callable $sync
+    ) {
+        return function (RequestInterface $request, array $options) use ($default, $sync) {
+            return empty($options[RequestOptions::SYNCHRONOUS])
+                ? $default($request, $options)
+                : $sync($request, $options);
+        };
+    }
+
+    /**
+     * Sends streaming requests to a streaming compatible handler while sending
+     * all other requests to a default handler.
+     *
+     * This, for example, could be useful for taking advantage of the
+     * performance benefits of curl while still supporting true streaming
+     * through the StreamHandler.
+     *
+     * @param callable $default   Handler used for non-streaming responses
+     * @param callable $streaming Handler used for streaming responses
+     *
+     * @return callable Returns the composed handler.
+     */
+    public static function wrapStreaming(
+        callable $default,
+        callable $streaming
+    ) {
+        return function (RequestInterface $request, array $options) use ($default, $streaming) {
+            return empty($options['stream'])
+                ? $default($request, $options)
+                : $streaming($request, $options);
+        };
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/StreamHandler.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Handler/StreamHandler.php
new file mode 100644 (file)
index 0000000..03429ee
--- /dev/null
@@ -0,0 +1,586 @@
+<?php
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Exception\ConnectException;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Promise\FulfilledPromise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Psr7;
+use GuzzleHttp\TransferStats;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * HTTP handler that uses PHP's HTTP stream wrapper.
+ */
+class StreamHandler
+{
+    private $lastHeaders = [];
+
+    /**
+     * Sends an HTTP request.
+     *
+     * @param RequestInterface $request Request to send.
+     * @param array            $options Request transfer options.
+     *
+     * @return PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        // Sleep if there is a delay specified.
+        if (isset($options['delay'])) {
+            usleep($options['delay'] * 1000);
+        }
+
+        $startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
+
+        try {
+            // Does not support the expect header.
+            $request = $request->withoutHeader('Expect');
+
+            // Append a content-length header if body size is zero to match
+            // cURL's behavior.
+            if (0 === $request->getBody()->getSize()) {
+                $request = $request->withHeader('Content-Length', '0');
+            }
+
+            return $this->createResponse(
+                $request,
+                $options,
+                $this->createStream($request, $options),
+                $startTime
+            );
+        } catch (\InvalidArgumentException $e) {
+            throw $e;
+        } catch (\Exception $e) {
+            // Determine if the error was a networking error.
+            $message = $e->getMessage();
+            // This list can probably get more comprehensive.
+            if (strpos($message, 'getaddrinfo') // DNS lookup failed
+                || strpos($message, 'Connection refused')
+                || strpos($message, "couldn't connect to host") // error on HHVM
+                || strpos($message, "connection attempt failed")
+            ) {
+                $e = new ConnectException($e->getMessage(), $request, $e);
+            }
+            $e = RequestException::wrapException($request, $e);
+            $this->invokeStats($options, $request, $startTime, null, $e);
+
+            return \GuzzleHttp\Promise\rejection_for($e);
+        }
+    }
+
+    private function invokeStats(
+        array $options,
+        RequestInterface $request,
+        $startTime,
+        ResponseInterface $response = null,
+        $error = null
+    ) {
+        if (isset($options['on_stats'])) {
+            $stats = new TransferStats(
+                $request,
+                $response,
+                Utils::currentTime() - $startTime,
+                $error,
+                []
+            );
+            call_user_func($options['on_stats'], $stats);
+        }
+    }
+
+    private function createResponse(
+        RequestInterface $request,
+        array $options,
+        $stream,
+        $startTime
+    ) {
+        $hdrs = $this->lastHeaders;
+        $this->lastHeaders = [];
+        $parts = explode(' ', array_shift($hdrs), 3);
+        $ver = explode('/', $parts[0])[1];
+        $status = $parts[1];
+        $reason = isset($parts[2]) ? $parts[2] : null;
+        $headers = \GuzzleHttp\headers_from_lines($hdrs);
+        list($stream, $headers) = $this->checkDecode($options, $headers, $stream);
+        $stream = Psr7\stream_for($stream);
+        $sink = $stream;
+
+        if (strcasecmp('HEAD', $request->getMethod())) {
+            $sink = $this->createSink($stream, $options);
+        }
+
+        $response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
+
+        if (isset($options['on_headers'])) {
+            try {
+                $options['on_headers']($response);
+            } catch (\Exception $e) {
+                $msg = 'An error was encountered during the on_headers event';
+                $ex = new RequestException($msg, $request, $response, $e);
+                return \GuzzleHttp\Promise\rejection_for($ex);
+            }
+        }
+
+        // Do not drain when the request is a HEAD request because they have
+        // no body.
+        if ($sink !== $stream) {
+            $this->drain(
+                $stream,
+                $sink,
+                $response->getHeaderLine('Content-Length')
+            );
+        }
+
+        $this->invokeStats($options, $request, $startTime, $response, null);
+
+        return new FulfilledPromise($response);
+    }
+
+    private function createSink(StreamInterface $stream, array $options)
+    {
+        if (!empty($options['stream'])) {
+            return $stream;
+        }
+
+        $sink = isset($options['sink'])
+            ? $options['sink']
+            : fopen('php://temp', 'r+');
+
+        return is_string($sink)
+            ? new Psr7\LazyOpenStream($sink, 'w+')
+            : Psr7\stream_for($sink);
+    }
+
+    private function checkDecode(array $options, array $headers, $stream)
+    {
+        // Automatically decode responses when instructed.
+        if (!empty($options['decode_content'])) {
+            $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
+            if (isset($normalizedKeys['content-encoding'])) {
+                $encoding = $headers[$normalizedKeys['content-encoding']];
+                if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
+                    $stream = new Psr7\InflateStream(
+                        Psr7\stream_for($stream)
+                    );
+                    $headers['x-encoded-content-encoding']
+                        = $headers[$normalizedKeys['content-encoding']];
+                    // Remove content-encoding header
+                    unset($headers[$normalizedKeys['content-encoding']]);
+                    // Fix content-length header
+                    if (isset($normalizedKeys['content-length'])) {
+                        $headers['x-encoded-content-length']
+                            = $headers[$normalizedKeys['content-length']];
+
+                        $length = (int) $stream->getSize();
+                        if ($length === 0) {
+                            unset($headers[$normalizedKeys['content-length']]);
+                        } else {
+                            $headers[$normalizedKeys['content-length']] = [$length];
+                        }
+                    }
+                }
+            }
+        }
+
+        return [$stream, $headers];
+    }
+
+    /**
+     * Drains the source stream into the "sink" client option.
+     *
+     * @param StreamInterface $source
+     * @param StreamInterface $sink
+     * @param string          $contentLength Header specifying the amount of
+     *                                       data to read.
+     *
+     * @return StreamInterface
+     * @throws \RuntimeException when the sink option is invalid.
+     */
+    private function drain(
+        StreamInterface $source,
+        StreamInterface $sink,
+        $contentLength
+    ) {
+        // If a content-length header is provided, then stop reading once
+        // that number of bytes has been read. This can prevent infinitely
+        // reading from a stream when dealing with servers that do not honor
+        // Connection: Close headers.
+        Psr7\copy_to_stream(
+            $source,
+            $sink,
+            (strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1
+        );
+
+        $sink->seek(0);
+        $source->close();
+
+        return $sink;
+    }
+
+    /**
+     * Create a resource and check to ensure it was created successfully
+     *
+     * @param callable $callback Callable that returns stream resource
+     *
+     * @return resource
+     * @throws \RuntimeException on error
+     */
+    private function createResource(callable $callback)
+    {
+        $errors = null;
+        set_error_handler(function ($_, $msg, $file, $line) use (&$errors) {
+            $errors[] = [
+                'message' => $msg,
+                'file'    => $file,
+                'line'    => $line
+            ];
+            return true;
+        });
+
+        $resource = $callback();
+        restore_error_handler();
+
+        if (!$resource) {
+            $message = 'Error creating resource: ';
+            foreach ($errors as $err) {
+                foreach ($err as $key => $value) {
+                    $message .= "[$key] $value" . PHP_EOL;
+                }
+            }
+            throw new \RuntimeException(trim($message));
+        }
+
+        return $resource;
+    }
+
+    private function createStream(RequestInterface $request, array $options)
+    {
+        static $methods;
+        if (!$methods) {
+            $methods = array_flip(get_class_methods(__CLASS__));
+        }
+
+        // HTTP/1.1 streams using the PHP stream wrapper require a
+        // Connection: close header
+        if ($request->getProtocolVersion() == '1.1'
+            && !$request->hasHeader('Connection')
+        ) {
+            $request = $request->withHeader('Connection', 'close');
+        }
+
+        // Ensure SSL is verified by default
+        if (!isset($options['verify'])) {
+            $options['verify'] = true;
+        }
+
+        $params = [];
+        $context = $this->getDefaultContext($request);
+
+        if (isset($options['on_headers']) && !is_callable($options['on_headers'])) {
+            throw new \InvalidArgumentException('on_headers must be callable');
+        }
+
+        if (!empty($options)) {
+            foreach ($options as $key => $value) {
+                $method = "add_{$key}";
+                if (isset($methods[$method])) {
+                    $this->{$method}($request, $context, $value, $params);
+                }
+            }
+        }
+
+        if (isset($options['stream_context'])) {
+            if (!is_array($options['stream_context'])) {
+                throw new \InvalidArgumentException('stream_context must be an array');
+            }
+            $context = array_replace_recursive(
+                $context,
+                $options['stream_context']
+            );
+        }
+
+        // Microsoft NTLM authentication only supported with curl handler
+        if (isset($options['auth'])
+            && is_array($options['auth'])
+            && isset($options['auth'][2])
+            && 'ntlm' == $options['auth'][2]
+        ) {
+            throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
+        }
+
+        $uri = $this->resolveHost($request, $options);
+
+        $context = $this->createResource(
+            function () use ($context, $params) {
+                return stream_context_create($context, $params);
+            }
+        );
+
+        return $this->createResource(
+            function () use ($uri, &$http_response_header, $context, $options) {
+                $resource = fopen((string) $uri, 'r', null, $context);
+                $this->lastHeaders = $http_response_header;
+
+                if (isset($options['read_timeout'])) {
+                    $readTimeout = $options['read_timeout'];
+                    $sec = (int) $readTimeout;
+                    $usec = ($readTimeout - $sec) * 100000;
+                    stream_set_timeout($resource, $sec, $usec);
+                }
+
+                return $resource;
+            }
+        );
+    }
+
+    private function resolveHost(RequestInterface $request, array $options)
+    {
+        $uri = $request->getUri();
+
+        if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) {
+            if ('v4' === $options['force_ip_resolve']) {
+                $records = dns_get_record($uri->getHost(), DNS_A);
+                if (!isset($records[0]['ip'])) {
+                    throw new ConnectException(
+                        sprintf(
+                            "Could not resolve IPv4 address for host '%s'",
+                            $uri->getHost()
+                        ),
+                        $request
+                    );
+                }
+                $uri = $uri->withHost($records[0]['ip']);
+            } elseif ('v6' === $options['force_ip_resolve']) {
+                $records = dns_get_record($uri->getHost(), DNS_AAAA);
+                if (!isset($records[0]['ipv6'])) {
+                    throw new ConnectException(
+                        sprintf(
+                            "Could not resolve IPv6 address for host '%s'",
+                            $uri->getHost()
+                        ),
+                        $request
+                    );
+                }
+                $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']');
+            }
+        }
+
+        return $uri;
+    }
+
+    private function getDefaultContext(RequestInterface $request)
+    {
+        $headers = '';
+        foreach ($request->getHeaders() as $name => $value) {
+            foreach ($value as $val) {
+                $headers .= "$name: $val\r\n";
+            }
+        }
+
+        $context = [
+            'http' => [
+                'method'           => $request->getMethod(),
+                'header'           => $headers,
+                'protocol_version' => $request->getProtocolVersion(),
+                'ignore_errors'    => true,
+                'follow_location'  => 0,
+            ],
+        ];
+
+        $body = (string) $request->getBody();
+
+        if (!empty($body)) {
+            $context['http']['content'] = $body;
+            // Prevent the HTTP handler from adding a Content-Type header.
+            if (!$request->hasHeader('Content-Type')) {
+                $context['http']['header'] .= "Content-Type:\r\n";
+            }
+        }
+
+        $context['http']['header'] = rtrim($context['http']['header']);
+
+        return $context;
+    }
+
+    private function add_proxy(RequestInterface $request, &$options, $value, &$params)
+    {
+        $uri = null;
+
+        if (!is_array($value)) {
+            $uri = $value;
+        } else {
+            $scheme = $request->getUri()->getScheme();
+            if (isset($value[$scheme])) {
+                if (!isset($value['no'])
+                    || !\GuzzleHttp\is_host_in_noproxy(
+                        $request->getUri()->getHost(),
+                        $value['no']
+                    )
+                ) {
+                    $uri = $value[$scheme];
+                }
+            }
+        }
+
+        if (!$uri) {
+            return;
+        }
+
+        $parsed = $this->parse_proxy($uri);
+        $options['http']['proxy'] = $parsed['proxy'];
+
+        if ($parsed['auth']) {
+            if (!isset($options['http']['header'])) {
+                $options['http']['header'] = [];
+            }
+            $options['http']['header'] .= "\r\nProxy-Authorization: {$parsed['auth']}";
+        }
+    }
+
+    private function parse_proxy($url)
+    {
+        $parsed = \parse_url($url);
+
+        if ($parsed !== false && isset($parsed['scheme']) && $parsed['scheme'] === 'http') {
+            if (isset($parsed['host']) && isset($parsed['port'])) {
+                $auth = null;
+                if (isset($parsed['user']) && isset($parsed['pass'])) {
+                    $auth = \base64_encode("{$parsed['user']}:{$parsed['pass']}");
+                }
+
+                return [
+                    'proxy' => "tcp://{$parsed['host']}:{$parsed['port']}",
+                    'auth' => $auth ? "Basic {$auth}" : null,
+                ];
+            }
+        }
+
+        // Return proxy as-is.
+        return [
+            'proxy' => $url,
+            'auth' => null,
+        ];
+    }
+
+    private function add_timeout(RequestInterface $request, &$options, $value, &$params)
+    {
+        if ($value > 0) {
+            $options['http']['timeout'] = $value;
+        }
+    }
+
+    private function add_verify(RequestInterface $request, &$options, $value, &$params)
+    {
+        if ($value === true) {
+            // PHP 5.6 or greater will find the system cert by default. When
+            // < 5.6, use the Guzzle bundled cacert.
+            if (PHP_VERSION_ID < 50600) {
+                $options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle();
+            }
+        } elseif (is_string($value)) {
+            $options['ssl']['cafile'] = $value;
+            if (!file_exists($value)) {
+                throw new \RuntimeException("SSL CA bundle not found: $value");
+            }
+        } elseif ($value === false) {
+            $options['ssl']['verify_peer'] = false;
+            $options['ssl']['verify_peer_name'] = false;
+            return;
+        } else {
+            throw new \InvalidArgumentException('Invalid verify request option');
+        }
+
+        $options['ssl']['verify_peer'] = true;
+        $options['ssl']['verify_peer_name'] = true;
+        $options['ssl']['allow_self_signed'] = false;
+    }
+
+    private function add_cert(RequestInterface $request, &$options, $value, &$params)
+    {
+        if (is_array($value)) {
+            $options['ssl']['passphrase'] = $value[1];
+            $value = $value[0];
+        }
+
+        if (!file_exists($value)) {
+            throw new \RuntimeException("SSL certificate not found: {$value}");
+        }
+
+        $options['ssl']['local_cert'] = $value;
+    }
+
+    private function add_progress(RequestInterface $request, &$options, $value, &$params)
+    {
+        $this->addNotification(
+            $params,
+            function ($code, $a, $b, $c, $transferred, $total) use ($value) {
+                if ($code == STREAM_NOTIFY_PROGRESS) {
+                    $value($total, $transferred, null, null);
+                }
+            }
+        );
+    }
+
+    private function add_debug(RequestInterface $request, &$options, $value, &$params)
+    {
+        if ($value === false) {
+            return;
+        }
+
+        static $map = [
+            STREAM_NOTIFY_CONNECT       => 'CONNECT',
+            STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
+            STREAM_NOTIFY_AUTH_RESULT   => 'AUTH_RESULT',
+            STREAM_NOTIFY_MIME_TYPE_IS  => 'MIME_TYPE_IS',
+            STREAM_NOTIFY_FILE_SIZE_IS  => 'FILE_SIZE_IS',
+            STREAM_NOTIFY_REDIRECTED    => 'REDIRECTED',
+            STREAM_NOTIFY_PROGRESS      => 'PROGRESS',
+            STREAM_NOTIFY_FAILURE       => 'FAILURE',
+            STREAM_NOTIFY_COMPLETED     => 'COMPLETED',
+            STREAM_NOTIFY_RESOLVE       => 'RESOLVE',
+        ];
+        static $args = ['severity', 'message', 'message_code',
+            'bytes_transferred', 'bytes_max'];
+
+        $value = \GuzzleHttp\debug_resource($value);
+        $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
+        $this->addNotification(
+            $params,
+            function () use ($ident, $value, $map, $args) {
+                $passed = func_get_args();
+                $code = array_shift($passed);
+                fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
+                foreach (array_filter($passed) as $i => $v) {
+                    fwrite($value, $args[$i] . ': "' . $v . '" ');
+                }
+                fwrite($value, "\n");
+            }
+        );
+    }
+
+    private function addNotification(array &$params, callable $notify)
+    {
+        // Wrap the existing function if needed.
+        if (!isset($params['notification'])) {
+            $params['notification'] = $notify;
+        } else {
+            $params['notification'] = $this->callArray([
+                $params['notification'],
+                $notify
+            ]);
+        }
+    }
+
+    private function callArray(array $functions)
+    {
+        return function () use ($functions) {
+            $args = func_get_args();
+            foreach ($functions as $fn) {
+                call_user_func_array($fn, $args);
+            }
+        };
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/HandlerStack.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/HandlerStack.php
new file mode 100644 (file)
index 0000000..6a49cc0
--- /dev/null
@@ -0,0 +1,277 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Creates a composed Guzzle handler function by stacking middlewares on top of
+ * an HTTP handler function.
+ */
+class HandlerStack
+{
+    /** @var callable|null */
+    private $handler;
+
+    /** @var array */
+    private $stack = [];
+
+    /** @var callable|null */
+    private $cached;
+
+    /**
+     * Creates a default handler stack that can be used by clients.
+     *
+     * The returned handler will wrap the provided handler or use the most
+     * appropriate default handler for your system. The returned HandlerStack has
+     * support for cookies, redirects, HTTP error exceptions, and preparing a body
+     * before sending.
+     *
+     * The returned handler stack can be passed to a client in the "handler"
+     * option.
+     *
+     * @param callable $handler HTTP handler function to use with the stack. If no
+     *                          handler is provided, the best handler for your
+     *                          system will be utilized.
+     *
+     * @return HandlerStack
+     */
+    public static function create(callable $handler = null)
+    {
+        $stack = new self($handler ?: choose_handler());
+        $stack->push(Middleware::httpErrors(), 'http_errors');
+        $stack->push(Middleware::redirect(), 'allow_redirects');
+        $stack->push(Middleware::cookies(), 'cookies');
+        $stack->push(Middleware::prepareBody(), 'prepare_body');
+
+        return $stack;
+    }
+
+    /**
+     * @param callable $handler Underlying HTTP handler.
+     */
+    public function __construct(callable $handler = null)
+    {
+        $this->handler = $handler;
+    }
+
+    /**
+     * Invokes the handler stack as a composed handler
+     *
+     * @param RequestInterface $request
+     * @param array            $options
+     *
+     * @return ResponseInterface|PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        $handler = $this->resolve();
+
+        return $handler($request, $options);
+    }
+
+    /**
+     * Dumps a string representation of the stack.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        $depth = 0;
+        $stack = [];
+        if ($this->handler) {
+            $stack[] = "0) Handler: " . $this->debugCallable($this->handler);
+        }
+
+        $result = '';
+        foreach (array_reverse($this->stack) as $tuple) {
+            $depth++;
+            $str = "{$depth}) Name: '{$tuple[1]}', ";
+            $str .= "Function: " . $this->debugCallable($tuple[0]);
+            $result = "> {$str}\n{$result}";
+            $stack[] = $str;
+        }
+
+        foreach (array_keys($stack) as $k) {
+            $result .= "< {$stack[$k]}\n";
+        }
+
+        return $result;
+    }
+
+    /**
+     * Set the HTTP handler that actually returns a promise.
+     *
+     * @param callable $handler Accepts a request and array of options and
+     *                          returns a Promise.
+     */
+    public function setHandler(callable $handler)
+    {
+        $this->handler = $handler;
+        $this->cached = null;
+    }
+
+    /**
+     * Returns true if the builder has a handler.
+     *
+     * @return bool
+     */
+    public function hasHandler()
+    {
+        return (bool) $this->handler;
+    }
+
+    /**
+     * Unshift a middleware to the bottom of the stack.
+     *
+     * @param callable $middleware Middleware function
+     * @param string   $name       Name to register for this middleware.
+     */
+    public function unshift(callable $middleware, $name = null)
+    {
+        array_unshift($this->stack, [$middleware, $name]);
+        $this->cached = null;
+    }
+
+    /**
+     * Push a middleware to the top of the stack.
+     *
+     * @param callable $middleware Middleware function
+     * @param string   $name       Name to register for this middleware.
+     */
+    public function push(callable $middleware, $name = '')
+    {
+        $this->stack[] = [$middleware, $name];
+        $this->cached = null;
+    }
+
+    /**
+     * Add a middleware before another middleware by name.
+     *
+     * @param string   $findName   Middleware to find
+     * @param callable $middleware Middleware function
+     * @param string   $withName   Name to register for this middleware.
+     */
+    public function before($findName, callable $middleware, $withName = '')
+    {
+        $this->splice($findName, $withName, $middleware, true);
+    }
+
+    /**
+     * Add a middleware after another middleware by name.
+     *
+     * @param string   $findName   Middleware to find
+     * @param callable $middleware Middleware function
+     * @param string   $withName   Name to register for this middleware.
+     */
+    public function after($findName, callable $middleware, $withName = '')
+    {
+        $this->splice($findName, $withName, $middleware, false);
+    }
+
+    /**
+     * Remove a middleware by instance or name from the stack.
+     *
+     * @param callable|string $remove Middleware to remove by instance or name.
+     */
+    public function remove($remove)
+    {
+        $this->cached = null;
+        $idx = is_callable($remove) ? 0 : 1;
+        $this->stack = array_values(array_filter(
+            $this->stack,
+            function ($tuple) use ($idx, $remove) {
+                return $tuple[$idx] !== $remove;
+            }
+        ));
+    }
+
+    /**
+     * Compose the middleware and handler into a single callable function.
+     *
+     * @return callable
+     */
+    public function resolve()
+    {
+        if (!$this->cached) {
+            if (!($prev = $this->handler)) {
+                throw new \LogicException('No handler has been specified');
+            }
+
+            foreach (array_reverse($this->stack) as $fn) {
+                $prev = $fn[0]($prev);
+            }
+
+            $this->cached = $prev;
+        }
+
+        return $this->cached;
+    }
+
+    /**
+     * @param string $name
+     * @return int
+     */
+    private function findByName($name)
+    {
+        foreach ($this->stack as $k => $v) {
+            if ($v[1] === $name) {
+                return $k;
+            }
+        }
+
+        throw new \InvalidArgumentException("Middleware not found: $name");
+    }
+
+    /**
+     * Splices a function into the middleware list at a specific position.
+     *
+     * @param string   $findName
+     * @param string   $withName
+     * @param callable $middleware
+     * @param bool     $before
+     */
+    private function splice($findName, $withName, callable $middleware, $before)
+    {
+        $this->cached = null;
+        $idx = $this->findByName($findName);
+        $tuple = [$middleware, $withName];
+
+        if ($before) {
+            if ($idx === 0) {
+                array_unshift($this->stack, $tuple);
+            } else {
+                $replacement = [$tuple, $this->stack[$idx]];
+                array_splice($this->stack, $idx, 1, $replacement);
+            }
+        } elseif ($idx === count($this->stack) - 1) {
+            $this->stack[] = $tuple;
+        } else {
+            $replacement = [$this->stack[$idx], $tuple];
+            array_splice($this->stack, $idx, 1, $replacement);
+        }
+    }
+
+    /**
+     * Provides a debug string for a given callable.
+     *
+     * @param array|callable $fn Function to write as a string.
+     *
+     * @return string
+     */
+    private function debugCallable($fn)
+    {
+        if (is_string($fn)) {
+            return "callable({$fn})";
+        }
+
+        if (is_array($fn)) {
+            return is_string($fn[0])
+                ? "callable({$fn[0]}::{$fn[1]})"
+                : "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])";
+        }
+
+        return 'callable(' . spl_object_hash($fn) . ')';
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/MessageFormatter.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/MessageFormatter.php
new file mode 100644 (file)
index 0000000..dc36bb5
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+namespace GuzzleHttp;
+
+use Psr\Http\Message\MessageInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Formats log messages using variable substitutions for requests, responses,
+ * and other transactional data.
+ *
+ * The following variable substitutions are supported:
+ *
+ * - {request}:        Full HTTP request message
+ * - {response}:       Full HTTP response message
+ * - {ts}:             ISO 8601 date in GMT
+ * - {date_iso_8601}   ISO 8601 date in GMT
+ * - {date_common_log} Apache common log date using the configured timezone.
+ * - {host}:           Host of the request
+ * - {method}:         Method of the request
+ * - {uri}:            URI of the request
+ * - {version}:        Protocol version
+ * - {target}:         Request target of the request (path + query + fragment)
+ * - {hostname}:       Hostname of the machine that sent the request
+ * - {code}:           Status code of the response (if available)
+ * - {phrase}:         Reason phrase of the response  (if available)
+ * - {error}:          Any error messages (if available)
+ * - {req_header_*}:   Replace `*` with the lowercased name of a request header to add to the message
+ * - {res_header_*}:   Replace `*` with the lowercased name of a response header to add to the message
+ * - {req_headers}:    Request headers
+ * - {res_headers}:    Response headers
+ * - {req_body}:       Request body
+ * - {res_body}:       Response body
+ */
+class MessageFormatter
+{
+    /**
+     * Apache Common Log Format.
+     * @link http://httpd.apache.org/docs/2.4/logs.html#common
+     * @var string
+     */
+    const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
+    const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
+    const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
+
+    /** @var string Template used to format log messages */
+    private $template;
+
+    /**
+     * @param string $template Log message template
+     */
+    public function __construct($template = self::CLF)
+    {
+        $this->template = $template ?: self::CLF;
+    }
+
+    /**
+     * Returns a formatted message string.
+     *
+     * @param RequestInterface  $request  Request that was sent
+     * @param ResponseInterface $response Response that was received
+     * @param \Exception        $error    Exception that was received
+     *
+     * @return string
+     */
+    public function format(
+        RequestInterface $request,
+        ResponseInterface $response = null,
+        \Exception $error = null
+    ) {
+        $cache = [];
+
+        return preg_replace_callback(
+            '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
+            function (array $matches) use ($request, $response, $error, &$cache) {
+                if (isset($cache[$matches[1]])) {
+                    return $cache[$matches[1]];
+                }
+
+                $result = '';
+                switch ($matches[1]) {
+                    case 'request':
+                        $result = Psr7\str($request);
+                        break;
+                    case 'response':
+                        $result = $response ? Psr7\str($response) : '';
+                        break;
+                    case 'req_headers':
+                        $result = trim($request->getMethod()
+                                . ' ' . $request->getRequestTarget())
+                            . ' HTTP/' . $request->getProtocolVersion() . "\r\n"
+                            . $this->headers($request);
+                        break;
+                    case 'res_headers':
+                        $result = $response ?
+                            sprintf(
+                                'HTTP/%s %d %s',
+                                $response->getProtocolVersion(),
+                                $response->getStatusCode(),
+                                $response->getReasonPhrase()
+                            ) . "\r\n" . $this->headers($response)
+                            : 'NULL';
+                        break;
+                    case 'req_body':
+                        $result = $request->getBody();
+                        break;
+                    case 'res_body':
+                        $result = $response ? $response->getBody() : 'NULL';
+                        break;
+                    case 'ts':
+                    case 'date_iso_8601':
+                        $result = gmdate('c');
+                        break;
+                    case 'date_common_log':
+                        $result = date('d/M/Y:H:i:s O');
+                        break;
+                    case 'method':
+                        $result = $request->getMethod();
+                        break;
+                    case 'version':
+                        $result = $request->getProtocolVersion();
+                        break;
+                    case 'uri':
+                    case 'url':
+                        $result = $request->getUri();
+                        break;
+                    case 'target':
+                        $result = $request->getRequestTarget();
+                        break;
+                    case 'req_version':
+                        $result = $request->getProtocolVersion();
+                        break;
+                    case 'res_version':
+                        $result = $response
+                            ? $response->getProtocolVersion()
+                            : 'NULL';
+                        break;
+                    case 'host':
+                        $result = $request->getHeaderLine('Host');
+                        break;
+                    case 'hostname':
+                        $result = gethostname();
+                        break;
+                    case 'code':
+                        $result = $response ? $response->getStatusCode() : 'NULL';
+                        break;
+                    case 'phrase':
+                        $result = $response ? $response->getReasonPhrase() : 'NULL';
+                        break;
+                    case 'error':
+                        $result = $error ? $error->getMessage() : 'NULL';
+                        break;
+                    default:
+                        // handle prefixed dynamic headers
+                        if (strpos($matches[1], 'req_header_') === 0) {
+                            $result = $request->getHeaderLine(substr($matches[1], 11));
+                        } elseif (strpos($matches[1], 'res_header_') === 0) {
+                            $result = $response
+                                ? $response->getHeaderLine(substr($matches[1], 11))
+                                : 'NULL';
+                        }
+                }
+
+                $cache[$matches[1]] = $result;
+                return $result;
+            },
+            $this->template
+        );
+    }
+
+    /**
+     * Get headers from message as string
+     *
+     * @return string
+     */
+    private function headers(MessageInterface $message)
+    {
+        $result = '';
+        foreach ($message->getHeaders() as $name => $values) {
+            $result .= $name . ': ' . implode(', ', $values) . "\r\n";
+        }
+
+        return trim($result);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Middleware.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Middleware.php
new file mode 100644 (file)
index 0000000..bffc197
--- /dev/null
@@ -0,0 +1,254 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Cookie\CookieJarInterface;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Promise\RejectedPromise;
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Functions used to create and wrap handlers with handler middleware.
+ */
+final class Middleware
+{
+    /**
+     * Middleware that adds cookies to requests.
+     *
+     * The options array must be set to a CookieJarInterface in order to use
+     * cookies. This is typically handled for you by a client.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function cookies()
+    {
+        return function (callable $handler) {
+            return function ($request, array $options) use ($handler) {
+                if (empty($options['cookies'])) {
+                    return $handler($request, $options);
+                } elseif (!($options['cookies'] instanceof CookieJarInterface)) {
+                    throw new \InvalidArgumentException('cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface');
+                }
+                $cookieJar = $options['cookies'];
+                $request = $cookieJar->withCookieHeader($request);
+                return $handler($request, $options)
+                    ->then(
+                        function ($response) use ($cookieJar, $request) {
+                            $cookieJar->extractCookies($request, $response);
+                            return $response;
+                        }
+                    );
+            };
+        };
+    }
+
+    /**
+     * Middleware that throws exceptions for 4xx or 5xx responses when the
+     * "http_error" request option is set to true.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function httpErrors()
+    {
+        return function (callable $handler) {
+            return function ($request, array $options) use ($handler) {
+                if (empty($options['http_errors'])) {
+                    return $handler($request, $options);
+                }
+                return $handler($request, $options)->then(
+                    function (ResponseInterface $response) use ($request) {
+                        $code = $response->getStatusCode();
+                        if ($code < 400) {
+                            return $response;
+                        }
+                        throw RequestException::create($request, $response);
+                    }
+                );
+            };
+        };
+    }
+
+    /**
+     * Middleware that pushes history data to an ArrayAccess container.
+     *
+     * @param array|\ArrayAccess $container Container to hold the history (by reference).
+     *
+     * @return callable Returns a function that accepts the next handler.
+     * @throws \InvalidArgumentException if container is not an array or ArrayAccess.
+     */
+    public static function history(&$container)
+    {
+        if (!is_array($container) && !$container instanceof \ArrayAccess) {
+            throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
+        }
+
+        return function (callable $handler) use (&$container) {
+            return function ($request, array $options) use ($handler, &$container) {
+                return $handler($request, $options)->then(
+                    function ($value) use ($request, &$container, $options) {
+                        $container[] = [
+                            'request'  => $request,
+                            'response' => $value,
+                            'error'    => null,
+                            'options'  => $options
+                        ];
+                        return $value;
+                    },
+                    function ($reason) use ($request, &$container, $options) {
+                        $container[] = [
+                            'request'  => $request,
+                            'response' => null,
+                            'error'    => $reason,
+                            'options'  => $options
+                        ];
+                        return \GuzzleHttp\Promise\rejection_for($reason);
+                    }
+                );
+            };
+        };
+    }
+
+    /**
+     * Middleware that invokes a callback before and after sending a request.
+     *
+     * The provided listener cannot modify or alter the response. It simply
+     * "taps" into the chain to be notified before returning the promise. The
+     * before listener accepts a request and options array, and the after
+     * listener accepts a request, options array, and response promise.
+     *
+     * @param callable $before Function to invoke before forwarding the request.
+     * @param callable $after  Function invoked after forwarding.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function tap(callable $before = null, callable $after = null)
+    {
+        return function (callable $handler) use ($before, $after) {
+            return function ($request, array $options) use ($handler, $before, $after) {
+                if ($before) {
+                    $before($request, $options);
+                }
+                $response = $handler($request, $options);
+                if ($after) {
+                    $after($request, $options, $response);
+                }
+                return $response;
+            };
+        };
+    }
+
+    /**
+     * Middleware that handles request redirects.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function redirect()
+    {
+        return function (callable $handler) {
+            return new RedirectMiddleware($handler);
+        };
+    }
+
+    /**
+     * Middleware that retries requests based on the boolean result of
+     * invoking the provided "decider" function.
+     *
+     * If no delay function is provided, a simple implementation of exponential
+     * backoff will be utilized.
+     *
+     * @param callable $decider Function that accepts the number of retries,
+     *                          a request, [response], and [exception] and
+     *                          returns true if the request is to be retried.
+     * @param callable $delay   Function that accepts the number of retries and
+     *                          returns the number of milliseconds to delay.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function retry(callable $decider, callable $delay = null)
+    {
+        return function (callable $handler) use ($decider, $delay) {
+            return new RetryMiddleware($decider, $handler, $delay);
+        };
+    }
+
+    /**
+     * Middleware that logs requests, responses, and errors using a message
+     * formatter.
+     *
+     * @param LoggerInterface  $logger Logs messages.
+     * @param MessageFormatter $formatter Formatter used to create message strings.
+     * @param string           $logLevel Level at which to log requests.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = 'info' /* \Psr\Log\LogLevel::INFO */)
+    {
+        return function (callable $handler) use ($logger, $formatter, $logLevel) {
+            return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
+                return $handler($request, $options)->then(
+                    function ($response) use ($logger, $request, $formatter, $logLevel) {
+                        $message = $formatter->format($request, $response);
+                        $logger->log($logLevel, $message);
+                        return $response;
+                    },
+                    function ($reason) use ($logger, $request, $formatter) {
+                        $response = $reason instanceof RequestException
+                            ? $reason->getResponse()
+                            : null;
+                        $message = $formatter->format($request, $response, $reason);
+                        $logger->notice($message);
+                        return \GuzzleHttp\Promise\rejection_for($reason);
+                    }
+                );
+            };
+        };
+    }
+
+    /**
+     * This middleware adds a default content-type if possible, a default
+     * content-length or transfer-encoding header, and the expect header.
+     *
+     * @return callable
+     */
+    public static function prepareBody()
+    {
+        return function (callable $handler) {
+            return new PrepareBodyMiddleware($handler);
+        };
+    }
+
+    /**
+     * Middleware that applies a map function to the request before passing to
+     * the next handler.
+     *
+     * @param callable $fn Function that accepts a RequestInterface and returns
+     *                     a RequestInterface.
+     * @return callable
+     */
+    public static function mapRequest(callable $fn)
+    {
+        return function (callable $handler) use ($fn) {
+            return function ($request, array $options) use ($handler, $fn) {
+                return $handler($fn($request), $options);
+            };
+        };
+    }
+
+    /**
+     * Middleware that applies a map function to the resolved promise's
+     * response.
+     *
+     * @param callable $fn Function that accepts a ResponseInterface and
+     *                     returns a ResponseInterface.
+     * @return callable
+     */
+    public static function mapResponse(callable $fn)
+    {
+        return function (callable $handler) use ($fn) {
+            return function ($request, array $options) use ($handler, $fn) {
+                return $handler($request, $options)->then($fn);
+            };
+        };
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Pool.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Pool.php
new file mode 100644 (file)
index 0000000..5838db4
--- /dev/null
@@ -0,0 +1,134 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\EachPromise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Promise\PromisorInterface;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Sends an iterator of requests concurrently using a capped pool size.
+ *
+ * The pool will read from an iterator until it is cancelled or until the
+ * iterator is consumed. When a request is yielded, the request is sent after
+ * applying the "request_options" request options (if provided in the ctor).
+ *
+ * When a function is yielded by the iterator, the function is provided the
+ * "request_options" array that should be merged on top of any existing
+ * options, and the function MUST then return a wait-able promise.
+ */
+class Pool implements PromisorInterface
+{
+    /** @var EachPromise */
+    private $each;
+
+    /**
+     * @param ClientInterface $client   Client used to send the requests.
+     * @param array|\Iterator $requests Requests or functions that return
+     *                                  requests to send concurrently.
+     * @param array           $config   Associative array of options
+     *     - concurrency: (int) Maximum number of requests to send concurrently
+     *     - options: Array of request options to apply to each request.
+     *     - fulfilled: (callable) Function to invoke when a request completes.
+     *     - rejected: (callable) Function to invoke when a request is rejected.
+     */
+    public function __construct(
+        ClientInterface $client,
+        $requests,
+        array $config = []
+    ) {
+        // Backwards compatibility.
+        if (isset($config['pool_size'])) {
+            $config['concurrency'] = $config['pool_size'];
+        } elseif (!isset($config['concurrency'])) {
+            $config['concurrency'] = 25;
+        }
+
+        if (isset($config['options'])) {
+            $opts = $config['options'];
+            unset($config['options']);
+        } else {
+            $opts = [];
+        }
+
+        $iterable = \GuzzleHttp\Promise\iter_for($requests);
+        $requests = function () use ($iterable, $client, $opts) {
+            foreach ($iterable as $key => $rfn) {
+                if ($rfn instanceof RequestInterface) {
+                    yield $key => $client->sendAsync($rfn, $opts);
+                } elseif (is_callable($rfn)) {
+                    yield $key => $rfn($opts);
+                } else {
+                    throw new \InvalidArgumentException('Each value yielded by '
+                        . 'the iterator must be a Psr7\Http\Message\RequestInterface '
+                        . 'or a callable that returns a promise that fulfills '
+                        . 'with a Psr7\Message\Http\ResponseInterface object.');
+                }
+            }
+        };
+
+        $this->each = new EachPromise($requests(), $config);
+    }
+
+    /**
+     * Get promise
+     *
+     * @return PromiseInterface
+     */
+    public function promise()
+    {
+        return $this->each->promise();
+    }
+
+    /**
+     * Sends multiple requests concurrently and returns an array of responses
+     * and exceptions that uses the same ordering as the provided requests.
+     *
+     * IMPORTANT: This method keeps every request and response in memory, and
+     * as such, is NOT recommended when sending a large number or an
+     * indeterminate number of requests concurrently.
+     *
+     * @param ClientInterface $client   Client used to send the requests
+     * @param array|\Iterator $requests Requests to send concurrently.
+     * @param array           $options  Passes through the options available in
+     *                                  {@see GuzzleHttp\Pool::__construct}
+     *
+     * @return array Returns an array containing the response or an exception
+     *               in the same order that the requests were sent.
+     * @throws \InvalidArgumentException if the event format is incorrect.
+     */
+    public static function batch(
+        ClientInterface $client,
+        $requests,
+        array $options = []
+    ) {
+        $res = [];
+        self::cmpCallback($options, 'fulfilled', $res);
+        self::cmpCallback($options, 'rejected', $res);
+        $pool = new static($client, $requests, $options);
+        $pool->promise()->wait();
+        ksort($res);
+
+        return $res;
+    }
+
+    /**
+     * Execute callback(s)
+     *
+     * @return void
+     */
+    private static function cmpCallback(array &$options, $name, array &$results)
+    {
+        if (!isset($options[$name])) {
+            $options[$name] = function ($v, $k) use (&$results) {
+                $results[$k] = $v;
+            };
+        } else {
+            $currentFn = $options[$name];
+            $options[$name] = function ($v, $k) use (&$results, $currentFn) {
+                $currentFn($v, $k);
+                $results[$k] = $v;
+            };
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php
new file mode 100644 (file)
index 0000000..568a1e9
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Prepares requests that contain a body, adding the Content-Length,
+ * Content-Type, and Expect headers.
+ */
+class PrepareBodyMiddleware
+{
+    /** @var callable  */
+    private $nextHandler;
+
+    /**
+     * @param callable $nextHandler Next handler to invoke.
+     */
+    public function __construct(callable $nextHandler)
+    {
+        $this->nextHandler = $nextHandler;
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param array            $options
+     *
+     * @return PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        $fn = $this->nextHandler;
+
+        // Don't do anything if the request has no body.
+        if ($request->getBody()->getSize() === 0) {
+            return $fn($request, $options);
+        }
+
+        $modify = [];
+
+        // Add a default content-type if possible.
+        if (!$request->hasHeader('Content-Type')) {
+            if ($uri = $request->getBody()->getMetadata('uri')) {
+                if ($type = Psr7\mimetype_from_filename($uri)) {
+                    $modify['set_headers']['Content-Type'] = $type;
+                }
+            }
+        }
+
+        // Add a default content-length or transfer-encoding header.
+        if (!$request->hasHeader('Content-Length')
+            && !$request->hasHeader('Transfer-Encoding')
+        ) {
+            $size = $request->getBody()->getSize();
+            if ($size !== null) {
+                $modify['set_headers']['Content-Length'] = $size;
+            } else {
+                $modify['set_headers']['Transfer-Encoding'] = 'chunked';
+            }
+        }
+
+        // Add the expect header if needed.
+        $this->addExpectHeader($request, $options, $modify);
+
+        return $fn(Psr7\modify_request($request, $modify), $options);
+    }
+
+    /**
+     * Add expect header
+     *
+     * @return void
+     */
+    private function addExpectHeader(
+        RequestInterface $request,
+        array $options,
+        array &$modify
+    ) {
+        // Determine if the Expect header should be used
+        if ($request->hasHeader('Expect')) {
+            return;
+        }
+
+        $expect = isset($options['expect']) ? $options['expect'] : null;
+
+        // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
+        if ($expect === false || $request->getProtocolVersion() < 1.1) {
+            return;
+        }
+
+        // The expect header is unconditionally enabled
+        if ($expect === true) {
+            $modify['set_headers']['Expect'] = '100-Continue';
+            return;
+        }
+
+        // By default, send the expect header when the payload is > 1mb
+        if ($expect === null) {
+            $expect = 1048576;
+        }
+
+        // Always add if the body cannot be rewound, the size cannot be
+        // determined, or the size is greater than the cutoff threshold
+        $body = $request->getBody();
+        $size = $body->getSize();
+
+        if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
+            $modify['set_headers']['Expect'] = '100-Continue';
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RedirectMiddleware.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RedirectMiddleware.php
new file mode 100644 (file)
index 0000000..e4644b7
--- /dev/null
@@ -0,0 +1,255 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\BadResponseException;
+use GuzzleHttp\Exception\TooManyRedirectsException;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Request redirect middleware.
+ *
+ * Apply this middleware like other middleware using
+ * {@see \GuzzleHttp\Middleware::redirect()}.
+ */
+class RedirectMiddleware
+{
+    const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
+
+    const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
+
+    public static $defaultSettings = [
+        'max'             => 5,
+        'protocols'       => ['http', 'https'],
+        'strict'          => false,
+        'referer'         => false,
+        'track_redirects' => false,
+    ];
+
+    /** @var callable  */
+    private $nextHandler;
+
+    /**
+     * @param callable $nextHandler Next handler to invoke.
+     */
+    public function __construct(callable $nextHandler)
+    {
+        $this->nextHandler = $nextHandler;
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param array            $options
+     *
+     * @return PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        $fn = $this->nextHandler;
+
+        if (empty($options['allow_redirects'])) {
+            return $fn($request, $options);
+        }
+
+        if ($options['allow_redirects'] === true) {
+            $options['allow_redirects'] = self::$defaultSettings;
+        } elseif (!is_array($options['allow_redirects'])) {
+            throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
+        } else {
+            // Merge the default settings with the provided settings
+            $options['allow_redirects'] += self::$defaultSettings;
+        }
+
+        if (empty($options['allow_redirects']['max'])) {
+            return $fn($request, $options);
+        }
+
+        return $fn($request, $options)
+            ->then(function (ResponseInterface $response) use ($request, $options) {
+                return $this->checkRedirect($request, $options, $response);
+            });
+    }
+
+    /**
+     * @param RequestInterface  $request
+     * @param array             $options
+     * @param ResponseInterface $response
+     *
+     * @return ResponseInterface|PromiseInterface
+     */
+    public function checkRedirect(
+        RequestInterface $request,
+        array $options,
+        ResponseInterface $response
+    ) {
+        if (substr($response->getStatusCode(), 0, 1) != '3'
+            || !$response->hasHeader('Location')
+        ) {
+            return $response;
+        }
+
+        $this->guardMax($request, $options);
+        $nextRequest = $this->modifyRequest($request, $options, $response);
+
+        if (isset($options['allow_redirects']['on_redirect'])) {
+            call_user_func(
+                $options['allow_redirects']['on_redirect'],
+                $request,
+                $response,
+                $nextRequest->getUri()
+            );
+        }
+
+        /** @var PromiseInterface|ResponseInterface $promise */
+        $promise = $this($nextRequest, $options);
+
+        // Add headers to be able to track history of redirects.
+        if (!empty($options['allow_redirects']['track_redirects'])) {
+            return $this->withTracking(
+                $promise,
+                (string) $nextRequest->getUri(),
+                $response->getStatusCode()
+            );
+        }
+
+        return $promise;
+    }
+
+    /**
+     * Enable tracking on promise.
+     *
+     * @return PromiseInterface
+     */
+    private function withTracking(PromiseInterface $promise, $uri, $statusCode)
+    {
+        return $promise->then(
+            function (ResponseInterface $response) use ($uri, $statusCode) {
+                // Note that we are pushing to the front of the list as this
+                // would be an earlier response than what is currently present
+                // in the history header.
+                $historyHeader = $response->getHeader(self::HISTORY_HEADER);
+                $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
+                array_unshift($historyHeader, $uri);
+                array_unshift($statusHeader, $statusCode);
+                return $response->withHeader(self::HISTORY_HEADER, $historyHeader)
+                                ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
+            }
+        );
+    }
+
+    /**
+     * Check for too many redirects
+     *
+     * @return void
+     *
+     * @throws TooManyRedirectsException Too many redirects.
+     */
+    private function guardMax(RequestInterface $request, array &$options)
+    {
+        $current = isset($options['__redirect_count'])
+            ? $options['__redirect_count']
+            : 0;
+        $options['__redirect_count'] = $current + 1;
+        $max = $options['allow_redirects']['max'];
+
+        if ($options['__redirect_count'] > $max) {
+            throw new TooManyRedirectsException(
+                "Will not follow more than {$max} redirects",
+                $request
+            );
+        }
+    }
+
+    /**
+     * @param RequestInterface  $request
+     * @param array             $options
+     * @param ResponseInterface $response
+     *
+     * @return RequestInterface
+     */
+    public function modifyRequest(
+        RequestInterface $request,
+        array $options,
+        ResponseInterface $response
+    ) {
+        // Request modifications to apply.
+        $modify = [];
+        $protocols = $options['allow_redirects']['protocols'];
+
+        // Use a GET request if this is an entity enclosing request and we are
+        // not forcing RFC compliance, but rather emulating what all browsers
+        // would do.
+        $statusCode = $response->getStatusCode();
+        if ($statusCode == 303 ||
+            ($statusCode <= 302 && !$options['allow_redirects']['strict'])
+        ) {
+            $modify['method'] = 'GET';
+            $modify['body'] = '';
+        }
+
+        $uri = $this->redirectUri($request, $response, $protocols);
+        if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
+            $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion'];
+            $uri = Utils::idnUriConvert($uri, $idnOptions);
+        }
+
+        $modify['uri'] = $uri;
+        Psr7\rewind_body($request);
+
+        // Add the Referer header if it is told to do so and only
+        // add the header if we are not redirecting from https to http.
+        if ($options['allow_redirects']['referer']
+            && $modify['uri']->getScheme() === $request->getUri()->getScheme()
+        ) {
+            $uri = $request->getUri()->withUserInfo('');
+            $modify['set_headers']['Referer'] = (string) $uri;
+        } else {
+            $modify['remove_headers'][] = 'Referer';
+        }
+
+        // Remove Authorization header if host is different.
+        if ($request->getUri()->getHost() !== $modify['uri']->getHost()) {
+            $modify['remove_headers'][] = 'Authorization';
+        }
+
+        return Psr7\modify_request($request, $modify);
+    }
+
+    /**
+     * Set the appropriate URL on the request based on the location header
+     *
+     * @param RequestInterface  $request
+     * @param ResponseInterface $response
+     * @param array             $protocols
+     *
+     * @return UriInterface
+     */
+    private function redirectUri(
+        RequestInterface $request,
+        ResponseInterface $response,
+        array $protocols
+    ) {
+        $location = Psr7\UriResolver::resolve(
+            $request->getUri(),
+            new Psr7\Uri($response->getHeaderLine('Location'))
+        );
+
+        // Ensure that the redirect URI is allowed based on the protocols.
+        if (!in_array($location->getScheme(), $protocols)) {
+            throw new BadResponseException(
+                sprintf(
+                    'Redirect URI, %s, does not use one of the allowed redirect protocols: %s',
+                    $location,
+                    implode(', ', $protocols)
+                ),
+                $request,
+                $response
+            );
+        }
+
+        return $location;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RequestOptions.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RequestOptions.php
new file mode 100644 (file)
index 0000000..355f658
--- /dev/null
@@ -0,0 +1,263 @@
+<?php
+namespace GuzzleHttp;
+
+/**
+ * This class contains a list of built-in Guzzle request options.
+ *
+ * More documentation for each option can be found at http://guzzlephp.org/.
+ *
+ * @link http://docs.guzzlephp.org/en/v6/request-options.html
+ */
+final class RequestOptions
+{
+    /**
+     * allow_redirects: (bool|array) Controls redirect behavior. Pass false
+     * to disable redirects, pass true to enable redirects, pass an
+     * associative to provide custom redirect settings. Defaults to "false".
+     * This option only works if your handler has the RedirectMiddleware. When
+     * passing an associative array, you can provide the following key value
+     * pairs:
+     *
+     * - max: (int, default=5) maximum number of allowed redirects.
+     * - strict: (bool, default=false) Set to true to use strict redirects
+     *   meaning redirect POST requests with POST requests vs. doing what most
+     *   browsers do which is redirect POST requests with GET requests
+     * - referer: (bool, default=false) Set to true to enable the Referer
+     *   header.
+     * - protocols: (array, default=['http', 'https']) Allowed redirect
+     *   protocols.
+     * - on_redirect: (callable) PHP callable that is invoked when a redirect
+     *   is encountered. The callable is invoked with the request, the redirect
+     *   response that was received, and the effective URI. Any return value
+     *   from the on_redirect function is ignored.
+     */
+    const ALLOW_REDIRECTS = 'allow_redirects';
+
+    /**
+     * auth: (array) Pass an array of HTTP authentication parameters to use
+     * with the request. The array must contain the username in index [0],
+     * the password in index [1], and you can optionally provide a built-in
+     * authentication type in index [2]. Pass null to disable authentication
+     * for a request.
+     */
+    const AUTH = 'auth';
+
+    /**
+     * body: (resource|string|null|int|float|StreamInterface|callable|\Iterator)
+     * Body to send in the request.
+     */
+    const BODY = 'body';
+
+    /**
+     * cert: (string|array) Set to a string to specify the path to a file
+     * containing a PEM formatted SSL client side certificate. If a password
+     * is required, then set cert to an array containing the path to the PEM
+     * file in the first array element followed by the certificate password
+     * in the second array element.
+     */
+    const CERT = 'cert';
+
+    /**
+     * cookies: (bool|GuzzleHttp\Cookie\CookieJarInterface, default=false)
+     * Specifies whether or not cookies are used in a request or what cookie
+     * jar to use or what cookies to send. This option only works if your
+     * handler has the `cookie` middleware. Valid values are `false` and
+     * an instance of {@see GuzzleHttp\Cookie\CookieJarInterface}.
+     */
+    const COOKIES = 'cookies';
+
+    /**
+     * connect_timeout: (float, default=0) Float describing the number of
+     * seconds to wait while trying to connect to a server. Use 0 to wait
+     * indefinitely (the default behavior).
+     */
+    const CONNECT_TIMEOUT = 'connect_timeout';
+
+    /**
+     * debug: (bool|resource) Set to true or set to a PHP stream returned by
+     * fopen()  enable debug output with the HTTP handler used to send a
+     * request.
+     */
+    const DEBUG = 'debug';
+
+    /**
+     * decode_content: (bool, default=true) Specify whether or not
+     * Content-Encoding responses (gzip, deflate, etc.) are automatically
+     * decoded.
+     */
+    const DECODE_CONTENT = 'decode_content';
+
+    /**
+     * delay: (int) The amount of time to delay before sending in milliseconds.
+     */
+    const DELAY = 'delay';
+
+    /**
+     * expect: (bool|integer) Controls the behavior of the
+     * "Expect: 100-Continue" header.
+     *
+     * Set to `true` to enable the "Expect: 100-Continue" header for all
+     * requests that sends a body. Set to `false` to disable the
+     * "Expect: 100-Continue" header for all requests. Set to a number so that
+     * the size of the payload must be greater than the number in order to send
+     * the Expect header. Setting to a number will send the Expect header for
+     * all requests in which the size of the payload cannot be determined or
+     * where the body is not rewindable.
+     *
+     * By default, Guzzle will add the "Expect: 100-Continue" header when the
+     * size of the body of a request is greater than 1 MB and a request is
+     * using HTTP/1.1.
+     */
+    const EXPECT = 'expect';
+
+    /**
+     * form_params: (array) Associative array of form field names to values
+     * where each value is a string or array of strings. Sets the Content-Type
+     * header to application/x-www-form-urlencoded when no Content-Type header
+     * is already present.
+     */
+    const FORM_PARAMS = 'form_params';
+
+    /**
+     * headers: (array) Associative array of HTTP headers. Each value MUST be
+     * a string or array of strings.
+     */
+    const HEADERS = 'headers';
+
+    /**
+     * http_errors: (bool, default=true) Set to false to disable exceptions
+     * when a non- successful HTTP response is received. By default,
+     * exceptions will be thrown for 4xx and 5xx responses. This option only
+     * works if your handler has the `httpErrors` middleware.
+     */
+    const HTTP_ERRORS = 'http_errors';
+
+    /**
+     * idn: (bool|int, default=true) A combination of IDNA_* constants for
+     * idn_to_ascii() PHP's function (see "options" parameter). Set to false to
+     * disable IDN support completely, or to true to use the default
+     * configuration (IDNA_DEFAULT constant).
+     */
+    const IDN_CONVERSION = 'idn_conversion';
+
+    /**
+     * json: (mixed) Adds JSON data to a request. The provided value is JSON
+     * encoded and a Content-Type header of application/json will be added to
+     * the request if no Content-Type header is already present.
+     */
+    const JSON = 'json';
+
+    /**
+     * multipart: (array) Array of associative arrays, each containing a
+     * required "name" key mapping to the form field, name, a required
+     * "contents" key mapping to a StreamInterface|resource|string, an
+     * optional "headers" associative array of custom headers, and an
+     * optional "filename" key mapping to a string to send as the filename in
+     * the part. If no "filename" key is present, then no "filename" attribute
+     * will be added to the part.
+     */
+    const MULTIPART = 'multipart';
+
+    /**
+     * on_headers: (callable) A callable that is invoked when the HTTP headers
+     * of the response have been received but the body has not yet begun to
+     * download.
+     */
+    const ON_HEADERS = 'on_headers';
+
+    /**
+     * on_stats: (callable) allows you to get access to transfer statistics of
+     * a request and access the lower level transfer details of the handler
+     * associated with your client. ``on_stats`` is a callable that is invoked
+     * when a handler has finished sending a request. The callback is invoked
+     * with transfer statistics about the request, the response received, or
+     * the error encountered. Included in the data is the total amount of time
+     * taken to send the request.
+     */
+    const ON_STATS = 'on_stats';
+
+    /**
+     * progress: (callable) Defines a function to invoke when transfer
+     * progress is made. The function accepts the following positional
+     * arguments: the total number of bytes expected to be downloaded, the
+     * number of bytes downloaded so far, the number of bytes expected to be
+     * uploaded, the number of bytes uploaded so far.
+     */
+    const PROGRESS = 'progress';
+
+    /**
+     * proxy: (string|array) Pass a string to specify an HTTP proxy, or an
+     * array to specify different proxies for different protocols (where the
+     * key is the protocol and the value is a proxy string).
+     */
+    const PROXY = 'proxy';
+
+    /**
+     * query: (array|string) Associative array of query string values to add
+     * to the request. This option uses PHP's http_build_query() to create
+     * the string representation. Pass a string value if you need more
+     * control than what this method provides
+     */
+    const QUERY = 'query';
+
+    /**
+     * sink: (resource|string|StreamInterface) Where the data of the
+     * response is written to. Defaults to a PHP temp stream. Providing a
+     * string will write data to a file by the given name.
+     */
+    const SINK = 'sink';
+
+    /**
+     * synchronous: (bool) Set to true to inform HTTP handlers that you intend
+     * on waiting on the response. This can be useful for optimizations. Note
+     * that a promise is still returned if you are using one of the async
+     * client methods.
+     */
+    const SYNCHRONOUS = 'synchronous';
+
+    /**
+     * ssl_key: (array|string) Specify the path to a file containing a private
+     * SSL key in PEM format. If a password is required, then set to an array
+     * containing the path to the SSL key in the first array element followed
+     * by the password required for the certificate in the second element.
+     */
+    const SSL_KEY = 'ssl_key';
+
+    /**
+     * stream: Set to true to attempt to stream a response rather than
+     * download it all up-front.
+     */
+    const STREAM = 'stream';
+
+    /**
+     * verify: (bool|string, default=true) Describes the SSL certificate
+     * verification behavior of a request. Set to true to enable SSL
+     * certificate verification using the system CA bundle when available
+     * (the default). Set to false to disable certificate verification (this
+     * is insecure!). Set to a string to provide the path to a CA bundle on
+     * disk to enable verification using a custom certificate.
+     */
+    const VERIFY = 'verify';
+
+    /**
+     * timeout: (float, default=0) Float describing the timeout of the
+     * request in seconds. Use 0 to wait indefinitely (the default behavior).
+     */
+    const TIMEOUT = 'timeout';
+
+    /**
+     * read_timeout: (float, default=default_socket_timeout ini setting) Float describing
+     * the body read timeout, for stream requests.
+     */
+    const READ_TIMEOUT = 'read_timeout';
+
+    /**
+     * version: (float) Specifies the HTTP protocol version to attempt to use.
+     */
+    const VERSION = 'version';
+
+    /**
+     * force_ip_resolve: (bool) Force client to use only ipv4 or ipv6 protocol
+     */
+    const FORCE_IP_RESOLVE = 'force_ip_resolve';
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RetryMiddleware.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/RetryMiddleware.php
new file mode 100644 (file)
index 0000000..5acc8c5
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Promise\RejectedPromise;
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Middleware that retries requests based on the boolean result of
+ * invoking the provided "decider" function.
+ */
+class RetryMiddleware
+{
+    /** @var callable  */
+    private $nextHandler;
+
+    /** @var callable */
+    private $decider;
+
+    /** @var callable */
+    private $delay;
+
+    /**
+     * @param callable $decider     Function that accepts the number of retries,
+     *                              a request, [response], and [exception] and
+     *                              returns true if the request is to be
+     *                              retried.
+     * @param callable $nextHandler Next handler to invoke.
+     * @param callable $delay       Function that accepts the number of retries
+     *                              and [response] and returns the number of
+     *                              milliseconds to delay.
+     */
+    public function __construct(
+        callable $decider,
+        callable $nextHandler,
+        callable $delay = null
+    ) {
+        $this->decider = $decider;
+        $this->nextHandler = $nextHandler;
+        $this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
+    }
+
+    /**
+     * Default exponential backoff delay function.
+     *
+     * @param int $retries
+     *
+     * @return int milliseconds.
+     */
+    public static function exponentialDelay($retries)
+    {
+        return (int) pow(2, $retries - 1) * 1000;
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param array            $options
+     *
+     * @return PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        if (!isset($options['retries'])) {
+            $options['retries'] = 0;
+        }
+
+        $fn = $this->nextHandler;
+        return $fn($request, $options)
+            ->then(
+                $this->onFulfilled($request, $options),
+                $this->onRejected($request, $options)
+            );
+    }
+
+    /**
+     * Execute fulfilled closure
+     *
+     * @return mixed
+     */
+    private function onFulfilled(RequestInterface $req, array $options)
+    {
+        return function ($value) use ($req, $options) {
+            if (!call_user_func(
+                $this->decider,
+                $options['retries'],
+                $req,
+                $value,
+                null
+            )) {
+                return $value;
+            }
+            return $this->doRetry($req, $options, $value);
+        };
+    }
+
+    /**
+     * Execute rejected closure
+     *
+     * @return callable
+     */
+    private function onRejected(RequestInterface $req, array $options)
+    {
+        return function ($reason) use ($req, $options) {
+            if (!call_user_func(
+                $this->decider,
+                $options['retries'],
+                $req,
+                null,
+                $reason
+            )) {
+                return \GuzzleHttp\Promise\rejection_for($reason);
+            }
+            return $this->doRetry($req, $options);
+        };
+    }
+
+    /**
+     * @return self
+     */
+    private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
+    {
+        $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);
+
+        return $this($request, $options);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/TransferStats.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/TransferStats.php
new file mode 100644 (file)
index 0000000..87fb3c0
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+namespace GuzzleHttp;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Represents data at the point after it was transferred either successfully
+ * or after a network error.
+ */
+final class TransferStats
+{
+    private $request;
+    private $response;
+    private $transferTime;
+    private $handlerStats;
+    private $handlerErrorData;
+
+    /**
+     * @param RequestInterface       $request          Request that was sent.
+     * @param ResponseInterface|null $response         Response received (if any)
+     * @param float|null             $transferTime     Total handler transfer time.
+     * @param mixed                  $handlerErrorData Handler error data.
+     * @param array                  $handlerStats     Handler specific stats.
+     */
+    public function __construct(
+        RequestInterface $request,
+        ResponseInterface $response = null,
+        $transferTime = null,
+        $handlerErrorData = null,
+        $handlerStats = []
+    ) {
+        $this->request = $request;
+        $this->response = $response;
+        $this->transferTime = $transferTime;
+        $this->handlerErrorData = $handlerErrorData;
+        $this->handlerStats = $handlerStats;
+    }
+
+    /**
+     * @return RequestInterface
+     */
+    public function getRequest()
+    {
+        return $this->request;
+    }
+
+    /**
+     * Returns the response that was received (if any).
+     *
+     * @return ResponseInterface|null
+     */
+    public function getResponse()
+    {
+        return $this->response;
+    }
+
+    /**
+     * Returns true if a response was received.
+     *
+     * @return bool
+     */
+    public function hasResponse()
+    {
+        return $this->response !== null;
+    }
+
+    /**
+     * Gets handler specific error data.
+     *
+     * This might be an exception, a integer representing an error code, or
+     * anything else. Relying on this value assumes that you know what handler
+     * you are using.
+     *
+     * @return mixed
+     */
+    public function getHandlerErrorData()
+    {
+        return $this->handlerErrorData;
+    }
+
+    /**
+     * Get the effective URI the request was sent to.
+     *
+     * @return UriInterface
+     */
+    public function getEffectiveUri()
+    {
+        return $this->request->getUri();
+    }
+
+    /**
+     * Get the estimated time the request was being transferred by the handler.
+     *
+     * @return float|null Time in seconds.
+     */
+    public function getTransferTime()
+    {
+        return $this->transferTime;
+    }
+
+    /**
+     * Gets an array of all of the handler specific transfer data.
+     *
+     * @return array
+     */
+    public function getHandlerStats()
+    {
+        return $this->handlerStats;
+    }
+
+    /**
+     * Get a specific handler statistic from the handler by name.
+     *
+     * @param string $stat Handler specific transfer stat to retrieve.
+     *
+     * @return mixed|null
+     */
+    public function getHandlerStat($stat)
+    {
+        return isset($this->handlerStats[$stat])
+            ? $this->handlerStats[$stat]
+            : null;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/UriTemplate.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/UriTemplate.php
new file mode 100644 (file)
index 0000000..96dcfd0
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+namespace GuzzleHttp;
+
+/**
+ * Expands URI templates. Userland implementation of PECL uri_template.
+ *
+ * @link http://tools.ietf.org/html/rfc6570
+ */
+class UriTemplate
+{
+    /** @var string URI template */
+    private $template;
+
+    /** @var array Variables to use in the template expansion */
+    private $variables;
+
+    /** @var array Hash for quick operator lookups */
+    private static $operatorHash = [
+        ''  => ['prefix' => '',  'joiner' => ',', 'query' => false],
+        '+' => ['prefix' => '',  'joiner' => ',', 'query' => false],
+        '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false],
+        '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false],
+        '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false],
+        ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true],
+        '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true],
+        '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true]
+    ];
+
+    /** @var array Delimiters */
+    private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$',
+        '&', '\'', '(', ')', '*', '+', ',', ';', '='];
+
+    /** @var array Percent encoded delimiters */
+    private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D',
+        '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C',
+        '%3B', '%3D'];
+
+    public function expand($template, array $variables)
+    {
+        if (false === strpos($template, '{')) {
+            return $template;
+        }
+
+        $this->template = $template;
+        $this->variables = $variables;
+
+        return preg_replace_callback(
+            '/\{([^\}]+)\}/',
+            [$this, 'expandMatch'],
+            $this->template
+        );
+    }
+
+    /**
+     * Parse an expression into parts
+     *
+     * @param string $expression Expression to parse
+     *
+     * @return array Returns an associative array of parts
+     */
+    private function parseExpression($expression)
+    {
+        $result = [];
+
+        if (isset(self::$operatorHash[$expression[0]])) {
+            $result['operator'] = $expression[0];
+            $expression = substr($expression, 1);
+        } else {
+            $result['operator'] = '';
+        }
+
+        foreach (explode(',', $expression) as $value) {
+            $value = trim($value);
+            $varspec = [];
+            if ($colonPos = strpos($value, ':')) {
+                $varspec['value'] = substr($value, 0, $colonPos);
+                $varspec['modifier'] = ':';
+                $varspec['position'] = (int) substr($value, $colonPos + 1);
+            } elseif (substr($value, -1) === '*') {
+                $varspec['modifier'] = '*';
+                $varspec['value'] = substr($value, 0, -1);
+            } else {
+                $varspec['value'] = (string) $value;
+                $varspec['modifier'] = '';
+            }
+            $result['values'][] = $varspec;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Process an expansion
+     *
+     * @param array $matches Matches met in the preg_replace_callback
+     *
+     * @return string Returns the replacement string
+     */
+    private function expandMatch(array $matches)
+    {
+        static $rfc1738to3986 = ['+' => '%20', '%7e' => '~'];
+
+        $replacements = [];
+        $parsed = self::parseExpression($matches[1]);
+        $prefix = self::$operatorHash[$parsed['operator']]['prefix'];
+        $joiner = self::$operatorHash[$parsed['operator']]['joiner'];
+        $useQuery = self::$operatorHash[$parsed['operator']]['query'];
+
+        foreach ($parsed['values'] as $value) {
+            if (!isset($this->variables[$value['value']])) {
+                continue;
+            }
+
+            $variable = $this->variables[$value['value']];
+            $actuallyUseQuery = $useQuery;
+            $expanded = '';
+
+            if (is_array($variable)) {
+                $isAssoc = $this->isAssoc($variable);
+                $kvp = [];
+                foreach ($variable as $key => $var) {
+                    if ($isAssoc) {
+                        $key = rawurlencode($key);
+                        $isNestedArray = is_array($var);
+                    } else {
+                        $isNestedArray = false;
+                    }
+
+                    if (!$isNestedArray) {
+                        $var = rawurlencode($var);
+                        if ($parsed['operator'] === '+' ||
+                            $parsed['operator'] === '#'
+                        ) {
+                            $var = $this->decodeReserved($var);
+                        }
+                    }
+
+                    if ($value['modifier'] === '*') {
+                        if ($isAssoc) {
+                            if ($isNestedArray) {
+                                // Nested arrays must allow for deeply nested
+                                // structures.
+                                $var = strtr(
+                                    http_build_query([$key => $var]),
+                                    $rfc1738to3986
+                                );
+                            } else {
+                                $var = $key . '=' . $var;
+                            }
+                        } elseif ($key > 0 && $actuallyUseQuery) {
+                            $var = $value['value'] . '=' . $var;
+                        }
+                    }
+
+                    $kvp[$key] = $var;
+                }
+
+                if (empty($variable)) {
+                    $actuallyUseQuery = false;
+                } elseif ($value['modifier'] === '*') {
+                    $expanded = implode($joiner, $kvp);
+                    if ($isAssoc) {
+                        // Don't prepend the value name when using the explode
+                        // modifier with an associative array.
+                        $actuallyUseQuery = false;
+                    }
+                } else {
+                    if ($isAssoc) {
+                        // When an associative array is encountered and the
+                        // explode modifier is not set, then the result must be
+                        // a comma separated list of keys followed by their
+                        // respective values.
+                        foreach ($kvp as $k => &$v) {
+                            $v = $k . ',' . $v;
+                        }
+                    }
+                    $expanded = implode(',', $kvp);
+                }
+            } else {
+                if ($value['modifier'] === ':') {
+                    $variable = substr($variable, 0, $value['position']);
+                }
+                $expanded = rawurlencode($variable);
+                if ($parsed['operator'] === '+' || $parsed['operator'] === '#') {
+                    $expanded = $this->decodeReserved($expanded);
+                }
+            }
+
+            if ($actuallyUseQuery) {
+                if (!$expanded && $joiner !== '&') {
+                    $expanded = $value['value'];
+                } else {
+                    $expanded = $value['value'] . '=' . $expanded;
+                }
+            }
+
+            $replacements[] = $expanded;
+        }
+
+        $ret = implode($joiner, $replacements);
+        if ($ret && $prefix) {
+            return $prefix . $ret;
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Determines if an array is associative.
+     *
+     * This makes the assumption that input arrays are sequences or hashes.
+     * This assumption is a tradeoff for accuracy in favor of speed, but it
+     * should work in almost every case where input is supplied for a URI
+     * template.
+     *
+     * @param array $array Array to check
+     *
+     * @return bool
+     */
+    private function isAssoc(array $array)
+    {
+        return $array && array_keys($array)[0] !== 0;
+    }
+
+    /**
+     * Removes percent encoding on reserved characters (used with + and #
+     * modifiers).
+     *
+     * @param string $string String to fix
+     *
+     * @return string
+     */
+    private function decodeReserved($string)
+    {
+        return str_replace(self::$delimsPct, self::$delims, $string);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Utils.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/Utils.php
new file mode 100644 (file)
index 0000000..c698acb
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\InvalidArgumentException;
+use Psr\Http\Message\UriInterface;
+use Symfony\Polyfill\Intl\Idn\Idn;
+
+final class Utils
+{
+    /**
+     * Wrapper for the hrtime() or microtime() functions
+     * (depending on the PHP version, one of the two is used)
+     *
+     * @return float|mixed UNIX timestamp
+     *
+     * @internal
+     */
+    public static function currentTime()
+    {
+        return function_exists('hrtime') ? hrtime(true) / 1e9 : microtime(true);
+    }
+
+    /**
+     * @param int $options
+     *
+     * @return UriInterface
+     * @throws InvalidArgumentException
+     *
+     * @internal
+     */
+    public static function idnUriConvert(UriInterface $uri, $options = 0)
+    {
+        if ($uri->getHost()) {
+            $asciiHost = self::idnToAsci($uri->getHost(), $options, $info);
+            if ($asciiHost === false) {
+                $errorBitSet = isset($info['errors']) ? $info['errors'] : 0;
+
+                $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) {
+                    return substr($name, 0, 11) === 'IDNA_ERROR_';
+                });
+
+                $errors = [];
+                foreach ($errorConstants as $errorConstant) {
+                    if ($errorBitSet & constant($errorConstant)) {
+                        $errors[] = $errorConstant;
+                    }
+                }
+
+                $errorMessage = 'IDN conversion failed';
+                if ($errors) {
+                    $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')';
+                }
+
+                throw new InvalidArgumentException($errorMessage);
+            } else {
+                if ($uri->getHost() !== $asciiHost) {
+                    // Replace URI only if the ASCII version is different
+                    $uri = $uri->withHost($asciiHost);
+                }
+            }
+        }
+
+        return $uri;
+    }
+
+    /**
+     * @param string $domain
+     * @param int    $options
+     * @param array  $info
+     *
+     * @return string|false
+     */
+    private static function idnToAsci($domain, $options, &$info = [])
+    {
+        if (\preg_match('%^[ -~]+$%', $domain) === 1) {
+            return $domain;
+        }
+
+        if (\extension_loaded('intl') && defined('INTL_IDNA_VARIANT_UTS46')) {
+            return \idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $info);
+        }
+
+        /*
+         * The Idn class is marked as @internal. Verify that class and method exists.
+         */
+        if (method_exists(Idn::class, 'idn_to_ascii')) {
+            return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info);
+        }
+
+        throw new \RuntimeException('ext-intl or symfony/polyfill-intl-idn not loaded or too old');
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/functions.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/functions.php
new file mode 100644 (file)
index 0000000..c2afd8c
--- /dev/null
@@ -0,0 +1,334 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Handler\CurlHandler;
+use GuzzleHttp\Handler\CurlMultiHandler;
+use GuzzleHttp\Handler\Proxy;
+use GuzzleHttp\Handler\StreamHandler;
+
+/**
+ * Expands a URI template
+ *
+ * @param string $template  URI template
+ * @param array  $variables Template variables
+ *
+ * @return string
+ */
+function uri_template($template, array $variables)
+{
+    if (extension_loaded('uri_template')) {
+        // @codeCoverageIgnoreStart
+        return \uri_template($template, $variables);
+        // @codeCoverageIgnoreEnd
+    }
+
+    static $uriTemplate;
+    if (!$uriTemplate) {
+        $uriTemplate = new UriTemplate();
+    }
+
+    return $uriTemplate->expand($template, $variables);
+}
+
+/**
+ * Debug function used to describe the provided value type and class.
+ *
+ * @param mixed $input
+ *
+ * @return string Returns a string containing the type of the variable and
+ *                if a class is provided, the class name.
+ */
+function describe_type($input)
+{
+    switch (gettype($input)) {
+        case 'object':
+            return 'object(' . get_class($input) . ')';
+        case 'array':
+            return 'array(' . count($input) . ')';
+        default:
+            ob_start();
+            var_dump($input);
+            // normalize float vs double
+            return str_replace('double(', 'float(', rtrim(ob_get_clean()));
+    }
+}
+
+/**
+ * Parses an array of header lines into an associative array of headers.
+ *
+ * @param iterable $lines Header lines array of strings in the following
+ *                     format: "Name: Value"
+ * @return array
+ */
+function headers_from_lines($lines)
+{
+    $headers = [];
+
+    foreach ($lines as $line) {
+        $parts = explode(':', $line, 2);
+        $headers[trim($parts[0])][] = isset($parts[1])
+            ? trim($parts[1])
+            : null;
+    }
+
+    return $headers;
+}
+
+/**
+ * Returns a debug stream based on the provided variable.
+ *
+ * @param mixed $value Optional value
+ *
+ * @return resource
+ */
+function debug_resource($value = null)
+{
+    if (is_resource($value)) {
+        return $value;
+    } elseif (defined('STDOUT')) {
+        return STDOUT;
+    }
+
+    return fopen('php://output', 'w');
+}
+
+/**
+ * Chooses and creates a default handler to use based on the environment.
+ *
+ * The returned handler is not wrapped by any default middlewares.
+ *
+ * @return callable Returns the best handler for the given system.
+ * @throws \RuntimeException if no viable Handler is available.
+ */
+function choose_handler()
+{
+    $handler = null;
+    if (function_exists('curl_multi_exec') && function_exists('curl_exec')) {
+        $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
+    } elseif (function_exists('curl_exec')) {
+        $handler = new CurlHandler();
+    } elseif (function_exists('curl_multi_exec')) {
+        $handler = new CurlMultiHandler();
+    }
+
+    if (ini_get('allow_url_fopen')) {
+        $handler = $handler
+            ? Proxy::wrapStreaming($handler, new StreamHandler())
+            : new StreamHandler();
+    } elseif (!$handler) {
+        throw new \RuntimeException('GuzzleHttp requires cURL, the '
+            . 'allow_url_fopen ini setting, or a custom HTTP handler.');
+    }
+
+    return $handler;
+}
+
+/**
+ * Get the default User-Agent string to use with Guzzle
+ *
+ * @return string
+ */
+function default_user_agent()
+{
+    static $defaultAgent = '';
+
+    if (!$defaultAgent) {
+        $defaultAgent = 'GuzzleHttp/' . Client::VERSION;
+        if (extension_loaded('curl') && function_exists('curl_version')) {
+            $defaultAgent .= ' curl/' . \curl_version()['version'];
+        }
+        $defaultAgent .= ' PHP/' . PHP_VERSION;
+    }
+
+    return $defaultAgent;
+}
+
+/**
+ * Returns the default cacert bundle for the current system.
+ *
+ * First, the openssl.cafile and curl.cainfo php.ini settings are checked.
+ * If those settings are not configured, then the common locations for
+ * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X
+ * and Windows are checked. If any of these file locations are found on
+ * disk, they will be utilized.
+ *
+ * Note: the result of this function is cached for subsequent calls.
+ *
+ * @return string
+ * @throws \RuntimeException if no bundle can be found.
+ */
+function default_ca_bundle()
+{
+    static $cached = null;
+    static $cafiles = [
+        // Red Hat, CentOS, Fedora (provided by the ca-certificates package)
+        '/etc/pki/tls/certs/ca-bundle.crt',
+        // Ubuntu, Debian (provided by the ca-certificates package)
+        '/etc/ssl/certs/ca-certificates.crt',
+        // FreeBSD (provided by the ca_root_nss package)
+        '/usr/local/share/certs/ca-root-nss.crt',
+        // SLES 12 (provided by the ca-certificates package)
+        '/var/lib/ca-certificates/ca-bundle.pem',
+        // OS X provided by homebrew (using the default path)
+        '/usr/local/etc/openssl/cert.pem',
+        // Google app engine
+        '/etc/ca-certificates.crt',
+        // Windows?
+        'C:\\windows\\system32\\curl-ca-bundle.crt',
+        'C:\\windows\\curl-ca-bundle.crt',
+    ];
+
+    if ($cached) {
+        return $cached;
+    }
+
+    if ($ca = ini_get('openssl.cafile')) {
+        return $cached = $ca;
+    }
+
+    if ($ca = ini_get('curl.cainfo')) {
+        return $cached = $ca;
+    }
+
+    foreach ($cafiles as $filename) {
+        if (file_exists($filename)) {
+            return $cached = $filename;
+        }
+    }
+
+    throw new \RuntimeException(
+        <<< EOT
+No system CA bundle could be found in any of the the common system locations.
+PHP versions earlier than 5.6 are not properly configured to use the system's
+CA bundle by default. In order to verify peer certificates, you will need to
+supply the path on disk to a certificate bundle to the 'verify' request
+option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not
+need a specific certificate bundle, then Mozilla provides a commonly used CA
+bundle which can be downloaded here (provided by the maintainer of cURL):
+https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once
+you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP
+ini setting to point to the path to the file, allowing you to omit the 'verify'
+request option. See http://curl.haxx.se/docs/sslcerts.html for more
+information.
+EOT
+    );
+}
+
+/**
+ * Creates an associative array of lowercase header names to the actual
+ * header casing.
+ *
+ * @param array $headers
+ *
+ * @return array
+ */
+function normalize_header_keys(array $headers)
+{
+    $result = [];
+    foreach (array_keys($headers) as $key) {
+        $result[strtolower($key)] = $key;
+    }
+
+    return $result;
+}
+
+/**
+ * Returns true if the provided host matches any of the no proxy areas.
+ *
+ * This method will strip a port from the host if it is present. Each pattern
+ * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a
+ * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" ==
+ * "baz.foo.com", but ".foo.com" != "foo.com").
+ *
+ * Areas are matched in the following cases:
+ * 1. "*" (without quotes) always matches any hosts.
+ * 2. An exact match.
+ * 3. The area starts with "." and the area is the last part of the host. e.g.
+ *    '.mit.edu' will match any host that ends with '.mit.edu'.
+ *
+ * @param string $host         Host to check against the patterns.
+ * @param array  $noProxyArray An array of host patterns.
+ *
+ * @return bool
+ */
+function is_host_in_noproxy($host, array $noProxyArray)
+{
+    if (strlen($host) === 0) {
+        throw new \InvalidArgumentException('Empty host provided');
+    }
+
+    // Strip port if present.
+    if (strpos($host, ':')) {
+        $host = explode($host, ':', 2)[0];
+    }
+
+    foreach ($noProxyArray as $area) {
+        // Always match on wildcards.
+        if ($area === '*') {
+            return true;
+        } elseif (empty($area)) {
+            // Don't match on empty values.
+            continue;
+        } elseif ($area === $host) {
+            // Exact matches.
+            return true;
+        } else {
+            // Special match if the area when prefixed with ".". Remove any
+            // existing leading "." and add a new leading ".".
+            $area = '.' . ltrim($area, '.');
+            if (substr($host, -(strlen($area))) === $area) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+/**
+ * Wrapper for json_decode that throws when an error occurs.
+ *
+ * @param string $json    JSON data to parse
+ * @param bool $assoc     When true, returned objects will be converted
+ *                        into associative arrays.
+ * @param int    $depth   User specified recursion depth.
+ * @param int    $options Bitmask of JSON decode options.
+ *
+ * @return mixed
+ * @throws Exception\InvalidArgumentException if the JSON cannot be decoded.
+ * @link http://www.php.net/manual/en/function.json-decode.php
+ */
+function json_decode($json, $assoc = false, $depth = 512, $options = 0)
+{
+    $data = \json_decode($json, $assoc, $depth, $options);
+    if (JSON_ERROR_NONE !== json_last_error()) {
+        throw new Exception\InvalidArgumentException(
+            'json_decode error: ' . json_last_error_msg()
+        );
+    }
+
+    return $data;
+}
+
+/**
+ * Wrapper for JSON encoding that throws when an error occurs.
+ *
+ * @param mixed $value   The value being encoded
+ * @param int    $options JSON encode option bitmask
+ * @param int    $depth   Set the maximum depth. Must be greater than zero.
+ *
+ * @return string
+ * @throws Exception\InvalidArgumentException if the JSON cannot be encoded.
+ * @link http://www.php.net/manual/en/function.json-encode.php
+ */
+function json_encode($value, $options = 0, $depth = 512)
+{
+    $json = \json_encode($value, $options, $depth);
+    if (JSON_ERROR_NONE !== json_last_error()) {
+        throw new Exception\InvalidArgumentException(
+            'json_encode error: ' . json_last_error_msg()
+        );
+    }
+
+    return $json;
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/functions_include.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/guzzle/src/functions_include.php
new file mode 100644 (file)
index 0000000..a93393a
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+// Don't redefine the functions if included multiple times.
+if (!function_exists('GuzzleHttp\uri_template')) {
+    require __DIR__ . '/functions.php';
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/CHANGELOG.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/CHANGELOG.md
new file mode 100644 (file)
index 0000000..551929f
--- /dev/null
@@ -0,0 +1,65 @@
+# CHANGELOG
+
+
+## 1.3.1 - 2016-12-20
+
+### Fixed
+
+- `wait()` foreign promise compatibility
+
+
+## 1.3.0 - 2016-11-18
+
+### Added
+
+- Adds support for custom task queues.
+
+### Fixed
+
+- Fixed coroutine promise memory leak.
+
+
+## 1.2.0 - 2016-05-18
+
+### Changed
+
+- Update to now catch `\Throwable` on PHP 7+
+
+
+## 1.1.0 - 2016-03-07
+
+### Changed
+
+- Update EachPromise to prevent recurring on a iterator when advancing, as this
+  could trigger fatal generator errors.
+- Update Promise to allow recursive waiting without unwrapping exceptions.
+
+
+## 1.0.3 - 2015-10-15
+
+### Changed
+
+- Update EachPromise to immediately resolve when the underlying promise iterator
+  is empty. Previously, such a promise would throw an exception when its `wait`
+  function was called.
+
+
+## 1.0.2 - 2015-05-15
+
+### Changed
+
+- Conditionally require functions.php.
+
+
+## 1.0.1 - 2015-06-24
+
+### Changed
+
+- Updating EachPromise to call next on the underlying promise iterator as late
+  as possible to ensure that generators that generate new requests based on
+  callbacks are not iterated until after callbacks are invoked.
+
+
+## 1.0.0 - 2015-05-12
+
+- Initial release
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/LICENSE b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/LICENSE
new file mode 100644 (file)
index 0000000..67f91a1
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2016 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/Makefile b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/Makefile
new file mode 100644 (file)
index 0000000..8d5b3ef
--- /dev/null
@@ -0,0 +1,13 @@
+all: clean test
+
+test:
+       vendor/bin/phpunit
+
+coverage:
+       vendor/bin/phpunit --coverage-html=artifacts/coverage
+
+view-coverage:
+       open artifacts/coverage/index.html
+
+clean:
+       rm -rf artifacts/*
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/README.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/README.md
new file mode 100644 (file)
index 0000000..7b607e2
--- /dev/null
@@ -0,0 +1,504 @@
+# Guzzle Promises
+
+[Promises/A+](https://promisesaplus.com/) implementation that handles promise
+chaining and resolution iteratively, allowing for "infinite" promise chaining
+while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/)
+for a general introduction to promises.
+
+- [Features](#features)
+- [Quick start](#quick-start)
+- [Synchronous wait](#synchronous-wait)
+- [Cancellation](#cancellation)
+- [API](#api)
+  - [Promise](#promise)
+  - [FulfilledPromise](#fulfilledpromise)
+  - [RejectedPromise](#rejectedpromise)
+- [Promise interop](#promise-interop)
+- [Implementation notes](#implementation-notes)
+
+
+# Features
+
+- [Promises/A+](https://promisesaplus.com/) implementation.
+- Promise resolution and chaining is handled iteratively, allowing for
+  "infinite" promise chaining.
+- Promises have a synchronous `wait` method.
+- Promises can be cancelled.
+- Works with any object that has a `then` function.
+- C# style async/await coroutine promises using
+  `GuzzleHttp\Promise\coroutine()`.
+
+
+# Quick start
+
+A *promise* represents the eventual result of an asynchronous operation. The
+primary way of interacting with a promise is through its `then` method, which
+registers callbacks to receive either a promise's eventual value or the reason
+why the promise cannot be fulfilled.
+
+
+## Callbacks
+
+Callbacks are registered with the `then` method by providing an optional 
+`$onFulfilled` followed by an optional `$onRejected` function.
+
+
+```php
+use GuzzleHttp\Promise\Promise;
+
+$promise = new Promise();
+$promise->then(
+    // $onFulfilled
+    function ($value) {
+        echo 'The promise was fulfilled.';
+    },
+    // $onRejected
+    function ($reason) {
+        echo 'The promise was rejected.';
+    }
+);
+```
+
+*Resolving* a promise means that you either fulfill a promise with a *value* or
+reject a promise with a *reason*. Resolving a promises triggers callbacks
+registered with the promises's `then` method. These callbacks are triggered
+only once and in the order in which they were added.
+
+
+## Resolving a promise
+
+Promises are fulfilled using the `resolve($value)` method. Resolving a promise
+with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger
+all of the onFulfilled callbacks (resolving a promise with a rejected promise
+will reject the promise and trigger the `$onRejected` callbacks).
+
+```php
+use GuzzleHttp\Promise\Promise;
+
+$promise = new Promise();
+$promise
+    ->then(function ($value) {
+        // Return a value and don't break the chain
+        return "Hello, " . $value;
+    })
+    // This then is executed after the first then and receives the value
+    // returned from the first then.
+    ->then(function ($value) {
+        echo $value;
+    });
+
+// Resolving the promise triggers the $onFulfilled callbacks and outputs
+// "Hello, reader".
+$promise->resolve('reader.');
+```
+
+
+## Promise forwarding
+
+Promises can be chained one after the other. Each then in the chain is a new
+promise. The return value of a promise is what's forwarded to the next
+promise in the chain. Returning a promise in a `then` callback will cause the
+subsequent promises in the chain to only be fulfilled when the returned promise
+has been fulfilled. The next promise in the chain will be invoked with the
+resolved value of the promise.
+
+```php
+use GuzzleHttp\Promise\Promise;
+
+$promise = new Promise();
+$nextPromise = new Promise();
+
+$promise
+    ->then(function ($value) use ($nextPromise) {
+        echo $value;
+        return $nextPromise;
+    })
+    ->then(function ($value) {
+        echo $value;
+    });
+
+// Triggers the first callback and outputs "A"
+$promise->resolve('A');
+// Triggers the second callback and outputs "B"
+$nextPromise->resolve('B');
+```
+
+## Promise rejection
+
+When a promise is rejected, the `$onRejected` callbacks are invoked with the
+rejection reason.
+
+```php
+use GuzzleHttp\Promise\Promise;
+
+$promise = new Promise();
+$promise->then(null, function ($reason) {
+    echo $reason;
+});
+
+$promise->reject('Error!');
+// Outputs "Error!"
+```
+
+## Rejection forwarding
+
+If an exception is thrown in an `$onRejected` callback, subsequent
+`$onRejected` callbacks are invoked with the thrown exception as the reason.
+
+```php
+use GuzzleHttp\Promise\Promise;
+
+$promise = new Promise();
+$promise->then(null, function ($reason) {
+    throw new \Exception($reason);
+})->then(null, function ($reason) {
+    assert($reason->getMessage() === 'Error!');
+});
+
+$promise->reject('Error!');
+```
+
+You can also forward a rejection down the promise chain by returning a
+`GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or
+`$onRejected` callback.
+
+```php
+use GuzzleHttp\Promise\Promise;
+use GuzzleHttp\Promise\RejectedPromise;
+
+$promise = new Promise();
+$promise->then(null, function ($reason) {
+    return new RejectedPromise($reason);
+})->then(null, function ($reason) {
+    assert($reason === 'Error!');
+});
+
+$promise->reject('Error!');
+```
+
+If an exception is not thrown in a `$onRejected` callback and the callback
+does not return a rejected promise, downstream `$onFulfilled` callbacks are
+invoked using the value returned from the `$onRejected` callback.
+
+```php
+use GuzzleHttp\Promise\Promise;
+use GuzzleHttp\Promise\RejectedPromise;
+
+$promise = new Promise();
+$promise
+    ->then(null, function ($reason) {
+        return "It's ok";
+    })
+    ->then(function ($value) {
+        assert($value === "It's ok");
+    });
+
+$promise->reject('Error!');
+```
+
+# Synchronous wait
+
+You can synchronously force promises to complete using a promise's `wait`
+method. When creating a promise, you can provide a wait function that is used
+to synchronously force a promise to complete. When a wait function is invoked
+it is expected to deliver a value to the promise or reject the promise. If the
+wait function does not deliver a value, then an exception is thrown. The wait
+function provided to a promise constructor is invoked when the `wait` function
+of the promise is called.
+
+```php
+$promise = new Promise(function () use (&$promise) {
+    $promise->resolve('foo');
+});
+
+// Calling wait will return the value of the promise.
+echo $promise->wait(); // outputs "foo"
+```
+
+If an exception is encountered while invoking the wait function of a promise,
+the promise is rejected with the exception and the exception is thrown.
+
+```php
+$promise = new Promise(function () use (&$promise) {
+    throw new \Exception('foo');
+});
+
+$promise->wait(); // throws the exception.
+```
+
+Calling `wait` on a promise that has been fulfilled will not trigger the wait
+function. It will simply return the previously resolved value.
+
+```php
+$promise = new Promise(function () { die('this is not called!'); });
+$promise->resolve('foo');
+echo $promise->wait(); // outputs "foo"
+```
+
+Calling `wait` on a promise that has been rejected will throw an exception. If
+the rejection reason is an instance of `\Exception` the reason is thrown.
+Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason
+can be obtained by calling the `getReason` method of the exception.
+
+```php
+$promise = new Promise();
+$promise->reject('foo');
+$promise->wait();
+```
+
+> PHP Fatal error:  Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo'
+
+
+## Unwrapping a promise
+
+When synchronously waiting on a promise, you are joining the state of the
+promise into the current state of execution (i.e., return the value of the
+promise if it was fulfilled or throw an exception if it was rejected). This is
+called "unwrapping" the promise. Waiting on a promise will by default unwrap
+the promise state.
+
+You can force a promise to resolve and *not* unwrap the state of the promise
+by passing `false` to the first argument of the `wait` function:
+
+```php
+$promise = new Promise();
+$promise->reject('foo');
+// This will not throw an exception. It simply ensures the promise has
+// been resolved.
+$promise->wait(false);
+```
+
+When unwrapping a promise, the resolved value of the promise will be waited
+upon until the unwrapped value is not a promise. This means that if you resolve
+promise A with a promise B and unwrap promise A, the value returned by the
+wait function will be the value delivered to promise B.
+
+**Note**: when you do not unwrap the promise, no value is returned.
+
+
+# Cancellation
+
+You can cancel a promise that has not yet been fulfilled using the `cancel()`
+method of a promise. When creating a promise you can provide an optional
+cancel function that when invoked cancels the action of computing a resolution
+of the promise.
+
+
+# API
+
+
+## Promise
+
+When creating a promise object, you can provide an optional `$waitFn` and
+`$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is
+expected to resolve the promise. `$cancelFn` is a function with no arguments
+that is expected to cancel the computation of a promise. It is invoked when the
+`cancel()` method of a promise is called.
+
+```php
+use GuzzleHttp\Promise\Promise;
+
+$promise = new Promise(
+    function () use (&$promise) {
+        $promise->resolve('waited');
+    },
+    function () {
+        // do something that will cancel the promise computation (e.g., close
+        // a socket, cancel a database query, etc...)
+    }
+);
+
+assert('waited' === $promise->wait());
+```
+
+A promise has the following methods:
+
+- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
+  
+  Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
+
+- `otherwise(callable $onRejected) : PromiseInterface`
+  
+  Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
+
+- `wait($unwrap = true) : mixed`
+
+  Synchronously waits on the promise to complete.
+  
+  `$unwrap` controls whether or not the value of the promise is returned for a
+  fulfilled promise or if an exception is thrown if the promise is rejected.
+  This is set to `true` by default.
+
+- `cancel()`
+
+  Attempts to cancel the promise if possible. The promise being cancelled and
+  the parent most ancestor that has not yet been resolved will also be
+  cancelled. Any promises waiting on the cancelled promise to resolve will also
+  be cancelled.
+
+- `getState() : string`
+
+  Returns the state of the promise. One of `pending`, `fulfilled`, or
+  `rejected`.
+
+- `resolve($value)`
+
+  Fulfills the promise with the given `$value`.
+
+- `reject($reason)`
+
+  Rejects the promise with the given `$reason`.
+
+
+## FulfilledPromise
+
+A fulfilled promise can be created to represent a promise that has been
+fulfilled.
+
+```php
+use GuzzleHttp\Promise\FulfilledPromise;
+
+$promise = new FulfilledPromise('value');
+
+// Fulfilled callbacks are immediately invoked.
+$promise->then(function ($value) {
+    echo $value;
+});
+```
+
+
+## RejectedPromise
+
+A rejected promise can be created to represent a promise that has been
+rejected.
+
+```php
+use GuzzleHttp\Promise\RejectedPromise;
+
+$promise = new RejectedPromise('Error');
+
+// Rejected callbacks are immediately invoked.
+$promise->then(null, function ($reason) {
+    echo $reason;
+});
+```
+
+
+# Promise interop
+
+This library works with foreign promises that have a `then` method. This means
+you can use Guzzle promises with [React promises](https://github.com/reactphp/promise)
+for example. When a foreign promise is returned inside of a then method
+callback, promise resolution will occur recursively.
+
+```php
+// Create a React promise
+$deferred = new React\Promise\Deferred();
+$reactPromise = $deferred->promise();
+
+// Create a Guzzle promise that is fulfilled with a React promise.
+$guzzlePromise = new \GuzzleHttp\Promise\Promise();
+$guzzlePromise->then(function ($value) use ($reactPromise) {
+    // Do something something with the value...
+    // Return the React promise
+    return $reactPromise;
+});
+```
+
+Please note that wait and cancel chaining is no longer possible when forwarding
+a foreign promise. You will need to wrap a third-party promise with a Guzzle
+promise in order to utilize wait and cancel functions with foreign promises.
+
+
+## Event Loop Integration
+
+In order to keep the stack size constant, Guzzle promises are resolved
+asynchronously using a task queue. When waiting on promises synchronously, the
+task queue will be automatically run to ensure that the blocking promise and
+any forwarded promises are resolved. When using promises asynchronously in an
+event loop, you will need to run the task queue on each tick of the loop. If
+you do not run the task queue, then promises will not be resolved.
+
+You can run the task queue using the `run()` method of the global task queue
+instance.
+
+```php
+// Get the global task queue
+$queue = \GuzzleHttp\Promise\queue();
+$queue->run();
+```
+
+For example, you could use Guzzle promises with React using a periodic timer:
+
+```php
+$loop = React\EventLoop\Factory::create();
+$loop->addPeriodicTimer(0, [$queue, 'run']);
+```
+
+*TODO*: Perhaps adding a `futureTick()` on each tick would be faster?
+
+
+# Implementation notes
+
+
+## Promise resolution and chaining is handled iteratively
+
+By shuffling pending handlers from one owner to another, promises are
+resolved iteratively, allowing for "infinite" then chaining.
+
+```php
+<?php
+require 'vendor/autoload.php';
+
+use GuzzleHttp\Promise\Promise;
+
+$parent = new Promise();
+$p = $parent;
+
+for ($i = 0; $i < 1000; $i++) {
+    $p = $p->then(function ($v) {
+        // The stack size remains constant (a good thing)
+        echo xdebug_get_stack_depth() . ', ';
+        return $v + 1;
+    });
+}
+
+$parent->resolve(0);
+var_dump($p->wait()); // int(1000)
+
+```
+
+When a promise is fulfilled or rejected with a non-promise value, the promise
+then takes ownership of the handlers of each child promise and delivers values
+down the chain without using recursion.
+
+When a promise is resolved with another promise, the original promise transfers
+all of its pending handlers to the new promise. When the new promise is
+eventually resolved, all of the pending handlers are delivered the forwarded
+value.
+
+
+## A promise is the deferred.
+
+Some promise libraries implement promises using a deferred object to represent
+a computation and a promise object to represent the delivery of the result of
+the computation. This is a nice separation of computation and delivery because
+consumers of the promise cannot modify the value that will be eventually
+delivered.
+
+One side effect of being able to implement promise resolution and chaining
+iteratively is that you need to be able for one promise to reach into the state
+of another promise to shuffle around ownership of handlers. In order to achieve
+this without making the handlers of a promise publicly mutable, a promise is
+also the deferred value, allowing promises of the same parent class to reach
+into and modify the private properties of promises of the same type. While this
+does allow consumers of the value to modify the resolution or rejection of the
+deferred, it is a small price to pay for keeping the stack size constant.
+
+```php
+$promise = new Promise();
+$promise->then(function ($value) { echo $value; });
+// The promise is the deferred value, so you can deliver a value to it.
+$promise->resolve('foo');
+// prints "foo"
+```
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/composer.json b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/composer.json
new file mode 100644 (file)
index 0000000..ec41a61
--- /dev/null
@@ -0,0 +1,34 @@
+{
+    "name": "guzzlehttp/promises",
+    "description": "Guzzle promises library",
+    "keywords": ["promise"],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Michael Dowling",
+            "email": "mtdowling@gmail.com",
+            "homepage": "https://github.com/mtdowling"
+        }
+    ],
+    "require": {
+        "php": ">=5.5.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^4.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "GuzzleHttp\\Promise\\": "src/"
+        },
+        "files": ["src/functions_include.php"]
+    },
+    "scripts": {
+        "test": "vendor/bin/phpunit",
+        "test-ci": "vendor/bin/phpunit --coverage-text"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.4-dev"
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/AggregateException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/AggregateException.php
new file mode 100644 (file)
index 0000000..6a5690c
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * Exception thrown when too many errors occur in the some() or any() methods.
+ */
+class AggregateException extends RejectionException
+{
+    public function __construct($msg, array $reasons)
+    {
+        parent::__construct(
+            $reasons,
+            sprintf('%s; %d rejected promises', $msg, count($reasons))
+        );
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/CancellationException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/CancellationException.php
new file mode 100644 (file)
index 0000000..cb360b8
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * Exception that is set as the reason for a promise that has been cancelled.
+ */
+class CancellationException extends RejectionException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/Coroutine.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/Coroutine.php
new file mode 100644 (file)
index 0000000..6aa0958
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+use Exception;
+use Generator;
+use Throwable;
+
+/**
+ * Creates a promise that is resolved using a generator that yields values or
+ * promises (somewhat similar to C#'s async keyword).
+ *
+ * When called, the coroutine function will start an instance of the generator
+ * and returns a promise that is fulfilled with its final yielded value.
+ *
+ * Control is returned back to the generator when the yielded promise settles.
+ * This can lead to less verbose code when doing lots of sequential async calls
+ * with minimal processing in between.
+ *
+ *     use GuzzleHttp\Promise;
+ *
+ *     function createPromise($value) {
+ *         return new Promise\FulfilledPromise($value);
+ *     }
+ *
+ *     $promise = Promise\coroutine(function () {
+ *         $value = (yield createPromise('a'));
+ *         try {
+ *             $value = (yield createPromise($value . 'b'));
+ *         } catch (\Exception $e) {
+ *             // The promise was rejected.
+ *         }
+ *         yield $value . 'c';
+ *     });
+ *
+ *     // Outputs "abc"
+ *     $promise->then(function ($v) { echo $v; });
+ *
+ * @param callable $generatorFn Generator function to wrap into a promise.
+ *
+ * @return Promise
+ * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
+ */
+final class Coroutine implements PromiseInterface
+{
+    /**
+     * @var PromiseInterface|null
+     */
+    private $currentPromise;
+
+    /**
+     * @var Generator
+     */
+    private $generator;
+
+    /**
+     * @var Promise
+     */
+    private $result;
+
+    public function __construct(callable $generatorFn)
+    {
+        $this->generator = $generatorFn();
+        $this->result = new Promise(function () {
+            while (isset($this->currentPromise)) {
+                $this->currentPromise->wait();
+            }
+        });
+        $this->nextCoroutine($this->generator->current());
+    }
+
+    public function then(
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    ) {
+        return $this->result->then($onFulfilled, $onRejected);
+    }
+
+    public function otherwise(callable $onRejected)
+    {
+        return $this->result->otherwise($onRejected);
+    }
+
+    public function wait($unwrap = true)
+    {
+        return $this->result->wait($unwrap);
+    }
+
+    public function getState()
+    {
+        return $this->result->getState();
+    }
+
+    public function resolve($value)
+    {
+        $this->result->resolve($value);
+    }
+
+    public function reject($reason)
+    {
+        $this->result->reject($reason);
+    }
+
+    public function cancel()
+    {
+        $this->currentPromise->cancel();
+        $this->result->cancel();
+    }
+
+    private function nextCoroutine($yielded)
+    {
+        $this->currentPromise = promise_for($yielded)
+            ->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
+    }
+
+    /**
+     * @internal
+     */
+    public function _handleSuccess($value)
+    {
+        unset($this->currentPromise);
+        try {
+            $next = $this->generator->send($value);
+            if ($this->generator->valid()) {
+                $this->nextCoroutine($next);
+            } else {
+                $this->result->resolve($value);
+            }
+        } catch (Exception $exception) {
+            $this->result->reject($exception);
+        } catch (Throwable $throwable) {
+            $this->result->reject($throwable);
+        }
+    }
+
+    /**
+     * @internal
+     */
+    public function _handleFailure($reason)
+    {
+        unset($this->currentPromise);
+        try {
+            $nextYield = $this->generator->throw(exception_for($reason));
+            // The throw was caught, so keep iterating on the coroutine
+            $this->nextCoroutine($nextYield);
+        } catch (Exception $exception) {
+            $this->result->reject($exception);
+        } catch (Throwable $throwable) {
+            $this->result->reject($throwable);
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/EachPromise.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/EachPromise.php
new file mode 100644 (file)
index 0000000..d0ddf60
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * Represents a promise that iterates over many promises and invokes
+ * side-effect functions in the process.
+ */
+class EachPromise implements PromisorInterface
+{
+    private $pending = [];
+
+    /** @var \Iterator */
+    private $iterable;
+
+    /** @var callable|int */
+    private $concurrency;
+
+    /** @var callable */
+    private $onFulfilled;
+
+    /** @var callable */
+    private $onRejected;
+
+    /** @var Promise */
+    private $aggregate;
+
+    /** @var bool */
+    private $mutex;
+
+    /**
+     * Configuration hash can include the following key value pairs:
+     *
+     * - fulfilled: (callable) Invoked when a promise fulfills. The function
+     *   is invoked with three arguments: the fulfillment value, the index
+     *   position from the iterable list of the promise, and the aggregate
+     *   promise that manages all of the promises. The aggregate promise may
+     *   be resolved from within the callback to short-circuit the promise.
+     * - rejected: (callable) Invoked when a promise is rejected. The
+     *   function is invoked with three arguments: the rejection reason, the
+     *   index position from the iterable list of the promise, and the
+     *   aggregate promise that manages all of the promises. The aggregate
+     *   promise may be resolved from within the callback to short-circuit
+     *   the promise.
+     * - concurrency: (integer) Pass this configuration option to limit the
+     *   allowed number of outstanding concurrently executing promises,
+     *   creating a capped pool of promises. There is no limit by default.
+     *
+     * @param mixed    $iterable Promises or values to iterate.
+     * @param array    $config   Configuration options
+     */
+    public function __construct($iterable, array $config = [])
+    {
+        $this->iterable = iter_for($iterable);
+
+        if (isset($config['concurrency'])) {
+            $this->concurrency = $config['concurrency'];
+        }
+
+        if (isset($config['fulfilled'])) {
+            $this->onFulfilled = $config['fulfilled'];
+        }
+
+        if (isset($config['rejected'])) {
+            $this->onRejected = $config['rejected'];
+        }
+    }
+
+    public function promise()
+    {
+        if ($this->aggregate) {
+            return $this->aggregate;
+        }
+
+        try {
+            $this->createPromise();
+            $this->iterable->rewind();
+            $this->refillPending();
+        } catch (\Throwable $e) {
+            $this->aggregate->reject($e);
+        } catch (\Exception $e) {
+            $this->aggregate->reject($e);
+        }
+
+        return $this->aggregate;
+    }
+
+    private function createPromise()
+    {
+        $this->mutex = false;
+        $this->aggregate = new Promise(function () {
+            reset($this->pending);
+            if (empty($this->pending) && !$this->iterable->valid()) {
+                $this->aggregate->resolve(null);
+                return;
+            }
+
+            // Consume a potentially fluctuating list of promises while
+            // ensuring that indexes are maintained (precluding array_shift).
+            while ($promise = current($this->pending)) {
+                next($this->pending);
+                $promise->wait();
+                if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
+                    return;
+                }
+            }
+        });
+
+        // Clear the references when the promise is resolved.
+        $clearFn = function () {
+            $this->iterable = $this->concurrency = $this->pending = null;
+            $this->onFulfilled = $this->onRejected = null;
+        };
+
+        $this->aggregate->then($clearFn, $clearFn);
+    }
+
+    private function refillPending()
+    {
+        if (!$this->concurrency) {
+            // Add all pending promises.
+            while ($this->addPending() && $this->advanceIterator());
+            return;
+        }
+
+        // Add only up to N pending promises.
+        $concurrency = is_callable($this->concurrency)
+            ? call_user_func($this->concurrency, count($this->pending))
+            : $this->concurrency;
+        $concurrency = max($concurrency - count($this->pending), 0);
+        // Concurrency may be set to 0 to disallow new promises.
+        if (!$concurrency) {
+            return;
+        }
+        // Add the first pending promise.
+        $this->addPending();
+        // Note this is special handling for concurrency=1 so that we do
+        // not advance the iterator after adding the first promise. This
+        // helps work around issues with generators that might not have the
+        // next value to yield until promise callbacks are called.
+        while (--$concurrency
+            && $this->advanceIterator()
+            && $this->addPending());
+    }
+
+    private function addPending()
+    {
+        if (!$this->iterable || !$this->iterable->valid()) {
+            return false;
+        }
+
+        $promise = promise_for($this->iterable->current());
+        $idx = $this->iterable->key();
+
+        $this->pending[$idx] = $promise->then(
+            function ($value) use ($idx) {
+                if ($this->onFulfilled) {
+                    call_user_func(
+                        $this->onFulfilled, $value, $idx, $this->aggregate
+                    );
+                }
+                $this->step($idx);
+            },
+            function ($reason) use ($idx) {
+                if ($this->onRejected) {
+                    call_user_func(
+                        $this->onRejected, $reason, $idx, $this->aggregate
+                    );
+                }
+                $this->step($idx);
+            }
+        );
+
+        return true;
+    }
+
+    private function advanceIterator()
+    {
+        // Place a lock on the iterator so that we ensure to not recurse,
+        // preventing fatal generator errors.
+        if ($this->mutex) {
+            return false;
+        }
+
+        $this->mutex = true;
+
+        try {
+            $this->iterable->next();
+            $this->mutex = false;
+            return true;
+        } catch (\Throwable $e) {
+            $this->aggregate->reject($e);
+            $this->mutex = false;
+            return false;
+        } catch (\Exception $e) {
+            $this->aggregate->reject($e);
+            $this->mutex = false;
+            return false;
+        }
+    }
+
+    private function step($idx)
+    {
+        // If the promise was already resolved, then ignore this step.
+        if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
+            return;
+        }
+
+        unset($this->pending[$idx]);
+
+        // Only refill pending promises if we are not locked, preventing the
+        // EachPromise to recursively invoke the provided iterator, which
+        // cause a fatal error: "Cannot resume an already running generator"
+        if ($this->advanceIterator() && !$this->checkIfFinished()) {
+            // Add more pending promises if possible.
+            $this->refillPending();
+        }
+    }
+
+    private function checkIfFinished()
+    {
+        if (!$this->pending && !$this->iterable->valid()) {
+            // Resolve the promise if there's nothing left to do.
+            $this->aggregate->resolve(null);
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/FulfilledPromise.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/FulfilledPromise.php
new file mode 100644 (file)
index 0000000..dbbeeb9
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * A promise that has been fulfilled.
+ *
+ * Thenning off of this promise will invoke the onFulfilled callback
+ * immediately and ignore other callbacks.
+ */
+class FulfilledPromise implements PromiseInterface
+{
+    private $value;
+
+    public function __construct($value)
+    {
+        if (method_exists($value, 'then')) {
+            throw new \InvalidArgumentException(
+                'You cannot create a FulfilledPromise with a promise.');
+        }
+
+        $this->value = $value;
+    }
+
+    public function then(
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    ) {
+        // Return itself if there is no onFulfilled function.
+        if (!$onFulfilled) {
+            return $this;
+        }
+
+        $queue = queue();
+        $p = new Promise([$queue, 'run']);
+        $value = $this->value;
+        $queue->add(static function () use ($p, $value, $onFulfilled) {
+            if ($p->getState() === self::PENDING) {
+                try {
+                    $p->resolve($onFulfilled($value));
+                } catch (\Throwable $e) {
+                    $p->reject($e);
+                } catch (\Exception $e) {
+                    $p->reject($e);
+                }
+            }
+        });
+
+        return $p;
+    }
+
+    public function otherwise(callable $onRejected)
+    {
+        return $this->then(null, $onRejected);
+    }
+
+    public function wait($unwrap = true, $defaultDelivery = null)
+    {
+        return $unwrap ? $this->value : null;
+    }
+
+    public function getState()
+    {
+        return self::FULFILLED;
+    }
+
+    public function resolve($value)
+    {
+        if ($value !== $this->value) {
+            throw new \LogicException("Cannot resolve a fulfilled promise");
+        }
+    }
+
+    public function reject($reason)
+    {
+        throw new \LogicException("Cannot reject a fulfilled promise");
+    }
+
+    public function cancel()
+    {
+        // pass
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/Promise.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/Promise.php
new file mode 100644 (file)
index 0000000..844ada0
--- /dev/null
@@ -0,0 +1,280 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * Promises/A+ implementation that avoids recursion when possible.
+ *
+ * @link https://promisesaplus.com/
+ */
+class Promise implements PromiseInterface
+{
+    private $state = self::PENDING;
+    private $result;
+    private $cancelFn;
+    private $waitFn;
+    private $waitList;
+    private $handlers = [];
+
+    /**
+     * @param callable $waitFn   Fn that when invoked resolves the promise.
+     * @param callable $cancelFn Fn that when invoked cancels the promise.
+     */
+    public function __construct(
+        callable $waitFn = null,
+        callable $cancelFn = null
+    ) {
+        $this->waitFn = $waitFn;
+        $this->cancelFn = $cancelFn;
+    }
+
+    public function then(
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    ) {
+        if ($this->state === self::PENDING) {
+            $p = new Promise(null, [$this, 'cancel']);
+            $this->handlers[] = [$p, $onFulfilled, $onRejected];
+            $p->waitList = $this->waitList;
+            $p->waitList[] = $this;
+            return $p;
+        }
+
+        // Return a fulfilled promise and immediately invoke any callbacks.
+        if ($this->state === self::FULFILLED) {
+            return $onFulfilled
+                ? promise_for($this->result)->then($onFulfilled)
+                : promise_for($this->result);
+        }
+
+        // It's either cancelled or rejected, so return a rejected promise
+        // and immediately invoke any callbacks.
+        $rejection = rejection_for($this->result);
+        return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
+    }
+
+    public function otherwise(callable $onRejected)
+    {
+        return $this->then(null, $onRejected);
+    }
+
+    public function wait($unwrap = true)
+    {
+        $this->waitIfPending();
+
+        $inner = $this->result instanceof PromiseInterface
+            ? $this->result->wait($unwrap)
+            : $this->result;
+
+        if ($unwrap) {
+            if ($this->result instanceof PromiseInterface
+                || $this->state === self::FULFILLED
+            ) {
+                return $inner;
+            } else {
+                // It's rejected so "unwrap" and throw an exception.
+                throw exception_for($inner);
+            }
+        }
+    }
+
+    public function getState()
+    {
+        return $this->state;
+    }
+
+    public function cancel()
+    {
+        if ($this->state !== self::PENDING) {
+            return;
+        }
+
+        $this->waitFn = $this->waitList = null;
+
+        if ($this->cancelFn) {
+            $fn = $this->cancelFn;
+            $this->cancelFn = null;
+            try {
+                $fn();
+            } catch (\Throwable $e) {
+                $this->reject($e);
+            } catch (\Exception $e) {
+                $this->reject($e);
+            }
+        }
+
+        // Reject the promise only if it wasn't rejected in a then callback.
+        if ($this->state === self::PENDING) {
+            $this->reject(new CancellationException('Promise has been cancelled'));
+        }
+    }
+
+    public function resolve($value)
+    {
+        $this->settle(self::FULFILLED, $value);
+    }
+
+    public function reject($reason)
+    {
+        $this->settle(self::REJECTED, $reason);
+    }
+
+    private function settle($state, $value)
+    {
+        if ($this->state !== self::PENDING) {
+            // Ignore calls with the same resolution.
+            if ($state === $this->state && $value === $this->result) {
+                return;
+            }
+            throw $this->state === $state
+                ? new \LogicException("The promise is already {$state}.")
+                : new \LogicException("Cannot change a {$this->state} promise to {$state}");
+        }
+
+        if ($value === $this) {
+            throw new \LogicException('Cannot fulfill or reject a promise with itself');
+        }
+
+        // Clear out the state of the promise but stash the handlers.
+        $this->state = $state;
+        $this->result = $value;
+        $handlers = $this->handlers;
+        $this->handlers = null;
+        $this->waitList = $this->waitFn = null;
+        $this->cancelFn = null;
+
+        if (!$handlers) {
+            return;
+        }
+
+        // If the value was not a settled promise or a thenable, then resolve
+        // it in the task queue using the correct ID.
+        if (!method_exists($value, 'then')) {
+            $id = $state === self::FULFILLED ? 1 : 2;
+            // It's a success, so resolve the handlers in the queue.
+            queue()->add(static function () use ($id, $value, $handlers) {
+                foreach ($handlers as $handler) {
+                    self::callHandler($id, $value, $handler);
+                }
+            });
+        } elseif ($value instanceof Promise
+            && $value->getState() === self::PENDING
+        ) {
+            // We can just merge our handlers onto the next promise.
+            $value->handlers = array_merge($value->handlers, $handlers);
+        } else {
+            // Resolve the handlers when the forwarded promise is resolved.
+            $value->then(
+                static function ($value) use ($handlers) {
+                    foreach ($handlers as $handler) {
+                        self::callHandler(1, $value, $handler);
+                    }
+                },
+                static function ($reason) use ($handlers) {
+                    foreach ($handlers as $handler) {
+                        self::callHandler(2, $reason, $handler);
+                    }
+                }
+            );
+        }
+    }
+
+    /**
+     * Call a stack of handlers using a specific callback index and value.
+     *
+     * @param int   $index   1 (resolve) or 2 (reject).
+     * @param mixed $value   Value to pass to the callback.
+     * @param array $handler Array of handler data (promise and callbacks).
+     *
+     * @return array Returns the next group to resolve.
+     */
+    private static function callHandler($index, $value, array $handler)
+    {
+        /** @var PromiseInterface $promise */
+        $promise = $handler[0];
+
+        // The promise may have been cancelled or resolved before placing
+        // this thunk in the queue.
+        if ($promise->getState() !== self::PENDING) {
+            return;
+        }
+
+        try {
+            if (isset($handler[$index])) {
+                $promise->resolve($handler[$index]($value));
+            } elseif ($index === 1) {
+                // Forward resolution values as-is.
+                $promise->resolve($value);
+            } else {
+                // Forward rejections down the chain.
+                $promise->reject($value);
+            }
+        } catch (\Throwable $reason) {
+            $promise->reject($reason);
+        } catch (\Exception $reason) {
+            $promise->reject($reason);
+        }
+    }
+
+    private function waitIfPending()
+    {
+        if ($this->state !== self::PENDING) {
+            return;
+        } elseif ($this->waitFn) {
+            $this->invokeWaitFn();
+        } elseif ($this->waitList) {
+            $this->invokeWaitList();
+        } else {
+            // If there's not wait function, then reject the promise.
+            $this->reject('Cannot wait on a promise that has '
+                . 'no internal wait function. You must provide a wait '
+                . 'function when constructing the promise to be able to '
+                . 'wait on a promise.');
+        }
+
+        queue()->run();
+
+        if ($this->state === self::PENDING) {
+            $this->reject('Invoking the wait callback did not resolve the promise');
+        }
+    }
+
+    private function invokeWaitFn()
+    {
+        try {
+            $wfn = $this->waitFn;
+            $this->waitFn = null;
+            $wfn(true);
+        } catch (\Exception $reason) {
+            if ($this->state === self::PENDING) {
+                // The promise has not been resolved yet, so reject the promise
+                // with the exception.
+                $this->reject($reason);
+            } else {
+                // The promise was already resolved, so there's a problem in
+                // the application.
+                throw $reason;
+            }
+        }
+    }
+
+    private function invokeWaitList()
+    {
+        $waitList = $this->waitList;
+        $this->waitList = null;
+
+        foreach ($waitList as $result) {
+            while (true) {
+                $result->waitIfPending();
+
+                if ($result->result instanceof Promise) {
+                    $result = $result->result;
+                } else {
+                    if ($result->result instanceof PromiseInterface) {
+                        $result->result->wait(false);
+                    }
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/PromiseInterface.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/PromiseInterface.php
new file mode 100644 (file)
index 0000000..8f5f4b9
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * A promise represents the eventual result of an asynchronous operation.
+ *
+ * The primary way of interacting with a promise is through its then method,
+ * which registers callbacks to receive either a promise’s eventual value or
+ * the reason why the promise cannot be fulfilled.
+ *
+ * @link https://promisesaplus.com/
+ */
+interface PromiseInterface
+{
+    const PENDING = 'pending';
+    const FULFILLED = 'fulfilled';
+    const REJECTED = 'rejected';
+
+    /**
+     * Appends fulfillment and rejection handlers to the promise, and returns
+     * a new promise resolving to the return value of the called handler.
+     *
+     * @param callable $onFulfilled Invoked when the promise fulfills.
+     * @param callable $onRejected  Invoked when the promise is rejected.
+     *
+     * @return PromiseInterface
+     */
+    public function then(
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    );
+
+    /**
+     * Appends a rejection handler callback to the promise, and returns a new
+     * promise resolving to the return value of the callback if it is called,
+     * or to its original fulfillment value if the promise is instead
+     * fulfilled.
+     *
+     * @param callable $onRejected Invoked when the promise is rejected.
+     *
+     * @return PromiseInterface
+     */
+    public function otherwise(callable $onRejected);
+
+    /**
+     * Get the state of the promise ("pending", "rejected", or "fulfilled").
+     *
+     * The three states can be checked against the constants defined on
+     * PromiseInterface: PENDING, FULFILLED, and REJECTED.
+     *
+     * @return string
+     */
+    public function getState();
+
+    /**
+     * Resolve the promise with the given value.
+     *
+     * @param mixed $value
+     * @throws \RuntimeException if the promise is already resolved.
+     */
+    public function resolve($value);
+
+    /**
+     * Reject the promise with the given reason.
+     *
+     * @param mixed $reason
+     * @throws \RuntimeException if the promise is already resolved.
+     */
+    public function reject($reason);
+
+    /**
+     * Cancels the promise if possible.
+     *
+     * @link https://github.com/promises-aplus/cancellation-spec/issues/7
+     */
+    public function cancel();
+
+    /**
+     * Waits until the promise completes if possible.
+     *
+     * Pass $unwrap as true to unwrap the result of the promise, either
+     * returning the resolved value or throwing the rejected exception.
+     *
+     * If the promise cannot be waited on, then the promise will be rejected.
+     *
+     * @param bool $unwrap
+     *
+     * @return mixed
+     * @throws \LogicException if the promise has no wait function or if the
+     *                         promise does not settle after waiting.
+     */
+    public function wait($unwrap = true);
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/PromisorInterface.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/PromisorInterface.php
new file mode 100644 (file)
index 0000000..b07fe32
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * Interface used with classes that return a promise.
+ */
+interface PromisorInterface
+{
+    /**
+     * Returns a promise.
+     *
+     * @return PromiseInterface
+     */
+    public function promise();
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/RejectedPromise.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/RejectedPromise.php
new file mode 100644 (file)
index 0000000..2bc6508
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * A promise that has been rejected.
+ *
+ * Thenning off of this promise will invoke the onRejected callback
+ * immediately and ignore other callbacks.
+ */
+class RejectedPromise implements PromiseInterface
+{
+    private $reason;
+
+    public function __construct($reason)
+    {
+        if (method_exists($reason, 'then')) {
+            throw new \InvalidArgumentException(
+                'You cannot create a RejectedPromise with a promise.');
+        }
+
+        $this->reason = $reason;
+    }
+
+    public function then(
+        callable $onFulfilled = null,
+        callable $onRejected = null
+    ) {
+        // If there's no onRejected callback then just return self.
+        if (!$onRejected) {
+            return $this;
+        }
+
+        $queue = queue();
+        $reason = $this->reason;
+        $p = new Promise([$queue, 'run']);
+        $queue->add(static function () use ($p, $reason, $onRejected) {
+            if ($p->getState() === self::PENDING) {
+                try {
+                    // Return a resolved promise if onRejected does not throw.
+                    $p->resolve($onRejected($reason));
+                } catch (\Throwable $e) {
+                    // onRejected threw, so return a rejected promise.
+                    $p->reject($e);
+                } catch (\Exception $e) {
+                    // onRejected threw, so return a rejected promise.
+                    $p->reject($e);
+                }
+            }
+        });
+
+        return $p;
+    }
+
+    public function otherwise(callable $onRejected)
+    {
+        return $this->then(null, $onRejected);
+    }
+
+    public function wait($unwrap = true, $defaultDelivery = null)
+    {
+        if ($unwrap) {
+            throw exception_for($this->reason);
+        }
+    }
+
+    public function getState()
+    {
+        return self::REJECTED;
+    }
+
+    public function resolve($value)
+    {
+        throw new \LogicException("Cannot resolve a rejected promise");
+    }
+
+    public function reject($reason)
+    {
+        if ($reason !== $this->reason) {
+            throw new \LogicException("Cannot reject a rejected promise");
+        }
+    }
+
+    public function cancel()
+    {
+        // pass
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/RejectionException.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/RejectionException.php
new file mode 100644 (file)
index 0000000..07c1136
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * A special exception that is thrown when waiting on a rejected promise.
+ *
+ * The reason value is available via the getReason() method.
+ */
+class RejectionException extends \RuntimeException
+{
+    /** @var mixed Rejection reason. */
+    private $reason;
+
+    /**
+     * @param mixed $reason       Rejection reason.
+     * @param string $description Optional description
+     */
+    public function __construct($reason, $description = null)
+    {
+        $this->reason = $reason;
+
+        $message = 'The promise was rejected';
+
+        if ($description) {
+            $message .= ' with reason: ' . $description;
+        } elseif (is_string($reason)
+            || (is_object($reason) && method_exists($reason, '__toString'))
+        ) {
+            $message .= ' with reason: ' . $this->reason;
+        } elseif ($reason instanceof \JsonSerializable) {
+            $message .= ' with reason: '
+                . json_encode($this->reason, JSON_PRETTY_PRINT);
+        }
+
+        parent::__construct($message);
+    }
+
+    /**
+     * Returns the rejection reason.
+     *
+     * @return mixed
+     */
+    public function getReason()
+    {
+        return $this->reason;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/TaskQueue.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/TaskQueue.php
new file mode 100644 (file)
index 0000000..6e8a2a0
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * A task queue that executes tasks in a FIFO order.
+ *
+ * This task queue class is used to settle promises asynchronously and
+ * maintains a constant stack size. You can use the task queue asynchronously
+ * by calling the `run()` function of the global task queue in an event loop.
+ *
+ *     GuzzleHttp\Promise\queue()->run();
+ */
+class TaskQueue implements TaskQueueInterface
+{
+    private $enableShutdown = true;
+    private $queue = [];
+
+    public function __construct($withShutdown = true)
+    {
+        if ($withShutdown) {
+            register_shutdown_function(function () {
+                if ($this->enableShutdown) {
+                    // Only run the tasks if an E_ERROR didn't occur.
+                    $err = error_get_last();
+                    if (!$err || ($err['type'] ^ E_ERROR)) {
+                        $this->run();
+                    }
+                }
+            });
+        }
+    }
+
+    public function isEmpty()
+    {
+        return !$this->queue;
+    }
+
+    public function add(callable $task)
+    {
+        $this->queue[] = $task;
+    }
+
+    public function run()
+    {
+        /** @var callable $task */
+        while ($task = array_shift($this->queue)) {
+            $task();
+        }
+    }
+
+    /**
+     * The task queue will be run and exhausted by default when the process
+     * exits IFF the exit is not the result of a PHP E_ERROR error.
+     *
+     * You can disable running the automatic shutdown of the queue by calling
+     * this function. If you disable the task queue shutdown process, then you
+     * MUST either run the task queue (as a result of running your event loop
+     * or manually using the run() method) or wait on each outstanding promise.
+     *
+     * Note: This shutdown will occur before any destructors are triggered.
+     */
+    public function disableShutdown()
+    {
+        $this->enableShutdown = false;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/TaskQueueInterface.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/TaskQueueInterface.php
new file mode 100644 (file)
index 0000000..ac8306e
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+interface TaskQueueInterface
+{
+    /**
+     * Returns true if the queue is empty.
+     *
+     * @return bool
+     */
+    public function isEmpty();
+
+    /**
+     * Adds a task to the queue that will be executed the next time run is
+     * called.
+     *
+     * @param callable $task
+     */
+    public function add(callable $task);
+
+    /**
+     * Execute all of the pending task in the queue.
+     */
+    public function run();
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/functions.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/functions.php
new file mode 100644 (file)
index 0000000..4e27709
--- /dev/null
@@ -0,0 +1,457 @@
+<?php
+namespace GuzzleHttp\Promise;
+
+/**
+ * Get the global task queue used for promise resolution.
+ *
+ * This task queue MUST be run in an event loop in order for promises to be
+ * settled asynchronously. It will be automatically run when synchronously
+ * waiting on a promise.
+ *
+ * <code>
+ * while ($eventLoop->isRunning()) {
+ *     GuzzleHttp\Promise\queue()->run();
+ * }
+ * </code>
+ *
+ * @param TaskQueueInterface $assign Optionally specify a new queue instance.
+ *
+ * @return TaskQueueInterface
+ */
+function queue(TaskQueueInterface $assign = null)
+{
+    static $queue;
+
+    if ($assign) {
+        $queue = $assign;
+    } elseif (!$queue) {
+        $queue = new TaskQueue();
+    }
+
+    return $queue;
+}
+
+/**
+ * Adds a function to run in the task queue when it is next `run()` and returns
+ * a promise that is fulfilled or rejected with the result.
+ *
+ * @param callable $task Task function to run.
+ *
+ * @return PromiseInterface
+ */
+function task(callable $task)
+{
+    $queue = queue();
+    $promise = new Promise([$queue, 'run']);
+    $queue->add(function () use ($task, $promise) {
+        try {
+            $promise->resolve($task());
+        } catch (\Throwable $e) {
+            $promise->reject($e);
+        } catch (\Exception $e) {
+            $promise->reject($e);
+        }
+    });
+
+    return $promise;
+}
+
+/**
+ * Creates a promise for a value if the value is not a promise.
+ *
+ * @param mixed $value Promise or value.
+ *
+ * @return PromiseInterface
+ */
+function promise_for($value)
+{
+    if ($value instanceof PromiseInterface) {
+        return $value;
+    }
+
+    // Return a Guzzle promise that shadows the given promise.
+    if (method_exists($value, 'then')) {
+        $wfn = method_exists($value, 'wait') ? [$value, 'wait'] : null;
+        $cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null;
+        $promise = new Promise($wfn, $cfn);
+        $value->then([$promise, 'resolve'], [$promise, 'reject']);
+        return $promise;
+    }
+
+    return new FulfilledPromise($value);
+}
+
+/**
+ * Creates a rejected promise for a reason if the reason is not a promise. If
+ * the provided reason is a promise, then it is returned as-is.
+ *
+ * @param mixed $reason Promise or reason.
+ *
+ * @return PromiseInterface
+ */
+function rejection_for($reason)
+{
+    if ($reason instanceof PromiseInterface) {
+        return $reason;
+    }
+
+    return new RejectedPromise($reason);
+}
+
+/**
+ * Create an exception for a rejected promise value.
+ *
+ * @param mixed $reason
+ *
+ * @return \Exception|\Throwable
+ */
+function exception_for($reason)
+{
+    return $reason instanceof \Exception || $reason instanceof \Throwable
+        ? $reason
+        : new RejectionException($reason);
+}
+
+/**
+ * Returns an iterator for the given value.
+ *
+ * @param mixed $value
+ *
+ * @return \Iterator
+ */
+function iter_for($value)
+{
+    if ($value instanceof \Iterator) {
+        return $value;
+    } elseif (is_array($value)) {
+        return new \ArrayIterator($value);
+    } else {
+        return new \ArrayIterator([$value]);
+    }
+}
+
+/**
+ * Synchronously waits on a promise to resolve and returns an inspection state
+ * array.
+ *
+ * Returns a state associative array containing a "state" key mapping to a
+ * valid promise state. If the state of the promise is "fulfilled", the array
+ * will contain a "value" key mapping to the fulfilled value of the promise. If
+ * the promise is rejected, the array will contain a "reason" key mapping to
+ * the rejection reason of the promise.
+ *
+ * @param PromiseInterface $promise Promise or value.
+ *
+ * @return array
+ */
+function inspect(PromiseInterface $promise)
+{
+    try {
+        return [
+            'state' => PromiseInterface::FULFILLED,
+            'value' => $promise->wait()
+        ];
+    } catch (RejectionException $e) {
+        return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
+    } catch (\Throwable $e) {
+        return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
+    } catch (\Exception $e) {
+        return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
+    }
+}
+
+/**
+ * Waits on all of the provided promises, but does not unwrap rejected promises
+ * as thrown exception.
+ *
+ * Returns an array of inspection state arrays.
+ *
+ * @param PromiseInterface[] $promises Traversable of promises to wait upon.
+ *
+ * @return array
+ * @see GuzzleHttp\Promise\inspect for the inspection state array format.
+ */
+function inspect_all($promises)
+{
+    $results = [];
+    foreach ($promises as $key => $promise) {
+        $results[$key] = inspect($promise);
+    }
+
+    return $results;
+}
+
+/**
+ * Waits on all of the provided promises and returns the fulfilled values.
+ *
+ * Returns an array that contains the value of each promise (in the same order
+ * the promises were provided). An exception is thrown if any of the promises
+ * are rejected.
+ *
+ * @param mixed $promises Iterable of PromiseInterface objects to wait on.
+ *
+ * @return array
+ * @throws \Exception on error
+ * @throws \Throwable on error in PHP >=7
+ */
+function unwrap($promises)
+{
+    $results = [];
+    foreach ($promises as $key => $promise) {
+        $results[$key] = $promise->wait();
+    }
+
+    return $results;
+}
+
+/**
+ * Given an array of promises, return a promise that is fulfilled when all the
+ * items in the array are fulfilled.
+ *
+ * The promise's fulfillment value is an array with fulfillment values at
+ * respective positions to the original array. If any promise in the array
+ * rejects, the returned promise is rejected with the rejection reason.
+ *
+ * @param mixed $promises Promises or values.
+ *
+ * @return PromiseInterface
+ */
+function all($promises)
+{
+    $results = [];
+    return each(
+        $promises,
+        function ($value, $idx) use (&$results) {
+            $results[$idx] = $value;
+        },
+        function ($reason, $idx, Promise $aggregate) {
+            $aggregate->reject($reason);
+        }
+    )->then(function () use (&$results) {
+        ksort($results);
+        return $results;
+    });
+}
+
+/**
+ * Initiate a competitive race between multiple promises or values (values will
+ * become immediately fulfilled promises).
+ *
+ * When count amount of promises have been fulfilled, the returned promise is
+ * fulfilled with an array that contains the fulfillment values of the winners
+ * in order of resolution.
+ *
+ * This prommise is rejected with a {@see GuzzleHttp\Promise\AggregateException}
+ * if the number of fulfilled promises is less than the desired $count.
+ *
+ * @param int   $count    Total number of promises.
+ * @param mixed $promises Promises or values.
+ *
+ * @return PromiseInterface
+ */
+function some($count, $promises)
+{
+    $results = [];
+    $rejections = [];
+
+    return each(
+        $promises,
+        function ($value, $idx, PromiseInterface $p) use (&$results, $count) {
+            if ($p->getState() !== PromiseInterface::PENDING) {
+                return;
+            }
+            $results[$idx] = $value;
+            if (count($results) >= $count) {
+                $p->resolve(null);
+            }
+        },
+        function ($reason) use (&$rejections) {
+            $rejections[] = $reason;
+        }
+    )->then(
+        function () use (&$results, &$rejections, $count) {
+            if (count($results) !== $count) {
+                throw new AggregateException(
+                    'Not enough promises to fulfill count',
+                    $rejections
+                );
+            }
+            ksort($results);
+            return array_values($results);
+        }
+    );
+}
+
+/**
+ * Like some(), with 1 as count. However, if the promise fulfills, the
+ * fulfillment value is not an array of 1 but the value directly.
+ *
+ * @param mixed $promises Promises or values.
+ *
+ * @return PromiseInterface
+ */
+function any($promises)
+{
+    return some(1, $promises)->then(function ($values) { return $values[0]; });
+}
+
+/**
+ * Returns a promise that is fulfilled when all of the provided promises have
+ * been fulfilled or rejected.
+ *
+ * The returned promise is fulfilled with an array of inspection state arrays.
+ *
+ * @param mixed $promises Promises or values.
+ *
+ * @return PromiseInterface
+ * @see GuzzleHttp\Promise\inspect for the inspection state array format.
+ */
+function settle($promises)
+{
+    $results = [];
+
+    return each(
+        $promises,
+        function ($value, $idx) use (&$results) {
+            $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
+        },
+        function ($reason, $idx) use (&$results) {
+            $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
+        }
+    )->then(function () use (&$results) {
+        ksort($results);
+        return $results;
+    });
+}
+
+/**
+ * Given an iterator that yields promises or values, returns a promise that is
+ * fulfilled with a null value when the iterator has been consumed or the
+ * aggregate promise has been fulfilled or rejected.
+ *
+ * $onFulfilled is a function that accepts the fulfilled value, iterator
+ * index, and the aggregate promise. The callback can invoke any necessary side
+ * effects and choose to resolve or reject the aggregate promise if needed.
+ *
+ * $onRejected is a function that accepts the rejection reason, iterator
+ * index, and the aggregate promise. The callback can invoke any necessary side
+ * effects and choose to resolve or reject the aggregate promise if needed.
+ *
+ * @param mixed    $iterable    Iterator or array to iterate over.
+ * @param callable $onFulfilled
+ * @param callable $onRejected
+ *
+ * @return PromiseInterface
+ */
+function each(
+    $iterable,
+    callable $onFulfilled = null,
+    callable $onRejected = null
+) {
+    return (new EachPromise($iterable, [
+        'fulfilled' => $onFulfilled,
+        'rejected'  => $onRejected
+    ]))->promise();
+}
+
+/**
+ * Like each, but only allows a certain number of outstanding promises at any
+ * given time.
+ *
+ * $concurrency may be an integer or a function that accepts the number of
+ * pending promises and returns a numeric concurrency limit value to allow for
+ * dynamic a concurrency size.
+ *
+ * @param mixed        $iterable
+ * @param int|callable $concurrency
+ * @param callable     $onFulfilled
+ * @param callable     $onRejected
+ *
+ * @return PromiseInterface
+ */
+function each_limit(
+    $iterable,
+    $concurrency,
+    callable $onFulfilled = null,
+    callable $onRejected = null
+) {
+    return (new EachPromise($iterable, [
+        'fulfilled'   => $onFulfilled,
+        'rejected'    => $onRejected,
+        'concurrency' => $concurrency
+    ]))->promise();
+}
+
+/**
+ * Like each_limit, but ensures that no promise in the given $iterable argument
+ * is rejected. If any promise is rejected, then the aggregate promise is
+ * rejected with the encountered rejection.
+ *
+ * @param mixed        $iterable
+ * @param int|callable $concurrency
+ * @param callable     $onFulfilled
+ *
+ * @return PromiseInterface
+ */
+function each_limit_all(
+    $iterable,
+    $concurrency,
+    callable $onFulfilled = null
+) {
+    return each_limit(
+        $iterable,
+        $concurrency,
+        $onFulfilled,
+        function ($reason, $idx, PromiseInterface $aggregate) {
+            $aggregate->reject($reason);
+        }
+    );
+}
+
+/**
+ * Returns true if a promise is fulfilled.
+ *
+ * @param PromiseInterface $promise
+ *
+ * @return bool
+ */
+function is_fulfilled(PromiseInterface $promise)
+{
+    return $promise->getState() === PromiseInterface::FULFILLED;
+}
+
+/**
+ * Returns true if a promise is rejected.
+ *
+ * @param PromiseInterface $promise
+ *
+ * @return bool
+ */
+function is_rejected(PromiseInterface $promise)
+{
+    return $promise->getState() === PromiseInterface::REJECTED;
+}
+
+/**
+ * Returns true if a promise is fulfilled or rejected.
+ *
+ * @param PromiseInterface $promise
+ *
+ * @return bool
+ */
+function is_settled(PromiseInterface $promise)
+{
+    return $promise->getState() !== PromiseInterface::PENDING;
+}
+
+/**
+ * @see Coroutine
+ *
+ * @param callable $generatorFn
+ *
+ * @return PromiseInterface
+ */
+function coroutine(callable $generatorFn)
+{
+    return new Coroutine($generatorFn);
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/functions_include.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/promises/src/functions_include.php
new file mode 100644 (file)
index 0000000..34cd171
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+// Don't redefine the functions if included multiple times.
+if (!function_exists('GuzzleHttp\Promise\promise_for')) {
+    require __DIR__ . '/functions.php';
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/CHANGELOG.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/CHANGELOG.md
new file mode 100644 (file)
index 0000000..8a3743d
--- /dev/null
@@ -0,0 +1,246 @@
+# Change Log
+
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+
+## [Unreleased]
+
+
+## [1.6.0]
+
+### Added
+
+- Allowed version `^3.0` of `ralouphie/getallheaders` dependency (#244)
+- Added MIME type for WEBP image format (#246)
+- Added more validation of values according to PSR-7 and RFC standards, e.g. status code range (#250, #272)
+
+### Changed
+
+- Tests don't pass with HHVM 4.0, so HHVM support got dropped. Other libraries like composer have done the same. (#262)
+- Accept port number 0 to be valid (#270)
+
+### Fixed
+
+- Fixed subsequent reads from `php://input` in ServerRequest (#247)
+- Fixed readable/writable detection for certain stream modes (#248)
+- Fixed encoding of special characters in the `userInfo` component of an URI (#253)
+
+
+## [1.5.2] - 2018-12-04
+
+### Fixed
+
+- Check body size when getting the message summary
+
+
+## [1.5.1] - 2018-12-04
+
+### Fixed
+
+- Get the summary of a body only if it is readable
+
+
+## [1.5.0] - 2018-12-03
+
+### Added
+
+- Response first-line to response string exception (fixes #145)
+- A test for #129 behavior
+- `get_message_body_summary` function in order to get the message summary
+- `3gp` and `mkv` mime types
+
+### Changed
+
+- Clarify exception message when stream is detached
+
+### Deprecated
+
+- Deprecated parsing folded header lines as per RFC 7230
+
+### Fixed
+
+- Fix `AppendStream::detach` to not close streams
+- `InflateStream` preserves `isSeekable` attribute of the underlying stream
+- `ServerRequest::getUriFromGlobals` to support URLs in query parameters
+
+
+Several other fixes and improvements.
+
+
+## [1.4.2] - 2017-03-20
+
+### Fixed
+
+- Reverted BC break to `Uri::resolve` and `Uri::removeDotSegments` by removing
+  calls to `trigger_error` when deprecated methods are invoked.
+
+
+## [1.4.1] - 2017-02-27
+
+### Added
+
+- Rriggering of silenced deprecation warnings.
+
+### Fixed
+
+- Reverted BC break by reintroducing behavior to automagically fix a URI with a
+  relative path and an authority by adding a leading slash to the path. It's only
+  deprecated now.
+
+
+## [1.4.0] - 2017-02-21
+
+### Added
+
+- Added common URI utility methods based on RFC 3986 (see documentation in the readme):
+  - `Uri::isDefaultPort`
+  - `Uri::isAbsolute`
+  - `Uri::isNetworkPathReference`
+  - `Uri::isAbsolutePathReference`
+  - `Uri::isRelativePathReference`
+  - `Uri::isSameDocumentReference`
+  - `Uri::composeComponents`
+  - `UriNormalizer::normalize`
+  - `UriNormalizer::isEquivalent`
+  - `UriResolver::relativize`
+
+### Changed
+
+- Ensure `ServerRequest::getUriFromGlobals` returns a URI in absolute form.
+- Allow `parse_response` to parse a response without delimiting space and reason.
+- Ensure each URI modification results in a valid URI according to PSR-7 discussions.
+  Invalid modifications will throw an exception instead of returning a wrong URI or
+  doing some magic.
+  - `(new Uri)->withPath('foo')->withHost('example.com')` will throw an exception
+    because the path of a URI with an authority must start with a slash "/" or be empty
+  - `(new Uri())->withScheme('http')` will return `'http://localhost'`
+
+### Deprecated
+
+- `Uri::resolve` in favor of `UriResolver::resolve`
+- `Uri::removeDotSegments` in favor of `UriResolver::removeDotSegments`
+
+### Fixed
+
+- `Stream::read` when length parameter <= 0.
+- `copy_to_stream` reads bytes in chunks instead of `maxLen` into memory.
+- `ServerRequest::getUriFromGlobals` when `Host` header contains port.
+- Compatibility of URIs with `file` scheme and empty host.
+
+
+## [1.3.1] - 2016-06-25
+
+### Fixed
+
+- `Uri::__toString` for network path references, e.g. `//example.org`.
+- Missing lowercase normalization for host.
+- Handling of URI components in case they are `'0'` in a lot of places,
+  e.g. as a user info password.
+- `Uri::withAddedHeader` to correctly merge headers with different case.
+- Trimming of header values in `Uri::withAddedHeader`. Header values may
+  be surrounded by whitespace which should be ignored according to RFC 7230
+  Section 3.2.4. This does not apply to header names.
+- `Uri::withAddedHeader` with an array of header values.
+- `Uri::resolve` when base path has no slash and handling of fragment.
+- Handling of encoding in `Uri::with(out)QueryValue` so one can pass the
+  key/value both in encoded as well as decoded form to those methods. This is
+  consistent with withPath, withQuery etc.
+- `ServerRequest::withoutAttribute` when attribute value is null.
+
+
+## [1.3.0] - 2016-04-13
+
+### Added
+
+- Remaining interfaces needed for full PSR7 compatibility
+  (ServerRequestInterface, UploadedFileInterface, etc.).
+- Support for stream_for from scalars.
+
+### Changed
+
+- Can now extend Uri.
+
+### Fixed
+- A bug in validating request methods by making it more permissive.
+
+
+## [1.2.3] - 2016-02-18
+
+### Fixed
+
+- Support in `GuzzleHttp\Psr7\CachingStream` for seeking forward on remote
+  streams, which can sometimes return fewer bytes than requested with `fread`.
+- Handling of gzipped responses with FNAME headers.
+
+
+## [1.2.2] - 2016-01-22
+
+### Added
+
+- Support for URIs without any authority.
+- Support for HTTP 451 'Unavailable For Legal Reasons.'
+- Support for using '0' as a filename.
+- Support for including non-standard ports in Host headers.
+
+
+## [1.2.1] - 2015-11-02
+
+### Changes
+
+- Now supporting negative offsets when seeking to SEEK_END.
+
+
+## [1.2.0] - 2015-08-15
+
+### Changed
+
+- Body as `"0"` is now properly added to a response.
+- Now allowing forward seeking in CachingStream.
+- Now properly parsing HTTP requests that contain proxy targets in
+  `parse_request`.
+- functions.php is now conditionally required.
+- user-info is no longer dropped when resolving URIs.
+
+
+## [1.1.0] - 2015-06-24
+
+### Changed
+
+- URIs can now be relative.
+- `multipart/form-data` headers are now overridden case-insensitively.
+- URI paths no longer encode the following characters because they are allowed
+  in URIs: "(", ")", "*", "!", "'"
+- A port is no longer added to a URI when the scheme is missing and no port is
+  present.
+
+
+## 1.0.0 - 2015-05-19
+
+Initial release.
+
+Currently unsupported:
+
+- `Psr\Http\Message\ServerRequestInterface`
+- `Psr\Http\Message\UploadedFileInterface`
+
+
+
+[Unreleased]: https://github.com/guzzle/psr7/compare/1.6.0...HEAD
+[1.6.0]: https://github.com/guzzle/psr7/compare/1.5.2...1.6.0
+[1.5.2]: https://github.com/guzzle/psr7/compare/1.5.1...1.5.2
+[1.5.1]: https://github.com/guzzle/psr7/compare/1.5.0...1.5.1
+[1.5.0]: https://github.com/guzzle/psr7/compare/1.4.2...1.5.0
+[1.4.2]: https://github.com/guzzle/psr7/compare/1.4.1...1.4.2
+[1.4.1]: https://github.com/guzzle/psr7/compare/1.4.0...1.4.1
+[1.4.0]: https://github.com/guzzle/psr7/compare/1.3.1...1.4.0
+[1.3.1]: https://github.com/guzzle/psr7/compare/1.3.0...1.3.1
+[1.3.0]: https://github.com/guzzle/psr7/compare/1.2.3...1.3.0
+[1.2.3]: https://github.com/guzzle/psr7/compare/1.2.2...1.2.3
+[1.2.2]: https://github.com/guzzle/psr7/compare/1.2.1...1.2.2
+[1.2.1]: https://github.com/guzzle/psr7/compare/1.2.0...1.2.1
+[1.2.0]: https://github.com/guzzle/psr7/compare/1.1.0...1.2.0
+[1.1.0]: https://github.com/guzzle/psr7/compare/1.0.0...1.1.0
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/LICENSE b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/LICENSE
new file mode 100644 (file)
index 0000000..581d95f
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/README.md b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/README.md
new file mode 100644 (file)
index 0000000..c60a6a3
--- /dev/null
@@ -0,0 +1,745 @@
+# PSR-7 Message Implementation
+
+This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/)
+message implementation, several stream decorators, and some helpful
+functionality like query string parsing.
+
+
+[![Build Status](https://travis-ci.org/guzzle/psr7.svg?branch=master)](https://travis-ci.org/guzzle/psr7)
+
+
+# Stream implementation
+
+This package comes with a number of stream implementations and stream
+decorators.
+
+
+## AppendStream
+
+`GuzzleHttp\Psr7\AppendStream`
+
+Reads from multiple streams, one after the other.
+
+```php
+use GuzzleHttp\Psr7;
+
+$a = Psr7\stream_for('abc, ');
+$b = Psr7\stream_for('123.');
+$composed = new Psr7\AppendStream([$a, $b]);
+
+$composed->addStream(Psr7\stream_for(' Above all listen to me'));
+
+echo $composed; // abc, 123. Above all listen to me.
+```
+
+
+## BufferStream
+
+`GuzzleHttp\Psr7\BufferStream`
+
+Provides a buffer stream that can be written to fill a buffer, and read
+from to remove bytes from the buffer.
+
+This stream returns a "hwm" metadata value that tells upstream consumers
+what the configured high water mark of the stream is, or the maximum
+preferred size of the buffer.
+
+```php
+use GuzzleHttp\Psr7;
+
+// When more than 1024 bytes are in the buffer, it will begin returning
+// false to writes. This is an indication that writers should slow down.
+$buffer = new Psr7\BufferStream(1024);
+```
+
+
+## CachingStream
+
+The CachingStream is used to allow seeking over previously read bytes on
+non-seekable streams. This can be useful when transferring a non-seekable
+entity body fails due to needing to rewind the stream (for example, resulting
+from a redirect). Data that is read from the remote stream will be buffered in
+a PHP temp stream so that previously read bytes are cached first in memory,
+then on disk.
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for(fopen('http://www.google.com', 'r'));
+$stream = new Psr7\CachingStream($original);
+
+$stream->read(1024);
+echo $stream->tell();
+// 1024
+
+$stream->seek(0);
+echo $stream->tell();
+// 0
+```
+
+
+## DroppingStream
+
+`GuzzleHttp\Psr7\DroppingStream`
+
+Stream decorator that begins dropping data once the size of the underlying
+stream becomes too full.
+
+```php
+use GuzzleHttp\Psr7;
+
+// Create an empty stream
+$stream = Psr7\stream_for();
+
+// Start dropping data when the stream has more than 10 bytes
+$dropping = new Psr7\DroppingStream($stream, 10);
+
+$dropping->write('01234567890123456789');
+echo $stream; // 0123456789
+```
+
+
+## FnStream
+
+`GuzzleHttp\Psr7\FnStream`
+
+Compose stream implementations based on a hash of functions.
+
+Allows for easy testing and extension of a provided stream without needing
+to create a concrete class for a simple extension point.
+
+```php
+
+use GuzzleHttp\Psr7;
+
+$stream = Psr7\stream_for('hi');
+$fnStream = Psr7\FnStream::decorate($stream, [
+    'rewind' => function () use ($stream) {
+        echo 'About to rewind - ';
+        $stream->rewind();
+        echo 'rewound!';
+    }
+]);
+
+$fnStream->rewind();
+// Outputs: About to rewind - rewound!
+```
+
+
+## InflateStream
+
+`GuzzleHttp\Psr7\InflateStream`
+
+Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
+
+This stream decorator skips the first 10 bytes of the given stream to remove
+the gzip header, converts the provided stream to a PHP stream resource,
+then appends the zlib.inflate filter. The stream is then converted back
+to a Guzzle stream resource to be used as a Guzzle stream.
+
+
+## LazyOpenStream
+
+`GuzzleHttp\Psr7\LazyOpenStream`
+
+Lazily reads or writes to a file that is opened only after an IO operation
+take place on the stream.
+
+```php
+use GuzzleHttp\Psr7;
+
+$stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
+// The file has not yet been opened...
+
+echo $stream->read(10);
+// The file is opened and read from only when needed.
+```
+
+
+## LimitStream
+
+`GuzzleHttp\Psr7\LimitStream`
+
+LimitStream can be used to read a subset or slice of an existing stream object.
+This can be useful for breaking a large file into smaller pieces to be sent in
+chunks (e.g. Amazon S3's multipart upload API).
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+'));
+echo $original->getSize();
+// >>> 1048576
+
+// Limit the size of the body to 1024 bytes and start reading from byte 2048
+$stream = new Psr7\LimitStream($original, 1024, 2048);
+echo $stream->getSize();
+// >>> 1024
+echo $stream->tell();
+// >>> 0
+```
+
+
+## MultipartStream
+
+`GuzzleHttp\Psr7\MultipartStream`
+
+Stream that when read returns bytes for a streaming multipart or
+multipart/form-data stream.
+
+
+## NoSeekStream
+
+`GuzzleHttp\Psr7\NoSeekStream`
+
+NoSeekStream wraps a stream and does not allow seeking.
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for('foo');
+$noSeek = new Psr7\NoSeekStream($original);
+
+echo $noSeek->read(3);
+// foo
+var_export($noSeek->isSeekable());
+// false
+$noSeek->seek(0);
+var_export($noSeek->read(3));
+// NULL
+```
+
+
+## PumpStream
+
+`GuzzleHttp\Psr7\PumpStream`
+
+Provides a read only stream that pumps data from a PHP callable.
+
+When invoking the provided callable, the PumpStream will pass the amount of
+data requested to read to the callable. The callable can choose to ignore
+this value and return fewer or more bytes than requested. Any extra data
+returned by the provided callable is buffered internally until drained using
+the read() function of the PumpStream. The provided callable MUST return
+false when there is no more data to read.
+
+
+## Implementing stream decorators
+
+Creating a stream decorator is very easy thanks to the
+`GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that
+implement `Psr\Http\Message\StreamInterface` by proxying to an underlying
+stream. Just `use` the `StreamDecoratorTrait` and implement your custom
+methods.
+
+For example, let's say we wanted to call a specific function each time the last
+byte is read from a stream. This could be implemented by overriding the
+`read()` method.
+
+```php
+use Psr\Http\Message\StreamInterface;
+use GuzzleHttp\Psr7\StreamDecoratorTrait;
+
+class EofCallbackStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    private $callback;
+
+    public function __construct(StreamInterface $stream, callable $cb)
+    {
+        $this->stream = $stream;
+        $this->callback = $cb;
+    }
+
+    public function read($length)
+    {
+        $result = $this->stream->read($length);
+
+        // Invoke the callback when EOF is hit.
+        if ($this->eof()) {
+            call_user_func($this->callback);
+        }
+
+        return $result;
+    }
+}
+```
+
+This decorator could be added to any existing stream and used like so:
+
+```php
+use GuzzleHttp\Psr7;
+
+$original = Psr7\stream_for('foo');
+
+$eofStream = new EofCallbackStream($original, function () {
+    echo 'EOF!';
+});
+
+$eofStream->read(2);
+$eofStream->read(1);
+// echoes "EOF!"
+$eofStream->seek(0);
+$eofStream->read(3);
+// echoes "EOF!"
+```
+
+
+## PHP StreamWrapper
+
+You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a
+PSR-7 stream as a PHP stream resource.
+
+Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP
+stream from a PSR-7 stream.
+
+```php
+use GuzzleHttp\Psr7\StreamWrapper;
+
+$stream = GuzzleHttp\Psr7\stream_for('hello!');
+$resource = StreamWrapper::getResource($stream);
+echo fread($resource, 6); // outputs hello!
+```
+
+
+# Function API
+
+There are various functions available under the `GuzzleHttp\Psr7` namespace.
+
+
+## `function str`
+
+`function str(MessageInterface $message)`
+
+Returns the string representation of an HTTP message.
+
+```php
+$request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
+echo GuzzleHttp\Psr7\str($request);
+```
+
+
+## `function uri_for`
+
+`function uri_for($uri)`
+
+This function accepts a string or `Psr\Http\Message\UriInterface` and returns a
+UriInterface for the given value. If the value is already a `UriInterface`, it
+is returned as-is.
+
+```php
+$uri = GuzzleHttp\Psr7\uri_for('http://example.com');
+assert($uri === GuzzleHttp\Psr7\uri_for($uri));
+```
+
+
+## `function stream_for`
+
+`function stream_for($resource = '', array $options = [])`
+
+Create a new stream based on the input type.
+
+Options is an associative array that can contain the following keys:
+
+* - metadata: Array of custom metadata.
+* - size: Size of the stream.
+
+This method accepts the following `$resource` types:
+
+- `Psr\Http\Message\StreamInterface`: Returns the value as-is.
+- `string`: Creates a stream object that uses the given string as the contents.
+- `resource`: Creates a stream object that wraps the given PHP stream resource.
+- `Iterator`: If the provided value implements `Iterator`, then a read-only
+  stream object will be created that wraps the given iterable. Each time the
+  stream is read from, data from the iterator will fill a buffer and will be
+  continuously called until the buffer is equal to the requested read size.
+  Subsequent read calls will first read from the buffer and then call `next`
+  on the underlying iterator until it is exhausted.
+- `object` with `__toString()`: If the object has the `__toString()` method,
+  the object will be cast to a string and then a stream will be returned that
+  uses the string value.
+- `NULL`: When `null` is passed, an empty stream object is returned.
+- `callable` When a callable is passed, a read-only stream object will be
+  created that invokes the given callable. The callable is invoked with the
+  number of suggested bytes to read. The callable can return any number of
+  bytes, but MUST return `false` when there is no more data to return. The
+  stream object that wraps the callable will invoke the callable until the
+  number of requested bytes are available. Any additional bytes will be
+  buffered and used in subsequent reads.
+
+```php
+$stream = GuzzleHttp\Psr7\stream_for('foo');
+$stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r'));
+
+$generator = function ($bytes) {
+    for ($i = 0; $i < $bytes; $i++) {
+        yield ' ';
+    }
+}
+
+$stream = GuzzleHttp\Psr7\stream_for($generator(100));
+```
+
+
+## `function parse_header`
+
+`function parse_header($header)`
+
+Parse an array of header values containing ";" separated data into an array of
+associative arrays representing the header key value pair data of the header.
+When a parameter does not contain a value, but just contains a key, this
+function will inject a key with a '' string value.
+
+
+## `function normalize_header`
+
+`function normalize_header($header)`
+
+Converts an array of header values that may contain comma separated headers
+into an array of headers with no comma separated values.
+
+
+## `function modify_request`
+
+`function modify_request(RequestInterface $request, array $changes)`
+
+Clone and modify a request with the given changes. This method is useful for
+reducing the number of clones needed to mutate a message.
+
+The changes can be one of:
+
+- method: (string) Changes the HTTP method.
+- set_headers: (array) Sets the given headers.
+- remove_headers: (array) Remove the given headers.
+- body: (mixed) Sets the given body.
+- uri: (UriInterface) Set the URI.
+- query: (string) Set the query string value of the URI.
+- version: (string) Set the protocol version.
+
+
+## `function rewind_body`
+
+`function rewind_body(MessageInterface $message)`
+
+Attempts to rewind a message body and throws an exception on failure. The body
+of the message will only be rewound if a call to `tell()` returns a value other
+than `0`.
+
+
+## `function try_fopen`
+
+`function try_fopen($filename, $mode)`
+
+Safely opens a PHP stream resource using a filename.
+
+When fopen fails, PHP normally raises a warning. This function adds an error
+handler that checks for errors and throws an exception instead.
+
+
+## `function copy_to_string`
+
+`function copy_to_string(StreamInterface $stream, $maxLen = -1)`
+
+Copy the contents of a stream into a string until the given number of bytes
+have been read.
+
+
+## `function copy_to_stream`
+
+`function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)`
+
+Copy the contents of a stream into another stream until the given number of
+bytes have been read.
+
+
+## `function hash`
+
+`function hash(StreamInterface $stream, $algo, $rawOutput = false)`
+
+Calculate a hash of a Stream. This method reads the entire stream to calculate
+a rolling hash (based on PHP's hash_init functions).
+
+
+## `function readline`
+
+`function readline(StreamInterface $stream, $maxLength = null)`
+
+Read a line from the stream up to the maximum allowed buffer length.
+
+
+## `function parse_request`
+
+`function parse_request($message)`
+
+Parses a request message string into a request object.
+
+
+## `function parse_response`
+
+`function parse_response($message)`
+
+Parses a response message string into a response object.
+
+
+## `function parse_query`
+
+`function parse_query($str, $urlEncoding = true)`
+
+Parse a query string into an associative array.
+
+If multiple values are found for the same key, the value of that key value pair
+will become an array. This function does not parse nested PHP style arrays into
+an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
+`['foo[a]' => '1', 'foo[b]' => '2']`).
+
+
+## `function build_query`
+
+`function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
+
+Build a query string from an array of key value pairs.
+
+This function can use the return value of parse_query() to build a query string.
+This function does not modify the provided keys when an array is encountered
+(like http_build_query would).
+
+
+## `function mimetype_from_filename`
+
+`function mimetype_from_filename($filename)`
+
+Determines the mimetype of a file by looking at its extension.
+
+
+## `function mimetype_from_extension`
+
+`function mimetype_from_extension($extension)`
+
+Maps a file extensions to a mimetype.
+
+
+# Additional URI Methods
+
+Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,
+this library also provides additional functionality when working with URIs as static methods.
+
+## URI Types
+
+An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
+An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
+the base URI. Relative references can be divided into several forms according to
+[RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2):
+
+- network-path references, e.g. `//example.com/path`
+- absolute-path references, e.g. `/path`
+- relative-path references, e.g. `subpath`
+
+The following methods can be used to identify the type of the URI.
+
+### `GuzzleHttp\Psr7\Uri::isAbsolute`
+
+`public static function isAbsolute(UriInterface $uri): bool`
+
+Whether the URI is absolute, i.e. it has a scheme.
+
+### `GuzzleHttp\Psr7\Uri::isNetworkPathReference`
+
+`public static function isNetworkPathReference(UriInterface $uri): bool`
+
+Whether the URI is a network-path reference. A relative reference that begins with two slash characters is
+termed an network-path reference.
+
+### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference`
+
+`public static function isAbsolutePathReference(UriInterface $uri): bool`
+
+Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is
+termed an absolute-path reference.
+
+### `GuzzleHttp\Psr7\Uri::isRelativePathReference`
+
+`public static function isRelativePathReference(UriInterface $uri): bool`
+
+Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is
+termed a relative-path reference.
+
+### `GuzzleHttp\Psr7\Uri::isSameDocumentReference`
+
+`public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool`
+
+Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its
+fragment component, identical to the base URI. When no base URI is given, only an empty URI reference
+(apart from its fragment) is considered a same-document reference.
+
+## URI Components
+
+Additional methods to work with URI components.
+
+### `GuzzleHttp\Psr7\Uri::isDefaultPort`
+
+`public static function isDefaultPort(UriInterface $uri): bool`
+
+Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null
+or the standard port. This method can be used independently of the implementation.
+
+### `GuzzleHttp\Psr7\Uri::composeComponents`
+
+`public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
+
+Composes a URI reference string from its various components according to
+[RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called
+manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
+
+### `GuzzleHttp\Psr7\Uri::fromParts`
+
+`public static function fromParts(array $parts): UriInterface`
+
+Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components.
+
+
+### `GuzzleHttp\Psr7\Uri::withQueryValue`
+
+`public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface`
+
+Creates a new URI with a specific query string value. Any existing query string values that exactly match the
+provided key are removed and replaced with the given key value pair. A value of null will set the query string
+key without a value, e.g. "key" instead of "key=value".
+
+### `GuzzleHttp\Psr7\Uri::withQueryValues`
+
+`public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface`
+
+Creates a new URI with multiple query string values. It has the same behavior as `withQueryValue()` but for an
+associative array of key => value.
+
+### `GuzzleHttp\Psr7\Uri::withoutQueryValue`
+
+`public static function withoutQueryValue(UriInterface $uri, $key): UriInterface`
+
+Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the
+provided key are removed.
+
+## Reference Resolution
+
+`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
+to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers
+do when resolving a link in a website based on the current request URI.
+
+### `GuzzleHttp\Psr7\UriResolver::resolve`
+
+`public static function resolve(UriInterface $base, UriInterface $rel): UriInterface`
+
+Converts the relative URI into a new URI that is resolved against the base URI.
+
+### `GuzzleHttp\Psr7\UriResolver::removeDotSegments`
+
+`public static function removeDotSegments(string $path): string`
+
+Removes dot segments from a path and returns the new path according to
+[RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4).
+
+### `GuzzleHttp\Psr7\UriResolver::relativize`
+
+`public static function relativize(UriInterface $base, UriInterface $target): UriInterface`
+
+Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve():
+
+```php
+(string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
+```
+
+One use-case is to use the current request URI as base URI and then generate relative links in your documents
+to reduce the document size or offer self-contained downloadable document archives.
+
+```php
+$base = new Uri('http://example.com/a/b/');
+echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c'));  // prints 'c'.
+echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y'));  // prints '../x/y'.
+echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
+echo UriResolver::relativize($base, new Uri('http://example.org/a/b/'));   // prints '//example.org/a/b/'.
+```
+
+## Normalization and Comparison
+
+`GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
+[RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6).
+
+### `GuzzleHttp\Psr7\UriNormalizer::normalize`
+
+`public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface`
+
+Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
+This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask
+of normalizations to apply. The following normalizations are available:
+
+- `UriNormalizer::PRESERVING_NORMALIZATIONS`
+
+    Default normalizations which only include the ones that preserve semantics.
+
+- `UriNormalizer::CAPITALIZE_PERCENT_ENCODING`
+
+    All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
+
+    Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b`
+
+- `UriNormalizer::DECODE_UNRESERVED_CHARACTERS`
+
+    Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of
+    ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should
+    not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved
+    characters by URI normalizers.
+
+    Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/`
+
+- `UriNormalizer::CONVERT_EMPTY_PATH`
+
+    Converts the empty path to "/" for http and https URIs.
+
+    Example: `http://example.org` → `http://example.org/`
+
+- `UriNormalizer::REMOVE_DEFAULT_HOST`
+
+    Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host
+    "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to
+    RFC 3986.
+
+    Example: `file://localhost/myfile` → `file:///myfile`
+
+- `UriNormalizer::REMOVE_DEFAULT_PORT`
+
+    Removes the default port of the given URI scheme from the URI.
+
+    Example: `http://example.org:80/` → `http://example.org/`
+
+- `UriNormalizer::REMOVE_DOT_SEGMENTS`
+
+    Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would
+    change the semantics of the URI reference.
+
+    Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html`
+
+- `UriNormalizer::REMOVE_DUPLICATE_SLASHES`
+
+    Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes
+    and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization
+    may change the semantics. Encoded slashes (%2F) are not removed.
+
+    Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html`
+
+- `UriNormalizer::SORT_QUERY_PARAMETERS`
+
+    Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be
+    significant (this is not defined by the standard). So this normalization is not safe and may change the semantics
+    of the URI.
+
+    Example: `?lang=en&article=fred` → `?article=fred&lang=en`
+
+### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent`
+
+`public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool`
+
+Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given
+`$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent.
+This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
+equivalence or difference of relative references does not mean anything.
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/composer.json b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/composer.json
new file mode 100644 (file)
index 0000000..168a055
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "name": "guzzlehttp/psr7",
+    "type": "library",
+    "description": "PSR-7 message implementation that also provides common utility methods",
+    "keywords": ["request", "response", "message", "stream", "http", "uri", "url", "psr-7"],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Michael Dowling",
+            "email": "mtdowling@gmail.com",
+            "homepage": "https://github.com/mtdowling"
+        },
+        {
+            "name": "Tobias Schultze",
+            "homepage": "https://github.com/Tobion"
+        }
+    ],
+    "require": {
+        "php": ">=5.4.0",
+        "psr/http-message": "~1.0",
+        "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8",
+        "ext-zlib": "*"
+    },
+    "provide": {
+        "psr/http-message-implementation": "1.0"
+    },
+    "suggest": {
+        "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
+    },
+    "autoload": {
+        "psr-4": {
+            "GuzzleHttp\\Psr7\\": "src/"
+        },
+        "files": ["src/functions_include.php"]
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "GuzzleHttp\\Tests\\Psr7\\": "tests/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.6-dev"
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/AppendStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/AppendStream.php
new file mode 100644 (file)
index 0000000..472a0d6
--- /dev/null
@@ -0,0 +1,241 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Reads from multiple streams, one after the other.
+ *
+ * This is a read-only stream decorator.
+ */
+class AppendStream implements StreamInterface
+{
+    /** @var StreamInterface[] Streams being decorated */
+    private $streams = [];
+
+    private $seekable = true;
+    private $current = 0;
+    private $pos = 0;
+
+    /**
+     * @param StreamInterface[] $streams Streams to decorate. Each stream must
+     *                                   be readable.
+     */
+    public function __construct(array $streams = [])
+    {
+        foreach ($streams as $stream) {
+            $this->addStream($stream);
+        }
+    }
+
+    public function __toString()
+    {
+        try {
+            $this->rewind();
+            return $this->getContents();
+        } catch (\Exception $e) {
+            return '';
+        }
+    }
+
+    /**
+     * Add a stream to the AppendStream
+     *
+     * @param StreamInterface $stream Stream to append. Must be readable.
+     *
+     * @throws \InvalidArgumentException if the stream is not readable
+     */
+    public function addStream(StreamInterface $stream)
+    {
+        if (!$stream->isReadable()) {
+            throw new \InvalidArgumentException('Each stream must be readable');
+        }
+
+        // The stream is only seekable if all streams are seekable
+        if (!$stream->isSeekable()) {
+            $this->seekable = false;
+        }
+
+        $this->streams[] = $stream;
+    }
+
+    public function getContents()
+    {
+        return copy_to_string($this);
+    }
+
+    /**
+     * Closes each attached stream.
+     *
+     * {@inheritdoc}
+     */
+    public function close()
+    {
+        $this->pos = $this->current = 0;
+        $this->seekable = true;
+
+        foreach ($this->streams as $stream) {
+            $stream->close();
+        }
+
+        $this->streams = [];
+    }
+
+    /**
+     * Detaches each attached stream.
+     *
+     * Returns null as it's not clear which underlying stream resource to return.
+     *
+     * {@inheritdoc}
+     */
+    public function detach()
+    {
+        $this->pos = $this->current = 0;
+        $this->seekable = true;
+
+        foreach ($this->streams as $stream) {
+            $stream->detach();
+        }
+
+        $this->streams = [];
+    }
+
+    public function tell()
+    {
+        return $this->pos;
+    }
+
+    /**
+     * Tries to calculate the size by adding the size of each stream.
+     *
+     * If any of the streams do not return a valid number, then the size of the
+     * append stream cannot be determined and null is returned.
+     *
+     * {@inheritdoc}
+     */
+    public function getSize()
+    {
+        $size = 0;
+
+        foreach ($this->streams as $stream) {
+            $s = $stream->getSize();
+            if ($s === null) {
+                return null;
+            }
+            $size += $s;
+        }
+
+        return $size;
+    }
+
+    public function eof()
+    {
+        return !$this->streams ||
+            ($this->current >= count($this->streams) - 1 &&
+             $this->streams[$this->current]->eof());
+    }
+
+    public function rewind()
+    {
+        $this->seek(0);
+    }
+
+    /**
+     * Attempts to seek to the given position. Only supports SEEK_SET.
+     *
+     * {@inheritdoc}
+     */
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        if (!$this->seekable) {
+            throw new \RuntimeException('This AppendStream is not seekable');
+        } elseif ($whence !== SEEK_SET) {
+            throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
+        }
+
+        $this->pos = $this->current = 0;
+
+        // Rewind each stream
+        foreach ($this->streams as $i => $stream) {
+            try {
+                $stream->rewind();
+            } catch (\Exception $e) {
+                throw new \RuntimeException('Unable to seek stream '
+                    . $i . ' of the AppendStream', 0, $e);
+            }
+        }
+
+        // Seek to the actual position by reading from each stream
+        while ($this->pos < $offset && !$this->eof()) {
+            $result = $this->read(min(8096, $offset - $this->pos));
+            if ($result === '') {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Reads from all of the appended streams until the length is met or EOF.
+     *
+     * {@inheritdoc}
+     */
+    public function read($length)
+    {
+        $buffer = '';
+        $total = count($this->streams) - 1;
+        $remaining = $length;
+        $progressToNext = false;
+
+        while ($remaining > 0) {
+
+            // Progress to the next stream if needed.
+            if ($progressToNext || $this->streams[$this->current]->eof()) {
+                $progressToNext = false;
+                if ($this->current === $total) {
+                    break;
+                }
+                $this->current++;
+            }
+
+            $result = $this->streams[$this->current]->read($remaining);
+
+            // Using a loose comparison here to match on '', false, and null
+            if ($result == null) {
+                $progressToNext = true;
+                continue;
+            }
+
+            $buffer .= $result;
+            $remaining = $length - strlen($buffer);
+        }
+
+        $this->pos += strlen($buffer);
+
+        return $buffer;
+    }
+
+    public function isReadable()
+    {
+        return true;
+    }
+
+    public function isWritable()
+    {
+        return false;
+    }
+
+    public function isSeekable()
+    {
+        return $this->seekable;
+    }
+
+    public function write($string)
+    {
+        throw new \RuntimeException('Cannot write to an AppendStream');
+    }
+
+    public function getMetadata($key = null)
+    {
+        return $key ? null : [];
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/BufferStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/BufferStream.php
new file mode 100644 (file)
index 0000000..af4d4c2
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Provides a buffer stream that can be written to to fill a buffer, and read
+ * from to remove bytes from the buffer.
+ *
+ * This stream returns a "hwm" metadata value that tells upstream consumers
+ * what the configured high water mark of the stream is, or the maximum
+ * preferred size of the buffer.
+ */
+class BufferStream implements StreamInterface
+{
+    private $hwm;
+    private $buffer = '';
+
+    /**
+     * @param int $hwm High water mark, representing the preferred maximum
+     *                 buffer size. If the size of the buffer exceeds the high
+     *                 water mark, then calls to write will continue to succeed
+     *                 but will return false to inform writers to slow down
+     *                 until the buffer has been drained by reading from it.
+     */
+    public function __construct($hwm = 16384)
+    {
+        $this->hwm = $hwm;
+    }
+
+    public function __toString()
+    {
+        return $this->getContents();
+    }
+
+    public function getContents()
+    {
+        $buffer = $this->buffer;
+        $this->buffer = '';
+
+        return $buffer;
+    }
+
+    public function close()
+    {
+        $this->buffer = '';
+    }
+
+    public function detach()
+    {
+        $this->close();
+    }
+
+    public function getSize()
+    {
+        return strlen($this->buffer);
+    }
+
+    public function isReadable()
+    {
+        return true;
+    }
+
+    public function isWritable()
+    {
+        return true;
+    }
+
+    public function isSeekable()
+    {
+        return false;
+    }
+
+    public function rewind()
+    {
+        $this->seek(0);
+    }
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        throw new \RuntimeException('Cannot seek a BufferStream');
+    }
+
+    public function eof()
+    {
+        return strlen($this->buffer) === 0;
+    }
+
+    public function tell()
+    {
+        throw new \RuntimeException('Cannot determine the position of a BufferStream');
+    }
+
+    /**
+     * Reads data from the buffer.
+     */
+    public function read($length)
+    {
+        $currentLength = strlen($this->buffer);
+
+        if ($length >= $currentLength) {
+            // No need to slice the buffer because we don't have enough data.
+            $result = $this->buffer;
+            $this->buffer = '';
+        } else {
+            // Slice up the result to provide a subset of the buffer.
+            $result = substr($this->buffer, 0, $length);
+            $this->buffer = substr($this->buffer, $length);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Writes data to the buffer.
+     */
+    public function write($string)
+    {
+        $this->buffer .= $string;
+
+        // TODO: What should happen here?
+        if (strlen($this->buffer) >= $this->hwm) {
+            return false;
+        }
+
+        return strlen($string);
+    }
+
+    public function getMetadata($key = null)
+    {
+        if ($key == 'hwm') {
+            return $this->hwm;
+        }
+
+        return $key ? null : [];
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/CachingStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/CachingStream.php
new file mode 100644 (file)
index 0000000..ed68f08
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator that can cache previously read bytes from a sequentially
+ * read stream.
+ */
+class CachingStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    /** @var StreamInterface Stream being wrapped */
+    private $remoteStream;
+
+    /** @var int Number of bytes to skip reading due to a write on the buffer */
+    private $skipReadBytes = 0;
+
+    /**
+     * We will treat the buffer object as the body of the stream
+     *
+     * @param StreamInterface $stream Stream to cache
+     * @param StreamInterface $target Optionally specify where data is cached
+     */
+    public function __construct(
+        StreamInterface $stream,
+        StreamInterface $target = null
+    ) {
+        $this->remoteStream = $stream;
+        $this->stream = $target ?: new Stream(fopen('php://temp', 'r+'));
+    }
+
+    public function getSize()
+    {
+        return max($this->stream->getSize(), $this->remoteStream->getSize());
+    }
+
+    public function rewind()
+    {
+        $this->seek(0);
+    }
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        if ($whence == SEEK_SET) {
+            $byte = $offset;
+        } elseif ($whence == SEEK_CUR) {
+            $byte = $offset + $this->tell();
+        } elseif ($whence == SEEK_END) {
+            $size = $this->remoteStream->getSize();
+            if ($size === null) {
+                $size = $this->cacheEntireStream();
+            }
+            $byte = $size + $offset;
+        } else {
+            throw new \InvalidArgumentException('Invalid whence');
+        }
+
+        $diff = $byte - $this->stream->getSize();
+
+        if ($diff > 0) {
+            // Read the remoteStream until we have read in at least the amount
+            // of bytes requested, or we reach the end of the file.
+            while ($diff > 0 && !$this->remoteStream->eof()) {
+                $this->read($diff);
+                $diff = $byte - $this->stream->getSize();
+            }
+        } else {
+            // We can just do a normal seek since we've already seen this byte.
+            $this->stream->seek($byte);
+        }
+    }
+
+    public function read($length)
+    {
+        // Perform a regular read on any previously read data from the buffer
+        $data = $this->stream->read($length);
+        $remaining = $length - strlen($data);
+
+        // More data was requested so read from the remote stream
+        if ($remaining) {
+            // If data was written to the buffer in a position that would have
+            // been filled from the remote stream, then we must skip bytes on
+            // the remote stream to emulate overwriting bytes from that
+            // position. This mimics the behavior of other PHP stream wrappers.
+            $remoteData = $this->remoteStream->read(
+                $remaining + $this->skipReadBytes
+            );
+
+            if ($this->skipReadBytes) {
+                $len = strlen($remoteData);
+                $remoteData = substr($remoteData, $this->skipReadBytes);
+                $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
+            }
+
+            $data .= $remoteData;
+            $this->stream->write($remoteData);
+        }
+
+        return $data;
+    }
+
+    public function write($string)
+    {
+        // When appending to the end of the currently read stream, you'll want
+        // to skip bytes from being read from the remote stream to emulate
+        // other stream wrappers. Basically replacing bytes of data of a fixed
+        // length.
+        $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
+        if ($overflow > 0) {
+            $this->skipReadBytes += $overflow;
+        }
+
+        return $this->stream->write($string);
+    }
+
+    public function eof()
+    {
+        return $this->stream->eof() && $this->remoteStream->eof();
+    }
+
+    /**
+     * Close both the remote stream and buffer stream
+     */
+    public function close()
+    {
+        $this->remoteStream->close() && $this->stream->close();
+    }
+
+    private function cacheEntireStream()
+    {
+        $target = new FnStream(['write' => 'strlen']);
+        copy_to_stream($this, $target);
+
+        return $this->tell();
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/DroppingStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/DroppingStream.php
new file mode 100644 (file)
index 0000000..8935c80
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator that begins dropping data once the size of the underlying
+ * stream becomes too full.
+ */
+class DroppingStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    private $maxLength;
+
+    /**
+     * @param StreamInterface $stream    Underlying stream to decorate.
+     * @param int             $maxLength Maximum size before dropping data.
+     */
+    public function __construct(StreamInterface $stream, $maxLength)
+    {
+        $this->stream = $stream;
+        $this->maxLength = $maxLength;
+    }
+
+    public function write($string)
+    {
+        $diff = $this->maxLength - $this->stream->getSize();
+
+        // Begin returning 0 when the underlying stream is too large.
+        if ($diff <= 0) {
+            return 0;
+        }
+
+        // Write the stream or a subset of the stream if needed.
+        if (strlen($string) < $diff) {
+            return $this->stream->write($string);
+        }
+
+        return $this->stream->write(substr($string, 0, $diff));
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/FnStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/FnStream.php
new file mode 100644 (file)
index 0000000..73daea6
--- /dev/null
@@ -0,0 +1,158 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Compose stream implementations based on a hash of functions.
+ *
+ * Allows for easy testing and extension of a provided stream without needing
+ * to create a concrete class for a simple extension point.
+ */
+class FnStream implements StreamInterface
+{
+    /** @var array */
+    private $methods;
+
+    /** @var array Methods that must be implemented in the given array */
+    private static $slots = ['__toString', 'close', 'detach', 'rewind',
+        'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
+        'isReadable', 'read', 'getContents', 'getMetadata'];
+
+    /**
+     * @param array $methods Hash of method name to a callable.
+     */
+    public function __construct(array $methods)
+    {
+        $this->methods = $methods;
+
+        // Create the functions on the class
+        foreach ($methods as $name => $fn) {
+            $this->{'_fn_' . $name} = $fn;
+        }
+    }
+
+    /**
+     * Lazily determine which methods are not implemented.
+     * @throws \BadMethodCallException
+     */
+    public function __get($name)
+    {
+        throw new \BadMethodCallException(str_replace('_fn_', '', $name)
+            . '() is not implemented in the FnStream');
+    }
+
+    /**
+     * The close method is called on the underlying stream only if possible.
+     */
+    public function __destruct()
+    {
+        if (isset($this->_fn_close)) {
+            call_user_func($this->_fn_close);
+        }
+    }
+
+    /**
+     * An unserialize would allow the __destruct to run when the unserialized value goes out of scope.
+     * @throws \LogicException
+     */
+    public function __wakeup()
+    {
+        throw new \LogicException('FnStream should never be unserialized');
+    }
+
+    /**
+     * Adds custom functionality to an underlying stream by intercepting
+     * specific method calls.
+     *
+     * @param StreamInterface $stream  Stream to decorate
+     * @param array           $methods Hash of method name to a closure
+     *
+     * @return FnStream
+     */
+    public static function decorate(StreamInterface $stream, array $methods)
+    {
+        // If any of the required methods were not provided, then simply
+        // proxy to the decorated stream.
+        foreach (array_diff(self::$slots, array_keys($methods)) as $diff) {
+            $methods[$diff] = [$stream, $diff];
+        }
+
+        return new self($methods);
+    }
+
+    public function __toString()
+    {
+        return call_user_func($this->_fn___toString);
+    }
+
+    public function close()
+    {
+        return call_user_func($this->_fn_close);
+    }
+
+    public function detach()
+    {
+        return call_user_func($this->_fn_detach);
+    }
+
+    public function getSize()
+    {
+        return call_user_func($this->_fn_getSize);
+    }
+
+    public function tell()
+    {
+        return call_user_func($this->_fn_tell);
+    }
+
+    public function eof()
+    {
+        return call_user_func($this->_fn_eof);
+    }
+
+    public function isSeekable()
+    {
+        return call_user_func($this->_fn_isSeekable);
+    }
+
+    public function rewind()
+    {
+        call_user_func($this->_fn_rewind);
+    }
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        call_user_func($this->_fn_seek, $offset, $whence);
+    }
+
+    public function isWritable()
+    {
+        return call_user_func($this->_fn_isWritable);
+    }
+
+    public function write($string)
+    {
+        return call_user_func($this->_fn_write, $string);
+    }
+
+    public function isReadable()
+    {
+        return call_user_func($this->_fn_isReadable);
+    }
+
+    public function read($length)
+    {
+        return call_user_func($this->_fn_read, $length);
+    }
+
+    public function getContents()
+    {
+        return call_user_func($this->_fn_getContents);
+    }
+
+    public function getMetadata($key = null)
+    {
+        return call_user_func($this->_fn_getMetadata, $key);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/InflateStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/InflateStream.php
new file mode 100644 (file)
index 0000000..5e4f602
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
+ *
+ * This stream decorator skips the first 10 bytes of the given stream to remove
+ * the gzip header, converts the provided stream to a PHP stream resource,
+ * then appends the zlib.inflate filter. The stream is then converted back
+ * to a Guzzle stream resource to be used as a Guzzle stream.
+ *
+ * @link http://tools.ietf.org/html/rfc1952
+ * @link http://php.net/manual/en/filters.compression.php
+ */
+class InflateStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    public function __construct(StreamInterface $stream)
+    {
+        // read the first 10 bytes, ie. gzip header
+        $header = $stream->read(10);
+        $filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);
+        // Skip the header, that is 10 + length of filename + 1 (nil) bytes
+        $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
+        $resource = StreamWrapper::getResource($stream);
+        stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
+        $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource));
+    }
+
+    /**
+     * @param StreamInterface $stream
+     * @param $header
+     * @return int
+     */
+    private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
+    {
+        $filename_header_length = 0;
+
+        if (substr(bin2hex($header), 6, 2) === '08') {
+            // we have a filename, read until nil
+            $filename_header_length = 1;
+            while ($stream->read(1) !== chr(0)) {
+                $filename_header_length++;
+            }
+        }
+
+        return $filename_header_length;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/LazyOpenStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/LazyOpenStream.php
new file mode 100644 (file)
index 0000000..02cec3a
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Lazily reads or writes to a file that is opened only after an IO operation
+ * take place on the stream.
+ */
+class LazyOpenStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    /** @var string File to open */
+    private $filename;
+
+    /** @var string $mode */
+    private $mode;
+
+    /**
+     * @param string $filename File to lazily open
+     * @param string $mode     fopen mode to use when opening the stream
+     */
+    public function __construct($filename, $mode)
+    {
+        $this->filename = $filename;
+        $this->mode = $mode;
+    }
+
+    /**
+     * Creates the underlying stream lazily when required.
+     *
+     * @return StreamInterface
+     */
+    protected function createStream()
+    {
+        return stream_for(try_fopen($this->filename, $this->mode));
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/LimitStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/LimitStream.php
new file mode 100644 (file)
index 0000000..e4f239e
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+
+/**
+ * Decorator used to return only a subset of a stream
+ */
+class LimitStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    /** @var int Offset to start reading from */
+    private $offset;
+
+    /** @var int Limit the number of bytes that can be read */
+    private $limit;
+
+    /**
+     * @param StreamInterface $stream Stream to wrap
+     * @param int             $limit  Total number of bytes to allow to be read
+     *                                from the stream. Pass -1 for no limit.
+     * @param int             $offset Position to seek to before reading (only
+     *                                works on seekable streams).
+     */
+    public function __construct(
+        StreamInterface $stream,
+        $limit = -1,
+        $offset = 0
+    ) {
+        $this->stream = $stream;
+        $this->setLimit($limit);
+        $this->setOffset($offset);
+    }
+
+    public function eof()
+    {
+        // Always return true if the underlying stream is EOF
+        if ($this->stream->eof()) {
+            return true;
+        }
+
+        // No limit and the underlying stream is not at EOF
+        if ($this->limit == -1) {
+            return false;
+        }
+
+        return $this->stream->tell() >= $this->offset + $this->limit;
+    }
+
+    /**
+     * Returns the size of the limited subset of data
+     * {@inheritdoc}
+     */
+    public function getSize()
+    {
+        if (null === ($length = $this->stream->getSize())) {
+            return null;
+        } elseif ($this->limit == -1) {
+            return $length - $this->offset;
+        } else {
+            return min($this->limit, $length - $this->offset);
+        }
+    }
+
+    /**
+     * Allow for a bounded seek on the read limited stream
+     * {@inheritdoc}
+     */
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        if ($whence !== SEEK_SET || $offset < 0) {
+            throw new \RuntimeException(sprintf(
+                'Cannot seek to offset %s with whence %s',
+                $offset,
+                $whence
+            ));
+        }
+
+        $offset += $this->offset;
+
+        if ($this->limit !== -1) {
+            if ($offset > $this->offset + $this->limit) {
+                $offset = $this->offset + $this->limit;
+            }
+        }
+
+        $this->stream->seek($offset);
+    }
+
+    /**
+     * Give a relative tell()
+     * {@inheritdoc}
+     */
+    public function tell()
+    {
+        return $this->stream->tell() - $this->offset;
+    }
+
+    /**
+     * Set the offset to start limiting from
+     *
+     * @param int $offset Offset to seek to and begin byte limiting from
+     *
+     * @throws \RuntimeException if the stream cannot be seeked.
+     */
+    public function setOffset($offset)
+    {
+        $current = $this->stream->tell();
+
+        if ($current !== $offset) {
+            // If the stream cannot seek to the offset position, then read to it
+            if ($this->stream->isSeekable()) {
+                $this->stream->seek($offset);
+            } elseif ($current > $offset) {
+                throw new \RuntimeException("Could not seek to stream offset $offset");
+            } else {
+                $this->stream->read($offset - $current);
+            }
+        }
+
+        $this->offset = $offset;
+    }
+
+    /**
+     * Set the limit of bytes that the decorator allows to be read from the
+     * stream.
+     *
+     * @param int $limit Number of bytes to allow to be read from the stream.
+     *                   Use -1 for no limit.
+     */
+    public function setLimit($limit)
+    {
+        $this->limit = $limit;
+    }
+
+    public function read($length)
+    {
+        if ($this->limit == -1) {
+            return $this->stream->read($length);
+        }
+
+        // Check if the current position is less than the total allowed
+        // bytes + original offset
+        $remaining = ($this->offset + $this->limit) - $this->stream->tell();
+        if ($remaining > 0) {
+            // Only return the amount of requested data, ensuring that the byte
+            // limit is not exceeded
+            return $this->stream->read(min($remaining, $length));
+        }
+
+        return '';
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MessageTrait.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MessageTrait.php
new file mode 100644 (file)
index 0000000..a7966d1
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Trait implementing functionality common to requests and responses.
+ */
+trait MessageTrait
+{
+    /** @var array Map of all registered headers, as original name => array of values */
+    private $headers = [];
+
+    /** @var array Map of lowercase header name => original name at registration */
+    private $headerNames  = [];
+
+    /** @var string */
+    private $protocol = '1.1';
+
+    /** @var StreamInterface */
+    private $stream;
+
+    public function getProtocolVersion()
+    {
+        return $this->protocol;
+    }
+
+    public function withProtocolVersion($version)
+    {
+        if ($this->protocol === $version) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->protocol = $version;
+        return $new;
+    }
+
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+
+    public function hasHeader($header)
+    {
+        return isset($this->headerNames[strtolower($header)]);
+    }
+
+    public function getHeader($header)
+    {
+        $header = strtolower($header);
+
+        if (!isset($this->headerNames[$header])) {
+            return [];
+        }
+
+        $header = $this->headerNames[$header];
+
+        return $this->headers[$header];
+    }
+
+    public function getHeaderLine($header)
+    {
+        return implode(', ', $this->getHeader($header));
+    }
+
+    public function withHeader($header, $value)
+    {
+        $this->assertHeader($header);
+        $value = $this->normalizeHeaderValue($value);
+        $normalized = strtolower($header);
+
+        $new = clone $this;
+        if (isset($new->headerNames[$normalized])) {
+            unset($new->headers[$new->headerNames[$normalized]]);
+        }
+        $new->headerNames[$normalized] = $header;
+        $new->headers[$header] = $value;
+
+        return $new;
+    }
+
+    public function withAddedHeader($header, $value)
+    {
+        $this->assertHeader($header);
+        $value = $this->normalizeHeaderValue($value);
+        $normalized = strtolower($header);
+
+        $new = clone $this;
+        if (isset($new->headerNames[$normalized])) {
+            $header = $this->headerNames[$normalized];
+            $new->headers[$header] = array_merge($this->headers[$header], $value);
+        } else {
+            $new->headerNames[$normalized] = $header;
+            $new->headers[$header] = $value;
+        }
+
+        return $new;
+    }
+
+    public function withoutHeader($header)
+    {
+        $normalized = strtolower($header);
+
+        if (!isset($this->headerNames[$normalized])) {
+            return $this;
+        }
+
+        $header = $this->headerNames[$normalized];
+
+        $new = clone $this;
+        unset($new->headers[$header], $new->headerNames[$normalized]);
+
+        return $new;
+    }
+
+    public function getBody()
+    {
+        if (!$this->stream) {
+            $this->stream = stream_for('');
+        }
+
+        return $this->stream;
+    }
+
+    public function withBody(StreamInterface $body)
+    {
+        if ($body === $this->stream) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->stream = $body;
+        return $new;
+    }
+
+    private function setHeaders(array $headers)
+    {
+        $this->headerNames = $this->headers = [];
+        foreach ($headers as $header => $value) {
+            if (is_int($header)) {
+                // Numeric array keys are converted to int by PHP but having a header name '123' is not forbidden by the spec
+                // and also allowed in withHeader(). So we need to cast it to string again for the following assertion to pass.
+                $header = (string) $header;
+            }
+            $this->assertHeader($header);
+            $value = $this->normalizeHeaderValue($value);
+            $normalized = strtolower($header);
+            if (isset($this->headerNames[$normalized])) {
+                $header = $this->headerNames[$normalized];
+                $this->headers[$header] = array_merge($this->headers[$header], $value);
+            } else {
+                $this->headerNames[$normalized] = $header;
+                $this->headers[$header] = $value;
+            }
+        }
+    }
+
+    private function normalizeHeaderValue($value)
+    {
+        if (!is_array($value)) {
+            return $this->trimHeaderValues([$value]);
+        }
+
+        if (count($value) === 0) {
+            throw new \InvalidArgumentException('Header value can not be an empty array.');
+        }
+
+        return $this->trimHeaderValues($value);
+    }
+
+    /**
+     * Trims whitespace from the header values.
+     *
+     * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
+     *
+     * header-field = field-name ":" OWS field-value OWS
+     * OWS          = *( SP / HTAB )
+     *
+     * @param string[] $values Header values
+     *
+     * @return string[] Trimmed header values
+     *
+     * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
+     */
+    private function trimHeaderValues(array $values)
+    {
+        return array_map(function ($value) {
+            if (!is_scalar($value) && null !== $value) {
+                throw new \InvalidArgumentException(sprintf(
+                    'Header value must be scalar or null but %s provided.',
+                    is_object($value) ? get_class($value) : gettype($value)
+                ));
+            }
+
+            return trim((string) $value, " \t");
+        }, $values);
+    }
+
+    private function assertHeader($header)
+    {
+        if (!is_string($header)) {
+            throw new \InvalidArgumentException(sprintf(
+                'Header name must be a string but %s provided.',
+                is_object($header) ? get_class($header) : gettype($header)
+            ));
+        }
+
+        if ($header === '') {
+            throw new \InvalidArgumentException('Header name can not be empty.');
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MultipartStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/MultipartStream.php
new file mode 100644 (file)
index 0000000..c0fd584
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream that when read returns bytes for a streaming multipart or
+ * multipart/form-data stream.
+ */
+class MultipartStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    private $boundary;
+
+    /**
+     * @param array  $elements Array of associative arrays, each containing a
+     *                         required "name" key mapping to the form field,
+     *                         name, a required "contents" key mapping to a
+     *                         StreamInterface/resource/string, an optional
+     *                         "headers" associative array of custom headers,
+     *                         and an optional "filename" key mapping to a
+     *                         string to send as the filename in the part.
+     * @param string $boundary You can optionally provide a specific boundary
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function __construct(array $elements = [], $boundary = null)
+    {
+        $this->boundary = $boundary ?: sha1(uniqid('', true));
+        $this->stream = $this->createStream($elements);
+    }
+
+    /**
+     * Get the boundary
+     *
+     * @return string
+     */
+    public function getBoundary()
+    {
+        return $this->boundary;
+    }
+
+    public function isWritable()
+    {
+        return false;
+    }
+
+    /**
+     * Get the headers needed before transferring the content of a POST file
+     */
+    private function getHeaders(array $headers)
+    {
+        $str = '';
+        foreach ($headers as $key => $value) {
+            $str .= "{$key}: {$value}\r\n";
+        }
+
+        return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n";
+    }
+
+    /**
+     * Create the aggregate stream that will be used to upload the POST data
+     */
+    protected function createStream(array $elements)
+    {
+        $stream = new AppendStream();
+
+        foreach ($elements as $element) {
+            $this->addElement($stream, $element);
+        }
+
+        // Add the trailing boundary with CRLF
+        $stream->addStream(stream_for("--{$this->boundary}--\r\n"));
+
+        return $stream;
+    }
+
+    private function addElement(AppendStream $stream, array $element)
+    {
+        foreach (['contents', 'name'] as $key) {
+            if (!array_key_exists($key, $element)) {
+                throw new \InvalidArgumentException("A '{$key}' key is required");
+            }
+        }
+
+        $element['contents'] = stream_for($element['contents']);
+
+        if (empty($element['filename'])) {
+            $uri = $element['contents']->getMetadata('uri');
+            if (substr($uri, 0, 6) !== 'php://') {
+                $element['filename'] = $uri;
+            }
+        }
+
+        list($body, $headers) = $this->createElement(
+            $element['name'],
+            $element['contents'],
+            isset($element['filename']) ? $element['filename'] : null,
+            isset($element['headers']) ? $element['headers'] : []
+        );
+
+        $stream->addStream(stream_for($this->getHeaders($headers)));
+        $stream->addStream($body);
+        $stream->addStream(stream_for("\r\n"));
+    }
+
+    /**
+     * @return array
+     */
+    private function createElement($name, StreamInterface $stream, $filename, array $headers)
+    {
+        // Set a default content-disposition header if one was no provided
+        $disposition = $this->getHeader($headers, 'content-disposition');
+        if (!$disposition) {
+            $headers['Content-Disposition'] = ($filename === '0' || $filename)
+                ? sprintf('form-data; name="%s"; filename="%s"',
+                    $name,
+                    basename($filename))
+                : "form-data; name=\"{$name}\"";
+        }
+
+        // Set a default content-length header if one was no provided
+        $length = $this->getHeader($headers, 'content-length');
+        if (!$length) {
+            if ($length = $stream->getSize()) {
+                $headers['Content-Length'] = (string) $length;
+            }
+        }
+
+        // Set a default Content-Type if one was not supplied
+        $type = $this->getHeader($headers, 'content-type');
+        if (!$type && ($filename === '0' || $filename)) {
+            if ($type = mimetype_from_filename($filename)) {
+                $headers['Content-Type'] = $type;
+            }
+        }
+
+        return [$stream, $headers];
+    }
+
+    private function getHeader(array $headers, $key)
+    {
+        $lowercaseHeader = strtolower($key);
+        foreach ($headers as $k => $v) {
+            if (strtolower($k) === $lowercaseHeader) {
+                return $v;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/NoSeekStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/NoSeekStream.php
new file mode 100644 (file)
index 0000000..2332218
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator that prevents a stream from being seeked
+ */
+class NoSeekStream implements StreamInterface
+{
+    use StreamDecoratorTrait;
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        throw new \RuntimeException('Cannot seek a NoSeekStream');
+    }
+
+    public function isSeekable()
+    {
+        return false;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/PumpStream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/PumpStream.php
new file mode 100644 (file)
index 0000000..ffb5440
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Provides a read only stream that pumps data from a PHP callable.
+ *
+ * When invoking the provided callable, the PumpStream will pass the amount of
+ * data requested to read to the callable. The callable can choose to ignore
+ * this value and return fewer or more bytes than requested. Any extra data
+ * returned by the provided callable is buffered internally until drained using
+ * the read() function of the PumpStream. The provided callable MUST return
+ * false when there is no more data to read.
+ */
+class PumpStream implements StreamInterface
+{
+    /** @var callable */
+    private $source;
+
+    /** @var int */
+    private $size;
+
+    /** @var int */
+    private $tellPos = 0;
+
+    /** @var array */
+    private $metadata;
+
+    /** @var BufferStream */
+    private $buffer;
+
+    /**
+     * @param callable $source Source of the stream data. The callable MAY
+     *                         accept an integer argument used to control the
+     *                         amount of data to return. The callable MUST
+     *                         return a string when called, or false on error
+     *                         or EOF.
+     * @param array $options   Stream options:
+     *                         - metadata: Hash of metadata to use with stream.
+     *                         - size: Size of the stream, if known.
+     */
+    public function __construct(callable $source, array $options = [])
+    {
+        $this->source = $source;
+        $this->size = isset($options['size']) ? $options['size'] : null;
+        $this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
+        $this->buffer = new BufferStream();
+    }
+
+    public function __toString()
+    {
+        try {
+            return copy_to_string($this);
+        } catch (\Exception $e) {
+            return '';
+        }
+    }
+
+    public function close()
+    {
+        $this->detach();
+    }
+
+    public function detach()
+    {
+        $this->tellPos = false;
+        $this->source = null;
+    }
+
+    public function getSize()
+    {
+        return $this->size;
+    }
+
+    public function tell()
+    {
+        return $this->tellPos;
+    }
+
+    public function eof()
+    {
+        return !$this->source;
+    }
+
+    public function isSeekable()
+    {
+        return false;
+    }
+
+    public function rewind()
+    {
+        $this->seek(0);
+    }
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        throw new \RuntimeException('Cannot seek a PumpStream');
+    }
+
+    public function isWritable()
+    {
+        return false;
+    }
+
+    public function write($string)
+    {
+        throw new \RuntimeException('Cannot write to a PumpStream');
+    }
+
+    public function isReadable()
+    {
+        return true;
+    }
+
+    public function read($length)
+    {
+        $data = $this->buffer->read($length);
+        $readLen = strlen($data);
+        $this->tellPos += $readLen;
+        $remaining = $length - $readLen;
+
+        if ($remaining) {
+            $this->pump($remaining);
+            $data .= $this->buffer->read($remaining);
+            $this->tellPos += strlen($data) - $readLen;
+        }
+
+        return $data;
+    }
+
+    public function getContents()
+    {
+        $result = '';
+        while (!$this->eof()) {
+            $result .= $this->read(1000000);
+        }
+
+        return $result;
+    }
+
+    public function getMetadata($key = null)
+    {
+        if (!$key) {
+            return $this->metadata;
+        }
+
+        return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
+    }
+
+    private function pump($length)
+    {
+        if ($this->source) {
+            do {
+                $data = call_user_func($this->source, $length);
+                if ($data === false || $data === null) {
+                    $this->source = null;
+                    return;
+                }
+                $this->buffer->write($data);
+                $length -= strlen($data);
+            } while ($length > 0);
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Request.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Request.php
new file mode 100644 (file)
index 0000000..59f337d
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use InvalidArgumentException;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * PSR-7 request implementation.
+ */
+class Request implements RequestInterface
+{
+    use MessageTrait;
+
+    /** @var string */
+    private $method;
+
+    /** @var null|string */
+    private $requestTarget;
+
+    /** @var UriInterface */
+    private $uri;
+
+    /**
+     * @param string                               $method  HTTP method
+     * @param string|UriInterface                  $uri     URI
+     * @param array                                $headers Request headers
+     * @param string|null|resource|StreamInterface $body    Request body
+     * @param string                               $version Protocol version
+     */
+    public function __construct(
+        $method,
+        $uri,
+        array $headers = [],
+        $body = null,
+        $version = '1.1'
+    ) {
+        $this->assertMethod($method);
+        if (!($uri instanceof UriInterface)) {
+            $uri = new Uri($uri);
+        }
+
+        $this->method = strtoupper($method);
+        $this->uri = $uri;
+        $this->setHeaders($headers);
+        $this->protocol = $version;
+
+        if (!isset($this->headerNames['host'])) {
+            $this->updateHostFromUri();
+        }
+
+        if ($body !== '' && $body !== null) {
+            $this->stream = stream_for($body);
+        }
+    }
+
+    public function getRequestTarget()
+    {
+        if ($this->requestTarget !== null) {
+            return $this->requestTarget;
+        }
+
+        $target = $this->uri->getPath();
+        if ($target == '') {
+            $target = '/';
+        }
+        if ($this->uri->getQuery() != '') {
+            $target .= '?' . $this->uri->getQuery();
+        }
+
+        return $target;
+    }
+
+    public function withRequestTarget($requestTarget)
+    {
+        if (preg_match('#\s#', $requestTarget)) {
+            throw new InvalidArgumentException(
+                'Invalid request target provided; cannot contain whitespace'
+            );
+        }
+
+        $new = clone $this;
+        $new->requestTarget = $requestTarget;
+        return $new;
+    }
+
+    public function getMethod()
+    {
+        return $this->method;
+    }
+
+    public function withMethod($method)
+    {
+        $this->assertMethod($method);
+        $new = clone $this;
+        $new->method = strtoupper($method);
+        return $new;
+    }
+
+    public function getUri()
+    {
+        return $this->uri;
+    }
+
+    public function withUri(UriInterface $uri, $preserveHost = false)
+    {
+        if ($uri === $this->uri) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->uri = $uri;
+
+        if (!$preserveHost || !isset($this->headerNames['host'])) {
+            $new->updateHostFromUri();
+        }
+
+        return $new;
+    }
+
+    private function updateHostFromUri()
+    {
+        $host = $this->uri->getHost();
+
+        if ($host == '') {
+            return;
+        }
+
+        if (($port = $this->uri->getPort()) !== null) {
+            $host .= ':' . $port;
+        }
+
+        if (isset($this->headerNames['host'])) {
+            $header = $this->headerNames['host'];
+        } else {
+            $header = 'Host';
+            $this->headerNames['host'] = 'Host';
+        }
+        // Ensure Host is the first header.
+        // See: http://tools.ietf.org/html/rfc7230#section-5.4
+        $this->headers = [$header => [$host]] + $this->headers;
+    }
+
+    private function assertMethod($method)
+    {
+        if (!is_string($method) || $method === '') {
+            throw new \InvalidArgumentException('Method must be a non-empty string.');
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Response.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Response.php
new file mode 100644 (file)
index 0000000..e7e04d8
--- /dev/null
@@ -0,0 +1,154 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * PSR-7 response implementation.
+ */
+class Response implements ResponseInterface
+{
+    use MessageTrait;
+
+    /** @var array Map of standard HTTP status code/reason phrases */
+    private static $phrases = [
+        100 => 'Continue',
+        101 => 'Switching Protocols',
+        102 => 'Processing',
+        200 => 'OK',
+        201 => 'Created',
+        202 => 'Accepted',
+        203 => 'Non-Authoritative Information',
+        204 => 'No Content',
+        205 => 'Reset Content',
+        206 => 'Partial Content',
+        207 => 'Multi-status',
+        208 => 'Already Reported',
+        300 => 'Multiple Choices',
+        301 => 'Moved Permanently',
+        302 => 'Found',
+        303 => 'See Other',
+        304 => 'Not Modified',
+        305 => 'Use Proxy',
+        306 => 'Switch Proxy',
+        307 => 'Temporary Redirect',
+        400 => 'Bad Request',
+        401 => 'Unauthorized',
+        402 => 'Payment Required',
+        403 => 'Forbidden',
+        404 => 'Not Found',
+        405 => 'Method Not Allowed',
+        406 => 'Not Acceptable',
+        407 => 'Proxy Authentication Required',
+        408 => 'Request Time-out',
+        409 => 'Conflict',
+        410 => 'Gone',
+        411 => 'Length Required',
+        412 => 'Precondition Failed',
+        413 => 'Request Entity Too Large',
+        414 => 'Request-URI Too Large',
+        415 => 'Unsupported Media Type',
+        416 => 'Requested range not satisfiable',
+        417 => 'Expectation Failed',
+        418 => 'I\'m a teapot',
+        422 => 'Unprocessable Entity',
+        423 => 'Locked',
+        424 => 'Failed Dependency',
+        425 => 'Unordered Collection',
+        426 => 'Upgrade Required',
+        428 => 'Precondition Required',
+        429 => 'Too Many Requests',
+        431 => 'Request Header Fields Too Large',
+        451 => 'Unavailable For Legal Reasons',
+        500 => 'Internal Server Error',
+        501 => 'Not Implemented',
+        502 => 'Bad Gateway',
+        503 => 'Service Unavailable',
+        504 => 'Gateway Time-out',
+        505 => 'HTTP Version not supported',
+        506 => 'Variant Also Negotiates',
+        507 => 'Insufficient Storage',
+        508 => 'Loop Detected',
+        511 => 'Network Authentication Required',
+    ];
+
+    /** @var string */
+    private $reasonPhrase = '';
+
+    /** @var int */
+    private $statusCode = 200;
+
+    /**
+     * @param int                                  $status  Status code
+     * @param array                                $headers Response headers
+     * @param string|null|resource|StreamInterface $body    Response body
+     * @param string                               $version Protocol version
+     * @param string|null                          $reason  Reason phrase (when empty a default will be used based on the status code)
+     */
+    public function __construct(
+        $status = 200,
+        array $headers = [],
+        $body = null,
+        $version = '1.1',
+        $reason = null
+    ) {
+        $this->assertStatusCodeIsInteger($status);
+        $status = (int) $status;
+        $this->assertStatusCodeRange($status);
+
+        $this->statusCode = $status;
+
+        if ($body !== '' && $body !== null) {
+            $this->stream = stream_for($body);
+        }
+
+        $this->setHeaders($headers);
+        if ($reason == '' && isset(self::$phrases[$this->statusCode])) {
+            $this->reasonPhrase = self::$phrases[$this->statusCode];
+        } else {
+            $this->reasonPhrase = (string) $reason;
+        }
+
+        $this->protocol = $version;
+    }
+
+    public function getStatusCode()
+    {
+        return $this->statusCode;
+    }
+
+    public function getReasonPhrase()
+    {
+        return $this->reasonPhrase;
+    }
+
+    public function withStatus($code, $reasonPhrase = '')
+    {
+        $this->assertStatusCodeIsInteger($code);
+        $code = (int) $code;
+        $this->assertStatusCodeRange($code);
+
+        $new = clone $this;
+        $new->statusCode = $code;
+        if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) {
+            $reasonPhrase = self::$phrases[$new->statusCode];
+        }
+        $new->reasonPhrase = $reasonPhrase;
+        return $new;
+    }
+
+    private function assertStatusCodeIsInteger($statusCode)
+    {
+        if (filter_var($statusCode, FILTER_VALIDATE_INT) === false) {
+            throw new \InvalidArgumentException('Status code must be an integer value.');
+        }
+    }
+
+    private function assertStatusCodeRange($statusCode)
+    {
+        if ($statusCode < 100 || $statusCode >= 600) {
+            throw new \InvalidArgumentException('Status code must be an integer value between 1xx and 5xx.');
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Rfc7230.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Rfc7230.php
new file mode 100644 (file)
index 0000000..505e474
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+namespace GuzzleHttp\Psr7;
+
+final class Rfc7230
+{
+    /**
+     * Header related regular expressions (copied from amphp/http package)
+     * (Note: once we require PHP 7.x we could just depend on the upstream package)
+     *
+     * Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons.
+     *
+     * @link    https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15
+     * @license https://github.com/amphp/http/blob/v1.0.1/LICENSE
+     */
+    const HEADER_REGEX = "(^([^()<>@,;:\\\"/[\]?={}\x01-\x20\x7F]++):[ \t]*+((?:[ \t]*+[\x21-\x7E\x80-\xFF]++)*+)[ \t]*+\r?\n)m";
+    const HEADER_FOLD_REGEX = "(\r?\n[ \t]++)";
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/ServerRequest.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/ServerRequest.php
new file mode 100644 (file)
index 0000000..1a09a6c
--- /dev/null
@@ -0,0 +1,376 @@
+<?php
+
+namespace GuzzleHttp\Psr7;
+
+use InvalidArgumentException;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\UriInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UploadedFileInterface;
+
+/**
+ * Server-side HTTP request
+ *
+ * Extends the Request definition to add methods for accessing incoming data,
+ * specifically server parameters, cookies, matched path parameters, query
+ * string arguments, body parameters, and upload file information.
+ *
+ * "Attributes" are discovered via decomposing the request (and usually
+ * specifically the URI path), and typically will be injected by the application.
+ *
+ * Requests are considered immutable; all methods that might change state are
+ * implemented such that they retain the internal state of the current
+ * message and return a new instance that contains the changed state.
+ */
+class ServerRequest extends Request implements ServerRequestInterface
+{
+    /**
+     * @var array
+     */
+    private $attributes = [];
+
+    /**
+     * @var array
+     */
+    private $cookieParams = [];
+
+    /**
+     * @var null|array|object
+     */
+    private $parsedBody;
+
+    /**
+     * @var array
+     */
+    private $queryParams = [];
+
+    /**
+     * @var array
+     */
+    private $serverParams;
+
+    /**
+     * @var array
+     */
+    private $uploadedFiles = [];
+
+    /**
+     * @param string                               $method       HTTP method
+     * @param string|UriInterface                  $uri          URI
+     * @param array                                $headers      Request headers
+     * @param string|null|resource|StreamInterface $body         Request body
+     * @param string                               $version      Protocol version
+     * @param array                                $serverParams Typically the $_SERVER superglobal
+     */
+    public function __construct(
+        $method,
+        $uri,
+        array $headers = [],
+        $body = null,
+        $version = '1.1',
+        array $serverParams = []
+    ) {
+        $this->serverParams = $serverParams;
+
+        parent::__construct($method, $uri, $headers, $body, $version);
+    }
+
+    /**
+     * Return an UploadedFile instance array.
+     *
+     * @param array $files A array which respect $_FILES structure
+     * @throws InvalidArgumentException for unrecognized values
+     * @return array
+     */
+    public static function normalizeFiles(array $files)
+    {
+        $normalized = [];
+
+        foreach ($files as $key => $value) {
+            if ($value instanceof UploadedFileInterface) {
+                $normalized[$key] = $value;
+            } elseif (is_array($value) && isset($value['tmp_name'])) {
+                $normalized[$key] = self::createUploadedFileFromSpec($value);
+            } elseif (is_array($value)) {
+                $normalized[$key] = self::normalizeFiles($value);
+                continue;
+            } else {
+                throw new InvalidArgumentException('Invalid value in files specification');
+            }
+        }
+
+        return $normalized;
+    }
+
+    /**
+     * Create and return an UploadedFile instance from a $_FILES specification.
+     *
+     * If the specification represents an array of values, this method will
+     * delegate to normalizeNestedFileSpec() and return that return value.
+     *
+     * @param array $value $_FILES struct
+     * @return array|UploadedFileInterface
+     */
+    private static function createUploadedFileFromSpec(array $value)
+    {
+        if (is_array($value['tmp_name'])) {
+            return self::normalizeNestedFileSpec($value);
+        }
+
+        return new UploadedFile(
+            $value['tmp_name'],
+            (int) $value['size'],
+            (int) $value['error'],
+            $value['name'],
+            $value['type']
+        );
+    }
+
+    /**
+     * Normalize an array of file specifications.
+     *
+     * Loops through all nested files and returns a normalized array of
+     * UploadedFileInterface instances.
+     *
+     * @param array $files
+     * @return UploadedFileInterface[]
+     */
+    private static function normalizeNestedFileSpec(array $files = [])
+    {
+        $normalizedFiles = [];
+
+        foreach (array_keys($files['tmp_name']) as $key) {
+            $spec = [
+                'tmp_name' => $files['tmp_name'][$key],
+                'size'     => $files['size'][$key],
+                'error'    => $files['error'][$key],
+                'name'     => $files['name'][$key],
+                'type'     => $files['type'][$key],
+            ];
+            $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
+        }
+
+        return $normalizedFiles;
+    }
+
+    /**
+     * Return a ServerRequest populated with superglobals:
+     * $_GET
+     * $_POST
+     * $_COOKIE
+     * $_FILES
+     * $_SERVER
+     *
+     * @return ServerRequestInterface
+     */
+    public static function fromGlobals()
+    {
+        $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
+        $headers = getallheaders();
+        $uri = self::getUriFromGlobals();
+        $body = new CachingStream(new LazyOpenStream('php://input', 'r+'));
+        $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
+
+        $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
+
+        return $serverRequest
+            ->withCookieParams($_COOKIE)
+            ->withQueryParams($_GET)
+            ->withParsedBody($_POST)
+            ->withUploadedFiles(self::normalizeFiles($_FILES));
+    }
+
+    private static function extractHostAndPortFromAuthority($authority)
+    {
+        $uri = 'http://'.$authority;
+        $parts = parse_url($uri);
+        if (false === $parts) {
+            return [null, null];
+        }
+
+        $host = isset($parts['host']) ? $parts['host'] : null;
+        $port = isset($parts['port']) ? $parts['port'] : null;
+
+        return [$host, $port];
+    }
+
+    /**
+     * Get a Uri populated with values from $_SERVER.
+     *
+     * @return UriInterface
+     */
+    public static function getUriFromGlobals()
+    {
+        $uri = new Uri('');
+
+        $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
+
+        $hasPort = false;
+        if (isset($_SERVER['HTTP_HOST'])) {
+            list($host, $port) = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
+            if ($host !== null) {
+                $uri = $uri->withHost($host);
+            }
+
+            if ($port !== null) {
+                $hasPort = true;
+                $uri = $uri->withPort($port);
+            }
+        } elseif (isset($_SERVER['SERVER_NAME'])) {
+            $uri = $uri->withHost($_SERVER['SERVER_NAME']);
+        } elseif (isset($_SERVER['SERVER_ADDR'])) {
+            $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
+        }
+
+        if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
+            $uri = $uri->withPort($_SERVER['SERVER_PORT']);
+        }
+
+        $hasQuery = false;
+        if (isset($_SERVER['REQUEST_URI'])) {
+            $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2);
+            $uri = $uri->withPath($requestUriParts[0]);
+            if (isset($requestUriParts[1])) {
+                $hasQuery = true;
+                $uri = $uri->withQuery($requestUriParts[1]);
+            }
+        }
+
+        if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
+            $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
+        }
+
+        return $uri;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getServerParams()
+    {
+        return $this->serverParams;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getUploadedFiles()
+    {
+        return $this->uploadedFiles;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withUploadedFiles(array $uploadedFiles)
+    {
+        $new = clone $this;
+        $new->uploadedFiles = $uploadedFiles;
+
+        return $new;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCookieParams()
+    {
+        return $this->cookieParams;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withCookieParams(array $cookies)
+    {
+        $new = clone $this;
+        $new->cookieParams = $cookies;
+
+        return $new;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getQueryParams()
+    {
+        return $this->queryParams;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withQueryParams(array $query)
+    {
+        $new = clone $this;
+        $new->queryParams = $query;
+
+        return $new;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getParsedBody()
+    {
+        return $this->parsedBody;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withParsedBody($data)
+    {
+        $new = clone $this;
+        $new->parsedBody = $data;
+
+        return $new;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAttributes()
+    {
+        return $this->attributes;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAttribute($attribute, $default = null)
+    {
+        if (false === array_key_exists($attribute, $this->attributes)) {
+            return $default;
+        }
+
+        return $this->attributes[$attribute];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withAttribute($attribute, $value)
+    {
+        $new = clone $this;
+        $new->attributes[$attribute] = $value;
+
+        return $new;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withoutAttribute($attribute)
+    {
+        if (false === array_key_exists($attribute, $this->attributes)) {
+            return $this;
+        }
+
+        $new = clone $this;
+        unset($new->attributes[$attribute]);
+
+        return $new;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Stream.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Stream.php
new file mode 100644 (file)
index 0000000..d9e7409
--- /dev/null
@@ -0,0 +1,267 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * PHP stream implementation.
+ *
+ * @var $stream
+ */
+class Stream implements StreamInterface
+{
+    /**
+     * Resource modes.
+     *
+     * @var string
+     *
+     * @see http://php.net/manual/function.fopen.php
+     * @see http://php.net/manual/en/function.gzopen.php
+     */
+    const READABLE_MODES = '/r|a\+|ab\+|w\+|wb\+|x\+|xb\+|c\+|cb\+/';
+    const WRITABLE_MODES = '/a|w|r\+|rb\+|rw|x|c/';
+
+    private $stream;
+    private $size;
+    private $seekable;
+    private $readable;
+    private $writable;
+    private $uri;
+    private $customMetadata;
+
+    /**
+     * This constructor accepts an associative array of options.
+     *
+     * - size: (int) If a read stream would otherwise have an indeterminate
+     *   size, but the size is known due to foreknowledge, then you can
+     *   provide that size, in bytes.
+     * - metadata: (array) Any additional metadata to return when the metadata
+     *   of the stream is accessed.
+     *
+     * @param resource $stream  Stream resource to wrap.
+     * @param array    $options Associative array of options.
+     *
+     * @throws \InvalidArgumentException if the stream is not a stream resource
+     */
+    public function __construct($stream, $options = [])
+    {
+        if (!is_resource($stream)) {
+            throw new \InvalidArgumentException('Stream must be a resource');
+        }
+
+        if (isset($options['size'])) {
+            $this->size = $options['size'];
+        }
+
+        $this->customMetadata = isset($options['metadata'])
+            ? $options['metadata']
+            : [];
+
+        $this->stream = $stream;
+        $meta = stream_get_meta_data($this->stream);
+        $this->seekable = $meta['seekable'];
+        $this->readable = (bool)preg_match(self::READABLE_MODES, $meta['mode']);
+        $this->writable = (bool)preg_match(self::WRITABLE_MODES, $meta['mode']);
+        $this->uri = $this->getMetadata('uri');
+    }
+
+    /**
+     * Closes the stream when the destructed
+     */
+    public function __destruct()
+    {
+        $this->close();
+    }
+
+    public function __toString()
+    {
+        try {
+            $this->seek(0);
+            return (string) stream_get_contents($this->stream);
+        } catch (\Exception $e) {
+            return '';
+        }
+    }
+
+    public function getContents()
+    {
+        if (!isset($this->stream)) {
+            throw new \RuntimeException('Stream is detached');
+        }
+
+        $contents = stream_get_contents($this->stream);
+
+        if ($contents === false) {
+            throw new \RuntimeException('Unable to read stream contents');
+        }
+
+        return $contents;
+    }
+
+    public function close()
+    {
+        if (isset($this->stream)) {
+            if (is_resource($this->stream)) {
+                fclose($this->stream);
+            }
+            $this->detach();
+        }
+    }
+
+    public function detach()
+    {
+        if (!isset($this->stream)) {
+            return null;
+        }
+
+        $result = $this->stream;
+        unset($this->stream);
+        $this->size = $this->uri = null;
+        $this->readable = $this->writable = $this->seekable = false;
+
+        return $result;
+    }
+
+    public function getSize()
+    {
+        if ($this->size !== null) {
+            return $this->size;
+        }
+
+        if (!isset($this->stream)) {
+            return null;
+        }
+
+        // Clear the stat cache if the stream has a URI
+        if ($this->uri) {
+            clearstatcache(true, $this->uri);
+        }
+
+        $stats = fstat($this->stream);
+        if (isset($stats['size'])) {
+            $this->size = $stats['size'];
+            return $this->size;
+        }
+
+        return null;
+    }
+
+    public function isReadable()
+    {
+        return $this->readable;
+    }
+
+    public function isWritable()
+    {
+        return $this->writable;
+    }
+
+    public function isSeekable()
+    {
+        return $this->seekable;
+    }
+
+    public function eof()
+    {
+        if (!isset($this->stream)) {
+            throw new \RuntimeException('Stream is detached');
+        }
+
+        return feof($this->stream);
+    }
+
+    public function tell()
+    {
+        if (!isset($this->stream)) {
+            throw new \RuntimeException('Stream is detached');
+        }
+
+        $result = ftell($this->stream);
+
+        if ($result === false) {
+            throw new \RuntimeException('Unable to determine stream position');
+        }
+
+        return $result;
+    }
+
+    public function rewind()
+    {
+        $this->seek(0);
+    }
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        $whence = (int) $whence;
+        
+        if (!isset($this->stream)) {
+            throw new \RuntimeException('Stream is detached');
+        }
+        if (!$this->seekable) {
+            throw new \RuntimeException('Stream is not seekable');
+        }
+        if (fseek($this->stream, $offset, $whence) === -1) {
+            throw new \RuntimeException('Unable to seek to stream position '
+                . $offset . ' with whence ' . var_export($whence, true));
+        }
+    }
+
+    public function read($length)
+    {
+        if (!isset($this->stream)) {
+            throw new \RuntimeException('Stream is detached');
+        }
+        if (!$this->readable) {
+            throw new \RuntimeException('Cannot read from non-readable stream');
+        }
+        if ($length < 0) {
+            throw new \RuntimeException('Length parameter cannot be negative');
+        }
+
+        if (0 === $length) {
+            return '';
+        }
+
+        $string = fread($this->stream, $length);
+        if (false === $string) {
+            throw new \RuntimeException('Unable to read from stream');
+        }
+
+        return $string;
+    }
+
+    public function write($string)
+    {
+        if (!isset($this->stream)) {
+            throw new \RuntimeException('Stream is detached');
+        }
+        if (!$this->writable) {
+            throw new \RuntimeException('Cannot write to a non-writable stream');
+        }
+
+        // We can't know the size after writing anything
+        $this->size = null;
+        $result = fwrite($this->stream, $string);
+
+        if ($result === false) {
+            throw new \RuntimeException('Unable to write to stream');
+        }
+
+        return $result;
+    }
+
+    public function getMetadata($key = null)
+    {
+        if (!isset($this->stream)) {
+            return $key ? null : [];
+        } elseif (!$key) {
+            return $this->customMetadata + stream_get_meta_data($this->stream);
+        } elseif (isset($this->customMetadata[$key])) {
+            return $this->customMetadata[$key];
+        }
+
+        $meta = stream_get_meta_data($this->stream);
+
+        return isset($meta[$key]) ? $meta[$key] : null;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/StreamDecoratorTrait.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/StreamDecoratorTrait.php
new file mode 100644 (file)
index 0000000..daec6f5
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Stream decorator trait
+ * @property StreamInterface stream
+ */
+trait StreamDecoratorTrait
+{
+    /**
+     * @param StreamInterface $stream Stream to decorate
+     */
+    public function __construct(StreamInterface $stream)
+    {
+        $this->stream = $stream;
+    }
+
+    /**
+     * Magic method used to create a new stream if streams are not added in
+     * the constructor of a decorator (e.g., LazyOpenStream).
+     *
+     * @param string $name Name of the property (allows "stream" only).
+     *
+     * @return StreamInterface
+     */
+    public function __get($name)
+    {
+        if ($name == 'stream') {
+            $this->stream = $this->createStream();
+            return $this->stream;
+        }
+
+        throw new \UnexpectedValueException("$name not found on class");
+    }
+
+    public function __toString()
+    {
+        try {
+            if ($this->isSeekable()) {
+                $this->seek(0);
+            }
+            return $this->getContents();
+        } catch (\Exception $e) {
+            // Really, PHP? https://bugs.php.net/bug.php?id=53648
+            trigger_error('StreamDecorator::__toString exception: '
+                . (string) $e, E_USER_ERROR);
+            return '';
+        }
+    }
+
+    public function getContents()
+    {
+        return copy_to_string($this);
+    }
+
+    /**
+     * Allow decorators to implement custom methods
+     *
+     * @param string $method Missing method name
+     * @param array  $args   Method arguments
+     *
+     * @return mixed
+     */
+    public function __call($method, array $args)
+    {
+        $result = call_user_func_array([$this->stream, $method], $args);
+
+        // Always return the wrapped object if the result is a return $this
+        return $result === $this->stream ? $this : $result;
+    }
+
+    public function close()
+    {
+        $this->stream->close();
+    }
+
+    public function getMetadata($key = null)
+    {
+        return $this->stream->getMetadata($key);
+    }
+
+    public function detach()
+    {
+        return $this->stream->detach();
+    }
+
+    public function getSize()
+    {
+        return $this->stream->getSize();
+    }
+
+    public function eof()
+    {
+        return $this->stream->eof();
+    }
+
+    public function tell()
+    {
+        return $this->stream->tell();
+    }
+
+    public function isReadable()
+    {
+        return $this->stream->isReadable();
+    }
+
+    public function isWritable()
+    {
+        return $this->stream->isWritable();
+    }
+
+    public function isSeekable()
+    {
+        return $this->stream->isSeekable();
+    }
+
+    public function rewind()
+    {
+        $this->seek(0);
+    }
+
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        $this->stream->seek($offset, $whence);
+    }
+
+    public function read($length)
+    {
+        return $this->stream->read($length);
+    }
+
+    public function write($string)
+    {
+        return $this->stream->write($string);
+    }
+
+    /**
+     * Implement in subclasses to dynamically create streams when requested.
+     *
+     * @return StreamInterface
+     * @throws \BadMethodCallException
+     */
+    protected function createStream()
+    {
+        throw new \BadMethodCallException('Not implemented');
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/StreamWrapper.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/StreamWrapper.php
new file mode 100644 (file)
index 0000000..0f3a285
--- /dev/null
@@ -0,0 +1,161 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Converts Guzzle streams into PHP stream resources.
+ */
+class StreamWrapper
+{
+    /** @var resource */
+    public $context;
+
+    /** @var StreamInterface */
+    private $stream;
+
+    /** @var string r, r+, or w */
+    private $mode;
+
+    /**
+     * Returns a resource representing the stream.
+     *
+     * @param StreamInterface $stream The stream to get a resource for
+     *
+     * @return resource
+     * @throws \InvalidArgumentException if stream is not readable or writable
+     */
+    public static function getResource(StreamInterface $stream)
+    {
+        self::register();
+
+        if ($stream->isReadable()) {
+            $mode = $stream->isWritable() ? 'r+' : 'r';
+        } elseif ($stream->isWritable()) {
+            $mode = 'w';
+        } else {
+            throw new \InvalidArgumentException('The stream must be readable, '
+                . 'writable, or both.');
+        }
+
+        return fopen('guzzle://stream', $mode, null, self::createStreamContext($stream));
+    }
+
+    /**
+     * Creates a stream context that can be used to open a stream as a php stream resource.
+     *
+     * @param StreamInterface $stream
+     *
+     * @return resource
+     */
+    public static function createStreamContext(StreamInterface $stream)
+    {
+        return stream_context_create([
+            'guzzle' => ['stream' => $stream]
+        ]);
+    }
+
+    /**
+     * Registers the stream wrapper if needed
+     */
+    public static function register()
+    {
+        if (!in_array('guzzle', stream_get_wrappers())) {
+            stream_wrapper_register('guzzle', __CLASS__);
+        }
+    }
+
+    public function stream_open($path, $mode, $options, &$opened_path)
+    {
+        $options = stream_context_get_options($this->context);
+
+        if (!isset($options['guzzle']['stream'])) {
+            return false;
+        }
+
+        $this->mode = $mode;
+        $this->stream = $options['guzzle']['stream'];
+
+        return true;
+    }
+
+    public function stream_read($count)
+    {
+        return $this->stream->read($count);
+    }
+
+    public function stream_write($data)
+    {
+        return (int) $this->stream->write($data);
+    }
+
+    public function stream_tell()
+    {
+        return $this->stream->tell();
+    }
+
+    public function stream_eof()
+    {
+        return $this->stream->eof();
+    }
+
+    public function stream_seek($offset, $whence)
+    {
+        $this->stream->seek($offset, $whence);
+
+        return true;
+    }
+
+    public function stream_cast($cast_as)
+    {
+        $stream = clone($this->stream);
+
+        return $stream->detach();
+    }
+
+    public function stream_stat()
+    {
+        static $modeMap = [
+            'r'  => 33060,
+            'rb' => 33060,
+            'r+' => 33206,
+            'w'  => 33188,
+            'wb' => 33188
+        ];
+
+        return [
+            'dev'     => 0,
+            'ino'     => 0,
+            'mode'    => $modeMap[$this->mode],
+            'nlink'   => 0,
+            'uid'     => 0,
+            'gid'     => 0,
+            'rdev'    => 0,
+            'size'    => $this->stream->getSize() ?: 0,
+            'atime'   => 0,
+            'mtime'   => 0,
+            'ctime'   => 0,
+            'blksize' => 0,
+            'blocks'  => 0
+        ];
+    }
+
+    public function url_stat($path, $flags)
+    {
+        return [
+            'dev'     => 0,
+            'ino'     => 0,
+            'mode'    => 0,
+            'nlink'   => 0,
+            'uid'     => 0,
+            'gid'     => 0,
+            'rdev'    => 0,
+            'size'    => 0,
+            'atime'   => 0,
+            'mtime'   => 0,
+            'ctime'   => 0,
+            'blksize' => 0,
+            'blocks'  => 0
+        ];
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UploadedFile.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UploadedFile.php
new file mode 100644 (file)
index 0000000..e62bd5c
--- /dev/null
@@ -0,0 +1,316 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use InvalidArgumentException;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UploadedFileInterface;
+use RuntimeException;
+
+class UploadedFile implements UploadedFileInterface
+{
+    /**
+     * @var int[]
+     */
+    private static $errors = [
+        UPLOAD_ERR_OK,
+        UPLOAD_ERR_INI_SIZE,
+        UPLOAD_ERR_FORM_SIZE,
+        UPLOAD_ERR_PARTIAL,
+        UPLOAD_ERR_NO_FILE,
+        UPLOAD_ERR_NO_TMP_DIR,
+        UPLOAD_ERR_CANT_WRITE,
+        UPLOAD_ERR_EXTENSION,
+    ];
+
+    /**
+     * @var string
+     */
+    private $clientFilename;
+
+    /**
+     * @var string
+     */
+    private $clientMediaType;
+
+    /**
+     * @var int
+     */
+    private $error;
+
+    /**
+     * @var null|string
+     */
+    private $file;
+
+    /**
+     * @var bool
+     */
+    private $moved = false;
+
+    /**
+     * @var int
+     */
+    private $size;
+
+    /**
+     * @var StreamInterface|null
+     */
+    private $stream;
+
+    /**
+     * @param StreamInterface|string|resource $streamOrFile
+     * @param int $size
+     * @param int $errorStatus
+     * @param string|null $clientFilename
+     * @param string|null $clientMediaType
+     */
+    public function __construct(
+        $streamOrFile,
+        $size,
+        $errorStatus,
+        $clientFilename = null,
+        $clientMediaType = null
+    ) {
+        $this->setError($errorStatus);
+        $this->setSize($size);
+        $this->setClientFilename($clientFilename);
+        $this->setClientMediaType($clientMediaType);
+
+        if ($this->isOk()) {
+            $this->setStreamOrFile($streamOrFile);
+        }
+    }
+
+    /**
+     * Depending on the value set file or stream variable
+     *
+     * @param mixed $streamOrFile
+     * @throws InvalidArgumentException
+     */
+    private function setStreamOrFile($streamOrFile)
+    {
+        if (is_string($streamOrFile)) {
+            $this->file = $streamOrFile;
+        } elseif (is_resource($streamOrFile)) {
+            $this->stream = new Stream($streamOrFile);
+        } elseif ($streamOrFile instanceof StreamInterface) {
+            $this->stream = $streamOrFile;
+        } else {
+            throw new InvalidArgumentException(
+                'Invalid stream or file provided for UploadedFile'
+            );
+        }
+    }
+
+    /**
+     * @param int $error
+     * @throws InvalidArgumentException
+     */
+    private function setError($error)
+    {
+        if (false === is_int($error)) {
+            throw new InvalidArgumentException(
+                'Upload file error status must be an integer'
+            );
+        }
+
+        if (false === in_array($error, UploadedFile::$errors)) {
+            throw new InvalidArgumentException(
+                'Invalid error status for UploadedFile'
+            );
+        }
+
+        $this->error = $error;
+    }
+
+    /**
+     * @param int $size
+     * @throws InvalidArgumentException
+     */
+    private function setSize($size)
+    {
+        if (false === is_int($size)) {
+            throw new InvalidArgumentException(
+                'Upload file size must be an integer'
+            );
+        }
+
+        $this->size = $size;
+    }
+
+    /**
+     * @param mixed $param
+     * @return boolean
+     */
+    private function isStringOrNull($param)
+    {
+        return in_array(gettype($param), ['string', 'NULL']);
+    }
+
+    /**
+     * @param mixed $param
+     * @return boolean
+     */
+    private function isStringNotEmpty($param)
+    {
+        return is_string($param) && false === empty($param);
+    }
+
+    /**
+     * @param string|null $clientFilename
+     * @throws InvalidArgumentException
+     */
+    private function setClientFilename($clientFilename)
+    {
+        if (false === $this->isStringOrNull($clientFilename)) {
+            throw new InvalidArgumentException(
+                'Upload file client filename must be a string or null'
+            );
+        }
+
+        $this->clientFilename = $clientFilename;
+    }
+
+    /**
+     * @param string|null $clientMediaType
+     * @throws InvalidArgumentException
+     */
+    private function setClientMediaType($clientMediaType)
+    {
+        if (false === $this->isStringOrNull($clientMediaType)) {
+            throw new InvalidArgumentException(
+                'Upload file client media type must be a string or null'
+            );
+        }
+
+        $this->clientMediaType = $clientMediaType;
+    }
+
+    /**
+     * Return true if there is no upload error
+     *
+     * @return boolean
+     */
+    private function isOk()
+    {
+        return $this->error === UPLOAD_ERR_OK;
+    }
+
+    /**
+     * @return boolean
+     */
+    public function isMoved()
+    {
+        return $this->moved;
+    }
+
+    /**
+     * @throws RuntimeException if is moved or not ok
+     */
+    private function validateActive()
+    {
+        if (false === $this->isOk()) {
+            throw new RuntimeException('Cannot retrieve stream due to upload error');
+        }
+
+        if ($this->isMoved()) {
+            throw new RuntimeException('Cannot retrieve stream after it has already been moved');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     * @throws RuntimeException if the upload was not successful.
+     */
+    public function getStream()
+    {
+        $this->validateActive();
+
+        if ($this->stream instanceof StreamInterface) {
+            return $this->stream;
+        }
+
+        return new LazyOpenStream($this->file, 'r+');
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see http://php.net/is_uploaded_file
+     * @see http://php.net/move_uploaded_file
+     * @param string $targetPath Path to which to move the uploaded file.
+     * @throws RuntimeException if the upload was not successful.
+     * @throws InvalidArgumentException if the $path specified is invalid.
+     * @throws RuntimeException on any error during the move operation, or on
+     *     the second or subsequent call to the method.
+     */
+    public function moveTo($targetPath)
+    {
+        $this->validateActive();
+
+        if (false === $this->isStringNotEmpty($targetPath)) {
+            throw new InvalidArgumentException(
+                'Invalid path provided for move operation; must be a non-empty string'
+            );
+        }
+
+        if ($this->file) {
+            $this->moved = php_sapi_name() == 'cli'
+                ? rename($this->file, $targetPath)
+                : move_uploaded_file($this->file, $targetPath);
+        } else {
+            copy_to_stream(
+                $this->getStream(),
+                new LazyOpenStream($targetPath, 'w')
+            );
+
+            $this->moved = true;
+        }
+
+        if (false === $this->moved) {
+            throw new RuntimeException(
+                sprintf('Uploaded file could not be moved to %s', $targetPath)
+            );
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return int|null The file size in bytes or null if unknown.
+     */
+    public function getSize()
+    {
+        return $this->size;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @see http://php.net/manual/en/features.file-upload.errors.php
+     * @return int One of PHP's UPLOAD_ERR_XXX constants.
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return string|null The filename sent by the client or null if none
+     *     was provided.
+     */
+    public function getClientFilename()
+    {
+        return $this->clientFilename;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getClientMediaType()
+    {
+        return $this->clientMediaType;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Uri.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/Uri.php
new file mode 100644 (file)
index 0000000..825a25e
--- /dev/null
@@ -0,0 +1,760 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\UriInterface;
+
+/**
+ * PSR-7 URI implementation.
+ *
+ * @author Michael Dowling
+ * @author Tobias Schultze
+ * @author Matthew Weier O'Phinney
+ */
+class Uri implements UriInterface
+{
+    /**
+     * Absolute http and https URIs require a host per RFC 7230 Section 2.7
+     * but in generic URIs the host can be empty. So for http(s) URIs
+     * we apply this default host when no host is given yet to form a
+     * valid URI.
+     */
+    const HTTP_DEFAULT_HOST = 'localhost';
+
+    private static $defaultPorts = [
+        'http'  => 80,
+        'https' => 443,
+        'ftp' => 21,
+        'gopher' => 70,
+        'nntp' => 119,
+        'news' => 119,
+        'telnet' => 23,
+        'tn3270' => 23,
+        'imap' => 143,
+        'pop' => 110,
+        'ldap' => 389,
+    ];
+
+    private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
+    private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
+    private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
+
+    /** @var string Uri scheme. */
+    private $scheme = '';
+
+    /** @var string Uri user info. */
+    private $userInfo = '';
+
+    /** @var string Uri host. */
+    private $host = '';
+
+    /** @var int|null Uri port. */
+    private $port;
+
+    /** @var string Uri path. */
+    private $path = '';
+
+    /** @var string Uri query string. */
+    private $query = '';
+
+    /** @var string Uri fragment. */
+    private $fragment = '';
+
+    /**
+     * @param string $uri URI to parse
+     */
+    public function __construct($uri = '')
+    {
+        // weak type check to also accept null until we can add scalar type hints
+        if ($uri != '') {
+            $parts = parse_url($uri);
+            if ($parts === false) {
+                throw new \InvalidArgumentException("Unable to parse URI: $uri");
+            }
+            $this->applyParts($parts);
+        }
+    }
+
+    public function __toString()
+    {
+        return self::composeComponents(
+            $this->scheme,
+            $this->getAuthority(),
+            $this->path,
+            $this->query,
+            $this->fragment
+        );
+    }
+
+    /**
+     * Composes a URI reference string from its various components.
+     *
+     * Usually this method does not need to be called manually but instead is used indirectly via
+     * `Psr\Http\Message\UriInterface::__toString`.
+     *
+     * PSR-7 UriInterface treats an empty component the same as a missing component as
+     * getQuery(), getFragment() etc. always return a string. This explains the slight
+     * difference to RFC 3986 Section 5.3.
+     *
+     * Another adjustment is that the authority separator is added even when the authority is missing/empty
+     * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
+     * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
+     * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
+     * that format).
+     *
+     * @param string $scheme
+     * @param string $authority
+     * @param string $path
+     * @param string $query
+     * @param string $fragment
+     *
+     * @return string
+     *
+     * @link https://tools.ietf.org/html/rfc3986#section-5.3
+     */
+    public static function composeComponents($scheme, $authority, $path, $query, $fragment)
+    {
+        $uri = '';
+
+        // weak type checks to also accept null until we can add scalar type hints
+        if ($scheme != '') {
+            $uri .= $scheme . ':';
+        }
+
+        if ($authority != ''|| $scheme === 'file') {
+            $uri .= '//' . $authority;
+        }
+
+        $uri .= $path;
+
+        if ($query != '') {
+            $uri .= '?' . $query;
+        }
+
+        if ($fragment != '') {
+            $uri .= '#' . $fragment;
+        }
+
+        return $uri;
+    }
+
+    /**
+     * Whether the URI has the default port of the current scheme.
+     *
+     * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
+     * independently of the implementation.
+     *
+     * @param UriInterface $uri
+     *
+     * @return bool
+     */
+    public static function isDefaultPort(UriInterface $uri)
+    {
+        return $uri->getPort() === null
+            || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
+    }
+
+    /**
+     * Whether the URI is absolute, i.e. it has a scheme.
+     *
+     * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
+     * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
+     * to another URI, the base URI. Relative references can be divided into several forms:
+     * - network-path references, e.g. '//example.com/path'
+     * - absolute-path references, e.g. '/path'
+     * - relative-path references, e.g. 'subpath'
+     *
+     * @param UriInterface $uri
+     *
+     * @return bool
+     * @see Uri::isNetworkPathReference
+     * @see Uri::isAbsolutePathReference
+     * @see Uri::isRelativePathReference
+     * @link https://tools.ietf.org/html/rfc3986#section-4
+     */
+    public static function isAbsolute(UriInterface $uri)
+    {
+        return $uri->getScheme() !== '';
+    }
+
+    /**
+     * Whether the URI is a network-path reference.
+     *
+     * A relative reference that begins with two slash characters is termed an network-path reference.
+     *
+     * @param UriInterface $uri
+     *
+     * @return bool
+     * @link https://tools.ietf.org/html/rfc3986#section-4.2
+     */
+    public static function isNetworkPathReference(UriInterface $uri)
+    {
+        return $uri->getScheme() === '' && $uri->getAuthority() !== '';
+    }
+
+    /**
+     * Whether the URI is a absolute-path reference.
+     *
+     * A relative reference that begins with a single slash character is termed an absolute-path reference.
+     *
+     * @param UriInterface $uri
+     *
+     * @return bool
+     * @link https://tools.ietf.org/html/rfc3986#section-4.2
+     */
+    public static function isAbsolutePathReference(UriInterface $uri)
+    {
+        return $uri->getScheme() === ''
+            && $uri->getAuthority() === ''
+            && isset($uri->getPath()[0])
+            && $uri->getPath()[0] === '/';
+    }
+
+    /**
+     * Whether the URI is a relative-path reference.
+     *
+     * A relative reference that does not begin with a slash character is termed a relative-path reference.
+     *
+     * @param UriInterface $uri
+     *
+     * @return bool
+     * @link https://tools.ietf.org/html/rfc3986#section-4.2
+     */
+    public static function isRelativePathReference(UriInterface $uri)
+    {
+        return $uri->getScheme() === ''
+            && $uri->getAuthority() === ''
+            && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
+    }
+
+    /**
+     * Whether the URI is a same-document reference.
+     *
+     * A same-document reference refers to a URI that is, aside from its fragment
+     * component, identical to the base URI. When no base URI is given, only an empty
+     * URI reference (apart from its fragment) is considered a same-document reference.
+     *
+     * @param UriInterface      $uri  The URI to check
+     * @param UriInterface|null $base An optional base URI to compare against
+     *
+     * @return bool
+     * @link https://tools.ietf.org/html/rfc3986#section-4.4
+     */
+    public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
+    {
+        if ($base !== null) {
+            $uri = UriResolver::resolve($base, $uri);
+
+            return ($uri->getScheme() === $base->getScheme())
+                && ($uri->getAuthority() === $base->getAuthority())
+                && ($uri->getPath() === $base->getPath())
+                && ($uri->getQuery() === $base->getQuery());
+        }
+
+        return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
+    }
+
+    /**
+     * Removes dot segments from a path and returns the new path.
+     *
+     * @param string $path
+     *
+     * @return string
+     *
+     * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead.
+     * @see UriResolver::removeDotSegments
+     */
+    public static function removeDotSegments($path)
+    {
+        return UriResolver::removeDotSegments($path);
+    }
+
+    /**
+     * Converts the relative URI into a new URI that is resolved against the base URI.
+     *
+     * @param UriInterface        $base Base URI
+     * @param string|UriInterface $rel  Relative URI
+     *
+     * @return UriInterface
+     *
+     * @deprecated since version 1.4. Use UriResolver::resolve instead.
+     * @see UriResolver::resolve
+     */
+    public static function resolve(UriInterface $base, $rel)
+    {
+        if (!($rel instanceof UriInterface)) {
+            $rel = new self($rel);
+        }
+
+        return UriResolver::resolve($base, $rel);
+    }
+
+    /**
+     * Creates a new URI with a specific query string value removed.
+     *
+     * Any existing query string values that exactly match the provided key are
+     * removed.
+     *
+     * @param UriInterface $uri URI to use as a base.
+     * @param string       $key Query string key to remove.
+     *
+     * @return UriInterface
+     */
+    public static function withoutQueryValue(UriInterface $uri, $key)
+    {
+        $result = self::getFilteredQueryString($uri, [$key]);
+
+        return $uri->withQuery(implode('&', $result));
+    }
+
+    /**
+     * Creates a new URI with a specific query string value.
+     *
+     * Any existing query string values that exactly match the provided key are
+     * removed and replaced with the given key value pair.
+     *
+     * A value of null will set the query string key without a value, e.g. "key"
+     * instead of "key=value".
+     *
+     * @param UriInterface $uri   URI to use as a base.
+     * @param string       $key   Key to set.
+     * @param string|null  $value Value to set
+     *
+     * @return UriInterface
+     */
+    public static function withQueryValue(UriInterface $uri, $key, $value)
+    {
+        $result = self::getFilteredQueryString($uri, [$key]);
+
+        $result[] = self::generateQueryString($key, $value);
+
+        return $uri->withQuery(implode('&', $result));
+    }
+
+    /**
+     * Creates a new URI with multiple specific query string values.
+     *
+     * It has the same behavior as withQueryValue() but for an associative array of key => value.
+     *
+     * @param UriInterface $uri           URI to use as a base.
+     * @param array        $keyValueArray Associative array of key and values
+     *
+     * @return UriInterface
+     */
+    public static function withQueryValues(UriInterface $uri, array $keyValueArray)
+    {
+        $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
+
+        foreach ($keyValueArray as $key => $value) {
+            $result[] = self::generateQueryString($key, $value);
+        }
+
+        return $uri->withQuery(implode('&', $result));
+    }
+
+    /**
+     * Creates a URI from a hash of `parse_url` components.
+     *
+     * @param array $parts
+     *
+     * @return UriInterface
+     * @link http://php.net/manual/en/function.parse-url.php
+     *
+     * @throws \InvalidArgumentException If the components do not form a valid URI.
+     */
+    public static function fromParts(array $parts)
+    {
+        $uri = new self();
+        $uri->applyParts($parts);
+        $uri->validateState();
+
+        return $uri;
+    }
+
+    public function getScheme()
+    {
+        return $this->scheme;
+    }
+
+    public function getAuthority()
+    {
+        $authority = $this->host;
+        if ($this->userInfo !== '') {
+            $authority = $this->userInfo . '@' . $authority;
+        }
+
+        if ($this->port !== null) {
+            $authority .= ':' . $this->port;
+        }
+
+        return $authority;
+    }
+
+    public function getUserInfo()
+    {
+        return $this->userInfo;
+    }
+
+    public function getHost()
+    {
+        return $this->host;
+    }
+
+    public function getPort()
+    {
+        return $this->port;
+    }
+
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    public function getQuery()
+    {
+        return $this->query;
+    }
+
+    public function getFragment()
+    {
+        return $this->fragment;
+    }
+
+    public function withScheme($scheme)
+    {
+        $scheme = $this->filterScheme($scheme);
+
+        if ($this->scheme === $scheme) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->scheme = $scheme;
+        $new->removeDefaultPort();
+        $new->validateState();
+
+        return $new;
+    }
+
+    public function withUserInfo($user, $password = null)
+    {
+        $info = $this->filterUserInfoComponent($user);
+        if ($password !== null) {
+            $info .= ':' . $this->filterUserInfoComponent($password);
+        }
+
+        if ($this->userInfo === $info) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->userInfo = $info;
+        $new->validateState();
+
+        return $new;
+    }
+
+    public function withHost($host)
+    {
+        $host = $this->filterHost($host);
+
+        if ($this->host === $host) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->host = $host;
+        $new->validateState();
+
+        return $new;
+    }
+
+    public function withPort($port)
+    {
+        $port = $this->filterPort($port);
+
+        if ($this->port === $port) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->port = $port;
+        $new->removeDefaultPort();
+        $new->validateState();
+
+        return $new;
+    }
+
+    public function withPath($path)
+    {
+        $path = $this->filterPath($path);
+
+        if ($this->path === $path) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->path = $path;
+        $new->validateState();
+
+        return $new;
+    }
+
+    public function withQuery($query)
+    {
+        $query = $this->filterQueryAndFragment($query);
+
+        if ($this->query === $query) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->query = $query;
+
+        return $new;
+    }
+
+    public function withFragment($fragment)
+    {
+        $fragment = $this->filterQueryAndFragment($fragment);
+
+        if ($this->fragment === $fragment) {
+            return $this;
+        }
+
+        $new = clone $this;
+        $new->fragment = $fragment;
+
+        return $new;
+    }
+
+    /**
+     * Apply parse_url parts to a URI.
+     *
+     * @param array $parts Array of parse_url parts to apply.
+     */
+    private function applyParts(array $parts)
+    {
+        $this->scheme = isset($parts['scheme'])
+            ? $this->filterScheme($parts['scheme'])
+            : '';
+        $this->userInfo = isset($parts['user'])
+            ? $this->filterUserInfoComponent($parts['user'])
+            : '';
+        $this->host = isset($parts['host'])
+            ? $this->filterHost($parts['host'])
+            : '';
+        $this->port = isset($parts['port'])
+            ? $this->filterPort($parts['port'])
+            : null;
+        $this->path = isset($parts['path'])
+            ? $this->filterPath($parts['path'])
+            : '';
+        $this->query = isset($parts['query'])
+            ? $this->filterQueryAndFragment($parts['query'])
+            : '';
+        $this->fragment = isset($parts['fragment'])
+            ? $this->filterQueryAndFragment($parts['fragment'])
+            : '';
+        if (isset($parts['pass'])) {
+            $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
+        }
+
+        $this->removeDefaultPort();
+    }
+
+    /**
+     * @param string $scheme
+     *
+     * @return string
+     *
+     * @throws \InvalidArgumentException If the scheme is invalid.
+     */
+    private function filterScheme($scheme)
+    {
+        if (!is_string($scheme)) {
+            throw new \InvalidArgumentException('Scheme must be a string');
+        }
+
+        return strtolower($scheme);
+    }
+
+    /**
+     * @param string $component
+     *
+     * @return string
+     *
+     * @throws \InvalidArgumentException If the user info is invalid.
+     */
+    private function filterUserInfoComponent($component)
+    {
+        if (!is_string($component)) {
+            throw new \InvalidArgumentException('User info must be a string');
+        }
+
+        return preg_replace_callback(
+            '/(?:[^%' . self::$charUnreserved . self::$charSubDelims . ']+|%(?![A-Fa-f0-9]{2}))/',
+            [$this, 'rawurlencodeMatchZero'],
+            $component
+        );
+    }
+
+    /**
+     * @param string $host
+     *
+     * @return string
+     *
+     * @throws \InvalidArgumentException If the host is invalid.
+     */
+    private function filterHost($host)
+    {
+        if (!is_string($host)) {
+            throw new \InvalidArgumentException('Host must be a string');
+        }
+
+        return strtolower($host);
+    }
+
+    /**
+     * @param int|null $port
+     *
+     * @return int|null
+     *
+     * @throws \InvalidArgumentException If the port is invalid.
+     */
+    private function filterPort($port)
+    {
+        if ($port === null) {
+            return null;
+        }
+
+        $port = (int) $port;
+        if (0 > $port || 0xffff < $port) {
+            throw new \InvalidArgumentException(
+                sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
+            );
+        }
+
+        return $port;
+    }
+
+    /**
+     * @param UriInterface $uri
+     * @param array        $keys
+     * 
+     * @return array
+     */
+    private static function getFilteredQueryString(UriInterface $uri, array $keys)
+    {
+        $current = $uri->getQuery();
+
+        if ($current === '') {
+            return [];
+        }
+
+        $decodedKeys = array_map('rawurldecode', $keys);
+
+        return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
+            return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
+        });
+    }
+
+    /**
+     * @param string      $key
+     * @param string|null $value
+     * 
+     * @return string
+     */
+    private static function generateQueryString($key, $value)
+    {
+        // Query string separators ("=", "&") within the key or value need to be encoded
+        // (while preventing double-encoding) before setting the query string. All other
+        // chars that need percent-encoding will be encoded by withQuery().
+        $queryString = strtr($key, self::$replaceQuery);
+
+        if ($value !== null) {
+            $queryString .= '=' . strtr($value, self::$replaceQuery);
+        }
+
+        return $queryString;
+    }
+
+    private function removeDefaultPort()
+    {
+        if ($this->port !== null && self::isDefaultPort($this)) {
+            $this->port = null;
+        }
+    }
+
+    /**
+     * Filters the path of a URI
+     *
+     * @param string $path
+     *
+     * @return string
+     *
+     * @throws \InvalidArgumentException If the path is invalid.
+     */
+    private function filterPath($path)
+    {
+        if (!is_string($path)) {
+            throw new \InvalidArgumentException('Path must be a string');
+        }
+
+        return preg_replace_callback(
+            '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
+            [$this, 'rawurlencodeMatchZero'],
+            $path
+        );
+    }
+
+    /**
+     * Filters the query string or fragment of a URI.
+     *
+     * @param string $str
+     *
+     * @return string
+     *
+     * @throws \InvalidArgumentException If the query or fragment is invalid.
+     */
+    private function filterQueryAndFragment($str)
+    {
+        if (!is_string($str)) {
+            throw new \InvalidArgumentException('Query and fragment must be a string');
+        }
+
+        return preg_replace_callback(
+            '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
+            [$this, 'rawurlencodeMatchZero'],
+            $str
+        );
+    }
+
+    private function rawurlencodeMatchZero(array $match)
+    {
+        return rawurlencode($match[0]);
+    }
+
+    private function validateState()
+    {
+        if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
+            $this->host = self::HTTP_DEFAULT_HOST;
+        }
+
+        if ($this->getAuthority() === '') {
+            if (0 === strpos($this->path, '//')) {
+                throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
+            }
+            if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
+                throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
+            }
+        } elseif (isset($this->path[0]) && $this->path[0] !== '/') {
+            @trigger_error(
+                'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
+                'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
+                E_USER_DEPRECATED
+            );
+            $this->path = '/'. $this->path;
+            //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UriNormalizer.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UriNormalizer.php
new file mode 100644 (file)
index 0000000..384c29e
--- /dev/null
@@ -0,0 +1,216 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Provides methods to normalize and compare URIs.
+ *
+ * @author Tobias Schultze
+ *
+ * @link https://tools.ietf.org/html/rfc3986#section-6
+ */
+final class UriNormalizer
+{
+    /**
+     * Default normalizations which only include the ones that preserve semantics.
+     *
+     * self::CAPITALIZE_PERCENT_ENCODING | self::DECODE_UNRESERVED_CHARACTERS | self::CONVERT_EMPTY_PATH |
+     * self::REMOVE_DEFAULT_HOST | self::REMOVE_DEFAULT_PORT | self::REMOVE_DOT_SEGMENTS
+     */
+    const PRESERVING_NORMALIZATIONS = 63;
+
+    /**
+     * All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
+     *
+     * Example: http://example.org/a%c2%b1b → http://example.org/a%C2%B1b
+     */
+    const CAPITALIZE_PERCENT_ENCODING = 1;
+
+    /**
+     * Decodes percent-encoded octets of unreserved characters.
+     *
+     * For consistency, percent-encoded octets in the ranges of ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39),
+     * hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should not be created by URI producers and,
+     * when found in a URI, should be decoded to their corresponding unreserved characters by URI normalizers.
+     *
+     * Example: http://example.org/%7Eusern%61me/ → http://example.org/~username/
+     */
+    const DECODE_UNRESERVED_CHARACTERS = 2;
+
+    /**
+     * Converts the empty path to "/" for http and https URIs.
+     *
+     * Example: http://example.org → http://example.org/
+     */
+    const CONVERT_EMPTY_PATH = 4;
+
+    /**
+     * Removes the default host of the given URI scheme from the URI.
+     *
+     * Only the "file" scheme defines the default host "localhost".
+     * All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile`
+     * are equivalent according to RFC 3986. The first format is not accepted
+     * by PHPs stream functions and thus already normalized implicitly to the
+     * second format in the Uri class. See `GuzzleHttp\Psr7\Uri::composeComponents`.
+     *
+     * Example: file://localhost/myfile → file:///myfile
+     */
+    const REMOVE_DEFAULT_HOST = 8;
+
+    /**
+     * Removes the default port of the given URI scheme from the URI.
+     *
+     * Example: http://example.org:80/ → http://example.org/
+     */
+    const REMOVE_DEFAULT_PORT = 16;
+
+    /**
+     * Removes unnecessary dot-segments.
+     *
+     * Dot-segments in relative-path references are not removed as it would
+     * change the semantics of the URI reference.
+     *
+     * Example: http://example.org/../a/b/../c/./d.html → http://example.org/a/c/d.html
+     */
+    const REMOVE_DOT_SEGMENTS = 32;
+
+    /**
+     * Paths which include two or more adjacent slashes are converted to one.
+     *
+     * Webservers usually ignore duplicate slashes and treat those URIs equivalent.
+     * But in theory those URIs do not need to be equivalent. So this normalization
+     * may change the semantics. Encoded slashes (%2F) are not removed.
+     *
+     * Example: http://example.org//foo///bar.html → http://example.org/foo/bar.html
+     */
+    const REMOVE_DUPLICATE_SLASHES = 64;
+
+    /**
+     * Sort query parameters with their values in alphabetical order.
+     *
+     * However, the order of parameters in a URI may be significant (this is not defined by the standard).
+     * So this normalization is not safe and may change the semantics of the URI.
+     *
+     * Example: ?lang=en&article=fred → ?article=fred&lang=en
+     *
+     * Note: The sorting is neither locale nor Unicode aware (the URI query does not get decoded at all) as the
+     * purpose is to be able to compare URIs in a reproducible way, not to have the params sorted perfectly.
+     */
+    const SORT_QUERY_PARAMETERS = 128;
+
+    /**
+     * Returns a normalized URI.
+     *
+     * The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
+     * This methods adds additional normalizations that can be configured with the $flags parameter.
+     *
+     * PSR-7 UriInterface cannot distinguish between an empty component and a missing component as
+     * getQuery(), getFragment() etc. always return a string. This means the URIs "/?#" and "/" are
+     * treated equivalent which is not necessarily true according to RFC 3986. But that difference
+     * is highly uncommon in reality. So this potential normalization is implied in PSR-7 as well.
+     *
+     * @param UriInterface $uri   The URI to normalize
+     * @param int          $flags A bitmask of normalizations to apply, see constants
+     *
+     * @return UriInterface The normalized URI
+     * @link https://tools.ietf.org/html/rfc3986#section-6.2
+     */
+    public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS)
+    {
+        if ($flags & self::CAPITALIZE_PERCENT_ENCODING) {
+            $uri = self::capitalizePercentEncoding($uri);
+        }
+
+        if ($flags & self::DECODE_UNRESERVED_CHARACTERS) {
+            $uri = self::decodeUnreservedCharacters($uri);
+        }
+
+        if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' &&
+            ($uri->getScheme() === 'http' || $uri->getScheme() === 'https')
+        ) {
+            $uri = $uri->withPath('/');
+        }
+
+        if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') {
+            $uri = $uri->withHost('');
+        }
+
+        if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) {
+            $uri = $uri->withPort(null);
+        }
+
+        if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) {
+            $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath()));
+        }
+
+        if ($flags & self::REMOVE_DUPLICATE_SLASHES) {
+            $uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath()));
+        }
+
+        if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') {
+            $queryKeyValues = explode('&', $uri->getQuery());
+            sort($queryKeyValues);
+            $uri = $uri->withQuery(implode('&', $queryKeyValues));
+        }
+
+        return $uri;
+    }
+
+    /**
+     * Whether two URIs can be considered equivalent.
+     *
+     * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also
+     * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be
+     * resolved against the same base URI. If this is not the case, determination of equivalence or difference of
+     * relative references does not mean anything.
+     *
+     * @param UriInterface $uri1           An URI to compare
+     * @param UriInterface $uri2           An URI to compare
+     * @param int          $normalizations A bitmask of normalizations to apply, see constants
+     *
+     * @return bool
+     * @link https://tools.ietf.org/html/rfc3986#section-6.1
+     */
+    public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS)
+    {
+        return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations);
+    }
+
+    private static function capitalizePercentEncoding(UriInterface $uri)
+    {
+        $regex = '/(?:%[A-Fa-f0-9]{2})++/';
+
+        $callback = function (array $match) {
+            return strtoupper($match[0]);
+        };
+
+        return
+            $uri->withPath(
+                preg_replace_callback($regex, $callback, $uri->getPath())
+            )->withQuery(
+                preg_replace_callback($regex, $callback, $uri->getQuery())
+            );
+    }
+
+    private static function decodeUnreservedCharacters(UriInterface $uri)
+    {
+        $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
+
+        $callback = function (array $match) {
+            return rawurldecode($match[0]);
+        };
+
+        return
+            $uri->withPath(
+                preg_replace_callback($regex, $callback, $uri->getPath())
+            )->withQuery(
+                preg_replace_callback($regex, $callback, $uri->getQuery())
+            );
+    }
+
+    private function __construct()
+    {
+        // cannot be instantiated
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UriResolver.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/UriResolver.php
new file mode 100644 (file)
index 0000000..c1cb8a2
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Resolves a URI reference in the context of a base URI and the opposite way.
+ *
+ * @author Tobias Schultze
+ *
+ * @link https://tools.ietf.org/html/rfc3986#section-5
+ */
+final class UriResolver
+{
+    /**
+     * Removes dot segments from a path and returns the new path.
+     *
+     * @param string $path
+     *
+     * @return string
+     * @link http://tools.ietf.org/html/rfc3986#section-5.2.4
+     */
+    public static function removeDotSegments($path)
+    {
+        if ($path === '' || $path === '/') {
+            return $path;
+        }
+
+        $results = [];
+        $segments = explode('/', $path);
+        foreach ($segments as $segment) {
+            if ($segment === '..') {
+                array_pop($results);
+            } elseif ($segment !== '.') {
+                $results[] = $segment;
+            }
+        }
+
+        $newPath = implode('/', $results);
+
+        if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) {
+            // Re-add the leading slash if necessary for cases like "/.."
+            $newPath = '/' . $newPath;
+        } elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) {
+            // Add the trailing slash if necessary
+            // If newPath is not empty, then $segment must be set and is the last segment from the foreach
+            $newPath .= '/';
+        }
+
+        return $newPath;
+    }
+
+    /**
+     * Converts the relative URI into a new URI that is resolved against the base URI.
+     *
+     * @param UriInterface $base Base URI
+     * @param UriInterface $rel  Relative URI
+     *
+     * @return UriInterface
+     * @link http://tools.ietf.org/html/rfc3986#section-5.2
+     */
+    public static function resolve(UriInterface $base, UriInterface $rel)
+    {
+        if ((string) $rel === '') {
+            // we can simply return the same base URI instance for this same-document reference
+            return $base;
+        }
+
+        if ($rel->getScheme() != '') {
+            return $rel->withPath(self::removeDotSegments($rel->getPath()));
+        }
+
+        if ($rel->getAuthority() != '') {
+            $targetAuthority = $rel->getAuthority();
+            $targetPath = self::removeDotSegments($rel->getPath());
+            $targetQuery = $rel->getQuery();
+        } else {
+            $targetAuthority = $base->getAuthority();
+            if ($rel->getPath() === '') {
+                $targetPath = $base->getPath();
+                $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery();
+            } else {
+                if ($rel->getPath()[0] === '/') {
+                    $targetPath = $rel->getPath();
+                } else {
+                    if ($targetAuthority != '' && $base->getPath() === '') {
+                        $targetPath = '/' . $rel->getPath();
+                    } else {
+                        $lastSlashPos = strrpos($base->getPath(), '/');
+                        if ($lastSlashPos === false) {
+                            $targetPath = $rel->getPath();
+                        } else {
+                            $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
+                        }
+                    }
+                }
+                $targetPath = self::removeDotSegments($targetPath);
+                $targetQuery = $rel->getQuery();
+            }
+        }
+
+        return new Uri(Uri::composeComponents(
+            $base->getScheme(),
+            $targetAuthority,
+            $targetPath,
+            $targetQuery,
+            $rel->getFragment()
+        ));
+    }
+
+    /**
+     * Returns the target URI as a relative reference from the base URI.
+     *
+     * This method is the counterpart to resolve():
+     *
+     *    (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
+     *
+     * One use-case is to use the current request URI as base URI and then generate relative links in your documents
+     * to reduce the document size or offer self-contained downloadable document archives.
+     *
+     *    $base = new Uri('http://example.com/a/b/');
+     *    echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c'));  // prints 'c'.
+     *    echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y'));  // prints '../x/y'.
+     *    echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
+     *    echo UriResolver::relativize($base, new Uri('http://example.org/a/b/'));   // prints '//example.org/a/b/'.
+     *
+     * This method also accepts a target that is already relative and will try to relativize it further. Only a
+     * relative-path reference will be returned as-is.
+     *
+     *    echo UriResolver::relativize($base, new Uri('/a/b/c'));  // prints 'c' as well
+     *
+     * @param UriInterface $base   Base URI
+     * @param UriInterface $target Target URI
+     *
+     * @return UriInterface The relative URI reference
+     */
+    public static function relativize(UriInterface $base, UriInterface $target)
+    {
+        if ($target->getScheme() !== '' &&
+            ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')
+        ) {
+            return $target;
+        }
+
+        if (Uri::isRelativePathReference($target)) {
+            // As the target is already highly relative we return it as-is. It would be possible to resolve
+            // the target with `$target = self::resolve($base, $target);` and then try make it more relative
+            // by removing a duplicate query. But let's not do that automatically.
+            return $target;
+        }
+
+        if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) {
+            return $target->withScheme('');
+        }
+
+        // We must remove the path before removing the authority because if the path starts with two slashes, the URI
+        // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also
+        // invalid.
+        $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost('');
+
+        if ($base->getPath() !== $target->getPath()) {
+            return $emptyPathUri->withPath(self::getRelativePath($base, $target));
+        }
+
+        if ($base->getQuery() === $target->getQuery()) {
+            // Only the target fragment is left. And it must be returned even if base and target fragment are the same.
+            return $emptyPathUri->withQuery('');
+        }
+
+        // If the base URI has a query but the target has none, we cannot return an empty path reference as it would
+        // inherit the base query component when resolving.
+        if ($target->getQuery() === '') {
+            $segments = explode('/', $target->getPath());
+            $lastSegment = end($segments);
+
+            return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment);
+        }
+
+        return $emptyPathUri;
+    }
+
+    private static function getRelativePath(UriInterface $base, UriInterface $target)
+    {
+        $sourceSegments = explode('/', $base->getPath());
+        $targetSegments = explode('/', $target->getPath());
+        array_pop($sourceSegments);
+        $targetLastSegment = array_pop($targetSegments);
+        foreach ($sourceSegments as $i => $segment) {
+            if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) {
+                unset($sourceSegments[$i], $targetSegments[$i]);
+            } else {
+                break;
+            }
+        }
+        $targetSegments[] = $targetLastSegment;
+        $relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments);
+
+        // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./".
+        // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
+        // as the first segment of a relative-path reference, as it would be mistaken for a scheme name.
+        if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) {
+            $relativePath = "./$relativePath";
+        } elseif ('/' === $relativePath[0]) {
+            if ($base->getAuthority() != '' && $base->getPath() === '') {
+                // In this case an extra slash is added by resolve() automatically. So we must not add one here.
+                $relativePath = ".$relativePath";
+            } else {
+                $relativePath = "./$relativePath";
+            }
+        }
+
+        return $relativePath;
+    }
+
+    private function __construct()
+    {
+        // cannot be instantiated
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/functions.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/functions.php
new file mode 100644 (file)
index 0000000..8e6dafe
--- /dev/null
@@ -0,0 +1,899 @@
+<?php
+namespace GuzzleHttp\Psr7;
+
+use Psr\Http\Message\MessageInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Returns the string representation of an HTTP message.
+ *
+ * @param MessageInterface $message Message to convert to a string.
+ *
+ * @return string
+ */
+function str(MessageInterface $message)
+{
+    if ($message instanceof RequestInterface) {
+        $msg = trim($message->getMethod() . ' '
+                . $message->getRequestTarget())
+            . ' HTTP/' . $message->getProtocolVersion();
+        if (!$message->hasHeader('host')) {
+            $msg .= "\r\nHost: " . $message->getUri()->getHost();
+        }
+    } elseif ($message instanceof ResponseInterface) {
+        $msg = 'HTTP/' . $message->getProtocolVersion() . ' '
+            . $message->getStatusCode() . ' '
+            . $message->getReasonPhrase();
+    } else {
+        throw new \InvalidArgumentException('Unknown message type');
+    }
+
+    foreach ($message->getHeaders() as $name => $values) {
+        $msg .= "\r\n{$name}: " . implode(', ', $values);
+    }
+
+    return "{$msg}\r\n\r\n" . $message->getBody();
+}
+
+/**
+ * Returns a UriInterface for the given value.
+ *
+ * This function accepts a string or {@see Psr\Http\Message\UriInterface} and
+ * returns a UriInterface for the given value. If the value is already a
+ * `UriInterface`, it is returned as-is.
+ *
+ * @param string|UriInterface $uri
+ *
+ * @return UriInterface
+ * @throws \InvalidArgumentException
+ */
+function uri_for($uri)
+{
+    if ($uri instanceof UriInterface) {
+        return $uri;
+    } elseif (is_string($uri)) {
+        return new Uri($uri);
+    }
+
+    throw new \InvalidArgumentException('URI must be a string or UriInterface');
+}
+
+/**
+ * Create a new stream based on the input type.
+ *
+ * Options is an associative array that can contain the following keys:
+ * - metadata: Array of custom metadata.
+ * - size: Size of the stream.
+ *
+ * @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data
+ * @param array                                                                  $options  Additional options
+ *
+ * @return StreamInterface
+ * @throws \InvalidArgumentException if the $resource arg is not valid.
+ */
+function stream_for($resource = '', array $options = [])
+{
+    if (is_scalar($resource)) {
+        $stream = fopen('php://temp', 'r+');
+        if ($resource !== '') {
+            fwrite($stream, $resource);
+            fseek($stream, 0);
+        }
+        return new Stream($stream, $options);
+    }
+
+    switch (gettype($resource)) {
+        case 'resource':
+            return new Stream($resource, $options);
+        case 'object':
+            if ($resource instanceof StreamInterface) {
+                return $resource;
+            } elseif ($resource instanceof \Iterator) {
+                return new PumpStream(function () use ($resource) {
+                    if (!$resource->valid()) {
+                        return false;
+                    }
+                    $result = $resource->current();
+                    $resource->next();
+                    return $result;
+                }, $options);
+            } elseif (method_exists($resource, '__toString')) {
+                return stream_for((string) $resource, $options);
+            }
+            break;
+        case 'NULL':
+            return new Stream(fopen('php://temp', 'r+'), $options);
+    }
+
+    if (is_callable($resource)) {
+        return new PumpStream($resource, $options);
+    }
+
+    throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
+}
+
+/**
+ * Parse an array of header values containing ";" separated data into an
+ * array of associative arrays representing the header key value pair
+ * data of the header. When a parameter does not contain a value, but just
+ * contains a key, this function will inject a key with a '' string value.
+ *
+ * @param string|array $header Header to parse into components.
+ *
+ * @return array Returns the parsed header values.
+ */
+function parse_header($header)
+{
+    static $trimmed = "\"'  \n\t\r";
+    $params = $matches = [];
+
+    foreach (normalize_header($header) as $val) {
+        $part = [];
+        foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
+            if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
+                $m = $matches[0];
+                if (isset($m[1])) {
+                    $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
+                } else {
+                    $part[] = trim($m[0], $trimmed);
+                }
+            }
+        }
+        if ($part) {
+            $params[] = $part;
+        }
+    }
+
+    return $params;
+}
+
+/**
+ * Converts an array of header values that may contain comma separated
+ * headers into an array of headers with no comma separated values.
+ *
+ * @param string|array $header Header to normalize.
+ *
+ * @return array Returns the normalized header field values.
+ */
+function normalize_header($header)
+{
+    if (!is_array($header)) {
+        return array_map('trim', explode(',', $header));
+    }
+
+    $result = [];
+    foreach ($header as $value) {
+        foreach ((array) $value as $v) {
+            if (strpos($v, ',') === false) {
+                $result[] = $v;
+                continue;
+            }
+            foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
+                $result[] = trim($vv);
+            }
+        }
+    }
+
+    return $result;
+}
+
+/**
+ * Clone and modify a request with the given changes.
+ *
+ * The changes can be one of:
+ * - method: (string) Changes the HTTP method.
+ * - set_headers: (array) Sets the given headers.
+ * - remove_headers: (array) Remove the given headers.
+ * - body: (mixed) Sets the given body.
+ * - uri: (UriInterface) Set the URI.
+ * - query: (string) Set the query string value of the URI.
+ * - version: (string) Set the protocol version.
+ *
+ * @param RequestInterface $request Request to clone and modify.
+ * @param array            $changes Changes to apply.
+ *
+ * @return RequestInterface
+ */
+function modify_request(RequestInterface $request, array $changes)
+{
+    if (!$changes) {
+        return $request;
+    }
+
+    $headers = $request->getHeaders();
+
+    if (!isset($changes['uri'])) {
+        $uri = $request->getUri();
+    } else {
+        // Remove the host header if one is on the URI
+        if ($host = $changes['uri']->getHost()) {
+            $changes['set_headers']['Host'] = $host;
+
+            if ($port = $changes['uri']->getPort()) {
+                $standardPorts = ['http' => 80, 'https' => 443];
+                $scheme = $changes['uri']->getScheme();
+                if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
+                    $changes['set_headers']['Host'] .= ':'.$port;
+                }
+            }
+        }
+        $uri = $changes['uri'];
+    }
+
+    if (!empty($changes['remove_headers'])) {
+        $headers = _caseless_remove($changes['remove_headers'], $headers);
+    }
+
+    if (!empty($changes['set_headers'])) {
+        $headers = _caseless_remove(array_keys($changes['set_headers']), $headers);
+        $headers = $changes['set_headers'] + $headers;
+    }
+
+    if (isset($changes['query'])) {
+        $uri = $uri->withQuery($changes['query']);
+    }
+
+    if ($request instanceof ServerRequestInterface) {
+        return (new ServerRequest(
+            isset($changes['method']) ? $changes['method'] : $request->getMethod(),
+            $uri,
+            $headers,
+            isset($changes['body']) ? $changes['body'] : $request->getBody(),
+            isset($changes['version'])
+                ? $changes['version']
+                : $request->getProtocolVersion(),
+            $request->getServerParams()
+        ))
+        ->withParsedBody($request->getParsedBody())
+        ->withQueryParams($request->getQueryParams())
+        ->withCookieParams($request->getCookieParams())
+        ->withUploadedFiles($request->getUploadedFiles());
+    }
+
+    return new Request(
+        isset($changes['method']) ? $changes['method'] : $request->getMethod(),
+        $uri,
+        $headers,
+        isset($changes['body']) ? $changes['body'] : $request->getBody(),
+        isset($changes['version'])
+            ? $changes['version']
+            : $request->getProtocolVersion()
+    );
+}
+
+/**
+ * Attempts to rewind a message body and throws an exception on failure.
+ *
+ * The body of the message will only be rewound if a call to `tell()` returns a
+ * value other than `0`.
+ *
+ * @param MessageInterface $message Message to rewind
+ *
+ * @throws \RuntimeException
+ */
+function rewind_body(MessageInterface $message)
+{
+    $body = $message->getBody();
+
+    if ($body->tell()) {
+        $body->rewind();
+    }
+}
+
+/**
+ * Safely opens a PHP stream resource using a filename.
+ *
+ * When fopen fails, PHP normally raises a warning. This function adds an
+ * error handler that checks for errors and throws an exception instead.
+ *
+ * @param string $filename File to open
+ * @param string $mode     Mode used to open the file
+ *
+ * @return resource
+ * @throws \RuntimeException if the file cannot be opened
+ */
+function try_fopen($filename, $mode)
+{
+    $ex = null;
+    set_error_handler(function () use ($filename, $mode, &$ex) {
+        $ex = new \RuntimeException(sprintf(
+            'Unable to open %s using mode %s: %s',
+            $filename,
+            $mode,
+            func_get_args()[1]
+        ));
+    });
+
+    $handle = fopen($filename, $mode);
+    restore_error_handler();
+
+    if ($ex) {
+        /** @var $ex \RuntimeException */
+        throw $ex;
+    }
+
+    return $handle;
+}
+
+/**
+ * Copy the contents of a stream into a string until the given number of
+ * bytes have been read.
+ *
+ * @param StreamInterface $stream Stream to read
+ * @param int             $maxLen Maximum number of bytes to read. Pass -1
+ *                                to read the entire stream.
+ * @return string
+ * @throws \RuntimeException on error.
+ */
+function copy_to_string(StreamInterface $stream, $maxLen = -1)
+{
+    $buffer = '';
+
+    if ($maxLen === -1) {
+        while (!$stream->eof()) {
+            $buf = $stream->read(1048576);
+            // Using a loose equality here to match on '' and false.
+            if ($buf == null) {
+                break;
+            }
+            $buffer .= $buf;
+        }
+        return $buffer;
+    }
+
+    $len = 0;
+    while (!$stream->eof() && $len < $maxLen) {
+        $buf = $stream->read($maxLen - $len);
+        // Using a loose equality here to match on '' and false.
+        if ($buf == null) {
+            break;
+        }
+        $buffer .= $buf;
+        $len = strlen($buffer);
+    }
+
+    return $buffer;
+}
+
+/**
+ * Copy the contents of a stream into another stream until the given number
+ * of bytes have been read.
+ *
+ * @param StreamInterface $source Stream to read from
+ * @param StreamInterface $dest   Stream to write to
+ * @param int             $maxLen Maximum number of bytes to read. Pass -1
+ *                                to read the entire stream.
+ *
+ * @throws \RuntimeException on error.
+ */
+function copy_to_stream(
+    StreamInterface $source,
+    StreamInterface $dest,
+    $maxLen = -1
+) {
+    $bufferSize = 8192;
+
+    if ($maxLen === -1) {
+        while (!$source->eof()) {
+            if (!$dest->write($source->read($bufferSize))) {
+                break;
+            }
+        }
+    } else {
+        $remaining = $maxLen;
+        while ($remaining > 0 && !$source->eof()) {
+            $buf = $source->read(min($bufferSize, $remaining));
+            $len = strlen($buf);
+            if (!$len) {
+                break;
+            }
+            $remaining -= $len;
+            $dest->write($buf);
+        }
+    }
+}
+
+/**
+ * Calculate a hash of a Stream
+ *
+ * @param StreamInterface $stream    Stream to calculate the hash for
+ * @param string          $algo      Hash algorithm (e.g. md5, crc32, etc)
+ * @param bool            $rawOutput Whether or not to use raw output
+ *
+ * @return string Returns the hash of the stream
+ * @throws \RuntimeException on error.
+ */
+function hash(
+    StreamInterface $stream,
+    $algo,
+    $rawOutput = false
+) {
+    $pos = $stream->tell();
+
+    if ($pos > 0) {
+        $stream->rewind();
+    }
+
+    $ctx = hash_init($algo);
+    while (!$stream->eof()) {
+        hash_update($ctx, $stream->read(1048576));
+    }
+
+    $out = hash_final($ctx, (bool) $rawOutput);
+    $stream->seek($pos);
+
+    return $out;
+}
+
+/**
+ * Read a line from the stream up to the maximum allowed buffer length
+ *
+ * @param StreamInterface $stream    Stream to read from
+ * @param int             $maxLength Maximum buffer length
+ *
+ * @return string
+ */
+function readline(StreamInterface $stream, $maxLength = null)
+{
+    $buffer = '';
+    $size = 0;
+
+    while (!$stream->eof()) {
+        // Using a loose equality here to match on '' and false.
+        if (null == ($byte = $stream->read(1))) {
+            return $buffer;
+        }
+        $buffer .= $byte;
+        // Break when a new line is found or the max length - 1 is reached
+        if ($byte === "\n" || ++$size === $maxLength - 1) {
+            break;
+        }
+    }
+
+    return $buffer;
+}
+
+/**
+ * Parses a request message string into a request object.
+ *
+ * @param string $message Request message string.
+ *
+ * @return Request
+ */
+function parse_request($message)
+{
+    $data = _parse_message($message);
+    $matches = [];
+    if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
+        throw new \InvalidArgumentException('Invalid request string');
+    }
+    $parts = explode(' ', $data['start-line'], 3);
+    $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
+
+    $request = new Request(
+        $parts[0],
+        $matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1],
+        $data['headers'],
+        $data['body'],
+        $version
+    );
+
+    return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
+}
+
+/**
+ * Parses a response message string into a response object.
+ *
+ * @param string $message Response message string.
+ *
+ * @return Response
+ */
+function parse_response($message)
+{
+    $data = _parse_message($message);
+    // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
+    // between status-code and reason-phrase is required. But browsers accept
+    // responses without space and reason as well.
+    if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
+        throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
+    }
+    $parts = explode(' ', $data['start-line'], 3);
+
+    return new Response(
+        $parts[1],
+        $data['headers'],
+        $data['body'],
+        explode('/', $parts[0])[1],
+        isset($parts[2]) ? $parts[2] : null
+    );
+}
+
+/**
+ * Parse a query string into an associative array.
+ *
+ * If multiple values are found for the same key, the value of that key
+ * value pair will become an array. This function does not parse nested
+ * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
+ * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
+ *
+ * @param string   $str         Query string to parse
+ * @param int|bool $urlEncoding How the query string is encoded
+ *
+ * @return array
+ */
+function parse_query($str, $urlEncoding = true)
+{
+    $result = [];
+
+    if ($str === '') {
+        return $result;
+    }
+
+    if ($urlEncoding === true) {
+        $decoder = function ($value) {
+            return rawurldecode(str_replace('+', ' ', $value));
+        };
+    } elseif ($urlEncoding === PHP_QUERY_RFC3986) {
+        $decoder = 'rawurldecode';
+    } elseif ($urlEncoding === PHP_QUERY_RFC1738) {
+        $decoder = 'urldecode';
+    } else {
+        $decoder = function ($str) { return $str; };
+    }
+
+    foreach (explode('&', $str) as $kvp) {
+        $parts = explode('=', $kvp, 2);
+        $key = $decoder($parts[0]);
+        $value = isset($parts[1]) ? $decoder($parts[1]) : null;
+        if (!isset($result[$key])) {
+            $result[$key] = $value;
+        } else {
+            if (!is_array($result[$key])) {
+                $result[$key] = [$result[$key]];
+            }
+            $result[$key][] = $value;
+        }
+    }
+
+    return $result;
+}
+
+/**
+ * Build a query string from an array of key value pairs.
+ *
+ * This function can use the return value of parse_query() to build a query
+ * string. This function does not modify the provided keys when an array is
+ * encountered (like http_build_query would).
+ *
+ * @param array     $params   Query string parameters.
+ * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
+ *                            to encode using RFC3986, or PHP_QUERY_RFC1738
+ *                            to encode using RFC1738.
+ * @return string
+ */
+function build_query(array $params, $encoding = PHP_QUERY_RFC3986)
+{
+    if (!$params) {
+        return '';
+    }
+
+    if ($encoding === false) {
+        $encoder = function ($str) { return $str; };
+    } elseif ($encoding === PHP_QUERY_RFC3986) {
+        $encoder = 'rawurlencode';
+    } elseif ($encoding === PHP_QUERY_RFC1738) {
+        $encoder = 'urlencode';
+    } else {
+        throw new \InvalidArgumentException('Invalid type');
+    }
+
+    $qs = '';
+    foreach ($params as $k => $v) {
+        $k = $encoder($k);
+        if (!is_array($v)) {
+            $qs .= $k;
+            if ($v !== null) {
+                $qs .= '=' . $encoder($v);
+            }
+            $qs .= '&';
+        } else {
+            foreach ($v as $vv) {
+                $qs .= $k;
+                if ($vv !== null) {
+                    $qs .= '=' . $encoder($vv);
+                }
+                $qs .= '&';
+            }
+        }
+    }
+
+    return $qs ? (string) substr($qs, 0, -1) : '';
+}
+
+/**
+ * Determines the mimetype of a file by looking at its extension.
+ *
+ * @param $filename
+ *
+ * @return null|string
+ */
+function mimetype_from_filename($filename)
+{
+    return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION));
+}
+
+/**
+ * Maps a file extensions to a mimetype.
+ *
+ * @param $extension string The file extension.
+ *
+ * @return string|null
+ * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
+ */
+function mimetype_from_extension($extension)
+{
+    static $mimetypes = [
+        '3gp' => 'video/3gpp',
+        '7z' => 'application/x-7z-compressed',
+        'aac' => 'audio/x-aac',
+        'ai' => 'application/postscript',
+        'aif' => 'audio/x-aiff',
+        'asc' => 'text/plain',
+        'asf' => 'video/x-ms-asf',
+        'atom' => 'application/atom+xml',
+        'avi' => 'video/x-msvideo',
+        'bmp' => 'image/bmp',
+        'bz2' => 'application/x-bzip2',
+        'cer' => 'application/pkix-cert',
+        'crl' => 'application/pkix-crl',
+        'crt' => 'application/x-x509-ca-cert',
+        'css' => 'text/css',
+        'csv' => 'text/csv',
+        'cu' => 'application/cu-seeme',
+        'deb' => 'application/x-debian-package',
+        'doc' => 'application/msword',
+        'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+        'dvi' => 'application/x-dvi',
+        'eot' => 'application/vnd.ms-fontobject',
+        'eps' => 'application/postscript',
+        'epub' => 'application/epub+zip',
+        'etx' => 'text/x-setext',
+        'flac' => 'audio/flac',
+        'flv' => 'video/x-flv',
+        'gif' => 'image/gif',
+        'gz' => 'application/gzip',
+        'htm' => 'text/html',
+        'html' => 'text/html',
+        'ico' => 'image/x-icon',
+        'ics' => 'text/calendar',
+        'ini' => 'text/plain',
+        'iso' => 'application/x-iso9660-image',
+        'jar' => 'application/java-archive',
+        'jpe' => 'image/jpeg',
+        'jpeg' => 'image/jpeg',
+        'jpg' => 'image/jpeg',
+        'js' => 'text/javascript',
+        'json' => 'application/json',
+        'latex' => 'application/x-latex',
+        'log' => 'text/plain',
+        'm4a' => 'audio/mp4',
+        'm4v' => 'video/mp4',
+        'mid' => 'audio/midi',
+        'midi' => 'audio/midi',
+        'mov' => 'video/quicktime',
+        'mkv' => 'video/x-matroska',
+        'mp3' => 'audio/mpeg',
+        'mp4' => 'video/mp4',
+        'mp4a' => 'audio/mp4',
+        'mp4v' => 'video/mp4',
+        'mpe' => 'video/mpeg',
+        'mpeg' => 'video/mpeg',
+        'mpg' => 'video/mpeg',
+        'mpg4' => 'video/mp4',
+        'oga' => 'audio/ogg',
+        'ogg' => 'audio/ogg',
+        'ogv' => 'video/ogg',
+        'ogx' => 'application/ogg',
+        'pbm' => 'image/x-portable-bitmap',
+        'pdf' => 'application/pdf',
+        'pgm' => 'image/x-portable-graymap',
+        'png' => 'image/png',
+        'pnm' => 'image/x-portable-anymap',
+        'ppm' => 'image/x-portable-pixmap',
+        'ppt' => 'application/vnd.ms-powerpoint',
+        'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+        'ps' => 'application/postscript',
+        'qt' => 'video/quicktime',
+        'rar' => 'application/x-rar-compressed',
+        'ras' => 'image/x-cmu-raster',
+        'rss' => 'application/rss+xml',
+        'rtf' => 'application/rtf',
+        'sgm' => 'text/sgml',
+        'sgml' => 'text/sgml',
+        'svg' => 'image/svg+xml',
+        'swf' => 'application/x-shockwave-flash',
+        'tar' => 'application/x-tar',
+        'tif' => 'image/tiff',
+        'tiff' => 'image/tiff',
+        'torrent' => 'application/x-bittorrent',
+        'ttf' => 'application/x-font-ttf',
+        'txt' => 'text/plain',
+        'wav' => 'audio/x-wav',
+        'webm' => 'video/webm',
+        'webp' => 'image/webp',
+        'wma' => 'audio/x-ms-wma',
+        'wmv' => 'video/x-ms-wmv',
+        'woff' => 'application/x-font-woff',
+        'wsdl' => 'application/wsdl+xml',
+        'xbm' => 'image/x-xbitmap',
+        'xls' => 'application/vnd.ms-excel',
+        'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+        'xml' => 'application/xml',
+        'xpm' => 'image/x-xpixmap',
+        'xwd' => 'image/x-xwindowdump',
+        'yaml' => 'text/yaml',
+        'yml' => 'text/yaml',
+        'zip' => 'application/zip',
+    ];
+
+    $extension = strtolower($extension);
+
+    return isset($mimetypes[$extension])
+        ? $mimetypes[$extension]
+        : null;
+}
+
+/**
+ * Parses an HTTP message into an associative array.
+ *
+ * The array contains the "start-line" key containing the start line of
+ * the message, "headers" key containing an associative array of header
+ * array values, and a "body" key containing the body of the message.
+ *
+ * @param string $message HTTP request or response to parse.
+ *
+ * @return array
+ * @internal
+ */
+function _parse_message($message)
+{
+    if (!$message) {
+        throw new \InvalidArgumentException('Invalid message');
+    }
+
+    $message = ltrim($message, "\r\n");
+
+    $messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
+
+    if ($messageParts === false || count($messageParts) !== 2) {
+        throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
+    }
+
+    list($rawHeaders, $body) = $messageParts;
+    $rawHeaders .= "\r\n"; // Put back the delimiter we split previously
+    $headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
+
+    if ($headerParts === false || count($headerParts) !== 2) {
+        throw new \InvalidArgumentException('Invalid message: Missing status line');
+    }
+
+    list($startLine, $rawHeaders) = $headerParts;
+
+    if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
+        // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
+        $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
+    }
+
+    /** @var array[] $headerLines */
+    $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
+
+    // If these aren't the same, then one line didn't match and there's an invalid header.
+    if ($count !== substr_count($rawHeaders, "\n")) {
+        // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
+        if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
+            throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
+        }
+
+        throw new \InvalidArgumentException('Invalid header syntax');
+    }
+
+    $headers = [];
+
+    foreach ($headerLines as $headerLine) {
+        $headers[$headerLine[1]][] = $headerLine[2];
+    }
+
+    return [
+        'start-line' => $startLine,
+        'headers' => $headers,
+        'body' => $body,
+    ];
+}
+
+/**
+ * Constructs a URI for an HTTP request message.
+ *
+ * @param string $path    Path from the start-line
+ * @param array  $headers Array of headers (each value an array).
+ *
+ * @return string
+ * @internal
+ */
+function _parse_request_uri($path, array $headers)
+{
+    $hostKey = array_filter(array_keys($headers), function ($k) {
+        return strtolower($k) === 'host';
+    });
+
+    // If no host is found, then a full URI cannot be constructed.
+    if (!$hostKey) {
+        return $path;
+    }
+
+    $host = $headers[reset($hostKey)][0];
+    $scheme = substr($host, -4) === ':443' ? 'https' : 'http';
+
+    return $scheme . '://' . $host . '/' . ltrim($path, '/');
+}
+
+/**
+ * Get a short summary of the message body
+ *
+ * Will return `null` if the response is not printable.
+ *
+ * @param MessageInterface $message    The message to get the body summary
+ * @param int              $truncateAt The maximum allowed size of the summary
+ *
+ * @return null|string
+ */
+function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
+{
+    $body = $message->getBody();
+
+    if (!$body->isSeekable() || !$body->isReadable()) {
+        return null;
+    }
+
+    $size = $body->getSize();
+
+    if ($size === 0) {
+        return null;
+    }
+
+    $summary = $body->read($truncateAt);
+    $body->rewind();
+
+    if ($size > $truncateAt) {
+        $summary .= ' (truncated...)';
+    }
+
+    // Matches any printable character, including unicode characters:
+    // letters, marks, numbers, punctuation, spacing, and separators.
+    if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
+        return null;
+    }
+
+    return $summary;
+}
+
+/** @internal */
+function _caseless_remove($keys, array $data)
+{
+    $result = [];
+
+    foreach ($keys as &$key) {
+        $key = strtolower($key);
+    }
+
+    foreach ($data as $k => $v) {
+        if (!in_array(strtolower($k), $keys)) {
+            $result[$k] = $v;
+        }
+    }
+
+    return $result;
+}
diff --git a/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/functions_include.php b/wcfsetup/install/files/lib/system/api/guzzlehttp/psr7/src/functions_include.php
new file mode 100644 (file)
index 0000000..96a4a83
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+// Don't redefine the functions if included multiple times.
+if (!function_exists('GuzzleHttp\Psr7\str')) {
+    require __DIR__ . '/functions.php';
+}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/LICENSE.md b/wcfsetup/install/files/lib/system/api/leafo/scssphp/LICENSE.md
deleted file mode 100644 (file)
index 2f5412f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2015 Leaf Corcoran, http://leafo.github.io/scssphp
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/README.md b/wcfsetup/install/files/lib/system/api/leafo/scssphp/README.md
deleted file mode 100644 (file)
index 53a4c7a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# scssphp
-### <http://leafo.github.io/scssphp>
-
-[![Build](https://travis-ci.org/leafo/scssphp.svg?branch=master)](http://travis-ci.org/leafo/scssphp)
-[![License](https://poser.pugx.org/leafo/scssphp/license.svg)](https://packagist.org/packages/leafo/scssphp)
-
-`scssphp` is a compiler for SCSS written in PHP.
-
-Checkout the homepage, <http://leafo.github.io/scssphp>, for directions on how to use.
-
-## Running Tests
-
-`scssphp` uses [PHPUnit](https://github.com/sebastianbergmann/phpunit) for testing.
-
-Run the following command from the root directory to run every test:
-
-    vendor/bin/phpunit tests
-
-There are several tests in the `tests/` directory:
-
-* `ApiTest.php` contains various unit tests that test the PHP interface.
-* `ExceptionTest.php` contains unit tests that test for exceptions thrown by the parser and compiler.
-* `FailingTest.php` contains tests reported in Github issues that demonstrate compatibility bugs.
-* `InputTest.php` compiles every `.scss` file in the `tests/inputs` directory
-  then compares to the respective `.css` file in the `tests/outputs` directory.
-* `ScssTest.php` extracts (ruby) `scss` tests from the `tests/scss_test.rb` file.
-* `ServerTest.php` contains functional tests for the `Server` class.
-
-When changing any of the tests in `tests/inputs`, the tests will most likely
-fail because the output has changed. Once you verify that the output is correct
-you can run the following command to rebuild all the tests:
-
-    BUILD=1 vendor/bin/phpunit tests
-
-This will compile all the tests, and save results into `tests/outputs`.
-
-To enable the `scss` compatibility tests:
-
-    TEST_SCSS_COMPAT=1 vendor/bin/phpunit tests
-
-## Coding Standard
-
-`scssphp` source conforms to [PSR2](http://www.php-fig.org/psr/psr-2/).
-
-Run the following command from the root directory to check the code for "sniffs".
-
-    vendor/bin/phpcs --standard=PSR2 bin src tests
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/bin/pscss b/wcfsetup/install/files/lib/system/api/leafo/scssphp/bin/pscss
deleted file mode 100644 (file)
index ce80e6a..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/usr/bin/env php
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2015 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-error_reporting(E_ALL);
-
-if (version_compare(PHP_VERSION, '5.4') < 0) {
-    die('Requires PHP 5.4 or above');
-}
-
-include __DIR__ . '/../scss.inc.php';
-
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Parser;
-use Leafo\ScssPhp\Version;
-
-$style = null;
-$loadPaths = null;
-$precision = null;
-$dumpTree = false;
-$inputFile = null;
-$changeDir = false;
-$debugInfo = false;
-$lineNumbers = false;
-$ignoreErrors = false;
-$encoding = false;
-$sourceMap = false;
-
-/**
- * Parse argument
- *
- * @param integer $i
- * @param array $options
- *
- * @return string|null
- */
-function parseArgument(&$i, $options) {
-    global $argc;
-    global $argv;
-
-    if (! preg_match('/^(?:' . implode('|', (array) $options) . ')=?(.*)/', $argv[$i], $matches)) {
-        return;
-    }
-
-    if (strlen($matches[1])) {
-        return $matches[1];
-    }
-
-    if ($i + 1 < $argc) {
-        $i++;
-
-        return $argv[$i];
-    }
-}
-
-for ($i = 1; $i < $argc; $i++) {
-    if ($argv[$i] === '-h' || $argv[$i] === '--help') {
-        $exe = $argv[0];
-
-        $HELP = <<<EOT
-Usage: $exe [options] [input-file]
-
-Options include:
-
-    -h, --help          Show this message
-    --continue-on-error Continue compilation (as best as possible) when error encountered
-    --debug-info        Annotate selectors with CSS referring to the source file and line number
-    -f=format           Set the output format (compact, compressed, crunched, expanded, or nested)
-    -i=path             Set import path
-    --iso8859-1         Use iso8859-1 encoding instead of utf-8 (default utf-8)
-    --line-numbers      Annotate selectors with comments referring to the source file and line number
-    -p=precision        Set decimal number precision (default 10)
-    --sourcemap         Create source map file
-    -T                  Dump formatted parse tree
-    -v, --version       Print the version
-
-EOT;
-        exit($HELP);
-    }
-
-    if ($argv[$i] === '-v' || $argv[$i] === '--version') {
-        exit(Version::VERSION . "\n");
-    }
-
-    if ($argv[$i] === '--continue-on-error') {
-        $ignoreErrors = true;
-        continue;
-    }
-
-    if ($argv[$i] === '--debug-info') {
-        $debugInfo = true;
-        continue;
-    }
-
-    if ($argv[$i] === '--iso8859-1') {
-        $encoding = 'iso8859-1';
-        continue;
-    }
-
-    if ($argv[$i] === '--line-numbers' || $argv[$i] === '--line-comments') {
-        $lineNumbers = true;
-        continue;
-    }
-
-    if ($argv[$i] === '--sourcemap') {
-        $sourceMap = true;
-        continue;
-    }
-
-    if ($argv[$i] === '-T') {
-        $dumpTree = true;
-        continue;
-    }
-
-    $value = parseArgument($i, array('-f', '--style'));
-
-    if (isset($value)) {
-        $style = $value;
-        continue;
-    }
-
-    $value = parseArgument($i, array('-i', '--load_paths'));
-
-    if (isset($value)) {
-        $loadPaths = $value;
-        continue;
-    }
-
-    $value = parseArgument($i, array('-p', '--precision'));
-
-    if (isset($value)) {
-        $precision = $value;
-        continue;
-    }
-
-    if (file_exists($argv[$i])) {
-        $inputFile = $argv[$i];
-        continue;
-    }
-}
-
-
-if ($inputFile) {
-    $data = file_get_contents($inputFile);
-
-    $newWorkingDir = dirname(realpath($inputFile));
-    $oldWorkingDir = getcwd();
-
-    if ($oldWorkingDir !== $newWorkingDir) {
-        $changeDir = chdir($newWorkingDir);
-        $inputFile = basename($inputFile);
-    }
-} else {
-    $data = '';
-
-    while (! feof(STDIN)) {
-        $data .= fread(STDIN, 8192);
-    }
-}
-
-if ($dumpTree) {
-    $parser = new Parser($inputFile);
-
-    print_r(json_decode(json_encode($parser->parse($data)), true));
-
-    exit();
-}
-
-$scss = new Compiler();
-
-if ($debugInfo) {
-    $scss->setLineNumberStyle(Compiler::DEBUG_INFO);
-}
-
-if ($lineNumbers) {
-    $scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
-}
-
-if ($ignoreErrors) {
-    $scss->setIgnoreErrors($ignoreErrors);
-}
-
-if ($loadPaths) {
-    $scss->setImportPaths(explode(PATH_SEPARATOR, $loadPaths));
-}
-
-if ($precision) {
-    $scss->setNumberPrecision($precision);
-}
-
-if ($style) {
-    $scss->setFormatter('Leafo\\ScssPhp\\Formatter\\' . ucfirst($style));
-}
-
-if ($sourceMap) {
-    $scss->setSourceMap(Compiler::SOURCE_MAP_INLINE);
-}
-
-if ($encoding) {
-    $scss->setEncoding($encoding);
-}
-
-echo $scss->compile($data, $inputFile);
-
-if ($changeDir) {
-    chdir($oldWorkingDir);
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/composer.json b/wcfsetup/install/files/lib/system/api/leafo/scssphp/composer.json
deleted file mode 100644 (file)
index 95118a3..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-    "name": "leafo/scssphp",
-    "type": "library",
-    "description": "scssphp is a compiler for SCSS written in PHP.",
-    "keywords": ["css", "stylesheet", "scss", "sass", "less"],
-    "homepage": "http://leafo.github.io/scssphp/",
-    "license": [
-        "MIT"
-    ],
-    "authors": [
-        {
-            "name": "Leaf Corcoran",
-            "email": "leafot@gmail.com",
-            "homepage": "http://leafo.net"
-        }
-    ],
-    "autoload": {
-        "psr-4": { "Leafo\\ScssPhp\\": "src/" }
-    },
-    "autoload-dev": {
-        "psr-4": { "Leafo\\ScssPhp\\Test\\": "tests/" }
-    },
-    "require": {
-        "php": ">=5.4.0"
-    },
-    "require-dev": {
-        "squizlabs/php_codesniffer": "~2.5",
-        "phpunit/phpunit": "~4.6"
-    },
-    "bin": ["bin/pscss"],
-    "archive": {
-        "exclude": [
-            "/Makefile",
-            "/.gitattributes",
-            "/.gitignore",
-            "/.travis.yml",
-            "/phpunit.xml.dist",
-            "/tests"
-        ]
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/example/Server.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/example/Server.php
deleted file mode 100644 (file)
index 54060b1..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2017 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Exception\ServerException;
-use Leafo\ScssPhp\Version;
-
-/**
- * Server
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Server
-{
-    /**
-     * @var boolean
-     */
-    private $showErrorsAsCSS;
-
-    /**
-     * @var string
-     */
-    private $dir;
-
-    /**
-     * @var string
-     */
-    private $cacheDir;
-
-    /**
-     * @var \Leafo\ScssPhp\Compiler
-     */
-    private $scss;
-
-    /**
-     * Join path components
-     *
-     * @param string $left  Path component, left of the directory separator
-     * @param string $right Path component, right of the directory separator
-     *
-     * @return string
-     */
-    protected function join($left, $right)
-    {
-        return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\');
-    }
-
-    /**
-     * Get name of requested .scss file
-     *
-     * @return string|null
-     */
-    protected function inputName()
-    {
-        switch (true) {
-            case isset($_GET['p']):
-                return $_GET['p'];
-            case isset($_SERVER['PATH_INFO']):
-                return $_SERVER['PATH_INFO'];
-            case isset($_SERVER['DOCUMENT_URI']):
-                return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
-        }
-    }
-
-    /**
-     * Get path to requested .scss file
-     *
-     * @return string
-     */
-    protected function findInput()
-    {
-        if (($input = $this->inputName())
-            && strpos($input, '..') === false
-            && substr($input, -5) === '.scss'
-        ) {
-            $name = $this->join($this->dir, $input);
-
-            if (is_file($name) && is_readable($name)) {
-                return $name;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Get path to cached .css file
-     *
-     * @return string
-     */
-    protected function cacheName($fname)
-    {
-        return $this->join($this->cacheDir, md5($fname) . '.css');
-    }
-
-    /**
-     * Get path to meta data
-     *
-     * @return string
-     */
-    protected function metadataName($out)
-    {
-        return $out . '.meta';
-    }
-
-    /**
-     * Determine whether .scss file needs to be re-compiled.
-     *
-     * @param string $out  Output path
-     * @param string $etag ETag
-     *
-     * @return boolean True if compile required.
-     */
-    protected function needsCompile($out, &$etag)
-    {
-        if (! is_file($out)) {
-            return true;
-        }
-
-        $mtime = filemtime($out);
-
-        $metadataName = $this->metadataName($out);
-
-        if (is_readable($metadataName)) {
-            $metadata = unserialize(file_get_contents($metadataName));
-
-            foreach ($metadata['imports'] as $import => $originalMtime) {
-                $currentMtime = filemtime($import);
-
-                if ($currentMtime !== $originalMtime || $currentMtime > $mtime) {
-                    return true;
-                }
-            }
-
-            $metaVars = crc32(serialize($this->scss->getVariables()));
-
-            if ($metaVars !== $metadata['vars']) {
-                return true;
-            }
-
-            $etag = $metadata['etag'];
-
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Get If-Modified-Since header from client request
-     *
-     * @return string|null
-     */
-    protected function getIfModifiedSinceHeader()
-    {
-        $modifiedSince = null;
-
-        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
-            $modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
-
-            if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) {
-                $modifiedSince = substr($modifiedSince, 0, $semicolonPos);
-            }
-        }
-
-        return $modifiedSince;
-    }
-
-    /**
-     * Get If-None-Match header from client request
-     *
-     * @return string|null
-     */
-    protected function getIfNoneMatchHeader()
-    {
-        $noneMatch = null;
-
-        if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
-            $noneMatch = $_SERVER['HTTP_IF_NONE_MATCH'];
-        }
-
-        return $noneMatch;
-    }
-
-    /**
-     * Compile .scss file
-     *
-     * @param string $in  Input path (.scss)
-     * @param string $out Output path (.css)
-     *
-     * @return array
-     */
-    protected function compile($in, $out)
-    {
-        $start   = microtime(true);
-        $css     = $this->scss->compile(file_get_contents($in), $in);
-        $elapsed = round((microtime(true) - $start), 4);
-
-        $v    = Version::VERSION;
-        $t    = gmdate('r');
-        $css  = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
-        $etag = md5($css);
-
-        file_put_contents($out, $css);
-        file_put_contents(
-            $this->metadataName($out),
-            serialize([
-                'etag'    => $etag,
-                'imports' => $this->scss->getParsedFiles(),
-                'vars'    => crc32(serialize($this->scss->getVariables())),
-            ])
-        );
-
-        return [$css, $etag];
-    }
-
-    /**
-     * Format error as a pseudo-element in CSS
-     *
-     * @param \Exception $error
-     *
-     * @return string
-     */
-    protected function createErrorCSS(\Exception $error)
-    {
-        $message = str_replace(
-            ["'", "\n"],
-            ["\\'", "\\A"],
-            $error->getfile() . ":\n\n" . $error->getMessage()
-        );
-
-        return "body { display: none !important; }
-                html:after {
-                    background: white;
-                    color: black;
-                    content: '$message';
-                    display: block !important;
-                    font-family: mono;
-                    padding: 1em;
-                    white-space: pre;
-                }";
-    }
-
-    /**
-     * Render errors as a pseudo-element within valid CSS, displaying the errors on any
-     * page that includes this CSS.
-     *
-     * @param boolean $show
-     */
-    public function showErrorsAsCSS($show = true)
-    {
-        $this->showErrorsAsCSS = $show;
-    }
-
-    /**
-     * Compile .scss file
-     *
-     * @param string $in  Input file (.scss)
-     * @param string $out Output file (.css) optional
-     *
-     * @return string|bool
-     *
-     * @throws \Leafo\ScssPhp\Exception\ServerException
-     */
-    public function compileFile($in, $out = null)
-    {
-        if (! is_readable($in)) {
-            throw new ServerException('load error: failed to find ' . $in);
-        }
-
-        $pi = pathinfo($in);
-
-        $this->scss->addImportPath($pi['dirname'] . '/');
-
-        $compiled = $this->scss->compile(file_get_contents($in), $in);
-
-        if ($out !== null) {
-            return file_put_contents($out, $compiled);
-        }
-
-        return $compiled;
-    }
-
-    /**
-     * Check if file need compiling
-     *
-     * @param string $in  Input file (.scss)
-     * @param string $out Output file (.css)
-     *
-     * @return bool
-     */
-    public function checkedCompile($in, $out)
-    {
-        if (! is_file($out) || filemtime($in) > filemtime($out)) {
-            $this->compileFile($in, $out);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Compile requested scss and serve css.  Outputs HTTP response.
-     *
-     * @param string $salt Prefix a string to the filename for creating the cache name hash
-     */
-    public function serve($salt = '')
-    {
-        $protocol = isset($_SERVER['SERVER_PROTOCOL'])
-            ? $_SERVER['SERVER_PROTOCOL']
-            : 'HTTP/1.0';
-
-        if ($input = $this->findInput()) {
-            $output = $this->cacheName($salt . $input);
-            $etag = $noneMatch = trim($this->getIfNoneMatchHeader(), '"');
-
-            if ($this->needsCompile($output, $etag)) {
-                try {
-                    list($css, $etag) = $this->compile($input, $output);
-
-                    $lastModified = gmdate('r', filemtime($output));
-
-                    header('Last-Modified: ' . $lastModified);
-                    header('Content-type: text/css');
-                    header('ETag: "' . $etag . '"');
-
-                    echo $css;
-                } catch (\Exception $e) {
-                    if ($this->showErrorsAsCSS) {
-                        header('Content-type: text/css');
-
-                        echo $this->createErrorCSS($e);
-                    } else {
-                        header($protocol . ' 500 Internal Server Error');
-                        header('Content-type: text/plain');
-
-                        echo 'Parse error: ' . $e->getMessage() . "\n";
-                    }
-                }
-
-                return;
-            }
-
-            header('X-SCSS-Cache: true');
-            header('Content-type: text/css');
-            header('ETag: "' . $etag . '"');
-
-            if ($etag === $noneMatch) {
-                header($protocol . ' 304 Not Modified');
-
-                return;
-            }
-
-            $modifiedSince = $this->getIfModifiedSinceHeader();
-            $mtime = filemtime($output);
-
-            if (strtotime($modifiedSince) === $mtime) {
-                header($protocol . ' 304 Not Modified');
-
-                return;
-            }
-
-            $lastModified  = gmdate('r', $mtime);
-            header('Last-Modified: ' . $lastModified);
-
-            echo file_get_contents($output);
-
-            return;
-        }
-
-        header($protocol . ' 404 Not Found');
-        header('Content-type: text/plain');
-
-        $v = Version::VERSION;
-        echo "/* INPUT NOT FOUND scss $v */\n";
-    }
-
-    /**
-     * Based on explicit input/output files does a full change check on cache before compiling.
-     *
-     * @param string  $in
-     * @param string  $out
-     * @param boolean $force
-     *
-     * @return string Compiled CSS results
-     *
-     * @throws \Leafo\ScssPhp\Exception\ServerException
-     */
-    public function checkedCachedCompile($in, $out, $force = false)
-    {
-        if (! is_file($in) || ! is_readable($in)) {
-            throw new ServerException('Invalid or unreadable input file specified.');
-        }
-
-        if (is_dir($out) || ! is_writable(file_exists($out) ? $out : dirname($out))) {
-            throw new ServerException('Invalid or unwritable output file specified.');
-        }
-
-        if ($force || $this->needsCompile($out, $etag)) {
-            list($css, $etag) = $this->compile($in, $out);
-        } else {
-            $css = file_get_contents($out);
-        }
-
-        return $css;
-    }
-
-    /**
-     * Execute scssphp on a .scss file or a scssphp cache structure
-     *
-     * The scssphp cache structure contains information about a specific
-     * scss file having been parsed. It can be used as a hint for future
-     * calls to determine whether or not a rebuild is required.
-     *
-     * The cache structure contains two important keys that may be used
-     * externally:
-     *
-     * compiled: The final compiled CSS
-     * updated: The time (in seconds) the CSS was last compiled
-     *
-     * The cache structure is a plain-ol' PHP associative array and can
-     * be serialized and unserialized without a hitch.
-     *
-     * @param mixed   $in    Input
-     * @param boolean $force Force rebuild?
-     *
-     * @return array scssphp cache structure
-     */
-    public function cachedCompile($in, $force = false)
-    {
-        // assume no root
-        $root = null;
-
-        if (is_string($in)) {
-            $root = $in;
-        } elseif (is_array($in) and isset($in['root'])) {
-            if ($force or ! isset($in['files'])) {
-                // If we are forcing a recompile or if for some reason the
-                // structure does not contain any file information we should
-                // specify the root to trigger a rebuild.
-                $root = $in['root'];
-            } elseif (isset($in['files']) and is_array($in['files'])) {
-                foreach ($in['files'] as $fname => $ftime) {
-                    if (! file_exists($fname) or filemtime($fname) > $ftime) {
-                        // One of the files we knew about previously has changed
-                        // so we should look at our incoming root again.
-                        $root = $in['root'];
-                        break;
-                    }
-                }
-            }
-        } else {
-            // TODO: Throw an exception? We got neither a string nor something
-            // that looks like a compatible lessphp cache structure.
-            return null;
-        }
-
-        if ($root !== null) {
-            // If we have a root value which means we should rebuild.
-            $out = [];
-            $out['root'] = $root;
-            $out['compiled'] = $this->compileFile($root);
-            $out['files'] = $this->scss->getParsedFiles();
-            $out['updated'] = time();
-            return $out;
-        } else {
-            // No changes, pass back the structure
-            // we were given initially.
-            return $in;
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param string                       $dir      Root directory to .scss files
-     * @param string                       $cacheDir Cache directory
-     * @param \Leafo\ScssPhp\Compiler|null $scss     SCSS compiler instance
-     */
-    public function __construct($dir, $cacheDir = null, $scss = null)
-    {
-        $this->dir = $dir;
-
-        if (! isset($cacheDir)) {
-            $cacheDir = $this->join($dir, 'scss_cache');
-        }
-
-        $this->cacheDir = $cacheDir;
-
-        if (! is_dir($this->cacheDir)) {
-            throw new ServerException('Cache directory doesn\'t exist: ' . $cacheDir);
-        }
-
-        if (! isset($scss)) {
-            $scss = new Compiler();
-            $scss->setImportPaths($this->dir);
-        }
-
-        $this->scss = $scss;
-        $this->showErrorsAsCSS = false;
-
-        date_default_timezone_set('UTC');
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/scss.inc.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/scss.inc.php
deleted file mode 100644 (file)
index d75ecb5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-if (version_compare(PHP_VERSION, '5.4') < 0) {
-    throw new \Exception('scssphp requires PHP 5.4 or above');
-}
-
-if (! class_exists('Leafo\ScssPhp\Version', false)) {
-    include_once __DIR__ . '/src/Base/Range.php';
-    include_once __DIR__ . '/src/Block.php';
-    include_once __DIR__ . '/src/Colors.php';
-    include_once __DIR__ . '/src/Compiler.php';
-    include_once __DIR__ . '/src/Compiler/Environment.php';
-    include_once __DIR__ . '/src/Exception/CompilerException.php';
-    include_once __DIR__ . '/src/Exception/ParserException.php';
-    include_once __DIR__ . '/src/Exception/RangeException.php';
-    include_once __DIR__ . '/src/Exception/ServerException.php';
-    include_once __DIR__ . '/src/Formatter.php';
-    include_once __DIR__ . '/src/Formatter/Compact.php';
-    include_once __DIR__ . '/src/Formatter/Compressed.php';
-    include_once __DIR__ . '/src/Formatter/Crunched.php';
-    include_once __DIR__ . '/src/Formatter/Debug.php';
-    include_once __DIR__ . '/src/Formatter/Expanded.php';
-    include_once __DIR__ . '/src/Formatter/Nested.php';
-    include_once __DIR__ . '/src/Formatter/OutputBlock.php';
-    include_once __DIR__ . '/src/Node.php';
-    include_once __DIR__ . '/src/Node/Number.php';
-    include_once __DIR__ . '/src/Parser.php';
-    include_once __DIR__ . '/src/SourceMap/Base64.php';
-    include_once __DIR__ . '/src/SourceMap/Base64VLQ.php';
-    include_once __DIR__ . '/src/SourceMap/SourceMapGenerator.php';
-    include_once __DIR__ . '/src/Type.php';
-    include_once __DIR__ . '/src/Util.php';
-    include_once __DIR__ . '/src/Version.php';
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Base/Range.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Base/Range.php
deleted file mode 100644 (file)
index 8bcc6ec..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2015-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Base;
-
-/**
- * Range
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Range
-{
-    public $first;
-    public $last;
-
-    /**
-     * Initialize range
-     *
-     * @param integer|float $first
-     * @param integer|float $last
-     */
-    public function __construct($first, $last)
-    {
-        $this->first = $first;
-        $this->last = $last;
-    }
-
-    /**
-     * Test for inclusion in range
-     *
-     * @param integer|float $value
-     *
-     * @return boolean
-     */
-    public function includes($value)
-    {
-        return $value >= $this->first && $value <= $this->last;
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Block.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Block.php
deleted file mode 100644 (file)
index 2edbc8a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-/**
- * Block
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Block
-{
-    /**
-     * @var string
-     */
-    public $type;
-
-    /**
-     * @var \Leafo\ScssPhp\Block
-     */
-    public $parent;
-
-    /**
-     * @var string
-     */
-    public $sourceName;
-
-    /**
-     * @var integer
-     */
-    public $sourceIndex;
-
-    /**
-     * @var integer
-     */
-    public $sourceLine;
-
-    /**
-     * @var integer
-     */
-    public $sourceColumn;
-
-    /**
-     * @var array
-     */
-    public $selectors;
-
-    /**
-     * @var array
-     */
-    public $comments;
-
-    /**
-     * @var array
-     */
-    public $children;
-    /**
-     * @var \Leafo\ScssPhp\Block
-     */
-    public $selfParent;
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Colors.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Colors.php
deleted file mode 100644 (file)
index 2314ea5..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-/**
- * CSS Colors
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Colors
-{
-    /**
-     * CSS Colors
-     *
-     * @see http://www.w3.org/TR/css3-color
-     *
-     * @var array
-     */
-    public static $cssColors = [
-        'aliceblue' => '240,248,255',
-        'antiquewhite' => '250,235,215',
-        'aqua' => '0,255,255',
-        'aquamarine' => '127,255,212',
-        'azure' => '240,255,255',
-        'beige' => '245,245,220',
-        'bisque' => '255,228,196',
-        'black' => '0,0,0',
-        'blanchedalmond' => '255,235,205',
-        'blue' => '0,0,255',
-        'blueviolet' => '138,43,226',
-        'brown' => '165,42,42',
-        'burlywood' => '222,184,135',
-        'cadetblue' => '95,158,160',
-        'chartreuse' => '127,255,0',
-        'chocolate' => '210,105,30',
-        'coral' => '255,127,80',
-        'cornflowerblue' => '100,149,237',
-        'cornsilk' => '255,248,220',
-        'crimson' => '220,20,60',
-        'cyan' => '0,255,255',
-        'darkblue' => '0,0,139',
-        'darkcyan' => '0,139,139',
-        'darkgoldenrod' => '184,134,11',
-        'darkgray' => '169,169,169',
-        'darkgreen' => '0,100,0',
-        'darkgrey' => '169,169,169',
-        'darkkhaki' => '189,183,107',
-        'darkmagenta' => '139,0,139',
-        'darkolivegreen' => '85,107,47',
-        'darkorange' => '255,140,0',
-        'darkorchid' => '153,50,204',
-        'darkred' => '139,0,0',
-        'darksalmon' => '233,150,122',
-        'darkseagreen' => '143,188,143',
-        'darkslateblue' => '72,61,139',
-        'darkslategray' => '47,79,79',
-        'darkslategrey' => '47,79,79',
-        'darkturquoise' => '0,206,209',
-        'darkviolet' => '148,0,211',
-        'deeppink' => '255,20,147',
-        'deepskyblue' => '0,191,255',
-        'dimgray' => '105,105,105',
-        'dimgrey' => '105,105,105',
-        'dodgerblue' => '30,144,255',
-        'firebrick' => '178,34,34',
-        'floralwhite' => '255,250,240',
-        'forestgreen' => '34,139,34',
-        'fuchsia' => '255,0,255',
-        'gainsboro' => '220,220,220',
-        'ghostwhite' => '248,248,255',
-        'gold' => '255,215,0',
-        'goldenrod' => '218,165,32',
-        'gray' => '128,128,128',
-        'green' => '0,128,0',
-        'greenyellow' => '173,255,47',
-        'grey' => '128,128,128',
-        'honeydew' => '240,255,240',
-        'hotpink' => '255,105,180',
-        'indianred' => '205,92,92',
-        'indigo' => '75,0,130',
-        'ivory' => '255,255,240',
-        'khaki' => '240,230,140',
-        'lavender' => '230,230,250',
-        'lavenderblush' => '255,240,245',
-        'lawngreen' => '124,252,0',
-        'lemonchiffon' => '255,250,205',
-        'lightblue' => '173,216,230',
-        'lightcoral' => '240,128,128',
-        'lightcyan' => '224,255,255',
-        'lightgoldenrodyellow' => '250,250,210',
-        'lightgray' => '211,211,211',
-        'lightgreen' => '144,238,144',
-        'lightgrey' => '211,211,211',
-        'lightpink' => '255,182,193',
-        'lightsalmon' => '255,160,122',
-        'lightseagreen' => '32,178,170',
-        'lightskyblue' => '135,206,250',
-        'lightslategray' => '119,136,153',
-        'lightslategrey' => '119,136,153',
-        'lightsteelblue' => '176,196,222',
-        'lightyellow' => '255,255,224',
-        'lime' => '0,255,0',
-        'limegreen' => '50,205,50',
-        'linen' => '250,240,230',
-        'magenta' => '255,0,255',
-        'maroon' => '128,0,0',
-        'mediumaquamarine' => '102,205,170',
-        'mediumblue' => '0,0,205',
-        'mediumorchid' => '186,85,211',
-        'mediumpurple' => '147,112,219',
-        'mediumseagreen' => '60,179,113',
-        'mediumslateblue' => '123,104,238',
-        'mediumspringgreen' => '0,250,154',
-        'mediumturquoise' => '72,209,204',
-        'mediumvioletred' => '199,21,133',
-        'midnightblue' => '25,25,112',
-        'mintcream' => '245,255,250',
-        'mistyrose' => '255,228,225',
-        'moccasin' => '255,228,181',
-        'navajowhite' => '255,222,173',
-        'navy' => '0,0,128',
-        'oldlace' => '253,245,230',
-        'olive' => '128,128,0',
-        'olivedrab' => '107,142,35',
-        'orange' => '255,165,0',
-        'orangered' => '255,69,0',
-        'orchid' => '218,112,214',
-        'palegoldenrod' => '238,232,170',
-        'palegreen' => '152,251,152',
-        'paleturquoise' => '175,238,238',
-        'palevioletred' => '219,112,147',
-        'papayawhip' => '255,239,213',
-        'peachpuff' => '255,218,185',
-        'peru' => '205,133,63',
-        'pink' => '255,192,203',
-        'plum' => '221,160,221',
-        'powderblue' => '176,224,230',
-        'purple' => '128,0,128',
-        'rebeccapurple' => '102,51,153',
-        'red' => '255,0,0',
-        'rosybrown' => '188,143,143',
-        'royalblue' => '65,105,225',
-        'saddlebrown' => '139,69,19',
-        'salmon' => '250,128,114',
-        'sandybrown' => '244,164,96',
-        'seagreen' => '46,139,87',
-        'seashell' => '255,245,238',
-        'sienna' => '160,82,45',
-        'silver' => '192,192,192',
-        'skyblue' => '135,206,235',
-        'slateblue' => '106,90,205',
-        'slategray' => '112,128,144',
-        'slategrey' => '112,128,144',
-        'snow' => '255,250,250',
-        'springgreen' => '0,255,127',
-        'steelblue' => '70,130,180',
-        'tan' => '210,180,140',
-        'teal' => '0,128,128',
-        'thistle' => '216,191,216',
-        'tomato' => '255,99,71',
-        'transparent' => '0,0,0,0',
-        'turquoise' => '64,224,208',
-        'violet' => '238,130,238',
-        'wheat' => '245,222,179',
-        'white' => '255,255,255',
-        'whitesmoke' => '245,245,245',
-        'yellow' => '255,255,0',
-        'yellowgreen' => '154,205,50',
-    ];
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Compiler.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Compiler.php
deleted file mode 100644 (file)
index d547c15..0000000
+++ /dev/null
@@ -1,5415 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-use Leafo\ScssPhp\Base\Range;
-use Leafo\ScssPhp\Block;
-use Leafo\ScssPhp\Colors;
-use Leafo\ScssPhp\Compiler\Environment;
-use Leafo\ScssPhp\Exception\CompilerException;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-use Leafo\ScssPhp\Node;
-use Leafo\ScssPhp\SourceMap\SourceMapGenerator;
-use Leafo\ScssPhp\Type;
-use Leafo\ScssPhp\Parser;
-use Leafo\ScssPhp\Util;
-
-/**
- * The scss compiler and parser.
- *
- * Converting SCSS to CSS is a three stage process. The incoming file is parsed
- * by `Parser` into a syntax tree, then it is compiled into another tree
- * representing the CSS structure by `Compiler`. The CSS tree is fed into a
- * formatter, like `Formatter` which then outputs CSS as a string.
- *
- * During the first compile, all values are *reduced*, which means that their
- * types are brought to the lowest form before being dump as strings. This
- * handles math equations, variable dereferences, and the like.
- *
- * The `compile` function of `Compiler` is the entry point.
- *
- * In summary:
- *
- * The `Compiler` class creates an instance of the parser, feeds it SCSS code,
- * then transforms the resulting tree to a CSS tree. This class also holds the
- * evaluation context, such as all available mixins and variables at any given
- * time.
- *
- * The `Parser` class is only concerned with parsing its input.
- *
- * The `Formatter` takes a CSS tree, and dumps it to a formatted string,
- * handling things like indentation.
- */
-
-/**
- * SCSS compiler
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Compiler
-{
-    const LINE_COMMENTS = 1;
-    const DEBUG_INFO    = 2;
-
-    const WITH_RULE     = 1;
-    const WITH_MEDIA    = 2;
-    const WITH_SUPPORTS = 4;
-    const WITH_ALL      = 7;
-
-    const SOURCE_MAP_NONE   = 0;
-    const SOURCE_MAP_INLINE = 1;
-    const SOURCE_MAP_FILE   = 2;
-
-    /**
-     * @var array
-     */
-    static protected $operatorNames = [
-        '+'   => 'add',
-        '-'   => 'sub',
-        '*'   => 'mul',
-        '/'   => 'div',
-        '%'   => 'mod',
-
-        '=='  => 'eq',
-        '!='  => 'neq',
-        '<'   => 'lt',
-        '>'   => 'gt',
-
-        '<='  => 'lte',
-        '>='  => 'gte',
-        '<=>' => 'cmp',
-    ];
-
-    /**
-     * @var array
-     */
-    static protected $namespaces = [
-        'special'  => '%',
-        'mixin'    => '@',
-        'function' => '^',
-    ];
-
-    static public $true = [Type::T_KEYWORD, 'true'];
-    static public $false = [Type::T_KEYWORD, 'false'];
-    static public $null = [Type::T_NULL];
-    static public $nullString = [Type::T_STRING, '', []];
-    static public $defaultValue = [Type::T_KEYWORD, ''];
-    static public $selfSelector = [Type::T_SELF];
-    static public $emptyList = [Type::T_LIST, '', []];
-    static public $emptyMap = [Type::T_MAP, [], []];
-    static public $emptyString = [Type::T_STRING, '"', []];
-    static public $with = [Type::T_KEYWORD, 'with'];
-    static public $without = [Type::T_KEYWORD, 'without'];
-
-    protected $importPaths = [''];
-    protected $importCache = [];
-    protected $importedFiles = [];
-    protected $userFunctions = [];
-    protected $registeredVars = [];
-    protected $registeredFeatures = [
-        'extend-selector-pseudoclass' => false,
-        'at-error'                    => true,
-        'units-level-3'               => false,
-        'global-variable-shadowing'   => false,
-    ];
-
-    protected $encoding = null;
-    protected $lineNumberStyle = null;
-
-    protected $sourceMap = self::SOURCE_MAP_NONE;
-    protected $sourceMapOptions = [];
-
-    /**
-     * @var string|\Leafo\ScssPhp\Formatter
-     */
-    protected $formatter = 'Leafo\ScssPhp\Formatter\Nested';
-
-    protected $rootEnv;
-    protected $rootBlock;
-
-    /**
-     * @var \Leafo\ScssPhp\Compiler\Environment
-     */
-    protected $env;
-    protected $scope;
-    protected $storeEnv;
-    protected $charsetSeen;
-    protected $sourceNames;
-
-    protected $indentLevel;
-    protected $commentsSeen;
-    protected $extends;
-    protected $extendsMap;
-    protected $parsedFiles;
-    protected $parser;
-    protected $sourceIndex;
-    protected $sourceLine;
-    protected $sourceColumn;
-    protected $stderr;
-    protected $shouldEvaluate;
-    protected $ignoreErrors;
-
-    /**
-     * Constructor
-     */
-    public function __construct()
-    {
-        $this->parsedFiles = [];
-        $this->sourceNames = [];
-    }
-
-    /**
-     * Compile scss
-     *
-     * @api
-     *
-     * @param string $code
-     * @param string $path
-     *
-     * @return string
-     */
-    public function compile($code, $path = null)
-    {
-        $this->indentLevel    = -1;
-        $this->commentsSeen   = [];
-        $this->extends        = [];
-        $this->extendsMap     = [];
-        $this->sourceIndex    = null;
-        $this->sourceLine     = null;
-        $this->sourceColumn   = null;
-        $this->env            = null;
-        $this->scope          = null;
-        $this->storeEnv       = null;
-        $this->charsetSeen    = null;
-        $this->shouldEvaluate = null;
-        $this->stderr         = fopen('php://stderr', 'w');
-
-        $this->parser = $this->parserFactory($path);
-        $tree = $this->parser->parse($code);
-        $this->parser = null;
-
-        $this->formatter = new $this->formatter();
-        $this->rootBlock = null;
-        $this->rootEnv   = $this->pushEnv($tree);
-
-        $this->injectVariables($this->registeredVars);
-        $this->compileRoot($tree);
-        $this->popEnv();
-
-        $sourceMapGenerator = null;
-
-        if ($this->sourceMap) {
-            if (is_object($this->sourceMap) && $this->sourceMap instanceof SourceMapGenerator) {
-                $sourceMapGenerator = $this->sourceMap;
-                $this->sourceMap = self::SOURCE_MAP_FILE;
-            } elseif ($this->sourceMap !== self::SOURCE_MAP_NONE) {
-                $sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions);
-            }
-        }
-
-        $out = $this->formatter->format($this->scope, $sourceMapGenerator);
-
-        if (! empty($out) && $this->sourceMap && $this->sourceMap !== self::SOURCE_MAP_NONE) {
-            $sourceMap    = $sourceMapGenerator->generateJson();
-            $sourceMapUrl = null;
-
-            switch ($this->sourceMap) {
-                case self::SOURCE_MAP_INLINE:
-                    $sourceMapUrl = sprintf('data:application/json,%s', Util::encodeURIComponent($sourceMap));
-                    break;
-
-                case self::SOURCE_MAP_FILE:
-                    $sourceMapUrl = $sourceMapGenerator->saveMap($sourceMap);
-                    break;
-            }
-
-            $out .= sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl);
-        }
-
-        return $out;
-    }
-
-    /**
-     * Instantiate parser
-     *
-     * @param string $path
-     *
-     * @return \Leafo\ScssPhp\Parser
-     */
-    protected function parserFactory($path)
-    {
-        $parser = new Parser($path, count($this->sourceNames), $this->encoding);
-
-        $this->sourceNames[] = $path;
-        $this->addParsedFile($path);
-
-        return $parser;
-    }
-
-    /**
-     * Is self extend?
-     *
-     * @param array $target
-     * @param array $origin
-     *
-     * @return boolean
-     */
-    protected function isSelfExtend($target, $origin)
-    {
-        foreach ($origin as $sel) {
-            if (in_array($target, $sel)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Push extends
-     *
-     * @param array     $target
-     * @param array     $origin
-     * @param \stdClass $block
-     */
-    protected function pushExtends($target, $origin, $block)
-    {
-        if ($this->isSelfExtend($target, $origin)) {
-            return;
-        }
-
-        $i = count($this->extends);
-        $this->extends[] = [$target, $origin, $block];
-
-        foreach ($target as $part) {
-            if (isset($this->extendsMap[$part])) {
-                $this->extendsMap[$part][] = $i;
-            } else {
-                $this->extendsMap[$part] = [$i];
-            }
-        }
-    }
-
-    /**
-     * Make output block
-     *
-     * @param string $type
-     * @param array  $selectors
-     *
-     * @return \Leafo\ScssPhp\Formatter\OutputBlock
-     */
-    protected function makeOutputBlock($type, $selectors = null)
-    {
-        $out = new OutputBlock;
-        $out->type         = $type;
-        $out->lines        = [];
-        $out->children     = [];
-        $out->parent       = $this->scope;
-        $out->selectors    = $selectors;
-        $out->depth        = $this->env->depth;
-
-        if ($this->env->block instanceof Block) {
-            $out->sourceName   = $this->env->block->sourceName;
-            $out->sourceLine   = $this->env->block->sourceLine;
-            $out->sourceColumn = $this->env->block->sourceColumn;
-        } else {
-            $out->sourceName   = null;
-            $out->sourceLine   = null;
-            $out->sourceColumn = null;
-        }
-
-        return $out;
-    }
-
-    /**
-     * Compile root
-     *
-     * @param \Leafo\ScssPhp\Block $rootBlock
-     */
-    protected function compileRoot(Block $rootBlock)
-    {
-        $this->rootBlock = $this->scope = $this->makeOutputBlock(Type::T_ROOT);
-
-        $this->compileChildrenNoReturn($rootBlock->children, $this->scope);
-        $this->flattenSelectors($this->scope);
-        $this->missingSelectors();
-    }
-
-    /**
-     * Report missing selectors
-     */
-    protected function missingSelectors()
-    {
-        foreach ($this->extends as $extend) {
-            if (isset($extend[3])) {
-                continue;
-            }
-
-            list($target, $origin, $block) = $extend;
-
-            // ignore if !optional
-            if ($block[2]) {
-                continue;
-            }
-
-            $target = implode(' ', $target);
-            $origin = $this->collapseSelectors($origin);
-
-            $this->sourceLine = $block[Parser::SOURCE_LINE];
-            $this->throwError("\"$origin\" failed to @extend \"$target\". The selector \"$target\" was not found.");
-        }
-    }
-
-    /**
-     * Flatten selectors
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
-     * @param string                               $parentKey
-     */
-    protected function flattenSelectors(OutputBlock $block, $parentKey = null)
-    {
-        if ($block->selectors) {
-            $selectors = [];
-
-            foreach ($block->selectors as $s) {
-                $selectors[] = $s;
-
-                if (! is_array($s)) {
-                    continue;
-                }
-
-                // check extends
-                if (! empty($this->extendsMap)) {
-                    $this->matchExtends($s, $selectors);
-
-                    // remove duplicates
-                    array_walk($selectors, function (&$value) {
-                        $value = serialize($value);
-                    });
-
-                    $selectors = array_unique($selectors);
-
-                    array_walk($selectors, function (&$value) {
-                        $value = unserialize($value);
-                    });
-                }
-            }
-
-            $block->selectors = [];
-            $placeholderSelector = false;
-
-            foreach ($selectors as $selector) {
-                if ($this->hasSelectorPlaceholder($selector)) {
-                    $placeholderSelector = true;
-                    continue;
-                }
-
-                $block->selectors[] = $this->compileSelector($selector);
-            }
-
-            if ($placeholderSelector && 0 === count($block->selectors) && null !== $parentKey) {
-                unset($block->parent->children[$parentKey]);
-
-                return;
-            }
-        }
-
-        foreach ($block->children as $key => $child) {
-            $this->flattenSelectors($child, $key);
-        }
-    }
-
-    /**
-     * Match extends
-     *
-     * @param array   $selector
-     * @param array   $out
-     * @param integer $from
-     * @param boolean $initial
-     */
-    protected function matchExtends($selector, &$out, $from = 0, $initial = true)
-    {
-        foreach ($selector as $i => $part) {
-            if ($i < $from) {
-                continue;
-            }
-
-            if ($this->matchExtendsSingle($part, $origin)) {
-                $after = array_slice($selector, $i + 1);
-                $before = array_slice($selector, 0, $i);
-
-                list($before, $nonBreakableBefore) = $this->extractRelationshipFromFragment($before);
-
-                foreach ($origin as $new) {
-                    $k = 0;
-
-                    // remove shared parts
-                    if ($initial) {
-                        while ($k < $i && isset($new[$k]) && $selector[$k] === $new[$k]) {
-                            $k++;
-                        }
-                    }
-
-                    $replacement = [];
-                    $tempReplacement = $k > 0 ? array_slice($new, $k) : $new;
-
-                    for ($l = count($tempReplacement) - 1; $l >= 0; $l--) {
-                        $slice = [];
-                        foreach ($tempReplacement[$l] as $chunk) {
-                            if (!in_array($chunk, $slice)) {
-                                $slice[] = $chunk;
-                            }
-                        }
-                        array_unshift($replacement, $slice);
-
-                        if (! $this->isImmediateRelationshipCombinator(end($slice))) {
-                            break;
-                        }
-                    }
-
-                    $afterBefore = $l != 0 ? array_slice($tempReplacement, 0, $l) : [];
-
-                    // Merge shared direct relationships.
-                    $mergedBefore = $this->mergeDirectRelationships($afterBefore, $nonBreakableBefore);
-
-                    $result = array_merge(
-                        $before,
-                        $mergedBefore,
-                        $replacement,
-                        $after
-                    );
-
-                    if ($result === $selector) {
-                        continue;
-                    }
-
-                    $out[] = $result;
-
-                    // recursively check for more matches
-                    $this->matchExtends($result, $out, count($before) + count($mergedBefore), false);
-
-                    // selector sequence merging
-                    if (! empty($before) && count($new) > 1) {
-                        $sharedParts = $k > 0 ? array_slice($before, 0, $k) : [];
-                        $postSharedParts = $k > 0 ? array_slice($before, $k) : $before;
-
-                        list($injectBetweenSharedParts, $nonBreakable2) = $this->extractRelationshipFromFragment($afterBefore);
-
-                        $result2 = array_merge(
-                            $sharedParts,
-                            $injectBetweenSharedParts,
-                            $postSharedParts,
-                            $nonBreakable2,
-                            $nonBreakableBefore,
-                            $replacement,
-                            $after
-                        );
-
-                        $out[] = $result2;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Match extends single
-     *
-     * @param array $rawSingle
-     * @param array $outOrigin
-     *
-     * @return boolean
-     */
-    protected function matchExtendsSingle($rawSingle, &$outOrigin)
-    {
-        $counts = [];
-        $single = [];
-
-        foreach ($rawSingle as $part) {
-            // matches Number
-            if (! is_string($part)) {
-                return false;
-            }
-
-            if (! preg_match('/^[\[.:#%]/', $part) && count($single)) {
-                $single[count($single) - 1] .= $part;
-            } else {
-                $single[] = $part;
-            }
-        }
-
-        $extendingDecoratedTag = false;
-
-        if (count($single) > 1) {
-            $matches = null;
-            $extendingDecoratedTag = preg_match('/^[a-z0-9]+$/i', $single[0], $matches) ? $matches[0] : false;
-        }
-
-        foreach ($single as $part) {
-            if (isset($this->extendsMap[$part])) {
-                foreach ($this->extendsMap[$part] as $idx) {
-                    $counts[$idx] = isset($counts[$idx]) ? $counts[$idx] + 1 : 1;
-                }
-            }
-        }
-
-        $outOrigin = [];
-        $found = false;
-
-        foreach ($counts as $idx => $count) {
-            list($target, $origin, /* $block */) = $this->extends[$idx];
-
-            // check count
-            if ($count !== count($target)) {
-                continue;
-            }
-
-            $this->extends[$idx][3] = true;
-
-            $rem = array_diff($single, $target);
-
-            foreach ($origin as $j => $new) {
-                // prevent infinite loop when target extends itself
-                if ($this->isSelfExtend($single, $origin)) {
-                    return false;
-                }
-
-                $replacement = end($new);
-
-                // Extending a decorated tag with another tag is not possible.
-                if ($extendingDecoratedTag && $replacement[0] != $extendingDecoratedTag &&
-                    preg_match('/^[a-z0-9]+$/i', $replacement[0])
-                ) {
-                    unset($origin[$j]);
-                    continue;
-                }
-
-                $combined = $this->combineSelectorSingle($replacement, $rem);
-
-                if (count(array_diff($combined, $origin[$j][count($origin[$j]) - 1]))) {
-                    $origin[$j][count($origin[$j]) - 1] = $combined;
-                }
-            }
-
-            $outOrigin = array_merge($outOrigin, $origin);
-
-            $found = true;
-        }
-
-        return $found;
-    }
-
-
-    /**
-     * Extract a relationship from the fragment.
-     *
-     * When extracting the last portion of a selector we will be left with a
-     * fragment which may end with a direction relationship combinator. This
-     * method will extract the relationship fragment and return it along side
-     * the rest.
-     *
-     * @param array $fragment The selector fragment maybe ending with a direction relationship combinator.
-     * @return array The selector without the relationship fragment if any, the relationship fragment.
-     */
-    protected function extractRelationshipFromFragment(array $fragment)
-    {
-        $parents = [];
-        $children = [];
-        $j = $i = count($fragment);
-
-        for (;;) {
-            $children = $j != $i ? array_slice($fragment, $j, $i - $j) : [];
-            $parents = array_slice($fragment, 0, $j);
-            $slice = end($parents);
-
-            if (empty($slice) || ! $this->isImmediateRelationshipCombinator($slice[0])) {
-                break;
-            }
-
-            $j -= 2;
-        }
-
-        return [$parents, $children];
-    }
-
-    /**
-     * Combine selector single
-     *
-     * @param array $base
-     * @param array $other
-     *
-     * @return array
-     */
-    protected function combineSelectorSingle($base, $other)
-    {
-        $tag = [];
-        $out = [];
-        $wasTag = true;
-
-        foreach ([$base, $other] as $single) {
-            foreach ($single as $part) {
-                if (preg_match('/^[\[.:#]/', $part)) {
-                    $out[] = $part;
-                    $wasTag = false;
-                } elseif (preg_match('/^[^_-]/', $part)) {
-                    $tag[] = $part;
-                    $wasTag = true;
-                } elseif ($wasTag) {
-                    $tag[count($tag) - 1] .= $part;
-                } else {
-                    $out[count($out) - 1] .= $part;
-                }
-            }
-        }
-
-        if (count($tag)) {
-            array_unshift($out, $tag[0]);
-        }
-
-        return $out;
-    }
-
-    /**
-     * Compile media
-     *
-     * @param \Leafo\ScssPhp\Block $media
-     */
-    protected function compileMedia(Block $media)
-    {
-        $this->pushEnv($media);
-
-        $mediaQuery = $this->compileMediaQuery($this->multiplyMedia($this->env));
-
-        if (! empty($mediaQuery)) {
-            $this->scope = $this->makeOutputBlock(Type::T_MEDIA, [$mediaQuery]);
-
-            $parentScope = $this->mediaParent($this->scope);
-            $parentScope->children[] = $this->scope;
-
-            // top level properties in a media cause it to be wrapped
-            $needsWrap = false;
-
-            foreach ($media->children as $child) {
-                $type = $child[0];
-
-                if ($type !== Type::T_BLOCK &&
-                    $type !== Type::T_MEDIA &&
-                    $type !== Type::T_DIRECTIVE &&
-                    $type !== Type::T_IMPORT
-                ) {
-                    $needsWrap = true;
-                    break;
-                }
-            }
-
-            if ($needsWrap) {
-                $wrapped = new Block;
-                $wrapped->sourceName   = $media->sourceName;
-                $wrapped->sourceIndex  = $media->sourceIndex;
-                $wrapped->sourceLine   = $media->sourceLine;
-                $wrapped->sourceColumn = $media->sourceColumn;
-                $wrapped->selectors    = [];
-                $wrapped->comments     = [];
-                $wrapped->parent       = $media;
-                $wrapped->children     = $media->children;
-
-                $media->children = [[Type::T_BLOCK, $wrapped]];
-            }
-
-            $this->compileChildrenNoReturn($media->children, $this->scope);
-
-            $this->scope = $this->scope->parent;
-        }
-
-        $this->popEnv();
-    }
-
-    /**
-     * Media parent
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $scope
-     *
-     * @return \Leafo\ScssPhp\Formatter\OutputBlock
-     */
-    protected function mediaParent(OutputBlock $scope)
-    {
-        while (! empty($scope->parent)) {
-            if (! empty($scope->type) && $scope->type !== Type::T_MEDIA) {
-                break;
-            }
-
-            $scope = $scope->parent;
-        }
-
-        return $scope;
-    }
-
-    /**
-     * Compile directive
-     *
-     * @param \Leafo\ScssPhp\Block $block
-     */
-    protected function compileDirective(Block $block)
-    {
-        $s = '@' . $block->name;
-
-        if (! empty($block->value)) {
-            $s .= ' ' . $this->compileValue($block->value);
-        }
-
-        if ($block->name === 'keyframes' || substr($block->name, -10) === '-keyframes') {
-            $this->compileKeyframeBlock($block, [$s]);
-        } else {
-            $this->compileNestedBlock($block, [$s]);
-        }
-    }
-
-    /**
-     * Compile at-root
-     *
-     * @param \Leafo\ScssPhp\Block $block
-     */
-    protected function compileAtRoot(Block $block)
-    {
-        $env     = $this->pushEnv($block);
-        $envs    = $this->compactEnv($env);
-        $without = isset($block->with) ? $this->compileWith($block->with) : static::WITH_RULE;
-
-        // wrap inline selector
-        if ($block->selector) {
-            $wrapped = new Block;
-            $wrapped->sourceName   = $block->sourceName;
-            $wrapped->sourceIndex  = $block->sourceIndex;
-            $wrapped->sourceLine   = $block->sourceLine;
-            $wrapped->sourceColumn = $block->sourceColumn;
-            $wrapped->selectors    = $block->selector;
-            $wrapped->comments     = [];
-            $wrapped->parent       = $block;
-            $wrapped->children     = $block->children;
-            $wrapped->selfParent   = $block->selfParent;
-
-            $block->children = [[Type::T_BLOCK, $wrapped]];
-        }
-
-        $this->env = $this->filterWithout($envs, $without);
-        $newBlock  = $this->spliceTree($envs, $block, $without);
-
-        $saveScope   = $this->scope;
-        $this->scope = $this->rootBlock;
-
-        $this->compileChild($newBlock, $this->scope);
-
-        $this->scope = $saveScope;
-        $this->env   = $this->extractEnv($envs);
-
-        $this->popEnv();
-    }
-
-    /**
-     * Splice parse tree
-     *
-     * @param array                $envs
-     * @param \Leafo\ScssPhp\Block $block
-     * @param integer              $without
-     *
-     * @return array
-     */
-    protected function spliceTree($envs, Block $block, $without)
-    {
-        $newBlock = null;
-
-        foreach ($envs as $e) {
-            if (! isset($e->block)) {
-                continue;
-            }
-
-            if ($e->block === $block) {
-                continue;
-            }
-
-            if (isset($e->block->type) && $e->block->type === Type::T_AT_ROOT) {
-                continue;
-            }
-
-            if ($e->block && $this->isWithout($without, $e->block)) {
-                continue;
-            }
-
-            $b = new Block;
-            $b->sourceName   = $e->block->sourceName;
-            $b->sourceIndex  = $e->block->sourceIndex;
-            $b->sourceLine   = $e->block->sourceLine;
-            $b->sourceColumn = $e->block->sourceColumn;
-            $b->selectors    = [];
-            $b->comments     = $e->block->comments;
-            $b->parent       = null;
-
-            if ($newBlock) {
-                $type = isset($newBlock->type) ? $newBlock->type : Type::T_BLOCK;
-
-                $b->children = [[$type, $newBlock]];
-
-                $newBlock->parent = $b;
-            } elseif (count($block->children)) {
-                foreach ($block->children as $child) {
-                    if ($child[0] === Type::T_BLOCK) {
-                        $child[1]->parent = $b;
-                    }
-                }
-
-                $b->children = $block->children;
-            }
-
-            if (isset($e->block->type)) {
-                $b->type = $e->block->type;
-            }
-
-            if (isset($e->block->name)) {
-                $b->name = $e->block->name;
-            }
-
-            if (isset($e->block->queryList)) {
-                $b->queryList = $e->block->queryList;
-            }
-
-            if (isset($e->block->value)) {
-                $b->value = $e->block->value;
-            }
-
-            $newBlock = $b;
-        }
-
-        $newBlock->selfParent   = $block->selfParent;
-        $type = isset($newBlock->type) ? $newBlock->type : Type::T_BLOCK;
-
-        return [$type, $newBlock];
-    }
-
-    /**
-     * Compile @at-root's with: inclusion / without: exclusion into filter flags
-     *
-     * @param array $with
-     *
-     * @return integer
-     */
-    protected function compileWith($with)
-    {
-        static $mapping = [
-            'rule'     => self::WITH_RULE,
-            'media'    => self::WITH_MEDIA,
-            'supports' => self::WITH_SUPPORTS,
-            'all'      => self::WITH_ALL,
-        ];
-
-        // exclude selectors by default
-        $without = static::WITH_RULE;
-
-        if ($this->libMapHasKey([$with, static::$with])) {
-            $without = static::WITH_ALL;
-
-            $list = $this->coerceList($this->libMapGet([$with, static::$with]));
-
-            foreach ($list[2] as $item) {
-                $keyword = $this->compileStringContent($this->coerceString($item));
-
-                if (array_key_exists($keyword, $mapping)) {
-                    $without &= ~($mapping[$keyword]);
-                }
-            }
-        }
-
-        if ($this->libMapHasKey([$with, static::$without])) {
-            $without = 0;
-
-            $list = $this->coerceList($this->libMapGet([$with, static::$without]));
-
-            foreach ($list[2] as $item) {
-                $keyword = $this->compileStringContent($this->coerceString($item));
-
-                if (array_key_exists($keyword, $mapping)) {
-                    $without |= $mapping[$keyword];
-                }
-            }
-        }
-
-        return $without;
-    }
-
-    /**
-     * Filter env stack
-     *
-     * @param array   $envs
-     * @param integer $without
-     *
-     * @return \Leafo\ScssPhp\Compiler\Environment
-     */
-    protected function filterWithout($envs, $without)
-    {
-        $filtered = [];
-
-        foreach ($envs as $e) {
-            if ($e->block && $this->isWithout($without, $e->block)) {
-                continue;
-            }
-
-            $filtered[] = $e;
-        }
-
-        return $this->extractEnv($filtered);
-    }
-
-    /**
-     * Filter WITH rules
-     *
-     * @param integer              $without
-     * @param \Leafo\ScssPhp\Block $block
-     *
-     * @return boolean
-     */
-    protected function isWithout($without, Block $block)
-    {
-        if ((($without & static::WITH_RULE) && isset($block->selectors)) ||
-            (($without & static::WITH_MEDIA) &&
-                isset($block->type) && $block->type === Type::T_MEDIA) ||
-            (($without & static::WITH_SUPPORTS) &&
-                isset($block->type) && $block->type === Type::T_DIRECTIVE &&
-                isset($block->name) && $block->name === 'supports')
-        ) {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Compile keyframe block
-     *
-     * @param \Leafo\ScssPhp\Block $block
-     * @param array                $selectors
-     */
-    protected function compileKeyframeBlock(Block $block, $selectors)
-    {
-        $env = $this->pushEnv($block);
-
-        $envs = $this->compactEnv($env);
-
-        $this->env = $this->extractEnv(array_filter($envs, function (Environment $e) {
-            return ! isset($e->block->selectors);
-        }));
-
-        $this->scope = $this->makeOutputBlock($block->type, $selectors);
-        $this->scope->depth = 1;
-        $this->scope->parent->children[] = $this->scope;
-
-        $this->compileChildrenNoReturn($block->children, $this->scope);
-
-        $this->scope = $this->scope->parent;
-        $this->env   = $this->extractEnv($envs);
-
-        $this->popEnv();
-    }
-
-    /**
-     * Compile nested block
-     *
-     * @param \Leafo\ScssPhp\Block $block
-     * @param array                $selectors
-     */
-    protected function compileNestedBlock(Block $block, $selectors)
-    {
-        $this->pushEnv($block);
-
-        $this->scope = $this->makeOutputBlock($block->type, $selectors);
-        $this->scope->parent->children[] = $this->scope;
-
-        $this->compileChildrenNoReturn($block->children, $this->scope);
-
-        $this->scope = $this->scope->parent;
-
-        $this->popEnv();
-    }
-
-    /**
-     * Recursively compiles a block.
-     *
-     * A block is analogous to a CSS block in most cases. A single SCSS document
-     * is encapsulated in a block when parsed, but it does not have parent tags
-     * so all of its children appear on the root level when compiled.
-     *
-     * Blocks are made up of selectors and children.
-     *
-     * The children of a block are just all the blocks that are defined within.
-     *
-     * Compiling the block involves pushing a fresh environment on the stack,
-     * and iterating through the props, compiling each one.
-     *
-     * @see Compiler::compileChild()
-     *
-     * @param \Leafo\ScssPhp\Block $block
-     */
-    protected function compileBlock(Block $block)
-    {
-        $env = $this->pushEnv($block);
-        $env->selectors = $this->evalSelectors($block->selectors);
-
-        $out = $this->makeOutputBlock(null);
-
-        if (isset($this->lineNumberStyle) && count($env->selectors) && count($block->children)) {
-            $annotation = $this->makeOutputBlock(Type::T_COMMENT);
-            $annotation->depth = 0;
-
-            $file = $this->sourceNames[$block->sourceIndex];
-            $line = $block->sourceLine;
-
-            switch ($this->lineNumberStyle) {
-                case static::LINE_COMMENTS:
-                    $annotation->lines[] = '/* line ' . $line
-                                         . ($file ? ', ' . $file : '')
-                                         . ' */';
-                    break;
-
-                case static::DEBUG_INFO:
-                    $annotation->lines[] = '@media -sass-debug-info{'
-                                         . ($file ? 'filename{font-family:"' . $file . '"}' : '')
-                                         . 'line{font-family:' . $line . '}}';
-                    break;
-            }
-
-            $this->scope->children[] = $annotation;
-        }
-
-        $this->scope->children[] = $out;
-
-        if (count($block->children)) {
-            $out->selectors = $this->multiplySelectors($env, $block->selfParent);
-
-            $this->compileChildrenNoReturn($block->children, $out);
-        }
-
-        $this->formatter->stripSemicolon($out->lines);
-
-        $this->popEnv();
-    }
-
-    /**
-     * Compile root level comment
-     *
-     * @param array $block
-     */
-    protected function compileComment($block)
-    {
-        $out = $this->makeOutputBlock(Type::T_COMMENT);
-        $out->lines[] = $block[1];
-        $this->scope->children[] = $out;
-    }
-
-    /**
-     * Evaluate selectors
-     *
-     * @param array $selectors
-     *
-     * @return array
-     */
-    protected function evalSelectors($selectors)
-    {
-        $this->shouldEvaluate = false;
-
-        $selectors = array_map([$this, 'evalSelector'], $selectors);
-
-        // after evaluating interpolates, we might need a second pass
-        if ($this->shouldEvaluate) {
-            $buffer = $this->collapseSelectors($selectors);
-            $parser = $this->parserFactory(__METHOD__);
-
-            if ($parser->parseSelector($buffer, $newSelectors)) {
-                $selectors = array_map([$this, 'evalSelector'], $newSelectors);
-            }
-        }
-
-        return $selectors;
-    }
-
-    /**
-     * Evaluate selector
-     *
-     * @param array $selector
-     *
-     * @return array
-     */
-    protected function evalSelector($selector)
-    {
-        return array_map([$this, 'evalSelectorPart'], $selector);
-    }
-
-    /**
-     * Evaluate selector part; replaces all the interpolates, stripping quotes
-     *
-     * @param array $part
-     *
-     * @return array
-     */
-    protected function evalSelectorPart($part)
-    {
-        foreach ($part as &$p) {
-            if (is_array($p) && ($p[0] === Type::T_INTERPOLATE || $p[0] === Type::T_STRING)) {
-                $p = $this->compileValue($p);
-
-                // force re-evaluation
-                if (strpos($p, '&') !== false || strpos($p, ',') !== false) {
-                    $this->shouldEvaluate = true;
-                }
-            } elseif (is_string($p) && strlen($p) >= 2 &&
-                ($first = $p[0]) && ($first === '"' || $first === "'") &&
-                substr($p, -1) === $first
-            ) {
-                $p = substr($p, 1, -1);
-            }
-        }
-
-        return $this->flattenSelectorSingle($part);
-    }
-
-    /**
-     * Collapse selectors
-     *
-     * @param array $selectors
-     *
-     * @return string
-     */
-    protected function collapseSelectors($selectors)
-    {
-        $parts = [];
-
-        foreach ($selectors as $selector) {
-            $output = '';
-
-            array_walk_recursive(
-                $selector,
-                function ($value, $key) use (&$output) {
-                    $output .= $value;
-                }
-            );
-
-            $parts[] = $output;
-        }
-
-        return implode(', ', $parts);
-    }
-
-    /**
-     * Flatten selector single; joins together .classes and #ids
-     *
-     * @param array $single
-     *
-     * @return array
-     */
-    protected function flattenSelectorSingle($single)
-    {
-        $joined = [];
-
-        foreach ($single as $part) {
-            if (empty($joined) ||
-                ! is_string($part) ||
-                preg_match('/[\[.:#%]/', $part)
-            ) {
-                $joined[] = $part;
-                continue;
-            }
-
-            if (is_array(end($joined))) {
-                $joined[] = $part;
-            } else {
-                $joined[count($joined) - 1] .= $part;
-            }
-        }
-
-        return $joined;
-    }
-
-    /**
-     * Compile selector to string; self(&) should have been replaced by now
-     *
-     * @param string|array $selector
-     *
-     * @return string
-     */
-    protected function compileSelector($selector)
-    {
-        if (! is_array($selector)) {
-            return $selector; // media and the like
-        }
-
-        return implode(
-            ' ',
-            array_map(
-                [$this, 'compileSelectorPart'],
-                $selector
-            )
-        );
-    }
-
-    /**
-     * Compile selector part
-     *
-     * @param array $piece
-     *
-     * @return string
-     */
-    protected function compileSelectorPart($piece)
-    {
-        foreach ($piece as &$p) {
-            if (! is_array($p)) {
-                continue;
-            }
-
-            switch ($p[0]) {
-                case Type::T_SELF:
-                    $p = '&';
-                    break;
-
-                default:
-                    $p = $this->compileValue($p);
-                    break;
-            }
-        }
-
-        return implode($piece);
-    }
-
-    /**
-     * Has selector placeholder?
-     *
-     * @param array $selector
-     *
-     * @return boolean
-     */
-    protected function hasSelectorPlaceholder($selector)
-    {
-        if (! is_array($selector)) {
-            return false;
-        }
-
-        foreach ($selector as $parts) {
-            foreach ($parts as $part) {
-                if (strlen($part) && '%' === $part[0]) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Compile children and return result
-     *
-     * @param array                                $stms
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
-     *
-     * @return array|null
-     */
-    protected function compileChildren($stms, OutputBlock $out)
-    {
-        foreach ($stms as $stm) {
-            $ret = $this->compileChild($stm, $out);
-
-            if (isset($ret)) {
-                return $ret;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Compile children and throw exception if unexpected @return
-     *
-     * @param array                                $stms
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
-     *
-     * @throws \Exception
-     */
-    protected function compileChildrenNoReturn($stms, OutputBlock $out)
-    {
-        foreach ($stms as $stm) {
-            $ret = $this->compileChild($stm, $out);
-
-            if (isset($ret)) {
-                $this->throwError('@return may only be used within a function');
-
-                return;
-            }
-        }
-    }
-
-    /**
-     * Compile media query
-     *
-     * @param array $queryList
-     *
-     * @return string
-     */
-    protected function compileMediaQuery($queryList)
-    {
-        $out = '@media';
-        $first = true;
-
-        foreach ($queryList as $query) {
-            $type = null;
-            $parts = [];
-
-            foreach ($query as $q) {
-                switch ($q[0]) {
-                    case Type::T_MEDIA_TYPE:
-                        if ($type) {
-                            $type = $this->mergeMediaTypes(
-                                $type,
-                                array_map([$this, 'compileValue'], array_slice($q, 1))
-                            );
-
-                            if (empty($type)) { // merge failed
-                                return null;
-                            }
-                        } else {
-                            $type = array_map([$this, 'compileValue'], array_slice($q, 1));
-                        }
-                        break;
-
-                    case Type::T_MEDIA_EXPRESSION:
-                        if (isset($q[2])) {
-                            $parts[] = '('
-                                . $this->compileValue($q[1])
-                                . $this->formatter->assignSeparator
-                                . $this->compileValue($q[2])
-                                . ')';
-                        } else {
-                            $parts[] = '('
-                                . $this->compileValue($q[1])
-                                . ')';
-                        }
-                        break;
-
-                    case Type::T_MEDIA_VALUE:
-                        $parts[] = $this->compileValue($q[1]);
-                        break;
-                }
-            }
-
-            if ($type) {
-                array_unshift($parts, implode(' ', array_filter($type)));
-            }
-
-            if (! empty($parts)) {
-                if ($first) {
-                    $first = false;
-                    $out .= ' ';
-                } else {
-                    $out .= $this->formatter->tagSeparator;
-                }
-
-                $out .= implode(' and ', $parts);
-            }
-        }
-
-        return $out;
-    }
-
-    protected function mergeDirectRelationships($selectors1, $selectors2)
-    {
-        if (empty($selectors1) || empty($selectors2)) {
-            return array_merge($selectors1, $selectors2);
-        }
-
-        $part1 = end($selectors1);
-        $part2 = end($selectors2);
-
-        if (! $this->isImmediateRelationshipCombinator($part1[0]) || $part1 !== $part2) {
-            return array_merge($selectors1, $selectors2);
-        }
-
-        $merged = [];
-
-        do {
-            $part1 = array_pop($selectors1);
-            $part2 = array_pop($selectors2);
-
-            if ($this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
-                $merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged);
-                break;
-            }
-
-            array_unshift($merged, $part1);
-            array_unshift($merged, [array_pop($selectors1)[0] . array_pop($selectors2)[0]]);
-        } while (! empty($selectors1) && ! empty($selectors2));
-
-        return $merged;
-    }
-
-    /**
-     * Merge media types
-     *
-     * @param array $type1
-     * @param array $type2
-     *
-     * @return array|null
-     */
-    protected function mergeMediaTypes($type1, $type2)
-    {
-        if (empty($type1)) {
-            return $type2;
-        }
-
-        if (empty($type2)) {
-            return $type1;
-        }
-
-        $m1 = '';
-        $t1 = '';
-
-        if (count($type1) > 1) {
-            $m1= strtolower($type1[0]);
-            $t1= strtolower($type1[1]);
-        } else {
-            $t1 = strtolower($type1[0]);
-        }
-
-        $m2 = '';
-        $t2 = '';
-
-        if (count($type2) > 1) {
-            $m2 = strtolower($type2[0]);
-            $t2 = strtolower($type2[1]);
-        } else {
-            $t2 = strtolower($type2[0]);
-        }
-
-        if (($m1 === Type::T_NOT) ^ ($m2 === Type::T_NOT)) {
-            if ($t1 === $t2) {
-                return null;
-            }
-
-            return [
-                $m1 === Type::T_NOT ? $m2 : $m1,
-                $m1 === Type::T_NOT ? $t2 : $t1,
-            ];
-        }
-
-        if ($m1 === Type::T_NOT && $m2 === Type::T_NOT) {
-            // CSS has no way of representing "neither screen nor print"
-            if ($t1 !== $t2) {
-                return null;
-            }
-
-            return [Type::T_NOT, $t1];
-        }
-
-        if ($t1 !== $t2) {
-            return null;
-        }
-
-        // t1 == t2, neither m1 nor m2 are "not"
-        return [empty($m1)? $m2 : $m1, $t1];
-    }
-
-    /**
-     * Compile import; returns true if the value was something that could be imported
-     *
-     * @param array   $rawPath
-     * @param array   $out
-     * @param boolean $once
-     *
-     * @return boolean
-     */
-    protected function compileImport($rawPath, $out, $once = false)
-    {
-        if ($rawPath[0] === Type::T_STRING) {
-            $path = $this->compileStringContent($rawPath);
-
-            if ($path = $this->findImport($path)) {
-                if (! $once || ! in_array($path, $this->importedFiles)) {
-                    $this->importFile($path, $out);
-                    $this->importedFiles[] = $path;
-                }
-
-                return true;
-            }
-
-            return false;
-        }
-
-        if ($rawPath[0] === Type::T_LIST) {
-            // handle a list of strings
-            if (count($rawPath[2]) === 0) {
-                return false;
-            }
-
-            foreach ($rawPath[2] as $path) {
-                if ($path[0] !== Type::T_STRING) {
-                    return false;
-                }
-            }
-
-            foreach ($rawPath[2] as $path) {
-                $this->compileImport($path, $out);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Compile child; returns a value to halt execution
-     *
-     * @param array                                $child
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
-     *
-     * @return array
-     */
-    protected function compileChild($child, OutputBlock $out)
-    {
-        $this->sourceIndex  = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
-        $this->sourceLine   = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
-        $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
-
-        switch ($child[0]) {
-            case Type::T_SCSSPHP_IMPORT_ONCE:
-                $rawPath = $this->reduce($child[1]);
-
-                if (! $this->compileImport($rawPath, $out, true)) {
-                    $out->lines[] = '@import ' . $this->compileValue($rawPath) . ';';
-                }
-                break;
-
-            case Type::T_IMPORT:
-                $rawPath = $this->reduce($child[1]);
-
-                if (! $this->compileImport($rawPath, $out)) {
-                    $out->lines[] = '@import ' . $this->compileValue($rawPath) . ';';
-                }
-                break;
-
-            case Type::T_DIRECTIVE:
-                $this->compileDirective($child[1]);
-                break;
-
-            case Type::T_AT_ROOT:
-                $this->compileAtRoot($child[1]);
-                break;
-
-            case Type::T_MEDIA:
-                $this->compileMedia($child[1]);
-                break;
-
-            case Type::T_BLOCK:
-                $this->compileBlock($child[1]);
-                break;
-
-            case Type::T_CHARSET:
-                if (! $this->charsetSeen) {
-                    $this->charsetSeen = true;
-
-                    $out->lines[] = '@charset ' . $this->compileValue($child[1]) . ';';
-                }
-                break;
-
-            case Type::T_ASSIGN:
-                list(, $name, $value) = $child;
-
-                if ($name[0] === Type::T_VARIABLE) {
-                    $flags = isset($child[3]) ? $child[3] : [];
-                    $isDefault = in_array('!default', $flags);
-                    $isGlobal = in_array('!global', $flags);
-
-                    if ($isGlobal) {
-                        $this->set($name[1], $this->reduce($value), false, $this->rootEnv, $value);
-                        break;
-                    }
-
-                    $shouldSet = $isDefault &&
-                        (($result = $this->get($name[1], false)) === null
-                        || $result === static::$null);
-
-                    if (! $isDefault || $shouldSet) {
-                        $this->set($name[1], $this->reduce($value), false, null, $value);
-                    }
-                    break;
-                }
-
-                $compiledName = $this->compileValue($name);
-
-                // handle shorthand syntax: size / line-height
-                if ($compiledName === 'font') {
-                    if ($value[0] === Type::T_VARIABLE) {
-                        // if the font value comes from variable, the content is already reduced (which means formulars where already calculated)
-                        // so we need the original unreduced value
-                        $value = $this->get($value[1], true, null, true);
-                    }
-
-                    $fontValue=&$value;
-                    if ($value[0] === Type::T_LIST && $value[1]==',') {
-                        // this is the case if more than one font is given: example: "font: 400 1em/1.3 arial,helvetica"
-                        // we need to handle the first list element
-                        $fontValue=&$value[2][0];
-                    }
-
-                    if ($fontValue[0] === Type::T_EXPRESSION && $fontValue[1] === '/') {
-                        $fontValue = $this->expToString($fontValue);
-                    } elseif ($fontValue[0] === Type::T_LIST) {
-                        foreach ($fontValue[2] as &$item) {
-                            if ($item[0] === Type::T_EXPRESSION && $item[1] === '/') {
-                                $item = $this->expToString($item);
-                            }
-                        }
-                    }
-                }
-
-                // if the value reduces to null from something else then
-                // the property should be discarded
-                if ($value[0] !== Type::T_NULL) {
-                    $value = $this->reduce($value);
-
-                    if ($value[0] === Type::T_NULL || $value === static::$nullString) {
-                        break;
-                    }
-                }
-
-                $compiledValue = $this->compileValue($value);
-
-                $out->lines[] = $this->formatter->property(
-                    $compiledName,
-                    $compiledValue
-                );
-                break;
-
-            case Type::T_COMMENT:
-                if ($out->type === Type::T_ROOT) {
-                    $this->compileComment($child);
-                    break;
-                }
-
-                $out->lines[] = $child[1];
-                break;
-
-            case Type::T_MIXIN:
-            case Type::T_FUNCTION:
-                list(, $block) = $child;
-
-                $this->set(static::$namespaces[$block->type] . $block->name, $block);
-                break;
-
-            case Type::T_EXTEND:
-                foreach ($child[1] as $sel) {
-                    $results = $this->evalSelectors([$sel]);
-
-                    foreach ($results as $result) {
-                        // only use the first one
-                        $result = current($result);
-
-                        $this->pushExtends($result, $out->selectors, $child);
-                    }
-                }
-                break;
-
-            case Type::T_IF:
-                list(, $if) = $child;
-
-                if ($this->isTruthy($this->reduce($if->cond, true))) {
-                    return $this->compileChildren($if->children, $out);
-                }
-
-                foreach ($if->cases as $case) {
-                    if ($case->type === Type::T_ELSE ||
-                        $case->type === Type::T_ELSEIF && $this->isTruthy($this->reduce($case->cond))
-                    ) {
-                        return $this->compileChildren($case->children, $out);
-                    }
-                }
-                break;
-
-            case Type::T_EACH:
-                list(, $each) = $child;
-
-                $list = $this->coerceList($this->reduce($each->list));
-
-                $this->pushEnv();
-
-                foreach ($list[2] as $item) {
-                    if (count($each->vars) === 1) {
-                        $this->set($each->vars[0], $item, true);
-                    } else {
-                        list(,, $values) = $this->coerceList($item);
-
-                        foreach ($each->vars as $i => $var) {
-                            $this->set($var, isset($values[$i]) ? $values[$i] : static::$null, true);
-                        }
-                    }
-
-                    $ret = $this->compileChildren($each->children, $out);
-
-                    if ($ret) {
-                        if ($ret[0] !== Type::T_CONTROL) {
-                            $this->popEnv();
-
-                            return $ret;
-                        }
-
-                        if ($ret[1]) {
-                            break;
-                        }
-                    }
-                }
-
-                $this->popEnv();
-                break;
-
-            case Type::T_WHILE:
-                list(, $while) = $child;
-
-                while ($this->isTruthy($this->reduce($while->cond, true))) {
-                    $ret = $this->compileChildren($while->children, $out);
-
-                    if ($ret) {
-                        if ($ret[0] !== Type::T_CONTROL) {
-                            return $ret;
-                        }
-
-                        if ($ret[1]) {
-                            break;
-                        }
-                    }
-                }
-                break;
-
-            case Type::T_FOR:
-                list(, $for) = $child;
-
-                $start = $this->reduce($for->start, true);
-                $end   = $this->reduce($for->end, true);
-
-                if (! ($start[2] == $end[2] || $end->unitless())) {
-                    $this->throwError('Incompatible units: "%s" and "%s".', $start->unitStr(), $end->unitStr());
-
-                    break;
-                }
-
-                $unit  = $start[2];
-                $start = $start[1];
-                $end   = $end[1];
-
-                $d = $start < $end ? 1 : -1;
-
-                for (;;) {
-                    if ((! $for->until && $start - $d == $end) ||
-                        ($for->until && $start == $end)
-                    ) {
-                        break;
-                    }
-
-                    $this->set($for->var, new Node\Number($start, $unit));
-                    $start += $d;
-
-                    $ret = $this->compileChildren($for->children, $out);
-
-                    if ($ret) {
-                        if ($ret[0] !== Type::T_CONTROL) {
-                            return $ret;
-                        }
-
-                        if ($ret[1]) {
-                            break;
-                        }
-                    }
-                }
-                break;
-
-            case Type::T_BREAK:
-                return [Type::T_CONTROL, true];
-
-            case Type::T_CONTINUE:
-                return [Type::T_CONTROL, false];
-
-            case Type::T_RETURN:
-                return $this->reduce($child[1], true);
-
-            case Type::T_NESTED_PROPERTY:
-                list(, $prop) = $child;
-
-                $prefixed = [];
-                $prefix = $this->compileValue($prop->prefix) . '-';
-
-                foreach ($prop->children as $child) {
-                    switch ($child[0]) {
-                        case Type::T_ASSIGN:
-                            array_unshift($child[1][2], $prefix);
-                            break;
-
-                        case Type::T_NESTED_PROPERTY:
-                            array_unshift($child[1]->prefix[2], $prefix);
-                            break;
-                    }
-
-                    $prefixed[] = $child;
-                }
-
-                $this->compileChildrenNoReturn($prefixed, $out);
-                break;
-
-            case Type::T_INCLUDE:
-                // including a mixin
-                list(, $name, $argValues, $content) = $child;
-
-                $mixin = $this->get(static::$namespaces['mixin'] . $name, false);
-
-                if (! $mixin) {
-                    $this->throwError("Undefined mixin $name");
-                    break;
-                }
-
-                $callingScope = $this->getStoreEnv();
-
-                // push scope, apply args
-                $this->pushEnv();
-                $this->env->depth--;
-
-                $storeEnv = $this->storeEnv;
-                $this->storeEnv = $this->env;
-
-                if (isset($content)) {
-                    $content->scope = $callingScope;
-
-                    $this->setRaw(static::$namespaces['special'] . 'content', $content, $this->env);
-                }
-
-                if (isset($mixin->args)) {
-                    $this->applyArguments($mixin->args, $argValues);
-                }
-
-                $this->env->marker = 'mixin';
-
-                $this->compileChildrenNoReturn($mixin->children, $out);
-
-                $this->storeEnv = $storeEnv;
-
-                $this->popEnv();
-                break;
-
-            case Type::T_MIXIN_CONTENT:
-                $content = $this->get(static::$namespaces['special'] . 'content', false, $this->getStoreEnv())
-                         ?: $this->get(static::$namespaces['special'] . 'content', false, $this->env);
-
-                if (! $content) {
-                    $content = new \stdClass();
-                    $content->scope = new \stdClass();
-                    $content->children = $this->storeEnv->parent->block->children;
-                    break;
-                }
-
-                $storeEnv = $this->storeEnv;
-                $this->storeEnv = $content->scope;
-
-                $this->compileChildrenNoReturn($content->children, $out);
-
-                $this->storeEnv = $storeEnv;
-                break;
-
-            case Type::T_DEBUG:
-                list(, $value) = $child;
-
-                $fname = $this->sourceNames[$this->sourceIndex];
-                $line = $this->sourceLine;
-                $value = $this->compileValue($this->reduce($value, true));
-                fwrite($this->stderr, "File $fname on line $line DEBUG: $value\n");
-                break;
-
-            case Type::T_WARN:
-                list(, $value) = $child;
-
-                $fname = $this->sourceNames[$this->sourceIndex];
-                $line = $this->sourceLine;
-                $value = $this->compileValue($this->reduce($value, true));
-                fwrite($this->stderr, "File $fname on line $line WARN: $value\n");
-                break;
-
-            case Type::T_ERROR:
-                list(, $value) = $child;
-
-                $fname = $this->sourceNames[$this->sourceIndex];
-                $line = $this->sourceLine;
-                $value = $this->compileValue($this->reduce($value, true));
-                $this->throwError("File $fname on line $line ERROR: $value\n");
-                break;
-
-            case Type::T_CONTROL:
-                $this->throwError('@break/@continue not permitted in this scope');
-                break;
-
-            default:
-                $this->throwError("unknown child type: $child[0]");
-        }
-    }
-
-    /**
-     * Reduce expression to string
-     *
-     * @param array $exp
-     *
-     * @return array
-     */
-    protected function expToString($exp)
-    {
-        list(, $op, $left, $right, /* $inParens */, $whiteLeft, $whiteRight) = $exp;
-
-        $content = [$this->reduce($left)];
-
-        if ($whiteLeft) {
-            $content[] = ' ';
-        }
-
-        $content[] = $op;
-
-        if ($whiteRight) {
-            $content[] = ' ';
-        }
-
-        $content[] = $this->reduce($right);
-
-        return [Type::T_STRING, '', $content];
-    }
-
-    /**
-     * Is truthy?
-     *
-     * @param array $value
-     *
-     * @return array
-     */
-    protected function isTruthy($value)
-    {
-        return $value !== static::$false && $value !== static::$null;
-    }
-
-    /**
-     * Is the value a direct relationship combinator?
-     *
-     * @param string $value
-     *
-     * @return boolean
-     */
-    protected function isImmediateRelationshipCombinator($value)
-    {
-        return $value === '>' || $value === '+' || $value === '~';
-    }
-
-    /**
-     * Should $value cause its operand to eval
-     *
-     * @param array $value
-     *
-     * @return boolean
-     */
-    protected function shouldEval($value)
-    {
-        switch ($value[0]) {
-            case Type::T_EXPRESSION:
-                if ($value[1] === '/') {
-                    return $this->shouldEval($value[2]) || $this->shouldEval($value[3]);
-                }
-
-                // fall-thru
-            case Type::T_VARIABLE:
-            case Type::T_FUNCTION_CALL:
-                return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Reduce value
-     *
-     * @param array   $value
-     * @param boolean $inExp
-     *
-     * @return array|\Leafo\ScssPhp\Node\Number
-     */
-    protected function reduce($value, $inExp = false)
-    {
-        if ($value === null) {
-            return $value;
-        }
-
-        switch ($value[0]) {
-            case Type::T_EXPRESSION:
-                list(, $op, $left, $right, $inParens) = $value;
-
-                $opName = isset(static::$operatorNames[$op]) ? static::$operatorNames[$op] : $op;
-                $inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right);
-
-                $left = $this->reduce($left, true);
-
-                if ($op !== 'and' && $op !== 'or') {
-                    $right = $this->reduce($right, true);
-                }
-
-                // special case: looks like css shorthand
-                if ($opName == 'div' && ! $inParens && ! $inExp && isset($right[2])
-                    && (($right[0] !== Type::T_NUMBER && $right[2] != '')
-                    || ($right[0] === Type::T_NUMBER && ! $right->unitless()))
-                ) {
-                    return $this->expToString($value);
-                }
-
-                $left = $this->coerceForExpression($left);
-                $right = $this->coerceForExpression($right);
-
-                $ltype = $left[0];
-                $rtype = $right[0];
-
-                $ucOpName = ucfirst($opName);
-                $ucLType  = ucfirst($ltype);
-                $ucRType  = ucfirst($rtype);
-
-                // this tries:
-                // 1. op[op name][left type][right type]
-                // 2. op[left type][right type] (passing the op as first arg
-                // 3. op[op name]
-                $fn = "op${ucOpName}${ucLType}${ucRType}";
-
-                if (is_callable([$this, $fn]) ||
-                    (($fn = "op${ucLType}${ucRType}") &&
-                        is_callable([$this, $fn]) &&
-                        $passOp = true) ||
-                    (($fn = "op${ucOpName}") &&
-                        is_callable([$this, $fn]) &&
-                        $genOp = true)
-                ) {
-                    $coerceUnit = false;
-
-                    if (! isset($genOp) &&
-                        $left[0] === Type::T_NUMBER && $right[0] === Type::T_NUMBER
-                    ) {
-                        $coerceUnit = true;
-
-                        switch ($opName) {
-                            case 'mul':
-                                $targetUnit = $left[2];
-
-                                foreach ($right[2] as $unit => $exp) {
-                                    $targetUnit[$unit] = (isset($targetUnit[$unit]) ? $targetUnit[$unit] : 0) + $exp;
-                                }
-                                break;
-
-                            case 'div':
-                                $targetUnit = $left[2];
-
-                                foreach ($right[2] as $unit => $exp) {
-                                    $targetUnit[$unit] = (isset($targetUnit[$unit]) ? $targetUnit[$unit] : 0) - $exp;
-                                }
-                                break;
-
-                            case 'mod':
-                                $targetUnit = $left[2];
-                                break;
-
-                            default:
-                                $targetUnit = $left->unitless() ? $right[2] : $left[2];
-                        }
-
-                        if (! $left->unitless() && ! $right->unitless()) {
-                            $left = $left->normalize();
-                            $right = $right->normalize();
-                        }
-                    }
-
-                    $shouldEval = $inParens || $inExp;
-
-                    if (isset($passOp)) {
-                        $out = $this->$fn($op, $left, $right, $shouldEval);
-                    } else {
-                        $out = $this->$fn($left, $right, $shouldEval);
-                    }
-
-                    if (isset($out)) {
-                        if ($coerceUnit && $out[0] === Type::T_NUMBER) {
-                            $out = $out->coerce($targetUnit);
-                        }
-
-                        return $out;
-                    }
-                }
-
-                return $this->expToString($value);
-
-            case Type::T_UNARY:
-                list(, $op, $exp, $inParens) = $value;
-
-                $inExp = $inExp || $this->shouldEval($exp);
-                $exp = $this->reduce($exp);
-
-                if ($exp[0] === Type::T_NUMBER) {
-                    switch ($op) {
-                        case '+':
-                            return new Node\Number($exp[1], $exp[2]);
-
-                        case '-':
-                            return new Node\Number(-$exp[1], $exp[2]);
-                    }
-                }
-
-                if ($op === 'not') {
-                    if ($inExp || $inParens) {
-                        if ($exp === static::$false || $exp === static::$null) {
-                            return static::$true;
-                        }
-
-                        return static::$false;
-                    }
-
-                    $op = $op . ' ';
-                }
-
-                return [Type::T_STRING, '', [$op, $exp]];
-
-            case Type::T_VARIABLE:
-                return $this->reduce($this->get($value[1]));
-
-            case Type::T_LIST:
-                foreach ($value[2] as &$item) {
-                    $item = $this->reduce($item);
-                }
-
-                return $value;
-
-            case Type::T_MAP:
-                foreach ($value[1] as &$item) {
-                    $item = $this->reduce($item);
-                }
-
-                foreach ($value[2] as &$item) {
-                    $item = $this->reduce($item);
-                }
-
-                return $value;
-
-            case Type::T_STRING:
-                foreach ($value[2] as &$item) {
-                    if (is_array($item) || $item instanceof \ArrayAccess) {
-                        $item = $this->reduce($item);
-                    }
-                }
-
-                return $value;
-
-            case Type::T_INTERPOLATE:
-                $value[1] = $this->reduce($value[1]);
-
-                return $value;
-
-            case Type::T_FUNCTION_CALL:
-                return $this->fncall($value[1], $value[2]);
-
-            default:
-                return $value;
-        }
-    }
-
-    /**
-     * Function caller
-     *
-     * @param string $name
-     * @param array  $argValues
-     *
-     * @return array|null
-     */
-    protected function fncall($name, $argValues)
-    {
-        // SCSS @function
-        if ($this->callScssFunction($name, $argValues, $returnValue)) {
-            return $returnValue;
-        }
-
-        // native PHP functions
-        if ($this->callNativeFunction($name, $argValues, $returnValue)) {
-            return $returnValue;
-        }
-
-        // for CSS functions, simply flatten the arguments into a list
-        $listArgs = [];
-
-        foreach ((array) $argValues as $arg) {
-            if (empty($arg[0])) {
-                $listArgs[] = $this->reduce($arg[1]);
-            }
-        }
-
-        return [Type::T_FUNCTION, $name, [Type::T_LIST, ',', $listArgs]];
-    }
-
-    /**
-     * Normalize name
-     *
-     * @param string $name
-     *
-     * @return string
-     */
-    protected function normalizeName($name)
-    {
-        return str_replace('-', '_', $name);
-    }
-
-    /**
-     * Normalize value
-     *
-     * @param array $value
-     *
-     * @return array
-     */
-    public function normalizeValue($value)
-    {
-        $value = $this->coerceForExpression($this->reduce($value));
-
-        switch ($value[0]) {
-            case Type::T_LIST:
-                $value = $this->extractInterpolation($value);
-
-                if ($value[0] !== Type::T_LIST) {
-                    return [Type::T_KEYWORD, $this->compileValue($value)];
-                }
-
-                foreach ($value[2] as $key => $item) {
-                    $value[2][$key] = $this->normalizeValue($item);
-                }
-
-                return $value;
-
-            case Type::T_STRING:
-                return [$value[0], '"', [$this->compileStringContent($value)]];
-
-            case Type::T_NUMBER:
-                return $value->normalize();
-
-            case Type::T_INTERPOLATE:
-                return [Type::T_KEYWORD, $this->compileValue($value)];
-
-            default:
-                return $value;
-        }
-    }
-
-    /**
-     * Add numbers
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    protected function opAddNumberNumber($left, $right)
-    {
-        return new Node\Number($left[1] + $right[1], $left[2]);
-    }
-
-    /**
-     * Multiply numbers
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    protected function opMulNumberNumber($left, $right)
-    {
-        return new Node\Number($left[1] * $right[1], $left[2]);
-    }
-
-    /**
-     * Subtract numbers
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    protected function opSubNumberNumber($left, $right)
-    {
-        return new Node\Number($left[1] - $right[1], $left[2]);
-    }
-
-    /**
-     * Divide numbers
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array|\Leafo\ScssPhp\Node\Number
-     */
-    protected function opDivNumberNumber($left, $right)
-    {
-        if ($right[1] == 0) {
-            return [Type::T_STRING, '', [$left[1] . $left[2] . '/' . $right[1] . $right[2]]];
-        }
-
-        return new Node\Number($left[1] / $right[1], $left[2]);
-    }
-
-    /**
-     * Mod numbers
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    protected function opModNumberNumber($left, $right)
-    {
-        return new Node\Number($left[1] % $right[1], $left[2]);
-    }
-
-    /**
-     * Add strings
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array|null
-     */
-    protected function opAdd($left, $right)
-    {
-        if ($strLeft = $this->coerceString($left)) {
-            if ($right[0] === Type::T_STRING) {
-                $right[1] = '';
-            }
-
-            $strLeft[2][] = $right;
-
-            return $strLeft;
-        }
-
-        if ($strRight = $this->coerceString($right)) {
-            if ($left[0] === Type::T_STRING) {
-                $left[1] = '';
-            }
-
-            array_unshift($strRight[2], $left);
-
-            return $strRight;
-        }
-        return null;
-    }
-
-    /**
-     * Boolean and
-     *
-     * @param array   $left
-     * @param array   $right
-     * @param boolean $shouldEval
-     *
-     * @return array|null
-     */
-    protected function opAnd($left, $right, $shouldEval)
-    {
-        if (! $shouldEval) {
-            return null;
-        }
-
-        if ($left !== static::$false and $left !== static::$null) {
-            return $this->reduce($right, true);
-        }
-
-        return $left;
-    }
-
-    /**
-     * Boolean or
-     *
-     * @param array   $left
-     * @param array   $right
-     * @param boolean $shouldEval
-     *
-     * @return array|null
-     */
-    protected function opOr($left, $right, $shouldEval)
-    {
-        if (! $shouldEval) {
-            return null;
-        }
-
-        if ($left !== static::$false and $left !== static::$null) {
-            return $left;
-        }
-
-        return $this->reduce($right, true);
-    }
-
-    /**
-     * Compare colors
-     *
-     * @param string $op
-     * @param array  $left
-     * @param array  $right
-     *
-     * @return array
-     */
-    protected function opColorColor($op, $left, $right)
-    {
-        $out = [Type::T_COLOR];
-
-        foreach ([1, 2, 3] as $i) {
-            $lval = isset($left[$i]) ? $left[$i] : 0;
-            $rval = isset($right[$i]) ? $right[$i] : 0;
-
-            switch ($op) {
-                case '+':
-                    $out[] = $lval + $rval;
-                    break;
-
-                case '-':
-                    $out[] = $lval - $rval;
-                    break;
-
-                case '*':
-                    $out[] = $lval * $rval;
-                    break;
-
-                case '%':
-                    $out[] = $lval % $rval;
-                    break;
-
-                case '/':
-                    if ($rval == 0) {
-                        $this->throwError("color: Can't divide by zero");
-                        break 2;
-                    }
-
-                    $out[] = (int) ($lval / $rval);
-                    break;
-
-                case '==':
-                    return $this->opEq($left, $right);
-
-                case '!=':
-                    return $this->opNeq($left, $right);
-
-                default:
-                    $this->throwError("color: unknown op $op");
-                    break 2;
-            }
-        }
-
-        if (isset($left[4])) {
-            $out[4] = $left[4];
-        } elseif (isset($right[4])) {
-            $out[4] = $right[4];
-        }
-
-        return $this->fixColor($out);
-    }
-
-    /**
-     * Compare color and number
-     *
-     * @param string $op
-     * @param array  $left
-     * @param array  $right
-     *
-     * @return array
-     */
-    protected function opColorNumber($op, $left, $right)
-    {
-        $value = $right[1];
-
-        return $this->opColorColor(
-            $op,
-            $left,
-            [Type::T_COLOR, $value, $value, $value]
-        );
-    }
-
-    /**
-     * Compare number and color
-     *
-     * @param string $op
-     * @param array  $left
-     * @param array  $right
-     *
-     * @return array
-     */
-    protected function opNumberColor($op, $left, $right)
-    {
-        $value = $left[1];
-
-        return $this->opColorColor(
-            $op,
-            [Type::T_COLOR, $value, $value, $value],
-            $right
-        );
-    }
-
-    /**
-     * Compare number1 == number2
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array
-     */
-    protected function opEq($left, $right)
-    {
-        if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) {
-            $lStr[1] = '';
-            $rStr[1] = '';
-
-            $left = $this->compileValue($lStr);
-            $right = $this->compileValue($rStr);
-        }
-
-        return $this->toBool($left === $right);
-    }
-
-    /**
-     * Compare number1 != number2
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array
-     */
-    protected function opNeq($left, $right)
-    {
-        if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) {
-            $lStr[1] = '';
-            $rStr[1] = '';
-
-            $left = $this->compileValue($lStr);
-            $right = $this->compileValue($rStr);
-        }
-
-        return $this->toBool($left !== $right);
-    }
-
-    /**
-     * Compare number1 >= number2
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array
-     */
-    protected function opGteNumberNumber($left, $right)
-    {
-        return $this->toBool($left[1] >= $right[1]);
-    }
-
-    /**
-     * Compare number1 > number2
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array
-     */
-    protected function opGtNumberNumber($left, $right)
-    {
-        return $this->toBool($left[1] > $right[1]);
-    }
-
-    /**
-     * Compare number1 <= number2
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array
-     */
-    protected function opLteNumberNumber($left, $right)
-    {
-        return $this->toBool($left[1] <= $right[1]);
-    }
-
-    /**
-     * Compare number1 < number2
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return array
-     */
-    protected function opLtNumberNumber($left, $right)
-    {
-        return $this->toBool($left[1] < $right[1]);
-    }
-
-    /**
-     * Three-way comparison, aka spaceship operator
-     *
-     * @param array $left
-     * @param array $right
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    protected function opCmpNumberNumber($left, $right)
-    {
-        $n = $left[1] - $right[1];
-
-        return new Node\Number($n ? $n / abs($n) : 0, '');
-    }
-
-    /**
-     * Cast to boolean
-     *
-     * @api
-     *
-     * @param mixed $thing
-     *
-     * @return array
-     */
-    public function toBool($thing)
-    {
-        return $thing ? static::$true : static::$false;
-    }
-
-    /**
-     * Compiles a primitive value into a CSS property value.
-     *
-     * Values in scssphp are typed by being wrapped in arrays, their format is
-     * typically:
-     *
-     *     array(type, contents [, additional_contents]*)
-     *
-     * The input is expected to be reduced. This function will not work on
-     * things like expressions and variables.
-     *
-     * @api
-     *
-     * @param array $value
-     *
-     * @return string
-     */
-    public function compileValue($value)
-    {
-        $value = $this->reduce($value);
-
-        switch ($value[0]) {
-            case Type::T_KEYWORD:
-                return $value[1];
-
-            case Type::T_COLOR:
-                // [1] - red component (either number for a %)
-                // [2] - green component
-                // [3] - blue component
-                // [4] - optional alpha component
-                list(, $r, $g, $b) = $value;
-
-                $r = round($r);
-                $g = round($g);
-                $b = round($b);
-
-                if (count($value) === 5 && $value[4] !== 1) { // rgba
-                    $a = new Node\Number($value[4], '');
-
-                    return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $a . ')';
-                }
-
-                $h = sprintf('#%02x%02x%02x', $r, $g, $b);
-
-                // Converting hex color to short notation (e.g. #003399 to #039)
-                if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
-                    $h = '#' . $h[1] . $h[3] . $h[5];
-                }
-
-                return $h;
-
-            case Type::T_NUMBER:
-                return $value->output($this);
-
-            case Type::T_STRING:
-                return $value[1] . $this->compileStringContent($value) . $value[1];
-
-            case Type::T_FUNCTION:
-                $args = ! empty($value[2]) ? $this->compileValue($value[2]) : '';
-
-                return "$value[1]($args)";
-
-            case Type::T_LIST:
-                $value = $this->extractInterpolation($value);
-
-                if ($value[0] !== Type::T_LIST) {
-                    return $this->compileValue($value);
-                }
-
-                list(, $delim, $items) = $value;
-
-                if ($delim !== ' ') {
-                    $delim .= ' ';
-                }
-
-                $filtered = [];
-
-                foreach ($items as $item) {
-                    if ($item[0] === Type::T_NULL) {
-                        continue;
-                    }
-
-                    $filtered[] = $this->compileValue($item);
-                }
-
-                return implode("$delim", $filtered);
-
-            case Type::T_MAP:
-                $keys = $value[1];
-                $values = $value[2];
-                $filtered = [];
-
-                for ($i = 0, $s = count($keys); $i < $s; $i++) {
-                    $filtered[$this->compileValue($keys[$i])] = $this->compileValue($values[$i]);
-                }
-
-                array_walk($filtered, function (&$value, $key) {
-                    $value = $key . ': ' . $value;
-                });
-
-                return '(' . implode(', ', $filtered) . ')';
-
-            case Type::T_INTERPOLATED:
-                // node created by extractInterpolation
-                list(, $interpolate, $left, $right) = $value;
-                list(,, $whiteLeft, $whiteRight) = $interpolate;
-
-                $left = count($left[2]) > 0 ?
-                    $this->compileValue($left) . $whiteLeft : '';
-
-                $right = count($right[2]) > 0 ?
-                    $whiteRight . $this->compileValue($right) : '';
-
-                return $left . $this->compileValue($interpolate) . $right;
-
-            case Type::T_INTERPOLATE:
-                // strip quotes if it's a string
-                $reduced = $this->reduce($value[1]);
-
-                switch ($reduced[0]) {
-                    case Type::T_LIST:
-                        $reduced = $this->extractInterpolation($reduced);
-
-                        if ($reduced[0] !== Type::T_LIST) {
-                            break;
-                        }
-
-                        list(, $delim, $items) = $reduced;
-
-                        if ($delim !== ' ') {
-                            $delim .= ' ';
-                        }
-
-                        $filtered = [];
-
-                        foreach ($items as $item) {
-                            if ($item[0] === Type::T_NULL) {
-                                continue;
-                            }
-
-                            $temp = $this->compileValue([Type::T_KEYWORD, $item]);
-                            if ($temp[0] === Type::T_STRING) {
-                                $filtered[] = $this->compileStringContent($temp);
-                            } elseif ($temp[0] === Type::T_KEYWORD) {
-                                $filtered[] = $temp[1];
-                            } else {
-                                $filtered[] = $this->compileValue($temp);
-                            }
-                        }
-
-                        $reduced = [Type::T_KEYWORD, implode("$delim", $filtered)];
-                        break;
-
-                    case Type::T_STRING:
-                        $reduced = [Type::T_KEYWORD, $this->compileStringContent($reduced)];
-                        break;
-
-                    case Type::T_NULL:
-                        $reduced = [Type::T_KEYWORD, ''];
-                }
-
-                return $this->compileValue($reduced);
-
-            case Type::T_NULL:
-                return 'null';
-
-            default:
-                $this->throwError("unknown value type: $value[0]");
-        }
-    }
-
-    /**
-     * Flatten list
-     *
-     * @param array $list
-     *
-     * @return string
-     */
-    protected function flattenList($list)
-    {
-        return $this->compileValue($list);
-    }
-
-    /**
-     * Compile string content
-     *
-     * @param array $string
-     *
-     * @return string
-     */
-    protected function compileStringContent($string)
-    {
-        $parts = [];
-
-        foreach ($string[2] as $part) {
-            if (is_array($part) || $part instanceof \ArrayAccess) {
-                $parts[] = $this->compileValue($part);
-            } else {
-                $parts[] = $part;
-            }
-        }
-
-        return implode($parts);
-    }
-
-    /**
-     * Extract interpolation; it doesn't need to be recursive, compileValue will handle that
-     *
-     * @param array $list
-     *
-     * @return array
-     */
-    protected function extractInterpolation($list)
-    {
-        $items = $list[2];
-
-        foreach ($items as $i => $item) {
-            if ($item[0] === Type::T_INTERPOLATE) {
-                $before = [Type::T_LIST, $list[1], array_slice($items, 0, $i)];
-                $after  = [Type::T_LIST, $list[1], array_slice($items, $i + 1)];
-
-                return [Type::T_INTERPOLATED, $item, $before, $after];
-            }
-        }
-
-        return $list;
-    }
-
-    /**
-     * Find the final set of selectors
-     *
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     * @param Leafo\ScssPhp\Block $selfParent
-     *
-     * @return array
-     */
-    protected function multiplySelectors(Environment $env, $selfParent = null)
-    {
-        $envs            = $this->compactEnv($env);
-        $selectors       = [];
-        $parentSelectors = [[]];
-
-        $selfParentSelectors = null;
-        if (!is_null($selfParent) and $selfParent->selectors) {
-            $selfParentSelectors = $this->evalSelectors($selfParent->selectors);
-        }
-
-        while ($env = array_pop($envs)) {
-            if (empty($env->selectors)) {
-                continue;
-            }
-
-            $selectors = [];
-
-            foreach ($env->selectors as $selector) {
-                foreach ($parentSelectors as $parent) {
-                    $selectors[] = $this->joinSelectors($parent, $selector, $selfParentSelectors);
-                }
-            }
-
-            $parentSelectors = $selectors;
-        }
-
-        return $selectors;
-    }
-
-    /**
-     * Join selectors; looks for & to replace, or append parent before child
-     *
-     * @param array $parent
-     * @param array $child
-     * @param array $selfParentSelectors
-     * @return array
-     */
-    protected function joinSelectors($parent, $child, $selfParentSelectors = null)
-    {
-        $setSelf = false;
-        $out = [];
-
-        foreach ($child as $part) {
-            $newPart = [];
-
-            foreach ($part as $p) {
-                if ($p === static::$selfSelector) {
-                    $setSelf = true;
-                    if (is_null($selfParentSelectors)) {
-                        $selfParentSelectors = $parent;
-                    }
-                    foreach ($selfParentSelectors as $i => $parentPart) {
-                        if ($i > 0) {
-                            $out[] = $newPart;
-                            $newPart = [];
-                        }
-
-                        foreach ($parentPart as $pp) {
-                            $newPart[] = (is_array($pp) ? implode($pp) : $pp);
-                        }
-                    }
-                } else {
-                    $newPart[] = $p;
-                }
-            }
-
-            $out[] = $newPart;
-        }
-
-        return $setSelf ? $out : array_merge($parent, $child);
-    }
-
-    /**
-     * Multiply media
-     *
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     * @param array                               $childQueries
-     *
-     * @return array
-     */
-    protected function multiplyMedia(Environment $env = null, $childQueries = null)
-    {
-        if (! isset($env) ||
-            ! empty($env->block->type) && $env->block->type !== Type::T_MEDIA
-        ) {
-            return $childQueries;
-        }
-
-        // plain old block, skip
-        if (empty($env->block->type)) {
-            return $this->multiplyMedia($env->parent, $childQueries);
-        }
-
-        $parentQueries = isset($env->block->queryList)
-            ? $env->block->queryList
-            : [[[Type::T_MEDIA_VALUE, $env->block->value]]];
-
-        if ($childQueries === null) {
-            $childQueries = $parentQueries;
-        } else {
-            $originalQueries = $childQueries;
-            $childQueries = [];
-
-            foreach ($parentQueries as $parentQuery) {
-                foreach ($originalQueries as $childQuery) {
-                    $childQueries []= array_merge($parentQuery, $childQuery);
-                }
-            }
-        }
-
-        return $this->multiplyMedia($env->parent, $childQueries);
-    }
-
-    /**
-     * Convert env linked list to stack
-     *
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     *
-     * @return array
-     */
-    protected function compactEnv(Environment $env)
-    {
-        for ($envs = []; $env; $env = $env->parent) {
-            $envs[] = $env;
-        }
-
-        return $envs;
-    }
-
-    /**
-     * Convert env stack to singly linked list
-     *
-     * @param array $envs
-     *
-     * @return \Leafo\ScssPhp\Compiler\Environment
-     */
-    protected function extractEnv($envs)
-    {
-        for ($env = null; $e = array_pop($envs);) {
-            $e->parent = $env;
-            $env = $e;
-        }
-
-        return $env;
-    }
-
-    /**
-     * Push environment
-     *
-     * @param \Leafo\ScssPhp\Block $block
-     *
-     * @return \Leafo\ScssPhp\Compiler\Environment
-     */
-    protected function pushEnv(Block $block = null)
-    {
-        $env = new Environment;
-        $env->parent = $this->env;
-        $env->store  = [];
-        $env->block  = $block;
-        $env->depth  = isset($this->env->depth) ? $this->env->depth + 1 : 0;
-
-        $this->env = $env;
-
-        return $env;
-    }
-
-    /**
-     * Pop environment
-     */
-    protected function popEnv()
-    {
-        $this->env = $this->env->parent;
-    }
-
-    /**
-     * Get store environment
-     *
-     * @return \Leafo\ScssPhp\Compiler\Environment
-     */
-    protected function getStoreEnv()
-    {
-        return isset($this->storeEnv) ? $this->storeEnv : $this->env;
-    }
-
-    /**
-     * Set variable
-     *
-     * @param string                              $name
-     * @param mixed                               $value
-     * @param boolean                             $shadow
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     * @param mixed                               $valueUnreduced
-     */
-    protected function set($name, $value, $shadow = false, Environment $env = null, $valueUnreduced = null)
-    {
-        $name = $this->normalizeName($name);
-
-        if (! isset($env)) {
-            $env = $this->getStoreEnv();
-        }
-
-        if ($shadow) {
-            $this->setRaw($name, $value, $env, $valueUnreduced);
-        } else {
-            $this->setExisting($name, $value, $env, $valueUnreduced);
-        }
-    }
-
-    /**
-     * Set existing variable
-     *
-     * @param string                              $name
-     * @param mixed                               $value
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     * @param mixed                               $valueUnreduced
-     */
-    protected function setExisting($name, $value, Environment $env, $valueUnreduced = null)
-    {
-        $storeEnv = $env;
-
-        $hasNamespace = $name[0] === '^' || $name[0] === '@' || $name[0] === '%';
-
-        for (;;) {
-            if (array_key_exists($name, $env->store)) {
-                break;
-            }
-
-            if (! $hasNamespace && isset($env->marker)) {
-                $env = $storeEnv;
-                break;
-            }
-
-            if (! isset($env->parent)) {
-                $env = $storeEnv;
-                break;
-            }
-
-            $env = $env->parent;
-        }
-
-        $env->store[$name] = $value;
-        if ($valueUnreduced) {
-            $env->storeUnreduced[$name] = $valueUnreduced;
-        }
-    }
-
-    /**
-     * Set raw variable
-     *
-     * @param string                              $name
-     * @param mixed                               $value
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     * @param mixed                               $valueUnreduced
-     */
-    protected function setRaw($name, $value, Environment $env, $valueUnreduced = null)
-    {
-        $env->store[$name] = $value;
-        if ($valueUnreduced) {
-            $env->storeUnreduced[$name] = $valueUnreduced;
-        }
-    }
-
-    /**
-     * Get variable
-     *
-     * @api
-     *
-     * @param string                              $name
-     * @param boolean                             $shouldThrow
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     * @param boolean                             $unreduced
-     *
-     * @return mixed|null
-     */
-    public function get($name, $shouldThrow = true, Environment $env = null, $unreduced = false)
-    {
-        $normalizedName = $this->normalizeName($name);
-        $specialContentKey = static::$namespaces['special'] . 'content';
-
-        if (! isset($env)) {
-            $env = $this->getStoreEnv();
-        }
-
-        $nextIsRoot = false;
-        $hasNamespace = $normalizedName[0] === '^' || $normalizedName[0] === '@' || $normalizedName[0] === '%';
-
-        for (;;) {
-            if (array_key_exists($normalizedName, $env->store)) {
-                if ($unreduced && isset($env->storeUnreduced[$normalizedName])) {
-                    return $env->storeUnreduced[$normalizedName];
-                }
-                return $env->store[$normalizedName];
-            }
-
-            if (! $hasNamespace && isset($env->marker)) {
-                if (! $nextIsRoot && ! empty($env->store[$specialContentKey])) {
-                    $env = $env->store[$specialContentKey]->scope;
-                    $nextIsRoot = true;
-                    continue;
-                }
-
-                $env = $this->rootEnv;
-                continue;
-            }
-
-            if (! isset($env->parent)) {
-                break;
-            }
-
-            $env = $env->parent;
-        }
-
-        if ($shouldThrow) {
-            $this->throwError("Undefined variable \$$name");
-        }
-
-        // found nothing
-        return null;
-    }
-
-    /**
-     * Has variable?
-     *
-     * @param string                              $name
-     * @param \Leafo\ScssPhp\Compiler\Environment $env
-     *
-     * @return boolean
-     */
-    protected function has($name, Environment $env = null)
-    {
-        return $this->get($name, false, $env) !== null;
-    }
-
-    /**
-     * Inject variables
-     *
-     * @param array $args
-     */
-    protected function injectVariables(array $args)
-    {
-        if (empty($args)) {
-            return;
-        }
-
-        $parser = $this->parserFactory(__METHOD__);
-
-        foreach ($args as $name => $strValue) {
-            if ($name[0] === '$') {
-                $name = substr($name, 1);
-            }
-
-            if (! $parser->parseValue($strValue, $value)) {
-                $value = $this->coerceValue($strValue);
-            }
-
-            $this->set($name, $value);
-        }
-    }
-
-    /**
-     * Set variables
-     *
-     * @api
-     *
-     * @param array $variables
-     */
-    public function setVariables(array $variables)
-    {
-        $this->registeredVars = array_merge($this->registeredVars, $variables);
-    }
-
-    /**
-     * Unset variable
-     *
-     * @api
-     *
-     * @param string $name
-     */
-    public function unsetVariable($name)
-    {
-        unset($this->registeredVars[$name]);
-    }
-
-    /**
-     * Returns list of variables
-     *
-     * @api
-     *
-     * @return array
-     */
-    public function getVariables()
-    {
-        return $this->registeredVars;
-    }
-
-    /**
-     * Adds to list of parsed files
-     *
-     * @api
-     *
-     * @param string $path
-     */
-    public function addParsedFile($path)
-    {
-        if (isset($path) && file_exists($path)) {
-            $this->parsedFiles[realpath($path)] = filemtime($path);
-        }
-    }
-
-    /**
-     * Returns list of parsed files
-     *
-     * @api
-     *
-     * @return array
-     */
-    public function getParsedFiles()
-    {
-        return $this->parsedFiles;
-    }
-
-    /**
-     * Add import path
-     *
-     * @api
-     *
-     * @param string|callable $path
-     */
-    public function addImportPath($path)
-    {
-        if (! in_array($path, $this->importPaths)) {
-            $this->importPaths[] = $path;
-        }
-    }
-
-    /**
-     * Set import paths
-     *
-     * @api
-     *
-     * @param string|array $path
-     */
-    public function setImportPaths($path)
-    {
-        $this->importPaths = (array) $path;
-    }
-
-    /**
-     * Set number precision
-     *
-     * @api
-     *
-     * @param integer $numberPrecision
-     */
-    public function setNumberPrecision($numberPrecision)
-    {
-        Node\Number::$precision = $numberPrecision;
-    }
-
-    /**
-     * Set formatter
-     *
-     * @api
-     *
-     * @param string $formatterName
-     */
-    public function setFormatter($formatterName)
-    {
-        $this->formatter = $formatterName;
-    }
-
-    /**
-     * Set line number style
-     *
-     * @api
-     *
-     * @param string $lineNumberStyle
-     */
-    public function setLineNumberStyle($lineNumberStyle)
-    {
-        $this->lineNumberStyle = $lineNumberStyle;
-    }
-
-    /**
-     * Enable/disable source maps
-     *
-     * @api
-     *
-     * @param integer $sourceMap
-     */
-    public function setSourceMap($sourceMap)
-    {
-        $this->sourceMap = $sourceMap;
-    }
-
-    /**
-     * Set source map options
-     *
-     * @api
-     *
-     * @param array $sourceMapOptions
-     */
-    public function setSourceMapOptions($sourceMapOptions)
-    {
-        $this->sourceMapOptions = $sourceMapOptions;
-    }
-
-    /**
-     * Register function
-     *
-     * @api
-     *
-     * @param string   $name
-     * @param callable $func
-     * @param array    $prototype
-     */
-    public function registerFunction($name, $func, $prototype = null)
-    {
-        $this->userFunctions[$this->normalizeName($name)] = [$func, $prototype];
-    }
-
-    /**
-     * Unregister function
-     *
-     * @api
-     *
-     * @param string $name
-     */
-    public function unregisterFunction($name)
-    {
-        unset($this->userFunctions[$this->normalizeName($name)]);
-    }
-
-    /**
-     * Add feature
-     *
-     * @api
-     *
-     * @param string $name
-     */
-    public function addFeature($name)
-    {
-        $this->registeredFeatures[$name] = true;
-    }
-
-    /**
-     * Import file
-     *
-     * @param string $path
-     * @param array  $out
-     */
-    protected function importFile($path, $out)
-    {
-        // see if tree is cached
-        $realPath = realpath($path);
-
-        if (isset($this->importCache[$realPath])) {
-            $this->handleImportLoop($realPath);
-
-            $tree = $this->importCache[$realPath];
-        } else {
-            $code   = file_get_contents($path);
-            $parser = $this->parserFactory($path);
-            $tree   = $parser->parse($code);
-
-            $this->importCache[$realPath] = $tree;
-        }
-
-        $pi = pathinfo($path);
-        array_unshift($this->importPaths, $pi['dirname']);
-        $this->compileChildrenNoReturn($tree->children, $out);
-        array_shift($this->importPaths);
-    }
-
-    /**
-     * Return the file path for an import url if it exists
-     *
-     * @api
-     *
-     * @param string $url
-     *
-     * @return string|null
-     */
-    public function findImport($url)
-    {
-        $urls = [];
-
-        // for "normal" scss imports (ignore vanilla css and external requests)
-        if (! preg_match('/\.css$|^https?:\/\//', $url)) {
-            // try both normal and the _partial filename
-            $urls = [$url, preg_replace('/[^\/]+$/', '_\0', $url)];
-        }
-
-        $hasExtension = preg_match('/[.]s?css$/', $url);
-
-        foreach ($this->importPaths as $dir) {
-            if (is_string($dir)) {
-                // check urls for normal import paths
-                foreach ($urls as $full) {
-                    $separator = (
-                        !empty($dir) &&
-                        substr($dir, -1) !== '/' &&
-                        substr($full, 0, 1) !== '/'
-                    ) ? '/' : '';
-                    $full = $dir . $separator . $full;
-
-                    if ($this->fileExists($file = $full . '.scss') ||
-                        ($hasExtension && $this->fileExists($file = $full))
-                    ) {
-                        return $file;
-                    }
-                }
-            } elseif (is_callable($dir)) {
-                // check custom callback for import path
-                $file = call_user_func($dir, $url);
-
-                if ($file !== null) {
-                    return $file;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Set encoding
-     *
-     * @api
-     *
-     * @param string $encoding
-     */
-    public function setEncoding($encoding)
-    {
-        $this->encoding = $encoding;
-    }
-
-    /**
-     * Ignore errors?
-     *
-     * @api
-     *
-     * @param boolean $ignoreErrors
-     *
-     * @return \Leafo\ScssPhp\Compiler
-     */
-    public function setIgnoreErrors($ignoreErrors)
-    {
-        $this->ignoreErrors = $ignoreErrors;
-        return $this;
-    }
-
-    /**
-     * Throw error (exception)
-     *
-     * @api
-     *
-     * @param string $msg Message with optional sprintf()-style vararg parameters
-     *
-     * @throws \Leafo\ScssPhp\Exception\CompilerException
-     */
-    public function throwError($msg)
-    {
-        if ($this->ignoreErrors) {
-            return;
-        }
-
-        if (func_num_args() > 1) {
-            $msg = call_user_func_array('sprintf', func_get_args());
-        }
-
-        $line = $this->sourceLine;
-        $loc = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] . " on line $line" : "line: $line";
-        $msg = "$msg: $loc";
-
-        throw new CompilerException($msg);
-    }
-
-    /**
-     * Handle import loop
-     *
-     * @param string $name
-     *
-     * @throws \Exception
-     */
-    protected function handleImportLoop($name)
-    {
-        for ($env = $this->env; $env; $env = $env->parent) {
-            $file = $this->sourceNames[$env->block->sourceIndex];
-
-            if (realpath($file) === $name) {
-                $this->throwError('An @import loop has been found: %s imports %s', $file, basename($file));
-                break;
-            }
-        }
-    }
-
-    /**
-     * Does file exist?
-     *
-     * @param string $name
-     *
-     * @return boolean
-     */
-    protected function fileExists($name)
-    {
-        return file_exists($name) && is_file($name);
-    }
-
-    /**
-     * Call SCSS @function
-     *
-     * @param string $name
-     * @param array  $argValues
-     * @param array  $returnValue
-     *
-     * @return boolean Returns true if returnValue is set; otherwise, false
-     */
-    protected function callScssFunction($name, $argValues, &$returnValue)
-    {
-        $func = $this->get(static::$namespaces['function'] . $name, false);
-
-        if (! $func) {
-            return false;
-        }
-
-        $this->pushEnv();
-
-        $storeEnv = $this->storeEnv;
-        $this->storeEnv = $this->env;
-
-        // set the args
-        if (isset($func->args)) {
-            $this->applyArguments($func->args, $argValues);
-        }
-
-        // throw away lines and children
-        $tmp = new OutputBlock;
-        $tmp->lines    = [];
-        $tmp->children = [];
-
-        $this->env->marker = 'function';
-
-        $ret = $this->compileChildren($func->children, $tmp);
-
-        $this->storeEnv = $storeEnv;
-
-        $this->popEnv();
-
-        $returnValue = ! isset($ret) ? static::$defaultValue : $ret;
-
-        return true;
-    }
-
-    /**
-     * Call built-in and registered (PHP) functions
-     *
-     * @param string $name
-     * @param array  $args
-     * @param array  $returnValue
-     *
-     * @return boolean Returns true if returnValue is set; otherwise, false
-     */
-    protected function callNativeFunction($name, $args, &$returnValue)
-    {
-        // try a lib function
-        $name = $this->normalizeName($name);
-
-        if (isset($this->userFunctions[$name])) {
-            // see if we can find a user function
-            list($f, $prototype) = $this->userFunctions[$name];
-        } elseif (($f = $this->getBuiltinFunction($name)) && is_callable($f)) {
-            $libName   = $f[1];
-            $prototype = isset(static::$$libName) ? static::$$libName : null;
-        } else {
-            return false;
-        }
-
-        @list($sorted, $kwargs) = $this->sortArgs($prototype, $args);
-
-        if ($name !== 'if' && $name !== 'call') {
-            foreach ($sorted as &$val) {
-                $val = $this->reduce($val, true);
-            }
-        }
-
-        $returnValue = call_user_func($f, $sorted, $kwargs);
-
-        if (! isset($returnValue)) {
-            return false;
-        }
-
-        $returnValue = $this->coerceValue($returnValue);
-
-        return true;
-    }
-
-    /**
-     * Get built-in function
-     *
-     * @param string $name Normalized name
-     *
-     * @return array
-     */
-    protected function getBuiltinFunction($name)
-    {
-        $libName = 'lib' . preg_replace_callback(
-            '/_(.)/',
-            function ($m) {
-                return ucfirst($m[1]);
-            },
-            ucfirst($name)
-        );
-
-        return [$this, $libName];
-    }
-
-    /**
-     * Sorts keyword arguments
-     *
-     * @param array $prototype
-     * @param array $args
-     *
-     * @return array
-     */
-    protected function sortArgs($prototype, $args)
-    {
-        $keyArgs = [];
-        $posArgs = [];
-
-        // separate positional and keyword arguments
-        foreach ($args as $arg) {
-            list($key, $value) = $arg;
-
-            $key = $key[1];
-
-            if (empty($key)) {
-                $posArgs[] = empty($arg[2]) ? $value : $arg;
-            } else {
-                $keyArgs[$key] = $value;
-            }
-        }
-
-        if (! isset($prototype)) {
-            return [$posArgs, $keyArgs];
-        }
-
-        // copy positional args
-        $finalArgs = array_pad($posArgs, count($prototype), null);
-
-        // overwrite positional args with keyword args
-        foreach ($prototype as $i => $names) {
-            foreach ((array) $names as $name) {
-                if (isset($keyArgs[$name])) {
-                    $finalArgs[$i] = $keyArgs[$name];
-                }
-            }
-        }
-
-        return [$finalArgs, $keyArgs];
-    }
-
-    /**
-     * Apply argument values per definition
-     *
-     * @param array $argDef
-     * @param array $argValues
-     *
-     * @throws \Exception
-     */
-    protected function applyArguments($argDef, $argValues)
-    {
-        $storeEnv = $this->getStoreEnv();
-
-        $env = new Environment;
-        $env->store = $storeEnv->store;
-
-        $hasVariable = false;
-        $args = [];
-
-        foreach ($argDef as $i => $arg) {
-            list($name, $default, $isVariable) = $argDef[$i];
-
-            $args[$name] = [$i, $name, $default, $isVariable];
-            $hasVariable |= $isVariable;
-        }
-
-        $keywordArgs = [];
-        $deferredKeywordArgs = [];
-        $remaining = [];
-
-        // assign the keyword args
-        foreach ((array) $argValues as $arg) {
-            if (! empty($arg[0])) {
-                if (! isset($args[$arg[0][1]])) {
-                    if ($hasVariable) {
-                        $deferredKeywordArgs[$arg[0][1]] = $arg[1];
-                    } else {
-                        $this->throwError("Mixin or function doesn't have an argument named $%s.", $arg[0][1]);
-                        break;
-                    }
-                } elseif ($args[$arg[0][1]][0] < count($remaining)) {
-                    $this->throwError("The argument $%s was passed both by position and by name.", $arg[0][1]);
-                    break;
-                } else {
-                    $keywordArgs[$arg[0][1]] = $arg[1];
-                }
-            } elseif (count($keywordArgs)) {
-                $this->throwError('Positional arguments must come before keyword arguments.');
-                break;
-            } elseif ($arg[2] === true) {
-                $val = $this->reduce($arg[1], true);
-
-                if ($val[0] === Type::T_LIST) {
-                    foreach ($val[2] as $name => $item) {
-                        if (! is_numeric($name)) {
-                            $keywordArgs[$name] = $item;
-                        } else {
-                            $remaining[] = $item;
-                        }
-                    }
-                } elseif ($val[0] === Type::T_MAP) {
-                    foreach ($val[1] as $i => $name) {
-                        $name = $this->compileStringContent($this->coerceString($name));
-                        $item = $val[2][$i];
-
-                        if (! is_numeric($name)) {
-                            $keywordArgs[$name] = $item;
-                        } else {
-                            $remaining[] = $item;
-                        }
-                    }
-                } else {
-                    $remaining[] = $val;
-                }
-            } else {
-                $remaining[] = $arg[1];
-            }
-        }
-
-        foreach ($args as $arg) {
-            list($i, $name, $default, $isVariable) = $arg;
-
-            if ($isVariable) {
-                $val = [Type::T_LIST, ',', [], $isVariable];
-
-                for ($count = count($remaining); $i < $count; $i++) {
-                    $val[2][] = $remaining[$i];
-                }
-
-                foreach ($deferredKeywordArgs as $itemName => $item) {
-                    $val[2][$itemName] = $item;
-                }
-            } elseif (isset($remaining[$i])) {
-                $val = $remaining[$i];
-            } elseif (isset($keywordArgs[$name])) {
-                $val = $keywordArgs[$name];
-            } elseif (! empty($default)) {
-                continue;
-            } else {
-                $this->throwError("Missing argument $name");
-                break;
-            }
-
-            $this->set($name, $this->reduce($val, true), true, $env);
-        }
-
-        $storeEnv->store = $env->store;
-
-        foreach ($args as $arg) {
-            list($i, $name, $default, $isVariable) = $arg;
-
-            if ($isVariable || isset($remaining[$i]) || isset($keywordArgs[$name]) || empty($default)) {
-                continue;
-            }
-
-            $this->set($name, $this->reduce($default, true), true);
-        }
-    }
-
-    /**
-     * Coerce a php value into a scss one
-     *
-     * @param mixed $value
-     *
-     * @return array|\Leafo\ScssPhp\Node\Number
-     */
-    protected function coerceValue($value)
-    {
-        if (is_array($value) || $value instanceof \ArrayAccess) {
-            return $value;
-        }
-
-        if (is_bool($value)) {
-            return $this->toBool($value);
-        }
-
-        if ($value === null) {
-            return static::$null;
-        }
-
-        if (is_numeric($value)) {
-            return new Node\Number($value, '');
-        }
-
-        if ($value === '') {
-            return static::$emptyString;
-        }
-
-        if (preg_match('/^(#([0-9a-f]{6})|#([0-9a-f]{3}))$/i', $value, $m)) {
-            $color = [Type::T_COLOR];
-
-            if (isset($m[3])) {
-                $num = hexdec($m[3]);
-
-                foreach ([3, 2, 1] as $i) {
-                    $t = $num & 0xf;
-                    $color[$i] = $t << 4 | $t;
-                    $num >>= 4;
-                }
-            } else {
-                $num = hexdec($m[2]);
-
-                foreach ([3, 2, 1] as $i) {
-                    $color[$i] = $num & 0xff;
-                    $num >>= 8;
-                }
-            }
-
-            return $color;
-        }
-
-        return [Type::T_KEYWORD, $value];
-    }
-
-    /**
-     * Coerce something to map
-     *
-     * @param array $item
-     *
-     * @return array
-     */
-    protected function coerceMap($item)
-    {
-        if ($item[0] === Type::T_MAP) {
-            return $item;
-        }
-
-        if ($item === static::$emptyList) {
-            return static::$emptyMap;
-        }
-
-        return [Type::T_MAP, [$item], [static::$null]];
-    }
-
-    /**
-     * Coerce something to list
-     *
-     * @param array  $item
-     * @param string $delim
-     *
-     * @return array
-     */
-    protected function coerceList($item, $delim = ',')
-    {
-        if (isset($item) && $item[0] === Type::T_LIST) {
-            return $item;
-        }
-
-        if (isset($item) && $item[0] === Type::T_MAP) {
-            $keys = $item[1];
-            $values = $item[2];
-            $list = [];
-
-            for ($i = 0, $s = count($keys); $i < $s; $i++) {
-                $key = $keys[$i];
-                $value = $values[$i];
-
-                $list[] = [
-                    Type::T_LIST,
-                    '',
-                    [[Type::T_KEYWORD, $this->compileStringContent($this->coerceString($key))], $value]
-                ];
-            }
-
-            return [Type::T_LIST, ',', $list];
-        }
-
-        return [Type::T_LIST, $delim, ! isset($item) ? []: [$item]];
-    }
-
-    /**
-     * Coerce color for expression
-     *
-     * @param array $value
-     *
-     * @return array|null
-     */
-    protected function coerceForExpression($value)
-    {
-        if ($color = $this->coerceColor($value)) {
-            return $color;
-        }
-
-        return $value;
-    }
-
-    /**
-     * Coerce value to color
-     *
-     * @param array $value
-     *
-     * @return array|null
-     */
-    protected function coerceColor($value)
-    {
-        switch ($value[0]) {
-            case Type::T_COLOR:
-                return $value;
-
-            case Type::T_KEYWORD:
-                $name = strtolower($value[1]);
-
-                if (isset(Colors::$cssColors[$name])) {
-                    $rgba = explode(',', Colors::$cssColors[$name]);
-
-                    return isset($rgba[3])
-                        ? [Type::T_COLOR, (int) $rgba[0], (int) $rgba[1], (int) $rgba[2], (int) $rgba[3]]
-                        : [Type::T_COLOR, (int) $rgba[0], (int) $rgba[1], (int) $rgba[2]];
-                }
-
-                return null;
-        }
-
-        return null;
-    }
-
-    /**
-     * Coerce value to string
-     *
-     * @param array $value
-     *
-     * @return array|null
-     */
-    protected function coerceString($value)
-    {
-        if ($value[0] === Type::T_STRING) {
-            return $value;
-        }
-
-        return [Type::T_STRING, '', [$this->compileValue($value)]];
-    }
-
-    /**
-     * Coerce value to a percentage
-     *
-     * @param array $value
-     *
-     * @return integer|float
-     */
-    protected function coercePercent($value)
-    {
-        if ($value[0] === Type::T_NUMBER) {
-            if (! empty($value[2]['%'])) {
-                return $value[1] / 100;
-            }
-
-            return $value[1];
-        }
-
-        return 0;
-    }
-
-    /**
-     * Assert value is a map
-     *
-     * @api
-     *
-     * @param array $value
-     *
-     * @return array
-     *
-     * @throws \Exception
-     */
-    public function assertMap($value)
-    {
-        $value = $this->coerceMap($value);
-
-        if ($value[0] !== Type::T_MAP) {
-            $this->throwError('expecting map, %s received', $value[0]);
-        }
-
-        return $value;
-    }
-
-    /**
-     * Assert value is a list
-     *
-     * @api
-     *
-     * @param array $value
-     *
-     * @return array
-     *
-     * @throws \Exception
-     */
-    public function assertList($value)
-    {
-        if ($value[0] !== Type::T_LIST) {
-            $this->throwError('expecting list, %s received', $value[0]);
-        }
-
-        return $value;
-    }
-
-    /**
-     * Assert value is a color
-     *
-     * @api
-     *
-     * @param array $value
-     *
-     * @return array
-     *
-     * @throws \Exception
-     */
-    public function assertColor($value)
-    {
-        if ($color = $this->coerceColor($value)) {
-            return $color;
-        }
-
-        $this->throwError('expecting color, %s received', $value[0]);
-    }
-
-    /**
-     * Assert value is a number
-     *
-     * @api
-     *
-     * @param array $value
-     *
-     * @return integer|float
-     *
-     * @throws \Exception
-     */
-    public function assertNumber($value)
-    {
-        if ($value[0] !== Type::T_NUMBER) {
-            $this->throwError('expecting number, %s received', $value[0]);
-        }
-
-        return $value[1];
-    }
-
-    /**
-     * Make sure a color's components don't go out of bounds
-     *
-     * @param array $c
-     *
-     * @return array
-     */
-    protected function fixColor($c)
-    {
-        foreach ([1, 2, 3] as $i) {
-            if ($c[$i] < 0) {
-                $c[$i] = 0;
-            }
-
-            if ($c[$i] > 255) {
-                $c[$i] = 255;
-            }
-        }
-
-        return $c;
-    }
-
-    /**
-     * Convert RGB to HSL
-     *
-     * @api
-     *
-     * @param integer $red
-     * @param integer $green
-     * @param integer $blue
-     *
-     * @return array
-     */
-    public function toHSL($red, $green, $blue)
-    {
-        $min = min($red, $green, $blue);
-        $max = max($red, $green, $blue);
-
-        $l = $min + $max;
-        $d = $max - $min;
-
-        if ((int) $d === 0) {
-            $h = $s = 0;
-        } else {
-            if ($l < 255) {
-                $s = $d / $l;
-            } else {
-                $s = $d / (510 - $l);
-            }
-
-            if ($red == $max) {
-                $h = 60 * ($green - $blue) / $d;
-            } elseif ($green == $max) {
-                $h = 60 * ($blue - $red) / $d + 120;
-            } elseif ($blue == $max) {
-                $h = 60 * ($red - $green) / $d + 240;
-            }
-        }
-
-        return [Type::T_HSL, fmod($h, 360), $s * 100, $l / 5.1];
-    }
-
-    /**
-     * Hue to RGB helper
-     *
-     * @param float $m1
-     * @param float $m2
-     * @param float $h
-     *
-     * @return float
-     */
-    protected function hueToRGB($m1, $m2, $h)
-    {
-        if ($h < 0) {
-            $h += 1;
-        } elseif ($h > 1) {
-            $h -= 1;
-        }
-
-        if ($h * 6 < 1) {
-            return $m1 + ($m2 - $m1) * $h * 6;
-        }
-
-        if ($h * 2 < 1) {
-            return $m2;
-        }
-
-        if ($h * 3 < 2) {
-            return $m1 + ($m2 - $m1) * (2/3 - $h) * 6;
-        }
-
-        return $m1;
-    }
-
-    /**
-     * Convert HSL to RGB
-     *
-     * @api
-     *
-     * @param integer $hue        H from 0 to 360
-     * @param integer $saturation S from 0 to 100
-     * @param integer $lightness  L from 0 to 100
-     *
-     * @return array
-     */
-    public function toRGB($hue, $saturation, $lightness)
-    {
-        if ($hue < 0) {
-            $hue += 360;
-        }
-
-        $h = $hue / 360;
-        $s = min(100, max(0, $saturation)) / 100;
-        $l = min(100, max(0, $lightness)) / 100;
-
-        $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s;
-        $m1 = $l * 2 - $m2;
-
-        $r = $this->hueToRGB($m1, $m2, $h + 1/3) * 255;
-        $g = $this->hueToRGB($m1, $m2, $h) * 255;
-        $b = $this->hueToRGB($m1, $m2, $h - 1/3) * 255;
-
-        $out = [Type::T_COLOR, $r, $g, $b];
-
-        return $out;
-    }
-
-    // Built in functions
-
-    //protected static $libCall = ['name', 'args...'];
-    protected function libCall($args, $kwargs)
-    {
-        $name = $this->compileStringContent($this->coerceString($this->reduce(array_shift($args), true)));
-
-        $posArgs = [];
-
-        foreach ($args as $arg) {
-            if (empty($arg[0])) {
-                if ($arg[2] === true) {
-                    $tmp = $this->reduce($arg[1]);
-
-                    if ($tmp[0] === Type::T_LIST) {
-                        foreach ($tmp[2] as $item) {
-                            $posArgs[] = [null, $item, false];
-                        }
-                    } else {
-                        $posArgs[] = [null, $tmp, true];
-                    }
-
-                    continue;
-                }
-
-                $posArgs[] = [null, $this->reduce($arg), false];
-                continue;
-            }
-
-            $posArgs[] = [null, $arg, false];
-        }
-
-        if (count($kwargs)) {
-            foreach ($kwargs as $key => $value) {
-                $posArgs[] = [[Type::T_VARIABLE, $key], $value, false];
-            }
-        }
-
-        return $this->reduce([Type::T_FUNCTION_CALL, $name, $posArgs]);
-    }
-
-    protected static $libIf = ['condition', 'if-true', 'if-false'];
-    protected function libIf($args)
-    {
-        list($cond, $t, $f) = $args;
-
-        if (! $this->isTruthy($this->reduce($cond, true))) {
-            return $this->reduce($f, true);
-        }
-
-        return $this->reduce($t, true);
-    }
-
-    protected static $libIndex = ['list', 'value'];
-    protected function libIndex($args)
-    {
-        list($list, $value) = $args;
-
-        if ($value[0] === Type::T_MAP) {
-            return static::$null;
-        }
-
-        if ($list[0] === Type::T_MAP ||
-            $list[0] === Type::T_STRING ||
-            $list[0] === Type::T_KEYWORD ||
-            $list[0] === Type::T_INTERPOLATE
-        ) {
-            $list = $this->coerceList($list, ' ');
-        }
-
-        if ($list[0] !== Type::T_LIST) {
-            return static::$null;
-        }
-
-        $values = [];
-
-        foreach ($list[2] as $item) {
-            $values[] = $this->normalizeValue($item);
-        }
-
-        $key = array_search($this->normalizeValue($value), $values);
-
-        return false === $key ? static::$null : $key + 1;
-    }
-
-    protected static $libRgb = ['red', 'green', 'blue'];
-    protected function libRgb($args)
-    {
-        list($r, $g, $b) = $args;
-
-        return [Type::T_COLOR, $r[1], $g[1], $b[1]];
-    }
-
-    protected static $libRgba = [
-        ['red', 'color'],
-        'green', 'blue', 'alpha'];
-    protected function libRgba($args)
-    {
-        if ($color = $this->coerceColor($args[0])) {
-            $num = isset($args[3]) ? $args[3] : $args[1];
-            $alpha = $this->assertNumber($num);
-            $color[4] = $alpha;
-
-            return $color;
-        }
-
-        list($r, $g, $b, $a) = $args;
-
-        return [Type::T_COLOR, $r[1], $g[1], $b[1], $a[1]];
-    }
-
-    // helper function for adjust_color, change_color, and scale_color
-    protected function alterColor($args, $fn)
-    {
-        $color = $this->assertColor($args[0]);
-
-        foreach ([1, 2, 3, 7] as $i) {
-            if (isset($args[$i])) {
-                $val = $this->assertNumber($args[$i]);
-                $ii = $i === 7 ? 4 : $i; // alpha
-                $color[$ii] = call_user_func($fn, isset($color[$ii]) ? $color[$ii] : 0, $val, $i);
-            }
-        }
-
-        if (isset($args[4]) || isset($args[5]) || isset($args[6])) {
-            $hsl = $this->toHSL($color[1], $color[2], $color[3]);
-
-            foreach ([4, 5, 6] as $i) {
-                if (isset($args[$i])) {
-                    $val = $this->assertNumber($args[$i]);
-                    $hsl[$i - 3] = call_user_func($fn, $hsl[$i - 3], $val, $i);
-                }
-            }
-
-            $rgb = $this->toRGB($hsl[1], $hsl[2], $hsl[3]);
-
-            if (isset($color[4])) {
-                $rgb[4] = $color[4];
-            }
-
-            $color = $rgb;
-        }
-
-        return $color;
-    }
-
-    protected static $libAdjustColor = [
-        'color', 'red', 'green', 'blue',
-        'hue', 'saturation', 'lightness', 'alpha'
-    ];
-    protected function libAdjustColor($args)
-    {
-        return $this->alterColor($args, function ($base, $alter, $i) {
-            return $base + $alter;
-        });
-    }
-
-    protected static $libChangeColor = [
-        'color', 'red', 'green', 'blue',
-        'hue', 'saturation', 'lightness', 'alpha'
-    ];
-    protected function libChangeColor($args)
-    {
-        return $this->alterColor($args, function ($base, $alter, $i) {
-            return $alter;
-        });
-    }
-
-    protected static $libScaleColor = [
-        'color', 'red', 'green', 'blue',
-        'hue', 'saturation', 'lightness', 'alpha'
-    ];
-    protected function libScaleColor($args)
-    {
-        return $this->alterColor($args, function ($base, $scale, $i) {
-            // 1, 2, 3 - rgb
-            // 4, 5, 6 - hsl
-            // 7 - a
-            switch ($i) {
-                case 1:
-                case 2:
-                case 3:
-                    $max = 255;
-                    break;
-
-                case 4:
-                    $max = 360;
-                    break;
-
-                case 7:
-                    $max = 1;
-                    break;
-
-                default:
-                    $max = 100;
-            }
-
-            $scale = $scale / 100;
-
-            if ($scale < 0) {
-                return $base * $scale + $base;
-            }
-
-            return ($max - $base) * $scale + $base;
-        });
-    }
-
-    protected static $libIeHexStr = ['color'];
-    protected function libIeHexStr($args)
-    {
-        $color = $this->coerceColor($args[0]);
-        $color[4] = isset($color[4]) ? round(255 * $color[4]) : 255;
-
-        return sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3]);
-    }
-
-    protected static $libRed = ['color'];
-    protected function libRed($args)
-    {
-        $color = $this->coerceColor($args[0]);
-
-        return $color[1];
-    }
-
-    protected static $libGreen = ['color'];
-    protected function libGreen($args)
-    {
-        $color = $this->coerceColor($args[0]);
-
-        return $color[2];
-    }
-
-    protected static $libBlue = ['color'];
-    protected function libBlue($args)
-    {
-        $color = $this->coerceColor($args[0]);
-
-        return $color[3];
-    }
-
-    protected static $libAlpha = ['color'];
-    protected function libAlpha($args)
-    {
-        if ($color = $this->coerceColor($args[0])) {
-            return isset($color[4]) ? $color[4] : 1;
-        }
-
-        // this might be the IE function, so return value unchanged
-        return null;
-    }
-
-    protected static $libOpacity = ['color'];
-    protected function libOpacity($args)
-    {
-        $value = $args[0];
-
-        if ($value[0] === Type::T_NUMBER) {
-            return null;
-        }
-
-        return $this->libAlpha($args);
-    }
-
-    // mix two colors
-    protected static $libMix = ['color-1', 'color-2', 'weight'];
-    protected function libMix($args)
-    {
-        list($first, $second, $weight) = $args;
-
-        $first = $this->assertColor($first);
-        $second = $this->assertColor($second);
-
-        if (! isset($weight)) {
-            $weight = 0.5;
-        } else {
-            $weight = $this->coercePercent($weight);
-        }
-
-        $firstAlpha = isset($first[4]) ? $first[4] : 1;
-        $secondAlpha = isset($second[4]) ? $second[4] : 1;
-
-        $w = $weight * 2 - 1;
-        $a = $firstAlpha - $secondAlpha;
-
-        $w1 = (($w * $a === -1 ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2.0;
-        $w2 = 1.0 - $w1;
-
-        $new = [Type::T_COLOR,
-            $w1 * $first[1] + $w2 * $second[1],
-            $w1 * $first[2] + $w2 * $second[2],
-            $w1 * $first[3] + $w2 * $second[3],
-        ];
-
-        if ($firstAlpha != 1.0 || $secondAlpha != 1.0) {
-            $new[] = $firstAlpha * $weight + $secondAlpha * (1 - $weight);
-        }
-
-        return $this->fixColor($new);
-    }
-
-    protected static $libHsl = ['hue', 'saturation', 'lightness'];
-    protected function libHsl($args)
-    {
-        list($h, $s, $l) = $args;
-
-        return $this->toRGB($h[1], $s[1], $l[1]);
-    }
-
-    protected static $libHsla = ['hue', 'saturation', 'lightness', 'alpha'];
-    protected function libHsla($args)
-    {
-        list($h, $s, $l, $a) = $args;
-
-        $color = $this->toRGB($h[1], $s[1], $l[1]);
-        $color[4] = $a[1];
-
-        return $color;
-    }
-
-    protected static $libHue = ['color'];
-    protected function libHue($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
-
-        return new Node\Number($hsl[1], 'deg');
-    }
-
-    protected static $libSaturation = ['color'];
-    protected function libSaturation($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
-
-        return new Node\Number($hsl[2], '%');
-    }
-
-    protected static $libLightness = ['color'];
-    protected function libLightness($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
-
-        return new Node\Number($hsl[3], '%');
-    }
-
-    protected function adjustHsl($color, $idx, $amount)
-    {
-        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
-        $hsl[$idx] += $amount;
-        $out = $this->toRGB($hsl[1], $hsl[2], $hsl[3]);
-
-        if (isset($color[4])) {
-            $out[4] = $color[4];
-        }
-
-        return $out;
-    }
-
-    protected static $libAdjustHue = ['color', 'degrees'];
-    protected function libAdjustHue($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $degrees = $this->assertNumber($args[1]);
-
-        return $this->adjustHsl($color, 1, $degrees);
-    }
-
-    protected static $libLighten = ['color', 'amount'];
-    protected function libLighten($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%');
-
-        return $this->adjustHsl($color, 3, $amount);
-    }
-
-    protected static $libDarken = ['color', 'amount'];
-    protected function libDarken($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%');
-
-        return $this->adjustHsl($color, 3, -$amount);
-    }
-
-    protected static $libSaturate = ['color', 'amount'];
-    protected function libSaturate($args)
-    {
-        $value = $args[0];
-
-        if ($value[0] === Type::T_NUMBER) {
-            return null;
-        }
-
-        $color = $this->assertColor($value);
-        $amount = 100 * $this->coercePercent($args[1]);
-
-        return $this->adjustHsl($color, 2, $amount);
-    }
-
-    protected static $libDesaturate = ['color', 'amount'];
-    protected function libDesaturate($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $amount = 100 * $this->coercePercent($args[1]);
-
-        return $this->adjustHsl($color, 2, -$amount);
-    }
-
-    protected static $libGrayscale = ['color'];
-    protected function libGrayscale($args)
-    {
-        $value = $args[0];
-
-        if ($value[0] === Type::T_NUMBER) {
-            return null;
-        }
-
-        return $this->adjustHsl($this->assertColor($value), 2, -100);
-    }
-
-    protected static $libComplement = ['color'];
-    protected function libComplement($args)
-    {
-        return $this->adjustHsl($this->assertColor($args[0]), 1, 180);
-    }
-
-    protected static $libInvert = ['color'];
-    protected function libInvert($args)
-    {
-        $value = $args[0];
-
-        if ($value[0] === Type::T_NUMBER) {
-            return null;
-        }
-
-        $color = $this->assertColor($value);
-        $color[1] = 255 - $color[1];
-        $color[2] = 255 - $color[2];
-        $color[3] = 255 - $color[3];
-
-        return $color;
-    }
-
-    // increases opacity by amount
-    protected static $libOpacify = ['color', 'amount'];
-    protected function libOpacify($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $amount = $this->coercePercent($args[1]);
-
-        $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount;
-        $color[4] = min(1, max(0, $color[4]));
-
-        return $color;
-    }
-
-    protected static $libFadeIn = ['color', 'amount'];
-    protected function libFadeIn($args)
-    {
-        return $this->libOpacify($args);
-    }
-
-    // decreases opacity by amount
-    protected static $libTransparentize = ['color', 'amount'];
-    protected function libTransparentize($args)
-    {
-        $color = $this->assertColor($args[0]);
-        $amount = $this->coercePercent($args[1]);
-
-        $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount;
-        $color[4] = min(1, max(0, $color[4]));
-
-        return $color;
-    }
-
-    protected static $libFadeOut = ['color', 'amount'];
-    protected function libFadeOut($args)
-    {
-        return $this->libTransparentize($args);
-    }
-
-    protected static $libUnquote = ['string'];
-    protected function libUnquote($args)
-    {
-        $str = $args[0];
-
-        if ($str[0] === Type::T_STRING) {
-            $str[1] = '';
-        }
-
-        return $str;
-    }
-
-    protected static $libQuote = ['string'];
-    protected function libQuote($args)
-    {
-        $value = $args[0];
-
-        if ($value[0] === Type::T_STRING && ! empty($value[1])) {
-            return $value;
-        }
-
-        return [Type::T_STRING, '"', [$value]];
-    }
-
-    protected static $libPercentage = ['value'];
-    protected function libPercentage($args)
-    {
-        return new Node\Number($this->coercePercent($args[0]) * 100, '%');
-    }
-
-    protected static $libRound = ['value'];
-    protected function libRound($args)
-    {
-        $num = $args[0];
-
-        return new Node\Number(round($num[1]), $num[2]);
-    }
-
-    protected static $libFloor = ['value'];
-    protected function libFloor($args)
-    {
-        $num = $args[0];
-
-        return new Node\Number(floor($num[1]), $num[2]);
-    }
-
-    protected static $libCeil = ['value'];
-    protected function libCeil($args)
-    {
-        $num = $args[0];
-
-        return new Node\Number(ceil($num[1]), $num[2]);
-    }
-
-    protected static $libAbs = ['value'];
-    protected function libAbs($args)
-    {
-        $num = $args[0];
-
-        return new Node\Number(abs($num[1]), $num[2]);
-    }
-
-    protected function libMin($args)
-    {
-        $numbers = $this->getNormalizedNumbers($args);
-        $min = null;
-
-        foreach ($numbers as $key => $number) {
-            if (null === $min || $number[1] <= $min[1]) {
-                $min = [$key, $number[1]];
-            }
-        }
-
-        return $args[$min[0]];
-    }
-
-    protected function libMax($args)
-    {
-        $numbers = $this->getNormalizedNumbers($args);
-        $max = null;
-
-        foreach ($numbers as $key => $number) {
-            if (null === $max || $number[1] >= $max[1]) {
-                $max = [$key, $number[1]];
-            }
-        }
-
-        return $args[$max[0]];
-    }
-
-    /**
-     * Helper to normalize args containing numbers
-     *
-     * @param array $args
-     *
-     * @return array
-     */
-    protected function getNormalizedNumbers($args)
-    {
-        $unit = null;
-        $originalUnit = null;
-        $numbers = [];
-
-        foreach ($args as $key => $item) {
-            if ($item[0] !== Type::T_NUMBER) {
-                $this->throwError('%s is not a number', $item[0]);
-                break;
-            }
-
-            $number = $item->normalize();
-
-            if (null === $unit) {
-                $unit = $number[2];
-                $originalUnit = $item->unitStr();
-            } elseif ($number[1] && $unit !== $number[2]) {
-                $this->throwError('Incompatible units: "%s" and "%s".', $originalUnit, $item->unitStr());
-                break;
-            }
-
-            $numbers[$key] = $number;
-        }
-
-        return $numbers;
-    }
-
-    protected static $libLength = ['list'];
-    protected function libLength($args)
-    {
-        $list = $this->coerceList($args[0]);
-
-        return count($list[2]);
-    }
-
-    //protected static $libListSeparator = ['list...'];
-    protected function libListSeparator($args)
-    {
-        if (count($args) > 1) {
-            return 'comma';
-        }
-
-        $list = $this->coerceList($args[0]);
-
-        if (count($list[2]) <= 1) {
-            return 'space';
-        }
-
-        if ($list[1] === ',') {
-            return 'comma';
-        }
-
-        return 'space';
-    }
-
-    protected static $libNth = ['list', 'n'];
-    protected function libNth($args)
-    {
-        $list = $this->coerceList($args[0]);
-        $n = $this->assertNumber($args[1]);
-
-        if ($n > 0) {
-            $n--;
-        } elseif ($n < 0) {
-            $n += count($list[2]);
-        }
-
-        return isset($list[2][$n]) ? $list[2][$n] : static::$defaultValue;
-    }
-
-    protected static $libSetNth = ['list', 'n', 'value'];
-    protected function libSetNth($args)
-    {
-        $list = $this->coerceList($args[0]);
-        $n = $this->assertNumber($args[1]);
-
-        if ($n > 0) {
-            $n--;
-        } elseif ($n < 0) {
-            $n += count($list[2]);
-        }
-
-        if (! isset($list[2][$n])) {
-            $this->throwError('Invalid argument for "n"');
-
-            return null;
-        }
-
-        $list[2][$n] = $args[2];
-
-        return $list;
-    }
-
-    protected static $libMapGet = ['map', 'key'];
-    protected function libMapGet($args)
-    {
-        $map = $this->assertMap($args[0]);
-        $key = $this->compileStringContent($this->coerceString($args[1]));
-
-        for ($i = count($map[1]) - 1; $i >= 0; $i--) {
-            if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
-                return $map[2][$i];
-            }
-        }
-
-        return static::$null;
-    }
-
-    protected static $libMapKeys = ['map'];
-    protected function libMapKeys($args)
-    {
-        $map = $this->assertMap($args[0]);
-        $keys = $map[1];
-
-        return [Type::T_LIST, ',', $keys];
-    }
-
-    protected static $libMapValues = ['map'];
-    protected function libMapValues($args)
-    {
-        $map = $this->assertMap($args[0]);
-        $values = $map[2];
-
-        return [Type::T_LIST, ',', $values];
-    }
-
-    protected static $libMapRemove = ['map', 'key'];
-    protected function libMapRemove($args)
-    {
-        $map = $this->assertMap($args[0]);
-        $key = $this->compileStringContent($this->coerceString($args[1]));
-
-        for ($i = count($map[1]) - 1; $i >= 0; $i--) {
-            if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
-                array_splice($map[1], $i, 1);
-                array_splice($map[2], $i, 1);
-            }
-        }
-
-        return $map;
-    }
-
-    protected static $libMapHasKey = ['map', 'key'];
-    protected function libMapHasKey($args)
-    {
-        $map = $this->assertMap($args[0]);
-        $key = $this->compileStringContent($this->coerceString($args[1]));
-
-        for ($i = count($map[1]) - 1; $i >= 0; $i--) {
-            if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    protected static $libMapMerge = ['map-1', 'map-2'];
-    protected function libMapMerge($args)
-    {
-        $map1 = $this->assertMap($args[0]);
-        $map2 = $this->assertMap($args[1]);
-
-        foreach ($map2[1] as $i2 => $key2) {
-            $key = $this->compileStringContent($this->coerceString($key2));
-
-            foreach ($map1[1] as $i1 => $key1) {
-                if ($key === $this->compileStringContent($this->coerceString($key1))) {
-                    $map1[2][$i1] = $map2[2][$i2];
-                    continue 2;
-                }
-            }
-
-            $map1[1][] = $map2[1][$i2];
-            $map1[2][] = $map2[2][$i2];
-        }
-
-        return $map1;
-    }
-
-    protected static $libKeywords = ['args'];
-    protected function libKeywords($args)
-    {
-        $this->assertList($args[0]);
-
-        $keys = [];
-        $values = [];
-
-        foreach ($args[0][2] as $name => $arg) {
-            $keys[] = [Type::T_KEYWORD, $name];
-            $values[] = $arg;
-        }
-
-        return [Type::T_MAP, $keys, $values];
-    }
-
-    protected function listSeparatorForJoin($list1, $sep)
-    {
-        if (! isset($sep)) {
-            return $list1[1];
-        }
-
-        switch ($this->compileValue($sep)) {
-            case 'comma':
-                return ',';
-
-            case 'space':
-                return '';
-
-            default:
-                return $list1[1];
-        }
-    }
-
-    protected static $libJoin = ['list1', 'list2', 'separator'];
-    protected function libJoin($args)
-    {
-        list($list1, $list2, $sep) = $args;
-
-        $list1 = $this->coerceList($list1, ' ');
-        $list2 = $this->coerceList($list2, ' ');
-        $sep = $this->listSeparatorForJoin($list1, $sep);
-
-        return [Type::T_LIST, $sep, array_merge($list1[2], $list2[2])];
-    }
-
-    protected static $libAppend = ['list', 'val', 'separator'];
-    protected function libAppend($args)
-    {
-        list($list1, $value, $sep) = $args;
-
-        $list1 = $this->coerceList($list1, ' ');
-        $sep = $this->listSeparatorForJoin($list1, $sep);
-
-        return [Type::T_LIST, $sep, array_merge($list1[2], [$value])];
-    }
-
-    protected function libZip($args)
-    {
-        foreach ($args as $arg) {
-            $this->assertList($arg);
-        }
-
-        $lists = [];
-        $firstList = array_shift($args);
-
-        foreach ($firstList[2] as $key => $item) {
-            $list = [Type::T_LIST, '', [$item]];
-
-            foreach ($args as $arg) {
-                if (isset($arg[2][$key])) {
-                    $list[2][] = $arg[2][$key];
-                } else {
-                    break 2;
-                }
-            }
-
-            $lists[] = $list;
-        }
-
-        return [Type::T_LIST, ',', $lists];
-    }
-
-    protected static $libTypeOf = ['value'];
-    protected function libTypeOf($args)
-    {
-        $value = $args[0];
-
-        switch ($value[0]) {
-            case Type::T_KEYWORD:
-                if ($value === static::$true || $value === static::$false) {
-                    return 'bool';
-                }
-
-                if ($this->coerceColor($value)) {
-                    return 'color';
-                }
-
-                // fall-thru
-            case Type::T_FUNCTION:
-                return 'string';
-
-            case Type::T_LIST:
-                if (isset($value[3]) && $value[3]) {
-                    return 'arglist';
-                }
-
-                // fall-thru
-            default:
-                return $value[0];
-        }
-    }
-
-    protected static $libUnit = ['number'];
-    protected function libUnit($args)
-    {
-        $num = $args[0];
-
-        if ($num[0] === Type::T_NUMBER) {
-            return [Type::T_STRING, '"', [$num->unitStr()]];
-        }
-
-        return '';
-    }
-
-    protected static $libUnitless = ['number'];
-    protected function libUnitless($args)
-    {
-        $value = $args[0];
-
-        return $value[0] === Type::T_NUMBER && $value->unitless();
-    }
-
-    protected static $libComparable = ['number-1', 'number-2'];
-    protected function libComparable($args)
-    {
-        list($number1, $number2) = $args;
-
-        if (! isset($number1[0]) || $number1[0] !== Type::T_NUMBER ||
-            ! isset($number2[0]) || $number2[0] !== Type::T_NUMBER
-        ) {
-            $this->throwError('Invalid argument(s) for "comparable"');
-
-            return null;
-        }
-
-        $number1 = $number1->normalize();
-        $number2 = $number2->normalize();
-
-        return $number1[2] === $number2[2] || $number1->unitless() || $number2->unitless();
-    }
-
-    protected static $libStrIndex = ['string', 'substring'];
-    protected function libStrIndex($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $stringContent = $this->compileStringContent($string);
-
-        $substring = $this->coerceString($args[1]);
-        $substringContent = $this->compileStringContent($substring);
-
-        $result = strpos($stringContent, $substringContent);
-
-        return $result === false ? static::$null : new Node\Number($result + 1, '');
-    }
-
-    protected static $libStrInsert = ['string', 'insert', 'index'];
-    protected function libStrInsert($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $stringContent = $this->compileStringContent($string);
-
-        $insert = $this->coerceString($args[1]);
-        $insertContent = $this->compileStringContent($insert);
-
-        list(, $index) = $args[2];
-
-        $string[2] = [substr_replace($stringContent, $insertContent, $index - 1, 0)];
-
-        return $string;
-    }
-
-    protected static $libStrLength = ['string'];
-    protected function libStrLength($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $stringContent = $this->compileStringContent($string);
-
-        return new Node\Number(strlen($stringContent), '');
-    }
-
-    protected static $libStrSlice = ['string', 'start-at', 'end-at'];
-    protected function libStrSlice($args)
-    {
-        if (isset($args[2]) && $args[2][1] == 0) {
-            return static::$nullString;
-        }
-
-        $string = $this->coerceString($args[0]);
-        $stringContent = $this->compileStringContent($string);
-
-        $start = (int) $args[1][1];
-
-        if ($start > 0) {
-            $start--;
-        }
-
-        $end    = (int) $args[2][1];
-        $length = $end < 0 ? $end + 1 : ($end > 0 ? $end - $start : $end);
-
-        $string[2] = $length
-            ? [substr($stringContent, $start, $length)]
-            : [substr($stringContent, $start)];
-
-        return $string;
-    }
-
-    protected static $libToLowerCase = ['string'];
-    protected function libToLowerCase($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $stringContent = $this->compileStringContent($string);
-
-        $string[2] = [function_exists('mb_strtolower') ? mb_strtolower($stringContent) : strtolower($stringContent)];
-
-        return $string;
-    }
-
-    protected static $libToUpperCase = ['string'];
-    protected function libToUpperCase($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $stringContent = $this->compileStringContent($string);
-
-        $string[2] = [function_exists('mb_strtoupper') ? mb_strtoupper($stringContent) : strtoupper($stringContent)];
-
-        return $string;
-    }
-
-    protected static $libFeatureExists = ['feature'];
-    protected function libFeatureExists($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $name = $this->compileStringContent($string);
-
-        return $this->toBool(
-            array_key_exists($name, $this->registeredFeatures) ? $this->registeredFeatures[$name] : false
-        );
-    }
-
-    protected static $libFunctionExists = ['name'];
-    protected function libFunctionExists($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $name = $this->compileStringContent($string);
-
-        // user defined functions
-        if ($this->has(static::$namespaces['function'] . $name)) {
-            return true;
-        }
-
-        $name = $this->normalizeName($name);
-
-        if (isset($this->userFunctions[$name])) {
-            return true;
-        }
-
-        // built-in functions
-        $f = $this->getBuiltinFunction($name);
-
-        return $this->toBool(is_callable($f));
-    }
-
-    protected static $libGlobalVariableExists = ['name'];
-    protected function libGlobalVariableExists($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $name = $this->compileStringContent($string);
-
-        return $this->has($name, $this->rootEnv);
-    }
-
-    protected static $libMixinExists = ['name'];
-    protected function libMixinExists($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $name = $this->compileStringContent($string);
-
-        return $this->has(static::$namespaces['mixin'] . $name);
-    }
-
-    protected static $libVariableExists = ['name'];
-    protected function libVariableExists($args)
-    {
-        $string = $this->coerceString($args[0]);
-        $name = $this->compileStringContent($string);
-
-        return $this->has($name);
-    }
-
-    /**
-     * Workaround IE7's content counter bug.
-     *
-     * @param array $args
-     *
-     * @return array
-     */
-    protected function libCounter($args)
-    {
-        $list = array_map([$this, 'compileValue'], $args);
-
-        return [Type::T_STRING, '', ['counter(' . implode(',', $list) . ')']];
-    }
-
-    protected static $libRandom = ['limit'];
-    protected function libRandom($args)
-    {
-        if (isset($args[0])) {
-            $n = $this->assertNumber($args[0]);
-
-            if ($n < 1) {
-                $this->throwError("limit must be greater than or equal to 1");
-
-                return null;
-            }
-
-            return new Node\Number(mt_rand(1, $n), '');
-        }
-
-        return new Node\Number(mt_rand(1, mt_getrandmax()), '');
-    }
-
-    protected function libUniqueId()
-    {
-        static $id;
-
-        if (! isset($id)) {
-            $id = mt_rand(0, pow(36, 8));
-        }
-
-        $id += mt_rand(0, 10) + 1;
-
-        return [Type::T_STRING, '', ['u' . str_pad(base_convert($id, 10, 36), 8, '0', STR_PAD_LEFT)]];
-    }
-
-    protected static $libInspect = ['value'];
-    protected function libInspect($args)
-    {
-        if ($args[0] === static::$null) {
-            return [Type::T_KEYWORD, 'null'];
-        }
-
-        return $args[0];
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Compiler/Environment.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Compiler/Environment.php
deleted file mode 100644 (file)
index 99231f3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Compiler;
-
-/**
- * Compiler environment
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Environment
-{
-    /**
-     * @var \Leafo\ScssPhp\Block
-     */
-    public $block;
-
-    /**
-     * @var \Leafo\ScssPhp\Compiler\Environment
-     */
-    public $parent;
-
-    /**
-     * @var array
-     */
-    public $store;
-
-    /**
-     * @var array
-     */
-    public $storeUnreduced;
-
-    /**
-     * @var integer
-     */
-    public $depth;
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/CompilerException.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/CompilerException.php
deleted file mode 100644 (file)
index 7ca2e2b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Exception;
-
-/**
- * Compiler exception
- *
- * @author Oleksandr Savchenko <traveltino@gmail.com>
- */
-class CompilerException extends \Exception
-{
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/ParserException.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/ParserException.php
deleted file mode 100644 (file)
index 6d64335..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Exception;
-
-/**
- * Parser Exception
- *
- * @author Oleksandr Savchenko <traveltino@gmail.com>
- */
-class ParserException extends \Exception
-{
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/RangeException.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/RangeException.php
deleted file mode 100644 (file)
index 3ba6bf1..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Exception;
-
-/**
- * Range exception
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class RangeException extends \Exception
-{
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/ServerException.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Exception/ServerException.php
deleted file mode 100644 (file)
index d0ed084..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Exception;
-
-/**
- * Server Exception
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class ServerException extends \Exception
-{
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter.php
deleted file mode 100644 (file)
index b4f90aa..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-use Leafo\ScssPhp\Formatter\OutputBlock;
-use Leafo\ScssPhp\SourceMap\SourceMapGenerator;
-
-/**
- * Base formatter
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-abstract class Formatter
-{
-    /**
-     * @var integer
-     */
-    public $indentLevel;
-
-    /**
-     * @var string
-     */
-    public $indentChar;
-
-    /**
-     * @var string
-     */
-    public $break;
-
-    /**
-     * @var string
-     */
-    public $open;
-
-    /**
-     * @var string
-     */
-    public $close;
-
-    /**
-     * @var string
-     */
-    public $tagSeparator;
-
-    /**
-     * @var string
-     */
-    public $assignSeparator;
-
-    /**
-     * @var boolean
-     */
-    public $keepSemicolons;
-
-    /**
-     * @var \Leafo\ScssPhp\Formatter\OutputBlock
-     */
-    protected $currentBlock;
-
-    /**
-     * @var integer
-     */
-    protected $currentLine;
-
-    /**
-     * @var integer
-     */
-    protected $currentColumn;
-
-    /**
-     * @var \Leafo\ScssPhp\SourceMap\SourceMapGenerator
-     */
-    protected $sourceMapGenerator;
-
-    /**
-     * Initialize formatter
-     *
-     * @api
-     */
-    abstract public function __construct();
-
-    /**
-     * Return indentation (whitespace)
-     *
-     * @return string
-     */
-    protected function indentStr()
-    {
-        return '';
-    }
-
-    /**
-     * Return property assignment
-     *
-     * @api
-     *
-     * @param string $name
-     * @param mixed  $value
-     *
-     * @return string
-     */
-    public function property($name, $value)
-    {
-        return rtrim($name) . $this->assignSeparator . $value . ';';
-    }
-
-    /**
-     * Strip semi-colon appended by property(); it's a separator, not a terminator
-     *
-     * @api
-     *
-     * @param array $lines
-     */
-    public function stripSemicolon(&$lines)
-    {
-        if ($this->keepSemicolons) {
-            return;
-        }
-
-        if (($count = count($lines))
-            && substr($lines[$count - 1], -1) === ';'
-        ) {
-            $lines[$count - 1] = substr($lines[$count - 1], 0, -1);
-        }
-    }
-
-    /**
-     * Output lines inside a block
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
-     */
-    protected function blockLines(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $glue = $this->break . $inner;
-
-        $this->write($inner . implode($glue, $block->lines));
-
-        if (! empty($block->children)) {
-            $this->write($this->break);
-        }
-    }
-
-    /**
-     * Output block selectors
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
-     */
-    protected function blockSelectors(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $this->write($inner
-            . implode($this->tagSeparator, $block->selectors)
-            . $this->open . $this->break);
-    }
-
-    /**
-     * Output block children
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
-     */
-    protected function blockChildren(OutputBlock $block)
-    {
-        foreach ($block->children as $child) {
-            $this->block($child);
-        }
-    }
-
-    /**
-     * Output non-empty block
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
-     */
-    protected function block(OutputBlock $block)
-    {
-        if (empty($block->lines) && empty($block->children)) {
-            return;
-        }
-
-        $this->currentBlock = $block;
-
-        $pre = $this->indentStr();
-
-        if (! empty($block->selectors)) {
-            $this->blockSelectors($block);
-
-            $this->indentLevel++;
-        }
-
-        if (! empty($block->lines)) {
-            $this->blockLines($block);
-        }
-
-        if (! empty($block->children)) {
-            $this->blockChildren($block);
-        }
-
-        if (! empty($block->selectors)) {
-            $this->indentLevel--;
-
-            if (empty($block->children)) {
-                $this->write($this->break);
-            }
-
-            $this->write($pre . $this->close . $this->break);
-        }
-    }
-
-    /**
-     * Entry point to formatting a block
-     *
-     * @api
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock             $block              An abstract syntax tree
-     * @param \Leafo\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator
-     *
-     * @return string
-     */
-    public function format(OutputBlock $block, SourceMapGenerator $sourceMapGenerator = null)
-    {
-        $this->sourceMapGenerator = null;
-
-        if ($sourceMapGenerator) {
-            $this->currentLine = 1;
-            $this->currentColumn = 0;
-            $this->sourceMapGenerator = $sourceMapGenerator;
-        }
-
-        ob_start();
-
-        $this->block($block);
-
-        $out = ob_get_clean();
-
-        return $out;
-    }
-
-    /**
-     * @param string $str
-     */
-    protected function write($str)
-    {
-        if ($this->sourceMapGenerator) {
-            $this->sourceMapGenerator->addMapping(
-                $this->currentLine,
-                $this->currentColumn,
-                $this->currentBlock->sourceLine,
-                $this->currentBlock->sourceColumn - 1, //columns from parser are off by one
-                $this->currentBlock->sourceName
-            );
-
-            $lines = explode("\n", $str);
-            $lineCount = count($lines);
-            $this->currentLine += $lineCount-1;
-
-            $lastLine = array_pop($lines);
-
-            $this->currentColumn = ($lineCount === 1 ? $this->currentColumn : 0) + strlen($lastLine);
-        }
-
-        echo $str;
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Compact.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Compact.php
deleted file mode 100644 (file)
index 4efa1a0..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-use Leafo\ScssPhp\Formatter;
-
-/**
- * Compact formatter
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Compact extends Formatter
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function __construct()
-    {
-        $this->indentLevel = 0;
-        $this->indentChar = '';
-        $this->break = '';
-        $this->open = ' {';
-        $this->close = "}\n\n";
-        $this->tagSeparator = ',';
-        $this->assignSeparator = ':';
-        $this->keepSemicolons = true;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function indentStr()
-    {
-        return ' ';
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Compressed.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Compressed.php
deleted file mode 100644 (file)
index 1faa7e1..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-
-/**
- * Compressed formatter
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Compressed extends Formatter
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function __construct()
-    {
-        $this->indentLevel = 0;
-        $this->indentChar = '  ';
-        $this->break = '';
-        $this->open = '{';
-        $this->close = '}';
-        $this->tagSeparator = ',';
-        $this->assignSeparator = ':';
-        $this->keepSemicolons = false;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function blockLines(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $glue = $this->break . $inner;
-
-        foreach ($block->lines as $index => $line) {
-            if (substr($line, 0, 2) === '/*' && substr($line, 2, 1) !== '!') {
-                unset($block->lines[$index]);
-            } elseif (substr($line, 0, 3) === '/*!') {
-                $block->lines[$index] = '/*' . substr($line, 3);
-            }
-        }
-
-        $this->write($inner . implode($glue, $block->lines));
-
-        if (! empty($block->children)) {
-            $this->write($this->break);
-        }
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Crunched.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Crunched.php
deleted file mode 100644 (file)
index 42d77b5..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-
-/**
- * Crunched formatter
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Crunched extends Formatter
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function __construct()
-    {
-        $this->indentLevel = 0;
-        $this->indentChar = '  ';
-        $this->break = '';
-        $this->open = '{';
-        $this->close = '}';
-        $this->tagSeparator = ',';
-        $this->assignSeparator = ':';
-        $this->keepSemicolons = false;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function blockLines(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $glue = $this->break . $inner;
-
-        foreach ($block->lines as $index => $line) {
-            if (substr($line, 0, 2) === '/*') {
-                unset($block->lines[$index]);
-            }
-        }
-
-        $this->write($inner . implode($glue, $block->lines));
-
-        if (! empty($block->children)) {
-            $this->write($this->break);
-        }
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Debug.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Debug.php
deleted file mode 100644 (file)
index bfcbf41..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-
-/**
- * Debug formatter
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Debug extends Formatter
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function __construct()
-    {
-        $this->indentLevel = 0;
-        $this->indentChar = '';
-        $this->break = "\n";
-        $this->open = ' {';
-        $this->close = ' }';
-        $this->tagSeparator = ', ';
-        $this->assignSeparator = ': ';
-        $this->keepSemicolons = true;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function indentStr()
-    {
-        return str_repeat('  ', $this->indentLevel);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockLines(OutputBlock $block)
-    {
-        $indent = $this->indentStr();
-
-        if (empty($block->lines)) {
-            $this->write("{$indent}block->lines: []\n");
-
-            return;
-        }
-
-        foreach ($block->lines as $index => $line) {
-            $this->write("{$indent}block->lines[{$index}]: $line\n");
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockSelectors(OutputBlock $block)
-    {
-        $indent = $this->indentStr();
-
-        if (empty($block->selectors)) {
-            $this->write("{$indent}block->selectors: []\n");
-
-            return;
-        }
-
-        foreach ($block->selectors as $index => $selector) {
-            $this->write("{$indent}block->selectors[{$index}]: $selector\n");
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockChildren(OutputBlock $block)
-    {
-        $indent = $this->indentStr();
-
-        if (empty($block->children)) {
-            $this->write("{$indent}block->children: []\n");
-
-            return;
-        }
-
-        $this->indentLevel++;
-
-        foreach ($block->children as $i => $child) {
-            $this->block($child);
-        }
-
-        $this->indentLevel--;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function block(OutputBlock $block)
-    {
-        $indent = $this->indentStr();
-
-        $this->write("{$indent}block->type: {$block->type}\n" .
-             "{$indent}block->depth: {$block->depth}\n");
-
-        $this->currentBlock = $block;
-
-        $this->blockSelectors($block);
-        $this->blockLines($block);
-        $this->blockChildren($block);
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Expanded.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Expanded.php
deleted file mode 100644 (file)
index d8c1e88..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-
-/**
- * Expanded formatter
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Expanded extends Formatter
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function __construct()
-    {
-        $this->indentLevel = 0;
-        $this->indentChar = '  ';
-        $this->break = "\n";
-        $this->open = ' {';
-        $this->close = '}';
-        $this->tagSeparator = ', ';
-        $this->assignSeparator = ': ';
-        $this->keepSemicolons = true;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function indentStr()
-    {
-        return str_repeat($this->indentChar, $this->indentLevel);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockLines(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $glue = $this->break . $inner;
-
-        foreach ($block->lines as $index => $line) {
-            if (substr($line, 0, 2) === '/*') {
-                $block->lines[$index] = preg_replace('/(\r|\n)+/', $glue, $line);
-            }
-        }
-
-        $this->write($inner . implode($glue, $block->lines));
-
-        if (empty($block->selectors) || ! empty($block->children)) {
-            $this->write($this->break);
-        }
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Nested.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/Nested.php
deleted file mode 100644 (file)
index 8f72206..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-use Leafo\ScssPhp\Formatter;
-use Leafo\ScssPhp\Formatter\OutputBlock;
-
-/**
- * Nested formatter
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Nested extends Formatter
-{
-    /**
-     * @var integer
-     */
-    private $depth;
-
-    /**
-     * {@inheritdoc}
-     */
-    public function __construct()
-    {
-        $this->indentLevel = 0;
-        $this->indentChar = '  ';
-        $this->break = "\n";
-        $this->open = ' {';
-        $this->close = ' }';
-        $this->tagSeparator = ', ';
-        $this->assignSeparator = ': ';
-        $this->keepSemicolons = true;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function indentStr()
-    {
-        $n = $this->depth - 1;
-
-        return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockLines(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $glue = $this->break . $inner;
-
-        foreach ($block->lines as $index => $line) {
-            if (substr($line, 0, 2) === '/*') {
-                $block->lines[$index] = preg_replace('/(\r|\n)+/', $glue, $line);
-            }
-        }
-
-        $this->write($inner . implode($glue, $block->lines));
-
-        if (! empty($block->children)) {
-            $this->write($this->break);
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockSelectors(OutputBlock $block)
-    {
-        $inner = $this->indentStr();
-
-        $this->write($inner
-            . implode($this->tagSeparator, $block->selectors)
-            . $this->open . $this->break);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function blockChildren(OutputBlock $block)
-    {
-        foreach ($block->children as $i => $child) {
-            $this->block($child);
-
-            if ($i < count($block->children) - 1) {
-                $this->write($this->break);
-
-                if (isset($block->children[$i + 1])) {
-                    $next = $block->children[$i + 1];
-
-                    if ($next->depth === max($block->depth, 1) && $child->depth >= $next->depth) {
-                        $this->write($this->break);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function block(OutputBlock $block)
-    {
-        if ($block->type === 'root') {
-            $this->adjustAllChildren($block);
-        }
-
-        if (empty($block->lines) && empty($block->children)) {
-            return;
-        }
-
-        $this->currentBlock = $block;
-
-
-        $this->depth = $block->depth;
-
-        if (! empty($block->selectors)) {
-            $this->blockSelectors($block);
-
-            $this->indentLevel++;
-        }
-
-        if (! empty($block->lines)) {
-            $this->blockLines($block);
-        }
-
-        if (! empty($block->children)) {
-            $this->blockChildren($block);
-        }
-
-        if (! empty($block->selectors)) {
-            $this->indentLevel--;
-
-            $this->write($this->close);
-        }
-
-        if ($block->type === 'root') {
-            $this->write($this->break);
-        }
-    }
-
-    /**
-     * Adjust the depths of all children, depth first
-     *
-     * @param \Leafo\ScssPhp\Formatter\OutputBlock $block
-     */
-    private function adjustAllChildren(OutputBlock $block)
-    {
-        // flatten empty nested blocks
-        $children = [];
-
-        foreach ($block->children as $i => $child) {
-            if (empty($child->lines) && empty($child->children)) {
-                if (isset($block->children[$i + 1])) {
-                    $block->children[$i + 1]->depth = $child->depth;
-                }
-
-                continue;
-            }
-
-            $children[] = $child;
-        }
-
-        $count = count($children);
-
-        for ($i = 0; $i < $count; $i++) {
-            $depth = $children[$i]->depth;
-            $j = $i + 1;
-
-            if (isset($children[$j]) && $depth < $children[$j]->depth) {
-                $childDepth = $children[$j]->depth;
-
-                for (; $j < $count; $j++) {
-                    if ($depth < $children[$j]->depth && $childDepth >= $children[$j]->depth) {
-                        $children[$j]->depth = $depth + 1;
-                    }
-                }
-            }
-        }
-
-        $block->children = $children;
-
-        // make relative to parent
-        foreach ($block->children as $child) {
-            $this->adjustAllChildren($child);
-
-            $child->depth = $child->depth - $block->depth;
-        }
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/OutputBlock.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Formatter/OutputBlock.php
deleted file mode 100644 (file)
index 5eb589c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Formatter;
-
-/**
- * Output block
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class OutputBlock
-{
-    /**
-     * @var string
-     */
-    public $type;
-
-    /**
-     * @var integer
-     */
-    public $depth;
-
-    /**
-     * @var array
-     */
-    public $selectors;
-
-    /**
-     * @var array
-     */
-    public $lines;
-
-    /**
-     * @var array
-     */
-    public $children;
-
-    /**
-     * @var \Leafo\ScssPhp\Formatter\OutputBlock
-     */
-    public $parent;
-
-    /**
-     * @var string
-     */
-    public $sourceName;
-
-    /**
-     * @var integer
-     */
-    public $sourceLine;
-
-    /**
-     * @var integer
-     */
-    public $sourceColumn;
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Node.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Node.php
deleted file mode 100644 (file)
index b9f7945..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-/**
- * Base node
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-abstract class Node
-{
-    /**
-     * @var string
-     */
-    public $type;
-
-    /**
-     * @var integer
-     */
-    public $sourceIndex;
-
-    /**
-     * @var integer
-     */
-    public $sourceLine;
-
-    /**
-     * @var integer
-     */
-    public $sourceColumn;
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Node/Number.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Node/Number.php
deleted file mode 100644 (file)
index 42c1680..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\Node;
-
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Node;
-use Leafo\ScssPhp\Type;
-
-/**
- * Dimension + optional units
- *
- * {@internal
- *     This is a work-in-progress.
- *
- *     The \ArrayAccess interface is temporary until the migration is complete.
- * }}
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Number extends Node implements \ArrayAccess
-{
-    /**
-     * @var integer
-     */
-    static public $precision = 10;
-
-    /**
-     * @see http://www.w3.org/TR/2012/WD-css3-values-20120308/
-     *
-     * @var array
-     */
-    static protected $unitTable = [
-        'in' => [
-            'in' => 1,
-            'pc' => 6,
-            'pt' => 72,
-            'px' => 96,
-            'cm' => 2.54,
-            'mm' => 25.4,
-            'q'  => 101.6,
-        ],
-        'turn' => [
-            'deg'  => 360,
-            'grad' => 400,
-            'rad'  => 6.28318530717958647692528676, // 2 * M_PI
-            'turn' => 1,
-        ],
-        's' => [
-            's'  => 1,
-            'ms' => 1000,
-        ],
-        'Hz' => [
-            'Hz'  => 1,
-            'kHz' => 0.001,
-        ],
-        'dpi' => [
-            'dpi'  => 1,
-            'dpcm' => 2.54,
-            'dppx' => 96,
-        ],
-    ];
-
-    /**
-     * @var integer|float
-     */
-    public $dimension;
-
-    /**
-     * @var array
-     */
-    public $units;
-
-    /**
-     * Initialize number
-     *
-     * @param mixed $dimension
-     * @param mixed $initialUnit
-     */
-    public function __construct($dimension, $initialUnit)
-    {
-        $this->type      = Type::T_NUMBER;
-        $this->dimension = $dimension;
-        $this->units     = is_array($initialUnit)
-            ? $initialUnit
-            : ($initialUnit ? [$initialUnit => 1]
-                            : []);
-    }
-
-    /**
-     * Coerce number to target units
-     *
-     * @param array $units
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    public function coerce($units)
-    {
-        if ($this->unitless()) {
-            return new Number($this->dimension, $units);
-        }
-
-        $dimension = $this->dimension;
-
-        foreach (static::$unitTable['in'] as $unit => $conv) {
-            $from       = isset($this->units[$unit]) ? $this->units[$unit] : 0;
-            $to         = isset($units[$unit]) ? $units[$unit] : 0;
-            $factor     = pow($conv, $from - $to);
-            $dimension /= $factor;
-        }
-
-        return new Number($dimension, $units);
-    }
-
-    /**
-     * Normalize number
-     *
-     * @return \Leafo\ScssPhp\Node\Number
-     */
-    public function normalize()
-    {
-        $dimension = $this->dimension;
-        $units     = [];
-
-        $this->normalizeUnits($dimension, $units, 'in');
-
-        return new Number($dimension, $units);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function offsetExists($offset)
-    {
-        if ($offset === -3) {
-            return $this->sourceColumn !== null;
-        }
-
-        if ($offset === -2) {
-            return $this->sourceLine !== null;
-        }
-
-        if ($offset === -1
-            || $offset === 0
-            || $offset === 1
-            || $offset === 2
-        ) {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function offsetGet($offset)
-    {
-        switch ($offset) {
-            case -3:
-                return $this->sourceColumn;
-
-            case -2:
-                return $this->sourceLine;
-
-            case -1:
-                return $this->sourceIndex;
-
-            case 0:
-                return $this->type;
-
-            case 1:
-                return $this->dimension;
-
-            case 2:
-                return $this->units;
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function offsetSet($offset, $value)
-    {
-        if ($offset === 1) {
-            $this->dimension = $value;
-        } elseif ($offset === 2) {
-            $this->units = $value;
-        } elseif ($offset == -1) {
-            $this->sourceIndex = $value;
-        } elseif ($offset == -2) {
-            $this->sourceLine = $value;
-        } elseif ($offset == -3) {
-            $this->sourceColumn = $value;
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function offsetUnset($offset)
-    {
-        if ($offset === 1) {
-            $this->dimension = null;
-        } elseif ($offset === 2) {
-            $this->units = null;
-        } elseif ($offset === -1) {
-            $this->sourceIndex = null;
-        } elseif ($offset === -2) {
-            $this->sourceLine = null;
-        } elseif ($offset === -3) {
-            $this->sourceColumn = null;
-        }
-    }
-
-    /**
-     * Returns true if the number is unitless
-     *
-     * @return boolean
-     */
-    public function unitless()
-    {
-        return ! array_sum($this->units);
-    }
-
-    /**
-     * Returns unit(s) as the product of numerator units divided by the product of denominator units
-     *
-     * @return string
-     */
-    public function unitStr()
-    {
-        $numerators   = [];
-        $denominators = [];
-
-        foreach ($this->units as $unit => $unitSize) {
-            if ($unitSize > 0) {
-                $numerators = array_pad($numerators, count($numerators) + $unitSize, $unit);
-                continue;
-            }
-
-            if ($unitSize < 0) {
-                $denominators = array_pad($denominators, count($denominators) + $unitSize, $unit);
-                continue;
-            }
-        }
-
-        return implode('*', $numerators) . (count($denominators) ? '/' . implode('*', $denominators) : '');
-    }
-
-    /**
-     * Output number
-     *
-     * @param \Leafo\ScssPhp\Compiler $compiler
-     *
-     * @return string
-     */
-    public function output(Compiler $compiler = null)
-    {
-        $dimension = round($this->dimension, static::$precision);
-
-        $units = array_filter($this->units, function ($unitSize) {
-            return $unitSize;
-        });
-
-        if (count($units) > 1 && array_sum($units) === 0) {
-            $dimension = $this->dimension;
-            $units     = [];
-
-            $this->normalizeUnits($dimension, $units, 'in');
-
-            $dimension = round($dimension, static::$precision);
-            $units     = array_filter($units, function ($unitSize) {
-                return $unitSize;
-            });
-        }
-
-        $unitSize = array_sum($units);
-
-        if ($compiler && ($unitSize > 1 || $unitSize < 0 || count($units) > 1)) {
-            $compiler->throwError((string) $dimension . $this->unitStr() . " isn't a valid CSS value.");
-        }
-
-        reset($units);
-        $unit = key($units);
-        $dimension = number_format($dimension, static::$precision, '.', '');
-
-        return (static::$precision ? rtrim(rtrim($dimension, '0'), '.') : $dimension) . $unit;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function __toString()
-    {
-        return $this->output();
-    }
-
-    /**
-     * Normalize units
-     *
-     * @param integer|float $dimension
-     * @param array         $units
-     * @param string        $baseUnit
-     */
-    private function normalizeUnits(&$dimension, &$units, $baseUnit = 'in')
-    {
-        $dimension = $this->dimension;
-        $units     = [];
-
-        foreach ($this->units as $unit => $exp) {
-            if (isset(static::$unitTable[$baseUnit][$unit])) {
-                $factor = pow(static::$unitTable[$baseUnit][$unit], $exp);
-
-                $unit = $baseUnit;
-                $dimension /= $factor;
-            }
-
-            $units[$unit] = $exp + (isset($units[$unit]) ? $units[$unit] : 0);
-        }
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Parser.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Parser.php
deleted file mode 100644 (file)
index 1eda928..0000000
+++ /dev/null
@@ -1,2638 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-use Leafo\ScssPhp\Block;
-use Leafo\ScssPhp\Compiler;
-use Leafo\ScssPhp\Exception\ParserException;
-use Leafo\ScssPhp\Node;
-use Leafo\ScssPhp\Type;
-
-/**
- * Parser
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Parser
-{
-    const SOURCE_INDEX  = -1;
-    const SOURCE_LINE   = -2;
-    const SOURCE_COLUMN = -3;
-
-    /**
-     * @var array
-     */
-    protected static $precedence = [
-        '='   => 0,
-        'or'  => 1,
-        'and' => 2,
-        '=='  => 3,
-        '!='  => 3,
-        '<=>' => 3,
-        '<='  => 4,
-        '>='  => 4,
-        '<'   => 4,
-        '>'   => 4,
-        '+'   => 5,
-        '-'   => 5,
-        '*'   => 6,
-        '/'   => 6,
-        '%'   => 6,
-    ];
-
-    protected static $commentPattern;
-    protected static $operatorPattern;
-    protected static $whitePattern;
-
-    private $sourceName;
-    private $sourceIndex;
-    private $sourcePositions;
-    private $charset;
-    private $count;
-    private $env;
-    private $inParens;
-    private $eatWhiteDefault;
-    private $buffer;
-    private $utf8;
-    private $encoding;
-    private $patternModifiers;
-
-    /**
-     * Constructor
-     *
-     * @api
-     *
-     * @param string  $sourceName
-     * @param integer $sourceIndex
-     * @param string  $encoding
-     */
-    public function __construct($sourceName, $sourceIndex = 0, $encoding = 'utf-8')
-    {
-        $this->sourceName       = $sourceName ?: '(stdin)';
-        $this->sourceIndex      = $sourceIndex;
-        $this->charset          = null;
-        $this->utf8             = ! $encoding || strtolower($encoding) === 'utf-8';
-        $this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais';
-
-        if (empty(static::$operatorPattern)) {
-            static::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=\>|\<\=?|and|or)';
-
-            $commentSingle      = '\/\/';
-            $commentMultiLeft   = '\/\*';
-            $commentMultiRight  = '\*\/';
-
-            static::$commentPattern = $commentMultiLeft . '.*?' . $commentMultiRight;
-            static::$whitePattern = $this->utf8
-                ? '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisuS'
-                : '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisS';
-        }
-    }
-
-    /**
-     * Get source file name
-     *
-     * @api
-     *
-     * @return string
-     */
-    public function getSourceName()
-    {
-        return $this->sourceName;
-    }
-
-    /**
-     * Throw parser error
-     *
-     * @api
-     *
-     * @param string $msg
-     *
-     * @throws \Leafo\ScssPhp\Exception\ParserException
-     */
-    public function throwParseError($msg = 'parse error')
-    {
-        list($line, /* $column */) = $this->getSourcePosition($this->count);
-
-        $loc = empty($this->sourceName) ? "line: $line" : "$this->sourceName on line $line";
-
-        if ($this->peek("(.*?)(\n|$)", $m, $this->count)) {
-            throw new ParserException("$msg: failed at `$m[1]` $loc");
-        }
-
-        throw new ParserException("$msg: $loc");
-    }
-
-    /**
-     * Parser buffer
-     *
-     * @api
-     *
-     * @param string $buffer
-     *
-     * @return \Leafo\ScssPhp\Block
-     */
-    public function parse($buffer)
-    {
-        // strip BOM (byte order marker)
-        if (substr($buffer, 0, 3) === "\xef\xbb\xbf") {
-            $buffer = substr($buffer, 3);
-        }
-
-        $this->buffer          = rtrim($buffer, "\x00..\x1f");
-        $this->count           = 0;
-        $this->env             = null;
-        $this->inParens        = false;
-        $this->eatWhiteDefault = true;
-
-        $this->saveEncoding();
-        $this->extractLineNumbers($buffer);
-
-        $this->pushBlock(null); // root block
-        $this->whitespace();
-        $this->pushBlock(null);
-        $this->popBlock();
-
-        while ($this->parseChunk()) {
-            ;
-        }
-
-        if ($this->count !== strlen($this->buffer)) {
-            $this->throwParseError();
-        }
-
-        if (! empty($this->env->parent)) {
-            $this->throwParseError('unclosed block');
-        }
-
-        if ($this->charset) {
-            array_unshift($this->env->children, $this->charset);
-        }
-
-        $this->env->isRoot    = true;
-
-        $this->restoreEncoding();
-
-        return $this->env;
-    }
-
-    /**
-     * Parse a value or value list
-     *
-     * @api
-     *
-     * @param string $buffer
-     * @param string $out
-     *
-     * @return boolean
-     */
-    public function parseValue($buffer, &$out)
-    {
-        $this->count           = 0;
-        $this->env             = null;
-        $this->inParens        = false;
-        $this->eatWhiteDefault = true;
-        $this->buffer          = (string) $buffer;
-
-        $this->saveEncoding();
-
-        $list = $this->valueList($out);
-
-        $this->restoreEncoding();
-
-        return $list;
-    }
-
-    /**
-     * Parse a selector or selector list
-     *
-     * @api
-     *
-     * @param string $buffer
-     * @param string $out
-     *
-     * @return boolean
-     */
-    public function parseSelector($buffer, &$out)
-    {
-        $this->count           = 0;
-        $this->env             = null;
-        $this->inParens        = false;
-        $this->eatWhiteDefault = true;
-        $this->buffer          = (string) $buffer;
-
-        $this->saveEncoding();
-
-        $selector = $this->selectors($out);
-
-        $this->restoreEncoding();
-
-        return $selector;
-    }
-
-    /**
-     * Parse a single chunk off the head of the buffer and append it to the
-     * current parse environment.
-     *
-     * Returns false when the buffer is empty, or when there is an error.
-     *
-     * This function is called repeatedly until the entire document is
-     * parsed.
-     *
-     * This parser is most similar to a recursive descent parser. Single
-     * functions represent discrete grammatical rules for the language, and
-     * they are able to capture the text that represents those rules.
-     *
-     * Consider the function Compiler::keyword(). (All parse functions are
-     * structured the same.)
-     *
-     * The function takes a single reference argument. When calling the
-     * function it will attempt to match a keyword on the head of the buffer.
-     * If it is successful, it will place the keyword in the referenced
-     * argument, advance the position in the buffer, and return true. If it
-     * fails then it won't advance the buffer and it will return false.
-     *
-     * All of these parse functions are powered by Compiler::match(), which behaves
-     * the same way, but takes a literal regular expression. Sometimes it is
-     * more convenient to use match instead of creating a new function.
-     *
-     * Because of the format of the functions, to parse an entire string of
-     * grammatical rules, you can chain them together using &&.
-     *
-     * But, if some of the rules in the chain succeed before one fails, then
-     * the buffer position will be left at an invalid state. In order to
-     * avoid this, Compiler::seek() is used to remember and set buffer positions.
-     *
-     * Before parsing a chain, use $s = $this->count to remember the current
-     * position into $s. Then if a chain fails, use $this->seek($s) to
-     * go back where we started.
-     *
-     * @return boolean
-     */
-    protected function parseChunk()
-    {
-        $s = $this->count;
-
-        // the directives
-        if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] === '@') {
-            if ($this->literal('@at-root', 8) &&
-                ($this->selectors($selector) || true) &&
-                ($this->map($with) || true) &&
-                $this->matchChar('{')
-            ) {
-                $atRoot = $this->pushSpecialBlock(Type::T_AT_ROOT, $s);
-                $atRoot->selector = $selector;
-                $atRoot->with = $with;
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@media', 6) && $this->mediaQueryList($mediaQueryList) && $this->matchChar('{')) {
-                $media = $this->pushSpecialBlock(Type::T_MEDIA, $s);
-                $media->queryList = $mediaQueryList[2];
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@mixin', 6) &&
-                $this->keyword($mixinName) &&
-                ($this->argumentDef($args) || true) &&
-                $this->matchChar('{')
-            ) {
-                $mixin = $this->pushSpecialBlock(Type::T_MIXIN, $s);
-                $mixin->name = $mixinName;
-                $mixin->args = $args;
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@include', 8) &&
-                $this->keyword($mixinName) &&
-                ($this->matchChar('(') &&
-                    ($this->argValues($argValues) || true) &&
-                    $this->matchChar(')') || true) &&
-                ($this->end() ||
-                    $this->matchChar('{') && $hasBlock = true)
-            ) {
-                $child = [Type::T_INCLUDE, $mixinName, isset($argValues) ? $argValues : null, null];
-
-                if (! empty($hasBlock)) {
-                    $include = $this->pushSpecialBlock(Type::T_INCLUDE, $s);
-                    $include->child = $child;
-                } else {
-                    $this->append($child, $s);
-                }
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@scssphp-import-once', 20) &&
-                $this->valueList($importPath) &&
-                $this->end()
-            ) {
-                $this->append([Type::T_SCSSPHP_IMPORT_ONCE, $importPath], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@import', 7) &&
-                $this->valueList($importPath) &&
-                $this->end()
-            ) {
-                $this->append([Type::T_IMPORT, $importPath], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@import', 7) &&
-                $this->url($importPath) &&
-                $this->end()
-            ) {
-                $this->append([Type::T_IMPORT, $importPath], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@extend', 7) &&
-                $this->selectors($selectors) &&
-                $this->end()
-            ) {
-                // check for '!flag'
-                $optional = $this->stripOptionalFlag($selectors);
-                $this->append([Type::T_EXTEND, $selectors, $optional], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@function', 9) &&
-                $this->keyword($fnName) &&
-                $this->argumentDef($args) &&
-                $this->matchChar('{')
-            ) {
-                $func = $this->pushSpecialBlock(Type::T_FUNCTION, $s);
-                $func->name = $fnName;
-                $func->args = $args;
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@break', 6) && $this->end()) {
-                $this->append([Type::T_BREAK], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@continue', 9) && $this->end()) {
-                $this->append([Type::T_CONTINUE], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-
-            if ($this->literal('@return', 7) && ($this->valueList($retVal) || true) && $this->end()) {
-                $this->append([Type::T_RETURN, isset($retVal) ? $retVal : [Type::T_NULL]], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@each', 5) &&
-                $this->genericList($varNames, 'variable', ',', false) &&
-                $this->literal('in', 2) &&
-                $this->valueList($list) &&
-                $this->matchChar('{')
-            ) {
-                $each = $this->pushSpecialBlock(Type::T_EACH, $s);
-
-                foreach ($varNames[2] as $varName) {
-                    $each->vars[] = $varName[1];
-                }
-
-                $each->list = $list;
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@while', 6) &&
-                $this->expression($cond) &&
-                $this->matchChar('{')
-            ) {
-                $while = $this->pushSpecialBlock(Type::T_WHILE, $s);
-                $while->cond = $cond;
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@for', 4) &&
-                $this->variable($varName) &&
-                $this->literal('from', 4) &&
-                $this->expression($start) &&
-                ($this->literal('through', 7) ||
-                    ($forUntil = true && $this->literal('to', 2))) &&
-                $this->expression($end) &&
-                $this->matchChar('{')
-            ) {
-                $for = $this->pushSpecialBlock(Type::T_FOR, $s);
-                $for->var = $varName[1];
-                $for->start = $start;
-                $for->end = $end;
-                $for->until = isset($forUntil);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@if', 3) && $this->valueList($cond) && $this->matchChar('{')) {
-                $if = $this->pushSpecialBlock(Type::T_IF, $s);
-                $if->cond = $cond;
-                $if->cases = [];
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@debug', 6) &&
-                $this->valueList($value) &&
-                $this->end()
-            ) {
-                $this->append([Type::T_DEBUG, $value], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@warn', 5) &&
-                $this->valueList($value) &&
-                $this->end()
-            ) {
-                $this->append([Type::T_WARN, $value], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@error', 6) &&
-                $this->valueList($value) &&
-                $this->end()
-            ) {
-                $this->append([Type::T_ERROR, $value], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->literal('@content', 8) && $this->end()) {
-                $this->append([Type::T_MIXIN_CONTENT], $s);
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            $last = $this->last();
-
-            if (isset($last) && $last[0] === Type::T_IF) {
-                list(, $if) = $last;
-
-                if ($this->literal('@else', 5)) {
-                    if ($this->matchChar('{')) {
-                        $else = $this->pushSpecialBlock(Type::T_ELSE, $s);
-                    } elseif ($this->literal('if', 2) && $this->valueList($cond) && $this->matchChar('{')) {
-                        $else = $this->pushSpecialBlock(Type::T_ELSEIF, $s);
-                        $else->cond = $cond;
-                    }
-
-                    if (isset($else)) {
-                        $else->dontAppend = true;
-                        $if->cases[] = $else;
-
-                        return true;
-                    }
-                }
-
-                $this->seek($s);
-            }
-
-            // only retain the first @charset directive encountered
-            if ($this->literal('@charset', 8) &&
-                $this->valueList($charset) &&
-                $this->end()
-            ) {
-                if (! isset($this->charset)) {
-                    $statement = [Type::T_CHARSET, $charset];
-
-                    list($line, $column) = $this->getSourcePosition($s);
-
-                    $statement[static::SOURCE_LINE]   = $line;
-                    $statement[static::SOURCE_COLUMN] = $column;
-                    $statement[static::SOURCE_INDEX]  = $this->sourceIndex;
-
-                    $this->charset = $statement;
-                }
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            // doesn't match built in directive, do generic one
-            if ($this->matchChar('@', false) &&
-                $this->keyword($dirName) &&
-                ($this->variable($dirValue) || $this->openString('{', $dirValue) || true) &&
-                $this->matchChar('{')
-            ) {
-                if ($dirName === 'media') {
-                    $directive = $this->pushSpecialBlock(Type::T_MEDIA, $s);
-                } else {
-                    $directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s);
-                    $directive->name = $dirName;
-                }
-
-                if (isset($dirValue)) {
-                    $directive->value = $dirValue;
-                }
-
-                return true;
-            }
-
-            $this->seek($s);
-
-            return false;
-        }
-
-        // property shortcut
-        // captures most properties before having to parse a selector
-        if ($this->keyword($name, false) &&
-            $this->literal(': ', 2) &&
-            $this->valueList($value) &&
-            $this->end()
-        ) {
-            $name = [Type::T_STRING, '', [$name]];
-            $this->append([Type::T_ASSIGN, $name, $value], $s);
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        // variable assigns
-        if ($this->variable($name) &&
-            $this->matchChar(':') &&
-            $this->valueList($value) &&
-            $this->end()
-        ) {
-            // check for '!flag'
-            $assignmentFlags = $this->stripAssignmentFlags($value);
-            $this->append([Type::T_ASSIGN, $name, $value, $assignmentFlags], $s);
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        // misc
-        if ($this->literal('-->', 3)) {
-            return true;
-        }
-
-        // opening css block
-        if ($this->selectors($selectors) && $this->matchChar('{')) {
-            $this->pushBlock($selectors, $s);
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        // property assign, or nested assign
-        if ($this->propertyName($name) && $this->matchChar(':')) {
-            $foundSomething = false;
-
-            if ($this->valueList($value)) {
-                $this->append([Type::T_ASSIGN, $name, $value], $s);
-                $foundSomething = true;
-            }
-
-            if ($this->matchChar('{')) {
-                $propBlock = $this->pushSpecialBlock(Type::T_NESTED_PROPERTY, $s);
-                $propBlock->prefix = $name;
-                $foundSomething = true;
-            } elseif ($foundSomething) {
-                $foundSomething = $this->end();
-            }
-
-            if ($foundSomething) {
-                return true;
-            }
-        }
-
-        $this->seek($s);
-
-        // closing a block
-        if ($this->matchChar('}')) {
-            $block = $this->popBlock();
-
-            if (isset($block->type) && $block->type === Type::T_INCLUDE) {
-                $include = $block->child;
-                unset($block->child);
-                $include[3] = $block;
-                $this->append($include, $s);
-            } elseif (empty($block->dontAppend)) {
-                $type = isset($block->type) ? $block->type : Type::T_BLOCK;
-                $this->append([$type, $block], $s);
-            }
-
-            return true;
-        }
-
-        // extra stuff
-        if ($this->matchChar(';') ||
-            $this->literal('<!--', 4)
-        ) {
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Push block onto parse tree
-     *
-     * @param array   $selectors
-     * @param integer $pos
-     *
-     * @return \Leafo\ScssPhp\Block
-     */
-    protected function pushBlock($selectors, $pos = 0)
-    {
-        list($line, $column) = $this->getSourcePosition($pos);
-
-        $b = new Block;
-        $b->sourceName   = $this->sourceName;
-        $b->sourceLine   = $line;
-        $b->sourceColumn = $column;
-        $b->sourceIndex  = $this->sourceIndex;
-        $b->selectors    = $selectors;
-        $b->comments     = [];
-        $b->parent       = $this->env;
-
-        if (! $this->env) {
-            $b->children = [];
-        } elseif (empty($this->env->children)) {
-            $this->env->children = $this->env->comments;
-            $b->children = [];
-            $this->env->comments = [];
-        } else {
-            $b->children = $this->env->comments;
-            $this->env->comments = [];
-        }
-
-        $this->env = $b;
-
-        return $b;
-    }
-
-    /**
-     * Push special (named) block onto parse tree
-     *
-     * @param string  $type
-     * @param integer $pos
-     *
-     * @return \Leafo\ScssPhp\Block
-     */
-    protected function pushSpecialBlock($type, $pos)
-    {
-        $block = $this->pushBlock(null, $pos);
-        $block->type = $type;
-
-        return $block;
-    }
-
-    /**
-     * Pop scope and return last block
-     *
-     * @return \Leafo\ScssPhp\Block
-     *
-     * @throws \Exception
-     */
-    protected function popBlock()
-    {
-        $block = $this->env;
-
-        if (empty($block->parent)) {
-            $this->throwParseError('unexpected }');
-        }
-
-        if ($block->type == Type::T_AT_ROOT) {
-            // keeps the parent in case of self selector &
-            $block->selfParent = $block->parent;
-        }
-
-        $this->env = $block->parent;
-        unset($block->parent);
-
-        $comments = $block->comments;
-        if ($comments) {
-            $this->env->comments = $comments;
-            unset($block->comments);
-        }
-
-        return $block;
-    }
-
-    /**
-     * Peek input stream
-     *
-     * @param string  $regex
-     * @param array   $out
-     * @param integer $from
-     *
-     * @return integer
-     */
-    protected function peek($regex, &$out, $from = null)
-    {
-        if (! isset($from)) {
-            $from = $this->count;
-        }
-
-        $r = '/' . $regex . '/' . $this->patternModifiers;
-        $result = preg_match($r, $this->buffer, $out, null, $from);
-
-        return $result;
-    }
-
-    /**
-     * Seek to position in input stream (or return current position in input stream)
-     *
-     * @param integer $where
-     *
-     * @return integer
-     */
-    protected function seek($where)
-    {
-        $this->count = $where;
-    }
-
-    /**
-     * Match string looking for either ending delim, escape, or string interpolation
-     *
-     * {@internal This is a workaround for preg_match's 250K string match limit. }}
-     *
-     * @param array  $m     Matches (passed by reference)
-     * @param string $delim Delimeter
-     *
-     * @return boolean True if match; false otherwise
-     */
-    protected function matchString(&$m, $delim)
-    {
-        $token = null;
-
-        $end = strlen($this->buffer);
-
-        // look for either ending delim, escape, or string interpolation
-        foreach (['#{', '\\', $delim] as $lookahead) {
-            $pos = strpos($this->buffer, $lookahead, $this->count);
-
-            if ($pos !== false && $pos < $end) {
-                $end = $pos;
-                $token = $lookahead;
-            }
-        }
-
-        if (! isset($token)) {
-            return false;
-        }
-
-        $match = substr($this->buffer, $this->count, $end - $this->count);
-        $m = [
-            $match . $token,
-            $match,
-            $token
-        ];
-        $this->count = $end + strlen($token);
-
-        return true;
-    }
-
-    /**
-     * Try to match something on head of buffer
-     *
-     * @param string  $regex
-     * @param array   $out
-     * @param boolean $eatWhitespace
-     *
-     * @return boolean
-     */
-    protected function match($regex, &$out, $eatWhitespace = null)
-    {
-
-        $r = '/' . $regex . '/' . $this->patternModifiers;
-
-        if (! preg_match($r, $this->buffer, $out, null, $this->count)) {
-            return false;
-        }
-
-        $this->count += strlen($out[0]);
-
-        if (! isset($eatWhitespace)) {
-            $eatWhitespace = $this->eatWhiteDefault;
-        }
-
-        if ($eatWhitespace) {
-            $this->whitespace();
-        }
-
-        return true;
-    }
-
-
-    /**
-     * Match a single string
-     *
-     * @param string  $char
-     * @param boolean $eatWhitespace
-     *
-     * @return boolean
-     */
-    protected function matchChar($char, $eatWhitespace = null)
-    {
-
-        if (! isset($this->buffer[$this->count]) || $this->buffer[$this->count] !== $char) {
-            return false;
-        }
-
-        $this->count++;
-
-        if (! isset($eatWhitespace)) {
-            $eatWhitespace = $this->eatWhiteDefault;
-        }
-
-        if ($eatWhitespace) {
-            $this->whitespace();
-        }
-        return true;
-    }
-
-
-    /**
-     * Match literal string
-     *
-     * @param string  $what
-     * @param integer $len
-     * @param boolean $eatWhitespace
-     *
-     * @return boolean
-     */
-    protected function literal($what, $len, $eatWhitespace = null)
-    {
-
-        if (strcasecmp(substr($this->buffer, $this->count, $len), $what) !== 0) {
-            return false;
-        }
-
-        $this->count += $len;
-
-        if (! isset($eatWhitespace)) {
-            $eatWhitespace = $this->eatWhiteDefault;
-        }
-
-        if ($eatWhitespace) {
-            $this->whitespace();
-        }
-        return true;
-    }
-
-
-    /**
-     * Match some whitespace
-     *
-     * @return boolean
-     */
-    protected function whitespace()
-    {
-        $gotWhite = false;
-
-        while (preg_match(static::$whitePattern, $this->buffer, $m, null, $this->count)) {
-            if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
-                $this->appendComment([Type::T_COMMENT, $m[1]]);
-
-                $this->commentsSeen[$this->count] = true;
-            }
-
-            $this->count += strlen($m[0]);
-            $gotWhite = true;
-        }
-
-        return $gotWhite;
-    }
-
-    /**
-     * Append comment to current block
-     *
-     * @param array $comment
-     */
-    protected function appendComment($comment)
-    {
-        $comment[1] = substr(preg_replace(['/^\s+/m', '/^(.)/m'], ['', ' \1'], $comment[1]), 1);
-
-        $this->env->comments[] = $comment;
-    }
-
-    /**
-     * Append statement to current block
-     *
-     * @param array   $statement
-     * @param integer $pos
-     */
-    protected function append($statement, $pos = null)
-    {
-        if ($pos !== null) {
-            list($line, $column) = $this->getSourcePosition($pos);
-
-            $statement[static::SOURCE_LINE]   = $line;
-            $statement[static::SOURCE_COLUMN] = $column;
-            $statement[static::SOURCE_INDEX]  = $this->sourceIndex;
-        }
-
-        $this->env->children[] = $statement;
-
-        $comments = $this->env->comments;
-
-        if ($comments) {
-            $this->env->children = array_merge($this->env->children, $comments);
-            $this->env->comments = [];
-        }
-    }
-
-    /**
-     * Returns last child was appended
-     *
-     * @return array|null
-     */
-    protected function last()
-    {
-        $i = count($this->env->children) - 1;
-
-        if (isset($this->env->children[$i])) {
-            return $this->env->children[$i];
-        }
-    }
-
-    /**
-     * Parse media query list
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function mediaQueryList(&$out)
-    {
-        return $this->genericList($out, 'mediaQuery', ',', false);
-    }
-
-    /**
-     * Parse media query
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function mediaQuery(&$out)
-    {
-        $expressions = null;
-        $parts = [];
-
-        if (($this->literal('only', 4) && ($only = true) || $this->literal('not', 3) && ($not = true) || true) &&
-            $this->mixedKeyword($mediaType)
-        ) {
-            $prop = [Type::T_MEDIA_TYPE];
-
-            if (isset($only)) {
-                $prop[] = [Type::T_KEYWORD, 'only'];
-            }
-
-            if (isset($not)) {
-                $prop[] = [Type::T_KEYWORD, 'not'];
-            }
-
-            $media = [Type::T_LIST, '', []];
-
-            foreach ((array) $mediaType as $type) {
-                if (is_array($type)) {
-                    $media[2][] = $type;
-                } else {
-                    $media[2][] = [Type::T_KEYWORD, $type];
-                }
-            }
-
-            $prop[]  = $media;
-            $parts[] = $prop;
-        }
-
-        if (empty($parts) || $this->literal('and', 3)) {
-            $this->genericList($expressions, 'mediaExpression', 'and', false);
-
-            if (is_array($expressions)) {
-                $parts = array_merge($parts, $expressions[2]);
-            }
-        }
-
-        $out = $parts;
-
-        return true;
-    }
-
-    /**
-     * Parse media expression
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function mediaExpression(&$out)
-    {
-        $s = $this->count;
-        $value = null;
-
-        if ($this->matchChar('(') &&
-            $this->expression($feature) &&
-            ($this->matchChar(':') && $this->expression($value) || true) &&
-            $this->matchChar(')')
-        ) {
-            $out = [Type::T_MEDIA_EXPRESSION, $feature];
-
-            if ($value) {
-                $out[] = $value;
-            }
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        return false;
-    }
-
-    /**
-     * Parse argument values
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function argValues(&$out)
-    {
-        if ($this->genericList($list, 'argValue', ',', false)) {
-            $out = $list[2];
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse argument value
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function argValue(&$out)
-    {
-        $s = $this->count;
-
-        $keyword = null;
-
-        if (! $this->variable($keyword) || ! $this->matchChar(':')) {
-            $this->seek($s);
-            $keyword = null;
-        }
-
-        if ($this->genericList($value, 'expression')) {
-            $out = [$keyword, $value, false];
-            $s = $this->count;
-
-            if ($this->literal('...', 3)) {
-                $out[2] = true;
-            } else {
-                $this->seek($s);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse comma separated value list
-     *
-     * @param string $out
-     *
-     * @return boolean
-     */
-    protected function valueList(&$out)
-    {
-        return $this->genericList($out, 'spaceList', ',');
-    }
-
-    /**
-     * Parse space separated value list
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function spaceList(&$out)
-    {
-        return $this->genericList($out, 'expression');
-    }
-
-    /**
-     * Parse generic list
-     *
-     * @param array    $out
-     * @param callable $parseItem
-     * @param string   $delim
-     * @param boolean  $flatten
-     *
-     * @return boolean
-     */
-    protected function genericList(&$out, $parseItem, $delim = '', $flatten = true)
-    {
-        $s = $this->count;
-        $items = [];
-        $value = null;
-        while ($this->$parseItem($value)) {
-            $items[] = $value;
-
-            if ($delim) {
-                if (! $this->literal($delim, strlen($delim))) {
-                    break;
-                }
-            }
-        }
-
-        if (!$items) {
-            $this->seek($s);
-
-            return false;
-        }
-
-        if ($flatten && count($items) === 1) {
-            $out = $items[0];
-        } else {
-            $out = [Type::T_LIST, $delim, $items];
-        }
-
-        return true;
-    }
-
-    /**
-     * Parse expression
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function expression(&$out)
-    {
-        $s = $this->count;
-
-        if ($this->matchChar('(')) {
-            if ($this->matchChar(')')) {
-                $out = [Type::T_LIST, '', []];
-
-                return true;
-            }
-
-            if ($this->valueList($out) && $this->matchChar(')') && $out[0] === Type::T_LIST) {
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->map($out)) {
-                return true;
-            }
-
-            $this->seek($s);
-        }
-
-        if ($this->value($lhs)) {
-            $out = $this->expHelper($lhs, 0);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse left-hand side of subexpression
-     *
-     * @param array   $lhs
-     * @param integer $minP
-     *
-     * @return array
-     */
-    protected function expHelper($lhs, $minP)
-    {
-        $operators = static::$operatorPattern;
-
-        $ss = $this->count;
-        $whiteBefore = isset($this->buffer[$this->count - 1]) &&
-            ctype_space($this->buffer[$this->count - 1]);
-
-        while ($this->match($operators, $m, false) && static::$precedence[$m[1]] >= $minP) {
-            $whiteAfter = isset($this->buffer[$this->count]) &&
-                ctype_space($this->buffer[$this->count]);
-            $varAfter = isset($this->buffer[$this->count]) &&
-                $this->buffer[$this->count] === '$';
-
-            $this->whitespace();
-
-            $op = $m[1];
-
-            // don't turn negative numbers into expressions
-            if ($op === '-' && $whiteBefore && ! $whiteAfter && ! $varAfter) {
-                break;
-            }
-
-            if (! $this->value($rhs)) {
-                break;
-            }
-
-            // peek and see if rhs belongs to next operator
-            if ($this->peek($operators, $next) && static::$precedence[$next[1]] > static::$precedence[$op]) {
-                $rhs = $this->expHelper($rhs, static::$precedence[$next[1]]);
-            }
-
-            $lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter];
-            $ss = $this->count;
-            $whiteBefore = isset($this->buffer[$this->count - 1]) &&
-                ctype_space($this->buffer[$this->count - 1]);
-        }
-
-        $this->seek($ss);
-
-        return $lhs;
-    }
-
-    /**
-     * Parse value
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function value(&$out)
-    {
-
-        if (! isset($this->buffer[$this->count])) {
-            return false;
-        }
-
-        $s = $this->count;
-        $char = $this->buffer[$this->count];
-
-        if ($this->literal('url(', 4) && $this->match('data:([a-z]+)\/([a-z0-9.+-]+);base64,', $m, false)) {
-            $len = strspn($this->buffer, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwyxz0123456789+/=', $this->count);
-
-            $this->count += $len;
-
-            if ($this->matchChar(')')) {
-                $content = substr($this->buffer, $s, $this->count - $s);
-                $out = [Type::T_KEYWORD, $content];
-
-                return true;
-            }
-        }
-
-        $this->seek($s);
-
-        // not
-        if ($char === 'n' && $this->literal('not', 3, false)) {
-            if ($this->whitespace() && $this->value($inner)) {
-                $out = [Type::T_UNARY, 'not', $inner, $this->inParens];
-                return true;
-            }
-
-            $this->seek($s);
-
-            if ($this->parenValue($inner)) {
-                $out = [Type::T_UNARY, 'not', $inner, $this->inParens];
-                return true;
-            }
-
-            $this->seek($s);
-        }
-
-        // addition
-        if ($char === '+') {
-            $this->count++;
-            if ($this->value($inner)) {
-                $out = [Type::T_UNARY, '+', $inner, $this->inParens];
-                return true;
-            }
-            $this->count--;
-            return false;
-        }
-
-
-        // negation
-        if ($char === '-') {
-            $this->count++;
-            if ($this->variable($inner) || $this->unit($inner) || $this->parenValue($inner)) {
-                $out = [Type::T_UNARY, '-', $inner, $this->inParens];
-                return true;
-            }
-            $this->count--;
-        }
-
-        // paren
-        if ($char === '(' && $this->parenValue($out)) {
-            return true;
-        }
-
-        if ($char === '#') {
-            if ($this->interpolation($out) || $this->color($out)) {
-                return true;
-            }
-        }
-
-        if ($char === '$' && $this->variable($out)) {
-            return true;
-        }
-
-        if ($char === 'p' && $this->progid($out)) {
-            return true;
-        }
-
-        if (($char === '"' || $char === "'") && $this->string($out)) {
-            return true;
-        }
-
-
-        if ($this->unit($out)) {
-            return true;
-        }
-
-        if ($this->keyword($keyword, false)) {
-            if ($this->func($keyword, $out)) {
-                return true;
-            }
-
-            $this->whitespace();
-
-            if ($keyword === 'null') {
-                $out = [Type::T_NULL];
-            } else {
-                $out = [Type::T_KEYWORD, $keyword];
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse parenthesized value
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function parenValue(&$out)
-    {
-        $s = $this->count;
-
-        $inParens = $this->inParens;
-
-        if ($this->matchChar('(')) {
-            if ($this->matchChar(')')) {
-                $out = [Type::T_LIST, '', []];
-
-                return true;
-            }
-
-            $this->inParens = true;
-
-            if ($this->expression($exp) && $this->matchChar(')')) {
-                $out = $exp;
-                $this->inParens = $inParens;
-
-                return true;
-            }
-        }
-
-        $this->inParens = $inParens;
-        $this->seek($s);
-
-        return false;
-    }
-
-    /**
-     * Parse "progid:"
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function progid(&$out)
-    {
-        $s = $this->count;
-
-        if ($this->literal('progid:', 7, false) &&
-            $this->openString('(', $fn) &&
-            $this->matchChar('(')
-        ) {
-            $this->openString(')', $args, '(');
-
-            if ($this->matchChar(')')) {
-                $out = [Type::T_STRING, '', [
-                    'progid:', $fn, '(', $args, ')'
-                ]];
-
-                return true;
-            }
-        }
-
-        $this->seek($s);
-
-        return false;
-    }
-
-    /**
-     * Parse function call
-     *
-     * @param string $name
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function func($name, &$func)
-    {
-        $s = $this->count;
-
-        if ($this->matchChar('(')) {
-            if ($name === 'alpha' && $this->argumentList($args)) {
-                $func = [Type::T_FUNCTION, $name, [Type::T_STRING, '', $args]];
-
-                return true;
-            }
-
-            if ($name !== 'expression' && ! preg_match('/^(-[a-z]+-)?calc$/', $name)) {
-                $ss = $this->count;
-
-                if ($this->argValues($args) && $this->matchChar(')')) {
-                    $func = [Type::T_FUNCTION_CALL, $name, $args];
-
-                    return true;
-                }
-
-                $this->seek($ss);
-            }
-
-            if (($this->openString(')', $str, '(') || true) &&
-                $this->matchChar(')')
-            ) {
-                $args = [];
-
-                if (! empty($str)) {
-                    $args[] = [null, [Type::T_STRING, '', [$str]]];
-                }
-
-                $func = [Type::T_FUNCTION_CALL, $name, $args];
-
-                return true;
-            }
-        }
-
-        $this->seek($s);
-
-        return false;
-    }
-
-    /**
-     * Parse function call argument list
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function argumentList(&$out)
-    {
-        $s = $this->count;
-        $this->matchChar('(');
-
-        $args = [];
-
-        while ($this->keyword($var)) {
-            if ($this->matchChar('=') && $this->expression($exp)) {
-                $args[] = [Type::T_STRING, '', [$var . '=']];
-                $arg = $exp;
-            } else {
-                break;
-            }
-
-            $args[] = $arg;
-
-            if (! $this->matchChar(',')) {
-                break;
-            }
-
-            $args[] = [Type::T_STRING, '', [', ']];
-        }
-
-        if (! $this->matchChar(')') || !$args) {
-            $this->seek($s);
-
-            return false;
-        }
-
-        $out = $args;
-
-        return true;
-    }
-
-    /**
-     * Parse mixin/function definition  argument list
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function argumentDef(&$out)
-    {
-        $s = $this->count;
-        $this->matchChar('(');
-
-        $args = [];
-
-        while ($this->variable($var)) {
-            $arg = [$var[1], null, false];
-
-            $ss = $this->count;
-
-            if ($this->matchChar(':') && $this->genericList($defaultVal, 'expression')) {
-                $arg[1] = $defaultVal;
-            } else {
-                $this->seek($ss);
-            }
-
-            $ss = $this->count;
-
-            if ($this->literal('...', 3)) {
-                $sss = $this->count;
-
-                if (! $this->matchChar(')')) {
-                    $this->throwParseError('... has to be after the final argument');
-                }
-
-                $arg[2] = true;
-                $this->seek($sss);
-            } else {
-                $this->seek($ss);
-            }
-
-            $args[] = $arg;
-
-            if (! $this->matchChar(',')) {
-                break;
-            }
-        }
-
-        if (! $this->matchChar(')')) {
-            $this->seek($s);
-
-            return false;
-        }
-
-        $out = $args;
-
-        return true;
-    }
-
-    /**
-     * Parse map
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function map(&$out)
-    {
-        $s = $this->count;
-
-        if (! $this->matchChar('(')) {
-            return false;
-        }
-
-        $keys = [];
-        $values = [];
-
-        while ($this->genericList($key, 'expression') && $this->matchChar(':') &&
-            $this->genericList($value, 'expression')
-        ) {
-            $keys[] = $key;
-            $values[] = $value;
-
-            if (! $this->matchChar(',')) {
-                break;
-            }
-        }
-
-        if (!$keys || ! $this->matchChar(')')) {
-            $this->seek($s);
-
-            return false;
-        }
-
-        $out = [Type::T_MAP, $keys, $values];
-
-        return true;
-    }
-
-    /**
-     * Parse color
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function color(&$out)
-    {
-        $color = [Type::T_COLOR];
-        $s     = $this->count;
-
-        if ($this->match('(#([0-9a-f]+))', $m)) {
-            $nofValues = strlen($m[2]);
-            $hasAlpha  = $nofValues === 4 || $nofValues === 8;
-            $channels  = $hasAlpha ? [4, 3, 2, 1] : [3, 2, 1];
-
-            switch ($nofValues) {
-                case 3:
-                case 4:
-                    $num = hexdec($m[2]);
-
-                    foreach ($channels as $i) {
-                        $t = $num & 0xf;
-                        $color[$i] = $t << 4 | $t;
-                        $num >>= 4;
-                    }
-                    break;
-
-                case 6:
-                case 8:
-                    $num = hexdec($m[2]);
-
-                    foreach ($channels as $i) {
-                        $color[$i] = $num & 0xff;
-                        $num >>= 8;
-                    }
-                    break;
-
-                default:
-                    $this->seek($s);
-
-                    return false;
-            }
-
-            if ($hasAlpha) {
-                if ($color[4] === 255) {
-                    $color[4] = 1; // fully opaque
-                } else {
-                    $color[4] = round($color[4] / 255, 3);
-                }
-            }
-
-            $out = $color;
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse number with unit
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function unit(&$unit)
-    {
-        if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m)) {
-            $unit = new Node\Number($m[1], empty($m[3]) ? '' : $m[3]);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse string
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function string(&$out)
-    {
-        $s = $this->count;
-
-        if ($this->matchChar('"', false)) {
-            $delim = '"';
-        } elseif ($this->matchChar("'", false)) {
-            $delim = "'";
-        } else {
-            return false;
-        }
-
-        $content = [];
-        $oldWhite = $this->eatWhiteDefault;
-        $this->eatWhiteDefault = false;
-        $hasInterpolation = false;
-
-        while ($this->matchString($m, $delim)) {
-            if ($m[1] !== '') {
-                $content[] = $m[1];
-            }
-
-            if ($m[2] === '#{') {
-                $this->count -= strlen($m[2]);
-
-                if ($this->interpolation($inter, false)) {
-                    $content[] = $inter;
-                    $hasInterpolation = true;
-                } else {
-                    $this->count += strlen($m[2]);
-                    $content[] = '#{'; // ignore it
-                }
-            } elseif ($m[2] === '\\') {
-                if ($this->matchChar('"', false)) {
-                    $content[] = $m[2] . '"';
-                } elseif ($this->matchChar("'", false)) {
-                    $content[] = $m[2] . "'";
-                } elseif ($this->literal("\\", 1, false)) {
-                    $content[] = $m[2] . "\\";
-                } else {
-                    $content[] = $m[2];
-                }
-            } else {
-                $this->count -= strlen($delim);
-                break; // delim
-            }
-        }
-
-        $this->eatWhiteDefault = $oldWhite;
-
-        if ($this->literal($delim, strlen($delim))) {
-            if ($hasInterpolation) {
-                $delim = '"';
-
-                foreach ($content as &$string) {
-                    if ($string === "\\\\") {
-                        $string = "\\";
-                    } elseif ($string === "\\'") {
-                        $string = "'";
-                    } elseif ($string === '\\"') {
-                        $string = '"';
-                    }
-                }
-            }
-
-            $out = [Type::T_STRING, $delim, $content];
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        return false;
-    }
-
-    /**
-     * Parse keyword or interpolation
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function mixedKeyword(&$out)
-    {
-        $parts = [];
-
-        $oldWhite = $this->eatWhiteDefault;
-        $this->eatWhiteDefault = false;
-
-        for (;;) {
-            if ($this->keyword($key)) {
-                $parts[] = $key;
-                continue;
-            }
-
-            if ($this->interpolation($inter)) {
-                $parts[] = $inter;
-                continue;
-            }
-
-            break;
-        }
-
-        $this->eatWhiteDefault = $oldWhite;
-
-        if (!$parts) {
-            return false;
-        }
-
-        if ($this->eatWhiteDefault) {
-            $this->whitespace();
-        }
-
-        $out = $parts;
-
-        return true;
-    }
-
-    /**
-     * Parse an unbounded string stopped by $end
-     *
-     * @param string $end
-     * @param array  $out
-     * @param string $nestingOpen
-     *
-     * @return boolean
-     */
-    protected function openString($end, &$out, $nestingOpen = null)
-    {
-        $oldWhite = $this->eatWhiteDefault;
-        $this->eatWhiteDefault = false;
-
-        $patt = '(.*?)([\'"]|#\{|' . $this->pregQuote($end) . '|' . static::$commentPattern . ')';
-
-        $nestingLevel = 0;
-
-        $content = [];
-
-        while ($this->match($patt, $m, false)) {
-            if (isset($m[1]) && $m[1] !== '') {
-                $content[] = $m[1];
-
-                if ($nestingOpen) {
-                    $nestingLevel += substr_count($m[1], $nestingOpen);
-                }
-            }
-
-            $tok = $m[2];
-
-            $this->count-= strlen($tok);
-
-            if ($tok === $end && ! $nestingLevel--) {
-                break;
-            }
-
-            if (($tok === "'" || $tok === '"') && $this->string($str)) {
-                $content[] = $str;
-                continue;
-            }
-
-            if ($tok === '#{' && $this->interpolation($inter)) {
-                $content[] = $inter;
-                continue;
-            }
-
-            $content[] = $tok;
-            $this->count+= strlen($tok);
-        }
-
-        $this->eatWhiteDefault = $oldWhite;
-
-        if (!$content) {
-            return false;
-        }
-
-        // trim the end
-        if (is_string(end($content))) {
-            $content[count($content) - 1] = rtrim(end($content));
-        }
-
-        $out = [Type::T_STRING, '', $content];
-
-        return true;
-    }
-
-    /**
-     * Parser interpolation
-     *
-     * @param array   $out
-     * @param boolean $lookWhite save information about whitespace before and after
-     *
-     * @return boolean
-     */
-    protected function interpolation(&$out, $lookWhite = true)
-    {
-        $oldWhite = $this->eatWhiteDefault;
-        $this->eatWhiteDefault = true;
-
-        $s = $this->count;
-
-        if ($this->literal('#{', 2) && $this->valueList($value) && $this->matchChar('}', false)) {
-            if ($lookWhite) {
-                $left = preg_match('/\s/', $this->buffer[$s - 1]) ? ' ' : '';
-                $right = preg_match('/\s/', $this->buffer[$this->count]) ? ' ': '';
-            } else {
-                $left = $right = false;
-            }
-
-            $out = [Type::T_INTERPOLATE, $value, $left, $right];
-            $this->eatWhiteDefault = $oldWhite;
-
-            if ($this->eatWhiteDefault) {
-                $this->whitespace();
-            }
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        if ($this->literal('#{', 2) && $this->selectorSingle($sel) && $this->matchChar('}', false)) {
-            $out = $sel[0];
-
-            $this->eatWhiteDefault = $oldWhite;
-
-            if ($this->eatWhiteDefault) {
-                $this->whitespace();
-            }
-
-            return true;
-        }
-
-        $this->seek($s);
-        $this->eatWhiteDefault = $oldWhite;
-
-        return false;
-    }
-
-    /**
-     * Parse property name (as an array of parts or a string)
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function propertyName(&$out)
-    {
-        $parts = [];
-
-        $oldWhite = $this->eatWhiteDefault;
-        $this->eatWhiteDefault = false;
-
-        for (;;) {
-            if ($this->interpolation($inter)) {
-                $parts[] = $inter;
-                continue;
-            }
-
-            if ($this->keyword($text)) {
-                $parts[] = $text;
-                continue;
-            }
-
-            if (!$parts && $this->match('[:.#]', $m, false)) {
-                // css hacks
-                $parts[] = $m[0];
-                continue;
-            }
-
-            break;
-        }
-
-        $this->eatWhiteDefault = $oldWhite;
-
-        if (!$parts) {
-            return false;
-        }
-
-        // match comment hack
-        if (preg_match(
-            static::$whitePattern,
-            $this->buffer,
-            $m,
-            null,
-            $this->count
-        )) {
-            if (! empty($m[0])) {
-                $parts[] = $m[0];
-                $this->count += strlen($m[0]);
-            }
-        }
-
-        $this->whitespace(); // get any extra whitespace
-
-        $out = [Type::T_STRING, '', $parts];
-
-        return true;
-    }
-
-    /**
-     * Parse comma separated selector list
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function selectors(&$out)
-    {
-        $s = $this->count;
-        $selectors = [];
-
-        while ($this->selector($sel)) {
-            $selectors[] = $sel;
-
-            if (! $this->matchChar(',')) {
-                break;
-            }
-
-            while ($this->matchChar(',')) {
-                ; // ignore extra
-            }
-        }
-
-        if (!$selectors) {
-            $this->seek($s);
-
-            return false;
-        }
-
-        $out = $selectors;
-
-        return true;
-    }
-
-    /**
-     * Parse whitespace separated selector list
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function selector(&$out)
-    {
-        $selector = [];
-
-        for (;;) {
-            if ($this->match('[>+~]+', $m)) {
-                $selector[] = [$m[0]];
-                continue;
-            }
-
-            if ($this->selectorSingle($part)) {
-                $selector[] = $part;
-                $this->match('\s+', $m);
-                continue;
-            }
-
-            if ($this->match('\/[^\/]+\/', $m)) {
-                $selector[] = [$m[0]];
-                continue;
-            }
-
-            break;
-        }
-
-        if (!$selector) {
-            return false;
-        }
-
-        $out = $selector;
-        return true;
-    }
-
-    /**
-     * Parse the parts that make up a selector
-     *
-     * {@internal
-     *     div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder
-     * }}
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function selectorSingle(&$out)
-    {
-        $oldWhite = $this->eatWhiteDefault;
-        $this->eatWhiteDefault = false;
-
-        $parts = [];
-
-        if ($this->matchChar('*', false)) {
-            $parts[] = '*';
-        }
-
-        for (;;) {
-            if (! isset($this->buffer[$this->count])) {
-                break;
-            }
-
-            $s = $this->count;
-            $char = $this->buffer[$this->count];
-
-            // see if we can stop early
-            if ($char === '{' || $char === ',' || $char === ';' || $char === '}' || $char === '@') {
-                break;
-            }
-
-
-            //self
-            switch ($char) {
-                case '&':
-                    $parts[] = Compiler::$selfSelector;
-                    $this->count++;
-                    continue 2;
-                case '.':
-                    $parts[] = '.';
-                    $this->count++;
-                    continue 2;
-                case '|':
-                    $parts[] = '|';
-                    $this->count++;
-                    continue 2;
-            }
-
-
-            if ($char === '\\' && $this->match('\\\\\S', $m)) {
-                $parts[] = $m[0];
-                continue;
-            }
-
-
-            if ($char === '%') {
-                $this->count++;
-                if ($this->placeholder($placeholder)) {
-                    $parts[] = '%';
-                    $parts[] = $placeholder;
-                    continue;
-                }
-                break;
-            }
-
-            if ($char === '#') {
-                if ($this->interpolation($inter)) {
-                    $parts[] = $inter;
-                    continue;
-                }
-
-                $parts[] = '#';
-                $this->count++;
-                continue;
-            }
-
-
-            // a pseudo selector
-            if ($char === ':') {
-                if ($this->buffer[$this->count + 1] === ':') {
-                    $this->count += 2;
-                    $part = '::';
-                } else {
-                    $this->count++;
-                    $part = ':';
-                }
-                if ($this->mixedKeyword($nameParts)) {
-                    $parts[] = $part;
-
-                    foreach ($nameParts as $sub) {
-                        $parts[] = $sub;
-                    }
-
-                    $ss = $this->count;
-
-                    if ($this->matchChar('(') &&
-                      ($this->openString(')', $str, '(') || true) &&
-                      $this->matchChar(')')
-                    ) {
-                        $parts[] = '(';
-
-                        if (! empty($str)) {
-                            $parts[] = $str;
-                        }
-
-                        $parts[] = ')';
-                    } else {
-                        $this->seek($ss);
-                    }
-
-                    continue;
-                }
-            }
-
-
-            $this->seek($s);
-
-
-            // attribute selector
-            if ($char === '[' &&
-              $this->matchChar('[') &&
-              ($this->openString(']', $str, '[') || true) &&
-              $this->matchChar(']')
-            ) {
-                $parts[] = '[';
-
-                if (! empty($str)) {
-                    $parts[] = $str;
-                }
-
-                $parts[] = ']';
-
-                continue;
-            }
-
-            $this->seek($s);
-
-
-            // for keyframes
-            if ($this->unit($unit)) {
-                $parts[] = $unit;
-                continue;
-            }
-
-            if ($this->keyword($name)) {
-                $parts[] = $name;
-                continue;
-            }
-
-
-
-
-            break;
-        }
-
-        $this->eatWhiteDefault = $oldWhite;
-
-        if (!$parts) {
-            return false;
-        }
-
-        $out = $parts;
-
-        return true;
-    }
-
-    /**
-     * Parse a variable
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function variable(&$out)
-    {
-        $s = $this->count;
-
-        if ($this->matchChar('$', false) && $this->keyword($name)) {
-            $out = [Type::T_VARIABLE, $name];
-
-            return true;
-        }
-
-        $this->seek($s);
-
-        return false;
-    }
-
-    /**
-     * Parse a keyword
-     *
-     * @param string  $word
-     * @param boolean $eatWhitespace
-     *
-     * @return boolean
-     */
-    protected function keyword(&$word, $eatWhitespace = null)
-    {
-        if ($this->match(
-            $this->utf8
-                ? '(([\pL\w_\-\*!"\']|[\\\\].)([\pL\w\-_"\']|[\\\\].)*)'
-                : '(([\w_\-\*!"\']|[\\\\].)([\w\-_"\']|[\\\\].)*)',
-            $m,
-            $eatWhitespace
-        )) {
-            $word = $m[1];
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse a placeholder
-     *
-     * @param string $placeholder
-     *
-     * @return boolean
-     */
-    protected function placeholder(&$placeholder)
-    {
-        if ($this->match(
-            $this->utf8
-                ? '([\pL\w\-_]+|#[{][$][\pL\w\-_]+[}])'
-                : '([\w\-_]+|#[{][$][\w\-_]+[}])',
-            $m
-        )) {
-            $placeholder = $m[1];
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse a url
-     *
-     * @param array $out
-     *
-     * @return boolean
-     */
-    protected function url(&$out)
-    {
-        if ($this->match('(url\(\s*(["\']?)([^)]+)\2\s*\))', $m)) {
-            $out = [Type::T_STRING, '', ['url(' . $m[2] . $m[3] . $m[2] . ')']];
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Consume an end of statement delimiter
-     *
-     * @return boolean
-     */
-    protected function end()
-    {
-        if ($this->matchChar(';')) {
-            return true;
-        }
-
-        if ($this->count === strlen($this->buffer) || $this->buffer[$this->count] === '}') {
-            // if there is end of file or a closing block next then we don't need a ;
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Strip assignment flag from the list
-     *
-     * @param array $value
-     *
-     * @return array
-     */
-    protected function stripAssignmentFlags(&$value)
-    {
-        $flags = [];
-
-        for ($token = &$value; $token[0] === Type::T_LIST && ($s = count($token[2])); $token = &$lastNode) {
-            $lastNode = &$token[2][$s - 1];
-
-            while ($lastNode[0] === Type::T_KEYWORD && in_array($lastNode[1], ['!default', '!global'])) {
-                array_pop($token[2]);
-
-                $node = end($token[2]);
-
-                $token = $this->flattenList($token);
-
-                $flags[] = $lastNode[1];
-
-                $lastNode = $node;
-            }
-        }
-
-        return $flags;
-    }
-
-    /**
-     * Strip optional flag from selector list
-     *
-     * @param array $selectors
-     *
-     * @return string
-     */
-    protected function stripOptionalFlag(&$selectors)
-    {
-        $optional = false;
-
-        $selector = end($selectors);
-        $part = end($selector);
-
-        if ($part === ['!optional']) {
-            array_pop($selectors[count($selectors) - 1]);
-
-            $optional = true;
-        }
-
-        return $optional;
-    }
-
-    /**
-     * Turn list of length 1 into value type
-     *
-     * @param array $value
-     *
-     * @return array
-     */
-    protected function flattenList($value)
-    {
-        if ($value[0] === Type::T_LIST && count($value[2]) === 1) {
-            return $this->flattenList($value[2][0]);
-        }
-
-        return $value;
-    }
-
-    /**
-     * @deprecated
-     *
-     * {@internal
-     *     advance counter to next occurrence of $what
-     *     $until - don't include $what in advance
-     *     $allowNewline, if string, will be used as valid char set
-     * }}
-     */
-    protected function to($what, &$out, $until = false, $allowNewline = false)
-    {
-        if (is_string($allowNewline)) {
-            $validChars = $allowNewline;
-        } else {
-            $validChars = $allowNewline ? '.' : "[^\n]";
-        }
-
-        if (! $this->match('(' . $validChars . '*?)' . $this->pregQuote($what), $m, ! $until)) {
-            return false;
-        }
-
-        if ($until) {
-            $this->count -= strlen($what); // give back $what
-        }
-
-        $out = $m[1];
-
-        return true;
-    }
-
-    /**
-     * @deprecated
-     */
-    protected function show()
-    {
-        if ($this->peek("(.*?)(\n|$)", $m, $this->count)) {
-            return $m[1];
-        }
-
-        return '';
-    }
-
-    /**
-     * Quote regular expression
-     *
-     * @param string $what
-     *
-     * @return string
-     */
-    private function pregQuote($what)
-    {
-        return preg_quote($what, '/');
-    }
-
-    /**
-     * Extract line numbers from buffer
-     *
-     * @param string $buffer
-     */
-    private function extractLineNumbers($buffer)
-    {
-        $this->sourcePositions = [0 => 0];
-        $prev = 0;
-
-        while (($pos = strpos($buffer, "\n", $prev)) !== false) {
-            $this->sourcePositions[] = $pos;
-            $prev = $pos + 1;
-        }
-
-        $this->sourcePositions[] = strlen($buffer);
-
-        if (substr($buffer, -1) !== "\n") {
-            $this->sourcePositions[] = strlen($buffer) + 1;
-        }
-    }
-
-    /**
-     * Get source line number and column (given character position in the buffer)
-     *
-     * @param integer $pos
-     *
-     * @return integer
-     */
-    private function getSourcePosition($pos)
-    {
-        $low = 0;
-        $high = count($this->sourcePositions);
-
-        while ($low < $high) {
-            $mid = (int) (($high + $low) / 2);
-
-            if ($pos < $this->sourcePositions[$mid]) {
-                $high = $mid - 1;
-                continue;
-            }
-
-            if ($pos >= $this->sourcePositions[$mid + 1]) {
-                $low = $mid + 1;
-                continue;
-            }
-
-            return [$mid + 1, $pos - $this->sourcePositions[$mid]];
-        }
-
-        return [$low + 1, $pos - $this->sourcePositions[$low]];
-    }
-
-    /**
-     * Save internal encoding
-     */
-    private function saveEncoding()
-    {
-        if (version_compare(PHP_VERSION, '7.2.0') >= 0) {
-            return;
-        }
-
-        $iniDirective = 'mbstring' . '.func_overload'; // deprecated in PHP 7.2
-
-        if (ini_get($iniDirective) & 2) {
-            $this->encoding = mb_internal_encoding();
-
-            mb_internal_encoding('iso-8859-1');
-        }
-    }
-
-    /**
-     * Restore internal encoding
-     */
-    private function restoreEncoding()
-    {
-        if ($this->encoding) {
-            mb_internal_encoding($this->encoding);
-        }
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64.php
deleted file mode 100644 (file)
index 54015bb..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2015 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\SourceMap;
-
-/**
- * Base 64 Encode/Decode
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Base64
-{
-    /**
-     * @var array
-     */
-    private static $encodingMap = [
-        0 => 'A',
-        1 => 'B',
-        2 => 'C',
-        3 => 'D',
-        4 => 'E',
-        5 => 'F',
-        6 => 'G',
-        7 => 'H',
-        8 => 'I',
-        9 => 'J',
-        10 => 'K',
-        11 => 'L',
-        12 => 'M',
-        13 => 'N',
-        14 => 'O',
-        15 => 'P',
-        16 => 'Q',
-        17 => 'R',
-        18 => 'S',
-        19 => 'T',
-        20 => 'U',
-        21 => 'V',
-        22 => 'W',
-        23 => 'X',
-        24 => 'Y',
-        25 => 'Z',
-        26 => 'a',
-        27 => 'b',
-        28 => 'c',
-        29 => 'd',
-        30 => 'e',
-        31 => 'f',
-        32 => 'g',
-        33 => 'h',
-        34 => 'i',
-        35 => 'j',
-        36 => 'k',
-        37 => 'l',
-        38 => 'm',
-        39 => 'n',
-        40 => 'o',
-        41 => 'p',
-        42 => 'q',
-        43 => 'r',
-        44 => 's',
-        45 => 't',
-        46 => 'u',
-        47 => 'v',
-        48 => 'w',
-        49 => 'x',
-        50 => 'y',
-        51 => 'z',
-        52 => '0',
-        53 => '1',
-        54 => '2',
-        55 => '3',
-        56 => '4',
-        57 => '5',
-        58 => '6',
-        59 => '7',
-        60 => '8',
-        61 => '9',
-        62 => '+',
-        63 => '/',
-    ];
-
-    /**
-     * @var array
-     */
-    private static $decodingMap = [
-        'A' => 0,
-        'B' => 1,
-        'C' => 2,
-        'D' => 3,
-        'E' => 4,
-        'F' => 5,
-        'G' => 6,
-        'H' => 7,
-        'I' => 8,
-        'J' => 9,
-        'K' => 10,
-        'L' => 11,
-        'M' => 12,
-        'N' => 13,
-        'O' => 14,
-        'P' => 15,
-        'Q' => 16,
-        'R' => 17,
-        'S' => 18,
-        'T' => 19,
-        'U' => 20,
-        'V' => 21,
-        'W' => 22,
-        'X' => 23,
-        'Y' => 24,
-        'Z' => 25,
-        'a' => 26,
-        'b' => 27,
-        'c' => 28,
-        'd' => 29,
-        'e' => 30,
-        'f' => 31,
-        'g' => 32,
-        'h' => 33,
-        'i' => 34,
-        'j' => 35,
-        'k' => 36,
-        'l' => 37,
-        'm' => 38,
-        'n' => 39,
-        'o' => 40,
-        'p' => 41,
-        'q' => 42,
-        'r' => 43,
-        's' => 44,
-        't' => 45,
-        'u' => 46,
-        'v' => 47,
-        'w' => 48,
-        'x' => 49,
-        'y' => 50,
-        'z' => 51,
-        0 => 52,
-        1 => 53,
-        2 => 54,
-        3 => 55,
-        4 => 56,
-        5 => 57,
-        6 => 58,
-        7 => 59,
-        8 => 60,
-        9 => 61,
-        '+' => 62,
-        '/' => 63,
-    ];
-
-    /**
-     * Convert to base64
-     *
-     * @param integer $value
-     *
-     * @return string
-     */
-    public static function encode($value)
-    {
-        return self::$encodingMap[$value];
-    }
-
-    /**
-     * Convert from base64
-     *
-     * @param string $value
-     *
-     * @return integer
-     */
-    public static function decode($value)
-    {
-        return self::$decodingMap[$value];
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64VLQ.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64VLQ.php
deleted file mode 100644 (file)
index 6de3b5e..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2015 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\SourceMap;
-
-use Leafo\ScssPhp\SourceMap\Base64;
-
-/**
- * Base 64 VLQ
- *
- * Based on the Base 64 VLQ implementation in Closure Compiler:
- * https://github.com/google/closure-compiler/blob/master/src/com/google/debugging/sourcemap/Base64VLQ.java
- *
- * Copyright 2011 The Closure Compiler Authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @author John Lenz <johnlenz@google.com>
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Base64VLQ
-{
-    // A Base64 VLQ digit can represent 5 bits, so it is base-32.
-    const VLQ_BASE_SHIFT = 5;
-
-    // A mask of bits for a VLQ digit (11111), 31 decimal.
-    const VLQ_BASE_MASK = 31;
-
-    // The continuation bit is the 6th bit.
-    const VLQ_CONTINUATION_BIT = 32;
-
-    /**
-     * Returns the VLQ encoded value.
-     *
-     * @param integer $value
-     *
-     * @return string
-     */
-    public static function encode($value)
-    {
-        $encoded = '';
-        $vlq = self::toVLQSigned($value);
-
-        do {
-            $digit = $vlq & self::VLQ_BASE_MASK;
-            $vlq >>= self::VLQ_BASE_SHIFT;
-
-            if ($vlq > 0) {
-                $digit |= self::VLQ_CONTINUATION_BIT;
-            }
-
-            $encoded .= Base64::encode($digit);
-        } while ($vlq > 0);
-
-        return $encoded;
-    }
-
-    /**
-     * Decodes VLQValue.
-     *
-     * @param string $str
-     * @param integer $index
-     *
-     * @return integer
-     */
-    public static function decode($str, &$index)
-    {
-        $result = 0;
-        $shift = 0;
-
-        do {
-            $c = $str[$index++];
-            $digit = Base64::decode($c);
-            $continuation = ($digit & self::VLQ_CONTINUATION_BIT) != 0;
-            $digit &= self::VLQ_BASE_MASK;
-            $result = $result + ($digit << $shift);
-            $shift = $shift + self::VLQ_BASE_SHIFT;
-        } while ($continuation);
-
-        return self::fromVLQSigned($result);
-    }
-
-    /**
-     * Converts from a two-complement value to a value where the sign bit is
-     * is placed in the least significant bit.  For example, as decimals:
-     *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
-     *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
-     *
-     * @param integer $value
-     *
-     * @return integer
-     */
-    private static function toVLQSigned($value)
-    {
-        if ($value < 0) {
-            return ((-$value) << 1) + 1;
-        }
-
-        return ($value << 1) + 0;
-    }
-
-    /**
-     * Converts to a two-complement value from a value where the sign bit is
-     * is placed in the least significant bit.  For example, as decimals:
-     *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
-     *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
-     *
-     * @param integer $value
-     *
-     * @return integer
-     */
-    private static function fromVLQSigned($value)
-    {
-        $negate = ($value & 1) === 1;
-        $value = $value >> 1;
-
-        return $negate ? -$value : $value;
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64VLQEncoder.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/Base64VLQEncoder.php
deleted file mode 100644 (file)
index caf56c7..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\SourceMap;
-
-/**
- * Base64 VLQ Encoder
- *
- * {@internal Derivative of oyejorge/less.php's lib/SourceMap/Base64VLQ.php, relicensed with permission. }}
- *
- * @author Josh Schmidt <oyejorge@gmail.com>
- * @author Nicolas FRANÇOIS <nicolas.francois@frog-labs.com>
- */
-class Base64VLQEncoder
-{
-    /**
-     * Shift
-     *
-     * @var integer
-     */
-    private $shift = 5;
-
-    /**
-     * Mask
-     *
-     * @var integer
-     */
-    private $mask = 0x1F; // == (1 << shift) == 0b00011111
-
-    /**
-     * Continuation bit
-     *
-     * @var integer
-     */
-    private $continuationBit = 0x20; // == (mask - 1 ) == 0b00100000
-
-    /**
-     * Char to integer map
-     *
-     * @var array
-     */
-    private $charToIntMap = [
-        'A' => 0,  'B' => 1,  'C' => 2,  'D' => 3,  'E' => 4,  'F' => 5,  'G' => 6,  'H' => 7,
-        'I' => 8,  'J' => 9,  'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13, 'O' => 14, 'P' => 15,
-        'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19, 'U' => 20, 'V' => 21, 'W' => 22, 'X' => 23,
-        'Y' => 24, 'Z' => 25, 'a' => 26, 'b' => 27, 'c' => 28, 'd' => 29, 'e' => 30, 'f' => 31,
-        'g' => 32, 'h' => 33, 'i' => 34, 'j' => 35, 'k' => 36, 'l' => 37, 'm' => 38, 'n' => 39,
-        'o' => 40, 'p' => 41, 'q' => 42, 'r' => 43, 's' => 44, 't' => 45, 'u' => 46, 'v' => 47,
-        'w' => 48, 'x' => 49, 'y' => 50, 'z' => 51,   0 => 52,   1 => 53,   2 => 54,   3 => 55,
-          4 => 56,   5 => 57,   6 => 58,   7 => 59,   8 => 60,   9 => 61, '+' => 62, '/' => 63,
-    ];
-
-    /**
-     * Integer to char map
-     *
-     * @var array
-     */
-    private $intToCharMap = [
-         0 => 'A',  1 => 'B',  2 => 'C',  3 => 'D',  4 => 'E',  5 => 'F',  6 => 'G',  7 => 'H',
-         8 => 'I',  9 => 'J', 10 => 'K', 11 => 'L', 12 => 'M', 13 => 'N', 14 => 'O', 15 => 'P',
-        16 => 'Q', 17 => 'R', 18 => 'S', 19 => 'T', 20 => 'U', 21 => 'V', 22 => 'W', 23 => 'X',
-        24 => 'Y', 25 => 'Z', 26 => 'a', 27 => 'b', 28 => 'c', 29 => 'd', 30 => 'e', 31 => 'f',
-        32 => 'g', 33 => 'h', 34 => 'i', 35 => 'j', 36 => 'k', 37 => 'l', 38 => 'm', 39 => 'n',
-        40 => 'o', 41 => 'p', 42 => 'q', 43 => 'r', 44 => 's', 45 => 't', 46 => 'u', 47 => 'v',
-        48 => 'w', 49 => 'x', 50 => 'y', 51 => 'z', 52 => '0', 53 => '1', 54 => '2', 55 => '3',
-        56 => '4', 57 => '5', 58 => '6', 59 => '7', 60 => '8', 61 => '9', 62 => '+', 63 => '/',
-    ];
-
-    /**
-     * Constructor
-     */
-    public function __construct()
-    {
-        // I leave it here for future reference
-        // foreach (str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/') as $i => $char)
-        // {
-        //     $this->charToIntMap[$char] = $i;
-        //     $this->intToCharMap[$i] = $char;
-        // }
-    }
-
-    /**
-     * Convert from a two-complement value to a value where the sign bit is
-     * is placed in the least significant bit. For example, as decimals:
-     *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
-     *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
-     * We generate the value for 32 bit machines, hence -2147483648 becomes 1, not 4294967297,
-     * even on a 64 bit machine.
-     *
-     * @param string $aValue
-     */
-    public function toVLQSigned($aValue)
-    {
-        return 0xffffffff & ($aValue < 0 ? ((-$aValue) << 1) + 1 : ($aValue << 1) + 0);
-    }
-
-    /**
-     * Convert to a two-complement value from a value where the sign bit is
-     * is placed in the least significant bit. For example, as decimals:
-     *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
-     *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
-     * We assume that the value was generated with a 32 bit machine in mind.
-     * Hence
-     *   1 becomes -2147483648
-     * even on a 64 bit machine.
-     *
-     * @param integer $aValue
-     */
-    public function fromVLQSigned($aValue)
-    {
-        return $aValue & 1 ? $this->zeroFill(~$aValue + 2, 1) | (-1 - 0x7fffffff) : $this->zeroFill($aValue, 1);
-    }
-
-    /**
-     * Return the base 64 VLQ encoded value.
-     *
-     * @param string $aValue The value to encode
-     *
-     * @return string The encoded value
-     */
-    public function encode($aValue)
-    {
-        $encoded = '';
-        $vlq = $this->toVLQSigned($aValue);
-
-        do {
-            $digit = $vlq & $this->mask;
-            $vlq = $this->zeroFill($vlq, $this->shift);
-
-            if ($vlq > 0) {
-                $digit |= $this->continuationBit;
-            }
-
-            $encoded .= $this->base64Encode($digit);
-        } while ($vlq > 0);
-
-        return $encoded;
-    }
-
-    /**
-     * Return the value decoded from base 64 VLQ.
-     *
-     * @param string $encoded The encoded value to decode
-     *
-     * @return integer The decoded value
-     */
-    public function decode($encoded)
-    {
-        $vlq = 0;
-        $i = 0;
-
-        do {
-            $digit = $this->base64Decode($encoded[$i]);
-            $vlq |= ($digit & $this->mask) << ($i * $this->shift);
-            $i++;
-        } while ($digit & $this->continuationBit);
-
-        return $this->fromVLQSigned($vlq);
-    }
-
-    /**
-     * Right shift with zero fill.
-     *
-     * @param integer $a number to shift
-     * @param integer $b number of bits to shift
-     *
-     * @return integer
-     */
-    public function zeroFill($a, $b)
-    {
-        return ($a >= 0) ? ($a >> $b) : ($a >> $b) & (PHP_INT_MAX >> ($b - 1));
-    }
-
-    /**
-     * Encode single 6-bit digit as base64.
-     *
-     * @param integer $number
-     *
-     * @return string
-     *
-     * @throws \Exception If the number is invalid
-     */
-    public function base64Encode($number)
-    {
-        if ($number < 0 || $number > 63) {
-            throw new \Exception(sprintf('Invalid number "%s" given. Must be between 0 and 63.', $number));
-        }
-
-        return $this->intToCharMap[$number];
-    }
-
-    /**
-     * Decode single 6-bit digit from base64
-     *
-     * @param string $char
-     *
-     * @return integer
-     *
-     * @throws \Exception If the number is invalid
-     */
-    public function base64Decode($char)
-    {
-        if (! array_key_exists($char, $this->charToIntMap)) {
-            throw new \Exception(sprintf('Invalid base 64 digit "%s" given.', $char));
-        }
-
-        return $this->charToIntMap[$char];
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/SourceMapGenerator.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/SourceMap/SourceMapGenerator.php
deleted file mode 100644 (file)
index 3c636a8..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp\SourceMap;
-
-use Leafo\ScssPhp\Exception\CompilerException;
-
-/**
- * Source Map Generator
- *
- * {@internal Derivative of oyejorge/less.php's lib/SourceMap/Generator.php, relicensed with permission. }}
- *
- * @author Josh Schmidt <oyejorge@gmail.com>
- * @author Nicolas FRANÇOIS <nicolas.francois@frog-labs.com>
- */
-class SourceMapGenerator
-{
-    /**
-     * What version of source map does the generator generate?
-     */
-    const VERSION = 3;
-
-    /**
-     * Array of default options
-     *
-     * @var array
-     */
-    protected $defaultOptions = [
-        // an optional source root, useful for relocating source files
-        // on a server or removing repeated values in the 'sources' entry.
-        // This value is prepended to the individual entries in the 'source' field.
-        'sourceRoot' => '',
-
-        // an optional name of the generated code that this source map is associated with.
-        'sourceMapFilename' => null,
-
-        // url of the map
-        'sourceMapURL' => null,
-
-        // absolute path to a file to write the map to
-        'sourceMapWriteTo' => null,
-
-        // output source contents?
-        'outputSourceFiles' => false,
-
-        // base path for filename normalization
-        'sourceMapRootpath' => '',
-
-        // base path for filename normalization
-        'sourceMapBasepath' => ''
-    ];
-
-    /**
-     * The base64 VLQ encoder
-     *
-     * @var \Leafo\ScssPhp\SourceMap\Base64VLQ
-     */
-    protected $encoder;
-
-    /**
-     * Array of mappings
-     *
-     * @var array
-     */
-    protected $mappings = [];
-
-    /**
-     * Array of contents map
-     *
-     * @var array
-     */
-    protected $contentsMap = [];
-
-    /**
-     * File to content map
-     *
-     * @var array
-     */
-    protected $sources = [];
-    protected $source_keys = [];
-
-    /**
-     * @var array
-     */
-    private $options;
-
-    public function __construct(array $options = [])
-    {
-        $this->options = array_merge($this->defaultOptions, $options);
-        $this->encoder = new Base64VLQ();
-    }
-
-    /**
-     * Adds a mapping
-     *
-     * @param integer $generatedLine   The line number in generated file
-     * @param integer $generatedColumn The column number in generated file
-     * @param integer $originalLine    The line number in original file
-     * @param integer $originalColumn  The column number in original file
-     * @param string  $sourceFile      The original source file
-     */
-    public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $sourceFile)
-    {
-        $this->mappings[] = [
-            'generated_line' => $generatedLine,
-            'generated_column' => $generatedColumn,
-            'original_line' => $originalLine,
-            'original_column' => $originalColumn,
-            'source_file' => $sourceFile
-        ];
-
-        $this->sources[$sourceFile] = $sourceFile;
-    }
-
-    /**
-     * Saves the source map to a file
-     *
-     * @param string $file    The absolute path to a file
-     * @param string $content The content to write
-     *
-     * @throws \Leafo\ScssPhp\Exception\CompilerException If the file could not be saved
-     */
-    public function saveMap($content)
-    {
-        $file = $this->options['sourceMapWriteTo'];
-        $dir  = dirname($file);
-
-        // directory does not exist
-        if (! is_dir($dir)) {
-            // FIXME: create the dir automatically?
-            throw new CompilerException(sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir));
-        }
-
-        // FIXME: proper saving, with dir write check!
-        if (file_put_contents($file, $content) === false) {
-            throw new CompilerException(sprintf('Cannot save the source map to "%s"', $file));
-        }
-
-        return $this->options['sourceMapURL'];
-    }
-
-    /**
-     * Generates the JSON source map
-     *
-     * @return string
-     *
-     * @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#
-     */
-    public function generateJson()
-    {
-        $sourceMap = [];
-        $mappings  = $this->generateMappings();
-
-        // File version (always the first entry in the object) and must be a positive integer.
-        $sourceMap['version'] = self::VERSION;
-
-        // An optional name of the generated code that this source map is associated with.
-        $file = $this->options['sourceMapFilename'];
-
-        if ($file) {
-            $sourceMap['file'] = $file;
-        }
-
-        // An optional source root, useful for relocating source files on a server or removing repeated values in the
-        // 'sources' entry. This value is prepended to the individual entries in the 'source' field.
-        $root = $this->options['sourceRoot'];
-
-        if ($root) {
-            $sourceMap['sourceRoot'] = $root;
-        }
-
-        // A list of original sources used by the 'mappings' entry.
-        $sourceMap['sources'] = [];
-
-        foreach ($this->sources as $source_uri => $source_filename) {
-            $sourceMap['sources'][] = $this->normalizeFilename($source_filename);
-        }
-
-        // A list of symbol names used by the 'mappings' entry.
-        $sourceMap['names'] = [];
-
-        // A string with the encoded mapping data.
-        $sourceMap['mappings'] = $mappings;
-
-        if ($this->options['outputSourceFiles']) {
-            // An optional list of source content, useful when the 'source' can't be hosted.
-            // The contents are listed in the same order as the sources above.
-            // 'null' may be used if some original sources should be retrieved by name.
-            $sourceMap['sourcesContent'] = $this->getSourcesContent();
-        }
-
-        // less.js compat fixes
-        if (count($sourceMap['sources']) && empty($sourceMap['sourceRoot'])) {
-            unset($sourceMap['sourceRoot']);
-        }
-
-        return json_encode($sourceMap, JSON_UNESCAPED_SLASHES);
-    }
-
-    /**
-     * Returns the sources contents
-     *
-     * @return array|null
-     */
-    protected function getSourcesContent()
-    {
-        if (empty($this->sources)) {
-            return null;
-        }
-
-        $content = [];
-
-        foreach ($this->sources as $sourceFile) {
-            $content[] = file_get_contents($sourceFile);
-        }
-
-        return $content;
-    }
-
-    /**
-     * Generates the mappings string
-     *
-     * @return string
-     */
-    public function generateMappings()
-    {
-        if (! count($this->mappings)) {
-            return '';
-        }
-
-        $this->source_keys = array_flip(array_keys($this->sources));
-
-        // group mappings by generated line number.
-        $groupedMap = $groupedMapEncoded = [];
-
-        foreach ($this->mappings as $m) {
-            $groupedMap[$m['generated_line']][] = $m;
-        }
-
-        ksort($groupedMap);
-        $lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0;
-
-        foreach ($groupedMap as $lineNumber => $line_map) {
-            while (++$lastGeneratedLine < $lineNumber) {
-                $groupedMapEncoded[] = ';';
-            }
-
-            $lineMapEncoded = [];
-            $lastGeneratedColumn = 0;
-
-            foreach ($line_map as $m) {
-                $mapEncoded = $this->encoder->encode($m['generated_column'] - $lastGeneratedColumn);
-                $lastGeneratedColumn = $m['generated_column'];
-
-                // find the index
-                if ($m['source_file']) {
-                    $index = $this->findFileIndex($m['source_file']);
-
-                    if ($index !== false) {
-                        $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex);
-                        $lastOriginalIndex = $index;
-                        // lines are stored 0-based in SourceMap spec version 3
-                        $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine);
-                        $lastOriginalLine = $m['original_line'] - 1;
-                        $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn);
-                        $lastOriginalColumn = $m['original_column'];
-                    }
-                }
-
-                $lineMapEncoded[] = $mapEncoded;
-            }
-
-            $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';';
-        }
-
-        return rtrim(implode($groupedMapEncoded), ';');
-    }
-
-    /**
-     * Finds the index for the filename
-     *
-     * @param string $filename
-     *
-     * @return integer|false
-     */
-    protected function findFileIndex($filename)
-    {
-        return $this->source_keys[$filename];
-    }
-
-    protected function normalizeFilename($filename)
-    {
-        $filename = $this->fixWindowsPath($filename);
-        $rootpath = $this->options['sourceMapRootpath'];
-        $basePath = $this->options['sourceMapBasepath'];
-
-        // "Trim" the 'sourceMapBasepath' from the output filename.
-        if (strlen($basePath) && strpos($filename, $basePath) === 0) {
-            $filename = substr($filename, strlen($basePath));
-        }
-
-        // Remove extra leading path separators.
-        if (strpos($filename, '\\') === 0 || strpos($filename, '/') === 0) {
-            $filename = substr($filename, 1);
-        }
-
-        return $rootpath . $filename;
-    }
-
-    /**
-     * Fix windows paths
-     *
-     * @param string  $path
-     * @param boolean $addEndSlash
-     *
-     * @return string
-     */
-    public function fixWindowsPath($path, $addEndSlash = false)
-    {
-        $slash = ($addEndSlash) ? '/' : '';
-
-        if (! empty($path)) {
-            $path = str_replace('\\', '/', $path);
-            $path = rtrim($path, '/') . $slash;
-        }
-
-        return $path;
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Type.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Type.php
deleted file mode 100644 (file)
index e84c47e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-/**
- * Block/node types
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Type
-{
-    const T_ASSIGN = 'assign';
-    const T_AT_ROOT = 'at-root';
-    const T_BLOCK = 'block';
-    const T_BREAK = 'break';
-    const T_CHARSET = 'charset';
-    const T_COLOR = 'color';
-    const T_COMMENT = 'comment';
-    const T_CONTINUE = 'continue';
-    const T_CONTROL = 'control';
-    const T_DEBUG = 'debug';
-    const T_DIRECTIVE = 'directive';
-    const T_EACH = 'each';
-    const T_ELSE = 'else';
-    const T_ELSEIF = 'elseif';
-    const T_ERROR = 'error';
-    const T_EXPRESSION = 'exp';
-    const T_EXTEND = 'extend';
-    const T_FOR = 'for';
-    const T_FUNCTION = 'function';
-    const T_FUNCTION_CALL = 'fncall';
-    const T_HSL = 'hsl';
-    const T_IF = 'if';
-    const T_IMPORT = 'import';
-    const T_INCLUDE = 'include';
-    const T_INTERPOLATE = 'interpolate';
-    const T_INTERPOLATED = 'interpolated';
-    const T_KEYWORD = 'keyword';
-    const T_LIST = 'list';
-    const T_MAP = 'map';
-    const T_MEDIA = 'media';
-    const T_MEDIA_EXPRESSION = 'mediaExp';
-    const T_MEDIA_TYPE = 'mediaType';
-    const T_MEDIA_VALUE = 'mediaValue';
-    const T_MIXIN = 'mixin';
-    const T_MIXIN_CONTENT = 'mixin_content';
-    const T_NESTED_PROPERTY = 'nestedprop';
-    const T_NOT = 'not';
-    const T_NULL = 'null';
-    const T_NUMBER = 'number';
-    const T_RETURN = 'return';
-    const T_ROOT = 'root';
-    const T_SCSSPHP_IMPORT_ONCE = 'scssphp-import-once';
-    const T_SELF = 'self';
-    const T_STRING = 'string';
-    const T_UNARY = 'unary';
-    const T_VARIABLE = 'var';
-    const T_WARN = 'warn';
-    const T_WHILE = 'while';
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Util.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Util.php
deleted file mode 100644 (file)
index a1e5065..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-use Leafo\ScssPhp\Base\Range;
-use Leafo\ScssPhp\Exception\RangeException;
-
-/**
- * Utilty functions
- *
- * @author Anthon Pang <anthon.pang@gmail.com>
- */
-class Util
-{
-    /**
-     * Asserts that `value` falls within `range` (inclusive), leaving
-     * room for slight floating-point errors.
-     *
-     * @param string                    $name  The name of the value. Used in the error message.
-     * @param \Leafo\ScssPhp\Base\Range $range Range of values.
-     * @param array                     $value The value to check.
-     * @param string                    $unit  The unit of the value. Used in error reporting.
-     *
-     * @return mixed `value` adjusted to fall within range, if it was outside by a floating-point margin.
-     *
-     * @throws \Leafo\ScssPhp\Exception\RangeException
-     */
-    public static function checkRange($name, Range $range, $value, $unit = '')
-    {
-        $val = $value[1];
-        $grace = new Range(-0.00001, 0.00001);
-
-        if ($range->includes($val)) {
-            return $val;
-        }
-
-        if ($grace->includes($val - $range->first)) {
-            return $range->first;
-        }
-
-        if ($grace->includes($val - $range->last)) {
-            return $range->last;
-        }
-
-        throw new RangeException("$name {$val} must be between {$range->first} and {$range->last}$unit");
-    }
-
-    /**
-     * Encode URI component
-     *
-     * @param string $string
-     *
-     * @return string
-     */
-    public static function encodeURIComponent($string)
-    {
-        $revert = ['%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')'];
-
-        return strtr(rawurlencode($string), $revert);
-    }
-}
diff --git a/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Version.php b/wcfsetup/install/files/lib/system/api/leafo/scssphp/src/Version.php
deleted file mode 100644 (file)
index ec0fee6..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-/**
- * SCSSPHP
- *
- * @copyright 2012-2018 Leaf Corcoran
- *
- * @license http://opensource.org/licenses/MIT MIT
- *
- * @link http://leafo.github.io/scssphp
- */
-
-namespace Leafo\ScssPhp;
-
-/**
- * SCSSPHP version
- *
- * @author Leaf Corcoran <leafot@gmail.com>
- */
-class Version
-{
-    const VERSION = 'v0.7.8';
-}
index ce33ed1c805c22514ca13a5927f26cf32d4ecf44..b923cf7181bd02a987e685988a26185d0c5d4aff 100644 (file)
@@ -21,9 +21,7 @@
         "php": ">=4.4.0"
     },
     "autoload": {
-        "psr-0": {
-            "PEAR": ""
-        }
+        "classmap": ["PEAR/"]
     },
     "extra": {
         "branch-alias": {
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/CHANGELOG.md b/wcfsetup/install/files/lib/system/api/psr/http-message/CHANGELOG.md
new file mode 100644 (file)
index 0000000..74b1ef9
--- /dev/null
@@ -0,0 +1,36 @@
+# Changelog
+
+All notable changes to this project will be documented in this file, in reverse chronological order by release.
+
+## 1.0.1 - 2016-08-06
+
+### Added
+
+- Nothing.
+
+### Deprecated
+
+- Nothing.
+
+### Removed
+
+- Nothing.
+
+### Fixed
+
+- Updated all `@return self` annotation references in interfaces to use
+  `@return static`, which more closelly follows the semantics of the
+  specification.
+- Updated the `MessageInterface::getHeaders()` return annotation to use the
+  value `string[][]`, indicating the format is a nested array of strings.
+- Updated the `@link` annotation for `RequestInterface::withRequestTarget()`
+  to point to the correct section of RFC 7230.
+- Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation
+  to add the parameter name (`$uploadedFiles`).
+- Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()`
+  method to correctly reference the method parameter (it was referencing an
+  incorrect parameter name previously).
+
+## 1.0.0 - 2016-05-18
+
+Initial stable release; reflects accepted PSR-7 specification.
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/LICENSE b/wcfsetup/install/files/lib/system/api/psr/http-message/LICENSE
new file mode 100644 (file)
index 0000000..c2d8e45
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2014 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/README.md b/wcfsetup/install/files/lib/system/api/psr/http-message/README.md
new file mode 100644 (file)
index 0000000..2818533
--- /dev/null
@@ -0,0 +1,13 @@
+PSR Http Message
+================
+
+This repository holds all interfaces/classes/traits related to
+[PSR-7](http://www.php-fig.org/psr/psr-7/).
+
+Note that this is not a HTTP message implementation of its own. It is merely an
+interface that describes a HTTP message. See the specification for more details.
+
+Usage
+-----
+
+We'll certainly need some stuff in here.
\ No newline at end of file
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/composer.json b/wcfsetup/install/files/lib/system/api/psr/http-message/composer.json
new file mode 100644 (file)
index 0000000..b0d2937
--- /dev/null
@@ -0,0 +1,26 @@
+{
+    "name": "psr/http-message",
+    "description": "Common interface for HTTP messages",
+    "keywords": ["psr", "psr-7", "http", "http-message", "request", "response"],
+    "homepage": "https://github.com/php-fig/http-message",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "http://www.php-fig.org/"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Psr\\Http\\Message\\": "src/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0.x-dev"
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/MessageInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/MessageInterface.php
new file mode 100644 (file)
index 0000000..dd46e5e
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * HTTP messages consist of requests from a client to a server and responses
+ * from a server to a client. This interface defines the methods common to
+ * each.
+ *
+ * Messages are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ *
+ * @link http://www.ietf.org/rfc/rfc7230.txt
+ * @link http://www.ietf.org/rfc/rfc7231.txt
+ */
+interface MessageInterface
+{
+    /**
+     * Retrieves the HTTP protocol version as a string.
+     *
+     * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
+     *
+     * @return string HTTP protocol version.
+     */
+    public function getProtocolVersion();
+
+    /**
+     * Return an instance with the specified HTTP protocol version.
+     *
+     * The version string MUST contain only the HTTP version number (e.g.,
+     * "1.1", "1.0").
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * new protocol version.
+     *
+     * @param string $version HTTP protocol version
+     * @return static
+     */
+    public function withProtocolVersion($version);
+
+    /**
+     * Retrieves all message header values.
+     *
+     * The keys represent the header name as it will be sent over the wire, and
+     * each value is an array of strings associated with the header.
+     *
+     *     // Represent the headers as a string
+     *     foreach ($message->getHeaders() as $name => $values) {
+     *         echo $name . ": " . implode(", ", $values);
+     *     }
+     *
+     *     // Emit headers iteratively:
+     *     foreach ($message->getHeaders() as $name => $values) {
+     *         foreach ($values as $value) {
+     *             header(sprintf('%s: %s', $name, $value), false);
+     *         }
+     *     }
+     *
+     * While header names are not case-sensitive, getHeaders() will preserve the
+     * exact case in which headers were originally specified.
+     *
+     * @return string[][] Returns an associative array of the message's headers. Each
+     *     key MUST be a header name, and each value MUST be an array of strings
+     *     for that header.
+     */
+    public function getHeaders();
+
+    /**
+     * Checks if a header exists by the given case-insensitive name.
+     *
+     * @param string $name Case-insensitive header field name.
+     * @return bool Returns true if any header names match the given header
+     *     name using a case-insensitive string comparison. Returns false if
+     *     no matching header name is found in the message.
+     */
+    public function hasHeader($name);
+
+    /**
+     * Retrieves a message header value by the given case-insensitive name.
+     *
+     * This method returns an array of all the header values of the given
+     * case-insensitive header name.
+     *
+     * If the header does not appear in the message, this method MUST return an
+     * empty array.
+     *
+     * @param string $name Case-insensitive header field name.
+     * @return string[] An array of string values as provided for the given
+     *    header. If the header does not appear in the message, this method MUST
+     *    return an empty array.
+     */
+    public function getHeader($name);
+
+    /**
+     * Retrieves a comma-separated string of the values for a single header.
+     *
+     * This method returns all of the header values of the given
+     * case-insensitive header name as a string concatenated together using
+     * a comma.
+     *
+     * NOTE: Not all header values may be appropriately represented using
+     * comma concatenation. For such headers, use getHeader() instead
+     * and supply your own delimiter when concatenating.
+     *
+     * If the header does not appear in the message, this method MUST return
+     * an empty string.
+     *
+     * @param string $name Case-insensitive header field name.
+     * @return string A string of values as provided for the given header
+     *    concatenated together using a comma. If the header does not appear in
+     *    the message, this method MUST return an empty string.
+     */
+    public function getHeaderLine($name);
+
+    /**
+     * Return an instance with the provided value replacing the specified header.
+     *
+     * While header names are case-insensitive, the casing of the header will
+     * be preserved by this function, and returned from getHeaders().
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * new and/or updated header and value.
+     *
+     * @param string $name Case-insensitive header field name.
+     * @param string|string[] $value Header value(s).
+     * @return static
+     * @throws \InvalidArgumentException for invalid header names or values.
+     */
+    public function withHeader($name, $value);
+
+    /**
+     * Return an instance with the specified header appended with the given value.
+     *
+     * Existing values for the specified header will be maintained. The new
+     * value(s) will be appended to the existing list. If the header did not
+     * exist previously, it will be added.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * new header and/or value.
+     *
+     * @param string $name Case-insensitive header field name to add.
+     * @param string|string[] $value Header value(s).
+     * @return static
+     * @throws \InvalidArgumentException for invalid header names or values.
+     */
+    public function withAddedHeader($name, $value);
+
+    /**
+     * Return an instance without the specified header.
+     *
+     * Header resolution MUST be done without case-sensitivity.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that removes
+     * the named header.
+     *
+     * @param string $name Case-insensitive header field name to remove.
+     * @return static
+     */
+    public function withoutHeader($name);
+
+    /**
+     * Gets the body of the message.
+     *
+     * @return StreamInterface Returns the body as a stream.
+     */
+    public function getBody();
+
+    /**
+     * Return an instance with the specified message body.
+     *
+     * The body MUST be a StreamInterface object.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return a new instance that has the
+     * new body stream.
+     *
+     * @param StreamInterface $body Body.
+     * @return static
+     * @throws \InvalidArgumentException When the body is not valid.
+     */
+    public function withBody(StreamInterface $body);
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/RequestInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/RequestInterface.php
new file mode 100644 (file)
index 0000000..a96d4fd
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an outgoing, client-side request.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - HTTP method
+ * - URI
+ * - Headers
+ * - Message body
+ *
+ * During construction, implementations MUST attempt to set the Host header from
+ * a provided URI if no Host header is provided.
+ *
+ * Requests are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface RequestInterface extends MessageInterface
+{
+    /**
+     * Retrieves the message's request target.
+     *
+     * Retrieves the message's request-target either as it will appear (for
+     * clients), as it appeared at request (for servers), or as it was
+     * specified for the instance (see withRequestTarget()).
+     *
+     * In most cases, this will be the origin-form of the composed URI,
+     * unless a value was provided to the concrete implementation (see
+     * withRequestTarget() below).
+     *
+     * If no URI is available, and no request-target has been specifically
+     * provided, this method MUST return the string "/".
+     *
+     * @return string
+     */
+    public function getRequestTarget();
+
+    /**
+     * Return an instance with the specific request-target.
+     *
+     * If the request needs a non-origin-form request-target — e.g., for
+     * specifying an absolute-form, authority-form, or asterisk-form —
+     * this method may be used to create an instance with the specified
+     * request-target, verbatim.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * changed request target.
+     *
+     * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
+     *     request-target forms allowed in request messages)
+     * @param mixed $requestTarget
+     * @return static
+     */
+    public function withRequestTarget($requestTarget);
+
+    /**
+     * Retrieves the HTTP method of the request.
+     *
+     * @return string Returns the request method.
+     */
+    public function getMethod();
+
+    /**
+     * Return an instance with the provided HTTP method.
+     *
+     * While HTTP method names are typically all uppercase characters, HTTP
+     * method names are case-sensitive and thus implementations SHOULD NOT
+     * modify the given string.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * changed request method.
+     *
+     * @param string $method Case-sensitive method.
+     * @return static
+     * @throws \InvalidArgumentException for invalid HTTP methods.
+     */
+    public function withMethod($method);
+
+    /**
+     * Retrieves the URI instance.
+     *
+     * This method MUST return a UriInterface instance.
+     *
+     * @link http://tools.ietf.org/html/rfc3986#section-4.3
+     * @return UriInterface Returns a UriInterface instance
+     *     representing the URI of the request.
+     */
+    public function getUri();
+
+    /**
+     * Returns an instance with the provided URI.
+     *
+     * This method MUST update the Host header of the returned request by
+     * default if the URI contains a host component. If the URI does not
+     * contain a host component, any pre-existing Host header MUST be carried
+     * over to the returned request.
+     *
+     * You can opt-in to preserving the original state of the Host header by
+     * setting `$preserveHost` to `true`. When `$preserveHost` is set to
+     * `true`, this method interacts with the Host header in the following ways:
+     *
+     * - If the Host header is missing or empty, and the new URI contains
+     *   a host component, this method MUST update the Host header in the returned
+     *   request.
+     * - If the Host header is missing or empty, and the new URI does not contain a
+     *   host component, this method MUST NOT update the Host header in the returned
+     *   request.
+     * - If a Host header is present and non-empty, this method MUST NOT update
+     *   the Host header in the returned request.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * new UriInterface instance.
+     *
+     * @link http://tools.ietf.org/html/rfc3986#section-4.3
+     * @param UriInterface $uri New request URI to use.
+     * @param bool $preserveHost Preserve the original state of the Host header.
+     * @return static
+     */
+    public function withUri(UriInterface $uri, $preserveHost = false);
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/ResponseInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/ResponseInterface.php
new file mode 100644 (file)
index 0000000..c306514
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an outgoing, server-side response.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - Status code and reason phrase
+ * - Headers
+ * - Message body
+ *
+ * Responses are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface ResponseInterface extends MessageInterface
+{
+    /**
+     * Gets the response status code.
+     *
+     * The status code is a 3-digit integer result code of the server's attempt
+     * to understand and satisfy the request.
+     *
+     * @return int Status code.
+     */
+    public function getStatusCode();
+
+    /**
+     * Return an instance with the specified status code and, optionally, reason phrase.
+     *
+     * If no reason phrase is specified, implementations MAY choose to default
+     * to the RFC 7231 or IANA recommended reason phrase for the response's
+     * status code.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * updated status and reason phrase.
+     *
+     * @link http://tools.ietf.org/html/rfc7231#section-6
+     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+     * @param int $code The 3-digit integer result code to set.
+     * @param string $reasonPhrase The reason phrase to use with the
+     *     provided status code; if none is provided, implementations MAY
+     *     use the defaults as suggested in the HTTP specification.
+     * @return static
+     * @throws \InvalidArgumentException For invalid status code arguments.
+     */
+    public function withStatus($code, $reasonPhrase = '');
+
+    /**
+     * Gets the response reason phrase associated with the status code.
+     *
+     * Because a reason phrase is not a required element in a response
+     * status line, the reason phrase value MAY be null. Implementations MAY
+     * choose to return the default RFC 7231 recommended reason phrase (or those
+     * listed in the IANA HTTP Status Code Registry) for the response's
+     * status code.
+     *
+     * @link http://tools.ietf.org/html/rfc7231#section-6
+     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+     * @return string Reason phrase; must return an empty string if none present.
+     */
+    public function getReasonPhrase();
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/ServerRequestInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/ServerRequestInterface.php
new file mode 100644 (file)
index 0000000..0251234
--- /dev/null
@@ -0,0 +1,261 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an incoming, server-side HTTP request.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - HTTP method
+ * - URI
+ * - Headers
+ * - Message body
+ *
+ * Additionally, it encapsulates all data as it has arrived to the
+ * application from the CGI and/or PHP environment, including:
+ *
+ * - The values represented in $_SERVER.
+ * - Any cookies provided (generally via $_COOKIE)
+ * - Query string arguments (generally via $_GET, or as parsed via parse_str())
+ * - Upload files, if any (as represented by $_FILES)
+ * - Deserialized body parameters (generally from $_POST)
+ *
+ * $_SERVER values MUST be treated as immutable, as they represent application
+ * state at the time of request; as such, no methods are provided to allow
+ * modification of those values. The other values provide such methods, as they
+ * can be restored from $_SERVER or the request body, and may need treatment
+ * during the application (e.g., body parameters may be deserialized based on
+ * content type).
+ *
+ * Additionally, this interface recognizes the utility of introspecting a
+ * request to derive and match additional parameters (e.g., via URI path
+ * matching, decrypting cookie values, deserializing non-form-encoded body
+ * content, matching authorization headers to users, etc). These parameters
+ * are stored in an "attributes" property.
+ *
+ * Requests are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface ServerRequestInterface extends RequestInterface
+{
+    /**
+     * Retrieve server parameters.
+     *
+     * Retrieves data related to the incoming request environment,
+     * typically derived from PHP's $_SERVER superglobal. The data IS NOT
+     * REQUIRED to originate from $_SERVER.
+     *
+     * @return array
+     */
+    public function getServerParams();
+
+    /**
+     * Retrieve cookies.
+     *
+     * Retrieves cookies sent by the client to the server.
+     *
+     * The data MUST be compatible with the structure of the $_COOKIE
+     * superglobal.
+     *
+     * @return array
+     */
+    public function getCookieParams();
+
+    /**
+     * Return an instance with the specified cookies.
+     *
+     * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
+     * be compatible with the structure of $_COOKIE. Typically, this data will
+     * be injected at instantiation.
+     *
+     * This method MUST NOT update the related Cookie header of the request
+     * instance, nor related values in the server params.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * updated cookie values.
+     *
+     * @param array $cookies Array of key/value pairs representing cookies.
+     * @return static
+     */
+    public function withCookieParams(array $cookies);
+
+    /**
+     * Retrieve query string arguments.
+     *
+     * Retrieves the deserialized query string arguments, if any.
+     *
+     * Note: the query params might not be in sync with the URI or server
+     * params. If you need to ensure you are only getting the original
+     * values, you may need to parse the query string from `getUri()->getQuery()`
+     * or from the `QUERY_STRING` server param.
+     *
+     * @return array
+     */
+    public function getQueryParams();
+
+    /**
+     * Return an instance with the specified query string arguments.
+     *
+     * These values SHOULD remain immutable over the course of the incoming
+     * request. They MAY be injected during instantiation, such as from PHP's
+     * $_GET superglobal, or MAY be derived from some other value such as the
+     * URI. In cases where the arguments are parsed from the URI, the data
+     * MUST be compatible with what PHP's parse_str() would return for
+     * purposes of how duplicate query parameters are handled, and how nested
+     * sets are handled.
+     *
+     * Setting query string arguments MUST NOT change the URI stored by the
+     * request, nor the values in the server params.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * updated query string arguments.
+     *
+     * @param array $query Array of query string arguments, typically from
+     *     $_GET.
+     * @return static
+     */
+    public function withQueryParams(array $query);
+
+    /**
+     * Retrieve normalized file upload data.
+     *
+     * This method returns upload metadata in a normalized tree, with each leaf
+     * an instance of Psr\Http\Message\UploadedFileInterface.
+     *
+     * These values MAY be prepared from $_FILES or the message body during
+     * instantiation, or MAY be injected via withUploadedFiles().
+     *
+     * @return array An array tree of UploadedFileInterface instances; an empty
+     *     array MUST be returned if no data is present.
+     */
+    public function getUploadedFiles();
+
+    /**
+     * Create a new instance with the specified uploaded files.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * updated body parameters.
+     *
+     * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
+     * @return static
+     * @throws \InvalidArgumentException if an invalid structure is provided.
+     */
+    public function withUploadedFiles(array $uploadedFiles);
+
+    /**
+     * Retrieve any parameters provided in the request body.
+     *
+     * If the request Content-Type is either application/x-www-form-urlencoded
+     * or multipart/form-data, and the request method is POST, this method MUST
+     * return the contents of $_POST.
+     *
+     * Otherwise, this method may return any results of deserializing
+     * the request body content; as parsing returns structured content, the
+     * potential types MUST be arrays or objects only. A null value indicates
+     * the absence of body content.
+     *
+     * @return null|array|object The deserialized body parameters, if any.
+     *     These will typically be an array or object.
+     */
+    public function getParsedBody();
+
+    /**
+     * Return an instance with the specified body parameters.
+     *
+     * These MAY be injected during instantiation.
+     *
+     * If the request Content-Type is either application/x-www-form-urlencoded
+     * or multipart/form-data, and the request method is POST, use this method
+     * ONLY to inject the contents of $_POST.
+     *
+     * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
+     * deserializing the request body content. Deserialization/parsing returns
+     * structured data, and, as such, this method ONLY accepts arrays or objects,
+     * or a null value if nothing was available to parse.
+     *
+     * As an example, if content negotiation determines that the request data
+     * is a JSON payload, this method could be used to create a request
+     * instance with the deserialized parameters.
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * updated body parameters.
+     *
+     * @param null|array|object $data The deserialized body data. This will
+     *     typically be in an array or object.
+     * @return static
+     * @throws \InvalidArgumentException if an unsupported argument type is
+     *     provided.
+     */
+    public function withParsedBody($data);
+
+    /**
+     * Retrieve attributes derived from the request.
+     *
+     * The request "attributes" may be used to allow injection of any
+     * parameters derived from the request: e.g., the results of path
+     * match operations; the results of decrypting cookies; the results of
+     * deserializing non-form-encoded message bodies; etc. Attributes
+     * will be application and request specific, and CAN be mutable.
+     *
+     * @return array Attributes derived from the request.
+     */
+    public function getAttributes();
+
+    /**
+     * Retrieve a single derived request attribute.
+     *
+     * Retrieves a single derived request attribute as described in
+     * getAttributes(). If the attribute has not been previously set, returns
+     * the default value as provided.
+     *
+     * This method obviates the need for a hasAttribute() method, as it allows
+     * specifying a default value to return if the attribute is not found.
+     *
+     * @see getAttributes()
+     * @param string $name The attribute name.
+     * @param mixed $default Default value to return if the attribute does not exist.
+     * @return mixed
+     */
+    public function getAttribute($name, $default = null);
+
+    /**
+     * Return an instance with the specified derived request attribute.
+     *
+     * This method allows setting a single derived request attribute as
+     * described in getAttributes().
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that has the
+     * updated attribute.
+     *
+     * @see getAttributes()
+     * @param string $name The attribute name.
+     * @param mixed $value The value of the attribute.
+     * @return static
+     */
+    public function withAttribute($name, $value);
+
+    /**
+     * Return an instance that removes the specified derived request attribute.
+     *
+     * This method allows removing a single derived request attribute as
+     * described in getAttributes().
+     *
+     * This method MUST be implemented in such a way as to retain the
+     * immutability of the message, and MUST return an instance that removes
+     * the attribute.
+     *
+     * @see getAttributes()
+     * @param string $name The attribute name.
+     * @return static
+     */
+    public function withoutAttribute($name);
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/StreamInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/StreamInterface.php
new file mode 100644 (file)
index 0000000..f68f391
--- /dev/null
@@ -0,0 +1,158 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Describes a data stream.
+ *
+ * Typically, an instance will wrap a PHP stream; this interface provides
+ * a wrapper around the most common operations, including serialization of
+ * the entire stream to a string.
+ */
+interface StreamInterface
+{
+    /**
+     * Reads all data from the stream into a string, from the beginning to end.
+     *
+     * This method MUST attempt to seek to the beginning of the stream before
+     * reading data and read the stream until the end is reached.
+     *
+     * Warning: This could attempt to load a large amount of data into memory.
+     *
+     * This method MUST NOT raise an exception in order to conform with PHP's
+     * string casting operations.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
+     * @return string
+     */
+    public function __toString();
+
+    /**
+     * Closes the stream and any underlying resources.
+     *
+     * @return void
+     */
+    public function close();
+
+    /**
+     * Separates any underlying resources from the stream.
+     *
+     * After the stream has been detached, the stream is in an unusable state.
+     *
+     * @return resource|null Underlying PHP stream, if any
+     */
+    public function detach();
+
+    /**
+     * Get the size of the stream if known.
+     *
+     * @return int|null Returns the size in bytes if known, or null if unknown.
+     */
+    public function getSize();
+
+    /**
+     * Returns the current position of the file read/write pointer
+     *
+     * @return int Position of the file pointer
+     * @throws \RuntimeException on error.
+     */
+    public function tell();
+
+    /**
+     * Returns true if the stream is at the end of the stream.
+     *
+     * @return bool
+     */
+    public function eof();
+
+    /**
+     * Returns whether or not the stream is seekable.
+     *
+     * @return bool
+     */
+    public function isSeekable();
+
+    /**
+     * Seek to a position in the stream.
+     *
+     * @link http://www.php.net/manual/en/function.fseek.php
+     * @param int $offset Stream offset
+     * @param int $whence Specifies how the cursor position will be calculated
+     *     based on the seek offset. Valid values are identical to the built-in
+     *     PHP $whence values for `fseek()`.  SEEK_SET: Set position equal to
+     *     offset bytes SEEK_CUR: Set position to current location plus offset
+     *     SEEK_END: Set position to end-of-stream plus offset.
+     * @throws \RuntimeException on failure.
+     */
+    public function seek($offset, $whence = SEEK_SET);
+
+    /**
+     * Seek to the beginning of the stream.
+     *
+     * If the stream is not seekable, this method will raise an exception;
+     * otherwise, it will perform a seek(0).
+     *
+     * @see seek()
+     * @link http://www.php.net/manual/en/function.fseek.php
+     * @throws \RuntimeException on failure.
+     */
+    public function rewind();
+
+    /**
+     * Returns whether or not the stream is writable.
+     *
+     * @return bool
+     */
+    public function isWritable();
+
+    /**
+     * Write data to the stream.
+     *
+     * @param string $string The string that is to be written.
+     * @return int Returns the number of bytes written to the stream.
+     * @throws \RuntimeException on failure.
+     */
+    public function write($string);
+
+    /**
+     * Returns whether or not the stream is readable.
+     *
+     * @return bool
+     */
+    public function isReadable();
+
+    /**
+     * Read data from the stream.
+     *
+     * @param int $length Read up to $length bytes from the object and return
+     *     them. Fewer than $length bytes may be returned if underlying stream
+     *     call returns fewer bytes.
+     * @return string Returns the data read from the stream, or an empty string
+     *     if no bytes are available.
+     * @throws \RuntimeException if an error occurs.
+     */
+    public function read($length);
+
+    /**
+     * Returns the remaining contents in a string
+     *
+     * @return string
+     * @throws \RuntimeException if unable to read or an error occurs while
+     *     reading.
+     */
+    public function getContents();
+
+    /**
+     * Get stream metadata as an associative array or retrieve a specific key.
+     *
+     * The keys returned are identical to the keys returned from PHP's
+     * stream_get_meta_data() function.
+     *
+     * @link http://php.net/manual/en/function.stream-get-meta-data.php
+     * @param string $key Specific metadata to retrieve.
+     * @return array|mixed|null Returns an associative array if no key is
+     *     provided. Returns a specific key value if a key is provided and the
+     *     value is found, or null if the key is not found.
+     */
+    public function getMetadata($key = null);
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/UploadedFileInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/UploadedFileInterface.php
new file mode 100644 (file)
index 0000000..f8a6901
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Value object representing a file uploaded through an HTTP request.
+ *
+ * Instances of this interface are considered immutable; all methods that
+ * might change state MUST be implemented such that they retain the internal
+ * state of the current instance and return an instance that contains the
+ * changed state.
+ */
+interface UploadedFileInterface
+{
+    /**
+     * Retrieve a stream representing the uploaded file.
+     *
+     * This method MUST return a StreamInterface instance, representing the
+     * uploaded file. The purpose of this method is to allow utilizing native PHP
+     * stream functionality to manipulate the file upload, such as
+     * stream_copy_to_stream() (though the result will need to be decorated in a
+     * native PHP stream wrapper to work with such functions).
+     *
+     * If the moveTo() method has been called previously, this method MUST raise
+     * an exception.
+     *
+     * @return StreamInterface Stream representation of the uploaded file.
+     * @throws \RuntimeException in cases when no stream is available or can be
+     *     created.
+     */
+    public function getStream();
+
+    /**
+     * Move the uploaded file to a new location.
+     *
+     * Use this method as an alternative to move_uploaded_file(). This method is
+     * guaranteed to work in both SAPI and non-SAPI environments.
+     * Implementations must determine which environment they are in, and use the
+     * appropriate method (move_uploaded_file(), rename(), or a stream
+     * operation) to perform the operation.
+     *
+     * $targetPath may be an absolute path, or a relative path. If it is a
+     * relative path, resolution should be the same as used by PHP's rename()
+     * function.
+     *
+     * The original file or stream MUST be removed on completion.
+     *
+     * If this method is called more than once, any subsequent calls MUST raise
+     * an exception.
+     *
+     * When used in an SAPI environment where $_FILES is populated, when writing
+     * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
+     * used to ensure permissions and upload status are verified correctly.
+     *
+     * If you wish to move to a stream, use getStream(), as SAPI operations
+     * cannot guarantee writing to stream destinations.
+     *
+     * @see http://php.net/is_uploaded_file
+     * @see http://php.net/move_uploaded_file
+     * @param string $targetPath Path to which to move the uploaded file.
+     * @throws \InvalidArgumentException if the $targetPath specified is invalid.
+     * @throws \RuntimeException on any error during the move operation, or on
+     *     the second or subsequent call to the method.
+     */
+    public function moveTo($targetPath);
+    
+    /**
+     * Retrieve the file size.
+     *
+     * Implementations SHOULD return the value stored in the "size" key of
+     * the file in the $_FILES array if available, as PHP calculates this based
+     * on the actual size transmitted.
+     *
+     * @return int|null The file size in bytes or null if unknown.
+     */
+    public function getSize();
+    
+    /**
+     * Retrieve the error associated with the uploaded file.
+     *
+     * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
+     *
+     * If the file was uploaded successfully, this method MUST return
+     * UPLOAD_ERR_OK.
+     *
+     * Implementations SHOULD return the value stored in the "error" key of
+     * the file in the $_FILES array.
+     *
+     * @see http://php.net/manual/en/features.file-upload.errors.php
+     * @return int One of PHP's UPLOAD_ERR_XXX constants.
+     */
+    public function getError();
+    
+    /**
+     * Retrieve the filename sent by the client.
+     *
+     * Do not trust the value returned by this method. A client could send
+     * a malicious filename with the intention to corrupt or hack your
+     * application.
+     *
+     * Implementations SHOULD return the value stored in the "name" key of
+     * the file in the $_FILES array.
+     *
+     * @return string|null The filename sent by the client or null if none
+     *     was provided.
+     */
+    public function getClientFilename();
+    
+    /**
+     * Retrieve the media type sent by the client.
+     *
+     * Do not trust the value returned by this method. A client could send
+     * a malicious media type with the intention to corrupt or hack your
+     * application.
+     *
+     * Implementations SHOULD return the value stored in the "type" key of
+     * the file in the $_FILES array.
+     *
+     * @return string|null The media type sent by the client or null if none
+     *     was provided.
+     */
+    public function getClientMediaType();
+}
diff --git a/wcfsetup/install/files/lib/system/api/psr/http-message/src/UriInterface.php b/wcfsetup/install/files/lib/system/api/psr/http-message/src/UriInterface.php
new file mode 100644 (file)
index 0000000..9d7ab9e
--- /dev/null
@@ -0,0 +1,323 @@
+<?php
+namespace Psr\Http\Message;
+
+/**
+ * Value object representing a URI.
+ *
+ * This interface is meant to represent URIs according to RFC 3986 and to
+ * provide methods for most common operations. Additional functionality for
+ * working with URIs can be provided on top of the interface or externally.
+ * Its primary use is for HTTP requests, but may also be used in other
+ * contexts.
+ *
+ * Instances of this interface are considered immutable; all methods that
+ * might change state MUST be implemented such that they retain the internal
+ * state of the current instance and return an instance that contains the
+ * changed state.
+ *
+ * Typically the Host header will be also be present in the request message.
+ * For server-side requests, the scheme will typically be discoverable in the
+ * server parameters.
+ *
+ * @link http://tools.ietf.org/html/rfc3986 (the URI specification)
+ */
+interface UriInterface
+{
+    /**
+     * Retrieve the scheme component of the URI.
+     *
+     * If no scheme is present, this method MUST return an empty string.
+     *
+     * The value returned MUST be normalized to lowercase, per RFC 3986
+     * Section 3.1.
+     *
+     * The trailing ":" character is not part of the scheme and MUST NOT be
+     * added.
+     *
+     * @see https://tools.ietf.org/html/rfc3986#section-3.1
+     * @return string The URI scheme.
+     */
+    public function getScheme();
+
+    /**
+     * Retrieve the authority component of the URI.
+     *
+     * If no authority information is present, this method MUST return an empty
+     * string.
+     *
+     * The authority syntax of the URI is:
+     *
+     * <pre>
+     * [user-info@]host[:port]
+     * </pre>
+     *
+     * If the port component is not set or is the standard port for the current
+     * scheme, it SHOULD NOT be included.
+     *
+     * @see https://tools.ietf.org/html/rfc3986#section-3.2
+     * @return string The URI authority, in "[user-info@]host[:port]" format.
+     */
+    public function getAuthority();
+
+    /**
+     * Retrieve the user information component of the URI.
+     *
+     * If no user information is present, this method MUST return an empty
+     * string.
+     *
+     * If a user is present in the URI, this will return that value;
+     * additionally, if the password is also present, it will be appended to the
+     * user value, with a colon (":") separating the values.
+     *
+     * The trailing "@" character is not part of the user information and MUST
+     * NOT be added.
+     *
+     * @return string The URI user information, in "username[:password]" format.
+     */
+    public function getUserInfo();
+
+    /**
+     * Retrieve the host component of the URI.
+     *
+     * If no host is present, this method MUST return an empty string.
+     *
+     * The value returned MUST be normalized to lowercase, per RFC 3986
+     * Section 3.2.2.
+     *
+     * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
+     * @return string The URI host.
+     */
+    public function getHost();
+
+    /**
+     * Retrieve the port component of the URI.
+     *
+     * If a port is present, and it is non-standard for the current scheme,
+     * this method MUST return it as an integer. If the port is the standard port
+     * used with the current scheme, this method SHOULD return null.
+     *
+     * If no port is present, and no scheme is present, this method MUST return
+     * a null value.
+     *
+     * If no port is present, but a scheme is present, this method MAY return
+     * the standard port for that scheme, but SHOULD return null.
+     *
+     * @return null|int The URI port.
+     */
+    public function getPort();
+
+    /**
+     * Retrieve the path component of the URI.
+     *
+     * The path can either be empty or absolute (starting with a slash) or
+     * rootless (not starting with a slash). Implementations MUST support all
+     * three syntaxes.
+     *
+     * Normally, the empty path "" and absolute path "/" are considered equal as
+     * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
+     * do this normalization because in contexts with a trimmed base path, e.g.
+     * the front controller, this difference becomes significant. It's the task
+     * of the user to handle both "" and "/".
+     *
+     * The value returned MUST be percent-encoded, but MUST NOT double-encode
+     * any characters. To determine what characters to encode, please refer to
+     * RFC 3986, Sections 2 and 3.3.
+     *
+     * As an example, if the value should include a slash ("/") not intended as
+     * delimiter between path segments, that value MUST be passed in encoded
+     * form (e.g., "%2F") to the instance.
+     *
+     * @see https://tools.ietf.org/html/rfc3986#section-2
+     * @see https://tools.ietf.org/html/rfc3986#section-3.3
+     * @return string The URI path.
+     */
+    public function getPath();
+
+    /**
+     * Retrieve the query string of the URI.
+     *
+     * If no query string is present, this method MUST return an empty string.
+     *
+     * The leading "?" character is not part of the query and MUST NOT be
+     * added.
+     *
+     * The value returned MUST be percent-encoded, but MUST NOT double-encode
+     * any characters. To determine what characters to encode, please refer to
+     * RFC 3986, Sections 2 and 3.4.
+     *
+     * As an example, if a value in a key/value pair of the query string should
+     * include an ampersand ("&") not intended as a delimiter between values,
+     * that value MUST be passed in encoded form (e.g., "%26") to the instance.
+     *
+     * @see https://tools.ietf.org/html/rfc3986#section-2
+     * @see https://tools.ietf.org/html/rfc3986#section-3.4
+     * @return string The URI query string.
+     */
+    public function getQuery();
+
+    /**
+     * Retrieve the fragment component of the URI.
+     *
+     * If no fragment is present, this method MUST return an empty string.
+     *
+     * The leading "#" character is not part of the fragment and MUST NOT be
+     * added.
+     *
+     * The value returned MUST be percent-encoded, but MUST NOT double-encode
+     * any characters. To determine what characters to encode, please refer to
+     * RFC 3986, Sections 2 and 3.5.
+     *
+     * @see https://tools.ietf.org/html/rfc3986#section-2
+     * @see https://tools.ietf.org/html/rfc3986#section-3.5
+     * @return string The URI fragment.
+     */
+    public function getFragment();
+
+    /**
+     * Return an instance with the specified scheme.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified scheme.
+     *
+     * Implementations MUST support the schemes "http" and "https" case
+     * insensitively, and MAY accommodate other schemes if required.
+     *
+     * An empty scheme is equivalent to removing the scheme.
+     *
+     * @param string $scheme The scheme to use with the new instance.
+     * @return static A new instance with the specified scheme.
+     * @throws \InvalidArgumentException for invalid or unsupported schemes.
+     */
+    public function withScheme($scheme);
+
+    /**
+     * Return an instance with the specified user information.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified user information.
+     *
+     * Password is optional, but the user information MUST include the
+     * user; an empty string for the user is equivalent to removing user
+     * information.
+     *
+     * @param string $user The user name to use for authority.
+     * @param null|string $password The password associated with $user.
+     * @return static A new instance with the specified user information.
+     */
+    public function withUserInfo($user, $password = null);
+
+    /**
+     * Return an instance with the specified host.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified host.
+     *
+     * An empty host value is equivalent to removing the host.
+     *
+     * @param string $host The hostname to use with the new instance.
+     * @return static A new instance with the specified host.
+     * @throws \InvalidArgumentException for invalid hostnames.
+     */
+    public function withHost($host);
+
+    /**
+     * Return an instance with the specified port.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified port.
+     *
+     * Implementations MUST raise an exception for ports outside the
+     * established TCP and UDP port ranges.
+     *
+     * A null value provided for the port is equivalent to removing the port
+     * information.
+     *
+     * @param null|int $port The port to use with the new instance; a null value
+     *     removes the port information.
+     * @return static A new instance with the specified port.
+     * @throws \InvalidArgumentException for invalid ports.
+     */
+    public function withPort($port);
+
+    /**
+     * Return an instance with the specified path.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified path.
+     *
+     * The path can either be empty or absolute (starting with a slash) or
+     * rootless (not starting with a slash). Implementations MUST support all
+     * three syntaxes.
+     *
+     * If the path is intended to be domain-relative rather than path relative then
+     * it must begin with a slash ("/"). Paths not starting with a slash ("/")
+     * are assumed to be relative to some base path known to the application or
+     * consumer.
+     *
+     * Users can provide both encoded and decoded path characters.
+     * Implementations ensure the correct encoding as outlined in getPath().
+     *
+     * @param string $path The path to use with the new instance.
+     * @return static A new instance with the specified path.
+     * @throws \InvalidArgumentException for invalid paths.
+     */
+    public function withPath($path);
+
+    /**
+     * Return an instance with the specified query string.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified query string.
+     *
+     * Users can provide both encoded and decoded query characters.
+     * Implementations ensure the correct encoding as outlined in getQuery().
+     *
+     * An empty query string value is equivalent to removing the query string.
+     *
+     * @param string $query The query string to use with the new instance.
+     * @return static A new instance with the specified query string.
+     * @throws \InvalidArgumentException for invalid query strings.
+     */
+    public function withQuery($query);
+
+    /**
+     * Return an instance with the specified URI fragment.
+     *
+     * This method MUST retain the state of the current instance, and return
+     * an instance that contains the specified URI fragment.
+     *
+     * Users can provide both encoded and decoded fragment characters.
+     * Implementations ensure the correct encoding as outlined in getFragment().
+     *
+     * An empty fragment value is equivalent to removing the fragment.
+     *
+     * @param string $fragment The fragment to use with the new instance.
+     * @return static A new instance with the specified fragment.
+     */
+    public function withFragment($fragment);
+
+    /**
+     * Return the string representation as a URI reference.
+     *
+     * Depending on which components of the URI are present, the resulting
+     * string is either a full URI or relative reference according to RFC 3986,
+     * Section 4.1. The method concatenates the various components of the URI,
+     * using the appropriate delimiters:
+     *
+     * - If a scheme is present, it MUST be suffixed by ":".
+     * - If an authority is present, it MUST be prefixed by "//".
+     * - The path can be concatenated without delimiters. But there are two
+     *   cases where the path has to be adjusted to make the URI reference
+     *   valid as PHP does not allow to throw an exception in __toString():
+     *     - If the path is rootless and an authority is present, the path MUST
+     *       be prefixed by "/".
+     *     - If the path is starting with more than one "/" and no authority is
+     *       present, the starting slashes MUST be reduced to one.
+     * - If a query is present, it MUST be prefixed by "?".
+     * - If a fragment is present, it MUST be prefixed by "#".
+     *
+     * @see http://tools.ietf.org/html/rfc3986#section-4.1
+     * @return string
+     */
+    public function __toString();
+}
diff --git a/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/LICENSE b/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/LICENSE
new file mode 100644 (file)
index 0000000..be5540c
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Ralph Khattar
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/README.md b/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/README.md
new file mode 100644 (file)
index 0000000..9430d76
--- /dev/null
@@ -0,0 +1,27 @@
+getallheaders
+=============
+
+PHP `getallheaders()` polyfill. Compatible with PHP >= 5.3.
+
+[![Build Status](https://travis-ci.org/ralouphie/getallheaders.svg?branch=master)](https://travis-ci.org/ralouphie/getallheaders)
+[![Coverage Status](https://coveralls.io/repos/ralouphie/getallheaders/badge.png?branch=master)](https://coveralls.io/r/ralouphie/getallheaders?branch=master)
+[![Latest Stable Version](https://poser.pugx.org/ralouphie/getallheaders/v/stable.png)](https://packagist.org/packages/ralouphie/getallheaders)
+[![Latest Unstable Version](https://poser.pugx.org/ralouphie/getallheaders/v/unstable.png)](https://packagist.org/packages/ralouphie/getallheaders)
+[![License](https://poser.pugx.org/ralouphie/getallheaders/license.png)](https://packagist.org/packages/ralouphie/getallheaders)
+
+
+This is a simple polyfill for [`getallheaders()`](http://www.php.net/manual/en/function.getallheaders.php).
+
+## Install
+
+For PHP version **`>= 5.6`**:
+
+```
+composer require ralouphie/getallheaders
+```
+
+For PHP version **`< 5.6`**:
+
+```
+composer require ralouphie/getallheaders "^2"
+```
diff --git a/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/composer.json b/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/composer.json
new file mode 100644 (file)
index 0000000..de8ce62
--- /dev/null
@@ -0,0 +1,26 @@
+{
+       "name": "ralouphie/getallheaders",
+       "description": "A polyfill for getallheaders.",
+       "license": "MIT",
+       "authors": [
+               {
+                       "name": "Ralph Khattar",
+                       "email": "ralph.khattar@gmail.com"
+               }
+       ],
+       "require": {
+               "php": ">=5.6"
+       },
+       "require-dev": {
+               "phpunit/phpunit": "^5 || ^6.5",
+               "php-coveralls/php-coveralls": "^2.1"
+       },
+       "autoload": {
+               "files": ["src/getallheaders.php"]
+       },
+       "autoload-dev": {
+               "psr-4": {
+                       "getallheaders\\Tests\\": "tests/"
+               }
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/src/getallheaders.php b/wcfsetup/install/files/lib/system/api/ralouphie/getallheaders/src/getallheaders.php
new file mode 100644 (file)
index 0000000..c7285a5
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+if (!function_exists('getallheaders')) {
+
+    /**
+     * Get all HTTP header key/values as an associative array for the current request.
+     *
+     * @return string[string] The HTTP header key/value pairs.
+     */
+    function getallheaders()
+    {
+        $headers = array();
+
+        $copy_server = array(
+            'CONTENT_TYPE'   => 'Content-Type',
+            'CONTENT_LENGTH' => 'Content-Length',
+            'CONTENT_MD5'    => 'Content-Md5',
+        );
+
+        foreach ($_SERVER as $key => $value) {
+            if (substr($key, 0, 5) === 'HTTP_') {
+                $key = substr($key, 5);
+                if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
+                    $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
+                    $headers[$key] = $value;
+                }
+            } elseif (isset($copy_server[$key])) {
+                $headers[$copy_server[$key]] = $value;
+            }
+        }
+
+        if (!isset($headers['Authorization'])) {
+            if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
+                $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+            } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
+                $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
+                $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
+            } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
+                $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
+            }
+        }
+
+        return $headers;
+    }
+
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/LICENSE.md b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/LICENSE.md
new file mode 100644 (file)
index 0000000..afcfdfb
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2015 Leaf Corcoran, http://scssphp.github.io/scssphp
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/README.md b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/README.md
new file mode 100644 (file)
index 0000000..0b48519
--- /dev/null
@@ -0,0 +1,46 @@
+# scssphp
+### <https://scssphp.github.io/scssphp>
+
+[![Build](https://travis-ci.com/scssphp/scssphp.svg?branch=master)](https://travis-ci.com/scssphp/scssphp)
+[![License](https://poser.pugx.org/scssphp/scssphp/license)](https://packagist.org/packages/scssphp/scssphp)
+
+`scssphp` is a compiler for SCSS written in PHP.
+
+Checkout the homepage, <https://scssphp.github.io/scssphp>, for directions on how to use.
+
+## Running Tests
+
+`scssphp` uses [PHPUnit](https://github.com/sebastianbergmann/phpunit) for testing.
+
+Run the following command from the root directory to run every test:
+
+    vendor/bin/phpunit tests
+
+There are several tests in the `tests/` directory:
+
+* `ApiTest.php` contains various unit tests that test the PHP interface.
+* `ExceptionTest.php` contains unit tests that test for exceptions thrown by the parser and compiler.
+* `FailingTest.php` contains tests reported in Github issues that demonstrate compatibility bugs.
+* `InputTest.php` compiles every `.scss` file in the `tests/inputs` directory
+  then compares to the respective `.css` file in the `tests/outputs` directory.
+* `ScssTest.php` extracts (ruby) `scss` tests from the `tests/scss_test.rb` file.
+
+When changing any of the tests in `tests/inputs`, the tests will most likely
+fail because the output has changed. Once you verify that the output is correct
+you can run the following command to rebuild all the tests:
+
+    BUILD=1 vendor/bin/phpunit tests
+
+This will compile all the tests, and save results into `tests/outputs`.
+
+To enable the `scss` compatibility tests:
+
+    TEST_SCSS_COMPAT=1 vendor/bin/phpunit tests
+
+## Coding Standard
+
+`scssphp` source conforms to [PSR12](https://www.php-fig.org/psr/psr-12/).
+
+Run the following command from the root directory to check the code for "sniffs".
+
+    vendor/bin/phpcs --standard=PSR12 --extensions=php bin src tests *.php
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/bin/pscss
new file mode 100644 (file)
index 0000000..b3c8a73
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/env php
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+error_reporting(E_ALL);
+
+if (version_compare(PHP_VERSION, '5.6') < 0) {
+    die('Requires PHP 5.6 or above');
+}
+
+include __DIR__ . '/../scss.inc.php';
+
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Parser;
+use ScssPhp\ScssPhp\Version;
+
+$style = null;
+$loadPaths = null;
+$dumpTree = false;
+$inputFile = null;
+$changeDir = false;
+$encoding = false;
+$sourceMap = false;
+
+/**
+ * Parse argument
+ *
+ * @param integer $i
+ * @param array $options
+ *
+ * @return string|null
+ */
+function parseArgument(&$i, $options) {
+    global $argc;
+    global $argv;
+
+    if (! preg_match('/^(?:' . implode('|', (array) $options) . ')=?(.*)/', $argv[$i], $matches)) {
+        return;
+    }
+
+    if (strlen($matches[1])) {
+        return $matches[1];
+    }
+
+    if ($i + 1 < $argc) {
+        $i++;
+
+        return $argv[$i];
+    }
+}
+
+for ($i = 1; $i < $argc; $i++) {
+    if ($argv[$i] === '-?' || $argv[$i] === '-h' || $argv[$i] === '--help') {
+        $exe = $argv[0];
+
+        $HELP = <<<EOT
+Usage: $exe [options] [input-file]
+
+Options include:
+
+    --help              Show this message [-h, -?]
+    --continue-on-error [deprecated] Ignored
+    --debug-info        [deprecated] Ignored [-g]
+    --dump-tree         Dump formatted parse tree [-T]
+    --iso8859-1         Use iso8859-1 encoding instead of default utf-8
+    --line-numbers      [deprecated] Ignored [--line-comments]
+    --load-path=PATH    Set import path [-I]
+    --precision=N       [deprecated] Ignored. (default 10) [-p]
+    --sourcemap         Create source map file
+    --style=FORMAT      Set the output format (compact, compressed, crunched, expanded, or nested) [-s, -t]
+    --version           Print the version [-v]
+
+EOT;
+        exit($HELP);
+    }
+
+    if ($argv[$i] === '-v' || $argv[$i] === '--version') {
+        exit(Version::VERSION . "\n");
+    }
+
+    // Keep parsing --continue-on-error to avoid BC breaks for scripts using it
+    if ($argv[$i] === '--continue-on-error') {
+        // TODO report it as a warning ?
+        continue;
+    }
+
+    // Keep parsing it to avoid BC breaks for scripts using it
+    if ($argv[$i] === '-g' || $argv[$i] === '--debug-info') {
+        // TODO report it as a warning ?
+        continue;
+    }
+
+    if ($argv[$i] === '--iso8859-1') {
+        $encoding = 'iso8859-1';
+        continue;
+    }
+
+    // Keep parsing it to avoid BC breaks for scripts using it
+    if ($argv[$i] === '--line-numbers' || $argv[$i] === '--line-comments') {
+        // TODO report it as a warning ?
+        continue;
+    }
+
+    if ($argv[$i] === '--sourcemap') {
+        $sourceMap = true;
+        continue;
+    }
+
+    if ($argv[$i] === '-T' || $argv[$i] === '--dump-tree') {
+        $dumpTree = true;
+        continue;
+    }
+
+    $value = parseArgument($i, array('-t', '-s', '--style'));
+
+    if (isset($value)) {
+        $style = $value;
+        continue;
+    }
+
+    $value = parseArgument($i, array('-I', '--load-path'));
+
+    if (isset($value)) {
+        $loadPaths = $value;
+        continue;
+    }
+
+    // Keep parsing --precision to avoid BC breaks for scripts using it
+    $value = parseArgument($i, array('-p', '--precision'));
+
+    if (isset($value)) {
+        // TODO report it as a warning ?
+        continue;
+    }
+
+    if (file_exists($argv[$i])) {
+        $inputFile = $argv[$i];
+        continue;
+    }
+}
+
+
+if ($inputFile) {
+    $data = file_get_contents($inputFile);
+
+    $newWorkingDir = dirname(realpath($inputFile));
+    $oldWorkingDir = getcwd();
+
+    if ($oldWorkingDir !== $newWorkingDir) {
+        $changeDir = chdir($newWorkingDir);
+        $inputFile = basename($inputFile);
+    }
+} else {
+    $data = '';
+
+    while (! feof(STDIN)) {
+        $data .= fread(STDIN, 8192);
+    }
+}
+
+if ($dumpTree) {
+    $parser = new Parser($inputFile);
+
+    print_r(json_decode(json_encode($parser->parse($data)), true));
+
+    exit();
+}
+
+$scss = new Compiler();
+
+if ($loadPaths) {
+    $scss->setImportPaths(explode(PATH_SEPARATOR, $loadPaths));
+}
+
+if ($style) {
+    $scss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\' . ucfirst($style));
+}
+
+if ($sourceMap) {
+    $scss->setSourceMap(Compiler::SOURCE_MAP_INLINE);
+}
+
+if ($encoding) {
+    $scss->setEncoding($encoding);
+}
+
+echo $scss->compile($data, $inputFile);
+
+if ($changeDir) {
+    chdir($oldWorkingDir);
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/composer.json
new file mode 100644 (file)
index 0000000..6ac1312
--- /dev/null
@@ -0,0 +1,64 @@
+{
+    "name": "scssphp/scssphp",
+    "type": "library",
+    "description": "scssphp is a compiler for SCSS written in PHP.",
+    "keywords": ["css", "stylesheet", "scss", "sass", "less"],
+    "homepage": "http://scssphp.github.io/scssphp/",
+    "license": [
+        "MIT"
+    ],
+    "authors": [
+        {
+            "name": "Anthon Pang",
+            "email": "apang@softwaredevelopment.ca",
+            "homepage": "https://github.com/robocoder"
+        },
+        {
+            "name": "Cédric Morin",
+            "email": "cedric@yterium.com",
+            "homepage": "https://github.com/Cerdic"
+        }
+    ],
+    "autoload": {
+        "psr-4": { "ScssPhp\\ScssPhp\\": "src/" }
+    },
+    "autoload-dev": {
+        "psr-4": { "ScssPhp\\ScssPhp\\Tests\\": "tests/" }
+    },
+    "require": {
+        "php": ">=5.6.0",
+        "ext-json": "*",
+        "ext-ctype": "*"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3 || ^9.4",
+        "sass/sass-spec": "2020.08.10",
+        "squizlabs/php_codesniffer": "~3.5",
+        "twbs/bootstrap": "~4.3",
+        "zurb/foundation": "~6.5"
+    },
+    "repositories": [
+        {
+            "type": "package",
+            "package": {
+                "name": "sass/sass-spec",
+                "version": "2020.08.10",
+                "source": {
+                    "type": "git",
+                    "url": "https://github.com/sass/sass-spec.git",
+                    "reference": "73222792c42a516d62e2e25c3f5d9e35f5567030"
+                },
+                "dist": {
+                    "type": "zip",
+                    "url": "https://api.github.com/repos/sass/sass-spec/zipball/73222792c42a516d62e2e25c3f5d9e35f5567030",
+                    "reference": "73222792c42a516d62e2e25c3f5d9e35f5567030",
+                    "shasum": ""
+                }
+            }
+        }
+    ],
+    "bin": ["bin/pscss"],
+    "config": {
+        "sort-packages": true
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/phpcs.xml.dist b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/phpcs.xml.dist
new file mode 100644 (file)
index 0000000..b162dbd
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<ruleset name="PSR12 (adapted for PHP 5.6+)">
+    <rule ref="PSR12">
+        <!-- Ignore this PHP 7.1+ sniff as long as we support PHP 5.6+ -->
+        <exclude name="PSR12.Properties.ConstantVisibility.NotFound"/>
+
+        <!-- This sniff doesn't ignore comment blocks -->
+<!--
+        <exclude name="Generic.Files.LineLength"/>
+-->
+    </rule>
+</ruleset>
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/scss.inc.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/scss.inc.php
new file mode 100644 (file)
index 0000000..96532aa
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+if (version_compare(PHP_VERSION, '5.6') < 0) {
+    throw new \Exception('scssphp requires PHP 5.6 or above');
+}
+
+if (! class_exists('ScssPhp\ScssPhp\Version', false)) {
+    include_once __DIR__ . '/src/Base/Range.php';
+    include_once __DIR__ . '/src/Block.php';
+    include_once __DIR__ . '/src/Cache.php';
+    include_once __DIR__ . '/src/Colors.php';
+    include_once __DIR__ . '/src/Compiler.php';
+    include_once __DIR__ . '/src/Compiler/Environment.php';
+    include_once __DIR__ . '/src/Exception/SassException.php';
+    include_once __DIR__ . '/src/Exception/SassScriptException.php';
+    include_once __DIR__ . '/src/Exception/CompilerException.php';
+    include_once __DIR__ . '/src/Exception/ParserException.php';
+    include_once __DIR__ . '/src/Exception/RangeException.php';
+    include_once __DIR__ . '/src/Exception/ServerException.php';
+    include_once __DIR__ . '/src/Formatter.php';
+    include_once __DIR__ . '/src/Formatter/Compact.php';
+    include_once __DIR__ . '/src/Formatter/Compressed.php';
+    include_once __DIR__ . '/src/Formatter/Crunched.php';
+    include_once __DIR__ . '/src/Formatter/Debug.php';
+    include_once __DIR__ . '/src/Formatter/Expanded.php';
+    include_once __DIR__ . '/src/Formatter/Nested.php';
+    include_once __DIR__ . '/src/Formatter/OutputBlock.php';
+    include_once __DIR__ . '/src/Node.php';
+    include_once __DIR__ . '/src/Node/Number.php';
+    include_once __DIR__ . '/src/Parser.php';
+    include_once __DIR__ . '/src/SourceMap/Base64.php';
+    include_once __DIR__ . '/src/SourceMap/Base64VLQ.php';
+    include_once __DIR__ . '/src/SourceMap/SourceMapGenerator.php';
+    include_once __DIR__ . '/src/Type.php';
+    include_once __DIR__ . '/src/Util.php';
+    include_once __DIR__ . '/src/Version.php';
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Base/Range.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Base/Range.php
new file mode 100644 (file)
index 0000000..2846746
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2015-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Base;
+
+/**
+ * Range
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Range
+{
+    public $first;
+    public $last;
+
+    /**
+     * Initialize range
+     *
+     * @param integer|float $first
+     * @param integer|float $last
+     */
+    public function __construct($first, $last)
+    {
+        $this->first = $first;
+        $this->last = $last;
+    }
+
+    /**
+     * Test for inclusion in range
+     *
+     * @param integer|float $value
+     *
+     * @return boolean
+     */
+    public function includes($value)
+    {
+        return $value >= $this->first && $value <= $this->last;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Block.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Block.php
new file mode 100644 (file)
index 0000000..aaeba71
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+/**
+ * Block
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Block
+{
+    /**
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @var \ScssPhp\ScssPhp\Block
+     */
+    public $parent;
+
+    /**
+     * @var string
+     */
+    public $sourceName;
+
+    /**
+     * @var integer
+     */
+    public $sourceIndex;
+
+    /**
+     * @var integer
+     */
+    public $sourceLine;
+
+    /**
+     * @var integer
+     */
+    public $sourceColumn;
+
+    /**
+     * @var array
+     */
+    public $selectors;
+
+    /**
+     * @var array
+     */
+    public $comments;
+
+    /**
+     * @var array
+     */
+    public $children;
+
+    /**
+     * @var \ScssPhp\ScssPhp\Block
+     */
+    public $selfParent;
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Cache.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Cache.php
new file mode 100644 (file)
index 0000000..02d47ac
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+use Exception;
+
+/**
+ * The scss cache manager.
+ *
+ * In short:
+ *
+ * allow to put in cache/get from cache a generic result from a known operation on a generic dataset,
+ * taking in account options that affects the result
+ *
+ * The cache manager is agnostic about data format and only the operation is expected to be described by string
+ */
+
+/**
+ * SCSS cache
+ *
+ * @author Cedric Morin <cedric@yterium.com>
+ */
+class Cache
+{
+    const CACHE_VERSION = 1;
+
+    // directory used for storing data
+    public static $cacheDir = false;
+
+    // prefix for the storing data
+    public static $prefix = 'scssphp_';
+
+    // force a refresh : 'once' for refreshing the first hit on a cache only, true to never use the cache in this hit
+    public static $forceRefresh = false;
+
+    // specifies the number of seconds after which data cached will be seen as 'garbage' and potentially cleaned up
+    public static $gcLifetime = 604800;
+
+    // array of already refreshed cache if $forceRefresh==='once'
+    protected static $refreshed = [];
+
+    /**
+     * Constructor
+     *
+     * @param array $options
+     */
+    public function __construct($options)
+    {
+        // check $cacheDir
+        if (isset($options['cacheDir'])) {
+            self::$cacheDir = $options['cacheDir'];
+        }
+
+        if (empty(self::$cacheDir)) {
+            throw new Exception('cacheDir not set');
+        }
+
+        if (isset($options['prefix'])) {
+            self::$prefix = $options['prefix'];
+        }
+
+        if (empty(self::$prefix)) {
+            throw new Exception('prefix not set');
+        }
+
+        if (isset($options['forceRefresh'])) {
+            self::$forceRefresh = $options['forceRefresh'];
+        }
+
+        self::checkCacheDir();
+    }
+
+    /**
+     * Get the cached result of $operation on $what,
+     * which is known as dependant from the content of $options
+     *
+     * @param string  $operation    parse, compile...
+     * @param mixed   $what         content key (e.g., filename to be treated)
+     * @param array   $options      any option that affect the operation result on the content
+     * @param integer $lastModified last modified timestamp
+     *
+     * @return mixed
+     *
+     * @throws \Exception
+     */
+    public function getCache($operation, $what, $options = [], $lastModified = null)
+    {
+        $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options);
+
+        if (
+            ((self::$forceRefresh === false) || (self::$forceRefresh === 'once' &&
+            isset(self::$refreshed[$fileCache]))) && file_exists($fileCache)
+        ) {
+            $cacheTime = filemtime($fileCache);
+
+            if (
+                (\is_null($lastModified) || $cacheTime > $lastModified) &&
+                $cacheTime + self::$gcLifetime > time()
+            ) {
+                $c = file_get_contents($fileCache);
+                $c = unserialize($c);
+
+                if (\is_array($c) && isset($c['value'])) {
+                    return $c['value'];
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Put in cache the result of $operation on $what,
+     * which is known as dependant from the content of $options
+     *
+     * @param string $operation
+     * @param mixed  $what
+     * @param mixed  $value
+     * @param array  $options
+     */
+    public function setCache($operation, $what, $value, $options = [])
+    {
+        $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options);
+
+        $c = ['value' => $value];
+        $c = serialize($c);
+
+        file_put_contents($fileCache, $c);
+
+        if (self::$forceRefresh === 'once') {
+            self::$refreshed[$fileCache] = true;
+        }
+    }
+
+    /**
+     * Get the cache name for the caching of $operation on $what,
+     * which is known as dependant from the content of $options
+     *
+     * @param string $operation
+     * @param mixed  $what
+     * @param array  $options
+     *
+     * @return string
+     */
+    private static function cacheName($operation, $what, $options = [])
+    {
+        $t = [
+          'version' => self::CACHE_VERSION,
+          'operation' => $operation,
+          'what' => $what,
+          'options' => $options
+        ];
+
+        $t = self::$prefix
+          . sha1(json_encode($t))
+          . ".$operation"
+          . ".scsscache";
+
+        return $t;
+    }
+
+    /**
+     * Check that the cache dir exists and is writeable
+     *
+     * @throws \Exception
+     */
+    public static function checkCacheDir()
+    {
+        self::$cacheDir = str_replace('\\', '/', self::$cacheDir);
+        self::$cacheDir = rtrim(self::$cacheDir, '/') . '/';
+
+        if (! is_dir(self::$cacheDir)) {
+            throw new Exception('Cache directory doesn\'t exist: ' . self::$cacheDir);
+        }
+
+        if (! is_writable(self::$cacheDir)) {
+            throw new Exception('Cache directory isn\'t writable: ' . self::$cacheDir);
+        }
+    }
+
+    /**
+     * Delete unused cached files
+     */
+    public static function cleanCache()
+    {
+        static $clean = false;
+
+        if ($clean || empty(self::$cacheDir)) {
+            return;
+        }
+
+        $clean = true;
+
+        // only remove files with extensions created by SCSSPHP Cache
+        // css files removed based on the list files
+        $removeTypes = ['scsscache' => 1];
+
+        $files = scandir(self::$cacheDir);
+
+        if (! $files) {
+            return;
+        }
+
+        $checkTime = time() - self::$gcLifetime;
+
+        foreach ($files as $file) {
+            // don't delete if the file wasn't created with SCSSPHP Cache
+            if (strpos($file, self::$prefix) !== 0) {
+                continue;
+            }
+
+            $parts = explode('.', $file);
+            $type = array_pop($parts);
+
+            if (! isset($removeTypes[$type])) {
+                continue;
+            }
+
+            $fullPath = self::$cacheDir . $file;
+            $mtime = filemtime($fullPath);
+
+            // don't delete if it's a relatively new file
+            if ($mtime > $checkTime) {
+                continue;
+            }
+
+            unlink($fullPath);
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Colors.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Colors.php
new file mode 100644 (file)
index 0000000..4b62c36
--- /dev/null
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+/**
+ * CSS Colors
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Colors
+{
+    /**
+     * CSS Colors
+     *
+     * @see http://www.w3.org/TR/css3-color
+     *
+     * @var array
+     */
+    protected static $cssColors = [
+        'aliceblue' => '240,248,255',
+        'antiquewhite' => '250,235,215',
+        'cyan' => '0,255,255',
+        'aqua' => '0,255,255',
+        'aquamarine' => '127,255,212',
+        'azure' => '240,255,255',
+        'beige' => '245,245,220',
+        'bisque' => '255,228,196',
+        'black' => '0,0,0',
+        'blanchedalmond' => '255,235,205',
+        'blue' => '0,0,255',
+        'blueviolet' => '138,43,226',
+        'brown' => '165,42,42',
+        'burlywood' => '222,184,135',
+        'cadetblue' => '95,158,160',
+        'chartreuse' => '127,255,0',
+        'chocolate' => '210,105,30',
+        'coral' => '255,127,80',
+        'cornflowerblue' => '100,149,237',
+        'cornsilk' => '255,248,220',
+        'crimson' => '220,20,60',
+        'darkblue' => '0,0,139',
+        'darkcyan' => '0,139,139',
+        'darkgoldenrod' => '184,134,11',
+        'darkgray' => '169,169,169',
+        'darkgrey' => '169,169,169',
+        'darkgreen' => '0,100,0',
+        'darkkhaki' => '189,183,107',
+        'darkmagenta' => '139,0,139',
+        'darkolivegreen' => '85,107,47',
+        'darkorange' => '255,140,0',
+        'darkorchid' => '153,50,204',
+        'darkred' => '139,0,0',
+        'darksalmon' => '233,150,122',
+        'darkseagreen' => '143,188,143',
+        'darkslateblue' => '72,61,139',
+        'darkslategray' => '47,79,79',
+        'darkslategrey' => '47,79,79',
+        'darkturquoise' => '0,206,209',
+        'darkviolet' => '148,0,211',
+        'deeppink' => '255,20,147',
+        'deepskyblue' => '0,191,255',
+        'dimgray' => '105,105,105',
+        'dimgrey' => '105,105,105',
+        'dodgerblue' => '30,144,255',
+        'firebrick' => '178,34,34',
+        'floralwhite' => '255,250,240',
+        'forestgreen' => '34,139,34',
+        'magenta' => '255,0,255',
+        'fuchsia' => '255,0,255',
+        'gainsboro' => '220,220,220',
+        'ghostwhite' => '248,248,255',
+        'gold' => '255,215,0',
+        'goldenrod' => '218,165,32',
+        'gray' => '128,128,128',
+        'grey' => '128,128,128',
+        'green' => '0,128,0',
+        'greenyellow' => '173,255,47',
+        'honeydew' => '240,255,240',
+        'hotpink' => '255,105,180',
+        'indianred' => '205,92,92',
+        'indigo' => '75,0,130',
+        'ivory' => '255,255,240',
+        'khaki' => '240,230,140',
+        'lavender' => '230,230,250',
+        'lavenderblush' => '255,240,245',
+        'lawngreen' => '124,252,0',
+        'lemonchiffon' => '255,250,205',
+        'lightblue' => '173,216,230',
+        'lightcoral' => '240,128,128',
+        'lightcyan' => '224,255,255',
+        'lightgoldenrodyellow' => '250,250,210',
+        'lightgray' => '211,211,211',
+        'lightgrey' => '211,211,211',
+        'lightgreen' => '144,238,144',
+        'lightpink' => '255,182,193',
+        'lightsalmon' => '255,160,122',
+        'lightseagreen' => '32,178,170',
+        'lightskyblue' => '135,206,250',
+        'lightslategray' => '119,136,153',
+        'lightslategrey' => '119,136,153',
+        'lightsteelblue' => '176,196,222',
+        'lightyellow' => '255,255,224',
+        'lime' => '0,255,0',
+        'limegreen' => '50,205,50',
+        'linen' => '250,240,230',
+        'maroon' => '128,0,0',
+        'mediumaquamarine' => '102,205,170',
+        'mediumblue' => '0,0,205',
+        'mediumorchid' => '186,85,211',
+        'mediumpurple' => '147,112,219',
+        'mediumseagreen' => '60,179,113',
+        'mediumslateblue' => '123,104,238',
+        'mediumspringgreen' => '0,250,154',
+        'mediumturquoise' => '72,209,204',
+        'mediumvioletred' => '199,21,133',
+        'midnightblue' => '25,25,112',
+        'mintcream' => '245,255,250',
+        'mistyrose' => '255,228,225',
+        'moccasin' => '255,228,181',
+        'navajowhite' => '255,222,173',
+        'navy' => '0,0,128',
+        'oldlace' => '253,245,230',
+        'olive' => '128,128,0',
+        'olivedrab' => '107,142,35',
+        'orange' => '255,165,0',
+        'orangered' => '255,69,0',
+        'orchid' => '218,112,214',
+        'palegoldenrod' => '238,232,170',
+        'palegreen' => '152,251,152',
+        'paleturquoise' => '175,238,238',
+        'palevioletred' => '219,112,147',
+        'papayawhip' => '255,239,213',
+        'peachpuff' => '255,218,185',
+        'peru' => '205,133,63',
+        'pink' => '255,192,203',
+        'plum' => '221,160,221',
+        'powderblue' => '176,224,230',
+        'purple' => '128,0,128',
+        'red' => '255,0,0',
+        'rosybrown' => '188,143,143',
+        'royalblue' => '65,105,225',
+        'saddlebrown' => '139,69,19',
+        'salmon' => '250,128,114',
+        'sandybrown' => '244,164,96',
+        'seagreen' => '46,139,87',
+        'seashell' => '255,245,238',
+        'sienna' => '160,82,45',
+        'silver' => '192,192,192',
+        'skyblue' => '135,206,235',
+        'slateblue' => '106,90,205',
+        'slategray' => '112,128,144',
+        'slategrey' => '112,128,144',
+        'snow' => '255,250,250',
+        'springgreen' => '0,255,127',
+        'steelblue' => '70,130,180',
+        'tan' => '210,180,140',
+        'teal' => '0,128,128',
+        'thistle' => '216,191,216',
+        'tomato' => '255,99,71',
+        'turquoise' => '64,224,208',
+        'violet' => '238,130,238',
+        'wheat' => '245,222,179',
+        'white' => '255,255,255',
+        'whitesmoke' => '245,245,245',
+        'yellow' => '255,255,0',
+        'yellowgreen' => '154,205,50',
+        'rebeccapurple' => '102,51,153',
+        'transparent' => '0,0,0,0',
+    ];
+
+    /**
+     * Convert named color in a [r,g,b[,a]] array
+     *
+     * @param string $colorName
+     *
+     * @return array|null
+     */
+    public static function colorNameToRGBa($colorName)
+    {
+        if (\is_string($colorName) && isset(static::$cssColors[$colorName])) {
+            $rgba = explode(',', static::$cssColors[$colorName]);
+
+            // only case with opacity is transparent, with opacity=0, so we can intval on opacity also
+            $rgba = array_map('intval', $rgba);
+
+            return $rgba;
+        }
+
+        return null;
+    }
+
+    /**
+     * Reverse conversion : from RGBA to a color name if possible
+     *
+     * @param integer $r
+     * @param integer $g
+     * @param integer $b
+     * @param integer $a
+     *
+     * @return string|null
+     */
+    public static function RGBaToColorName($r, $g, $b, $a = 1)
+    {
+        static $reverseColorTable = null;
+
+        if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b) || ! is_numeric($a)) {
+            return null;
+        }
+
+        if ($a < 1) {
+            return null;
+        }
+
+        if (\is_null($reverseColorTable)) {
+            $reverseColorTable = [];
+
+            foreach (static::$cssColors as $name => $rgb_str) {
+                $rgb_str = explode(',', $rgb_str);
+
+                if (
+                    \count($rgb_str) == 3 &&
+                    ! isset($reverseColorTable[\intval($rgb_str[0])][\intval($rgb_str[1])][\intval($rgb_str[2])])
+                ) {
+                    $reverseColorTable[\intval($rgb_str[0])][\intval($rgb_str[1])][\intval($rgb_str[2])] = $name;
+                }
+            }
+        }
+
+        if (isset($reverseColorTable[\intval($r)][\intval($g)][\intval($b)])) {
+            return $reverseColorTable[\intval($r)][\intval($g)][\intval($b)];
+        }
+
+        return null;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler.php
new file mode 100644 (file)
index 0000000..2840cd5
--- /dev/null
@@ -0,0 +1,8544 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+use ScssPhp\ScssPhp\Base\Range;
+use ScssPhp\ScssPhp\Block;
+use ScssPhp\ScssPhp\Cache;
+use ScssPhp\ScssPhp\Colors;
+use ScssPhp\ScssPhp\Compiler\Environment;
+use ScssPhp\ScssPhp\Exception\CompilerException;
+use ScssPhp\ScssPhp\Exception\SassScriptException;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Node;
+use ScssPhp\ScssPhp\Node\Number;
+use ScssPhp\ScssPhp\SourceMap\SourceMapGenerator;
+use ScssPhp\ScssPhp\Type;
+use ScssPhp\ScssPhp\Parser;
+use ScssPhp\ScssPhp\Util;
+
+/**
+ * The scss compiler and parser.
+ *
+ * Converting SCSS to CSS is a three stage process. The incoming file is parsed
+ * by `Parser` into a syntax tree, then it is compiled into another tree
+ * representing the CSS structure by `Compiler`. The CSS tree is fed into a
+ * formatter, like `Formatter` which then outputs CSS as a string.
+ *
+ * During the first compile, all values are *reduced*, which means that their
+ * types are brought to the lowest form before being dump as strings. This
+ * handles math equations, variable dereferences, and the like.
+ *
+ * The `compile` function of `Compiler` is the entry point.
+ *
+ * In summary:
+ *
+ * The `Compiler` class creates an instance of the parser, feeds it SCSS code,
+ * then transforms the resulting tree to a CSS tree. This class also holds the
+ * evaluation context, such as all available mixins and variables at any given
+ * time.
+ *
+ * The `Parser` class is only concerned with parsing its input.
+ *
+ * The `Formatter` takes a CSS tree, and dumps it to a formatted string,
+ * handling things like indentation.
+ */
+
+/**
+ * SCSS compiler
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Compiler
+{
+    /**
+     * @deprecated
+     */
+    const LINE_COMMENTS = 1;
+    /**
+     * @deprecated
+     */
+    const DEBUG_INFO    = 2;
+
+    /**
+     * @deprecated
+     */
+    const WITH_RULE     = 1;
+    /**
+     * @deprecated
+     */
+    const WITH_MEDIA    = 2;
+    /**
+     * @deprecated
+     */
+    const WITH_SUPPORTS = 4;
+    /**
+     * @deprecated
+     */
+    const WITH_ALL      = 7;
+
+    const SOURCE_MAP_NONE   = 0;
+    const SOURCE_MAP_INLINE = 1;
+    const SOURCE_MAP_FILE   = 2;
+
+    /**
+     * @var array
+     */
+    protected static $operatorNames = [
+        '+'   => 'add',
+        '-'   => 'sub',
+        '*'   => 'mul',
+        '/'   => 'div',
+        '%'   => 'mod',
+
+        '=='  => 'eq',
+        '!='  => 'neq',
+        '<'   => 'lt',
+        '>'   => 'gt',
+
+        '<='  => 'lte',
+        '>='  => 'gte',
+    ];
+
+    /**
+     * @var array
+     */
+    protected static $namespaces = [
+        'special'  => '%',
+        'mixin'    => '@',
+        'function' => '^',
+    ];
+
+    public static $true         = [Type::T_KEYWORD, 'true'];
+    public static $false        = [Type::T_KEYWORD, 'false'];
+    /** @deprecated */
+    public static $NaN          = [Type::T_KEYWORD, 'NaN'];
+    /** @deprecated */
+    public static $Infinity     = [Type::T_KEYWORD, 'Infinity'];
+    public static $null         = [Type::T_NULL];
+    public static $nullString   = [Type::T_STRING, '', []];
+    public static $defaultValue = [Type::T_KEYWORD, ''];
+    public static $selfSelector = [Type::T_SELF];
+    public static $emptyList    = [Type::T_LIST, '', []];
+    public static $emptyMap     = [Type::T_MAP, [], []];
+    public static $emptyString  = [Type::T_STRING, '"', []];
+    public static $with         = [Type::T_KEYWORD, 'with'];
+    public static $without      = [Type::T_KEYWORD, 'without'];
+
+    protected $importPaths = [''];
+    protected $importCache = [];
+    protected $importedFiles = [];
+    protected $userFunctions = [];
+    protected $registeredVars = [];
+    protected $registeredFeatures = [
+        'extend-selector-pseudoclass' => false,
+        'at-error'                    => true,
+        'units-level-3'               => false,
+        'global-variable-shadowing'   => false,
+    ];
+
+    protected $encoding = null;
+    /**
+     * @deprecated
+     */
+    protected $lineNumberStyle = null;
+
+    protected $sourceMap = self::SOURCE_MAP_NONE;
+    protected $sourceMapOptions = [];
+
+    /**
+     * @var string|\ScssPhp\ScssPhp\Formatter
+     */
+    protected $formatter = 'ScssPhp\ScssPhp\Formatter\Nested';
+
+    protected $rootEnv;
+    protected $rootBlock;
+
+    /**
+     * @var \ScssPhp\ScssPhp\Compiler\Environment
+     */
+    protected $env;
+    protected $scope;
+    protected $storeEnv;
+    protected $charsetSeen;
+    protected $sourceNames;
+
+    protected $cache;
+
+    protected $indentLevel;
+    protected $extends;
+    protected $extendsMap;
+    protected $parsedFiles;
+    protected $parser;
+    protected $sourceIndex;
+    protected $sourceLine;
+    protected $sourceColumn;
+    protected $stderr;
+    protected $shouldEvaluate;
+    protected $ignoreErrors;
+    protected $ignoreCallStackMessage = false;
+
+    protected $callStack = [];
+
+    /**
+     * Constructor
+     *
+     * @param array|null $cacheOptions
+     */
+    public function __construct($cacheOptions = null)
+    {
+        $this->parsedFiles = [];
+        $this->sourceNames = [];
+
+        if ($cacheOptions) {
+            $this->cache = new Cache($cacheOptions);
+        }
+
+        $this->stderr = fopen('php://stderr', 'w');
+    }
+
+    /**
+     * Get compiler options
+     *
+     * @return array
+     */
+    public function getCompileOptions()
+    {
+        $options = [
+            'importPaths'        => $this->importPaths,
+            'registeredVars'     => $this->registeredVars,
+            'registeredFeatures' => $this->registeredFeatures,
+            'encoding'           => $this->encoding,
+            'sourceMap'          => serialize($this->sourceMap),
+            'sourceMapOptions'   => $this->sourceMapOptions,
+            'formatter'          => $this->formatter,
+        ];
+
+        return $options;
+    }
+
+    /**
+     * Set an alternative error output stream, for testing purpose only
+     *
+     * @param resource $handle
+     */
+    public function setErrorOuput($handle)
+    {
+        $this->stderr = $handle;
+    }
+
+    /**
+     * Compile scss
+     *
+     * @api
+     *
+     * @param string $code
+     * @param string $path
+     *
+     * @return string
+     */
+    public function compile($code, $path = null)
+    {
+        if ($this->cache) {
+            $cacheKey       = ($path ? $path : '(stdin)') . ':' . md5($code);
+            $compileOptions = $this->getCompileOptions();
+            $cache          = $this->cache->getCache('compile', $cacheKey, $compileOptions);
+
+            if (\is_array($cache) && isset($cache['dependencies']) && isset($cache['out'])) {
+                // check if any dependency file changed before accepting the cache
+                foreach ($cache['dependencies'] as $file => $mtime) {
+                    if (! is_file($file) || filemtime($file) !== $mtime) {
+                        unset($cache);
+                        break;
+                    }
+                }
+
+                if (isset($cache)) {
+                    return $cache['out'];
+                }
+            }
+        }
+
+
+        $this->indentLevel    = -1;
+        $this->extends        = [];
+        $this->extendsMap     = [];
+        $this->sourceIndex    = null;
+        $this->sourceLine     = null;
+        $this->sourceColumn   = null;
+        $this->env            = null;
+        $this->scope          = null;
+        $this->storeEnv       = null;
+        $this->charsetSeen    = null;
+        $this->shouldEvaluate = null;
+        $this->ignoreCallStackMessage = false;
+
+        try {
+            $this->parser = $this->parserFactory($path);
+            $tree         = $this->parser->parse($code);
+            $this->parser = null;
+
+            $this->formatter = new $this->formatter();
+            $this->rootBlock = null;
+            $this->rootEnv   = $this->pushEnv($tree);
+
+            $this->injectVariables($this->registeredVars);
+            $this->compileRoot($tree);
+            $this->popEnv();
+
+            $sourceMapGenerator = null;
+
+            if ($this->sourceMap) {
+                if (\is_object($this->sourceMap) && $this->sourceMap instanceof SourceMapGenerator) {
+                    $sourceMapGenerator = $this->sourceMap;
+                    $this->sourceMap = self::SOURCE_MAP_FILE;
+                } elseif ($this->sourceMap !== self::SOURCE_MAP_NONE) {
+                    $sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions);
+                }
+            }
+
+            $out = $this->formatter->format($this->scope, $sourceMapGenerator);
+
+            if (! empty($out) && $this->sourceMap && $this->sourceMap !== self::SOURCE_MAP_NONE) {
+                $sourceMap    = $sourceMapGenerator->generateJson();
+                $sourceMapUrl = null;
+
+                switch ($this->sourceMap) {
+                    case self::SOURCE_MAP_INLINE:
+                        $sourceMapUrl = sprintf('data:application/json,%s', Util::encodeURIComponent($sourceMap));
+                        break;
+
+                    case self::SOURCE_MAP_FILE:
+                        $sourceMapUrl = $sourceMapGenerator->saveMap($sourceMap);
+                        break;
+                }
+
+                $out .= sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl);
+            }
+        } catch (SassScriptException $e) {
+            throw $this->error($e->getMessage());
+        }
+
+        if ($this->cache && isset($cacheKey) && isset($compileOptions)) {
+            $v = [
+                'dependencies' => $this->getParsedFiles(),
+                'out' => &$out,
+            ];
+
+            $this->cache->setCache('compile', $cacheKey, $v, $compileOptions);
+        }
+
+        if (!$this->charsetSeen && function_exists('mb_strlen')) {
+            if (strlen($out) !== mb_strlen($out)) {
+                $out = '@charset "UTF-8";' . "\n" . $out;
+            }
+        }
+
+        return $out;
+    }
+
+    /**
+     * Instantiate parser
+     *
+     * @param string $path
+     *
+     * @return \ScssPhp\ScssPhp\Parser
+     */
+    protected function parserFactory($path)
+    {
+        // https://sass-lang.com/documentation/at-rules/import
+        // CSS files imported by Sass don’t allow any special Sass features.
+        // In order to make sure authors don’t accidentally write Sass in their CSS,
+        // all Sass features that aren’t also valid CSS will produce errors.
+        // Otherwise, the CSS will be rendered as-is. It can even be extended!
+        $cssOnly = false;
+
+        if (substr($path, '-4') === '.css') {
+            $cssOnly = true;
+        }
+
+        $parser = new Parser($path, \count($this->sourceNames), $this->encoding, $this->cache, $cssOnly);
+
+        $this->sourceNames[] = $path;
+        $this->addParsedFile($path);
+
+        return $parser;
+    }
+
+    /**
+     * Is self extend?
+     *
+     * @param array $target
+     * @param array $origin
+     *
+     * @return boolean
+     */
+    protected function isSelfExtend($target, $origin)
+    {
+        foreach ($origin as $sel) {
+            if (\in_array($target, $sel)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Push extends
+     *
+     * @param array      $target
+     * @param array      $origin
+     * @param array|null $block
+     */
+    protected function pushExtends($target, $origin, $block)
+    {
+        $i = \count($this->extends);
+        $this->extends[] = [$target, $origin, $block];
+
+        foreach ($target as $part) {
+            if (isset($this->extendsMap[$part])) {
+                $this->extendsMap[$part][] = $i;
+            } else {
+                $this->extendsMap[$part] = [$i];
+            }
+        }
+    }
+
+    /**
+     * Make output block
+     *
+     * @param string $type
+     * @param array  $selectors
+     *
+     * @return \ScssPhp\ScssPhp\Formatter\OutputBlock
+     */
+    protected function makeOutputBlock($type, $selectors = null)
+    {
+        $out = new OutputBlock();
+        $out->type      = $type;
+        $out->lines     = [];
+        $out->children  = [];
+        $out->parent    = $this->scope;
+        $out->selectors = $selectors;
+        $out->depth     = $this->env->depth;
+
+        if ($this->env->block instanceof Block) {
+            $out->sourceName   = $this->env->block->sourceName;
+            $out->sourceLine   = $this->env->block->sourceLine;
+            $out->sourceColumn = $this->env->block->sourceColumn;
+        } else {
+            $out->sourceName   = null;
+            $out->sourceLine   = null;
+            $out->sourceColumn = null;
+        }
+
+        return $out;
+    }
+
+    /**
+     * Compile root
+     *
+     * @param \ScssPhp\ScssPhp\Block $rootBlock
+     */
+    protected function compileRoot(Block $rootBlock)
+    {
+        $this->rootBlock = $this->scope = $this->makeOutputBlock(Type::T_ROOT);
+
+        $this->compileChildrenNoReturn($rootBlock->children, $this->scope);
+        $this->flattenSelectors($this->scope);
+        $this->missingSelectors();
+    }
+
+    /**
+     * Report missing selectors
+     */
+    protected function missingSelectors()
+    {
+        foreach ($this->extends as $extend) {
+            if (isset($extend[3])) {
+                continue;
+            }
+
+            list($target, $origin, $block) = $extend;
+
+            // ignore if !optional
+            if ($block[2]) {
+                continue;
+            }
+
+            $target = implode(' ', $target);
+            $origin = $this->collapseSelectors($origin);
+
+            $this->sourceLine = $block[Parser::SOURCE_LINE];
+            throw $this->error("\"$origin\" failed to @extend \"$target\". The selector \"$target\" was not found.");
+        }
+    }
+
+    /**
+     * Flatten selectors
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     * @param string                                 $parentKey
+     */
+    protected function flattenSelectors(OutputBlock $block, $parentKey = null)
+    {
+        if ($block->selectors) {
+            $selectors = [];
+
+            foreach ($block->selectors as $s) {
+                $selectors[] = $s;
+
+                if (! \is_array($s)) {
+                    continue;
+                }
+
+                // check extends
+                if (! empty($this->extendsMap)) {
+                    $this->matchExtends($s, $selectors);
+
+                    // remove duplicates
+                    array_walk($selectors, function (&$value) {
+                        $value = serialize($value);
+                    });
+
+                    $selectors = array_unique($selectors);
+
+                    array_walk($selectors, function (&$value) {
+                        $value = unserialize($value);
+                    });
+                }
+            }
+
+            $block->selectors = [];
+            $placeholderSelector = false;
+
+            foreach ($selectors as $selector) {
+                if ($this->hasSelectorPlaceholder($selector)) {
+                    $placeholderSelector = true;
+                    continue;
+                }
+
+                $block->selectors[] = $this->compileSelector($selector);
+            }
+
+            if ($placeholderSelector && 0 === \count($block->selectors) && null !== $parentKey) {
+                unset($block->parent->children[$parentKey]);
+
+                return;
+            }
+        }
+
+        foreach ($block->children as $key => $child) {
+            $this->flattenSelectors($child, $key);
+        }
+    }
+
+    /**
+     * Glue parts of :not( or :nth-child( ... that are in general splitted in selectors parts
+     *
+     * @param array $parts
+     *
+     * @return array
+     */
+    protected function glueFunctionSelectors($parts)
+    {
+        $new = [];
+
+        foreach ($parts as $part) {
+            if (\is_array($part)) {
+                $part = $this->glueFunctionSelectors($part);
+                $new[] = $part;
+            } else {
+                // a selector part finishing with a ) is the last part of a :not( or :nth-child(
+                // and need to be joined to this
+                if (
+                    \count($new) && \is_string($new[\count($new) - 1]) &&
+                    \strlen($part) && substr($part, -1) === ')' && strpos($part, '(') === false
+                ) {
+                    while (\count($new) > 1 && substr($new[\count($new) - 1], -1) !== '(') {
+                        $part = array_pop($new) . $part;
+                    }
+                    $new[\count($new) - 1] .= $part;
+                } else {
+                    $new[] = $part;
+                }
+            }
+        }
+
+        return $new;
+    }
+
+    /**
+     * Match extends
+     *
+     * @param array   $selector
+     * @param array   $out
+     * @param integer $from
+     * @param boolean $initial
+     */
+    protected function matchExtends($selector, &$out, $from = 0, $initial = true)
+    {
+        static $partsPile = [];
+        $selector = $this->glueFunctionSelectors($selector);
+
+        if (\count($selector) == 1 && \in_array(reset($selector), $partsPile)) {
+            return;
+        }
+
+        $outRecurs = [];
+
+        foreach ($selector as $i => $part) {
+            if ($i < $from) {
+                continue;
+            }
+
+            // check that we are not building an infinite loop of extensions
+            // if the new part is just including a previous part don't try to extend anymore
+            if (\count($part) > 1) {
+                foreach ($partsPile as $previousPart) {
+                    if (! \count(array_diff($previousPart, $part))) {
+                        continue 2;
+                    }
+                }
+            }
+
+            $partsPile[] = $part;
+
+            if ($this->matchExtendsSingle($part, $origin, $initial)) {
+                $after       = \array_slice($selector, $i + 1);
+                $before      = \array_slice($selector, 0, $i);
+                list($before, $nonBreakableBefore) = $this->extractRelationshipFromFragment($before);
+
+                foreach ($origin as $new) {
+                    $k = 0;
+
+                    // remove shared parts
+                    if (\count($new) > 1) {
+                        while ($k < $i && isset($new[$k]) && $selector[$k] === $new[$k]) {
+                            $k++;
+                        }
+                    }
+
+                    if (\count($nonBreakableBefore) && $k === \count($new)) {
+                        $k--;
+                    }
+
+                    $replacement = [];
+                    $tempReplacement = $k > 0 ? \array_slice($new, $k) : $new;
+
+                    for ($l = \count($tempReplacement) - 1; $l >= 0; $l--) {
+                        $slice = [];
+
+                        foreach ($tempReplacement[$l] as $chunk) {
+                            if (! \in_array($chunk, $slice)) {
+                                $slice[] = $chunk;
+                            }
+                        }
+
+                        array_unshift($replacement, $slice);
+
+                        if (! $this->isImmediateRelationshipCombinator(end($slice))) {
+                            break;
+                        }
+                    }
+
+                    $afterBefore = $l != 0 ? \array_slice($tempReplacement, 0, $l) : [];
+
+                    // Merge shared direct relationships.
+                    $mergedBefore = $this->mergeDirectRelationships($afterBefore, $nonBreakableBefore);
+
+                    $result = array_merge(
+                        $before,
+                        $mergedBefore,
+                        $replacement,
+                        $after
+                    );
+
+                    if ($result === $selector) {
+                        continue;
+                    }
+
+                    $this->pushOrMergeExtentedSelector($out, $result);
+
+                    // recursively check for more matches
+                    $startRecurseFrom = \count($before) + min(\count($nonBreakableBefore), \count($mergedBefore));
+
+                    if (\count($origin) > 1) {
+                        $this->matchExtends($result, $out, $startRecurseFrom, false);
+                    } else {
+                        $this->matchExtends($result, $outRecurs, $startRecurseFrom, false);
+                    }
+
+                    // selector sequence merging
+                    if (! empty($before) && \count($new) > 1) {
+                        $preSharedParts = $k > 0 ? \array_slice($before, 0, $k) : [];
+                        $postSharedParts = $k > 0 ? \array_slice($before, $k) : $before;
+
+                        list($betweenSharedParts, $nonBreakabl2) = $this->extractRelationshipFromFragment($afterBefore);
+
+                        $result2 = array_merge(
+                            $preSharedParts,
+                            $betweenSharedParts,
+                            $postSharedParts,
+                            $nonBreakabl2,
+                            $nonBreakableBefore,
+                            $replacement,
+                            $after
+                        );
+
+                        $this->pushOrMergeExtentedSelector($out, $result2);
+                    }
+                }
+            }
+            array_pop($partsPile);
+        }
+
+        while (\count($outRecurs)) {
+            $result = array_shift($outRecurs);
+            $this->pushOrMergeExtentedSelector($out, $result);
+        }
+    }
+
+    /**
+     * Test a part for being a pseudo selector
+     *
+     * @param string $part
+     * @param array  $matches
+     *
+     * @return boolean
+     */
+    protected function isPseudoSelector($part, &$matches)
+    {
+        if (
+            strpos($part, ':') === 0 &&
+            preg_match(",^::?([\w-]+)\((.+)\)$,", $part, $matches)
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Push extended selector except if
+     *  - this is a pseudo selector
+     *  - same as previous
+     *  - in a white list
+     * in this case we merge the pseudo selector content
+     *
+     * @param array $out
+     * @param array $extended
+     */
+    protected function pushOrMergeExtentedSelector(&$out, $extended)
+    {
+        if (\count($out) && \count($extended) === 1 && \count(reset($extended)) === 1) {
+            $single = reset($extended);
+            $part = reset($single);
+
+            if (
+                $this->isPseudoSelector($part, $matchesExtended) &&
+                \in_array($matchesExtended[1], [ 'slotted' ])
+            ) {
+                $prev = end($out);
+                $prev = $this->glueFunctionSelectors($prev);
+
+                if (\count($prev) === 1 && \count(reset($prev)) === 1) {
+                    $single = reset($prev);
+                    $part = reset($single);
+
+                    if (
+                        $this->isPseudoSelector($part, $matchesPrev) &&
+                        $matchesPrev[1] === $matchesExtended[1]
+                    ) {
+                        $extended = explode($matchesExtended[1] . '(', $matchesExtended[0], 2);
+                        $extended[1] = $matchesPrev[2] . ', ' . $extended[1];
+                        $extended = implode($matchesExtended[1] . '(', $extended);
+                        $extended = [ [ $extended ]];
+                        array_pop($out);
+                    }
+                }
+            }
+        }
+        $out[] = $extended;
+    }
+
+    /**
+     * Match extends single
+     *
+     * @param array   $rawSingle
+     * @param array   $outOrigin
+     * @param boolean $initial
+     *
+     * @return boolean
+     */
+    protected function matchExtendsSingle($rawSingle, &$outOrigin, $initial = true)
+    {
+        $counts = [];
+        $single = [];
+
+        // simple usual cases, no need to do the whole trick
+        if (\in_array($rawSingle, [['>'],['+'],['~']])) {
+            return false;
+        }
+
+        foreach ($rawSingle as $part) {
+            // matches Number
+            if (! \is_string($part)) {
+                return false;
+            }
+
+            if (! preg_match('/^[\[.:#%]/', $part) && \count($single)) {
+                $single[\count($single) - 1] .= $part;
+            } else {
+                $single[] = $part;
+            }
+        }
+
+        $extendingDecoratedTag = false;
+
+        if (\count($single) > 1) {
+            $matches = null;
+            $extendingDecoratedTag = preg_match('/^[a-z0-9]+$/i', $single[0], $matches) ? $matches[0] : false;
+        }
+
+        $outOrigin = [];
+        $found = false;
+
+        foreach ($single as $k => $part) {
+            if (isset($this->extendsMap[$part])) {
+                foreach ($this->extendsMap[$part] as $idx) {
+                    $counts[$idx] = isset($counts[$idx]) ? $counts[$idx] + 1 : 1;
+                }
+            }
+
+            if (
+                $initial &&
+                $this->isPseudoSelector($part, $matches) &&
+                ! \in_array($matches[1], [ 'not' ])
+            ) {
+                $buffer    = $matches[2];
+                $parser    = $this->parserFactory(__METHOD__);
+
+                if ($parser->parseSelector($buffer, $subSelectors, false)) {
+                    foreach ($subSelectors as $ksub => $subSelector) {
+                        $subExtended = [];
+                        $this->matchExtends($subSelector, $subExtended, 0, false);
+
+                        if ($subExtended) {
+                            $subSelectorsExtended = $subSelectors;
+                            $subSelectorsExtended[$ksub] = $subExtended;
+
+                            foreach ($subSelectorsExtended as $ksse => $sse) {
+                                $subSelectorsExtended[$ksse] = $this->collapseSelectors($sse);
+                            }
+
+                            $subSelectorsExtended = implode(', ', $subSelectorsExtended);
+                            $singleExtended = $single;
+                            $singleExtended[$k] = str_replace('(' . $buffer . ')', "($subSelectorsExtended)", $part);
+                            $outOrigin[] = [ $singleExtended ];
+                            $found = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        foreach ($counts as $idx => $count) {
+            list($target, $origin, /* $block */) = $this->extends[$idx];
+
+            $origin = $this->glueFunctionSelectors($origin);
+
+            // check count
+            if ($count !== \count($target)) {
+                continue;
+            }
+
+            $this->extends[$idx][3] = true;
+
+            $rem = array_diff($single, $target);
+
+            foreach ($origin as $j => $new) {
+                // prevent infinite loop when target extends itself
+                if ($this->isSelfExtend($single, $origin) && ! $initial) {
+                    return false;
+                }
+
+                $replacement = end($new);
+
+                // Extending a decorated tag with another tag is not possible.
+                if (
+                    $extendingDecoratedTag && $replacement[0] != $extendingDecoratedTag &&
+                    preg_match('/^[a-z0-9]+$/i', $replacement[0])
+                ) {
+                    unset($origin[$j]);
+                    continue;
+                }
+
+                $combined = $this->combineSelectorSingle($replacement, $rem);
+
+                if (\count(array_diff($combined, $origin[$j][\count($origin[$j]) - 1]))) {
+                    $origin[$j][\count($origin[$j]) - 1] = $combined;
+                }
+            }
+
+            $outOrigin = array_merge($outOrigin, $origin);
+
+            $found = true;
+        }
+
+        return $found;
+    }
+
+    /**
+     * Extract a relationship from the fragment.
+     *
+     * When extracting the last portion of a selector we will be left with a
+     * fragment which may end with a direction relationship combinator. This
+     * method will extract the relationship fragment and return it along side
+     * the rest.
+     *
+     * @param array $fragment The selector fragment maybe ending with a direction relationship combinator.
+     *
+     * @return array The selector without the relationship fragment if any, the relationship fragment.
+     */
+    protected function extractRelationshipFromFragment(array $fragment)
+    {
+        $parents = [];
+        $children = [];
+
+        $j = $i = \count($fragment);
+
+        for (;;) {
+            $children = $j != $i ? \array_slice($fragment, $j, $i - $j) : [];
+            $parents  = \array_slice($fragment, 0, $j);
+            $slice    = end($parents);
+
+            if (empty($slice) || ! $this->isImmediateRelationshipCombinator($slice[0])) {
+                break;
+            }
+
+            $j -= 2;
+        }
+
+        return [$parents, $children];
+    }
+
+    /**
+     * Combine selector single
+     *
+     * @param array $base
+     * @param array $other
+     *
+     * @return array
+     */
+    protected function combineSelectorSingle($base, $other)
+    {
+        $tag    = [];
+        $out    = [];
+        $wasTag = false;
+        $pseudo = [];
+
+        while (\count($other) && strpos(end($other), ':') === 0) {
+            array_unshift($pseudo, array_pop($other));
+        }
+
+        foreach ([array_reverse($base), array_reverse($other)] as $single) {
+            $rang = count($single);
+
+            foreach ($single as $part) {
+                if (preg_match('/^[\[:]/', $part)) {
+                    $out[] = $part;
+                    $wasTag = false;
+                } elseif (preg_match('/^[\.#]/', $part)) {
+                    array_unshift($out, $part);
+                    $wasTag = false;
+                } elseif (preg_match('/^[^_-]/', $part) && $rang === 1) {
+                    $tag[] = $part;
+                    $wasTag = true;
+                } elseif ($wasTag) {
+                    $tag[\count($tag) - 1] .= $part;
+                } else {
+                    array_unshift($out, $part);
+                }
+                $rang--;
+            }
+        }
+
+        if (\count($tag)) {
+            array_unshift($out, $tag[0]);
+        }
+
+        while (\count($pseudo)) {
+            $out[] = array_shift($pseudo);
+        }
+
+        return $out;
+    }
+
+    /**
+     * Compile media
+     *
+     * @param \ScssPhp\ScssPhp\Block $media
+     */
+    protected function compileMedia(Block $media)
+    {
+        $this->pushEnv($media);
+
+        $mediaQueries = $this->compileMediaQuery($this->multiplyMedia($this->env));
+
+        if (! empty($mediaQueries) && $mediaQueries) {
+            $previousScope = $this->scope;
+            $parentScope = $this->mediaParent($this->scope);
+
+            foreach ($mediaQueries as $mediaQuery) {
+                $this->scope = $this->makeOutputBlock(Type::T_MEDIA, [$mediaQuery]);
+
+                $parentScope->children[] = $this->scope;
+                $parentScope = $this->scope;
+            }
+
+            // top level properties in a media cause it to be wrapped
+            $needsWrap = false;
+
+            foreach ($media->children as $child) {
+                $type = $child[0];
+
+                if (
+                    $type !== Type::T_BLOCK &&
+                    $type !== Type::T_MEDIA &&
+                    $type !== Type::T_DIRECTIVE &&
+                    $type !== Type::T_IMPORT
+                ) {
+                    $needsWrap = true;
+                    break;
+                }
+            }
+
+            if ($needsWrap) {
+                $wrapped = new Block();
+                $wrapped->sourceName   = $media->sourceName;
+                $wrapped->sourceIndex  = $media->sourceIndex;
+                $wrapped->sourceLine   = $media->sourceLine;
+                $wrapped->sourceColumn = $media->sourceColumn;
+                $wrapped->selectors    = [];
+                $wrapped->comments     = [];
+                $wrapped->parent       = $media;
+                $wrapped->children     = $media->children;
+
+                $media->children = [[Type::T_BLOCK, $wrapped]];
+            }
+
+            $this->compileChildrenNoReturn($media->children, $this->scope);
+
+            $this->scope = $previousScope;
+        }
+
+        $this->popEnv();
+    }
+
+    /**
+     * Media parent
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+     *
+     * @return \ScssPhp\ScssPhp\Formatter\OutputBlock
+     */
+    protected function mediaParent(OutputBlock $scope)
+    {
+        while (! empty($scope->parent)) {
+            if (! empty($scope->type) && $scope->type !== Type::T_MEDIA) {
+                break;
+            }
+
+            $scope = $scope->parent;
+        }
+
+        return $scope;
+    }
+
+    /**
+     * Compile directive
+     *
+     * @param \ScssPhp\ScssPhp\Block|array $block
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     */
+    protected function compileDirective($directive, OutputBlock $out)
+    {
+        if (\is_array($directive)) {
+            $directiveName = $this->compileDirectiveName($directive[0]);
+            $s = '@' . $directiveName;
+
+            if (! empty($directive[1])) {
+                $s .= ' ' . $this->compileValue($directive[1]);
+            }
+            // sass-spec compliance on newline after directives, a bit tricky :/
+            $appendNewLine = (! empty($directive[2]) || strpos($s, "\n")) ? "\n" : "";
+            if (\is_array($directive[0]) && empty($directive[1])) {
+                $appendNewLine = "\n";
+            }
+
+            if (empty($directive[3])) {
+                $this->appendRootDirective($s . ';' . $appendNewLine, $out, [Type::T_COMMENT, Type::T_DIRECTIVE]);
+            } else {
+                $this->appendOutputLine($out, Type::T_DIRECTIVE, $s . ';');
+            }
+        } else {
+            $directive->name = $this->compileDirectiveName($directive->name);
+            $s = '@' . $directive->name;
+
+            if (! empty($directive->value)) {
+                $s .= ' ' . $this->compileValue($directive->value);
+            }
+
+            if ($directive->name === 'keyframes' || substr($directive->name, -10) === '-keyframes') {
+                $this->compileKeyframeBlock($directive, [$s]);
+            } else {
+                $this->compileNestedBlock($directive, [$s]);
+            }
+        }
+    }
+
+    /**
+     * directive names can include some interpolation
+     *
+     * @param string|array $directiveName
+     * @return array|string
+     * @throws CompilerException
+     */
+    protected function compileDirectiveName($directiveName)
+    {
+        if (is_string($directiveName)) {
+            return $directiveName;
+        }
+
+        return $this->compileValue($directiveName);
+    }
+
+    /**
+     * Compile at-root
+     *
+     * @param \ScssPhp\ScssPhp\Block $block
+     */
+    protected function compileAtRoot(Block $block)
+    {
+        $env     = $this->pushEnv($block);
+        $envs    = $this->compactEnv($env);
+        list($with, $without) = $this->compileWith(isset($block->with) ? $block->with : null);
+
+        // wrap inline selector
+        if ($block->selector) {
+            $wrapped = new Block();
+            $wrapped->sourceName   = $block->sourceName;
+            $wrapped->sourceIndex  = $block->sourceIndex;
+            $wrapped->sourceLine   = $block->sourceLine;
+            $wrapped->sourceColumn = $block->sourceColumn;
+            $wrapped->selectors    = $block->selector;
+            $wrapped->comments     = [];
+            $wrapped->parent       = $block;
+            $wrapped->children     = $block->children;
+            $wrapped->selfParent   = $block->selfParent;
+
+            $block->children = [[Type::T_BLOCK, $wrapped]];
+            $block->selector = null;
+        }
+
+        $selfParent = $block->selfParent;
+
+        if (
+            ! $block->selfParent->selectors &&
+            isset($block->parent) && $block->parent &&
+            isset($block->parent->selectors) && $block->parent->selectors
+        ) {
+            $selfParent = $block->parent;
+        }
+
+        $this->env = $this->filterWithWithout($envs, $with, $without);
+
+        $saveScope   = $this->scope;
+        $this->scope = $this->filterScopeWithWithout($saveScope, $with, $without);
+
+        // propagate selfParent to the children where they still can be useful
+        $this->compileChildrenNoReturn($block->children, $this->scope, $selfParent);
+
+        $this->scope = $this->completeScope($this->scope, $saveScope);
+        $this->scope = $saveScope;
+        $this->env   = $this->extractEnv($envs);
+
+        $this->popEnv();
+    }
+
+    /**
+     * Filter at-root scope depending of with/without option
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+     * @param array                                  $with
+     * @param array                                  $without
+     *
+     * @return mixed
+     */
+    protected function filterScopeWithWithout($scope, $with, $without)
+    {
+        $filteredScopes = [];
+        $childStash = [];
+
+        if ($scope->type === TYPE::T_ROOT) {
+            return $scope;
+        }
+
+        // start from the root
+        while ($scope->parent && $scope->parent->type !== TYPE::T_ROOT) {
+            array_unshift($childStash, $scope);
+            $scope = $scope->parent;
+        }
+
+        for (;;) {
+            if (! $scope) {
+                break;
+            }
+
+            if ($this->isWith($scope, $with, $without)) {
+                $s = clone $scope;
+                $s->children = [];
+                $s->lines    = [];
+                $s->parent   = null;
+
+                if ($s->type !== Type::T_MEDIA && $s->type !== Type::T_DIRECTIVE) {
+                    $s->selectors = [];
+                }
+
+                $filteredScopes[] = $s;
+            }
+
+            if (\count($childStash)) {
+                $scope = array_shift($childStash);
+            } elseif ($scope->children) {
+                $scope = end($scope->children);
+            } else {
+                $scope = null;
+            }
+        }
+
+        if (! \count($filteredScopes)) {
+            return $this->rootBlock;
+        }
+
+        $newScope = array_shift($filteredScopes);
+        $newScope->parent = $this->rootBlock;
+
+        $this->rootBlock->children[] = $newScope;
+
+        $p = &$newScope;
+
+        while (\count($filteredScopes)) {
+            $s = array_shift($filteredScopes);
+            $s->parent = $p;
+            $p->children[] = $s;
+            $newScope = &$p->children[0];
+            $p = &$p->children[0];
+        }
+
+        return $newScope;
+    }
+
+    /**
+     * found missing selector from a at-root compilation in the previous scope
+     * (if at-root is just enclosing a property, the selector is in the parent tree)
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $previousScope
+     *
+     * @return mixed
+     */
+    protected function completeScope($scope, $previousScope)
+    {
+        if (! $scope->type && (! $scope->selectors || ! \count($scope->selectors)) && \count($scope->lines)) {
+            $scope->selectors = $this->findScopeSelectors($previousScope, $scope->depth);
+        }
+
+        if ($scope->children) {
+            foreach ($scope->children as $k => $c) {
+                $scope->children[$k] = $this->completeScope($c, $previousScope);
+            }
+        }
+
+        return $scope;
+    }
+
+    /**
+     * Find a selector by the depth node in the scope
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope
+     * @param integer                                $depth
+     *
+     * @return array
+     */
+    protected function findScopeSelectors($scope, $depth)
+    {
+        if ($scope->depth === $depth && $scope->selectors) {
+            return $scope->selectors;
+        }
+
+        if ($scope->children) {
+            foreach (array_reverse($scope->children) as $c) {
+                if ($s = $this->findScopeSelectors($c, $depth)) {
+                    return $s;
+                }
+            }
+        }
+
+        return [];
+    }
+
+    /**
+     * Compile @at-root's with: inclusion / without: exclusion into 2 lists uses to filter scope/env later
+     *
+     * @param array $withCondition
+     *
+     * @return array
+     */
+    protected function compileWith($withCondition)
+    {
+        // just compile what we have in 2 lists
+        $with = [];
+        $without = ['rule' => true];
+
+        if ($withCondition) {
+            if ($withCondition[0] === Type::T_INTERPOLATE) {
+                $w = $this->compileValue($withCondition);
+
+                $buffer = "($w)";
+                $parser = $this->parserFactory(__METHOD__);
+
+                if ($parser->parseValue($buffer, $reParsedWith)) {
+                    $withCondition = $reParsedWith;
+                }
+            }
+
+            if ($this->libMapHasKey([$withCondition, static::$with])) {
+                $without = []; // cancel the default
+                $list = $this->coerceList($this->libMapGet([$withCondition, static::$with]));
+
+                foreach ($list[2] as $item) {
+                    $keyword = $this->compileStringContent($this->coerceString($item));
+
+                    $with[$keyword] = true;
+                }
+            }
+
+            if ($this->libMapHasKey([$withCondition, static::$without])) {
+                $without = []; // cancel the default
+                $list = $this->coerceList($this->libMapGet([$withCondition, static::$without]));
+
+                foreach ($list[2] as $item) {
+                    $keyword = $this->compileStringContent($this->coerceString($item));
+
+                    $without[$keyword] = true;
+                }
+            }
+        }
+
+        return [$with, $without];
+    }
+
+    /**
+     * Filter env stack
+     *
+     * @param array $envs
+     * @param array $with
+     * @param array $without
+     *
+     * @return \ScssPhp\ScssPhp\Compiler\Environment
+     */
+    protected function filterWithWithout($envs, $with, $without)
+    {
+        $filtered = [];
+
+        foreach ($envs as $e) {
+            if ($e->block && ! $this->isWith($e->block, $with, $without)) {
+                $ec = clone $e;
+                $ec->block     = null;
+                $ec->selectors = [];
+
+                $filtered[] = $ec;
+            } else {
+                $filtered[] = $e;
+            }
+        }
+
+        return $this->extractEnv($filtered);
+    }
+
+    /**
+     * Filter WITH rules
+     *
+     * @param \ScssPhp\ScssPhp\Block|\ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     * @param array                                                         $with
+     * @param array                                                         $without
+     *
+     * @return boolean
+     */
+    protected function isWith($block, $with, $without)
+    {
+        if (isset($block->type)) {
+            if ($block->type === Type::T_MEDIA) {
+                return $this->testWithWithout('media', $with, $without);
+            }
+
+            if ($block->type === Type::T_DIRECTIVE) {
+                if (isset($block->name)) {
+                    return $this->testWithWithout($this->compileDirectiveName($block->name), $with, $without);
+                } elseif (isset($block->selectors) && preg_match(',@(\w+),ims', json_encode($block->selectors), $m)) {
+                    return $this->testWithWithout($m[1], $with, $without);
+                } else {
+                    return $this->testWithWithout('???', $with, $without);
+                }
+            }
+        } elseif (isset($block->selectors)) {
+            // a selector starting with number is a keyframe rule
+            if (\count($block->selectors)) {
+                $s = reset($block->selectors);
+
+                while (\is_array($s)) {
+                    $s = reset($s);
+                }
+
+                if (\is_object($s) && $s instanceof Number) {
+                    return $this->testWithWithout('keyframes', $with, $without);
+                }
+            }
+
+            return $this->testWithWithout('rule', $with, $without);
+        }
+
+        return true;
+    }
+
+    /**
+     * Test a single type of block against with/without lists
+     *
+     * @param string $what
+     * @param array  $with
+     * @param array  $without
+     *
+     * @return boolean
+     *   true if the block should be kept, false to reject
+     */
+    protected function testWithWithout($what, $with, $without)
+    {
+        // if without, reject only if in the list (or 'all' is in the list)
+        if (\count($without)) {
+            return (isset($without[$what]) || isset($without['all'])) ? false : true;
+        }
+
+        // otherwise reject all what is not in the with list
+        return (isset($with[$what]) || isset($with['all'])) ? true : false;
+    }
+
+
+    /**
+     * Compile keyframe block
+     *
+     * @param \ScssPhp\ScssPhp\Block $block
+     * @param array                  $selectors
+     */
+    protected function compileKeyframeBlock(Block $block, $selectors)
+    {
+        $env = $this->pushEnv($block);
+
+        $envs = $this->compactEnv($env);
+
+        $this->env = $this->extractEnv(array_filter($envs, function (Environment $e) {
+            return ! isset($e->block->selectors);
+        }));
+
+        $this->scope = $this->makeOutputBlock($block->type, $selectors);
+        $this->scope->depth = 1;
+        $this->scope->parent->children[] = $this->scope;
+
+        $this->compileChildrenNoReturn($block->children, $this->scope);
+
+        $this->scope = $this->scope->parent;
+        $this->env   = $this->extractEnv($envs);
+
+        $this->popEnv();
+    }
+
+    /**
+     * Compile nested properties lines
+     *
+     * @param \ScssPhp\ScssPhp\Block                 $block
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     */
+    protected function compileNestedPropertiesBlock(Block $block, OutputBlock $out)
+    {
+        $prefix = $this->compileValue($block->prefix) . '-';
+
+        $nested = $this->makeOutputBlock($block->type);
+        $nested->parent = $out;
+
+        if ($block->hasValue) {
+            $nested->depth = $out->depth + 1;
+        }
+
+        $out->children[] = $nested;
+
+        foreach ($block->children as $child) {
+            switch ($child[0]) {
+                case Type::T_ASSIGN:
+                    array_unshift($child[1][2], $prefix);
+                    break;
+
+                case Type::T_NESTED_PROPERTY:
+                    array_unshift($child[1]->prefix[2], $prefix);
+                    break;
+            }
+
+            $this->compileChild($child, $nested);
+        }
+    }
+
+    /**
+     * Compile nested block
+     *
+     * @param \ScssPhp\ScssPhp\Block $block
+     * @param array                  $selectors
+     */
+    protected function compileNestedBlock(Block $block, $selectors)
+    {
+        $this->pushEnv($block);
+
+        $this->scope = $this->makeOutputBlock($block->type, $selectors);
+        $this->scope->parent->children[] = $this->scope;
+
+        // wrap assign children in a block
+        // except for @font-face
+        if ($block->type !== Type::T_DIRECTIVE || $this->compileDirectiveName($block->name) !== 'font-face') {
+            // need wrapping?
+            $needWrapping = false;
+
+            foreach ($block->children as $child) {
+                if ($child[0] === Type::T_ASSIGN) {
+                    $needWrapping = true;
+                    break;
+                }
+            }
+
+            if ($needWrapping) {
+                $wrapped = new Block();
+                $wrapped->sourceName   = $block->sourceName;
+                $wrapped->sourceIndex  = $block->sourceIndex;
+                $wrapped->sourceLine   = $block->sourceLine;
+                $wrapped->sourceColumn = $block->sourceColumn;
+                $wrapped->selectors    = [];
+                $wrapped->comments     = [];
+                $wrapped->parent       = $block;
+                $wrapped->children     = $block->children;
+                $wrapped->selfParent   = $block->selfParent;
+
+                $block->children = [[Type::T_BLOCK, $wrapped]];
+            }
+        }
+
+        $this->compileChildrenNoReturn($block->children, $this->scope);
+
+        $this->scope = $this->scope->parent;
+
+        $this->popEnv();
+    }
+
+    /**
+     * Recursively compiles a block.
+     *
+     * A block is analogous to a CSS block in most cases. A single SCSS document
+     * is encapsulated in a block when parsed, but it does not have parent tags
+     * so all of its children appear on the root level when compiled.
+     *
+     * Blocks are made up of selectors and children.
+     *
+     * The children of a block are just all the blocks that are defined within.
+     *
+     * Compiling the block involves pushing a fresh environment on the stack,
+     * and iterating through the props, compiling each one.
+     *
+     * @see Compiler::compileChild()
+     *
+     * @param \ScssPhp\ScssPhp\Block $block
+     */
+    protected function compileBlock(Block $block)
+    {
+        $env = $this->pushEnv($block);
+        $env->selectors = $this->evalSelectors($block->selectors);
+
+        $out = $this->makeOutputBlock(null);
+
+        $this->scope->children[] = $out;
+
+        if (\count($block->children)) {
+            $out->selectors = $this->multiplySelectors($env, $block->selfParent);
+
+            // propagate selfParent to the children where they still can be useful
+            $selfParentSelectors = null;
+
+            if (isset($block->selfParent->selectors)) {
+                $selfParentSelectors = $block->selfParent->selectors;
+                $block->selfParent->selectors = $out->selectors;
+            }
+
+            $this->compileChildrenNoReturn($block->children, $out, $block->selfParent);
+
+            // and revert for the following children of the same block
+            if ($selfParentSelectors) {
+                $block->selfParent->selectors = $selfParentSelectors;
+            }
+        }
+
+        $this->popEnv();
+    }
+
+
+    /**
+     * Compile the value of a comment that can have interpolation
+     *
+     * @param array   $value
+     * @param boolean $pushEnv
+     *
+     * @return array|mixed|string
+     */
+    protected function compileCommentValue($value, $pushEnv = false)
+    {
+        $c = $value[1];
+
+        if (isset($value[2])) {
+            if ($pushEnv) {
+                $this->pushEnv();
+            }
+
+            $ignoreCallStackMessage = $this->ignoreCallStackMessage;
+            $this->ignoreCallStackMessage = true;
+
+            try {
+                $c = $this->compileValue($value[2]);
+            } catch (\Exception $e) {
+                // ignore error in comment compilation which are only interpolation
+            }
+
+            $this->ignoreCallStackMessage = $ignoreCallStackMessage;
+
+            if ($pushEnv) {
+                $this->popEnv();
+            }
+        }
+
+        return $c;
+    }
+
+    /**
+     * Compile root level comment
+     *
+     * @param array $block
+     */
+    protected function compileComment($block)
+    {
+        $out = $this->makeOutputBlock(Type::T_COMMENT);
+        $out->lines[] = $this->compileCommentValue($block, true);
+
+        $this->scope->children[] = $out;
+    }
+
+    /**
+     * Evaluate selectors
+     *
+     * @param array $selectors
+     *
+     * @return array
+     */
+    protected function evalSelectors($selectors)
+    {
+        $this->shouldEvaluate = false;
+
+        $selectors = array_map([$this, 'evalSelector'], $selectors);
+
+        // after evaluating interpolates, we might need a second pass
+        if ($this->shouldEvaluate) {
+            $selectors = $this->replaceSelfSelector($selectors, '&');
+            $buffer    = $this->collapseSelectors($selectors);
+            $parser    = $this->parserFactory(__METHOD__);
+
+            if ($parser->parseSelector($buffer, $newSelectors, true)) {
+                $selectors = array_map([$this, 'evalSelector'], $newSelectors);
+            }
+        }
+
+        return $selectors;
+    }
+
+    /**
+     * Evaluate selector
+     *
+     * @param array $selector
+     *
+     * @return array
+     */
+    protected function evalSelector($selector)
+    {
+        return array_map([$this, 'evalSelectorPart'], $selector);
+    }
+
+    /**
+     * Evaluate selector part; replaces all the interpolates, stripping quotes
+     *
+     * @param array $part
+     *
+     * @return array
+     */
+    protected function evalSelectorPart($part)
+    {
+        foreach ($part as &$p) {
+            if (\is_array($p) && ($p[0] === Type::T_INTERPOLATE || $p[0] === Type::T_STRING)) {
+                $p = $this->compileValue($p);
+
+                // force re-evaluation if self char or non standard char
+                if (preg_match(',[^\w-],', $p)) {
+                    $this->shouldEvaluate = true;
+                }
+            } elseif (
+                \is_string($p) && \strlen($p) >= 2 &&
+                ($first = $p[0]) && ($first === '"' || $first === "'") &&
+                substr($p, -1) === $first
+            ) {
+                $p = substr($p, 1, -1);
+            }
+        }
+
+        return $this->flattenSelectorSingle($part);
+    }
+
+    /**
+     * Collapse selectors
+     *
+     * @param array   $selectors
+     * @param boolean $selectorFormat
+     *   if false return a collapsed string
+     *   if true return an array description of a structured selector
+     *
+     * @return string
+     */
+    protected function collapseSelectors($selectors, $selectorFormat = false)
+    {
+        $parts = [];
+
+        foreach ($selectors as $selector) {
+            $output = [];
+            $glueNext = false;
+
+            foreach ($selector as $node) {
+                $compound = '';
+
+                array_walk_recursive(
+                    $node,
+                    function ($value, $key) use (&$compound) {
+                        $compound .= $value;
+                    }
+                );
+
+                if ($selectorFormat && $this->isImmediateRelationshipCombinator($compound)) {
+                    if (\count($output)) {
+                        $output[\count($output) - 1] .= ' ' . $compound;
+                    } else {
+                        $output[] = $compound;
+                    }
+
+                    $glueNext = true;
+                } elseif ($glueNext) {
+                    $output[\count($output) - 1] .= ' ' . $compound;
+                    $glueNext = false;
+                } else {
+                    $output[] = $compound;
+                }
+            }
+
+            if ($selectorFormat) {
+                foreach ($output as &$o) {
+                    $o = [Type::T_STRING, '', [$o]];
+                }
+
+                $output = [Type::T_LIST, ' ', $output];
+            } else {
+                $output = implode(' ', $output);
+            }
+
+            $parts[] = $output;
+        }
+
+        if ($selectorFormat) {
+            $parts = [Type::T_LIST, ',', $parts];
+        } else {
+            $parts = implode(', ', $parts);
+        }
+
+        return $parts;
+    }
+
+    /**
+     * Parse down the selector and revert [self] to "&" before a reparsing
+     *
+     * @param array $selectors
+     *
+     * @return array
+     */
+    protected function replaceSelfSelector($selectors, $replace = null)
+    {
+        foreach ($selectors as &$part) {
+            if (\is_array($part)) {
+                if ($part === [Type::T_SELF]) {
+                    if (\is_null($replace)) {
+                        $replace = $this->reduce([Type::T_SELF]);
+                        $replace = $this->compileValue($replace);
+                    }
+                    $part = $replace;
+                } else {
+                    $part = $this->replaceSelfSelector($part, $replace);
+                }
+            }
+        }
+
+        return $selectors;
+    }
+
+    /**
+     * Flatten selector single; joins together .classes and #ids
+     *
+     * @param array $single
+     *
+     * @return array
+     */
+    protected function flattenSelectorSingle($single)
+    {
+        $joined = [];
+
+        foreach ($single as $part) {
+            if (
+                empty($joined) ||
+                ! \is_string($part) ||
+                preg_match('/[\[.:#%]/', $part)
+            ) {
+                $joined[] = $part;
+                continue;
+            }
+
+            if (\is_array(end($joined))) {
+                $joined[] = $part;
+            } else {
+                $joined[\count($joined) - 1] .= $part;
+            }
+        }
+
+        return $joined;
+    }
+
+    /**
+     * Compile selector to string; self(&) should have been replaced by now
+     *
+     * @param string|array $selector
+     *
+     * @return string
+     */
+    protected function compileSelector($selector)
+    {
+        if (! \is_array($selector)) {
+            return $selector; // media and the like
+        }
+
+        return implode(
+            ' ',
+            array_map(
+                [$this, 'compileSelectorPart'],
+                $selector
+            )
+        );
+    }
+
+    /**
+     * Compile selector part
+     *
+     * @param array $piece
+     *
+     * @return string
+     */
+    protected function compileSelectorPart($piece)
+    {
+        foreach ($piece as &$p) {
+            if (! \is_array($p)) {
+                continue;
+            }
+
+            switch ($p[0]) {
+                case Type::T_SELF:
+                    $p = '&';
+                    break;
+
+                default:
+                    $p = $this->compileValue($p);
+                    break;
+            }
+        }
+
+        return implode($piece);
+    }
+
+    /**
+     * Has selector placeholder?
+     *
+     * @param array $selector
+     *
+     * @return boolean
+     */
+    protected function hasSelectorPlaceholder($selector)
+    {
+        if (! \is_array($selector)) {
+            return false;
+        }
+
+        foreach ($selector as $parts) {
+            foreach ($parts as $part) {
+                if (\strlen($part) && '%' === $part[0]) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    protected function pushCallStack($name = '')
+    {
+        $this->callStack[] = [
+          'n' => $name,
+          Parser::SOURCE_INDEX => $this->sourceIndex,
+          Parser::SOURCE_LINE => $this->sourceLine,
+          Parser::SOURCE_COLUMN => $this->sourceColumn
+        ];
+
+        // infinite calling loop
+        if (\count($this->callStack) > 25000) {
+            // not displayed but you can var_dump it to deep debug
+            $msg = $this->callStackMessage(true, 100);
+            $msg = 'Infinite calling loop';
+
+            throw $this->error($msg);
+        }
+    }
+
+    protected function popCallStack()
+    {
+        array_pop($this->callStack);
+    }
+
+    /**
+     * Compile children and return result
+     *
+     * @param array                                  $stms
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     * @param string                                 $traceName
+     *
+     * @return array|null
+     */
+    protected function compileChildren($stms, OutputBlock $out, $traceName = '')
+    {
+        $this->pushCallStack($traceName);
+
+        foreach ($stms as $stm) {
+            $ret = $this->compileChild($stm, $out);
+
+            if (isset($ret)) {
+                $this->popCallStack();
+
+                return $ret;
+            }
+        }
+
+        $this->popCallStack();
+
+        return null;
+    }
+
+    /**
+     * Compile children and throw exception if unexpected @return
+     *
+     * @param array                                  $stms
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     * @param \ScssPhp\ScssPhp\Block                 $selfParent
+     * @param string                                 $traceName
+     *
+     * @throws \Exception
+     */
+    protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null, $traceName = '')
+    {
+        $this->pushCallStack($traceName);
+
+        foreach ($stms as $stm) {
+            if ($selfParent && isset($stm[1]) && \is_object($stm[1]) && $stm[1] instanceof Block) {
+                $stm[1]->selfParent = $selfParent;
+                $ret = $this->compileChild($stm, $out);
+                $stm[1]->selfParent = null;
+            } elseif ($selfParent && \in_array($stm[0], [TYPE::T_INCLUDE, TYPE::T_EXTEND])) {
+                $stm['selfParent'] = $selfParent;
+                $ret = $this->compileChild($stm, $out);
+                unset($stm['selfParent']);
+            } else {
+                $ret = $this->compileChild($stm, $out);
+            }
+
+            if (isset($ret)) {
+                throw $this->error('@return may only be used within a function');
+            }
+        }
+
+        $this->popCallStack();
+    }
+
+
+    /**
+     * evaluate media query : compile internal value keeping the structure inchanged
+     *
+     * @param array $queryList
+     *
+     * @return array
+     */
+    protected function evaluateMediaQuery($queryList)
+    {
+        static $parser = null;
+
+        $outQueryList = [];
+
+        foreach ($queryList as $kql => $query) {
+            $shouldReparse = false;
+
+            foreach ($query as $kq => $q) {
+                for ($i = 1; $i < \count($q); $i++) {
+                    $value = $this->compileValue($q[$i]);
+
+                    // the parser had no mean to know if media type or expression if it was an interpolation
+                    // so you need to reparse if the T_MEDIA_TYPE looks like anything else a media type
+                    if (
+                        $q[0] == Type::T_MEDIA_TYPE &&
+                        (strpos($value, '(') !== false ||
+                        strpos($value, ')') !== false ||
+                        strpos($value, ':') !== false ||
+                        strpos($value, ',') !== false)
+                    ) {
+                        $shouldReparse = true;
+                    }
+
+                    $queryList[$kql][$kq][$i] = [Type::T_KEYWORD, $value];
+                }
+            }
+
+            if ($shouldReparse) {
+                if (\is_null($parser)) {
+                    $parser = $this->parserFactory(__METHOD__);
+                }
+
+                $queryString = $this->compileMediaQuery([$queryList[$kql]]);
+                $queryString = reset($queryString);
+
+                if (strpos($queryString, '@media ') === 0) {
+                    $queryString = substr($queryString, 7);
+                    $queries = [];
+
+                    if ($parser->parseMediaQueryList($queryString, $queries)) {
+                        $queries = $this->evaluateMediaQuery($queries[2]);
+
+                        while (\count($queries)) {
+                            $outQueryList[] = array_shift($queries);
+                        }
+
+                        continue;
+                    }
+                }
+            }
+
+            $outQueryList[] = $queryList[$kql];
+        }
+
+        return $outQueryList;
+    }
+
+    /**
+     * Compile media query
+     *
+     * @param array $queryList
+     *
+     * @return array
+     */
+    protected function compileMediaQuery($queryList)
+    {
+        $start   = '@media ';
+        $default = trim($start);
+        $out     = [];
+        $current = '';
+
+        foreach ($queryList as $query) {
+            $type = null;
+            $parts = [];
+
+            $mediaTypeOnly = true;
+
+            foreach ($query as $q) {
+                if ($q[0] !== Type::T_MEDIA_TYPE) {
+                    $mediaTypeOnly = false;
+                    break;
+                }
+            }
+
+            foreach ($query as $q) {
+                switch ($q[0]) {
+                    case Type::T_MEDIA_TYPE:
+                        $newType = array_map([$this, 'compileValue'], \array_slice($q, 1));
+
+                        // combining not and anything else than media type is too risky and should be avoided
+                        if (! $mediaTypeOnly) {
+                            if (\in_array(Type::T_NOT, $newType) || ($type && \in_array(Type::T_NOT, $type) )) {
+                                if ($type) {
+                                    array_unshift($parts, implode(' ', array_filter($type)));
+                                }
+
+                                if (! empty($parts)) {
+                                    if (\strlen($current)) {
+                                        $current .= $this->formatter->tagSeparator;
+                                    }
+
+                                    $current .= implode(' and ', $parts);
+                                }
+
+                                if ($current) {
+                                    $out[] = $start . $current;
+                                }
+
+                                $current = '';
+                                $type    = null;
+                                $parts   = [];
+                            }
+                        }
+
+                        if ($newType === ['all'] && $default) {
+                            $default = $start . 'all';
+                        }
+
+                        // all can be safely ignored and mixed with whatever else
+                        if ($newType !== ['all']) {
+                            if ($type) {
+                                $type = $this->mergeMediaTypes($type, $newType);
+
+                                if (empty($type)) {
+                                    // merge failed : ignore this query that is not valid, skip to the next one
+                                    $parts = [];
+                                    $default = ''; // if everything fail, no @media at all
+                                    continue 3;
+                                }
+                            } else {
+                                $type = $newType;
+                            }
+                        }
+                        break;
+
+                    case Type::T_MEDIA_EXPRESSION:
+                        if (isset($q[2])) {
+                            $parts[] = '('
+                                . $this->compileValue($q[1])
+                                . $this->formatter->assignSeparator
+                                . $this->compileValue($q[2])
+                                . ')';
+                        } else {
+                            $parts[] = '('
+                                . $this->compileValue($q[1])
+                                . ')';
+                        }
+                        break;
+
+                    case Type::T_MEDIA_VALUE:
+                        $parts[] = $this->compileValue($q[1]);
+                        break;
+                }
+            }
+
+            if ($type) {
+                array_unshift($parts, implode(' ', array_filter($type)));
+            }
+
+            if (! empty($parts)) {
+                if (\strlen($current)) {
+                    $current .= $this->formatter->tagSeparator;
+                }
+
+                $current .= implode(' and ', $parts);
+            }
+        }
+
+        if ($current) {
+            $out[] = $start . $current;
+        }
+
+        // no @media type except all, and no conflict?
+        if (! $out && $default) {
+            $out[] = $default;
+        }
+
+        return $out;
+    }
+
+    /**
+     * Merge direct relationships between selectors
+     *
+     * @param array $selectors1
+     * @param array $selectors2
+     *
+     * @return array
+     */
+    protected function mergeDirectRelationships($selectors1, $selectors2)
+    {
+        if (empty($selectors1) || empty($selectors2)) {
+            return array_merge($selectors1, $selectors2);
+        }
+
+        $part1 = end($selectors1);
+        $part2 = end($selectors2);
+
+        if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
+            return array_merge($selectors1, $selectors2);
+        }
+
+        $merged = [];
+
+        do {
+            $part1 = array_pop($selectors1);
+            $part2 = array_pop($selectors2);
+
+            if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
+                if ($this->isImmediateRelationshipCombinator(reset($merged)[0])) {
+                    array_unshift($merged, [$part1[0] . $part2[0]]);
+                    $merged = array_merge($selectors1, $selectors2, $merged);
+                } else {
+                    $merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged);
+                }
+
+                break;
+            }
+
+            array_unshift($merged, $part1);
+        } while (! empty($selectors1) && ! empty($selectors2));
+
+        return $merged;
+    }
+
+    /**
+     * Merge media types
+     *
+     * @param array $type1
+     * @param array $type2
+     *
+     * @return array|null
+     */
+    protected function mergeMediaTypes($type1, $type2)
+    {
+        if (empty($type1)) {
+            return $type2;
+        }
+
+        if (empty($type2)) {
+            return $type1;
+        }
+
+        if (\count($type1) > 1) {
+            $m1 = strtolower($type1[0]);
+            $t1 = strtolower($type1[1]);
+        } else {
+            $m1 = '';
+            $t1 = strtolower($type1[0]);
+        }
+
+        if (\count($type2) > 1) {
+            $m2 = strtolower($type2[0]);
+            $t2 = strtolower($type2[1]);
+        } else {
+            $m2 = '';
+            $t2 = strtolower($type2[0]);
+        }
+
+        if (($m1 === Type::T_NOT) ^ ($m2 === Type::T_NOT)) {
+            if ($t1 === $t2) {
+                return null;
+            }
+
+            return [
+                $m1 === Type::T_NOT ? $m2 : $m1,
+                $m1 === Type::T_NOT ? $t2 : $t1,
+            ];
+        }
+
+        if ($m1 === Type::T_NOT && $m2 === Type::T_NOT) {
+            // CSS has no way of representing "neither screen nor print"
+            if ($t1 !== $t2) {
+                return null;
+            }
+
+            return [Type::T_NOT, $t1];
+        }
+
+        if ($t1 !== $t2) {
+            return null;
+        }
+
+        // t1 == t2, neither m1 nor m2 are "not"
+        return [empty($m1) ? $m2 : $m1, $t1];
+    }
+
+    /**
+     * Compile import; returns true if the value was something that could be imported
+     *
+     * @param array                                  $rawPath
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     * @param boolean                                $once
+     *
+     * @return boolean
+     */
+    protected function compileImport($rawPath, OutputBlock $out, $once = false)
+    {
+        if ($rawPath[0] === Type::T_STRING) {
+            $path = $this->compileStringContent($rawPath);
+
+            if (strpos($path, 'url(') !== 0 && $path = $this->findImport($path)) {
+                if (! $once || ! \in_array($path, $this->importedFiles)) {
+                    $this->importFile($path, $out);
+                    $this->importedFiles[] = $path;
+                }
+
+                return true;
+            }
+
+            $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out);
+
+            return false;
+        }
+
+        if ($rawPath[0] === Type::T_LIST) {
+            // handle a list of strings
+            if (\count($rawPath[2]) === 0) {
+                return false;
+            }
+
+            foreach ($rawPath[2] as $path) {
+                if ($path[0] !== Type::T_STRING) {
+                    $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out);
+
+                    return false;
+                }
+            }
+
+            foreach ($rawPath[2] as $path) {
+                $this->compileImport($path, $out, $once);
+            }
+
+            return true;
+        }
+
+        $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out);
+
+        return false;
+    }
+
+    /**
+     * @param $rawPath
+     * @return string
+     * @throws CompilerException
+     */
+    protected function compileImportPath($rawPath)
+    {
+        $path = $this->compileValue($rawPath);
+
+        // case url() without quotes : supress \r \n remaining in the path
+        // if this is a real string there can not be CR or LF char
+        if (strpos($path, 'url(') === 0) {
+            $path = str_replace(array("\r", "\n"), array('', ' '), $path);
+        } else {
+            // if this is a file name in a string, spaces shoudl be escaped
+            $path = $this->reduce($rawPath);
+            $path = $this->escapeImportPathString($path);
+            $path = $this->compileValue($path);
+        }
+
+        return $path;
+    }
+
+    /**
+     * @param array $path
+     * @return array
+     * @throws CompilerException
+     */
+    protected function escapeImportPathString($path)
+    {
+        switch ($path[0]) {
+            case Type::T_LIST:
+                foreach ($path[2] as $k => $v) {
+                    $path[2][$k] = $this->escapeImportPathString($v);
+                }
+                break;
+            case Type::T_STRING:
+                if ($path[1]) {
+                    $path = $this->compileValue($path);
+                    $path = str_replace(' ', '\\ ', $path);
+                    $path = [Type::T_KEYWORD, $path];
+                }
+                break;
+        }
+
+        return $path;
+    }
+
+    /**
+     * Append a root directive like @import or @charset as near as the possible from the source code
+     * (keeping before comments, @import and @charset coming before in the source code)
+     *
+     * @param string                                        $line
+     * @param @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     * @param array                                         $allowed
+     */
+    protected function appendRootDirective($line, $out, $allowed = [Type::T_COMMENT])
+    {
+        $root = $out;
+
+        while ($root->parent) {
+            $root = $root->parent;
+        }
+
+        $i = 0;
+
+        while ($i < \count($root->children)) {
+            if (! isset($root->children[$i]->type) || ! \in_array($root->children[$i]->type, $allowed)) {
+                break;
+            }
+
+            $i++;
+        }
+
+        // remove incompatible children from the bottom of the list
+        $saveChildren = [];
+
+        while ($i < \count($root->children)) {
+            $saveChildren[] = array_pop($root->children);
+        }
+
+        // insert the directive as a comment
+        $child = $this->makeOutputBlock(Type::T_COMMENT);
+        $child->lines[]      = $line;
+        $child->sourceName   = $this->sourceNames[$this->sourceIndex];
+        $child->sourceLine   = $this->sourceLine;
+        $child->sourceColumn = $this->sourceColumn;
+
+        $root->children[] = $child;
+
+        // repush children
+        while (\count($saveChildren)) {
+            $root->children[] = array_pop($saveChildren);
+        }
+    }
+
+    /**
+     * Append lines to the current output block:
+     * directly to the block or through a child if necessary
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     * @param string                                 $type
+     * @param string|mixed                           $line
+     */
+    protected function appendOutputLine(OutputBlock $out, $type, $line)
+    {
+        $outWrite = &$out;
+
+        // check if it's a flat output or not
+        if (\count($out->children)) {
+            $lastChild = &$out->children[\count($out->children) - 1];
+
+            if (
+                $lastChild->depth === $out->depth &&
+                \is_null($lastChild->selectors) &&
+                ! \count($lastChild->children)
+            ) {
+                $outWrite = $lastChild;
+            } else {
+                $nextLines = $this->makeOutputBlock($type);
+                $nextLines->parent = $out;
+                $nextLines->depth  = $out->depth;
+
+                $out->children[] = $nextLines;
+                $outWrite = &$nextLines;
+            }
+        }
+
+        $outWrite->lines[] = $line;
+    }
+
+    /**
+     * Compile child; returns a value to halt execution
+     *
+     * @param array                                  $child
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     *
+     * @return array
+     */
+    protected function compileChild($child, OutputBlock $out)
+    {
+        if (isset($child[Parser::SOURCE_LINE])) {
+            $this->sourceIndex  = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
+            $this->sourceLine   = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
+            $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
+        } elseif (\is_array($child) && isset($child[1]->sourceLine)) {
+            $this->sourceIndex  = $child[1]->sourceIndex;
+            $this->sourceLine   = $child[1]->sourceLine;
+            $this->sourceColumn = $child[1]->sourceColumn;
+        } elseif (! empty($out->sourceLine) && ! empty($out->sourceName)) {
+            $this->sourceLine   = $out->sourceLine;
+            $this->sourceIndex  = array_search($out->sourceName, $this->sourceNames);
+            $this->sourceColumn = $out->sourceColumn;
+
+            if ($this->sourceIndex === false) {
+                $this->sourceIndex = null;
+            }
+        }
+
+        switch ($child[0]) {
+            case Type::T_SCSSPHP_IMPORT_ONCE:
+                $rawPath = $this->reduce($child[1]);
+
+                $this->compileImport($rawPath, $out, true);
+                break;
+
+            case Type::T_IMPORT:
+                $rawPath = $this->reduce($child[1]);
+
+                $this->compileImport($rawPath, $out);
+                break;
+
+            case Type::T_DIRECTIVE:
+                $this->compileDirective($child[1], $out);
+                break;
+
+            case Type::T_AT_ROOT:
+                $this->compileAtRoot($child[1]);
+                break;
+
+            case Type::T_MEDIA:
+                $this->compileMedia($child[1]);
+                break;
+
+            case Type::T_BLOCK:
+                $this->compileBlock($child[1]);
+                break;
+
+            case Type::T_CHARSET:
+                if (! $this->charsetSeen) {
+                    $this->charsetSeen = true;
+                    $this->appendRootDirective('@charset ' . $this->compileValue($child[1]) . ';', $out);
+                }
+                break;
+
+            case Type::T_CUSTOM_PROPERTY:
+                list(, $name, $value) = $child;
+                $compiledName = $this->compileValue($name);
+
+                // if the value reduces to null from something else then
+                // the property should be discarded
+                if ($value[0] !== Type::T_NULL) {
+                    $value = $this->reduce($value);
+
+                    if ($value[0] === Type::T_NULL || $value === static::$nullString) {
+                        break;
+                    }
+                }
+
+                $compiledValue = $this->compileValue($value);
+
+                $line = $this->formatter->customProperty(
+                    $compiledName,
+                    $compiledValue
+                );
+
+                $this->appendOutputLine($out, Type::T_ASSIGN, $line);
+                break;
+
+            case Type::T_ASSIGN:
+                list(, $name, $value) = $child;
+
+                if ($name[0] === Type::T_VARIABLE) {
+                    $flags     = isset($child[3]) ? $child[3] : [];
+                    $isDefault = \in_array('!default', $flags);
+                    $isGlobal  = \in_array('!global', $flags);
+
+                    if ($isGlobal) {
+                        $this->set($name[1], $this->reduce($value), false, $this->rootEnv, $value);
+                        break;
+                    }
+
+                    $shouldSet = $isDefault &&
+                        (\is_null($result = $this->get($name[1], false)) ||
+                        $result === static::$null);
+
+                    if (! $isDefault || $shouldSet) {
+                        $this->set($name[1], $this->reduce($value), true, null, $value);
+                    }
+                    break;
+                }
+
+                $compiledName = $this->compileValue($name);
+
+                // handle shorthand syntaxes : size / line-height...
+                if (\in_array($compiledName, ['font', 'grid-row', 'grid-column', 'border-radius'])) {
+                    if ($value[0] === Type::T_VARIABLE) {
+                        // if the font value comes from variable, the content is already reduced
+                        // (i.e., formulas were already calculated), so we need the original unreduced value
+                        $value = $this->get($value[1], true, null, true);
+                    }
+
+                    $shorthandValue=&$value;
+
+                    $shorthandDividerNeedsUnit = false;
+                    $maxListElements           = null;
+                    $maxShorthandDividers      = 1;
+
+                    switch ($compiledName) {
+                        case 'border-radius':
+                            $maxListElements = 4;
+                            $shorthandDividerNeedsUnit = true;
+                            break;
+                    }
+
+                    if ($compiledName === 'font' && $value[0] === Type::T_LIST && $value[1] === ',') {
+                        // this is the case if more than one font is given: example: "font: 400 1em/1.3 arial,helvetica"
+                        // we need to handle the first list element
+                        $shorthandValue=&$value[2][0];
+                    }
+
+                    if ($shorthandValue[0] === Type::T_EXPRESSION && $shorthandValue[1] === '/') {
+                        $revert = true;
+
+                        if ($shorthandDividerNeedsUnit) {
+                            $divider = $shorthandValue[3];
+
+                            if (\is_array($divider)) {
+                                $divider = $this->reduce($divider, true);
+                            }
+
+                            if ($divider instanceof Number && \intval($divider->getDimension()) && $divider->unitless()) {
+                                $revert = false;
+                            }
+                        }
+
+                        if ($revert) {
+                            $shorthandValue = $this->expToString($shorthandValue);
+                        }
+                    } elseif ($shorthandValue[0] === Type::T_LIST) {
+                        foreach ($shorthandValue[2] as &$item) {
+                            if ($item[0] === Type::T_EXPRESSION && $item[1] === '/') {
+                                if ($maxShorthandDividers > 0) {
+                                    $revert = true;
+
+                                    // if the list of values is too long, this has to be a shorthand,
+                                    // otherwise it could be a real division
+                                    if (\is_null($maxListElements) || \count($shorthandValue[2]) <= $maxListElements) {
+                                        if ($shorthandDividerNeedsUnit) {
+                                            $divider = $item[3];
+
+                                            if (\is_array($divider)) {
+                                                $divider = $this->reduce($divider, true);
+                                            }
+
+                                            if ($divider instanceof Number && \intval($divider->getDimension()) && $divider->unitless()) {
+                                                $revert = false;
+                                            }
+                                        }
+                                    }
+
+                                    if ($revert) {
+                                        $item = $this->expToString($item);
+                                        $maxShorthandDividers--;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // if the value reduces to null from something else then
+                // the property should be discarded
+                if ($value[0] !== Type::T_NULL) {
+                    $value = $this->reduce($value);
+
+                    if ($value[0] === Type::T_NULL || $value === static::$nullString) {
+                        break;
+                    }
+                }
+
+                $compiledValue = $this->compileValue($value);
+
+                // ignore empty value
+                if (\strlen($compiledValue)) {
+                    $line = $this->formatter->property(
+                        $compiledName,
+                        $compiledValue
+                    );
+                    $this->appendOutputLine($out, Type::T_ASSIGN, $line);
+                }
+                break;
+
+            case Type::T_COMMENT:
+                if ($out->type === Type::T_ROOT) {
+                    $this->compileComment($child);
+                    break;
+                }
+
+                $line = $this->compileCommentValue($child, true);
+                $this->appendOutputLine($out, Type::T_COMMENT, $line);
+                break;
+
+            case Type::T_MIXIN:
+            case Type::T_FUNCTION:
+                list(, $block) = $child;
+                // the block need to be able to go up to it's parent env to resolve vars
+                $block->parentEnv = $this->getStoreEnv();
+                $this->set(static::$namespaces[$block->type] . $block->name, $block, true);
+                break;
+
+            case Type::T_EXTEND:
+                foreach ($child[1] as $sel) {
+                    $sel = $this->replaceSelfSelector($sel);
+                    $results = $this->evalSelectors([$sel]);
+
+                    foreach ($results as $result) {
+                        // only use the first one
+                        $result = current($result);
+                        $selectors = $out->selectors;
+
+                        if (! $selectors && isset($child['selfParent'])) {
+                            $selectors = $this->multiplySelectors($this->env, $child['selfParent']);
+                        }
+
+                        $this->pushExtends($result, $selectors, $child);
+                    }
+                }
+                break;
+
+            case Type::T_IF:
+                list(, $if) = $child;
+
+                if ($this->isTruthy($this->reduce($if->cond, true))) {
+                    return $this->compileChildren($if->children, $out);
+                }
+
+                foreach ($if->cases as $case) {
+                    if (
+                        $case->type === Type::T_ELSE ||
+                        $case->type === Type::T_ELSEIF && $this->isTruthy($this->reduce($case->cond))
+                    ) {
+                        return $this->compileChildren($case->children, $out);
+                    }
+                }
+                break;
+
+            case Type::T_EACH:
+                list(, $each) = $child;
+
+                $list = $this->coerceList($this->reduce($each->list), ',', true);
+
+                $this->pushEnv();
+
+                foreach ($list[2] as $item) {
+                    if (\count($each->vars) === 1) {
+                        $this->set($each->vars[0], $item, true);
+                    } else {
+                        list(,, $values) = $this->coerceList($item);
+
+                        foreach ($each->vars as $i => $var) {
+                            $this->set($var, isset($values[$i]) ? $values[$i] : static::$null, true);
+                        }
+                    }
+
+                    $ret = $this->compileChildren($each->children, $out);
+
+                    if ($ret) {
+                        $store = $this->env->store;
+                        $this->popEnv();
+                        $this->backPropagateEnv($store, $each->vars);
+
+                        return $ret;
+                    }
+                }
+                $store = $this->env->store;
+                $this->popEnv();
+                $this->backPropagateEnv($store, $each->vars);
+
+                break;
+
+            case Type::T_WHILE:
+                list(, $while) = $child;
+
+                while ($this->isTruthy($this->reduce($while->cond, true))) {
+                    $ret = $this->compileChildren($while->children, $out);
+
+                    if ($ret) {
+                        return $ret;
+                    }
+                }
+                break;
+
+            case Type::T_FOR:
+                list(, $for) = $child;
+
+                $start = $this->reduce($for->start, true);
+                $end   = $this->reduce($for->end, true);
+
+                if (! $start instanceof Number) {
+                    throw $this->error('%s is not a number', $start[0]);
+                }
+
+                if (! $end instanceof Number) {
+                    throw $this->error('%s is not a number', $end[0]);
+                }
+
+                $start->assertSameUnitOrUnitless($end);
+
+                $numeratorUnits = $start->getNumeratorUnits();
+                $denominatorUnits = $start->getDenominatorUnits();
+
+                $start = $start->getDimension();
+                $end   = $end->getDimension();
+
+                $d = $start < $end ? 1 : -1;
+
+                $this->pushEnv();
+
+                for (;;) {
+                    if (
+                        (! $for->until && $start - $d == $end) ||
+                        ($for->until && $start == $end)
+                    ) {
+                        break;
+                    }
+
+                    $this->set($for->var, new Number($start, $numeratorUnits, $denominatorUnits));
+                    $start += $d;
+
+                    $ret = $this->compileChildren($for->children, $out);
+
+                    if ($ret) {
+                        $store = $this->env->store;
+                        $this->popEnv();
+                        $this->backPropagateEnv($store, [$for->var]);
+
+                        return $ret;
+                    }
+                }
+
+                $store = $this->env->store;
+                $this->popEnv();
+                $this->backPropagateEnv($store, [$for->var]);
+
+                break;
+
+            case Type::T_RETURN:
+                return $this->reduce($child[1], true);
+
+            case Type::T_NESTED_PROPERTY:
+                $this->compileNestedPropertiesBlock($child[1], $out);
+                break;
+
+            case Type::T_INCLUDE:
+                // including a mixin
+                list(, $name, $argValues, $content, $argUsing) = $child;
+
+                $mixin = $this->get(static::$namespaces['mixin'] . $name, false);
+
+                if (! $mixin) {
+                    throw $this->error("Undefined mixin $name");
+                }
+
+                $callingScope = $this->getStoreEnv();
+
+                // push scope, apply args
+                $this->pushEnv();
+                $this->env->depth--;
+
+                // Find the parent selectors in the env to be able to know what '&' refers to in the mixin
+                // and assign this fake parent to childs
+                $selfParent = null;
+
+                if (isset($child['selfParent']) && isset($child['selfParent']->selectors)) {
+                    $selfParent = $child['selfParent'];
+                } else {
+                    $parentSelectors = $this->multiplySelectors($this->env);
+
+                    if ($parentSelectors) {
+                        $parent = new Block();
+                        $parent->selectors = $parentSelectors;
+
+                        foreach ($mixin->children as $k => $child) {
+                            if (isset($child[1]) && \is_object($child[1]) && $child[1] instanceof Block) {
+                                $mixin->children[$k][1]->parent = $parent;
+                            }
+                        }
+                    }
+                }
+
+                // clone the stored content to not have its scope spoiled by a further call to the same mixin
+                // i.e., recursive @include of the same mixin
+                if (isset($content)) {
+                    $copyContent = clone $content;
+                    $copyContent->scope = clone $callingScope;
+
+                    $this->setRaw(static::$namespaces['special'] . 'content', $copyContent, $this->env);
+                } else {
+                    $this->setRaw(static::$namespaces['special'] . 'content', null, $this->env);
+                }
+
+                // save the "using" argument list for applying it to when "@content" is invoked
+                if (isset($argUsing)) {
+                    $this->setRaw(static::$namespaces['special'] . 'using', $argUsing, $this->env);
+                } else {
+                    $this->setRaw(static::$namespaces['special'] . 'using', null, $this->env);
+                }
+
+                if (isset($mixin->args)) {
+                    $this->applyArguments($mixin->args, $argValues);
+                }
+
+                $this->env->marker = 'mixin';
+
+                if (! empty($mixin->parentEnv)) {
+                    $this->env->declarationScopeParent = $mixin->parentEnv;
+                } else {
+                    throw $this->error("@mixin $name() without parentEnv");
+                }
+
+                $this->compileChildrenNoReturn($mixin->children, $out, $selfParent, $this->env->marker . ' ' . $name);
+
+                $this->popEnv();
+                break;
+
+            case Type::T_MIXIN_CONTENT:
+                $env        = isset($this->storeEnv) ? $this->storeEnv : $this->env;
+                $content    = $this->get(static::$namespaces['special'] . 'content', false, $env);
+                $argUsing   = $this->get(static::$namespaces['special'] . 'using', false, $env);
+                $argContent = $child[1];
+
+                if (! $content) {
+                    break;
+                }
+
+                $storeEnv = $this->storeEnv;
+                $varsUsing = [];
+
+                if (isset($argUsing) && isset($argContent)) {
+                    // Get the arguments provided for the content with the names provided in the "using" argument list
+                    $this->storeEnv = null;
+                    $varsUsing = $this->applyArguments($argUsing, $argContent, false);
+                }
+
+                // restore the scope from the @content
+                $this->storeEnv = $content->scope;
+
+                // append the vars from using if any
+                foreach ($varsUsing as $name => $val) {
+                    $this->set($name, $val, true, $this->storeEnv);
+                }
+
+                $this->compileChildrenNoReturn($content->children, $out);
+
+                $this->storeEnv = $storeEnv;
+                break;
+
+            case Type::T_DEBUG:
+                list(, $value) = $child;
+
+                $fname = $this->sourceNames[$this->sourceIndex];
+                $line  = $this->sourceLine;
+                $value = $this->compileDebugValue($value);
+
+                fwrite($this->stderr, "$fname:$line DEBUG: $value\n");
+                break;
+
+            case Type::T_WARN:
+                list(, $value) = $child;
+
+                $fname = $this->sourceNames[$this->sourceIndex];
+                $line  = $this->sourceLine;
+                $value = $this->compileDebugValue($value);
+
+                fwrite($this->stderr, "WARNING: $value\n         on line $line of $fname\n\n");
+                break;
+
+            case Type::T_ERROR:
+                list(, $value) = $child;
+
+                $fname = $this->sourceNames[$this->sourceIndex];
+                $line  = $this->sourceLine;
+                $value = $this->compileValue($this->reduce($value, true));
+
+                throw $this->error("File $fname on line $line ERROR: $value\n");
+
+            default:
+                throw $this->error("unknown child type: $child[0]");
+        }
+    }
+
+    /**
+     * Reduce expression to string
+     *
+     * @param array $exp
+     * @param true $keepParens
+     *
+     * @return array
+     */
+    protected function expToString($exp, $keepParens = false)
+    {
+        list(, $op, $left, $right, $inParens, $whiteLeft, $whiteRight) = $exp;
+
+        $content = [];
+
+        if ($keepParens && $inParens) {
+            $content[] = '(';
+        }
+
+        $content[] = $this->reduce($left);
+
+        if ($whiteLeft) {
+            $content[] = ' ';
+        }
+
+        $content[] = $op;
+
+        if ($whiteRight) {
+            $content[] = ' ';
+        }
+
+        $content[] = $this->reduce($right);
+
+        if ($keepParens && $inParens) {
+            $content[] = ')';
+        }
+
+        return [Type::T_STRING, '', $content];
+    }
+
+    /**
+     * Is truthy?
+     *
+     * @param array $value
+     *
+     * @return boolean
+     */
+    protected function isTruthy($value)
+    {
+        return $value !== static::$false && $value !== static::$null;
+    }
+
+    /**
+     * Is the value a direct relationship combinator?
+     *
+     * @param string $value
+     *
+     * @return boolean
+     */
+    protected function isImmediateRelationshipCombinator($value)
+    {
+        return $value === '>' || $value === '+' || $value === '~';
+    }
+
+    /**
+     * Should $value cause its operand to eval
+     *
+     * @param array $value
+     *
+     * @return boolean
+     */
+    protected function shouldEval($value)
+    {
+        switch ($value[0]) {
+            case Type::T_EXPRESSION:
+                if ($value[1] === '/') {
+                    return $this->shouldEval($value[2]) || $this->shouldEval($value[3]);
+                }
+
+                // fall-thru
+            case Type::T_VARIABLE:
+            case Type::T_FUNCTION_CALL:
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Reduce value
+     *
+     * @param array   $value
+     * @param boolean $inExp
+     *
+     * @return null|string|array|Number
+     */
+    protected function reduce($value, $inExp = false)
+    {
+        if (\is_null($value)) {
+            return null;
+        }
+
+        switch ($value[0]) {
+            case Type::T_EXPRESSION:
+                list(, $op, $left, $right, $inParens) = $value;
+
+                $opName = isset(static::$operatorNames[$op]) ? static::$operatorNames[$op] : $op;
+                $inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right);
+
+                $left = $this->reduce($left, true);
+
+                if ($op !== 'and' && $op !== 'or') {
+                    $right = $this->reduce($right, true);
+                }
+
+                // special case: looks like css shorthand
+                if (
+                    $opName == 'div' && ! $inParens && ! $inExp &&
+                    (($right[0] !== Type::T_NUMBER && isset($right[2]) && $right[2] != '') ||
+                    ($right[0] === Type::T_NUMBER && ! $right->unitless()))
+                ) {
+                    return $this->expToString($value);
+                }
+
+                $left  = $this->coerceForExpression($left);
+                $right = $this->coerceForExpression($right);
+                $ltype = $left[0];
+                $rtype = $right[0];
+
+                $ucOpName = ucfirst($opName);
+                $ucLType  = ucfirst($ltype);
+                $ucRType  = ucfirst($rtype);
+
+                // this tries:
+                // 1. op[op name][left type][right type]
+                // 2. op[left type][right type] (passing the op as first arg
+                // 3. op[op name]
+                $fn = "op${ucOpName}${ucLType}${ucRType}";
+
+                if (
+                    \is_callable([$this, $fn]) ||
+                    (($fn = "op${ucLType}${ucRType}") &&
+                        \is_callable([$this, $fn]) &&
+                        $passOp = true) ||
+                    (($fn = "op${ucOpName}") &&
+                        \is_callable([$this, $fn]) &&
+                        $genOp = true)
+                ) {
+                    $shouldEval = $inParens || $inExp;
+
+                    if (isset($passOp)) {
+                        $out = $this->$fn($op, $left, $right, $shouldEval);
+                    } else {
+                        $out = $this->$fn($left, $right, $shouldEval);
+                    }
+
+                    if (isset($out)) {
+                        return $out;
+                    }
+                }
+
+                return $this->expToString($value);
+
+            case Type::T_UNARY:
+                list(, $op, $exp, $inParens) = $value;
+
+                $inExp = $inExp || $this->shouldEval($exp);
+                $exp = $this->reduce($exp);
+
+                if ($exp instanceof Number) {
+                    switch ($op) {
+                        case '+':
+                            return $exp;
+
+                        case '-':
+                            return $exp->unaryMinus();
+                    }
+                }
+
+                if ($op === 'not') {
+                    if ($inExp || $inParens) {
+                        if ($exp === static::$false || $exp === static::$null) {
+                            return static::$true;
+                        }
+
+                        return static::$false;
+                    }
+
+                    $op = $op . ' ';
+                }
+
+                return [Type::T_STRING, '', [$op, $exp]];
+
+            case Type::T_VARIABLE:
+                return $this->reduce($this->get($value[1]));
+
+            case Type::T_LIST:
+                foreach ($value[2] as &$item) {
+                    $item = $this->reduce($item);
+                }
+
+                return $value;
+
+            case Type::T_MAP:
+                foreach ($value[1] as &$item) {
+                    $item = $this->reduce($item);
+                }
+
+                foreach ($value[2] as &$item) {
+                    $item = $this->reduce($item);
+                }
+
+                return $value;
+
+            case Type::T_STRING:
+                foreach ($value[2] as &$item) {
+                    if (\is_array($item) || $item instanceof \ArrayAccess) {
+                        $item = $this->reduce($item);
+                    }
+                }
+
+                return $value;
+
+            case Type::T_INTERPOLATE:
+                $value[1] = $this->reduce($value[1]);
+
+                if ($inExp) {
+                    return $value[1];
+                }
+
+                return $value;
+
+            case Type::T_FUNCTION_CALL:
+                return $this->fncall($value[1], $value[2]);
+
+            case Type::T_SELF:
+                $selfParent = ! empty($this->env->block->selfParent) ? $this->env->block->selfParent : null;
+                $selfSelector = $this->multiplySelectors($this->env, $selfParent);
+                $selfSelector = $this->collapseSelectors($selfSelector, true);
+
+                return $selfSelector;
+
+            default:
+                return $value;
+        }
+    }
+
+    /**
+     * Function caller
+     *
+     * @param string $name
+     * @param array  $argValues
+     *
+     * @return array|null
+     */
+    protected function fncall($functionReference, $argValues)
+    {
+        // a string means this is a static hard reference coming from the parsing
+        if (is_string($functionReference)) {
+            $name = $functionReference;
+
+            $functionReference = $this->getFunctionReference($name);
+            if ($functionReference === static::$null || $functionReference[0] !== Type::T_FUNCTION_REFERENCE) {
+                $functionReference = [Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]];
+            }
+        }
+
+        // a function type means we just want a plain css function call
+        if ($functionReference[0] === Type::T_FUNCTION) {
+            // for CSS functions, simply flatten the arguments into a list
+            $listArgs = [];
+
+            foreach ((array) $argValues as $arg) {
+                if (empty($arg[0]) || count($argValues) === 1) {
+                    $listArgs[] = $this->reduce($this->stringifyFncallArgs($arg[1]));
+                }
+            }
+
+            return [Type::T_FUNCTION, $functionReference[1], [Type::T_LIST, ',', $listArgs]];
+        }
+
+        if ($functionReference === static::$null || $functionReference[0] !== Type::T_FUNCTION_REFERENCE) {
+            return static::$defaultValue;
+        }
+
+
+        switch ($functionReference[1]) {
+            // SCSS @function
+            case 'scss':
+                return $this->callScssFunction($functionReference[3], $argValues);
+
+            // native PHP functions
+            case 'user':
+            case 'native':
+                list(,,$name, $fn, $prototype) = $functionReference;
+
+                // special cases of css valid functions min/max
+                $name = strtolower($name);
+                if (\in_array($name, ['min', 'max'])) {
+                    $cssFunction = $this->cssValidArg(
+                        [Type::T_FUNCTION_CALL, $name, $argValues],
+                        ['min', 'max', 'calc', 'env', 'var']
+                    );
+                    if ($cssFunction !== false) {
+                        return $cssFunction;
+                    }
+                }
+                $returnValue = $this->callNativeFunction($name, $fn, $prototype, $argValues);
+
+                if (! isset($returnValue)) {
+                    return $this->fncall([Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]], $argValues);
+                }
+
+                return $returnValue;
+
+            default:
+                return static::$defaultValue;
+        }
+    }
+
+    protected function cssValidArg($arg, $allowed_function = [], $inFunction = false)
+    {
+        switch ($arg[0]) {
+            case Type::T_INTERPOLATE:
+                return [Type::T_KEYWORD, $this->CompileValue($arg)];
+
+            case Type::T_FUNCTION:
+                if (! \in_array($arg[1], $allowed_function)) {
+                    return false;
+                }
+                if ($arg[2][0] === Type::T_LIST) {
+                    foreach ($arg[2][2] as $k => $subarg) {
+                        $arg[2][2][$k] = $this->cssValidArg($subarg, $allowed_function, $arg[1]);
+                        if ($arg[2][2][$k] === false) {
+                            return false;
+                        }
+                    }
+                }
+                return $arg;
+
+            case Type::T_FUNCTION_CALL:
+                if (! \in_array($arg[1], $allowed_function)) {
+                    return false;
+                }
+                $cssArgs = [];
+                foreach ($arg[2] as $argValue) {
+                    if ($argValue === static::$null) {
+                        return false;
+                    }
+                    $cssArg = $this->cssValidArg($argValue[1], $allowed_function, $arg[1]);
+                    if (empty($argValue[0]) && $cssArg !== false) {
+                        $cssArgs[] = [$argValue[0], $cssArg];
+                    } else {
+                        return false;
+                    }
+                }
+
+                return $this->fncall([Type::T_FUNCTION, $arg[1], [Type::T_LIST, ',', []]], $cssArgs);
+
+            case Type::T_STRING:
+            case Type::T_KEYWORD:
+                if (!$inFunction or !\in_array($inFunction, ['calc', 'env', 'var'])) {
+                    return false;
+                }
+                return $this->stringifyFncallArgs($arg);
+
+            case Type::T_NUMBER:
+                return $this->stringifyFncallArgs($arg);
+
+            case Type::T_LIST:
+                if (!$inFunction) {
+                    return false;
+                }
+                if (empty($arg['enclosing']) and $arg[1] === '') {
+                    foreach ($arg[2] as $k => $subarg) {
+                        $arg[2][$k] = $this->cssValidArg($subarg, $allowed_function, $inFunction);
+                        if ($arg[2][$k] === false) {
+                            return false;
+                        }
+                    }
+                    $arg[0] = Type::T_STRING;
+                    return $arg;
+                }
+                return false;
+
+            case Type::T_EXPRESSION:
+                if (! \in_array($arg[1], ['+', '-', '/', '*'])) {
+                    return false;
+                }
+                $arg[2] = $this->cssValidArg($arg[2], $allowed_function, $inFunction);
+                $arg[3] = $this->cssValidArg($arg[3], $allowed_function, $inFunction);
+                if ($arg[2] === false || $arg[3] === false) {
+                    return false;
+                }
+                return $this->expToString($arg, true);
+
+            case Type::T_VARIABLE:
+            case Type::T_SELF:
+            default:
+                return false;
+        }
+    }
+
+
+    /**
+     * Reformat fncall arguments to proper css function output
+     *
+     * @param $arg
+     *
+     * @return array|\ArrayAccess|Number|string|null
+     */
+    protected function stringifyFncallArgs($arg)
+    {
+
+        switch ($arg[0]) {
+            case Type::T_LIST:
+                foreach ($arg[2] as $k => $v) {
+                    $arg[2][$k] = $this->stringifyFncallArgs($v);
+                }
+                break;
+
+            case Type::T_EXPRESSION:
+                if ($arg[1] === '/') {
+                    $arg[2] = $this->stringifyFncallArgs($arg[2]);
+                    $arg[3] = $this->stringifyFncallArgs($arg[3]);
+                    $arg[5] = $arg[6] = false; // no space around /
+                    $arg = $this->expToString($arg);
+                }
+                break;
+
+            case Type::T_FUNCTION_CALL:
+                $name = strtolower($arg[1]);
+
+                if (in_array($name, ['max', 'min', 'calc'])) {
+                    $args = $arg[2];
+                    $arg = $this->fncall([Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]], $args);
+                }
+                break;
+        }
+
+        return $arg;
+    }
+
+    /**
+     * Find a function reference
+     * @param string $name
+     * @param bool $safeCopy
+     * @return array
+     */
+    protected function getFunctionReference($name, $safeCopy = false)
+    {
+        // SCSS @function
+        if ($func = $this->get(static::$namespaces['function'] . $name, false)) {
+            if ($safeCopy) {
+                $func = clone $func;
+            }
+
+            return [Type::T_FUNCTION_REFERENCE, 'scss', $name, $func];
+        }
+
+        // native PHP functions
+
+        // try to find a native lib function
+        $normalizedName = $this->normalizeName($name);
+        $libName = null;
+
+        if (isset($this->userFunctions[$normalizedName])) {
+            // see if we can find a user function
+            list($f, $prototype) = $this->userFunctions[$normalizedName];
+
+            return [Type::T_FUNCTION_REFERENCE, 'user', $name, $f, $prototype];
+        }
+
+        if (($f = $this->getBuiltinFunction($normalizedName)) && \is_callable($f)) {
+            $libName   = $f[1];
+            $prototype = isset(static::$$libName) ? static::$$libName : null;
+
+            return [Type::T_FUNCTION_REFERENCE, 'native', $name, $f, $prototype];
+        }
+
+        return static::$null;
+    }
+
+
+    /**
+     * Normalize name
+     *
+     * @param string $name
+     *
+     * @return string
+     */
+    protected function normalizeName($name)
+    {
+        return str_replace('-', '_', $name);
+    }
+
+    /**
+     * Normalize value
+     *
+     * @param array $value
+     *
+     * @return array
+     */
+    public function normalizeValue($value)
+    {
+        $value = $this->coerceForExpression($this->reduce($value));
+
+        switch ($value[0]) {
+            case Type::T_LIST:
+                $value = $this->extractInterpolation($value);
+
+                if ($value[0] !== Type::T_LIST) {
+                    return [Type::T_KEYWORD, $this->compileValue($value)];
+                }
+
+                foreach ($value[2] as $key => $item) {
+                    $value[2][$key] = $this->normalizeValue($item);
+                }
+
+                if (! empty($value['enclosing'])) {
+                    unset($value['enclosing']);
+                }
+
+                return $value;
+
+            case Type::T_STRING:
+                return [$value[0], '"', [$this->compileStringContent($value)]];
+
+            case Type::T_INTERPOLATE:
+                return [Type::T_KEYWORD, $this->compileValue($value)];
+
+            default:
+                return $value;
+        }
+    }
+
+    /**
+     * Add numbers
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return Number
+     */
+    protected function opAddNumberNumber(Number $left, Number $right)
+    {
+        return $left->plus($right);
+    }
+
+    /**
+     * Multiply numbers
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return Number
+     */
+    protected function opMulNumberNumber(Number $left, Number $right)
+    {
+        return $left->times($right);
+    }
+
+    /**
+     * Subtract numbers
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return Number
+     */
+    protected function opSubNumberNumber(Number $left, Number $right)
+    {
+        return $left->minus($right);
+    }
+
+    /**
+     * Divide numbers
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return Number
+     */
+    protected function opDivNumberNumber(Number $left, Number $right)
+    {
+        return $left->dividedBy($right);
+    }
+
+    /**
+     * Mod numbers
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return Number
+     */
+    protected function opModNumberNumber(Number $left, Number $right)
+    {
+        return $left->modulo($right);
+    }
+
+    /**
+     * Add strings
+     *
+     * @param array $left
+     * @param array $right
+     *
+     * @return array|null
+     */
+    protected function opAdd($left, $right)
+    {
+        if ($strLeft = $this->coerceString($left)) {
+            if ($right[0] === Type::T_STRING) {
+                $right[1] = '';
+            }
+
+            $strLeft[2][] = $right;
+
+            return $strLeft;
+        }
+
+        if ($strRight = $this->coerceString($right)) {
+            if ($left[0] === Type::T_STRING) {
+                $left[1] = '';
+            }
+
+            array_unshift($strRight[2], $left);
+
+            return $strRight;
+        }
+
+        return null;
+    }
+
+    /**
+     * Boolean and
+     *
+     * @param array   $left
+     * @param array   $right
+     * @param boolean $shouldEval
+     *
+     * @return array|null
+     */
+    protected function opAnd($left, $right, $shouldEval)
+    {
+        $truthy = ($left === static::$null || $right === static::$null) ||
+                  ($left === static::$false || $left === static::$true) &&
+                  ($right === static::$false || $right === static::$true);
+
+        if (! $shouldEval) {
+            if (! $truthy) {
+                return null;
+            }
+        }
+
+        if ($left !== static::$false && $left !== static::$null) {
+            return $this->reduce($right, true);
+        }
+
+        return $left;
+    }
+
+    /**
+     * Boolean or
+     *
+     * @param array   $left
+     * @param array   $right
+     * @param boolean $shouldEval
+     *
+     * @return array|null
+     */
+    protected function opOr($left, $right, $shouldEval)
+    {
+        $truthy = ($left === static::$null || $right === static::$null) ||
+                  ($left === static::$false || $left === static::$true) &&
+                  ($right === static::$false || $right === static::$true);
+
+        if (! $shouldEval) {
+            if (! $truthy) {
+                return null;
+            }
+        }
+
+        if ($left !== static::$false && $left !== static::$null) {
+            return $left;
+        }
+
+        return $this->reduce($right, true);
+    }
+
+    /**
+     * Compare colors
+     *
+     * @param string $op
+     * @param array  $left
+     * @param array  $right
+     *
+     * @return array
+     */
+    protected function opColorColor($op, $left, $right)
+    {
+        $out = [Type::T_COLOR];
+
+        foreach ([1, 2, 3] as $i) {
+            $lval = isset($left[$i]) ? $left[$i] : 0;
+            $rval = isset($right[$i]) ? $right[$i] : 0;
+
+            switch ($op) {
+                case '+':
+                    $out[] = $lval + $rval;
+                    break;
+
+                case '-':
+                    $out[] = $lval - $rval;
+                    break;
+
+                case '*':
+                    $out[] = $lval * $rval;
+                    break;
+
+                case '%':
+                    if ($rval == 0) {
+                        throw $this->error("color: Can't take modulo by zero");
+                    }
+
+                    $out[] = $lval % $rval;
+                    break;
+
+                case '/':
+                    if ($rval == 0) {
+                        throw $this->error("color: Can't divide by zero");
+                    }
+
+                    $out[] = (int) ($lval / $rval);
+                    break;
+
+                case '==':
+                    return $this->opEq($left, $right);
+
+                case '!=':
+                    return $this->opNeq($left, $right);
+
+                default:
+                    throw $this->error("color: unknown op $op");
+            }
+        }
+
+        if (isset($left[4])) {
+            $out[4] = $left[4];
+        } elseif (isset($right[4])) {
+            $out[4] = $right[4];
+        }
+
+        return $this->fixColor($out);
+    }
+
+    /**
+     * Compare color and number
+     *
+     * @param string $op
+     * @param array  $left
+     * @param Number  $right
+     *
+     * @return array
+     */
+    protected function opColorNumber($op, $left, Number $right)
+    {
+        $value = $right->getDimension();
+
+        return $this->opColorColor(
+            $op,
+            $left,
+            [Type::T_COLOR, $value, $value, $value]
+        );
+    }
+
+    /**
+     * Compare number and color
+     *
+     * @param string $op
+     * @param Number  $left
+     * @param array  $right
+     *
+     * @return array
+     */
+    protected function opNumberColor($op, Number $left, $right)
+    {
+        $value = $left->getDimension();
+
+        return $this->opColorColor(
+            $op,
+            [Type::T_COLOR, $value, $value, $value],
+            $right
+        );
+    }
+
+    /**
+     * Compare number1 == number2
+     *
+     * @param array $left
+     * @param array $right
+     *
+     * @return array
+     */
+    protected function opEq($left, $right)
+    {
+        if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) {
+            $lStr[1] = '';
+            $rStr[1] = '';
+
+            $left = $this->compileValue($lStr);
+            $right = $this->compileValue($rStr);
+        }
+
+        return $this->toBool($left === $right);
+    }
+
+    /**
+     * Compare number1 != number2
+     *
+     * @param array $left
+     * @param array $right
+     *
+     * @return array
+     */
+    protected function opNeq($left, $right)
+    {
+        if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) {
+            $lStr[1] = '';
+            $rStr[1] = '';
+
+            $left = $this->compileValue($lStr);
+            $right = $this->compileValue($rStr);
+        }
+
+        return $this->toBool($left !== $right);
+    }
+
+    /**
+     * Compare number1 == number2
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return array
+     */
+    protected function opEqNumberNumber(Number $left, Number $right)
+    {
+        return $this->toBool($left->equals($right));
+    }
+
+    /**
+     * Compare number1 != number2
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return array
+     */
+    protected function opNeqNumberNumber(Number $left, Number $right)
+    {
+        return $this->toBool(!$left->equals($right));
+    }
+
+    /**
+     * Compare number1 >= number2
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return array
+     */
+    protected function opGteNumberNumber(Number $left, Number $right)
+    {
+        return $this->toBool($left->greaterThanOrEqual($right));
+    }
+
+    /**
+     * Compare number1 > number2
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return array
+     */
+    protected function opGtNumberNumber(Number $left, Number $right)
+    {
+        return $this->toBool($left->greaterThan($right));
+    }
+
+    /**
+     * Compare number1 <= number2
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return array
+     */
+    protected function opLteNumberNumber(Number $left, Number $right)
+    {
+        return $this->toBool($left->lessThanOrEqual($right));
+    }
+
+    /**
+     * Compare number1 < number2
+     *
+     * @param Number $left
+     * @param Number $right
+     *
+     * @return array
+     */
+    protected function opLtNumberNumber(Number $left, Number $right)
+    {
+        return $this->toBool($left->lessThan($right));
+    }
+
+    /**
+     * Cast to boolean
+     *
+     * @api
+     *
+     * @param mixed $thing
+     *
+     * @return array
+     */
+    public function toBool($thing)
+    {
+        return $thing ? static::$true : static::$false;
+    }
+
+    /**
+     * Escape non printable chars in strings output as in dart-sass
+     * @param $string
+     * @return string|string[]
+     */
+    public function escapeNonPrintableChars($string, $inKeyword = false)
+    {
+        static $replacement = [];
+        if (empty($replacement[$inKeyword])) {
+            for ($i = 0; $i < 32; $i++) {
+                if ($i !== 9 || $inKeyword) {
+                    $replacement[$inKeyword][chr($i)] = '\\' . dechex($i) . ($inKeyword ? ' ' : chr(0));
+                }
+            }
+        }
+        $string = str_replace(array_keys($replacement[$inKeyword]), array_values($replacement[$inKeyword]), $string);
+        // chr(0) is not a possible char from the input, so any chr(0) comes from our escaping replacement
+        if (strpos($string, chr(0)) !== false) {
+            if (substr($string, -1) === chr(0)) {
+                $string = substr($string, 0, -1);
+            }
+            $string = str_replace(
+                [chr(0) . '\\',chr(0) . ' '],
+                [ '\\', ' '],
+                $string
+            );
+            if (strpos($string, chr(0)) !== false) {
+                $parts = explode(chr(0), $string);
+                $string = array_shift($parts);
+                while (count($parts)) {
+                    $next = array_shift($parts);
+                    if (strpos("0123456789abcdefABCDEF" . chr(9), $next[0]) !== false) {
+                        $string .= " ";
+                    }
+                    $string .= $next;
+                }
+            }
+        }
+
+        return $string;
+    }
+
+    /**
+     * Compiles a primitive value into a CSS property value.
+     *
+     * Values in scssphp are typed by being wrapped in arrays, their format is
+     * typically:
+     *
+     *     array(type, contents [, additional_contents]*)
+     *
+     * The input is expected to be reduced. This function will not work on
+     * things like expressions and variables.
+     *
+     * @api
+     *
+     * @param array $value
+     *
+     * @return string|array
+     */
+    public function compileValue($value)
+    {
+        $value = $this->reduce($value);
+
+        switch ($value[0]) {
+            case Type::T_KEYWORD:
+                if (is_string($value[1])) {
+                    $value[1] = $this->escapeNonPrintableChars($value[1], true);
+                }
+                return $value[1];
+
+            case Type::T_COLOR:
+                // [1] - red component (either number for a %)
+                // [2] - green component
+                // [3] - blue component
+                // [4] - optional alpha component
+                list(, $r, $g, $b) = $value;
+
+                $r = $this->compileRGBAValue($r);
+                $g = $this->compileRGBAValue($g);
+                $b = $this->compileRGBAValue($b);
+
+                if (\count($value) === 5) {
+                    $alpha = $this->compileRGBAValue($value[4], true);
+
+                    if (! is_numeric($alpha) || $alpha < 1) {
+                        $colorName = Colors::RGBaToColorName($r, $g, $b, $alpha);
+
+                        if (! \is_null($colorName)) {
+                            return $colorName;
+                        }
+
+                        if (is_numeric($alpha)) {
+                            $a = new Number($alpha, '');
+                        } else {
+                            $a = $alpha;
+                        }
+
+                        return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $a . ')';
+                    }
+                }
+
+                if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b)) {
+                    return 'rgb(' . $r . ', ' . $g . ', ' . $b . ')';
+                }
+
+                $colorName = Colors::RGBaToColorName($r, $g, $b);
+
+                if (! \is_null($colorName)) {
+                    return $colorName;
+                }
+
+                $h = sprintf('#%02x%02x%02x', $r, $g, $b);
+
+                // Converting hex color to short notation (e.g. #003399 to #039)
+                if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
+                    $h = '#' . $h[1] . $h[3] . $h[5];
+                }
+
+                return $h;
+
+            case Type::T_NUMBER:
+                return $value->output($this);
+
+            case Type::T_STRING:
+                $content = $this->compileStringContent($value);
+
+                if ($value[1]) {
+                    $content = str_replace('\\', '\\\\', $content);
+
+                    $content = $this->escapeNonPrintableChars($content);
+
+                    // force double quote as string quote for the output in certain cases
+                    if (
+                        $value[1] === "'" &&
+                        (strpos($content, '"') === false or strpos($content, "'") !== false) &&
+                        strpbrk($content, '{}\\\'') !== false
+                    ) {
+                        $value[1] = '"';
+                    } elseif (
+                        $value[1] === '"' &&
+                        (strpos($content, '"') !== false and strpos($content, "'") === false)
+                    ) {
+                        $value[1] = "'";
+                    }
+
+                    $content = str_replace($value[1], '\\' . $value[1], $content);
+                }
+
+                return $value[1] . $content . $value[1];
+
+            case Type::T_FUNCTION:
+                $args = ! empty($value[2]) ? $this->compileValue($value[2]) : '';
+
+                return "$value[1]($args)";
+
+            case Type::T_FUNCTION_REFERENCE:
+                $name = ! empty($value[2]) ? $value[2] : '';
+
+                return "get-function(\"$name\")";
+
+            case Type::T_LIST:
+                $value = $this->extractInterpolation($value);
+
+                if ($value[0] !== Type::T_LIST) {
+                    return $this->compileValue($value);
+                }
+
+                list(, $delim, $items) = $value;
+                $pre = $post = '';
+
+                if (! empty($value['enclosing'])) {
+                    switch ($value['enclosing']) {
+                        case 'parent':
+                            //$pre = '(';
+                            //$post = ')';
+                            break;
+                        case 'forced_parent':
+                            $pre = '(';
+                            $post = ')';
+                            break;
+                        case 'bracket':
+                        case 'forced_bracket':
+                            $pre = '[';
+                            $post = ']';
+                            break;
+                    }
+                }
+
+                $prefix_value = '';
+
+                if ($delim !== ' ') {
+                    $prefix_value = ' ';
+                }
+
+                $filtered = [];
+
+                $same_string_quote = null;
+                foreach ($items as $item) {
+                    if (\is_null($same_string_quote)) {
+                        $same_string_quote = false;
+                        if ($item[0] === Type::T_STRING) {
+                            $same_string_quote = $item[1];
+                            foreach ($items as $ii) {
+                                if ($ii[0] !== Type::T_STRING) {
+                                    $same_string_quote = false;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if ($item[0] === Type::T_NULL) {
+                        continue;
+                    }
+                    if ($same_string_quote === '"' && $item[0] === Type::T_STRING && $item[1]) {
+                        $item[1] = $same_string_quote;
+                    }
+
+                    $compiled = $this->compileValue($item);
+
+                    if ($prefix_value && \strlen($compiled)) {
+                        $compiled = $prefix_value . $compiled;
+                    }
+
+                    $filtered[] = $compiled;
+                }
+
+                return $pre . substr(implode("$delim", $filtered), \strlen($prefix_value)) . $post;
+
+            case Type::T_MAP:
+                $keys     = $value[1];
+                $values   = $value[2];
+                $filtered = [];
+
+                for ($i = 0, $s = \count($keys); $i < $s; $i++) {
+                    $filtered[$this->compileValue($keys[$i])] = $this->compileValue($values[$i]);
+                }
+
+                array_walk($filtered, function (&$value, $key) {
+                    $value = $key . ': ' . $value;
+                });
+
+                return '(' . implode(', ', $filtered) . ')';
+
+            case Type::T_INTERPOLATED:
+                // node created by extractInterpolation
+                list(, $interpolate, $left, $right) = $value;
+                list(,, $whiteLeft, $whiteRight) = $interpolate;
+
+                $delim = $left[1];
+
+                if ($delim && $delim !== ' ' && ! $whiteLeft) {
+                    $delim .= ' ';
+                }
+
+                $left = \count($left[2]) > 0
+                    ?  $this->compileValue($left) . $delim . $whiteLeft
+                    : '';
+
+                $delim = $right[1];
+
+                if ($delim && $delim !== ' ') {
+                    $delim .= ' ';
+                }
+
+                $right = \count($right[2]) > 0 ?
+                    $whiteRight . $delim . $this->compileValue($right) : '';
+
+                return $left . $this->compileValue($interpolate) . $right;
+
+            case Type::T_INTERPOLATE:
+                // strip quotes if it's a string
+                $reduced = $this->reduce($value[1]);
+
+                switch ($reduced[0]) {
+                    case Type::T_LIST:
+                        $reduced = $this->extractInterpolation($reduced);
+
+                        if ($reduced[0] !== Type::T_LIST) {
+                            break;
+                        }
+
+                        list(, $delim, $items) = $reduced;
+
+                        if ($delim !== ' ') {
+                            $delim .= ' ';
+                        }
+
+                        $filtered = [];
+
+                        foreach ($items as $item) {
+                            if ($item[0] === Type::T_NULL) {
+                                continue;
+                            }
+
+                            $temp = $this->compileValue([Type::T_KEYWORD, $item]);
+
+                            if ($temp[0] === Type::T_STRING) {
+                                $filtered[] = $this->compileStringContent($temp);
+                            } elseif ($temp[0] === Type::T_KEYWORD) {
+                                $filtered[] = $temp[1];
+                            } else {
+                                $filtered[] = $this->compileValue($temp);
+                            }
+                        }
+
+                        $reduced = [Type::T_KEYWORD, implode("$delim", $filtered)];
+                        break;
+
+                    case Type::T_STRING:
+                        $reduced = [Type::T_STRING, '', [$this->compileStringContent($reduced)]];
+                        break;
+
+                    case Type::T_NULL:
+                        $reduced = [Type::T_KEYWORD, ''];
+                }
+
+                return $this->compileValue($reduced);
+
+            case Type::T_NULL:
+                return 'null';
+
+            case Type::T_COMMENT:
+                return $this->compileCommentValue($value);
+
+            default:
+                throw $this->error('unknown value type: ' . json_encode($value));
+        }
+    }
+
+    /**
+     * @param array $value
+     *
+     * @return array|string
+     */
+    protected function compileDebugValue($value)
+    {
+        $value = $this->reduce($value, true);
+
+        switch ($value[0]) {
+            case Type::T_STRING:
+                return $this->compileStringContent($value);
+
+            default:
+                return $this->compileValue($value);
+        }
+    }
+
+    /**
+     * Flatten list
+     *
+     * @param array $list
+     *
+     * @return string
+     */
+    protected function flattenList($list)
+    {
+        return $this->compileValue($list);
+    }
+
+    /**
+     * Compile string content
+     *
+     * @param array $string
+     *
+     * @return string
+     */
+    protected function compileStringContent($string)
+    {
+        $parts = [];
+
+        foreach ($string[2] as $part) {
+            if (\is_array($part) || $part instanceof \ArrayAccess) {
+                $parts[] = $this->compileValue($part);
+            } else {
+                $parts[] = $part;
+            }
+        }
+
+        return implode($parts);
+    }
+
+    /**
+     * Extract interpolation; it doesn't need to be recursive, compileValue will handle that
+     *
+     * @param array $list
+     *
+     * @return array
+     */
+    protected function extractInterpolation($list)
+    {
+        $items = $list[2];
+
+        foreach ($items as $i => $item) {
+            if ($item[0] === Type::T_INTERPOLATE) {
+                $before = [Type::T_LIST, $list[1], \array_slice($items, 0, $i)];
+                $after  = [Type::T_LIST, $list[1], \array_slice($items, $i + 1)];
+
+                return [Type::T_INTERPOLATED, $item, $before, $after];
+            }
+        }
+
+        return $list;
+    }
+
+    /**
+     * Find the final set of selectors
+     *
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     * @param \ScssPhp\ScssPhp\Block                $selfParent
+     *
+     * @return array
+     */
+    protected function multiplySelectors(Environment $env, $selfParent = null)
+    {
+        $envs            = $this->compactEnv($env);
+        $selectors       = [];
+        $parentSelectors = [[]];
+
+        $selfParentSelectors = null;
+
+        if (! \is_null($selfParent) && $selfParent->selectors) {
+            $selfParentSelectors = $this->evalSelectors($selfParent->selectors);
+        }
+
+        while ($env = array_pop($envs)) {
+            if (empty($env->selectors)) {
+                continue;
+            }
+
+            $selectors = $env->selectors;
+
+            do {
+                $stillHasSelf  = false;
+                $prevSelectors = $selectors;
+                $selectors     = [];
+
+                foreach ($parentSelectors as $parent) {
+                    foreach ($prevSelectors as $selector) {
+                        if ($selfParentSelectors) {
+                            foreach ($selfParentSelectors as $selfParent) {
+                                // if no '&' in the selector, each call will give same result, only add once
+                                $s = $this->joinSelectors($parent, $selector, $stillHasSelf, $selfParent);
+                                $selectors[serialize($s)] = $s;
+                            }
+                        } else {
+                            $s = $this->joinSelectors($parent, $selector, $stillHasSelf);
+                            $selectors[serialize($s)] = $s;
+                        }
+                    }
+                }
+            } while ($stillHasSelf);
+
+            $parentSelectors = $selectors;
+        }
+
+        $selectors = array_values($selectors);
+
+        // case we are just starting a at-root : nothing to multiply but parentSelectors
+        if (! $selectors && $selfParentSelectors) {
+            $selectors = $selfParentSelectors;
+        }
+
+        return $selectors;
+    }
+
+    /**
+     * Join selectors; looks for & to replace, or append parent before child
+     *
+     * @param array   $parent
+     * @param array   $child
+     * @param boolean $stillHasSelf
+     * @param array   $selfParentSelectors
+
+     * @return array
+     */
+    protected function joinSelectors($parent, $child, &$stillHasSelf, $selfParentSelectors = null)
+    {
+        $setSelf = false;
+        $out = [];
+
+        foreach ($child as $part) {
+            $newPart = [];
+
+            foreach ($part as $p) {
+                // only replace & once and should be recalled to be able to make combinations
+                if ($p === static::$selfSelector && $setSelf) {
+                    $stillHasSelf = true;
+                }
+
+                if ($p === static::$selfSelector && ! $setSelf) {
+                    $setSelf = true;
+
+                    if (\is_null($selfParentSelectors)) {
+                        $selfParentSelectors = $parent;
+                    }
+
+                    foreach ($selfParentSelectors as $i => $parentPart) {
+                        if ($i > 0) {
+                            $out[] = $newPart;
+                            $newPart = [];
+                        }
+
+                        foreach ($parentPart as $pp) {
+                            if (\is_array($pp)) {
+                                $flatten = [];
+
+                                array_walk_recursive($pp, function ($a) use (&$flatten) {
+                                    $flatten[] = $a;
+                                });
+
+                                $pp = implode($flatten);
+                            }
+
+                            $newPart[] = $pp;
+                        }
+                    }
+                } else {
+                    $newPart[] = $p;
+                }
+            }
+
+            $out[] = $newPart;
+        }
+
+        return $setSelf ? $out : array_merge($parent, $child);
+    }
+
+    /**
+     * Multiply media
+     *
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     * @param array                                 $childQueries
+     *
+     * @return array
+     */
+    protected function multiplyMedia(Environment $env = null, $childQueries = null)
+    {
+        if (
+            ! isset($env) ||
+            ! empty($env->block->type) && $env->block->type !== Type::T_MEDIA
+        ) {
+            return $childQueries;
+        }
+
+        // plain old block, skip
+        if (empty($env->block->type)) {
+            return $this->multiplyMedia($env->parent, $childQueries);
+        }
+
+        $parentQueries = isset($env->block->queryList)
+            ? $env->block->queryList
+            : [[[Type::T_MEDIA_VALUE, $env->block->value]]];
+
+        $store = [$this->env, $this->storeEnv];
+
+        $this->env      = $env;
+        $this->storeEnv = null;
+        $parentQueries  = $this->evaluateMediaQuery($parentQueries);
+
+        list($this->env, $this->storeEnv) = $store;
+
+        if (\is_null($childQueries)) {
+            $childQueries = $parentQueries;
+        } else {
+            $originalQueries = $childQueries;
+            $childQueries = [];
+
+            foreach ($parentQueries as $parentQuery) {
+                foreach ($originalQueries as $childQuery) {
+                    $childQueries[] = array_merge(
+                        $parentQuery,
+                        [[Type::T_MEDIA_TYPE, [Type::T_KEYWORD, 'all']]],
+                        $childQuery
+                    );
+                }
+            }
+        }
+
+        return $this->multiplyMedia($env->parent, $childQueries);
+    }
+
+    /**
+     * Convert env linked list to stack
+     *
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     *
+     * @return array
+     */
+    protected function compactEnv(Environment $env)
+    {
+        for ($envs = []; $env; $env = $env->parent) {
+            $envs[] = $env;
+        }
+
+        return $envs;
+    }
+
+    /**
+     * Convert env stack to singly linked list
+     *
+     * @param array $envs
+     *
+     * @return \ScssPhp\ScssPhp\Compiler\Environment
+     */
+    protected function extractEnv($envs)
+    {
+        for ($env = null; $e = array_pop($envs);) {
+            $e->parent = $env;
+            $env = $e;
+        }
+
+        return $env;
+    }
+
+    /**
+     * Push environment
+     *
+     * @param \ScssPhp\ScssPhp\Block $block
+     *
+     * @return \ScssPhp\ScssPhp\Compiler\Environment
+     */
+    protected function pushEnv(Block $block = null)
+    {
+        $env = new Environment();
+        $env->parent = $this->env;
+        $env->parentStore = $this->storeEnv;
+        $env->store  = [];
+        $env->block  = $block;
+        $env->depth  = isset($this->env->depth) ? $this->env->depth + 1 : 0;
+
+        $this->env = $env;
+        $this->storeEnv = null;
+
+        return $env;
+    }
+
+    /**
+     * Pop environment
+     */
+    protected function popEnv()
+    {
+        $this->storeEnv = $this->env->parentStore;
+        $this->env = $this->env->parent;
+    }
+
+    /**
+     * Propagate vars from a just poped Env (used in @each and @for)
+     *
+     * @param array      $store
+     * @param null|array $excludedVars
+     */
+    protected function backPropagateEnv($store, $excludedVars = null)
+    {
+        foreach ($store as $key => $value) {
+            if (empty($excludedVars) || ! \in_array($key, $excludedVars)) {
+                $this->set($key, $value, true);
+            }
+        }
+    }
+
+    /**
+     * Get store environment
+     *
+     * @return \ScssPhp\ScssPhp\Compiler\Environment
+     */
+    protected function getStoreEnv()
+    {
+        return isset($this->storeEnv) ? $this->storeEnv : $this->env;
+    }
+
+    /**
+     * Set variable
+     *
+     * @param string                                $name
+     * @param mixed                                 $value
+     * @param boolean                               $shadow
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     * @param mixed                                 $valueUnreduced
+     */
+    protected function set($name, $value, $shadow = false, Environment $env = null, $valueUnreduced = null)
+    {
+        $name = $this->normalizeName($name);
+
+        if (! isset($env)) {
+            $env = $this->getStoreEnv();
+        }
+
+        if ($shadow) {
+            $this->setRaw($name, $value, $env, $valueUnreduced);
+        } else {
+            $this->setExisting($name, $value, $env, $valueUnreduced);
+        }
+    }
+
+    /**
+     * Set existing variable
+     *
+     * @param string                                $name
+     * @param mixed                                 $value
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     * @param mixed                                 $valueUnreduced
+     */
+    protected function setExisting($name, $value, Environment $env, $valueUnreduced = null)
+    {
+        $storeEnv = $env;
+        $specialContentKey = static::$namespaces['special'] . 'content';
+
+        $hasNamespace = $name[0] === '^' || $name[0] === '@' || $name[0] === '%';
+
+        $maxDepth = 10000;
+
+        for (;;) {
+            if ($maxDepth-- <= 0) {
+                break;
+            }
+
+            if (\array_key_exists($name, $env->store)) {
+                break;
+            }
+
+            if (! $hasNamespace && isset($env->marker)) {
+                if (! empty($env->store[$specialContentKey])) {
+                    $env = $env->store[$specialContentKey]->scope;
+                    continue;
+                }
+
+                if (! empty($env->declarationScopeParent)) {
+                    $env = $env->declarationScopeParent;
+                    continue;
+                } else {
+                    $env = $storeEnv;
+                    break;
+                }
+            }
+
+            if (isset($env->parentStore)) {
+                $env = $env->parentStore;
+            } elseif (isset($env->parent)) {
+                $env = $env->parent;
+            } else {
+                $env = $storeEnv;
+                break;
+            }
+        }
+
+        $env->store[$name] = $value;
+
+        if ($valueUnreduced) {
+            $env->storeUnreduced[$name] = $valueUnreduced;
+        }
+    }
+
+    /**
+     * Set raw variable
+     *
+     * @param string                                $name
+     * @param mixed                                 $value
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     * @param mixed                                 $valueUnreduced
+     */
+    protected function setRaw($name, $value, Environment $env, $valueUnreduced = null)
+    {
+        $env->store[$name] = $value;
+
+        if ($valueUnreduced) {
+            $env->storeUnreduced[$name] = $valueUnreduced;
+        }
+    }
+
+    /**
+     * Get variable
+     *
+     * @api
+     *
+     * @param string                                $name
+     * @param boolean                               $shouldThrow
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     * @param boolean                               $unreduced
+     *
+     * @return mixed|null
+     */
+    public function get($name, $shouldThrow = true, Environment $env = null, $unreduced = false)
+    {
+        $normalizedName = $this->normalizeName($name);
+        $specialContentKey = static::$namespaces['special'] . 'content';
+
+        if (! isset($env)) {
+            $env = $this->getStoreEnv();
+        }
+
+        $hasNamespace = $normalizedName[0] === '^' || $normalizedName[0] === '@' || $normalizedName[0] === '%';
+
+        $maxDepth = 10000;
+
+        for (;;) {
+            if ($maxDepth-- <= 0) {
+                break;
+            }
+
+            if (\array_key_exists($normalizedName, $env->store)) {
+                if ($unreduced && isset($env->storeUnreduced[$normalizedName])) {
+                    return $env->storeUnreduced[$normalizedName];
+                }
+
+                return $env->store[$normalizedName];
+            }
+
+            if (! $hasNamespace && isset($env->marker)) {
+                if (! empty($env->store[$specialContentKey])) {
+                    $env = $env->store[$specialContentKey]->scope;
+                    continue;
+                }
+
+                if (! empty($env->declarationScopeParent)) {
+                    $env = $env->declarationScopeParent;
+                } else {
+                    $env = $this->rootEnv;
+                }
+                continue;
+            }
+
+            if (isset($env->parentStore)) {
+                $env = $env->parentStore;
+            } elseif (isset($env->parent)) {
+                $env = $env->parent;
+            } else {
+                break;
+            }
+        }
+
+        if ($shouldThrow) {
+            throw $this->error("Undefined variable \$$name" . ($maxDepth <= 0 ? ' (infinite recursion)' : ''));
+        }
+
+        // found nothing
+        return null;
+    }
+
+    /**
+     * Has variable?
+     *
+     * @param string                                $name
+     * @param \ScssPhp\ScssPhp\Compiler\Environment $env
+     *
+     * @return boolean
+     */
+    protected function has($name, Environment $env = null)
+    {
+        return ! \is_null($this->get($name, false, $env));
+    }
+
+    /**
+     * Inject variables
+     *
+     * @param array $args
+     */
+    protected function injectVariables(array $args)
+    {
+        if (empty($args)) {
+            return;
+        }
+
+        $parser = $this->parserFactory(__METHOD__);
+
+        foreach ($args as $name => $strValue) {
+            if ($name[0] === '$') {
+                $name = substr($name, 1);
+            }
+
+            if (! $parser->parseValue($strValue, $value)) {
+                $value = $this->coerceValue($strValue);
+            }
+
+            $this->set($name, $value);
+        }
+    }
+
+    /**
+     * Set variables
+     *
+     * @api
+     *
+     * @param array $variables
+     */
+    public function setVariables(array $variables)
+    {
+        $this->registeredVars = array_merge($this->registeredVars, $variables);
+    }
+
+    /**
+     * Unset variable
+     *
+     * @api
+     *
+     * @param string $name
+     */
+    public function unsetVariable($name)
+    {
+        unset($this->registeredVars[$name]);
+    }
+
+    /**
+     * Returns list of variables
+     *
+     * @api
+     *
+     * @return array
+     */
+    public function getVariables()
+    {
+        return $this->registeredVars;
+    }
+
+    /**
+     * Adds to list of parsed files
+     *
+     * @api
+     *
+     * @param string $path
+     */
+    public function addParsedFile($path)
+    {
+        if (isset($path) && is_file($path)) {
+            $this->parsedFiles[realpath($path)] = filemtime($path);
+        }
+    }
+
+    /**
+     * Returns list of parsed files
+     *
+     * @api
+     *
+     * @return array
+     */
+    public function getParsedFiles()
+    {
+        return $this->parsedFiles;
+    }
+
+    /**
+     * Add import path
+     *
+     * @api
+     *
+     * @param string|callable $path
+     */
+    public function addImportPath($path)
+    {
+        if (! \in_array($path, $this->importPaths)) {
+            $this->importPaths[] = $path;
+        }
+    }
+
+    /**
+     * Set import paths
+     *
+     * @api
+     *
+     * @param string|array $path
+     */
+    public function setImportPaths($path)
+    {
+        $this->importPaths = (array) $path;
+    }
+
+    /**
+     * Set number precision
+     *
+     * @api
+     *
+     * @param integer $numberPrecision
+     *
+     * @deprecated The number precision is not configurable anymore. The default is enough for all browsers.
+     */
+    public function setNumberPrecision($numberPrecision)
+    {
+        @trigger_error('The number precision is not configurable anymore. '
+            . 'The default is enough for all browsers.', E_USER_DEPRECATED);
+    }
+
+    /**
+     * Set formatter
+     *
+     * @api
+     *
+     * @param string $formatterName
+     */
+    public function setFormatter($formatterName)
+    {
+        $this->formatter = $formatterName;
+    }
+
+    /**
+     * Set line number style
+     *
+     * @api
+     *
+     * @param string $lineNumberStyle
+     *
+     * @deprecated The line number output is not supported anymore. Use source maps instead.
+     */
+    public function setLineNumberStyle($lineNumberStyle)
+    {
+        @trigger_error('The line number output is not supported anymore. '
+                       . 'Use source maps instead.', E_USER_DEPRECATED);
+    }
+
+    /**
+     * Enable/disable source maps
+     *
+     * @api
+     *
+     * @param integer $sourceMap
+     */
+    public function setSourceMap($sourceMap)
+    {
+        $this->sourceMap = $sourceMap;
+    }
+
+    /**
+     * Set source map options
+     *
+     * @api
+     *
+     * @param array $sourceMapOptions
+     */
+    public function setSourceMapOptions($sourceMapOptions)
+    {
+        $this->sourceMapOptions = $sourceMapOptions;
+    }
+
+    /**
+     * Register function
+     *
+     * @api
+     *
+     * @param string   $name
+     * @param callable $func
+     * @param array    $prototype
+     */
+    public function registerFunction($name, $func, $prototype = null)
+    {
+        $this->userFunctions[$this->normalizeName($name)] = [$func, $prototype];
+    }
+
+    /**
+     * Unregister function
+     *
+     * @api
+     *
+     * @param string $name
+     */
+    public function unregisterFunction($name)
+    {
+        unset($this->userFunctions[$this->normalizeName($name)]);
+    }
+
+    /**
+     * Add feature
+     *
+     * @api
+     *
+     * @param string $name
+     *
+     * @deprecated Registering additional features is deprecated.
+     */
+    public function addFeature($name)
+    {
+        @trigger_error('Registering additional features is deprecated.', E_USER_DEPRECATED);
+
+        $this->registeredFeatures[$name] = true;
+    }
+
+    /**
+     * Import file
+     *
+     * @param string                                 $path
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out
+     */
+    protected function importFile($path, OutputBlock $out)
+    {
+        $this->pushCallStack('import ' . $path);
+        // see if tree is cached
+        $realPath = realpath($path);
+
+        if (isset($this->importCache[$realPath])) {
+            $this->handleImportLoop($realPath);
+
+            $tree = $this->importCache[$realPath];
+        } else {
+            $code   = file_get_contents($path);
+            $parser = $this->parserFactory($path);
+            $tree   = $parser->parse($code);
+
+            $this->importCache[$realPath] = $tree;
+        }
+
+        $pi = pathinfo($path);
+
+        array_unshift($this->importPaths, $pi['dirname']);
+        $this->compileChildrenNoReturn($tree->children, $out);
+        array_shift($this->importPaths);
+        $this->popCallStack();
+    }
+
+    /**
+     * Return the file path for an import url if it exists
+     *
+     * @api
+     *
+     * @param string $url
+     *
+     * @return string|null
+     */
+    public function findImport($url)
+    {
+        $urls = [];
+
+        $hasExtension = preg_match('/[.]s?css$/', $url);
+
+        // for "normal" scss imports (ignore vanilla css and external requests)
+        if (! preg_match('~\.css$|^https?://|^//~', $url)) {
+            $isPartial = (strpos(basename($url), '_') === 0);
+
+            // try both normal and the _partial filename
+            $urls = [$url . ($hasExtension ? '' : '.scss')];
+
+            if (! $isPartial) {
+                $urls[] = preg_replace('~[^/]+$~', '_\0', $url) . ($hasExtension ? '' : '.scss');
+            }
+
+            if (! $hasExtension) {
+                $urls[] = "$url/index.scss";
+                // allow to find a plain css file, *if* no scss or partial scss is found
+                $urls[] .= $url . '.css';
+            }
+        }
+
+        foreach ($this->importPaths as $dir) {
+            if (\is_string($dir)) {
+                // check urls for normal import paths
+                foreach ($urls as $full) {
+                    $found = [];
+                    $separator = (
+                        ! empty($dir) &&
+                        substr($dir, -1) !== '/' &&
+                        substr($full, 0, 1) !== '/'
+                    ) ? '/' : '';
+                    $full = $dir . $separator . $full;
+
+                    if (is_file($file = $full)) {
+                        $found[] = $file;
+                    }
+                    if (! $isPartial) {
+                        $full = dirname($full) . '/_' . basename($full);
+                        if (is_file($file = $full)) {
+                            $found[] = $file;
+                        }
+                    }
+                    if ($found) {
+                        if (\count($found) === 1) {
+                            return reset($found);
+                        }
+                        if (\count($found) > 1) {
+                            throw $this->error(
+                                "Error: It's not clear which file to import. Found: " . implode(', ', $found)
+                            );
+                        }
+                    }
+                }
+            } elseif (\is_callable($dir)) {
+                // check custom callback for import path
+                $file = \call_user_func($dir, $url);
+
+                if (! \is_null($file)) {
+                    return $file;
+                }
+            }
+        }
+
+        if ($urls) {
+            if (! $hasExtension || preg_match('/[.]scss$/', $url)) {
+                throw $this->error("`$url` file not found for @import");
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Set encoding
+     *
+     * @api
+     *
+     * @param string $encoding
+     */
+    public function setEncoding($encoding)
+    {
+        $this->encoding = $encoding;
+    }
+
+    /**
+     * Ignore errors?
+     *
+     * @api
+     *
+     * @param boolean $ignoreErrors
+     *
+     * @return \ScssPhp\ScssPhp\Compiler
+     *
+     * @deprecated Ignoring Sass errors is not longer supported.
+     */
+    public function setIgnoreErrors($ignoreErrors)
+    {
+        @trigger_error('Ignoring Sass errors is not longer supported.', E_USER_DEPRECATED);
+
+        return $this;
+    }
+
+    /**
+     * Get source position
+     *
+     * @api
+     *
+     * @return array
+     */
+    public function getSourcePosition()
+    {
+        $sourceFile = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] : '';
+
+        return [$sourceFile, $this->sourceLine, $this->sourceColumn];
+    }
+
+    /**
+     * Throw error (exception)
+     *
+     * @api
+     *
+     * @param string $msg Message with optional sprintf()-style vararg parameters
+     *
+     * @throws \ScssPhp\ScssPhp\Exception\CompilerException
+     *
+     * @deprecated use "error" and throw the exception in the caller instead.
+     */
+    public function throwError($msg)
+    {
+        @trigger_error(
+            'The method "throwError" is deprecated. Use "error" and throw the exception in the caller instead',
+            E_USER_DEPRECATED
+        );
+
+        throw $this->error(...func_get_args());
+    }
+
+    /**
+     * Build an error (exception)
+     *
+     * @api
+     *
+     * @param string $msg Message with optional sprintf()-style vararg parameters
+     *
+     * @return CompilerException
+     */
+    public function error($msg, ...$args)
+    {
+        if ($args) {
+            $msg = sprintf($msg, ...$args);
+        }
+
+        if (! $this->ignoreCallStackMessage) {
+            $line   = $this->sourceLine;
+            $column = $this->sourceColumn;
+
+            $loc = isset($this->sourceNames[$this->sourceIndex])
+                ? $this->sourceNames[$this->sourceIndex] . " on line $line, at column $column"
+                : "line: $line, column: $column";
+
+            $msg = "$msg: $loc";
+
+            $callStackMsg = $this->callStackMessage();
+
+            if ($callStackMsg) {
+                $msg .= "\nCall Stack:\n" . $callStackMsg;
+            }
+        }
+
+        return new CompilerException($msg);
+    }
+
+    /**
+     * @param string $functionName
+     * @param array $ExpectedArgs
+     * @param int $nbActual
+     * @return CompilerException
+     */
+    public function errorArgsNumber($functionName, $ExpectedArgs, $nbActual)
+    {
+        $nbExpected = \count($ExpectedArgs);
+
+        if ($nbActual > $nbExpected) {
+            return $this->error(
+                'Error: Only %d arguments allowed in %s(), but %d were passed.',
+                $nbExpected,
+                $functionName,
+                $nbActual
+            );
+        } else {
+            $missing = [];
+
+            while (count($ExpectedArgs) && count($ExpectedArgs) > $nbActual) {
+                array_unshift($missing, array_pop($ExpectedArgs));
+            }
+
+            return $this->error(
+                'Error: %s() argument%s %s missing.',
+                $functionName,
+                count($missing) > 1 ? 's' : '',
+                implode(', ', $missing)
+            );
+        }
+    }
+
+    /**
+     * Beautify call stack for output
+     *
+     * @param boolean $all
+     * @param null    $limit
+     *
+     * @return string
+     */
+    protected function callStackMessage($all = false, $limit = null)
+    {
+        $callStackMsg = [];
+        $ncall = 0;
+
+        if ($this->callStack) {
+            foreach (array_reverse($this->callStack) as $call) {
+                if ($all || (isset($call['n']) && $call['n'])) {
+                    $msg = '#' . $ncall++ . ' ' . $call['n'] . ' ';
+                    $msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]])
+                          ? $this->sourceNames[$call[Parser::SOURCE_INDEX]]
+                          : '(unknown file)');
+                    $msg .= ' on line ' . $call[Parser::SOURCE_LINE];
+
+                    $callStackMsg[] = $msg;
+
+                    if (! \is_null($limit) && $ncall > $limit) {
+                        break;
+                    }
+                }
+            }
+        }
+
+        return implode("\n", $callStackMsg);
+    }
+
+    /**
+     * Handle import loop
+     *
+     * @param string $name
+     *
+     * @throws \Exception
+     */
+    protected function handleImportLoop($name)
+    {
+        for ($env = $this->env; $env; $env = $env->parent) {
+            if (! $env->block) {
+                continue;
+            }
+
+            $file = $this->sourceNames[$env->block->sourceIndex];
+
+            if (realpath($file) === $name) {
+                throw $this->error('An @import loop has been found: %s imports %s', $file, basename($file));
+            }
+        }
+    }
+
+    /**
+     * Call SCSS @function
+     *
+     * @param Object $func
+     * @param array  $argValues
+     *
+     * @return array $returnValue
+     */
+    protected function callScssFunction($func, $argValues)
+    {
+        if (! $func) {
+            return static::$defaultValue;
+        }
+        $name = $func->name;
+
+        $this->pushEnv();
+
+        // set the args
+        if (isset($func->args)) {
+            $this->applyArguments($func->args, $argValues);
+        }
+
+        // throw away lines and children
+        $tmp = new OutputBlock();
+        $tmp->lines    = [];
+        $tmp->children = [];
+
+        $this->env->marker = 'function';
+
+        if (! empty($func->parentEnv)) {
+            $this->env->declarationScopeParent = $func->parentEnv;
+        } else {
+            throw $this->error("@function $name() without parentEnv");
+        }
+
+        $ret = $this->compileChildren($func->children, $tmp, $this->env->marker . ' ' . $name);
+
+        $this->popEnv();
+
+        return ! isset($ret) ? static::$defaultValue : $ret;
+    }
+
+    /**
+     * Call built-in and registered (PHP) functions
+     *
+     * @param string $name
+     * @param string|array $function
+     * @param array  $prototype
+     * @param array  $args
+     *
+     * @return array
+     */
+    protected function callNativeFunction($name, $function, $prototype, $args)
+    {
+        $libName = (is_array($function) ? end($function) : null);
+        $sorted_kwargs = $this->sortNativeFunctionArgs($libName, $prototype, $args);
+
+        if (\is_null($sorted_kwargs)) {
+            return null;
+        }
+        @list($sorted, $kwargs) = $sorted_kwargs;
+
+        if ($name !== 'if' && $name !== 'call') {
+            $inExp = true;
+
+            if ($name === 'join') {
+                $inExp = false;
+            }
+
+            foreach ($sorted as &$val) {
+                $val = $this->reduce($val, $inExp);
+            }
+        }
+
+        $returnValue = \call_user_func($function, $sorted, $kwargs);
+
+        if (! isset($returnValue)) {
+            return null;
+        }
+
+        return $this->coerceValue($returnValue);
+    }
+
+    /**
+     * Get built-in function
+     *
+     * @param string $name Normalized name
+     *
+     * @return array
+     */
+    protected function getBuiltinFunction($name)
+    {
+        $libName = self::normalizeNativeFunctionName($name);
+        return [$this, $libName];
+    }
+
+    /**
+     * Normalize native function name
+     * @param $name
+     * @return string
+     */
+    public static function normalizeNativeFunctionName($name)
+    {
+        $name = str_replace("-", "_", $name);
+        $libName = 'lib' . preg_replace_callback(
+            '/_(.)/',
+            function ($m) {
+                return ucfirst($m[1]);
+            },
+            ucfirst($name)
+        );
+        return $libName;
+    }
+
+    /**
+     * Check if a function is a native built-in scss function, for css parsing
+     * @param $name
+     * @return bool
+     */
+    public static function isNativeFunction($name)
+    {
+        return method_exists(Compiler::class, self::normalizeNativeFunctionName($name));
+    }
+
+    /**
+     * Sorts keyword arguments
+     *
+     * @param string $functionName
+     * @param array  $prototypes
+     * @param array  $args
+     *
+     * @return array|null
+     */
+    protected function sortNativeFunctionArgs($functionName, $prototypes, $args)
+    {
+        static $parser = null;
+
+        if (! isset($prototypes)) {
+            $keyArgs = [];
+            $posArgs = [];
+
+            if (\is_array($args) && \count($args) && \end($args) === static::$null) {
+                array_pop($args);
+            }
+
+            // separate positional and keyword arguments
+            foreach ($args as $arg) {
+                list($key, $value) = $arg;
+
+                if (empty($key) or empty($key[1])) {
+                    $posArgs[] = empty($arg[2]) ? $value : $arg;
+                } else {
+                    $keyArgs[$key[1]] = $value;
+                }
+            }
+
+            return [$posArgs, $keyArgs];
+        }
+
+        // specific cases ?
+        if (\in_array($functionName, ['libRgb', 'libRgba', 'libHsl', 'libHsla'])) {
+            // notation 100 127 255 / 0 is in fact a simple list of 4 values
+            foreach ($args as $k => $arg) {
+                if ($arg[1][0] === Type::T_LIST && \count($arg[1][2]) === 3) {
+                    $last = end($arg[1][2]);
+
+                    if ($last[0] === Type::T_EXPRESSION && $last[1] === '/') {
+                        array_pop($arg[1][2]);
+                        $arg[1][2][] = $last[2];
+                        $arg[1][2][] = $last[3];
+                        $args[$k] = $arg;
+                    }
+                }
+            }
+        }
+
+        $finalArgs = [];
+
+        if (! \is_array(reset($prototypes))) {
+            $prototypes = [$prototypes];
+        }
+
+        $keyArgs = [];
+
+        // trying each prototypes
+        $prototypeHasMatch = false;
+        $exceptionMessage = '';
+
+        foreach ($prototypes as $prototype) {
+            $argDef = [];
+
+            foreach ($prototype as $i => $p) {
+                $default = null;
+                $p       = explode(':', $p, 2);
+                $name    = array_shift($p);
+
+                if (\count($p)) {
+                    $p = trim(reset($p));
+
+                    if ($p === 'null') {
+                        // differentiate this null from the static::$null
+                        $default = [Type::T_KEYWORD, 'null'];
+                    } else {
+                        if (\is_null($parser)) {
+                            $parser = $this->parserFactory(__METHOD__);
+                        }
+
+                        $parser->parseValue($p, $default);
+                    }
+                }
+
+                $isVariable = false;
+
+                if (substr($name, -3) === '...') {
+                    $isVariable = true;
+                    $name = substr($name, 0, -3);
+                }
+
+                $argDef[] = [$name, $default, $isVariable];
+            }
+
+            $ignoreCallStackMessage = $this->ignoreCallStackMessage;
+            $this->ignoreCallStackMessage = true;
+
+            try {
+                if (\count($args) > \count($argDef)) {
+                    $lastDef = end($argDef);
+
+                    // check that last arg is not a ...
+                    if (empty($lastDef[2])) {
+                        throw $this->errorArgsNumber($functionName, $argDef, \count($args));
+                    }
+                }
+                $vars = $this->applyArguments($argDef, $args, false, false);
+
+                // ensure all args are populated
+                foreach ($prototype as $i => $p) {
+                    $name = explode(':', $p)[0];
+
+                    if (! isset($finalArgs[$i])) {
+                        $finalArgs[$i] = null;
+                    }
+                }
+
+                // apply positional args
+                foreach (array_values($vars) as $i => $val) {
+                    $finalArgs[$i] = $val;
+                }
+
+                $keyArgs = array_merge($keyArgs, $vars);
+                $prototypeHasMatch = true;
+
+                // overwrite positional args with keyword args
+                foreach ($prototype as $i => $p) {
+                    $name = explode(':', $p)[0];
+
+                    if (isset($keyArgs[$name])) {
+                        $finalArgs[$i] = $keyArgs[$name];
+                    }
+
+                    // special null value as default: translate to real null here
+                    if ($finalArgs[$i] === [Type::T_KEYWORD, 'null']) {
+                        $finalArgs[$i] = null;
+                    }
+                }
+                // should we break if this prototype seems fulfilled?
+            } catch (CompilerException $e) {
+                $exceptionMessage = $e->getMessage();
+            }
+            $this->ignoreCallStackMessage = $ignoreCallStackMessage;
+        }
+
+        if ($exceptionMessage && ! $prototypeHasMatch) {
+            if (\in_array($functionName, ['libRgb', 'libRgba', 'libHsl', 'libHsla'])) {
+                // if var() or calc() is used as an argument, return as a css function
+                foreach ($args as $arg) {
+                    if ($arg[1][0] === Type::T_FUNCTION_CALL && in_array($arg[1][1], ['var'])) {
+                        return null;
+                    }
+                }
+            }
+
+            throw $this->error($exceptionMessage);
+        }
+
+        return [$finalArgs, $keyArgs];
+    }
+
+    /**
+     * Apply argument values per definition
+     *
+     * @param array   $argDef
+     * @param array   $argValues
+     * @param boolean $storeInEnv
+     * @param boolean $reduce
+     *   only used if $storeInEnv = false
+     *
+     * @return array
+     *
+     * @throws \Exception
+     */
+    protected function applyArguments($argDef, $argValues, $storeInEnv = true, $reduce = true)
+    {
+        $output = [];
+
+        if (\is_array($argValues) && \count($argValues) && end($argValues) === static::$null) {
+            array_pop($argValues);
+        }
+
+        if ($storeInEnv) {
+            $storeEnv = $this->getStoreEnv();
+
+            $env = new Environment();
+            $env->store = $storeEnv->store;
+        }
+
+        $hasVariable = false;
+        $args = [];
+
+        foreach ($argDef as $i => $arg) {
+            list($name, $default, $isVariable) = $argDef[$i];
+
+            $args[$name] = [$i, $name, $default, $isVariable];
+            $hasVariable |= $isVariable;
+        }
+
+        $splatSeparator      = null;
+        $keywordArgs         = [];
+        $deferredKeywordArgs = [];
+        $deferredNamedKeywordArgs = [];
+        $remaining           = [];
+        $hasKeywordArgument  = false;
+
+        // assign the keyword args
+        foreach ((array) $argValues as $arg) {
+            if (! empty($arg[0])) {
+                $hasKeywordArgument = true;
+
+                $name = $arg[0][1];
+
+                if (! isset($args[$name])) {
+                    foreach (array_keys($args) as $an) {
+                        if (str_replace('_', '-', $an) === str_replace('_', '-', $name)) {
+                            $name = $an;
+                            break;
+                        }
+                    }
+                }
+
+                if (! isset($args[$name]) || $args[$name][3]) {
+                    if ($hasVariable) {
+                        $deferredNamedKeywordArgs[$name] = $arg[1];
+                    } else {
+                        throw $this->error("Mixin or function doesn't have an argument named $%s.", $arg[0][1]);
+                    }
+                } elseif ($args[$name][0] < \count($remaining)) {
+                    throw $this->error("The argument $%s was passed both by position and by name.", $arg[0][1]);
+                } else {
+                    $keywordArgs[$name] = $arg[1];
+                }
+            } elseif (! empty($arg[2])) {
+                // $arg[2] means a var followed by ... in the arg ($list... )
+                $val = $this->reduce($arg[1], true);
+
+                if ($val[0] === Type::T_LIST) {
+                    foreach ($val[2] as $name => $item) {
+                        if (! is_numeric($name)) {
+                            if (! isset($args[$name])) {
+                                foreach (array_keys($args) as $an) {
+                                    if (str_replace('_', '-', $an) === str_replace('_', '-', $name)) {
+                                        $name = $an;
+                                        break;
+                                    }
+                                }
+                            }
+
+                            if ($hasVariable) {
+                                $deferredKeywordArgs[$name] = $item;
+                            } else {
+                                $keywordArgs[$name] = $item;
+                            }
+                        } else {
+                            if (\is_null($splatSeparator)) {
+                                $splatSeparator = $val[1];
+                            }
+
+                            $remaining[] = $item;
+                        }
+                    }
+                } elseif ($val[0] === Type::T_MAP) {
+                    foreach ($val[1] as $i => $name) {
+                        $name = $this->compileStringContent($this->coerceString($name));
+                        $item = $val[2][$i];
+
+                        if (! is_numeric($name)) {
+                            if (! isset($args[$name])) {
+                                foreach (array_keys($args) as $an) {
+                                    if (str_replace('_', '-', $an) === str_replace('_', '-', $name)) {
+                                        $name = $an;
+                                        break;
+                                    }
+                                }
+                            }
+
+                            if ($hasVariable) {
+                                $deferredKeywordArgs[$name] = $item;
+                            } else {
+                                $keywordArgs[$name] = $item;
+                            }
+                        } else {
+                            if (\is_null($splatSeparator)) {
+                                $splatSeparator = $val[1];
+                            }
+
+                            $remaining[] = $item;
+                        }
+                    }
+                } else {
+                    $remaining[] = $val;
+                }
+            } elseif ($hasKeywordArgument) {
+                throw $this->error('Positional arguments must come before keyword arguments.');
+            } else {
+                $remaining[] = $arg[1];
+            }
+        }
+
+        foreach ($args as $arg) {
+            list($i, $name, $default, $isVariable) = $arg;
+
+            if ($isVariable) {
+                // only if more than one arg : can not be passed as position and value
+                // see https://github.com/sass/libsass/issues/2927
+                if (count($args) > 1) {
+                    if (isset($remaining[$i]) && isset($deferredNamedKeywordArgs[$name])) {
+                        throw $this->error("The argument $%s was passed both by position and by name.", $name);
+                    }
+                }
+
+                $val = [Type::T_LIST, \is_null($splatSeparator) ? ',' : $splatSeparator , [], $isVariable];
+
+                for ($count = \count($remaining); $i < $count; $i++) {
+                    $val[2][] = $remaining[$i];
+                }
+
+                foreach ($deferredKeywordArgs as $itemName => $item) {
+                    $val[2][$itemName] = $item;
+                }
+
+                foreach ($deferredNamedKeywordArgs as $itemName => $item) {
+                    $val[2][$itemName] = $item;
+                }
+            } elseif (isset($remaining[$i])) {
+                $val = $remaining[$i];
+            } elseif (isset($keywordArgs[$name])) {
+                $val = $keywordArgs[$name];
+            } elseif (! empty($default)) {
+                continue;
+            } else {
+                throw $this->error("Missing argument $name");
+            }
+
+            if ($storeInEnv) {
+                $this->set($name, $this->reduce($val, true), true, $env);
+            } else {
+                $output[$name] = ($reduce ? $this->reduce($val, true) : $val);
+            }
+        }
+
+        if ($storeInEnv) {
+            $storeEnv->store = $env->store;
+        }
+
+        foreach ($args as $arg) {
+            list($i, $name, $default, $isVariable) = $arg;
+
+            if ($isVariable || isset($remaining[$i]) || isset($keywordArgs[$name]) || empty($default)) {
+                continue;
+            }
+
+            if ($storeInEnv) {
+                $this->set($name, $this->reduce($default, true), true);
+            } else {
+                $output[$name] = ($reduce ? $this->reduce($default, true) : $default);
+            }
+        }
+
+        return $output;
+    }
+
+    /**
+     * Coerce a php value into a scss one
+     *
+     * @param mixed $value
+     *
+     * @return array|Number
+     */
+    protected function coerceValue($value)
+    {
+        if (\is_array($value) || $value instanceof \ArrayAccess) {
+            return $value;
+        }
+
+        if (\is_bool($value)) {
+            return $this->toBool($value);
+        }
+
+        if (\is_null($value)) {
+            return static::$null;
+        }
+
+        if (is_numeric($value)) {
+            return new Number($value, '');
+        }
+
+        if ($value === '') {
+            return static::$emptyString;
+        }
+
+        $value = [Type::T_KEYWORD, $value];
+        $color = $this->coerceColor($value);
+
+        if ($color) {
+            return $color;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Coerce something to map
+     *
+     * @param array $item
+     *
+     * @return array
+     */
+    protected function coerceMap($item)
+    {
+        if ($item[0] === Type::T_MAP) {
+            return $item;
+        }
+
+        if (
+            $item[0] === static::$emptyList[0] &&
+            $item[1] === static::$emptyList[1] &&
+            $item[2] === static::$emptyList[2]
+        ) {
+            return static::$emptyMap;
+        }
+
+        return $item;
+    }
+
+    /**
+     * Coerce something to list
+     *
+     * @param array   $item
+     * @param string  $delim
+     * @param boolean $removeTrailingNull
+     *
+     * @return array
+     */
+    protected function coerceList($item, $delim = ',', $removeTrailingNull = false)
+    {
+        if (isset($item) && $item[0] === Type::T_LIST) {
+            // remove trailing null from the list
+            if ($removeTrailingNull && end($item[2]) === static::$null) {
+                array_pop($item[2]);
+            }
+
+            return $item;
+        }
+
+        if (isset($item) && $item[0] === Type::T_MAP) {
+            $keys = $item[1];
+            $values = $item[2];
+            $list = [];
+
+            for ($i = 0, $s = \count($keys); $i < $s; $i++) {
+                $key = $keys[$i];
+                $value = $values[$i];
+
+                switch ($key[0]) {
+                    case Type::T_LIST:
+                    case Type::T_MAP:
+                    case Type::T_STRING:
+                    case Type::T_NULL:
+                        break;
+
+                    default:
+                        $key = [Type::T_KEYWORD, $this->compileStringContent($this->coerceString($key))];
+                        break;
+                }
+
+                $list[] = [
+                    Type::T_LIST,
+                    '',
+                    [$key, $value]
+                ];
+            }
+
+            return [Type::T_LIST, ',', $list];
+        }
+
+        return [Type::T_LIST, $delim, ! isset($item) ? [] : [$item]];
+    }
+
+    /**
+     * Coerce color for expression
+     *
+     * @param array $value
+     *
+     * @return array|null
+     */
+    protected function coerceForExpression($value)
+    {
+        if ($color = $this->coerceColor($value)) {
+            return $color;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Coerce value to color
+     *
+     * @param array $value
+     *
+     * @return array|null
+     */
+    protected function coerceColor($value, $inRGBFunction = false)
+    {
+        switch ($value[0]) {
+            case Type::T_COLOR:
+                for ($i = 1; $i <= 3; $i++) {
+                    if (! is_numeric($value[$i])) {
+                        $cv = $this->compileRGBAValue($value[$i]);
+
+                        if (! is_numeric($cv)) {
+                            return null;
+                        }
+
+                        $value[$i] = $cv;
+                    }
+
+                    if (isset($value[4])) {
+                        if (! is_numeric($value[4])) {
+                            $cv = $this->compileRGBAValue($value[4], true);
+
+                            if (! is_numeric($cv)) {
+                                return null;
+                            }
+
+                            $value[4] = $cv;
+                        }
+                    }
+                }
+
+                return $value;
+
+            case Type::T_LIST:
+                if ($inRGBFunction) {
+                    if (\count($value[2]) == 3 || \count($value[2]) == 4) {
+                        $color = $value[2];
+                        array_unshift($color, Type::T_COLOR);
+
+                        return $this->coerceColor($color);
+                    }
+                }
+
+                return null;
+
+            case Type::T_KEYWORD:
+                if (! \is_string($value[1])) {
+                    return null;
+                }
+
+                $name = strtolower($value[1]);
+
+                // hexa color?
+                if (preg_match('/^#([0-9a-f]+)$/i', $name, $m)) {
+                    $nofValues = \strlen($m[1]);
+
+                    if (\in_array($nofValues, [3, 4, 6, 8])) {
+                        $nbChannels = 3;
+                        $color      = [];
+                        $num        = hexdec($m[1]);
+
+                        switch ($nofValues) {
+                            case 4:
+                                $nbChannels = 4;
+                                // then continuing with the case 3:
+                            case 3:
+                                for ($i = 0; $i < $nbChannels; $i++) {
+                                    $t = $num & 0xf;
+                                    array_unshift($color, $t << 4 | $t);
+                                    $num >>= 4;
+                                }
+
+                                break;
+
+                            case 8:
+                                $nbChannels = 4;
+                                // then continuing with the case 6:
+                            case 6:
+                                for ($i = 0; $i < $nbChannels; $i++) {
+                                    array_unshift($color, $num & 0xff);
+                                    $num >>= 8;
+                                }
+
+                                break;
+                        }
+
+                        if ($nbChannels === 4) {
+                            if ($color[3] === 255) {
+                                $color[3] = 1; // fully opaque
+                            } else {
+                                $color[3] = round($color[3] / 255, Number::PRECISION);
+                            }
+                        }
+
+                        array_unshift($color, Type::T_COLOR);
+
+                        return $color;
+                    }
+                }
+
+                if ($rgba = Colors::colorNameToRGBa($name)) {
+                    return isset($rgba[3])
+                        ? [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2], $rgba[3]]
+                        : [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2]];
+                }
+
+                return null;
+        }
+
+        return null;
+    }
+
+    /**
+     * @param integer|Number $value
+     * @param boolean        $isAlpha
+     *
+     * @return integer|mixed
+     */
+    protected function compileRGBAValue($value, $isAlpha = false)
+    {
+        if ($isAlpha) {
+            return $this->compileColorPartValue($value, 0, 1, false);
+        }
+
+        return $this->compileColorPartValue($value, 0, 255, true);
+    }
+
+    /**
+     * @param mixed         $value
+     * @param integer|float $min
+     * @param integer|float $max
+     * @param boolean       $isInt
+     *
+     * @return integer|mixed
+     */
+    protected function compileColorPartValue($value, $min, $max, $isInt = true)
+    {
+        if (! is_numeric($value)) {
+            if (\is_array($value)) {
+                $reduced = $this->reduce($value);
+
+                if ($reduced instanceof Number) {
+                    $value = $reduced;
+                }
+            }
+
+            if ($value instanceof Number) {
+                if ($value->unitless()) {
+                    $num = $value->getDimension();
+                } elseif ($value->hasUnit('%')) {
+                    $num = $max * $value->getDimension() / 100;
+                } else {
+                    throw $this->error('Expected %s to have no units or "%%".', $value);
+                }
+
+                $value = $num;
+            } elseif (\is_array($value)) {
+                $value = $this->compileValue($value);
+            }
+        }
+
+        if (is_numeric($value)) {
+            if ($isInt) {
+                $value = round($value);
+            }
+
+            $value = min($max, max($min, $value));
+
+            return $value;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Coerce value to string
+     *
+     * @param array $value
+     *
+     * @return array|null
+     */
+    protected function coerceString($value)
+    {
+        if ($value[0] === Type::T_STRING) {
+            return $value;
+        }
+
+        return [Type::T_STRING, '', [$this->compileValue($value)]];
+    }
+
+    /**
+     * Assert value is a string (or keyword)
+     *
+     * @api
+     *
+     * @param array $value
+     * @param string $varName
+     *
+     * @return array
+     *
+     * @throws \Exception
+     */
+    public function assertString($value, $varName = null)
+    {
+        // case of url(...) parsed a a function
+        if ($value[0] === Type::T_FUNCTION) {
+            $value = $this->coerceString($value);
+        }
+
+        if (! \in_array($value[0], [Type::T_STRING, Type::T_KEYWORD])) {
+            $value = $this->compileValue($value);
+            $var_display = ($varName ? " \${$varName}:" : '');
+            throw $this->error("Error:{$var_display} $value is not a string.");
+        }
+
+        $value = $this->coerceString($value);
+
+        return $value;
+    }
+
+    /**
+     * Coerce value to a percentage
+     *
+     * @param array $value
+     *
+     * @return integer|float
+     */
+    protected function coercePercent($value)
+    {
+        if ($value instanceof Number) {
+            if ($value->hasUnit('%')) {
+                return $value->getDimension() / 100;
+            }
+
+            return $value->getDimension();
+        }
+
+        return 0;
+    }
+
+    /**
+     * Assert value is a map
+     *
+     * @api
+     *
+     * @param array $value
+     *
+     * @return array
+     *
+     * @throws \Exception
+     */
+    public function assertMap($value)
+    {
+        $value = $this->coerceMap($value);
+
+        if ($value[0] !== Type::T_MAP) {
+            throw $this->error('expecting map, %s received', $value[0]);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Assert value is a list
+     *
+     * @api
+     *
+     * @param array $value
+     *
+     * @return array
+     *
+     * @throws \Exception
+     */
+    public function assertList($value)
+    {
+        if ($value[0] !== Type::T_LIST) {
+            throw $this->error('expecting list, %s received', $value[0]);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Assert value is a color
+     *
+     * @api
+     *
+     * @param array $value
+     *
+     * @return array
+     *
+     * @throws \Exception
+     */
+    public function assertColor($value)
+    {
+        if ($color = $this->coerceColor($value)) {
+            return $color;
+        }
+
+        throw $this->error('expecting color, %s received', $value[0]);
+    }
+
+    /**
+     * Assert value is a number
+     *
+     * @api
+     *
+     * @param mixed $value
+     * @param string $varName
+     *
+     * @return Number
+     *
+     * @throws \Exception
+     */
+    public function assertNumber($value, $varName = null)
+    {
+        if (!$value instanceof Number) {
+            $value = $this->compileValue($value);
+            $var_display = ($varName ? " \${$varName}:" : '');
+            throw $this->error("Error:{$var_display} $value is not a number.");
+        }
+
+        return $value;
+    }
+
+    /**
+     * Assert value is a integer
+     *
+     * @api
+     *
+     * @param array $value
+     * @param string $varName
+     *
+     * @return integer|float
+     *
+     * @throws \Exception
+     */
+    public function assertInteger($value, $varName = null)
+    {
+
+        $value = $this->assertNumber($value, $varName)->getDimension();
+        if (round($value - \intval($value), Number::PRECISION) > 0) {
+            $var_display = ($varName ? " \${$varName}:" : '');
+            throw $this->error("Error:{$var_display} $value is not an integer.");
+        }
+
+        return intval($value);
+    }
+
+
+    /**
+     * Make sure a color's components don't go out of bounds
+     *
+     * @param array $c
+     *
+     * @return array
+     */
+    protected function fixColor($c)
+    {
+        foreach ([1, 2, 3] as $i) {
+            if ($c[$i] < 0) {
+                $c[$i] = 0;
+            }
+
+            if ($c[$i] > 255) {
+                $c[$i] = 255;
+            }
+        }
+
+        return $c;
+    }
+
+    /**
+     * Convert RGB to HSL
+     *
+     * @api
+     *
+     * @param integer $red
+     * @param integer $green
+     * @param integer $blue
+     *
+     * @return array
+     */
+    public function toHSL($red, $green, $blue)
+    {
+        $min = min($red, $green, $blue);
+        $max = max($red, $green, $blue);
+
+        $l = $min + $max;
+        $d = $max - $min;
+
+        if ((int) $d === 0) {
+            $h = $s = 0;
+        } else {
+            if ($l < 255) {
+                $s = $d / $l;
+            } else {
+                $s = $d / (510 - $l);
+            }
+
+            if ($red == $max) {
+                $h = 60 * ($green - $blue) / $d;
+            } elseif ($green == $max) {
+                $h = 60 * ($blue - $red) / $d + 120;
+            } elseif ($blue == $max) {
+                $h = 60 * ($red - $green) / $d + 240;
+            }
+        }
+
+        return [Type::T_HSL, fmod($h, 360), $s * 100, $l / 5.1];
+    }
+
+    /**
+     * Hue to RGB helper
+     *
+     * @param float $m1
+     * @param float $m2
+     * @param float $h
+     *
+     * @return float
+     */
+    protected function hueToRGB($m1, $m2, $h)
+    {
+        if ($h < 0) {
+            $h += 1;
+        } elseif ($h > 1) {
+            $h -= 1;
+        }
+
+        if ($h * 6 < 1) {
+            return $m1 + ($m2 - $m1) * $h * 6;
+        }
+
+        if ($h * 2 < 1) {
+            return $m2;
+        }
+
+        if ($h * 3 < 2) {
+            return $m1 + ($m2 - $m1) * (2 / 3 - $h) * 6;
+        }
+
+        return $m1;
+    }
+
+    /**
+     * Convert HSL to RGB
+     *
+     * @api
+     *
+     * @param integer $hue        H from 0 to 360
+     * @param integer $saturation S from 0 to 100
+     * @param integer $lightness  L from 0 to 100
+     *
+     * @return array
+     */
+    public function toRGB($hue, $saturation, $lightness)
+    {
+        if ($hue < 0) {
+            $hue += 360;
+        }
+
+        $h = $hue / 360;
+        $s = min(100, max(0, $saturation)) / 100;
+        $l = min(100, max(0, $lightness)) / 100;
+
+        $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s;
+        $m1 = $l * 2 - $m2;
+
+        $r = $this->hueToRGB($m1, $m2, $h + 1 / 3) * 255;
+        $g = $this->hueToRGB($m1, $m2, $h) * 255;
+        $b = $this->hueToRGB($m1, $m2, $h - 1 / 3) * 255;
+
+        $out = [Type::T_COLOR, $r, $g, $b];
+
+        return $out;
+    }
+
+    // Built in functions
+
+    protected static $libCall = ['function', 'args...'];
+    protected function libCall($args, $kwargs)
+    {
+        $functionReference = $this->reduce(array_shift($args), true);
+
+        if (in_array($functionReference[0], [Type::T_STRING, Type::T_KEYWORD])) {
+            $name = $this->compileStringContent($this->coerceString($this->reduce($functionReference, true)));
+            $warning = "DEPRECATION WARNING: Passing a string to call() is deprecated and will be illegal\n"
+                . "in Sass 4.0. Use call(function-reference($name)) instead.";
+            fwrite($this->stderr, "$warning\n\n");
+            $functionReference = $this->libGetFunction([$functionReference]);
+        }
+
+        if ($functionReference === static::$null) {
+            return static::$null;
+        }
+
+        if (! in_array($functionReference[0], [Type::T_FUNCTION_REFERENCE, Type::T_FUNCTION])) {
+            throw $this->error('Function reference expected, got ' . $functionReference[0]);
+        }
+
+        $callArgs = [];
+
+        // $kwargs['args'] is [Type::T_LIST, ',', [..]]
+        foreach ($kwargs['args'][2] as $varname => $arg) {
+            if (is_numeric($varname)) {
+                $varname = null;
+            } else {
+                $varname = [ 'var', $varname];
+            }
+
+            $callArgs[] = [$varname, $arg, false];
+        }
+
+        return $this->reduce([Type::T_FUNCTION_CALL, $functionReference, $callArgs]);
+    }
+
+
+    protected static $libGetFunction = [
+        ['name'],
+        ['name', 'css']
+    ];
+    protected function libGetFunction($args)
+    {
+        $name = $this->compileStringContent($this->coerceString($this->reduce(array_shift($args), true)));
+        $isCss = false;
+
+        if (count($args)) {
+            $isCss = $this->reduce(array_shift($args), true);
+            $isCss = (($isCss === static::$true) ? true : false);
+        }
+
+        if ($isCss) {
+            return [Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]];
+        }
+
+        return $this->getFunctionReference($name, true);
+    }
+
+    protected static $libIf = ['condition', 'if-true', 'if-false:'];
+    protected function libIf($args)
+    {
+        list($cond, $t, $f) = $args;
+
+        if (! $this->isTruthy($this->reduce($cond, true))) {
+            return $this->reduce($f, true);
+        }
+
+        return $this->reduce($t, true);
+    }
+
+    protected static $libIndex = ['list', 'value'];
+    protected function libIndex($args)
+    {
+        list($list, $value) = $args;
+
+        if (
+            $list[0] === Type::T_MAP ||
+            $list[0] === Type::T_STRING ||
+            $list[0] === Type::T_KEYWORD ||
+            $list[0] === Type::T_INTERPOLATE
+        ) {
+            $list = $this->coerceList($list, ' ');
+        }
+
+        if ($list[0] !== Type::T_LIST) {
+            return static::$null;
+        }
+
+        // Numbers are represented with value objects, for which the PHP equality operator does not
+        // match the Sass rules (and we cannot overload it). As they are the only type of values
+        // represented with a value object for now, they require a special case.
+        if ($value instanceof Number) {
+            $key = 0;
+            foreach ($list[2] as $item) {
+                $key++;
+                $itemValue = $this->normalizeValue($item);
+
+                if ($itemValue instanceof Number && $value->equals($itemValue)) {
+                    return new Number($key, '');
+                }
+            }
+            return static::$null;
+        }
+
+        $values = [];
+
+
+        foreach ($list[2] as $item) {
+            $values[] = $this->normalizeValue($item);
+        }
+
+        $key = array_search($this->normalizeValue($value), $values);
+
+        return false === $key ? static::$null : $key + 1;
+    }
+
+    protected static $libRgb = [
+        ['color'],
+        ['color', 'alpha'],
+        ['channels'],
+        ['red', 'green', 'blue'],
+        ['red', 'green', 'blue', 'alpha'] ];
+    protected function libRgb($args, $kwargs, $funcName = 'rgb')
+    {
+        switch (\count($args)) {
+            case 1:
+                if (! $color = $this->coerceColor($args[0], true)) {
+                    $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']];
+                }
+                break;
+
+            case 3:
+                $color = [Type::T_COLOR, $args[0], $args[1], $args[2]];
+
+                if (! $color = $this->coerceColor($color)) {
+                    $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']];
+                }
+
+                return $color;
+
+            case 2:
+                if ($color = $this->coerceColor($args[0], true)) {
+                    $alpha = $this->compileRGBAValue($args[1], true);
+
+                    if (is_numeric($alpha)) {
+                        $color[4] = $alpha;
+                    } else {
+                        $color = [Type::T_STRING, '',
+                            [$funcName . '(', $color[1], ', ', $color[2], ', ', $color[3], ', ', $alpha, ')']];
+                    }
+                } else {
+                    $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']];
+                }
+                break;
+
+            case 4:
+            default:
+                $color = [Type::T_COLOR, $args[0], $args[1], $args[2], $args[3]];
+
+                if (! $color = $this->coerceColor($color)) {
+                    $color = [Type::T_STRING, '',
+                        [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']];
+                }
+                break;
+        }
+
+        return $color;
+    }
+
+    protected static $libRgba = [
+        ['color'],
+        ['color', 'alpha'],
+        ['channels'],
+        ['red', 'green', 'blue'],
+        ['red', 'green', 'blue', 'alpha'] ];
+    protected function libRgba($args, $kwargs)
+    {
+        return $this->libRgb($args, $kwargs, 'rgba');
+    }
+
+    // helper function for adjust_color, change_color, and scale_color
+    protected function alterColor($args, $fn)
+    {
+        $color = $this->assertColor($args[0]);
+
+        foreach ([1 => 1, 2 => 2, 3 => 3, 7 => 4] as $iarg => $irgba) {
+            if (isset($args[$iarg])) {
+                $val = $this->assertNumber($args[$iarg])->getDimension();
+
+                if (! isset($color[$irgba])) {
+                    $color[$irgba] = (($irgba < 4) ? 0 : 1);
+                }
+
+                $color[$irgba] = \call_user_func($fn, $color[$irgba], $val, $iarg);
+            }
+        }
+
+        if (! empty($args[4]) || ! empty($args[5]) || ! empty($args[6])) {
+            $hsl = $this->toHSL($color[1], $color[2], $color[3]);
+
+            foreach ([4 => 1, 5 => 2, 6 => 3] as $iarg => $ihsl) {
+                if (! empty($args[$iarg])) {
+                    $val = $this->assertNumber($args[$iarg])->getDimension();
+                    $hsl[$ihsl] = \call_user_func($fn, $hsl[$ihsl], $val, $iarg);
+                }
+            }
+
+            $rgb = $this->toRGB($hsl[1], $hsl[2], $hsl[3]);
+
+            if (isset($color[4])) {
+                $rgb[4] = $color[4];
+            }
+
+            $color = $rgb;
+        }
+
+        return $color;
+    }
+
+    protected static $libAdjustColor = [
+        'color', 'red:null', 'green:null', 'blue:null',
+        'hue:null', 'saturation:null', 'lightness:null', 'alpha:null'
+    ];
+    protected function libAdjustColor($args)
+    {
+        return $this->alterColor($args, function ($base, $alter, $i) {
+            return $base + $alter;
+        });
+    }
+
+    protected static $libChangeColor = [
+        'color', 'red:null', 'green:null', 'blue:null',
+        'hue:null', 'saturation:null', 'lightness:null', 'alpha:null'
+    ];
+    protected function libChangeColor($args)
+    {
+        return $this->alterColor($args, function ($base, $alter, $i) {
+            return $alter;
+        });
+    }
+
+    protected static $libScaleColor = [
+        'color', 'red:null', 'green:null', 'blue:null',
+        'hue:null', 'saturation:null', 'lightness:null', 'alpha:null'
+    ];
+    protected function libScaleColor($args)
+    {
+        return $this->alterColor($args, function ($base, $scale, $i) {
+            // 1, 2, 3 - rgb
+            // 4, 5, 6 - hsl
+            // 7 - a
+            switch ($i) {
+                case 1:
+                case 2:
+                case 3:
+                    $max = 255;
+                    break;
+
+                case 4:
+                    $max = 360;
+                    break;
+
+                case 7:
+                    $max = 1;
+                    break;
+
+                default:
+                    $max = 100;
+            }
+
+            $scale = $scale / 100;
+
+            if ($scale < 0) {
+                return $base * $scale + $base;
+            }
+
+            return ($max - $base) * $scale + $base;
+        });
+    }
+
+    protected static $libIeHexStr = ['color'];
+    protected function libIeHexStr($args)
+    {
+        $color = $this->coerceColor($args[0]);
+
+        if (\is_null($color)) {
+            $this->throwError('Error: argument `$color` of `ie-hex-str($color)` must be a color');
+        }
+
+        $color[4] = isset($color[4]) ? round(255 * $color[4]) : 255;
+
+        return [Type::T_STRING, '', [sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3])]];
+    }
+
+    protected static $libRed = ['color'];
+    protected function libRed($args)
+    {
+        $color = $this->coerceColor($args[0]);
+
+        if (\is_null($color)) {
+            $this->throwError('Error: argument `$color` of `red($color)` must be a color');
+        }
+
+        return $color[1];
+    }
+
+    protected static $libGreen = ['color'];
+    protected function libGreen($args)
+    {
+        $color = $this->coerceColor($args[0]);
+
+        if (\is_null($color)) {
+            $this->throwError('Error: argument `$color` of `green($color)` must be a color');
+        }
+
+        return $color[2];
+    }
+
+    protected static $libBlue = ['color'];
+    protected function libBlue($args)
+    {
+        $color = $this->coerceColor($args[0]);
+
+        if (\is_null($color)) {
+            $this->throwError('Error: argument `$color` of `blue($color)` must be a color');
+        }
+
+        return $color[3];
+    }
+
+    protected static $libAlpha = ['color'];
+    protected function libAlpha($args)
+    {
+        if ($color = $this->coerceColor($args[0])) {
+            return isset($color[4]) ? $color[4] : 1;
+        }
+
+        // this might be the IE function, so return value unchanged
+        return null;
+    }
+
+    protected static $libOpacity = ['color'];
+    protected function libOpacity($args)
+    {
+        $value = $args[0];
+
+        if ($value instanceof Number) {
+            return null;
+        }
+
+        return $this->libAlpha($args);
+    }
+
+    // mix two colors
+    protected static $libMix = [
+        ['color1', 'color2', 'weight:0.5'],
+        ['color-1', 'color-2', 'weight:0.5']
+        ];
+    protected function libMix($args)
+    {
+        list($first, $second, $weight) = $args;
+
+        $first = $this->assertColor($first);
+        $second = $this->assertColor($second);
+
+        if (! isset($weight)) {
+            $weight = 0.5;
+        } else {
+            $weight = $this->coercePercent($weight);
+        }
+
+        $firstAlpha = isset($first[4]) ? $first[4] : 1;
+        $secondAlpha = isset($second[4]) ? $second[4] : 1;
+
+        $w = $weight * 2 - 1;
+        $a = $firstAlpha - $secondAlpha;
+
+        $w1 = (($w * $a === -1 ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2.0;
+        $w2 = 1.0 - $w1;
+
+        $new = [Type::T_COLOR,
+            $w1 * $first[1] + $w2 * $second[1],
+            $w1 * $first[2] + $w2 * $second[2],
+            $w1 * $first[3] + $w2 * $second[3],
+        ];
+
+        if ($firstAlpha != 1.0 || $secondAlpha != 1.0) {
+            $new[] = $firstAlpha * $weight + $secondAlpha * (1 - $weight);
+        }
+
+        return $this->fixColor($new);
+    }
+
+    protected static $libHsl = [
+        ['channels'],
+        ['hue', 'saturation', 'lightness'],
+        ['hue', 'saturation', 'lightness', 'alpha'] ];
+    protected function libHsl($args, $kwargs, $funcName = 'hsl')
+    {
+        $args_to_check = $args;
+
+        if (\count($args) == 1) {
+            if ($args[0][0] !== Type::T_LIST || \count($args[0][2]) < 3 || \count($args[0][2]) > 4) {
+                return [Type::T_STRING, '', [$funcName . '(', $args[0], ')']];
+            }
+
+            $args = $args[0][2];
+            $args_to_check = $kwargs['channels'][2];
+        }
+
+        foreach ($kwargs as $k => $arg) {
+            if (in_array($arg[0], [Type::T_FUNCTION_CALL]) && in_array($arg[1], ['min', 'max'])) {
+                return null;
+            }
+        }
+
+        foreach ($args_to_check as $k => $arg) {
+            if (in_array($arg[0], [Type::T_FUNCTION_CALL]) && in_array($arg[1], ['min', 'max'])) {
+                if (count($kwargs) > 1 || ($k >= 2 && count($args) === 4)) {
+                    return null;
+                }
+
+                $args[$k] = $this->stringifyFncallArgs($arg);
+            }
+
+            if (
+                $k >= 2 && count($args) === 4 &&
+                in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) &&
+                in_array($arg[1], ['calc','env'])
+            ) {
+                return null;
+            }
+        }
+
+        $hue = $this->reduce($args[0]);
+        $saturation = $this->reduce($args[1]);
+        $lightness = $this->reduce($args[2]);
+        $alpha = null;
+
+        if (\count($args) === 4) {
+            $alpha = $this->compileColorPartValue($args[3], 0, 100, false);
+
+            if (!$hue instanceof Number || !$saturation instanceof Number || ! $lightness instanceof Number || ! is_numeric($alpha)) {
+                return [Type::T_STRING, '',
+                    [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']];
+            }
+        } else {
+            if (!$hue instanceof Number || !$saturation instanceof Number || ! $lightness instanceof Number) {
+                return [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']];
+            }
+        }
+
+        $hueValue = $hue->getDimension() % 360;
+
+        while ($hueValue < 0) {
+            $hueValue += 360;
+        }
+
+        $color = $this->toRGB($hueValue, max(0, min($saturation->getDimension(), 100)), max(0, min($lightness->getDimension(), 100)));
+
+        if (! \is_null($alpha)) {
+            $color[4] = $alpha;
+        }
+
+        return $color;
+    }
+
+    protected static $libHsla = [
+            ['channels'],
+            ['hue', 'saturation', 'lightness'],
+            ['hue', 'saturation', 'lightness', 'alpha']];
+    protected function libHsla($args, $kwargs)
+    {
+        return $this->libHsl($args, $kwargs, 'hsla');
+    }
+
+    protected static $libHue = ['color'];
+    protected function libHue($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
+
+        return new Number($hsl[1], 'deg');
+    }
+
+    protected static $libSaturation = ['color'];
+    protected function libSaturation($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
+
+        return new Number($hsl[2], '%');
+    }
+
+    protected static $libLightness = ['color'];
+    protected function libLightness($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
+
+        return new Number($hsl[3], '%');
+    }
+
+    protected function adjustHsl($color, $idx, $amount)
+    {
+        $hsl = $this->toHSL($color[1], $color[2], $color[3]);
+        $hsl[$idx] += $amount;
+        $out = $this->toRGB($hsl[1], $hsl[2], $hsl[3]);
+
+        if (isset($color[4])) {
+            $out[4] = $color[4];
+        }
+
+        return $out;
+    }
+
+    protected static $libAdjustHue = ['color', 'degrees'];
+    protected function libAdjustHue($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $degrees = $this->assertNumber($args[1])->getDimension();
+
+        return $this->adjustHsl($color, 1, $degrees);
+    }
+
+    protected static $libLighten = ['color', 'amount'];
+    protected function libLighten($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%');
+
+        return $this->adjustHsl($color, 3, $amount);
+    }
+
+    protected static $libDarken = ['color', 'amount'];
+    protected function libDarken($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%');
+
+        return $this->adjustHsl($color, 3, -$amount);
+    }
+
+    protected static $libSaturate = [['color', 'amount'], ['amount']];
+    protected function libSaturate($args)
+    {
+        $value = $args[0];
+
+        if ($value instanceof Number) {
+            return null;
+        }
+
+        if (count($args) === 1) {
+            $val = $this->compileValue($value);
+            throw $this->error("\$amount: $val is not a number");
+        }
+
+        $color = $this->assertColor($value);
+        $amount = 100 * $this->coercePercent($args[1]);
+
+        return $this->adjustHsl($color, 2, $amount);
+    }
+
+    protected static $libDesaturate = ['color', 'amount'];
+    protected function libDesaturate($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $amount = 100 * $this->coercePercent($args[1]);
+
+        return $this->adjustHsl($color, 2, -$amount);
+    }
+
+    protected static $libGrayscale = ['color'];
+    protected function libGrayscale($args)
+    {
+        $value = $args[0];
+
+        if ($value instanceof Number) {
+            return null;
+        }
+
+        return $this->adjustHsl($this->assertColor($value), 2, -100);
+    }
+
+    protected static $libComplement = ['color'];
+    protected function libComplement($args)
+    {
+        return $this->adjustHsl($this->assertColor($args[0]), 1, 180);
+    }
+
+    protected static $libInvert = ['color', 'weight:1'];
+    protected function libInvert($args)
+    {
+        list($value, $weight) = $args;
+
+        if (! isset($weight)) {
+            $weight = 1;
+        } else {
+            $weight = $this->coercePercent($weight);
+        }
+
+        if ($value instanceof Number) {
+            return null;
+        }
+
+        $color = $this->assertColor($value);
+        $inverted = $color;
+        $inverted[1] = 255 - $inverted[1];
+        $inverted[2] = 255 - $inverted[2];
+        $inverted[3] = 255 - $inverted[3];
+
+        if ($weight < 1) {
+            return $this->libMix([$inverted, $color, new Number($weight, '')]);
+        }
+
+        return $inverted;
+    }
+
+    // increases opacity by amount
+    protected static $libOpacify = ['color', 'amount'];
+    protected function libOpacify($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $amount = $this->coercePercent($args[1]);
+
+        $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount;
+        $color[4] = min(1, max(0, $color[4]));
+
+        return $color;
+    }
+
+    protected static $libFadeIn = ['color', 'amount'];
+    protected function libFadeIn($args)
+    {
+        return $this->libOpacify($args);
+    }
+
+    // decreases opacity by amount
+    protected static $libTransparentize = ['color', 'amount'];
+    protected function libTransparentize($args)
+    {
+        $color = $this->assertColor($args[0]);
+        $amount = $this->coercePercent($args[1]);
+
+        $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount;
+        $color[4] = min(1, max(0, $color[4]));
+
+        return $color;
+    }
+
+    protected static $libFadeOut = ['color', 'amount'];
+    protected function libFadeOut($args)
+    {
+        return $this->libTransparentize($args);
+    }
+
+    protected static $libUnquote = ['string'];
+    protected function libUnquote($args)
+    {
+        $str = $args[0];
+
+        if ($str[0] === Type::T_STRING) {
+            $str[1] = '';
+        }
+
+        return $str;
+    }
+
+    protected static $libQuote = ['string'];
+    protected function libQuote($args)
+    {
+        $value = $args[0];
+
+        if ($value[0] === Type::T_STRING && ! empty($value[1])) {
+            $value[1] = '"';
+            return $value;
+        }
+
+        return [Type::T_STRING, '"', [$value]];
+    }
+
+    protected static $libPercentage = ['number'];
+    protected function libPercentage($args)
+    {
+        $num = $this->assertNumber($args[0], 'number');
+        $num->assertNoUnits('number');
+
+        return new Number($num->getDimension() * 100, '%');
+    }
+
+    protected static $libRound = ['number'];
+    protected function libRound($args)
+    {
+        $num = $this->assertNumber($args[0], 'number');
+
+        return new Number(round($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits());
+    }
+
+    protected static $libFloor = ['number'];
+    protected function libFloor($args)
+    {
+        $num = $this->assertNumber($args[0], 'number');
+
+        return new Number(floor($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits());
+    }
+
+    protected static $libCeil = ['number'];
+    protected function libCeil($args)
+    {
+        $num = $this->assertNumber($args[0], 'number');
+
+        return new Number(ceil($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits());
+    }
+
+    protected static $libAbs = ['number'];
+    protected function libAbs($args)
+    {
+        $num = $this->assertNumber($args[0], 'number');
+
+        return new Number(abs($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits());
+    }
+
+    protected function libMin($args)
+    {
+        /**
+         * @var Number|null
+         */
+        $min = null;
+
+        foreach ($args as $arg) {
+            $number = $this->assertNumber($arg);
+
+            if (\is_null($min) || $min->greaterThan($number)) {
+                $min = $number;
+            }
+        }
+
+        if (!\is_null($min)) {
+            return $min;
+        }
+
+        throw $this->error('At least one argument must be passed.');
+    }
+
+    protected function libMax($args)
+    {
+        /**
+         * @var Number|null
+         */
+        $max = null;
+
+        foreach ($args as $arg) {
+            $number = $this->assertNumber($arg);
+
+            if (\is_null($max) || $max->lessThan($number)) {
+                $max = $number;
+            }
+        }
+
+        if (!\is_null($max)) {
+            return $max;
+        }
+
+        throw $this->error('At least one argument must be passed.');
+    }
+
+    protected static $libLength = ['list'];
+    protected function libLength($args)
+    {
+        $list = $this->coerceList($args[0], ',', true);
+
+        return \count($list[2]);
+    }
+
+    //protected static $libListSeparator = ['list...'];
+    protected function libListSeparator($args)
+    {
+        if (\count($args) > 1) {
+            return 'comma';
+        }
+
+        if (! \in_array($args[0][0], [Type::T_LIST, Type::T_MAP])) {
+            return 'space';
+        }
+
+        $list = $this->coerceList($args[0]);
+
+        if (\count($list[2]) <= 1 && empty($list['enclosing'])) {
+            return 'space';
+        }
+
+        if ($list[1] === ',') {
+            return 'comma';
+        }
+
+        return 'space';
+    }
+
+    protected static $libNth = ['list', 'n'];
+    protected function libNth($args)
+    {
+        $list = $this->coerceList($args[0], ',', false);
+        $n = $this->assertNumber($args[1])->getDimension();
+
+        if ($n > 0) {
+            $n--;
+        } elseif ($n < 0) {
+            $n += \count($list[2]);
+        }
+
+        return isset($list[2][$n]) ? $list[2][$n] : static::$defaultValue;
+    }
+
+    protected static $libSetNth = ['list', 'n', 'value'];
+    protected function libSetNth($args)
+    {
+        $list = $this->coerceList($args[0]);
+        $n = $this->assertNumber($args[1])->getDimension();
+
+        if ($n > 0) {
+            $n--;
+        } elseif ($n < 0) {
+            $n += \count($list[2]);
+        }
+
+        if (! isset($list[2][$n])) {
+            throw $this->error('Invalid argument for "n"');
+        }
+
+        $list[2][$n] = $args[2];
+
+        return $list;
+    }
+
+    protected static $libMapGet = ['map', 'key'];
+    protected function libMapGet($args)
+    {
+        $map = $this->assertMap($args[0]);
+        $key = $args[1];
+
+        if (! \is_null($key)) {
+            $key = $this->compileStringContent($this->coerceString($key));
+
+            for ($i = \count($map[1]) - 1; $i >= 0; $i--) {
+                if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
+                    return $map[2][$i];
+                }
+            }
+        }
+
+        return static::$null;
+    }
+
+    protected static $libMapKeys = ['map'];
+    protected function libMapKeys($args)
+    {
+        $map = $this->assertMap($args[0]);
+        $keys = $map[1];
+
+        return [Type::T_LIST, ',', $keys];
+    }
+
+    protected static $libMapValues = ['map'];
+    protected function libMapValues($args)
+    {
+        $map = $this->assertMap($args[0]);
+        $values = $map[2];
+
+        return [Type::T_LIST, ',', $values];
+    }
+
+    protected static $libMapRemove = ['map', 'key...'];
+    protected function libMapRemove($args)
+    {
+        $map = $this->assertMap($args[0]);
+        $keyList = $this->assertList($args[1]);
+
+        $keys = [];
+
+        foreach ($keyList[2] as $key) {
+            $keys[] = $this->compileStringContent($this->coerceString($key));
+        }
+
+        for ($i = \count($map[1]) - 1; $i >= 0; $i--) {
+            if (in_array($this->compileStringContent($this->coerceString($map[1][$i])), $keys)) {
+                array_splice($map[1], $i, 1);
+                array_splice($map[2], $i, 1);
+            }
+        }
+
+        return $map;
+    }
+
+    protected static $libMapHasKey = ['map', 'key'];
+    protected function libMapHasKey($args)
+    {
+        $map = $this->assertMap($args[0]);
+        $key = $this->compileStringContent($this->coerceString($args[1]));
+
+        for ($i = \count($map[1]) - 1; $i >= 0; $i--) {
+            if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected static $libMapMerge = [
+        ['map1', 'map2'],
+        ['map-1', 'map-2']
+    ];
+    protected function libMapMerge($args)
+    {
+        $map1 = $this->assertMap($args[0]);
+        $map2 = $this->assertMap($args[1]);
+
+        foreach ($map2[1] as $i2 => $key2) {
+            $key = $this->compileStringContent($this->coerceString($key2));
+
+            foreach ($map1[1] as $i1 => $key1) {
+                if ($key === $this->compileStringContent($this->coerceString($key1))) {
+                    $map1[2][$i1] = $map2[2][$i2];
+                    continue 2;
+                }
+            }
+
+            $map1[1][] = $map2[1][$i2];
+            $map1[2][] = $map2[2][$i2];
+        }
+
+        return $map1;
+    }
+
+    protected static $libKeywords = ['args'];
+    protected function libKeywords($args)
+    {
+        $this->assertList($args[0]);
+
+        $keys = [];
+        $values = [];
+
+        foreach ($args[0][2] as $name => $arg) {
+            $keys[] = [Type::T_KEYWORD, $name];
+            $values[] = $arg;
+        }
+
+        return [Type::T_MAP, $keys, $values];
+    }
+
+    protected static $libIsBracketed = ['list'];
+    protected function libIsBracketed($args)
+    {
+        $list = $args[0];
+        $this->coerceList($list, ' ');
+
+        if (! empty($list['enclosing']) && $list['enclosing'] === 'bracket') {
+            return true;
+        }
+
+        return false;
+    }
+
+    protected function listSeparatorForJoin($list1, $sep)
+    {
+        if (! isset($sep)) {
+            return $list1[1];
+        }
+
+        switch ($this->compileValue($sep)) {
+            case 'comma':
+                return ',';
+
+            case 'space':
+                return ' ';
+
+            default:
+                return $list1[1];
+        }
+    }
+
+    protected static $libJoin = ['list1', 'list2', 'separator:null', 'bracketed:auto'];
+    protected function libJoin($args)
+    {
+        list($list1, $list2, $sep, $bracketed) = $args;
+
+        $list1 = $this->coerceList($list1, ' ', true);
+        $list2 = $this->coerceList($list2, ' ', true);
+        $sep   = $this->listSeparatorForJoin($list1, $sep);
+
+        if ($bracketed === static::$true) {
+            $bracketed = true;
+        } elseif ($bracketed === static::$false) {
+            $bracketed = false;
+        } elseif ($bracketed === [Type::T_KEYWORD, 'auto']) {
+            $bracketed = 'auto';
+        } elseif ($bracketed === static::$null) {
+            $bracketed = false;
+        } else {
+            $bracketed = $this->compileValue($bracketed);
+            $bracketed = ! ! $bracketed;
+
+            if ($bracketed === true) {
+                $bracketed = true;
+            }
+        }
+
+        if ($bracketed === 'auto') {
+            $bracketed = false;
+
+            if (! empty($list1['enclosing']) && $list1['enclosing'] === 'bracket') {
+                $bracketed = true;
+            }
+        }
+
+        $res = [Type::T_LIST, $sep, array_merge($list1[2], $list2[2])];
+
+        if (isset($list1['enclosing'])) {
+            $res['enlcosing'] = $list1['enclosing'];
+        }
+
+        if ($bracketed) {
+            $res['enclosing'] = 'bracket';
+        }
+
+        return $res;
+    }
+
+    protected static $libAppend = ['list', 'val', 'separator:null'];
+    protected function libAppend($args)
+    {
+        list($list1, $value, $sep) = $args;
+
+        $list1 = $this->coerceList($list1, ' ', true);
+        $sep   = $this->listSeparatorForJoin($list1, $sep);
+        $res   = [Type::T_LIST, $sep, array_merge($list1[2], [$value])];
+
+        if (isset($list1['enclosing'])) {
+            $res['enclosing'] = $list1['enclosing'];
+        }
+
+        return $res;
+    }
+
+    protected function libZip($args)
+    {
+        foreach ($args as $key => $arg) {
+            $args[$key] = $this->coerceList($arg);
+        }
+
+        $lists = [];
+        $firstList = array_shift($args);
+
+        $result = [Type::T_LIST, ',', $lists];
+        if (! \is_null($firstList)) {
+            foreach ($firstList[2] as $key => $item) {
+                $list = [Type::T_LIST, '', [$item]];
+
+                foreach ($args as $arg) {
+                    if (isset($arg[2][$key])) {
+                        $list[2][] = $arg[2][$key];
+                    } else {
+                        break 2;
+                    }
+                }
+
+                $lists[] = $list;
+            }
+
+            $result[2] = $lists;
+        } else {
+            $result['enclosing'] = 'parent';
+        }
+
+        return $result;
+    }
+
+    protected static $libTypeOf = ['value'];
+    protected function libTypeOf($args)
+    {
+        $value = $args[0];
+
+        switch ($value[0]) {
+            case Type::T_KEYWORD:
+                if ($value === static::$true || $value === static::$false) {
+                    return 'bool';
+                }
+
+                if ($this->coerceColor($value)) {
+                    return 'color';
+                }
+
+                // fall-thru
+            case Type::T_FUNCTION:
+                return 'string';
+
+            case Type::T_FUNCTION_REFERENCE:
+                return 'function';
+
+            case Type::T_LIST:
+                if (isset($value[3]) && $value[3]) {
+                    return 'arglist';
+                }
+
+                // fall-thru
+            default:
+                return $value[0];
+        }
+    }
+
+    protected static $libUnit = ['number'];
+    protected function libUnit($args)
+    {
+        $num = $args[0];
+
+        if ($num instanceof Number) {
+            return [Type::T_STRING, '"', [$num->unitStr()]];
+        }
+
+        return '';
+    }
+
+    protected static $libUnitless = ['number'];
+    protected function libUnitless($args)
+    {
+        $value = $args[0];
+
+        return $value instanceof Number && $value->unitless();
+    }
+
+    protected static $libComparable = [
+        ['number1', 'number2'],
+        ['number-1', 'number-2']
+    ];
+    protected function libComparable($args)
+    {
+        list($number1, $number2) = $args;
+
+        if (
+            ! $number1 instanceof Number ||
+            ! $number2 instanceof Number
+        ) {
+            throw $this->error('Invalid argument(s) for "comparable"');
+        }
+
+        return $number1->isComparableTo($number2);
+    }
+
+    protected static $libStrIndex = ['string', 'substring'];
+    protected function libStrIndex($args)
+    {
+        $string = $this->assertString($args[0], 'string');
+        $stringContent = $this->compileStringContent($string);
+
+        $substring = $this->assertString($args[1], 'substring');
+        $substringContent = $this->compileStringContent($substring);
+
+        if (! \strlen($substringContent)) {
+            $result = 0;
+        } else {
+            $result = strpos($stringContent, $substringContent);
+        }
+
+        return $result === false ? static::$null : new Number($result + 1, '');
+    }
+
+    protected static $libStrInsert = ['string', 'insert', 'index'];
+    protected function libStrInsert($args)
+    {
+        $string = $this->assertString($args[0], 'string');
+        $stringContent = $this->compileStringContent($string);
+
+        $insert = $this->assertString($args[1], 'insert');
+        $insertContent = $this->compileStringContent($insert);
+
+        $index = $this->assertInteger($args[2], 'index');
+        if ($index > 0) {
+            $index = $index - 1;
+        }
+        if ($index < 0) {
+            $index = Util::mbStrlen($stringContent) + 1 + $index;
+        }
+
+        $string[2] = [
+            Util::mbSubstr($stringContent, 0, $index),
+            $insertContent,
+            Util::mbSubstr($stringContent, $index)
+        ];
+
+        return $string;
+    }
+
+    protected static $libStrLength = ['string'];
+    protected function libStrLength($args)
+    {
+        $string = $this->assertString($args[0], 'string');
+        $stringContent = $this->compileStringContent($string);
+
+        return new Number(Util::mbStrlen($stringContent), '');
+    }
+
+    protected static $libStrSlice = ['string', 'start-at', 'end-at:-1'];
+    protected function libStrSlice($args)
+    {
+        if (isset($args[2]) && ! $args[2][1]) {
+            return static::$nullString;
+        }
+
+        $string = $this->coerceString($args[0]);
+        $stringContent = $this->compileStringContent($string);
+
+        $start = (int) $args[1][1];
+
+        if ($start > 0) {
+            $start--;
+        }
+
+        $end    = isset($args[2]) ? (int) $args[2][1] : -1;
+        $length = $end < 0 ? $end + 1 : ($end > 0 ? $end - $start : $end);
+
+        $string[2] = $length
+            ? [substr($stringContent, $start, $length)]
+            : [substr($stringContent, $start)];
+
+        return $string;
+    }
+
+    protected static $libToLowerCase = ['string'];
+    protected function libToLowerCase($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $stringContent = $this->compileStringContent($string);
+
+        $string[2] = [\function_exists('mb_strtolower') ? mb_strtolower($stringContent) : strtolower($stringContent)];
+
+        return $string;
+    }
+
+    protected static $libToUpperCase = ['string'];
+    protected function libToUpperCase($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $stringContent = $this->compileStringContent($string);
+
+        $string[2] = [\function_exists('mb_strtoupper') ? mb_strtoupper($stringContent) : strtoupper($stringContent)];
+
+        return $string;
+    }
+
+    protected static $libFeatureExists = ['feature'];
+    protected function libFeatureExists($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $name = $this->compileStringContent($string);
+
+        return $this->toBool(
+            \array_key_exists($name, $this->registeredFeatures) ? $this->registeredFeatures[$name] : false
+        );
+    }
+
+    protected static $libFunctionExists = ['name'];
+    protected function libFunctionExists($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $name = $this->compileStringContent($string);
+
+        // user defined functions
+        if ($this->has(static::$namespaces['function'] . $name)) {
+            return true;
+        }
+
+        $name = $this->normalizeName($name);
+
+        if (isset($this->userFunctions[$name])) {
+            return true;
+        }
+
+        // built-in functions
+        $f = $this->getBuiltinFunction($name);
+
+        return $this->toBool(\is_callable($f));
+    }
+
+    protected static $libGlobalVariableExists = ['name'];
+    protected function libGlobalVariableExists($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $name = $this->compileStringContent($string);
+
+        return $this->has($name, $this->rootEnv);
+    }
+
+    protected static $libMixinExists = ['name'];
+    protected function libMixinExists($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $name = $this->compileStringContent($string);
+
+        return $this->has(static::$namespaces['mixin'] . $name);
+    }
+
+    protected static $libVariableExists = ['name'];
+    protected function libVariableExists($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $name = $this->compileStringContent($string);
+
+        return $this->has($name);
+    }
+
+    /**
+     * Workaround IE7's content counter bug.
+     *
+     * @param array $args
+     *
+     * @return array
+     */
+    protected function libCounter($args)
+    {
+        $list = array_map([$this, 'compileValue'], $args);
+
+        return [Type::T_STRING, '', ['counter(' . implode(',', $list) . ')']];
+    }
+
+    protected static $libRandom = ['limit:null'];
+    protected function libRandom($args)
+    {
+        if (isset($args[0]) & $args[0] !== static::$null) {
+            $n = $this->assertNumber($args[0])->getDimension();
+
+            if ($n < 1) {
+                throw $this->error("\$limit must be greater than or equal to 1");
+            }
+
+            if (round($n - \intval($n), Number::PRECISION) > 0) {
+                throw $this->error("Expected \$limit to be an integer but got $n for `random`");
+            }
+
+            return new Number(mt_rand(1, \intval($n)), '');
+        }
+
+        $max = mt_getrandmax();
+        return new Number(mt_rand(0, $max - 1) / $max, '');
+    }
+
+    protected function libUniqueId()
+    {
+        static $id;
+
+        if (! isset($id)) {
+            $id = PHP_INT_SIZE === 4
+                ? mt_rand(0, pow(36, 5)) . str_pad(mt_rand(0, pow(36, 5)) % 10000000, 7, '0', STR_PAD_LEFT)
+                : mt_rand(0, pow(36, 8));
+        }
+
+        $id += mt_rand(0, 10) + 1;
+
+        return [Type::T_STRING, '', ['u' . str_pad(base_convert($id, 10, 36), 8, '0', STR_PAD_LEFT)]];
+    }
+
+    protected function inspectFormatValue($value, $force_enclosing_display = false)
+    {
+        if ($value === static::$null) {
+            $value = [Type::T_KEYWORD, 'null'];
+        }
+
+        $stringValue = [$value];
+
+        if ($value[0] === Type::T_LIST) {
+            if (end($value[2]) === static::$null) {
+                array_pop($value[2]);
+                $value[2][] = [Type::T_STRING, '', ['']];
+                $force_enclosing_display = true;
+            }
+
+            if (
+                ! empty($value['enclosing']) &&
+                ($force_enclosing_display ||
+                    ($value['enclosing'] === 'bracket') ||
+                    ! \count($value[2]))
+            ) {
+                $value['enclosing'] = 'forced_' . $value['enclosing'];
+                $force_enclosing_display = true;
+            }
+
+            foreach ($value[2] as $k => $listelement) {
+                $value[2][$k] = $this->inspectFormatValue($listelement, $force_enclosing_display);
+            }
+
+            $stringValue = [$value];
+        }
+
+        return [Type::T_STRING, '', $stringValue];
+    }
+
+    protected static $libInspect = ['value'];
+    protected function libInspect($args)
+    {
+        $value = $args[0];
+
+        return $this->inspectFormatValue($value);
+    }
+
+    /**
+     * Preprocess selector args
+     *
+     * @param array $arg
+     *
+     * @return array|boolean
+     */
+    protected function getSelectorArg($arg, $varname = null, $allowParent = false)
+    {
+        static $parser = null;
+
+        if (\is_null($parser)) {
+            $parser = $this->parserFactory(__METHOD__);
+        }
+
+        if (! $this->checkSelectorArgType($arg)) {
+            $var_display = ($varname ? ' $' . $varname . ':' : '');
+            $var_value = $this->compileValue($arg);
+            throw $this->error("Error:{$var_display} $var_value is not a valid selector: it must be a string,"
+                . " a list of strings, or a list of lists of strings");
+        }
+
+        $arg = $this->libUnquote([$arg]);
+        $arg = $this->compileValue($arg);
+
+        $parsedSelector = [];
+
+        if ($parser->parseSelector($arg, $parsedSelector, true)) {
+            $selector = $this->evalSelectors($parsedSelector);
+            $gluedSelector = $this->glueFunctionSelectors($selector);
+
+            if (! $allowParent) {
+                foreach ($gluedSelector as $selector) {
+                    foreach ($selector as $s) {
+                        if (in_array(static::$selfSelector, $s)) {
+                            $var_display = ($varname ? ' $' . $varname . ':' : '');
+                            throw $this->error("Error:{$var_display} Parent selectors aren't allowed here.");
+                        }
+                    }
+                }
+            }
+
+            return $gluedSelector;
+        }
+
+        $var_display = ($varname ? ' $' . $varname . ':' : '');
+        throw $this->error("Error:{$var_display} expected more input, invalid selector.");
+    }
+
+    /**
+     * Check variable type for getSelectorArg() function
+     * @param array $arg
+     * @param int $maxDepth
+     * @return bool
+     */
+    protected function checkSelectorArgType($arg, $maxDepth = 2)
+    {
+        if ($arg[0] === Type::T_LIST && $maxDepth > 0) {
+            foreach ($arg[2] as $elt) {
+                if (! $this->checkSelectorArgType($elt, $maxDepth - 1)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        if (!in_array($arg[0], [Type::T_STRING, Type::T_KEYWORD])) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Postprocess selector to output in right format
+     *
+     * @param array $selectors
+     *
+     * @return string
+     */
+    protected function formatOutputSelector($selectors)
+    {
+        $selectors = $this->collapseSelectors($selectors, true);
+
+        return $selectors;
+    }
+
+    protected static $libIsSuperselector = ['super', 'sub'];
+    protected function libIsSuperselector($args)
+    {
+        list($super, $sub) = $args;
+
+        $super = $this->getSelectorArg($super, 'super');
+        $sub = $this->getSelectorArg($sub, 'sub');
+
+        return $this->isSuperSelector($super, $sub);
+    }
+
+    /**
+     * Test a $super selector again $sub
+     *
+     * @param array $super
+     * @param array $sub
+     *
+     * @return boolean
+     */
+    protected function isSuperSelector($super, $sub)
+    {
+        // one and only one selector for each arg
+        if (! $super) {
+            throw $this->error('Invalid super selector for isSuperSelector()');
+        }
+
+        if (! $sub) {
+            throw $this->error('Invalid sub selector for isSuperSelector()');
+        }
+
+        if (count($sub) > 1) {
+            foreach ($sub as $s) {
+                if (! $this->isSuperSelector($super, [$s])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        if (count($super) > 1) {
+            foreach ($super as $s) {
+                if ($this->isSuperSelector([$s], $sub)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        $super = reset($super);
+        $sub = reset($sub);
+
+        $i = 0;
+        $nextMustMatch = false;
+
+        foreach ($super as $node) {
+            $compound = '';
+
+            array_walk_recursive(
+                $node,
+                function ($value, $key) use (&$compound) {
+                    $compound .= $value;
+                }
+            );
+
+            if ($this->isImmediateRelationshipCombinator($compound)) {
+                if ($node !== $sub[$i]) {
+                    return false;
+                }
+
+                $nextMustMatch = true;
+                $i++;
+            } else {
+                while ($i < \count($sub) && ! $this->isSuperPart($node, $sub[$i])) {
+                    if ($nextMustMatch) {
+                        return false;
+                    }
+
+                    $i++;
+                }
+
+                if ($i >= \count($sub)) {
+                    return false;
+                }
+
+                $nextMustMatch = false;
+                $i++;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Test a part of super selector again a part of sub selector
+     *
+     * @param array $superParts
+     * @param array $subParts
+     *
+     * @return boolean
+     */
+    protected function isSuperPart($superParts, $subParts)
+    {
+        $i = 0;
+
+        foreach ($superParts as $superPart) {
+            while ($i < \count($subParts) && $subParts[$i] !== $superPart) {
+                $i++;
+            }
+
+            if ($i >= \count($subParts)) {
+                return false;
+            }
+
+            $i++;
+        }
+
+        return true;
+    }
+
+    protected static $libSelectorAppend = ['selector...'];
+    protected function libSelectorAppend($args)
+    {
+        // get the selector... list
+        $args = reset($args);
+        $args = $args[2];
+
+        if (\count($args) < 1) {
+            throw $this->error('selector-append() needs at least 1 argument');
+        }
+
+        $selectors = [];
+        foreach ($args as $arg) {
+            $selectors[] = $this->getSelectorArg($arg, 'selector');
+        }
+
+        return $this->formatOutputSelector($this->selectorAppend($selectors));
+    }
+
+    /**
+     * Append parts of the last selector in the list to the previous, recursively
+     *
+     * @param array $selectors
+     *
+     * @return array
+     *
+     * @throws \ScssPhp\ScssPhp\Exception\CompilerException
+     */
+    protected function selectorAppend($selectors)
+    {
+        $lastSelectors = array_pop($selectors);
+
+        if (! $lastSelectors) {
+            throw $this->error('Invalid selector list in selector-append()');
+        }
+
+        while (\count($selectors)) {
+            $previousSelectors = array_pop($selectors);
+
+            if (! $previousSelectors) {
+                throw $this->error('Invalid selector list in selector-append()');
+            }
+
+            // do the trick, happening $lastSelector to $previousSelector
+            $appended = [];
+
+            foreach ($lastSelectors as $lastSelector) {
+                $previous = $previousSelectors;
+
+                foreach ($lastSelector as $lastSelectorParts) {
+                    foreach ($lastSelectorParts as $lastSelectorPart) {
+                        foreach ($previous as $i => $previousSelector) {
+                            foreach ($previousSelector as $j => $previousSelectorParts) {
+                                $previous[$i][$j][] = $lastSelectorPart;
+                            }
+                        }
+                    }
+                }
+
+                foreach ($previous as $ps) {
+                    $appended[] = $ps;
+                }
+            }
+
+            $lastSelectors = $appended;
+        }
+
+        return $lastSelectors;
+    }
+
+    protected static $libSelectorExtend = [
+        ['selector', 'extendee', 'extender'],
+        ['selectors', 'extendee', 'extender']
+    ];
+    protected function libSelectorExtend($args)
+    {
+        list($selectors, $extendee, $extender) = $args;
+
+        $selectors = $this->getSelectorArg($selectors, 'selector');
+        $extendee  = $this->getSelectorArg($extendee, 'extendee');
+        $extender  = $this->getSelectorArg($extender, 'extender');
+
+        if (! $selectors || ! $extendee || ! $extender) {
+            throw $this->error('selector-extend() invalid arguments');
+        }
+
+        $extended = $this->extendOrReplaceSelectors($selectors, $extendee, $extender);
+
+        return $this->formatOutputSelector($extended);
+    }
+
+    protected static $libSelectorReplace = [
+        ['selector', 'original', 'replacement'],
+        ['selectors', 'original', 'replacement']
+    ];
+    protected function libSelectorReplace($args)
+    {
+        list($selectors, $original, $replacement) = $args;
+
+        $selectors   = $this->getSelectorArg($selectors, 'selector');
+        $original    = $this->getSelectorArg($original, 'original');
+        $replacement = $this->getSelectorArg($replacement, 'replacement');
+
+        if (! $selectors || ! $original || ! $replacement) {
+            throw $this->error('selector-replace() invalid arguments');
+        }
+
+        $replaced = $this->extendOrReplaceSelectors($selectors, $original, $replacement, true);
+
+        return $this->formatOutputSelector($replaced);
+    }
+
+    /**
+     * Extend/replace in selectors
+     * used by selector-extend and selector-replace that use the same logic
+     *
+     * @param array   $selectors
+     * @param array   $extendee
+     * @param array   $extender
+     * @param boolean $replace
+     *
+     * @return array
+     */
+    protected function extendOrReplaceSelectors($selectors, $extendee, $extender, $replace = false)
+    {
+        $saveExtends = $this->extends;
+        $saveExtendsMap = $this->extendsMap;
+
+        $this->extends = [];
+        $this->extendsMap = [];
+
+        foreach ($extendee as $es) {
+            // only use the first one
+            $this->pushExtends(reset($es), $extender, null);
+        }
+
+        $extended = [];
+
+        foreach ($selectors as $selector) {
+            if (! $replace) {
+                $extended[] = $selector;
+            }
+
+            $n = \count($extended);
+
+            $this->matchExtends($selector, $extended);
+
+            // if didnt match, keep the original selector if we are in a replace operation
+            if ($replace && \count($extended) === $n) {
+                $extended[] = $selector;
+            }
+        }
+
+        $this->extends = $saveExtends;
+        $this->extendsMap = $saveExtendsMap;
+
+        return $extended;
+    }
+
+    protected static $libSelectorNest = ['selector...'];
+    protected function libSelectorNest($args)
+    {
+        // get the selector... list
+        $args = reset($args);
+        $args = $args[2];
+
+        if (\count($args) < 1) {
+            throw $this->error('selector-nest() needs at least 1 argument');
+        }
+
+        $selectorsMap = [];
+        foreach ($args as $arg) {
+            $selectorsMap[] = $this->getSelectorArg($arg, 'selector', true);
+        }
+
+        $envs = [];
+
+        foreach ($selectorsMap as $selectors) {
+            $env = new Environment();
+            $env->selectors = $selectors;
+
+            $envs[] = $env;
+        }
+
+        $envs            = array_reverse($envs);
+        $env             = $this->extractEnv($envs);
+        $outputSelectors = $this->multiplySelectors($env);
+
+        return $this->formatOutputSelector($outputSelectors);
+    }
+
+    protected static $libSelectorParse = [
+        ['selector'],
+        ['selectors']
+    ];
+    protected function libSelectorParse($args)
+    {
+        $selectors = reset($args);
+        $selectors = $this->getSelectorArg($selectors, 'selector');
+
+        return $this->formatOutputSelector($selectors);
+    }
+
+    protected static $libSelectorUnify = ['selectors1', 'selectors2'];
+    protected function libSelectorUnify($args)
+    {
+        list($selectors1, $selectors2) = $args;
+
+        $selectors1 = $this->getSelectorArg($selectors1, 'selectors1');
+        $selectors2 = $this->getSelectorArg($selectors2, 'selectors2');
+
+        if (! $selectors1 || ! $selectors2) {
+            throw $this->error('selector-unify() invalid arguments');
+        }
+
+        // only consider the first compound of each
+        $compound1 = reset($selectors1);
+        $compound2 = reset($selectors2);
+
+        // unify them and that's it
+        $unified = $this->unifyCompoundSelectors($compound1, $compound2);
+
+        return $this->formatOutputSelector($unified);
+    }
+
+    /**
+     * The selector-unify magic as its best
+     * (at least works as expected on test cases)
+     *
+     * @param array $compound1
+     * @param array $compound2
+     *
+     * @return array|mixed
+     */
+    protected function unifyCompoundSelectors($compound1, $compound2)
+    {
+        if (! \count($compound1)) {
+            return $compound2;
+        }
+
+        if (! \count($compound2)) {
+            return $compound1;
+        }
+
+        // check that last part are compatible
+        $lastPart1 = array_pop($compound1);
+        $lastPart2 = array_pop($compound2);
+        $last      = $this->mergeParts($lastPart1, $lastPart2);
+
+        if (! $last) {
+            return [[]];
+        }
+
+        $unifiedCompound = [$last];
+        $unifiedSelectors = [$unifiedCompound];
+
+        // do the rest
+        while (\count($compound1) || \count($compound2)) {
+            $part1 = end($compound1);
+            $part2 = end($compound2);
+
+            if ($part1 && ($match2 = $this->matchPartInCompound($part1, $compound2))) {
+                list($compound2, $part2, $after2) = $match2;
+
+                if ($after2) {
+                    $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after2);
+                }
+
+                $c = $this->mergeParts($part1, $part2);
+                $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]);
+
+                $part1 = $part2 = null;
+
+                array_pop($compound1);
+            }
+
+            if ($part2 && ($match1 = $this->matchPartInCompound($part2, $compound1))) {
+                list($compound1, $part1, $after1) = $match1;
+
+                if ($after1) {
+                    $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after1);
+                }
+
+                $c = $this->mergeParts($part2, $part1);
+                $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]);
+
+                $part1 = $part2 = null;
+
+                array_pop($compound2);
+            }
+
+            $new = [];
+
+            if ($part1 && $part2) {
+                array_pop($compound1);
+                array_pop($compound2);
+
+                $s   = $this->prependSelectors($unifiedSelectors, [$part2]);
+                $new = array_merge($new, $this->prependSelectors($s, [$part1]));
+                $s   = $this->prependSelectors($unifiedSelectors, [$part1]);
+                $new = array_merge($new, $this->prependSelectors($s, [$part2]));
+            } elseif ($part1) {
+                array_pop($compound1);
+
+                $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part1]));
+            } elseif ($part2) {
+                array_pop($compound2);
+
+                $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part2]));
+            }
+
+            if ($new) {
+                $unifiedSelectors = $new;
+            }
+        }
+
+        return $unifiedSelectors;
+    }
+
+    /**
+     * Prepend each selector from $selectors with $parts
+     *
+     * @param array $selectors
+     * @param array $parts
+     *
+     * @return array
+     */
+    protected function prependSelectors($selectors, $parts)
+    {
+        $new = [];
+
+        foreach ($selectors as $compoundSelector) {
+            array_unshift($compoundSelector, $parts);
+
+            $new[] = $compoundSelector;
+        }
+
+        return $new;
+    }
+
+    /**
+     * Try to find a matching part in a compound:
+     * - with same html tag name
+     * - with some class or id or something in common
+     *
+     * @param array $part
+     * @param array $compound
+     *
+     * @return array|boolean
+     */
+    protected function matchPartInCompound($part, $compound)
+    {
+        $partTag = $this->findTagName($part);
+        $before  = $compound;
+        $after   = [];
+
+        // try to find a match by tag name first
+        while (\count($before)) {
+            $p = array_pop($before);
+
+            if ($partTag && $partTag !== '*' && $partTag == $this->findTagName($p)) {
+                return [$before, $p, $after];
+            }
+
+            $after[] = $p;
+        }
+
+        // try again matching a non empty intersection and a compatible tagname
+        $before = $compound;
+        $after = [];
+
+        while (\count($before)) {
+            $p = array_pop($before);
+
+            if ($this->checkCompatibleTags($partTag, $this->findTagName($p))) {
+                if (\count(array_intersect($part, $p))) {
+                    return [$before, $p, $after];
+                }
+            }
+
+            $after[] = $p;
+        }
+
+        return false;
+    }
+
+    /**
+     * Merge two part list taking care that
+     * - the html tag is coming first - if any
+     * - the :something are coming last
+     *
+     * @param array $parts1
+     * @param array $parts2
+     *
+     * @return array
+     */
+    protected function mergeParts($parts1, $parts2)
+    {
+        $tag1 = $this->findTagName($parts1);
+        $tag2 = $this->findTagName($parts2);
+        $tag  = $this->checkCompatibleTags($tag1, $tag2);
+
+        // not compatible tags
+        if ($tag === false) {
+            return [];
+        }
+
+        if ($tag) {
+            if ($tag1) {
+                $parts1 = array_diff($parts1, [$tag1]);
+            }
+
+            if ($tag2) {
+                $parts2 = array_diff($parts2, [$tag2]);
+            }
+        }
+
+        $mergedParts = array_merge($parts1, $parts2);
+        $mergedOrderedParts = [];
+
+        foreach ($mergedParts as $part) {
+            if (strpos($part, ':') === 0) {
+                $mergedOrderedParts[] = $part;
+            }
+        }
+
+        $mergedParts = array_diff($mergedParts, $mergedOrderedParts);
+        $mergedParts = array_merge($mergedParts, $mergedOrderedParts);
+
+        if ($tag) {
+            array_unshift($mergedParts, $tag);
+        }
+
+        return $mergedParts;
+    }
+
+    /**
+     * Check the compatibility between two tag names:
+     * if both are defined they should be identical or one has to be '*'
+     *
+     * @param string $tag1
+     * @param string $tag2
+     *
+     * @return array|boolean
+     */
+    protected function checkCompatibleTags($tag1, $tag2)
+    {
+        $tags = [$tag1, $tag2];
+        $tags = array_unique($tags);
+        $tags = array_filter($tags);
+
+        if (\count($tags) > 1) {
+            $tags = array_diff($tags, ['*']);
+        }
+
+        // not compatible nodes
+        if (\count($tags) > 1) {
+            return false;
+        }
+
+        return $tags;
+    }
+
+    /**
+     * Find the html tag name in a selector parts list
+     *
+     * @param array $parts
+     *
+     * @return mixed|string
+     */
+    protected function findTagName($parts)
+    {
+        foreach ($parts as $part) {
+            if (! preg_match('/^[\[.:#%_-]/', $part)) {
+                return $part;
+            }
+        }
+
+        return '';
+    }
+
+    protected static $libSimpleSelectors = ['selector'];
+    protected function libSimpleSelectors($args)
+    {
+        $selector = reset($args);
+        $selector = $this->getSelectorArg($selector, 'selector');
+
+        // remove selectors list layer, keeping the first one
+        $selector = reset($selector);
+
+        // remove parts list layer, keeping the first part
+        $part = reset($selector);
+
+        $listParts = [];
+
+        foreach ($part as $p) {
+            $listParts[] = [Type::T_STRING, '', [$p]];
+        }
+
+        return [Type::T_LIST, ',', $listParts];
+    }
+
+    protected static $libScssphpGlob = ['pattern'];
+    protected function libScssphpGlob($args)
+    {
+        $string = $this->coerceString($args[0]);
+        $pattern = $this->compileStringContent($string);
+        $matches = glob($pattern);
+        $listParts = [];
+
+        foreach ($matches as $match) {
+            if (! is_file($match)) {
+                continue;
+            }
+
+            $listParts[] = [Type::T_STRING, '"', [$match]];
+        }
+
+        return [Type::T_LIST, ',', $listParts];
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler/Environment.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Compiler/Environment.php
new file mode 100644 (file)
index 0000000..dc2f86c
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Compiler;
+
+/**
+ * Compiler environment
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Environment
+{
+    /**
+     * @var \ScssPhp\ScssPhp\Block
+     */
+    public $block;
+
+    /**
+     * @var \ScssPhp\ScssPhp\Compiler\Environment
+     */
+    public $parent;
+
+    /**
+     * @var array
+     */
+    public $store;
+
+    /**
+     * @var array
+     */
+    public $storeUnreduced;
+
+    /**
+     * @var integer
+     */
+    public $depth;
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/CompilerException.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/CompilerException.php
new file mode 100644 (file)
index 0000000..343da4c
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Exception;
+
+/**
+ * Compiler exception
+ *
+ * @author Oleksandr Savchenko <traveltino@gmail.com>
+ */
+class CompilerException extends \Exception implements SassException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/ParserException.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/ParserException.php
new file mode 100644 (file)
index 0000000..5237f30
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Exception;
+
+/**
+ * Parser Exception
+ *
+ * @author Oleksandr Savchenko <traveltino@gmail.com>
+ */
+class ParserException extends \Exception implements SassException
+{
+    /**
+     * @var array
+     */
+    private $sourcePosition;
+
+    /**
+     * Get source position
+     *
+     * @api
+     */
+    public function getSourcePosition()
+    {
+        return $this->sourcePosition;
+    }
+
+    /**
+     * Set source position
+     *
+     * @api
+     *
+     * @param array $sourcePosition
+     */
+    public function setSourcePosition($sourcePosition)
+    {
+        $this->sourcePosition = $sourcePosition;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/RangeException.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/RangeException.php
new file mode 100644 (file)
index 0000000..b18c32d
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Exception;
+
+/**
+ * Range exception
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class RangeException extends \Exception implements SassException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/SassException.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/SassException.php
new file mode 100644 (file)
index 0000000..9f62b3c
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+namespace ScssPhp\ScssPhp\Exception;
+
+interface SassException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/SassScriptException.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/SassScriptException.php
new file mode 100644 (file)
index 0000000..7812379
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+
+namespace ScssPhp\ScssPhp\Exception;
+
+/**
+ * Internal exception thrown in places not having access to reporting the location.
+ *
+ * This class does not implement SassException on purpose, as it should never be returned to the outside code.
+ *
+ * @internal
+ */
+class SassScriptException extends \Exception
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/ServerException.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Exception/ServerException.php
new file mode 100644 (file)
index 0000000..ad5b379
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Exception;
+
+/**
+ * Server Exception
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class ServerException extends \Exception implements SassException
+{
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter.php
new file mode 100644 (file)
index 0000000..290f5f3
--- /dev/null
@@ -0,0 +1,333 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\SourceMap\SourceMapGenerator;
+
+/**
+ * Base formatter
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+abstract class Formatter
+{
+    /**
+     * @var integer
+     */
+    public $indentLevel;
+
+    /**
+     * @var string
+     */
+    public $indentChar;
+
+    /**
+     * @var string
+     */
+    public $break;
+
+    /**
+     * @var string
+     */
+    public $open;
+
+    /**
+     * @var string
+     */
+    public $close;
+
+    /**
+     * @var string
+     */
+    public $tagSeparator;
+
+    /**
+     * @var string
+     */
+    public $assignSeparator;
+
+    /**
+     * @var boolean
+     */
+    public $keepSemicolons;
+
+    /**
+     * @var \ScssPhp\ScssPhp\Formatter\OutputBlock
+     */
+    protected $currentBlock;
+
+    /**
+     * @var integer
+     */
+    protected $currentLine;
+
+    /**
+     * @var integer
+     */
+    protected $currentColumn;
+
+    /**
+     * @var \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator
+     */
+    protected $sourceMapGenerator;
+
+    /**
+     * @var string
+     */
+    protected $strippedSemicolon;
+
+    /**
+     * Initialize formatter
+     *
+     * @api
+     */
+    abstract public function __construct();
+
+    /**
+     * Return indentation (whitespace)
+     *
+     * @return string
+     */
+    protected function indentStr()
+    {
+        return '';
+    }
+
+    /**
+     * Return property assignment
+     *
+     * @api
+     *
+     * @param string $name
+     * @param mixed  $value
+     *
+     * @return string
+     */
+    public function property($name, $value)
+    {
+        return rtrim($name) . $this->assignSeparator . $value . ';';
+    }
+
+    /**
+     * Return custom property assignment
+     * differs in that you have to keep spaces in the value as is
+     *
+     * @api
+     *
+     * @param string $name
+     * @param mixed  $value
+     *
+     * @return string
+     */
+    public function customProperty($name, $value)
+    {
+        return rtrim($name) . trim($this->assignSeparator) . $value . ';';
+    }
+
+    /**
+     * Output lines inside a block
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     */
+    protected function blockLines(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+        $glue  = $this->break . $inner;
+
+        $this->write($inner . implode($glue, $block->lines));
+
+        if (! empty($block->children)) {
+            $this->write($this->break);
+        }
+    }
+
+    /**
+     * Output block selectors
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     */
+    protected function blockSelectors(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+
+        $this->write($inner
+            . implode($this->tagSeparator, $block->selectors)
+            . $this->open . $this->break);
+    }
+
+    /**
+     * Output block children
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     */
+    protected function blockChildren(OutputBlock $block)
+    {
+        foreach ($block->children as $child) {
+            $this->block($child);
+        }
+    }
+
+    /**
+     * Output non-empty block
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     */
+    protected function block(OutputBlock $block)
+    {
+        if (empty($block->lines) && empty($block->children)) {
+            return;
+        }
+
+        $this->currentBlock = $block;
+
+        $pre = $this->indentStr();
+
+        if (! empty($block->selectors)) {
+            $this->blockSelectors($block);
+
+            $this->indentLevel++;
+        }
+
+        if (! empty($block->lines)) {
+            $this->blockLines($block);
+        }
+
+        if (! empty($block->children)) {
+            $this->blockChildren($block);
+        }
+
+        if (! empty($block->selectors)) {
+            $this->indentLevel--;
+
+            if (! $this->keepSemicolons) {
+                $this->strippedSemicolon = '';
+            }
+
+            if (empty($block->children)) {
+                $this->write($this->break);
+            }
+
+            $this->write($pre . $this->close . $this->break);
+        }
+    }
+
+    /**
+     * Test and clean safely empty children
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     *
+     * @return boolean
+     */
+    protected function testEmptyChildren($block)
+    {
+        $isEmpty = empty($block->lines);
+
+        if ($block->children) {
+            foreach ($block->children as $k => &$child) {
+                if (! $this->testEmptyChildren($child)) {
+                    $isEmpty = false;
+                    continue;
+                }
+
+                if ($child->type === Type::T_MEDIA || $child->type === Type::T_DIRECTIVE) {
+                    $child->children = [];
+                    $child->selectors = null;
+                }
+            }
+        }
+
+        return $isEmpty;
+    }
+
+    /**
+     * Entry point to formatting a block
+     *
+     * @api
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock             $block              An abstract syntax tree
+     * @param \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator
+     *
+     * @return string
+     */
+    public function format(OutputBlock $block, SourceMapGenerator $sourceMapGenerator = null)
+    {
+        $this->sourceMapGenerator = null;
+
+        if ($sourceMapGenerator) {
+            $this->currentLine        = 1;
+            $this->currentColumn      = 0;
+            $this->sourceMapGenerator = $sourceMapGenerator;
+        }
+
+        $this->testEmptyChildren($block);
+
+        ob_start();
+
+        $this->block($block);
+
+        $out = ob_get_clean();
+
+        return $out;
+    }
+
+    /**
+     * Output content
+     *
+     * @param string $str
+     */
+    protected function write($str)
+    {
+        if (! empty($this->strippedSemicolon)) {
+            echo $this->strippedSemicolon;
+
+            $this->strippedSemicolon = '';
+        }
+
+        /*
+         * Maybe Strip semi-colon appended by property(); it's a separator, not a terminator
+         * will be striped for real before a closing, otherwise displayed unchanged starting the next write
+         */
+        if (
+            ! $this->keepSemicolons &&
+            $str &&
+            (strpos($str, ';') !== false) &&
+            (substr($str, -1) === ';')
+        ) {
+            $str = substr($str, 0, -1);
+
+            $this->strippedSemicolon = ';';
+        }
+
+        if ($this->sourceMapGenerator) {
+            $this->sourceMapGenerator->addMapping(
+                $this->currentLine,
+                $this->currentColumn,
+                $this->currentBlock->sourceLine,
+                //columns from parser are off by one
+                $this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0,
+                $this->currentBlock->sourceName
+            );
+
+            $lines = explode("\n", $str);
+            $lineCount = \count($lines);
+            $this->currentLine += $lineCount - 1;
+
+            $lastLine = array_pop($lines);
+
+            $this->currentColumn = ($lineCount === 1 ? $this->currentColumn : 0) + \strlen($lastLine);
+        }
+
+        echo $str;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Compact.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Compact.php
new file mode 100644 (file)
index 0000000..98009b4
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+use ScssPhp\ScssPhp\Formatter;
+
+/**
+ * Compact formatter
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Compact extends Formatter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->indentLevel = 0;
+        $this->indentChar = '';
+        $this->break = '';
+        $this->open = ' {';
+        $this->close = "}\n\n";
+        $this->tagSeparator = ',';
+        $this->assignSeparator = ':';
+        $this->keepSemicolons = true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function indentStr()
+    {
+        return ' ';
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Compressed.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Compressed.php
new file mode 100644 (file)
index 0000000..3fdb97a
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+
+/**
+ * Compressed formatter
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Compressed extends Formatter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->indentLevel = 0;
+        $this->indentChar = '  ';
+        $this->break = '';
+        $this->open = '{';
+        $this->close = '}';
+        $this->tagSeparator = ',';
+        $this->assignSeparator = ':';
+        $this->keepSemicolons = false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function blockLines(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+
+        $glue = $this->break . $inner;
+
+        foreach ($block->lines as $index => $line) {
+            if (substr($line, 0, 2) === '/*' && substr($line, 2, 1) !== '!') {
+                unset($block->lines[$index]);
+            } elseif (substr($line, 0, 3) === '/*!') {
+                $block->lines[$index] = '/*' . substr($line, 3);
+            }
+        }
+
+        $this->write($inner . implode($glue, $block->lines));
+
+        if (! empty($block->children)) {
+            $this->write($this->break);
+        }
+    }
+
+    /**
+     * Output block selectors
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     */
+    protected function blockSelectors(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+
+        $this->write(
+            $inner
+            . implode(
+                $this->tagSeparator,
+                str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors)
+            )
+            . $this->open . $this->break
+        );
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Crunched.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Crunched.php
new file mode 100644 (file)
index 0000000..137cdff
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+
+/**
+ * Crunched formatter
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Crunched extends Formatter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->indentLevel = 0;
+        $this->indentChar = '  ';
+        $this->break = '';
+        $this->open = '{';
+        $this->close = '}';
+        $this->tagSeparator = ',';
+        $this->assignSeparator = ':';
+        $this->keepSemicolons = false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function blockLines(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+
+        $glue = $this->break . $inner;
+
+        foreach ($block->lines as $index => $line) {
+            if (substr($line, 0, 2) === '/*') {
+                unset($block->lines[$index]);
+            }
+        }
+
+        $this->write($inner . implode($glue, $block->lines));
+
+        if (! empty($block->children)) {
+            $this->write($this->break);
+        }
+    }
+
+    /**
+     * Output block selectors
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     */
+    protected function blockSelectors(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+
+        $this->write(
+            $inner
+            . implode(
+                $this->tagSeparator,
+                str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors)
+            )
+            . $this->open . $this->break
+        );
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Debug.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Debug.php
new file mode 100644 (file)
index 0000000..5c539a2
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+
+/**
+ * Debug formatter
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Debug extends Formatter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->indentLevel = 0;
+        $this->indentChar = '';
+        $this->break = "\n";
+        $this->open = ' {';
+        $this->close = ' }';
+        $this->tagSeparator = ', ';
+        $this->assignSeparator = ': ';
+        $this->keepSemicolons = true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function indentStr()
+    {
+        return str_repeat('  ', $this->indentLevel);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function blockLines(OutputBlock $block)
+    {
+        $indent = $this->indentStr();
+
+        if (empty($block->lines)) {
+            $this->write("{$indent}block->lines: []\n");
+
+            return;
+        }
+
+        foreach ($block->lines as $index => $line) {
+            $this->write("{$indent}block->lines[{$index}]: $line\n");
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function blockSelectors(OutputBlock $block)
+    {
+        $indent = $this->indentStr();
+
+        if (empty($block->selectors)) {
+            $this->write("{$indent}block->selectors: []\n");
+
+            return;
+        }
+
+        foreach ($block->selectors as $index => $selector) {
+            $this->write("{$indent}block->selectors[{$index}]: $selector\n");
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function blockChildren(OutputBlock $block)
+    {
+        $indent = $this->indentStr();
+
+        if (empty($block->children)) {
+            $this->write("{$indent}block->children: []\n");
+
+            return;
+        }
+
+        $this->indentLevel++;
+
+        foreach ($block->children as $i => $child) {
+            $this->block($child);
+        }
+
+        $this->indentLevel--;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function block(OutputBlock $block)
+    {
+        $indent = $this->indentStr();
+
+        $this->write("{$indent}block->type: {$block->type}\n" .
+             "{$indent}block->depth: {$block->depth}\n");
+
+        $this->currentBlock = $block;
+
+        $this->blockSelectors($block);
+        $this->blockLines($block);
+        $this->blockChildren($block);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Expanded.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Expanded.php
new file mode 100644 (file)
index 0000000..3d5344c
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+
+/**
+ * Expanded formatter
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Expanded extends Formatter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->indentLevel = 0;
+        $this->indentChar = '  ';
+        $this->break = "\n";
+        $this->open = ' {';
+        $this->close = '}';
+        $this->tagSeparator = ', ';
+        $this->assignSeparator = ': ';
+        $this->keepSemicolons = true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function indentStr()
+    {
+        return str_repeat($this->indentChar, $this->indentLevel);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function blockLines(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+
+        $glue = $this->break . $inner;
+
+        foreach ($block->lines as $index => $line) {
+            if (substr($line, 0, 2) === '/*') {
+                $block->lines[$index] = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
+            }
+        }
+
+        $this->write($inner . implode($glue, $block->lines));
+
+        if (empty($block->selectors) || ! empty($block->children)) {
+            $this->write($this->break);
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Nested.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/Nested.php
new file mode 100644 (file)
index 0000000..046ecc8
--- /dev/null
@@ -0,0 +1,231 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+use ScssPhp\ScssPhp\Formatter;
+use ScssPhp\ScssPhp\Formatter\OutputBlock;
+use ScssPhp\ScssPhp\Type;
+
+/**
+ * Nested formatter
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Nested extends Formatter
+{
+    /**
+     * @var integer
+     */
+    private $depth;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct()
+    {
+        $this->indentLevel = 0;
+        $this->indentChar = '  ';
+        $this->break = "\n";
+        $this->open = ' {';
+        $this->close = ' }';
+        $this->tagSeparator = ', ';
+        $this->assignSeparator = ': ';
+        $this->keepSemicolons = true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function indentStr()
+    {
+        $n = $this->depth - 1;
+
+        return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function blockLines(OutputBlock $block)
+    {
+        $inner = $this->indentStr();
+        $glue  = $this->break . $inner;
+
+        foreach ($block->lines as $index => $line) {
+            if (substr($line, 0, 2) === '/*') {
+                $block->lines[$index] = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
+            }
+        }
+
+        $this->write($inner . implode($glue, $block->lines));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function block(OutputBlock $block)
+    {
+        static $depths;
+        static $downLevel;
+        static $closeBlock;
+        static $previousEmpty;
+        static $previousHasSelector;
+
+        if ($block->type === 'root') {
+            $depths = [ 0 ];
+            $downLevel = '';
+            $closeBlock = '';
+            $this->depth = 0;
+            $previousEmpty = false;
+            $previousHasSelector = false;
+        }
+
+        $isMediaOrDirective = \in_array($block->type, [Type::T_DIRECTIVE, Type::T_MEDIA]);
+        $isSupport = ($block->type === Type::T_DIRECTIVE
+            && $block->selectors && strpos(implode('', $block->selectors), '@supports') !== false);
+
+        while ($block->depth < end($depths) || ($block->depth == 1 && end($depths) == 1)) {
+            array_pop($depths);
+            $this->depth--;
+
+            if (
+                ! $this->depth && ($block->depth <= 1 || (! $this->indentLevel && $block->type === Type::T_COMMENT)) &&
+                (($block->selectors && ! $isMediaOrDirective) || $previousHasSelector)
+            ) {
+                $downLevel = $this->break;
+            }
+
+            if (empty($block->lines) && empty($block->children)) {
+                $previousEmpty = true;
+            }
+        }
+
+        if (empty($block->lines) && empty($block->children)) {
+            return;
+        }
+
+        $this->currentBlock = $block;
+
+        if (! empty($block->lines) || (! empty($block->children) && ($this->depth < 1 || $isSupport))) {
+            if ($block->depth > end($depths)) {
+                if (! $previousEmpty || $this->depth < 1) {
+                    $this->depth++;
+
+                    $depths[] = $block->depth;
+                } else {
+                    // keep the current depth unchanged but take the block depth as a new reference for following blocks
+                    array_pop($depths);
+
+                    $depths[] = $block->depth;
+                }
+            }
+        }
+
+        $previousEmpty = ($block->type === Type::T_COMMENT);
+        $previousHasSelector = false;
+
+        if (! empty($block->selectors)) {
+            if ($closeBlock) {
+                $this->write($closeBlock);
+                $closeBlock = '';
+            }
+
+            if ($downLevel) {
+                $this->write($downLevel);
+                $downLevel = '';
+            }
+
+            $this->blockSelectors($block);
+
+            $this->indentLevel++;
+        }
+
+        if (! empty($block->lines)) {
+            if ($closeBlock) {
+                $this->write($closeBlock);
+                $closeBlock = '';
+            }
+
+            if ($downLevel) {
+                $this->write($downLevel);
+                $downLevel = '';
+            }
+
+            $this->blockLines($block);
+
+            $closeBlock = $this->break;
+        }
+
+        if (! empty($block->children)) {
+            if ($this->depth > 0 && ($isMediaOrDirective || ! $this->hasFlatChild($block))) {
+                array_pop($depths);
+
+                $this->depth--;
+                $this->blockChildren($block);
+                $this->depth++;
+
+                $depths[] = $block->depth;
+            } else {
+                $this->blockChildren($block);
+            }
+        }
+
+        // reclear to not be spoiled by children if T_DIRECTIVE
+        if ($block->type === Type::T_DIRECTIVE) {
+            $previousHasSelector = false;
+        }
+
+        if (! empty($block->selectors)) {
+            $this->indentLevel--;
+
+            if (! $this->keepSemicolons) {
+                $this->strippedSemicolon = '';
+            }
+
+            $this->write($this->close);
+
+            $closeBlock = $this->break;
+
+            if ($this->depth > 1 && ! empty($block->children)) {
+                array_pop($depths);
+                $this->depth--;
+            }
+
+            if (! $isMediaOrDirective) {
+                $previousHasSelector = true;
+            }
+        }
+
+        if ($block->type === 'root') {
+            $this->write($this->break);
+        }
+    }
+
+    /**
+     * Block has flat child
+     *
+     * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
+     *
+     * @return boolean
+     */
+    private function hasFlatChild($block)
+    {
+        foreach ($block->children as $child) {
+            if (empty($child->selectors)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/OutputBlock.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Formatter/OutputBlock.php
new file mode 100644 (file)
index 0000000..8dcba7c
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Formatter;
+
+/**
+ * Output block
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class OutputBlock
+{
+    /**
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @var integer
+     */
+    public $depth;
+
+    /**
+     * @var array
+     */
+    public $selectors;
+
+    /**
+     * @var array
+     */
+    public $lines;
+
+    /**
+     * @var array
+     */
+    public $children;
+
+    /**
+     * @var \ScssPhp\ScssPhp\Formatter\OutputBlock
+     */
+    public $parent;
+
+    /**
+     * @var string
+     */
+    public $sourceName;
+
+    /**
+     * @var integer
+     */
+    public $sourceLine;
+
+    /**
+     * @var integer
+     */
+    public $sourceColumn;
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node.php
new file mode 100644 (file)
index 0000000..60d357e
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+/**
+ * Base node
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+abstract class Node
+{
+    /**
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @var integer
+     */
+    public $sourceIndex;
+
+    /**
+     * @var integer
+     */
+    public $sourceLine;
+
+    /**
+     * @var integer
+     */
+    public $sourceColumn;
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Node/Number.php
new file mode 100644 (file)
index 0000000..1ebd30d
--- /dev/null
@@ -0,0 +1,696 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\Node;
+
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Exception\SassScriptException;
+use ScssPhp\ScssPhp\Node;
+use ScssPhp\ScssPhp\Type;
+
+/**
+ * Dimension + optional units
+ *
+ * {@internal
+ *     This is a work-in-progress.
+ *
+ *     The \ArrayAccess interface is temporary until the migration is complete.
+ * }}
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Number extends Node implements \ArrayAccess
+{
+    const PRECISION = 10;
+
+    /**
+     * @var integer
+     * @deprecated use {Number::PRECISION} instead to read the precision. Configuring it is not supported anymore.
+     */
+    public static $precision = self::PRECISION;
+
+    /**
+     * @see http://www.w3.org/TR/2012/WD-css3-values-20120308/
+     *
+     * @var array
+     */
+    protected static $unitTable = [
+        'in' => [
+            'in' => 1,
+            'pc' => 6,
+            'pt' => 72,
+            'px' => 96,
+            'cm' => 2.54,
+            'mm' => 25.4,
+            'q'  => 101.6,
+        ],
+        'turn' => [
+            'deg'  => 360,
+            'grad' => 400,
+            'rad'  => 6.28318530717958647692528676, // 2 * M_PI
+            'turn' => 1,
+        ],
+        's' => [
+            's'  => 1,
+            'ms' => 1000,
+        ],
+        'Hz' => [
+            'Hz'  => 1,
+            'kHz' => 0.001,
+        ],
+        'dpi' => [
+            'dpi'  => 1,
+            'dpcm' => 1 / 2.54,
+            'dppx' => 1 / 96,
+        ],
+    ];
+
+    /**
+     * @var integer|float
+     */
+    private $dimension;
+
+    private $numeratorUnits;
+    private $denominatorUnits;
+
+    /**
+     * Initialize number
+     *
+     * @param integer|float   $dimension
+     * @param string[]|string $numeratorUnits
+     * @param string[]        $denominatorUnits
+     */
+    public function __construct($dimension, $numeratorUnits, array $denominatorUnits = [])
+    {
+        if (is_string($numeratorUnits)) {
+            $numeratorUnits = $numeratorUnits ? [$numeratorUnits] : [];
+        } elseif (isset($numeratorUnits['numerator_units'], $numeratorUnits['denominator_units'])) {
+            // TODO get rid of this once `$number[2]` is not used anymore
+            $denominatorUnits = $numeratorUnits['denominator_units'];
+            $numeratorUnits = $numeratorUnits['numerator_units'];
+        }
+
+        $this->dimension = $dimension;
+        $this->numeratorUnits = $numeratorUnits;
+        $this->denominatorUnits = $denominatorUnits;
+    }
+
+    /**
+     * @return float|int
+     */
+    public function getDimension()
+    {
+        return $this->dimension;
+    }
+
+    /**
+     * @return string[]
+     */
+    public function getNumeratorUnits()
+    {
+        return $this->numeratorUnits;
+    }
+
+    /**
+     * @return string[]
+     */
+    public function getDenominatorUnits()
+    {
+        return $this->denominatorUnits;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetExists($offset)
+    {
+        if ($offset === -3) {
+            return ! \is_null($this->sourceColumn);
+        }
+
+        if ($offset === -2) {
+            return ! \is_null($this->sourceLine);
+        }
+
+        if (
+            $offset === -1 ||
+            $offset === 0 ||
+            $offset === 1 ||
+            $offset === 2
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetGet($offset)
+    {
+        switch ($offset) {
+            case -3:
+                return $this->sourceColumn;
+
+            case -2:
+                return $this->sourceLine;
+
+            case -1:
+                return $this->sourceIndex;
+
+            case 0:
+                return Type::T_NUMBER;
+
+            case 1:
+                return $this->dimension;
+
+            case 2:
+                return array('numerator_units' => $this->numeratorUnits, 'denominator_units' => $this->denominatorUnits);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetSet($offset, $value)
+    {
+        throw new \BadMethodCallException('Number is immutable');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetUnset($offset)
+    {
+        throw new \BadMethodCallException('Number is immutable');
+    }
+
+    /**
+     * Returns true if the number is unitless
+     *
+     * @return boolean
+     */
+    public function unitless()
+    {
+        return \count($this->numeratorUnits) === 0 && \count($this->denominatorUnits) === 0;
+    }
+
+    /**
+     * Checks whether the number has exactly this unit
+     *
+     * @param string $unit
+     *
+     * @return bool
+     */
+    public function hasUnit($unit)
+    {
+        return \count($this->numeratorUnits) === 1 && \count($this->denominatorUnits) === 0 && $this->numeratorUnits[0] === $unit;
+    }
+
+    /**
+     * Returns unit(s) as the product of numerator units divided by the product of denominator units
+     *
+     * @return string
+     */
+    public function unitStr()
+    {
+        if ($this->unitless()) {
+            return '';
+        }
+
+        return self::getUnitString($this->numeratorUnits, $this->denominatorUnits);
+    }
+
+    public function assertNoUnits($varName = null)
+    {
+        if ($this->unitless()) {
+            return;
+        }
+
+        $varDisplay = !\is_null($varName) ? "\${$varName}: " : '';
+
+        throw new SassScriptException(sprintf('%sExpected %s to have no units', $varDisplay, $this));
+    }
+
+    public function assertSameUnitOrUnitless(Number $other)
+    {
+        if ($other->unitless()) {
+            return;
+        }
+
+        if ($this->numeratorUnits === $other->numeratorUnits && $this->denominatorUnits === $other->denominatorUnits) {
+            return;
+        }
+
+        throw new SassScriptException(sprintf(
+            'Incompatible units %s and %s.',
+            self::getUnitString($this->numeratorUnits, $this->denominatorUnits),
+            self::getUnitString($other->numeratorUnits, $other->denominatorUnits)
+        ));
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return bool
+     */
+    public function isComparableTo(Number $other)
+    {
+        if ($this->unitless() || $other->unitless()) {
+            return true;
+        }
+
+        try {
+            $this->greaterThan($other);
+            return true;
+        } catch (SassScriptException $e) {
+            return false;
+        }
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return bool
+     */
+    public function lessThan(Number $other)
+    {
+        return $this->coerceUnits($other, function ($num1, $num2) {
+            return $num1 < $num2;
+        });
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return bool
+     */
+    public function lessThanOrEqual(Number $other)
+    {
+        return $this->coerceUnits($other, function ($num1, $num2) {
+            return $num1 <= $num2;
+        });
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return bool
+     */
+    public function greaterThan(Number $other)
+    {
+        return $this->coerceUnits($other, function ($num1, $num2) {
+            return $num1 > $num2;
+        });
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return bool
+     */
+    public function greaterThanOrEqual(Number $other)
+    {
+        return $this->coerceUnits($other, function ($num1, $num2) {
+            return $num1 >= $num2;
+        });
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return Number
+     */
+    public function plus(Number $other)
+    {
+        return $this->coerceNumber($other, function ($num1, $num2) {
+            return $num1 + $num2;
+        });
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return Number
+     */
+    public function minus(Number $other)
+    {
+        return $this->coerceNumber($other, function ($num1, $num2) {
+            return $num1 - $num2;
+        });
+    }
+
+    /**
+     * @return Number
+     */
+    public function unaryMinus()
+    {
+        return new Number(-$this->dimension, $this->numeratorUnits, $this->denominatorUnits);
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return Number
+     */
+    public function modulo(Number $other)
+    {
+        return $this->coerceNumber($other, function ($num1, $num2) {
+            if ($num2 == 0) {
+                return NAN;
+            }
+
+            return $num1 % $num2;
+        });
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return Number
+     */
+    public function times(Number $other)
+    {
+        return $this->multiplyUnits($this->dimension * $other->dimension, $this->numeratorUnits, $this->denominatorUnits, $other->numeratorUnits, $other->denominatorUnits);
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return Number
+     */
+    public function dividedBy(Number $other)
+    {
+        if ($other->dimension == 0) {
+            if ($this->dimension == 0) {
+                $value = NAN;
+            } elseif ($this->dimension > 0) {
+                $value = INF;
+            } else {
+                $value = -INF;
+            }
+        } else {
+            $value = $this->dimension / $other->dimension;
+        }
+
+        return $this->multiplyUnits($value, $this->numeratorUnits, $this->denominatorUnits, $other->denominatorUnits, $other->numeratorUnits);
+    }
+
+    /**
+     * @param Number $other
+     *
+     * @return bool
+     */
+    public function equals(Number $other)
+    {
+        // Unitless numbers are convertable to unit numbers, but not equal, so we special-case unitless here.
+        if ($this->unitless() !== $other->unitless()) {
+            return false;
+        }
+
+        // In Sass, neither NaN nor Infinity are equal to themselves, while PHP defines INF==INF
+        if (is_nan($this->dimension) || is_nan($other->dimension) || !is_finite($this->dimension) || !is_finite($other->dimension)) {
+            return false;
+        }
+
+        if ($this->unitless()) {
+            return round($this->dimension, self::PRECISION) == round($other->dimension, self::PRECISION);
+        }
+
+        try {
+            return $this->coerceUnits($other, function ($num1, $num2) {
+                return round($num1,self::PRECISION) == round($num2, self::PRECISION);
+            });
+        } catch (SassScriptException $e) {
+            return false;
+        }
+    }
+
+    /**
+     * Output number
+     *
+     * @param \ScssPhp\ScssPhp\Compiler $compiler
+     *
+     * @return string
+     */
+    public function output(Compiler $compiler = null)
+    {
+        $dimension = round($this->dimension, self::PRECISION);
+
+        if (is_nan($dimension)) {
+            return 'NaN';
+        }
+
+        if ($dimension === INF) {
+            return 'Infinity';
+        }
+
+        if ($dimension === -INF) {
+            return '-Infinity';
+        }
+
+        if ($compiler) {
+            $unit = $this->unitStr();
+        } elseif (isset($this->numeratorUnits[0])) {
+            $unit = $this->numeratorUnits[0];
+        } else {
+            $unit = '';
+        }
+
+        $dimension = number_format($dimension, self::PRECISION, '.', '');
+
+        return rtrim(rtrim($dimension, '0'), '.') . $unit;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        return $this->output();
+    }
+
+    /**
+     * @param Number   $other
+     * @param callable $operation
+     *
+     * @return Number
+     *
+     * @phpstan-param callable(int|float, int|float): int|float $operation
+     */
+    private function coerceNumber(Number $other, $operation)
+    {
+        $result = $this->coerceUnits($other, $operation);
+
+        if (!$this->unitless()) {
+            return new Number($result, $this->numeratorUnits, $this->denominatorUnits);
+        }
+
+        return new Number($result, $other->numeratorUnits, $other->denominatorUnits);
+    }
+
+    /**
+     * @param Number $other
+     * @param callable $operation
+     *
+     * @return mixed
+     *
+     * @phpstan-template T
+     * @phpstan-param callable(int|float, int|float): T $operation
+     * @phpstan-return T
+     */
+    private function coerceUnits(Number $other, $operation)
+    {
+        if (!$this->unitless()) {
+            $num1 = $this->dimension;
+            $num2 = $other->valueInUnits($this->numeratorUnits, $this->denominatorUnits);
+        } else {
+            $num1 = $this->valueInUnits($other->numeratorUnits, $other->denominatorUnits);
+            $num2 = $other->dimension;
+        }
+
+        return \call_user_func($operation, $num1, $num2);
+    }
+
+    /**
+     * @param string[] $numeratorUnits
+     * @param string[] $denominatorUnits
+     *
+     * @return int|float
+     */
+    private function valueInUnits(array $numeratorUnits, array $denominatorUnits)
+    {
+        if (
+            $this->unitless()
+            || (\count($numeratorUnits) === 0 && \count($denominatorUnits) === 0)
+            || ($this->numeratorUnits === $numeratorUnits && $this->denominatorUnits === $denominatorUnits)
+        ) {
+            return $this->dimension;
+        }
+
+        $value = $this->dimension;
+        $oldNumerators = $this->numeratorUnits;
+
+        foreach ($numeratorUnits as $newNumerator) {
+            foreach ($oldNumerators as $key => $oldNumerator) {
+                $conversionFactor = self::getConversionFactor($newNumerator, $oldNumerator);
+
+                if (\is_null($conversionFactor)) {
+                    continue;
+                }
+
+                $value *= $conversionFactor;
+                unset($oldNumerators[$key]);
+                continue 2;
+            }
+
+            throw new SassScriptException(sprintf(
+                'Incompatible units %s and %s.',
+                self::getUnitString($this->numeratorUnits, $this->denominatorUnits),
+                self::getUnitString($numeratorUnits, $denominatorUnits)
+            ));
+        }
+
+        $oldDenominators = $this->denominatorUnits;
+
+        foreach ($denominatorUnits as $newDenominator) {
+            foreach ($oldDenominators as $key => $oldDenominator) {
+                $conversionFactor = self::getConversionFactor($newDenominator, $oldDenominator);
+
+                if (\is_null($conversionFactor)) {
+                    continue;
+                }
+
+                $value /= $conversionFactor;
+                unset($oldDenominators[$key]);
+                continue 2;
+            }
+
+            throw new SassScriptException(sprintf(
+                'Incompatible units %s and %s.',
+                self::getUnitString($this->numeratorUnits, $this->denominatorUnits),
+                self::getUnitString($numeratorUnits, $denominatorUnits)
+            ));
+        }
+
+        if (\count($oldNumerators) || \count($oldDenominators)) {
+            throw new SassScriptException(sprintf(
+                'Incompatible units %s and %s.',
+                self::getUnitString($this->numeratorUnits, $this->denominatorUnits),
+                self::getUnitString($numeratorUnits, $denominatorUnits)
+            ));
+        }
+
+        return $value;
+    }
+
+    /**
+     * @param int|float $value
+     * @param string[] $numerators1
+     * @param string[] $denominators1
+     * @param string[] $numerators2
+     * @param string[] $denominators2
+     *
+     * @return Number
+     */
+    private function multiplyUnits($value, array $numerators1, array $denominators1, array $numerators2, array $denominators2)
+    {
+        $newNumerators = array();
+
+        foreach ($numerators1 as $numerator) {
+            foreach ($denominators2 as $key => $denominator) {
+                $conversionFactor = self::getConversionFactor($numerator, $denominator);
+
+                if (\is_null($conversionFactor)) {
+                    continue;
+                }
+
+                $value /= $conversionFactor;
+                unset($denominators2[$key]);
+                continue 2;
+            }
+
+            $newNumerators[] = $numerator;
+        }
+
+        foreach ($numerators2 as $numerator) {
+            foreach ($denominators1 as $key => $denominator) {
+                $conversionFactor = self::getConversionFactor($numerator, $denominator);
+
+                if (\is_null($conversionFactor)) {
+                    continue;
+                }
+
+                $value /= $conversionFactor;
+                unset($denominators1[$key]);
+                continue 2;
+            }
+
+            $newNumerators[] = $numerator;
+        }
+
+        $newDenominators = array_values(array_merge($denominators1, $denominators2));
+
+        return new Number($value, $newNumerators, $newDenominators);
+    }
+
+    /**
+     * Returns the number of [unit1]s per [unit2].
+     *
+     * Equivalently, `1unit1 * conversionFactor(unit1, unit2) = 1unit2`.
+     *
+     * @param string $unit1
+     * @param string $unit2
+     *
+     * @return float|int|null
+     */
+    private static function getConversionFactor($unit1, $unit2)
+    {
+        if ($unit1 === $unit2) {
+            return 1;
+        }
+
+        foreach (static::$unitTable as $unitVariants) {
+            if (isset($unitVariants[$unit1]) && isset($unitVariants[$unit2])) {
+                return $unitVariants[$unit1] / $unitVariants[$unit2];
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns unit(s) as the product of numerator units divided by the product of denominator units
+     *
+     * @param string[] $numerators
+     * @param string[] $denominators
+     *
+     * @return string
+     */
+    private static function getUnitString(array $numerators, array $denominators)
+    {
+        if (!\count($numerators)) {
+            if (\count($denominators) === 0) {
+                return 'no units';
+            }
+
+            if (\count($denominators) === 1) {
+                return $denominators[0] . '^-1';
+            }
+
+            return '(' . implode('*', $denominators) . ')^-1';
+        }
+
+        return implode('*', $numerators) . (\count($denominators) ? '/' . implode('*', $denominators) : '');
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Parser.php
new file mode 100644 (file)
index 0000000..55371e5
--- /dev/null
@@ -0,0 +1,3986 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+use ScssPhp\ScssPhp\Block;
+use ScssPhp\ScssPhp\Cache;
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Exception\ParserException;
+use ScssPhp\ScssPhp\Node;
+use ScssPhp\ScssPhp\Type;
+
+/**
+ * Parser
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Parser
+{
+    const SOURCE_INDEX  = -1;
+    const SOURCE_LINE   = -2;
+    const SOURCE_COLUMN = -3;
+
+    /**
+     * @var array
+     */
+    protected static $precedence = [
+        '='   => 0,
+        'or'  => 1,
+        'and' => 2,
+        '=='  => 3,
+        '!='  => 3,
+        '<='  => 4,
+        '>='  => 4,
+        '<'   => 4,
+        '>'   => 4,
+        '+'   => 5,
+        '-'   => 5,
+        '*'   => 6,
+        '/'   => 6,
+        '%'   => 6,
+    ];
+
+    protected static $commentPattern;
+    protected static $operatorPattern;
+    protected static $whitePattern;
+
+    protected $cache;
+
+    private $sourceName;
+    private $sourceIndex;
+    private $sourcePositions;
+    private $charset;
+    private $count;
+    private $env;
+    private $inParens;
+    private $eatWhiteDefault;
+    private $discardComments;
+    private $allowVars;
+    private $buffer;
+    private $utf8;
+    private $encoding;
+    private $patternModifiers;
+    private $commentsSeen;
+
+    private $cssOnly;
+
+    /**
+     * Constructor
+     *
+     * @api
+     *
+     * @param string                 $sourceName
+     * @param integer                $sourceIndex
+     * @param string                 $encoding
+     * @param \ScssPhp\ScssPhp\Cache $cache
+     */
+    public function __construct($sourceName, $sourceIndex = 0, $encoding = 'utf-8', $cache = null, $cssOnly = false)
+    {
+        $this->sourceName       = $sourceName ?: '(stdin)';
+        $this->sourceIndex      = $sourceIndex;
+        $this->charset          = null;
+        $this->utf8             = ! $encoding || strtolower($encoding) === 'utf-8';
+        $this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais';
+        $this->commentsSeen     = [];
+        $this->commentsSeen     = [];
+        $this->allowVars        = true;
+        $this->cssOnly          = $cssOnly;
+
+        if (empty(static::$operatorPattern)) {
+            static::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=?|and|or)';
+
+            $commentSingle      = '\/\/';
+            $commentMultiLeft   = '\/\*';
+            $commentMultiRight  = '\*\/';
+
+            static::$commentPattern = $commentMultiLeft . '.*?' . $commentMultiRight;
+            static::$whitePattern = $this->utf8
+                ? '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisuS'
+                : '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisS';
+        }
+
+        if ($cache) {
+            $this->cache = $cache;
+        }
+    }
+
+    /**
+     * Get source file name
+     *
+     * @api
+     *
+     * @return string
+     */
+    public function getSourceName()
+    {
+        return $this->sourceName;
+    }
+
+    /**
+     * Throw parser error
+     *
+     * @api
+     *
+     * @param string $msg
+     *
+     * @throws \ScssPhp\ScssPhp\Exception\ParserException
+     *
+     * @deprecated use "parseError" and throw the exception in the caller instead.
+     */
+    public function throwParseError($msg = 'parse error')
+    {
+        @trigger_error(
+            'The method "throwParseError" is deprecated. Use "parseError" and throw the exception in the caller instead',
+            E_USER_DEPRECATED
+        );
+
+        throw $this->parseError($msg);
+    }
+
+    /**
+     * Creates a parser error
+     *
+     * @api
+     *
+     * @param string $msg
+     *
+     * @return ParserException
+     */
+    public function parseError($msg = 'parse error')
+    {
+        list($line, $column) = $this->getSourcePosition($this->count);
+
+        $loc = empty($this->sourceName)
+             ? "line: $line, column: $column"
+             : "$this->sourceName on line $line, at column $column";
+
+        if ($this->peek('(.*?)(\n|$)', $m, $this->count)) {
+            $this->restoreEncoding();
+
+            $e = new ParserException("$msg: failed at `$m[1]` $loc");
+            $e->setSourcePosition([$this->sourceName, $line, $column]);
+
+            return $e;
+        }
+
+        $this->restoreEncoding();
+
+        $e = new ParserException("$msg: $loc");
+        $e->setSourcePosition([$this->sourceName, $line, $column]);
+
+        return $e;
+    }
+
+    /**
+     * Parser buffer
+     *
+     * @api
+     *
+     * @param string $buffer
+     *
+     * @return \ScssPhp\ScssPhp\Block
+     */
+    public function parse($buffer)
+    {
+        if ($this->cache) {
+            $cacheKey = $this->sourceName . ':' . md5($buffer);
+            $parseOptions = [
+                'charset' => $this->charset,
+                'utf8' => $this->utf8,
+            ];
+            $v = $this->cache->getCache('parse', $cacheKey, $parseOptions);
+
+            if (! \is_null($v)) {
+                return $v;
+            }
+        }
+
+        // strip BOM (byte order marker)
+        if (substr($buffer, 0, 3) === "\xef\xbb\xbf") {
+            $buffer = substr($buffer, 3);
+        }
+
+        $this->buffer          = rtrim($buffer, "\x00..\x1f");
+        $this->count           = 0;
+        $this->env             = null;
+        $this->inParens        = false;
+        $this->eatWhiteDefault = true;
+
+        $this->saveEncoding();
+        $this->extractLineNumbers($buffer);
+
+        $this->pushBlock(null); // root block
+        $this->whitespace();
+        $this->pushBlock(null);
+        $this->popBlock();
+
+        while ($this->parseChunk()) {
+            ;
+        }
+
+        if ($this->count !== \strlen($this->buffer)) {
+            throw $this->parseError();
+        }
+
+        if (! empty($this->env->parent)) {
+            throw $this->parseError('unclosed block');
+        }
+
+        if ($this->charset) {
+            array_unshift($this->env->children, $this->charset);
+        }
+
+        $this->restoreEncoding();
+
+        if ($this->cache) {
+            $this->cache->setCache('parse', $cacheKey, $this->env, $parseOptions);
+        }
+
+        return $this->env;
+    }
+
+    /**
+     * Parse a value or value list
+     *
+     * @api
+     *
+     * @param string       $buffer
+     * @param string|array $out
+     *
+     * @return boolean
+     */
+    public function parseValue($buffer, &$out)
+    {
+        $this->count           = 0;
+        $this->env             = null;
+        $this->inParens        = false;
+        $this->eatWhiteDefault = true;
+        $this->buffer          = (string) $buffer;
+
+        $this->saveEncoding();
+        $this->extractLineNumbers($this->buffer);
+
+        $list = $this->valueList($out);
+
+        $this->restoreEncoding();
+
+        return $list;
+    }
+
+    /**
+     * Parse a selector or selector list
+     *
+     * @api
+     *
+     * @param string       $buffer
+     * @param string|array $out
+     * @param bool         $shouldValidate
+     *
+     * @return boolean
+     */
+    public function parseSelector($buffer, &$out, $shouldValidate = true)
+    {
+        $this->count           = 0;
+        $this->env             = null;
+        $this->inParens        = false;
+        $this->eatWhiteDefault = true;
+        $this->buffer          = (string) $buffer;
+
+        $this->saveEncoding();
+        $this->extractLineNumbers($this->buffer);
+
+        $selector = $this->selectors($out);
+
+        $this->restoreEncoding();
+
+        if ($shouldValidate && $this->count !== strlen($buffer)) {
+            throw $this->parseError("`" . substr($buffer, $this->count) . "` is not a valid Selector in `$buffer`");
+        }
+
+        return $selector;
+    }
+
+    /**
+     * Parse a media Query
+     *
+     * @api
+     *
+     * @param string       $buffer
+     * @param string|array $out
+     *
+     * @return boolean
+     */
+    public function parseMediaQueryList($buffer, &$out)
+    {
+        $this->count           = 0;
+        $this->env             = null;
+        $this->inParens        = false;
+        $this->eatWhiteDefault = true;
+        $this->buffer          = (string) $buffer;
+
+        $this->saveEncoding();
+        $this->extractLineNumbers($this->buffer);
+
+        $isMediaQuery = $this->mediaQueryList($out);
+
+        $this->restoreEncoding();
+
+        return $isMediaQuery;
+    }
+
+    /**
+     * Parse a single chunk off the head of the buffer and append it to the
+     * current parse environment.
+     *
+     * Returns false when the buffer is empty, or when there is an error.
+     *
+     * This function is called repeatedly until the entire document is
+     * parsed.
+     *
+     * This parser is most similar to a recursive descent parser. Single
+     * functions represent discrete grammatical rules for the language, and
+     * they are able to capture the text that represents those rules.
+     *
+     * Consider the function Compiler::keyword(). (All parse functions are
+     * structured the same.)
+     *
+     * The function takes a single reference argument. When calling the
+     * function it will attempt to match a keyword on the head of the buffer.
+     * If it is successful, it will place the keyword in the referenced
+     * argument, advance the position in the buffer, and return true. If it
+     * fails then it won't advance the buffer and it will return false.
+     *
+     * All of these parse functions are powered by Compiler::match(), which behaves
+     * the same way, but takes a literal regular expression. Sometimes it is
+     * more convenient to use match instead of creating a new function.
+     *
+     * Because of the format of the functions, to parse an entire string of
+     * grammatical rules, you can chain them together using &&.
+     *
+     * But, if some of the rules in the chain succeed before one fails, then
+     * the buffer position will be left at an invalid state. In order to
+     * avoid this, Compiler::seek() is used to remember and set buffer positions.
+     *
+     * Before parsing a chain, use $s = $this->count to remember the current
+     * position into $s. Then if a chain fails, use $this->seek($s) to
+     * go back where we started.
+     *
+     * @return boolean
+     */
+    protected function parseChunk()
+    {
+        $s = $this->count;
+
+        // the directives
+        if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] === '@') {
+            if (
+                $this->literal('@at-root', 8) &&
+                ($this->selectors($selector) || true) &&
+                ($this->map($with) || true) &&
+                (($this->matchChar('(') &&
+                    $this->interpolation($with) &&
+                    $this->matchChar(')')) || true) &&
+                $this->matchChar('{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $atRoot = $this->pushSpecialBlock(Type::T_AT_ROOT, $s);
+                $atRoot->selector = $selector;
+                $atRoot->with     = $with;
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@media', 6) &&
+                $this->mediaQueryList($mediaQueryList) &&
+                $this->matchChar('{', false)
+            ) {
+                $media = $this->pushSpecialBlock(Type::T_MEDIA, $s);
+                $media->queryList = $mediaQueryList[2];
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@mixin', 6) &&
+                $this->keyword($mixinName) &&
+                ($this->argumentDef($args) || true) &&
+                $this->matchChar('{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $mixin = $this->pushSpecialBlock(Type::T_MIXIN, $s);
+                $mixin->name = $mixinName;
+                $mixin->args = $args;
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                ($this->literal('@include', 8) &&
+                    $this->keyword($mixinName) &&
+                    ($this->matchChar('(') &&
+                    ($this->argValues($argValues) || true) &&
+                    $this->matchChar(')') || true) &&
+                    ($this->end()) ||
+                ($this->literal('using', 5) &&
+                    $this->argumentDef($argUsing) &&
+                    ($this->end() || $this->matchChar('{') && $hasBlock = true)) ||
+                $this->matchChar('{') && $hasBlock = true)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $child = [
+                    Type::T_INCLUDE,
+                    $mixinName,
+                    isset($argValues) ? $argValues : null,
+                    null,
+                    isset($argUsing) ? $argUsing : null
+                ];
+
+                if (! empty($hasBlock)) {
+                    $include = $this->pushSpecialBlock(Type::T_INCLUDE, $s);
+                    $include->child = $child;
+                } else {
+                    $this->append($child, $s);
+                }
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@scssphp-import-once', 20) &&
+                $this->valueList($importPath) &&
+                $this->end()
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $this->append([Type::T_SCSSPHP_IMPORT_ONCE, $importPath], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@import', 7) &&
+                $this->valueList($importPath) &&
+                $importPath[0] !== Type::T_FUNCTION_CALL &&
+                $this->end()
+            ) {
+                if ($this->cssOnly) {
+                    $this->assertPlainCssValid([Type::T_IMPORT, $importPath], $s);
+                    $this->append([Type::T_COMMENT, rtrim(substr($this->buffer, $s, $this->count - $s))]);
+                    return true;
+                }
+
+                $this->append([Type::T_IMPORT, $importPath], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@import', 7) &&
+                $this->url($importPath) &&
+                $this->end()
+            ) {
+                if ($this->cssOnly) {
+                    $this->assertPlainCssValid([Type::T_IMPORT, $importPath], $s);
+                    $this->append([Type::T_COMMENT, rtrim(substr($this->buffer, $s, $this->count - $s))]);
+                    return true;
+                }
+
+                $this->append([Type::T_IMPORT, $importPath], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@extend', 7) &&
+                $this->selectors($selectors) &&
+                $this->end()
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                // check for '!flag'
+                $optional = $this->stripOptionalFlag($selectors);
+                $this->append([Type::T_EXTEND, $selectors, $optional], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@function', 9) &&
+                $this->keyword($fnName) &&
+                $this->argumentDef($args) &&
+                $this->matchChar('{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $func = $this->pushSpecialBlock(Type::T_FUNCTION, $s);
+                $func->name = $fnName;
+                $func->args = $args;
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@return', 7) &&
+                ($this->valueList($retVal) || true) &&
+                $this->end()
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $this->append([Type::T_RETURN, isset($retVal) ? $retVal : [Type::T_NULL]], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@each', 5) &&
+                $this->genericList($varNames, 'variable', ',', false) &&
+                $this->literal('in', 2) &&
+                $this->valueList($list) &&
+                $this->matchChar('{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $each = $this->pushSpecialBlock(Type::T_EACH, $s);
+
+                foreach ($varNames[2] as $varName) {
+                    $each->vars[] = $varName[1];
+                }
+
+                $each->list = $list;
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@while', 6) &&
+                $this->expression($cond) &&
+                $this->matchChar('{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                while (
+                    $cond[0] === Type::T_LIST &&
+                    ! empty($cond['enclosing']) &&
+                    $cond['enclosing'] === 'parent' &&
+                    \count($cond[2]) == 1
+                ) {
+                    $cond = reset($cond[2]);
+                }
+
+                $while = $this->pushSpecialBlock(Type::T_WHILE, $s);
+                $while->cond = $cond;
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@for', 4) &&
+                $this->variable($varName) &&
+                $this->literal('from', 4) &&
+                $this->expression($start) &&
+                ($this->literal('through', 7) ||
+                    ($forUntil = true && $this->literal('to', 2))) &&
+                $this->expression($end) &&
+                $this->matchChar('{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $for = $this->pushSpecialBlock(Type::T_FOR, $s);
+                $for->var   = $varName[1];
+                $for->start = $start;
+                $for->end   = $end;
+                $for->until = isset($forUntil);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@if', 3) &&
+                $this->functionCallArgumentsList($cond, false, '{', false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $if = $this->pushSpecialBlock(Type::T_IF, $s);
+
+                while (
+                    $cond[0] === Type::T_LIST &&
+                    ! empty($cond['enclosing']) &&
+                    $cond['enclosing'] === 'parent' &&
+                    \count($cond[2]) == 1
+                ) {
+                    $cond = reset($cond[2]);
+                }
+
+                $if->cond  = $cond;
+                $if->cases = [];
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@debug', 6) &&
+                $this->functionCallArgumentsList($value, false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $this->append([Type::T_DEBUG, $value], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@warn', 5) &&
+                $this->functionCallArgumentsList($value, false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $this->append([Type::T_WARN, $value], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@error', 6) &&
+                $this->functionCallArgumentsList($value, false)
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $this->append([Type::T_ERROR, $value], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@content', 8) &&
+                ($this->end() ||
+                    $this->matchChar('(') &&
+                    $this->argValues($argContent) &&
+                    $this->matchChar(')') &&
+                    $this->end())
+            ) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+                $this->append([Type::T_MIXIN_CONTENT, isset($argContent) ? $argContent : null], $s);
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            $last = $this->last();
+
+            if (isset($last) && $last[0] === Type::T_IF) {
+                list(, $if) = $last;
+
+                if ($this->literal('@else', 5)) {
+                    if ($this->matchChar('{', false)) {
+                        $else = $this->pushSpecialBlock(Type::T_ELSE, $s);
+                    } elseif (
+                        $this->literal('if', 2) &&
+                        $this->functionCallArgumentsList($cond, false, '{', false)
+                    ) {
+                        $else = $this->pushSpecialBlock(Type::T_ELSEIF, $s);
+                        $else->cond = $cond;
+                    }
+
+                    if (isset($else)) {
+                        $else->dontAppend = true;
+                        $if->cases[] = $else;
+
+                        return true;
+                    }
+                }
+
+                $this->seek($s);
+            }
+
+            // only retain the first @charset directive encountered
+            if (
+                $this->literal('@charset', 8) &&
+                $this->valueList($charset) &&
+                $this->end()
+            ) {
+                if (! isset($this->charset)) {
+                    $statement = [Type::T_CHARSET, $charset];
+
+                    list($line, $column) = $this->getSourcePosition($s);
+
+                    $statement[static::SOURCE_LINE]   = $line;
+                    $statement[static::SOURCE_COLUMN] = $column;
+                    $statement[static::SOURCE_INDEX]  = $this->sourceIndex;
+
+                    $this->charset = $statement;
+                }
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->literal('@supports', 9) &&
+                ($t1 = $this->supportsQuery($supportQuery)) &&
+                ($t2 = $this->matchChar('{', false))
+            ) {
+                $directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s);
+                $directive->name  = 'supports';
+                $directive->value = $supportQuery;
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            // doesn't match built in directive, do generic one
+            if (
+                $this->matchChar('@', false) &&
+                $this->mixedKeyword($dirName) &&
+                $this->directiveValue($dirValue, '{')
+            ) {
+                if (count($dirName) === 1 && is_string(reset($dirName))) {
+                    $dirName = reset($dirName);
+                } else {
+                    $dirName = [Type::T_STRING, '', $dirName];
+                }
+                if ($dirName === 'media') {
+                    $directive = $this->pushSpecialBlock(Type::T_MEDIA, $s);
+                } else {
+                    $directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s);
+                    $directive->name = $dirName;
+                }
+
+                if (isset($dirValue)) {
+                    ! $this->cssOnly || ($dirValue = $this->assertPlainCssValid($dirValue));
+                    $directive->value = $dirValue;
+                }
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            // maybe it's a generic blockless directive
+            if (
+                $this->matchChar('@', false) &&
+                $this->mixedKeyword($dirName) &&
+                ! $this->isKnownGenericDirective($dirName) &&
+                ($this->end(false) || ($this->directiveValue($dirValue, '') && $this->end(false)))
+            ) {
+                if (\count($dirName) === 1 && \is_string(\reset($dirName))) {
+                    $dirName = \reset($dirName);
+                } else {
+                    $dirName = [Type::T_STRING, '', $dirName];
+                }
+                if (
+                    ! empty($this->env->parent) &&
+                    $this->env->type &&
+                    ! \in_array($this->env->type, [Type::T_DIRECTIVE, Type::T_MEDIA])
+                ) {
+                    $plain = \trim(\substr($this->buffer, $s, $this->count - $s));
+                    throw $this->parseError(
+                        "Unknown directive `{$plain}` not allowed in `" . $this->env->type . "` block"
+                    );
+                }
+                // blockless directives with a blank line after keeps their blank lines after
+                // sass-spec compliance purpose
+                $s = $this->count;
+                $hasBlankLine = false;
+                if ($this->match('\s*?\n\s*\n', $out, false)) {
+                    $hasBlankLine = true;
+                    $this->seek($s);
+                }
+                $isNotRoot = ! empty($this->env->parent);
+                $this->append([Type::T_DIRECTIVE, [$dirName, $dirValue, $hasBlankLine, $isNotRoot]], $s);
+                $this->whitespace();
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            return false;
+        }
+
+        $inCssSelector = null;
+        if ($this->cssOnly) {
+            $inCssSelector = (! empty($this->env->parent) &&
+                ! in_array($this->env->type, [Type::T_DIRECTIVE, Type::T_MEDIA]));
+        }
+        // custom properties : right part is static
+        if (($this->customProperty($name) ) && $this->matchChar(':', false)) {
+            $start = $this->count;
+
+            // but can be complex and finish with ; or }
+            foreach ([';','}'] as $ending) {
+                if (
+                    $this->openString($ending, $stringValue, '(', ')', false) &&
+                    $this->end()
+                ) {
+                    $end = $this->count;
+                    $value = $stringValue;
+
+                    // check if we have only a partial value due to nested [] or { } to take in account
+                    $nestingPairs = [['[', ']'], ['{', '}']];
+
+                    foreach ($nestingPairs as $nestingPair) {
+                        $p = strpos($this->buffer, $nestingPair[0], $start);
+
+                        if ($p && $p < $end) {
+                            $this->seek($start);
+
+                            if (
+                                $this->openString($ending, $stringValue, $nestingPair[0], $nestingPair[1], false) &&
+                                $this->end() &&
+                                $this->count > $end
+                            ) {
+                                $end = $this->count;
+                                $value = $stringValue;
+                            }
+                        }
+                    }
+
+                    $this->seek($end);
+                    $this->append([Type::T_CUSTOM_PROPERTY, $name, $value], $s);
+
+                    return true;
+                }
+            }
+
+            // TODO: output an error here if nothing found according to sass spec
+        }
+
+        $this->seek($s);
+
+        // property shortcut
+        // captures most properties before having to parse a selector
+        if (
+            $this->keyword($name, false) &&
+            $this->literal(': ', 2) &&
+            $this->valueList($value) &&
+            $this->end()
+        ) {
+            $name = [Type::T_STRING, '', [$name]];
+            $this->append([Type::T_ASSIGN, $name, $value], $s);
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        // variable assigns
+        if (
+            $this->variable($name) &&
+            $this->matchChar(':') &&
+            $this->valueList($value) &&
+            $this->end()
+        ) {
+            ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+
+            // check for '!flag'
+            $assignmentFlags = $this->stripAssignmentFlags($value);
+            $this->append([Type::T_ASSIGN, $name, $value, $assignmentFlags], $s);
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        // misc
+        if ($this->literal('-->', 3)) {
+            return true;
+        }
+
+        // opening css block
+        if (
+            $this->selectors($selectors) &&
+            $this->matchChar('{', false)
+        ) {
+            ! $this->cssOnly || ! $inCssSelector || $this->assertPlainCssValid(false);
+
+            $this->pushBlock($selectors, $s);
+
+            if ($this->eatWhiteDefault) {
+                $this->whitespace();
+                $this->append(null); // collect comments at the beginning if needed
+            }
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        // property assign, or nested assign
+        if (
+            $this->propertyName($name) &&
+            $this->matchChar(':')
+        ) {
+            $foundSomething = false;
+
+            if ($this->valueList($value)) {
+                if (empty($this->env->parent)) {
+                    throw $this->parseError('expected "{"');
+                }
+
+                $this->append([Type::T_ASSIGN, $name, $value], $s);
+                $foundSomething = true;
+            }
+
+            if ($this->matchChar('{', false)) {
+                ! $this->cssOnly || $this->assertPlainCssValid(false);
+
+                $propBlock = $this->pushSpecialBlock(Type::T_NESTED_PROPERTY, $s);
+                $propBlock->prefix = $name;
+                $propBlock->hasValue = $foundSomething;
+
+                $foundSomething = true;
+            } elseif ($foundSomething) {
+                $foundSomething = $this->end();
+            }
+
+            if ($foundSomething) {
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        // closing a block
+        if ($this->matchChar('}', false)) {
+            $block = $this->popBlock();
+
+            if (! isset($block->type) || $block->type !== Type::T_IF) {
+                if ($this->env->parent) {
+                    $this->append(null); // collect comments before next statement if needed
+                }
+            }
+
+            if (isset($block->type) && $block->type === Type::T_INCLUDE) {
+                $include = $block->child;
+                unset($block->child);
+                $include[3] = $block;
+                $this->append($include, $s);
+            } elseif (empty($block->dontAppend)) {
+                $type = isset($block->type) ? $block->type : Type::T_BLOCK;
+                $this->append([$type, $block], $s);
+            }
+
+            // collect comments just after the block closing if needed
+            if ($this->eatWhiteDefault) {
+                $this->whitespace();
+
+                if ($this->env->comments) {
+                    $this->append(null);
+                }
+            }
+
+            return true;
+        }
+
+        // extra stuff
+        if (
+            $this->matchChar(';') ||
+            $this->literal('<!--', 4)
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Push block onto parse tree
+     *
+     * @param array   $selectors
+     * @param integer $pos
+     *
+     * @return \ScssPhp\ScssPhp\Block
+     */
+    protected function pushBlock($selectors, $pos = 0)
+    {
+        list($line, $column) = $this->getSourcePosition($pos);
+
+        $b = new Block();
+        $b->sourceName   = $this->sourceName;
+        $b->sourceLine   = $line;
+        $b->sourceColumn = $column;
+        $b->sourceIndex  = $this->sourceIndex;
+        $b->selectors    = $selectors;
+        $b->comments     = [];
+        $b->parent       = $this->env;
+
+        if (! $this->env) {
+            $b->children = [];
+        } elseif (empty($this->env->children)) {
+            $this->env->children = $this->env->comments;
+            $b->children = [];
+            $this->env->comments = [];
+        } else {
+            $b->children = $this->env->comments;
+            $this->env->comments = [];
+        }
+
+        $this->env = $b;
+
+        // collect comments at the beginning of a block if needed
+        if ($this->eatWhiteDefault) {
+            $this->whitespace();
+
+            if ($this->env->comments) {
+                $this->append(null);
+            }
+        }
+
+        return $b;
+    }
+
+    /**
+     * Push special (named) block onto parse tree
+     *
+     * @param string  $type
+     * @param integer $pos
+     *
+     * @return \ScssPhp\ScssPhp\Block
+     */
+    protected function pushSpecialBlock($type, $pos)
+    {
+        $block = $this->pushBlock(null, $pos);
+        $block->type = $type;
+
+        return $block;
+    }
+
+    /**
+     * Pop scope and return last block
+     *
+     * @return \ScssPhp\ScssPhp\Block
+     *
+     * @throws \Exception
+     */
+    protected function popBlock()
+    {
+
+        // collect comments ending just before of a block closing
+        if ($this->env->comments) {
+            $this->append(null);
+        }
+
+        // pop the block
+        $block = $this->env;
+
+        if (empty($block->parent)) {
+            throw $this->parseError('unexpected }');
+        }
+
+        if ($block->type == Type::T_AT_ROOT) {
+            // keeps the parent in case of self selector &
+            $block->selfParent = $block->parent;
+        }
+
+        $this->env = $block->parent;
+
+        unset($block->parent);
+
+        return $block;
+    }
+
+    /**
+     * Peek input stream
+     *
+     * @param string  $regex
+     * @param array   $out
+     * @param integer $from
+     *
+     * @return integer
+     */
+    protected function peek($regex, &$out, $from = null)
+    {
+        if (! isset($from)) {
+            $from = $this->count;
+        }
+
+        $r = '/' . $regex . '/' . $this->patternModifiers;
+        $result = preg_match($r, $this->buffer, $out, null, $from);
+
+        return $result;
+    }
+
+    /**
+     * Seek to position in input stream (or return current position in input stream)
+     *
+     * @param integer $where
+     */
+    protected function seek($where)
+    {
+        $this->count = $where;
+    }
+
+    /**
+     * Assert a parsed part is plain CSS Valid
+     *
+     * @param array $parsed
+     * @param int $startPos
+     * @throws ParserException
+     */
+    protected function assertPlainCssValid($parsed, $startPos = null)
+    {
+        $type = '';
+        if ($parsed) {
+            $type = $parsed[0];
+            $parsed = $this->isPlainCssValidElement($parsed);
+        }
+        if (! $parsed) {
+            if (! \is_null($startPos)) {
+                $plain = rtrim(substr($this->buffer, $startPos, $this->count - $startPos));
+                $message = "Error : `{$plain}` isn't allowed in plain CSS";
+            } else {
+                $message = 'Error: SCSS syntax not allowed in CSS file';
+            }
+            if ($type) {
+                $message .= " ($type)";
+            }
+            throw $this->parseError($message);
+        }
+
+        return $parsed;
+    }
+
+    /**
+     * Check a parsed element is plain CSS Valid
+     * @param array $parsed
+     * @return bool|array
+     */
+    protected function isPlainCssValidElement($parsed, $allowExpression = false)
+    {
+        // keep string as is
+        if (is_string($parsed)) {
+            return $parsed;
+        }
+
+        if (
+            \in_array($parsed[0], [Type::T_FUNCTION, Type::T_FUNCTION_CALL]) &&
+            !\in_array($parsed[1], [
+                'alpha',
+                'attr',
+                'calc',
+                'cubic-bezier',
+                'env',
+                'grayscale',
+                'hsl',
+                'hsla',
+                'invert',
+                'linear-gradient',
+                'min',
+                'max',
+                'radial-gradient',
+                'repeating-linear-gradient',
+                'repeating-radial-gradient',
+                'rgb',
+                'rgba',
+                'rotate',
+                'saturate',
+                'var',
+            ]) &&
+            Compiler::isNativeFunction($parsed[1])
+        ) {
+            return false;
+        }
+
+        switch ($parsed[0]) {
+            case Type::T_BLOCK:
+            case Type::T_KEYWORD:
+            case Type::T_NULL:
+            case Type::T_NUMBER:
+            case Type::T_MEDIA:
+                return $parsed;
+
+            case Type::T_COMMENT:
+                if (isset($parsed[2])) {
+                    return false;
+                }
+                return $parsed;
+
+            case Type::T_DIRECTIVE:
+                if (\is_array($parsed[1])) {
+                    $parsed[1][1] = $this->isPlainCssValidElement($parsed[1][1]);
+                    if (! $parsed[1][1]) {
+                        return false;
+                    }
+                }
+
+                return $parsed;
+
+            case Type::T_IMPORT:
+                if ($parsed[1][0] === Type::T_LIST) {
+                    return false;
+                }
+                $parsed[1] = $this->isPlainCssValidElement($parsed[1]);
+                if ($parsed[1] === false) {
+                    return false;
+                }
+                return $parsed;
+
+            case Type::T_STRING:
+                foreach ($parsed[2] as $k => $substr) {
+                    if (\is_array($substr)) {
+                        $parsed[2][$k] = $this->isPlainCssValidElement($substr);
+                        if (! $parsed[2][$k]) {
+                            return false;
+                        }
+                    }
+                }
+                return $parsed;
+
+            case Type::T_LIST:
+                if (!empty($parsed['enclosing'])) {
+                    return false;
+                }
+                foreach ($parsed[2] as $k => $listElement) {
+                    $parsed[2][$k] = $this->isPlainCssValidElement($listElement);
+                    if (! $parsed[2][$k]) {
+                        return false;
+                    }
+                }
+                return $parsed;
+
+            case Type::T_ASSIGN:
+                foreach ([1, 2, 3] as $k) {
+                    if (! empty($parsed[$k])) {
+                        $parsed[$k] = $this->isPlainCssValidElement($parsed[$k]);
+                        if (! $parsed[$k]) {
+                            return false;
+                        }
+                    }
+                }
+                return $parsed;
+
+            case Type::T_EXPRESSION:
+                list( ,$op, $lhs, $rhs, $inParens, $whiteBefore, $whiteAfter) = $parsed;
+                if (! $allowExpression &&  ! \in_array($op, ['and', 'or', '/'])) {
+                    return false;
+                }
+                $lhs = $this->isPlainCssValidElement($lhs, true);
+                if (! $lhs) {
+                    return false;
+                }
+                $rhs = $this->isPlainCssValidElement($rhs, true);
+                if (! $rhs) {
+                    return false;
+                }
+
+                return [
+                    Type::T_STRING,
+                    '', [
+                        $this->inParens ? '(' : '',
+                        $lhs,
+                        ($whiteBefore ? ' ' : '') . $op . ($whiteAfter ? ' ' : ''),
+                        $rhs,
+                        $this->inParens ? ')' : ''
+                    ]
+                ];
+
+            case Type::T_UNARY:
+                $parsed[2] = $this->isPlainCssValidElement($parsed[2]);
+                if (! $parsed[2]) {
+                    return false;
+                }
+                return $parsed;
+
+            case Type::T_FUNCTION:
+                $argsList = $parsed[2];
+                foreach ($argsList[2] as $argElement) {
+                    if (! $this->isPlainCssValidElement($argElement)) {
+                        return false;
+                    }
+                }
+                return $parsed;
+
+            case Type::T_FUNCTION_CALL:
+                $parsed[0] = Type::T_FUNCTION;
+                $argsList = [Type::T_LIST, ',', []];
+                foreach ($parsed[2] as $arg) {
+                    if ($arg[0] || ! empty($arg[2])) {
+                        // no named arguments possible in a css function call
+                        // nor ... argument
+                        return false;
+                    }
+                    $arg = $this->isPlainCssValidElement($arg[1], $parsed[1] === 'calc');
+                    if (! $arg) {
+                        return false;
+                    }
+                    $argsList[2][] = $arg;
+                }
+                $parsed[2] = $argsList;
+                return $parsed;
+        }
+
+        return false;
+    }
+
+    /**
+     * Match string looking for either ending delim, escape, or string interpolation
+     *
+     * {@internal This is a workaround for preg_match's 250K string match limit. }}
+     *
+     * @param array  $m     Matches (passed by reference)
+     * @param string $delim Delimiter
+     *
+     * @return boolean True if match; false otherwise
+     */
+    protected function matchString(&$m, $delim)
+    {
+        $token = null;
+
+        $end = \strlen($this->buffer);
+
+        // look for either ending delim, escape, or string interpolation
+        foreach (['#{', '\\', "\r", $delim] as $lookahead) {
+            $pos = strpos($this->buffer, $lookahead, $this->count);
+
+            if ($pos !== false && $pos < $end) {
+                $end = $pos;
+                $token = $lookahead;
+            }
+        }
+
+        if (! isset($token)) {
+            return false;
+        }
+
+        $match = substr($this->buffer, $this->count, $end - $this->count);
+        $m = [
+            $match . $token,
+            $match,
+            $token
+        ];
+        $this->count = $end + \strlen($token);
+
+        return true;
+    }
+
+    /**
+     * Try to match something on head of buffer
+     *
+     * @param string  $regex
+     * @param array   $out
+     * @param boolean $eatWhitespace
+     *
+     * @return boolean
+     */
+    protected function match($regex, &$out, $eatWhitespace = null)
+    {
+        $r = '/' . $regex . '/' . $this->patternModifiers;
+
+        if (! preg_match($r, $this->buffer, $out, null, $this->count)) {
+            return false;
+        }
+
+        $this->count += \strlen($out[0]);
+
+        if (! isset($eatWhitespace)) {
+            $eatWhitespace = $this->eatWhiteDefault;
+        }
+
+        if ($eatWhitespace) {
+            $this->whitespace();
+        }
+
+        return true;
+    }
+
+    /**
+     * Match a single string
+     *
+     * @param string  $char
+     * @param boolean $eatWhitespace
+     *
+     * @return boolean
+     */
+    protected function matchChar($char, $eatWhitespace = null)
+    {
+        if (! isset($this->buffer[$this->count]) || $this->buffer[$this->count] !== $char) {
+            return false;
+        }
+
+        $this->count++;
+
+        if (! isset($eatWhitespace)) {
+            $eatWhitespace = $this->eatWhiteDefault;
+        }
+
+        if ($eatWhitespace) {
+            $this->whitespace();
+        }
+
+        return true;
+    }
+
+    /**
+     * Match literal string
+     *
+     * @param string  $what
+     * @param integer $len
+     * @param boolean $eatWhitespace
+     *
+     * @return boolean
+     */
+    protected function literal($what, $len, $eatWhitespace = null)
+    {
+        if (strcasecmp(substr($this->buffer, $this->count, $len), $what) !== 0) {
+            return false;
+        }
+
+        $this->count += $len;
+
+        if (! isset($eatWhitespace)) {
+            $eatWhitespace = $this->eatWhiteDefault;
+        }
+
+        if ($eatWhitespace) {
+            $this->whitespace();
+        }
+
+        return true;
+    }
+
+    /**
+     * Match some whitespace
+     *
+     * @return boolean
+     */
+    protected function whitespace()
+    {
+        $gotWhite = false;
+
+        while (preg_match(static::$whitePattern, $this->buffer, $m, null, $this->count)) {
+            if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
+                // comment that are kept in the output CSS
+                $comment = [];
+                $startCommentCount = $this->count;
+                $endCommentCount = $this->count + \strlen($m[1]);
+
+                // find interpolations in comment
+                $p = strpos($this->buffer, '#{', $this->count);
+
+                while ($p !== false && $p < $endCommentCount) {
+                    $c           = substr($this->buffer, $this->count, $p - $this->count);
+                    $comment[]   = $c;
+                    $this->count = $p;
+                    $out         = null;
+
+                    if ($this->interpolation($out)) {
+                        // keep right spaces in the following string part
+                        if ($out[3]) {
+                            while ($this->buffer[$this->count - 1] !== '}') {
+                                $this->count--;
+                            }
+
+                            $out[3] = '';
+                        }
+
+                        $comment[] = [Type::T_COMMENT, substr($this->buffer, $p, $this->count - $p), $out];
+                    } else {
+                        $comment[] = substr($this->buffer, $this->count, 2);
+
+                        $this->count += 2;
+                    }
+
+                    $p = strpos($this->buffer, '#{', $this->count);
+                }
+
+                // remaining part
+                $c = substr($this->buffer, $this->count, $endCommentCount - $this->count);
+
+                if (! $comment) {
+                    // single part static comment
+                    $this->appendComment([Type::T_COMMENT, $c]);
+                } else {
+                    $comment[] = $c;
+                    $staticComment = substr($this->buffer, $startCommentCount, $endCommentCount - $startCommentCount);
+                    $this->appendComment([Type::T_COMMENT, $staticComment, [Type::T_STRING, '', $comment]]);
+                }
+
+                $this->commentsSeen[$startCommentCount] = true;
+                $this->count = $endCommentCount;
+            } else {
+                // comment that are ignored and not kept in the output css
+                $this->count += \strlen($m[0]);
+                // silent comments are not allowed in plain CSS files
+                ! $this->cssOnly
+                  || ! \strlen(trim($m[0]))
+                  || $this->assertPlainCssValid(false, $this->count - \strlen($m[0]));
+            }
+
+            $gotWhite = true;
+        }
+
+        return $gotWhite;
+    }
+
+    /**
+     * Append comment to current block
+     *
+     * @param array $comment
+     */
+    protected function appendComment($comment)
+    {
+        if (! $this->discardComments) {
+            $this->env->comments[] = $comment;
+        }
+    }
+
+    /**
+     * Append statement to current block
+     *
+     * @param array   $statement
+     * @param integer $pos
+     */
+    protected function append($statement, $pos = null)
+    {
+        if (! \is_null($statement)) {
+            ! $this->cssOnly || ($statement = $this->assertPlainCssValid($statement, $pos));
+
+            if (! \is_null($pos)) {
+                list($line, $column) = $this->getSourcePosition($pos);
+
+                $statement[static::SOURCE_LINE]   = $line;
+                $statement[static::SOURCE_COLUMN] = $column;
+                $statement[static::SOURCE_INDEX]  = $this->sourceIndex;
+            }
+
+            $this->env->children[] = $statement;
+        }
+
+        $comments = $this->env->comments;
+
+        if ($comments) {
+            $this->env->children = array_merge($this->env->children, $comments);
+            $this->env->comments = [];
+        }
+    }
+
+    /**
+     * Returns last child was appended
+     *
+     * @return array|null
+     */
+    protected function last()
+    {
+        $i = \count($this->env->children) - 1;
+
+        if (isset($this->env->children[$i])) {
+            return $this->env->children[$i];
+        }
+    }
+
+    /**
+     * Parse media query list
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function mediaQueryList(&$out)
+    {
+        return $this->genericList($out, 'mediaQuery', ',', false);
+    }
+
+    /**
+     * Parse media query
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function mediaQuery(&$out)
+    {
+        $expressions = null;
+        $parts = [];
+
+        if (
+            ($this->literal('only', 4) && ($only = true) ||
+            $this->literal('not', 3) && ($not = true) || true) &&
+            $this->mixedKeyword($mediaType)
+        ) {
+            $prop = [Type::T_MEDIA_TYPE];
+
+            if (isset($only)) {
+                $prop[] = [Type::T_KEYWORD, 'only'];
+            }
+
+            if (isset($not)) {
+                $prop[] = [Type::T_KEYWORD, 'not'];
+            }
+
+            $media = [Type::T_LIST, '', []];
+
+            foreach ((array) $mediaType as $type) {
+                if (\is_array($type)) {
+                    $media[2][] = $type;
+                } else {
+                    $media[2][] = [Type::T_KEYWORD, $type];
+                }
+            }
+
+            $prop[]  = $media;
+            $parts[] = $prop;
+        }
+
+        if (empty($parts) || $this->literal('and', 3)) {
+            $this->genericList($expressions, 'mediaExpression', 'and', false);
+
+            if (\is_array($expressions)) {
+                $parts = array_merge($parts, $expressions[2]);
+            }
+        }
+
+        $out = $parts;
+
+        return true;
+    }
+
+    /**
+     * Parse supports query
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function supportsQuery(&$out)
+    {
+        $expressions = null;
+        $parts = [];
+
+        $s = $this->count;
+
+        $not = false;
+
+        if (
+            ($this->literal('not', 3) && ($not = true) || true) &&
+            $this->matchChar('(') &&
+            ($this->expression($property)) &&
+            $this->literal(': ', 2) &&
+            $this->valueList($value) &&
+            $this->matchChar(')')
+        ) {
+            $support = [Type::T_STRING, '', [[Type::T_KEYWORD, ($not ? 'not ' : '') . '(']]];
+            $support[2][] = $property;
+            $support[2][] = [Type::T_KEYWORD, ': '];
+            $support[2][] = $value;
+            $support[2][] = [Type::T_KEYWORD, ')'];
+
+            $parts[] = $support;
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if (
+            $this->matchChar('(') &&
+            $this->supportsQuery($subQuery) &&
+            $this->matchChar(')')
+        ) {
+            $parts[] = [Type::T_STRING, '', [[Type::T_KEYWORD, '('], $subQuery, [Type::T_KEYWORD, ')']]];
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if (
+            $this->literal('not', 3) &&
+            $this->supportsQuery($subQuery)
+        ) {
+            $parts[] = [Type::T_STRING, '', [[Type::T_KEYWORD, 'not '], $subQuery]];
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if (
+            $this->literal('selector(', 9) &&
+            $this->selector($selector) &&
+            $this->matchChar(')')
+        ) {
+            $support = [Type::T_STRING, '', [[Type::T_KEYWORD, 'selector(']]];
+
+            $selectorList = [Type::T_LIST, '', []];
+
+            foreach ($selector as $sc) {
+                $compound = [Type::T_STRING, '', []];
+
+                foreach ($sc as $scp) {
+                    if (\is_array($scp)) {
+                        $compound[2][] = $scp;
+                    } else {
+                        $compound[2][] = [Type::T_KEYWORD, $scp];
+                    }
+                }
+
+                $selectorList[2][] = $compound;
+            }
+
+            $support[2][] = $selectorList;
+            $support[2][] = [Type::T_KEYWORD, ')'];
+            $parts[] = $support;
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if ($this->variable($var) or $this->interpolation($var)) {
+            $parts[] = $var;
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if (
+            $this->literal('and', 3) &&
+            $this->genericList($expressions, 'supportsQuery', ' and', false)
+        ) {
+            array_unshift($expressions[2], [Type::T_STRING, '', $parts]);
+
+            $parts = [$expressions];
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if (
+            $this->literal('or', 2) &&
+            $this->genericList($expressions, 'supportsQuery', ' or', false)
+        ) {
+            array_unshift($expressions[2], [Type::T_STRING, '', $parts]);
+
+            $parts = [$expressions];
+            $s = $this->count;
+        } else {
+            $this->seek($s);
+        }
+
+        if (\count($parts)) {
+            if ($this->eatWhiteDefault) {
+                $this->whitespace();
+            }
+
+            $out = [Type::T_STRING, '', $parts];
+
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Parse media expression
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function mediaExpression(&$out)
+    {
+        $s = $this->count;
+        $value = null;
+
+        if (
+            $this->matchChar('(') &&
+            $this->expression($feature) &&
+            ($this->matchChar(':') &&
+                $this->expression($value) || true) &&
+            $this->matchChar(')')
+        ) {
+            $out = [Type::T_MEDIA_EXPRESSION, $feature];
+
+            if ($value) {
+                $out[] = $value;
+            }
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse argument values
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function argValues(&$out)
+    {
+        $discardComments = $this->discardComments;
+        $this->discardComments = true;
+
+        if ($this->genericList($list, 'argValue', ',', false)) {
+            $out = $list[2];
+
+            $this->discardComments = $discardComments;
+
+            return true;
+        }
+
+        $this->discardComments = $discardComments;
+
+        return false;
+    }
+
+    /**
+     * Parse argument value
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function argValue(&$out)
+    {
+        $s = $this->count;
+
+        $keyword = null;
+
+        if (! $this->variable($keyword) || ! $this->matchChar(':')) {
+            $this->seek($s);
+
+            $keyword = null;
+        }
+
+        if ($this->genericList($value, 'expression', '', true)) {
+            $out = [$keyword, $value, false];
+            $s = $this->count;
+
+            if ($this->literal('...', 3)) {
+                $out[2] = true;
+            } else {
+                $this->seek($s);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if a generic directive is known to be able to allow almost any syntax or not
+     * @param $directiveName
+     * @return bool
+     */
+    protected function isKnownGenericDirective($directiveName)
+    {
+        if (\is_array($directiveName) && \is_string(reset($directiveName))) {
+            $directiveName = reset($directiveName);
+        }
+        if (! \is_string($directiveName)) {
+            return false;
+        }
+        if (
+            \in_array($directiveName, [
+            'at-root',
+            'media',
+            'mixin',
+            'include',
+            'scssphp-import-once',
+            'import',
+            'extend',
+            'function',
+            'break',
+            'continue',
+            'return',
+            'each',
+            'while',
+            'for',
+            'if',
+            'debug',
+            'warn',
+            'error',
+            'content',
+            'else',
+            'charset',
+            'supports',
+            // Todo
+            'use',
+            'forward',
+            ])
+        ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Parse directive value list that considers $vars as keyword
+     *
+     * @param array          $out
+     * @param boolean|string $endChar
+     *
+     * @return boolean
+     */
+    protected function directiveValue(&$out, $endChar = false)
+    {
+        $s = $this->count;
+
+        if ($this->variable($out)) {
+            if ($endChar && $this->matchChar($endChar, false)) {
+                return true;
+            }
+
+            if (! $endChar && $this->end()) {
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        if (\is_string($endChar) && $this->openString($endChar ? $endChar : ';', $out, null, null, true, ";}{")) {
+            if ($endChar && $this->matchChar($endChar, false)) {
+                return true;
+            }
+            $ss = $this->count;
+            if (!$endChar && $this->end()) {
+                $this->seek($ss);
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        $allowVars = $this->allowVars;
+        $this->allowVars = false;
+
+        $res = $this->genericList($out, 'spaceList', ',');
+        $this->allowVars = $allowVars;
+
+        if ($res) {
+            if ($endChar && $this->matchChar($endChar, false)) {
+                return true;
+            }
+
+            if (! $endChar && $this->end()) {
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        if ($endChar && $this->matchChar($endChar, false)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse comma separated value list
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function valueList(&$out)
+    {
+        $discardComments = $this->discardComments;
+        $this->discardComments = true;
+        $res = $this->genericList($out, 'spaceList', ',');
+        $this->discardComments = $discardComments;
+
+        return $res;
+    }
+
+    /**
+     * Parse a function call, where externals () are part of the call
+     * and not of the value list
+     *
+     * @param $out
+     * @param bool $mandatoryEnclos
+     * @param null|string $charAfter
+     * @param null|bool $eatWhiteSp
+     * @return bool
+     */
+    protected function functionCallArgumentsList(&$out, $mandatoryEnclos = true, $charAfter = null, $eatWhiteSp = null)
+    {
+        $s = $this->count;
+
+        if (
+            $this->matchChar('(') &&
+            $this->valueList($out) &&
+            $this->matchChar(')') &&
+            ($charAfter ? $this->matchChar($charAfter, $eatWhiteSp) : $this->end())
+        ) {
+            return true;
+        }
+
+        if (! $mandatoryEnclos) {
+            $this->seek($s);
+
+            if (
+                $this->valueList($out) &&
+                ($charAfter ? $this->matchChar($charAfter, $eatWhiteSp) : $this->end())
+            ) {
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse space separated value list
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function spaceList(&$out)
+    {
+        return $this->genericList($out, 'expression');
+    }
+
+    /**
+     * Parse generic list
+     *
+     * @param array    $out
+     * @param callable $parseItem
+     * @param string   $delim
+     * @param boolean  $flatten
+     *
+     * @return boolean
+     */
+    protected function genericList(&$out, $parseItem, $delim = '', $flatten = true)
+    {
+        $s     = $this->count;
+        $items = [];
+        $value = null;
+
+        while ($this->$parseItem($value)) {
+            $trailing_delim = false;
+            $items[] = $value;
+
+            if ($delim) {
+                if (! $this->literal($delim, \strlen($delim))) {
+                    break;
+                }
+
+                $trailing_delim = true;
+            } else {
+                // if no delim watch that a keyword didn't eat the single/double quote
+                // from the following starting string
+                if ($value[0] === Type::T_KEYWORD) {
+                    $word = $value[1];
+
+                    $last_char = substr($word, -1);
+
+                    if (
+                        strlen($word) > 1 &&
+                        in_array($last_char, [ "'", '"']) &&
+                        substr($word, -2, 1) !== '\\'
+                    ) {
+                        // if there is a non escaped opening quote in the keyword, this seems unlikely a mistake
+                        $word = str_replace('\\' . $last_char, '\\\\', $word);
+                        if (strpos($word, $last_char) < strlen($word) - 1) {
+                            continue;
+                        }
+
+                        $currentCount = $this->count;
+
+                        // let's try to rewind to previous char and try a parse
+                        $this->count--;
+                        // in case the keyword also eat spaces
+                        while (substr($this->buffer, $this->count, 1) !== $last_char) {
+                            $this->count--;
+                        }
+
+                        $nextValue = null;
+                        if ($this->$parseItem($nextValue)) {
+                            if ($nextValue[0] === Type::T_KEYWORD && $nextValue[1] === $last_char) {
+                                // bad try, forget it
+                                $this->seek($currentCount);
+                                continue;
+                            }
+                            if ($nextValue[0] !== Type::T_STRING) {
+                                // bad try, forget it
+                                $this->seek($currentCount);
+                                continue;
+                            }
+
+                            // OK it was a good idea
+                            $value[1] = substr($value[1], 0, -1);
+                            array_pop($items);
+                            $items[] = $value;
+                            $items[] = $nextValue;
+                        } else {
+                            // bad try, forget it
+                            $this->seek($currentCount);
+                            continue;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (! $items) {
+            $this->seek($s);
+
+            return false;
+        }
+
+        if ($trailing_delim) {
+            $items[] = [Type::T_NULL];
+        }
+
+        if ($flatten && \count($items) === 1) {
+            $out = $items[0];
+        } else {
+            $out = [Type::T_LIST, $delim, $items];
+        }
+
+        return true;
+    }
+
+    /**
+     * Parse expression
+     *
+     * @param array   $out
+     * @param boolean $listOnly
+     * @param boolean $lookForExp
+     *
+     * @return boolean
+     */
+    protected function expression(&$out, $listOnly = false, $lookForExp = true)
+    {
+        $s = $this->count;
+        $discard = $this->discardComments;
+        $this->discardComments = true;
+        $allowedTypes = ($listOnly ? [Type::T_LIST] : [Type::T_LIST, Type::T_MAP]);
+
+        if ($this->matchChar('(')) {
+            if ($this->enclosedExpression($lhs, $s, ')', $allowedTypes)) {
+                if ($lookForExp) {
+                    $out = $this->expHelper($lhs, 0);
+                } else {
+                    $out = $lhs;
+                }
+
+                $this->discardComments = $discard;
+
+                return true;
+            }
+
+            $this->seek($s);
+        }
+
+        if (\in_array(Type::T_LIST, $allowedTypes) && $this->matchChar('[')) {
+            if ($this->enclosedExpression($lhs, $s, ']', [Type::T_LIST])) {
+                if ($lookForExp) {
+                    $out = $this->expHelper($lhs, 0);
+                } else {
+                    $out = $lhs;
+                }
+
+                $this->discardComments = $discard;
+
+                return true;
+            }
+
+            $this->seek($s);
+        }
+
+        if (! $listOnly && $this->value($lhs)) {
+            if ($lookForExp) {
+                $out = $this->expHelper($lhs, 0);
+            } else {
+                $out = $lhs;
+            }
+
+            $this->discardComments = $discard;
+
+            return true;
+        }
+
+        $this->discardComments = $discard;
+
+        return false;
+    }
+
+    /**
+     * Parse expression specifically checking for lists in parenthesis or brackets
+     *
+     * @param array   $out
+     * @param integer $s
+     * @param string  $closingParen
+     * @param array   $allowedTypes
+     *
+     * @return boolean
+     */
+    protected function enclosedExpression(&$out, $s, $closingParen = ')', $allowedTypes = [Type::T_LIST, Type::T_MAP])
+    {
+        if ($this->matchChar($closingParen) && \in_array(Type::T_LIST, $allowedTypes)) {
+            $out = [Type::T_LIST, '', []];
+
+            switch ($closingParen) {
+                case ')':
+                    $out['enclosing'] = 'parent'; // parenthesis list
+                    break;
+
+                case ']':
+                    $out['enclosing'] = 'bracket'; // bracketed list
+                    break;
+            }
+
+            return true;
+        }
+
+        if (
+            $this->valueList($out) &&
+            $this->matchChar($closingParen) && ! ($closingParen === ')' &&
+            \in_array($out[0], [Type::T_EXPRESSION, Type::T_UNARY])) &&
+            \in_array(Type::T_LIST, $allowedTypes)
+        ) {
+            if ($out[0] !== Type::T_LIST || ! empty($out['enclosing'])) {
+                $out = [Type::T_LIST, '', [$out]];
+            }
+
+            switch ($closingParen) {
+                case ')':
+                    $out['enclosing'] = 'parent'; // parenthesis list
+                    break;
+
+                case ']':
+                    $out['enclosing'] = 'bracket'; // bracketed list
+                    break;
+            }
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        if (\in_array(Type::T_MAP, $allowedTypes) && $this->map($out)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse left-hand side of subexpression
+     *
+     * @param array   $lhs
+     * @param integer $minP
+     *
+     * @return array
+     */
+    protected function expHelper($lhs, $minP)
+    {
+        $operators = static::$operatorPattern;
+
+        $ss = $this->count;
+        $whiteBefore = isset($this->buffer[$this->count - 1]) &&
+            ctype_space($this->buffer[$this->count - 1]);
+
+        while ($this->match($operators, $m, false) && static::$precedence[$m[1]] >= $minP) {
+            $whiteAfter = isset($this->buffer[$this->count]) &&
+                ctype_space($this->buffer[$this->count]);
+            $varAfter = isset($this->buffer[$this->count]) &&
+                $this->buffer[$this->count] === '$';
+
+            $this->whitespace();
+
+            $op = $m[1];
+
+            // don't turn negative numbers into expressions
+            if ($op === '-' && $whiteBefore && ! $whiteAfter && ! $varAfter) {
+                break;
+            }
+
+            if (! $this->value($rhs) && ! $this->expression($rhs, true, false)) {
+                break;
+            }
+
+            if ($op === '-' && ! $whiteAfter && $rhs[0] === Type::T_KEYWORD) {
+                break;
+            }
+
+            // peek and see if rhs belongs to next operator
+            if ($this->peek($operators, $next) && static::$precedence[$next[1]] > static::$precedence[$op]) {
+                $rhs = $this->expHelper($rhs, static::$precedence[$next[1]]);
+            }
+
+            $lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter];
+
+            $ss = $this->count;
+            $whiteBefore = isset($this->buffer[$this->count - 1]) &&
+                ctype_space($this->buffer[$this->count - 1]);
+        }
+
+        $this->seek($ss);
+
+        return $lhs;
+    }
+
+    /**
+     * Parse value
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function value(&$out)
+    {
+        if (! isset($this->buffer[$this->count])) {
+            return false;
+        }
+
+        $s = $this->count;
+        $char = $this->buffer[$this->count];
+
+        if (
+            $this->literal('url(', 4) &&
+            $this->match('data:([a-z]+)\/([a-z0-9.+-]+);base64,', $m, false)
+        ) {
+            $len = strspn(
+                $this->buffer,
+                'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwyxz0123456789+/=',
+                $this->count
+            );
+
+            $this->count += $len;
+
+            if ($this->matchChar(')')) {
+                $content = substr($this->buffer, $s, $this->count - $s);
+                $out = [Type::T_KEYWORD, $content];
+
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        if (
+            $this->literal('url(', 4, false) &&
+            $this->match('\s*(\/\/[^\s\)]+)\s*', $m)
+        ) {
+            $content = 'url(' . $m[1];
+
+            if ($this->matchChar(')')) {
+                $content .= ')';
+                $out = [Type::T_KEYWORD, $content];
+
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        // not
+        if ($char === 'n' && $this->literal('not', 3, false)) {
+            if (
+                $this->whitespace() &&
+                $this->value($inner)
+            ) {
+                $out = [Type::T_UNARY, 'not', $inner, $this->inParens];
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if ($this->parenValue($inner)) {
+                $out = [Type::T_UNARY, 'not', $inner, $this->inParens];
+
+                return true;
+            }
+
+            $this->seek($s);
+        }
+
+        // addition
+        if ($char === '+') {
+            $this->count++;
+
+            $follow_white = $this->whitespace();
+
+            if ($this->value($inner)) {
+                $out = [Type::T_UNARY, '+', $inner, $this->inParens];
+
+                return true;
+            }
+
+            if ($follow_white) {
+                $out = [Type::T_KEYWORD, $char];
+                return  true;
+            }
+
+            $this->seek($s);
+
+            return false;
+        }
+
+        // negation
+        if ($char === '-') {
+            if ($this->customProperty($out)) {
+                return true;
+            }
+
+            $this->count++;
+
+            $follow_white = $this->whitespace();
+
+            if ($this->variable($inner) || $this->unit($inner) || $this->parenValue($inner)) {
+                $out = [Type::T_UNARY, '-', $inner, $this->inParens];
+
+                return true;
+            }
+
+            if (
+                $this->keyword($inner) &&
+                ! $this->func($inner, $out)
+            ) {
+                $out = [Type::T_UNARY, '-', $inner, $this->inParens];
+
+                return true;
+            }
+
+            if ($follow_white) {
+                $out = [Type::T_KEYWORD, $char];
+
+                return  true;
+            }
+
+            $this->seek($s);
+        }
+
+        // paren
+        if ($char === '(' && $this->parenValue($out)) {
+            return true;
+        }
+
+        if ($char === '#') {
+            if ($this->interpolation($out) || $this->color($out)) {
+                return true;
+            }
+
+            $this->count++;
+
+            if ($this->keyword($keyword)) {
+                $out = [Type::T_KEYWORD, '#' . $keyword];
+
+                return true;
+            }
+
+            $this->count--;
+        }
+
+        if ($this->matchChar('&', true)) {
+            $out = [Type::T_SELF];
+
+            return true;
+        }
+
+        if ($char === '$' && $this->variable($out)) {
+            return true;
+        }
+
+        if ($char === 'p' && $this->progid($out)) {
+            return true;
+        }
+
+        if (($char === '"' || $char === "'") && $this->string($out)) {
+            return true;
+        }
+
+        if ($this->unit($out)) {
+            return true;
+        }
+
+        // unicode range with wildcards
+        if (
+            $this->literal('U+', 2) &&
+            $this->match('\?+|([0-9A-F]+(\?+|(-[0-9A-F]+))?)', $m, false)
+        ) {
+            $unicode = explode('-', $m[0]);
+            if (strlen(reset($unicode)) <= 6 && strlen(end($unicode)) <= 6) {
+                $out = [Type::T_KEYWORD, 'U+' . $m[0]];
+
+                return true;
+            }
+            $this->count -= strlen($m[0]) + 2;
+        }
+
+        if ($this->keyword($keyword, false)) {
+            if ($this->func($keyword, $out)) {
+                return true;
+            }
+
+            $this->whitespace();
+
+            if ($keyword === 'null') {
+                $out = [Type::T_NULL];
+            } else {
+                $out = [Type::T_KEYWORD, $keyword];
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse parenthesized value
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function parenValue(&$out)
+    {
+        $s = $this->count;
+
+        $inParens = $this->inParens;
+
+        if ($this->matchChar('(')) {
+            if ($this->matchChar(')')) {
+                $out = [Type::T_LIST, '', []];
+
+                return true;
+            }
+
+            $this->inParens = true;
+
+            if (
+                $this->expression($exp) &&
+                $this->matchChar(')')
+            ) {
+                $out = $exp;
+                $this->inParens = $inParens;
+
+                return true;
+            }
+        }
+
+        $this->inParens = $inParens;
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse "progid:"
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function progid(&$out)
+    {
+        $s = $this->count;
+
+        if (
+            $this->literal('progid:', 7, false) &&
+            $this->openString('(', $fn) &&
+            $this->matchChar('(')
+        ) {
+            $this->openString(')', $args, '(');
+
+            if ($this->matchChar(')')) {
+                $out = [Type::T_STRING, '', [
+                    'progid:', $fn, '(', $args, ')'
+                ]];
+
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse function call
+     *
+     * @param string $name
+     * @param array  $func
+     *
+     * @return boolean
+     */
+    protected function func($name, &$func)
+    {
+        $s = $this->count;
+
+        if ($this->matchChar('(')) {
+            if ($name === 'alpha' && $this->argumentList($args)) {
+                $func = [Type::T_FUNCTION, $name, [Type::T_STRING, '', $args]];
+
+                return true;
+            }
+
+            if ($name !== 'expression' && ! preg_match('/^(-[a-z]+-)?calc$/', $name)) {
+                $ss = $this->count;
+
+                if (
+                    $this->argValues($args) &&
+                    $this->matchChar(')')
+                ) {
+                    $func = [Type::T_FUNCTION_CALL, $name, $args];
+
+                    return true;
+                }
+
+                $this->seek($ss);
+            }
+
+            if (
+                ($this->openString(')', $str, '(') || true) &&
+                $this->matchChar(')')
+            ) {
+                $args = [];
+
+                if (! empty($str)) {
+                    $args[] = [null, [Type::T_STRING, '', [$str]]];
+                }
+
+                $func = [Type::T_FUNCTION_CALL, $name, $args];
+
+                return true;
+            }
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse function call argument list
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function argumentList(&$out)
+    {
+        $s = $this->count;
+        $this->matchChar('(');
+
+        $args = [];
+
+        while ($this->keyword($var)) {
+            if (
+                $this->matchChar('=') &&
+                $this->expression($exp)
+            ) {
+                $args[] = [Type::T_STRING, '', [$var . '=']];
+                $arg = $exp;
+            } else {
+                break;
+            }
+
+            $args[] = $arg;
+
+            if (! $this->matchChar(',')) {
+                break;
+            }
+
+            $args[] = [Type::T_STRING, '', [', ']];
+        }
+
+        if (! $this->matchChar(')') || ! $args) {
+            $this->seek($s);
+
+            return false;
+        }
+
+        $out = $args;
+
+        return true;
+    }
+
+    /**
+     * Parse mixin/function definition  argument list
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function argumentDef(&$out)
+    {
+        $s = $this->count;
+        $this->matchChar('(');
+
+        $args = [];
+
+        while ($this->variable($var)) {
+            $arg = [$var[1], null, false];
+
+            $ss = $this->count;
+
+            if (
+                $this->matchChar(':') &&
+                $this->genericList($defaultVal, 'expression', '', true)
+            ) {
+                $arg[1] = $defaultVal;
+            } else {
+                $this->seek($ss);
+            }
+
+            $ss = $this->count;
+
+            if ($this->literal('...', 3)) {
+                $sss = $this->count;
+
+                if (! $this->matchChar(')')) {
+                    throw $this->parseError('... has to be after the final argument');
+                }
+
+                $arg[2] = true;
+
+                $this->seek($sss);
+            } else {
+                $this->seek($ss);
+            }
+
+            $args[] = $arg;
+
+            if (! $this->matchChar(',')) {
+                break;
+            }
+        }
+
+        if (! $this->matchChar(')')) {
+            $this->seek($s);
+
+            return false;
+        }
+
+        $out = $args;
+
+        return true;
+    }
+
+    /**
+     * Parse map
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function map(&$out)
+    {
+        $s = $this->count;
+
+        if (! $this->matchChar('(')) {
+            return false;
+        }
+
+        $keys = [];
+        $values = [];
+
+        while (
+            $this->genericList($key, 'expression', '', true) &&
+            $this->matchChar(':') &&
+            $this->genericList($value, 'expression', '', true)
+        ) {
+            $keys[] = $key;
+            $values[] = $value;
+
+            if (! $this->matchChar(',')) {
+                break;
+            }
+        }
+
+        if (! $keys || ! $this->matchChar(')')) {
+            $this->seek($s);
+
+            return false;
+        }
+
+        $out = [Type::T_MAP, $keys, $values];
+
+        return true;
+    }
+
+    /**
+     * Parse color
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function color(&$out)
+    {
+        $s = $this->count;
+
+        if ($this->match('(#([0-9a-f]+)\b)', $m)) {
+            if (\in_array(\strlen($m[2]), [3,4,6,8])) {
+                $out = [Type::T_KEYWORD, $m[0]];
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse number with unit
+     *
+     * @param array $unit
+     *
+     * @return boolean
+     */
+    protected function unit(&$unit)
+    {
+        $s = $this->count;
+
+        if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m, false)) {
+            if (\strlen($this->buffer) === $this->count || ! ctype_digit($this->buffer[$this->count])) {
+                $this->whitespace();
+
+                $unit = new Node\Number($m[1], empty($m[3]) ? '' : $m[3]);
+
+                return true;
+            }
+
+            $this->seek($s);
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse string
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function string(&$out, $keepDelimWithInterpolation = false)
+    {
+        $s = $this->count;
+
+        if ($this->matchChar('"', false)) {
+            $delim = '"';
+        } elseif ($this->matchChar("'", false)) {
+            $delim = "'";
+        } else {
+            return false;
+        }
+
+        $content = [];
+        $oldWhite = $this->eatWhiteDefault;
+        $this->eatWhiteDefault = false;
+        $hasInterpolation = false;
+
+        while ($this->matchString($m, $delim)) {
+            if ($m[1] !== '') {
+                $content[] = $m[1];
+            }
+
+            if ($m[2] === '#{') {
+                $this->count -= \strlen($m[2]);
+
+                if ($this->interpolation($inter, false)) {
+                    $content[] = $inter;
+                    $hasInterpolation = true;
+                } else {
+                    $this->count += \strlen($m[2]);
+                    $content[] = '#{'; // ignore it
+                }
+            } elseif ($m[2] === "\r") {
+                $content[] = chr(10);
+                // TODO : warning
+                # DEPRECATION WARNING on line x, column y of zzz:
+                # Unescaped multiline strings are deprecated and will be removed in a future version of Sass.
+                # To include a newline in a string, use "\a" or "\a " as in CSS.
+                if ($this->matchChar("\n", false)) {
+                    $content[] = ' ';
+                }
+            } elseif ($m[2] === '\\') {
+                if (
+                    $this->literal("\r\n", 2, false) ||
+                    $this->matchChar("\r", false) ||
+                    $this->matchChar("\n", false) ||
+                    $this->matchChar("\f", false)
+                ) {
+                    // this is a continuation escaping, to be ignored
+                } elseif ($this->matchEscapeCharacter($c)) {
+                    $content[] = $c;
+                } else {
+                    throw $this->parseError('Unterminated escape sequence');
+                }
+            } else {
+                $this->count -= \strlen($delim);
+                break; // delim
+            }
+        }
+
+        $this->eatWhiteDefault = $oldWhite;
+
+        if ($this->literal($delim, \strlen($delim))) {
+            if ($hasInterpolation && ! $keepDelimWithInterpolation) {
+                $delim = '"';
+            }
+
+            $out = [Type::T_STRING, $delim, $content];
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    protected function matchEscapeCharacter(&$out, $inKeywords = false)
+    {
+        $s = $this->count;
+        if ($this->match('[a-f0-9]', $m, false)) {
+            $hex = $m[0];
+
+            for ($i = 5; $i--;) {
+                if ($this->match('[a-f0-9]', $m, false)) {
+                    $hex .= $m[0];
+                } else {
+                    break;
+                }
+            }
+
+            $value = hexdec($hex);
+
+            if (!$inKeywords && ($value == 0 || ($value >= 0xD800 && $value <= 0xDFFF) || $value >= 0x10FFFF)) {
+                $out = "\xEF\xBF\xBD"; // "\u{FFFD}" but with a syntax supported on PHP 5
+            } elseif ($value < 0x20) {
+                $out = Util::mbChr($value);
+            } else {
+                $out = Util::mbChr($value);
+            }
+
+            return true;
+        }
+
+        if ($this->match('.', $m, false)) {
+            if ($inKeywords && in_array($m[0], ["'",'"','@','&',' ','\\',':','/','%'])) {
+                $this->seek($s);
+                return false;
+            }
+            $out = $m[0];
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse keyword or interpolation
+     *
+     * @param array   $out
+     * @param boolean $restricted
+     *
+     * @return boolean
+     */
+    protected function mixedKeyword(&$out, $restricted = false)
+    {
+        $parts = [];
+
+        $oldWhite = $this->eatWhiteDefault;
+        $this->eatWhiteDefault = false;
+
+        for (;;) {
+            if ($restricted ? $this->restrictedKeyword($key) : $this->keyword($key)) {
+                $parts[] = $key;
+                continue;
+            }
+
+            if ($this->interpolation($inter)) {
+                $parts[] = $inter;
+                continue;
+            }
+
+            break;
+        }
+
+        $this->eatWhiteDefault = $oldWhite;
+
+        if (! $parts) {
+            return false;
+        }
+
+        if ($this->eatWhiteDefault) {
+            $this->whitespace();
+        }
+
+        $out = $parts;
+
+        return true;
+    }
+
+    /**
+     * Parse an unbounded string stopped by $end
+     *
+     * @param string  $end
+     * @param array   $out
+     * @param string  $nestOpen
+     * @param string  $nestClose
+     * @param boolean $rtrim
+     * @param string $disallow
+     *
+     * @return boolean
+     */
+    protected function openString($end, &$out, $nestOpen = null, $nestClose = null, $rtrim = true, $disallow = null)
+    {
+        $oldWhite = $this->eatWhiteDefault;
+        $this->eatWhiteDefault = false;
+
+        if ($nestOpen && ! $nestClose) {
+            $nestClose = $end;
+        }
+
+        $patt = ($disallow ? '[^' . $this->pregQuote($disallow) . ']' : '.');
+        $patt = '(' . $patt . '*?)([\'"]|#\{|'
+            . $this->pregQuote($end) . '|'
+            . (($nestClose && $nestClose !== $end) ? $this->pregQuote($nestClose) . '|' : '')
+            . static::$commentPattern . ')';
+
+        $nestingLevel = 0;
+
+        $content = [];
+
+        while ($this->match($patt, $m, false)) {
+            if (isset($m[1]) && $m[1] !== '') {
+                $content[] = $m[1];
+
+                if ($nestOpen) {
+                    $nestingLevel += substr_count($m[1], $nestOpen);
+                }
+            }
+
+            $tok = $m[2];
+
+            $this->count -= \strlen($tok);
+
+            if ($tok === $end && ! $nestingLevel) {
+                break;
+            }
+
+            if ($tok === $nestClose) {
+                $nestingLevel--;
+            }
+
+            if (($tok === "'" || $tok === '"') && $this->string($str, true)) {
+                $content[] = $str;
+                continue;
+            }
+
+            if ($tok === '#{' && $this->interpolation($inter)) {
+                $content[] = $inter;
+                continue;
+            }
+
+            $content[] = $tok;
+            $this->count += \strlen($tok);
+        }
+
+        $this->eatWhiteDefault = $oldWhite;
+
+        if (! $content || $tok !== $end) {
+            return false;
+        }
+
+        // trim the end
+        if ($rtrim && \is_string(end($content))) {
+            $content[\count($content) - 1] = rtrim(end($content));
+        }
+
+        $out = [Type::T_STRING, '', $content];
+
+        return true;
+    }
+
+    /**
+     * Parser interpolation
+     *
+     * @param string|array $out
+     * @param boolean      $lookWhite save information about whitespace before and after
+     *
+     * @return boolean
+     */
+    protected function interpolation(&$out, $lookWhite = true)
+    {
+        $oldWhite = $this->eatWhiteDefault;
+        $allowVars = $this->allowVars;
+        $this->allowVars = true;
+        $this->eatWhiteDefault = true;
+
+        $s = $this->count;
+
+        if (
+            $this->literal('#{', 2) &&
+            $this->valueList($value) &&
+            $this->matchChar('}', false)
+        ) {
+            if ($value === [Type::T_SELF]) {
+                $out = $value;
+            } else {
+                if ($lookWhite) {
+                    $left = ($s > 0 && preg_match('/\s/', $this->buffer[$s - 1])) ? ' ' : '';
+                    $right = (
+                        ! empty($this->buffer[$this->count]) &&
+                        preg_match('/\s/', $this->buffer[$this->count])
+                    ) ? ' ' : '';
+                } else {
+                    $left = $right = false;
+                }
+
+                $out = [Type::T_INTERPOLATE, $value, $left, $right];
+            }
+
+            $this->eatWhiteDefault = $oldWhite;
+            $this->allowVars = $allowVars;
+
+            if ($this->eatWhiteDefault) {
+                $this->whitespace();
+            }
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        $this->eatWhiteDefault = $oldWhite;
+        $this->allowVars = $allowVars;
+
+        return false;
+    }
+
+    /**
+     * Parse property name (as an array of parts or a string)
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function propertyName(&$out)
+    {
+        $parts = [];
+
+        $oldWhite = $this->eatWhiteDefault;
+        $this->eatWhiteDefault = false;
+
+        for (;;) {
+            if ($this->interpolation($inter)) {
+                $parts[] = $inter;
+                continue;
+            }
+
+            if ($this->keyword($text)) {
+                $parts[] = $text;
+                continue;
+            }
+
+            if (! $parts && $this->match('[:.#]', $m, false)) {
+                // css hacks
+                $parts[] = $m[0];
+                continue;
+            }
+
+            break;
+        }
+
+        $this->eatWhiteDefault = $oldWhite;
+
+        if (! $parts) {
+            return false;
+        }
+
+        // match comment hack
+        if (preg_match(static::$whitePattern, $this->buffer, $m, null, $this->count)) {
+            if (! empty($m[0])) {
+                $parts[] = $m[0];
+                $this->count += \strlen($m[0]);
+            }
+        }
+
+        $this->whitespace(); // get any extra whitespace
+
+        $out = [Type::T_STRING, '', $parts];
+
+        return true;
+    }
+
+    /**
+     * Parse custom property name (as an array of parts or a string)
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function customProperty(&$out)
+    {
+        $s = $this->count;
+
+        if (! $this->literal('--', 2, false)) {
+            return false;
+        }
+
+        $parts = ['--'];
+
+        $oldWhite = $this->eatWhiteDefault;
+        $this->eatWhiteDefault = false;
+
+        for (;;) {
+            if ($this->interpolation($inter)) {
+                $parts[] = $inter;
+                continue;
+            }
+
+            if ($this->matchChar('&', false)) {
+                $parts[] = [Type::T_SELF];
+                continue;
+            }
+
+            if ($this->variable($var)) {
+                $parts[] = $var;
+                continue;
+            }
+
+            if ($this->keyword($text)) {
+                $parts[] = $text;
+                continue;
+            }
+
+            break;
+        }
+
+        $this->eatWhiteDefault = $oldWhite;
+
+        if (\count($parts) == 1) {
+            $this->seek($s);
+
+            return false;
+        }
+
+        $this->whitespace(); // get any extra whitespace
+
+        $out = [Type::T_STRING, '', $parts];
+
+        return true;
+    }
+
+    /**
+     * Parse comma separated selector list
+     *
+     * @param array   $out
+     * @param boolean $subSelector
+     *
+     * @return boolean
+     */
+    protected function selectors(&$out, $subSelector = false)
+    {
+        $s = $this->count;
+        $selectors = [];
+
+        while ($this->selector($sel, $subSelector)) {
+            $selectors[] = $sel;
+
+            if (! $this->matchChar(',', true)) {
+                break;
+            }
+
+            while ($this->matchChar(',', true)) {
+                ; // ignore extra
+            }
+        }
+
+        if (! $selectors) {
+            $this->seek($s);
+
+            return false;
+        }
+
+        $out = $selectors;
+
+        return true;
+    }
+
+    /**
+     * Parse whitespace separated selector list
+     *
+     * @param array   $out
+     * @param boolean $subSelector
+     *
+     * @return boolean
+     */
+    protected function selector(&$out, $subSelector = false)
+    {
+        $selector = [];
+
+        $discardComments = $this->discardComments;
+        $this->discardComments = true;
+
+        for (;;) {
+            $s = $this->count;
+
+            if ($this->match('[>+~]+', $m, true)) {
+                if (
+                    $subSelector && \is_string($subSelector) && strpos($subSelector, 'nth-') === 0 &&
+                    $m[0] === '+' && $this->match("(\d+|n\b)", $counter)
+                ) {
+                    $this->seek($s);
+                } else {
+                    $selector[] = [$m[0]];
+                    continue;
+                }
+            }
+
+            if ($this->selectorSingle($part, $subSelector)) {
+                $selector[] = $part;
+                $this->whitespace();
+                continue;
+            }
+
+            break;
+        }
+
+        $this->discardComments = $discardComments;
+
+        if (! $selector) {
+            return false;
+        }
+
+        $out = $selector;
+
+        return true;
+    }
+
+    /**
+     * Parse the parts that make up a selector
+     *
+     * {@internal
+     *     div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder
+     * }}
+     *
+     * @param array   $out
+     * @param boolean $subSelector
+     *
+     * @return boolean
+     */
+    protected function selectorSingle(&$out, $subSelector = false)
+    {
+        $oldWhite = $this->eatWhiteDefault;
+        $this->eatWhiteDefault = false;
+
+        $parts = [];
+
+        if ($this->matchChar('*', false)) {
+            $parts[] = '*';
+        }
+
+        for (;;) {
+            if (! isset($this->buffer[$this->count])) {
+                break;
+            }
+
+            $s = $this->count;
+            $char = $this->buffer[$this->count];
+
+            // see if we can stop early
+            if ($char === '{' || $char === ',' || $char === ';' || $char === '}' || $char === '@') {
+                break;
+            }
+
+            // parsing a sub selector in () stop with the closing )
+            if ($subSelector && $char === ')') {
+                break;
+            }
+
+            //self
+            switch ($char) {
+                case '&':
+                    $parts[] = Compiler::$selfSelector;
+                    $this->count++;
+                    ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+                    continue 2;
+
+                case '.':
+                    $parts[] = '.';
+                    $this->count++;
+                    continue 2;
+
+                case '|':
+                    $parts[] = '|';
+                    $this->count++;
+                    continue 2;
+            }
+
+            if ($char === '\\' && $this->match('\\\\\S', $m)) {
+                $parts[] = $m[0];
+                continue;
+            }
+
+            if ($char === '%') {
+                $this->count++;
+
+                if ($this->placeholder($placeholder)) {
+                    $parts[] = '%';
+                    $parts[] = $placeholder;
+                    ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+                    continue;
+                }
+
+                break;
+            }
+
+            if ($char === '#') {
+                if ($this->interpolation($inter)) {
+                    $parts[] = $inter;
+                    ! $this->cssOnly || $this->assertPlainCssValid(false, $s);
+                    continue;
+                }
+
+                $parts[] = '#';
+                $this->count++;
+                continue;
+            }
+
+            // a pseudo selector
+            if ($char === ':') {
+                if ($this->buffer[$this->count + 1] === ':') {
+                    $this->count += 2;
+                    $part = '::';
+                } else {
+                    $this->count++;
+                    $part = ':';
+                }
+
+                if ($this->mixedKeyword($nameParts, true)) {
+                    $parts[] = $part;
+
+                    foreach ($nameParts as $sub) {
+                        $parts[] = $sub;
+                    }
+
+                    $ss = $this->count;
+
+                    if (
+                        $nameParts === ['not'] ||
+                        $nameParts === ['is'] ||
+                        $nameParts === ['has'] ||
+                        $nameParts === ['where'] ||
+                        $nameParts === ['slotted'] ||
+                        $nameParts === ['nth-child'] ||
+                        $nameParts === ['nth-last-child'] ||
+                        $nameParts === ['nth-of-type'] ||
+                        $nameParts === ['nth-last-of-type']
+                    ) {
+                        if (
+                            $this->matchChar('(', true) &&
+                            ($this->selectors($subs, reset($nameParts)) || true) &&
+                            $this->matchChar(')')
+                        ) {
+                            $parts[] = '(';
+
+                            while ($sub = array_shift($subs)) {
+                                while ($ps = array_shift($sub)) {
+                                    foreach ($ps as &$p) {
+                                        $parts[] = $p;
+                                    }
+
+                                    if (\count($sub) && reset($sub)) {
+                                        $parts[] = ' ';
+                                    }
+                                }
+
+                                if (\count($subs) && reset($subs)) {
+                                    $parts[] = ', ';
+                                }
+                            }
+
+                            $parts[] = ')';
+                        } else {
+                            $this->seek($ss);
+                        }
+                    } elseif (
+                        $this->matchChar('(', true) &&
+                        ($this->openString(')', $str, '(') || true) &&
+                        $this->matchChar(')')
+                    ) {
+                        $parts[] = '(';
+
+                        if (! empty($str)) {
+                            $parts[] = $str;
+                        }
+
+                        $parts[] = ')';
+                    } else {
+                        $this->seek($ss);
+                    }
+
+                    continue;
+                }
+            }
+
+            $this->seek($s);
+
+            // 2n+1
+            if ($subSelector && \is_string($subSelector) && strpos($subSelector, 'nth-') === 0) {
+                if ($this->match("(\s*(\+\s*|\-\s*)?(\d+|n|\d+n))+", $counter)) {
+                    $parts[] = $counter[0];
+                    //$parts[] = str_replace(' ', '', $counter[0]);
+                    continue;
+                }
+            }
+
+            $this->seek($s);
+
+            // attribute selector
+            if (
+                $char === '[' &&
+                $this->matchChar('[') &&
+                ($this->openString(']', $str, '[') || true) &&
+                $this->matchChar(']')
+            ) {
+                $parts[] = '[';
+
+                if (! empty($str)) {
+                    $parts[] = $str;
+                }
+
+                $parts[] = ']';
+                continue;
+            }
+
+            $this->seek($s);
+
+            // for keyframes
+            if ($this->unit($unit)) {
+                $parts[] = $unit;
+                continue;
+            }
+
+            if ($this->restrictedKeyword($name)) {
+                $parts[] = $name;
+                continue;
+            }
+
+            break;
+        }
+
+        $this->eatWhiteDefault = $oldWhite;
+
+        if (! $parts) {
+            return false;
+        }
+
+        $out = $parts;
+
+        return true;
+    }
+
+    /**
+     * Parse a variable
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function variable(&$out)
+    {
+        $s = $this->count;
+
+        if (
+            $this->matchChar('$', false) &&
+            $this->keyword($name)
+        ) {
+            if ($this->allowVars) {
+                $out = [Type::T_VARIABLE, $name];
+            } else {
+                $out = [Type::T_KEYWORD, '$' . $name];
+            }
+
+            return true;
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse a keyword
+     *
+     * @param string  $word
+     * @param boolean $eatWhitespace
+     *
+     * @return boolean
+     */
+    protected function keyword(&$word, $eatWhitespace = null)
+    {
+        $s = $this->count;
+        $match = $this->match(
+            $this->utf8
+                ? '(([\pL\w\x{00A0}-\x{10FFFF}_\-\*!"\']|[\\\\].)([\pL\w\x{00A0}-\x{10FFFF}\-_"\']|[\\\\].)*)'
+                : '(([\w_\-\*!"\']|[\\\\].)([\w\-_"\']|[\\\\].)*)',
+            $m,
+            false
+        );
+
+        if ($match) {
+            $word = $m[1];
+
+            // handling of escaping in keyword : get the escaped char
+            if (strpos($word, '\\') !== false) {
+                $send = $this->count;
+                $escapedWord = [];
+                $this->seek($s);
+                $previousEscape = false;
+                while ($this->count < $send) {
+                    $char = $this->buffer[$this->count];
+                    $this->count++;
+                    if (
+                        $this->count < $send
+                        && $char === '\\'
+                        && !$previousEscape
+                        && $this->matchEscapeCharacter($out, true)
+                    ) {
+                        $escapedWord[] = $out;
+                    } else {
+                        if ($previousEscape) {
+                            $previousEscape = false;
+                        } elseif ($char === '\\') {
+                            $previousEscape = true;
+                        }
+                        $escapedWord[] = $char;
+                    }
+                }
+
+                $word = implode('', $escapedWord);
+            }
+
+            if (is_null($eatWhitespace) ? $this->eatWhiteDefault : $eatWhitespace) {
+                $this->whitespace();
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse a keyword that should not start with a number
+     *
+     * @param string  $word
+     * @param boolean $eatWhitespace
+     *
+     * @return boolean
+     */
+    protected function restrictedKeyword(&$word, $eatWhitespace = null)
+    {
+        $s = $this->count;
+
+        if ($this->keyword($word, $eatWhitespace) && (\ord($word[0]) > 57 || \ord($word[0]) < 48)) {
+            return true;
+        }
+
+        $this->seek($s);
+
+        return false;
+    }
+
+    /**
+     * Parse a placeholder
+     *
+     * @param string|array $placeholder
+     *
+     * @return boolean
+     */
+    protected function placeholder(&$placeholder)
+    {
+        $match = $this->match(
+            $this->utf8
+                ? '([\pL\w\-_]+)'
+                : '([\w\-_]+)',
+            $m
+        );
+
+        if ($match) {
+            $placeholder = $m[1];
+
+            return true;
+        }
+
+        if ($this->interpolation($placeholder)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parse a url
+     *
+     * @param array $out
+     *
+     * @return boolean
+     */
+    protected function url(&$out)
+    {
+        if ($this->literal('url(', 4)) {
+            $s = $this->count;
+
+            if (
+                ($this->string($out) || $this->spaceList($out)) &&
+                $this->matchChar(')')
+            ) {
+                $out = [Type::T_STRING, '', ['url(', $out, ')']];
+
+                return true;
+            }
+
+            $this->seek($s);
+
+            if (
+                $this->openString(')', $out) &&
+                $this->matchChar(')')
+            ) {
+                $out = [Type::T_STRING, '', ['url(', $out, ')']];
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Consume an end of statement delimiter
+     * @param bool $eatWhitespace
+     *
+     * @return boolean
+     */
+    protected function end($eatWhitespace = null)
+    {
+        if ($this->matchChar(';', $eatWhitespace)) {
+            return true;
+        }
+
+        if ($this->count === \strlen($this->buffer) || $this->buffer[$this->count] === '}') {
+            // if there is end of file or a closing block next then we don't need a ;
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Strip assignment flag from the list
+     *
+     * @param array $value
+     *
+     * @return array
+     */
+    protected function stripAssignmentFlags(&$value)
+    {
+        $flags = [];
+
+        for ($token = &$value; $token[0] === Type::T_LIST && ($s = \count($token[2])); $token = &$lastNode) {
+            $lastNode = &$token[2][$s - 1];
+
+            while ($lastNode[0] === Type::T_KEYWORD && \in_array($lastNode[1], ['!default', '!global'])) {
+                array_pop($token[2]);
+
+                $node     = end($token[2]);
+                $token    = $this->flattenList($token);
+                $flags[]  = $lastNode[1];
+                $lastNode = $node;
+            }
+        }
+
+        return $flags;
+    }
+
+    /**
+     * Strip optional flag from selector list
+     *
+     * @param array $selectors
+     *
+     * @return string
+     */
+    protected function stripOptionalFlag(&$selectors)
+    {
+        $optional = false;
+        $selector = end($selectors);
+        $part     = end($selector);
+
+        if ($part === ['!optional']) {
+            array_pop($selectors[\count($selectors) - 1]);
+
+            $optional = true;
+        }
+
+        return $optional;
+    }
+
+    /**
+     * Turn list of length 1 into value type
+     *
+     * @param array $value
+     *
+     * @return array
+     */
+    protected function flattenList($value)
+    {
+        if ($value[0] === Type::T_LIST && \count($value[2]) === 1) {
+            return $this->flattenList($value[2][0]);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Quote regular expression
+     *
+     * @param string $what
+     *
+     * @return string
+     */
+    private function pregQuote($what)
+    {
+        return preg_quote($what, '/');
+    }
+
+    /**
+     * Extract line numbers from buffer
+     *
+     * @param string $buffer
+     */
+    private function extractLineNumbers($buffer)
+    {
+        $this->sourcePositions = [0 => 0];
+        $prev = 0;
+
+        while (($pos = strpos($buffer, "\n", $prev)) !== false) {
+            $this->sourcePositions[] = $pos;
+            $prev = $pos + 1;
+        }
+
+        $this->sourcePositions[] = \strlen($buffer);
+
+        if (substr($buffer, -1) !== "\n") {
+            $this->sourcePositions[] = \strlen($buffer) + 1;
+        }
+    }
+
+    /**
+     * Get source line number and column (given character position in the buffer)
+     *
+     * @param integer $pos
+     *
+     * @return array
+     */
+    private function getSourcePosition($pos)
+    {
+        $low = 0;
+        $high = \count($this->sourcePositions);
+
+        while ($low < $high) {
+            $mid = (int) (($high + $low) / 2);
+
+            if ($pos < $this->sourcePositions[$mid]) {
+                $high = $mid - 1;
+                continue;
+            }
+
+            if ($pos >= $this->sourcePositions[$mid + 1]) {
+                $low = $mid + 1;
+                continue;
+            }
+
+            return [$mid + 1, $pos - $this->sourcePositions[$mid]];
+        }
+
+        return [$low + 1, $pos - $this->sourcePositions[$low]];
+    }
+
+    /**
+     * Save internal encoding
+     */
+    private function saveEncoding()
+    {
+        if (\extension_loaded('mbstring')) {
+            $this->encoding = mb_internal_encoding();
+
+            mb_internal_encoding('iso-8859-1');
+        }
+    }
+
+    /**
+     * Restore internal encoding
+     */
+    private function restoreEncoding()
+    {
+        if (\extension_loaded('mbstring') && $this->encoding) {
+            mb_internal_encoding($this->encoding);
+        }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/Base64.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/Base64.php
new file mode 100644 (file)
index 0000000..5fc56b2
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\SourceMap;
+
+/**
+ * Base 64 Encode/Decode
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Base64
+{
+    /**
+     * @var array
+     */
+    private static $encodingMap = [
+        0 => 'A',
+        1 => 'B',
+        2 => 'C',
+        3 => 'D',
+        4 => 'E',
+        5 => 'F',
+        6 => 'G',
+        7 => 'H',
+        8 => 'I',
+        9 => 'J',
+        10 => 'K',
+        11 => 'L',
+        12 => 'M',
+        13 => 'N',
+        14 => 'O',
+        15 => 'P',
+        16 => 'Q',
+        17 => 'R',
+        18 => 'S',
+        19 => 'T',
+        20 => 'U',
+        21 => 'V',
+        22 => 'W',
+        23 => 'X',
+        24 => 'Y',
+        25 => 'Z',
+        26 => 'a',
+        27 => 'b',
+        28 => 'c',
+        29 => 'd',
+        30 => 'e',
+        31 => 'f',
+        32 => 'g',
+        33 => 'h',
+        34 => 'i',
+        35 => 'j',
+        36 => 'k',
+        37 => 'l',
+        38 => 'm',
+        39 => 'n',
+        40 => 'o',
+        41 => 'p',
+        42 => 'q',
+        43 => 'r',
+        44 => 's',
+        45 => 't',
+        46 => 'u',
+        47 => 'v',
+        48 => 'w',
+        49 => 'x',
+        50 => 'y',
+        51 => 'z',
+        52 => '0',
+        53 => '1',
+        54 => '2',
+        55 => '3',
+        56 => '4',
+        57 => '5',
+        58 => '6',
+        59 => '7',
+        60 => '8',
+        61 => '9',
+        62 => '+',
+        63 => '/',
+    ];
+
+    /**
+     * @var array
+     */
+    private static $decodingMap = [
+        'A' => 0,
+        'B' => 1,
+        'C' => 2,
+        'D' => 3,
+        'E' => 4,
+        'F' => 5,
+        'G' => 6,
+        'H' => 7,
+        'I' => 8,
+        'J' => 9,
+        'K' => 10,
+        'L' => 11,
+        'M' => 12,
+        'N' => 13,
+        'O' => 14,
+        'P' => 15,
+        'Q' => 16,
+        'R' => 17,
+        'S' => 18,
+        'T' => 19,
+        'U' => 20,
+        'V' => 21,
+        'W' => 22,
+        'X' => 23,
+        'Y' => 24,
+        'Z' => 25,
+        'a' => 26,
+        'b' => 27,
+        'c' => 28,
+        'd' => 29,
+        'e' => 30,
+        'f' => 31,
+        'g' => 32,
+        'h' => 33,
+        'i' => 34,
+        'j' => 35,
+        'k' => 36,
+        'l' => 37,
+        'm' => 38,
+        'n' => 39,
+        'o' => 40,
+        'p' => 41,
+        'q' => 42,
+        'r' => 43,
+        's' => 44,
+        't' => 45,
+        'u' => 46,
+        'v' => 47,
+        'w' => 48,
+        'x' => 49,
+        'y' => 50,
+        'z' => 51,
+        0 => 52,
+        1 => 53,
+        2 => 54,
+        3 => 55,
+        4 => 56,
+        5 => 57,
+        6 => 58,
+        7 => 59,
+        8 => 60,
+        9 => 61,
+        '+' => 62,
+        '/' => 63,
+    ];
+
+    /**
+     * Convert to base64
+     *
+     * @param integer $value
+     *
+     * @return string
+     */
+    public static function encode($value)
+    {
+        return self::$encodingMap[$value];
+    }
+
+    /**
+     * Convert from base64
+     *
+     * @param string $value
+     *
+     * @return integer
+     */
+    public static function decode($value)
+    {
+        return self::$decodingMap[$value];
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/Base64VLQ.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/Base64VLQ.php
new file mode 100644 (file)
index 0000000..9083d78
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\SourceMap;
+
+use ScssPhp\ScssPhp\SourceMap\Base64;
+
+/**
+ * Base 64 VLQ
+ *
+ * Based on the Base 64 VLQ implementation in Closure Compiler:
+ * https://github.com/google/closure-compiler/blob/master/src/com/google/debugging/sourcemap/Base64VLQ.java
+ *
+ * Copyright 2011 The Closure Compiler Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author John Lenz <johnlenz@google.com>
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Base64VLQ
+{
+    // A Base64 VLQ digit can represent 5 bits, so it is base-32.
+    const VLQ_BASE_SHIFT = 5;
+
+    // A mask of bits for a VLQ digit (11111), 31 decimal.
+    const VLQ_BASE_MASK = 31;
+
+    // The continuation bit is the 6th bit.
+    const VLQ_CONTINUATION_BIT = 32;
+
+    /**
+     * Returns the VLQ encoded value.
+     *
+     * @param integer $value
+     *
+     * @return string
+     */
+    public static function encode($value)
+    {
+        $encoded = '';
+        $vlq = self::toVLQSigned($value);
+
+        do {
+            $digit = $vlq & self::VLQ_BASE_MASK;
+
+            //$vlq >>>= self::VLQ_BASE_SHIFT; // unsigned right shift
+            $vlq = (($vlq >> 1) & PHP_INT_MAX) >> (self::VLQ_BASE_SHIFT - 1);
+
+            if ($vlq > 0) {
+                $digit |= self::VLQ_CONTINUATION_BIT;
+            }
+
+            $encoded .= Base64::encode($digit);
+        } while ($vlq > 0);
+
+        return $encoded;
+    }
+
+    /**
+     * Decodes VLQValue.
+     *
+     * @param string $str
+     * @param integer $index
+     *
+     * @return integer
+     */
+    public static function decode($str, &$index)
+    {
+        $result = 0;
+        $shift = 0;
+
+        do {
+            $c = $str[$index++];
+            $digit = Base64::decode($c);
+            $continuation = ($digit & self::VLQ_CONTINUATION_BIT) != 0;
+            $digit &= self::VLQ_BASE_MASK;
+            $result = $result + ($digit << $shift);
+            $shift = $shift + self::VLQ_BASE_SHIFT;
+        } while ($continuation);
+
+        return self::fromVLQSigned($result);
+    }
+
+    /**
+     * Converts from a two-complement value to a value where the sign bit is
+     * is placed in the least significant bit.  For example, as decimals:
+     *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
+     *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
+     *
+     * @param integer $value
+     *
+     * @return integer
+     */
+    private static function toVLQSigned($value)
+    {
+        if ($value < 0) {
+            return ((-$value) << 1) + 1;
+        }
+
+        return ($value << 1) + 0;
+    }
+
+    /**
+     * Converts to a two-complement value from a value where the sign bit is
+     * is placed in the least significant bit.  For example, as decimals:
+     *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
+     *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
+     *
+     * @param integer $value
+     *
+     * @return integer
+     */
+    private static function fromVLQSigned($value)
+    {
+        $negate = ($value & 1) === 1;
+
+        //$value >>>= 1; // unsigned right shift
+        $value = ($value >> 1) & PHP_INT_MAX;
+
+        if (! $negate) {
+            return $value;
+        }
+
+        // We need to OR 0x80000000 here to ensure the 32nd bit (the sign bit) is
+        // always set for negative numbers. If `value` were 1, (meaning `negate` is
+        // true and all other bits were zeros), `value` would now be 0. -0 is just
+        // 0, and doesn't flip the 32nd bit as intended. All positive numbers will
+        // successfully flip the 32nd bit without issue, so it's a noop for them.
+        return -$value | 0x80000000;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php
new file mode 100644 (file)
index 0000000..d01f7cc
--- /dev/null
@@ -0,0 +1,349 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\SourceMap;
+
+use ScssPhp\ScssPhp\Exception\CompilerException;
+
+/**
+ * Source Map Generator
+ *
+ * {@internal Derivative of oyejorge/less.php's lib/SourceMap/Generator.php, relicensed with permission. }}
+ *
+ * @author Josh Schmidt <oyejorge@gmail.com>
+ * @author Nicolas FRANÇOIS <nicolas.francois@frog-labs.com>
+ */
+class SourceMapGenerator
+{
+    /**
+     * What version of source map does the generator generate?
+     */
+    const VERSION = 3;
+
+    /**
+     * Array of default options
+     *
+     * @var array
+     */
+    protected $defaultOptions = [
+        // an optional source root, useful for relocating source files
+        // on a server or removing repeated values in the 'sources' entry.
+        // This value is prepended to the individual entries in the 'source' field.
+        'sourceRoot' => '',
+
+        // an optional name of the generated code that this source map is associated with.
+        'sourceMapFilename' => null,
+
+        // url of the map
+        'sourceMapURL' => null,
+
+        // absolute path to a file to write the map to
+        'sourceMapWriteTo' => null,
+
+        // output source contents?
+        'outputSourceFiles' => false,
+
+        // base path for filename normalization
+        'sourceMapRootpath' => '',
+
+        // base path for filename normalization
+        'sourceMapBasepath' => ''
+    ];
+
+    /**
+     * The base64 VLQ encoder
+     *
+     * @var \ScssPhp\ScssPhp\SourceMap\Base64VLQ
+     */
+    protected $encoder;
+
+    /**
+     * Array of mappings
+     *
+     * @var array
+     */
+    protected $mappings = [];
+
+    /**
+     * Array of contents map
+     *
+     * @var array
+     */
+    protected $contentsMap = [];
+
+    /**
+     * File to content map
+     *
+     * @var array
+     */
+    protected $sources = [];
+    protected $sourceKeys = [];
+
+    /**
+     * @var array
+     */
+    private $options;
+
+    public function __construct(array $options = [])
+    {
+        $this->options = array_merge($this->defaultOptions, $options);
+        $this->encoder = new Base64VLQ();
+    }
+
+    /**
+     * Adds a mapping
+     *
+     * @param integer $generatedLine   The line number in generated file
+     * @param integer $generatedColumn The column number in generated file
+     * @param integer $originalLine    The line number in original file
+     * @param integer $originalColumn  The column number in original file
+     * @param string  $sourceFile      The original source file
+     */
+    public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $sourceFile)
+    {
+        $this->mappings[] = [
+            'generated_line'   => $generatedLine,
+            'generated_column' => $generatedColumn,
+            'original_line'    => $originalLine,
+            'original_column'  => $originalColumn,
+            'source_file'      => $sourceFile
+        ];
+
+        $this->sources[$sourceFile] = $sourceFile;
+    }
+
+    /**
+     * Saves the source map to a file
+     *
+     * @param string $content The content to write
+     *
+     * @return string
+     *
+     * @throws \ScssPhp\ScssPhp\Exception\CompilerException If the file could not be saved
+     */
+    public function saveMap($content)
+    {
+        $file = $this->options['sourceMapWriteTo'];
+        $dir  = \dirname($file);
+
+        // directory does not exist
+        if (! is_dir($dir)) {
+            // FIXME: create the dir automatically?
+            throw new CompilerException(
+                sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir)
+            );
+        }
+
+        // FIXME: proper saving, with dir write check!
+        if (file_put_contents($file, $content) === false) {
+            throw new CompilerException(sprintf('Cannot save the source map to "%s"', $file));
+        }
+
+        return $this->options['sourceMapURL'];
+    }
+
+    /**
+     * Generates the JSON source map
+     *
+     * @return string
+     *
+     * @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#
+     */
+    public function generateJson()
+    {
+        $sourceMap = [];
+        $mappings  = $this->generateMappings();
+
+        // File version (always the first entry in the object) and must be a positive integer.
+        $sourceMap['version'] = self::VERSION;
+
+        // An optional name of the generated code that this source map is associated with.
+        $file = $this->options['sourceMapFilename'];
+
+        if ($file) {
+            $sourceMap['file'] = $file;
+        }
+
+        // An optional source root, useful for relocating source files on a server or removing repeated values in the
+        // 'sources' entry. This value is prepended to the individual entries in the 'source' field.
+        $root = $this->options['sourceRoot'];
+
+        if ($root) {
+            $sourceMap['sourceRoot'] = $root;
+        }
+
+        // A list of original sources used by the 'mappings' entry.
+        $sourceMap['sources'] = [];
+
+        foreach ($this->sources as $sourceUri => $sourceFilename) {
+            $sourceMap['sources'][] = $this->normalizeFilename($sourceFilename);
+        }
+
+        // A list of symbol names used by the 'mappings' entry.
+        $sourceMap['names'] = [];
+
+        // A string with the encoded mapping data.
+        $sourceMap['mappings'] = $mappings;
+
+        if ($this->options['outputSourceFiles']) {
+            // An optional list of source content, useful when the 'source' can't be hosted.
+            // The contents are listed in the same order as the sources above.
+            // 'null' may be used if some original sources should be retrieved by name.
+            $sourceMap['sourcesContent'] = $this->getSourcesContent();
+        }
+
+        // less.js compat fixes
+        if (\count($sourceMap['sources']) && empty($sourceMap['sourceRoot'])) {
+            unset($sourceMap['sourceRoot']);
+        }
+
+        return json_encode($sourceMap, JSON_UNESCAPED_SLASHES);
+    }
+
+    /**
+     * Returns the sources contents
+     *
+     * @return array|null
+     */
+    protected function getSourcesContent()
+    {
+        if (empty($this->sources)) {
+            return null;
+        }
+
+        $content = [];
+
+        foreach ($this->sources as $sourceFile) {
+            $content[] = file_get_contents($sourceFile);
+        }
+
+        return $content;
+    }
+
+    /**
+     * Generates the mappings string
+     *
+     * @return string
+     */
+    public function generateMappings()
+    {
+        if (! \count($this->mappings)) {
+            return '';
+        }
+
+        $this->sourceKeys = array_flip(array_keys($this->sources));
+
+        // group mappings by generated line number.
+        $groupedMap = $groupedMapEncoded = [];
+
+        foreach ($this->mappings as $m) {
+            $groupedMap[$m['generated_line']][] = $m;
+        }
+
+        ksort($groupedMap);
+
+        $lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0;
+
+        foreach ($groupedMap as $lineNumber => $lineMap) {
+            while (++$lastGeneratedLine < $lineNumber) {
+                $groupedMapEncoded[] = ';';
+            }
+
+            $lineMapEncoded = [];
+            $lastGeneratedColumn = 0;
+
+            foreach ($lineMap as $m) {
+                $mapEncoded = $this->encoder->encode($m['generated_column'] - $lastGeneratedColumn);
+                $lastGeneratedColumn = $m['generated_column'];
+
+                // find the index
+                if ($m['source_file']) {
+                    $index = $this->findFileIndex($m['source_file']);
+
+                    if ($index !== false) {
+                        $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex);
+                        $lastOriginalIndex = $index;
+                        // lines are stored 0-based in SourceMap spec version 3
+                        $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine);
+                        $lastOriginalLine = $m['original_line'] - 1;
+                        $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn);
+                        $lastOriginalColumn = $m['original_column'];
+                    }
+                }
+
+                $lineMapEncoded[] = $mapEncoded;
+            }
+
+            $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';';
+        }
+
+        return rtrim(implode($groupedMapEncoded), ';');
+    }
+
+    /**
+     * Finds the index for the filename
+     *
+     * @param string $filename
+     *
+     * @return integer|false
+     */
+    protected function findFileIndex($filename)
+    {
+        return $this->sourceKeys[$filename];
+    }
+
+    /**
+     * Normalize filename
+     *
+     * @param string $filename
+     *
+     * @return string
+     */
+    protected function normalizeFilename($filename)
+    {
+        $filename = $this->fixWindowsPath($filename);
+        $rootpath = $this->options['sourceMapRootpath'];
+        $basePath = $this->options['sourceMapBasepath'];
+
+        // "Trim" the 'sourceMapBasepath' from the output filename.
+        if (\strlen($basePath) && strpos($filename, $basePath) === 0) {
+            $filename = substr($filename, \strlen($basePath));
+        }
+
+        // Remove extra leading path separators.
+        if (strpos($filename, '\\') === 0 || strpos($filename, '/') === 0) {
+            $filename = substr($filename, 1);
+        }
+
+        return $rootpath . $filename;
+    }
+
+    /**
+     * Fix windows paths
+     *
+     * @param string  $path
+     * @param boolean $addEndSlash
+     *
+     * @return string
+     */
+    public function fixWindowsPath($path, $addEndSlash = false)
+    {
+        $slash = ($addEndSlash) ? '/' : '';
+
+        if (! empty($path)) {
+            $path = str_replace('\\', '/', $path);
+            $path = rtrim($path, '/') . $slash;
+        }
+
+        return $path;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Type.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Type.php
new file mode 100644 (file)
index 0000000..549b08e
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+/**
+ * Block/node types
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Type
+{
+    const T_ASSIGN = 'assign';
+    const T_AT_ROOT = 'at-root';
+    const T_BLOCK = 'block';
+    /** @deprecated */
+    const T_BREAK = 'break';
+    const T_CHARSET = 'charset';
+    const T_COLOR = 'color';
+    const T_COMMENT = 'comment';
+    /** @deprecated */
+    const T_CONTINUE = 'continue';
+    /** @deprecated */
+    const T_CONTROL = 'control';
+    const T_CUSTOM_PROPERTY = 'custom';
+    const T_DEBUG = 'debug';
+    const T_DIRECTIVE = 'directive';
+    const T_EACH = 'each';
+    const T_ELSE = 'else';
+    const T_ELSEIF = 'elseif';
+    const T_ERROR = 'error';
+    const T_EXPRESSION = 'exp';
+    const T_EXTEND = 'extend';
+    const T_FOR = 'for';
+    const T_FUNCTION = 'function';
+    const T_FUNCTION_REFERENCE = 'function-reference';
+    const T_FUNCTION_CALL = 'fncall';
+    const T_HSL = 'hsl';
+    const T_IF = 'if';
+    const T_IMPORT = 'import';
+    const T_INCLUDE = 'include';
+    const T_INTERPOLATE = 'interpolate';
+    const T_INTERPOLATED = 'interpolated';
+    const T_KEYWORD = 'keyword';
+    const T_LIST = 'list';
+    const T_MAP = 'map';
+    const T_MEDIA = 'media';
+    const T_MEDIA_EXPRESSION = 'mediaExp';
+    const T_MEDIA_TYPE = 'mediaType';
+    const T_MEDIA_VALUE = 'mediaValue';
+    const T_MIXIN = 'mixin';
+    const T_MIXIN_CONTENT = 'mixin_content';
+    const T_NESTED_PROPERTY = 'nestedprop';
+    const T_NOT = 'not';
+    const T_NULL = 'null';
+    const T_NUMBER = 'number';
+    const T_RETURN = 'return';
+    const T_ROOT = 'root';
+    const T_SCSSPHP_IMPORT_ONCE = 'scssphp-import-once';
+    const T_SELF = 'self';
+    const T_STRING = 'string';
+    const T_UNARY = 'unary';
+    const T_VARIABLE = 'var';
+    const T_WARN = 'warn';
+    const T_WHILE = 'while';
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Util.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Util.php
new file mode 100644 (file)
index 0000000..980f570
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+use ScssPhp\ScssPhp\Base\Range;
+use ScssPhp\ScssPhp\Exception\RangeException;
+
+/**
+ * Utilty functions
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ */
+class Util
+{
+    /**
+     * Asserts that `value` falls within `range` (inclusive), leaving
+     * room for slight floating-point errors.
+     *
+     * @param string                    $name  The name of the value. Used in the error message.
+     * @param \ScssPhp\ScssPhp\Base\Range $range Range of values.
+     * @param array                     $value The value to check.
+     * @param string                    $unit  The unit of the value. Used in error reporting.
+     *
+     * @return mixed `value` adjusted to fall within range, if it was outside by a floating-point margin.
+     *
+     * @throws \ScssPhp\ScssPhp\Exception\RangeException
+     */
+    public static function checkRange($name, Range $range, $value, $unit = '')
+    {
+        $val = $value[1];
+        $grace = new Range(-0.00001, 0.00001);
+
+        if (! \is_numeric($val)) {
+            throw new RangeException("$name {$val} is not a number.");
+        }
+
+        if ($range->includes($val)) {
+            return $val;
+        }
+
+        if ($grace->includes($val - $range->first)) {
+            return $range->first;
+        }
+
+        if ($grace->includes($val - $range->last)) {
+            return $range->last;
+        }
+
+        throw new RangeException("$name {$val} must be between {$range->first} and {$range->last}$unit");
+    }
+
+    /**
+     * Encode URI component
+     *
+     * @param string $string
+     *
+     * @return string
+     */
+    public static function encodeURIComponent($string)
+    {
+        $revert = ['%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')'];
+
+        return strtr(rawurlencode($string), $revert);
+    }
+
+    /**
+     * mb_chr() wrapper
+     *
+     * @param integer $code
+     *
+     * @return string
+     */
+    public static function mbChr($code)
+    {
+        // Use the native implementation if available, but not on PHP 7.2 as mb_chr(0) is buggy there
+        if (\PHP_VERSION_ID > 70300 && \function_exists('mb_chr')) {
+            return mb_chr($code, 'UTF-8');
+        }
+
+        if (0x80 > $code %= 0x200000) {
+            $s = \chr($code);
+        } elseif (0x800 > $code) {
+            $s = \chr(0xC0 | $code >> 6) . \chr(0x80 | $code & 0x3F);
+        } elseif (0x10000 > $code) {
+            $s = \chr(0xE0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F);
+        } else {
+            $s = \chr(0xF0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3F)
+                . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F);
+        }
+
+        return $s;
+    }
+
+    /**
+     * mb_strlen() wrapper
+     *
+     * @param string $string
+     * @return false|int
+     */
+    public static function mbStrlen($string)
+    {
+        // Use the native implementation if available.
+        if (\function_exists('mb_strlen')) {
+            return mb_strlen($string, 'UTF-8');
+        }
+
+        if (\function_exists('iconv_strlen')) {
+            return @iconv_strlen($string, 'UTF-8');
+        }
+
+        return strlen($string);
+    }
+
+    /**
+     * mb_substr() wrapper
+     * @param string $string
+     * @param int $start
+     * @param null|int $length
+     * @return string
+     */
+    public static function mbSubstr($string, $start, $length = null)
+    {
+        // Use the native implementation if available.
+        if (\function_exists('mb_substr')) {
+            return mb_substr($string, $start, $length, 'UTF-8');
+        }
+
+        if (\function_exists('iconv_substr')) {
+            if ($start < 0) {
+                $start = static::mbStrlen($string) + $start;
+                if ($start < 0) {
+                    $start = 0;
+                }
+            }
+
+            if (null === $length) {
+                $length = 2147483647;
+            } elseif ($length < 0) {
+                $length = static::mbStrlen($string) + $length - $start;
+                if ($length < 0) {
+                    return '';
+                }
+            }
+
+            return (string)iconv_substr($string, $start, $length, 'UTF-8');
+        }
+
+        return substr($string, $start, $length);
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php b/wcfsetup/install/files/lib/system/api/scssphp/scssphp/src/Version.php
new file mode 100644 (file)
index 0000000..cd3e190
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp;
+
+/**
+ * SCSSPHP version
+ *
+ * @author Leaf Corcoran <leafot@gmail.com>
+ */
+class Version
+{
+    const VERSION = '1.3';
+}
index a677f43763ca467472898351b328aee41e2edd7c..9e936ec0448b8549e5edf08e5ac5f01491a8bfc8 100644 (file)
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2019 Fabien Potencier
+Copyright (c) 2004-2020 Fabien Potencier
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
index 1d5d8ff7ba1d82daadebd337afabc17fe4a75ce5..de2e74aa88cab989eea9eac2784c1679b0bb8978 100644 (file)
@@ -34,7 +34,7 @@ abstract class AbstractNode implements NodeInterface
     public function getNodeName()
     {
         if (null === $this->nodeName) {
-            $this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', \get_called_class());
+            $this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', static::class);
         }
 
         return $this->nodeName;
index 9869176b39466f838fedff946de855e34eea5bfd..72e94c3d5a63eb8ce79beed5b8558c4f7b003a38 100644 (file)
@@ -55,7 +55,7 @@ class StringHandler implements HandlerInterface
         $match = $reader->findPattern($this->patterns->getQuotedStringPattern($quote));
 
         if (!$match) {
-            throw new InternalErrorException(sprintf('Should have found at least an empty match at %s.', $reader->getPosition()));
+            throw new InternalErrorException(sprintf('Should have found at least an empty match at %d.', $reader->getPosition()));
         }
 
         // check unclosed strings
index 2b8aa6a192a77a935263c5a15465b5eba0e8f13c..a121ab8cfd6735c4ec4a9f09db82f1e70cc99e64 100644 (file)
@@ -58,7 +58,7 @@ class FunctionExtension extends AbstractExtension
         try {
             list($a, $b) = Parser::parseSeries($function->getArguments());
         } catch (SyntaxErrorException $e) {
-            throw new ExpressionErrorException(sprintf('Invalid series: %s', implode(', ', $function->getArguments())), 0, $e);
+            throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e);
         }
 
         $xpath->addStarPrefix();
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/Idn.php b/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/Idn.php
new file mode 100644 (file)
index 0000000..f54ffd5
--- /dev/null
@@ -0,0 +1,287 @@
+<?php
+
+/*
+ * Copyright (c) 2014 TrueServer B.V.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Originally forked from
+ * https://github.com/true/php-punycode/blob/v2.1.1/src/Punycode.php
+ */
+
+namespace Symfony\Polyfill\Intl\Idn;
+
+/**
+ * Partial intl implementation in pure PHP.
+ *
+ * Implemented:
+ * - idn_to_ascii - Convert domain name to IDNA ASCII form
+ * - idn_to_utf8  - Convert domain name from IDNA ASCII to Unicode
+ *
+ * @author Renan Gonçalves <renan.saddam@gmail.com>
+ * @author Sebastian Kroczek <sk@xbug.de>
+ * @author Dmitry Lukashin <dmitry@lukashin.ru>
+ * @author Laurent Bassin <laurent@bassin.info>
+ *
+ * @internal
+ */
+final class Idn
+{
+    const INTL_IDNA_VARIANT_2003 = 0;
+    const INTL_IDNA_VARIANT_UTS46 = 1;
+
+    private static $encodeTable = array(
+        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+        'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+    );
+
+    private static $decodeTable = array(
+        'a' => 0, 'b' => 1, 'c' => 2, 'd' => 3, 'e' => 4, 'f' => 5,
+        'g' => 6, 'h' => 7, 'i' => 8, 'j' => 9, 'k' => 10, 'l' => 11,
+        'm' => 12, 'n' => 13, 'o' => 14, 'p' => 15, 'q' => 16, 'r' => 17,
+        's' => 18, 't' => 19, 'u' => 20, 'v' => 21, 'w' => 22, 'x' => 23,
+        'y' => 24, 'z' => 25, '0' => 26, '1' => 27, '2' => 28, '3' => 29,
+        '4' => 30, '5' => 31, '6' => 32, '7' => 33, '8' => 34, '9' => 35,
+    );
+
+    public static function idn_to_ascii($domain, $options, $variant, &$idna_info = array())
+    {
+        if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
+            @trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
+        }
+
+        if (self::INTL_IDNA_VARIANT_UTS46 === $variant) {
+            $domain = mb_strtolower($domain, 'utf-8');
+        }
+
+        $parts = explode('.', $domain);
+
+        foreach ($parts as $i => &$part) {
+            if ('' === $part && \count($parts) > 1 + $i) {
+                return false;
+            }
+            if (false === $part = self::encodePart($part)) {
+                return false;
+            }
+        }
+
+        $output = implode('.', $parts);
+
+        $idna_info = array(
+            'result' => \strlen($output) > 255 ? false : $output,
+            'isTransitionalDifferent' => false,
+            'errors' => 0,
+        );
+
+        return $idna_info['result'];
+    }
+
+    public static function idn_to_utf8($domain, $options, $variant, &$idna_info = array())
+    {
+        if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
+            @trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
+        }
+
+        $parts = explode('.', $domain);
+
+        foreach ($parts as &$part) {
+            $length = \strlen($part);
+            if ($length < 1 || 63 < $length) {
+                continue;
+            }
+            if (0 !== strpos($part, 'xn--')) {
+                continue;
+            }
+
+            $part = substr($part, 4);
+            $part = self::decodePart($part);
+        }
+
+        $output = implode('.', $parts);
+
+        $idna_info = array(
+            'result' => \strlen($output) > 255 ? false : $output,
+            'isTransitionalDifferent' => false,
+            'errors' => 0,
+        );
+
+        return $idna_info['result'];
+    }
+
+    private static function encodePart($input)
+    {
+        if (\substr($input, 0, 1) === '-' || \substr($input, -1) === '-') {
+            return false;
+        }
+
+        $codePoints = self::listCodePoints($input);
+
+        $n = 128;
+        $bias = 72;
+        $delta = 0;
+        $h = $b = \count($codePoints['basic']);
+
+        $output = '';
+        foreach ($codePoints['basic'] as $code) {
+            $output .= mb_chr($code, 'utf-8');
+        }
+        if ($input === $output) {
+            return $output;
+        }
+        if ($b > 0) {
+            $output .= '-';
+        }
+
+        $codePoints['nonBasic'] = array_unique($codePoints['nonBasic']);
+        sort($codePoints['nonBasic']);
+
+        $i = 0;
+        $length = mb_strlen($input, 'utf-8');
+        while ($h < $length) {
+            $m = $codePoints['nonBasic'][$i++];
+            $delta += ($m - $n) * ($h + 1);
+            $n = $m;
+
+            foreach ($codePoints['all'] as $c) {
+                if ($c < $n || $c < 128) {
+                    ++$delta;
+                }
+                if ($c === $n) {
+                    $q = $delta;
+                    for ($k = 36;; $k += 36) {
+                        $t = self::calculateThreshold($k, $bias);
+                        if ($q < $t) {
+                            break;
+                        }
+
+                        $code = $t + (($q - $t) % (36 - $t));
+                        $output .= self::$encodeTable[$code];
+
+                        $q = ($q - $t) / (36 - $t);
+                    }
+
+                    $output .= self::$encodeTable[$q];
+                    $bias = self::adapt($delta, $h + 1, ($h === $b));
+                    $delta = 0;
+                    ++$h;
+                }
+            }
+
+            ++$delta;
+            ++$n;
+        }
+
+        $output = 'xn--'.$output;
+
+        return \strlen($output) < 1 || 63 < \strlen($output) ? false : strtolower($output);
+    }
+
+    private static function listCodePoints($input)
+    {
+        $codePoints = array(
+            'all' => array(),
+            'basic' => array(),
+            'nonBasic' => array(),
+        );
+
+        $length = mb_strlen($input, 'utf-8');
+        for ($i = 0; $i < $length; ++$i) {
+            $char = mb_substr($input, $i, 1, 'utf-8');
+            $code = mb_ord($char, 'utf-8');
+            if ($code < 128) {
+                $codePoints['all'][] = $codePoints['basic'][] = $code;
+            } else {
+                $codePoints['all'][] = $codePoints['nonBasic'][] = $code;
+            }
+        }
+
+        return $codePoints;
+    }
+
+    private static function calculateThreshold($k, $bias)
+    {
+        if ($k <= $bias + 1) {
+            return 1;
+        }
+        if ($k >= $bias + 26) {
+            return 26;
+        }
+
+        return $k - $bias;
+    }
+
+    private static function adapt($delta, $numPoints, $firstTime)
+    {
+        $delta = (int) ($firstTime ? $delta / 700 : $delta / 2);
+        $delta += (int) ($delta / $numPoints);
+
+        $k = 0;
+        while ($delta > 35 * 13) {
+            $delta = (int) ($delta / 35);
+            $k = $k + 36;
+        }
+
+        return $k + (int) (36 * $delta / ($delta + 38));
+    }
+
+    private static function decodePart($input)
+    {
+        $n = 128;
+        $i = 0;
+        $bias = 72;
+        $output = '';
+
+        $pos = strrpos($input, '-');
+        if (false !== $pos) {
+            $output = substr($input, 0, $pos++);
+        } else {
+            $pos = 0;
+        }
+
+        $outputLength = \strlen($output);
+        $inputLength = \strlen($input);
+
+        while ($pos < $inputLength) {
+            $oldi = $i;
+            $w = 1;
+
+            for ($k = 36;; $k += 36) {
+                $digit = self::$decodeTable[$input[$pos++]];
+                $i += $digit * $w;
+                $t = self::calculateThreshold($k, $bias);
+
+                if ($digit < $t) {
+                    break;
+                }
+
+                $w *= 36 - $t;
+            }
+
+            $bias = self::adapt($i - $oldi, ++$outputLength, 0 === $oldi);
+            $n = $n + (int) ($i / $outputLength);
+            $i = $i % $outputLength;
+            $output = mb_substr($output, 0, $i, 'utf-8').mb_chr($n, 'utf-8').mb_substr($output, $i, $outputLength - 1, 'utf-8');
+
+            ++$i;
+        }
+
+        return $output;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/LICENSE b/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/LICENSE
new file mode 100644 (file)
index 0000000..3f853aa
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2018-2019 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/README.md b/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/README.md
new file mode 100644 (file)
index 0000000..2e75f2e
--- /dev/null
@@ -0,0 +1,12 @@
+Symfony Polyfill / Intl: Idn
+============================
+
+This component provides [`idn_to_ascii`](https://php.net/idn-to-ascii) and [`idn_to_utf8`](https://php.net/idn-to-utf8) functions to users who run php versions without the [Intl](https://php.net/intl) extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/bootstrap.php b/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/bootstrap.php
new file mode 100644 (file)
index 0000000..f02d5de
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Intl\Idn as p;
+
+if (extension_loaded('intl')) {
+    return;
+}
+
+if (!defined('U_IDNA_PROHIBITED_ERROR')) {
+    define('U_IDNA_PROHIBITED_ERROR', 66560);
+}
+if (!defined('U_IDNA_ERROR_START')) {
+    define('U_IDNA_ERROR_START', 66560);
+}
+if (!defined('U_IDNA_UNASSIGNED_ERROR')) {
+    define('U_IDNA_UNASSIGNED_ERROR', 66561);
+}
+if (!defined('U_IDNA_CHECK_BIDI_ERROR')) {
+    define('U_IDNA_CHECK_BIDI_ERROR', 66562);
+}
+if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) {
+    define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563);
+}
+if (!defined('U_IDNA_ACE_PREFIX_ERROR')) {
+    define('U_IDNA_ACE_PREFIX_ERROR', 66564);
+}
+if (!defined('U_IDNA_VERIFICATION_ERROR')) {
+    define('U_IDNA_VERIFICATION_ERROR', 66565);
+}
+if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) {
+    define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566);
+}
+if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) {
+    define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567);
+}
+if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) {
+    define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568);
+}
+if (!defined('U_IDNA_ERROR_LIMIT')) {
+    define('U_IDNA_ERROR_LIMIT', 66569);
+}
+if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) {
+    define('U_STRINGPREP_PROHIBITED_ERROR', 66560);
+}
+if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) {
+    define('U_STRINGPREP_UNASSIGNED_ERROR', 66561);
+}
+if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) {
+    define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562);
+}
+if (!defined('IDNA_DEFAULT')) {
+    define('IDNA_DEFAULT', 0);
+}
+if (!defined('IDNA_ALLOW_UNASSIGNED')) {
+    define('IDNA_ALLOW_UNASSIGNED', 1);
+}
+if (!defined('IDNA_USE_STD3_RULES')) {
+    define('IDNA_USE_STD3_RULES', 2);
+}
+if (!defined('IDNA_CHECK_BIDI')) {
+    define('IDNA_CHECK_BIDI', 4);
+}
+if (!defined('IDNA_CHECK_CONTEXTJ')) {
+    define('IDNA_CHECK_CONTEXTJ', 8);
+}
+if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) {
+    define('IDNA_NONTRANSITIONAL_TO_ASCII', 16);
+}
+if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) {
+    define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32);
+}
+if (!defined('INTL_IDNA_VARIANT_2003')) {
+    define('INTL_IDNA_VARIANT_2003', 0);
+}
+if (!defined('INTL_IDNA_VARIANT_UTS46')) {
+    define('INTL_IDNA_VARIANT_UTS46', 1);
+}
+if (!defined('IDNA_ERROR_EMPTY_LABEL')) {
+    define('IDNA_ERROR_EMPTY_LABEL', 1);
+}
+if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) {
+    define('IDNA_ERROR_LABEL_TOO_LONG', 2);
+}
+if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) {
+    define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4);
+}
+if (!defined('IDNA_ERROR_LEADING_HYPHEN')) {
+    define('IDNA_ERROR_LEADING_HYPHEN', 8);
+}
+if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) {
+    define('IDNA_ERROR_TRAILING_HYPHEN', 16);
+}
+if (!defined('IDNA_ERROR_HYPHEN_3_4')) {
+    define('IDNA_ERROR_HYPHEN_3_4', 32);
+}
+if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) {
+    define('IDNA_ERROR_LEADING_COMBINING_MARK', 64);
+}
+if (!defined('IDNA_ERROR_DISALLOWED')) {
+    define('IDNA_ERROR_DISALLOWED', 128);
+}
+if (!defined('IDNA_ERROR_PUNYCODE')) {
+    define('IDNA_ERROR_PUNYCODE', 256);
+}
+if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) {
+    define('IDNA_ERROR_LABEL_HAS_DOT', 512);
+}
+if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) {
+    define('IDNA_ERROR_INVALID_ACE_LABEL', 1024);
+}
+if (!defined('IDNA_ERROR_BIDI')) {
+    define('IDNA_ERROR_BIDI', 2048);
+}
+if (!defined('IDNA_ERROR_CONTEXTJ')) {
+    define('IDNA_ERROR_CONTEXTJ', 4096);
+}
+
+if (PHP_VERSION_ID < 70400) {
+    if (!function_exists('idn_to_ascii')) {
+        function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
+    }
+    if (!function_exists('idn_to_utf8')) {
+        function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
+    }
+} else {
+    if (!function_exists('idn_to_ascii')) {
+        function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
+    }
+    if (!function_exists('idn_to_utf8')) {
+        function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/composer.json b/wcfsetup/install/files/lib/system/api/symfony/polyfill-intl-idn/composer.json
new file mode 100644 (file)
index 0000000..1c64acc
--- /dev/null
@@ -0,0 +1,40 @@
+{
+    "name": "symfony/polyfill-intl-idn",
+    "type": "library",
+    "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+    "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "idn"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Laurent Bassin",
+            "email": "laurent@bassin.info"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.3",
+        "symfony/polyfill-mbstring": "^1.3",
+        "symfony/polyfill-php72": "^1.10"
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" },
+        "files": [ "bootstrap.php" ]
+    },
+    "suggest": {
+        "ext-intl": "For best performance"
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.17-dev"
+        },
+        "thanks": {
+            "name": "symfony/polyfill",
+            "url": "https://github.com/symfony/polyfill"
+        }
+    }
+}
index 1fc4feea72cd8ba056ebb794a97a5a6254be08c7..15503bc9dd3a0ca943356e84cffcd69069ec4566 100644 (file)
@@ -512,7 +512,9 @@ final class Mbstring
             $offset = 0;
         } elseif ($offset = (int) $offset) {
             if ($offset < 0) {
-                $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
+                if (0 > $offset += self::mb_strlen($needle)) {
+                    $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
+                }
                 $offset = 0;
             } else {
                 $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
@@ -532,7 +534,7 @@ final class Mbstring
             return null;
         }
 
-        if ($split_length < 1) {
+        if (1 > $split_length = (int) $split_length) {
             trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
 
             return false;
@@ -542,6 +544,17 @@ final class Mbstring
             $encoding = mb_internal_encoding();
         }
 
+        if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
+            $rx = '/(';
+            while (65535 < $split_length) {
+                $rx .= '.{65535}';
+                $split_length -= 65535;
+            }
+            $rx .= '.{'.$split_length.'})/us';
+
+            return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+        }
+
         $result = array();
         $length = mb_strlen($string, $encoding);
 
@@ -815,11 +828,16 @@ final class Mbstring
             return self::$internalEncoding;
         }
 
+        if ('UTF-8' === $encoding) {
+            return 'UTF-8';
+        }
+
         $encoding = strtoupper($encoding);
 
         if ('8BIT' === $encoding || 'BINARY' === $encoding) {
             return 'CP850';
         }
+
         if ('UTF8' === $encoding) {
             return 'UTF-8';
         }
index 342e8286dbf694422c31e61b1a5bdf16f71785b4..4efb599d81fcc2374cbf42273628660f40c6c683 100644 (file)
@@ -2,7 +2,7 @@ Symfony Polyfill / Mbstring
 ===========================
 
 This component provides a partial, native PHP implementation for the
-[Mbstring](http://php.net/mbstring) extension.
+[Mbstring](https://php.net/mbstring) extension.
 
 More information can be found in the
 [main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
index e6fbfa64e6215a3e572d3d99f794cc6a85ea8af8..a22eca57bd99cc09a64162b32de0b143bf31be52 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-return array(
+return array (
   'A' => 'a',
   'B' => 'b',
   'C' => 'c',
@@ -510,6 +510,138 @@ return array(
   'Ⴥ' => 'ⴥ',
   'Ⴧ' => 'ⴧ',
   'Ⴭ' => 'ⴭ',
+  'Ꭰ' => 'ꭰ',
+  'Ꭱ' => 'ꭱ',
+  'Ꭲ' => 'ꭲ',
+  'Ꭳ' => 'ꭳ',
+  'Ꭴ' => 'ꭴ',
+  'Ꭵ' => 'ꭵ',
+  'Ꭶ' => 'ꭶ',
+  'Ꭷ' => 'ꭷ',
+  'Ꭸ' => 'ꭸ',
+  'Ꭹ' => 'ꭹ',
+  'Ꭺ' => 'ꭺ',
+  'Ꭻ' => 'ꭻ',
+  'Ꭼ' => 'ꭼ',
+  'Ꭽ' => 'ꭽ',
+  'Ꭾ' => 'ꭾ',
+  'Ꭿ' => 'ꭿ',
+  'Ꮀ' => 'ꮀ',
+  'Ꮁ' => 'ꮁ',
+  'Ꮂ' => 'ꮂ',
+  'Ꮃ' => 'ꮃ',
+  'Ꮄ' => 'ꮄ',
+  'Ꮅ' => 'ꮅ',
+  'Ꮆ' => 'ꮆ',
+  'Ꮇ' => 'ꮇ',
+  'Ꮈ' => 'ꮈ',
+  'Ꮉ' => 'ꮉ',
+  'Ꮊ' => 'ꮊ',
+  'Ꮋ' => 'ꮋ',
+  'Ꮌ' => 'ꮌ',
+  'Ꮍ' => 'ꮍ',
+  'Ꮎ' => 'ꮎ',
+  'Ꮏ' => 'ꮏ',
+  'Ꮐ' => 'ꮐ',
+  'Ꮑ' => 'ꮑ',
+  'Ꮒ' => 'ꮒ',
+  'Ꮓ' => 'ꮓ',
+  'Ꮔ' => 'ꮔ',
+  'Ꮕ' => 'ꮕ',
+  'Ꮖ' => 'ꮖ',
+  'Ꮗ' => 'ꮗ',
+  'Ꮘ' => 'ꮘ',
+  'Ꮙ' => 'ꮙ',
+  'Ꮚ' => 'ꮚ',
+  'Ꮛ' => 'ꮛ',
+  'Ꮜ' => 'ꮜ',
+  'Ꮝ' => 'ꮝ',
+  'Ꮞ' => 'ꮞ',
+  'Ꮟ' => 'ꮟ',
+  'Ꮠ' => 'ꮠ',
+  'Ꮡ' => 'ꮡ',
+  'Ꮢ' => 'ꮢ',
+  'Ꮣ' => 'ꮣ',
+  'Ꮤ' => 'ꮤ',
+  'Ꮥ' => 'ꮥ',
+  'Ꮦ' => 'ꮦ',
+  'Ꮧ' => 'ꮧ',
+  'Ꮨ' => 'ꮨ',
+  'Ꮩ' => 'ꮩ',
+  'Ꮪ' => 'ꮪ',
+  'Ꮫ' => 'ꮫ',
+  'Ꮬ' => 'ꮬ',
+  'Ꮭ' => 'ꮭ',
+  'Ꮮ' => 'ꮮ',
+  'Ꮯ' => 'ꮯ',
+  'Ꮰ' => 'ꮰ',
+  'Ꮱ' => 'ꮱ',
+  'Ꮲ' => 'ꮲ',
+  'Ꮳ' => 'ꮳ',
+  'Ꮴ' => 'ꮴ',
+  'Ꮵ' => 'ꮵ',
+  'Ꮶ' => 'ꮶ',
+  'Ꮷ' => 'ꮷ',
+  'Ꮸ' => 'ꮸ',
+  'Ꮹ' => 'ꮹ',
+  'Ꮺ' => 'ꮺ',
+  'Ꮻ' => 'ꮻ',
+  'Ꮼ' => 'ꮼ',
+  'Ꮽ' => 'ꮽ',
+  'Ꮾ' => 'ꮾ',
+  'Ꮿ' => 'ꮿ',
+  'Ᏸ' => 'ᏸ',
+  'Ᏹ' => 'ᏹ',
+  'Ᏺ' => 'ᏺ',
+  'Ᏻ' => 'ᏻ',
+  'Ᏼ' => 'ᏼ',
+  'Ᏽ' => 'ᏽ',
+  'Ა' => 'ა',
+  'Ბ' => 'ბ',
+  'Გ' => 'გ',
+  'Დ' => 'დ',
+  'Ე' => 'ე',
+  'Ვ' => 'ვ',
+  'Ზ' => 'ზ',
+  'Თ' => 'თ',
+  'Ი' => 'ი',
+  'Კ' => 'კ',
+  'Ლ' => 'ლ',
+  'Მ' => 'მ',
+  'Ნ' => 'ნ',
+  'Ო' => 'ო',
+  'Პ' => 'პ',
+  'Ჟ' => 'ჟ',
+  'Რ' => 'რ',
+  'Ს' => 'ს',
+  'Ტ' => 'ტ',
+  'Უ' => 'უ',
+  'Ფ' => 'ფ',
+  'Ქ' => 'ქ',
+  'Ღ' => 'ღ',
+  'Ყ' => 'ყ',
+  'Შ' => 'შ',
+  'Ჩ' => 'ჩ',
+  'Ც' => 'ც',
+  'Ძ' => 'ძ',
+  'Წ' => 'წ',
+  'Ჭ' => 'ჭ',
+  'Ხ' => 'ხ',
+  'Ჯ' => 'ჯ',
+  'Ჰ' => 'ჰ',
+  'Ჱ' => 'ჱ',
+  'Ჲ' => 'ჲ',
+  'Ჳ' => 'ჳ',
+  'Ჴ' => 'ჴ',
+  'Ჵ' => 'ჵ',
+  'Ჶ' => 'ჶ',
+  'Ჷ' => 'ჷ',
+  'Ჸ' => 'ჸ',
+  'Ჹ' => 'ჹ',
+  'Ჺ' => 'ჺ',
+  'Ჽ' => 'ჽ',
+  'Ჾ' => 'ჾ',
+  'Ჿ' => 'ჿ',
   'Ḁ' => 'ḁ',
   'Ḃ' => 'ḃ',
   'Ḅ' => 'ḅ',
@@ -993,8 +1125,24 @@ return array(
   'Ɜ' => 'ɜ',
   'Ɡ' => 'ɡ',
   'Ɬ' => 'ɬ',
+  'Ɪ' => 'ɪ',
   'Ʞ' => 'ʞ',
   'Ʇ' => 'ʇ',
+  'Ʝ' => 'ʝ',
+  'Ꭓ' => 'ꭓ',
+  'Ꞵ' => 'ꞵ',
+  'Ꞷ' => 'ꞷ',
+  'Ꞹ' => 'ꞹ',
+  'Ꞻ' => 'ꞻ',
+  'Ꞽ' => 'ꞽ',
+  'Ꞿ' => 'ꞿ',
+  'Ꟃ' => 'ꟃ',
+  'Ꞔ' => 'ꞔ',
+  'Ʂ' => 'ʂ',
+  'Ᶎ' => 'ᶎ',
+  'Ꟈ' => 'ꟈ',
+  'Ꟊ' => 'ꟊ',
+  'Ꟶ' => 'ꟶ',
   'A' => 'a',
   'B' => 'b',
   'C' => 'c',
@@ -1061,6 +1209,93 @@ return array(
   '𐐥' => '𐑍',
   '𐐦' => '𐑎',
   '𐐧' => '𐑏',
+  '𐒰' => '𐓘',
+  '𐒱' => '𐓙',
+  '𐒲' => '𐓚',
+  '𐒳' => '𐓛',
+  '𐒴' => '𐓜',
+  '𐒵' => '𐓝',
+  '𐒶' => '𐓞',
+  '𐒷' => '𐓟',
+  '𐒸' => '𐓠',
+  '𐒹' => '𐓡',
+  '𐒺' => '𐓢',
+  '𐒻' => '𐓣',
+  '𐒼' => '𐓤',
+  '𐒽' => '𐓥',
+  '𐒾' => '𐓦',
+  '𐒿' => '𐓧',
+  '𐓀' => '𐓨',
+  '𐓁' => '𐓩',
+  '𐓂' => '𐓪',
+  '𐓃' => '𐓫',
+  '𐓄' => '𐓬',
+  '𐓅' => '𐓭',
+  '𐓆' => '𐓮',
+  '𐓇' => '𐓯',
+  '𐓈' => '𐓰',
+  '𐓉' => '𐓱',
+  '𐓊' => '𐓲',
+  '𐓋' => '𐓳',
+  '𐓌' => '𐓴',
+  '𐓍' => '𐓵',
+  '𐓎' => '𐓶',
+  '𐓏' => '𐓷',
+  '𐓐' => '𐓸',
+  '𐓑' => '𐓹',
+  '𐓒' => '𐓺',
+  '𐓓' => '𐓻',
+  '𐲀' => '𐳀',
+  '𐲁' => '𐳁',
+  '𐲂' => '𐳂',
+  '𐲃' => '𐳃',
+  '𐲄' => '𐳄',
+  '𐲅' => '𐳅',
+  '𐲆' => '𐳆',
+  '𐲇' => '𐳇',
+  '𐲈' => '𐳈',
+  '𐲉' => '𐳉',
+  '𐲊' => '𐳊',
+  '𐲋' => '𐳋',
+  '𐲌' => '𐳌',
+  '𐲍' => '𐳍',
+  '𐲎' => '𐳎',
+  '𐲏' => '𐳏',
+  '𐲐' => '𐳐',
+  '𐲑' => '𐳑',
+  '𐲒' => '𐳒',
+  '𐲓' => '𐳓',
+  '𐲔' => '𐳔',
+  '𐲕' => '𐳕',
+  '𐲖' => '𐳖',
+  '𐲗' => '𐳗',
+  '𐲘' => '𐳘',
+  '𐲙' => '𐳙',
+  '𐲚' => '𐳚',
+  '𐲛' => '𐳛',
+  '𐲜' => '𐳜',
+  '𐲝' => '𐳝',
+  '𐲞' => '𐳞',
+  '𐲟' => '𐳟',
+  '𐲠' => '𐳠',
+  '𐲡' => '𐳡',
+  '𐲢' => '𐳢',
+  '𐲣' => '𐳣',
+  '𐲤' => '𐳤',
+  '𐲥' => '𐳥',
+  '𐲦' => '𐳦',
+  '𐲧' => '𐳧',
+  '𐲨' => '𐳨',
+  '𐲩' => '𐳩',
+  '𐲪' => '𐳪',
+  '𐲫' => '𐳫',
+  '𐲬' => '𐳬',
+  '𐲭' => '𐳭',
+  '𐲮' => '𐳮',
+  '𐲯' => '𐳯',
+  '𐲰' => '𐳰',
+  '𐲱' => '𐳱',
+  '𐲲' => '𐳲',
   '𑢠' => '𑣀',
   '𑢡' => '𑣁',
   '𑢢' => '𑣂',
@@ -1093,4 +1328,70 @@ return array(
   '𑢽' => '𑣝',
   '𑢾' => '𑣞',
   '𑢿' => '𑣟',
+  '𖹀' => '𖹠',
+  '𖹁' => '𖹡',
+  '𖹂' => '𖹢',
+  '𖹃' => '𖹣',
+  '𖹄' => '𖹤',
+  '𖹅' => '𖹥',
+  '𖹆' => '𖹦',
+  '𖹇' => '𖹧',
+  '𖹈' => '𖹨',
+  '𖹉' => '𖹩',
+  '𖹊' => '𖹪',
+  '𖹋' => '𖹫',
+  '𖹌' => '𖹬',
+  '𖹍' => '𖹭',
+  '𖹎' => '𖹮',
+  '𖹏' => '𖹯',
+  '𖹐' => '𖹰',
+  '𖹑' => '𖹱',
+  '𖹒' => '𖹲',
+  '𖹓' => '𖹳',
+  '𖹔' => '𖹴',
+  '𖹕' => '𖹵',
+  '𖹖' => '𖹶',
+  '𖹗' => '𖹷',
+  '𖹘' => '𖹸',
+  '𖹙' => '𖹹',
+  '𖹚' => '𖹺',
+  '𖹛' => '𖹻',
+  '𖹜' => '𖹼',
+  '𖹝' => '𖹽',
+  '𖹞' => '𖹾',
+  '𖹟' => '𖹿',
+  '𞤀' => '𞤢',
+  '𞤁' => '𞤣',
+  '𞤂' => '𞤤',
+  '𞤃' => '𞤥',
+  '𞤄' => '𞤦',
+  '𞤅' => '𞤧',
+  '𞤆' => '𞤨',
+  '𞤇' => '𞤩',
+  '𞤈' => '𞤪',
+  '𞤉' => '𞤫',
+  '𞤊' => '𞤬',
+  '𞤋' => '𞤭',
+  '𞤌' => '𞤮',
+  '𞤍' => '𞤯',
+  '𞤎' => '𞤰',
+  '𞤏' => '𞤱',
+  '𞤐' => '𞤲',
+  '𞤑' => '𞤳',
+  '𞤒' => '𞤴',
+  '𞤓' => '𞤵',
+  '𞤔' => '𞤶',
+  '𞤕' => '𞤷',
+  '𞤖' => '𞤸',
+  '𞤗' => '𞤹',
+  '𞤘' => '𞤺',
+  '𞤙' => '𞤻',
+  '𞤚' => '𞤼',
+  '𞤛' => '𞤽',
+  '𞤜' => '𞤾',
+  '𞤝' => '𞤿',
+  '𞤞' => '𞥀',
+  '𞤟' => '𞥁',
+  '𞤠' => '𞥂',
+  '𞤡' => '𞥃',
 );
index b8103b2e808dd0a670c04868f20edcc969ea7e70..ecbc15895eb71c7b92bb18bce90d955848b509a9 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-return array(
+return array (
   'a' => 'A',
   'b' => 'B',
   'c' => 'C',
@@ -225,6 +225,7 @@ return array(
   'ɦ' => 'Ɦ',
   'ɨ' => 'Ɨ',
   'ɩ' => 'Ɩ',
+  'ɪ' => 'Ɪ',
   'ɫ' => 'Ɫ',
   'ɬ' => 'Ɬ',
   'ɯ' => 'Ɯ',
@@ -233,6 +234,7 @@ return array(
   'ɵ' => 'Ɵ',
   'ɽ' => 'Ɽ',
   'ʀ' => 'Ʀ',
+  'ʂ' => 'Ʂ',
   'ʃ' => 'Ʃ',
   'ʇ' => 'Ʇ',
   'ʈ' => 'Ʈ',
@@ -241,6 +243,7 @@ return array(
   'ʋ' => 'Ʋ',
   'ʌ' => 'Ʌ',
   'ʒ' => 'Ʒ',
+  'ʝ' => 'Ʝ',
   'ʞ' => 'Ʞ',
   'ͅ' => 'Ι',
   'ͱ' => 'Ͱ',
@@ -493,8 +496,70 @@ return array(
   'ք' => 'Ք',
   'օ' => 'Օ',
   'ֆ' => 'Ֆ',
+  'ა' => 'Ა',
+  'ბ' => 'Ბ',
+  'გ' => 'Გ',
+  'დ' => 'Დ',
+  'ე' => 'Ე',
+  'ვ' => 'Ვ',
+  'ზ' => 'Ზ',
+  'თ' => 'Თ',
+  'ი' => 'Ი',
+  'კ' => 'Კ',
+  'ლ' => 'Ლ',
+  'მ' => 'Მ',
+  'ნ' => 'Ნ',
+  'ო' => 'Ო',
+  'პ' => 'Პ',
+  'ჟ' => 'Ჟ',
+  'რ' => 'Რ',
+  'ს' => 'Ს',
+  'ტ' => 'Ტ',
+  'უ' => 'Უ',
+  'ფ' => 'Ფ',
+  'ქ' => 'Ქ',
+  'ღ' => 'Ღ',
+  'ყ' => 'Ყ',
+  'შ' => 'Შ',
+  'ჩ' => 'Ჩ',
+  'ც' => 'Ც',
+  'ძ' => 'Ძ',
+  'წ' => 'Წ',
+  'ჭ' => 'Ჭ',
+  'ხ' => 'Ხ',
+  'ჯ' => 'Ჯ',
+  'ჰ' => 'Ჰ',
+  'ჱ' => 'Ჱ',
+  'ჲ' => 'Ჲ',
+  'ჳ' => 'Ჳ',
+  'ჴ' => 'Ჴ',
+  'ჵ' => 'Ჵ',
+  'ჶ' => 'Ჶ',
+  'ჷ' => 'Ჷ',
+  'ჸ' => 'Ჸ',
+  'ჹ' => 'Ჹ',
+  'ჺ' => 'Ჺ',
+  'ჽ' => 'Ჽ',
+  'ჾ' => 'Ჾ',
+  'ჿ' => 'Ჿ',
+  'ᏸ' => 'Ᏸ',
+  'ᏹ' => 'Ᏹ',
+  'ᏺ' => 'Ᏺ',
+  'ᏻ' => 'Ᏻ',
+  'ᏼ' => 'Ᏼ',
+  'ᏽ' => 'Ᏽ',
+  'ᲀ' => 'В',
+  'ᲁ' => 'Д',
+  'ᲂ' => 'О',
+  'ᲃ' => 'С',
+  'ᲄ' => 'Т',
+  'ᲅ' => 'Т',
+  'ᲆ' => 'Ъ',
+  'ᲇ' => 'Ѣ',
+  'ᲈ' => 'Ꙋ',
   'ᵹ' => 'Ᵹ',
   'ᵽ' => 'Ᵽ',
+  'ᶎ' => 'Ᶎ',
   'ḁ' => 'Ḁ',
   'ḃ' => 'Ḃ',
   'ḅ' => 'Ḅ',
@@ -993,6 +1058,7 @@ return array(
   'ꞌ' => 'Ꞌ',
   'ꞑ' => 'Ꞑ',
   'ꞓ' => 'Ꞓ',
+  'ꞔ' => 'Ꞔ',
   'ꞗ' => 'Ꞗ',
   'ꞙ' => 'Ꞙ',
   'ꞛ' => 'Ꞛ',
@@ -1003,6 +1069,97 @@ return array(
   'ꞥ' => 'Ꞥ',
   'ꞧ' => 'Ꞧ',
   'ꞩ' => 'Ꞩ',
+  'ꞵ' => 'Ꞵ',
+  'ꞷ' => 'Ꞷ',
+  'ꞹ' => 'Ꞹ',
+  'ꞻ' => 'Ꞻ',
+  'ꞽ' => 'Ꞽ',
+  'ꞿ' => 'Ꞿ',
+  'ꟃ' => 'Ꟃ',
+  'ꟈ' => 'Ꟈ',
+  'ꟊ' => 'Ꟊ',
+  'ꟶ' => 'Ꟶ',
+  'ꭓ' => 'Ꭓ',
+  'ꭰ' => 'Ꭰ',
+  'ꭱ' => 'Ꭱ',
+  'ꭲ' => 'Ꭲ',
+  'ꭳ' => 'Ꭳ',
+  'ꭴ' => 'Ꭴ',
+  'ꭵ' => 'Ꭵ',
+  'ꭶ' => 'Ꭶ',
+  'ꭷ' => 'Ꭷ',
+  'ꭸ' => 'Ꭸ',
+  'ꭹ' => 'Ꭹ',
+  'ꭺ' => 'Ꭺ',
+  'ꭻ' => 'Ꭻ',
+  'ꭼ' => 'Ꭼ',
+  'ꭽ' => 'Ꭽ',
+  'ꭾ' => 'Ꭾ',
+  'ꭿ' => 'Ꭿ',
+  'ꮀ' => 'Ꮀ',
+  'ꮁ' => 'Ꮁ',
+  'ꮂ' => 'Ꮂ',
+  'ꮃ' => 'Ꮃ',
+  'ꮄ' => 'Ꮄ',
+  'ꮅ' => 'Ꮅ',
+  'ꮆ' => 'Ꮆ',
+  'ꮇ' => 'Ꮇ',
+  'ꮈ' => 'Ꮈ',
+  'ꮉ' => 'Ꮉ',
+  'ꮊ' => 'Ꮊ',
+  'ꮋ' => 'Ꮋ',
+  'ꮌ' => 'Ꮌ',
+  'ꮍ' => 'Ꮍ',
+  'ꮎ' => 'Ꮎ',
+  'ꮏ' => 'Ꮏ',
+  'ꮐ' => 'Ꮐ',
+  'ꮑ' => 'Ꮑ',
+  'ꮒ' => 'Ꮒ',
+  'ꮓ' => 'Ꮓ',
+  'ꮔ' => 'Ꮔ',
+  'ꮕ' => 'Ꮕ',
+  'ꮖ' => 'Ꮖ',
+  'ꮗ' => 'Ꮗ',
+  'ꮘ' => 'Ꮘ',
+  'ꮙ' => 'Ꮙ',
+  'ꮚ' => 'Ꮚ',
+  'ꮛ' => 'Ꮛ',
+  'ꮜ' => 'Ꮜ',
+  'ꮝ' => 'Ꮝ',
+  'ꮞ' => 'Ꮞ',
+  'ꮟ' => 'Ꮟ',
+  'ꮠ' => 'Ꮠ',
+  'ꮡ' => 'Ꮡ',
+  'ꮢ' => 'Ꮢ',
+  'ꮣ' => 'Ꮣ',
+  'ꮤ' => 'Ꮤ',
+  'ꮥ' => 'Ꮥ',
+  'ꮦ' => 'Ꮦ',
+  'ꮧ' => 'Ꮧ',
+  'ꮨ' => 'Ꮨ',
+  'ꮩ' => 'Ꮩ',
+  'ꮪ' => 'Ꮪ',
+  'ꮫ' => 'Ꮫ',
+  'ꮬ' => 'Ꮬ',
+  'ꮭ' => 'Ꮭ',
+  'ꮮ' => 'Ꮮ',
+  'ꮯ' => 'Ꮯ',
+  'ꮰ' => 'Ꮰ',
+  'ꮱ' => 'Ꮱ',
+  'ꮲ' => 'Ꮲ',
+  'ꮳ' => 'Ꮳ',
+  'ꮴ' => 'Ꮴ',
+  'ꮵ' => 'Ꮵ',
+  'ꮶ' => 'Ꮶ',
+  'ꮷ' => 'Ꮷ',
+  'ꮸ' => 'Ꮸ',
+  'ꮹ' => 'Ꮹ',
+  'ꮺ' => 'Ꮺ',
+  'ꮻ' => 'Ꮻ',
+  'ꮼ' => 'Ꮼ',
+  'ꮽ' => 'Ꮽ',
+  'ꮾ' => 'Ꮾ',
+  'ꮿ' => 'Ꮿ',
   'a' => 'A',
   'b' => 'B',
   'c' => 'C',
@@ -1069,6 +1226,93 @@ return array(
   '𐑍' => '𐐥',
   '𐑎' => '𐐦',
   '𐑏' => '𐐧',
+  '𐓘' => '𐒰',
+  '𐓙' => '𐒱',
+  '𐓚' => '𐒲',
+  '𐓛' => '𐒳',
+  '𐓜' => '𐒴',
+  '𐓝' => '𐒵',
+  '𐓞' => '𐒶',
+  '𐓟' => '𐒷',
+  '𐓠' => '𐒸',
+  '𐓡' => '𐒹',
+  '𐓢' => '𐒺',
+  '𐓣' => '𐒻',
+  '𐓤' => '𐒼',
+  '𐓥' => '𐒽',
+  '𐓦' => '𐒾',
+  '𐓧' => '𐒿',
+  '𐓨' => '𐓀',
+  '𐓩' => '𐓁',
+  '𐓪' => '𐓂',
+  '𐓫' => '𐓃',
+  '𐓬' => '𐓄',
+  '𐓭' => '𐓅',
+  '𐓮' => '𐓆',
+  '𐓯' => '𐓇',
+  '𐓰' => '𐓈',
+  '𐓱' => '𐓉',
+  '𐓲' => '𐓊',
+  '𐓳' => '𐓋',
+  '𐓴' => '𐓌',
+  '𐓵' => '𐓍',
+  '𐓶' => '𐓎',
+  '𐓷' => '𐓏',
+  '𐓸' => '𐓐',
+  '𐓹' => '𐓑',
+  '𐓺' => '𐓒',
+  '𐓻' => '𐓓',
+  '𐳀' => '𐲀',
+  '𐳁' => '𐲁',
+  '𐳂' => '𐲂',
+  '𐳃' => '𐲃',
+  '𐳄' => '𐲄',
+  '𐳅' => '𐲅',
+  '𐳆' => '𐲆',
+  '𐳇' => '𐲇',
+  '𐳈' => '𐲈',
+  '𐳉' => '𐲉',
+  '𐳊' => '𐲊',
+  '𐳋' => '𐲋',
+  '𐳌' => '𐲌',
+  '𐳍' => '𐲍',
+  '𐳎' => '𐲎',
+  '𐳏' => '𐲏',
+  '𐳐' => '𐲐',
+  '𐳑' => '𐲑',
+  '𐳒' => '𐲒',
+  '𐳓' => '𐲓',
+  '𐳔' => '𐲔',
+  '𐳕' => '𐲕',
+  '𐳖' => '𐲖',
+  '𐳗' => '𐲗',
+  '𐳘' => '𐲘',
+  '𐳙' => '𐲙',
+  '𐳚' => '𐲚',
+  '𐳛' => '𐲛',
+  '𐳜' => '𐲜',
+  '𐳝' => '𐲝',
+  '𐳞' => '𐲞',
+  '𐳟' => '𐲟',
+  '𐳠' => '𐲠',
+  '𐳡' => '𐲡',
+  '𐳢' => '𐲢',
+  '𐳣' => '𐲣',
+  '𐳤' => '𐲤',
+  '𐳥' => '𐲥',
+  '𐳦' => '𐲦',
+  '𐳧' => '𐲧',
+  '𐳨' => '𐲨',
+  '𐳩' => '𐲩',
+  '𐳪' => '𐲪',
+  '𐳫' => '𐲫',
+  '𐳬' => '𐲬',
+  '𐳭' => '𐲭',
+  '𐳮' => '𐲮',
+  '𐳯' => '𐲯',
+  '𐳰' => '𐲰',
+  '𐳱' => '𐲱',
+  '𐳲' => '𐲲',
   '𑣀' => '𑢠',
   '𑣁' => '𑢡',
   '𑣂' => '𑢢',
@@ -1101,4 +1345,70 @@ return array(
   '𑣝' => '𑢽',
   '𑣞' => '𑢾',
   '𑣟' => '𑢿',
+  '𖹠' => '𖹀',
+  '𖹡' => '𖹁',
+  '𖹢' => '𖹂',
+  '𖹣' => '𖹃',
+  '𖹤' => '𖹄',
+  '𖹥' => '𖹅',
+  '𖹦' => '𖹆',
+  '𖹧' => '𖹇',
+  '𖹨' => '𖹈',
+  '𖹩' => '𖹉',
+  '𖹪' => '𖹊',
+  '𖹫' => '𖹋',
+  '𖹬' => '𖹌',
+  '𖹭' => '𖹍',
+  '𖹮' => '𖹎',
+  '𖹯' => '𖹏',
+  '𖹰' => '𖹐',
+  '𖹱' => '𖹑',
+  '𖹲' => '𖹒',
+  '𖹳' => '𖹓',
+  '𖹴' => '𖹔',
+  '𖹵' => '𖹕',
+  '𖹶' => '𖹖',
+  '𖹷' => '𖹗',
+  '𖹸' => '𖹘',
+  '𖹹' => '𖹙',
+  '𖹺' => '𖹚',
+  '𖹻' => '𖹛',
+  '𖹼' => '𖹜',
+  '𖹽' => '𖹝',
+  '𖹾' => '𖹞',
+  '𖹿' => '𖹟',
+  '𞤢' => '𞤀',
+  '𞤣' => '𞤁',
+  '𞤤' => '𞤂',
+  '𞤥' => '𞤃',
+  '𞤦' => '𞤄',
+  '𞤧' => '𞤅',
+  '𞤨' => '𞤆',
+  '𞤩' => '𞤇',
+  '𞤪' => '𞤈',
+  '𞤫' => '𞤉',
+  '𞤬' => '𞤊',
+  '𞤭' => '𞤋',
+  '𞤮' => '𞤌',
+  '𞤯' => '𞤍',
+  '𞤰' => '𞤎',
+  '𞤱' => '𞤏',
+  '𞤲' => '𞤐',
+  '𞤳' => '𞤑',
+  '𞤴' => '𞤒',
+  '𞤵' => '𞤓',
+  '𞤶' => '𞤔',
+  '𞤷' => '𞤕',
+  '𞤸' => '𞤖',
+  '𞤹' => '𞤗',
+  '𞤺' => '𞤘',
+  '𞤻' => '𞤙',
+  '𞤼' => '𞤚',
+  '𞤽' => '𞤛',
+  '𞤾' => '𞤜',
+  '𞤿' => '𞤝',
+  '𞥀' => '𞤞',
+  '𞥁' => '𞤟',
+  '𞥂' => '𞤠',
+  '𞥃' => '𞤡',
 );
index 204a41ba271e343369ecf9a63d617aae7f5271bc..b36a0926f2038e0e51a3646e87f10d4590b53f3a 100644 (file)
 
 use Symfony\Polyfill\Mbstring as p;
 
-if (!function_exists('mb_strlen')) {
-    define('MB_CASE_UPPER', 0);
-    define('MB_CASE_LOWER', 1);
-    define('MB_CASE_TITLE', 2);
-
+if (!function_exists('mb_convert_encoding')) {
     function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
+}
+if (!function_exists('mb_decode_mimeheader')) {
     function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
+}
+if (!function_exists('mb_encode_mimeheader')) {
     function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
+}
+if (!function_exists('mb_decode_numericentity')) {
     function mb_decode_numericentity($s, $convmap, $enc = null) { return p\Mbstring::mb_decode_numericentity($s, $convmap, $enc); }
+}
+if (!function_exists('mb_encode_numericentity')) {
     function mb_encode_numericentity($s, $convmap, $enc = null, $is_hex = false) { return p\Mbstring::mb_encode_numericentity($s, $convmap, $enc, $is_hex); }
+}
+if (!function_exists('mb_convert_case')) {
     function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
+}
+if (!function_exists('mb_internal_encoding')) {
     function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
+}
+if (!function_exists('mb_language')) {
     function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
+}
+if (!function_exists('mb_list_encodings')) {
     function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
+}
+if (!function_exists('mb_encoding_aliases')) {
     function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
+}
+if (!function_exists('mb_check_encoding')) {
     function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
+}
+if (!function_exists('mb_detect_encoding')) {
     function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
+}
+if (!function_exists('mb_detect_order')) {
     function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
+}
+if (!function_exists('mb_parse_str')) {
     function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
+}
+if (!function_exists('mb_strlen')) {
     function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
+}
+if (!function_exists('mb_strpos')) {
     function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
+}
+if (!function_exists('mb_strtolower')) {
     function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
+}
+if (!function_exists('mb_strtoupper')) {
     function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
+}
+if (!function_exists('mb_substitute_character')) {
     function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
+}
+if (!function_exists('mb_substr')) {
     function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
+}
+if (!function_exists('mb_stripos')) {
     function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
+}
+if (!function_exists('mb_stristr')) {
     function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
+}
+if (!function_exists('mb_strrchr')) {
     function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
+}
+if (!function_exists('mb_strrichr')) {
     function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
+}
+if (!function_exists('mb_strripos')) {
     function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
+}
+if (!function_exists('mb_strrpos')) {
     function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
+}
+if (!function_exists('mb_strstr')) {
     function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
+}
+if (!function_exists('mb_get_info')) {
     function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
+}
+if (!function_exists('mb_http_output')) {
     function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
+}
+if (!function_exists('mb_strwidth')) {
     function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
+}
+if (!function_exists('mb_substr_count')) {
     function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
+}
+if (!function_exists('mb_output_handler')) {
     function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
+}
+if (!function_exists('mb_http_input')) {
     function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
+}
+if (!function_exists('mb_convert_variables')) {
     function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
 }
-if (!function_exists('mb_chr')) {
+if (!function_exists('mb_ord')) {
     function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
+}
+if (!function_exists('mb_chr')) {
     function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
+}
+if (!function_exists('mb_scrub')) {
     function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
 }
-
 if (!function_exists('mb_str_split')) {
     function mb_str_split($string, $split_length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $split_length, $encoding); }
 }
+
+if (extension_loaded('mbstring')) {
+    return;
+}
+
+if (!defined('MB_CASE_UPPER')) {
+    define('MB_CASE_UPPER', 0);
+}
+if (!defined('MB_CASE_LOWER')) {
+    define('MB_CASE_LOWER', 1);
+}
+if (!defined('MB_CASE_TITLE')) {
+    define('MB_CASE_TITLE', 2);
+}
index 308f009a10a0dab6632cc54d286a0c115295df2f..69b3cd2285b17e9e7ee7821688d6abb75e22ef57 100644 (file)
     "minimum-stability": "dev",
     "extra": {
         "branch-alias": {
-            "dev-master": "1.12-dev"
+            "dev-master": "1.17-dev"
+        },
+        "thanks": {
+            "name": "symfony/polyfill",
+            "url": "https://github.com/symfony/polyfill"
         }
     }
 }
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/LICENSE b/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/LICENSE
new file mode 100644 (file)
index 0000000..4cd8bdd
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2019 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/Php72.php b/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/Php72.php
new file mode 100644 (file)
index 0000000..9b3edc7
--- /dev/null
@@ -0,0 +1,217 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php72;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * @internal
+ */
+final class Php72
+{
+    private static $hashMask;
+
+    public static function utf8_encode($s)
+    {
+        $s .= $s;
+        $len = \strlen($s);
+
+        for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
+            switch (true) {
+                case $s[$i] < "\x80": $s[$j] = $s[$i]; break;
+                case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break;
+                default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break;
+            }
+        }
+
+        return substr($s, 0, $j);
+    }
+
+    public static function utf8_decode($s)
+    {
+        $s = (string) $s;
+        $len = \strlen($s);
+
+        for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
+            switch ($s[$i] & "\xF0") {
+                case "\xC0":
+                case "\xD0":
+                    $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F");
+                    $s[$j] = $c < 256 ? \chr($c) : '?';
+                    break;
+
+                case "\xF0":
+                    ++$i;
+                    // no break
+
+                case "\xE0":
+                    $s[$j] = '?';
+                    $i += 2;
+                    break;
+
+                default:
+                    $s[$j] = $s[$i];
+            }
+        }
+
+        return substr($s, 0, $j);
+    }
+
+    public static function php_os_family()
+    {
+        if ('\\' === \DIRECTORY_SEPARATOR) {
+            return 'Windows';
+        }
+
+        $map = array(
+            'Darwin' => 'Darwin',
+            'DragonFly' => 'BSD',
+            'FreeBSD' => 'BSD',
+            'NetBSD' => 'BSD',
+            'OpenBSD' => 'BSD',
+            'Linux' => 'Linux',
+            'SunOS' => 'Solaris',
+        );
+
+        return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown';
+    }
+
+    public static function spl_object_id($object)
+    {
+        if (null === self::$hashMask) {
+            self::initHashMask();
+        }
+        if (null === $hash = spl_object_hash($object)) {
+            return;
+        }
+
+        // On 32-bit systems, PHP_INT_SIZE is 4,
+        return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
+    }
+
+    public static function sapi_windows_vt100_support($stream, $enable = null)
+    {
+        if (!\is_resource($stream)) {
+            trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);
+
+            return false;
+        }
+
+        $meta = stream_get_meta_data($stream);
+
+        if ('STDIO' !== $meta['stream_type']) {
+            trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', E_USER_WARNING);
+
+            return false;
+        }
+
+        // We cannot actually disable vt100 support if it is set
+        if (false === $enable || !self::stream_isatty($stream)) {
+            return false;
+        }
+
+        // The native function does not apply to stdin
+        $meta = array_map('strtolower', $meta);
+        $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri'];
+
+        return !$stdin
+            && (false !== getenv('ANSICON')
+            || 'ON' === getenv('ConEmuANSI')
+            || 'xterm' === getenv('TERM')
+            || 'Hyper' === getenv('TERM_PROGRAM'));
+    }
+
+    public static function stream_isatty($stream)
+    {
+        if (!\is_resource($stream)) {
+            trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);
+
+            return false;
+        }
+
+        if ('\\' === \DIRECTORY_SEPARATOR) {
+            $stat = @fstat($stream);
+            // Check if formatted mode is S_IFCHR
+            return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
+        }
+
+        return \function_exists('posix_isatty') && @posix_isatty($stream);
+    }
+
+    private static function initHashMask()
+    {
+        $obj = (object) array();
+        self::$hashMask = -1;
+
+        // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
+        $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
+        foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
+            if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
+                $frame['line'] = 0;
+                break;
+            }
+        }
+        if (!empty($frame['line'])) {
+            ob_start();
+            debug_zval_dump($obj);
+            self::$hashMask = (int) substr(ob_get_clean(), 17);
+        }
+
+        self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
+    }
+
+    public static function mb_chr($code, $encoding = null)
+    {
+        if (0x80 > $code %= 0x200000) {
+            $s = \chr($code);
+        } elseif (0x800 > $code) {
+            $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
+        } elseif (0x10000 > $code) {
+            $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
+        } else {
+            $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
+        }
+
+        if ('UTF-8' !== $encoding) {
+            $s = mb_convert_encoding($s, $encoding, 'UTF-8');
+        }
+
+        return $s;
+    }
+
+    public static function mb_ord($s, $encoding = null)
+    {
+        if (null == $encoding) {
+            $s = mb_convert_encoding($s, 'UTF-8');
+        } elseif ('UTF-8' !== $encoding) {
+            $s = mb_convert_encoding($s, 'UTF-8', $encoding);
+        }
+
+        if (1 === \strlen($s)) {
+            return \ord($s);
+        }
+
+        $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
+        if (0xF0 <= $code) {
+            return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
+        }
+        if (0xE0 <= $code) {
+            return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
+        }
+        if (0xC0 <= $code) {
+            return (($code - 0xC0) << 6) + $s[2] - 0x80;
+        }
+
+        return $code;
+    }
+}
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/README.md b/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/README.md
new file mode 100644 (file)
index 0000000..59dec8a
--- /dev/null
@@ -0,0 +1,28 @@
+Symfony Polyfill / Php72
+========================
+
+This component provides functions added to PHP 7.2 core:
+
+- [`spl_object_id`](https://php.net/spl_object_id)
+- [`stream_isatty`](https://php.net/stream_isatty)
+
+On Windows only:
+
+- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support)
+
+Moved to core since 7.2 (was in the optional XML extension earlier):
+
+- [`utf8_encode`](https://php.net/utf8_encode)
+- [`utf8_decode`](https://php.net/utf8_decode)
+
+Also, it provides constants added to PHP 7.2:
+- [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig)
+- [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family)
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/bootstrap.php b/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/bootstrap.php
new file mode 100644 (file)
index 0000000..a27a900
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Php72 as p;
+
+if (PHP_VERSION_ID >= 70200) {
+    return;
+}
+
+if (!defined('PHP_FLOAT_DIG')) {
+    define('PHP_FLOAT_DIG', 15);
+}
+if (!defined('PHP_FLOAT_EPSILON')) {
+    define('PHP_FLOAT_EPSILON', 2.2204460492503E-16);
+}
+if (!defined('PHP_FLOAT_MIN')) {
+    define('PHP_FLOAT_MIN', 2.2250738585072E-308);
+}
+if (!defined('PHP_FLOAT_MAX')) {
+    define('PHP_FLOAT_MAX', 1.7976931348623157E+308);
+}
+if (!defined('PHP_OS_FAMILY')) {
+    define('PHP_OS_FAMILY', p\Php72::php_os_family());
+}
+
+if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
+    function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
+}
+if (!function_exists('stream_isatty')) {
+    function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
+}
+if (!function_exists('utf8_encode')) {
+    function utf8_encode($s) { return p\Php72::utf8_encode($s); }
+}
+if (!function_exists('utf8_decode')) {
+    function utf8_decode($s) { return p\Php72::utf8_decode($s); }
+}
+if (!function_exists('spl_object_id')) {
+    function spl_object_id($s) { return p\Php72::spl_object_id($s); }
+}
+if (!function_exists('mb_ord')) {
+    function mb_ord($s, $enc = null) { return p\Php72::mb_ord($s, $enc); }
+}
+if (!function_exists('mb_chr')) {
+    function mb_chr($code, $enc = null) { return p\Php72::mb_chr($code, $enc); }
+}
+if (!function_exists('mb_scrub')) {
+    function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
+}
diff --git a/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/composer.json b/wcfsetup/install/files/lib/system/api/symfony/polyfill-php72/composer.json
new file mode 100644 (file)
index 0000000..314d713
--- /dev/null
@@ -0,0 +1,31 @@
+{
+    "name": "symfony/polyfill-php72",
+    "type": "library",
+    "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+    "keywords": ["polyfill", "shim", "compatibility", "portable"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.3"
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Polyfill\\Php72\\": "" },
+        "files": [ "bootstrap.php" ]
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.17-dev"
+        }
+    }
+}
index 675a807fd248dcf3d0f115db2b013c569b33f190..b3a95ffcb055ed6f3b79e6f502cff522baf4ced1 100644 (file)
@@ -200,8 +200,9 @@ class ApplicationHandler extends SingletonFactory {
                $protocolRegex = new Regex('^https(?=://)');
                if (empty($this->pageURLs)) {
                        foreach ($this->getApplications() as $application) {
-                               $this->pageURLs[] = preg_replace('~/$~', '', $protocolRegex->replace($application->getPageURL(), 'http'));
+                               $this->pageURLs[] = preg_replace('~/$~', '', $protocolRegex->replace(RouteHandler::getProtocol() . $application->domainName, 'http'));
                        }
+                       $this->pageURLs = array_unique($this->pageURLs);
                }
                
                foreach ($this->pageURLs as $pageURL) {
diff --git a/wcfsetup/install/files/lib/system/background/job/DownloadStyleLogoJob.class.php b/wcfsetup/install/files/lib/system/background/job/DownloadStyleLogoJob.class.php
new file mode 100644 (file)
index 0000000..b4b203c
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+namespace wcf\system\background\job;
+use GuzzleHttp\Psr7\Request;
+use wcf\data\style\Style;
+use wcf\data\style\StyleEditor;
+use wcf\system\io\HttpFactory;
+use wcf\util\Url;
+
+/**
+ * Downloads the style's logo and stores it locally within the style's asset path.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Background\Job
+ * @since      5.3
+ * @deprecated 5.3 - This background job is used for the upgrade from 5.2 to 5.3.
+ */
+class DownloadStyleLogoJob extends AbstractBackgroundJob {
+       /**
+        * @inheritDoc
+        */
+       const MAX_FAILURES = 5;
+       
+       /**
+        * @var int
+        */
+       protected $styleID;
+       
+       public function __construct(Style $style) {
+               $this->styleID = $style->styleID;
+       }
+       
+       /**
+        * @return      int     every 10 minutes
+        */
+       public function retryAfter() {
+               return 10 * 60;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function perform() {
+               $style = new Style($this->styleID);
+               if (!$style->styleID) return;
+               $styleEditor = new StyleEditor($style);
+               
+               $style->loadVariables();
+               $variables = $style->getVariables();
+               
+               $http = HttpFactory::makeClient([
+                       'timeout' => 10,
+               ]);
+               
+               foreach (['pageLogo', 'pageLogoMobile'] as $type) {
+                       if ($variables[$type] && Url::is($variables[$type])) {
+                               $extension = pathinfo(Url::parse($variables[$type])['path'], PATHINFO_EXTENSION);
+                               
+                               if (in_array($extension, ['gif','png','jpg','jpeg','svg','webp'])) {
+                                       $newLocation = $type . '.' . $extension;
+                                       
+                                       $http->send(new Request('GET', $variables[$type]), [
+                                               'sink' => $style->getAssetPath() . $newLocation,
+                                       ]);
+                                       
+                                       $variables[$type] = $newLocation;
+                               }
+                               else {
+                                       $variables[$type] = '';
+                               }
+                               
+                               $styleEditor->setVariables($variables);
+                       }
+               }
+               StyleEditor::resetCache();
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/background/job/NotificationEmailDeliveryBackgroundJob.class.php b/wcfsetup/install/files/lib/system/background/job/NotificationEmailDeliveryBackgroundJob.class.php
new file mode 100644 (file)
index 0000000..96d2a71
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+namespace wcf\system\background\job;
+use wcf\data\user\notification\UserNotification;
+use wcf\data\user\User;
+use wcf\system\session\SessionHandler;
+use wcf\system\user\notification\event\IUserNotificationEvent;
+use wcf\system\user\notification\UserNotificationHandler;
+use wcf\system\WCF;
+
+/**
+ * A NotificationEmailDelivery wraps EmailDeliverys and skips sending if the given associated
+ * notification is no longer valid.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Background\Job
+ * @since      5.3
+ */
+class NotificationEmailDeliveryBackgroundJob extends AbstractBackgroundJob {
+       const MAX_FAILURES = EmailDeliveryBackgroundJob::MAX_FAILURES;
+
+       /**
+        * @var EmailDeliveryBackgroundJob
+        */
+       private $job;
+       
+       /**
+        * @var int
+        */
+       private $notificationID;
+       
+       /**
+        * Wraps the given EmailDeliveryBackgroundJob and associates it with the given notification.
+        * 
+        * The recipient is technically redundant, because the information can be retrieved using $notification->userID,
+        * the value is used as a safety check within the constructor to make sure all the checks run against the expected
+        * user.
+        * 
+        * @param EmailDeliveryBackgroundJob $job 
+        * @param User $recipient
+        * @param UserNotification $notification 
+        */
+       public function __construct(EmailDeliveryBackgroundJob $job, UserNotification $notification, User $recipient) {
+               $this->job = $job;
+               $this->notificationID = $notification->notificationID;
+               
+               if ($notification->userID != $recipient->userID) {
+                       throw new \InvalidArgumentException("Mismatching userIDs within notification (".$notification->userID.") and recipient (".$recipient->userID.").");
+               }
+       }
+       
+       /**
+        * Pass the failure along to the inner job to benefit from the retryAfter() logic.
+        */
+       public function onFailure() {
+               $this->job->fail();
+       }
+
+       /**
+        * Inherit the retryAfter logic of the inner job.
+        */
+       public function retryAfter() {
+               return $this->job->retryAfter();
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function perform() {
+               // see UserNotificationHandler::fetchNotifications()
+               $sql = "SELECT          notification.*, notification_event.eventID, object_type.objectType
+                       FROM            wcf".WCF_N."_user_notification notification
+                       LEFT JOIN       wcf".WCF_N."_user_notification_event notification_event
+                       ON              (notification_event.eventID = notification.eventID)
+                       LEFT JOIN       wcf".WCF_N."_object_type object_type
+                       ON              (object_type.objectTypeID = notification_event.objectTypeID)
+                       WHERE           notification.notificationID = ?
+                       ORDER BY        notification.time DESC";
+               $statement = WCF::getDB()->prepareStatement($sql, 1);
+               $statement->execute([$this->notificationID]);
+               
+               /** @var UserNotification $notification */
+               $notification = $statement->fetchObject(UserNotification::class);
+               $statement->closeCursor();
+
+               // Drop email if the notification is deleted.
+               if (!$notification || !$notification->notificationID) {
+                       return;
+               }
+               
+               $user = WCF::getUser();
+               try {
+                       // Switch user, because processNotifications() checks the permissions as the current user.
+                       SessionHandler::getInstance()->changeUser(new User($notification->userID), true);
+                       
+                       $processedNotifications = UserNotificationHandler::getInstance()->processNotifications([$notification]);
+                       
+                       // Drop email if the processing dropped the notification (most likely due to a lack of permissions).
+                       if ($processedNotifications['count'] == 0) {
+                               return;
+                       }
+                       
+                       // If no notification was dropped we expect to get back exactly one notification ...
+                       if ($processedNotifications['count'] != 1) {
+                               throw new \LogicException("Unreachable");
+                       }
+                       
+                       $processedNotification = $processedNotifications['notifications'][0];
+
+                       // ... and we expect that this one notification is the one we passed in.
+                       if ($processedNotification['notificationID'] != $notification->notificationID) {
+                               throw new \LogicException("Unreachable");
+                       }
+                       
+                       /** @var IUserNotificationEvent $event */
+                       $event = $processedNotification['event'];
+                       
+                       // Drop email if the notification is already confirmed.
+                       if ($event->isConfirmed()) {
+                               return;
+                       }
+               }
+               finally {
+                       SessionHandler::getInstance()->changeUser($user, true);
+               }
+               
+               // If none of the checks failed we can send the notification after we switched
+               // back to the regular user (guest within the context of the queue).
+               $this->job->perform();
+       }
+}
index 24a33bace2874b821505982c0cd0950169343d7b..427d2bddcb4e91663c34f01c2e456880f70c00ec 100644 (file)
@@ -107,7 +107,7 @@ class AttachmentBBCode extends AbstractBBCode {
                                                $class = 'messageFloatObject'.ucfirst($alignment);
                                        }
                                        
-                                       $source = StringUtil::encodeHTML(LinkHandler::getInstance()->getLink('Attachment', ['object' => $attachment]));
+                                       $source = StringUtil::encodeHTML($attachment->getLink());
                                        $title = StringUtil::encodeHTML($attachment->filename);
                                        
                                        if ($parser instanceof HtmlBBCodeParser && $parser->getIsGoogleAmp()) {
@@ -160,14 +160,18 @@ class AttachmentBBCode extends AbstractBBCode {
                        else if (substr($attachment->fileType, 0, 6) === 'video/' && $parser->getOutputType() == 'text/html') {
                                return WCF::getTPL()->fetch('__videoAttachmentBBCode', 'wcf', [
                                        'attachment' => $attachment,
-                                       'attachmentIdentifier' => StringUtil::getRandomID()
+                                       'attachmentIdentifier' => StringUtil::getRandomID(),
+                               ]);
+                       }
+                       else if (substr($attachment->fileType, 0, 6) === 'audio/' && $parser->getOutputType() == 'text/html') {
+                               return WCF::getTPL()->fetch('__audioAttachmentBBCode', 'wcf', [
+                                       'attachment' => $attachment,
+                                       'attachmentIdentifier' => StringUtil::getRandomID(),
                                ]);
                        }
                        else {
                                // file
-                               return StringUtil::getAnchorTag(LinkHandler::getInstance()->getLink('Attachment', [
-                                       'object' => $attachment
-                               ]), $attachment->filename);
+                               return StringUtil::getAnchorTag($attachment->getLink(), $attachment->filename);
                        }
                }
                
index 49fca2711bb6b9764324dcb66f6eb1f8b092a86d..f0ecae44729b015815e992bfa958c375cbd61d15 100644 (file)
@@ -23,7 +23,7 @@ class MediaBBCode extends AbstractBBCode {
                        foreach (BBCodeMediaProvider::getCache() as $provider) {
                                if ($provider->matches($content)) {
                                        if ($parser instanceof HtmlBBCodeParser && $parser->getIsGoogleAmp()) {
-                                               return StringUtil::getAnchorTag($content);
+                                               return StringUtil::getAnchorTag($content, '', true, true);
                                        }
                                        else {
                                                return $provider->getOutput($content);
@@ -34,7 +34,7 @@ class MediaBBCode extends AbstractBBCode {
                else if ($parser->getOutputType() == 'text/simplified-html' && !$parser->getRemoveLinks()) {
                        foreach (BBCodeMediaProvider::getCache() as $provider) {
                                if ($provider->matches($content)) {
-                                       return StringUtil::getAnchorTag($content);
+                                       return StringUtil::getAnchorTag($content, '', true, true);
                                }
                        }
                }
index ff1b66526a4e72c38171ae8f3d0bd14751eb5ace..f9150502b24fa2e4df812960c8cd0eff632f1e9a 100644 (file)
@@ -201,7 +201,7 @@ class SimpleMessageParser extends SingletonFactory {
                                $url = 'http://'.$url;
                        }
                        
-                       $text = str_replace($hash, StringUtil::getAnchorTag($url), $text);
+                       $text = str_replace($hash, StringUtil::getAnchorTag($url, '', true, true), $text);
                }
                
                foreach ($this->cachedEmails as $hash => $email) {
index 332c2a9adb2450900b86e1d6016bb9dbeb5109b3..5c7532d81dd33a0a87b97fd11268339cc1c1b644 100644 (file)
@@ -36,6 +36,16 @@ class WoltLabSuiteMediaBBCode extends AbstractBBCode {
                if ($parser instanceof HtmlBBCodeParser && $parser->getRemoveLinks()) {
                        $removeLinks = true;
                }
+               else {
+                       /** @var \DOMElement $element */
+                       $element = $closingTag['__parents'][0] ?? null;
+                       if ($element && $element->nodeName === 'a') {
+                               // We do permit media elements to be nested inside a link, but we must suppress
+                               // the thumbnail link to be generated. Removing the link technically is meant
+                               // to be something else, but we use it here for backward compatibility.
+                               $removeLinks = true;
+                       }
+               }
                
                /** @var ViewableMedia $media */
                $media = MessageEmbeddedObjectManager::getInstance()->getObject('com.woltlab.wcf.media', $mediaID);
index 62c0e736e7e01278eebd480837d18f832e5c0598..cdd75f3b73bfb24da61cd2b4b173538cccdc5693 100644 (file)
@@ -13,7 +13,7 @@ use wcf\system\WCF;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Box
  */
-class TagCloudBoxController extends AbstractBoxController {
+abstract class TagCloudBoxController extends AbstractBoxController {
        /**
         * @inheritDoc
         */
index c25cb7b6447c85ccd51814e5d4fae4aa8ea3b6d5..aee80c2aeffb55668af434ef4972386421673682 100644 (file)
@@ -4,6 +4,7 @@ use wcf\data\DatabaseObject;
 use wcf\data\user\option\UserOption;
 use wcf\system\cache\builder\UserOptionCacheBuilder;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
+use wcf\system\condition\IObjectCondition;
 use wcf\system\user\UserBirthdayCache;
 use wcf\system\WCF;
 use wcf\util\DateUtil;
@@ -23,6 +24,12 @@ class TodaysBirthdaysBoxController extends AbstractDatabaseObjectListBoxControll
         */
        protected static $supportedPositions = ['sidebarLeft', 'sidebarRight'];
        
+       /**
+        * @inheritDoc
+        * @since       5.3
+        */
+       protected $conditionDefinition = 'com.woltlab.wcf.box.todaysBirthdays.condition';
+       
        /**
         * template name
         * @var string
@@ -96,6 +103,14 @@ class TodaysBirthdaysBoxController extends AbstractDatabaseObjectListBoxControll
                                        // show a maximum of x users
                                        if ($i == $this->limit) break;
                                        
+                                       foreach ($this->box->getConditions() as $condition) {
+                                               /** @var IObjectCondition $processor */
+                                               $processor = $condition->getObjectType()->getProcessor();
+                                               if (!$processor->checkObject($userProfile->getDecoratedObject(), $condition->conditionData)) {
+                                                       continue 2;
+                                               }
+                                       }
+                                       
                                        $birthdayUserOption->setUser($userProfile->getDecoratedObject());
                                        
                                        if (!$userProfile->isProtected() && $birthdayUserOption->isVisible() && substr($userProfile->birthday, 5) == $currentDay) {
@@ -109,7 +124,9 @@ class TodaysBirthdaysBoxController extends AbstractDatabaseObjectListBoxControll
                                        DatabaseObject::sort($visibleUserProfiles, $this->sortField, $this->sortOrder);
                                        
                                        $this->content = WCF::getTPL()->fetch($this->templateName, 'wcf', [
-                                               'birthdayUserProfiles' => $visibleUserProfiles
+                                               'birthdayUserProfiles' => $visibleUserProfiles,
+                                               'sortField' => $this->sortField,
+                                               'sortOrder' => $this->sortOrder,
                                        ], true);
                                }
                        }
index ffbf21308e81c4c72e3b5063b804230a9fcf2ef3..65a7ca0f76ec97b2556b68f4078ec619f9c1f548 100644 (file)
@@ -12,6 +12,12 @@ use wcf\system\WCF;
  * @since      3.0
  */
 class TodaysFollowingBirthdaysBoxController extends TodaysBirthdaysBoxController {
+       /**
+        * @inheritDoc
+        * @since       5.3
+        */
+       protected $conditionDefinition = 'com.woltlab.wcf.box.todaysFollowingBirthdays.condition';
+       
        /**
         * @inheritDoc
         */
index 0771c0c6a5d9d033f18994d86440ce6ebc75aba6..7af672c311e09af4ba17723323093b16c75c8752 100644 (file)
@@ -1,11 +1,13 @@
 <?php
 namespace wcf\system\box;
+use wcf\data\condition\Condition;
 use wcf\data\user\UserProfileList;
 use wcf\data\DatabaseObject;
 use wcf\system\cache\builder\MostActiveMembersCacheBuilder;
 use wcf\system\cache\builder\MostLikedMembersCacheBuilder;
 use wcf\system\cache\builder\NewestMembersCacheBuilder;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
+use wcf\system\condition\IObjectListCondition;
 use wcf\system\event\EventHandler;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
@@ -30,6 +32,11 @@ class UserListBoxController extends AbstractDatabaseObjectListBoxController {
                'registrationDate' => NewestMembersCacheBuilder::class
        ];
        
+       /**
+        * @inheritDoc
+        */
+       protected $conditionDefinition = 'com.woltlab.wcf.box.userList.condition';
+       
        /**
         * @inheritDoc
         */
@@ -88,9 +95,14 @@ class UserListBoxController extends AbstractDatabaseObjectListBoxController {
        protected function getObjectList() {
                // use specialized cache builders
                if ($this->sortOrder && $this->sortField && isset($this->cacheBuilders[$this->sortField])) {
+                       $conditions = array_filter($this->box->getConditions(), function(Condition $condition) {
+                               return $condition->getObjectType()->getProcessor() instanceof IObjectListCondition;
+                       });
+                       
                        $this->userIDs = call_user_func([$this->cacheBuilders[$this->sortField], 'getInstance'])->getData([
-                               'limit' => $this->limit,
-                               'sortOrder' => $this->sortOrder
+                               'conditions' => $conditions,
+                               'limit' => $this->limit, 
+                               'sortOrder' => $this->sortOrder,
                        ]);
                }
                
index a1e0a4c31889f5c13b301df810fa16e68789ebd1..b6cf1cff55f23bccf1db3ff3fef0b19798210839 100644 (file)
@@ -22,6 +22,11 @@ class UserOnlineListBoxController extends AbstractDatabaseObjectListBoxControlle
         */
        protected static $supportedPositions = ['footerBoxes', 'sidebarLeft', 'sidebarRight'];
        
+       /**
+        * @inheritDoc
+        */
+       protected $conditionDefinition = 'com.woltlab.wcf.box.userOnlineList.condition';
+       
        /**
         * enables the display of the user online record
         * @var boolean
index 495c02975349a33d878aef9dc5df5c24dea935ff..39e77086aeb80bc26819e238f1d3de8a7e749c11 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\box;
+use wcf\data\user\online\UserOnline;
 use wcf\data\user\online\UsersOnlineList;
 use wcf\data\user\UserProfile;
 use wcf\data\DatabaseObject;
@@ -102,7 +103,7 @@ class WhoWasOnlineBoxController extends AbstractDatabaseObjectListBoxController
                        });
                        foreach ($this->users as $key => $user) {
                                // remove invisible users
-                               if (!UsersOnlineList::isVisible($user->userID, $user->canViewOnlineStatus)) {
+                               if (!UsersOnlineList::isVisibleUser(new UserOnline($user->getDecoratedObject()))) {
                                        unset($this->users[$key]);
                                }
                        }
index 45fe0c346c545ea4919b53f7cac15b8b71e9c4db..c5240cce4c83cea5c9694ecb8ca665585af1d36e 100644 (file)
@@ -45,11 +45,7 @@ abstract class AbstractUserGroupsUserBulkProcessingAction extends AbstractUserBu
        public function __construct(DatabaseObject $object) {
                parent::__construct($object);
                
-               $this->availableUserGroups = UserGroup::getAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::OWNER, UserGroup::USERS]);
-               
-               uasort($this->availableUserGroups, function(UserGroup $groupA, UserGroup $groupB) {
-                       return strcmp($groupA->getName(), $groupB->getName());
-               });
+               $this->availableUserGroups = UserGroup::getSortedAccessibleGroups([], [UserGroup::GUESTS, UserGroup::EVERYONE, UserGroup::OWNER, UserGroup::USERS]);
        }
        
        /**
index 281c454818b1ad36e48ca0bab189430f4f900520..fee3852aec066ea5a59f8b7dcce6a574e25b378e 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 namespace wcf\system\cache\builder;
+use wcf\data\condition\Condition;
 use wcf\data\user\UserList;
+use wcf\system\condition\IObjectListCondition;
 
 /**
  * Caches a list of the newest members.
@@ -54,6 +56,14 @@ abstract class AbstractSortedUserCacheBuilder extends AbstractCacheBuilder {
                if ($this->positiveValuesOnly) {
                        $userProfileList->getConditionBuilder()->add('user_table.'.$this->sortField.' > ?', [0]);
                }
+               if (isset($parameters['conditions'])) {
+                       /** @var Condition $condition */
+                       foreach ($parameters['conditions'] as $condition) {
+                               /** @var IObjectListCondition $processor */
+                               $processor = $condition->getObjectType()->getProcessor();
+                               $processor->addObjectListCondition($userProfileList, $condition->conditionData);
+                       }
+               }
                $userProfileList->sqlOrderBy = 'user_table.'.$this->sortField.' '.$sortOrder;
                $userProfileList->sqlLimit = !empty($parameters['limit']) ? $parameters['limit'] : $this->defaultLimit;
                $userProfileList->readObjectIDs();
index 5ab18451c7aea32c0ab743350573a978fac9ac6c..d7ce616d4c0f16d619b118ecd717d76f05ea65db 100644 (file)
@@ -40,32 +40,35 @@ class EventListenerCacheBuilder extends AbstractCacheBuilder {
                /** @var EventListener $eventListener */
                while ($eventListener = $statement->fetchObject(EventListener::class)) {
                        $eventNames = $eventListener->getEventNames();
+                       $environments = $eventListener->environment == 'all' ? ['admin', 'user'] : [$eventListener->environment];
                        
-                       if (!$eventListener->inherit) {
-                               if (!isset($actions[$eventListener->environment])) {
-                                       $actions[$eventListener->environment] = [];
-                               }
-                               
-                               foreach ($eventNames as $eventName) {
-                                       $key = EventHandler::generateKey($eventListener->eventClassName, $eventName);
-                                       if (!isset($actions[$eventListener->environment][$key])) {
-                                               $actions[$eventListener->environment][$key] = [];
+                       foreach ($environments as $environment) {
+                               if (!$eventListener->inherit) {
+                                       if (!isset($actions[$environment])) {
+                                               $actions[$environment] = [];
                                        }
                                        
-                                       $actions[$eventListener->environment][$key][] = $eventListener;
-                               }
-                       }
-                       else {
-                               if (!isset($inheritedActions[$eventListener->environment])) {
-                                       $inheritedActions[$eventListener->environment] = [];
-                               }
-                               
-                               foreach ($eventNames as $eventName) {
-                                       if (!isset($inheritedActions[$eventListener->environment][$eventListener->eventClassName])) {
-                                               $inheritedActions[$eventListener->environment][$eventListener->eventClassName] = [];
+                                       foreach ($eventNames as $eventName) {
+                                               $key = EventHandler::generateKey($eventListener->eventClassName, $eventName);
+                                               if (!isset($actions[$environment][$key])) {
+                                                       $actions[$environment][$key] = [];
+                                               }
+                                               
+                                               $actions[$environment][$key][] = $eventListener;
+                                       }
+                               } 
+                               else {
+                                       if (!isset($inheritedActions[$environment])) {
+                                               $inheritedActions[$environment] = [];
                                        }
                                        
-                                       $inheritedActions[$eventListener->environment][$eventListener->eventClassName][$eventName][] = $eventListener;
+                                       foreach ($eventNames as $eventName) {
+                                               if (!isset($inheritedActions[$environment][$eventListener->eventClassName])) {
+                                                       $inheritedActions[$environment][$eventListener->eventClassName] = [];
+                                               }
+                                               
+                                               $inheritedActions[$environment][$eventListener->eventClassName][$eventName][] = $eventListener;
+                                       }
                                }
                        }
                }
index 6594fe880aa1bc6202739669ec5c532115c4698d..d62035b6e124b8c2cf8ce974b7318ffea995c5cb 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 namespace wcf\system\cache\builder;
-use wcf\data\user\User;
+use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\WCF;
 
 /**
@@ -31,12 +31,12 @@ class UserStatsCacheBuilder extends AbstractCacheBuilder {
                $data['members'] = $statement->fetchColumn();
                
                // newest member
-               $sql = "SELECT          *
+               $sql = "SELECT          userID
                        FROM            wcf".WCF_N."_user
                        ORDER BY        userID DESC";
                $statement = WCF::getDB()->prepareStatement($sql, 1);
                $statement->execute();
-               $data['newestMember'] = $statement->fetchObject(User::class);
+               $data['newestMember'] = UserProfileRuntimeCache::getInstance()->getObject($statement->fetchSingleColumn());
                
                return $data;
        }
index 6eea807cc0c223fa2ed7b85438f84d9a0190c182..39544679fe9c78283ba0f5e07c48d62fc004f8e5 100644 (file)
@@ -123,17 +123,6 @@ class ImportCLICommand implements ICLICommand {
                        return;
                }
                
-               if (PACKAGE_ID == 1) {
-                       CLIWCF::getReader()->println(StringUtil::stripHTML(WCF::getLanguage()->get('wcf.acp.dataImport.cli.info.wcf')));
-                       
-                       $answer = CLIWCF::getReader()->readLine('> ');
-                       if ($answer === null) exit;
-                       if (mb_strtolower($answer) != 'y') {
-                               CLIWCF::getReader()->setHistoryEnabled(true);
-                               return;
-                       }
-               }
-               
                // step 1) previous import
                $sql = "SELECT  COUNT(*)
                        FROM    wcf".WCF_N."_import_mapping";
index b705dfe4888181ad174adf7891f9c32b1d7d44f9..f7b392793722f8a2858fa7e55054b8821f5abd92 100644 (file)
@@ -143,7 +143,7 @@ class PackageCLICommand implements IArgumentedCLICommand {
                                $this->error('noValidInstall');
                        }
                        else if ($archive->getPackageInfo('isApplication') && $archive->hasUniqueAbbreviation()) {
-                               $this->error('noUniqueAbbrevation');
+                               $this->error('noUniqueAbbreviation');
                        }
                        else if ($archive->isAlreadyInstalled()) {
                                $this->error('uniqueAlreadyInstalled');
index 869d9f15d9bd17fd204c89468acbc0ca45ca8b42..5601f48c478d87d61cbc287c282020312bbe0313 100644 (file)
@@ -3,9 +3,11 @@ namespace wcf\system\cli\command;
 use phpline\internal\Log;
 use wcf\system\worker\IWorker;
 use wcf\system\CLIWCF;
+use wcf\system\io\File;
 use wcf\system\Regex;
 use wcf\util\CLIUtil;
 use wcf\util\DirectoryUtil;
+use wcf\util\JSON;
 use wcf\util\StringUtil;
 use Zend\Console\Exception\RuntimeException as ArgvException;
 use Zend\Console\Getopt as ArgvParser;
@@ -16,7 +18,7 @@ use Zend\ProgressBar\ProgressBar;
  * Executes cronjobs.
  * 
  * @author     Tim Duesterhus
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Cli\Command
  */
@@ -33,7 +35,9 @@ class WorkerCLICommand implements IArgumentedCLICommand {
        public function __construct() {
                $this->argv = new ArgvParser([
                        'l|list' => CLIWCF::getLanguage()->get('wcf.cli.worker.list'),
-                       'setParameter=s' => CLIWCF::getLanguage()->get('wcf.cli.worker.setParameter')
+                       'setParameter=s' => CLIWCF::getLanguage()->get('wcf.cli.worker.setParameter'),
+                       'threads=i' => CLIWCF::getLanguage()->get('wcf.cli.worker.threads'),
+                       'threadId=i' => CLIWCF::getLanguage()->get('wcf.cli.worker.threadId'),
                ]);
                $this->argv->setOptions([
                        ArgvParser::CONFIG_FREEFORM_FLAGS => true,
@@ -54,6 +58,19 @@ class WorkerCLICommand implements IArgumentedCLICommand {
                        return;
                }
                
+               $threads = 1;
+               $threadId = null;
+               if ($this->argv->threads !== null) {
+                       $threads = $this->argv->threads;
+                       if ($this->argv->threadId !== null) {
+                               $threadId = $this->argv->threadId;
+                               if ($this->argv->threadId >= $this->argv->threads) {
+                                       CLIWCF::getReader()->println(CLIWCF::getLanguage()->get('wcf.cli.worker.threadId.invalid'));
+                                       return;
+                               }
+                       }
+               }
+               
                $args = $this->argv->getRemainingArgs();
                // validate parameters
                if (count($args) != 1) {
@@ -109,28 +126,264 @@ class WorkerCLICommand implements IArgumentedCLICommand {
                $worker->validate();
                $worker->getProgress(); // make sure objects are counted
                
-               // initialize progressbar
+               // If multithreading is requested, but no threadId is given then this
+               // is the controller process invoked by the Administrator.
+               if ($threads > 1 && $threadId === null) {
+                       if (PHP_EOL === "\r\n") {
+                               CLIWCF::getReader()->println(CLIWCF::getLanguage()->get('wcf.cli.worker.threads.windows'));
+                               return;
+                       }
+                       $this->spawnController($worker, $threads);
+                       return;
+               }
+               
                $progressbar = new ProgressBar(new ConsoleProgressBar([
                        'width' => CLIWCF::getTerminal()->getWidth()
                ]));
                $progress = 0;
-               for ($i = 0; $progress < 100; $i++) {
-                       $worker->setLoopCount($i);
-                       $worker->validate();
-                       
-                       // execute worker
-                       $worker->execute();
-                       $worker->finalize();
-                       
-                       // update progress
-                       $progress = $worker->getProgress();
-                       $progressbar->update($progress);
+               $output = null;
+               if (!empty($_ENV['WCF_WORKER_STATUS_FD'])) {
+                       $output = new File("php://fd/".$_ENV['WCF_WORKER_STATUS_FD'], "w");
+               }
+               try {
+                       for ($i = ($threadId !== null ? ($threadId + 1) : 0); $progress < 100; $i += $threads) {
+                               $worker->setLoopCount($i);
+                               $worker->validate();
+                               
+                               // execute worker
+                               $worker->execute();
+                               $worker->finalize();
+                               
+                               // update progress
+                               $progress = $worker->getProgress();
+                               $progressbar->update($progress);
+                               if ($output) {
+                                       $output->write(JSON::encode([
+                                               'iteration' => $i,
+                                               'progress' => $progress,
+                                       ])."\n");
+                               }
+                       }
+               }
+               catch (\Exception $e) {
+                       if ($output) {
+                               $output->write(JSON::encode([
+                                       'error' => (string) $e,
+                               ]));
+                       }
+                       throw $e;
+               }
+               if ($output) {
+                       $output->write(JSON::encode([
+                               'finished' => true,
+                               'progress' => $progress,
+                       ])."\n");
+                       $output->close();
                }
                $progressbar->update($progress);
                
                $progressbar->finish();
        }
        
+       /**
+        * Contains the logic of the parent controller process in multithreading mode.
+        */
+       protected function spawnController(IWorker $worker, $threads) {
+               // Perform the first iteration before spawning the worker processes.
+               // The first iteration is usually used to perform clean-up operations
+               // that might interfere with the rebuilding happening within the workers.
+               $worker->setLoopCount(0);
+               $worker->validate();
+               $worker->execute();
+               $worker->finalize();
+               
+               $fileDescriptors = [
+                       // Bind STDIN to a pipe to allow sending the command.
+                       0 => ["pipe", "r"],
+                       // Close STDOUT / STDERR.
+                       1 => ["file", "/dev/null", "a"],
+                       2 => ["file", "/dev/null", "a"],
+                       // Open a pipe as a communication channel for status updates.
+                       3 => ["pipe", "w"],
+               ];
+               
+               // Invoke the worker processes with the same command line ...
+               $arguments = $_SERVER['argv'];
+               // ... with the quiet argument ...
+               $arguments[] = '-qqqqq';
+               // ... and requesting an unclean exit of an Exception is thrown.
+               $arguments[] = '--exitOnFail';
+               $commandLine = PHP_BINARY.' '.implode(' ', array_map('escapeshellarg', $arguments));
+               
+               Log::debug('Using "'.$commandLine.'" as the worker command line.');
+               
+               // Reuse the environment.
+               // - Specify TERM=dumb to prevent the worker from messing around with our terminal.
+               // - Specify WCF_WORKER_STATUS_FD to prevent the administrator from manually giving a threadId,
+               //   causing the worker to write into an arbitrary file descriptor (most likely the DB connection).
+               // - Specify WCF_SESSION_ID to perform the login.
+               $env = array_merge($_ENV, [
+                       'TERM' => 'dumb',
+                       'WCF_WORKER_STATUS_FD' => 3,
+                       'WCF_SESSION_ID' => CLIWCF::getSession()->sessionID,
+               ]);
+               
+               try {
+                       // 1) Spawn the processes.
+                       $processes = [];
+                       for ($threadId = 0; $threadId < $threads; $threadId++) {
+                               $process = proc_open($commandLine, $fileDescriptors, $pipes, null, $env, null);
+                               
+                               $consoleBar = new ConsoleProgressBar([
+                                       'width' => CLIWCF::getTerminal()->getWidth()
+                               ]);
+                               $consoleBar->setElements([
+                                       ConsoleProgressBar::ELEMENT_PERCENT,
+                                       ConsoleProgressBar::ELEMENT_BAR,
+                                       ConsoleProgressBar::ELEMENT_ETA,
+                                       ConsoleProgressBar::ELEMENT_TEXT,
+                               ]);
+                               $consoleBar->setTextWidth(30);
+                               $progressbar = new ProgressBar($consoleBar);
+                               $progressbar->update(0, 'T'.$threadId.': spawned');
+                               echo "\n";
+                               
+                               $processes[] = [
+                                       'threadId' => $threadId,
+                                       'pipes' => $pipes,
+                                       'process' => $process,
+                                       'progressbar' => $progressbar,
+                               ];
+                       }
+                       
+                       // 2) Start processing in all processes.
+                       foreach ($processes as $processData) {
+                               $workerCommand = 'worker --threads='.$threads.' --threadId='.$processData['threadId'].' "'.addcslashes(get_class($worker), "\\\"");
+                               fwrite($processData['pipes'][0], $workerCommand."\n");
+                               fclose($processData['pipes'][0]);
+                       }
+                       
+                       // 3) Handle their status output.
+                       while (true) {
+                               // 3.1) Check which processes' status FD is readable.
+                               $read = array_filter(array_map(function ($processData) {
+                                       return $processData['pipes'][3];
+                               }, $processes), function ($handle) {
+                                       return $handle !== false;
+                               });
+                               $write = null;
+                               $except = null;
+                               
+                               // 3.2) Exit if all status FDs have been closed.
+                               if (empty($read)) {
+                                       break;
+                               }
+                               
+                               stream_select($read, $write, $except, 2, null);
+                               
+                               // 3.3) Rerender the progressbars with the updated status information.
+                               echo "\033[".$threads."A"; // Move up $threads lines to move into the line of the first progress bar.
+                               $cursorOffset = -$threads;
+                               foreach ($processes as &$processData) {
+                                       $status = proc_get_status($processData['process']);
+                                       if ($status === false) {
+                                               throw new \LogicException('Unreachable');
+                                       }
+                                       
+                                       $line = false;
+                                       if ($processData['pipes'][3] !== false) {
+                                               if (in_array($processData['pipes'][3], $read)) {
+                                                       $line = fgets($processData['pipes'][3]);
+                                               }
+                                               
+                                               if (feof($processData['pipes'][3])) {
+                                                       fclose($processData['pipes'][3]);
+                                                       $processData['pipes'][3] = false;
+                                               }
+                                       }
+                                       
+                                       $statusPrefix = 'T'.$processData['threadId'].': ';
+                                       if ($line) {
+                                               // If a line could be read we update the progressbar with the data sent.
+                                               $parsedLine = JSON::decode(StringUtil::trim($line));
+                                               
+                                               if (!empty($parsedLine['error'])) {
+                                                       fwrite(STDERR, str_repeat("\n", -$cursorOffset + 1));
+                                                       fwrite(STDERR, str_repeat("=", 20)."\n");
+                                                       fwrite(STDERR, "Error in thread ".$processData['threadId']."\n");
+                                                       fwrite(STDERR, $parsedLine['error']."\n");
+                                                       fwrite(STDERR, str_repeat("=", 20)."\n");
+                                                       fwrite(STDERR, str_repeat("\n", $threads + $cursorOffset + 1));
+                                               }
+                                               else if (isset($parsedLine['finished'])) {
+                                                       $processData['progressbar']->update($parsedLine['progress'], $statusPrefix.'finished');
+                                               }
+                                               else {
+                                                       $processData['progressbar']->update($parsedLine['progress'], $statusPrefix.'loop#'.$parsedLine['iteration']);
+                                               }
+                                       }
+                                       else if (!$status['running']) {
+                                               // If the process exited we update the text status to indicate so.
+                                               $processData['progressbar']->update(null, $statusPrefix.'exited');
+                                       }
+                                       else {
+                                               // Otherwise just rerender the bar without changing anything.
+                                               $processData['progressbar']->update();
+                                       }
+                                       echo "\n";
+                                       $cursorOffset++;
+                                       
+                                       // Check the exit code after processing the status line, to allow for dumping the error message.
+                                       if (!$status['running'] && $status['exitcode'] != -1) {
+                                               if ($status['exitcode']) {
+                                                       throw new \Exception('Unclean exit of thread '.$processData['threadId'].' detected. Exiting.');
+                                               }
+                                       }
+                               }
+                               unset($processData);
+                       }
+                       
+                       // 4) Make sure to update the text status to 'exited' for every process to not confuse the user.
+                       echo "\033[".$threads."A";
+                       foreach ($processes as $processData) {
+                               $status = proc_get_status($processData['process']);
+                               if ($status === false) {
+                                       throw new \LogicException('Unreachable');
+                               }
+                               
+                               if (!$status['running']) {
+                                       $processData['progressbar']->update(null, 'T'.$processData['threadId'].': exited');
+                               }
+                               else {
+                                       throw new \LogicException('Unreachable');
+                               }
+                               echo "\n";
+                       }
+               }
+               finally {
+                       if ($cursorOffset) {
+                               // Move out of the progress bar area.
+                               echo str_repeat("\n", -$cursorOffset);
+                       }
+                       echo "\n";
+
+                       // Kill all remaining processes and check their status to not leave zombies.
+                       // There should not be any running processes at this point, except in case of
+                       // an unclean exit of one process
+                       foreach ($processes as $processData) {
+                               if (proc_get_status($processData['process'])['running']) {
+                                       echo "Killing thread ".$processData['threadId']."\n";
+                                       proc_terminate($processData['process'], 9);
+                                       $i = 0;
+                                       while (proc_get_status($processData['process'])['running']) {
+                                               usleep(100000);
+                                               if ($i++ > 3) echo "Waiting for exit\n";
+                                       }
+                               }
+                       }
+               }
+       }
+       
        /**
         * Returns an array with the list of all available workers.
         * 
index 87582ec07a8158db5f75cf98ae9f72b64eefef34..f8bfc47628756ab275c6fda726d6416c1fcae0e6 100644 (file)
@@ -20,12 +20,12 @@ class UserClipboardAction extends AbstractClipboardAction {
        /**
         * @inheritDoc
         */
-       protected $actionClassActions = ['delete', 'resendActivationMail'];
+       protected $actionClassActions = ['delete', 'resendActivationMail', 'confirmEmail', 'unconfirmEmail'];
        
        /**
         * @inheritDoc
         */
-       protected $supportedActions = ['assignToGroup', 'ban', 'delete', 'enable', 'exportMailAddress', 'merge', 'sendMail', 'sendNewPassword', 'resendActivationMail'];
+       protected $supportedActions = ['assignToGroup', 'ban', 'confirmEmail', 'delete', 'enable', 'exportMailAddress', 'merge', 'sendMail', 'sendNewPassword', 'resendActivationMail', 'unconfirmEmail'];
        
        /**
         * @inheritDoc
@@ -161,6 +161,48 @@ class UserClipboardAction extends AbstractClipboardAction {
                return array_values($userIDs);
        }
        
+       /**
+        * Returns the ids of the users which can be marked as email confirmed.
+        *
+        * @return      integer[]
+        * @since       5.3
+        */
+       protected function validateConfirmEmail() {
+               // check permissions
+               if (!WCF::getSession()->getPermission('admin.user.canEnableUser')) {
+                       return [];
+               }
+               
+               $userIDs = [];
+               foreach ($this->objects as $user) {
+                       /** @var User $user */
+                       if (!$user->isEmailConfirmed()) $userIDs[] = $user->userID;
+               }
+               
+               return $this->__validateAccessibleGroups($userIDs);
+       }
+       
+       /**
+        * Returns the ids of the users which can be unmarked as email confirmed.
+        *
+        * @return      integer[]
+        * @since       5.3
+        */
+       protected function validateUnconfirmEmail() {
+               // check permissions
+               if (!WCF::getSession()->getPermission('admin.user.canEnableUser')) {
+                       return [];
+               }
+               
+               $userIDs = [];
+               foreach ($this->objects as $user) {
+                       /** @var User $user */
+                       if ($user->isEmailConfirmed()) $userIDs[] = $user->userID;
+               }
+               
+               return $this->__validateAccessibleGroups($userIDs);
+       }
+       
        /**
         * Returns the ids of the users which can be sent new passwords.
         * 
@@ -195,7 +237,8 @@ class UserClipboardAction extends AbstractClipboardAction {
                
                $userIDs = [];
                foreach ($this->objects as $user) {
-                       if ($user->activationCode) $userIDs[] = $user->userID;
+                       /** @var User $user */
+                       if ($user->pendingActivation()) $userIDs[] = $user->userID;
                }
                
                return $userIDs;
@@ -227,13 +270,14 @@ class UserClipboardAction extends AbstractClipboardAction {
         */
        protected function validateResendActivationMail() {
                // check permissions
-               if (!WCF::getSession()->getPermission('admin.user.canEnableUser') || REGISTER_ACTIVATION_METHOD != 1) {
+               if (!WCF::getSession()->getPermission('admin.user.canEnableUser') || !(REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER)) {
                        return [];
                }
                
                $userIDs = [];
                foreach ($this->objects as $user) {
-                       if ($user->activationCode) $userIDs[] = $user->userID;
+                       /** @var User $user */
+                       if ($user->canEmailConfirm()) $userIDs[] = $user->userID;
                }
                
                return $userIDs;
index 76c378767116f674b59435baabe23fc01a0f34af..419f1f7bc9839ba96dbdd29f04503bb5a127c937 100644 (file)
@@ -2,6 +2,7 @@
 namespace wcf\system\comment\manager;
 use wcf\data\comment\response\CommentResponse;
 use wcf\data\comment\Comment;
+use wcf\data\DatabaseObjectDecorator;
 use wcf\system\bbcode\BBCodeHandler;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
@@ -231,4 +232,25 @@ abstract class AbstractCommentManager extends SingletonFactory implements IComme
                return $this->getLink($response->getComment()->objectTypeID, $response->getComment()->objectID)
                        . '#comment' . $response->commentID . '/response' . $response->responseID;
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isContentAuthor($commentOrResponse) {
+               return false;
+       }
+       
+       /**
+        * Returns the object ID for the given Comment or CommentResponse.
+        * 
+        * @return integer
+        */
+       protected final function getObjectID($commentOrResponse) {
+               if ($commentOrResponse instanceof CommentResponse || ($commentOrResponse instanceof DatabaseObjectDecorator && $commentOrResponse->getDecoratedObject() instanceof CommentResponse)) {
+                       return $commentOrResponse->getComment()->objectID;
+               }
+               else {
+                       return $commentOrResponse->objectID;
+               }
+       }
 }
index c91c5888f552005c7f41751406cb4a67713ddb84..01958a42e34d3182913ea7fa8a5f065467a4f956 100644 (file)
@@ -7,6 +7,7 @@ use wcf\data\comment\response\CommentResponseList;
 use wcf\data\comment\CommentList;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
+use wcf\system\cache\runtime\ViewableArticleContentRuntimeCache;
 use wcf\system\like\IViewableLikeProvider;
 use wcf\system\WCF;
 
@@ -169,7 +170,9 @@ class ArticleCommentManager extends AbstractCommentManager implements IViewableL
                                                        'commentAuthor' => $comment->userID ? $users[$comment->userID] : null,
                                                        'comment' => $comment,
                                                        'articleContent' => $articleContents[$comment->objectID],
-                                                       'like' => $like
+                                                       'reaction' => $like,
+                                                       // @deprecated 5.3 Use `$reaction` instead
+                                                       'like' => $like,
                                                ]);
                                                $like->setTitle($text);
                                                
@@ -192,8 +195,10 @@ class ArticleCommentManager extends AbstractCommentManager implements IViewableL
                                                        'responseAuthor' => $comment->userID ? $users[$response->userID] : null,
                                                        'commentAuthor' => $comment->userID ? $users[$comment->userID] : null,
                                                        'articleContent' => $articleContents[$comment->objectID],
+                                                       'reaction' => $like,
+                                                       // @deprecated 5.3 Use `$reaction` instead
                                                        'like' => $like,
-                                                       'response' => $response
+                                                       'response' => $response,
                                                ]);
                                                $like->setTitle($text);
                                                
@@ -204,4 +209,12 @@ class ArticleCommentManager extends AbstractCommentManager implements IViewableL
                        }
                }
        }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isContentAuthor($commentOrResponse) {
+               $articleContent = ViewableArticleContentRuntimeCache::getInstance()->getObject($this->getObjectID($commentOrResponse));
+               return $commentOrResponse->userID && $articleContent->getArticle()->userID == $commentOrResponse->userID;
+       }
 }
index 807af53684d045c1cfba01e42aee260cd7ecdeca..75e6ae0544fe2de9b65f7abcd02bc86ad9b9b09c 100644 (file)
@@ -147,4 +147,13 @@ interface ICommentManager {
         * Sets the list of disallowed bbcodes.
         */
        public function setDisallowedBBCodes();
+       
+       /**
+        * Returns whether the given Comment or CommentResponse was created by
+        * the content's author.
+        * 
+        * @param       Comment|CommentResponse $commentOrResponse
+        * @return      boolean
+        */
+       public function isContentAuthor($commentOrResponse);
 }
index fdd42fc953f550aec94ecab137cd3d6c316f413e..1cfe306bc9c86b2f988bae325dc1904a506ad368 100644 (file)
@@ -163,7 +163,9 @@ class PageCommentManager extends AbstractCommentManager implements IViewableLike
                                                        'commentAuthor' => $comment->userID ? $users[$comment->userID] : null,
                                                        'comment' => $comment,
                                                        'page' => $pages[$comment->objectID],
-                                                       'like' => $like
+                                                       'reaction' => $like,
+                                                       // @deprecated 5.3 Use `$reaction` instead
+                                                       'like' => $like,
                                                ]);
                                                $like->setTitle($text);
                                                
@@ -186,6 +188,8 @@ class PageCommentManager extends AbstractCommentManager implements IViewableLike
                                                        'responseAuthor' => $comment->userID ? $users[$response->userID] : null,
                                                        'commentAuthor' => $comment->userID ? $users[$comment->userID] : null,
                                                        'page' => $pages[$comment->objectID],
+                                                       'reaction' => $like,
+                                                       // @deprecated 5.3 Use `$reaction` instead
                                                        'like' => $like,
                                                        'response' => $response
                                                ]);
index 77ebdce387bbac4f577d868e93ee981a3168870f..29dc8a061aab21ce292c890142edd1378ec236a1 100644 (file)
@@ -212,7 +212,9 @@ class UserProfileCommentManager extends AbstractCommentManager implements IViewa
                                                        'commentAuthor' => $comment->userID ? $users[$comment->userID] : null,
                                                        'comment' => $comment,
                                                        'user' => $users[$comment->objectID],
-                                                       'like' => $like
+                                                       'reaction' => $like,
+                                                       // @deprecated 5.3 Use `$reaction` instead
+                                                       'like' => $like,
                                                ]);
                                                $like->setTitle($text);
                                                
@@ -235,6 +237,8 @@ class UserProfileCommentManager extends AbstractCommentManager implements IViewa
                                                        'responseAuthor' => $response->userID ? $users[$response->userID] : null,
                                                        'commentAuthor' => $comment->userID ? $users[$comment->userID] : null,
                                                        'user' => $users[$comment->objectID],
+                                                       'reaction' => $like,
+                                                       // @deprecated 5.3 Use `$reaction` instead
                                                        'like' => $like,
                                                        'response' => $response
                                                ]);
diff --git a/wcfsetup/install/files/lib/system/condition/UserCoverPhotoCondition.class.php b/wcfsetup/install/files/lib/system/condition/UserCoverPhotoCondition.class.php
new file mode 100644 (file)
index 0000000..02eb0b0
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+namespace wcf\system\condition;
+use wcf\data\condition\Condition;
+use wcf\data\user\User;
+use wcf\data\user\UserList;
+use wcf\data\DatabaseObjectList;
+use wcf\system\WCF;
+
+/**
+ * Condition implementation for the cover photo of a user.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Condition
+ * @since      5.3
+ */
+class UserCoverPhotoCondition extends AbstractSelectCondition implements IContentCondition, IObjectListCondition, IUserCondition {
+       use TObjectListUserCondition;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $fieldName = 'userCoverPhoto';
+       
+       /**
+        * @inheritDoc
+        */
+       protected $label = 'wcf.user.condition.coverPhoto';
+       
+       /**
+        * value of the "user has no cover photo" option
+        * @var integer
+        */
+       const NO_COVER_PHOTO = 0;
+       
+       /**
+        * value of the "user has a cover photo" option
+        * @var integer
+        */
+       const COVER_PHOTO = 1;
+       
+       /**
+        * @inheritDoc
+        */
+       public function addObjectListCondition(DatabaseObjectList $objectList, array $conditionData) {
+               if (!($objectList instanceof UserList)) {
+                       throw new \InvalidArgumentException("Object list is no instance of '".UserList::class."', instance of '".get_class($objectList)."' given.");
+               }
+               
+               switch ($conditionData['userCoverPhoto']) {
+                       case self::NO_COVER_PHOTO:
+                               $objectList->getConditionBuilder()->add('(user_table.coverPhotoHash = ? OR user_table.coverPhotoHash IS NULL)', ['']);
+                       break;
+                       
+                       case self::COVER_PHOTO:
+                               $objectList->getConditionBuilder()->add('(user_table.coverPhotoHash <> ? AND user_table.coverPhotoHash IS NOT NULL)', ['']);
+                       break;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function checkUser(Condition $condition, User $user) {
+               switch ($condition->userCoverPhoto) {
+                       case self::NO_COVER_PHOTO:
+                               return $user->coverPhotoExtension === '' || $user->coverPhotoExtension === null;
+                       break;
+                       
+                       case self::COVER_PHOTO:
+                               return $user->coverPhotoExtension !== '' && $user->coverPhotoExtension !== null;
+                       break;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected function getOptions() {
+               return [
+                       self::NO_SELECTION_VALUE => 'wcf.global.noSelection',
+                       self::NO_COVER_PHOTO => 'wcf.user.condition.coverPhoto.noCoverPhoto',
+                       self::COVER_PHOTO => 'wcf.user.condition.coverPhoto.coverPhoto'
+               ];
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function showContent(Condition $condition) {
+               if (!WCF::getUser()->userID) return false;
+               
+               return $this->checkUser($condition, WCF::getUser());
+       }
+}
index 6393665a69c85ab5522c3c75cf329236ee8f8b51..4803df2d63014e204d0108ea9d423e83a1e9e7ca 100644 (file)
@@ -2,6 +2,7 @@
 namespace wcf\system\condition;
 use wcf\data\condition\Condition;
 use wcf\data\user\group\UserGroup;
+use wcf\data\user\online\UsersOnlineList;
 use wcf\data\user\User;
 use wcf\data\user\UserList;
 use wcf\data\DatabaseObjectList;
@@ -60,15 +61,20 @@ class UserGroupCondition extends AbstractMultipleFieldsCondition implements ICon
         * @inheritDoc
         */
        public function addObjectListCondition(DatabaseObjectList $objectList, array $conditionData) {
-               if (!($objectList instanceof UserList)) {
-                       throw new \InvalidArgumentException("Object list is no instance of '".UserList::class."', instance of '".get_class($objectList)."' given.");
+               if (!($objectList instanceof UserList) && !($objectList instanceof UsersOnlineList)) {
+                       throw new \InvalidArgumentException("Object list is neither an instance of '".UserList::class."' nor of '".UsersOnlineList::class."', instance of '".get_class($objectList)."' given.");
+               }
+               
+               $tableName = 'user_table';
+               if ($objectList instanceof UsersOnlineList) {
+                       $tableName = 'session';
                }
                
                if (isset($conditionData['groupIDs'])) {
-                       $objectList->getConditionBuilder()->add('user_table.userID IN (SELECT userID FROM wcf'.WCF_N.'_user_to_group WHERE groupID IN (?) GROUP BY userID HAVING COUNT(userID) = ?)', [$conditionData['groupIDs'], count($conditionData['groupIDs'])]);
+                       $objectList->getConditionBuilder()->add($tableName . '.userID IN (SELECT userID FROM wcf'.WCF_N.'_user_to_group WHERE groupID IN (?) GROUP BY userID HAVING COUNT(userID) = ?)', [$conditionData['groupIDs'], count($conditionData['groupIDs'])]);
                }
                if (isset($conditionData['notGroupIDs'])) {
-                       $objectList->getConditionBuilder()->add('user_table.userID NOT IN (SELECT userID FROM wcf'.WCF_N.'_user_to_group WHERE groupID IN (?))', [$conditionData['notGroupIDs']]);
+                       $objectList->getConditionBuilder()->add($tableName . '.userID NOT IN (SELECT userID FROM wcf'.WCF_N.'_user_to_group WHERE groupID IN (?))', [$conditionData['notGroupIDs']]);
                }
        }
        
@@ -169,11 +175,7 @@ HTML;
                                $invalidGroupTypes[] = UserGroup::GUESTS;
                        }
                        
-                       $this->userGroups = UserGroup::getAccessibleGroups([], $invalidGroupTypes);
-                       
-                       uasort($this->userGroups, function(UserGroup $groupA, UserGroup $groupB) {
-                               return strcmp($groupA->getName(), $groupB->getName());
-                       });
+                       $this->userGroups = UserGroup::getSortedAccessibleGroups([], $invalidGroupTypes);
                }
                
                return $this->userGroups;
diff --git a/wcfsetup/install/files/lib/system/condition/UserSignatureCondition.class.php b/wcfsetup/install/files/lib/system/condition/UserSignatureCondition.class.php
new file mode 100644 (file)
index 0000000..e2baa48
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+namespace wcf\system\condition;
+use wcf\data\condition\Condition;
+use wcf\data\user\User;
+use wcf\data\user\UserList;
+use wcf\data\DatabaseObjectList;
+use wcf\system\WCF;
+
+/**
+ * Condition implementation for the signature of a user.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Condition
+ * @since      5.3
+ */
+class UserSignatureCondition extends AbstractSelectCondition implements IContentCondition, IObjectListCondition, IUserCondition {
+       use TObjectListUserCondition;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $fieldName = 'userSignature';
+       
+       /**
+        * @inheritDoc
+        */
+       protected $label = 'wcf.user.condition.signature';
+       
+       /**
+        * value of the "user has no signature" option
+        * @var integer
+        */
+       const NO_SIGNATURE = 0;
+       
+       /**
+        * value of the "user has a signature" option
+        * @var integer
+        */
+       const SIGNATURE = 1;
+       
+       /**
+        * @inheritDoc
+        */
+       public function addObjectListCondition(DatabaseObjectList $objectList, array $conditionData) {
+               if (!($objectList instanceof UserList)) {
+                       throw new \InvalidArgumentException("Object list is no instance of '".UserList::class."', instance of '".get_class($objectList)."' given.");
+               }
+               
+               switch ($conditionData['userSignature']) {
+                       case self::NO_SIGNATURE:
+                               $objectList->getConditionBuilder()->add('(user_table.signature = ? OR user_table.signature IS NULL)', ['']);
+                       break;
+                       
+                       case self::SIGNATURE:
+                               $objectList->getConditionBuilder()->add('(user_table.signature <> ? AND user_table.signature IS NOT NULL)', ['']);
+                       break;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function checkUser(Condition $condition, User $user) {
+               switch ($condition->userSignature) {
+                       case self::NO_SIGNATURE:
+                               return $user->signature === '' || $user->signature === null;
+                       break;
+                       
+                       case self::SIGNATURE:
+                               return $user->signature !== '' && $user->signature !== null;
+                       break;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected function getOptions() {
+               return [
+                       self::NO_SELECTION_VALUE => 'wcf.global.noSelection',
+                       self::NO_SIGNATURE => 'wcf.user.condition.signature.noSignature',
+                       self::SIGNATURE => 'wcf.user.condition.signature.signature'
+               ];
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function showContent(Condition $condition) {
+               if (!WCF::getUser()->userID) return false;
+               
+               return $this->checkUser($condition, WCF::getUser());
+       }
+}
index 47093fdb18a8f5ba29559fba0287960172a27942..327044dba1e7c7657db8d1290bacbdba81d7442c 100644 (file)
@@ -47,6 +47,19 @@ class UserStateCondition extends AbstractSingleFieldCondition implements IConten
         */
        protected $userIsNotBanned = 0;
        
+       /**
+        * true if the the user has confirmed their email address
+        *
+        * @var integer
+        */
+       protected $userIsEmailConfirmed = 0;
+       
+       /**
+        * true if the the user has not confirmed their email address
+        * @var integer
+        */
+       protected $userIsNotEmailConfirmed = 0;
+       
        /**
         * @inheritDoc
         */
@@ -67,6 +80,15 @@ class UserStateCondition extends AbstractSingleFieldCondition implements IConten
                                $objectList->getConditionBuilder()->add('user_table.activationCode <> ?', [0]);
                        }
                }
+               
+               if (isset($conditionData['userIsEmailConfirmed'])) {
+                       if ($conditionData['userIsEmailConfirmed']) {
+                               $objectList->getConditionBuilder()->add('user_table.emailConfirmed IS NULL');
+                       }
+                       else {
+                               $objectList->getConditionBuilder()->add('user_table.emailConfirmed IS NOT NULL');
+                       }
+               }
        }
        
        /**
@@ -82,10 +104,21 @@ class UserStateCondition extends AbstractSingleFieldCondition implements IConten
                /** @noinspection PhpUndefinedFieldInspection */
                $userIsEnabled = $condition->userIsEnabled;
                if ($userIsEnabled !== null) {
-                       if ($userIsEnabled && $user->activationCode) {
+                       if ($userIsEnabled && $user->pendingActivation()) {
                                return false;
                        }
-                       else if (!$userIsEnabled && !$user->activationCode) {
+                       else if (!$userIsEnabled && !$user->pendingActivation()) {
+                               return false;
+                       }
+               }
+               
+               /** @noinspection PhpUndefinedFieldInspection */
+               $userIsEmailConfirmed = $condition->userIsEmailConfirmed;
+               if ($userIsEmailConfirmed !== null) {
+                       if ($userIsEmailConfirmed && !$user->isEmailConfirmed()) {
+                               return false;
+                       }
+                       else if (!$userIsEmailConfirmed && $user->isEmailConfirmed()) {
                                return false;
                        }
                }
@@ -111,6 +144,12 @@ class UserStateCondition extends AbstractSingleFieldCondition implements IConten
                else if ($this->userIsDisabled) {
                        $data['userIsEnabled'] = 0;
                }
+               if ($this->userIsEmailConfirmed) {
+                       $data['userIsEmailConfirmed'] = 1;
+               }
+               else if ($this->userIsNotEmailConfirmed) {
+                       $data['userIsEmailConfirmed'] = 0;
+               } 
                
                if (!empty($data)) {
                        return $data;
@@ -142,12 +181,16 @@ class UserStateCondition extends AbstractSingleFieldCondition implements IConten
                $userIsBanned = WCF::getLanguage()->get('wcf.user.condition.state.isBanned');
                $userIsDisabled = WCF::getLanguage()->get('wcf.user.condition.state.isDisabled');
                $userIsEnabled = WCF::getLanguage()->get('wcf.user.condition.state.isEnabled');
+               $userIsEmailConfirmed = WCF::getLanguage()->get('wcf.user.condition.state.isEmailConfirmed');
+               $userIsNotEmailConfirmed = WCF::getLanguage()->get('wcf.user.condition.state.isNotEmailConfirmed');
                
                return <<<HTML
 <label><input type="checkbox" name="userIsBanned" value="1"{$this->getCheckedAttribute('userIsBanned')}> {$userIsBanned}</label>
 <label><input type="checkbox" name="userIsNotBanned" value="1"{$this->getCheckedAttribute('userIsNotBanned')}> {$userIsNotBanned}</label>
 <label><input type="checkbox" name="userIsEnabled" value="1"{$this->getCheckedAttribute('userIsEnabled')}> {$userIsEnabled}</label>
 <label><input type="checkbox" name="userIsDisabled" value="1"{$this->getCheckedAttribute('userIsDisabled')}> {$userIsDisabled}</label>
+<label><input type="checkbox" name="userIsEmailConfirmed" value="1"{$this->getCheckedAttribute('userIsEmailConfirmed')}> {$userIsEmailConfirmed}</label>
+<label><input type="checkbox" name="userIsNotEmailConfirmed" value="1"{$this->getCheckedAttribute('userIsNotEmailConfirmed')}> {$userIsNotEmailConfirmed}</label>
 HTML;
        }
        
@@ -159,6 +202,8 @@ HTML;
                if (isset($_POST['userIsDisabled'])) $this->userIsDisabled = 1;
                if (isset($_POST['userIsEnabled'])) $this->userIsEnabled = 1;
                if (isset($_POST['userIsNotBanned'])) $this->userIsNotBanned = 1;
+               if (isset($_POST['userIsEmailConfirmed'])) $this->userIsEmailConfirmed = 1;
+               if (isset($_POST['userIsNotEmailConfirmed'])) $this->userIsNotEmailConfirmed = 1;
        }
        
        /**
@@ -169,6 +214,8 @@ HTML;
                $this->userIsDisabled = 0;
                $this->userIsEnabled = 0;
                $this->userIsNotBanned = 0;
+               $this->userIsEmailConfirmed = 0;
+               $this->userIsNotEmailConfirmed = 0;
        }
        
        /**
@@ -188,6 +235,13 @@ HTML;
                        $this->userIsEnabled = $userIsEnabled;
                        $this->userIsDisabled = !$userIsEnabled;
                }
+               
+               /** @noinspection PhpUndefinedFieldInspection */
+               $userIsEmailConfirmed = $condition->userIsEmailConfirmed;
+               if ($condition->userIsEmailConfirmed !== null) {
+                       $this->userIsEmailConfirmed = $userIsEmailConfirmed;
+                       $this->userIsNotEmailConfirmed = !$userIsEmailConfirmed;
+               }
        }
        
        /**
@@ -205,6 +259,12 @@ HTML;
                        
                        throw new UserInputException('userIsEnabled', 'conflict');
                }
+               
+               if ($this->userIsEmailConfirmed && $this->userIsNotEmailConfirmed) {
+                       $this->errorMessage = 'wcf.user.condition.state.isEmailConfirmed.error.conflict';
+                       
+                       throw new UserInputException('userIsEmailConfirmed', 'conflict');
+               }
        }
        
        /**
index 1fc4b4cd51d39d3d815a3a127f41b20e2672d97c..ba0e355ff616742632df007e63cb091060c368f1 100644 (file)
@@ -7,7 +7,7 @@ use wcf\data\DatabaseObjectList;
 use wcf\system\WCF;
 
 /**
- * Condition implementation for the user id of an user.
+ * Condition implementation for the user id of a user.
  * 
  * @author      Alexander Ebert
  * @copyright  2001-2019 WoltLab GmbH
diff --git a/wcfsetup/install/files/lib/system/condition/user/UserLastActivityTimeIntervalDaysCondition.class.php b/wcfsetup/install/files/lib/system/condition/user/UserLastActivityTimeIntervalDaysCondition.class.php
new file mode 100644 (file)
index 0000000..18665dd
--- /dev/null
@@ -0,0 +1,191 @@
+<?php
+namespace wcf\system\condition\user;
+use wcf\data\condition\Condition;
+use wcf\data\DatabaseObject;
+use wcf\data\DatabaseObjectList;
+use wcf\data\user\User;
+use wcf\data\user\UserList;
+use wcf\system\condition\AbstractSingleFieldCondition;
+use wcf\system\condition\IObjectCondition;
+use wcf\system\condition\IObjectListCondition;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+use wcf\util\ClassUtil;
+
+/**
+ * User condition for the interval (in days) of their last activity.
+ * 
+ * @author      Matthias Schmidt
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Condition\User
+ * @since       5.3
+ */
+class UserLastActivityTimeIntervalDaysCondition extends AbstractSingleFieldCondition implements IObjectCondition, IObjectListCondition {
+       /**
+        * @inheritDoc
+        */
+       protected $label = 'wcf.user.condition.lastActivityTimeIntervalDays';
+       
+       /**
+        * end value of the days interval
+        * @var int|string
+        */
+       protected $endDays = '';
+       
+       /**
+        * start value of the days interval
+        * @var int|string
+        */
+       protected $startDays = '';
+       
+       /**
+        * @inheritDoc
+        */
+       public function addObjectListCondition(DatabaseObjectList $objectList, array $conditionData) {
+               if (!($objectList instanceof UserList)) {
+                       throw new \InvalidArgumentException("Object list is no instance of '" . UserList::class . "', instance of '".get_class($objectList)."' given.");
+               }
+               
+               /** @noinspection PhpUndefinedFieldInspection */
+               if ($this->object->ignoreZeroTime) {
+                       $objectList->getConditionBuilder()->add('user_table.lastActivityTime <> ?', [0]);
+               }
+               if (isset($conditionData['startDays'])) {
+                       $objectList->getConditionBuilder()->add('user_table.lastActivityTime <= ?', [TIME_NOW - $conditionData['startDays'] * 24 * 3600]);
+               }
+               if (isset($conditionData['endDays'])) {
+                       $objectList->getConditionBuilder()->add('user_table.lastActivityTime >= ?', [TIME_NOW - $conditionData['endDays'] * 24 * 3600]);
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function checkObject(DatabaseObject $object, array $conditionData) {
+               if (!($object instanceof User) && !ClassUtil::isDecoratedInstanceOf($object, User::class)) {
+                       throw new \InvalidArgumentException("Object is no instance of '" . User::class . "', instance of '".get_class($object)."' given.");
+               }
+               
+               if (isset($conditionData['startDays'])) {
+                       if ($object->lastActivityTime > TIME_NOW - $conditionData['startDays'] * 24 * 3600) {
+                               return false;
+                       }
+                       
+                       if (isset($conditionData['endDays'])) {
+                               if ($object->lastActivityTime < TIME_NOW - $conditionData['endDays'] * 24 * 3600) {
+                                       return false;
+                               }
+                       }
+                       
+                       return true;
+               }
+               else if (isset($conditionData['endDays']) && $object->lastActivityTime < TIME_NOW - $conditionData['endDays'] * 24 * 3600) {
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getData() {
+               $data = [];
+               
+               if (strlen($this->startDays)) {
+                       $data['startDays'] = $this->startDays;
+               }
+               if (strlen($this->endDays)) {
+                       $data['endDays'] = $this->endDays;
+               }
+               
+               if (!empty($data)) {
+                       return $data;
+               }
+               
+               return null;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected function getFieldElement() {
+               $start = WCF::getLanguage()->get('wcf.date.period.start');
+               $end = WCF::getLanguage()->get('wcf.date.period.end');
+               $days = WCF::getLanguage()->get('wcf.acp.option.suffix.days');
+               
+               return <<<HTML
+<div class="inputAddon">
+       <input type="number" id="userLastActivityTimeIntervalStartDays" name="userLastActivityTimeIntervalStartDays" class="short" min="1" value="{$this->startDays}" placeholder="{$start}">
+       <span class="inputSuffix">{$days}</span>
+</div>
+<div class="inputAddon">
+       <input type="number" id="userLastActivityTimeIntervalEndDays" name="userLastActivityTimeIntervalEndDays" class="short" min="1" value="{$this->endDays}" placeholder="{$end}">
+       <span class="inputSuffix">{$days}</span>
+</div>
+HTML;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readFormParameters() {
+               if (isset($_POST['userLastActivityTimeIntervalEndDays'])) $this->endDays = $_POST['userLastActivityTimeIntervalEndDays'];
+               if (isset($_POST['userLastActivityTimeIntervalStartDays'])) $this->startDays = $_POST['userLastActivityTimeIntervalStartDays'];
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function reset() {
+               $this->endDays = '';
+               $this->startDays = '';
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function setData(Condition $condition) {
+               /** @noinspection PhpUndefinedFieldInspection */
+               $endDays = $condition->endDays;
+               if ($endDays) {
+                       $this->endDays = $endDays;
+               }
+               
+               /** @noinspection PhpUndefinedFieldInspection */
+               $startDays = $condition->startDays;
+               if ($startDays) {
+                       $this->startDays = $startDays;
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               $endDays = $startDays = null;
+               if (strlen($this->startDays)) {
+                       $startDays = intval($this->startDays);
+                       if ($startDays <= 0) {
+                               $this->errorMessage = 'wcf.user.condition.lastActivityTimeIntervalDays.error.invalidStart';
+                               
+                               throw new UserInputException('userLastActivityTimeIntervalDays', 'invalidStart');
+                       }
+               }
+               if (strlen($this->endDays)) {
+                       $endDays = intval($this->endDays);
+                       if ($endDays <= 0) {
+                               $this->errorMessage = 'wcf.user.condition.lastActivityTimeIntervalDays.error.invalidEnd';
+                               
+                               throw new UserInputException('userLastActivityTimeIntervalDays', 'invalidEnd');
+                       }
+               }
+               
+               if ($endDays !== null && $startDays !== null && $endDays <= $startDays) {
+                       $this->errorMessage = 'wcf.user.condition.lastActivityTimeIntervalDays.error.endBeforeStart';
+                       
+                       throw new UserInputException('userLastActivityTimeIntervalDays', 'endBeforeStart');
+               }
+       }
+}
index 8c1aec7e4ab845e24450332d134badd9d2c1fcad..ef88021e1540a8fad4f85b7f997d5de19c5e2190 100644 (file)
@@ -152,6 +152,15 @@ class DailyCleanUpCronjob extends AbstractCronjob {
                        ]);
                }
                
+               if (MODIFICATION_LOG_EXPIRATION > 0) {
+                       $sql = "DELETE FROM     wcf".WCF_N."_modification_log
+                               WHERE           time < ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               TIME_NOW - 86400 * MODIFICATION_LOG_EXPIRATION
+                       ]);
+               }
+               
                // clean up error logs
                $files = @glob(WCF_DIR.'log/*.txt');
                if (is_array($files)) {
index 001329003758fe99c3514d4ac11f073bf90f452e..89040ef1cc539401609bc149c54cd9252ee9d8aa 100644 (file)
@@ -7,12 +7,14 @@ use wcf\data\user\User;
 use wcf\data\user\UserEditor;
 use wcf\data\user\UserList;
 use wcf\data\user\UserProfile;
+use wcf\form\NotificationUnsubscribeForm;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\email\mime\MimePartFacade;
 use wcf\system\email\mime\RecipientAwareTextMimePart;
 use wcf\system\email\Email;
 use wcf\system\email\UserMailbox;
+use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\event\IUserNotificationEvent;
 use wcf\system\user\notification\UserNotificationHandler;
 use wcf\system\WCF;
@@ -145,7 +147,7 @@ class DailyMailNotificationCronjob extends AbstractCronjob {
                        $user = $users[$userID];
                        
                        // no notifications for disabled or banned users
-                       if ($user->activationCode) continue;
+                       if (!$user->isEmailConfirmed()) continue;
                        if ($user->banned) continue;
                        
                        $notifications = array_map(function ($notificationID) use ($notificationObjects, $eventObjects, $user, $objectTypes, $authors, $authorToNotification, $unknownAuthor) {
@@ -212,6 +214,11 @@ class DailyMailNotificationCronjob extends AbstractCronjob {
                        $email = new Email();
                        $email->setSubject($user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.daily.subject', ['count' => count($notifications)]));
                        $email->addRecipient(new UserMailbox($user));
+                       $email->setListID('daily.notification');
+                       $email->setListUnsubscribe(LinkHandler::getInstance()->getControllerLink(NotificationUnsubscribeForm::class, [
+                               'userID' => $user->userID,
+                               'token' => $user->notificationMailToken,
+                       ]), true);
                        
                        $html = new RecipientAwareTextMimePart('text/html', 'email_dailyNotification', 'wcf', ['notifications' => $notifications]);
                        $plainText = new RecipientAwareTextMimePart('text/plain', 'email_dailyNotification', 'wcf', ['notifications' => $notifications]);
index 589d9db38004a054d5525454c888a4cb34dd3a10..379052d6a2290bcfa53aa49157e80247320a203d 100644 (file)
@@ -1,7 +1,9 @@
 <?php
 namespace wcf\system\cronjob;
 use wcf\data\cronjob\Cronjob;
+use wcf\system\language\LanguageFactory;
 use wcf\system\package\PackageUpdateDispatcher;
+use wcf\system\WCF;
 
 /**
  * Fetches update package information.
@@ -19,7 +21,20 @@ class GetUpdateInfoCronjob extends AbstractCronjob {
                parent::execute($cronjob);
                
                if (!ENABLE_BENCHMARK) {
-                       PackageUpdateDispatcher::getInstance()->refreshPackageDatabase([], true);
+                       try {
+                               $currentLanguage = WCF::getLanguage();
+                               // Always fetch package information using the default language.
+                               if ($currentLanguage->languageID !== LanguageFactory::getInstance()->getDefaultLanguage()->languageID) {
+                                       WCF::setLanguage(LanguageFactory::getInstance()->getDefaultLanguage());
+                               }
+                               
+                               PackageUpdateDispatcher::getInstance()->refreshPackageDatabase([], true);
+                       }
+                       finally {
+                               if ($currentLanguage->languageID !== LanguageFactory::getInstance()->getDefaultLanguage()->languageID) {
+                                       WCF::setLanguage($currentLanguage);
+                               }
+                       }
                }
        }
 }
index 97ee7bec1838ff02457e328cc23fb12a9c393bff..25b1897643112f4732e87988a711f8ddae044a5c 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\database\editor;
+use wcf\system\database\exception\DatabaseQueryExecutionException;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\Regex;
 
@@ -286,9 +287,19 @@ class MySQLDatabaseEditor extends DatabaseEditor {
         * @inheritDoc
         */
        public function dropColumn($tableName, $columnName) {
-               $sql = "ALTER TABLE `".$tableName."` DROP COLUMN `".$columnName."`";
-               $statement = $this->dbObj->prepareStatement($sql);
-               $statement->execute();
+               try {
+                       $sql = "ALTER TABLE `".$tableName."` DROP COLUMN `".$columnName."`";
+                       $statement = $this->dbObj->prepareStatement($sql);
+                       $statement->execute();
+               }
+               catch (DatabaseQueryExecutionException $e) {
+                       if ($e->getCode() != '42000') {
+                               throw $e;
+                       }
+                       if (in_array($columnName, array_column($this->getColumns($tableName), 'name'))) {
+                               throw $e;
+                       }
+               }
        }
        
        /**
@@ -331,27 +342,57 @@ class MySQLDatabaseEditor extends DatabaseEditor {
         * @inheritDoc
         */
        public function dropIndex($tableName, $indexName) {
-               $sql = "ALTER TABLE `".$tableName."` DROP INDEX `".$indexName."`";
-               $statement = $this->dbObj->prepareStatement($sql);
-               $statement->execute();
+               try {
+                       $sql = "ALTER TABLE `".$tableName."` DROP INDEX `".$indexName."`";
+                       $statement = $this->dbObj->prepareStatement($sql);
+                       $statement->execute();
+               }
+               catch (DatabaseQueryExecutionException $e) {
+                       if ($e->getCode() != '42000') {
+                               throw $e;
+                       }
+                       if (in_array($indexName, $this->getIndices($tableName))) {
+                               throw $e;
+                       }
+               }
        }
        
        /**
         * @inheritDoc
         */
        public function dropPrimaryKey($tableName) {
-               $sql = "ALTER TABLE ".$tableName." DROP PRIMARY KEY";
-               $statement = $this->dbObj->prepareStatement($sql);
-               $statement->execute();
+               try {
+                       $sql = "ALTER TABLE ".$tableName." DROP PRIMARY KEY";
+                       $statement = $this->dbObj->prepareStatement($sql);
+                       $statement->execute();
+               }
+               catch (DatabaseQueryExecutionException $e) {
+                       if ($e->getCode() != '42000') {
+                               throw $e;
+                       }
+                       if (in_array("PRIMARY", $this->getIndices($tableName))) {
+                               throw $e;
+                       }
+               }
        }
        
        /**
         * @inheritDoc
         */
        public function dropForeignKey($tableName, $indexName) {
-               $sql = "ALTER TABLE `".$tableName."` DROP FOREIGN KEY `".$indexName."`";
-               $statement = $this->dbObj->prepareStatement($sql);
-               $statement->execute();
+               try {
+                       $sql = "ALTER TABLE `".$tableName."` DROP FOREIGN KEY `".$indexName."`";
+                       $statement = $this->dbObj->prepareStatement($sql);
+                       $statement->execute();
+               }
+               catch (DatabaseQueryExecutionException $e) {
+                       if ($e->getCode() != '42000') {
+                               throw $e;
+                       }
+                       if (in_array($indexName, array_keys($this->getForeignKeys($tableName)))) {
+                               throw $e;
+                       }
+               }
        }
        
        /**
index c04043f836c6f21018c9bc52ee627bc24a03ec63..16bf66151febbdc7f6bd134518c383778bbeade8 100644 (file)
@@ -19,6 +19,18 @@ class DatabaseQueryExecutionException extends DatabaseQueryException implements
         */
        protected $parameters = [];
        
+       /**
+        * @var string|null
+        * @since 5.3
+        */
+       protected $sqlState;
+       
+       /**
+        * @var string|null
+        * @since 5.3
+        */
+       protected $driverCode;
+       
        /** @noinspection PhpMissingParentConstructorInspection */
        /**
         * @inheritDoc
@@ -27,6 +39,31 @@ class DatabaseQueryExecutionException extends DatabaseQueryException implements
                parent::__construct($message, $previous);
                
                $this->parameters = $parameters;
+               if ($previous) {
+                       $errorInfo = $previous->errorInfo;
+                       $this->sqlState = $errorInfo[0] ?? null;
+                       $this->driverCode = $errorInfo[1] ?? null;
+               }
+       }
+       
+       /**
+        * Returns the ANSI SQLSTATE or null.
+        * 
+        * @return string|null
+        * @since 5.3
+        */
+       public function getSqlState() {
+               return $this->sqlState;
+       }
+
+       /**
+        * Returns the driver specific error code or null.
+        * 
+        * @return string|null
+        * @since 5.3
+        */
+       public function getDriverCode() {
+               return $this->driverCode;
        }
        
        /**
index 43073a8566fdc3dc9c0e2ca93714db59acf8234a..89e5a43d8b92c5199e1eca0c49696310eb1dd07e 100644 (file)
@@ -69,6 +69,15 @@ class DebugPreparedStatement extends PreparedStatement {
                return parent::fetchObject($className);
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function fetchSingleObject($className) {
+               $this->debugThrowIfNotExecutedBefore();
+               
+               return parent::fetchSingleObject($className);
+       }
+       
        /**
         * @inheritDoc
         */
index a4b0675b12a56c5a53b9651c50787979f8835ea4..37e43df7ae1c2825c39f01e7306080d8d428ee98 100644 (file)
@@ -170,6 +170,26 @@ class PreparedStatement {
                return null;
        }
        
+       /**
+        * Fetches the next row from a result set in a database object.
+        * Closes the 'cursor' afterwards to free up the connection
+        * for new queries.
+        * Note: It is not possible to fetch further rows after calling
+        * this method!
+        *
+        * @param       string                  $className
+        * @return      DatabaseObject|null
+        * @since       5.3
+        */
+       public function fetchSingleObject($className) {
+               $row = $this->fetchSingleRow();
+               if ($row !== false) {
+                       return new $className(null, $row);
+               }
+               
+               return null;
+       }
+       
        /**
         * Fetches the all rows from a result set into database objects.
         * 
index 87fc5051e438ac2f29cbda716c656f3746517aad..318d517c89e25cec96b91e1aca3c9b728ac4fa9a 100644 (file)
@@ -448,6 +448,12 @@ class DatabaseTableChangeProcessor {
                                                }
                                        }
                                        else if ($matchingExistingForeignKey === null) {
+                                               // If the referenced database table does not already exists, delay the
+                                               // foreign key creation until after the referenced table has been created.
+                                               if (!in_array($foreignKey->getReferencedTable(), $this->existingTableNames)) {
+                                                       continue;
+                                               }
+                                               
                                                if (!isset($this->foreignKeysToAdd[$tableName])) {
                                                        $this->foreignKeysToAdd[$tableName] = [];
                                                }
@@ -648,10 +654,18 @@ class DatabaseTableChangeProcessor {
                $this->dbEditor->createTable($table->getName(), $columnData, $indexData);
                
                foreach ($table->getForeignKeys() as $foreignKey) {
-                       $this->dbEditor->addForeignKey($table->getName(), $foreignKey->getName(), $foreignKey->getData());
-                       
-                       // foreign keys need to be explicitly logged for proper uninstallation
-                       $this->createForeignKeyLog($table->getName(), $foreignKey);
+                       // Only try to create the foreign key if the referenced database table already exists.
+                       // If it will be created later on, delay the foreign key creation until after the
+                       // referenced table has been created.
+                       if (
+                               in_array($foreignKey->getReferencedTable(), $this->existingTableNames)
+                               || $foreignKey->getReferencedTable() === $table->getName()
+                       ) {
+                               $this->dbEditor->addForeignKey($table->getName(), $foreignKey->getName(), $foreignKey->getData());
+                               
+                               // foreign keys need to be explicitly logged for proper uninstallation
+                               $this->createForeignKeyLog($table->getName(), $foreignKey);
+                       }
                }
        }
        
@@ -1149,6 +1163,24 @@ class DatabaseTableChangeProcessor {
                                                }
                                        }
                                }
+
+                               foreach ($table->getForeignKeys() as $foreignKey) {
+                                       $referencedTableExists = in_array($foreignKey->getReferencedTable(), $this->existingTableNames);
+                                       foreach ($this->tables as $processedTable) {
+                                               if ($processedTable->getName() === $foreignKey->getReferencedTable()) {
+                                                       $referencedTableExists = !$processedTable->willBeDropped();
+                                               }
+                                       }
+                                       
+                                       if (!$referencedTableExists) {
+                                               $errors[] = [
+                                                       'columnNames' => implode(',', $foreignKey->getColumns()),
+                                                       'referencedTableName' => $foreignKey->getReferencedTable(),
+                                                       'tableName' => $table->getName(),
+                                                       'type' => 'unknownTableInForeignKey',
+                                               ];
+                                       }
+                               }
                        }
                }
                
index f2d52825c7709dcea9bb586fb4f3e23252dba915..28189562524a139e885205134450f947a599c530 100644 (file)
@@ -19,7 +19,7 @@ class DevtoolsSetup extends SingletonFactory {
         * configuration file in the server's document root
         * @var string
         */
-       const CONFIGURATION_FILE = 'wsc-dev-config-52.json';
+       const CONFIGURATION_FILE = 'wsc-dev-config-53.json';
        
        /**
         * configuration data
index 7f60265fbcc3f35820d7fcddd0d9733b1d1a7f73..18919c5be3926a409a02d6d448596a7a037fe943 100644 (file)
@@ -57,6 +57,34 @@ class Email {
         */
        protected $inReplyTo = [];
        
+       /**
+        * List-Id header
+        * @var string
+        * @since 5.3
+        */
+       protected $listId;
+       
+       /**
+        * Human readable part of the List-Id header
+        * @var string
+        * @since 5.3
+        */
+       protected $listIdHuman;
+       
+       /**
+        * List-Unsubscribe URI
+        * @var string
+        * @since 5.3
+        */
+       protected $listUnsubscribe;
+       
+       /**
+        * Whether the listUnsubscribe URI has One-Click support
+        * @var boolean
+        * @since 5.3
+        */
+       protected $listUnsubscribeOneClick = false;
+       
        /**
         * Date header
         * @var \DateTime
@@ -241,6 +269,83 @@ class Email {
                return $this->references;
        }
        
+       /**
+        * Sets the list-label part of the email's 'List-Id'.
+        * 
+        * @param       string          $listId
+        * @param       string          $humanReadable
+        * @throws      \DomainException
+        * @since 5.3
+        */
+       public function setListID($listId, $humanReadable = null) {
+               if ($listId === null) {
+                       $this->listId = null;
+                       return;
+               }
+               
+               if (!preg_match('(^'.EmailGrammar::getGrammar('list-label').'$)', $listId)) {
+                       throw new \DomainException("The given list id '".$listId."' is invalid.");
+               }
+               if (strlen($listId) > 200) {
+                       throw new \DomainException("The given list id '".$listId."' is not allowed. The maximum allowed length is 200 bytes.");
+               }
+               if ($humanReadable !== null) {
+                       $humanReadable = EmailGrammar::encodeHeader($humanReadable);
+                       if (!preg_match('(^'.EmailGrammar::getGrammar('phrase').'$)', $humanReadable)) {
+                               throw new \DomainException("The given human readable name '".$humanReadable."' is invalid.");
+                       }
+               }
+               
+               $this->listId = $listId;
+               $this->listIdHuman = $humanReadable;
+       }
+       
+       /**
+        * Returns the email's full 'List-Id' including the host. Returns 'null'
+        * if no 'List-Id' is set.
+        * 
+        * @return      ?string
+        * @since 5.3
+        */
+       public function getListID() {
+               if ($this->listId === null) {
+                       return null;
+               }
+               
+               return ($this->listIdHuman ? $this->listIdHuman.' ' : '').'<'.$this->listId.'.list-id.'.self::getHost().'>';
+       }
+       
+       /**
+        * Sets the URI for the 'List-Unsubscribe' header.
+        * 
+        * If $supportsOneClick is set to true the 'List-Unsubscribe-Post' header
+        * with the value 'List-Unsubscribe=One-Click' is added.
+        * 
+        * @param       string          $uri
+        * @param       boolean         $supportsOneClick
+        * @since 5.3
+        */
+       public function setListUnsubscribe($uri, $supportsOneClick = false) {
+               if ($uri === null) {
+                       $this->listUnsubscribe = null;
+                       return;
+               }
+               
+               $this->listUnsubscribe = $uri;
+               $this->listUnsubscribeOneClick = $supportsOneClick;
+       }
+       
+       /**
+        * Returns the email's full 'List-Id' including the host. Returns 'null'
+        * if no 'List-Id' is set.
+        * 
+        * @return      ?string
+        * @since 5.3
+        */
+       public function getListUnsubscribeUri() {
+               return $this->listUnsubscribe;
+       }
+       
        /**
         * Sets the email's 'From'.
         * 
@@ -394,6 +499,15 @@ class Email {
                if ($this->getInReplyTo()) {
                        $headers[] = ['in-reply-to', implode("\r\n   ", $this->getInReplyTo())];
                }
+               if ($this->getListID()) {
+                       $headers[] = ['list-id', $this->getListID()];
+               }
+               if ($this->getListUnsubscribeUri()) {
+                       $headers[] = ['list-unsubscribe', '<'.$this->getListUnsubscribeUri().'>'];
+                       if ($this->listUnsubscribeOneClick) {
+                               $headers[] = ['list-unsubscribe-post', 'List-Unsubscribe=One-Click'];
+                       }
+               }
                $headers[] = ['mime-version', '1.0'];
                
                if (!$this->body) {
@@ -425,6 +539,15 @@ class Email {
                                case 'message-id':
                                        $name = 'Message-ID';
                                        break;
+                               case 'list-id':
+                                       $name = 'List-ID';
+                                       break;
+                               case 'list-unsubscribe-post':
+                                       // This case is identical to the default case below.
+                                       // It is special cased, because the grammar of this header is defined
+                                       // to be pretty tight.
+                                       $name = 'List-Unsubscribe-Post';
+                                       break;
                                case 'mime-version':
                                        $name = 'MIME-Version';
                                        break;
index 504060ebdd214010b2430a1a52a66e107414481f..60229c05c390e9517bf35f65d5541578ea6463bc 100644 (file)
@@ -36,6 +36,7 @@ final class EmailGrammar {
                        case 'atom':
                                return "(?:".self::getGrammar('CFWS')."?".self::getGrammar('atext')."+".self::getGrammar('CFWS')."?)";
                        case 'id-left':
+                       case 'list-label':
                        case 'dot-atom-text':
                                return "(?:".self::getGrammar('atext')."+(?:\\.".self::getGrammar('atext').'+)*)';
                        case 'no-fold-literal':
index 99b01f8ddaf7576cce512cde376e435deeffb0fd..59e710f49b1938d6e796b00086147ee9d1ec1f4d 100644 (file)
@@ -201,6 +201,10 @@ class SmtpEmailTransport implements IEmailTransport {
                                }
                        }
                        else {
+                               if ($this->connection->eof()) {
+                                       throw new TransientFailure("Unexpected EOF / connection close from SMTP server.");
+                               }
+                               
                                throw new TransientFailure("Unexpected reply '".$data."' from SMTP server.");
                        }
                }
@@ -303,11 +307,12 @@ class SmtpEmailTransport implements IEmailTransport {
        protected function auth() {
                if (!$this->username || !$this->password) return;
                
+               $authException = null;
                foreach ($this->features as $feature) {
                        $parameters = explode(" ", $feature);
                        
                        if ($parameters[0] == 'auth') {
-                               // try mechanisms in order of preference
+                               // Try mechanisms in order of preference.
                                foreach (['login', 'plain'] as $method) {
                                        if (in_array($method, $parameters)) {
                                                switch ($method) {
@@ -317,6 +322,7 @@ class SmtpEmailTransport implements IEmailTransport {
                                                                        $this->read([334]);
                                                                }
                                                                catch (SystemException $e) {
+                                                                       $authException = $e;
                                                                        // try next authentication method
                                                                        continue 2;
                                                                }
@@ -326,6 +332,8 @@ class SmtpEmailTransport implements IEmailTransport {
                                                                $this->write(base64_encode($this->password));
                                                                $this->lastWrite = '*redacted*';
                                                                $this->read([235]);
+                                                               
+                                                               // Authentication was successful.
                                                                return;
                                                        break;
                                                        case 'plain':
@@ -335,22 +343,27 @@ class SmtpEmailTransport implements IEmailTransport {
                                                                        $this->read([334]);
                                                                }
                                                                catch (SystemException $e) {
+                                                                       $authException = $e;
                                                                        // try next authentication method
                                                                        continue 2;
                                                                }
                                                                $this->write(base64_encode("\0".$this->username."\0".$this->password));
                                                                $this->lastWrite = '*redacted*';
                                                                $this->read([235]);
+                                                               
+                                                               // Authentication was successful.
                                                                return;
                                                }
                                        }
                                }
                                
-                               return;
+                               // No mechanism was accepted.
+                               break;
                        }
                }
                
                // server does not support auth
+               throw new TransientFailure("Remote SMTP server does not support AUTH, but SMTP credentials are specified.", 0, $authException);
        }
        
        /**
@@ -379,7 +392,6 @@ class SmtpEmailTransport implements IEmailTransport {
         * @param       Mailbox         $envelopeTo
         * @throws      \Exception
         * @throws      PermanentFailure
-        * @throws      SystemException
         */
        public function deliver(Email $email, Mailbox $envelopeFrom, Mailbox $envelopeTo) {
                // delivery is locked
@@ -398,7 +410,7 @@ class SmtpEmailTransport implements IEmailTransport {
                                $this->disconnect();
                                throw $e;
                        }
-                       catch (SystemException $e) {
+                       catch (\Exception $e) {
                                $this->disconnect();
                                throw $e;
                        }
index ad21599de7e39e865ce710ccea784a802c806f78..f2589bf80ee669b7faa3b9e0bcda25f7a52b89a0 100644 (file)
@@ -15,7 +15,7 @@ interface IEventListener {
        /**
         * Executes this action.
         * 
-        * @param       object          $eventObj
+        * @param       mixed           $eventObj
         * @param       string          $className
         * @param       string          $eventName
         */
diff --git a/wcfsetup/install/files/lib/system/event/listener/AbstractEventListener.class.php b/wcfsetup/install/files/lib/system/event/listener/AbstractEventListener.class.php
new file mode 100644 (file)
index 0000000..b403b2d
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+namespace wcf\system\event\listener;
+use wcf\data\AbstractDatabaseObjectAction;
+
+/**
+ * Preferred implementation for event listeners that dynamically invokes methods based on a predictable
+ * naming schema derived from the event name. In addition, `AbstractDatabaseObjectAction` supports deep
+ * method invocations for the generic action events. However, when there is no specific method, it will
+ * attempt to invoke the regular method instead.
+ * 
+ * Examples:
+ * Regular classes
+ *   eventName: makeSnafucated
+ *   derived method: onMakeSnafucated()
+ * 
+ * Classes deriving from AbstractDatabaseObjectAction
+ *   eventName: initializeAction
+ *   actionName: makeSnafucated
+ *   derived method: onInitializeActionMakeSnafucated()
+ *   ATTENTION: If this method does not exist, it will attempt to invoke `onInitializeAction()` instead. 
+ *
+ * @author      Olaf Braun, Alexander Ebert
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Event\Listener
+ */
+abstract class AbstractEventListener implements IParameterizedEventListener {
+       /**
+        * @inheritDoc
+        */
+       public final function execute($eventObj, $className, $eventName, array &$parameters) {
+               static $genericDboActionNames = ['finalizeAction', 'initializeAction', 'validateAction'];
+               
+               $methodName = 'on' . ucfirst($eventName);
+               
+               if ($eventObj instanceof AbstractDatabaseObjectAction && in_array($eventName, $genericDboActionNames)) {
+                       $actionMethod = $methodName . ucfirst($eventObj->getActionName());
+                       if (method_exists($this, $actionMethod)) {
+                               $this->{$actionMethod}($eventObj, $parameters);
+                               return;
+                       }
+               }
+               
+               if (method_exists($this, $methodName)) {
+                       $this->{$methodName}($eventObj, $parameters);
+               }
+       }
+}
index 4ddae09cb1c0826df29bf1075424433affdf69c7..89cd8897694340071da983b6061775a8d76fabc9 100644 (file)
@@ -16,7 +16,7 @@ interface IParameterizedEventListener {
        /**
         * Executes this action.
         * 
-        * @param       object          $eventObj       Object firing the event
+        * @param       mixed           $eventObj       Object firing the event
         * @param       string          $className      class name of $eventObj
         * @param       string          $eventName      name of the event fired
         * @param       array           &$parameters    given parameters
index 771c991ef8f3455ec9052a9c3b23a50f54860f72..d1f6ac24fa5cad4d0b5a7a8f5833a92461fb712e 100644 (file)
@@ -8,5 +8,6 @@ namespace wcf\system\exception;
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Exception
+ * @deprecated 5.3 This exception was created for use with HTTPRequest which is deprecated.
  */
 class HTTPNotFoundException extends SystemException { }
index d175a4007db5c11d65e6e20a6471f57029c031d4..3db445f4483bbd27ed5d34d711d2e320b9514c4d 100644 (file)
@@ -8,5 +8,6 @@ namespace wcf\system\exception;
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Exception
+ * @deprecated 5.3 This exception was created for use with HTTPRequest which is deprecated.
  */
 class HTTPServerErrorException extends SystemException { }
index a9792fc4560a1d7d0d369df56a3628425866028f..f767019e3422156b6149060373307cc0f0df25e4 100644 (file)
@@ -8,5 +8,6 @@ namespace wcf\system\exception;
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Exception
+ * @deprecated 5.3 This exception was created for use with HTTPRequest which is deprecated.
  */
 class HTTPUnauthorizedException extends SystemException { }
index 83938b1f23316c918cf5fbdc40b4db42c51e4983..34c62c1294559f064203177c331882e6e42d7b88 100644 (file)
@@ -43,6 +43,13 @@ class UploadField {
         */
        public $allowSvgImage = false;
        
+       /**
+        * Acceptable file types.
+        * @var string[]|null
+        * @since 5.3
+        */
+       public $acceptableFiles = null;
+       
        /**
         * UploadField constructor.
         *
@@ -58,7 +65,7 @@ class UploadField {
         * @return boolean
         */
        public function supportMultipleFiles() {
-               return $this->maxFiles > 1;
+               return $this->maxFiles === null || $this->maxFiles > 1;
        }
        
        /**
@@ -119,10 +126,24 @@ class UploadField {
         * Sets the flag for `imageOnly`. This flag indicates whether only images
         * can uploaded via this field. Other file types will be rejected during upload.
         * 
+        * If set to `true` will also set the acceptable types to `image/*`. If set to
+        * false it will clear the acceptable types if they are `image/*`.
+        * 
         * @param       boolean       $imageOnly
         */
        public function setImageOnly($imageOnly) {
                $this->imageOnly = $imageOnly;
+               
+               if ($imageOnly) {
+                       $this->setAcceptableFiles(['image/*']);
+               }
+               else {
+                       // Using == here is safe, because we match a single element array containing
+                       // a scalar value.
+                       if ($this->getAcceptableFiles() == ['image/*']) {
+                               $this->setAcceptableFiles(null);
+                       }
+               }
        }
        
        /**
@@ -145,4 +166,36 @@ class UploadField {
                
                $this->allowSvgImage = $allowSvgImage;
        }
+       
+       /**
+        * Specifies acceptable file types. Use null to not specify any restrictions.
+        * 
+        * <strong>Heads up:</strong> This feature is used to improve user experience, by removing
+        * unacceptable files from the file picker. It does not validate the type of the uploaded
+        * file. You are responsible to perform (proper) validation on the server side.
+        * 
+        * Valid values are specified as "Unique file type specifiers":
+        * - A case insensitive file extension starting with a dot.
+        * - A mime type.
+        * - `audio/*`
+        * - `image/*`
+        * - `video/*`
+        * 
+        * @see         https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers
+        * @param       string[]|null     $acceptableFiles
+        * @since       5.3
+        */
+       public function setAcceptableFiles($acceptableFiles = null) {
+               $this->acceptableFiles = $acceptableFiles;
+       }
+       
+       /**
+        * Returns the acceptable file types.
+        * 
+        * @return      string[]|null
+        * @since       5.3
+        */
+       public function getAcceptableFiles() {
+               return $this->acceptableFiles;
+       }
 }
index 223321f2176b26833333299ef298a5c46f2b5c1c..7c4e92903de5d7ffcfc7458e5251d74a30581d4d 100644 (file)
@@ -3,7 +3,7 @@ namespace wcf\system\file\upload;
 use wcf\system\exception\ImplementationException;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
-use wcf\util\FileUtil;
+use wcf\util\ImageUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -24,7 +24,8 @@ class UploadHandler extends SingletonFactory {
        
        /**
         * Contains the valid image extensions w/o svg.
-        * var string
+        * @var string
+        * @deprecated 5.3 Use \wcf\util\ImageUtil::$imageExtensions instead (direct replacement).
         */
        const VALID_IMAGE_EXTENSIONS = ['jpeg', 'jpg', 'png', 'gif'];
        
@@ -437,20 +438,9 @@ class UploadHandler extends SingletonFactory {
         * @param       string          $imageName
         * @param       bool            $svgImageAllowed
         * @return      bool
+        * @deprecated  5.3 Use \wcf\util\ImageUtil::isImage() instead (direct replacement).
         */
        public static function isValidImage($location, $imageName, $svgImageAllowed) {
-               if (!file_exists($location)) {
-                       return false;
-               }
-               
-               if (@getimagesize($location) === false && (!$svgImageAllowed || !in_array(FileUtil::getMimeType($location), ['image/svg', 'image/svg+xml']))) {
-                       return false; 
-               }
-               
-               if (!in_array(mb_strtolower(pathinfo($imageName, PATHINFO_EXTENSION)), array_merge(self::VALID_IMAGE_EXTENSIONS, $svgImageAllowed ? ['svg'] : []))) {
-                       return false;
-               }
-               
-               return true;
+               return ImageUtil::isImage($location, $imageName, $svgImageAllowed);
        }
 }
index 8fe3d7a93d0a0063a54ab6822b87c6509759c6ed..88308ebbe7ea19bffaf395907926bf1d1318a0eb 100644 (file)
@@ -527,6 +527,29 @@ class FormDocument implements IFormDocument {
                return $this->invalid;
        }
        
+       /**
+        * @inheritDoc
+        * @since       5.3
+        */
+       public function needsRequiredFieldsInfo() {
+               /** @var IFormNode $node */
+               foreach ($this->getIterator() as $node) {
+                       if (
+                               $node->isAvailable()
+                               && $node instanceof IFormElement
+                               && $node->getLabel() !== null
+                               && (
+                                       ($node instanceof IFormContainer && $node->markAsRequired())
+                                       || ($node instanceof IFormField && $node->isRequired())
+                               )
+                       ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+       
        /**
         * @inheritDoc
         */
index 7025fc9495d3cef6b96627d9003c2c54d7d2edb4..6009d40b2d5d1b5fe1f7e0e52db96f206c928936 100644 (file)
@@ -287,6 +287,14 @@ interface IFormDocument extends IFormParentNode {
         */
        public function invalid($invalid = true);
        
+       /**
+        * Returns `true` if the information about required fields has to be shown below the form.
+        * 
+        * @return      bool
+        * @since       5.3
+        */
+       public function needsRequiredFieldsInfo();
+       
        /**
         * Sets the updated object (and loads the field values from the given object) and returns
         * this document.
index ba164f9137922112374405ce1d3687ae16cc8822..b14bacac94b38247f9efd7f537334427d9ec426e 100644 (file)
@@ -59,6 +59,14 @@ class FormContainer implements IFormContainer {
                );
        }
        
+       /**
+        * @inheritDoc
+        * @since       5.3
+        */
+       public function markAsRequired() {
+               return false;
+       }
+       
        /**
         * @inheritDoc
         */
index efdbbb942005547009438ebbe903122d96de2517..e654776f28d964340cd6fd23834ef74848de86af 100644 (file)
@@ -15,6 +15,14 @@ use wcf\system\form\builder\IFormParentNode;
  * @since      5.2
  */
 interface IFormContainer extends IFormChildNode, IFormElement, IFormParentNode {
+       /**
+        * Returns `true` if the whole container should be marked as required in the form output.
+        * 
+        * @return      bool
+        * @since       5.3
+        */
+       public function markAsRequired();
+       
        /**
         * Informs the form container of the updated object and this method is called by
         * `IFormDocument::updatedObject()` to inform the container that object data is being loaded.
index 419ec8c8c458446bd91c527af53189247cc0f525..71b680dcf0eaf4f8bbaef93b0901a90f534f5739 100644 (file)
@@ -70,7 +70,7 @@ class SuffixFormFieldContainer extends FormContainer {
        }
        
        /**
-        * Returns the intial option of the suffix selection dropdown.
+        * Returns the initial option of the suffix selection dropdown.
         * 
         * @return      array
         * @throws      \BadMethodCallException         if no suffix field is set or has no options
index 51c645528c77ff0bc152f29a7580db180e2cd948..2ad7b5d341597876d50bd6840935ef7c32e50730 100644 (file)
@@ -46,6 +46,13 @@ class WysiwygFormContainer extends FormContainer {
         */
        protected $attachmentData;
        
+       /**
+        * `true` if the preview button should be shown and `false` otherwise
+        * @var         bool
+        * @since       5.3
+        */
+       protected $enablePreviewButton = true;
+       
        /**
         * name of the relevant message object type
         * @var string
@@ -206,6 +213,26 @@ class WysiwygFormContainer extends FormContainer {
                return $this;
        }
        
+       /**
+        * Sets whether the preview button should be shown or not and returns this form container.
+        * 
+        * By default, the preview button is shown.
+        * 
+        * @param       bool                            $enablePreviewButton
+        * @return      WysiwygFormContainer            this form container
+        * @since       5.3
+        * @throws      \BadMethodCallException         if the form field container has already been populated yet
+        */
+       public function enablePreviewButton($enablePreviewButton = true) {
+               if ($this->isPopulated) {
+                       throw new \BadMethodCallException('Enabling and disabling the preview button is only possible before the form has been built.');
+               }
+               
+               $this->enablePreviewButton = $enablePreviewButton;
+               
+               return $this;
+       }
+       
        /**
         * Returns the form field handling attachments.
         * 
@@ -316,6 +343,26 @@ class WysiwygFormContainer extends FormContainer {
                return $this->required;
        }
        
+       /**
+        * Returns `true` if the preview button will be shown and returns `false` otherwise.
+        * 
+        * By default, the preview button is shown.
+        * 
+        * @return      bool
+        * @since       5.3
+        */
+       public function isPreviewButtonEnabled() {
+               return $this->enablePreviewButton;
+       }
+       
+       /**
+        * @since       5.3
+        * @inheritDoc
+        */
+       public function markAsRequired() {
+               return $this->getWysiwygField()->isRequired();
+       }
+       
        /**
         * Sets the message object type used by the wysiwyg form field.
         * 
@@ -440,12 +487,14 @@ class WysiwygFormContainer extends FormContainer {
                        $this->setAttachmentHandler();
                }
                
-               $this->getDocument()->addButton(
-                       WysiwygPreviewFormButton::create($this->getWysiwygId() . 'PreviewButton')
-                               ->objectType($this->messageObjectType)
-                               ->wysiwygId($this->getWysiwygId())
-                               ->objectId($this->getObjectId())
-               );
+               if ($this->enablePreviewButton) {
+                       $this->getDocument()->addButton(
+                               WysiwygPreviewFormButton::create($this->getWysiwygId() . 'PreviewButton')
+                                       ->objectType($this->messageObjectType)
+                                       ->wysiwygId($this->getWysiwygId())
+                                       ->objectId($this->getObjectId())
+                       );
+               }
                
                EventHandler::getInstance()->fireAction($this, 'populate');
        }
diff --git a/wcfsetup/install/files/lib/system/form/builder/field/CheckboxFormField.class.php b/wcfsetup/install/files/lib/system/form/builder/field/CheckboxFormField.class.php
new file mode 100644 (file)
index 0000000..495577b
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+namespace wcf\system\form\builder\field;
+use wcf\system\WCF;
+
+/**
+ * Implementation of a checkbox form field for boolen values.
+ * 
+ * @author     Peter Lohse
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Form\Builder\Field
+ * @since      5.3
+ */
+class CheckboxFormField extends BooleanFormField {
+       /**
+        * @inheritDoc
+        */
+       public function getHtml() {
+               if ($this->requiresLabel() && $this->getLabel() === null) {
+                       throw new \UnexpectedValueException("Form field '{$this->getPrefixedId()}' requires a label.");
+               }
+               
+               return WCF::getTPL()->fetch(
+                       '__checkboxFormField',
+                       'wcf',
+                       [
+                               'field' => $this,
+                       ]
+               );
+       }
+}
index d095b3246874268f00d8e30b6bafa0e46220dc0b..0f1e944269cf980419f05c81ff85f5f00eef80db 100644 (file)
@@ -7,6 +7,7 @@ use wcf\system\file\upload\UploadHandler;
 use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
 use wcf\system\form\builder\field\validation\FormFieldValidationError;
 use wcf\system\form\builder\IFormDocument;
+use wcf\util\ImageUtil;
 
 /**
  * Implementation of a form field for to uploads.
@@ -42,6 +43,13 @@ class UploadFormField extends AbstractFormField {
         */
        protected $allowSvgImage = false;
        
+       /**
+        * Acceptable file types.
+        * @var null|string[]
+        * @since 5.3
+        */
+       protected $acceptableFiles = null;
+       
        /**
         * maximum filesize for each uploaded file
         * @var null|number
@@ -110,6 +118,7 @@ class UploadFormField extends AbstractFormField {
                if ($this->isImageOnly()) {
                        $uploadField->setAllowSvgImage($this->svgImageAllowed());
                }
+               $uploadField->setAcceptableFiles($this->getAcceptableFiles());
                
                return $uploadField;
        }
@@ -305,7 +314,7 @@ class UploadFormField extends AbstractFormField {
                                        if (!is_string($v) || !file_exists($v)) {
                                                throw new \InvalidArgumentException("The " . $method . " must return an array of strings with the file locations.");
                                        }
-                                       return new UploadFile($v, basename($v), UploadHandler::isValidImage($v, basename($v), $this->svgImageAllowed()), true, $this->svgImageAllowed());
+                                       return new UploadFile($v, basename($v), ImageUtil::isImage($v, basename($v), $this->svgImageAllowed()), true, $this->svgImageAllowed());
                                }, $value);
                                
                                $this->value($value);
@@ -597,7 +606,10 @@ class UploadFormField extends AbstractFormField {
        /**
         * Sets the flag for `imageOnly`. This flag indicates whether only images 
         * can uploaded via this field. Other file types will be rejected during upload.
-        *
+        * 
+        * If set to `true` will also set the acceptable types to `image/*`. If set to
+        * false it will clear the acceptable types if they are `image/*`.
+        * 
         * @param       boolean         $imageOnly
         * @return      static                          this field
         * 
@@ -623,6 +635,16 @@ class UploadFormField extends AbstractFormField {
                }
                
                $this->imageOnly = $imageOnly;
+               if ($imageOnly) {
+                       $this->setAcceptableFiles(['image/*']);
+               }
+               else {
+                       // Using == here is safe, because we match a single element array containing
+                       // a scalar value.
+                       if ($this->getAcceptableFiles() == ['image/*']) {
+                               $this->setAcceptableFiles(null);
+                       }
+               }
                
                return $this;
        }
@@ -668,4 +690,38 @@ class UploadFormField extends AbstractFormField {
        public function svgImageAllowed() {
                return $this->allowSvgImage;
        }
+       
+       /**
+        * Specifies acceptable file types. Use null to not specify any restrictions.
+        * 
+        * <strong>Heads up:</strong> This feature is used to improve user experience, by removing
+        * unacceptable files from the file picker. It does not validate the type of the uploaded
+        * file. You are responsible to perform (proper) validation on the server side.
+        * 
+        * Valid values are specified as "Unique file type specifiers":
+        * - A case insensitive file extension starting with a dot.
+        * - A mime type.
+        * - `audio/*`
+        * - `image/*`
+        * - `video/*`
+        * 
+        * @see         https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers
+        * @param       string[]|null     $acceptableFiles
+        * @since       5.3
+        */
+       public function setAcceptableFiles($acceptableFiles = null) {
+               $this->acceptableFiles = $acceptableFiles;
+               
+               return $this;
+       }
+       
+       /**
+        * Returns the acceptable file types.
+        * 
+        * @return      string[]|null
+        * @since       5.3
+        */
+       public function getAcceptableFiles() {
+               return $this->acceptableFiles;
+       }
 }
index 9e8feb8324d817211ee1deee241abb1d23b91716..df113c53143e3f2f667ef9cd14a15fd32c59d344 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system\html\input\node;
 use wcf\data\smiley\Smiley;
 use wcf\data\smiley\SmileyCache;
 use wcf\system\bbcode\BBCodeHandler;
+use wcf\system\bbcode\HtmlBBCodeParser;
 use wcf\system\html\node\AbstractHtmlNodeProcessor;
 use wcf\util\DOMUtil;
 use wcf\util\JSON;
@@ -153,6 +154,44 @@ class HtmlInputNodeImg extends AbstractHtmlInputNode {
                $newElement->setAttribute('data-name', 'wsm');
                $newElement->setAttribute('data-attributes', base64_encode(JSON::encode($attributes)));
                DOMUtil::replaceElement($element, $newElement, false);
+               
+               // The media bbcode is a block element that may not be placed inside inline elements.
+               $parent = $newElement;
+               $blockLevelParent = null;
+               $blockElements = HtmlBBCodeParser::getInstance()->getBlockBBCodes();
+               while ($parent = $parent->parentNode) {
+                       switch ($parent->nodeName) {
+                               case 'a':
+                                       // Permit the media element to be placed inside a link.
+                                       break 2;
+                               
+                               case 'blockquote':
+                               case 'body':
+                               case 'code':
+                               case 'div':
+                               case 'li':
+                               case 'p':
+                               case 'td':
+                               case 'woltlab-quote':
+                               case 'woltlab-spoiler':
+                                       $blockLevelParent = $parent;
+                                       break 2;
+                               
+                               case 'woltlab-metacode':
+                                       if (in_array($parent->getAttribute('data-name'), $blockElements)) {
+                                               $blockLevelParent = $parent;
+                                               break 2;
+                                       }
+                                       break;
+                       }
+               }
+               
+               if ($blockLevelParent !== null) {
+                       $element = DOMUtil::splitParentsUntil($newElement, $parent);
+                       if ($element !== $newElement) {
+                               DOMUtil::insertBefore($newElement, $element);
+                       }
+               }
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeSmall.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeSmall.class.php
new file mode 100644 (file)
index 0000000..ac127f7
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+namespace wcf\system\html\input\node;
+use wcf\system\bbcode\BBCodeHandler;
+use wcf\system\html\node\AbstractHtmlNodeProcessor;
+use wcf\util\DOMUtil;
+
+/**
+ * Converts `<small>` elements into their CSS equivalent.
+ *
+ * @author      Alexander Ebert
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Html\Input\Node
+ * @since       5.3
+ */
+class HtmlInputNodeSmall extends AbstractHtmlInputNode {
+       /**
+        * @inheritDoc
+        */
+       protected $tagName = 'small';
+       
+       /**
+        * @inheritDoc
+        */
+       public function isAllowed(AbstractHtmlNodeProcessor $htmlNodeProcessor) {
+               if (BBCodeHandler::getInstance()->isAvailableBBCode('size')) {
+                       return [];
+               }
+               
+               return ['size'];
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) {
+               /** @var \DOMElement $element */
+               foreach ($elements as $element) {
+                       if (DOMUtil::isRemoved($element) || !$element->parentNode) {
+                               continue;
+                       }
+                       
+                       $span = $element->ownerDocument->createElement('span');
+                       $span->setAttribute('style', "font-size: 10pt");
+                       
+                       $element->parentNode->insertBefore($span, $element);
+                       $span->appendChild($element);
+                       
+                       DOMUtil::removeNode($element, true);
+               }
+       }
+}
index a789066f881663dd58a3e1578e9a5b554295473e..79dea3071a2d1521d5716cd00b4d14e90c95e6fd 100644 (file)
@@ -384,7 +384,7 @@ class HtmlInputNodeTextParser {
                                        $offset = $pos + mb_strlen($marker);
                                }
                        }
-                       while ($pos);
+                       while ($pos !== false);
                };
                
                foreach ($users as $userID => $username) {
index 39b0fbf4567db2d2ef1dc8616c2f9e91633e6d81..55cadf3c789c175c2e7492e8ca262251aa3c3bda 100644 (file)
@@ -17,6 +17,12 @@ use wcf\util\DOMUtil;
  * @since      3.0
  */
 class HtmlInputNodeWoltlabMetacodeMarker extends AbstractHtmlInputNode {
+       /**
+        * list of tag names that should be considered as block level elements
+        * @var string[]
+        */
+       public static $customBlockElementTagNames = [];
+       
        /**
         * list of bbcodes that represent block elements
         * @var string[]
@@ -508,17 +514,14 @@ class HtmlInputNodeWoltlabMetacodeMarker extends AbstractHtmlInputNode {
                        case 'woltlab-quote':
                        case 'woltlab-spoiler':
                                return true;
-                               break;
                        
                        case 'woltlab-metacode':
                                /** @var \DOMElement $node */
-                               if (in_array($node->getAttribute('data-name'), $this->blockElements)) {
-                                       return true;
-                               }
-                               break;
+                               return in_array($node->getAttribute('data-name'), $this->blockElements);
+                               
+                       default:
+                               return in_array($node->nodeName, self::$customBlockElementTagNames);
                }
-               
-               return false;
        }
        
        /**
index f3fdfe0f3c424fc92e66e97d3ffeb11e972a753f..e07b677798f1d497d280807f3a7dc737123fc2de 100644 (file)
@@ -283,7 +283,7 @@ abstract class AbstractHtmlNodeProcessor implements IHtmlNodeProcessor {
                }
                
                $elements = [];
-               foreach ($this->getDocument()->getElementsByTagName($tagName) as $element) {
+               foreach ($this->getXPath()->query("//{$tagName}") as $element) {
                        $elements[] = $element;
                }
                
@@ -304,7 +304,7 @@ abstract class AbstractHtmlNodeProcessor implements IHtmlNodeProcessor {
                
                $tags = [];
                /** @var \DOMElement $tag */
-               foreach ($this->getDocument()->getElementsByTagName('*') as $tag) {
+               foreach ($this->getXPath()->query("//*") as $tag) {
                        $tagName = $tag->nodeName;
                        if (!isset($tags[$tagName])) $tags[$tagName] = $tagName;
                }
index a04419c5fb036c4a3005806eb8b3ee25298da559..caaa0cd40b71c79745d055f84bed36524ad7d406 100644 (file)
@@ -138,9 +138,10 @@ class HtmlNodePlainLink {
         * Replaces the entire link, including any formatting, with the provided bbcode. This is
         * available for standalone links only.
         * 
-        * @param BBCode $bbcode
+        * @param BBCode        $bbcode
+        * @param int|null      $overrideObjectID
         */
-       public function replaceWithBBCode(BBCode $bbcode) {
+       public function replaceWithBBCode(BBCode $bbcode, $overrideObjectID = null) {
                $this->markAsTainted();
                
                if ($this->objectID === 0) {
@@ -149,7 +150,7 @@ class HtmlNodePlainLink {
                
                $metacodeElement = $this->link->ownerDocument->createElement('woltlab-metacode');
                $metacodeElement->setAttribute('data-name', $bbcode->bbcodeTag);
-               $metacodeElement->setAttribute('data-attributes', base64_encode(JSON::encode([$this->objectID])));
+               $metacodeElement->setAttribute('data-attributes', base64_encode(JSON::encode([($overrideObjectID !== null ? $overrideObjectID : $this->objectID)])));
                
                if ($bbcode->isBlockElement) {
                        if (!$this->isStandalone()) {
index 0e5b2cb27bc6e08512d8d2f67794c6390c6aa04c..b343b1fe7b8a36318c09cd33888445d7f91ed846 100644 (file)
@@ -65,18 +65,6 @@ class AmpHtmlOutputProcessor extends HtmlOutputProcessor {
                        while ($elements->length) {
                                /** @var \DOMElement $element */
                                $element = $elements->item(0);
-                               if ($tag === 'img') {
-                                       $styles = $element->getAttribute('style');
-                                       if (preg_match('~\bheight:\s*(\d+)px\b~', $styles, $matches)) $element->setAttribute('height', $matches[1]);
-                                       if (preg_match('~\bwidth:\s*(\d+)px\b~', $styles, $matches)) $element->setAttribute('width', $matches[1]);
-                                       
-                                       if (!$element->getAttribute('height') || !$element->getAttribute('width')) {
-                                               DOMUtil::removeNode($element);
-                                               continue;
-                                       }
-                                       
-                                       $element->removeAttribute('style');
-                               }
                                
                                $newElement = $element->ownerDocument->createElement('amp-' . $tag);
                                
@@ -87,6 +75,22 @@ class AmpHtmlOutputProcessor extends HtmlOutputProcessor {
                                        $newElement->setAttribute($attr->localName, $attr->nodeValue);
                                }
                                
+                               if ($tag === 'img') {
+                                       $styles = $newElement->getAttribute('style');
+                                       $newElement->removeAttribute('style');
+                                       if (preg_match('~\bheight:\s*(\d+)px\b~', $styles, $matches)) $newElement->setAttribute('height', $matches[1]);
+                                       if (preg_match('~\bwidth:\s*(\d+)px\b~', $styles, $matches)) $newElement->setAttribute('width', $matches[1]);
+                                       
+                                       if (!$newElement->getAttribute('height') || !$newElement->getAttribute('width')) {
+                                               $newElement->setAttribute('layout', 'fill');
+                                               
+                                               $container = $newElement->ownerDocument->createElement('span');
+                                               $container->setAttribute('class', 'unknownDimensionContainer');
+                                               $container->appendChild($newElement);
+                                               $newElement = $container;
+                                       }
+                               }
+                               
                                $element->parentNode->insertBefore($newElement, $element);
                                DOMUtil::removeNode($element);
                        }
index ea9ec8400b9187a2a855208df30739306e0baf64..547c38f2b04597dd19dbccdc4ccc892c66e9d176 100644 (file)
@@ -47,6 +47,12 @@ class HtmlOutputProcessor extends AbstractHtmlProcessor {
         */
        protected $outputType = 'text/html';
        
+       /**
+        * enables rel=ugc for external links
+        * @var bool
+        */
+       public $enableUgc = true;
+       
        /**
         * Processes the input html string.
         *
@@ -59,11 +65,18 @@ class HtmlOutputProcessor extends AbstractHtmlProcessor {
        public function process($html, $objectType, $objectID, $doKeywordHighlighting = true, $languageID = null) {
                $this->languageID = $languageID;
                $this->setContext($objectType, $objectID);
-               
-               $this->getHtmlOutputNodeProcessor()->setOutputType($this->outputType);
-               $this->getHtmlOutputNodeProcessor()->enableKeywordHighlighting($doKeywordHighlighting);
-               $this->getHtmlOutputNodeProcessor()->load($this, $html);
-               $this->getHtmlOutputNodeProcessor()->process();
+
+               MessageEmbeddedObjectManager::getInstance()->setActiveMessage($objectType, $objectID, $this->languageID);
+
+               try {
+                       $this->getHtmlOutputNodeProcessor()->setOutputType($this->outputType);
+                       $this->getHtmlOutputNodeProcessor()->enableKeywordHighlighting($doKeywordHighlighting);
+                       $this->getHtmlOutputNodeProcessor()->load($this, $html);
+                       $this->getHtmlOutputNodeProcessor()->process();
+               }
+               finally {
+                       MessageEmbeddedObjectManager::getInstance()->reset();
+               }
        }
        
        /**
@@ -84,7 +97,17 @@ class HtmlOutputProcessor extends AbstractHtmlProcessor {
         * @inheritDoc
         */
        public function getHtml() {
-               return $this->getHtmlOutputNodeProcessor()->getHtml();
+               $context = $this->getContext();
+               MessageEmbeddedObjectManager::getInstance()->setActiveMessage($context['objectType'], $context['objectID'], $this->languageID);
+
+               try {
+                       $html = $this->getHtmlOutputNodeProcessor()->getHtml();
+               }
+               finally {
+                       MessageEmbeddedObjectManager::getInstance()->reset();
+               }
+
+               return $html;
        }
        
        /**
@@ -94,7 +117,6 @@ class HtmlOutputProcessor extends AbstractHtmlProcessor {
        public function setContext($objectType, $objectID) {
                parent::setContext($objectType, $objectID);
                
-               MessageEmbeddedObjectManager::getInstance()->setActiveMessage($objectType, $objectID, $this->languageID);
                $objectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.message', $objectType);
                if ($this->enableToc === null) {
                        $this->enableToc = (!empty($objectType->additionalData['enableToc']));
index 338dc88a6621ec636ee73c390926c05b7a678ee2..9ddc5dcebb5b1505d24e5a8308505b59a80682e9 100644 (file)
@@ -32,7 +32,8 @@ class HtmlOutputNodeA extends AbstractHtmlOutputNode {
                                $element->setAttribute('href', preg_replace('~^https?://~', RouteHandler::getProtocol(), $href));
                        }
                        else {
-                               self::markLinkAsExternal($element);
+                               /** @var HtmlOutputNodeProcessor $htmlNodeProcessor */
+                               self::markLinkAsExternal($element, $htmlNodeProcessor->getHtmlProcessor()->enableUgc);
                        }
                        
                        $value = StringUtil::trim($element->textContent);
@@ -67,27 +68,23 @@ class HtmlOutputNodeA extends AbstractHtmlOutputNode {
         * Marks an element as external.
         * 
         * @param       \DOMElement     $element
+        * @param       bool            $isUgc
         */
-       public static function markLinkAsExternal(\DOMElement $element) {
+       public static function markLinkAsExternal(\DOMElement $element, $isUgc = false) {
                $element->setAttribute('class', 'externalURL');
                
-               $rel = '';
-               if (EXTERNAL_LINK_REL_NOFOLLOW) {
-                       $rel = 'nofollow';
-               }
-               
+               $rel = 'nofollow';
                if (EXTERNAL_LINK_TARGET_BLANK) {
-                       if (!empty($rel)) $rel .= ' ';
-                       
-                       $rel .= 'noopener noreferrer';
+                       $rel .= ' noopener noreferrer';
                        
                        $element->setAttribute('target', '_blank');
                }
-               
-               if (!empty($rel)) {
-                       $element->setAttribute('rel', $rel);
+               if ($isUgc) {
+                       $rel .= ' ugc';
                }
                
+               $element->setAttribute('rel', $rel);
+               
                // If the link contains only a single image that is floated to the right,
                // then the external link marker is misaligned. Inheriting the CSS class
                // will cause the link marker to behave properly.
index 6f4e0b90505165ebdc60d26cc830d794f8b056f2..d03f0c1137b84f9bf3d31cabc255d4c1d7f02ee0 100644 (file)
@@ -85,7 +85,8 @@ class HtmlOutputNodeImg extends AbstractHtmlOutputNode {
                                        if (IMAGE_PROXY_INSECURE_ONLY && $urlComponents['scheme'] === 'https') {
                                                // proxy is enabled for insecure connections only
                                                if (!IMAGE_ALLOW_EXTERNAL_SOURCE && !$this->isAllowedOrigin($src)) {
-                                                       $this->replaceExternalSource($element, $src);
+                                                       /** @var HtmlOutputNodeProcessor $htmlNodeProcessor */
+                                                       $this->replaceExternalSource($element, $src, $htmlNodeProcessor->getHtmlProcessor()->enableUgc);
                                                }
                                                
                                                continue;
@@ -133,7 +134,8 @@ class HtmlOutputNodeImg extends AbstractHtmlOutputNode {
                                        }
                                }
                                else if (!IMAGE_ALLOW_EXTERNAL_SOURCE && !$this->isAllowedOrigin($src)) {
-                                       $this->replaceExternalSource($element, $src);
+                                       /** @var HtmlOutputNodeProcessor $htmlNodeProcessor */
+                                       $this->replaceExternalSource($element, $src, $htmlNodeProcessor->getHtmlProcessor()->enableUgc);
                                }
                                else if (MESSAGE_FORCE_SECURE_IMAGES && Url::parse($src)['scheme'] === 'http') {
                                        // rewrite protocol to `https`
@@ -148,15 +150,16 @@ class HtmlOutputNodeImg extends AbstractHtmlOutputNode {
         * 
         * @param       \DOMElement     $element
         * @param       string          $src
+        * @param       bool            $isUgc
         */
-       protected function replaceExternalSource(\DOMElement $element, $src) {
+       protected function replaceExternalSource(\DOMElement $element, $src, $isUgc = false) {
                $element->parentNode->insertBefore($element->ownerDocument->createTextNode('['.WCF::getLanguage()->get('wcf.bbcode.image.blocked').': '), $element);
                
                if (!DOMUtil::hasParent($element, 'a')) {
                        $link = $element->ownerDocument->createElement('a');
                        $link->setAttribute('href', $src);
                        $link->textContent = $src;
-                       HtmlOutputNodeA::markLinkAsExternal($link);
+                       HtmlOutputNodeA::markLinkAsExternal($link, $isUgc);
                }
                else {
                        $link = $element->ownerDocument->createTextNode($src);
diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeKbd.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeKbd.class.php
new file mode 100644 (file)
index 0000000..72152cb
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+namespace wcf\system\html\output\node;
+use wcf\system\html\node\AbstractHtmlNodeProcessor;
+
+/**
+ * Replaces the leading and trailing space with `&nbsp;` to prevent the browser from implicitly trimming
+ * it on display.
+ * 
+ * @author      Alexander Ebert
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Html\Output\Node
+ * @since       5.3
+ */
+class HtmlOutputNodeKbd extends AbstractHtmlOutputNode {
+       /**
+        * @inheritDoc
+        */
+       protected $tagName = 'kbd';
+       
+       /**
+        * @inheritDoc
+        */
+       public function process(array $elements, AbstractHtmlNodeProcessor $htmlNodeProcessor) {
+               /** @var \DOMElement $element */
+               foreach ($elements as $element) {
+                       $textContent = $element->textContent;
+                       
+                       if (mb_strlen($textContent) !== 0) {
+                               if ($textContent[0] === ' ') {
+                                       $textContent = "\u{00A0}" . mb_substr($textContent, 1);
+                               }
+                               
+                               if (mb_substr($textContent, -1, 1) === ' ') {
+                                       $textContent = mb_substr($textContent, 0, -1) . "\u{00A0}";
+                               }
+                               
+                               $element->textContent = $textContent;
+                       }
+               }
+       }
+}
index a546ab6ee8d5c45c843281916bff4b6b1d02eb46..a52bf9275728ff58c8ca828bacd13518c506b51a 100644 (file)
@@ -108,47 +108,7 @@ class HtmlOutputNodePre extends AbstractHtmlOutputNode {
                }
                
                if (!$highlighter) {
-                       // try to guess highlighter
-                       if (mb_strpos($content, '<?php') !== false) {
-                               $highlighter = 'php';
-                       }
-                       else if (mb_strpos($content, '<html') !== false) {
-                               $highlighter = 'html';
-                       }
-                       else if (mb_strpos($content, '<?xml') === 0) {
-                               $highlighter = 'xml';
-                       }
-                       else if (       mb_strpos($content, 'SELECT') === 0
-                               ||      mb_strpos($content, 'UPDATE') === 0
-                               ||      mb_strpos($content, 'INSERT') === 0
-                               ||      mb_strpos($content, 'DELETE') === 0) {
-                               $highlighter = 'sql';
-                       }
-                       else if (mb_strpos($content, 'import java.') !== false) {
-                               $highlighter = 'java';
-                       }
-                       else if (       mb_strpos($content, "---") !== false
-                               &&      mb_strpos($content, "\n+++") !== false) {
-                               $highlighter = 'diff';
-                       }
-                       else if (mb_strpos($content, "\n#include ") !== false) {
-                               $highlighter = 'c';
-                       }
-                       else if (mb_strpos($content, '#!/usr/bin/perl') === 0) {
-                               $highlighter = 'perl';
-                       }
-                       else if (mb_strpos($content, 'def __init__(self') !== false) {
-                               $highlighter = 'python';
-                       }
-                       else if (Regex::compile('^#!/bin/(ba|z)?sh')->match($content)) {
-                               $highlighter = 'bash';
-                       }
-                       else if (mb_strpos($content, '\\documentclass') !== false) {
-                               $highlighter = 'latex';
-                       }
-                       else if (mb_strpos($content, '!important;') !== false) {
-                               $highlighter = 'css';
-                       }
+                       $highlighter = $this->guessHighlighter($content);
                }
                $eventData = [
                        'highlighter' => $highlighter,
@@ -190,6 +150,102 @@ class HtmlOutputNodePre extends AbstractHtmlOutputNode {
                return WCF::getTPL()->fetch('codeMetaCode');
        }
        
+       /**
+        * Returns a likely highlighter for the given content.
+        * 
+        * @param string $content
+        * @return string
+        */
+       public function guessHighlighter($content) {
+               // PHP at the beginning is almost surely PHP.
+               if (mb_strpos($content, '<?php') === 0) {
+                       return 'php';
+               }
+               
+               if (    mb_strpos($content, 'SELECT') === 0
+               ||      mb_strpos($content, 'UPDATE') === 0
+               ||      mb_strpos($content, 'INSERT') === 0
+               ||      mb_strpos($content, 'DELETE') === 0) {
+                       return 'sql';
+               }
+               
+               if (mb_strpos($content, 'import java.') !== false) {
+                       return 'java';
+               }
+               
+               if (mb_strpos($content, 'using System;') !== false) {
+                       return 'csharp';
+               }
+               
+               if (    mb_strpos($content, "---") !== false
+               &&      mb_strpos($content, "\n+++") !== false) {
+                       return 'diff';
+               }
+               
+               if (mb_strpos($content, "\n#include ") !== false) {
+                       return 'c';
+               }
+               
+               if (mb_strpos($content, '#!/usr/bin/perl') === 0) {
+                       return 'perl';
+               }
+               
+               if (    mb_strpos($content, '#!/usr/bin/python') === 0
+               ||      mb_strpos($content, 'def __init__(self') !== false
+               ||      Regex::compile("from (\S+) import (\S+)")->match($content)) {
+                       return 'python';
+               }
+               
+               if (Regex::compile('^#!/bin/(ba|z)?sh')->match($content)) {
+                       return 'bash';
+               }
+               
+               if (    mb_strpos($content, 'FROM') === 0
+               &&      mb_strpos($content, "RUN") !== false) {
+                       return 'docker';
+               }
+               
+               if (    mb_stripos($content, "RewriteRule") !== false
+               ||      mb_stripos($content, "RewriteEngine On") !== false
+               ||      mb_stripos($content, "AuthUserFile") !== false) {
+                       return 'apacheconf';
+               }
+               
+               if (mb_strpos($content, '\\documentclass') !== false) {
+                       return 'latex';
+               }
+               
+               // PHP somewhere later might not necessarily be PHP, it could also be
+               // a .patch or a Dockerfile.
+               if (mb_strpos($content, '<?php') !== false) {
+                       return 'php';
+               }
+               
+               if (    mb_strpos($content, '{/if}') !== false
+               &&      (       mb_strpos($content, '<div') !== false
+                       ||      mb_strpos($content, '<span') !== false)) {
+                       return 'smarty';
+               }
+               
+               if (mb_strpos($content, '<html') !== false) {
+                       return 'html';
+               }
+               
+               if (mb_strpos($content, '<?xml') === 0) {
+                       return 'xml';
+               }
+               
+               if (mb_strpos($content, '@mixin') !== false) {
+                       return 'scss';
+               }
+               
+               if (mb_strpos($content, '!important;') !== false) {
+                       return 'css';
+               }
+               
+               return '';
+       }
+       
        /**
         * Returns a unique ID for this code block.
         *
index 86160cb32e6aa1146bfa3ebaa446445943b9f166..9ac423ce5195d85a67e47f78b4185bfd5fb6d641 100644 (file)
@@ -91,18 +91,14 @@ class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor {
                $this->invokeNodeHandlers('wcf\system\html\output\node\HtmlOutputNode', ['woltlab-metacode']);
                
                if ($this->getHtmlProcessor()->removeLinks) {
-                       $links = $this->getDocument()->getElementsByTagName('a');
-                       while ($links->length) {
-                               DOMUtil::removeNode($links->item(0), true);
+                       foreach ($this->getXPath()->query('//a') as $link) {
+                               DOMUtil::removeNode($link, true);
                        }
                }
                
                if ($this->outputType !== 'text/html') {
                        // convert `<p>...</p>` into `...<br><br>`
-                       $paragraphs = $this->getDocument()->getElementsByTagName('p');
-                       while ($paragraphs->length) {
-                               $paragraph = $paragraphs->item(0);
-                               
+                       foreach ($this->getXPath()->query('//p') as $paragraph) {
                                $isLastNode = true;
                                $sibling = $paragraph;
                                while ($sibling = $sibling->nextSibling) {
@@ -161,10 +157,7 @@ class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor {
                                
                                // insert a trailing newline for certain elements, such as `<br>` or `<li>`
                                foreach (self::$plainTextNewlineTags as $tagName) {
-                                       $elements = $this->getDocument()->getElementsByTagName($tagName);
-                                       while ($elements->length) {
-                                               $element = $elements->item(0);
-                                               
+                                       foreach ($this->getXPath()->query("//{$tagName}") as $element) {
                                                $newline = $this->getDocument()->createTextNode("\n");
                                                $element->parentNode->insertBefore($newline, $element->nextSibling);
                                                DOMUtil::removeNode($element, true);
@@ -172,9 +165,8 @@ class HtmlOutputNodeProcessor extends AbstractHtmlNodeProcessor {
                                }
                                
                                // remove all other elements
-                               $elements = $this->getDocument()->getElementsByTagName('*');
-                               while ($elements->length) {
-                                       DOMUtil::removeNode($elements->item(0), true);
+                               foreach ($this->getXPath()->query('//*') as $element) {
+                                       DOMUtil::removeNode($element, true);
                                }
                        }
                }
index 436b1c19457b3a4c7ddb431c0986d6424ae43d1e..5d21c4ac4beff5085708aca51b4fd9b0ef7eff7d 100644 (file)
@@ -23,6 +23,7 @@ class HtmlToc {
                $titleRegex = new Regex('[^\p{L}\p{N}]+', Regex::UTF_8);
                
                // fetch all headings in their order of appearance
+               $usedIDs = [];
                /** @var HtmlTocItem[] $headings */
                $headings = [];
                /** @var \DOMElement $hElement */
@@ -38,7 +39,16 @@ class HtmlToc {
                        // trim to 80 characters
                        $id = rtrim(mb_substr($id, 0, 80), '-');
                        $id = mb_strtolower($id);
-                       
+                       if (isset($usedIDs[$id])) {
+                               $i = 2;
+                               do {
+                                       $newID = $id . '--' . ($i++);
+                               }
+                               while (isset($usedIDs[$newID]));
+                               $id = $newID;
+                       }
+                       $usedIDs[$id] = $id;
+
                        // Using the 'normalized' title allows for human-readable anchors that will remain
                        // valid even when new headings are being added or existing ones are removed. This
                        // also covers the relocation of a heading to a new position.
index b84c0ab97cf1506c591e1aebf0bcaca0a36a3452..5ffad1643824055f0135486255984268f62ccf5b 100644 (file)
@@ -133,12 +133,12 @@ class GDImageAdapter implements IImageAdapter {
        /**
         * @inheritDoc
         */
-       public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) {
+       public function createThumbnail($maxWidth, $maxHeight, $preserveAspectRatio = true) {
                $x = $y = 0;
                $sourceWidth = $this->width;
                $sourceHeight = $this->height;
                
-               if ($obtainDimensions) {
+               if ($preserveAspectRatio) {
                        if ($maxWidth / $this->width < $maxHeight / $this->height) {
                                $width = $maxWidth;
                                $height = round($this->height * ($width / $this->width));
index ea60187154c4d2e938ba9fc3a91b0049e22705bc..4bef9df37375c28922566fd90e7b5caff8d0644c 100644 (file)
@@ -38,10 +38,10 @@ interface IImageAdapter {
         * 
         * @param       integer         $maxWidth
         * @param       integer         $maxHeight
-        * @param       boolean         $obtainDimensions
+        * @param       boolean         $preserveAspectRatio
         * @return      mixed
         */
-       public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true);
+       public function createThumbnail($maxWidth, $maxHeight, $preserveAspectRatio = true);
        
        /**
         * Clips a part of currently loaded image, overwrites image resource within instance.
diff --git a/wcfsetup/install/files/lib/system/image/adapter/IMemoryAwareImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/IMemoryAwareImageAdapter.class.php
new file mode 100644 (file)
index 0000000..f68388a
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+namespace wcf\system\image\adapter;
+
+/**
+ * A memory aware image adapter is able to determine whether it is
+ * likely able to process an image within the process' memory limit.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Image\Adapter
+ * @since      5.3
+ */
+interface IMemoryAwareImageAdapter extends IImageAdapter {
+       /**
+        * Returns whether it is believed that sufficient memory
+        * is available to process an image with the given properties.
+        * 
+        * @param       integer         $width
+        * @param       integer         $height
+        * @param       string          $mimeType
+        * @return      boolean
+        */
+       public function checkMemoryLimit($width, $height, $mimeType);
+}
index 627062443f47bcd0d1dae7995d16666e31424dcf..5f68955439e76fe62389ef09b657bf3c6e4dd95c 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\system\image\adapter;
 use wcf\system\exception\SystemException;
+use wcf\util\FileUtil;
 
 /**
  * Wrapper for image adapters.
@@ -10,7 +11,7 @@ use wcf\system\exception\SystemException;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Image\Adapter
  */
-class ImageAdapter implements IImageAdapter {
+class ImageAdapter implements IImageAdapter, IMemoryAwareImageAdapter {
        /**
         * IImageAdapter object
         * @var IImageAdapter
@@ -70,7 +71,7 @@ class ImageAdapter implements IImageAdapter {
        /**
         * @inheritDoc
         */
-       public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) {
+       public function createThumbnail($maxWidth, $maxHeight, $preserveAspectRatio = true) {
                if ($maxWidth > $this->getWidth() && $maxHeight > $this->getHeight()) {
                        throw new SystemException("Dimensions for thumbnail can not exceed image dimensions.");
                }
@@ -78,7 +79,7 @@ class ImageAdapter implements IImageAdapter {
                $maxHeight = min($maxHeight, $this->getHeight());
                $maxWidth = min($maxWidth, $this->getWidth());
                
-               return $this->adapter->createThumbnail($maxWidth, $maxHeight, $obtainDimensions);
+               return $this->adapter->createThumbnail($maxWidth, $maxHeight, $preserveAspectRatio);
        }
        
        /**
@@ -352,6 +353,19 @@ class ImageAdapter implements IImageAdapter {
                $this->overlayImage($file, $x, $y, $opacity);
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function checkMemoryLimit($width, $height, $mimeType) {
+               if ($this->adapter instanceof IMemoryAwareImageAdapter) {
+                       return $this->adapter->checkMemoryLimit($width, $height, $mimeType);
+               }
+               
+               $channels = $mimeType == 'image/png' ? 4 : 3;
+               
+               return FileUtil::checkMemoryLimit($width * $height * $channels * 2.1);
+       }
+       
        /**
         * @inheritDoc
         */
index fa08741c16e4480cc9e2b1723b042cd71b775dd8..eb1912e9ec540fc7bbb9aaa9477d75c4550f8bf0 100644 (file)
@@ -117,14 +117,14 @@ class ImagickImageAdapter implements IImageAdapter {
        /**
         * @inheritDoc
         */
-       public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) {
+       public function createThumbnail($maxWidth, $maxHeight, $preserveAspectRatio = true) {
                $thumbnail = clone $this->imagick;
                
                if ($thumbnail->getImageFormat() == 'GIF') {
                        $thumbnail = $thumbnail->coalesceImages();
                        
                        do {
-                               if ($obtainDimensions) {
+                               if ($preserveAspectRatio) {
                                        $thumbnail->thumbnailImage($maxWidth, $maxHeight, true);
                                        $thumbnail->setImagePage(0, 0, 0, 0);
                                }
@@ -135,7 +135,7 @@ class ImagickImageAdapter implements IImageAdapter {
                        }
                        while ($thumbnail->nextImage());
                }
-               else if ($obtainDimensions) {
+               else if ($preserveAspectRatio) {
                        $thumbnail->thumbnailImage($maxWidth, $maxHeight, true);
                }
                else {
@@ -349,15 +349,17 @@ class ImagickImageAdapter implements IImageAdapter {
                        throw new SystemException("Given image is not a valid Imagick-object.");
                }
                
-               // circumvent writeImages() bug in version 3.1.0 RC 1
-               if (phpversion('imagick') == '3.1.0RC1' && $this->supportsWritingAnimatedGIF) {
-                       $file = fopen($filename, 'w');
-                       $image->writeImagesFile($file);
-                       fclose($file);
-               }
-               else {
-                       $image->writeImages($filename, true);
+               // Greatly reduces the time required to create the image and drastically
+               // reduces the filesize to more reasonable levels without a visible
+               // quality loss.
+               //
+               // See https://github.com/Imagick/imagick/issues/360
+               if ($image->getImageFormat() == 'GIF') {
+                       $image = $image->deconstructImages();
+                       $image->quantizeImages(256, \Imagick::COLORSPACE_SRGB, 0, false, false);
                }
+               
+               $image->writeImages($filename, true);
        }
        
        /**
index 3755c6d512f8d58bc212097ae4e901b6f71e3b7a..0ec022913c72f14fe5395d92d0c81d69f4306cac 100644 (file)
@@ -112,11 +112,6 @@ class MediaImporter extends AbstractImporter {
                        $statement->execute([$media->mediaID, $languageID ?: null, $contentData['title'], $contentData['caption'], $contentData['altText']]);
                }
                
-               // create thumbnails
-               if ($media->isImage) {
-                       $this->getSaveStrategy()->generateThumbnails($media);
-               }
-               
                ImportHandler::getInstance()->saveNewID('com.woltlab.wcf.media', $oldID, $media->mediaID);
                return $media->mediaID;
        }
index c6a79eb2313f324c9dd29064ff2e3f6e7bb5b91d..9faefeb8246f1739b583d5b0d1dcd78b66def7d0 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system\importer;
 use wcf\data\user\group\UserGroup;
 use wcf\data\user\group\UserGroupAction;
 use wcf\data\user\group\UserGroupEditor;
+use wcf\system\option\user\group\UserGroupOptionHandler;
 
 /**
  * Imports user groups.
@@ -32,7 +33,8 @@ class UserGroupImporter extends AbstractImporter {
                        }
                        
                        $action = new UserGroupAction([], 'create', [
-                               'data' => $data
+                               'data' => $data,
+                               'options' => $this->getOptionHandler()->save(),
                        ]);
                        $returnValues = $action->executeAction();
                        $group = $returnValues['returnValues'];
@@ -75,4 +77,12 @@ class UserGroupImporter extends AbstractImporter {
                
                return $newGroupID;
        }
+       
+       protected function getOptionHandler() {
+               $optionHandler = new UserGroupOptionHandler(false, '', '');
+               $optionHandler->init();
+               $optionHandler->readData();
+               
+               return $optionHandler;
+       }
 }
index 1ecd17568f915338f4e2eef10b1cfc3fb470ce47..a423d5d26a719c4c20494c28aa81e461a832efc3 100644 (file)
@@ -176,7 +176,7 @@ class UserImporter extends AbstractImporter {
                        }
                }
                
-               if (!$user->activationCode) $defaultGroupIDs = UserGroup::getGroupIDsByType([UserGroup::EVERYONE, UserGroup::USERS]);
+               if (!$user->pendingActivation()) $defaultGroupIDs = UserGroup::getGroupIDsByType([UserGroup::EVERYONE, UserGroup::USERS]);
                else $defaultGroupIDs = UserGroup::getGroupIDsByType([UserGroup::EVERYONE, UserGroup::GUESTS]);
                
                $groupIDs = array_merge($groupIDs, $defaultGroupIDs);
diff --git a/wcfsetup/install/files/lib/system/io/HttpFactory.class.php b/wcfsetup/install/files/lib/system/io/HttpFactory.class.php
new file mode 100644 (file)
index 0000000..7ee07e2
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+namespace wcf\system\io;
+use GuzzleHttp\Client;
+use GuzzleHttp\ClientInterface;
+
+/**
+ * Factory for HTTP Clients.
+ * 
+ * As of right now the factory returns objects that implement Guzzle's ClientInterface.
+ * Even if Guzzle will remain the HTTP client of choice for the foreseeable future you should
+ * strive to use PSR-7 objects instead of relying on Guzzle's shortcuts for best compatibility.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Io
+ * @since      5.3
+ */
+final class HttpFactory {
+       /**
+        * @var Client
+        */
+       private static $defaultClient;
+       
+       /**
+        * Returns a RFC 7231#5.5.3 compatible user agent.
+        * 
+        * @return string
+        */
+       public static function getDefaultUserAgent() {
+               return 'WoltLabSuite/'.\wcf\getMinorVersion();
+       }
+       
+       /**
+        * Returns a reference to the default HTTP client.
+        * 
+        * @return ClientInterface
+        */
+       public static function getDefaultClient() {
+               if (self::$defaultClient === null) {
+                       self::$defaultClient = static::makeClient();
+               }
+               
+               return self::$defaultClient;
+       }
+       
+       /**
+        * Creates a new HTTP client.
+        * 
+        * The HTTP proxy will automatically be enabled, unless
+        * specifically removed by passing appropriate options.
+        * 
+        * @return ClientInterface
+        * @see Client
+        */
+       public static function makeClient(array $options = []) {
+               $defaults = [
+                       'proxy' => PROXY_SERVER_HTTP,
+                       'headers' => [],
+               ];
+               
+               foreach ($defaults as $key => $value) {
+                       if (!array_key_exists($key, $options)) {
+                               $options[$key] = $value;
+                       }
+               }
+               
+               $foundUserAgent = false;
+               foreach ($options['headers'] as $headerName => $value) {
+                       if (strtolower($headerName) === 'user-agent') {
+                               $foundUserAgent = true;
+                               break;
+                       }
+               }
+               if (!$foundUserAgent) {
+                       $options['headers']['user-agent'] = self::getDefaultUserAgent();
+               }
+               
+               return new Client($options);
+       }
+}
index 170374e089cee0026612cbf094c6578926dcd8fe..90f9b38c31bdd8441ea64935830650148df7934b 100644 (file)
@@ -104,12 +104,17 @@ class RemoteFile extends File {
                // PHP 5.6.8+ defines STREAM_CRYPTO_METHOD_TLS_CLIENT as STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT for BC reasons.
                // STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT was introduced in PHP 5.6.8, but is not exposed to userland. Try to use
                // it for forward compatibility.
-               if (defined('STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT')) $cryptoType = STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT;
+               // 
+               // As of PHP 7.2+ STREAM_CRYPTO_METHOD_TLS_CLIENT is equivalent to STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT.
+               // see: https://wiki.php.net/rfc/improved-tls-constants
+               // see: https://github.com/php/php-src/blob/197cac65fdf712effb19ad3e40688ceb7ebc7f7d/main/streams/php_stream_transport.h#L173-L175
+               if (defined('STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT')) $cryptoType |= STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT;
                
                // Add bits for all known TLS versions for the reasons above.
                if (defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) $cryptoType |= STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
                if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) $cryptoType |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
                if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) $cryptoType |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+               if (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) $cryptoType |= STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
                
                return stream_socket_enable_crypto($this->resource, $enable, $cryptoType);
        }
index 2c5f32144820086d5880f1f43083f2334d596581..ff2b882664857e1e41bbb97e268b1440a4494c7c 100644 (file)
@@ -180,14 +180,10 @@ class Tar implements IArchive {
                $this->file->seek($header['offset']);
                
                // read data
-               $content = '';
-               $n = floor($header['size'] / 512);
-               for ($i = 0; $i < $n; $i++) {
-                       $content .= $this->file->read(512);
-               }
-               if (($header['size'] % 512) != 0) {
-                       $buffer = $this->file->read(512);
-                       $content .= substr($buffer, 0, $header['size'] % 512);
+               $content = $this->file->read($header['size']);
+               
+               if (strlen($content) != $header['size']) {
+                       throw new SystemException("Could not untar file '".$header['filename']."' to string. Maybe the archive is truncated?");
                }
                
                return $content;
diff --git a/wcfsetup/install/files/lib/system/language/I18nPlural.class.php b/wcfsetup/install/files/lib/system/language/I18nPlural.class.php
new file mode 100644 (file)
index 0000000..07c52e2
--- /dev/null
@@ -0,0 +1,515 @@
+<?php /** @noinspection ALL */
+namespace wcf\system\language;
+use wcf\system\WCF;
+
+/**
+ * Provides functions for pluralization rules.
+ * 
+ * @author     Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Language
+ * @since      5.3
+ * @see https://unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
+ */
+class I18nPlural {
+       const PLURAL_FEW = 'few';
+       const PLURAL_MANY = 'many';
+       const PLURAL_ONE = 'one';
+       const PLURAL_OTHER = 'other';
+       const PLURAL_TWO = 'two';
+       const PLURAL_ZERO = 'zero';
+       
+       /**
+        * Returns the plural category for the given value.
+        * 
+        * @param       number         $value
+        * @param       string         $languageCode
+        * @return      string
+        */
+       public static function getCategory($value, $languageCode = null) {
+               if ($languageCode === null) {
+                       $languageCode = WCF::getLanguage()->getFixedLanguageCode();
+               }
+               
+               // Fallback: handle unknown languages as English
+               if (!method_exists(self::class, $languageCode)) {
+                       $languageCode = 'en';
+               }
+               
+               if ($category = self::$languageCode($value)) {
+                       return $category;
+               }
+               
+               return self::PLURAL_OTHER;
+       }
+       
+       /**
+        * `f` is the fractional number as a whole number (1.234 yields 234)
+        *
+        * @param       number          $n
+        * @return      integer
+        */
+       private static function getF($n) {
+               $n = (string)$n;
+               $pos = strpos($n, '.');
+               if ($pos === false) {
+                       return 0;
+               }
+               
+               return intval(substr($n, $pos + 1));
+       }
+       
+       /**
+        * `v` represents the number of digits of the fractional part (1.234 yields 3)
+        *
+        * @param       number          $n
+        * @return      integer
+        */
+       private static function getV($n) {
+               return strlen(preg_replace('/^[^.]*\.?/', '', (string)$n));
+       }
+       
+       // Afrikaans
+       private static function af($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Amharic
+       private static function am($n) {
+               $i = floor(abs($n));
+               if ($n == 1 || $i === 0) return self::PLURAL_ONE;
+       }
+       
+       // Arabic
+       private static function ar($n) {
+               if ($n == 0) return self::PLURAL_ZERO;
+               if ($n == 1) return self::PLURAL_ONE;
+               if ($n == 2) return self::PLURAL_TWO;
+               
+               $mod100 = $n % 100;
+               if ($mod100 >= 3 && $mod100 <= 10) return self::PLURAL_FEW;
+               if ($mod100 >= 11 && $mod100 <= 99) return self::PLURAL_MANY;
+       }
+       
+       // Assamese
+       private static function as($n) {
+               $i = floor(abs($n));
+               if ($n == 1 || $i === 0) return self::PLURAL_ONE;
+       }
+       
+       // Azerbaijani
+       private static function az($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Belarusian
+       private static function be($n) {
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               
+               if ($mod10 == 1 && $mod100 != 11) return self::PLURAL_ONE;
+               if ($mod10 >= 2 && $mod10 <= 4 && !($mod100 >= 12 && $mod100 <= 14)) return self::PLURAL_FEW;
+               if ($mod10 == 0 || ($mod10 >= 5 && $mod10 <= 9) || ($mod100 >= 11 && $mod100 <= 14)) return self::PLURAL_MANY;
+       }
+       
+       // Bulgarian
+       private static function bg($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Bengali
+       private static function bn($n) {
+               $i = floor(abs($n));
+               if ($n == 1 || $i === 0) return self::PLURAL_ONE;
+       }
+       
+       // Tibetan
+       private static function bo($n) {}
+       
+       // Bosnian
+       private static function bs($n) {
+               $v = self::getV($n);
+               $f = self::getF($n);
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               $fMod10 = $f % 10;
+               $fMod100 = $f % 100;
+               
+               if (($v == 0 && $mod10 == 1 && $mod100 != 11) || ($fMod10 == 1 && $fMod100 != 11)) return self::PLURAL_ONE;
+               if (($v == 0 && $mod10 >= 2 && $mod10 <= 4 && $mod100 >= 12 && $mod100 <= 14)
+                       || ($fMod10 >= 2 && $fMod10 <= 4 && $fMod100 >= 12 && $fMod100 <= 14)) return self::PLURAL_FEW;
+       }
+               
+       // Czech
+       private static function cs($n) {
+               $v = self::getV($n);
+               
+               if ($n == 1 && $v === 0) return self::PLURAL_ONE;
+               if ($n >= 2 && $n <= 4 && $v === 0) return self::PLURAL_FEW;
+               if ($v === 0) return self::PLURAL_MANY;
+       }
+       
+       // Welsh
+       private static function cy($n) {
+               if ($n == 0) return self::PLURAL_ZERO;
+               if ($n == 1) return self::PLURAL_ONE;
+               if ($n == 2) return self::PLURAL_TWO;
+               if ($n == 3) return self::PLURAL_FEW;
+               if ($n == 6) return self::PLURAL_MANY;
+       }
+       
+       // Danish
+       private static function da($n) {
+               if ($n > 0 && $n < 2) return self::PLURAL_ONE;
+       }
+       
+       // Greek
+       private static function el($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+
+       // Catalan (ca)
+       // German (de)
+       // English (en)
+       // Estonian (et)
+       // Finnish (fi)
+       // Italian (it)
+       // Dutch (nl)
+       // Swedish (sv)
+       // Swahili (sw)
+       // Urdu (ur)
+       private static function en($n) {
+               if ($n == 1 && self::getV($n) === 0) return self::PLURAL_ONE;
+       }
+       
+       // Spanish
+       private static function es($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Basque
+       private static function eu($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Persian
+       private static function fa($n) {
+               if ($n >= 0 && $n <= 1) return self::PLURAL_ONE;
+       }
+       
+       // French
+       private static function fr($n) {
+               if ($n >= 0 && $n < 2) return self::PLURAL_ONE;
+       }
+       
+       // Irish
+       private static function ga($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+               if ($n == 2) return self::PLURAL_TWO;
+               if ($n == 3 || $n == 4 || $n == 5 || $n == 6) return self::PLURAL_FEW;
+               if ($n == 7 || $n == 8 || $n == 9 || $n == 10) return self::PLURAL_MANY;
+       }
+       
+       // Gujarati
+       private static function gu($n) {
+               if ($n >= 0 && $n <= 1) return self::PLURAL_ONE;
+       }
+       
+       // Hebrew
+       private static function he($n) {
+               $v = self::getV($n);
+               
+               if ($n == 1 && $v === 0) return self::PLURAL_ONE;
+               if ($n == 2 && $v === 0) return self::PLURAL_TWO;
+               if ($n > 10 && $v === 0 && $n % 10 == 0) return self::PLURAL_MANY;
+       }
+       
+       // Hindi
+       private static function hi($n) {
+               if ($n >= 0 && $n <= 1) return self::PLURAL_ONE;
+       }
+       
+       // Croatian
+       private static function hr($n) {
+               // same as Bosnian
+               return self::bs($n);
+       }
+       
+       // Hungarian
+       private static function hu($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Armenian
+       private static function hy($n) {
+               if ($n >= 0 && $n < 2) return self::PLURAL_ONE;
+       }
+       
+       // Indonesian
+       private static function id($n) {}
+       
+       // Icelandic
+       private static function is($n) {
+               $f = self::getF($n);
+               
+               if ($f === 0 && $n % 10 === 1 && !($n % 100 === 11) || !($f === 0)) return self::PLURAL_ONE;
+       }
+       
+       // Japanese
+       private static function ja($n) {}
+       
+       // Javanese
+       private static function jv($n) {}
+       
+       // Georgian
+       private static function ka($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Kazakh
+       private static function kk($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Khmer
+       private static function km($n) {}
+       
+       // Kannada
+       private static function kn($n) {
+               if ($n >= 0 && $n <= 1) return self::PLURAL_ONE;
+       }
+       
+       // Korean
+       private static function ko($n) {}
+       
+       // Kurdish
+       private static function ku($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Kyrgyz
+       private static function ky($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Luxembourgish
+       private static function lb($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Lao
+       private static function lo($n) {}
+       
+       // Lithuanian
+       private static function lt($n) {
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               
+               if ($mod10 == 1 && !($mod100 >= 11 && $mod100 <= 19)) return self::PLURAL_ONE;
+               if ($mod10 >= 2 && $mod10 <= 9 && !($mod100 >= 11 && $mod100 <= 19)) return self::PLURAL_FEW;
+               if (self::getF($n) != 0) return self::PLURAL_MANY;
+       }
+       
+       // Latvian
+       private static function lv($n) {
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               $v = self::getV($n);
+               $f = self::getF($n);
+               $fMod10 = $f % 10;
+               $fMod100 = $f % 100;
+               
+               if ($mod10 == 0 || ($mod100 >= 11 && $mod100 <= 19) || ($v == 2 && $fMod100 >= 11 && $fMod100 <= 19)) return self::PLURAL_ZERO;
+               if (($mod10 == 1 && $mod100 != 11) || ($v == 2 && $fMod10 == 1 && $fMod100 != 11) || ($v != 2 && $fMod10 == 1)) return self::PLURAL_ONE;
+       }
+       
+       // Macedonian
+       private static function mk($n) {
+               $v = self::getV($n);
+               $f = self::getF($n);
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               $fMod10 = $f % 10;
+               $fMod100 = $f % 100;
+               
+               if (($v == 0 && $mod10 == 1 && $mod100 != 11) || ($fMod10 == 1 && $fMod100 != 11)) return self::PLURAL_ONE;
+       }
+       
+       // Malayalam
+       private static function ml($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Mongolian 
+       private static function mn($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Marathi 
+       private static function mr($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Malay 
+       private static function ms($n) {}
+       
+       // Maltese 
+       private static function mt($n) {
+               $mod100 = $n % 100;
+               
+               if ($n == 1) return self::PLURAL_ONE;
+               if ($n == 0 || ($mod100 >= 2 && $mod100 <= 10)) return self::PLURAL_FEW;
+               if ($mod100 >= 11 && $mod100 <= 19) return self::PLURAL_MANY;
+       }
+       
+       // Burmese
+       private static function my($n) {}
+       
+       // Norwegian
+       private static function no($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Nepali
+       private static function ne($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Odia
+       private static function or($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Punjabi
+       private static function pa($n) {
+               if ($n == 1 || $n == 0) return self::PLURAL_ONE;
+       }
+       
+       // Polish
+       private static function pl($n) {
+               $v = self::getV($n);
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               
+               if ($n == 1 && $v == 0) return self::PLURAL_ONE;
+               if ($v == 0 && $mod10 >= 2 && $mod10 <= 4 && !($mod100 >= 12 && $mod100 <= 14)) return self::PLURAL_FEW;
+               if ($v == 0 && (($n != 1 && $mod10 >= 0 && $mod10 <= 1) || ($mod10 >= 5 && $mod10 <= 9) || ($mod100 >= 12 && $mod100 <= 14))) return self::PLURAL_MANY;
+       }
+       
+       // Pashto
+       private static function ps($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Portuguese
+       private static function pt($n) {
+               if ($n >= 0 && $n < 2) return self::PLURAL_ONE;
+       }
+       
+       // Romanian
+       private static function ro($n) {
+               $v = self::getV($n);
+               $mod100 = $n % 100;
+               
+               if ($n == 1 && $v === 0) return self::PLURAL_ONE;
+               if ($v != 0 || $n == 0 || ($mod100 >= 2 && $mod100 <= 19)) return self::PLURAL_FEW;
+       }
+       
+       // Russian
+       private static function ru($n) {
+               $mod10 = $n % 10;
+               $mod100 = $n % 100;
+               
+               if (self::getV($n) == 0) {
+                       if ($mod10 == 1 && $mod100 != 11) return self::PLURAL_ONE;
+                       if ($mod10 >= 2 && $mod10 <= 4 && !($mod100 >= 12 && $mod100 <= 14)) return self::PLURAL_FEW;
+                       if ($mod10 == 0 || ($mod10 >= 5 && $mod10 <= 9) || ($mod100 >= 11 && $mod100 <= 14)) return self::PLURAL_MANY; 
+               }
+       }
+       
+       // Sindhi
+       private static function sd($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Sinhala
+       private static function si($n) {
+               if ($n == 0 || $n == 1 || (floor($n) == 0 && self::getF($n) == 1)) return self::PLURAL_ONE;
+       }
+       
+       // Slovak
+       private static function sk($n) {
+               // same as Czech
+               return self::cs($n);
+       }
+       
+       // Slovenian
+       private static function sl($n) {
+               $v = self::getV($n);
+               $mod100 = $n % 100;
+               
+               if ($v == 0 && $mod100 == 1) return self::PLURAL_ONE;
+               if ($v == 0 && $mod100 == 2) return self::PLURAL_TWO;
+               if (($v == 0 && ($mod100 == 3 || $mod100 == 4)) || $v != 0) return self::PLURAL_FEW;
+       }
+       
+       // Albanian
+       private static function sq($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Serbian
+       private static function sr($n) {
+               // same as Bosnian
+               return self::bs($n);
+       }
+       
+       // Tamil
+       private static function ta($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Telugu
+       private static function te($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Tajik
+       private static function tg($n) {}
+       
+       // Thai
+       private static function th($n) {}
+       
+       // Turkmen
+       private static function tk($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Turkish
+       private static function tr($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Uyghur
+       private static function ug($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Ukrainian
+       private static function uk($n) {
+               // same as Russian
+               return self::ru($n);
+       }
+       
+       // Uzbek
+       private static function uz($n) {
+               if ($n == 1) return self::PLURAL_ONE;
+       }
+       
+       // Vietnamese
+       private static function vi($n) {}
+       
+       // Chinese
+       private static function zh($n) {}
+}
index 49913a9a8c8f8ae91ebcd337dbbbdbfdbe10a460..9a5c31b16dcb32770b1e2c8632b228b108e52c7d 100644 (file)
@@ -4,6 +4,8 @@ use wcf\data\user\menu\item\UserMenuItem;
 use wcf\system\cache\builder\UserMenuCacheBuilder;
 use wcf\system\menu\ITreeMenuItem;
 use wcf\system\menu\TreeMenu;
+use wcf\system\option\user\UserOptionHandler;
+use wcf\system\WCF;
 
 /**
  * Builds the user menu.
@@ -14,6 +16,12 @@ use wcf\system\menu\TreeMenu;
  * @package    WoltLabSuite\Core\System\Menu\User
  */
 class UserMenu extends TreeMenu {
+       /**
+        * user option handler for the `settings` category
+        * @var UserOptionHandler
+        */
+       protected $optionHandler;
+       
        /**
         * @inheritDoc
         */
@@ -21,6 +29,8 @@ class UserMenu extends TreeMenu {
                parent::loadCache();
                
                $this->menuItems = UserMenuCacheBuilder::getInstance()->getData();
+               $this->optionHandler = new UserOptionHandler(false, '', 'settings');
+               $this->optionHandler->setUser(WCF::getUser());
        }
        
        /**
@@ -31,6 +41,14 @@ class UserMenu extends TreeMenu {
                
                if (!parent::checkMenuItem($item)) return false;
                
+               // Hide links to user option categories without accessible options.
+               if (strpos($item->menuItem, 'wcf.user.option.category.') === 0) {
+                       $categoryName = str_replace('wcf.user.option.category.', '', $item->menuItem);
+                       if (!$this->optionHandler->countCategoryOptions($categoryName)) {
+                               return false;
+                       }
+               }
+               
                return $item->getProcessor()->isVisible();
        }
 }
index 0ba5658c1edc692fd212f0d6aae7fe1c799de7bc..81c62ce460f303efd5dd1528f19fbe8839ec70f9 100644 (file)
@@ -211,7 +211,7 @@ class QuickReplyManager extends SingletonFactory {
                $parameters['data'] = array_merge($additionalFields, $parameters['data']);
                
                // attachment support
-               if (MODULE_ATTACHMENT && !empty($parameters['tmpHash']) && $object instanceof IAttachmentMessageQuickReplyAction) {
+               if (!empty($parameters['tmpHash']) && $object instanceof IAttachmentMessageQuickReplyAction) {
                        $parameters['attachmentHandler'] = $object->getAttachmentHandler($this->container);
                }
                
index f7aef7d9a3c483172b1e910c059b0e151f0f42fe..d9af6697608b1a767a0f10e7869d2ca2881b9871 100644 (file)
@@ -66,6 +66,12 @@ class MessageEmbeddedObjectManager extends SingletonFactory {
                'insert' => [],
                'remove' => []
        ];
+
+       /**
+        * A list of previous active message settings used to restore
+        * the internal state in case of nested message processing.
+        */
+       protected $activeMessageHistory = [];
        
        /**
         * Registers the embedded objects found in given message.
@@ -283,10 +289,36 @@ class MessageEmbeddedObjectManager extends SingletonFactory {
         * @param       integer         $languageID
         */
        public function setActiveMessage($messageObjectType, $messageID, $languageID = null) {
+               if ($this->activeMessageObjectTypeID) {
+                       $this->activeMessageHistory[] = [
+                               'activeMessageID' => $this->activeMessageID,
+                               'activeMessageLanguageID' => $this->activeMessageLanguageID,
+                               'activeMessageObjectTypeID' => $this->activeMessageObjectTypeID,
+                       ];
+               }
+
                $this->activeMessageObjectTypeID = ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.message', $messageObjectType);
                $this->activeMessageID = $messageID;
                $this->activeMessageLanguageID = $languageID;
        }
+
+       /**
+        * Restores the internal state in case of nested message processing.
+        */
+       public function reset() {
+               $newState = \array_pop($this->activeMessageHistory);
+               if ($newState === null) {
+                       $newState = [
+                               'activeMessageID' => null,
+                               'activeMessageLanguageID' => null,
+                               'activeMessageObjectTypeID' => null,
+                       ];
+               }
+
+               $this->activeMessageID = $newState['activeMessageID'];
+               $this->activeMessageLanguageID = $newState['activeMessageLanguageID'];
+               $this->activeMessageObjectTypeID = $newState['activeMessageObjectTypeID'];
+       }
        
        /**
         * Returns the language id of the active message.
index 22bb8d773062d2722fdde51af2fd543bcdc82eb6..69239e11ad4de98cf86a03c48601f9baecb8b00d 100644 (file)
@@ -16,7 +16,7 @@ interface ISearchableUserOption {
         * Returns the html code for the search form element of this option.
         * 
         * @param       Option          $option
-        * @param       string          $value
+        * @param       mixed           $value
         * @return      string          html
         */
        public function getSearchFormElement(Option $option, $value);
index 24f3d6c6bdf8ee5594e19f69255b76bf3135c4ac..f8befc6904737b510f7b0d2e096f3dafe296bb00 100644 (file)
@@ -246,6 +246,34 @@ class OptionHandler implements IOptionHandler {
                return $children;
        }
        
+       /**
+        * Counts the number of options in a specific option category.
+        *
+        * @param       string          $categoryName
+        * @return      int
+        */
+       public function countCategoryOptions($categoryName = '') {
+               $count = 0;
+               
+               if (isset($this->cachedCategoryStructure[$categoryName])) {
+                       foreach ($this->cachedCategoryStructure[$categoryName] as $subCategoryName) {
+                               $count += $this->countCategoryOptions($subCategoryName);
+                       }
+               }
+               
+               if ($categoryName !== '') {
+                       if (isset($this->cachedOptionToCategories[$categoryName])) {
+                               foreach ($this->cachedOptionToCategories[$categoryName] as $optionName) {
+                                       if (isset($this->options[$optionName]) && $this->checkOption($this->options[$optionName])) {
+                                               $count++;
+                                       }
+                               }
+                       }
+               }
+               
+               return $count;
+       }
+       
        /**
         * @inheritDoc
         */
index 04a083f4dc488ccf574f18a3731a34e6b2a81377..14a4c053c3a821602970562cab2a561ea3e354e0 100644 (file)
@@ -19,9 +19,6 @@ class FacebookUserOptionOutput implements IUserOptionOutput {
        public function getOutput(User $user, UserOption $option, $value) {
                if (empty($value)) return '';
                
-               $url = StringUtil::encodeHTML('https://www.facebook.com/'.$value);
-               $value = StringUtil::encodeHTML($value);
-               
-               return '<a href="'.$url.'" class="externalURL"'.((EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK) ? (' rel="'.(EXTERNAL_LINK_REL_NOFOLLOW ? 'nofollow' : '').((EXTERNAL_LINK_REL_NOFOLLOW && EXTERNAL_LINK_TARGET_BLANK) ? ' ' : '').(EXTERNAL_LINK_TARGET_BLANK ? 'noopener noreferrer' : '').'"') : '').(EXTERNAL_LINK_TARGET_BLANK ? ' target="_blank"' : '').'>'.$value.'</a>';
+               return StringUtil::getAnchorTag('https://www.facebook.com/'.$value, $value, true, true);
        }
 }
index 1dd36cb9ce9487f0635bb83632abb2cd2220b5c4..6d28096ec5aa0ea0f86445348be2d9b504ce5a02 100644 (file)
@@ -19,9 +19,6 @@ class TwitterUserOptionOutput implements IUserOptionOutput {
        public function getOutput(User $user, UserOption $option, $value) {
                if (empty($value)) return '';
                
-               $url = StringUtil::encodeHTML('https://twitter.com/'.$value);
-               $value = StringUtil::encodeHTML($value);
-               
-               return '<a href="'.$url.'" class="externalURL"'.((EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK) ? (' rel="'.(EXTERNAL_LINK_REL_NOFOLLOW ? 'nofollow' : '').((EXTERNAL_LINK_REL_NOFOLLOW && EXTERNAL_LINK_TARGET_BLANK) ? ' ' : '').(EXTERNAL_LINK_TARGET_BLANK ? 'noopener noreferrer' : '').'"') : '').(EXTERNAL_LINK_TARGET_BLANK ? ' target="_blank"' : '').'>'.$value.'</a>';
+               return StringUtil::getAnchorTag('https://twitter.com/'.$value, $value, true, true);
        }
 }
index eae428bfbb706dab91c4a888fa30d59ec1749d93..0f2f1822dfff051645a5aca4b38cc821a3035670 100644 (file)
@@ -20,8 +20,8 @@ class URLUserOptionOutput implements IUserOptionOutput {
                if (empty($value) || $value == 'http://') return '';
                
                $value = self::getURL($value);
-               $value = StringUtil::encodeHTML($value);
-               return '<a href="'.$value.'" class="externalURL"'.((EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK) ? (' rel="'.(EXTERNAL_LINK_REL_NOFOLLOW ? 'nofollow' : '').((EXTERNAL_LINK_REL_NOFOLLOW && EXTERNAL_LINK_TARGET_BLANK) ? ' ' : '').(EXTERNAL_LINK_TARGET_BLANK ? 'noopener noreferrer' : '').'"') : '').(EXTERNAL_LINK_TARGET_BLANK ? ' target="_blank"' : '').'>'.$value.'</a>';
+               
+               return StringUtil::getAnchorTag($value, $value, true, true);
        }
        
        /**
index df9410e4056ae33a4ce6535e472bce0ff35b26e3..c92710befaca63a6b18d1e5c15f6bcaae8bf4f3d 100644 (file)
@@ -24,11 +24,7 @@ class UserGroupsUserGroupOptionType extends AbstractOptionType implements IUserG
                $selectedGroups = explode(',', $value);
                
                // get all groups
-               $groups = UserGroup::getGroupsByType();
-               
-               usort($groups, function(UserGroup $groupA, UserGroup $groupB) {
-                       return strcasecmp($groupA->getName(), $groupB->getName());
-               });
+               $groups = UserGroup::getSortedGroupsByType();
                
                // generate html
                $html = '';
index e67a9b5c41fe4ae3e6a5554b471f3a9051decec9..1e9d5008835f50481a4a50ad4fe31cf873046c4e 100644 (file)
@@ -88,6 +88,12 @@ class PackageArchive {
         */
        const INFO_FILE = 'package.xml';
        
+       /**
+        * marker for the void instruction
+        * @var string
+        */
+       const VOID_MARKER = "===void===";
+       
        /**
         * Creates a new PackageArchive object.
         * 
@@ -351,6 +357,24 @@ class PackageArchive {
                        $fromVersion = $element->getAttribute('fromversion');
                        $type = $element->getAttribute('type');
                        
+                       $void = $xpath->query('./ns:void', $element);
+                       if ($void->length > 1) {
+                               throw new PackageValidationException(PackageValidationException::VOID_NOT_ALONE);
+                       }
+                       else if ($void->length == 1) {
+                               if (!empty($instructionData)) {
+                                       throw new PackageValidationException(PackageValidationException::VOID_NOT_ALONE);
+                               }
+                               if ($type == 'install') {
+                                       throw new PackageValidationException(PackageValidationException::VOID_ON_INSTALL);
+                               }
+                               
+                               $instructionData[] = [
+                                       'pip' => self::VOID_MARKER,
+                                       'value' => '',
+                               ];
+                       }
+                       
                        if ($type == 'install') {
                                $this->instructions['install'] = $instructionData;
                        }
index ae1024bb905e1ce7f75e4d326fc7355f212a343f..9db1c2ad9dff06cd3f6f0cef2ee5b390afad5122 100644 (file)
@@ -522,12 +522,19 @@ class PackageInstallationDispatcher {
                                $host = str_replace(RouteHandler::getProtocol(), '', RouteHandler::getHost());
                                $path = RouteHandler::getPath(['acp']);
                                
+                               $isTainted = 1;
+                               if ($this->getPackage()->package == 'com.woltlab.wcf') {
+                                       // com.woltlab.wcf is special, because promptPackageDir() will not be executed.
+                                       $isTainted = 0;
+                               }
+                               
                                // insert as application
                                ApplicationEditor::create([
                                        'domainName' => $host,
                                        'domainPath' => $path,
                                        'cookieDomain' => $host,
-                                       'packageID' => $package->packageID
+                                       'packageID' => $package->packageID,
+                                       'isTainted' => $isTainted,
                                ]);
                        }
                }
@@ -703,6 +710,10 @@ class PackageInstallationDispatcher {
        protected function executePIP(array $nodeData) {
                $step = new PackageInstallationStep();
                
+               if ($nodeData['pip'] == PackageArchive::VOID_MARKER) {
+                       return $step;
+               }
+               
                // fetch all pips associated with current PACKAGE_ID and include pips
                // previously installed by current installation queue
                $sql = "SELECT  pluginName, className
@@ -956,10 +967,13 @@ class PackageInstallationDispatcher {
                                
                                $domainPath = FileUtil::addLeadingSlash($domainPath);
                                
-                               // update application path
+                               // update application path and untaint application
                                $application = new Application($this->getPackage()->packageID);
                                $applicationEditor = new ApplicationEditor($application);
-                               $applicationEditor->update(['domainPath' => $domainPath]);
+                               $applicationEditor->update([
+                                       'domainPath' => $domainPath,
+                                       'isTainted' => 0,
+                               ]);
                                
                                // create directory and set permissions
                                @mkdir($packageDir, 0777, true);
index 4e0b6870b0e9b5f9fe001ea65a8e0d98ec4406cc..742e3e685842c5c4b5cd67d1277cb7690051202f 100644 (file)
@@ -2,8 +2,6 @@
 namespace wcf\system\package;
 use wcf\data\package\update\server\PackageUpdateServer;
 use wcf\data\package\update\server\PackageUpdateServerEditor;
-use wcf\data\package\update\version\PackageUpdateVersionEditor;
-use wcf\data\package\update\PackageUpdateEditor;
 use wcf\data\package\Package;
 use wcf\system\cache\builder\PackageUpdateCacheBuilder;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
@@ -15,6 +13,7 @@ use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 use wcf\util\HTTPRequest;
 use wcf\util\JSON;
+use wcf\util\StringUtil;
 use wcf\util\XML;
 
 /**
@@ -81,8 +80,17 @@ class PackageUpdateDispatcher extends SingletonFactory {
                                $errorMessage = $e->getMessage();
                        }
                        catch (PackageUpdateUnauthorizedException $e) {
-                               $reply = $e->getRequest()->getReply();
-                               list($errorMessage) = reset($reply['httpHeaders']);
+                               $body = $e->getRequest()->getReply()['body'];
+                               
+                               // Try to find the page <title>.
+                               if (preg_match('~<title>(?<title>.*?)</title>~', $body, $matches)) {
+                                       $errorMessage = $matches['title'];
+                               }
+                               else {
+                                       $errorMessage = $body;
+                               }
+                               
+                               $errorMessage = mb_substr(StringUtil::trim(strip_tags($errorMessage)), 0, 65000);
                        }
                        
                        if ($errorMessage) {
@@ -472,127 +480,149 @@ class PackageUpdateDispatcher extends SingletonFactory {
         * @param       integer         $packageUpdateServerID
         */
        protected function savePackageUpdates(array &$allNewPackages, $packageUpdateServerID) {
-               // insert updates
                $excludedPackagesParameters = $fromversionParameters = $insertParameters = $optionalInserts = $requirementInserts = $compatibilityInserts = [];
+               $sql = "INSERT INTO     wcf" . WCF_N . "_package_update
+                                       (packageUpdateServerID, package, packageName, packageDescription, author, authorURL, isApplication, pluginStoreFileID)
+                       VALUES          (?, ?, ?, ?, ?, ?, ?, ?)";
+               $statement = WCF::getDB()->prepareStatement($sql);
                WCF::getDB()->beginTransaction();
                foreach ($allNewPackages as $identifier => $packageData) {
-                       // create new database entry
-                       $packageUpdate = PackageUpdateEditor::create([
-                               'packageUpdateServerID' => $packageUpdateServerID,
-                               'package' => $identifier,
-                               'packageName' => $packageData['packageName'],
-                               'packageDescription' => $packageData['packageDescription'],
-                               'author' => $packageData['author'],
-                               'authorURL' => $packageData['authorURL'],
-                               'isApplication' => $packageData['isApplication'],
-                               'pluginStoreFileID' => $packageData['pluginStoreFileID']
+                       $statement->execute([
+                               $packageUpdateServerID,
+                               $identifier,
+                               $packageData['packageName'],
+                               $packageData['packageDescription'],
+                               $packageData['author'],
+                               $packageData['authorURL'],
+                               $packageData['isApplication'],
+                               $packageData['pluginStoreFileID'],
                        ]);
+               }
+               WCF::getDB()->commitTransaction();
+               
+               $sql = "SELECT  packageUpdateID, package
+                       FROM    wcf" . WCF_N . "_package_update
+                       WHERE   packageUpdateServerID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute([$packageUpdateServerID]);
+               $packageUpdateIDs = $statement->fetchMap('package', 'packageUpdateID');
+               
+               $sql = "INSERT INTO     wcf" . WCF_N . "_package_update_version
+                                       (filename, license, licenseURL, isAccessible, packageDate, packageUpdateID, packageVersion)
+                       VALUES          (?, ?, ?, ?, ?, ?, ?)";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               WCF::getDB()->beginTransaction();
+               foreach ($allNewPackages as $package => $packageData) {
+                       foreach ($packageData['versions'] as $packageVersion => $versionData) {
+                               $statement->execute([
+                                       $versionData['file'] ?? '',
+                                       $versionData['license']['license'] ?? '',
+                                       $versionData['license']['licenseURL'] ?? '',
+                                       $versionData['isAccessible'] ? 1 : 0,
+                                       $versionData['packageDate'],
+                                       $packageUpdateIDs[$package],
+                                       $packageVersion,
+                               ]);
+                       }
+               }
+               WCF::getDB()->commitTransaction();
+               
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add('packageUpdateID IN (?)', [array_values($packageUpdateIDs)]);
+               $sql = "SELECT  packageUpdateVersionID, packageUpdateID, packageVersion
+                       FROM    wcf" . WCF_N . "_package_update_version
+                       ".$conditions;
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute($conditions->getParameters());
+               $packageUpdateVersions = [];
+               while ($row = $statement->fetchArray()) {
+                       if (!isset($packageUpdateVersions[$row['packageUpdateID']])) {
+                               $packageUpdateVersions[$row['packageUpdateID']] = [];
+                       }
                        
-                       $packageUpdateID = $packageUpdate->packageUpdateID;
-                       
-                       // register version(s) of this update package.
-                       if (isset($packageData['versions'])) {
-                               foreach ($packageData['versions'] as $packageVersion => $versionData) {
-                                       if (isset($versionData['file'])) $packageFile = $versionData['file'];
-                                       else $packageFile = '';
-                                       
-                                       // create new database entry
-                                       $version = PackageUpdateVersionEditor::create([
-                                               'filename' => $packageFile,
-                                               'license' => isset($versionData['license']['license']) ? $versionData['license']['license'] : '',
-                                               'licenseURL' => isset($versionData['license']['license']) ? $versionData['license']['licenseURL'] : '',
-                                               'isAccessible' => $versionData['isAccessible'] ? 1 : 0,
-                                               'packageDate' => $versionData['packageDate'],
-                                               'packageUpdateID' => $packageUpdateID,
-                                               'packageVersion' => $packageVersion
-                                       ]);
-                                       
-                                       $packageUpdateVersionID = $version->packageUpdateVersionID;
-                                       
-                                       // register requirement(s) of this update package version.
-                                       if (isset($versionData['requiredPackages'])) {
-                                               foreach ($versionData['requiredPackages'] as $requiredIdentifier => $required) {
-                                                       $requirementInserts[] = [
-                                                               'packageUpdateVersionID' => $packageUpdateVersionID,
-                                                               'package' => $requiredIdentifier,
-                                                               'minversion' => isset($required['minversion']) ? $required['minversion'] : ''
-                                                       ];
-                                               }
+                       $packageUpdateVersions[$row['packageUpdateID']][$row['packageVersion']] = $row['packageUpdateVersionID'];
+               }
+               
+               foreach ($allNewPackages as $package => $packageData) {
+                       foreach ($packageData['versions'] as $packageVersion => $versionData) {
+                               $packageUpdateID = $packageUpdateIDs[$package];
+                               $packageUpdateVersionID = $packageUpdateVersions[$packageUpdateID][$packageVersion];
+                               
+                               if (isset($versionData['requiredPackages'])) {
+                                       foreach ($versionData['requiredPackages'] as $requiredIdentifier => $required) {
+                                               $requirementInserts[] = [
+                                                       'packageUpdateVersionID' => $packageUpdateVersionID,
+                                                       'package' => $requiredIdentifier,
+                                                       'minversion' => $required['minversion'] ?? ''
+                                               ];
                                        }
-                                       
-                                       // register optional packages of this update package version
-                                       if (isset($versionData['optionalPackages'])) {
-                                               foreach ($versionData['optionalPackages'] as $optionalPackage) {
-                                                       $optionalInserts[] = [
-                                                               'packageUpdateVersionID' => $packageUpdateVersionID,
-                                                               'package' => $optionalPackage
-                                                       ];
-                                               }
+                               }
+                               
+                               if (isset($versionData['optionalPackages'])) {
+                                       foreach ($versionData['optionalPackages'] as $optionalPackage) {
+                                               $optionalInserts[] = [
+                                                       'packageUpdateVersionID' => $packageUpdateVersionID,
+                                                       'package' => $optionalPackage
+                                               ];
                                        }
-                                       
-                                       // register excluded packages of this update package version.
-                                       if (isset($versionData['excludedPackages'])) {
-                                               foreach ($versionData['excludedPackages'] as $excludedIdentifier => $exclusion) {
-                                                       $excludedPackagesParameters[] = [
-                                                               'packageUpdateVersionID' => $packageUpdateVersionID,
-                                                               'excludedPackage' => $excludedIdentifier,
-                                                               'excludedPackageVersion' => isset($exclusion['version']) ? $exclusion['version'] : ''
-                                                       ];
-                                               }
+                               }
+                               
+                               if (isset($versionData['excludedPackages'])) {
+                                       foreach ($versionData['excludedPackages'] as $excludedIdentifier => $exclusion) {
+                                               $excludedPackagesParameters[] = [
+                                                       'packageUpdateVersionID' => $packageUpdateVersionID,
+                                                       'excludedPackage' => $excludedIdentifier,
+                                                       'excludedPackageVersion' => $exclusion['version'] ?? ''
+                                               ];
                                        }
-                                       
-                                       // register fromversions of this update package version.
-                                       if (isset($versionData['fromversions'])) {
-                                               foreach ($versionData['fromversions'] as $fromversion) {
-                                                       $fromversionInserts[] = [
-                                                               'packageUpdateVersionID' => $packageUpdateVersionID,
-                                                               'fromversion' => $fromversion
-                                                       ];
-                                               }
+                               }
+                               
+                               if (isset($versionData['fromversions'])) {
+                                       foreach ($versionData['fromversions'] as $fromversion) {
+                                               $fromversionInserts[] = [
+                                                       'packageUpdateVersionID' => $packageUpdateVersionID,
+                                                       'fromversion' => $fromversion
+                                               ];
+                                       }
+                               }
+                               
+                               // @deprecated 5.2
+                               if (isset($versionData['compatibility'])) {
+                                       foreach ($versionData['compatibility'] as $version) {
+                                               $compatibilityInserts[] = [
+                                                       'packageUpdateVersionID' => $packageUpdateVersionID,
+                                                       'version' => $version
+                                               ];
                                        }
                                        
-                                       // register compatibility versions of this update package version.
-                                       // @deprecated 5.2
-                                       if (isset($versionData['compatibility'])) {
-                                               foreach ($versionData['compatibility'] as $version) {
-                                                       $compatibilityInserts[] = [
-                                                               'packageUpdateVersionID' => $packageUpdateVersionID,
-                                                               'version' => $version
-                                                       ];
-                                               }
+                                       // The API compatibility versions are deprecated, any package that exposes them must
+                                       // exclude at most `com.woltlab.wcf` in version `6.0.0 Alpha 1`.
+                                       if (!empty($compatibilityInserts)) {
+                                               if (!isset($versionData['excludedPackages'])) $versionData['excludedPackages'] = [];
+                                               $excludeCore60 = '6.0.0 Alpha 1';
                                                
-                                               // The API compatibility versions are deprecated, any package that exposes them must
-                                               // exclude at most `com.woltlab.wcf` in version `6.0.0 Alpha 1`.
-                                               if (!empty($compatibilityInserts)) {
-                                                       if (!isset($versionData['excludedPackages'])) $versionData['excludedPackages'] = [];
-                                                       $excludeCore60 = '6.0.0 Alpha 1';
-                                                       
-                                                       $coreExclude = null;
-                                                       $versionData['excludedPackages'] = array_filter($versionData['excludedPackages'], function($excludedPackage, $excludedVersion) use (&$coreExclude) {
-                                                               if ($excludedPackage === 'com.woltlab.wcf') {
-                                                                       $coreExclude = $excludedVersion;
-                                                                       return false;
-                                                               }
-                                                               
-                                                               return true;
-                                                       }, ARRAY_FILTER_USE_BOTH);
-                                                       
-                                                       if ($coreExclude === null || Package::compareVersion($coreExclude, $excludeCore60, '>')) {
-                                                               $versionData['excludedPackages'][] = [
-                                                                       'packageUpdateVersionID' => $packageUpdateVersionID,
-                                                                       'excludedPackage' => 'com.woltlab.wcf',
-                                                                       'excludedPackageVersion' => $excludeCore60,
-                                                               ];
+                                               $coreExclude = null;
+                                               $versionData['excludedPackages'] = array_filter($versionData['excludedPackages'], function($excludedPackage, $excludedVersion) use (&$coreExclude) {
+                                                       if ($excludedPackage === 'com.woltlab.wcf') {
+                                                               $coreExclude = $excludedVersion;
+                                                               return false;
                                                        }
+                                                       
+                                                       return true;
+                                               }, ARRAY_FILTER_USE_BOTH);
+                                               
+                                               if ($coreExclude === null || Package::compareVersion($coreExclude, $excludeCore60, '>')) {
+                                                       $versionData['excludedPackages'][] = [
+                                                               'packageUpdateVersionID' => $packageUpdateVersionID,
+                                                               'excludedPackage' => 'com.woltlab.wcf',
+                                                               'excludedPackageVersion' => $excludeCore60,
+                                                       ];
                                                }
                                        }
                                }
                        }
                }
-               WCF::getDB()->commitTransaction();
                
-               // save requirements, excluded packages and fromversions
-               // insert requirements
                if (!empty($requirementInserts)) {
                        $sql = "INSERT INTO     wcf".WCF_N."_package_update_requirement
                                                (packageUpdateVersionID, package, minversion)
@@ -609,7 +639,6 @@ class PackageUpdateDispatcher extends SingletonFactory {
                        WCF::getDB()->commitTransaction();
                }
                
-               // insert optionals
                if (!empty($optionalInserts)) {
                        $sql = "INSERT INTO     wcf".WCF_N."_package_update_optional
                                                (packageUpdateVersionID, package)
@@ -625,7 +654,6 @@ class PackageUpdateDispatcher extends SingletonFactory {
                        WCF::getDB()->commitTransaction();
                }
                
-               // insert excludes
                if (!empty($excludedPackagesParameters)) {
                        $sql = "INSERT INTO     wcf".WCF_N."_package_update_exclusion
                                                (packageUpdateVersionID, excludedPackage, excludedPackageVersion)
@@ -642,7 +670,6 @@ class PackageUpdateDispatcher extends SingletonFactory {
                        WCF::getDB()->commitTransaction();
                }
                
-               // insert fromversions
                if (!empty($fromversionInserts)) {
                        $sql = "INSERT INTO     wcf".WCF_N."_package_update_fromversion
                                                (packageUpdateVersionID, fromversion)
@@ -658,7 +685,6 @@ class PackageUpdateDispatcher extends SingletonFactory {
                        WCF::getDB()->commitTransaction();
                }
                
-               // insert compatibility versions
                // @deprecated 5.2
                if (!empty($compatibilityInserts)) {
                        $sql = "INSERT INTO     wcf".WCF_N."_package_update_compatibility
@@ -850,29 +876,32 @@ class PackageUpdateDispatcher extends SingletonFactory {
         * @throws      SystemException
         */
        public function getPackageUpdateVersions($package, $version = '') {
+               $packageUpdateServerIDs = [];
+               foreach (PackageUpdateServer::getActiveUpdateServers() as $packageUpdateServer) {
+                       $packageUpdateServerIDs[] = $packageUpdateServer->packageUpdateServerID;
+               }
+               
                // get newest package version
                if (empty($version)) {
                        $version = $this->getNewestPackageVersion($package);
                }
                
                // get versions
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add('pu.package = ?', [$package]);
+               $conditions->add('puv.packageVersion = ?', [$version]);
+               $conditions->add('puv.isAccessible = ?', [1]);
+               $conditions->add('pus.packageUpdateServerID IN (?)', [$packageUpdateServerIDs]);
+               
                $sql = "SELECT          puv.*, pu.*, pus.serverURL, pus.loginUsername, pus.loginPassword
                        FROM            wcf".WCF_N."_package_update_version puv
                        LEFT JOIN       wcf".WCF_N."_package_update pu
                        ON              (pu.packageUpdateID = puv.packageUpdateID)
                        LEFT JOIN       wcf".WCF_N."_package_update_server pus
                        ON              (pus.packageUpdateServerID = pu.packageUpdateServerID)
-                       WHERE           pu.package = ?
-                                       AND puv.packageVersion = ?
-                                       AND puv.isAccessible = ?
-                                       AND pus.isDisabled = ?";
+                       ".$conditions;
                $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([
-                       $package,
-                       $version,
-                       1,
-                       0
-               ]);
+               $statement->execute($conditions->getParameters());
                $versions = $statement->fetchAll(\PDO::FETCH_ASSOC);
                
                if (empty($versions)) {
index 3bcacfba77d22afa2a2419cda19bc006690fd95f..25693dbcc2c4d8969b3c2036f4bd7d234012d15a 100644 (file)
@@ -52,9 +52,19 @@ class PackageUpdateUnauthorizedException extends UserException {
         */
        public function getRenderedTemplate() {
                $serverReply = $this->request->getReply();
+
+               $authInsufficient = (isset($serverReply['httpHeaders']['wcf-update-server-auth'][0]) && $serverReply['httpHeaders']['wcf-update-server-auth'][0] === 'unauthorized');
+               if (ENABLE_ENTERPRISE_MODE && $authInsufficient && !empty($this->packageUpdateVersion['pluginStoreFileID'])) {
+                       WCF::getTPL()->assign([
+                               'packageName' => $this->packageUpdateVersion['packageName'],
+                               'pluginStoreFileID' => $this->packageUpdateVersion['pluginStoreFileID'],
+                       ]);
+
+                       return WCF::getTPL()->fetch('packageUpdateUnauthorizedPurchaseRequired');
+               }
                
                WCF::getTPL()->assign([
-                       'authInsufficient' => (isset($serverReply['httpHeaders']['wcf-update-server-auth'][0]) && $serverReply['httpHeaders']['wcf-update-server-auth'][0] === 'unauthorized'),
+                       'authInsufficient' => $authInsufficient,
                        'packageUpdateVersion' => $this->packageUpdateVersion,
                        'request' => $this->request,
                        'updateServer' => $this->updateServer,
index 83d0f6e941b31200b6596b957546dc398eb1fc6d..3c3fb1db2ce45412056f2086a86770d053d423c3 100644 (file)
@@ -12,6 +12,7 @@ use wcf\system\form\builder\container\FormContainer;
 use wcf\system\form\builder\field\BooleanFormField;
 use wcf\system\form\builder\field\ClassNameFormField;
 use wcf\system\form\builder\field\IntegerFormField;
+use wcf\system\form\builder\field\ItemListFormField;
 use wcf\system\form\builder\field\option\OptionFormField;
 use wcf\system\form\builder\field\SingleSelectionFormField;
 use wcf\system\form\builder\field\TextFormField;
@@ -26,7 +27,7 @@ use wcf\util\StringUtil;
  * Installs, updates and deletes event listeners.
  * 
  * @author     Matthias Schmidt, Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2021 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Package\Plugin
  */
@@ -233,7 +234,7 @@ class EventListenerPackageInstallationPlugin extends AbstractXMLPackageInstallat
                                ->required()
                                ->instantiable(false),
                        
-                       TextFormField::create('eventName')
+                       ItemListFormField::create('eventName')
                                ->objectProperty('eventname')
                                ->label('wcf.acp.pip.eventListener.eventName')
                                ->description('wcf.acp.pip.eventListener.eventName.description')
@@ -250,7 +251,8 @@ class EventListenerPackageInstallationPlugin extends AbstractXMLPackageInstallat
                                ->description('wcf.acp.pip.eventListener.environment.description')
                                ->options([
                                        'admin' => 'admin',
-                                       'user' => 'user'
+                                       'user' => 'user',
+                                       'all' => 'all',
                                ])
                                ->value('user'),
                        
index 97d19c07726cce8167a2cdecbde7cd3c5fd775cb..9452a6c2cb9125c5bd2d2b01b2b866787123ea4e 100644 (file)
@@ -6,7 +6,6 @@ use wcf\data\object\type\ObjectTypeEditor;
 use wcf\data\DatabaseObjectList;
 use wcf\data\page\PageNode;
 use wcf\data\page\PageNodeTree;
-use wcf\data\user\group\option\UserGroupOption;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\condition\AbstractIntegerCondition;
 use wcf\system\condition\UserGroupCondition;
@@ -42,7 +41,7 @@ use wcf\util\DirectoryUtil;
  * Installs, updates and deletes object types.
  * 
  * @author     Alexander Ebert, Matthias Schmidt
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Acp\Package\Plugin
  */
index 6971bb702cc02cfa5b2a00e3c46302a86fc8a85b..5c67bb0419a9ac718c31951194fc5baa6fd61eed 100644 (file)
@@ -32,7 +32,7 @@ class StylePackageInstallationPlugin extends AbstractPackageInstallationPlugin {
                $styleEditor = StyleHandler::getInstance()->getStyleByName($this->installation->getPackageName(), false);
                
                // import style
-               $style = StyleEditor::import($filename, $this->installation->getPackageID(), $styleEditor);
+               $style = StyleEditor::import($filename, $this->installation->getPackageID(), $styleEditor, !PACKAGE_ID);
                
                // set style as default
                if (isset($this->instruction['attributes']['default'])) {
@@ -69,11 +69,10 @@ class StylePackageInstallationPlugin extends AbstractPackageInstallationPlugin {
                        $styleList->sqlOrderBy = 'style.styleID ASC';
                        $styleList->sqlLimit = 1;
                        $styleList->readObjects();
-                       $styles = $styleList->getObjects();
+                       $style = $styleList->getSingleObject();
                        
-                       if (!empty($styles)) {
-                               $styleEditor = new StyleEditor(current($styles));
-                               $styleEditor->setAsDefault();
+                       if ($style !== null) {
+                               (new StyleEditor($style))->setAsDefault();
                        }
                }
        }
index 4f01326166ca3e02663f44171dc7081b7a67dd22..bf8971d688c74956c2c317e9f86a2faaf4f86d05 100644 (file)
@@ -114,6 +114,18 @@ class PackageValidationException extends SystemException {
         */
        const MISSING_API_VERSION = 15;
        
+       /**
+        * the void is not the only instruction
+        * @var integer
+        */
+       const VOID_NOT_ALONE = 16;
+       
+       /**
+        * the void is used during installation
+        * @var integer
+        */
+       const VOID_ON_INSTALL = 17;
+       
        /**
         * Creates a new PackageArchiveValidationException.
         * 
index 33ae932d5a52a24f688884c67cbb0219c594a14c..a3867eae23d252a3318ed0c40b2a6b0775bc7ab0 100644 (file)
@@ -35,7 +35,10 @@ trait TUserOnlineLocationPageHandler {
                        return '';
                }
                
-               return WCF::getLanguage()->getDynamicVariable('wcf.page.onlineLocation.'.$page->identifier, ['user' => $userObject]);
+               return WCF::getLanguage()->getDynamicVariable('wcf.page.onlineLocation.'.$page->identifier, [
+                       'user' => $userObject,
+                       'userOnline' => $user,
+               ]);
        }
        
        /**
index 3e311a01208130541d5368376cfaf3053e456c07..7d4f7819e9d6a624bc861a1629c11db86d63a91a 100644 (file)
@@ -789,4 +789,23 @@ class ReactionHandler extends SingletonFactory {
                
                return null;
        }
+       
+       /**
+        * Renders an inline list of reaction counts.
+        * 
+        * @param       int[]   $reactionCounts         format: `[reactionID => count]`
+        * @return      string
+        * @since       5.3
+        */
+       public function renderInlineList(array $reactionCounts) {
+               $reactionsOuput = [];
+               foreach ($reactionCounts as $reactionTypeID => $count) {
+                       $reactionsOuput[] = WCF::getLanguage()->getDynamicVariable('wcf.reactions.reactionTypeCount', [
+                               'count' => $count,
+                               'reaction' => $this->getReactionTypeByID($reactionTypeID),
+                       ]);
+               }
+               
+               return implode(', ', $reactionsOuput);
+       }
 }
index 6d5941d345b17a2e6b4d095f0b8d53ce37fe02db..cb2a4c9240a62cb596644fc3321511786be03ac3 100644 (file)
@@ -36,7 +36,8 @@ class RecaptchaHandlerV2 extends SingletonFactory {
                        $key = RECAPTCHA_PRIVATEKEY_INVISIBLE;
                }
                else {
-                       throw new \InvalidArgumentException('$type must be either v2 or invisible.');
+                       // The bot modified the `recaptcha-type` form field.
+                       throw new UserInputException('recaptchaString', 'false');
                }
                
                $request = new HTTPRequest('https://www.google.com/recaptcha/api/siteverify?secret='.rawurlencode($key).'&response='.rawurlencode($response).'&remoteip='.rawurlencode(UserUtil::getIpAddress()), ['timeout' => 10]);
index b2b4dbf01e8414970feee4c159801a940de9cb6b..28c23c4439dc8ea3f4a668ce0d80707238cdc504 100644 (file)
@@ -186,6 +186,9 @@ class SearchResultTextParser extends SingletonFactory {
                // remove nonessentials
                $text = Regex::compile('<!-- begin:parser_nonessential -->.*?<!-- end:parser_nonessential -->', Regex::DOT_ALL)->replace($text, '');
                
+               // Convert `<br>` into spaces to prevent sentences being "glued" together.
+               $text = str_replace("<br>", " ", $text);
+               
                // remove html codes
                $text = StringUtil::stripHTML($text);
                
index c7ec7cfe30d0993cb9aad638b5dd5969e7a4f3e0..c45e8dc41132f42c4c81f3b2027b97d581e4cf5c 100644 (file)
@@ -26,6 +26,10 @@ class OptionACPSearchResultProvider extends AbstractCategorizedACPSearchResultPr
         * @inheritDoc
         */
        public function search($query) {
+               if (!WCF::getSession()->getPermission('admin.configuration.canEditOption')) {
+                       return [];
+               }
+               
                $results = [];
                
                // search by language item
index f0359c64268da2430c4279dc152dcef267b293a0..f39fd1125babe3193029b6e27afa3bf80bc3de62 100644 (file)
@@ -2,7 +2,6 @@
 namespace wcf\system\search\acp;
 use wcf\data\package\Package;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
-use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 
 /**
@@ -59,10 +58,7 @@ class PackageACPSearchResultProvider implements IACPSearchResultProvider {
                
                /** @var Package $package */
                while ($package = $statement->fetchObject(Package::class)) {
-                       $results[] = new ACPSearchResult($package->getName(), LinkHandler::getInstance()->getLink('Package', [
-                               'id' => $package->packageID,
-                               'title' => $package->getName()
-                       ]));
+                       $results[] = new ACPSearchResult($package->getName(), $package->getLink());
                }
                
                return $results;
index 01d8bfa00af9ed0e4a0a0dc804af93ab0fbf0833..5ab909a3ade6bdf0a392aba634649e3abc9476cf 100644 (file)
@@ -25,6 +25,10 @@ class UserGroupOptionACPSearchResultProvider extends AbstractCategorizedACPSearc
         * @inheritDoc
         */
        public function search($query) {
+               if (!WCF::getSession()->getPermission('admin.user.canEditGroup')) {
+                       return [];
+               }
+               
                $results = [];
                
                // search by language item
diff --git a/wcfsetup/install/files/lib/system/style/FontManager.class.php b/wcfsetup/install/files/lib/system/style/FontManager.class.php
new file mode 100644 (file)
index 0000000..d55120e
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+namespace wcf\system\style;
+use GuzzleHttp\ClientInterface;
+use GuzzleHttp\Exception\ClientException;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Psr7\Request;
+use wcf\system\io\AtomicWriter;
+use wcf\system\io\HttpFactory;
+use wcf\system\SingletonFactory;
+use wcf\system\style\exception\FontDownloadFailed;
+use wcf\util\FileUtil;
+use wcf\util\JSON;
+
+/**
+ * Manages webfont families.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Style
+ * @since      5.3
+ */
+class FontManager extends SingletonFactory {
+       /**
+        * @var ClientInterface
+        */
+       protected $http;
+       
+       /**
+        * @inheritDoc
+        */
+       protected function init() {
+               $this->http = HttpFactory::makeClient([
+                       'base_uri' => 'https://fonts.woltlab.com/',
+                       'timeout' => 10,
+               ]);
+       }
+       
+       /**
+        * Returns the path to the family's CSS file.
+        * 
+        * @return      string
+        */
+       public function getCssFilename($family) {
+               return WCF_DIR.'font/families/'.$family.'/font.css';
+       }
+       
+       /**
+        * Returns whether the family's CSS file exists, implying that
+        * the family is available.
+        * 
+        * @return      boolean
+        */
+       public function isFamilyDownloaded($family) {
+               return is_readable($this->getCssFilename($family));
+       }
+       
+       /**
+        * Fetch the list of available families and returns it as an array.
+        * 
+        * @return      string[]
+        */
+       public function fetchAvailableFamilies() {
+               $response = $this->http->send(new Request('GET', 'families.json'));
+               return JSON::decode($response->getBody());
+       }
+       
+       /**
+        * Downloads the given font family, stores it in font/families/<family> and
+        * returns the decoded font manifest.
+        * 
+        * @param       string  $family
+        * @return      mixed[]
+        */
+       public function downloadFamily($family) {
+               try {
+                       $response = $this->http->send(new Request('GET', $family.'/manifest.json'));
+                       $manifest = JSON::decode($response->getBody());
+                       
+                       $familyDirectory = dirname($this->getCssFilename($family));
+                       FileUtil::makePath($familyDirectory);
+                       
+                       $css = $manifest['css'];
+                       
+                       foreach ($manifest['font_files'] as $filename) {
+                               if ($filename !== basename($filename)) {
+                                       throw new \InvalidArgumentException("Invalid filename '".$filename."' given.");
+                               }
+                               
+                               $response = $this->http->send(new Request('GET', $family.'/'.$filename), [
+                                       // https://github.com/guzzle/guzzle/issues/2735
+                                       'sink' => \GuzzleHttp\Psr7\stream_for(fopen("php://temp", "w+")),
+                               ]);
+                               
+                               $file = new AtomicWriter($familyDirectory.'/'.$filename);
+                               while (!$response->getBody()->eof()) {
+                                       $file->write($response->getBody()->read(8192));
+                               }
+                               $response->getBody()->close();
+                               $file->flush();
+                               $file->close();
+                               
+                               $css = str_replace('url("' . $filename . '")', 'url(getFont("'.rawurlencode($filename).'", "'.rawurlencode($family).'", "'.TIME_NOW.'"))', $css);
+                       }
+                       
+                       file_put_contents($this->getCssFilename($family), $css);
+                       
+                       return $manifest;
+               }
+               catch (ClientException $e) {
+                       if ($e->getResponse()->getStatusCode() == 404) {
+                               throw new FontDownloadFailed("Unable to download font family '".$family."'.", 'notFound', $e);
+                       }
+                       else {
+                               throw new FontDownloadFailed("Unable to download font family '".$family."'.", '', $e);
+                       }
+               }               
+               catch (RequestException $e) {
+                       throw new FontDownloadFailed("Unable to download font family '".$family."'.", '', $e);
+               }
+       }
+}
index ddd649b644fb564ca32572513404642ec3163624..25bff71e8215cf38aa7a539754b7792b227c6c50 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\system\style;
-use Leafo\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Compiler;
+use ScssPhp\ScssPhp\Formatter\Crunched as CrunchedFormatter;
 use wcf\data\application\Application;
 use wcf\data\option\Option;
 use wcf\data\style\Style;
@@ -17,17 +18,23 @@ use wcf\util\StyleUtil;
  * Provides access to the SCSS PHP compiler.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Style
  */
 class StyleCompiler extends SingletonFactory {
        /**
         * SCSS compiler object
-        * @var \Leafo\ScssPhp\Compiler
+        * @var Compiler
         */
        protected $compiler = null;
        
+       /**
+        * Contains all files, which are compiled for a style.
+        * @var string[]
+        */
+       protected $files; 
+       
        /**
         * names of option types which are supported as additional variables
         * @var string[]
@@ -59,38 +66,152 @@ class StyleCompiler extends SingletonFactory {
        }
        
        /**
-        * Compiles SCSS stylesheets.
+        * Returns the default style variables as array. 
         * 
-        * @param       Style   $style
+        * @return      string[]
+        * @since       5.3
         */
-       public function compile(Style $style) {
-               $files = $this->getCoreFiles();
+       public static function getDefaultVariables() {
+               $variables = [];
                
-               // read stylesheets in dependency order
-               $sql = "SELECT          filename, application
-                       FROM            wcf".WCF_N."_package_installation_file_log
-                       WHERE           CONVERT(filename using utf8) REGEXP ?
-                                       AND packageID <> ?
-                       ORDER BY        packageID";
+               $sql = "SELECT          variable.variableName, variable.defaultValue
+                       FROM            wcf".WCF_N."_style_variable variable
+                       ORDER BY        variable.variableID ASC";
                $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute([
-                       'style/([a-zA-Z0-9\-\.]+)\.scss',
-                       1
-               ]);
-               while ($row = $statement->fetchArray()) {
-                       // the global values will always be evaluated last
-                       if ($row['filename'] === self::FILE_GLOBAL_VALUES) {
-                               continue;
+               $statement->execute();
+               $variables = $statement->fetchMap('variableName', 'defaultValue');
+               
+               // see https://github.com/WoltLab/WCF/issues/2636
+               if (empty($variables['wcfPageThemeColor'])) {
+                       $variables['wcfPageThemeColor'] = $variables['wcfHeaderBackground'];
+               }
+               
+               return $variables;
+       }
+       
+       /**
+        * Test a style with the given apiVersion, imagePath and variables. If the style is valid and does not throw an
+        * error, null is returned. Otherwise the exception is returned (!).
+        * 
+        * @param       string                  $testFileDir
+        * @param       string                  $styleName
+        * @param       string                  $apiVersion
+        * @param       string                  $imagePath
+        * @param       string[]                $variables
+        * @param       string|null             $customCustomSCSSFile
+        * @return      null|\Exception
+        * @since       5.3           
+        */
+       public function testStyle($testFileDir, $styleName, $apiVersion, $imagePath, array $variables, $customCustomSCSSFile = null) {
+               $individualScss = '';
+               if (isset($variables['individualScss'])) {
+                       $individualScss = $variables['individualScss'];
+                       unset($variables['individualScss']);
+               }
+               
+               // add style image path
+               if ($imagePath) {
+                       $imagePath = FileUtil::getRelativePath(WCF_DIR . 'style/', WCF_DIR . $imagePath);
+                       $imagePath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator($imagePath));
+               } 
+               else {
+                       $imagePath = '../images/';
+               }
+               $variables['style_image_path'] = "'{$imagePath}'";
+               
+               // apply overrides
+               if (isset($variables['overrideScss'])) {
+                       $lines = explode("\n", StringUtil::unifyNewlines($variables['overrideScss']));
+                       foreach ($lines as $line) {
+                               if (preg_match('~^@([a-zA-Z]+): ?([@a-zA-Z0-9 ,\.\(\)\%\#-]+);$~', $line, $matches)) {
+                                       $variables[$matches[1]] = $matches[2];
+                               }
+                       }
+                       unset($variables['overrideScss']);
+               }
+               
+               // api version
+               $variables['apiVersion'] = $apiVersion;
+               
+               $parameters = ['scss' => ''];
+               EventHandler::getInstance()->fireAction($this, 'compile', $parameters);
+               
+               $files = $this->getFiles();
+               
+               if ($customCustomSCSSFile !== null) {
+                       if (($customSCSSFileKey = array_search(WCF_DIR . self::FILE_GLOBAL_VALUES, $files)) !== false) {
+                               unset($files[$customSCSSFileKey]);
                        }
                        
-                       $files[] = Application::getDirectory($row['application']).$row['filename'];
+                       $files[] = $customCustomSCSSFile;
                }
                
-               // global SCSS
-               if (file_exists(WCF_DIR . self::FILE_GLOBAL_VALUES)) {
-                       $files[] = WCF_DIR . self::FILE_GLOBAL_VALUES;
+               try {
+                       $this->compileStylesheet(
+                               FileUtil::addTrailingSlash($testFileDir) . 'style',
+                               $files,
+                               $variables,
+                               $individualScss . (!empty($parameters['scss']) ? "\n" . $parameters['scss'] : ''),
+                               function($content) use ($styleName) {
+                                       $header = "/* stylesheet for '".$styleName."', generated on ".gmdate('r')." -- DO NOT EDIT */";
+                                       return '@charset "UTF-8";' . "\n\n{$header}\n\n" . preg_replace('~^@charset "UTF-8";\r?\n~', '', $content);
+                               }
+                       );
+               }
+               catch (\Exception $e) {
+                       return $e;
+               }
+               
+               return null;
+       }
+       
+       /**
+        * Returns a array with all files, which should be compiled for a style. 
+        * 
+        * @return      string[]
+        * @since       5.3
+        */
+       protected function getFiles() {
+               if (!$this->files) {
+                       $files = $this->getCoreFiles();
+                       
+                       // read stylesheets in dependency order
+                       $sql = "SELECT          filename, application
+                               FROM            wcf".WCF_N."_package_installation_file_log
+                               WHERE           CONVERT(filename using utf8) REGEXP ?
+                                               AND packageID <> ?
+                               ORDER BY        packageID";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([
+                               'style/([a-zA-Z0-9\-\.]+)\.scss',
+                               1
+                       ]);
+                       while ($row = $statement->fetchArray()) {
+                               // the global values will always be evaluated last
+                               if ($row['filename'] === self::FILE_GLOBAL_VALUES) {
+                                       continue;
+                               }
+                               
+                               $files[] = Application::getDirectory($row['application']).$row['filename'];
+                       }
+                       
+                       // global SCSS
+                       if (file_exists(WCF_DIR . self::FILE_GLOBAL_VALUES)) {
+                               $files[] = WCF_DIR . self::FILE_GLOBAL_VALUES;
+                       }
+                       
+                       $this->files = $files;
                }
                
+               return $this->files;
+       }
+       
+       /**
+        * Compiles SCSS stylesheets.
+        * 
+        * @param       Style   $style
+        */
+       public function compile(Style $style) {
                // get style variables
                $variables = $style->getVariables();
                $individualScss = '';
@@ -125,12 +246,13 @@ class StyleCompiler extends SingletonFactory {
                EventHandler::getInstance()->fireAction($this, 'compile', $parameters);
                
                $this->compileStylesheet(
-                       WCF_DIR.'style/style-'.$style->styleID,
-                       $files,
+                       $this->getFilenameForStyle($style),
+                       $this->getFiles(),
                        $variables,
                        $individualScss . (!empty($parameters['scss']) ? "\n" . $parameters['scss'] : ''),
                        function($content) use ($style) {
-                               return "/* stylesheet for '".$style->styleName."', generated on ".gmdate('r')." -- DO NOT EDIT */\n\n" . $content;
+                               $header = "/* stylesheet for '".$style->styleName."', generated on ".gmdate('r')." -- DO NOT EDIT */";
+                               return '@charset "UTF-8";' . "\n\n{$header}\n\n" . preg_replace('~^@charset "UTF-8";\r?\n~', '', $content);
                        }
                );
        }
@@ -139,11 +261,6 @@ class StyleCompiler extends SingletonFactory {
         * Compiles SCSS stylesheets for ACP usage.
         */
        public function compileACP() {
-               if (substr(WCF_VERSION, 0, 3) == '2.1') {
-                       // work-around for wcf2.1 update
-                       return;
-               }
-               
                $files = $this->getCoreFiles();
                
                // ACP uses a slightly different layout
@@ -190,7 +307,8 @@ class StyleCompiler extends SingletonFactory {
                                $content = str_replace('../icon/', '../../icon/', $content);
                                $content = preg_replace('~\.\./images/~', '../../images/', $content);
                                
-                               return "/* stylesheet for ACP, generated on ".gmdate('r')." -- DO NOT EDIT */\n\n" . $content;
+                               $header = "/* stylesheet for the admin panel, generated on ".gmdate('r')." -- DO NOT EDIT */";
+                               return '@charset "UTF-8";' . "\n\n{$header}\n\n" . preg_replace('~^@charset "UTF-8";\r?\n~', '', $content);
                        }
                );
        }
@@ -273,6 +391,36 @@ class StyleCompiler extends SingletonFactory {
                        $content .= $this->prepareFile($mixin);
                }
                
+               if (ApplicationHandler::getInstance()->isMultiDomainSetup()) {
+                       $content .= <<<'EOT'
+                               @function getFont($filename, $family: "/", $version: "") {
+                                       @return "../font/getFont.php?family=" + $family + "&filename=" + $filename + "&v=" + $version;
+                               }
+EOT;
+               }
+               else {
+                       $content .= <<<'EOT'
+                               @function getFont($filename, $family: "/", $version: "") {
+                                       @if ($family != "") {
+                                               $family: "families/" + $family + "/";
+                                       }
+                                       @if ($version != "") {
+                                               $version: "?v=" + $version;
+                                       }
+                                       
+                                       @return "../font/" + $family + $filename + $version;
+                               }
+EOT;
+               }
+               
+               // add google fonts
+               if (!empty($variables['wcfFontFamilyGoogle']) && PACKAGE_ID) {
+                       $cssFile = FontManager::getInstance()->getCssFilename(substr($variables['wcfFontFamilyGoogle'], 1, -1));
+                       if (is_readable($cssFile)) {
+                               $content .= file_get_contents($cssFile);
+                       }
+               }
+               
                return $content;
        }
        
@@ -302,7 +450,6 @@ class StyleCompiler extends SingletonFactory {
         * @param       string[]        $variables
         * @param       string          $individualScss
         * @param       callable        $callback
-        * @throws      SystemException
         */
        protected function compileStylesheet($filename, array $files, array $variables, $individualScss, callable $callback) {
                foreach ($variables as &$value) {
@@ -356,7 +503,7 @@ class StyleCompiler extends SingletonFactory {
                }
                
                try {
-                       $this->compiler->setFormatter('Leafo\ScssPhp\Formatter\Crunched');
+                       $this->compiler->setFormatter(CrunchedFormatter::class);
                        $content = $this->compiler->compile($scss);
                }
                catch (\Exception $e) {
@@ -374,10 +521,24 @@ class StyleCompiler extends SingletonFactory {
                
                // force code boxes to be always LTR
                $content .= "\n/* RTL fix for code boxes */\n";
-               $content .= '.codeBox > div > ol > li > span:last-child, .redactor-layer pre { direction: ltr; text-align: left; } .codeBox > div > ol > li > span:last-child { display: block; }';
+               $content .= ".redactor-layer pre { direction: ltr; text-align: left; }\n";
+               $content .= ".codeBoxCode { direction: ltr; } \n";
+               $content .= ".codeBox .codeBoxCode { padding-left: 7ch; padding-right: 0; } \n";
+               $content .= ".codeBox .codeBoxCode > code .codeBoxLine > a { margin-left: -7ch; margin-right: 0; text-align: right; } \n";
                
                // write stylesheet for RTL
                file_put_contents($filename.'-rtl.css', $content);
                FileUtil::makeWritable($filename.'-rtl.css');
        }
+       
+       /**
+        * Returns the name of the CSS file for a specific style. 
+        * 
+        * @param       Style           $style
+        * @return      string
+        * @since       5.3
+        */
+       public static function getFilenameForStyle(Style $style) {
+               return WCF_DIR.'style/style-'.$style->styleID;
+       }
 }
diff --git a/wcfsetup/install/files/lib/system/style/exception/FontDownloadFailed.class.php b/wcfsetup/install/files/lib/system/style/exception/FontDownloadFailed.class.php
new file mode 100644 (file)
index 0000000..0d9c6ee
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+namespace wcf\system\style\exception;
+
+/**
+ * Indicates that the font download failed.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Style
+ * @since      5.3
+ */
+class FontDownloadFailed extends \Exception {
+       /**
+        * @var string
+        */
+       private $reason = '';
+       
+       public function __construct($message, $reason = '', \Throwable $previous = null) {
+               parent::__construct($message, 0, $previous);
+               
+               $this->reason = $reason;
+       }
+       
+       /**
+        * @return string
+        */
+       public function getReason() {
+               return $this->reason;
+       }
+}
index c7038bfcd4f7bdd2a72301e285d8e7c298530c2d..2916dee430a8a41736c5307474691a18c6e5d6aa 100644 (file)
@@ -1,2 +1,5 @@
 <?php
-require(WCF_DIR.'lib/system/api/leafo/scssphp/scss.inc.php');
+/**
+ * @deprecated 5.3 The SCSS compiler is a composer package as of 5.2.
+ */
+require(WCF_DIR.'lib/system/api/scssphp/scssphp/scss.inc.php');
index db14f9297673171e8342217ab8d614995ef35a90..3578026f68e12f572f5c60a01e075f26fa19d02d 100644 (file)
@@ -6,6 +6,7 @@ use wcf\data\tag\TagAction;
 use wcf\data\tag\TagList;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\InvalidObjectTypeException;
+use wcf\system\language\LanguageFactory;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
@@ -163,9 +164,17 @@ class TagEngine extends SingletonFactory {
                                if (!$languageID) unset($languageIDs[$index]);
                        }
                        
-                       if (!empty($languageIDs)) {
-                               $conditions->add("tag_to_object.languageID IN (?)", [$languageIDs]);
+                       // The `languageID` is part of the index, skipping it will cause MySQL to skip the
+                       // `objectID` column, causing a partial table scan.
+                       if (empty($languageIDs)) {
+                               // The `languageID` column is never null, tags are always assigned to a language
+                               // thus we cannot use the content language ids here.
+                               foreach (LanguageFactory::getInstance()->getLanguages() as $language) {
+                                       $languageIDs[] = $language->languageID;
+                               }
                        }
+                       
+                       $conditions->add("tag_to_object.languageID IN (?)", [$languageIDs]);
                }
                
                $sql = "SELECT          tag.*, tag_to_object.objectID
index 5da3fa9a22ab1934b065f5479fa6190e3ce6a553..0193cde72175d4a698a77b98b781880f989f46d5 100644 (file)
@@ -44,6 +44,7 @@ class TemplateScriptingCompiler {
         */
        protected $enterpriseFunctions = [
                'addslashes',
+               'array_diff',
                'array_fill',
                'array_keys',
                'array_pop',
@@ -77,6 +78,7 @@ class TemplateScriptingCompiler {
                'implode',
                'in_array',
                'is_array',
+               'is_null',
                'is_numeric',
                'is_object',
                'iterator_count',
diff --git a/wcfsetup/install/files/lib/system/template/plugin/AnchorAttributesFunctionTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/AnchorAttributesFunctionTemplatePlugin.class.php
new file mode 100644 (file)
index 0000000..5ec59f3
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+namespace wcf\system\template\plugin;
+use wcf\system\application\ApplicationHandler;
+use wcf\system\request\RouteHandler;
+use wcf\system\template\TemplateEngine;
+use wcf\util\StringUtil;
+
+/**
+ * Template function plugin which generates attributes for `a` HTML elements.
+ *
+ * Required parameter:
+ *      `url` (string)
+ * Optional parameter:
+ *      `appendHref` (bool, default true)
+ *      `appendClassname` (bool, default true)
+ *      `isUgc` (bool, default false)
+ *
+ * Usage:
+ *      {anchorAttributes url=$url}
+ *
+ * @author     Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Template\Plugin
+ * @since      5.3
+ */
+class AnchorAttributesFunctionTemplatePlugin implements IFunctionTemplatePlugin {
+       /**
+        * @inheritDoc
+        */
+       public function execute($tagArgs, TemplateEngine $tplObj) {
+               if (empty($tagArgs['url'])) {
+                       throw new \InvalidArgumentException("Missing 'url' attribute.");
+               }
+               $url = $tagArgs['url'];
+               $appendClassname = $tagArgs['appendClassname'] ?? true;
+               $appendHref = $tagArgs['appendHref'] ?? true;
+               $isUgc = $tagArgs['isUgc'] ?? false;
+               
+               $external = true;
+               if (ApplicationHandler::getInstance()->isInternalURL($url)) {
+                       $external = false;
+                       $url = preg_replace('~^https?://~', RouteHandler::getProtocol(), $url);
+               }
+               
+               $attributes = '';
+               if ($appendHref) {
+                       $attributes .= ' href="' . StringUtil::encodeHTML($url) . '"';
+               }
+               
+               if ($external) {
+                       if ($appendClassname) {
+                               $attributes .= ' class="externalURL"';
+                       }
+                       
+                       $rel = 'nofollow';
+                       if (EXTERNAL_LINK_TARGET_BLANK) {
+                               $rel .= ' noopener noreferrer';
+                               $attributes .= ' target="_blank"';
+                       }
+                       if ($isUgc) {
+                               $rel .= ' ugc';
+                       }
+                       
+                       $attributes .= ' rel="' . $rel . '"';
+               }
+               
+               return StringUtil::trim($attributes);
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php
new file mode 100644 (file)
index 0000000..f8296a1
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+namespace wcf\system\template\plugin;
+use wcf\data\ILinkableObject;
+use wcf\data\IPopoverObject;
+use wcf\data\ITitledLinkObject;
+use wcf\data\ITitledObject;
+use wcf\system\template\TemplateEngine;
+use wcf\util\ClassUtil;
+use wcf\util\StringUtil;
+
+/**
+ * Template function plugin which generate `a` HTML elements.
+ * 
+ * Required parameters are either:
+ *     `object` (`ITitledLinkObject`)
+ * or both:
+ *     `link` (`ILinkableObject`)
+ *     `content` (`ITitledObject`, object with `__toString()` method, or string)
+ * 
+ * The only additional parameter that is treated in a special way is `append` whose value is appended
+ * to the link.
+ * All other additional parameter values are added as attributes to the `a` element. Parameter names
+ * in camel case are changed to kebab case (`fooBar` becomes `foo-bar`).
+ * 
+ * The only additional parameter name that is disallowed is `href`.
+ *
+ * Usage:
+ *     {anchor object=$object data-foo='bar'}
+ *     {anchor object=$object}
+ *     {anchor object=$object append='#anchor'}
+ *     {anchor link=$linkObject content=$titleObject}
+ *     {anchor link=$linkObject content='Title'}
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Template\Plugin
+ * @since      5.3
+ */
+class AnchorFunctionTemplatePlugin implements IFunctionTemplatePlugin {
+       /**
+        * @inheritDoc
+        */
+       public function execute($tagArgs, TemplateEngine $tplObj) {
+               $link = $content = $object = null;
+               if (isset($tagArgs['object'])) {
+                       $object = $tagArgs['object'];
+                       unset($tagArgs['object']);
+                       
+                       if (!($object instanceof ITitledLinkObject) && !ClassUtil::isDecoratedInstanceOf($object, ITitledLinkObject::class)) {
+                               throw new \InvalidArgumentException("'object' attribute does not implement interface '" . ITitledLinkObject::class . "'.");
+                       }
+                       
+                       $link = $object->getLink();
+                       $content = $object->getTitle();
+               }
+               else if (isset($tagArgs['link']) && isset($tagArgs['content'])) {
+                       if (!($tagArgs['link'] instanceof ILinkableObject) && !ClassUtil::isDecoratedInstanceOf($tagArgs['link'], ILinkableObject::class)) {
+                               throw new \InvalidArgumentException("'link' attribute does not implement interface '" . ILinkableObject::class . "'.");
+                       }
+                       
+                       $link = $tagArgs['link']->getLink();
+                       unset($tagArgs['link']);
+                       
+                       if (is_object($tagArgs['content'])) {
+                               if ($tagArgs['content'] instanceof ITitledObject || ClassUtil::isDecoratedInstanceOf($tagArgs['content'], ITitledObject::class)) {
+                                       $content = $tagArgs['content']->getTitle();
+                               }
+                               else if (method_exists($tagArgs['content'], '__toString')) {
+                                       $content = (string)$tagArgs['content'];
+                               }
+                               else {
+                                       throw new \InvalidArgumentException("'content' object does not implement " . ITitledObject::class . ".");
+                               }
+                       }
+                       else if (is_string($tagArgs['content']) || is_numeric($tagArgs['content'])) {
+                               $content = $tagArgs['content'];
+                       }
+                       else {
+                               throw new \InvalidArgumentException("'content' attribute is of invalid type " . gettype($tagArgs['content']) . ".");
+                       }
+                       unset($tagArgs['content']);
+               }
+               else {
+                       throw new \InvalidArgumentException("Missing 'object' attribute or 'link' and 'content' attributes.");
+               }
+               
+               if (isset($tagArgs['href'])) {
+                       throw new \InvalidArgumentException("'href' attribute is not allowed.");
+               }
+               
+               $append = '';
+               if (isset($tagArgs['append'])) {
+                       $append = $tagArgs['append'];
+                       unset($tagArgs['append']);
+               }
+               
+               $classes = [];
+               $additionalParameters = '';
+               foreach ($tagArgs as $name => $value) {
+                       if (!preg_match('~^[a-z]+([A-z]+)+$~', $name)) {
+                               throw new \InvalidArgumentException("Invalid additional argument name '{$name}'.");
+                       }
+                       
+                       if ($name === 'class') {
+                               $classes = explode(' ', $value);
+                       }
+                       
+                       $additionalParameters .= ' ' . strtolower(preg_replace('~([A-Z])~', '-$1', $name)) . '="' . StringUtil::encodeHTML($value) . '"';
+               }
+               
+               if (
+                       $object !== null
+                       && ($object instanceof IPopoverObject || ClassUtil::isDecoratedInstanceOf($object, IPopoverObject::class))
+                       && in_array($object->getPopoverLinkClass(), $classes)
+               ) {
+                       $additionalParameters .= ' data-object-id="' . $object->getObjectID() . '"';
+               }
+               
+               return '<a href="' . StringUtil::encodeHTML($link . $append) . '"' . $additionalParameters . '>' . StringUtil::encodeHTML($content) . '</a>';
+       }
+}
index 78c8588d801ff77ee822b371ba73d24a8304ee20..befeb33857799004a584686b8286c7043cb6e3dc 100644 (file)
@@ -35,6 +35,6 @@ class IpSearchModifierTemplatePlugin implements IModifierTemplatePlugin {
                $url = sprintf(IP_ADDRESS_SEARCH_ENGINE ?: self::SEARCH_ENGINE_URL_DEFAULT, $ipAddress);
                $title = WCF::getLanguage()->getDynamicVariable('wcf.user.ipAddress.searchEngine', ['host' => $domain, 'ipAddress' => $ipAddress]);
                
-               return '<a href="' . $url . '"' . (EXTERNAL_LINK_REL_NOFOLLOW ? ' rel="nofollow"' : '') .(EXTERNAL_LINK_TARGET_BLANK ? ' target="_blank"' : '') . ' title="' . $title . '">' . $ipAddress . '</a>';
+               return '<a '. StringUtil::getAnchorTagAttributes($url) .' title="' . $title . '">' . $ipAddress . '</a>';
        }
 }
diff --git a/wcfsetup/install/files/lib/system/template/plugin/JslangCompilerTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/JslangCompilerTemplatePlugin.class.php
new file mode 100644 (file)
index 0000000..fa52c1d
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+namespace wcf\system\template\plugin;
+use wcf\system\template\TemplateScriptingCompiler;
+
+/**
+ * Template compiler plugin which compiles dynamic language variables for the assignment in javascript code.
+ *
+ * Usage:
+ *     {jslang}$blah{/jslang}
+ *     {jslang var=$x}foo{/jslang}
+ *
+ * @author     Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Template\Plugin
+ * @since       5.3
+ */
+class JslangCompilerTemplatePlugin implements ICompilerTemplatePlugin {
+       /**
+        * @inheritDoc
+        */
+       public function executeStart($tagArgs, TemplateScriptingCompiler $compiler) {
+               $compiler->pushTag('jslang');
+               
+               $tagArgs = $compiler::makeArgString($tagArgs);
+               return "<?php
+                       \$this->tagStack[] = ['jslang', array_merge(\$this->v, [$tagArgs])];
+                       ob_start();
+                       ?>";
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function executeEnd(TemplateScriptingCompiler $compiler) {
+               $compiler->popTag('jslang');
+               return "<?php
+                       echo wcf\util\StringUtil::encodeJS(wcf\system\WCF::getLanguage()->tplGet(ob_get_clean(), \$this->tagStack[count(\$this->tagStack) - 1][1]));
+                       array_pop(\$this->tagStack); ?>";
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/template/plugin/JslangPrefilterTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/JslangPrefilterTemplatePlugin.class.php
new file mode 100644 (file)
index 0000000..8f393ea
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+namespace wcf\system\template\plugin;
+use wcf\system\template\TemplateScriptingCompiler;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
+
+/**
+ * Template prefilter plugin which compiles static language variables for the assignment in javascript code.
+ *
+ * Usage:
+ *     {jslang}wcf.foo.bar{/jslang}
+ * 
+ * @author     Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Template\Plugin
+ * @since       5.3
+ */
+class JslangPrefilterTemplatePlugin implements IPrefilterTemplatePlugin {
+       /**
+        * @inheritDoc
+        */
+       public function execute($templateName, $sourceContent, TemplateScriptingCompiler $compiler) {
+               $ldq = preg_quote($compiler->getLeftDelimiter(), '~');
+               $rdq = preg_quote($compiler->getRightDelimiter(), '~');
+               $sourceContent = preg_replace_callback("~{$ldq}jslang{$rdq}([\w\.]+){$ldq}/jslang{$rdq}~", function ($match) {
+                       $value = WCF::getLanguage()->get($match[1]);
+                       if (strpos($value, '{') !== false) {
+                               $variableName = '__jslang_capture_' . substr(StringUtil::getRandomID(), 0, 8);
+                               $value = "{capture assign='" . $variableName . "'}" . $value . "{/capture}{@$" . $variableName . "|encodeJS}";
+                       }
+                       else {
+                               $value = StringUtil::encodeJS($value);
+                       }
+                       
+                       return $value;
+               }, $sourceContent);
+               
+               return $sourceContent;
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/template/plugin/PluralFunctionTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/PluralFunctionTemplatePlugin.class.php
new file mode 100644 (file)
index 0000000..1867718
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+namespace wcf\system\template\plugin;
+use wcf\system\exception\SystemException;
+use wcf\system\language\I18nPlural;
+use wcf\system\template\TemplateEngine;
+use wcf\util\StringUtil;
+
+/**
+ * Template function plugin which generate plural phrases.
+ *
+ * Languages vary in how they handle plurals of nouns or unit expressions.
+ * Some languages have two forms, like English; some languages have only a
+ * single form; and some languages have multiple forms.
+ * 
+ * Supported parameters:
+ * value (number|array|Countable - required)
+ * other (string - required)
+ * zero (string), one (string), two (string), few (string), many (string)
+ * 
+ * Usage:
+ *      {plural value=$number zero='0' one='1' two='2' few='few' many='many' other='#'}
+ *      There {plural value=$worlds one='is one world' other='are # worlds'}
+ *      Updated {plural value=$minutes 0='just now' 1='one minute ago' other='# minutes ago'}
+ *
+ * @author     Marcel Werk
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Template\Plugin
+ * @since      5.3
+ */
+class PluralFunctionTemplatePlugin implements IFunctionTemplatePlugin {
+       /**
+        * @inheritDoc
+        */
+       public function execute($tagArgs, TemplateEngine $tplObj) {
+               if (!isset($tagArgs['value'])) {
+                       throw new SystemException("Missing attribute 'value'");
+               }
+               if (!isset($tagArgs['other'])) {
+                       throw new SystemException("Missing attribute 'other'");
+               }
+               
+               $value = $tagArgs['value'];
+               if (is_countable($value)) {
+                       $value = count($value);
+               }
+               
+               // handle numeric attributes
+               foreach ($tagArgs as $key => $_value) {
+                       if (is_numeric($key)) {
+                               if ($key == $value) return $_value;
+                       }
+               }
+               
+               $category = I18nPlural::getCategory($value);
+               if (!isset($tagArgs[$category])) {
+                       $category = I18nPlural::PLURAL_OTHER;
+               }
+               
+               $string = $tagArgs[$category];
+               if (strpos($string, '#') !== false) {
+                       return str_replace('#', StringUtil::formatNumeric($value), $string);
+               }
+               
+               return $string;
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/template/plugin/UserFunctionTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/UserFunctionTemplatePlugin.class.php
new file mode 100644 (file)
index 0000000..4587380
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+namespace wcf\system\template\plugin;
+use wcf\data\user\UserProfile;
+use wcf\system\template\TemplateEngine;
+use wcf\util\ClassUtil;
+use wcf\util\StringUtil;
+
+/**
+ * Template function plugin which generates links to user profiles.
+ * 
+ * Attributes:
+ * - `object` (required) has to be a (decorated) `UserProfile` object.
+ * - `type` (optional) supports the following values:
+ *      - `default` (default value) generates a link with the formatted username with popover support.
+ *      - `avatarXY` generates a link with the user's avatar in size `XY`.
+ *      - `plain` generates a link link without username formatting and popover support
+ * - `append` (optional) is appended to the user link.
+ * 
+ * All other additional parameter values are added as attributes to the `a` element. Parameter names
+ * in camel case are changed to kebab case (`fooBar` becomes `foo-bar`).
+ *
+ * Usage:
+ *      {user object=$user}
+ *      {user object=$user type='plain'}
+ *      {user object=$user type='avatar48'}
+ *      {user object=$user append='#wall'}
+ * 
+ * @author      Matthias Schmidt
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Template\Plugin
+ * @since       5.3
+ */
+class UserFunctionTemplatePlugin implements IFunctionTemplatePlugin {
+       /**
+        * @inheritDoc
+        */
+       public function execute($tagArgs, TemplateEngine $tplObj) {
+               if (!isset($tagArgs['object'])) {
+                       throw new \InvalidArgumentException("Missing 'object' attribute.");
+               }
+               
+               $object = $tagArgs['object'];
+               unset($tagArgs['object']);
+               if (!($object instanceof UserProfile) && !ClassUtil::isDecoratedInstanceOf($object, UserProfile::class)) {
+                       $type = gettype($object);
+                       if (is_object($object)) {
+                               $type = "'" . get_class($object) . "' object";
+                       }
+                       
+                       throw new \InvalidArgumentException("'object' attribute is no '" . UserProfile::class . "' object, instead {$type} given.");
+               }
+               
+               $additionalParameters = '';
+               $content = '';
+               if (isset($tagArgs['type'])) {
+                       $type = $tagArgs['type'];
+                       unset($tagArgs['type']);
+                       
+                       if ($type === 'plain') {
+                               $content = StringUtil::encodeHTML($object->getTitle());
+                       }
+                       else if (preg_match('~^avatar(\d+)$~', $type, $matches)) {
+                               $content = $object->getAvatar()->getImageTag($matches[1]);
+                       }
+                       else if ($type !== 'default') {
+                               throw new \InvalidArgumentException("Unknown 'type' value '{$type}'.");
+                       }
+               }
+               
+               // default case
+               if ($content === '') {
+                       $additionalParameters = ' data-object-id="' . $object->getObjectID() . '"';
+                       $content = $object->getFormattedUsername();
+                       if (isset($tagArgs['class'])) {
+                               $tagArgs['class'] = 'userLink ' . $tagArgs['class'];
+                       }
+                       else {
+                               $tagArgs['class'] = 'userLink';
+                       }
+               }
+               
+               if (isset($tagArgs['href'])) {
+                       throw new \InvalidArgumentException("'href' attribute is not allowed.");
+               }
+               
+               $append = '';
+               if (isset($tagArgs['append'])) {
+                       $append = $tagArgs['append'];
+                       unset($tagArgs['append']);
+               }
+               
+               foreach ($tagArgs as $name => $value) {
+                       if (!preg_match('~^[a-z]+([A-z]+)+$~', $name)) {
+                               throw new \InvalidArgumentException("Invalid additional argument name '{$name}'.");
+                       }
+                       
+                       $additionalParameters .= ' ' . strtolower(preg_replace('~([A-Z])~', '-$1', $name))
+                               . '="' . StringUtil::encodeHTML($value) . '"';
+               }
+               
+               return '<a href="' . StringUtil::encodeHTML($object->getLink() . $append) . '"' . $additionalParameters . '>' . $content . '</a>';
+       }
+}
index 9bb1874936536863c5397b8d4cbd28b8a7b5949b..3aa6a891e064eb5b0d7cdaed28eb3850219db8e9 100644 (file)
@@ -85,6 +85,8 @@ class DefaultUploadFileSaveStrategy implements IUploadFileSaveStrategy {
                if (is_subclass_of($baseClass, IThumbnailFile::class)) {
                        $this->options['thumbnailSizes'] = call_user_func([$baseClass, 'getThumbnailSizes']);
                }
+               
+               $this->options['action'] = $this->options['action'] ?? 'create';
        }
        
        /**
@@ -105,10 +107,13 @@ class DefaultUploadFileSaveStrategy implements IUploadFileSaveStrategy {
                        'filesize' => $uploadFile->getFilesize(),
                        'fileType' => $uploadFile->getMimeType(),
                        'fileHash' => sha1_file($uploadFile->getLocation()),
-                       'uploadTime' => TIME_NOW,
-                       'userID' => WCF::getUser()->userID ?: null
+                       'userID' => WCF::getUser()->userID ?: null,
                ], $this->data);
                
+               if ($this->options['action'] === 'create') {
+                       $data['uploadTime'] = TIME_NOW;
+               }
+               
                // get image data
                if (($imageData = $uploadFile->getImageData()) !== null) {
                        $data['width'] = $imageData['width'];
@@ -121,12 +126,20 @@ class DefaultUploadFileSaveStrategy implements IUploadFileSaveStrategy {
                }
                
                /** @var IDatabaseObjectAction $action */
-               $action = new $this->actionClassName([], 'create', [
-                       'data' => $data
+               $objects = [];
+               if (isset($this->options['object'])) {
+                       $objects = [$this->options['object']];
+               }
+               $action = new $this->actionClassName($objects, $this->options['action'], [
+                       'data' => $data,
                ]);
                
                /** @var IThumbnailFile $object */
                $object = $action->executeAction()['returnValues'];
+               if (isset($this->options['object'])) {
+                       $className = get_class($this->options['object']);
+                       $object = new $className($this->options['object']->getObjectID());
+               }
                
                $dir = dirname($object->getLocation());
                if (!@file_exists($dir)) {
@@ -164,15 +177,15 @@ class DefaultUploadFileSaveStrategy implements IUploadFileSaveStrategy {
                                        $object = $parameters['object'];
                                }
                                
+                               $adapter = ImageHandler::getInstance()->getAdapter();
                                // rotate image based on the exif data
                                if (!empty($this->options['rotateImages'])) {
                                        if ($object->isImage) {
-                                               if (FileUtil::checkMemoryLimit($object->width * $object->height * ($object->fileType == 'image/png' ? 4 : 3) * 2.1)) {
+                                               if ($adapter->checkMemoryLimit($object->width, $object->height, $object->fileType)) {
                                                        $exifData = ExifUtil::getExifData($object->getLocation());
                                                        if (!empty($exifData)) {
                                                                $orientation = ExifUtil::getOrientation($exifData);
                                                                if ($orientation != ExifUtil::ORIENTATION_ORIGINAL) {
-                                                                       $adapter = ImageHandler::getInstance()->getAdapter();
                                                                        $adapter->loadFile($object->getLocation());
                                                                        
                                                                        $newImage = null;
@@ -279,12 +292,13 @@ class DefaultUploadFileSaveStrategy implements IUploadFileSaveStrategy {
                        return;
                }
                
+               $adapter = ImageHandler::getInstance()->getAdapter();
+               
                // check memory limit
-               if (!FileUtil::checkMemoryLimit($file->width * $file->height * ($file->fileType == 'image/png' ? 4 : 3) * 2.1)) {
+               if (!$adapter->checkMemoryLimit($file->width, $file->height, $file->fileType)) {
                        return;
                }
                
-               $adapter = ImageHandler::getInstance()->getAdapter();
                $adapter->loadFile($file->getLocation());
                
                $updateData = [];
@@ -308,6 +322,9 @@ class DefaultUploadFileSaveStrategy implements IUploadFileSaveStrategy {
                        if ($file->width > $sizeData['width'] || $file->height > $sizeData['height']) {
                                $thumbnail = $adapter->createThumbnail($sizeData['width'], $sizeData['height'], isset($sizeData['retainDimensions']) ? $sizeData['retainDimensions'] : true);
                                $adapter->writeImage($thumbnail, $thumbnailLocation);
+                               // Clear thumbnail as soon as possible to free up the memory for the next size.
+                               $thumbnail = null;
+                               
                                if (file_exists($thumbnailLocation) && ($imageData = @getimagesize($thumbnailLocation)) !== false) {
                                        $updateData[$prefix.'Type'] = $imageData['mime'];
                                        $updateData[$prefix.'Size'] = @filesize($thumbnailLocation);
index 3a79a15d75a65b12fd00d99b1fae740d22b66208..05b6125350f2313343530aea4f3a6c05e5ddcd82 100644 (file)
@@ -52,13 +52,13 @@ class DefaultUploadFileValidationStrategy implements IUploadFileValidationStrate
                        return false;
                }
                
-               if ($uploadFile->getFilesize() > $this->maxFilesize) {
-                       $uploadFile->setValidationErrorType('tooLarge');
+               if (!preg_match($this->fileExtensionRegex, mb_strtolower($uploadFile->getFilename()))) {
+                       $uploadFile->setValidationErrorType('invalidExtension');
                        return false;
                }
                
-               if (!preg_match($this->fileExtensionRegex, mb_strtolower($uploadFile->getFilename()))) {
-                       $uploadFile->setValidationErrorType('invalidExtension');
+               if ($uploadFile->getFilesize() > $this->maxFilesize) {
+                       $uploadFile->setValidationErrorType('tooLarge');
                        return false;
                }
                
diff --git a/wcfsetup/install/files/lib/system/upload/MediaReplaceUploadFileValidationStrategy.class.php b/wcfsetup/install/files/lib/system/upload/MediaReplaceUploadFileValidationStrategy.class.php
new file mode 100644 (file)
index 0000000..0d0387c
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+namespace wcf\system\upload;
+use wcf\data\media\Media;
+
+/**
+ * Upload file validation strategy implementation for media file replacements.
+ * 
+ * @author      Matthias Schmidt
+ * @copyright   2001-2020 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Upload
+ * @since       5.3
+ */
+class MediaReplaceUploadFileValidationStrategy extends MediaUploadFileValidationStrategy {
+       /**
+        * media whose file will be replaced
+        * @var Media
+        */
+       protected $media;
+       
+       /**
+        * Creates a new instance of MediaReplaceUploadFileValidationStrategy.
+        * 
+        * @param       Media           $media
+        */
+       public function __construct(Media $media) {
+               $this->media = $media;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate(UploadFile $uploadFile) {
+               if (!parent::validate($uploadFile)) {
+                       return false;
+               }
+               
+               if ($this->media->fileType !== $uploadFile->getMimeType()) {
+                       $uploadFile->setValidationErrorType('differentFileType');
+                       return false;
+               }
+               
+               if (strtolower(pathinfo($this->media->filename, PATHINFO_EXTENSION)) !== strtolower($uploadFile->getFileExtension())) {
+                       $uploadFile->setValidationErrorType('differentFileExtension');
+                       return false;
+               }
+               
+               return true;
+       }
+}
index dfcaaf0e33d2a75e46075c8b66368b6ffae3bc54..efc03f53877643e0122b346bf3d044a443f8e849 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 namespace wcf\system\upload;
 use wcf\data\user\cover\photo\UserCoverPhoto;
+use wcf\system\image\ImageHandler;
 use wcf\system\WCF;
 use wcf\util\ExifUtil;
-use wcf\util\FileUtil;
 
 /**
  * Upload file validation strategy implementation for user cover photos.
@@ -59,7 +59,7 @@ class UserCoverPhotoUploadFileValidationStrategy implements IUploadFileValidatio
                // estimate if there is enough memory for a resize, if there is,
                // we do not need to mark an image which is too high or too wide
                // as invalid
-               $sufficientMemory = FileUtil::checkMemoryLimit($width * $height * ($uploadFile->getFileExtension() == 'png' ? 4 : 3) * 2.1);
+               $sufficientMemory = ImageHandler::getInstance()->getAdapter()->checkMemoryLimit($width, $height, $imageData['mimeType']);
                
                // check width
                if ($width < UserCoverPhoto::MIN_WIDTH) {
index e7327424cf2621c4d3d7163298bf26398a54005c..c5f3d3f0ce421127e4ba3f8cf154a97dd0cb8649 100644 (file)
@@ -1,59 +1,32 @@
 <?php
 namespace wcf\system\user\activity\event;
 use wcf\data\article\ViewableArticleList;
-use wcf\data\comment\response\CommentResponseList;
-use wcf\data\comment\CommentList;
-use wcf\data\user\UserList;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 
 /**
  * User activity event implementation for responses to article comments.
- *
+ * 
  * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\User\Activity\Event
  * @since      3.0
  */
 class ArticleCommentResponseUserActivityEvent extends SingletonFactory implements IUserActivityEvent {
+       use TCommentResponseUserActivityEvent;
+       
        /**
         * @inheritDoc
         */
        public function prepare(array $events) {
-               $responseIDs = [];
-               foreach ($events as $event) {
-                       $responseIDs[] = $event->objectID;
-               }
-               
-               // fetch responses
-               $responseList = new CommentResponseList();
-               $responseList->setObjectIDs($responseIDs);
-               $responseList->readObjects();
-               $responses = $responseList->getObjects();
-               
-               // fetch comments
-               $commentIDs = $comments = [];
-               foreach ($responses as $response) {
-                       $commentIDs[] = $response->commentID;
-               }
-               if (!empty($commentIDs)) {
-                       $commentList = new CommentList();
-                       $commentList->setObjectIDs($commentIDs);
-                       $commentList->readObjects();
-                       $comments = $commentList->getObjects();
-               }
+               $this->readResponseData($events);
                
                // fetch articles
-               $articleContentIDs = [];
-               foreach ($comments as $comment) {
-                       $articleContentIDs[] = $comment->objectID;
-               }
-               
                $articles = $articleContentToArticle = [];
-               if (!empty($articleContentIDs)) {
+               if (!empty($this->commentObjectIDs)) {
                        $articleList = new ViewableArticleList();
-                       $articleList->getConditionBuilder()->add("article.articleID IN (SELECT articleID FROM wcf".WCF_N."_article_content WHERE articleContentID IN (?))", [$articleContentIDs]);
+                       $articleList->getConditionBuilder()->add("article.articleID IN (SELECT articleID FROM wcf".WCF_N."_article_content WHERE articleContentID IN (?))", [$this->commentObjectIDs]);
                        $articleList->readObjects();
                        foreach ($articleList as $article) {
                                $articles[$article->articleID] = $article;
@@ -62,24 +35,12 @@ class ArticleCommentResponseUserActivityEvent extends SingletonFactory implement
                        }
                }
                
-               // fetch users
-               $userIDs = $users = [];
-               foreach ($comments as $comment) {
-                       $userIDs[] = $comment->userID;
-               }
-               if (!empty($userIDs)) {
-                       $userList = new UserList();
-                       $userList->setObjectIDs($userIDs);
-                       $userList->readObjects();
-                       $users = $userList->getObjects();
-               }
-               
                // set message
                foreach ($events as $event) {
-                       if (isset($responses[$event->objectID])) {
-                               $response = $responses[$event->objectID];
-                               $comment = $comments[$response->commentID];
-                               if (isset($articleContentToArticle[$comment->objectID]) && isset($users[$comment->userID])) {
+                       if (isset($this->responses[$event->objectID])) {
+                               $response = $this->responses[$event->objectID];
+                               $comment = $this->comments[$response->commentID];
+                               if (isset($articleContentToArticle[$comment->objectID]) && isset($this->commentAuthors[$comment->userID])) {
                                        $article = $articles[$articleContentToArticle[$comment->objectID]];
                                        
                                        // check permissions
@@ -90,10 +51,10 @@ class ArticleCommentResponseUserActivityEvent extends SingletonFactory implement
                                        
                                        // title
                                        $text = WCF::getLanguage()->getDynamicVariable('wcf.article.recentActivity.articleCommentResponse', [
-                                               'commentAuthor' => $users[$comment->userID],
+                                               'commentAuthor' => $this->commentAuthors[$comment->userID],
                                                'commentID' => $comment->commentID,
                                                'responseID' => $response->responseID,
-                                               'article' => $article
+                                               'article' => $article,
                                        ]);
                                        $event->setTitle($text);
                                        
index 65d71f4221308747627d3c138ae9eab16e896dff..2d76ff634c49e4318a240e5bcd0419df3a0ecf91 100644 (file)
@@ -1,69 +1,33 @@
 <?php
 namespace wcf\system\user\activity\event;
-use wcf\data\comment\response\CommentResponseList;
-use wcf\data\comment\CommentList;
 use wcf\data\page\PageCache;
-use wcf\data\user\UserList;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 
 /**
  * User activity event implementation for responses to page comments.
- *
+ * 
  * @author     Joshua Ruesweg
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\User\Activity\Event
  * @since      5.2
  */
 class PageCommentResponseUserActivityEvent extends SingletonFactory implements IUserActivityEvent {
+       use TCommentResponseUserActivityEvent;
+       
        /**
         * @inheritDoc
         */
        public function prepare(array $events) {
-               $responseIDs = [];
-               foreach ($events as $event) {
-                       $responseIDs[] = $event->objectID;
-               }
-               
-               // fetch responses
-               $responseList = new CommentResponseList();
-               $responseList->setObjectIDs($responseIDs);
-               $responseList->readObjects();
-               $responses = $responseList->getObjects();
-               
-               // fetch comments
-               $commentIDs = $comments = [];
-               foreach ($responses as $response) {
-                       $commentIDs[] = $response->commentID;
-               }
-               
-               if (!empty($commentIDs)) {
-                       $commentList = new CommentList();
-                       $commentList->setObjectIDs($commentIDs);
-                       $commentList->readObjects();
-                       $comments = $commentList->getObjects();
-               }
-               
-               // fetch users
-               $userIDs = $users = [];
-               foreach ($comments as $comment) {
-                       $userIDs[] = $comment->userID;
-               }
-               
-               if (!empty($userIDs)) {
-                       $userList = new UserList();
-                       $userList->setObjectIDs($userIDs);
-                       $userList->readObjects();
-                       $users = $userList->getObjects();
-               }
+               $this->readResponseData($events);
                
                // set message
                foreach ($events as $event) {
-                       if (isset($responses[$event->objectID])) {
-                               $response = $responses[$event->objectID];
-                               $comment = $comments[$response->commentID];
-                               if (PageCache::getInstance()->getPage($comment->objectID) && isset($users[$comment->userID])) {
+                       if (isset($this->responses[$event->objectID])) {
+                               $response = $this->responses[$event->objectID];
+                               $comment = $this->comments[$response->commentID];
+                               if (PageCache::getInstance()->getPage($comment->objectID) && isset($this->commentAuthors[$comment->userID])) {
                                        $page = PageCache::getInstance()->getPage($comment->objectID);
                                        
                                        // check permissions
@@ -74,10 +38,10 @@ class PageCommentResponseUserActivityEvent extends SingletonFactory implements I
                                        
                                        // title
                                        $text = WCF::getLanguage()->getDynamicVariable('wcf.page.recentActivity.pageCommentResponse', [
-                                               'commentAuthor' => $users[$comment->userID],
+                                               'commentAuthor' => $this->commentAuthors[$comment->userID],
                                                'commentID' => $comment->commentID,
                                                'responseID' => $response->responseID,
-                                               'page' => $page
+                                               'page' => $page,
                                        ]);
                                        $event->setTitle($text);
                                        
index 9e975638a445640fd75cd99943ef8633b4ab0a4b..7aa05d28e489a089f0b5b67a7b22dba3729b9ffc 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 namespace wcf\system\user\activity\event;
-use wcf\data\comment\response\CommentResponseList;
-use wcf\data\comment\CommentList;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
@@ -10,11 +8,13 @@ use wcf\system\WCF;
  * User activity event implementation for profile comment responses.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\User\Activity\Event
  */
 class ProfileCommentResponseUserActivityEvent extends SingletonFactory implements IUserActivityEvent {
+       use TCommentResponseUserActivityEvent;
+       
        /**
         * @inheritDoc
         */
@@ -23,34 +23,12 @@ class ProfileCommentResponseUserActivityEvent extends SingletonFactory implement
                        return;
                }
                
-               $responseIDs = [];
-               foreach ($events as $event) {
-                       $responseIDs[] = $event->objectID;
-               }
-               
-               // fetch responses
-               $responseList = new CommentResponseList();
-               $responseList->setObjectIDs($responseIDs);
-               $responseList->readObjects();
-               $responses = $responseList->getObjects();
-               
-               // fetch comments
-               $commentIDs = $comments = [];
-               foreach ($responses as $response) {
-                       $commentIDs[] = $response->commentID;
-               }
-               if (!empty($commentIDs)) {
-                       $commentList = new CommentList();
-                       $commentList->setObjectIDs($commentIDs);
-                       $commentList->readObjects();
-                       $comments = $commentList->getObjects();
-               }
+               $this->readResponseData($events);
                
                // fetch users
                $userIDs = $users = [];
-               foreach ($comments as $comment) {
+               foreach ($this->comments as $comment) {
                        $userIDs[] = $comment->objectID;
-                       $userIDs[] = $comment->userID;
                }
                if (!empty($userIDs)) {
                        $users = UserProfileRuntimeCache::getInstance()->getObjects($userIDs);
@@ -58,19 +36,19 @@ class ProfileCommentResponseUserActivityEvent extends SingletonFactory implement
                
                // set message
                foreach ($events as $event) {
-                       if (isset($responses[$event->objectID])) {
-                               $response = $responses[$event->objectID];
-                               $comment = $comments[$response->commentID];
-                               if (isset($users[$comment->objectID]) && isset($users[$comment->userID])) {
+                       if (isset($this->responses[$event->objectID])) {
+                               $response = $this->responses[$event->objectID];
+                               $comment = $this->comments[$response->commentID];
+                               if (isset($users[$comment->objectID]) && isset($this->commentAuthors[$comment->userID])) {
                                        if (!$users[$comment->objectID]->isProtected()) {
                                                $event->setIsAccessible();
                                                
                                                // title
                                                $text = WCF::getLanguage()->getDynamicVariable('wcf.user.profile.recentActivity.profileCommentResponse', [
-                                                       'commentAuthor' => $users[$comment->userID],
+                                                       'commentAuthor' => $this->commentAuthors[$comment->userID],
                                                        'commentID' => $comment->commentID,
                                                        'responseID' => $response->responseID,
-                                                       'user' => $users[$comment->objectID]
+                                                       'user' => $users[$comment->objectID],
                                                ]);
                                                $event->setTitle($text);
                                                
diff --git a/wcfsetup/install/files/lib/system/user/activity/event/TCommentResponseUserActivityEvent.class.php b/wcfsetup/install/files/lib/system/user/activity/event/TCommentResponseUserActivityEvent.class.php
new file mode 100644 (file)
index 0000000..d505dfa
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+namespace wcf\system\user\activity\event;
+use wcf\data\comment\Comment;
+use wcf\data\comment\response\CommentResponse;
+use wcf\data\user\activity\event\ViewableUserActivityEvent;
+use wcf\data\user\UserProfile;
+use wcf\system\cache\runtime\CommentResponseRuntimeCache;
+use wcf\system\cache\runtime\CommentRuntimeCache;
+use wcf\system\cache\runtime\UserProfileRuntimeCache;
+
+/**
+ * Provides a method to read the comment response, comment, and user objects related to comment
+ * response user activity events.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\User\Activity\Event
+ * @since      5.3
+ */
+trait TCommentResponseUserActivityEvent {
+       /**
+        * user objects for the comment authors
+        * @var UserProfile[]
+        */
+       protected $commentAuthors = [];
+       
+       /**
+        * ids of the objects the comments belongs to
+        * @var int[] 
+        */
+       protected $commentObjectIDs = [];
+       
+       /**
+        * comment objects the responses belongs to
+        * @var Comment[]
+        */
+       protected $comments = [];
+       
+       /**
+        * comment response the comment response user activity events belong to
+        * @var CommentResponse[]
+        */
+       protected $responses = [];
+       
+       /**
+        * Reads the data of the comment responses the given events belong to.
+        * 
+        * @param       ViewableUserActivityEvent[]     $events
+        */
+       protected function readResponseData(array $events) {
+               $responseIDs = [];
+               foreach ($events as $event) {
+                       $responseIDs[] = $event->objectID;
+               }
+               
+               $this->responses = CommentResponseRuntimeCache::getInstance()->getObjects($responseIDs);
+               
+               $commentIDs = [];
+               foreach ($this->responses as $response) {
+                       $commentIDs[] = $response->commentID;
+               }
+               
+               if (!empty($commentIDs)) {
+                       $this->comments = CommentRuntimeCache::getInstance()->getObjects($commentIDs);
+               }
+               
+               $userIDs = [];
+               foreach ($this->comments as $comment) {
+                       $userIDs[] = $comment->userID;
+                       $this->commentObjectIDs[] = $comment->objectID;
+               }
+               if (!empty($userIDs)) {
+                       $this->commentAuthors = UserProfileRuntimeCache::getInstance()->getObjects($userIDs);
+               }
+       }
+}
index e7ceb7aa901233b5c2c734a7329549b5995d05c7..adfb0823cec7ee5406f4712a91417484187b2cd6 100644 (file)
@@ -3,7 +3,7 @@ namespace wcf\system\user\authentication;
 use wcf\system\SingletonFactory;
 
 /**
- * Abstract implementation of an user authentication.
+ * Abstract implementation of a user authentication.
  * 
  * @author     Marcel Werk
  * @copyright  2001-2019 WoltLab GmbH
index 4672efdfa0dccaf4ff79a5c801c4edd9a3e3e8ee..577efecbfdda567e1c7fe51c7bd9cd9bf4c8bc64 100644 (file)
@@ -9,6 +9,9 @@ use wcf\data\user\notification\UserNotificationAction;
 use wcf\data\user\User;
 use wcf\data\user\UserEditor;
 use wcf\data\user\UserProfile;
+use wcf\form\NotificationUnsubscribeForm;
+use wcf\system\background\job\NotificationEmailDeliveryBackgroundJob;
+use wcf\system\background\BackgroundQueueHandler;
 use wcf\system\cache\builder\UserNotificationEventCacheBuilder;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
@@ -672,7 +675,7 @@ class UserNotificationHandler extends SingletonFactory {
         */
        public function sendInstantMailNotification(UserNotification $notification, User $user, IUserNotificationEvent $event) {
                // no notifications for disabled or banned users
-               if ($user->activationCode) return;
+               if (!$user->isEmailConfirmed()) return;
                if ($user->banned) return;
                
                // recipient's language
@@ -693,6 +696,17 @@ class UserNotificationHandler extends SingletonFactory {
                        'title' => $event->getEmailTitle()
                ]));
                $email->addRecipient(new UserMailbox($user));
+               $humanReadableListId = $user->getLanguage()->getDynamicVariable('wcf.user.notification.'.$event->objectType.'.'.$event->eventName);
+               $email->setListID($event->eventName.'.'.$event->objectType.'.instant.notification', $humanReadableListId);
+               $email->setListUnsubscribe(LinkHandler::getInstance()->getControllerLink(NotificationUnsubscribeForm::class, [
+                       // eventID is not part of the parameter list, because we can't communicate that
+                       // only a single type would be unsubscribed.
+                       // The recipient's expectations when performing the One-Click unsubscribing are that
+                       // no further emails will be received. Not following that expectation might result in
+                       // harsh filtering.
+                       'userID' => $user->userID,
+                       'token' => $user->notificationMailToken,
+               ]), true);
                
                $message = $event->getEmailMessage('instant');
                if (is_array($message)) {
@@ -726,7 +740,11 @@ class UserNotificationHandler extends SingletonFactory {
                        ]));
                }
                
-               $email->send();
+               $jobs = $email->getJobs();
+               foreach ($jobs as $job) {
+                       $wrappedJob = new NotificationEmailDeliveryBackgroundJob($job, $notification, $user);
+                       BackgroundQueueHandler::getInstance()->enqueueIn($wrappedJob);
+               }
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/system/user/notification/event/ArticleLikeUserNotificationEvent.class.php b/wcfsetup/install/files/lib/system/user/notification/event/ArticleLikeUserNotificationEvent.class.php
new file mode 100644 (file)
index 0000000..e88d55c
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+namespace wcf\system\user\notification\event;
+use wcf\data\article\category\ArticleCategory;
+use wcf\data\article\LikeableArticle;
+use wcf\data\user\UserProfile;
+use wcf\system\cache\runtime\ViewableArticleRuntimeCache;
+use wcf\system\user\notification\object\LikeUserNotificationObject;
+use wcf\system\user\storage\UserStorageHandler;
+use wcf\system\WCF;
+
+/**
+ * User notification event for post likes.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    WoltLab License <http://www.woltlab.com/license-agreement.html>
+ * @package    WoltLabSuite\Core\System\User\Notification\Event
+ * @since      5.3
+ * 
+ * @method     LikeUserNotificationObject      getUserNotificationObject()
+ */
+class ArticleLikeUserNotificationEvent extends AbstractSharedUserNotificationEvent implements ITestableUserNotificationEvent {
+       use TTestableLikeUserNotificationEvent {
+               TTestableLikeUserNotificationEvent::canBeTriggeredByGuests insteadof TTestableUserNotificationEvent;
+       }
+       use TTestableArticleUserNotificationEvent;
+       use TTestableCategorizedUserNotificationEvent;
+       use TTestableUserNotificationEvent;
+       use TReactionUserNotificationEvent;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $stackable = true;
+       
+       /**
+        * @inheritDoc
+        */
+       protected function prepare() {
+               ViewableArticleRuntimeCache::getInstance()->cacheObjectID($this->getUserNotificationObject()->objectID);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getTitle() {
+               $count = count($this->getAuthors());
+               if ($count > 1) {
+                       return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.title.stacked', [
+                               'count' => $count,
+                               'timesTriggered' => $this->notification->timesTriggered
+                       ]);
+               }
+               
+               return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.title');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getMessage() {
+               $article = ViewableArticleRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID);
+               $authors = array_values($this->getAuthors());
+               $count = count($authors);
+               
+               if ($count > 1) {
+                       return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.message.stacked', [
+                               'author' => $this->author,
+                               'authors' => $authors,
+                               'count' => $count,
+                               'others' => $count - 1,
+                               'article' => $article,
+                               'reactions' => $this->getReactionsForAuthors(),
+                       ]);
+               }
+               
+               return $this->getLanguage()->getDynamicVariable('wcf.article.like.notification.message', [
+                       'author' => $this->author,
+                       'article' => $article,
+                       'userNotificationObject' => $this->getUserNotificationObject(),
+                       'reactions' => $this->getReactionsForAuthors(),
+               ]);
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function getEmailMessage($notificationType = 'instant') {
+               // not supported
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getLink() {
+               return ViewableArticleRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID)->getLink();
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function supportsEmailNotification() {
+               return false;
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function getEventHash() {
+               return sha1($this->eventID . '-' . $this->additionalData['objectID']);
+       }
+       
+       /** @noinspection PhpMissingParentCallCommonInspection */
+       /**
+        * @inheritDoc
+        */
+       public function checkAccess() {
+               if (!ViewableArticleRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID)->canRead()) {
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'wbbUnreadWatchedThreads');
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadArticles');
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadWatchedArticles');
+                       UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadArticlesByCategory');
+                       
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isVisible() {
+               if (!MODULE_ARTICLE || !MODULE_LIKE) {
+                       return false;
+               }
+               
+               return parent::isVisible();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected static function createTestLikeObject(UserProfile $recipient, UserProfile $author) {
+               return new LikeableArticle(self::getTestArticle(self::createTestCategory(ArticleCategory::OBJECT_TYPE_NAME), $author));
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       protected static function getTestLikeableObjectTypeName() {
+               return 'com.woltlab.wcf.likeableArticle';
+       }
+}
index 9e18b93990135c6f74d318bd11298d02c8b23c78..ce96adc2262c2f481882f020b3402230087a85b6 100644 (file)
@@ -3,7 +3,6 @@ namespace wcf\system\user\notification\event;
 use wcf\data\user\follow\UserFollow;
 use wcf\data\user\follow\UserFollowAction;
 use wcf\data\user\UserProfile;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\object\IUserNotificationObject;
 use wcf\system\user\notification\object\UserFollowUserNotificationObject;
 
@@ -11,7 +10,7 @@ use wcf\system\user\notification\object\UserFollowUserNotificationObject;
  * Notification event for followers.
  * 
  * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\User\Notification\Event
  * 
@@ -70,7 +69,7 @@ class UserFollowFollowingUserNotificationEvent extends AbstractUserNotificationE
         * @inheritDoc
         */
        public function getLink() {
-               return LinkHandler::getInstance()->getLink('User', ['object' => $this->author]);
+               return $this->author->getLink();
        }
        
        /**
index 202a765556fded23debae5a0d533115df1019566..e761464c13d23791fab3549c84bf6c787a2cff6e 100644 (file)
@@ -3,7 +3,6 @@ namespace wcf\system\user\notification\event;
 use wcf\data\user\UserProfile;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\comment\CommentHandler;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\object\LikeUserNotificationObject;
 use wcf\system\WCF;
 
@@ -96,7 +95,7 @@ class UserProfileCommentLikeUserNotificationEvent extends AbstractSharedUserNoti
                        $owner = UserProfileRuntimeCache::getInstance()->getObject($this->additionalData['objectID']);
                }
                
-               return LinkHandler::getInstance()->getLink('User', ['object' => $owner], '#wall/comment' . $this->getCommentID());
+               return $owner->getLink() . '#wall/comment' . $this->getCommentID();
        }
        
        /**
index f737828b4d63eddbccc894cbea848b3e267cae53..a927a1b7264691feee4907bda7ca4a934cff1a3c 100644 (file)
@@ -3,7 +3,6 @@ namespace wcf\system\user\notification\event;
 use wcf\data\user\UserProfile;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\comment\CommentHandler;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\object\LikeUserNotificationObject;
 use wcf\system\WCF;
 
@@ -103,11 +102,7 @@ class UserProfileCommentResponseLikeUserNotificationEvent extends AbstractShared
                        $owner = UserProfileRuntimeCache::getInstance()->getObject($this->additionalData['objectID']);
                }
                
-               return LinkHandler::getInstance()->getLink(
-                       'User',
-                       ['object' => $owner],
-                       '#wall/comment' . $this->additionalData['commentID'] . '/response' . $this->getResponseID()
-               );
+               return $owner->getLink() . '#wall/comment' . $this->additionalData['commentID'] . '/response' . $this->getResponseID();
        }
        
        /**
index 6c77e2ff9aedfc81ed1c1e74a9794c3b2b1a3789..7b1ab0c06c58b815e152298799cc0ed0c1f7aafb 100644 (file)
@@ -5,7 +5,6 @@ use wcf\system\cache\runtime\CommentRuntimeCache;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\comment\CommentHandler;
 use wcf\system\email\Email;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\object\CommentResponseUserNotificationObject;
 
 /**
@@ -123,11 +122,8 @@ class UserProfileCommentResponseOwnerUserNotificationEvent extends AbstractShare
         * @inheritDoc
         */
        public function getLink() {
-               return LinkHandler::getInstance()->getLink(
-                       'User',
-                       ['object' => UserProfileRuntimeCache::getInstance()->getObject($this->additionalData['objectID'])],
-                       '#wall/comment' . $this->getUserNotificationObject()->commentID
-               );
+               return UserProfileRuntimeCache::getInstance()->getObject($this->additionalData['objectID'])->getLink() .
+                       '#wall/comment' . $this->getUserNotificationObject()->commentID;
        }
        
        /**
index 4da2d378ecf69c57e964f71e37fa1006ef1a8c89..f994687d1331afe6cf18799144fefb16939c20d3 100644 (file)
@@ -3,7 +3,6 @@ namespace wcf\system\user\notification\event;
 use wcf\data\user\UserProfile;
 use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\comment\CommentHandler;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\object\CommentUserNotificationObject;
 
 /**
@@ -93,11 +92,8 @@ class UserProfileCommentUserNotificationEvent extends AbstractSharedUserNotifica
         * @inheritDoc
         */
        public function getLink() {
-               return LinkHandler::getInstance()->getLink(
-                       'User',
-                       ['object' => UserProfileRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID)],
-                       '#wall/comment' . $this->getUserNotificationObject()->commentID
-               );
+               return UserProfileRuntimeCache::getInstance()->getObject($this->getUserNotificationObject()->objectID)->getLink() .
+                       '#wall/comment' . $this->getUserNotificationObject()->commentID;
        }
        
        /**
index 1e69acb9c7c0727f0619f98d93f6edbd03f8c724..5c51349a44b9d1b3801f79525f0dd1c0cb17d619 100644 (file)
@@ -1,19 +1,18 @@
 <?php
 namespace wcf\system\user\notification\event;
 use wcf\data\user\UserProfile;
-use wcf\system\request\LinkHandler;
 use wcf\system\user\notification\object\UserFollowUserNotificationObject;
 use wcf\system\user\notification\object\UserRegistrationUserNotificationObject;
 
 /**
  * Notification event for new user registrations.
- *
+ * 
  * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\User\Notification\Event
  * @since       5.2
- *
+ * 
  * @method     UserRegistrationUserNotificationObject  getUserNotificationObject()
  */
 class UserRegistrationUserNotificationEvent extends AbstractUserNotificationEvent implements ITestableUserNotificationEvent {
@@ -69,7 +68,7 @@ class UserRegistrationUserNotificationEvent extends AbstractUserNotificationEven
         * @inheritDoc
         */
        public function getLink() {
-               return LinkHandler::getInstance()->getLink('User', ['object' => $this->author]);
+               return $this->author->getLink();
        }
        
        /**
index ce9e8080e481203f2c1c3cf5b7cacaf411e3bf80..85b52fb7c37ddaeffe5054251fb9d01f4fff50c9 100644 (file)
@@ -47,7 +47,6 @@ class SignatureCache extends SingletonFactory {
                                $this->cacheUserSignature([$user->userID]);
                        }
                        
-                       $this->htmlOutputProcessor->setContext('com.woltlab.wcf.user.signature', $user->userID);
                        $this->htmlOutputProcessor->process($user->signature, 'com.woltlab.wcf.user.signature', $user->userID);
                        $this->signatures[$user->userID] = $this->htmlOutputProcessor->getHtml();
                }
index 418f5ad9ed68c2bfb965967b9119b6ffbceb0576..5b236891003e03621da60799137693a15e16ceed 100644 (file)
@@ -10,7 +10,7 @@ use wcf\system\WCF;
 /**
  * Handles the persistent user data storage.
  * 
- * @author     Alexander Ebert
+ * @author     Tim Duesterhus, Alexander Ebert
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Storage
@@ -23,16 +23,9 @@ class UserStorageHandler extends SingletonFactory {
        protected $cache = [];
        
        /**
-        * list of outdated data records
-        * @var mixed[][]
+        * @var (string|null)[][]
         */
-       protected $resetFields = [];
-       
-       /**
-        * list of updated or new data records
-        * @var mixed[][]
-        */
-       protected $updateFields = [];
+       protected $log = [];
        
        /**
         * redis instance
@@ -62,7 +55,10 @@ class UserStorageHandler extends SingletonFactory {
                
                $tmp = [];
                foreach ($userIDs as $userID) {
-                       if (!isset($this->cache[$userID])) $tmp[] = $userID;
+                       if (!isset($this->cache[$userID])) {
+                               $tmp[] = $userID;
+                               $this->cache[$userID] = [];
+                       }
                }
                
                // ignore users whose storage data is already loaded
@@ -77,22 +73,21 @@ class UserStorageHandler extends SingletonFactory {
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute($conditions->getParameters());
                while ($row = $statement->fetchArray()) {
-                       if (!isset($this->cache[$row['userID']])) {
-                               $this->cache[$row['userID']] = [];
-                       }
-                       
-                       // Skip the field, if the value was reset before the storage had been loaded.
-                       if (isset($this->resetFields[$row['userID']]) && in_array($row['field'], $this->resetFields[$row['userID']])) {
-                               continue;
+                       if (isset($this->log[$row['userID']])) {
+                               if (array_key_exists($row['field'], $this->log[$row['userID']])) {
+                                       $logged = $this->log[$row['userID']][$row['field']];
+                                       
+                                       // Use the new value if the field was updated.
+                                       if ($logged !== null) {
+                                               $this->cache[$row['userID']][$row['field']] = $logged;
+                                       }
+                                       
+                                       // In any case: Skip this field, because it was updated or resetted before it was loaded.
+                                       continue;
+                               }
                        }
                        
-                       // Use the new value, if the field was updated before the storage had been loaded.
-                       if (isset($this->updateFields[$row['userID']][$row['field']])) {
-                               $this->cache[$row['userID']][$row['field']] = $this->updateFields[$row['userID']][$row['field']];
-                       }
-                       else {
-                               $this->cache[$row['userID']][$row['field']] = $row['fieldValue'];
-                       }
+                       $this->cache[$row['userID']][$row['field']] = $row['fieldValue'];
                }
        }
        
@@ -184,17 +179,15 @@ class UserStorageHandler extends SingletonFactory {
                        return;
                }
                
-               $this->updateFields[$userID][$field] = $fieldValue;
+               if (!isset($this->log[$userID])) {
+                       $this->log[$userID] = [];
+               }
+               $this->log[$userID][$field] = $fieldValue;
                
                // update data cache for given user
                if (isset($this->cache[$userID])) {
                        $this->cache[$userID][$field] = $fieldValue;
                }
-               
-               // The reset is superfluous, because the value is going to be updated.
-               if (isset($this->resetFields[$userID]) && in_array($field, $this->resetFields[$userID])) {
-                       unset($this->resetFields[$userID][array_search($field, $this->resetFields[$userID])]);
-               }
        }
        
        /**
@@ -214,16 +207,12 @@ class UserStorageHandler extends SingletonFactory {
                }
                
                foreach ($userIDs as $userID) {
-                       $this->resetFields[$userID][] = $field;
-                       
-                       if (isset($this->cache[$userID][$field])) {
-                               unset($this->cache[$userID][$field]);
+                       if (!isset($this->log[$userID])) {
+                               $this->log[$userID] = [];
                        }
+                       $this->log[$userID][$field] = null;
                        
-                       // The update is superfluous, because the value is going to be reset.
-                       if (isset($this->updateFields[$userID][$field])) {
-                               unset($this->updateFields[$userID][$field]);
-                       }
+                       unset($this->cache[$userID][$field]);
                }
        }
        
@@ -244,21 +233,11 @@ class UserStorageHandler extends SingletonFactory {
                $statement->execute([$field]);
                
                foreach ($this->cache as $userID => $fields) {
-                       if (isset($fields[$field])) {
-                               unset($this->cache[$userID][$field]);
-                       }
-               }
-               
-               foreach ($this->updateFields as $userID => $fields) {
-                       if (isset($fields[$field])) {
-                               unset($this->updateFields[$userID][$field]);
-                       }
+                       unset($this->cache[$userID][$field]);
                }
                
-               foreach ($this->resetFields as $userID => $fields) {
-                       if (in_array($field, $fields)) {
-                               unset($this->resetFields[$userID][array_search($field, $this->resetFields[$userID])]);
-                       }
+               foreach ($this->log as $userID => $fields) {
+                       unset($this->log[$userID][$field]);
                }
        }
        
@@ -268,78 +247,60 @@ class UserStorageHandler extends SingletonFactory {
        public function shutdown() {
                if ($this->redis) return;
                
-               $toReset = [];
-               
-               // remove outdated entries
-               foreach ($this->resetFields as $userID => $fields) {
-                       foreach ($fields as $field) {
-                               if (!isset($toReset[$field])) $toReset[$field] = [];
-                               $toReset[$field][] = $userID;
-                       }
-               }
-               foreach ($this->updateFields as $userID => $fieldValues) {
-                       foreach ($fieldValues as $field => $fieldValue) {
-                               if (!isset($toReset[$field])) $toReset[$field] = [];
-                               $toReset[$field][] = $userID;
-                       }
-               }
-               ksort($toReset);
-               
-               // exclude values which should be resetted
-               foreach ($this->updateFields as $userID => $fieldValues) {
-                       if (isset($this->resetFields[$userID])) {
-                               foreach ($fieldValues as $field => $fieldValue) {
-                                       if (in_array($field, $this->resetFields[$userID])) {
-                                               unset($this->updateFields[$userID][$field]);
-                                       }
-                               }
-                               
-                               if (empty($this->updateFields[$userID])) {
-                                       unset($this->updateFields[$userID]);
-                               }
-                       }
-               }
-               ksort($this->updateFields);
-               
                $i = 0;
                while (true) {
                        try {
-                               WCF::getDB()->beginTransaction();
-                               
-                               // reset data
-                               foreach ($toReset as $field => $userIDs) {
-                                       sort($userIDs);
+                               foreach ($this->log as $userID => $fields) {
+                                       if (empty($fields)) {
+                                               // Delete log entry as it was handled (by doing nothing).
+                                               // This can happen if ->resetAll() is called for the only updated
+                                               // field of a user.
+                                               unset($this->log[$userID]);
+                                               continue;
+                                       }
+                                       
+                                       WCF::getDB()->beginTransaction();
+                                       
+                                       ksort($fields);
+                                       
+                                       // Lock the user.
+                                       $sql = "SELECT  *
+                                               FROM    wcf".WCF_N."_user
+                                               WHERE   userID = ?
+                                               FOR UPDATE";
+                                       $statement = WCF::getDB()->prepareStatement($sql);
+                                       $statement->execute([$userID]);
+                                       
+                                       // Delete existing data.
                                        $conditions = new PreparedStatementConditionBuilder();
-                                       $conditions->add("userID IN (?)", [$userIDs]);
-                                       $conditions->add("field = ?", [$field]);
+                                       $conditions->add("userID = ?", [$userID]);
+                                       $conditions->add("field IN (?)", [array_keys($fields)]);
                                        
                                        $sql = "DELETE FROM     wcf".WCF_N."_user_storage
                                                ".$conditions;
                                        $statement = WCF::getDB()->prepareStatement($sql);
                                        $statement->execute($conditions->getParameters());
-                               }
-                               
-                               // insert data
-                               if (!empty($this->updateFields)) {
+                                       
+                                       // Insert updated data.
                                        $sql = "INSERT INTO     wcf".WCF_N."_user_storage
                                                                (userID, field, fieldValue)
                                                VALUES          (?, ?, ?)";
                                        $statement = WCF::getDB()->prepareStatement($sql);
-                                       
-                                       foreach ($this->updateFields as $userID => $fieldValues) {
-                                               ksort($fieldValues);
+                                       foreach ($fields as $field => $fieldValue) {
+                                               if ($fieldValue === null) continue;
                                                
-                                               foreach ($fieldValues as $field => $fieldValue) {
-                                                       $statement->execute([
-                                                               $userID,
-                                                               $field,
-                                                               $fieldValue
-                                                       ]);
-                                               }
+                                               $statement->execute([
+                                                       $userID,
+                                                       $field,
+                                                       $fieldValue
+                                               ]);
                                        }
+                                       
+                                       WCF::getDB()->commitTransaction();
+                                       
+                                       // Delete log entry as the commit succeeded.
+                                       unset($this->log[$userID]);
                                }
-                               
-                               WCF::getDB()->commitTransaction();
                                break;
                        }
                        catch (\Exception $e) {
@@ -354,7 +315,6 @@ class UserStorageHandler extends SingletonFactory {
                                usleep(mt_rand(0, .1e6)); // 0 to .1 seconds
                        }
                }
-               $this->resetFields = $this->updateFields = [];
        }
        
        /**
@@ -367,11 +327,13 @@ class UserStorageHandler extends SingletonFactory {
                        return;
                }
                
-               $this->resetFields = $this->updateFields = $this->cache = [];
+               $this->cache = [];
                
                $sql = "DELETE FROM     wcf".WCF_N."_user_storage";
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute();
+               
+               $this->log = [];
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/system/worker/DatabaseConvertEncodingWorker.class.php b/wcfsetup/install/files/lib/system/worker/DatabaseConvertEncodingWorker.class.php
deleted file mode 100644 (file)
index c4ad4b9..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-namespace wcf\system\worker;
-use wcf\system\request\LinkHandler;
-use wcf\system\WCF;
-
-/**
- * Worker implementation for database table encoding conversion.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\System\Worker
- */
-class DatabaseConvertEncodingWorker extends AbstractRebuildDataWorker {
-       /**
-        * @inheritDoc
-        */
-       protected $limit = 1;
-       
-       /**
-        * @inheritDoc
-        */
-       public function initObjectList() {
-               // This rebuild worker has no database object list
-               // therefore we do nothing in this method an overwrite
-               // the parent method, that it does not throw an exception.
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function countObjects() {
-               if ($this->count === null) {
-                       $this->count = count($this->getTables());
-               }
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function getProceedURL() {
-               return LinkHandler::getInstance()->getLink('RebuildData');
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function validate() {
-               WCF::getSession()->checkPermissions(['admin.management.canRebuildData']);
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function execute() {
-               $tables = $this->getTables();
-               
-               $statement = WCF::getDB()->prepareStatement("SET FOREIGN_KEY_CHECKS=0");
-               $statement->execute();
-               
-               $convertTables = array_slice($tables, $this->limit * $this->loopCount, $this->limit);
-               foreach ($convertTables as $table) {
-                       $sql = "ALTER TABLE " . $table . " CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute();
-                       
-                       $sql = "ALTER TABLE " . $table . " DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute();
-               }
-               
-               $statement = WCF::getDB()->prepareStatement("SET FOREIGN_KEY_CHECKS=1");
-               $statement->execute();
-       }
-       
-       /**
-        * Returns the list of known database tables.
-        * 
-        * @return      string[]
-        */
-       protected function getTables() {
-               $sql = "SELECT  DISTINCT sqlTable
-                       FROM    wcf".WCF_N."_package_installation_sql_log";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute();
-               $tables = [];
-               while ($table = $statement->fetchColumn()) {
-                       $tables[] = $table;
-               }
-               
-               return $tables;
-       }
-}
index efcc13d1d91550bb9052e743164b6edb769feb31..f6d6d5eed4b73dab6ef8319a3ac9e08289ae0589 100755 (executable)
@@ -9,6 +9,7 @@ use wcf\system\exception\ImplementationException;
 use wcf\system\exception\ParentClassException;
 use wcf\system\io\AtomicWriter;
 use wcf\system\io\File;
+use wcf\system\registry\RegistryHandler;
 use wcf\system\request\LinkHandler;
 use wcf\system\Regex;
 use wcf\system\WCF;
@@ -30,6 +31,12 @@ class SitemapRebuildWorker extends AbstractRebuildDataWorker {
         */
        const SITEMAP_OBJECT_LIMIT = 50000;
        
+       /**
+        * Prefix for stored data in the registry.
+        * @since 5.3
+        */
+       const REGISTRY_PREFIX = 'sitemapData_';
+       
        /**
         * @inheritDoc
         */
@@ -83,6 +90,7 @@ class SitemapRebuildWorker extends AbstractRebuildDataWorker {
                                // read sitemaps
                                $sitemapObjects = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.sitemap.object');
                                foreach ($sitemapObjects as $sitemapObject) {
+                                       self::prepareSitemapObject($sitemapObject);
                                        $processor = $sitemapObject->getProcessor();
                                        
                                        if ($processor->isAvailableType() && ($sitemapObject->isDisabled === null || !$sitemapObject->isDisabled)) {
@@ -426,4 +434,25 @@ class SitemapRebuildWorker extends AbstractRebuildDataWorker {
        private function changeToActualUser() {
                WCF::getSession()->changeUser($this->actualUser, true);
        }
+       
+       /**
+        * Reads the columns changed by the user for this sitemap object from the registry and modifies the object accordingly.
+        * 
+        * @param       ObjectType      $object
+        * @since       5.3
+        */
+       public static function prepareSitemapObject(ObjectType $object) {
+               $sitemapData = RegistryHandler::getInstance()->get('com.woltlab.wcf', self::REGISTRY_PREFIX . $object->objectType);
+               
+               if ($sitemapData !== null) {
+                       $sitemapData = @unserialize($sitemapData);
+                       
+                       if (is_array($sitemapData)) {
+                               $object->priority = $sitemapData['priority'];
+                               $object->changeFreq = $sitemapData['changeFreq'];
+                               $object->rebuildTime = $sitemapData['rebuildTime'];
+                               $object->isDisabled = $sitemapData['isDisabled'];
+                       }
+               }
+       }
 }
index 009fb72a184f55747676c766487f85aa770b695c..6985f891dc11fc85b793dbcffd358b853f44ff6a 100644 (file)
@@ -205,6 +205,8 @@ class UserRebuildDataWorker extends AbstractRebuildDataWorker {
                                        
                                        $thumbnail = $adapter->createThumbnail($width, $height, false);
                                        $adapter->writeImage($thumbnail, $avatar->getLocation());
+                                       // Clear thumbnail as soon as possible to free up the memory.
+                                       $thumbnail = null;
                                }
                                
                                if ($width != UserAvatar::AVATAR_SIZE || $height != UserAvatar::AVATAR_SIZE) {
index 0856d7510d6e8d2e59f2c079c886bdab8fce5cea..9009f91d2b47461d648fbe2d0f503075e2291542 100644 (file)
@@ -50,7 +50,7 @@ final class CryptoUtil {
                list($signature, $value) = $parts;
                $value = base64_decode($value);
                
-               return self::secureCompare($signature, self::getSignature($value));
+               return \hash_equals($signature, self::getSignature($value));
        }
 
        /**
index 52c46077272103ec187a9426be17aa7ddc362794..f362bb93622ee4429781293fd00d1ea15949f1da 100644 (file)
@@ -478,17 +478,24 @@ final class DOMUtil {
         * @param       boolean         $preserveChildNodes     preserve child nodes, only supported for elements
         */
        public static function removeNode(\DOMNode $node, $preserveChildNodes = false) {
+               $parent = $node->parentNode ?: $node->ownerDocument;
+
                if ($preserveChildNodes) {
                        if (!($node instanceof \DOMElement)) {
                                throw new \InvalidArgumentException("Preserving child nodes is only supported for DOMElement.");
                        }
                        
-                       while ($node->hasChildNodes()) {
-                               self::insertBefore($node->childNodes->item(0), $node);
+                       $children = [];
+                       foreach ($node->childNodes as $childNode) {
+                               $children[] = $childNode;
+                       }
+
+                       foreach ($children as $child) {
+                               $parent->insertBefore($child, $node);
                        }
                }
                
-               self::getParentNode($node)->removeChild($node);
+               $parent->removeChild($node);
        }
        
        /**
index c7440f7fa41c580c823fd6326119e45d456ec79b..161d4615fd82967dc8aceb4d5dc3925dba27d4dc 100644 (file)
@@ -1,9 +1,10 @@
 <?php
 namespace wcf\util;
+use wcf\system\exception\SystemException;
 use wcf\system\Regex;
 
 /**
- * Contains header-related functions.
+ * Contains helper functions to process the Exception log.
  * 
  * @author     Tim Duesterhus
  * @copyright  2001-2019 WoltLab GmbH
@@ -69,7 +70,7 @@ final class ExceptionLogUtil {
                }
                
                if (!$regex->match($entry)) {
-                       throw new \InvalidArgumentException('The given entry is malformed');
+                       throw new \InvalidArgumentException('The given entry is malformed.');
                }
                $matches = $regex->getMatches();
                $chainRegex->match($matches['chain'], true, Regex::ORDER_MATCH_BY_SET);
@@ -79,14 +80,32 @@ final class ExceptionLogUtil {
                                $item['information'] = null;
                        }
                        else {
-                               $item['information'] = unserialize(base64_decode($item['information']), ['allowed_classes' => false]);
+                               try {
+                                       $item['information'] = unserialize(base64_decode($item['information']), ['allowed_classes' => false]);
+                               }
+                               catch (SystemException $e) {
+                                       throw new \InvalidArgumentException('The additional information section of the given entry is malformed.', 0, $e);
+                               }
                        }
                        
-                       $item['stack'] = JSON::decode($item['stack']);
+                       try {
+                               $item['stack'] = JSON::decode($item['stack']);
+                       }
+                       catch (SystemException $e) {
+                               throw new \InvalidArgumentException('The stack trace of the given entry is malformed.', 0, $e);
+                       }
                        
                        return $item;
                }, $chainRegex->getMatches());
                
+               $matches['stackHash'] = sha1(implode("\0", array_map(function ($item) {
+                       $result = "";
+                       foreach ($item['stack'] as $stack) {
+                               $result .= $stack['file']."\t".$stack['line']."\t".$stack['class'].$stack['type'].$stack['function']."\n";
+                       }
+                       return $result;
+               }, $chainMatches)));
+               
                $matches['date'] = strtotime($matches['date']);
                $matches['chain'] = $chainMatches;
                
index cbb148e0a0026b5ffdb41cd95dbfb61e9c739449..d0b83a326aae185e95c2e71dd724ec16f210af43 100644 (file)
@@ -39,8 +39,6 @@ final class FileUtil {
         */
        public static function getTempFolder() {
                try {
-                       // This method does not contain any shut up operator by intent.
-                       // Any operation that fails here is fatal.
                        $path = WCF_DIR.'tmp/';
                        
                        if (is_file($path)) {
@@ -63,8 +61,10 @@ final class FileUtil {
                        if (!is_writable($path)) {
                                throw new SystemException("Temporary folder '".$path."' is not writable. Please check the permissions using your favorite ftp program.");
                        }
-                       
-                       file_put_contents($path.'/.htaccess', 'deny from all');
+
+                       if (@md5_file($path . '/.htaccess') !== '5cc8a02be988615b049f5abecba2f3a0') {
+                               file_put_contents($path.'/.htaccess', 'deny from all');
+                       }
                        
                        return $path;
                }
index 59390485d4e770d1f194ced4b75960b9c1606e1c..2cb85ab0678e97d0a86925250aa158a5cba4d659 100644 (file)
@@ -1,11 +1,17 @@
 <?php
 namespace wcf\util;
+use GuzzleHttp\Exception\BadResponseException;
+use GuzzleHttp\Exception\TooManyRedirectsException;
+use GuzzleHttp\Exception\TransferException;
+use GuzzleHttp\Psr7\Request;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
 use wcf\system\exception\HTTPNotFoundException;
 use wcf\system\exception\HTTPServerErrorException;
 use wcf\system\exception\HTTPUnauthorizedException;
 use wcf\system\exception\SystemException;
-use wcf\system\io\RemoteFile;
-use wcf\system\Regex;
+use wcf\system\io\HttpFactory;
 use wcf\system\WCF;
 use wcf\util\exception\HTTPException;
 
@@ -17,6 +23,7 @@ use wcf\util\exception\HTTPException;
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Util
+ * @deprecated 5.3 - Use Guzzle via \wcf\system\io\HttpFactory.
  */
 final class HTTPRequest {
        /**
@@ -37,54 +44,6 @@ final class HTTPRequest {
         */
        private $files = [];
        
-       /**
-        * indicates if request will be made via SSL
-        * @var boolean
-        */
-       private $useSSL = false;
-       
-       /**
-        * indicates if the connection to the proxy target will be made via SSL
-        * @var boolean
-        */
-       private $originUseSSL = false;
-       
-       /**
-        * target host
-        * @var string
-        */
-       private $host;
-       
-       /**
-        * target host if a proxy is used
-        * @var string
-        */
-       private $originHost;
-       
-       /**
-        * target port
-        * @var integer
-        */
-       private $port;
-       
-       /**
-        * target port if a proxy is used
-        * @var integer
-        */
-       private $originPort;
-       
-       /**
-        * target path
-        * @var string
-        */
-       private $path;
-       
-       /**
-        * target query string
-        * @var string
-        */
-       private $query;
-       
        /**
         * request URL
         * @var string
@@ -97,35 +56,22 @@ final class HTTPRequest {
         */
        private $headers = [];
        
-       /**
-        * legacy headers
-        * @var string[]
-        */
-       private $legacyHeaders = [];
-       
        /**
         * request body
         * @var string
         */
        private $body = '';
        
-       /**
-        * reply headers
-        * @var string[]
-        */
-       private $replyHeaders = [];
-       
        /**
         * reply body
         * @var string
         */
-       private $replyBody = '';
+       private $replyBody;
        
        /**
-        * reply status code
-        * @var integer
+        * @var ResponseInterface
         */
-       private $statusCode = 0;
+       private $response;
        
        /**
         * Constructs a new instance of HTTPRequest.
@@ -136,7 +82,7 @@ final class HTTPRequest {
         * @param       array           $files          Files to attach to the request
         */
        public function __construct($url, array $options = [], $postParameters = [], array $files = []) {
-               $this->setURL($url);
+               $this->url = $url;
                
                $this->postParameters = $postParameters;
                $this->files = $files;
@@ -206,387 +152,109 @@ final class HTTPRequest {
                                
                                $this->body .= "--".$boundary."--";
                        }
-                       $this->addHeader('content-length', strlen($this->body));
-               }
-               if (isset($this->options['auth'])) {
-                       $this->addHeader('authorization', "Basic ".base64_encode($options['auth']['username'].":".$options['auth']['password']));
                }
                $this->addHeader('connection', 'Close');
        }
        
-       /**
-        * Parses the given URL and applies PROXY_SERVER_HTTP.
-        * 
-        * @param       string          $url
-        * @throws      SystemException
-        */
-       private function setURL($url) {
-               $parsedUrl = $originUrl = Url::parse($url);
-               if (empty($originUrl['scheme']) || empty($originUrl['host'])) {
-                       throw new SystemException("Invalid URL '{$url}' given");
-               }
-               
-               $this->originUseSSL = $originUrl['scheme'] === 'https';
-               $this->originHost = $originUrl['host'];
-               $this->originPort = isset($originUrl['port']) ? $originUrl['port'] : ($this->originUseSSL ? 443 : 80);
-               
-               if (PROXY_SERVER_HTTP && !$this->originUseSSL) {
-                       $this->path = $url;
-                       $this->query = '';
-               }
-               else {
-                       $this->path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '/';
-                       $this->query = isset($parsedUrl['query']) ? $parsedUrl['query'] : '';
-               }
-               
-               if (PROXY_SERVER_HTTP && Url::is(PROXY_SERVER_HTTP)) {
-                       $parsedUrl = Url::parse(PROXY_SERVER_HTTP);
-               }
-               
-               $this->useSSL = $parsedUrl['scheme'] === 'https';
-               $this->host = $parsedUrl['host'];
-               $this->port = isset($parsedUrl['port']) ? $parsedUrl['port'] : ($this->useSSL ? 443 : 80);
-               
-               // update the 'Host:' header if URL has changed
-               if ($this->url != $url) {
-                       $this->addHeader('host', $this->originHost.($this->originPort != ($this->originUseSSL ? 443 : 80) ? ':'.$this->originPort : ''));
-               }
-               
-               $this->url = $url;
-       }
-       
        /**
         * Executes the HTTP request.
         */
        public function execute() {
-               // connect
-               $remoteFile = new RemoteFile(($this->useSSL ? 'ssl://' : '').$this->host, $this->port, $this->options['timeout'], [
-                       'ssl' => [
-                               'peer_name' => $this->originHost
-                       ]
-               ]);
+               $redirectHandler = function(RequestInterface $request, ResponseInterface $response, UriInterface $uri) {
+                       $this->url = (string) $uri;
+                       $this->response = $response;
+               };
                
-               if ($this->originUseSSL && PROXY_SERVER_HTTP) {
-                       if ($this->useSSL) throw new SystemException("Unable to proxy HTTPS when using TLS for proxy connection");
-                       
-                       $request = "CONNECT ".$this->originHost.":".$this->originPort." HTTP/1.0\r\n";
-                       if (isset($this->headers['user-agent'])) {
-                               $request .= 'user-agent: '.reset($this->headers['user-agent'])."\r\n";
-                       }
-                       $request .= "Host: ".$this->originHost.":".$this->originPort."\r\n";
-                       $request .= "\r\n";
-                       $remoteFile->puts($request);
-                       $this->replyHeaders = [];
-                       while (!$remoteFile->eof()) {
-                               $line = $remoteFile->gets();
-                               if (rtrim($line) === '') {
-                                       $this->parseReplyHeaders();
-                                       
-                                       break;
-                               }
-                               $this->replyHeaders[] = $line;
-                       }
-                       if ($this->statusCode != 200) throw new HTTPException($this, "Expected 200 Ok as reply to my CONNECT", $this->statusCode);
-                       $remoteFile->setTLS(true);
+               $options = [
+                       'connect_timeout' => $this->options['timeout'],
+                       'read_timeout' => $this->options['timeout'],
+                       'allow_redirects' => [
+                               'max' => $this->options['maxDepth'],
+                               'track_redirects' => true,
+                               'on_redirect' => $redirectHandler,
+                       ],
+               ];
+               if (isset($this->options['maxLength'])) {
+                       $options['stream'] = true;
                }
-               
-               $request = $this->options['method']." ".$this->path.($this->query ? '?'.$this->query : '')." HTTP/1.1\r\n";
-               
-               // add headers
-               foreach ($this->headers as $name => $values) {
-                       foreach ($values as $value) {
-                               $request .= $name.": ".$value."\r\n";
-                       }
+               if (isset($this->options['auth'])) {
+                       $options['auth'] = [
+                               $this->options['auth']['username'],
+                               $this->options['auth']['password'],
+                       ];
                }
-               $request .= "\r\n";
-               
-               // add post parameters
-               if ($this->options['method'] !== 'GET') $request .= $this->body."\r\n\r\n";
                
-               $remoteFile->puts($request);
+               $client = HttpFactory::makeClient($options);
                
-               $inHeader = true;
-               $this->replyHeaders = [];
-               $this->replyBody = '';
-               $chunkLength = 0;
-               $bodyLength = 0;
-               
-               $chunkedTransferRegex = new Regex('(^|,)[ \t]*chunked[ \t]*$', Regex::CASE_INSENSITIVE);
-               // read http response, until one of is true
-               // a) EOF is reached
-               // b) bodyLength is at least maxLength
-               // c) bodyLength is at least Content-Length
-               while (!(
-                       $remoteFile->eof() ||
-                       (isset($this->options['maxLength']) && $bodyLength >= $this->options['maxLength']) ||
-                       (isset($this->replyHeaders['content-length']) && $bodyLength >= end($this->replyHeaders['content-length']))
-               )) {
-                       
-                       if ($chunkLength) {
-                               if (isset($this->options['maxLength'])) $chunkLength = min($chunkLength, $this->options['maxLength'] - $bodyLength);
-                               $line = $remoteFile->read($chunkLength);
-                       }
-                       else if (!$inHeader && (!isset($this->replyHeaders['transfer-encoding']) || !$chunkedTransferRegex->match(end($this->replyHeaders['transfer-encoding'])))) {
-                               $length = 1024;
-                               if (isset($this->options['maxLength'])) $length = min($length, $this->options['maxLength'] - $bodyLength);
-                               if (isset($this->replyHeaders['content-length'])) $length = min($length, end($this->replyHeaders['content-length']) - $bodyLength);
-                               
-                               $line = $remoteFile->read($length);
-                       }
-                       else {
-                               $line = $remoteFile->gets();
-                       }
-                       
-                       if ($inHeader) {
-                               if (rtrim($line) === '') {
-                                       $inHeader = false;
-                                       $this->parseReplyHeaders();
-                                       
-                                       continue;
-                               }
-                               $this->replyHeaders[] = $line;
-                       }
-                       else {
-                               if (isset($this->replyHeaders['transfer-encoding']) && $chunkedTransferRegex->match(end($this->replyHeaders['transfer-encoding']))) {
-                                       // last chunk finished
-                                       if ($chunkLength === 0) {
-                                               // read hex data and trash chunk-extension
-                                               list($hex) = explode(';', $line, 2);
-                                               $chunkLength = hexdec($hex);
-                                               
-                                               // $chunkLength === 0 -> no more data
-                                               if ($chunkLength === 0) {
-                                                       // clear remaining response
-                                                       while (!$remoteFile->gets(1024));
-                                                       
-                                                       // remove chunked from transfer-encoding
-                                                       $this->replyHeaders['transfer-encoding'] = array_filter(array_map(function ($element) use ($chunkedTransferRegex) {
-                                                               return $chunkedTransferRegex->replace($element, '');
-                                                       }, $this->replyHeaders['transfer-encoding']), 'trim');
-                                                       if (empty($this->replyHeaders['transfer-encoding'])) unset($this->replyHeaders['transfer-encoding']);
-                                                       
-                                                       // break out of main reading loop
-                                                       break;
-                                               }
-                                       }
-                                       else {
-                                               $this->replyBody .= $line;
-                                               $chunkLength -= strlen($line);
-                                               $bodyLength += strlen($line);
-                                               if ($chunkLength === 0) $remoteFile->read(2); // CRLF
-                                       }
-                               }
-                               else {
-                                       $this->replyBody .= $line;
-                                       $bodyLength += strlen($line);
-                               }
-                       }
+               $headers = [];
+               foreach ($this->headers as $name => $values) {
+                       $headers[$name] = implode(', ', $values);
                }
                
-               if (isset($this->options['maxLength'])) $this->replyBody = substr($this->replyBody, 0, $this->options['maxLength']);
-               
-               $remoteFile->close();
-               
-               $this->parseReply();
-       }
-       
-       /**
-        * Parses the reply headers.
-        */
-       private function parseReplyHeaders() {
-               $statusLine = array_shift($this->replyHeaders);
+               $request = new Request($this->options['method'], $this->url, $headers, $this->body);
                
-               // get status code
-               $regex = new Regex('^HTTP/1.\d+\s+(\d{3})');
-               if (!$regex->match($statusLine)) throw new HTTPException($this, "Unexpected status '".$statusLine."'");
-               $matches = $regex->getMatches();
-               $this->statusCode = $matches[1];
-               
-               $headers = [];
-               $lastKey = '';
-               foreach ($this->replyHeaders as $header) {
-                       if (strpos($header, ':') === false) {
-                               $headers[trim($header)] = [trim($header)];
-                               continue;
-                       }
-                       
-                       // 4.2 Header fields can be
-                       // extended over multiple lines by preceding each extra line with at
-                       // least one SP or HT.
-                       if (ltrim($header, "\t ") !== $header) {
-                               $headers[$lastKey][] = array_pop($headers[$lastKey]).' '.trim($header);
-                       }
-                       else {
-                               list($key, $value) = explode(':', $header, 2);
-                               
-                               $lastKey = $key;
-                               if (!isset($headers[$key])) $headers[$key] = [];
-                               $headers[$key][] = trim($value);
-                       }
+               try {
+                       $this->response = $client->send($request, [
+                               // https://github.com/guzzle/guzzle/issues/2735
+                               'sink' => \GuzzleHttp\Psr7\stream_for(fopen("php://temp", "w+")),
+                       ]);
                }
-               // 4.2 Field names are case-insensitive.
-               $this->replyHeaders = array_change_key_case($headers);
-               if (isset($this->replyHeaders['transfer-encoding'])) $this->replyHeaders['transfer-encoding'] = [implode(',', $this->replyHeaders['transfer-encoding'])];
-               $this->legacyHeaders = array_map(function ($item) {
-                       return end($item);
-               }, $headers);
-       }
-       
-       /**
-        * Parses the reply.
-        */
-       private function parseReply() {
-               // 4.4 Messages MUST NOT include both a Content-Length header field and a
-               // non-identity transfer-coding. If the message does include a non-
-               // identity transfer-coding, the Content-Length MUST be ignored.
-               if (isset($this->replyHeaders['content-length']) && (!isset($this->replyHeaders['transfer-encoding']) || strtolower(end($this->replyHeaders['transfer-encoding'])) !== 'identity') && !isset($this->options['maxLength'])) {
-                       if (strlen($this->replyBody) != end($this->replyHeaders['content-length'])) {
-                               throw new HTTPException($this, 'Body length does not match length given in header');
-                       }
+               catch (TooManyRedirectsException $e) {
+                       throw new HTTPException(
+                               $this,
+                               "Received status code '".$this->response->getStatusCode()."' from server, but recursion level is exhausted",
+                               $this->response->getStatusCode(),
+                               $e
+                       );
                }
-               
-               // validate status code
-               switch ($this->statusCode) {
-                       case '301':
-                       case '302':
-                       case '303':
-                       case '307':
-                               // redirect
-                               if ($this->options['maxDepth'] <= 0) {
-                                       throw new HTTPException(
-                                               $this,
-                                               "Received status code '".$this->statusCode."' from server, but recursion level is exhausted",
-                                               $this->statusCode
-                                       );
-                               }
-                               
-                               $newRequest = clone $this;
-                               $newRequest->options['maxDepth']--;
-                               
-                               // 10.3.4 The response to the request can be found under a different URI and SHOULD
-                               // be retrieved using a GET method on that resource.
-                               if ($this->statusCode == '303') {
-                                       $newRequest->options['method'] = 'GET';
-                                       $newRequest->postParameters = [];
-                                       $newRequest->addHeader('content-length', '');
-                                       $newRequest->addHeader('content-type', '');
-                               }
-                               
-                               try {
-                                       $newRequest->setURL(end($this->replyHeaders['location']));
-                               }
-                               catch (SystemException $e) {
-                                       throw new HTTPException(
-                                               $this,
-                                               "Received 'Location: ".end($this->replyHeaders['location'])."' from server, which is invalid.",
-                                               0,
-                                               $e
-                                       );
-                               }
-                               
-                               try {
-                                       $newRequest->execute();
-                               }
-                               finally {
-                                       // update data with data from the inner request
-                                       $this->url = $newRequest->url;
-                                       $this->statusCode = $newRequest->statusCode;
-                                       $this->replyHeaders = $newRequest->replyHeaders;
-                                       $this->legacyHeaders = $newRequest->legacyHeaders;
-                                       $this->replyBody = $newRequest->replyBody;
-                               }
-                               
-                               return;
-                       break;
+               catch (BadResponseException $e) {
+                       $this->response = $e->getResponse();
                        
-                       case '206':
-                               // check, if partial content was expected
-                               if (!isset($this->headers['range'])) {
-                                       throw new HTTPServerErrorException(
-                                               "Received unexpected status code '206' from server",
+                       switch ($this->response->getStatusCode()) {
+                               case '401':
+                               case '402':
+                               case '403':
+                                       throw new HTTPUnauthorizedException(
+                                               "Received status code '".$this->response->getStatusCode()."' from server",
                                                0,
                                                '',
                                                new HTTPException(
-                                                       $this, 
-                                                       'Received partial response, without sending a range header', 
-                                                       206
+                                                       $this,
+                                                       "Received status code '".$this->response->getStatusCode()."' from server",
+                                                       (string) $this->response->getStatusCode(),
+                                                       $e
                                                )
                                        );
-                               }
-                               else if (!isset($this->replyHeaders['content-range'])) {
-                                       throw new HTTPServerErrorException(
-                                               "Content-Range is missing in reply header",
+                               case '404':
+                                       throw new HTTPNotFoundException(
+                                               "Received status code '404' from server",
                                                0,
                                                '',
                                                new HTTPException(
                                                        $this,
-                                                       'Server replied with 206 Partial Content, without sending a Content-Range header', 
-                                                       206
+                                                       "Received status code '".$this->response->getStatusCode()."' from server",
+                                                       (string) $this->response->getStatusCode(),
+                                                       $e
                                                )
                                        );
-                               }
-                       break;
-                       
-                       case '401':
-                       case '402':
-                       case '403':
-                               throw new HTTPUnauthorizedException(
-                                       "Received status code '".$this->statusCode."' from server",
-                                       0,
-                                       '',
-                                       new HTTPException(
-                                               $this,
-                                               "Received status code '".$this->statusCode."' from server",
-                                               $this->statusCode
-                                       )
-                               );
-                       break;
-                       
-                       case '404':
-                               throw new HTTPNotFoundException(
-                                       "Received status code '404' from server",
-                                       0,
-                                       '',
-                                       new HTTPException(
-                                               $this,
-                                               "Received status code '".$this->statusCode."' from server",
-                                               $this->statusCode
-                                       )
-                               );
-                       break;
-                       
-                       default:
-                               // 6.1.1 However, applications MUST
-                               // understand the class of any status code, as indicated by the first
-                               // digit, and treat any unrecognized response as being equivalent to the
-                               // x00 status code of that class, with the exception that an
-                               // unrecognized response MUST NOT be cached.
-                               switch (substr($this->statusCode, 0, 1)) {
-                                       case '2': // 200 and unknown 2XX
-                                       case '3': // 300 and unknown 3XX
-                                               // we are fine
-                                       break;
-                                       case '5': // 500 and unknown 5XX
+                               default:
+                                       if (substr($this->response->getStatusCode(), 0, 1) == '5') {
                                                throw new HTTPServerErrorException(
-                                                       "Received status code '".$this->statusCode."' from server",
+                                                       "Received status code '".$this->response->getStatusCode()."' from server",
                                                        0,
                                                        '',
                                                        new HTTPException(
                                                                $this,
-                                                               "Received status code '".$this->statusCode."' from server",
-                                                               $this->statusCode
+                                                               "Received status code '".$this->response->getStatusCode()."' from server",
+                                                               (string) $this->response->getStatusCode(),
+                                                               $e
                                                        )
                                                );
-                                       break;
-                                       default:
-                                               throw new HTTPException(
-                                                       $this,
-                                                       "Received unhandled status code '".$this->statusCode."' from server",
-                                                       $this->statusCode
-                                               );
-                                       break;
-                               }
-                       break;
+                                       }
+                       }
+               }
+               catch (TransferException $e) {
+                       throw new SystemException('Failed to HTTPRequest', 0, '', $e);
                }
        }
        
@@ -597,12 +265,57 @@ final class HTTPRequest {
         * @return      array
         */
        public function getReply() {
+               if (!$this->response) {
+                       return [
+                               'statusCode' => 0,
+                               'headers' => [],
+                               'httpHeaders' => [],
+                               'body' => '',
+                               'url' => $this->url
+                       ];
+               }
+
+               $headers = [];
+               $legacyHeaders = [];
+               
+               foreach ($this->response->getHeaders() as $name => $values) {
+                       $headers[strtolower($name)] = $values;
+                       $legacyHeaders[$name] = end($values);
+               }
+               
+               if ($this->replyBody === null) {
+                       try {
+                               $bodyLength = 0;
+                               while (!$this->response->getBody()->eof()) {
+                                       $toRead = 8192;
+                                       if (isset($this->options['maxLength'])) {
+                                               $toRead = min($toRead, $this->options['maxLength'] - $bodyLength);
+                                       }
+                                       
+                                       $data = $this->response->getBody()->read($toRead);
+                                       $this->replyBody .= $data;
+                                       $bodyLength += strlen($data);
+                                       
+                                       if (isset($this->options['maxLength']) && $bodyLength >= $this->options['maxLength']) {
+                                               break;
+                                       }
+                               }       
+                       }
+                       finally {
+                               $this->response->getBody()->close();
+                       }
+                       
+                       if (isset($this->options['maxLength'])) {
+                               $this->replyBody = substr($this->replyBody, 0, $this->options['maxLength']);
+                       }
+               }
+               
                return [
-                       'statusCode' => $this->statusCode
-                       'headers' => $this->legacyHeaders,
-                       'httpHeaders' => $this->replyHeaders,
+                       'statusCode' => (string) $this->response->getStatusCode()
+                       'headers' => $legacyHeaders,
+                       'httpHeaders' => $headers,
                        'body' => $this->replyBody,
-                       'url' => $this->url
+                       'url' => $this->url,
                ];
        }
        
@@ -667,8 +380,6 @@ final class HTTPRequest {
         * Resets reply data when cloning.
         */
        private function __clone() {
-               $this->replyHeaders = [];
-               $this->replyBody = '';
-               $this->statusCode = 0;
+               $this->response = null;
        }
 }
index 602cdea7dec7d2ca6ed1a3246ff835b2c7727c9e..51dd03b3f33b97fedd87f79395874873dda89aaf 100644 (file)
@@ -115,6 +115,9 @@ final class ImageUtil {
                        $filename = FileUtil::getTemporaryFilename();
                        $thumbnail = $adapter->createThumbnail($maxWidth, $maxHeight, $obtainDimensions);
                        $adapter->writeImage($thumbnail, $filename);
+                       // Clear thumbnail as soon as possible to free up the memory.
+                       // This is technically useless, but done for consistency.
+                       $thumbnail = null;
                }
                
                return $filename;
index a66b0b6a454eb76deb8a098ccd51871f56b74f88..cde876f57a07f1e76a450c4bdd5f6fabfc9d53a5 100644 (file)
@@ -40,11 +40,74 @@ class MessageUtil {
                return $text;
        }
        
+       /**
+        * Returns the mentioned users in the given text.
+        *
+        * @param       HtmlInputProcessor      $htmlInputProcessor     html input processor instance
+        * @return      int[]                   ids of the mentioned users
+        * @since       5.3
+        */
+       public static function getMentionedUserIDs(HtmlInputProcessor $htmlInputProcessor) {
+               $userIDs = [];
+               $groups = [];
+               
+               $elements = $htmlInputProcessor->getHtmlInputNodeProcessor()->getDocument()->getElementsByTagName('woltlab-metacode');
+               /** @var \DOMElement $element */
+               foreach ($elements as $element) {
+                       $type = $element->getAttribute('data-name');
+                       if ($type !== 'user' && $type !== 'group') {
+                               continue;
+                       }
+                       
+                       if (DOMUtil::hasParent($element, 'woltlab-quote')) {
+                               // ignore mentions within quotes
+                               continue;
+                       }
+                       
+                       $attributes = $htmlInputProcessor->getHtmlInputNodeProcessor()->parseAttributes(
+                               $element->getAttribute('data-attributes')
+                       );
+                       
+                       if ($type === 'user') {
+                               if (!empty($attributes[0])) {
+                                       $userIDs[] = $attributes[0];
+                               }
+                       }
+                       else if ($type === 'group' && WCF::getSession()->getPermission('user.message.canMentionGroups')) {
+                               if (!empty($attributes[0])) {
+                                       $group = UserGroup::getGroupByID($attributes[0]);
+                                       if ($group !== null && $group->canBeMentioned() && !isset($groups[$group->groupID])) {
+                                               $groups[$group->groupID] = $group;
+                                       }
+                               }
+                       }
+               }
+               
+               $userIDs = array_unique($userIDs);
+               if (!empty($groups)) {
+                       $conditions = new PreparedStatementConditionBuilder();
+                       $conditions->add('groupID IN (?)', [array_keys($groups)]);
+                       if (!empty($userIDs)) $conditions->add('userID NOT IN (?)', [$userIDs]);
+                       
+                       $sql = "SELECT  userID
+                               FROM    wcf".WCF_N."_user_to_group
+                               ".$conditions;
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute($conditions->getParameters());
+                       while ($userID = $statement->fetchColumn()) {
+                               $userIDs[] = $userID;
+                       }
+               }
+               
+               return $userIDs;
+       }
+       
        /**
         * Returns the mentioned users in the given text.
         * 
         * @param       HtmlInputProcessor      $htmlInputProcessor     html input processor instance
         * @return      string[]                mentioned usernames
+        * @deprecated  5.3
         */
        public static function getMentionedUsers(HtmlInputProcessor $htmlInputProcessor) {
                $usernames = [];
index 1ac373c7826e29411e222d40c990077c831e41ea..806712476ebadf1b8fbc25c525da7b167c6ad69e 100644 (file)
@@ -30,6 +30,7 @@ final class PasswordUtil {
         * @var string[]
         */
        private static $supportedEncryptionTypes = [
+               'argon2',       // vBulletin 5.x
                'ipb2',         // Invision Power Board 2.x
                'ipb3',         // Invision Power Board 3.x
                'mybb1',        // MyBB 1.x
@@ -271,6 +272,19 @@ final class PasswordUtil {
                return '$' . self::BCRYPT_TYPE . '$' . self::BCRYPT_COST . '$' . $salt;
        }
        
+       /**
+        * Validates the password hash for Argon2 (argon2).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function argon2($username, $password, $salt, $dbHash) {
+               return password_verify($password, $dbHash);
+       }
+       
        /**
         * Validates the password hash for Invision Power Board 2.x (ipb2).
         * 
@@ -318,8 +332,117 @@ final class PasswordUtil {
         * @param       string          $dbHash
         * @return      boolean
         */
-       protected static function phpbb3($username, $password, $salt, $dbHash) {
-               return self::phpass($username, $password, $salt, $dbHash);
+       public static function phpbb3($username, $password, $salt, $dbHash) {
+               $phpassResult = self::phpass($username, $password, $salt, $dbHash);
+               
+               if ($phpassResult) {
+                       return true;
+               }
+               
+               if (!preg_match('/^\$([^$]+)\$/', $dbHash, $matches)) {
+                       return false;
+               }
+               
+               $algorithms = explode('\\', $matches[1]);
+               // Strip the type prefix.
+               $dbHash = substr($dbHash, strlen($matches[0]));
+               
+               // The following loop only supports the multi-hash variant.
+               // Everything else should already be handled at this point.
+               if (count($algorithms) == 1) {
+                       return false;
+               }
+               foreach ($algorithms as $algorithm) {
+                       $dollar = strpos($dbHash, '$');
+                       if ($dollar === false) {
+                               return false;
+                       }
+                       $settings = '$'.$algorithm.'$'.str_replace('\\', '$', substr($dbHash, 0, $dollar));
+                       $dbHash = substr($dbHash, $dollar + 1);
+                       
+                       switch ($algorithm) {
+                               case 'H':
+                               case 'P':
+                                       $password = str_replace($settings, '', self::phpass_hash_crypt_private($password, $settings));
+                               break;
+                               case '2a':
+                               case '2y':
+                                       $password = str_replace($settings, '', self::getSaltedHash($password, $settings));
+                               break;
+                       }
+               }
+               
+               return \hash_equals($dbHash, $password);
+       }
+       
+       private static function phpass_hash_crypt_private($password, $setting) {
+               static $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+               
+               $output = '*';
+               
+               // Check for correct hash
+               if (substr($setting, 0, 3) !== '$H$' && substr($setting, 0, 3) !== '$P$') {
+                       return $output;
+               }
+               
+               $count_log2 = strpos($itoa64, $setting[3]);
+               
+               if ($count_log2 < 7 || $count_log2 > 30) {
+                       return $output;
+               }
+               
+               $count = 1 << $count_log2;
+               $salt = substr($setting, 4, 8);
+               
+               if (strlen($salt) != 8) {
+                       return $output;
+               }
+               
+               $hash = md5($salt . $password, true);
+               do {
+                       $hash = md5($hash . $password, true);
+               }
+               while (--$count);
+               
+               $output = substr($setting, 0, 12);
+               $hash_encode64 = function ($input, $count, &$itoa64) {
+                       $output = '';
+                       $i = 0;
+                       
+                       do {
+                               $value = ord($input[$i++]);
+                               $output .= $itoa64[$value & 0x3f];
+                               
+                               if ($i < $count) {
+                                       $value |= ord($input[$i]) << 8;
+                               }
+                               
+                               $output .= $itoa64[($value >> 6) & 0x3f];
+                               
+                               if ($i++ >= $count) {
+                                       break;
+                               }
+                               
+                               if ($i < $count) {
+                                       $value |= ord($input[$i]) << 16;
+                               }
+                               
+                               $output .= $itoa64[($value >> 12) & 0x3f];
+                               
+                               if ($i++ >= $count) {
+                                       break;
+                               }
+                               
+                               $output .= $itoa64[($value >> 18) & 0x3f];
+                       }
+                       while ($i < $count);
+                       
+                       return $output;
+               };
+               
+               $output .= $hash_encode64($hash, 16, $itoa64);
+               
+               return $output;
        }
        
        /**
@@ -336,77 +459,7 @@ final class PasswordUtil {
                        return \hash_equals(md5($password), $dbHash);
                }
                
-               $hash_crypt_private = function ($password, $setting) {
-                       static $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-                       
-                       $output = '*';
-                       
-                       // Check for correct hash
-                       if (substr($setting, 0, 3) !== '$H$' && substr($setting, 0, 3) !== '$P$') {
-                               return $output;
-                       }
-                       
-                       $count_log2 = strpos($itoa64, $setting[3]);
-                       
-                       if ($count_log2 < 7 || $count_log2 > 30) {
-                               return $output;
-                       }
-                       
-                       $count = 1 << $count_log2;
-                       $salt = substr($setting, 4, 8);
-                       
-                       if (strlen($salt) != 8) {
-                               return $output;
-                       }
-                       
-                       $hash = md5($salt . $password, true);
-                       do {
-                               $hash = md5($hash . $password, true);
-                       }
-                       while (--$count);
-                       
-                       $output = substr($setting, 0, 12);
-                       $hash_encode64 = function ($input, $count, &$itoa64) {
-                               $output = '';
-                               $i = 0;
-                               
-                               do {
-                                       $value = ord($input[$i++]);
-                                       $output .= $itoa64[$value & 0x3f];
-                                       
-                                       if ($i < $count) {
-                                               $value |= ord($input[$i]) << 8;
-                                       }
-                                       
-                                       $output .= $itoa64[($value >> 6) & 0x3f];
-                                       
-                                       if ($i++ >= $count) {
-                                               break;
-                                       }
-                                       
-                                       if ($i < $count) {
-                                               $value |= ord($input[$i]) << 16;
-                                       }
-                                       
-                                       $output .= $itoa64[($value >> 12) & 0x3f];
-                                       
-                                       if ($i++ >= $count) {
-                                               break;
-                                       }
-                                       
-                                       $output .= $itoa64[($value >> 18) & 0x3f];
-                               }
-                               while ($i < $count);
-                               
-                               return $output;
-                       };
-                       
-                       $output .= $hash_encode64($hash, 16, $itoa64);
-                       
-                       return $output;
-               };
-               
-               return \hash_equals($hash_crypt_private($password, $dbHash), $dbHash);
+               return \hash_equals(self::phpass_hash_crypt_private($password, $dbHash), $dbHash);
        }
        
        /**
index 10e187e60c22065243565e990d533bbf7e4db3b5..192783c3277112eb7d0af42cc7e8ae4551ec7330 100644 (file)
@@ -667,17 +667,12 @@ final class StringUtil {
         * @param       string          $url
         * @param       string          $title
         * @param       boolean         $encodeTitle
+        * @param       boolean         $isUgc          true to add rel=ugc to the anchor tag 
         * @return      string          anchor tag
         */
-       public static function getAnchorTag($url, $title = '', $encodeTitle = true) {
+       public static function getAnchorTag($url, $title = '', $encodeTitle = true, $isUgc = false) {
                $url = self::trim($url);
                
-               $external = true;
-               if (ApplicationHandler::getInstance()->isInternalURL($url)) {
-                       $external = false;
-                       $url = preg_replace('~^https?://~', RouteHandler::getProtocol(), $url);
-               }
-               
                // cut visible url
                if (empty($title)) {
                        // use URL and remove protocol and www subdomain
@@ -690,7 +685,40 @@ final class StringUtil {
                        if (!$encodeTitle) $title = self::encodeHTML($title);
                }
                
-               return '<a href="'.self::encodeHTML($url).'"'.($external ? (' class="externalURL"'.((EXTERNAL_LINK_REL_NOFOLLOW || EXTERNAL_LINK_TARGET_BLANK) ? (' rel="'.(EXTERNAL_LINK_REL_NOFOLLOW ? 'nofollow' : '').((EXTERNAL_LINK_REL_NOFOLLOW && EXTERNAL_LINK_TARGET_BLANK) ? ' ' : '').(EXTERNAL_LINK_TARGET_BLANK ? 'noopener noreferrer' : '').'"') : '').(EXTERNAL_LINK_TARGET_BLANK ? ' target="_blank"' : '')) : '').'>'.($encodeTitle ? self::encodeHTML($title) : $title).'</a>';
+               return '<a '. self::getAnchorTagAttributes($url, $isUgc) .'>' . ($encodeTitle ? self::encodeHTML($title) : $title) . '</a>';
+       }
+       
+       /**
+        * Generates the attributes for an anchor tag from given URL.
+        *
+        * @param       string          $url
+        * @param       boolean         $isUgc          true to add rel=ugc to the attributes
+        * @return      string          attributes
+        * @since       5.3
+        */
+       public static function getAnchorTagAttributes($url, $isUgc = false) {
+               $external = true;
+               if (ApplicationHandler::getInstance()->isInternalURL($url)) {
+                       $external = false;
+                       $url = preg_replace('~^https?://~', RouteHandler::getProtocol(), $url);
+               }
+               
+               $attributes = 'href="' . self::encodeHTML($url) . '"';
+               if ($external) {
+                       $attributes .= ' class="externalURL"';
+                       $rel = 'nofollow';
+                       if (EXTERNAL_LINK_TARGET_BLANK) {
+                               $rel .= ' noopener noreferrer';
+                               $attributes .= 'target="_blank"';
+                       }
+                       if ($isUgc) {
+                               $rel .= ' ugc';
+                       }
+                       
+                       $attributes .= ' rel="' . $rel . '"';
+               }
+               
+               return $attributes;
        }
        
        /**
index 120503561627eb08e0fd3167da968b3d85269d8b..f0ab7f805286cd93d16f1fa7b60f84738fd3654f 100644 (file)
@@ -69,21 +69,11 @@ final class UserRegistrationUtil {
        }
        
        /**
-        * Returns true if the given password is secure.
+        * Always returns true.
         * 
-        * @param       string          $password
-        * @return      boolean
+        * @deprecated  5.3 - Take a look at the zxcvbn verdict from WoltLabSuite/Core/Ui/User/PasswordStrength.
         */
        public static function isSecurePassword($password) {
-               if (REGISTER_ENABLE_PASSWORD_SECURITY_CHECK) {
-                       if (mb_strlen($password) < REGISTER_PASSWORD_MIN_LENGTH) return false;
-                       
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_DIGIT && !preg_match('![0-9]+!', $password)) return false;
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE && !preg_match('![a-z]+!', $password)) return false;
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE && !preg_match('![A-Z]+!', $password)) return false;
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR && !preg_match('![^A-Za-z0-9]+!', $password)) return false;
-               }
-               
                return true;
        }
        
@@ -94,34 +84,7 @@ final class UserRegistrationUtil {
         * @return      string
         */
        public static function getPasswordRulesAttributeValue() {
-               if (REGISTER_ENABLE_PASSWORD_SECURITY_CHECK) {
-                       $rules = '';
-                       
-                       if (REGISTER_PASSWORD_MIN_LENGTH) {
-                               $rules .= 'minlength:'.REGISTER_PASSWORD_MIN_LENGTH.';';
-                       }
-                       
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_DIGIT) {
-                               $rules .= 'required:digit;';
-                       }
-                       
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE) {
-                               $rules .= 'required:lower;';
-                       }
-                       
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE) {
-                               $rules .= 'required:upper;';
-                       }
-                       
-                       if (REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR) {
-                               $rules .= 'required:special;';
-                       }
-               }
-               else {
-                       $rules = "minlength:8;";
-               }
-               
-               return $rules;
+               return "minlength:8;";
        }
        
        /**
index 0efd4ae341723f49fbe1527323a0464657db93f7..1a68f868dad9d581e67ab3ff2b8e1214eede5e07 100644 (file)
@@ -13,6 +13,7 @@ use wcf\util\StringUtil;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\Util\Exception
  * @since      3.0
+ * @deprecated 5.3 This exception is intimately tied to HTTPRequest which is deprecated.
  */
 class HTTPException extends SystemException implements IExtraInformationException {
        /**
index 444f8245601c5e2ecabceccec231024c55b13936..de100f59114422923c88d1c94b78fd2822badeea 100644 (file)
@@ -10,7 +10,7 @@
 
 define('LAST_UPDATE_TIME', TIME_NOW);
 
-$prefix = 'wsc52_';
+$prefix = 'wsc_';
 if (file_exists(WCF_DIR . 'cookiePrefix.txt')) {
        // randomized cookie prefix during setup
        $prefix = file_get_contents(WCF_DIR . 'cookiePrefix.txt');
index e1db536a4209b54cf71f68f21ab5e9cbc83535df..f2bd7fbf8fc356f13392d19451f6ac98ee1a610b 100644 (file)
        border-radius: 2px;
        clear: both;
        margin: 1em 0;
-       overflow: hidden;
        padding: 10px;
        position: relative;
        
        &.collapsed {
-               max-height: 200px;
+               .codeBoxCode {
+                       max-height: 200px;
+                       overflow: hidden;
+               }
                
                > .toggleButton {
                        bottom: 0;
-                       box-shadow: 0 -10px 50px 10px opacify($wcfContentBackground, .9);
                        left: 0;
                        padding-bottom: 10px;
                        position: absolute;
                        right: 0;
                        z-index: 1;
+                       
+                       &::before {
+                               background-image: linear-gradient(to top, opacify($wcfContentBackground, .9), transparentize($wcfContentBackground, 1));
+                               content: "";
+                               height: 60px;
+                               left: 0;
+                               pointer-events: none;
+                               position: absolute;
+                               right: 0;
+                               top: -60px;
+                       }
                }
        }
        
-       > div {
-               > .codeBoxHeader {
-                       align-items: center;
-                       display: flex;
-                       
-                       /* required to avoid layout jumping caused by the dynamically added 24px button */
-                       min-height: 24px;
+       .codeBoxHeader {
+               position: sticky;
+               top: 50px;
+               z-index: 1;
+               padding: 10px 10px 10px;
+               margin: -10px -10px 0;
+               background-color: $wcfContentBackground;
+               
+               align-items: center;
+               display: flex;
+               
+               /* required to avoid layout jumping caused by the dynamically added 24px button */
+               min-height: 24px;
+               
+               > .codeBoxHeadline {
+                       flex: 1 1 auto;
+                       padding: 0 10px;
                        
-                       > .codeBoxHeadline {
-                               flex: 1 1 auto;
-                               padding: 0 10px;
-                               
-                               @include wcfFontHeadline;
+                       @include wcfFontHeadline;
+
+                       @include screen-sm-down {
+                               overflow: auto;
+                               white-space: nowrap;
                        }
                }
+
+               .icon {
+                       flex: 0 0 auto;
+               }
+       }
+       
+       .codeBoxCode {
+               position: relative;
+               padding-left: 7ch;
                
-               > .codeBoxCode {
-                       padding-left: 7ch;
+               > code {
+                       display: block;
+                       overflow-x: auto;
+                       font-family: Consolas, 'Courier New', monospace;
                        
-                       > code {
+                       .codeBoxLine {
                                display: block;
-                               overflow-x: auto;
-                               font-family: Consolas, 'Courier New', monospace;
                                
-                               .codeBoxLine {
-                                       > a {
-                                               margin-left: -7ch;
-                                               overflow: hidden;
-                                               position: absolute;
-                                               text-align: right;
-                                               text-overflow: ellipsis;
-                                               white-space: nowrap;
-                                               /* No one has line numbers greater than 999999 */
-                                               width: 6ch;
-               
-                                               &::before {
-                                                       content: attr(title);
-                                               }
-                                       }
-                                       
-                                       > span {
-                                               white-space: pre-wrap;
-                                               word-break: break-all;
-                                       }
-                                       
-                                       &:target {
-                                               background-color: rgba(255, 255, 102, 1);
+                               > a {
+                                       margin-left: -7ch;
+                                       overflow: hidden;
+                                       position: absolute;
+                                       text-align: right;
+                                       text-overflow: ellipsis;
+                                       white-space: nowrap;
+                                       /* No one has line numbers greater than 999999 */
+                                       width: 6ch;
+       
+                                       &::before {
+                                               content: attr(title);
                                        }
                                }
+                               
+                               > span {
+                                       white-space: pre-wrap;
+                                       word-break: break-all;
+                               }
+                               
+                               &:target {
+                                       background-color: rgba(255, 255, 102, 1);
+                               }
                        }
                }
        }
        }
 }
 
+.anchorFixedHeader:not(.disableAnchorFixedHeader):target .codeBoxHeader {
+       top: -30px; /* see wsc31.scss */
+}
+
+.dialogContent .codeBox .codeBoxHeader {
+       /* Prevent the header being sticky inside dialogs, which doesn't really work.  */
+       position: static;
+}
+
 
 /* PrismJS 1.15.0
 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=autoloader */
@@ -201,7 +239,7 @@ https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javasc
  
  .token.important,
  .token.bold {
-        font-weight: bold;
+        font-weight: 600;
  }
  .token.italic {
         font-style: italic;
@@ -210,4 +248,4 @@ https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javasc
  .token.entity {
         cursor: help;
  }
\ No newline at end of file
index 7e34235116316adbfbfc1b0b927674adaeadd9d2..ee887dcd6d2607bd8e3d5d3263f3b81c61dd5db8 100644 (file)
@@ -25,6 +25,13 @@ kbd {
        vertical-align: middle;
        word-break: break-all;
        word-wrap: break-word;
+       
+       @include screen-sm-down {
+               /* Reduce the padding to prevent pixel rounding errors in the font rendering that
+                  can cause the page to display a horizontal scrollbar when <kbd> appears at the
+                  edge of the content container. */
+               padding: 0 3px;
+       }
 }
 
 @supports (-webkit-overflow-scrolling: touch) {
index 35e7c241a4e510ac3e9b016a9d9473b8785728f3..20cde765c3ac4dd097b9a20dfe29c3e103bad239 100644 (file)
@@ -1,14 +1,26 @@
 .mediaBBCode {
-       display: inline-block;
+       display: inline-table;
        max-width: 100%;
        
        .mediaBBCodeCaption {
                color: $wcfContentDimmedText;
-               display: block;
+               // https://stackoverflow.com/a/11652170/782822
+               display: table-caption;
+               caption-side: bottom;
                margin-top: 5px;
                text-align: center;
                
                @include wcfFontSmall;
+               
+               .mediaBBCodeCaptionAlignment {
+                       // https://stackoverflow.com/a/43627669/782822
+                       display: inline-block;
+                       text-align: justify;
+               }
+       }
+       
+       video {
+               max-width: 100%;
        }
 }
 
index 95da242ba9d1a7eabcf7a6840a3badafe7bc0aba..60bce55ea2558b65fa78c88a1f4ec7a73c06eb05 100644 (file)
@@ -1,11 +1,11 @@
 /* do NOT reference fonts directly, always make use of 'getFont.php' */
 @font-face {
        font-family: 'FontAwesome';
-       src: url('../font/getFont.php?type=eot&v=4.7.0');
-       src: url('../font/getFont.php?type=eot&v=4.7.0#iefix') format('embedded-opentype'),
-       url('../font/getFont.php?type=woff2&v=4.7.0') format('woff2'),
-       url('../font/getFont.php?type=woff&v=4.7.0') format('woff'),
-       url('../font/getFont.php?type=ttf&v=4.7.0') format('truetype');
+       src: url(getFont('fontawesome-webfont.eot', '', '4.7.0'));
+       src: url(getFont('fontawesome-webfont.eot', '', '4.7.0') + "#iefix") format('embedded-opentype'),
+       url(getFont('fontawesome-webfont.woff2', '', '4.7.0')) format('woff2'),
+       url(getFont('fontawesome-webfont.woff', '', '4.7.0')) format('woff'),
+       url(getFont('fontawesome-webfont.ttf', '', '4.7.0')) format('truetype');
        font-weight: normal;
        font-style: normal;
 }
index da6b60e3e01059a534c92c445cdd34c59d4d2302..beaa0688c36902a5629de371a5e97d64813f7313 100644 (file)
        padding-right: 10px;
 }
 
-@include screen-xs {
+/* collapsible sidebar for mobile devices */
+@include screen-md-down {
        .main > .layoutBoundary {
                display: flex;
                flex-wrap: wrap;
index 604d2079054c7980e318174ad4cd8fc073a77f02..ef1556a542691e185ee34c32481d1bb90c663895 100644 (file)
@@ -67,6 +67,7 @@
                .contentHeaderNavigation > ul {
                        @include inlineList;
                        
+                       align-items: flex-start;
                        justify-content: flex-end;
                        margin-top: 20px;
                }
@@ -93,6 +94,7 @@
                        > ul {
                                @include inlineList;
                                
+                               align-items: flex-start;
                                flex-wrap: wrap;
                                justify-content: flex-end;
                                margin-top: -5px;
index 29dc64b66c5d161e28c091e5b86d5779f87e9c84..56923a614a3566a124b4bbceba11416f52be0391 100644 (file)
@@ -279,6 +279,70 @@ input {
        }
 }
 
+.formFieldRequired,
 .customOptionRequired {
        color: rgba(204, 0, 1, 1) !important;
 }
+
+/* password strength estimator */
+.inputAddonPasswordStrength {
+       align-items: flex-start;
+       
+       @include screen-xs {
+               flex-direction: column;
+       }
+}
+
+.passwordStrengthRating {
+       flex: 0 0 auto;
+       
+       @include screen-sm-up {
+               margin-left: 10px;
+       }
+       
+       @include screen-xs {
+               margin-top: 5px;
+               width: 100%;
+       }
+}
+
+.passwordStrengthScore {
+       background-color: rgb(224, 224, 224);
+       border-radius: 3px;
+       display: block;
+       height: 10px;
+       overflow: hidden;
+       position: relative;
+       
+       &::before {
+               background-color: transparent;
+               bottom: 0;
+               content: "";
+               left: 0;
+               position: absolute;
+               top: 0;
+               transition: background-color .12s linear, width .12s linear;
+               width: 0;
+       }
+       
+       &[data-score="0"]::before {
+               background-color: #DD2C00;
+               width: 5%;
+       }
+       &[data-score="1"]::before {
+               background-color: #FF9100;
+               width: 20%;
+       }
+       &[data-score="2"]::before {
+               background-color: #CDDC39;
+               width: 50%;
+       }
+       &[data-score="3"]::before {
+               background-color: #64DD17;
+               width: 85%;
+       }
+       &[data-score="4"]::before {
+               background-color: #2E7D32;
+               width: 100%;
+       }
+}
index 8b22c4e6eede993b3198b1b1b972f5509d73759a..33af4821333e209ad19dde246f2a30beb2c77b70 100644 (file)
@@ -142,11 +142,6 @@ ol.nativeList {
        ol {
                list-style-type: decimal;
        }
-       
-       em {
-               /* slight margin to prevent visual merge with adjacent words */
-               margin-right: 2px;
-       }
 }
 
 .containerContent,
index 849697b983c3286dfd319717537ee6500cf1d474..712243718cbb5fb37249014afdd0bce7d6be10ec 100644 (file)
                        content: attr(data-placeholder);
                        position: relative;
                        top: 2px;
-                       
-                       @include screen-sm-up {
-                               @include wcfFontSection;
-                       }
                }
                
                > .commentListAddCommentEditorContainer {
 .commentModerationDisabledComment {
        margin: 0 -20px;
 }
+
+/* Prevent images in comments in the sidebar box from becoming too large */
+.sidebarCommentContent {
+       img {
+               max-width: 100%;
+               max-height: 300px;
+       }
+}
index e8890d35cf7fb05ab07e2f2392111549e40981cd..155e641b5b577d213768c575b9781dbe6e61e444 100644 (file)
 
 @include screen-lg {
        /* There are no sidebars, use a three column layout. */
-       .content:first-child:last-child {
+       .content:first-child:last-child,
+       .boxesTop,
+       .boxesBottom {
                .contentItemMultiColumn {
                        /* The `flex` shorthand fails in IE11 if `calc()` is used. */
                        flex-grow: 0;
index a538d280d9836d7dcb2fed1d339a76d969157145..573c0811b5cb2847d230938b393a000ed40eb51a 100644 (file)
                display: none;
        }
        
-       &.interactiveDropdownUserMenu > .interactiveDropdownItemsContainer {
-               overflow: visible;
-               max-height: none;
+       &.interactiveDropdownUserMenu {
+               > .interactiveDropdownItemsContainer {
+                       overflow: visible;
+                       max-height: none;
+                       
+                       a {
+                               color: $wcfContentLink;
+                               
+                               &:hover {
+                                       color: $wcfContentLinkActive;
+                               }
+                       }
+               }
        }
        
        @include screen-sm-md {
@@ -63,7 +73,7 @@
        background-color: $wcfSidebarBackground;
        color: $wcfSidebarHeadlineText;
        display: flex;
-       padding: 10px 20px;
+       padding: 10px;
        
        a {
                color: $wcfSidebarHeadlineLink;
 /* dropdown item list */
 .interactiveDropdownItems {
        > li {
-               padding: 15px 20px;
+               padding: 10px;
                position: relative;
                
                &:not(:last-child) {
                }
                
                a {
-                       color: $wcfContentLink;
+                       color: inherit;
                        
                        &:hover {
-                               color: $wcfContentLinkActive;
+                               color: inherit;
                        }
                }
                
+               h3 a {
+                       font-weight: 600;
+               }
+               
                .box48 {
                        align-items: center;
                        overflow: hidden;
                }
                
+               small {
+                       align-items: center;
+                       color: $wcfContentDimmedText;
+                       display: flex;
+                       margin-top: 3px;
+                       
+                       .separatorLeft {
+                               margin-left: 0.25em;
+                       }
+               }
+               
                @include screen-sm-down {
                        padding: 10px;
                }
                flex: 1 1 auto;
        }
        
-       h3 {
-               font-weight: bold;
+       small::after {
+               background-color: rgb(49, 138, 220);
+               border-radius: 50%;
+               content: "";
+               height: 8px;
+               margin-left: 5px;
+               width: 8px;
        }
 }
 
        align-self: center;
        flex: 0 0 auto;
        margin-left: 5px;
+       
+       a {
+               pointer-events: all;
+       }
 }
 
 /* Adds a link spanning the entire item while being placed behind all other links appearing
        > .interactiveDropdownItemMarkAsRead {
                pointer-events: none;
                z-index: 20;
-               
-               a {
-                       pointer-events: all;
-               }
        }
        
        > .interactiveDropdownItemShadowLink {
        background-color: $wcfSidebarBackground;
        color: $wcfSidebarHeadlineText;
        display: block;
-       padding: 10px 20px;
+       padding: 10px;
        text-align: center;
        
        &:hover {
index 2b8dc8c4b61099f0c10a7b867824f94dfa657200..15175ff8a41a6ef7818f5d8916d83fa7d281efe8 100644 (file)
@@ -3,11 +3,21 @@
        border: 1px solid $wcfContentBorderInner;
        border-radius: 3px;
        margin: 10px 0;
+       max-width: 600px;
 }
 
 .embeddedContentLink {
        display: block;
        padding: 10px;
+       position: relative;
+}
+
+.embeddedContentLinkShadow {
+       bottom: 0;
+       left: 0;
+       position: absolute;
+       right: 0;
+       top: 0;
 }
 
 .embeddedContentCategory {
@@ -32,7 +42,8 @@
        position: relative;
 }
 .embeddedContentDescription::after {
-       background-image: linear-gradient(to top, $wcfContentBackground, transparent);
+       /* Do not use `transparent` here, because of an ancient iOS rendering bug. */
+       background-image: linear-gradient(to top, $wcfContentBackground, transparentize($wcfContentBackground, 1));
        bottom: 0;
        content: "";
        left: 0;
index a8b0718c7c4d33cb89135455e22999be6addc9f3..d99114ea8e3d80975f16d6d3b9391cdafb253f89 100644 (file)
                padding: 0 !important;
        }
 }
+
+.inputItemListLimitReached {
+       color: $wcfContentDimmedText;
+       vertical-align: middle;
+       
+       /* The input field does not have a distinct appearance, making the text unselectable
+          will prevent the browser from displaying a potentially misleading caret cursor. */
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
index 2bf6caa07590cf76db8fad04f3e159a0b408c206..a915b552901a87b2c9b8140c08ee612ab334c2c1 100644 (file)
 }
 
 [id^=mediaEditor] {
+       .mediaEditorButtons {
+               margin-bottom: 20px;
+       }
+       
        .mediaThumbnail {
                text-align: center;
                margin-bottom: 20px;
index f52e06a1a69dd21523cef9559daba1c7afa320fb..de0c65a95036818ba60565015a1fbed14572a5e5 100644 (file)
        top: 0;
        left: -1px;
        bottom: 0;
-       width: calc(100% + 1px);
+       width: calc(100vw + 1px);
        z-index: 450;
        
        @include screen-sm-up {
index ce16ea7bfd63e00f9d09f66f069589b0559ba6e2..9936de3003fa04a1e0d82ebaeb95ded2d3655bc6 100644 (file)
 }
 
 .messageTitle {
-       @include screen-sm-up {
-               @include wcfFontHeadline;
-       }
-       
-       @include screen-xs {
-               @include wcfFontDefault;
-       }
-       
        color: $wcfContentHeadlineText;
                
        a {
index cc9e14e35129828e28a52befc79429afa79ec1c6..aed0ef6f08dc432fd90e3e6556e569e1952b269e 100644 (file)
        .tabularListColumns.new,
        tr.new { // deprecated
                .columnSubject > h3 > .messageGroupLink {
-                       font-weight: bold;
+                       font-weight: 600;
                }
        }
        
 
 .contentHeader.messageGroupContentHeader {
        > .contentHeaderIcon {
-               @include screen-lg {
+               @include screen-md-up {
                        position: relative;
                }
        }
diff --git a/wcfsetup/install/files/style/ui/messageUserConsent.scss b/wcfsetup/install/files/style/ui/messageUserConsent.scss
new file mode 100644 (file)
index 0000000..8413d5a
--- /dev/null
@@ -0,0 +1,34 @@
+.messageUserConsent {
+       background-color: $wcfContentBackground;
+       border-radius: 2px;
+       box-shadow: 0 0 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
+       margin: 10px 0;
+       max-width: 600px;
+       padding: 20px;
+       
+       @include screen-sm-down {
+               padding: 10px;
+       }
+}
+
+.messageUserConsentHeader {
+       display: flex;
+       justify-content: space-between;
+}
+
+.messageUserConsentTitle {
+       font-size: 18px;
+       font-weight: 600;
+       line-height: 1.05;
+       margin-bottom: 10px;
+}
+
+.messageUserConsentButtonContainer {
+       margin: 10px 0;
+       text-align: center;
+}
+
+.messageUserConsentNotice {
+       color: $wcfContentDimmedText;
+       font-size: 12px;
+}
diff --git a/wcfsetup/install/files/style/ui/notification.scss b/wcfsetup/install/files/style/ui/notification.scss
new file mode 100644 (file)
index 0000000..b19d36c
--- /dev/null
@@ -0,0 +1,89 @@
+.notificationSettings {
+       margin-top: 30px;
+}
+
+.notificationSettingsCategory,
+.notificationSettingsItem {
+       display: flex;
+}
+
+.notificationSettingsCategory {
+       border-bottom: 2px solid currentColor;
+       color: $wcfTabularBoxHeadline;
+       font-weight: 600;
+       padding: 5px 0;
+}
+
+.notificationSettingsItem {
+       align-items: center;
+       padding: 5px 0;
+}
+
+.notificationSettingsItem:not(:last-child) {
+       border-bottom: 1px solid $wcfContentBorderInner;
+}
+
+.notificationSettingsEvent {
+       flex: 1 auto;
+       
+       > label {
+               cursor: pointer;
+               display: block;
+       }
+}
+
+.notificationSettingsEvent:hover + .notificationSettingsState,
+.notificationSettingsState > label:hover {
+       .fa-bell, .fa-bell-slash {
+               transform: scale(1.2);
+       }
+}
+
+.notificationSettingsState {
+       align-items: center;
+       display: flex;
+       flex: 0 0 34px;
+       justify-content: center;
+       
+       @include screen-sm-up {
+               margin: 0 20px;
+       }
+       
+       @include screen-xs {
+               margin: 0 10px;
+       }
+       
+       input[type="checkbox"] {
+               opacity: 0;
+               position: absolute;
+               z-index: -1;
+               
+               &.focus-visible:focus ~ .icon {
+                       transform: scale(1.2);
+               }
+               
+               &:not(:checked) + .fa-bell {
+                       display: none;
+               }
+               
+               &:checked ~ .fa-bell-slash {
+                       display: none;
+               }
+       }
+}
+
+.notificationSettingsEmail {
+       align-items: center;
+       display: flex;
+       flex: 0 0 45px;
+       justify-content: flex-end;
+}
+.notificationSettingsEmailType {
+       align-items: center;
+       display: flex;
+       
+       &.disabled {
+               filter: grayscale(1);
+               opacity: .75;
+       }
+}
index 2e019081741183a8e2d76a30e4170606d2b10a02..3235c7ee905a8cad22ff7871b11fb4122cb4b79a 100644 (file)
@@ -1,70 +1,70 @@
-@keyframes wcfPageAction {
-       0%   { visibility: visible; transform: translateY(-10px); opacity: 0; }
-       100% { visibility: visible; transform: translateY(0);     opacity: 1; }
-}
-
-@keyframes wcfPageActionOut {
-       0%   { visibility: visible; transform: translateY(0);     opacity: 1; }
-       100% { visibility: hidden;  transform: translateY(-10px); opacity: 0; }
-}
-
-@keyframes wcfPageActionRemove {
-       0%   { visibility: visible; transform: translateY(0);     opacity: 1; }
-       60%  { visibility: hidden;  transform: translateY(-10px); opacity: 0; }
-       100% { visibility: hidden;  transform: translateY(-10px); opacity: 0; max-width: 0; }
-}
-
 .pageAction {
        bottom: 10px;
+       display: flex;
+       justify-content: flex-end;
+       left: 10px;
+       pointer-events: none;
        position: fixed;
        right: 10px;
        z-index: 400;
        
-       @include inlineList;
+       .pageActionButtons {
+               display: flex;
+               flex: 0 auto;
+               overflow: auto;
+       }
        
-       > li {
-               animation: wcfPageActionOut .3s;
-               animation-fill-mode: forwards;
+       .pageActionButtons,
+       .pageActionButtonToTop {
+               pointer-events: all;
+       }
+       
+       .pageActionButton {
                display: flex;
-               
-               // required to animate 'max-width' properly when removing items
-               max-width: 400px;
+               flex: 0 0 auto;
                white-space: nowrap;
                
-               &[aria-hidden="false"] {
-                       animation: wcfPageAction .3s;
-                       animation-fill-mode: forwards;
+               &:not(:first-child) {
+                       margin-left: 5px;
                }
                
                &.remove {
-                       animation: wcfPageActionRemove .5s;
-                       animation-fill-mode: forwards;
-               }
-               
-               &.initiallyHidden {
-                       animation: 0;
-                       visibility: hidden;
+                       opacity: 0 !important;
+                       visibility: hidden !important;
                }
+       }
+       
+       .pageActionButton,
+       .pageActionButtonToTop {
+               opacity: 0;
+               transition: visibility .12s linear, opacity .12s linear;
+               visibility: hidden;
                
-               &.toTop > a {
-                       padding: 2px;
+               &[aria-hidden="false"] {
+                       opacity: 1;
+                       visibility: visible;
                }
        }
        
-       @include screen-xs {
-               flex-wrap: nowrap;
-               left: 10px;
+       .pageActionButtonToTop {
+               align-self: flex-start;
+               flex: 0 0 auto;
+               margin-left: 5px;
+               padding: 2px;
+       }
+       
+       @include screen-sm-down {
+               /* The iOS bottom touch zone is approximately 30px high. Any touches within will show the
+                  menu instead of registering any touch on a button. */
+               bottom: 30px;
+               transition: bottom .12s linear;
                
-               > li {
-                       flex: 1 1 auto;
-                       max-width: none;
-                       overflow: hidden;
-                       
-                       > a {
-                               overflow: hidden;
-                               text-align: center;
-                               text-overflow: ellipsis;
-                               width: 100%;
+               &:not(.pageActionHasContextButtons) {
+                       &.scrolledDown .pageActionButton,
+                       &.scrolledDown .pageActionButtonToTop {
+                               opacity: 0;
+                               visibility: hidden;
+                               transition-delay: .4s;
                        }
                }
        }
 
 @include screen-xs {
        .redactorActive .pageAction {
-               display: none !important;
+               bottom: 10px;
+
+               &:not(.pageActionHasContextButtons) {
+                       display: none !important;
+               }
        }
 }
index de11e8a9613efd6e42b7a06bfbbe9c7cee3b9698..6ee3b28159c24e1e395a39266e93420dfa9388f1 100644 (file)
@@ -4,6 +4,7 @@
        background-color: $wcfContentBackground;
        border-radius: 2px;
        box-shadow: 0 2px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
+       overflow: hidden;
        position: absolute;
        top: 0;
        vertical-align: middle;
        > .elementPointer {
                display: none;
        }
+       
+       @include screen-xs {
+               &.inverseOrder .reactionTypeButtonList {
+                       flex-direction: column;
+               }
+       }
 }
 
 .reactionType {
@@ -53,7 +60,7 @@
        vertical-align: middle;
        
        &::before {
-               content: ' × ';
+               content: '\202f×\202f';
        }
 }
 
                }
        }
        
+       @include screen-xs {
+               max-height: 200px;
+               overflow: auto;
+               
+               &::after,
+               &::before {
+                       content: "";
+                       height: 40px;
+                       left: 0;
+                       opacity: 0;
+                       pointer-events: none;
+                       position: absolute;
+                       right: 0;
+                       transition: opacity .12s linear;
+               }
+               
+               &::after {
+                       background-image: linear-gradient(to bottom, transparent, $wcfContentBackground);
+                       bottom: 0;
+               }
+               &.overflowBottom::after {
+                       opacity: 1;
+               }
+               
+               &::before {
+                       background-image: linear-gradient(to top, transparent, $wcfContentBackground);
+                       top: 0;
+               }
+               &.overflowTop::before {
+                       opacity: 1;
+               }
+       }
+       
        @include screen-md-down {
                padding: 5px 0;
                
        }
 }
 
+@include screen-xs {
+       .reactionTypeButtonList {
+               display: flex;
+               flex-direction: column-reverse;
+       }
+}
+
 #likeList .likeTypeSelection {
        display: flex;
+       flex-wrap: wrap;
        justify-content: flex-end;
        
-       .buttonGroup li {
-               display: flex;
-               justify-content: stretch;
+       .buttonGroup {
+               margin-bottom: 0;
                
-               a {
+               li {
                        display: flex;
-                       align-items: center;
+                       justify-content: stretch;
+                       
+                       a {
+                               display: flex;
+                               align-items: center;
+                       }
                }
        }
 }
index fe4add69c4bd1c839cadb4346c12659de614028e..1ce4d82cf700c3ab469748e8a76ac0757a5faf79 100644 (file)
        @include wcfFontHeadline;
 }
 
-.redactor-dropdown-h4 {
-       // TODO: add styling
-}
-
 /* alignment plugin */
 .text-center {
        text-align: center !important;
                &::after {
                        color: $wcfSidebarText;
                        content: attr(data-placeholder);
-                       
-                       @include screen-sm-up {
-                               @include wcfFontSection;
-                       }
                }
                
                > .messageBody {
index ec24d03de1fad0c0984de392ec8c80930a2726dc..9458c4b99df8415d0b698d10e4231da544b382d1 100644 (file)
                }
                
                &.columnTitle {
-                       font-weight: bold;
+                       font-weight: 600;
                        text-align: left;
                }
                
index bc7f6f78b54e3ce6533a9a4df62e0202e18bf045..f86ebe829cdd74fc684e3b33d988daa353d967bf 100644 (file)
@@ -50,7 +50,7 @@
        z-index: 350;
        
        &.touchForceInaccessible {
-               pointer-events: none !important;
+               display: none;
        }
        
        @include screen-md-down {
index 1f416c27a46823729319a2eb6249bb09cda2d989..50638a0275e238f3a5bd36f28b3dad9dfc674a5c 100644 (file)
                        > span:last-child {
                                margin-left: 5px;
                        }
+
+                       input,
+                       .trophyIcon {
+                               flex-shrink: 0;
+                       }
                }
        }
 }
 
+/* trophies in message sidebar */
 .specialTrophyContainer {
        margin-top: 10px;
        
        > ul {
                display: flex;
                justify-content: center;
+               flex-wrap: wrap;
+               margin-bottom: -5px;
+               margin-right: -5px;
                
-               > li:not(:last-child) {
+               > li {
+                       margin-bottom: 5px;
                        margin-right: 5px;
                }
        }
        }
 }
 
+/* trophies in user profile header */
 .specialTrophyUserContainer > ul {
+       align-items: center;
        display: flex;
+       flex-wrap: wrap;
+       margin-right: -5px;
        margin-top: -15px;
-       margin-bottom: 5px;
        
-       > li:not(:last-child) {
+       > li {
+               margin-bottom: 5px;
                margin-right: 5px;
        }
 }
        margin-top: 5px;
        margin-bottom: 5px;
 }
+
+.sortableNodeLabel > .trophyIcon {
+    margin-right: 5px;
+}
index e441ea52ffd173ac85b728bf0ec515c9c18a0c9d..4c280362701ca27c8d485f10ac08ae909c9f3ba3 100644 (file)
                <item name="wcf.acp.article.views"><![CDATA[Zugriffe]]></item>
                <item name="wcf.acp.article.lastVersion"><![CDATA[Es gibt <a href="{link controller='VersionTrackerList' objectType='com.woltlab.wcf.article' objectID=$article->articleID isACP=true}{/link}">vorherige Versionen</a> dieses Artikels, die letzte Änderung erfolgte durch „{$lastVersion->username}“ ({@$lastVersion->time|time}).]]></item>
                <item name="wcf.acp.article.isDeleted"><![CDATA[Gelöscht]]></item>
+               <item name="wcf.acp.article.metaTitle"><![CDATA[Meta Titel]]></item>
+               <item name="wcf.acp.article.metaDescription"><![CDATA[Meta Description]]></item>
        </category>
        <category name="wcf.acp.attachment">
                <item name="wcf.acp.attachment.list"><![CDATA[Dateianhänge]]></item>
                <item name="wcf.acp.dataImport.cli.configure.data.error.noSelection"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} keine Daten zum Import ausgewählt. Der Import wird beendet.]]></item>
                <item name="wcf.acp.dataImport.cli.configure.data.error.invalid"><![CDATA[Der ausgewählte Datentyp ist ungültig.]]></item>
                <item name="wcf.acp.dataImport.cli.configure.data.selectAll"><![CDATA[Alle Daten]]></item>
-               <item name="wcf.acp.dataImport.cli.info.wcf"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} keine App beim Skript-Aufruf mittels --packageID={PACKAGE_ID} geladen. Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} Daten für eine App importieren {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, {if LANGUAGE_USE_INFORMAL_VARIANT}musst du{else}müssen Sie{/if} das Skript mit der ID des entsprechenden Pakets starten. {if LANGUAGE_USE_INFORMAL_VARIANT}Möchtest du{else}Möchten Sie{/if} mit dem Import fortfahren? [YN]]]></item>
                <item name="wcf.acp.dataImport.cli.selection"><![CDATA[Auswahl? [{if $minSelection == $maxSelection}{$minSelection}{else}{$minSelection}-{$maxSelection}{/if}]]]></item>
                <item name="wcf.acp.dataImport.completed"><![CDATA[Import abgeschlossen.]]></item>
                <item name="wcf.acp.dataImport.configure.data"><![CDATA[Daten]]></item>
                <item name="wcf.acp.devtools.project.edit.error.brokenPath"><![CDATA[Es existiert keine <kbd>package.xml</kbd> im angegebenen Pfad. Die Paket-Dateien wurden entweder gelöscht oder verschoben.]]></item>
                <item name="wcf.acp.devtools.project.edit.warning.missingElements"><![CDATA[Die folgenden Informationen fehlen in der <kbd>package.xml</kbd>-Datei: {implode from=$missingElements item=missingElement}<kbd>{$missingElement}</kbd>{/implode}.]]></item>
                <item name="wcf.acp.devtools.project.license"><![CDATA[Lizenz]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.languageID"><![CDATA[Sprache]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.languageItem"><![CDATA[Name des Texts]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.lastTime"><![CDATA[Zeitpunkt des letzten Auftretens]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Eintrag wirklich löschen?]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.stackTrace"><![CDATA[Stacktrace]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.showStackTrace"><![CDATA[Stacktrace anzeigen]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.clearLog"><![CDATA[Alle Einträge löschen]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.clearLog.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} wirklich alle Einträge löschen?]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.stackTrace.toggleOutputFormat"><![CDATA[Zeilenumbrüche einschalten/ausschalten]]></item>
        </category>
        <category name="wcf.acp.email">
                <item name="wcf.acp.email.smtp.test"><![CDATA[SMTP-Verbindungstest]]></item>
@@ -677,7 +687,7 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.group.option.admin.management.canViewLog"><![CDATA[Kann Protokolle abrufen]]></item>
                <item name="wcf.acp.group.option.admin.configuration.canManageApplication"><![CDATA[Kann Apps verwalten]]></item>
                <item name="wcf.acp.group.option.admin.management.canManageCronjob"><![CDATA[Kann zeitgesteuerte Aufgaben verwalten]]></item>
-               <item name="wcf.acp.group.option.admin.configuration.package.canEditServer"><![CDATA[Kann Update-Server bearbeiten]]></item>
+               <item name="wcf.acp.group.option.admin.configuration.package.canEditServer"><![CDATA[Kann Paket-Server bearbeiten]]></item>
                <item name="wcf.acp.group.option.admin.configuration.package.canInstallPackage"><![CDATA[Kann Pakete installieren]]></item>
                <item name="wcf.acp.group.option.admin.configuration.package.canUninstallPackage"><![CDATA[Kann Pakete deinstallieren]]></item>
                <item name="wcf.acp.group.option.admin.configuration.package.canUpdatePackage"><![CDATA[Kann Pakete aktualisieren]]></item>
@@ -757,7 +767,6 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.group.option.user.profile.avatar.maxSize"><![CDATA[Maximale Dateigröße]]></item>
                <item name="wcf.acp.group.option.user.profile.canChangeEmail"><![CDATA[Kann E-Mail-Adresse ändern]]></item>
                <item name="wcf.acp.group.option.user.profile.canEditUserTitle"><![CDATA[Kann eigenen Benutzertitel bearbeiten]]></item>
-               <item name="wcf.acp.group.option.user.profile.canMail"><![CDATA[Kann E-Mails an andere Benutzer senden]]></item>
                <item name="wcf.acp.group.option.user.profile.canQuit"><![CDATA[Kann Benutzerkonto löschen]]></item>
                <item name="wcf.acp.group.option.user.profile.canRename"><![CDATA[Kann Benutzernamen ändern]]></item>
                <item name="wcf.acp.group.option.user.profile.canViewMembersList"><![CDATA[Kann Mitglieder-Liste sehen]]></item>
@@ -768,8 +777,8 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.group.option.user.signature.disallowedBBCodes.description"><![CDATA[Die hier ausgewählten BBCodes dürfen von Mitgliedern dieser Benutzergruppe in ihrer Signatur <em>nicht</em> verwendet werden.]]></item>
                <item name="wcf.acp.group.priority"><![CDATA[Priorisierung]]></item>
                <item name="wcf.acp.group.priority.description"><![CDATA[Bestimmt u.a. die Reihenfolge auf der Team-Seite sowie die Auswahl von Benutzerrängen und „Wer ist online“-Darstellungen auf Basis der höchsten Priorität.]]></item>
-               <item name="wcf.acp.group.userOnlineMarking"><![CDATA[„Benutzer online“-Darstellung]]></item>
-               <item name="wcf.acp.group.userOnlineMarking.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} die HTML-Formatierung für Mitglieder dieser Benutzergruppe in der „Wer ist online“-Anzeige anpassen. <em>&lt;strong&gt;%s&lt;/strong&gt;</em> stellt Mitglieder dieser Gruppe beispielsweise in Fettdruck dar.]]></item>
+               <item name="wcf.acp.group.userOnlineMarking"><![CDATA[Benutzer-Darstellung]]></item>
+               <item name="wcf.acp.group.userOnlineMarking.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} die HTML-Formatierung für Mitglieder dieser Benutzergruppe anpassen. <em>&lt;strong&gt;%s&lt;/strong&gt;</em> stellt Mitglieder dieser Gruppe beispielsweise in Fettdruck dar.]]></item>
                <item name="wcf.acp.group.userOnlineMarking.error.invalid"><![CDATA[Die Darstellung muss „%s“ enthalten]]></item>
                <item name="wcf.acp.group.showOnTeamPage"><![CDATA[Mitglieder dieser Benutzergruppe auf der Team-Seite anzeigen]]></item>
                <item name="wcf.acp.group.option.admin.user.canEnableUser"><![CDATA[Kann Benutzer aktivieren]]></item>
@@ -872,6 +881,8 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.group.option.user.profile.trophy.canSeeTrophies"><![CDATA[Kann Trophäen sehen]]></item>
                <item name="wcf.acp.group.option.user.profile.trophy.maxUserSpecialTrophies"><![CDATA[Maximale Anzahl an besonderen Trophäen]]></item>
                <item name="wcf.acp.group.option.user.profile.trophy.maxUserSpecialTrophies.description"><![CDATA[Besondere Trophäen können vom Benutzer individuell ausgewählt werden und werden in der Message-Sidebar und im Benutzerprofil angezeigt.]]></item>
+               <item name="wcf.acp.group.option.category.user.profile.payment"><![CDATA[Zahlungsoptionen]]></item>
+               <item name="wcf.acp.group.option.user.profile.payment.canBuyPaidSubscription"><![CDATA[Kann bezahlte Mitgliedschaften kaufen]]></item>
                <item name="wcf.acp.group.option.category.user.profile.coverPhoto"><![CDATA[Titelbilder]]></item>
                <item name="wcf.acp.group.option.user.profile.coverPhoto.canSeeCoverPhotos"><![CDATA[Kann Titelbilder sehen]]></item>
                <item name="wcf.acp.group.option.user.profile.coverPhoto.canUploadCoverPhoto"><![CDATA[Kann eigenes Titelbild hochladen]]></item>
@@ -883,6 +894,7 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.group.option.user.contactForm.attachment.allowedExtensions.description"><![CDATA[Eine Dateiendung pro Zeile]]></item>
                <item name="wcf.acp.group.option.user.contactForm.attachment.maxCount"><![CDATA[Maximale Dateianhänge pro Nachricht]]></item>
                <item name="wcf.acp.group.option.user.profile.canEditUserProfile"><![CDATA[Kann eigenes Profil bearbeiten]]></item>
+               <item name="wcf.acp.group.option.user.profile.canHideOnlineStatus"><![CDATA[Kann Online-Status verbergen]]></item>
                <item name="wcf.acp.group.allowMention"><![CDATA[Benutzergruppe kann erwähnt werden]]></item>
                <item name="wcf.acp.group.type.owner"><![CDATA[Besitzer]]></item>
                <item name="wcf.acp.group.type.owner.description"><![CDATA[Die Besitzer-Gruppe verfügt über nicht entziehbare Berechtigungen und kann von anderen Gruppen nicht bearbeitet werden, diese Gruppe kann nur durch die Besitzer-Gruppe selbst bearbeitet werden. Mitglieder dieser Gruppe können andere Benutzer zu dieser Gruppe hinzufügen, sich aber selbst nicht daraus entfernen.]]></item>
@@ -901,7 +913,6 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.index.credits.productManager"><![CDATA[Projektleitung]]></item>
                <item name="wcf.acp.index.credits.trademarks"><![CDATA[„WoltLab&reg;“ und „Burning Board&reg;“ sind eingetragene Gemeinschaftsmarken beim europäischen Harmonisierungsamt für den Binnenmarkt (OHIM) in Alicante, Spanien.]]></item>
                <item name="wcf.acp.index.credits.contributor.more"><![CDATA[Weitere]]></item>
-               <item name="wcf.acp.index.innoDBWarning"><![CDATA[Die MySQL-Einstellung „innodb_flush_log_at_trx_commit“ steht auf dem Wert „1“ und verursacht dadurch eine starke Verlangsamung bestimmter Datenbankabfragen. Es wird empfohlen diesen Wert auf „2“ zu setzen.]]></item>
                <item name="wcf.acp.index.inRescueMode"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du rufst{else}Sie rufen{/if} diese Installation über eine abweichende Domain auf, etwa aufgrund eines Umzuges. Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}korrigiere{else}korrigieren Sie{/if} die Einstellungen unter <a href="{link controller='ApplicationManagement'}{/link}">Apps verwalten</a>.]]></item>
                <item name="wcf.acp.index.tmpBroken"><![CDATA[Für den ordnungsgemäßen Betrieb muss das Verzeichnis „{WCF_DIR|concat:'tmp/'}“ existieren und beschreibbar sein. Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}überprüfe{else}überprüfen Sie{/if} auch die Zugriffsrechte auf den Ordner „{'WCF_DIR'|constant}“.]]></item>
                <item name="wcf.acp.index.news"><![CDATA[Nachrichten]]></item>
@@ -930,7 +941,7 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.index.woltlab.pluginStore"><![CDATA[Plugin-Store]]></item>
                <item name="wcf.acp.index.tinyBuild"><![CDATA[Die Seitenbeschleunigung für Gäste verbessert die Ladezeiten für Besucher und Suchmaschinen, es wird empfohlen diese <a href="{link controller='Option' id=1 optionName="visitor_use_tiny_build"}#category_module.system{/link}">zu aktivieren</a>.]]></item>
                <item name="wcf.acp.index.recaptchaWithoutKey"><![CDATA[Die Nutzung von reCAPTCHA ohne einen individuellen Website-Schlüssel wird von Google nicht mehr unterstützt.<br><br>Für eine weitere Nutzung {if LANGUAGE_USE_INFORMAL_VARIANT}musst du{else}müssen Sie{/if} <a href="{$recaptchaKeyLink}">einen Schlüssel in den Optionen hinterlegen</a>, unterhalb des Eingabefeldes befindet sich eine Anleitung zum Anfordern des Schlüssels.]]></item>
-               <item name="wcf.acp.index.missingLanguageItems"><![CDATA[Es wurden fehlende Sprachvariablen protokolliert (zuletzt: {@$missingLanguageItemsMTime|time}). {if LANGUAGE_USE_INFORMAL_VARIANT}Überprüfe{else}Überprüfen Sie{/if} die Datei <kbd>{'WCF_DIR'|constant}log/missingLanguageItems.txt</kbd> für weitere Informationen.]]></item>
+               <item name="wcf.acp.index.missingLanguageItems"><![CDATA[Es wurden fehlende Sprachvariablen protokolliert (zuletzt: {@$missingLanguageItemsMTime|time}). {if LANGUAGE_USE_INFORMAL_VARIANT}Überprüfe{else}Überprüfen Sie{/if} die <a href="{link controller='DevtoolsMissingLanguageItemList'}{/link}">Liste der fehlenden Texte</a> für weitere Informationen.]]></item>
        </category>
        <category name="wcf.acp.label">
                <item name="wcf.acp.label.add"><![CDATA[Label hinzufügen]]></item>
@@ -1188,6 +1199,7 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.menu.link.reactionType.edit"><![CDATA[Reaktions-Typ bearbeiten]]></item>
                <item name="wcf.acp.menu.link.language.item.add"><![CDATA[Text hinzufügen]]></item>
                <item name="wcf.acp.menu.link.systemCheck"><![CDATA[Systemüberprüfung]]></item>
+               <item name="wcf.acp.menu.link.devtools.missingLanguageItem.list"><![CDATA[Fehlende Texte]]></item>
        </category>
        <category name="wcf.acp.modificationLog">
                <item name="wcf.acp.modificationLog.list"><![CDATA[Globales Änderungsprotokoll]]></item>
@@ -1307,6 +1319,8 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.error.controllerReplacementUnknown"><![CDATA[Der Controller „{$urlControllerReplacementError}“ ist unbekannt.]]></item>
                <item name="wcf.acp.option.error.tooHigh"><![CDATA[Der angegebene Wert ist zu hoch.{if $option->maxvalue !== null} Der maximale Wert ist {#$option->maxvalue}.{/if}]]></item>
                <item name="wcf.acp.option.error.tooLow"><![CDATA[Der angegebene Wert ist zu gering.{if $option->minvalue !== null} Der minimale Wert ist {#$option->minvalue}.{/if}]]></item>
+               <item name="wcf.acp.option.error.tooLong"><![CDATA[Der eingegebene Text ist zu lang.]]></item>
+               <item name="wcf.acp.option.error.tooShort"><![CDATA[Der eingegebene Text ist zu kurz.]]></item>
                <item name="wcf.acp.option.http_enable_gzip"><![CDATA[Gzip-Komprimierung aktivieren]]></item>
                <item name="wcf.acp.option.http_enable_gzip.description"><![CDATA[Aktiviert die Komprimierung der Inhalte bei der Übertragung vom Server an den Client. Dies reduziert den Traffic und kann den Ladevorgang erheblich beschleunigen.]]></item>
                <item name="wcf.acp.option.http_send_x_frame_options"><![CDATA[Einbindung in einem Frame verhindern]]></item>
@@ -1328,8 +1342,10 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.mail_send_method.debugFolder"><![CDATA[Debug (Ordner mit .eml-Dateien)]]></item>
                <item name="wcf.acp.option.mail_send_method.php"><![CDATA[PHP]]></item>
                <item name="wcf.acp.option.mail_send_method.smtp"><![CDATA[SMTP]]></item>
-               <item name="wcf.acp.option.mail_signature"><![CDATA[Signatur]]></item>
+               <item name="wcf.acp.option.mail_signature"><![CDATA[Signatur (Text)]]></item>
                <item name="wcf.acp.option.mail_signature.description"><![CDATA[Die Signatur wird an jede automatisch generierte E-Mail angehängt.]]></item>
+               <item name="wcf.acp.option.mail_signature_html"><![CDATA[Signatur (HTML)]]></item>
+               <item name="wcf.acp.option.mail_signature_html.description"><![CDATA[Die Signatur für die HTML-Version der versendeten E-Mails. Wenn keine HTML-Variante angegeben ist, dann wird die Text-Signatur verwendet.]]></item>
                <item name="wcf.acp.option.mail_smtp_host"><![CDATA[SMTP-Server]]></item>
                <item name="wcf.acp.option.mail_smtp_host.description"><![CDATA[Bei SMTP-Port 465 muss zusätzlich der Präfix <kbd>ssl://</kbd> angegeben werden, etwa <kbd>ssl://mail.example.com</kbd> statt nur <kbd>mail.example.com</kbd>.]]></item>
                <item name="wcf.acp.option.mail_smtp_port"><![CDATA[SMTP-Port]]></item>
@@ -1375,13 +1391,11 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.enable_debug_mode.description"><![CDATA[Aktiviert ausführliche Fehlerberichte. Diese Option sollte im Live-Betrieb abgeschaltet werden.]]></item>
                <item name="wcf.acp.option.enable_production_debug_mode"><![CDATA[Problemanalyse im Live-Betrieb]]></item>
                <item name="wcf.acp.option.enable_production_debug_mode.description"><![CDATA[Hängt die aktuelle URL an Datenbankabfragen an, um diese im Log des Datenbankservers einfacher identifizieren zu können.]]></item>
-               <item name="wcf.acp.option.external_link_rel_nofollow"><![CDATA[Externe Links mit dem Attribut „rel="nofollow"“ versehen]]></item>
-               <item name="wcf.acp.option.external_link_rel_nofollow.description"><![CDATA[Das Attribut „rel="nofollow"“ weist Suchmaschinen an, einen bestimmten Link auf einer Seite zu ignorieren.]]></item>
                <item name="wcf.acp.option.external_link_target_blank"><![CDATA[Externe Links in neuem Fenster öffnen]]></item>
                <item name="wcf.acp.option.external_link_target_blank.description"><![CDATA[Setzt das Attribut „target="_blank"“ auf externe Links und weist den Browser dadurch an, einen aufgerufenen Link in einem neuen Browser-Fenster zu öffnen.]]></item>
                <item name="wcf.acp.option.enable_benchmark"><![CDATA[Benchmark aktivieren]]></item>
                <item name="wcf.acp.option.enable_benchmark.description"><![CDATA[Erfasst zusätzliche Daten zur Ressourcennutzung von Komponenten. Diese Option sollte im Live-Betrieb abgeschaltet werden.]]></item>
-               <item name="wcf.acp.option.category.general.system.packageServer"><![CDATA[Update-Server]]></item>
+               <item name="wcf.acp.option.category.general.system.packageServer"><![CDATA[Paket-Server]]></item>
                <item name="wcf.acp.option.package_server_auth_code"><![CDATA[Authentifizierung-Code]]></item>
                <item name="wcf.acp.option.package_server_auth_code.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deinen{else}Ihren{/if} Authentifizierung-Code {if LANGUAGE_USE_INFORMAL_VARIANT}findest du{else}finden Sie{/if} in {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kundenkonto auf woltlab.com.]]></item>
                <item name="wcf.acp.option.enable_woltlab_news"><![CDATA[WoltLab-Nachrichten anzeigen]]></item>
@@ -1391,11 +1405,10 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.recaptcha_publickey.description"><![CDATA[Einen eigenen Websiteschlüssel für die Nutzung der reCAPTCHA-Funktion {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} auf der Website von <a href="https://www.google.com/recaptcha/admin" class="externalURL">reCAPTCHA</a> beantragen.]]></item>
                <item name="wcf.acp.option.recaptcha_privatekey"><![CDATA[Geheimer Schlüssel (reCAPTCHA, Version 2)]]></item>
                <item name="wcf.acp.option.recaptcha_publickey_invisible"><![CDATA[Websiteschlüssel (Unsichtbares reCAPTCHA)]]></item>
-               <item name="wcf.acp.option.recaptcha_publickey_invisible.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Trage{else}Tragen Sie{/if} hier, <b>zusätzlich</b> zu den obigen Schlüsseln, Schlüssel für das unsichtbare reCAPTCHA ein, wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} diese Variante nutzen {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}.]]></item>
+               <item name="wcf.acp.option.recaptcha_publickey_invisible.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Trage{else}Tragen Sie{/if} hier, <strong>zusätzlich</strong> zu den obigen Schlüsseln, Schlüssel für das unsichtbare reCAPTCHA ein, wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} diese Variante nutzen {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}.]]></item>
                <item name="wcf.acp.option.recaptcha_privatekey_invisible"><![CDATA[Geheimer Schlüssel (Unsichtbares reCAPTCHA)]]></item>
                <item name="wcf.acp.option.category.message.attachment"><![CDATA[Dateianhänge]]></item>
-               <item name="wcf.acp.option.attachment_enable_thumbnails"><![CDATA[Vorschaugrafiken von hochgeladenen Bilder erzeugen]]></item>
-               <item name="wcf.acp.option.attachment_retain_dimensions"><![CDATA[Bildformat beim Erzeugen von Vorschaugrafiken beibehalten]]></item>
+               <item name="wcf.acp.option.attachment_retain_dimensions"><![CDATA[Seitenverhältnis beim Erzeugen von Vorschaugrafiken beibehalten]]></item>
                <item name="wcf.acp.option.attachment_thumbnail_height"><![CDATA[Höhe der Vorschaugrafiken]]></item>
                <item name="wcf.acp.option.attachment_thumbnail_width"><![CDATA[Breite der Vorschaugrafiken]]></item>
                <item name="wcf.acp.option.category.message.attachment.autoscale"><![CDATA[Automatische Bildskalierung]]></item>
@@ -1408,7 +1421,6 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.attachment_image_autoscale_file_type"><![CDATA[Dateityp]]></item>
                <item name="wcf.acp.option.attachment_image_autoscale_file_type.jpeg"><![CDATA[JPEG (verlustbehaftet, erzeugt in der Regel kleine Dateien)]]></item>
                <item name="wcf.acp.option.attachment_image_autoscale_file_type.keep"><![CDATA[Dateityp beibehalten]]></item>
-               <item name="wcf.acp.option.module_attachment"><![CDATA[Dateianhänge]]></item>
                <item name="wcf.acp.option.module_smiley"><![CDATA[Smileys]]></item>
                <item name="wcf.acp.option.category.message.censorship"><![CDATA[Zensur-Funktion]]></item>
                <item name="wcf.acp.option.censored_words"><![CDATA[Zu zensierende Wörter]]></item>
@@ -1457,13 +1469,11 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.module_user_rank"><![CDATA[Benutzerränge]]></item>
                <item name="wcf.acp.option.module_user_signature"><![CDATA[Signaturen]]></item>
                <item name="wcf.acp.option.module_team_page"><![CDATA[Team-Seite]]></item>
-               <item name="wcf.acp.option.register_enable_password_security_check"><![CDATA[Sicherheitsüberprüfung aktivieren]]></item>
-               <item name="wcf.acp.option.register_enable_password_security_check.description"><![CDATA[Kennwörter werden auf ihre Sicherheit geprüft. Unsichere Kennwörter werden abgelehnt.]]></item>
-               <item name="wcf.acp.option.register_password_min_length"><![CDATA[Minimale Kennwortlänge]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_digit"><![CDATA[Kennwort muss Zahlen enthalten]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_lower_case"><![CDATA[Kennwort muss Kleinbuchstaben enthalten]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_special_char"><![CDATA[Kennwort muss Sonderzeichen enthalten]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_upper_case"><![CDATA[Kennwort muss Großbuchstaben enthalten]]></item>
+               <item name="wcf.acp.option.password_min_score"><![CDATA[Sicherheitslevel]]></item>
+               <item name="wcf.acp.option.password_min_score.description"><![CDATA[„Score“-Wert der <a href="https://github.com/dropbox/zxcvbn" class="externalURL">zxcvbn-Bibliothek</a>, den Kennwörter mindestens erreichen müssen.]]></item>
+               <item name="wcf.acp.option.password_min_score.0"><![CDATA[0: Deaktiviert]]></item>
+               <item name="wcf.acp.option.password_min_score.1"><![CDATA[1: Sehr leicht zu erraten (Eine Million Versuche)]]></item>
+               <item name="wcf.acp.option.password_min_score.2"><![CDATA[2: Leicht zu erraten (100 Millionen Versuche)]]></item>
                <item name="wcf.acp.option.register_forbidden_usernames"><![CDATA[Reservierte Namen]]></item>
                <item name="wcf.acp.option.register_forbidden_usernames.description"><![CDATA[Namen, die nicht als Benutzername verwendet werden dürfen. Ein Name pro Zeile]]></item>
                <item name="wcf.acp.option.register_forbidden_emails"><![CDATA[Reservierte E-Mail-Adressen]]></item>
@@ -1483,6 +1493,7 @@ ACHTUNG: Die oben genannten Meldungen sind stark gekürzt. Sie können Details z
                <item name="wcf.acp.option.register_activation_method"><![CDATA[Aktivierungsmethode]]></item>
                <item name="wcf.acp.option.register_activation_method.byAdmin"><![CDATA[Aktivierung erfolgt durch Administrator]]></item>
                <item name="wcf.acp.option.register_activation_method.byUser"><![CDATA[Benutzer aktiviert sich durch E-Mail-Bestätigung]]></item>
+               <item name="wcf.acp.option.register_activation_method.byUserAndAdmin"><![CDATA[Aktivierung erfolgt durch Administrator nach erfolgreicher E-Mail-Bestätigung]]></item>
                <item name="wcf.acp.option.register_activation_method.disabled"><![CDATA[Keine Aktivierung notwendig]]></item>
                <item name="wcf.acp.option.signature_max_image_height"><![CDATA[Maximale Höhe von Signatur-Bildern]]></item>
                <item name="wcf.acp.option.sitemap_index_time_frame"><![CDATA[Zeitfenster der Indexierung]]></item>
@@ -1567,7 +1578,6 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.option.google_maps_default_longitude"><![CDATA[Standard-Kartenposition (Längengrad)]]></item>
                <item name="wcf.acp.option.google_maps_access_user_location"><![CDATA[Aktuelle Benutzerposition verwenden]]></item>
                <item name="wcf.acp.option.google_maps_access_user_location.description"><![CDATA[Bei der Angabe von Positionen wird die aktuelle Position des Benutzers als Ausgangspunkt auf der Karte verwendet.]]></item>
-               <item name="wcf.acp.option.message_sidebar_enable_user_online_marking"><![CDATA[„Benutzer online“-Darstellung für Benutzernamen verwenden]]></item>
                <item name="wcf.acp.option.module_cookie_policy_page"><![CDATA[Erklärung zum „Einsatz von Cookies“ aktivieren]]></item>
                <item name="wcf.acp.option.module_cookie_policy_page.description"><![CDATA[Weist Besucher beim ersten Aufruf der Seite gemäß EU-Richtlinie 2009/136/EG auf den Einsatz von Cookies hin.]]></item>
                <item name="wcf.acp.option.show_update_notice_frontend"><![CDATA[Hinweis bei neuen Updates für Pakete im Frontend anzeigen]]></item>
@@ -1664,13 +1674,13 @@ Als Benachrichtigungs-URL in der Konfiguration der sofortigen Zahlungsbestätigu
                <item name="wcf.acp.option.language_use_informal_variant"><![CDATA[Informelle Anrede verwenden]]></item>
                <item name="wcf.acp.option.category.cms.media.thumbnail"><![CDATA[Vorschaugrafiken]]></item>
                <item name="wcf.acp.option.media_large_thumbnail_height"><![CDATA[Höhe der großen Vorschaugrafiken]]></item>
-               <item name="wcf.acp.option.media_large_thumbnail_retain_dimensions"><![CDATA[Bildformat beim Erzeugen von großen Vorschaugrafiken beibehalten]]></item>
+               <item name="wcf.acp.option.media_large_thumbnail_retain_dimensions"><![CDATA[Seitenverhältnis beim Erzeugen von großen Vorschaugrafiken beibehalten]]></item>
                <item name="wcf.acp.option.media_large_thumbnail_width"><![CDATA[Breite der großen Vorschaugrafiken]]></item>
                <item name="wcf.acp.option.media_medium_thumbnail_height"><![CDATA[Höhe der mittleren Vorschaugrafiken]]></item>
-               <item name="wcf.acp.option.media_medium_thumbnail_retain_dimensions"><![CDATA[Bildformat beim Erzeugen von mittleren Vorschaugrafiken beibehalten]]></item>
+               <item name="wcf.acp.option.media_medium_thumbnail_retain_dimensions"><![CDATA[Seitenverhältnis beim Erzeugen von mittleren Vorschaugrafiken beibehalten]]></item>
                <item name="wcf.acp.option.media_medium_thumbnail_width"><![CDATA[Breite der mittleren Vorschaugrafiken]]></item>
                <item name="wcf.acp.option.media_small_thumbnail_height"><![CDATA[Höhe der kleinen Vorschaugrafiken]]></item>
-               <item name="wcf.acp.option.media_small_thumbnail_retain_dimensions"><![CDATA[Bildformat beim Erzeugen von kleinen Vorschaugrafiken beibehalten]]></item>
+               <item name="wcf.acp.option.media_small_thumbnail_retain_dimensions"><![CDATA[Seitenverhältnis beim Erzeugen von kleinen Vorschaugrafiken beibehalten]]></item>
                <item name="wcf.acp.option.media_small_thumbnail_width"><![CDATA[Breite der kleinen Vorschaugrafiken]]></item>
                <item name="wcf.acp.option.article_sort_order"><![CDATA[Sortierungsreihenfolge]]></item>
                <item name="wcf.acp.option.article_sort_order.description"><![CDATA[Standard-Reihenfolge für die Liste der Artikel.]]></item>
@@ -1690,7 +1700,7 @@ Als Benachrichtigungs-URL in der Konfiguration der sofortigen Zahlungsbestätigu
                <item name="wcf.acp.option.enable_polling"><![CDATA[Hintergrund-Aktualisierung von Benachrichtigungen aktivieren]]></item>
                <item name="wcf.acp.option.enable_polling.description"><![CDATA[Neue Benachrichtigungen werden in periodischen Abständen automatisch abgerufen. Der Aktualisierungs-Intervall beträgt 5 Minuten und wird bei Inaktivität schrittweise auf 15 Minuten reduziert.]]></item>
                <item name="wcf.acp.option.enable_desktop_notifications"><![CDATA[Desktop-Benachrichtigungen verwenden]]></item>
-               <item name="wcf.acp.option.enable_desktop_notifications.description"><![CDATA[Neue Benachrichtigungen, die im Hintergrund abgerufen wurden, werden als kleines Benachrichtigungsfenster unmittelbar angezeigt. Einige wenige Browser, z. B. Internet Explorer, unterstützen diese Funktion nicht.]]></item>
+               <item name="wcf.acp.option.enable_desktop_notifications.description"><![CDATA[Neue Benachrichtigungen, die im Hintergrund abgerufen wurden, werden als kleines Benachrichtigungsfenster unmittelbar angezeigt.]]></item>
                <item name="wcf.acp.option.module_contact_form"><![CDATA[Kontaktformular aktivieren]]></item>
                <item name="wcf.acp.option.module_contact_form.description"><![CDATA[Aktiviert das Kontaktformular, nach Aktivierung können Sie die <a href="{link controller='ContactSettings'}{/link}">Eingabefelder und Empfänger</a> individuell konfigurieren.]]></item>
                <item name="wcf.acp.option.module_trophy"><![CDATA[Trophäen]]></item>
@@ -1716,7 +1726,7 @@ Als Benachrichtigungs-URL in der Konfiguration der sofortigen Zahlungsbestätigu
                <item name="wcf.acp.option.message_public_highlighters"><![CDATA[Auswählbare Syntax-Highlighter]]></item>
                <item name="wcf.acp.option.message_public_highlighters.description"><![CDATA[Die gewählten Syntax-Highlighter stehen dem Nutzer unmittelbar im Editor zur Verfügung. Die anderen Highlighter sind weiterhin verfügbar, der Nutzer muss jedoch den internen Namen kennen.]]></item>
                <item name="wcf.acp.option.log_missing_language_items"><![CDATA[Fehlende Sprachvariablen protokollieren]]></item>
-               <item name="wcf.acp.option.log_missing_language_items.description"><![CDATA[Die fehlenden Sprachvariablen werden in der Datei <kbd>{'WCF_DIR'|constant}log/missingLanguageItems.txt</kbd> protokolliert.]]></item>
+               <item name="wcf.acp.option.log_missing_language_items.description"><![CDATA[Die fehlenden Sprachvariablen können unter <a href="{link controller='DevtoolsMissingLanguageItemList'}{/link}">Fehlende Texte</a> eingesehen werden.]]></item>
                <item name="wcf.acp.option.category.general.system.ipAddress"><![CDATA[IP-Adressen]]></item>
                <item name="wcf.acp.option.prune_ip_address"><![CDATA[Speicherzeit für IP-Adressen]]></item>
                <item name="wcf.acp.option.prune_ip_address.description"><![CDATA[Zeitraum, nachdem alte IP-Adressen automatisch gelöscht werden. [0, um die Löschung zu deaktivieren]]]></item>
@@ -1755,6 +1765,11 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.option.blacklist_sfs_action.block"><![CDATA[Blockieren]]></item>
                <item name="wcf.acp.option.blacklist_sfs_action.description"><![CDATA[Es besteht immer das Risiko eines fehlerhaften Eintrages, daher wird die Einstellung <strong>Deaktivierung, erfordert manuelle Freischaltung</strong> ausdrücklich empfohlen.]]></item>
                <item name="wcf.acp.option.blacklist_sfs_action.disable"><![CDATA[Deaktivierung, erfordert manuelle Freischaltung]]></item>
+               <item name="wcf.acp.option.module_amp"><![CDATA[AMP]]></item>
+               <item name="wcf.acp.option.module_amp.description"><![CDATA[Aktiviert <abbr title="Accelerated Mobile Pages">AMP</abbr>-Versionen von bestimmten Seiten (z. B. Artikeln).]]></item>
+               <item name="wcf.acp.option.message_enable_user_consent"><![CDATA[Inhalte von externen Anbietern erst nach Zustimmung anzeigen]]></item>
+               <item name="wcf.acp.option.modification_log_expiration"><![CDATA[Speicherzeit für Änderungen]]></item>
+               <item name="wcf.acp.option.modification_log_expiration.description"><![CDATA[Zeitraum, nachdem alte Änderungen aus dem Änderungsprotokoll entfernt werden [0, um die Entfernung gänzlich zu deaktivieren]]]></item>
        </category>
        <category name="wcf.acp.customOption">
                <item name="wcf.acp.customOption.list"><![CDATA[Eingabefelder]]></item>
@@ -1807,7 +1822,7 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.package.description"><![CDATA[Beschreibung]]></item>
                <item name="wcf.acp.package.error.cli.installIsApplication"><![CDATA[Apps können per CLI nicht installiert werden.]]></item>
                <item name="wcf.acp.package.error.exceedsPhpLimit"><![CDATA[Die Datei ist größer als das PHP-Limit „upload_max_filesize“ und/oder „post_max_size“.]]></item>
-               <item name="wcf.acp.package.error.noUniqueAbbrevation"><![CDATA[Es ist bereits eine App installiert, die die gleiche Abkürzung besitzt.]]></item>
+               <item name="wcf.acp.package.error.noUniqueAbbreviation"><![CDATA[Es ist bereits eine App installiert, die die gleiche Abkürzung besitzt.]]></item>
                <item name="wcf.acp.package.error.noValidPackage"><![CDATA[Das angegebene Archiv ist kein gültiges Paket.]]></item>
                <item name="wcf.acp.package.error.sql.createTable"><![CDATA[Existierende Tabellen überschreiben]]></item>
                <item name="wcf.acp.package.error.sql.createTable.description"><![CDATA[Die oben genannten Tabellen existieren bereits und werden beim Fortfahren der Installation überschrieben. Alle Daten dieser Tabellen gehen unwiderruflich verloren.]]></item>
@@ -1899,6 +1914,9 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.package.update.excludedPackages.excluding.package"><![CDATA[„{$excludedPackage[packageName]}“ in Version „{$excludedPackage[packageVersion]}“ ist mit dem bereits installieren Paket „{$excludedPackage[existingPackageName]}“ nicht kompatibel]]></item>
                <item name="wcf.acp.package.update.path.incoherent"><![CDATA[Das Update erfordert eine Aktualisierung des Paketes „{$packageName}“ (installierte Version: {$currentVersion}) auf Version {$newVersion}, es wurden aber keine passenden Updates gefunden.]]></item>
                <item name="wcf.acp.package.update.path.unknown"><![CDATA[Das Update erfordert eine Aktualisierung des Paketes „{$packageName}“ (installierte Version: {$currentVersion}) auf Version {$newVersion}, es wurden aber keine verfügbaren Updates gefunden. Möglicherweise fehlt der passende Paket-Server?]]></item>
+               <item name="wcf.acp.package.update.purchaseRequired"><![CDATA[Kostenpflichtiges Paket]]></item>
+               <item name="wcf.acp.package.update.purchaseRequired.button.purchase"><![CDATA[Im Plugin-Store anzeigen]]></item>
+               <item name="wcf.acp.package.update.purchaseRequired.description"><![CDATA[Das Paket „{$packageName}“ ist kostenpflichtig und muss zuvor im Plugin-Store erworben werden.]]></item>
                <item name="wcf.acp.package.version"><![CDATA[Version]]></item>
                <item name="wcf.acp.package.packageDir.input"><![CDATA[Installationsverzeichnis]]></item>
                <item name="wcf.acp.package.upload"><![CDATA[Paket hochladen]]></item>
@@ -1926,6 +1944,8 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.package.validation.errorCode.13"><![CDATA[Die API-Version „{$version}“ ist ungültig.]]></item>
                <item name="wcf.acp.package.validation.errorCode.14"><![CDATA[Das Paket wurde für eine {if $isOlderVersion}ältere{else}neuere{/if} Version von WoltLab Suite entwickelt und ist nicht kompatibel.]]></item>
                <item name="wcf.acp.package.validation.errorCode.15"><![CDATA[Das Paket verfügt über keine Angaben zur API-Kompatibilität, eine Installation  mit aktivierten Entwickler-Werkzeugen ist daher nicht möglich.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.16"><![CDATA[Neben der &lt;void/&gt;-Anweisung werden weitere Package Installation Plugins angegeben.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.17"><![CDATA[Die &lt;void/&gt;-Anweisung ist in den Installations-Anweisungen unzulässig.]]></item>
                <item name="wcf.acp.package.validation.failed"><![CDATA[Das hochgeladene Paket kann nicht installiert werden, bitte {if LANGUAGE_USE_INFORMAL_VARIANT}beachte{else}beachten Sie{/if} das unten stehende Prüfungsergebnis.]]></item>
                <item name="wcf.acp.package.evaluation.expired"><![CDATA[Die Testphase von <strong>{$packageName}</strong> ist abgelaufen. Bitte aktualisiere{if !LANGUAGE_USE_INFORMAL_VARIANT}n Sie{/if} auf die aktuellste Version um diese Software weiterhin legal betreiben zu können.{if $pluginStoreFileID || $isWoltLab}<br>{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} die aktuelle Version sicher und bequem <strong>{if $pluginStoreFileID}<a href="https://pluginstore.woltlab.com/file/{$pluginStoreFileID}/">im WoltLab Plugin-Store</a>{else}<a href="https://www.woltlab.com/purchase/">auf WoltLab.com</a>{/if}</strong> erwerben.{/if}]]></item>
                <item name="wcf.acp.package.evaluation.pending"><![CDATA[Bei den folgenden installierten Apps handelt es sich um Testversionen, die am <strong>{$evaluationEndDate|plainTime}</strong> ({@$evaluationEndDate|dateDiff:TIME_NOW:true}) ablaufen. Mit Ablauf der Frist deaktiviert sich die App automatisch, es ist dann notwendig diese auf die endgültige Version zu aktualisieren, um den legalen Betrieb fortzusetzen.
@@ -1941,6 +1961,7 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.package.search.status.loading"><![CDATA[Suche läuft …]]></item>
                <item name="wcf.acp.package.search.status.noResults"><![CDATA[Die Suche ergab keine Treffer.]]></item>
                <item name="wcf.acp.package.search.status.refreshDatabase"><![CDATA[Die Paketlisten werden aktualisiert …]]></item>
+               <item name="wcf.acp.package.search.result.official"><![CDATA[{if $count === 0}Keine{elseif $count === 1}Ein{else}{#$count}{/if} Treffer in offiziellen WoltLab®-Paketen]]></item>
                <item name="wcf.acp.package.search.result.thirdParty"><![CDATA[{if $count === 0}Keine{elseif $count === 1}Ein{else}{#$count}{/if} Treffer in Paketquellen von Drittanbietern]]></item>
                <item name="wcf.acp.package.search.result.trusted"><![CDATA[{if $count === 0}Keine{elseif $count === 1}Ein{else}{#$count}{/if} Treffer in offiziellen Paketquellen]]></item>
                <item name="wcf.acp.package.error.databaseChange"><![CDATA[Das Datenbanklayout konnte aufgrund folgender Fehler nicht aktualisiert werden:
@@ -1963,6 +1984,8 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                Der Primärindex {$error[tableName]} ({$error[columnNames]}) enthält die Spalte {$error[columnName]}, deren Werte NULL sein können.
        {else if $error[type] === 'foreignForeignKeyDrop'}
                Der Fremdschlüssel {$error[tableName]} ({$error[columnNames]}) gehört zu einem anderen Paket und kann deshalb nicht gelöscht werden.
+       {else if $error[type] === 'unknownTableInForeignKey'}
+               Der Fremdschlüssel {$error[tableName]} ({$error[columnNames]}) referenziert eine unbekannte Tabelle {$error[referencedTableName]}.
        {else}
                Unbekannter Fehler.
        {/if}
@@ -2083,7 +2106,7 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.pluginStore.purchasedItems.status.install.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} das Produkt <span class="confirmationObject">{$product[packageName]}</span> wirklich installieren?]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.updateServer.disabled"><![CDATA[Der Paket-Server für „{$wcfMajorRelease}“ („http://store.woltlab.com/{$wcfMajorRelease}/“) ist deaktiviert und steht weder für Neuinstallation noch Updates zur Verfügung.]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.updateServer.missing"><![CDATA[Der Paket-Server für „{$wcfMajorRelease}“ ist bei {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} nicht eingetragen. Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} die unten stehenden Pakete installieren {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, {if LANGUAGE_USE_INFORMAL_VARIANT}musst du{else}müssen Sie{/if} diesen zuvor <a href="{link controller='PackageUpdateServerAdd'}{/link}">hinzufügen</a>.<br>Die Adresse des Servers lautet: „http://store.woltlab.com/{$wcfMajorRelease}/“]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.requireUpdate"><![CDATA[Der Paket-Server für „{$wcfMajorRelease}“ („http://store.woltlab.com/{$wcfMajorRelease}/“) wurde noch nicht abgefragt, bitte {if LANGUAGE_USE_INFORMAL_VARIANT}lass{else}lassen Sie{/if} zuerst nach Updates suchen, um den Server abzufragen.]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.requireUpdate"><![CDATA[Die Paket-Server wurden noch nicht vollständig abgefragt, bitte {if LANGUAGE_USE_INFORMAL_VARIANT}lass{else}lassen Sie{/if} zuerst nach Updates suchen.]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.wcfMajorRelease"><![CDATA[Paket-Server für „{$wcfMajorRelease}“]]></item>
        </category>
        <category name="wcf.acp.pip">
@@ -2340,11 +2363,11 @@ Die Datenbestände werden sorgfältig gepflegt, aber es ist nicht ausgeschlossen
                <item name="wcf.acp.pip.acpSearchProvider.providerName.error.tooFewSegments"><![CDATA[Der angegebene Name enthält nur {#$segmentCount} Abschnitt{if $segmentCount > 1}e{/if}.]]></item>
                <item name="wcf.acp.pip.acpSearchProvider.showOrder.description"><![CDATA[Der angegebene Wert bestimmt in welcher Reihenfolge die verschiedenen Arten von Suchergebnisse angezeigt werden.]]></item>
                <item name="wcf.acp.pip.eventListener.environment"><![CDATA[Umgebung]]></item>
-               <item name="wcf.acp.pip.eventListener.environment.description"><![CDATA[Die Umgebung entscheidet, ob der Event-Listener im Frontend (<kbd>user</kbd>) oder in der Administrationsoberfläche (<kbd>admin</kbd>) ausgeführt wird.]]></item>
+               <item name="wcf.acp.pip.eventListener.environment.description"><![CDATA[Die Umgebung entscheidet, ob der Event-Listener im Frontend (<kbd>user</kbd>), in der Administrationsoberfläche (<kbd>admin</kbd>) oder in beiden Umgebungen (<kbd>all</kbd>) ausgeführt wird.]]></item>
                <item name="wcf.acp.pip.eventListener.eventClassName"><![CDATA[PHP-Event-Klasse]]></item>
                <item name="wcf.acp.pip.eventListener.eventClassName.description"><![CDATA[Die angegebene Klasse (ohne Backslash als erstes Zeichen) feuert das Event ab. Alternativ erbt die angegebene Klasse von der Klasse, die das Event abfeuert,]]></item>
-               <item name="wcf.acp.pip.eventListener.eventName"><![CDATA[Eventname]]></item>
-               <item name="wcf.acp.pip.eventListener.eventName.description"><![CDATA[Name des Events der relevanten Klasse, auf das der Event-Listener reagiert.]]></item>
+               <item name="wcf.acp.pip.eventListener.eventName"><![CDATA[Eventnamen]]></item>
+               <item name="wcf.acp.pip.eventListener.eventName.description"><![CDATA[Namen der Events der relevanten Klasse, auf die der Event-Listener reagiert.]]></item>
                <item name="wcf.acp.pip.eventListener.inherit"><![CDATA[Vererbung unterstützen]]></item>
                <item name="wcf.acp.pip.eventListener.inherit.description"><![CDATA[Wird Vererbung unterstützt, reagiert der Event-Listener nicht nur, wenn das Event von der oben angegebenen Klasse ausgelöst wird, sondern auch wenn es von Kindklassen der angegebenen Klasse ausgelöst wird.]]></item>
                <item name="wcf.acp.pip.eventListener.listenerClassName"><![CDATA[PHP-Event-Listener-Klasse]]></item>
@@ -2626,8 +2649,6 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.poll.description"><![CDATA[Aktualisiert Zähler der Umfragen]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.article"><![CDATA[Artikel aktualisieren]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.article.description"><![CDATA[Aktualisiert den Suchindex für Artikel]]></item>
-               <item name="wcf.acp.rebuildData.com.woltlab.wcf.databaseConvertEncoding"><![CDATA[Datenbank-Kodierung konvertieren]]></item>
-               <item name="wcf.acp.rebuildData.com.woltlab.wcf.databaseConvertEncoding.description"><![CDATA[Warnung: Die Ausführung dieser Aktion kann bei umfangreichen Datenbanken sehr lange dauern.]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.comment"><![CDATA[Kommentare aktualisieren]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.comment.description"><![CDATA[Aktualisiert die Kommentare]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.comment.response"><![CDATA[Antworten auf Kommentare aktualisieren]]></item>
@@ -2758,21 +2779,26 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.systemCheck.mysql.innodb.description"><![CDATA[InnoDB (XtraDB unter MariaDB) ist eine transaktionale Storage-Engine von MySQL und wird zwingend für den Betrieb benötigt. Dies ist eine Standardfunktion von MySQL.]]></item>
                <item name="wcf.acp.systemCheck.directories.writable"><![CDATA[Beschreibbare Verzeichnisse]]></item>
                <item name="wcf.acp.systemCheck.directories.writable.description"><![CDATA[Einige Verzeichnisse werden zur Laufzeit durch die Software beschrieben, der PHP-Benutzer muss Schreibrechte haben.]]></item>
+               <item name="wcf.acp.systemCheck.php.gd"><![CDATA[Unterstützte Formate der GD-Bibliothek]]></item>
+               <item name="wcf.acp.systemCheck.php.gd.description"><![CDATA[Die GD-Bibliothek muss inklusive der Unterstützung der Formate „jpeg“ und „png“ installiert sein.]]></item>
        </category>
        <category name="wcf.acp.updateServer">
                <item name="wcf.acp.updateServer.add"><![CDATA[Server hinzufügen]]></item>
                <item name="wcf.acp.updateServer.delete.sure"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Server <span class="confirmationObject">{$updateServer->serverURL}</span> wirklich löschen?]]></item>
                <item name="wcf.acp.updateServer.edit"><![CDATA[Server bearbeiten]]></item>
                <item name="wcf.acp.updateServer.errorMessage"><![CDATA[Fehlermeldungen]]></item>
-               <item name="wcf.acp.updateServer.list"><![CDATA[Update-Server]]></item>
+               <item name="wcf.acp.updateServer.list"><![CDATA[Paket-Server]]></item>
                <item name="wcf.acp.updateServer.lastErrorMessage"><![CDATA[Beim letzten Verbindungsversuch trat folgender Fehler auf:]]></item>
                <item name="wcf.acp.updateServer.loginPassword"><![CDATA[Kennwort]]></item>
                <item name="wcf.acp.updateServer.loginPassword.description"><![CDATA[Kennwort für Authentifizierung (optional)]]></item>
+               <item name="wcf.acp.updateServer.loginPassword.noChange"><![CDATA[(keine Änderung)]]></item>
                <item name="wcf.acp.updateServer.loginUsername"><![CDATA[Benutzername]]></item>
                <item name="wcf.acp.updateServer.loginUsername.description"><![CDATA[Benutzernamen für Authentifizierung (optional)]]></item>
                <item name="wcf.acp.updateServer.packages"><![CDATA[Pakete]]></item>
                <item name="wcf.acp.updateServer.serverURL"><![CDATA[Adresse]]></item>
                <item name="wcf.acp.updateServer.serverURL.error.invalid"><![CDATA[Die eingetragene Adresse ist ungültig.]]></item>
+               <item name="wcf.acp.updateServer.serverURL.error.woltlab"><![CDATA[Die offiziellen Paketserver sind bereits hinterlegt und korrekt konfiguriert.]]></item>
+               <item name="wcf.acp.updateServer.serverURL.error.duplicate"><![CDATA[Dieser Paketserver ist bereits hinterlegt. {if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} <a href="{link controller="PackageUpdateServerEdit" id=$errorType[duplicate]->packageUpdateServerID}{/link}"><strong>den bestehenden Paketserver bearbeiten</strong></a>.]]></item>
                <item name="wcf.acp.updateServer.status"><![CDATA[Status]]></item>
                <item name="wcf.acp.updateServer.lastUpdateTime"><![CDATA[Letzter Zugriff]]></item>
        </category>
@@ -2827,6 +2853,7 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.style.advanced.overrideScss.error.invalid"><![CDATA[Eingabe „{$error[text]}“ ungültig]]></item>
                <item name="wcf.acp.style.advanced.overrideScss.error.predefined"><![CDATA[Variable „{$error[text]}“ wird bereits durch den Stil-Editor gesetzt]]></item>
                <item name="wcf.acp.style.advanced.overrideScss.error.unknown"><![CDATA[Variable „{$error[text]}“ unbekannt]]></item>
+               <item name="wcf.acp.style.advanced.individualScss.error"><![CDATA[Der SCSS-Code enthält einen Fehler: {$errorType.message}.]]></item>
                <item name="wcf.acp.style.apiVersion"><![CDATA[Kompatibilität mit WoltLab Suite in Version]]></item>
                <item name="wcf.acp.style.apiVersion.deprecated"><![CDATA[veraltet]]></item>
                <item name="wcf.acp.style.apiVersion.description"><![CDATA[Deaktiviert ausgewählte Stil-Verbesserungen, um die Kompatibilität mit Stilen für eine ältere Version von WoltLab Suite zu gewährleisten.]]></item>
@@ -2866,6 +2893,8 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.style.coverPhoto"><![CDATA[Standard-Titelbild]]></item>
                <item name="wcf.acp.style.coverPhoto.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} das Standard-Titelbild dieses Stils wirklich löschen? Nach dem Löschen wird das allgemeine, Stil-unabhängige Standard-Titelbild verwendet.]]></item>
                <item name="wcf.acp.style.coverPhoto.description"><![CDATA[Das Bild muss mindestens {$coverPhotoMinWidth}×{$coverPhotoMinHeight} Pixel groß sein, als Bildformate sind GIF, JPG, JPEG und PNG zulässig.]]></item>
+               <item name="wcf.acp.style.customAssets"><![CDATA[Zusätzliche Bilder]]></item>
+               <item name="wcf.acp.style.customAssets.description"><![CDATA[{literal}Die hochgeladenen Bilder werden unter demselben Dateinamen im <kbd>custom/</kbd>-Ordner innerhalb des Stil-Ordners gespeichert. Im CSS muss der Ordner mit der Variable <kbd>#{$style_image_path}custom/</kbd> verlinkt werden.{/literal}]]></item>
                <item name="wcf.acp.style.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Stil <span class="confirmationObject">{$style->styleName}</span> wirklich löschen?]]></item>
                <item name="wcf.acp.style.edit"><![CDATA[Stil bearbeiten]]></item>
                <item name="wcf.acp.style.exportAsPackage"><![CDATA[Als Paket exportieren]]></item>
@@ -2892,6 +2921,7 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.style.globalValues"><![CDATA[Stilunabhängiges CSS und SCSS]]></item>
                <item name="wcf.acp.style.globalValues.description"><![CDATA[Das unten stehende CSS und SCSS wird auf alle Stile angewandt, die individuelle Anpassungen in den Stilen sind jedoch höherwertig.]]></item>
                <item name="wcf.acp.style.globalValues.input"><![CDATA[Individuelles CSS und SCSS]]></item>
+               <item name="wcf.acp.style.globalValues.input.error"><![CDATA[Der SCSS-Code enthält einen Fehler: {$errorType.message}.]]></item>
                <item name="wcf.acp.style.image"><![CDATA[Vorschaubild]]></item>
                <item name="wcf.acp.style.image.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Lade{else}Laden Sie{/if} hier ein Vorschaubild dieses Stiles hoch, als Bildformate sind JPG und PNG zulässig. Es wird empfohlen Vorschaubilder immer mit der Größe 102×64 Pixel anzulegen, größere Grafiken werden automatisch skaliert.]]></item>
                <item name="wcf.acp.style.image2x"><![CDATA[Vorschaubild (HD)]]></item>
@@ -2921,7 +2951,6 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.style.styleVersion"><![CDATA[Version]]></item>
                <item name="wcf.acp.style.templateGroupID"><![CDATA[Templategruppe]]></item>
                <item name="wcf.acp.style.users"><![CDATA[Benutzer]]></item>
-               <item name="wcf.acp.style.image.error.invalidExtension"><![CDATA[Die Datei hat eine ungültige Dateiendung.]]></item>
                <item name="wcf.acp.style.imagePath.error.invalid"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} einen ungültigen Pfad eingegeben.]]></item>
                <item name="wcf.acp.style.styleVersion.error.invalid"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} eine ungültige Versionsnummer eingegeben.]]></item>
                <item name="wcf.acp.style.styleDate.error.invalid"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} ein ungültiges Datum eingegeben.]]></item>
@@ -2936,14 +2965,15 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.style.globals.fontSizeHeadline"><![CDATA[Schriftgröße (Überschrift)]]></item>
                <item name="wcf.acp.style.globals.fontSizeSection"><![CDATA[Schriftgröße (Sektions-Überschrift)]]></item>
                <item name="wcf.acp.style.globals.fontSizeTitle"><![CDATA[Schriftgröße (Seiten-Titel)]]></item>
-               <item name="wcf.acp.style.globals.useGoogleFont"><![CDATA[Google-Schriftart aktivieren]]></item>
                <item name="wcf.acp.style.globals.fontFamilyGoogle"><![CDATA[Schriftart]]></item>
+               <item name="wcf.acp.style.globals.fontFamilyGoogle.description"><![CDATA[Die angegebene Schriftart wird beim Speichern des Stils heruntergeladen und zwischengespeichert. Benutzer beziehen die Schriftart datenschutzkonform anschließend direkt von {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Seite.]]></item>
+               <item name="wcf.acp.style.globals.fontFamilyGoogle.error.downloadFailed"><![CDATA[Der Download der Schriftart ist fehlgeschlagen.]]></item>
+               <item name="wcf.acp.style.globals.fontFamilyGoogle.error.downloadFailed.notFound"><![CDATA[Die angegebene Schriftart konnte nicht gefunden werden.]]></item>
                <item name="wcf.acp.style.globals.fontFamilyFallback"><![CDATA[Schriftart (Fallback)]]></item>
                <item name="wcf.acp.style.general.favicon"><![CDATA[Favicon]]></item>
                <item name="wcf.acp.style.favicon"><![CDATA[Individuelles Favicon]]></item>
                <item name="wcf.acp.style.favicon.description"><![CDATA[Laden Sie hier ein 256×256 Pixel großes Bild hoch, als Bildformate sind JPG und PNG zulässig. Das hochgeladene Bild wird für die Erzeugung aller notwendigen Grafiken verwendet.]]></item>
                <item name="wcf.acp.style.favicon.error.dimensions"><![CDATA[Das Bild muss exakt 256×256 Pixel groß sein.]]></item>
-               <item name="wcf.acp.style.favicon.error.invalidExtension"><![CDATA[Die Datei hat eine ungültige Dateiendung.]]></item>
        </category>
        <category name="wcf.acp.tag">
                <item name="wcf.acp.tag.add"><![CDATA[Tag hinzufügen]]></item>
@@ -3042,7 +3072,6 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.user.search.display.itemsPerPage"><![CDATA[Benutzer pro Seite]]></item>
                <item name="wcf.acp.user.search.display.sort"><![CDATA[Sortierung]]></item>
                <item name="wcf.acp.user.search.error.noMatches"><![CDATA[Zu den angegebenen Kriterien wurde kein Benutzer gefunden.]]></item>
-               <item name="wcf.acp.user.search.matches"><![CDATA[{if $items == 1}Ein Ergebnis{else}{#$items} Ergebnisse{/if}]]></item>
                <item name="wcf.acp.user.sendMail"><![CDATA[E-Mail an Benutzer senden]]></item>
                <item name="wcf.acp.user.sendMail.all"><![CDATA[E-Mail an alle Benutzer senden]]></item>
                <item name="wcf.acp.user.sendMail.enableHTML"><![CDATA[E-Mail als HTML versenden]]></item>
@@ -3149,9 +3178,10 @@ Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} unter „Konfiguration 
                <item name="wcf.acp.user.disable"><![CDATA[Deaktivieren]]></item>
                <item name="wcf.acp.user.enable"><![CDATA[Aktivieren]]></item>
                <item name="wcf.acp.user.quickSearch.disabled"><![CDATA[Nicht aktivierte Benutzer]]></item>
+               <item name="wcf.acp.user.quickSearch.pendingActivation"><![CDATA[Benutzer die auf Freischaltung warten]]></item>
                <item name="wcf.acp.user.quickSearch.disabledAvatars"><![CDATA[Gesperrte Avatare]]></item>
                <item name="wcf.acp.user.quickSearch.disabledSignatures"><![CDATA[Gesperrte Signaturen]]></item>
-               <item name="wcf.acp.user.usersAwaitingApprovalInfo"><![CDATA[<a href="{link controller='UserQuickSearch'}mode=disabled{/link}">{#$usersAwaitingApproval} Benutzer</a> {if $usersAwaitingApproval == 1}wartet auf seine{else}warten auf ihre{/if} Aktivierung.]]></item>
+               <item name="wcf.acp.user.usersAwaitingApprovalInfo"><![CDATA[<a href="{link controller='UserQuickSearch'}mode=pendingActivation{/link}">{#$usersAwaitingApproval} Benutzer</a> {if $usersAwaitingApproval == 1}wartet auf seine{else}warten auf ihre{/if} Aktivierung.]]></item>
                <item name="wcf.acp.user.search.conditions.state.enabled"><![CDATA[Aktiviert]]></item>
                <item name="wcf.acp.user.search.conditions.state.disabled"><![CDATA[Nicht aktiviert]]></item>
                <item name="wcf.acp.user.sendNewPassword.mail.subject"><![CDATA[Neues Kennwort für {if LANGUAGE_USE_INFORMAL_VARIANT}dein{else}Ihr{/if} Benutzerkonto auf der Website: {@PAGE_TITLE|language}]]></item>
@@ -3205,11 +3235,13 @@ freigeschaltet. {if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if
                <item name="wcf.acp.user.bulkProcessing.removeFromUserGroups"><![CDATA[Aus Benutzergruppen entfernen]]></item>
                <item name="wcf.acp.user.bulkProcessing.sendMail"><![CDATA[E-Mail an Benutzer senden]]></item>
                <item name="wcf.acp.user.bulkProcessing.success"><![CDATA[Die gewählte Aktion wurde auf {#$affectedObjectCount} Benutzer ausgeführt.]]></item>
-               <item name="wcf.acp.user.bulkProcessing.warning"><![CDATA[Die Massenbearbeitung von Benutzern führt die unten ausgewählte Aktion <b>ohne zusätzliche Sicherheitsabfrage</b> bei allen Benutzern aus, die unter die eingestellten Bedingungen fallen.]]></item>
+               <item name="wcf.acp.user.bulkProcessing.warning"><![CDATA[Die Massenbearbeitung von Benutzern führt die unten ausgewählte Aktion <strong>ohne zusätzliche Sicherheitsabfrage</strong> bei allen Benutzern aus, die unter die eingestellten Bedingungen fallen.]]></item>
                <item name="wcf.acp.user.profileMenu.sort"><![CDATA[Benutzerprofil-Menü Sortierung]]></item>
                <item name="wcf.acp.user.action.sendMail"><![CDATA[E-Mail senden]]></item>
                <item name="wcf.acp.user.action.sendNewPassword"><![CDATA[Neues Passwort zusenden]]></item>
                <item name="wcf.acp.user.action.sendNewPassword.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} diesem Benutzer wirklich ein neues Kennwort zusenden?]]></item>
+               <item name="wcf.acp.user.action.confirmEmail"><![CDATA[E-Mail-Adresse bestätigen]]></item>
+               <item name="wcf.acp.user.action.unconfirmEmail"><![CDATA[Bestätigung der E-Mail-Adresse widerrufen]]></item>
                <item name="wcf.acp.user.exportGdpr"><![CDATA[Persönliche Daten exportieren (DSGVO)]]></item>
                <item name="wcf.acp.user.coverPhoto.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} ein Titelbild im Profil des Benutzers hochladen.]]></item>
        </category>
@@ -3256,9 +3288,13 @@ freigeschaltet. {if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if
                <item name="wcf.article.search.results"><![CDATA[Suchergebnisse]]></item>
                <item name="wcf.article.publicationStatus.0"><![CDATA[Dieser Artikel wurde noch nicht veröffentlicht.]]></item>
                <item name="wcf.article.publicationStatus.2"><![CDATA[Dieser Artikel wird am {@$publicationDate|plainTime} veröffentlicht.]]></item>
+               <item name="wcf.article.like.notification.title"><![CDATA[Reaktion auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel]]></item>
+               <item name="wcf.article.like.notification.title.stacked"><![CDATA[{#$count} Benutzer haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel reagiert]]></item>
+               <item name="wcf.article.like.notification.message"><![CDATA[<strong>{$author}</strong> hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel <strong>{$article->getTitle()}</strong> reagiert ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
+               <item name="wcf.article.like.notification.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel <strong>{$article->getTitle()}</strong> reagiert ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
        </category>
        <category name="wcf.attachment">
-               <item name="wcf.attachment.file.info"><![CDATA[({@$attachment->filesize|filesize}, <b>{#$attachment->downloads}</b> Mal heruntergeladen{if $attachment->downloads > 0}, zuletzt: {@$attachment->lastDownloadTime|time}{/if})]]></item>
+               <item name="wcf.attachment.file.info"><![CDATA[({@$attachment->filesize|filesize}, <strong>{#$attachment->downloads}</strong> Mal heruntergeladen{if $attachment->downloads > 0}, zuletzt: {@$attachment->lastDownloadTime|time}{/if})]]></item>
                <item name="wcf.attachment.image.info"><![CDATA[{@$attachment->filesize|filesize}, {#$attachment->width}×{#$attachment->height}, {#$attachment->downloads} Mal angesehen]]></item>
                <item name="wcf.attachment.files"><![CDATA[Dateien]]></item>
                <item name="wcf.attachment.images"><![CDATA[Bilder]]></item>
@@ -3352,9 +3388,12 @@ Fehler sind beispielsweise:
 - Nicht gefundene Befehle
 - Befehle, welche ihre Aktion nicht erfolgreich ausführen konnten
 - Systemfehler]]></item>
-               <item name="wcf.cli.help.packageID"><![CDATA[Die App mit der angegebenen Paket-ID wird als Standard für diese Sitzung verwendet.]]></item>
                <item name="wcf.cli.worker.setParameter"><![CDATA[Übergibt einen Parameter an den Worker. Bsp.: --setParameter param=wert]]></item>
                <item name="wcf.cli.worker.list"><![CDATA[Listet alle Worker auf.]]></item>
+               <item name="wcf.cli.worker.threads"><![CDATA[Gewünschte Anzahl von parallelen Prozessen.]]></item>
+               <item name="wcf.cli.worker.threads.windows"><![CDATA[Die parallele Verarbeitung mittels --threads steht unter Windows nicht zur Verfügung.]]></item>
+               <item name="wcf.cli.worker.threadId"><![CDATA[Gibt die Thread-ID während einer parallelen Verarbeitung an. Wird intern genutzt, wenn --threads gesetzt ist.]]></item>
+               <item name="wcf.cli.worker.threadId.invalid"><![CDATA[Die angegebene Thread-ID ist nicht gültig.]]></item>
                <item name="wcf.cli.error.help.noArguments"><![CDATA[Der Befehl "{$command}" unterstützt keine Parameter.]]></item>
                <item name="wcf.cli.error.language.notFound"><![CDATA[Die Sprache mit dem Sprachcode "{$languageCode}" konnte nicht gefunden werden.]]></item>
                <item name="wcf.cli.error.command.notFound"><![CDATA[Der Befehl "{$command}" konnte nicht gefunden werden. Benutze "commands", um verfügbare Befehle aufzulisten.]]></item>
@@ -3390,6 +3429,8 @@ Fehler sind beispielsweise:
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendMail"><![CDATA[E-Mail senden]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword"><![CDATA[Neues Kennwort senden ({#$count})]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} wirklich {if $count == 1}einem Benutzer{else}{#$count} Benutzern{/if} ein neues Kennwort zusenden?]]></item>
+               <item name="wcf.clipboard.item.com.woltlab.wcf.user.confirmEmail"><![CDATA[E-Mail-Adresse bestätigen ({#$count})]]></item>
+               <item name="wcf.clipboard.item.com.woltlab.wcf.user.unconfirmEmail"><![CDATA[Bestätigung der E-Mail-Adresse widerrufen ({#$count})]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.article.marked"><![CDATA[{if $count == 1}Ein{else}{#$count}{/if} Artikel]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.media.marked"><![CDATA[{if $count == 1}Eine Datei{else}{#$count} Dateien{/if}]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.tag.marked"><![CDATA[{if $count == 1}Ein Tag{else}{#$count} Tags{/if}]]></item>
@@ -3410,6 +3451,7 @@ Fehler sind beispielsweise:
                <item name="wcf.comment.guestDialog.title"><![CDATA[Gastkommentar]]></item>
                <item name="wcf.comment.sortField.cumulativeLikes"><![CDATA[Reaktionen]]></item>
                <item name="wcf.comment.sortField.time"><![CDATA[Datum]]></item>
+               <item name="wcf.comment.objectAuthor"><![CDATA[Autor]]></item>
        </category>
        <category name="wcf.condition">
                <item name="wcf.condition.greaterThan"><![CDATA[mehr als]]></item>
@@ -3445,7 +3487,7 @@ Dateianhänge:
 {/if}]]></item>
                <item name="wcf.contact.mail.html"><![CDATA[<h2>Hallo,</h2>
 
-<p>„{$name}“ hat {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} über das Kontaktformular auf Website <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> folgende Nachricht gesandt:</p>
+<p>„{$name}“ hat {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} über das Kontaktformular auf der Website <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> folgende Nachricht gesandt:</p>
 <p><br></p>
 <p>E-Mail-Adresse: <a href="mailto:{$emailAddress}">{$emailAddress}</a></p>
 {foreach from=$options item=option}
@@ -3849,6 +3891,7 @@ Dateianhänge:
                <item name="wcf.global.filter.visibility.showAll"><![CDATA[Alles anzeigen]]></item>
                <item name="wcf.global.success"><![CDATA[Die Aktion wurde erfolgreich ausgeführt.]]></item>
                <item name="wcf.global.success.add"><![CDATA[Der Eintrag wurde gespeichert.]]></item>
+               <item name="wcf.global.success.add.editCreatedObject"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} jetzt einen weiteren erstellen oder den <a href="{$objectEditLink}">zuvor erstellten Eintrag bearbeiten</a>.]]></item>
                <item name="wcf.global.success.edit"><![CDATA[Die Änderungen wurden gespeichert.]]></item>
                <item name="wcf.global.language.noSelection"><![CDATA[Keine Auswahl]]></item>
                <item name="wcf.global.loading"><![CDATA[Lädt …]]></item>
@@ -3885,7 +3928,7 @@ Dateianhänge:
                <item name="wcf.global.button.showAll"><![CDATA[Alle anzeigen]]></item>
                <item name="wcf.global.reason"><![CDATA[Begründung]]></item>
                <item name="wcf.global.settings"><![CDATA[Einstellungen]]></item>
-               <item name="wcf.global.bulkProcessing.warning"><![CDATA[Die Massenbearbeitung führt die unten ausgewählte Aktion <b>ohne zusätzliche Sicherheitsabfrage</b> aus!]]></item>
+               <item name="wcf.global.bulkProcessing.warning"><![CDATA[Die Massenbearbeitung führt die unten ausgewählte Aktion <strong>ohne zusätzliche Sicherheitsabfrage</strong> aus!]]></item>
                <item name="wcf.global.search"><![CDATA[Suche]]></item>
                <item name="wcf.global.select"><![CDATA[Auswählen]]></item>
                <item name="wcf.global.sorting"><![CDATA[Sortierung]]></item>
@@ -4021,14 +4064,14 @@ Dateianhänge:
                <item name="wcf.like.likes.noMoreEntries"><![CDATA[Keine weiteren Reaktionen]]></item>
                <item name="wcf.like.dislikes.more"><![CDATA[Weitere Dislikes]]></item>
                <item name="wcf.like.dislikes.noMoreEntries"><![CDATA[Keine weiteren Dislikes]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf den Kommentar {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">von {$commentAuthor->username}</a>{else}eines Gasts{/if} an der <a href="{$comment->getLink()}">Pinnwand von {$user->username}</a> reagiert.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment.response"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf die Antwort {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">von {$responseAuthor->username}</a>{else}eines Gasts{/if} zum Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} an der <a href="{$response->getLink()}">Pinnwand von {$user->username}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment"><![CDATA[Hat mit {@$reaction->render()} auf den Kommentar {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">von {$commentAuthor->username}</a>{else}eines Gasts{/if} an der <a href="{$comment->getLink()}">Pinnwand von {$user->username}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment.response"><![CDATA[Hat mit {@$reaction->render()} auf die Antwort {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">von {$responseAuthor->username}</a>{else}eines Gasts{/if} zum Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} an der <a href="{$response->getLink()}">Pinnwand von {$user->username}</a> reagiert.]]></item>
                <item name="wcf.like.objectType.com.woltlab.wcf.likeableArticle"><![CDATA[Artikel]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.likeableArticle"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf den Artikel <a href="{$article->getLink()}">{$article->getTitle()}</a> reagiert.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.articleComment"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf den Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zum Artikel <a href="{$comment->getLink()}">{$articleContent->getTitle()}</a> reagiert.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.articleComment.response"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf die Antwort {if $responseAuthor}von <a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}eines Gasts{/if} zum Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zum Artikel <a href="{$response->getLink()}">{$articleContent->getTitle()}</a> reagiert.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.pageComment"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf den Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zu der Seite <a href="{$comment->getLink()}">{$page->getTitle()}</a> reagiert.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.pageComment.response"><![CDATA[Hat mit <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> auf die Antwort {if $responseAuthor}von <a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}eines Gasts{/if} zum Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zu der Seite <a href="{$response->getLink()}">{$page->getTitle()}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.likeableArticle"><![CDATA[Hat mit {@$reaction->render()} auf den Artikel <a href="{$article->getLink()}">{$article->getTitle()}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.articleComment"><![CDATA[Hat mit {@$reaction->render()} auf den Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zum Artikel <a href="{$comment->getLink()}">{$articleContent->getTitle()}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.articleComment.response"><![CDATA[Hat mit {@$reaction->render()} auf die Antwort {if $responseAuthor}von <a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}eines Gasts{/if} zum Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zum Artikel <a href="{$response->getLink()}">{$articleContent->getTitle()}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.pageComment"><![CDATA[Hat mit {@$reaction->render()} auf den Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zu der Seite <a href="{$comment->getLink()}">{$page->getTitle()}</a> reagiert.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.pageComment.response"><![CDATA[Hat mit {@$reaction->render()} auf die Antwort {if $responseAuthor}von <a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}eines Gasts{/if} zum Kommentar {if $commentAuthor}von <a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}eines Gasts{/if} zu der Seite <a href="{$response->getLink()}">{$page->getTitle()}</a> reagiert.]]></item>
                <item name="wcf.like.reaction.label"><![CDATA[{#$reactions} Reaktion{if $reactions != 1}en{/if}]]></item>
                <item name="wcf.like.reaction.more"><![CDATA[Weitere Reaktionen]]></item>
                <item name="wcf.like.reaction.noMoreEntries"><![CDATA[Keine weiteren Reaktionen]]></item>
@@ -4056,6 +4099,7 @@ Dateianhänge:
        <category name="wcf.media">
                <item name="wcf.media.altText"><![CDATA[Alternativ-Text]]></item>
                <item name="wcf.media.button.insert"><![CDATA[Einfügen]]></item>
+               <item name="wcf.media.button.replaceFile"><![CDATA[Datei ersetzen]]></item>
                <item name="wcf.media.button.select"><![CDATA[Auswählen]]></item>
                <item name="wcf.media.caption"><![CDATA[Bildunterschrift]]></item>
                <item name="wcf.media.caption.enableHtml"><![CDATA[HTML in der Bildunterschrift verwenden]]></item>
@@ -4082,6 +4126,8 @@ Dateianhänge:
                <item name="wcf.media.media.pageTitle"><![CDATA[{if $__wcf->session->getPermission('admin.content.cms.canOnlyAccessOwnMedia')}Eigene {/if}Medien]]></item>
                <item name="wcf.media.search.cancel"><![CDATA[Suche abbrechen]]></item>
                <item name="wcf.media.search.placeholder"><![CDATA[Datei suchen]]></item>
+               <item name="wcf.media.upload.error.differentFileExtension"><![CDATA[Die neue Datei muss die gleiche Dateiendung haben wie die aktuelle Datei.]]></item>
+               <item name="wcf.media.upload.error.differentFileType"><![CDATA[Die neue Datei muss vom gleichen Dateityp sein wie die aktuelle Datei.]]></item>
                <item name="wcf.media.upload.error.noImage"><![CDATA[Die hochgeladene Datei ist kein Bild.]]></item>
                <item name="wcf.media.upload.error.uploadFailed"><![CDATA[Beim Hochladen der Datei ist ein unbekannter Fehler aufgetreten.]]></item>
                <item name="wcf.media.upload.success"><![CDATA[Die Datei wurde erfolgreich hochgeladen.]]></item>
@@ -4111,7 +4157,7 @@ Dateianhänge:
                <item name="wcf.message.quote.manageQuotes"><![CDATA[Zitate verwalten]]></item>
                <item name="wcf.message.quote.quoteSelected"><![CDATA[Zitat speichern]]></item>
                <item name="wcf.message.quote.quoteAndReply"><![CDATA[Zitat einfügen]]></item>
-               <item name="wcf.message.quote.showQuotes"><![CDATA[Zitate (#count#)]]></item>
+               <item name="wcf.message.quote.showQuotes"><![CDATA[{if $count == 1}Ein Zitat{else}{#$count} Zitate{/if}]]></item>
                <item name="wcf.message.quote.quoteMessage"><![CDATA[Zitieren]]></item>
                <item name="wcf.message.quote.removeAllQuotes"><![CDATA[Alle Zitate entfernen]]></item>
                <item name="wcf.message.quote.removeSelectedQuotes"><![CDATA[Markierte Zitate entfernen]]></item>
@@ -4140,6 +4186,10 @@ Dateianhänge:
                <item name="wcf.message.toc"><![CDATA[Inhaltsverzeichnis]]></item>
                <item name="wcf.message.toc.hide"><![CDATA[Verbergen]]></item>
                <item name="wcf.message.toc.show"><![CDATA[Anzeigen]]></item>
+               <item name="wcf.message.user.consent.button.enable"><![CDATA[Alle externen Inhalte anzeigen]]></item>
+               <item name="wcf.message.user.consent.description"><![CDATA[Inhalte von externen Seiten werden ohne {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Zustimmung nicht automatisch geladen und angezeigt.]]></item>
+               <item name="wcf.message.user.consent.notice"><![CDATA[Durch die Aktivierung der externen Inhalte {if LANGUAGE_USE_INFORMAL_VARIANT}erklärst du dich{else}erklären Sie sich{/if} damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.]]></item>
+               <item name="wcf.message.user.consent.title"><![CDATA[Externer Inhalt]]></item>
        </category>
        <category name="wcf.menu">
                <!-- category for menus and menu items -->
@@ -4154,6 +4204,8 @@ Dateianhänge:
                <item name="wcf.moderation.assignedUser.change"><![CDATA[Zugewiesenen Benutzer ändern]]></item>
                <item name="wcf.moderation.assignedUser.error.notAffected"><![CDATA[Dieser Benutzer hat unzureichende Zugriffsrechte]]></item>
                <item name="wcf.moderation.assignedUser.nobody"><![CDATA[Niemand]]></item>
+               <item name="wcf.moderation.assignedUsername"><![CDATA[Zugewiesener Benutzer]]></item>
+               <item name="wcf.moderation.filter"><![CDATA[Einträge filtern]]></item>
                <item name="wcf.moderation.filterByType"><![CDATA[Typ]]></item>
                <item name="wcf.moderation.filterByUser"><![CDATA[Zugewiesener Benutzer]]></item>
                <item name="wcf.moderation.filterByUser.allEntries"><![CDATA[Alle Einträge]]></item>
@@ -4166,14 +4218,14 @@ Dateianhänge:
                <item name="wcf.moderation.noMoreItems"><![CDATA[Keine weiteren Einträge]]></item>
                <item name="wcf.moderation.notification.comment.title"><![CDATA[Neuer Kommentar (Moderation)]]></item>
                <item name="wcf.moderation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Moderation)]]></item>
-               <item name="wcf.moderation.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zum Moderationseintrag <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.moderation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zum Moderationseintrag <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.moderation.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar zum Moderationseintrag <strong>{$moderationQueue}</strong> verfasst.]]></item>
+               <item name="wcf.moderation.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Kommentare zum Moderationseintrag <strong>{$moderationQueue}</strong> verfasst.]]></item>
                <item name="wcf.moderation.notification.comment.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zum Moderationseintrag {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] verfasst{if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}:{else}.{/if}]]></item>
                <item name="wcf.moderation.notification.comment.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zum Moderationseintrag <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.moderation.notification.commentResponse.title"><![CDATA[Neue Antwort (Moderation)]]></item>
                <item name="wcf.moderation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Moderation)]]></item>
-               <item name="wcf.moderation.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zum Moderationseintrag <a href="{@$moderationQueue->getLink()}#comment{@$commentID}/response{@$responseID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.moderation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Antworten zum Kommentar zum Moderationseintrag <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.moderation.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zum Kommentar von <strong>{$commentAuthor->username}</strong> zum Moderationseintrag <strong>{$moderationQueue}</strong> verfasst.]]></item>
+               <item name="wcf.moderation.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Antworten zum Kommentar zum Moderationseintrag <strong>{$moderationQueue}</strong> verfasst.]]></item>
                <item name="wcf.moderation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$notificationContent[variables][commentAuthor]->username}{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} zum Moderationseintrag {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.moderation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if} zum Moderationseintrag <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.moderation.status"><![CDATA[Status]]></item>
@@ -4203,6 +4255,9 @@ Dateianhänge:
                <item name="wcf.moderation.jumpToContent"><![CDATA[Zum Inhalt gehen]]></item>
                <item name="wcf.moderation.markAllAsRead"><![CDATA[Alle Einträge als gelesen markieren]]></item>
                <item name="wcf.moderation.markAsRead.doubleClick"><![CDATA[Eintrag durch Doppelklick als gelesen markieren]]></item>
+               <item name="wcf.moderation.comments"><![CDATA[Kommentare]]></item>
+               <item name="wcf.moderation.username"><![CDATA[Autor]]></item>
+               <item name="wcf.moderation.noEntries"><![CDATA[Es wurden keine Einträge gefunden. <a href="#" class="jsStaticDialog" data-dialog-id="moderationListSortFilter" role="button">Die Filter anpassen.</a>{if $hasActiveFilter} <a href="{link controller='ModerationList'}{/link}">Die aktiven Filter zurücksetzen.</a>{/if}]]></item>
        </category>
        <category name="wcf.moderation.activation">
                <item name="wcf.moderation.activation"><![CDATA[Freischaltung]]></item>
@@ -4212,14 +4267,14 @@ Dateianhänge:
                <item name="wcf.moderation.activation.enableContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} diesen Inhalt wirklich freischalten?]]></item>
                <item name="wcf.moderation.activation.notification.comment.title"><![CDATA[Neuer Kommentar (Freischaltung)]]></item>
                <item name="wcf.moderation.activation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Freischaltung)]]></item>
-               <item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.moderation.activation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar zum freizuschaltenden Inhalt <strong>{$moderationQueue}</strong> verfasst.]]></item>
+               <item name="wcf.moderation.activation.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Kommentare zum freizuschaltenden Inhalt <strong>{$moderationQueue}</strong> verfasst.]]></item>
                <item name="wcf.moderation.activation.notification.comment.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zum freizuschaltenden Inhalt {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.moderation.activation.notification.comment.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zum freizuschaltenden Inhalt <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.moderation.activation.notification.commentResponse.title"><![CDATA[Neue Antwort (Freischaltung)]]></item>
                <item name="wcf.moderation.activation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Freischaltung)]]></item>
-               <item name="wcf.moderation.activation.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}#comment{@$commentID}/response{@$responseID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.moderation.activation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentaren zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.moderation.activation.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zum Kommentar von <strong>{$commentAuthor}</strong> zum freizuschaltenden Inhalt <strong>{$moderationQueue}</strong> verfasst.]]></item>
+               <item name="wcf.moderation.activation.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Antworten zu Kommentaren zum freizuschaltenden Inhalt <strong>{$moderationQueue}</strong> verfasst.]]></item>
                <item name="wcf.moderation.activation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$notificationContent[variables][commentAuthor]->username}{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} zum freizuschaltenden Inhalt {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.moderation.activation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if} zum freizuschaltenden Inhalt <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.moderation.activation.removeContent"><![CDATA[Inhalt löschen]]></item>
@@ -4231,14 +4286,14 @@ Dateianhänge:
                <item name="wcf.moderation.report.details"><![CDATA[Informationen]]></item>
                <item name="wcf.moderation.report.notification.comment.title"><![CDATA[Neuer Kommentar (Meldung)]]></item>
                <item name="wcf.moderation.report.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Meldung)]]></item>
-               <item name="wcf.moderation.report.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zur Meldung <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.moderation.report.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zur Meldung <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.moderation.report.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar zur Meldung <strong>{$moderationQueue}</strong> verfasst.]]></item>
+               <item name="wcf.moderation.report.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Kommentare zur Meldung <strong>{$moderationQueue}</strong> verfasst.]]></item>
                <item name="wcf.moderation.report.notification.comment.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zu der Meldung {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.moderation.report.notification.comment.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zu der Meldung <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.moderation.report.notification.commentResponse.title"><![CDATA[Neue Antwort (Meldung)]]></item>
                <item name="wcf.moderation.report.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Meldung)]]></item>
-               <item name="wcf.moderation.report.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zur Meldung <a href="{@$moderationQueue->getLink()}#comment{@$commentID}/response{@$responseID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.moderation.report.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentare zur Meldung <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.moderation.report.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zum Kommentar von <strong>{$commentAuthor}</strong> zur Meldung <strong>{$moderationQueue}</strong> verfasst.]]></item>
+               <item name="wcf.moderation.report.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Antworten zu Kommentare zur Meldung <strong>{$moderationQueue}</strong> verfasst.]]></item>
                <item name="wcf.moderation.report.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$notificationContent[variables][commentAuthor]->username}{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} zur Meldung {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.moderation.report.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if} zur Meldung <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.moderation.report.reason"><![CDATA[Grund der Meldung]]></item>
@@ -4319,7 +4374,7 @@ Dateianhänge:
                <item name="wcf.paidSubscription.confirmTOS"><![CDATA[Hiermit bestätige ich mein Einverständnis mit den <a href="{PAID_SUBSCRIPTION_TOS_URL}">Nutzungsbedingungen</a>]]></item>
                <item name="wcf.paidSubscription.button.moreInformation"><![CDATA[Mehr Informationen]]></item>
                <item name="wcf.paidSubscription.expiringSubscription.notification.title"><![CDATA[Ablaufende Mitgliedschaft]]></item>
-               <item name="wcf.paidSubscription.expiringSubscription.notification.message"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Mitgliedschaft „{$userNotificationObject->getTitle()}“ läuft {dateInterval start=$notification->time end=$userNotificationObject->endDate full=true format='sentence'} (am {$userNotificationObject->endDate|date:'d. F'}) ab.]]></item>
+               <item name="wcf.paidSubscription.expiringSubscription.notification.message"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Mitgliedschaft <strong>{$userNotificationObject->getTitle()}</strong> läuft {dateInterval start=$notification->time end=$userNotificationObject->endDate full=true format='sentence'} (am {$userNotificationObject->endDate|date:'d. F'}) ab.]]></item>
                <item name="wcf.paidSubscription.expiringSubscription.notification.mail.plaintext"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Mitgliedschaft „{@$subscription->getTitle()}“ läuft {dateInterval start=$notification->time end=$subscription->endDate full=true format='sentence'} (am {@$subscription->endDate|date:'d. F'}) ab.]]></item>
                <item name="wcf.paidSubscription.expiringSubscription.notification.mail.html"><![CDATA[<p>{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Mitgliedschaft „{$subscription->getTitle()}“ läuft <b>{dateInterval start=$notification->time end=$subscription->endDate full=true format='sentence'}</b> (am {$subscription->endDate|date:'d. F'}) ab.</p>]]></item>
        </category>
@@ -4359,6 +4414,7 @@ Dateianhänge:
                <item name="wcf.reactions.summary.noReactions"><![CDATA[Es gibt bisher keine Reaktionen dieses Types auf das Objekt.]]></item>
                <item name="wcf.reactions.summary.listReactions"><![CDATA[Reaktionen auflisten]]></item>
                <item name="wcf.reactions.react"><![CDATA[Reagieren]]></item>
+               <item name="wcf.reactions.reactionTypeCount"><![CDATA[{@$reaction->renderIcon()}&#x202F;×&#x202F;{#$count}]]></item>
        </category>
        <category name="wcf.reactionType">
                <item name="wcf.reactionType.title1"><![CDATA[Gefällt mir]]></item>
@@ -4482,6 +4538,7 @@ Dateianhänge:
                <item name="wcf.user.usernameOrEmail"><![CDATA[Benutzername oder E-Mail-Adresse]]></item>
                <item name="wcf.user.gender.male"><![CDATA[Männlich]]></item>
                <item name="wcf.user.gender.female"><![CDATA[Weiblich]]></item>
+               <item name="wcf.user.gender.other"><![CDATA[Divers]]></item>
                <item name="wcf.user.members"><![CDATA[Mitglieder]]></item>
                <item name="wcf.user.members.filter"><![CDATA[Mitglieder filtern]]></item>
                <item name="wcf.user.members.noMembers"><![CDATA[Es wurden keine Mitglieder gefunden. <a href="{link controller='MembersList'}{/link}">Die aktiven Filter zurücksetzen.</a>]]></item>
@@ -4504,13 +4561,35 @@ Dateianhänge:
                <item name="wcf.user.styles"><![CDATA[Stile]]></item>
                <item name="wcf.user.style.description"><![CDATA[Stil der Benutzeroberfläche]]></item>
                <item name="wcf.user.username.description"><![CDATA[Der Benutzername muss mindestens {REGISTER_USERNAME_MIN_LENGTH} und darf maximal {REGISTER_USERNAME_MAX_LENGTH} Zeichen lang sein.]]></item>
-               <item name="wcf.user.password.description"><![CDATA[{if REGISTER_ENABLE_PASSWORD_SECURITY_CHECK}Das Kennwort muss aus Sicherheitsgründen mindestens {REGISTER_PASSWORD_MIN_LENGTH} Zeichen lang sein{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{*
-               *} und {*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}kleine Buchstaben{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} und{/if} {/if}große Buchstaben{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} und{/if} {/if}Zahlen{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT} und {/if}Sonderzeichen{/if} {*
-               *}enthalten{/if}.{else}Ein sicheres Kennwort sollte mindestens 8 Zeichen lang sein.{/if}]]></item>
+               <item name="wcf.user.password.description"><![CDATA[Ein sicheres Kennwort sollte mindestens 10 Zeichen lang sein.]]></item>
+               <item name="wcf.user.password.strength"><![CDATA[Passwortstärke]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.use_words_avoid_common_phrases"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Verwende{else}Verwenden Sie{/if} einige Wörter. {if LANGUAGE_USE_INFORMAL_VARIANT}Vermeide{else}Vermeiden Sie{/if} gängige Phrasen.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.no_need_for_symbols_digits_uppercase"><![CDATA[Sonderzeichen, Zahlen oder Großbuchstaben werden nicht benötigt.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.add_word_uncommon_better"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Ergänze{else}Ergänzen Sie{/if} ein oder zwei weitere Worte. Unübliche Worte sind zu bevorzugen.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.use_longer_keyboard_pattern"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Verwende{else}Verwenden Sie{/if} ein längeres und zufälligeres Muster auf der Tastatur.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_repeat"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Vermeide{else}Vermeiden Sie{/if} Wiederholungen.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_sequence"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Vermeide{else}Vermeiden Sie{/if} Sequenzen.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_recent_year"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Vermeide{else}Vermeiden Sie{/if} Jahreszahlen der letzten Jahre.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_associated_year"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Vermeide{else}Vermeiden Sie{/if} Jahreszahlen, die {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} zugeordnet werden können.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_date"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Vermeide{else}Vermeiden Sie{/if} Daten und Jahreszahlen, die {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} zugeordnet werden können.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.start_upper"><![CDATA[Großbuchstaben zu Beginn erhöhen die Sicherheit nicht.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.all_upper"><![CDATA[Nur Großbuchstaben sind genau so einfach zu erraten, wie nur Kleinbuchstaben.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.reversed"><![CDATA[Umgekehrte Worte sind nicht viel schwieriger zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.l33t"><![CDATA[Vorhersehbare Ersetzungen, wie beispielsweise „@“ statt „a“, erhöhen die Sicherheit nicht.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.straight_row"><![CDATA[Geradlinige Sequenzen auf der Tastatur sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.short_keyboard_pattern"><![CDATA[Kurze Sequenzen auf der Tastatur sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.repeat_single_char"><![CDATA[Wiederholungen wie beispielsweise „aaa“ sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.repeat"><![CDATA[Wiederholungen wie beispielsweise „abcabcabc“ sind nicht viel schwieriger zu erraten als „abc“.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.sequence"><![CDATA[Sequenzen wie „abc“ oder „6543“ sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.recent_year"><![CDATA[Kürzliche Jahreszahlen sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.date"><![CDATA[Daten sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.top_10"><![CDATA[Dies ist eines der 10 häufigsten Kennwörter.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.top_100"><![CDATA[Dies ist eines der 100 häufigsten Kennwörter.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.common"><![CDATA[Dies ist ein sehr häufiges Kennwort.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.common_alike"><![CDATA[Dies ist ähnlich zu einem sehr häufigen Kennwort.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.sole_word"><![CDATA[Ein einzelnes Wort ist einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.sole_name"><![CDATA[Alleinstehende Namen sind einfach zu erraten.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.name"><![CDATA[Häufige Namen sind einfach zu erraten.]]></item>
                <item name="wcf.user.lostPassword"><![CDATA[Kennwort vergessen]]></item>
                <item name="wcf.user.lostPassword.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Wenn du dein Kennwort vergessen hast, musst du entweder den Benutzernamen oder die E-Mail-Adresse angeben, die du in deinem Profil hinterlegt hast. Du kannst dabei nur eines der beiden Felder ausfüllen. Wenn du beide Daten nicht mehr weißt, wende dich bitte an den Administrator.{else}Wenn Sie Ihr Kennwort vergessen haben, müssen Sie entweder den Benutzernamen oder die E-Mail-Adresse angeben, die Sie in Ihrem Profil hinterlegt haben. Sie können dabei nur eines der beiden Felder ausfüllen. Wenn Sie beide Daten nicht mehr wissen, wenden Sie sich bitte an den Administrator.{/if}]]></item>
                <item name="wcf.user.lostPassword.email.error.notFound"><![CDATA[Es wurde kein Benutzer mit der E-Mail-Adresse: „{$email}“ gefunden.]]></item>
@@ -4560,20 +4639,14 @@ dann wird diese Anfrage am {$mailbox->getUser()->lastLostPasswordRequestTime+864
                <item name="wcf.user.quit.success"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Benutzerkonto wird am {TIME_NOW+7*86400|date} gelöscht. Bis dahin {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} die Löschung auf dieser Seite abbrechen.]]></item>
                <item name="wcf.user.quit.cancel.success"><![CDATA[Die Löschung {if LANGUAGE_USE_INFORMAL_VARIANT}deines{else}Ihres{/if} Benutzerkontos wurde erfolgreich abgebrochen.]]></item>
                <item name="wcf.user.emailActivation"><![CDATA[Neue E-Mail-Adresse aktivieren]]></item>
-               <item name="wcf.user.password.error.notSecure"><![CDATA[Das Kennwort muss aus Sicherheitsgründen mindestens {REGISTER_PASSWORD_MIN_LENGTH} Zeichen lang sein{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{*
-               *} und {*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}kleine Buchstaben{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} und{/if} {/if}große Buchstaben{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} und{/if} {/if}Zahlen{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT} und {/if}Sonderzeichen{/if} {*
-               *}enthalten{/if}.]]></item>
+               <item name="wcf.user.password.error.notSecure"><![CDATA[Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}wähle{else}wählen Sie{/if} ein sichereres Kennwort aus.]]></item>
                <item name="wcf.user.changeUsername.success"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Benutzername wurde erfolgreich geändert.]]></item>
                <item name="wcf.user.changeEmail.success"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} E-Mail-Adresse wurde erfolgreich geändert.]]></item>
                <item name="wcf.user.changeEmail.needReactivation"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} neue E-Mail-Adresse{if $newEmail|isset} („{$newEmail}“){/if} muss noch aktiviert werden. Dazu wurde eine E-Mail mit einem Aktivierungslink an die neue Adresse gesandt. {if LANGUAGE_USE_INFORMAL_VARIANT}Du musst{else}Sie müssen{/if} diesen Aktivierungslink aufrufen, um die neue E-Mail-Adresse zu aktivieren.]]></item>
                <item name="wcf.user.changeEmail.needReactivation.mail.subject"><![CDATA[Aktivierung der neuen E-Mail-Adresse auf der Website: {@PAGE_TITLE|language}]]></item>
                <item name="wcf.user.changeEmail.needReactivation.mail.html.headline"><![CDATA[Hallo {$mailbox->getUser()->username},]]></item>
                <item name="wcf.user.changeEmail.needReactivation.mail.html.intro"><![CDATA[
-<p>{if LANGUAGE_USE_INFORMAL_VARIANT}du hast deine{else}Sie haben Ihre{/if} E-Mail-Adresse auf der Website: <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> geändert. 
+<p>{if LANGUAGE_USE_INFORMAL_VARIANT}du hast deine{else}Sie haben Ihre{/if} E-Mail-Adresse auf der Website: <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> geändert.
 Zum Abschließen dieser Änderung {if LANGUAGE_USE_INFORMAL_VARIANT}musst du{else}müssen Sie{/if} einmalig die Gültigkeit der neuen E-Mail-Adresse bestätigen:</p>]]></item>
                <item name="wcf.user.changeEmail.needReactivation.mail.html.activate"><![CDATA[Neue E-Mail-Adresse aktivieren]]></item>
                <item name="wcf.user.changeEmail.needReactivation.mail.html.outro"><![CDATA[
@@ -4594,17 +4667,18 @@ Zum Abschließen dieser Änderung {if LANGUAGE_USE_INFORMAL_VARIANT}musst du{els
 dich{else}Sie
 sich{/if} nicht bei uns registriert {if LANGUAGE_USE_INFORMAL_VARIANT}hast{else}haben{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese E-Mail ignorieren.]]></item>
                <item name="wcf.user.changePassword.success"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Kennwort wurde erfolgreich geändert.]]></item>
-               <item name="wcf.user.activationCode"><![CDATA[9-stelliger Aktivierungscode]]></item>
+               <item name="wcf.user.activationCode"><![CDATA[Aktivierungscode]]></item>
                <item name="wcf.user.newActivationCode"><![CDATA[Neuen Aktivierungscode anfordern]]></item>
                <item name="wcf.user.registerActivation"><![CDATA[Registrierung abschließen]]></item>
                <item name="wcf.user.registerActivation.error.userAlreadyEnabled"><![CDATA[Dieser Benutzer ist bereits freigeschaltet.]]></item>
                <item name="wcf.user.registerActivation.success"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Benutzerkonto wurde erfolgreich freigeschaltet.]]></item>
+               <item name="wcf.user.registerActivation.success.awaitAdminActivation"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} E-Mail-Adresse wurde erfolgreich bestätigt. {if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Benutzerkonto muss nun noch von einem Administrator freigeschaltet werden.]]></item>
                <item name="wcf.user.activationCode.error.invalid"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} einen ungültigen Aktivierungscode eingegeben. {if LANGUAGE_USE_INFORMAL_VARIANT}Klicke auf den unten stehenden Link, falls du einen neuen Aktivierungscode anfordern möchtest.{else}Klicken Sie auf den unten stehenden Link, falls Sie einen neuen Aktivierungscode anfordern möchten.{/if}]]></item>
                <item name="wcf.user.registerNewActivationCode.email.description"><![CDATA[Optional {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} hier eine neue E-Mail-Adresse eintragen, an die der neue Aktivierungscode gesendet werden soll. {if LANGUAGE_USE_INFORMAL_VARIANT}Lasse{else}Lassen Sie{/if} dieses Feld frei, wenn der Aktivierungscode an die bestehende Adresse geschickt werden soll.]]></item>
                <item name="wcf.user.newActivationCode.success"><![CDATA[Eine E-Mail mit dem neuen Aktivierungscode wurde an {$email} versendet.]]></item>
                <item name="wcf.user.emailActivation.error.emailAlreadyEnabled"><![CDATA[Die neue E-Mail-Adresse ist bereits aktiviert.]]></item>
                <item name="wcf.user.emailActivation.success"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} neue E-Mail-Adresse wurde erfolgreich aktiviert.]]></item>
-               <item name="wcf.user.registerActivation.info"><![CDATA[Eine E-Mail mit dem 9-stelligen Aktivierungscode wurde an {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} E-Mail-Adresse {$__wcf->user->email} verschickt.]]></item>
+               <item name="wcf.user.registerActivation.info"><![CDATA[Eine E-Mail mit dem Aktivierungscode wurde an {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} E-Mail-Adresse {$__wcf->user->email} verschickt.]]></item>
                <item name="wcf.user.username.error.alreadyRenamed"><![CDATA[Der Benutzername wurde innerhalb der letzten {#$__wcf->getSession()->getPermission('user.profile.renamePeriod')} Tage bereits einmal verändert.]]></item>
                <item name="wcf.user.guest"><![CDATA[Gast]]></item>
                <item name="wcf.user.signature"><![CDATA[Signatur]]></item>
@@ -4706,11 +4780,11 @@ sich{/if} nicht bei uns registriert {if LANGUAGE_USE_INFORMAL_VARIANT}hast{else}
                <item name="wcf.user.register.needActivation.mail.subject"><![CDATA[Aktivierung der Registrierung auf der Website: {@PAGE_TITLE|language}]]></item>
                <item name="wcf.user.register.needActivation.mail.html.headline"><![CDATA[Hallo {$mailbox->getUser()->username},]]></item>
                <item name="wcf.user.register.needActivation.mail.html.intro"><![CDATA[
-<p>vielen Dank für {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Registrierung auf der Website: <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a>. Bevor {if LANGUAGE_USE_INFORMAL_VARIANT}du dein{else}Sie Ihr{/if} 
+<p>vielen Dank für {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Registrierung auf der Website: <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a>. Bevor {if LANGUAGE_USE_INFORMAL_VARIANT}du dein{else}Sie Ihr{/if} {* this line ends with a space *}
 Benutzerkonto vollständig verwenden {if LANGUAGE_USE_INFORMAL_VARIANT}kannst{else}können{/if}, ist es notwendig, dass {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} einmalig die Gültigkeit {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} E-Mail-Adresse {if LANGUAGE_USE_INFORMAL_VARIANT}bestätigst{else}bestätigen{/if}:</p>]]></item>
                <item name="wcf.user.register.needActivation.mail.html.activate"><![CDATA[Benutzerkonto aktivieren]]></item>
                <item name="wcf.user.register.needActivation.mail.html.outro"><![CDATA[
-<p>{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Aktivierungscode lautet: <kbd>{$mailbox->getUser()->activationCode}</kbd>.</p>
+<p>{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Aktivierungscode lautet: <kbd>{$mailbox->getUser()->emailConfirmed}</kbd>.</p>
 <p>Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} Probleme mit der Aktivierung {if LANGUAGE_USE_INFORMAL_VARIANT}deines{else}Ihres{/if} Benutzerkontos {if LANGUAGE_USE_INFORMAL_VARIANT}hast{else}haben{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}wende dich{else}wenden Sie sich{/if} bitte an den Administrator
 unter: <a href="mailto:{MAIL_ADMIN_ADDRESS}">{MAIL_ADMIN_ADDRESS}</a>. Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du dich{else}Sie sich{/if} nicht bei uns registriert {if LANGUAGE_USE_INFORMAL_VARIANT}hast{else}haben{/if},
 dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese E-Mail ignorieren.</p>]]></item>
@@ -4718,18 +4792,20 @@ dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese E-M
 
 vielen Dank für {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Registrierung auf der Website: {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}].
 Bevor {if LANGUAGE_USE_INFORMAL_VARIANT}du dein{else}Sie Ihr{/if} Benutzerkonto vollständig verwenden {if LANGUAGE_USE_INFORMAL_VARIANT}kannst{else}können{/if}, ist es notwendig,
-dass {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} einmalig durch Klicken des folgenden Links die Gültigkeit {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} 
+dass {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} einmalig durch Klicken des folgenden Links die Gültigkeit {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} {* this line ends with a space *}
 E-Mail-Adresse {if LANGUAGE_USE_INFORMAL_VARIANT}bestätigst{else}bestätigen{/if}:
 
-    {link controller='RegisterActivation' isEmail=true}u={@$mailbox->getUser()->userID}&a={@$mailbox->getUser()->activationCode}{/link} {* this line ends with a space *}
+    {link controller='RegisterActivation' isEmail=true}u={@$mailbox->getUser()->userID}&a={@$mailbox->getUser()->emailConfirmed}{/link} {* this line ends with a space *}
 
-{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Aktivierungscode lautet: {@$mailbox->getUser()->activationCode} {* this line ends with a space *}
+{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Aktivierungscode lautet: {@$mailbox->getUser()->emailConfirmed} {* this line ends with a space *}
 
 Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} Probleme mit der Aktivierung {if LANGUAGE_USE_INFORMAL_VARIANT}deines{else}Ihres{/if} Benutzerkontos {if LANGUAGE_USE_INFORMAL_VARIANT}hast{else}haben{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}wende
 dich{else}wenden
 Sie sich{/if} bitte an den Administrator unter: {@MAIL_ADMIN_ADDRESS}. Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du
 dich{else}Sie
 sich{/if} nicht bei uns registriert {if LANGUAGE_USE_INFORMAL_VARIANT}hast{else}haben{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese E-Mail ignorieren.]]></item>
+               <item name="wcf.user.register.needAdminActivation"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Dein{else}Ihr{/if} Benutzerkonto muss noch von einem Administrator freigeschaltet werden, um den vollen Funktionsumfang dieser Seite nutzen zu können.]]></item>
+               <item name="wcf.user.register.needEmailConfirmation"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} E-Mail-Adresse muss bestätigt werden. {if $__wcf->user->canEmailConfirm()}<a href="{link controller='RegisterNewActivationCode'}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}Bestätige jetzt deine{else}Bestätigen Sie jetzt Ihre{/if} E-Mail-Adresse</a>{else}{if LANGUAGE_USE_INFORMAL_VARIANT}Wende dich{else}Wenden Sie sich{/if} dafür direkt an den Administrator dieser Seite{/if}.]]></item>
                <!-- Success Messages -->
                <item name="wcf.user.register.success"><![CDATA[Vielen Dank für die Registrierung, {$user->username}. {if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Registrierung ist hiermit vollständig abgeschlossen.]]></item>
                <item name="wcf.user.register.success.needActivation"><![CDATA[Vielen Dank für die Registrierung, {$user->username}.<br>
@@ -4740,13 +4816,13 @@ Sobald {if LANGUAGE_USE_INFORMAL_VARIANT}dein{else}Ihr{/if} Benutzerkonto freige
                <item name="wcf.user.register.error.disabled"><![CDATA[Die Registrierung ist momentan deaktiviert.]]></item>
                <!-- Administrator Notification -->
                <item name="wcf.user.register.notification.mail"><![CDATA[Hallo Administrator,
-               
-auf der Website {@PAGE_TITLE|language} erfolgte eine neue Benutzeranmeldung durch: {@$user->username} 
 
-Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email} 
+auf der Website {@PAGE_TITLE|language} erfolgte eine neue Benutzeranmeldung durch: {@$user->username}.
+
+Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}.
 
 {if LANGUAGE_USE_INFORMAL_VARIANT}Du erreichst{else}Sie erreichen{/if} das Benutzerprofil des neuen Benutzers, indem {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} folgenden Link {if LANGUAGE_USE_INFORMAL_VARIANT}aufrufst{else}aufrufen{/if}:
-{link controller='User' object=$user isEmail=true}{/link} ]]></item>
+{link controller='User' object=$user isEmail=true}{/link}]]></item>
                <item name="wcf.user.register.notification.mail.subject"><![CDATA[Neue Benutzeranmeldung auf der Website: {@PAGE_TITLE|language}]]></item>
                <!-- Disclaimer -->
                <item name="wcf.user.register.disclaimer.accept"><![CDATA[Akzeptieren]]></item>
@@ -4776,13 +4852,14 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
                <item name="wcf.user.trophy.dialogTitle"><![CDATA[Trophäen von {$username}]]></item>
                <item name="wcf.user.trophy.trophies"><![CDATA[Trophäen]]></item>
                <item name="wcf.user.trophy.specialTrophies"><![CDATA[Besondere Trophäen]]></item>
-               <item name="wcf.user.trophy.specialTrophies.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Wähle{else}Wählen Sie{/if} hier {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} besonderen Trophäen aus, welche im Profil und in der Nachrichten-Seitenleiste angezeigt werden.]]></item>
+               <item name="wcf.user.trophy.specialTrophies.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Wähle{else}Wählen Sie{/if} hier {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} {if $__wcf->getSession()->getPermission('user.profile.trophy.maxUserSpecialTrophies') > 1}besonderen Trophäen{else}besondere Trophäe{/if} aus, welche im Profil und in der Nachrichten-Seitenleiste angezeigt {if $__wcf->getSession()->getPermission('user.profile.trophy.maxUserSpecialTrophies') > 1}werden. Es können maximal {#$__wcf->getSession()->getPermission('user.profile.trophy.maxUserSpecialTrophies')} Trophäen ausgewählt werden.{else}wird.{/if}]]></item>
                <item name="wcf.user.trophy.specialTrophies.error.tooMany"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} maximal {#$__wcf->session->getPermission('user.profile.trophy.maxUserSpecialTrophies')} Trophäen auswählen.]]></item>
                <item name="wcf.user.trophy.specialTrophies.error.invalid"><![CDATA[Die angegebenen Trophäen sind ungültig.]]></item>
                <item name="wcf.user.trophy.recentActivity.received"><![CDATA[Hat die Trophäe <a href="{$userTrophy->getTrophy()->getLink()}">{$userTrophy->getTrophy()->getTitle()}</a> erhalten.]]></item>
                <item name="wcf.user.trophy.condition.excludedTrophies"><![CDATA[Ausgeschlossene Trophäen]]></item>
                <item name="wcf.user.trophy.condition.excludedTrophyCategories"><![CDATA[Ausgeschlossene Trophäen Kategorien]]></item>
                <item name="wcf.user.trophy.trophyAwarded"><![CDATA[{#$items} Mal vergeben]]></item>
+               <item name="wcf.user.trophy.showMoreTrophies"><![CDATA[und {#$trophyCount} weitere]]></item>
        </category>
        <category name="wcf.acp.trophy">
                <item name="wcf.acp.trophy"><![CDATA[Trophäe]]></item>
@@ -4820,17 +4897,11 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
        </category>
        <category name="wcf.user.usersOnline">
                <item name="wcf.user.usersOnline"><![CDATA[Benutzer online]]></item>
-               <item name="wcf.user.usersOnline.detail"><![CDATA[
-{if $usersOnlineList->stats[members] > 0}
-       {#$usersOnlineList->stats[members]} Mitglied{if $usersOnlineList->stats[members] != 1}er{/if}
-{/if} 
-{if $usersOnlineList->stats[invisible] > 0}
-       (davon {#$usersOnlineList->stats[invisible]} unsichtbar)
-{/if}
-{if $usersOnlineList->stats[guests] > 0 && $usersOnlineList->stats[members] > 0}und{/if}
-{if $usersOnlineList->stats[guests] > 0}
-       {#$usersOnlineList->stats[guests]} Besucher
-{/if}]]></item>
+               <item name="wcf.user.usersOnline.detail"><![CDATA[{*
+*}{if $usersOnlineList->stats[members] > 0}{#$usersOnlineList->stats[members]} Mitglied{if $usersOnlineList->stats[members] != 1}er{/if}{/if}{*
+*}{if $usersOnlineList->stats[invisible] > 0} (davon {#$usersOnlineList->stats[invisible]} unsichtbar){/if}{*
+*}{if $usersOnlineList->stats[guests] > 0 && $usersOnlineList->stats[members] > 0} und {/if}{*
+*}{if $usersOnlineList->stats[guests] > 0}{#$usersOnlineList->stats[guests]} Besucher{/if}]]></item>
                <item name="wcf.user.usersOnline.invisible"><![CDATA[ (unsichtbar)]]></item>
                <item name="wcf.user.usersOnline.marking.legend"><![CDATA[Legende]]></item>
                <item name="wcf.user.usersOnline.guests"><![CDATA[Gäste]]></item>
@@ -4951,12 +5022,25 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
                <item name="wcf.user.condition.state.isEnabled"><![CDATA[Aktiviert]]></item>
                <item name="wcf.user.condition.state.isEnabled.error.conflict"><![CDATA[„Aktiviert“ und „Nicht aktiviert“ können nicht gleichzeitig ausgewählt werden.]]></item>
                <item name="wcf.user.condition.state.isNotBanned"><![CDATA[Nicht gesperrt]]></item>
+               <item name="wcf.user.condition.state.isEmailConfirmed"><![CDATA[Hat eine bestätigte E-Mail-Adresse]]></item>
+               <item name="wcf.user.condition.state.isEmailConfirmed.error.conflict"><![CDATA[„Hat eine bestätigte E-Mail-Adresse“ und „Hat keine bestätigte E-Mail-Adresse“ können nicht gleichzeitig ausgewählt werden.]]></item>
+               <item name="wcf.user.condition.state.isNotEmailConfirmed"><![CDATA[Hat keine bestätigte E-Mail-Adresse]]></item>
                <item name="wcf.user.condition.userTrophyIDs"><![CDATA[hat Trophäe]]></item>
                <item name="wcf.user.condition.userTrophyIDs.description"><![CDATA[Benutzer müssen alle ausgewählten Trophäen mindestens einmal erhalten haben.]]></item>
                <item name="wcf.user.condition.notUserTrophyIDs"><![CDATA[hat nicht Trophäe]]></item>
                <item name="wcf.user.condition.notUserTrophyIDs.description"><![CDATA[Benutzer dürfen keine der ausgewählten Trophäen erhalten haben.]]></item>
                <item name="wcf.user.condition.notUserTrophyIDs.error.userTrophyIntersection"><![CDATA[Die ausgewählten Trophäen in „hat Trophäe“ und „hat nicht Trophäe“ sind widersprüchlich.]]></item>
                <item name="wcf.user.condition.trophyPoints"><![CDATA[Trophäen]]></item>
+               <item name="wcf.user.condition.coverPhoto"><![CDATA[Titelbild]]></item>
+               <item name="wcf.user.condition.coverPhoto.coverPhoto"><![CDATA[Hat Titelbild]]></item>
+               <item name="wcf.user.condition.coverPhoto.noCoverPhoto"><![CDATA[Hat kein Titelbild]]></item>
+               <item name="wcf.user.condition.signature"><![CDATA[Signatur]]></item>
+               <item name="wcf.user.condition.signature.signature"><![CDATA[Hat Signatur]]></item>
+               <item name="wcf.user.condition.signature.noSignature"><![CDATA[Hat keine Signatur]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays"><![CDATA[Letzten Aktivität vor … Tagen]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays.error.endBeforeStart"><![CDATA[Der Endwert ist kleiner als der Startwert.]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays.error.invalidEnd"><![CDATA[Der Endwert ist ungültig.]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays.error.invalidStart"><![CDATA[Der Startwert ist ungültig.]]></item>
        </category>
        <category name="wcf.user.coverPhoto">
                <item name="wcf.user.coverPhoto"><![CDATA[Titelbild]]></item>
@@ -4987,11 +5071,14 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
                <item name="wcf.user.notification.noMoreNotifications"><![CDATA[Keine aktuellen Benachrichtigungen]]></item>
                <item name="wcf.user.notification.noNotifications"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} keine Benachrichtigungen.]]></item>
                <item name="wcf.user.notification.notifications"><![CDATA[Benachrichtigungen]]></item>
-               <item name="wcf.user.notification.notifications.description"><![CDATA[E-Mail-Benachrichtigungen werden nicht von allen verfügbaren Benachrichtigungen unterstützt.]]></item>
                <item name="wcf.user.notification.notifications.disabled"><![CDATA[Deaktiviert]]></item>
                <item name="wcf.user.notification.notifications.enabled"><![CDATA[Aktiviert]]></item>
                <item name="wcf.user.notification.showAll"><![CDATA[Alle Benachrichtigungen anzeigen]]></item>
-               <item name="wcf.user.notification.mail.disabled"><![CDATA[Die E-Mail-Benachrichtigung wurde erfolgreich abgeschaltet.]]></item>
+               <item name="wcf.user.notification.mail.disabled"><![CDATA[Die gewählten E-Mail-Benachrichtigungen wurde erfolgreich abbestellt.]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.confirm"><![CDATA[Gewählte E-Mail-Benachrichtigungen abbstellen]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.description"><![CDATA[Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}wähle{else}wählen Sie{/if} die Benachrichtigungsart, die {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} abbestellen {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if} aus und {if LANGUAGE_USE_INFORMAL_VARIANT}bestätige{else}bestätigen Sie{/if} die Abbestellung.]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.event"><![CDATA[Benachrichtigungsart]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.event.all"><![CDATA[Alle E-Mail-Benachrichtigungen]]></item>
                <item name="wcf.user.notification.mailNotificationType.none"><![CDATA[Keine E-Mail-Benachrichtigung]]></item>
                <item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Sofortige E-Mail-Benachrichtigung]]></item>
                <item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Tägliche E-Mail-Benachrichtigung]]></item>
@@ -5000,18 +5087,18 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
                <item name="wcf.user.notification.mail.subject"><![CDATA[Neue Benachrichtigung: {@$title}]]></item>
                <item name="wcf.user.notification.mail.plaintext.intro"><![CDATA[Hallo {@$mailbox->getUser()->username},]]></item>
                <item name="wcf.user.notification.mail.plaintext.outro"><![CDATA[Diese E-Mail ist eine automatische Benachrichtigung. BITTE {if LANGUAGE_USE_INFORMAL_VARIANT}ANTWORTE{else}ANTWORTEN SIE{/if} NICHT AUF DIESE E-MAIL.
-               
+
 {if LANGUAGE_USE_INFORMAL_VARIANT}Besuche deine{else}Besuchen Sie Ihre{/if} Benachrichtigungseinstellungen [URL:{link controller='NotificationSettings' isEmail=true}{/link}], um die
 Benachrichtigungen auf {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] nach {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Wünschen zu konfigurieren.
 
-Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} nur diese E-Mail-Benachrichtigung nicht mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt abbestellen: {link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}.]]></item>
+Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} nur diese E-Mail-Benachrichtigung nicht mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt abbestellen: {link controller='NotificationUnsubscribe' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}.]]></item>
                <item name="wcf.user.notification.mail.html.intro"><![CDATA[<h2>Hallo {$mailbox->getUser()->username},</h2>]]></item>
                <item name="wcf.user.notification.mail.html.outro"><![CDATA[<p>Diese E-Mail ist eine automatische Benachrichtigung. <b>Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}antworte{else}antworten Sie{/if} nicht auf diese E-Mail</b>.</p>
 
 <p>{if LANGUAGE_USE_INFORMAL_VARIANT}Besuche deine{else}Besuchen Sie Ihre{/if} <a href="{link controller='NotificationSettings' isHtmlEmail=true}{/link}">Benachrichtigungseinstellungen</a>, um die
 Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> nach {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Wünschen zu konfigurieren.</p>
 
-<p>Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} nur diese E-Mail-Benachrichtigung nicht mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt <a href="{link controller='NotificationDisable' isHtmlEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">abbestellen</a>.</p>]]></item>
+<p>Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} nur diese E-Mail-Benachrichtigung nicht mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt <a href="{link controller='NotificationUnsubscribe' isHtmlEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">abbestellen</a>.</p>]]></item>
                <item name="wcf.user.notification.mail.daily.subject"><![CDATA[{if $count == 1}Neue Benachrichtigung{else}{#$count} neue Benachrichtigungen{/if}]]></item>
                <item name="wcf.user.notification.mail.daily.plaintext.intro"><![CDATA[Hallo {@$mailbox->getUser()->username},
 
@@ -5023,7 +5110,7 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
 {if LANGUAGE_USE_INFORMAL_VARIANT}Besuche deine{else}Besuchen Sie Ihre{/if} Benachrichtigungseinstellungen [URL:{link controller='NotificationSettings' isEmail=true}{/link}], um die
 Benachrichtigungen auf {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] nach {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Wünschen zu konfigurieren.
 
-Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} keine E-Mail-Benachrichtigungen mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt abbestellen: {link controller='NotificationDisable' isEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}.]]></item>
+Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} keine E-Mail-Benachrichtigungen mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt abbestellen: {link controller='NotificationUnsubscribe' isEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}.]]></item>
                <item name="wcf.user.notification.mail.daily.html.intro"><![CDATA[<h2>Hallo {@$mailbox->getUser()->username},</h2>
 
 <p>{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} derzeit insgesamt {#$notifications|count} ungelesene Benachrichtigung{if $notifications|count != 1}en{/if}, die älter als 24 Stunden {if $notifications|count == 1}ist{else}sind{/if}:</p>]]></item>
@@ -5034,42 +5121,44 @@ Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} keine E-Mail-Benachricht
 <p>{if LANGUAGE_USE_INFORMAL_VARIANT}Besuche deine{else}Besuchen Sie Ihre{/if} <a href="{link controller='NotificationSettings' isHtmlEmail=true}{/link}">Benachrichtigungseinstellungen</a>, um die
 Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> nach {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Wünschen zu konfigurieren.</p>
 
-<p>Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} keine E-Mail-Benachrichtigungen mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt <a href="{link controller='NotificationDisable' isHtmlEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">abbestellen</a>.</p>]]></item>
+<p>Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} keine E-Mail-Benachrichtigungen mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt <a href="{link controller='NotificationUnsubscribe' isHtmlEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">abbestellen</a>.</p>]]></item>
                <item name="wcf.user.notification.mail.authorList.plaintext"><![CDATA[{if !$event->getAuthor()->userID}{if $guestTimesTriggered > 1}Gäste{else}Ein Gast{/if}{else}{@$event->getAuthor()->username} [URL:{link controller='User' object=$event->getAuthor() isEmail=true}{/link}]{/if}{if $count > 1 && $count < 4}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->username} [URL:{link controller='User' object=$authors[1] isEmail=true}{/link}]{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if}{@$authors[2]->username} [URL:{link controller='User' object=$authors[2] isEmail=true}{/link}]{/if}{elseif $count >= 4}{if $guestTimesTriggered},{else} und{/if} {#$count-1} weitere Benutzer{/if}{if $event->getAuthor()->userID && $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}{#$guestTimesTriggered} Gäste{/if}{/if}]]></item>
                <item name="wcf.user.notification.mail.authorList.html"><![CDATA[{if !$event->getAuthor()->userID}{if $guestTimesTriggered > 1}Gäste{else}Ein Gast{/if}{else}<a href="{link controller='User' object=$event->getAuthor() isHtmlEmail=true}{/link}">{$event->getAuthor()->username}</a>{/if}{if $count > 1 && $count < 4}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}<a href="{link controller='User' object=$authors[1] isHtmlEmail=true}{/link}">{$authors[1]->username}</a>{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if}<a href="{link controller='User' object=$authors[2] isHtmlEmail=true}{/link}">{$authors[2]->username}</a>{/if}{elseif $count >= 4}{if $guestTimesTriggered},{else} und{/if} {#$count-1} weitere Benutzer{/if}{if $event->getAuthor()->userID && $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}{#$guestTimesTriggered} Gäste{/if}{/if}]]></item>
+               <item name="wcf.user.notification.stacked.authorList"><![CDATA[{if !$guestTimesTriggered|isset}{assign var=guestTimesTriggered value=0}{/if}{if $count < 4}<strong>{$authors[0]}</strong>{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}<strong>{$authors[1]}</strong>{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} <strong>{$authors[2]}</strong>{/if}{/if}{if $guestTimesTriggered} und {plural value=$guestTimesTriggered one='ein Gast' other='# Gäste'}{/if}{else}<strong>{$authors[0]}</strong>{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {plural value=$guestTimesTriggered one='ein Gast' other='# Gäste'}{/if}{/if}]]></item>
+               <item name="wcf.user.notification.mail.jumpToContent"><![CDATA[Zum Inhalt springen]]></item>
                <!-- Notifications -->
                <item name="wcf.user.notification.com.woltlab.wcf.user"><![CDATA[Benutzer-Profile]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.follow.following"><![CDATA[Jemand folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}]]></item>
                <item name="wcf.user.notification.follow.title"><![CDATA[Neuer Follower]]></item>
                <item name="wcf.user.notification.follow.title.stacked"><![CDATA[{#$count} neue Follower]]></item>
-               <item name="wcf.user.notification.follow.message"><![CDATA[{@$author->getAnchorTag()} folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
-               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} folgen {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
+               <item name="wcf.user.notification.follow.message"><![CDATA[<strong>{$author}</strong> folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
+               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} folgen {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
                <item name="wcf.user.notification.follow.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1}folgt{else}folgen{/if} {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
                <item name="wcf.user.notification.follow.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1}folgt{else}folgen{/if} {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}:</p>]]></item>
                <item name="wcf.user.notification.comment.title"><![CDATA[Neuer Kommentar (Pinnwand)]]></item>
                <item name="wcf.user.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Pinnwand)]]></item>
-               <item name="wcf.user.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar an <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> verfasst.]]></item>
-               <item name="wcf.user.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben Kommentare an <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> verfasst.]]></item>
+               <item name="wcf.user.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand verfasst.]]></item>
+               <item name="wcf.user.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Kommentare an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand verfasst.]]></item>
                <item name="wcf.user.notification.comment.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}{/link}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.comment.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} an <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.comment.like.title"><![CDATA[Reaktion auf einen Kommentar (Pinnwand)]]></item>
                <item name="wcf.user.notification.comment.like.title.stacked"><![CDATA[{#$count} Benutzern haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar reagiert (Pinnwand)]]></item>
-               <item name="wcf.user.notification.comment.like.message"><![CDATA[{@$author->getAnchorTag()} hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">Pinnwand von {$owner->username}</a>{/if} reagiert ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
-               <item name="wcf.user.notification.comment.like.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">Pinnwand von {$owner->username}</a>{/if} reagiert ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
+               <item name="wcf.user.notification.comment.like.message"><![CDATA[<strong>{$author}</strong> hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $owner === null}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von <strong>{$owner}</strong>{/if} reagiert ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
+               <item name="wcf.user.notification.comment.like.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $owner === null}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von <strong>{$owner}</strong>{/if} reagiert ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
                <item name="wcf.user.notification.commentResponse.title"><![CDATA[Neue Antwort (Pinnwand)]]></item>
                <item name="wcf.user.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Pinnwand)]]></item>
-               <item name="wcf.user.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar an {if $owner->userID == $__wcf->getUser()->userID}<a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">Pinnwand von {$owner->username}</a>{/if} verfasst.]]></item>
-               <item name="wcf.user.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $owner->userID == $__wcf->getUser()->userID}<a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">Pinnwand von {$owner->username}</a>{/if} geantwortet.]]></item>
+               <item name="wcf.user.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar an {if $owner->userID == $__wcf->getUser()->userID}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von <strong>{$owner}</strong>{/if} verfasst.]]></item>
+               <item name="wcf.user.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $owner->userID == $__wcf->getUser()->userID}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von <strong>{$owner}</strong>{/if} geantwortet.]]></item>
                <item name="wcf.user.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar an {if $mailbox->getUser()->userID == $notificationContent[variables][owner]->userID}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von {@$notificationContent[variables][owner]->username}{/if} [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar an {if $mailbox->getUser()->userID == $notificationContent[variables][owner]->userID}<a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">Pinnwand von {$notificationContent[variables][owner]->username}</a>{/if} verfasst:</p>]]></item>
                <item name="wcf.user.notification.commentResponse.like.title"><![CDATA[Reaktion auf eine Antwort eines Kommentares (Pinnwand)]]></item>
                <item name="wcf.user.notification.commentResponse.like.title.stacked"><![CDATA[{#$count} Benutzer haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Antwort auf einen Kommentar reagiert (Pinnwand)]]></item>
-               <item name="wcf.user.notification.commentResponse.like.message"><![CDATA[{@$author->getAnchorTag()} hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Antwort auf einen Kommentar an {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">Pinnwand von {$owner->username}</a>{/if} reagiert ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
-               <item name="wcf.user.notification.commentResponse.like.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Antwort auf einen Kommentar an {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a>{else}der <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">Pinnwand von {$owner->username}</a>{/if} reagiert ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
+               <item name="wcf.user.notification.commentResponse.like.message"><![CDATA[<strong>{$author}</strong> hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Antwort auf einen Kommentar an {if $owner === null}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von <strong>{$owner}</strong>{/if} reagiert ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
+               <item name="wcf.user.notification.commentResponse.like.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Antwort auf einen Kommentar an {if $owner === null}{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand{else}der Pinnwand von <strong>{$owner}</strong>{/if} reagiert ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
                <item name="wcf.user.notification.commentResponseOwner.title"><![CDATA[Neue Antwort (Pinnwand)]]></item>
                <item name="wcf.user.notification.commentResponseOwner.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Pinnwand)]]></item>
-               <item name="wcf.user.notification.commentResponseOwner.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} an <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> verfasst.]]></item>
-               <item name="wcf.user.notification.commentResponseOwner.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben auf den Kommentar von {if $author->userID}<a href="{link controller='User' object=$author}{/link}" class="userLink" data-user-id="{@$author->userID}">{$author->username}</a>{else}{$author->username}{/if} an <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> geantwortet.]]></item>
+               <item name="wcf.user.notification.commentResponseOwner.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zum Kommentar von <strong>{$commentAuthor}</strong> an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand verfasst.]]></item>
+               <item name="wcf.user.notification.commentResponseOwner.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf den Kommentar von <strong>{$author}</strong> an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand geantwortet.]]></item>
                <item name="wcf.user.notification.commentResponseOwner.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$notificationContent[variables][commentAuthor]->username}{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.commentResponseOwner.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if} an <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.notification.comment"><![CDATA[Neuer Kommentar an {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand]]></item>
@@ -5080,7 +5169,7 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.notification.com.woltlab.wcf.paidSubscription.user.expiring"><![CDATA[Eine {if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Mitgliedschaften läuft bald ab]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.userTrophy.notification.received"><![CDATA[Trophäe erhalten]]></item>
                <item name="wcf.user.notification.trophy.received.title"><![CDATA[Trophäe erhalten]]></item>
-               <item name="wcf.user.notification.trophy.received.message"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} die Trophäe <a href="{$userTrophy->getTrophy()->getLink()}">{$userTrophy->getTrophy()->getTitle()}</a> erhalten.]]></item>
+               <item name="wcf.user.notification.trophy.received.message"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} die Trophäe <strong>{$userTrophy->getTrophy()}</strong> erhalten.]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.administration"><![CDATA[Administration]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.registration.notification.registration"><![CDATA[Neue Registrierung durch Benutzer]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.moderation"><![CDATA[Moderation]]></item>
@@ -5090,22 +5179,23 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.notification.com.woltlab.wcf.page.notification.comment"><![CDATA[Neuer Kommentar auf einer Seite]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponse"><![CDATA[Neue Antwort auf einen Kommentar auf einer Seite]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponseOwner"><![CDATA[Neue Antwort auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf einer Seite]]></item>
+               <item name="wcf.user.notification.com.woltlab.wcf.likeableArticle.notification.like"><![CDATA[Jemand hat auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Artikel reagiert]]></item>
                <item name="wcf.user.notification.pageComment.title"><![CDATA[Neuer Kommentar (Seite)]]></item>
                <item name="wcf.user.notification.pageComment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Seite)]]></item>
-               <item name="wcf.user.notification.pageComment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar auf der Seite <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.user.notification.pageComment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben Kommentare auf der Seite <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.user.notification.pageComment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar auf der Seite <strong>{$page->getTitle()}</strong> verfasst.]]></item>
+               <item name="wcf.user.notification.pageComment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Kommentare auf der Seite <strong>{$page->getTitle()}</strong> verfasst.]]></item>
                <item name="wcf.user.notification.pageComment.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} auf der Seite „{@$notificationContent[variables][page]->getTitle()}“ [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.pageComment.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} auf der Seite <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.pageComment.response.title"><![CDATA[Neue Antwort (Seite)]]></item>
                <item name="wcf.user.notification.pageComment.response.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Seite)]]></item>
-               <item name="wcf.user.notification.pageComment.response.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zu dem Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} auf der Seite <a href="{$page->getLink()}#comment{@$commentID}/response{@$responseID}">{$page->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.user.notification.pageComment.response.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben auf den Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} auf der Seite <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a> geantwortet.]]></item>
+               <item name="wcf.user.notification.pageComment.response.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zu dem Kommentar von <strong>{$commentAuthor}</strong> auf der Seite <strong>{$page->getTitle()}</strong> verfasst.]]></item>
+               <item name="wcf.user.notification.pageComment.response.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf den Kommentar von <strong>{$commentAuthor}</strong> auf der Seite <strong>{$page->getTitle()}</strong> geantwortet.]]></item>
                <item name="wcf.user.notification.pageComment.response.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$notificationContent[variables][commentAuthor]->username}{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} auf der Seite „{@$notificationContent[variables][page]->getTitle()}“ [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}/response{@$responseID}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.pageComment.response.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if} auf der Seite <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.pageComment.responseOwner.title"><![CDATA[Neue Antwort (Seite)]]></item>
                <item name="wcf.user.notification.pageComment.responseOwner.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Seite)]]></item>
-               <item name="wcf.user.notification.pageComment.responseOwner.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf der Seite <a href="{$page->getLink()}#comment{@$commentID}/response{@$responseID}">{$page->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.user.notification.pageComment.responseOwner.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf der Seite <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a> geantwortet.]]></item>
+               <item name="wcf.user.notification.pageComment.responseOwner.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf der Seite <strong>{$page->getTitle()}</strong> verfasst.]]></item>
+               <item name="wcf.user.notification.pageComment.responseOwner.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf der Seite <strong>{$page->getTitle()}</strong> geantwortet.]]></item>
                <item name="wcf.user.notification.pageComment.responseOwner.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf der Seite „{@$notificationContent[variables][page]->getTitle()}“ [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}/response{@$responseID}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.pageComment.responseOwner.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar auf der Seite <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.article.comment.notification.comment"><![CDATA[Neuer Kommentar zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel]]></item>
@@ -5113,25 +5203,25 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.notification.com.woltlab.wcf.article.comment.response.notification.commentResponseOwner"><![CDATA[Neue Antwort auf einen Kommentar zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel]]></item>
                <item name="wcf.user.notification.articleComment.title"><![CDATA[Neuer Kommentar (Artikel)]]></item>
                <item name="wcf.user.notification.articleComment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Artikel)]]></item>
-               <item name="wcf.user.notification.articleComment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <a href="{$article->getLink()}#comment{@$commentID}">{$article->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.user.notification.articleComment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben Kommentare zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <a href="{$article->getLink()}#comment{@$commentID}">{$article->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.user.notification.articleComment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
+               <item name="wcf.user.notification.articleComment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Kommentare zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
                <item name="wcf.user.notification.articleComment.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel „{@$notificationContent[variables][article]->getTitle()}“ [URL:{@$notificationContent[variables][article]->getLink()}#comment{@$commentID}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.articleComment.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat einen Kommentar{else}haben Kommentare{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <a href="{$notificationContent[variables][article]->getLink()}#comment{@$commentID}">{$notificationContent[variables][article]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.articleComment.response.title"><![CDATA[Neue Antwort (Artikel)]]></item>
                <item name="wcf.user.notification.articleComment.response.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Artikel)]]></item>
-               <item name="wcf.user.notification.articleComment.response.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar in dem Artikel <a href="{$article->getLink()}#comment{@$commentID}/response{@$responseID}">{$article->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.user.notification.articleComment.response.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben Antworten zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar zu dem Artikel <a href="{$article->getLink()}#comment{@$commentID}">{$article->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.user.notification.articleComment.response.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar in dem Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
+               <item name="wcf.user.notification.articleComment.response.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Antworten zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Kommentar zu dem Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
                <item name="wcf.user.notification.articleComment.response.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar zu dem Artikel „{@$notificationContent[variables][article]->getTitle()}“ [URL:{link controller='Article' object=$notificationContent[variables][article] isEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.articleComment.response.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} auf {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Kommentar zu dem Artikel <a href="{link controller='Article' object=$notificationContent[variables][article] isHtmlEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$notificationContent[variables][article]->getTitle()}</a> verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}</p>]]></item>
                <item name="wcf.user.notification.articleComment.responseOwner.title"><![CDATA[Neue Antwort (Artikel)]]></item>
                <item name="wcf.user.notification.articleComment.responseOwner.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Artikel)]]></item>
-               <item name="wcf.user.notification.articleComment.responseOwner.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <a href="{$article->getLink()}#comment{@$commentID}/response{@$responseID}">{$article->getTitle()}</a> verfasst.]]></item>
-               <item name="wcf.user.notification.articleComment.responseOwner.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} und {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} und{/if} {#$others} weitere Benutzer {if $guestTimesTriggered}und {if $guestTimesTriggered == 1}ein Gast{else}Gäste{/if}{/if}{/if} haben Antworten zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <a href="{$article->getLink()}#comment{@$commentID}/response{@$responseID}">{$article->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.user.notification.articleComment.responseOwner.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat eine Antwort zum Kommentar von <strong>{$commentAuthor}</strong> zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
+               <item name="wcf.user.notification.articleComment.responseOwner.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben Antworten zum Kommentar von <strong>{$commentAuthor}</strong> zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
                <item name="wcf.user.notification.articleComment.responseOwner.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$notificationContent[variables][commentAuthor]->username}{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel „{@$notificationContent[variables][article]->getTitle()}“ [URL:{link controller='Article' object=$notificationContent[variables][article] isEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.articleComment.responseOwner.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{@$notificationContent[variables][commentAuthor]->username}</a>{else}{@$notificationContent[variables][commentAuthor]->username}{/if} zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel <a href="{link controller='Article' object=$notificationContent[variables][article] isHtmlEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$notificationContent[variables][article]->getTitle()}</a> verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.article.notification.article"><![CDATA[Neuer Artikel in abonnierter Kategorie]]></item>
                <item name="wcf.user.notification.article.title"><![CDATA[Neuer Artikel]]></item>
-               <item name="wcf.user.notification.article.message"><![CDATA[{if $author->userID}{@$author->getAnchorTag()}{else}Ein Gast{/if} hat den Artikel <a href="{$article->getLink()}">{$article->getTitle()}</a> verfasst.]]></item>
+               <item name="wcf.user.notification.article.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat den Artikel <strong>{$article->getTitle()}</strong> verfasst.]]></item>
                <item name="wcf.user.notification.article.mail.plaintext"><![CDATA[{if $event->getAuthor()->userID}{@$event->getAuthor()->username} [URL:{link controller='User' object=$event->getAuthor() isEmail=true}{/link}]{else}Ein Gast{/if} hat den Artikel „{@$notificationContent[variables][articleContent]->getTitle()}“ [URL:{link controller='Article' object=$notificationContent[variables][articleContent] isEmail=true}{/link}] verfasst:]]></item>
                <item name="wcf.user.notification.article.mail.html"><![CDATA[<p>{if $event->getAuthor()->userID}<a href="{link controller='User' object=$event->getAuthor() isHtmlEmail=true}{/link}">{$event->getAuthor()->username}</a>{else}Ein Gast{/if} hat den Artikel <a href="{link controller='Article' object=$notificationContent[variables][articleContent] isHtmlEmail=true}{/link}">{$notificationContent[variables][articleContent]->getTitle()}</a> verfasst:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.articleComment.response.notification.commentResponseOwner"><![CDATA[Neue Antwort auf einen Kommentar zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel]]></item>
@@ -5139,10 +5229,12 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.notification.com.woltlab.wcf.articleComment.notification.comment"><![CDATA[Neuer Kommentar zu {if LANGUAGE_USE_INFORMAL_VARIANT}deinem{else}Ihrem{/if} Artikel]]></item>
                <item name="wcf.user.notification.userRegistration.title"><![CDATA[Neue Benutzer-Registrierung]]></item>
                <item name="wcf.user.notification.userRegistration.title.stacked"><![CDATA[{#$count} neue Benutzer-Registrierungen]]></item>
-               <item name="wcf.user.notification.userRegistration.message"><![CDATA[{@$author->getAnchorTag()} hat sich registriert.]]></item>
-               <item name="wcf.user.notification.userRegistration.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben sich registriert.]]></item>
+               <item name="wcf.user.notification.userRegistration.message"><![CDATA[<strong>{$author}</strong> hat sich registriert.]]></item>
+               <item name="wcf.user.notification.userRegistration.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} haben sich registriert.]]></item>
                <item name="wcf.user.notification.userRegistration.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1}hat{else}haben{/if} sich registriert.]]></item>
                <item name="wcf.user.notification.userRegistration.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1}hat{else}haben{/if} sich registriert:</p>]]></item>
+               <item name="wcf.user.notification.status.active"><![CDATA[Aktiv]]></item>
+               <item name="wcf.user.notification.status.email"><![CDATA[E-Mail]]></item>
        </category>
        <category name="wcf.user.profile">
                <item name="wcf.user.profile.content.about.noPublicData"><![CDATA[{if $userID == $__wcf->getUser()->userID}{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} noch keine sichtbaren Informationen hinterlegt.{else}Der Benutzer hat noch keine für {if LANGUAGE_USE_INFORMAL_VARIANT}dich{else}Sie{/if} sichtbaren Informationen hinterlegt.{/if}]]></item>
@@ -5181,7 +5273,6 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.option.birthday"><![CDATA[Geburtstag]]></item>
                <item name="wcf.user.option.birthdayShowYear"><![CDATA[Geburtsjahr im Profil anzeigen]]></item>
                <item name="wcf.user.option.birthdayShowYear.description"><![CDATA[Mitglieder können dadurch {if LANGUAGE_USE_INFORMAL_VARIANT}dein{else}Ihr{/if} Alter sehen.]]></item>
-               <item name="wcf.user.option.canMail"><![CDATA[Kann E-Mails senden]]></item>
                <item name="wcf.user.option.canViewEmailAddress"><![CDATA[Kann E-Mail-Adresse sehen]]></item>
                <item name="wcf.user.option.canViewOnlineStatus"><![CDATA[Kann Online-Status sehen]]></item>
                <item name="wcf.user.option.canViewProfile"><![CDATA[Kann Benutzerprofil sehen]]></item>
@@ -5205,7 +5296,6 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.option.occupation"><![CDATA[Beruf]]></item>
                <item name="wcf.user.option.showSignature"><![CDATA[Persönliche Signatur anderer Mitglieder anzeigen]]></item>
                <item name="wcf.user.option.timezone"><![CDATA[Zeitzone]]></item>
-               <item name="wcf.user.option.icq"><![CDATA[ICQ]]></item>
                <item name="wcf.user.option.skype"><![CDATA[Skype]]></item>
                <item name="wcf.user.option.facebook"><![CDATA[Facebook]]></item>
                <item name="wcf.user.option.twitter"><![CDATA[Twitter]]></item>
@@ -5215,10 +5305,9 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
                <item name="wcf.user.option.searchRadioButtonOption"><![CDATA[Auswahl des Benutzers bei „{$option->getTitle()}“:]]></item>
                <item name="wcf.user.option.searchTextOption"><![CDATA[„{$option->getTitle()}“ enthält:]]></item>
                <item name="wcf.user.option.searchBooleanOption"><![CDATA[Auswahl des Benutzers bei „{$option->getTitle()}“:]]></item>
+               <item name="wcf.user.option.enableEmbeddedMedia"><![CDATA[Alle externen Inhalte anzeigen]]></item>
        </category>
        <category name="wcf.user.mail">
-               <item name="wcf.user.mail.information"><![CDATA[Informationen]]></item>
-               <item name="wcf.user.mail.mail.subject"><![CDATA[Nachricht von {@$username}: {@$subject}]]></item>
                <item name="wcf.user.mail.mail.plaintext"><![CDATA[Hallo {@$mailbox->getUser()->username},
 
 „{@$username}“ hat {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} über die Website {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] folgende Nachricht gesandt:
@@ -5229,11 +5318,6 @@ Benachrichtigungen auf <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|lang
 <p>„{$username}“ hat {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if} über die Website <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> folgende Nachricht gesandt:</p>
 
 <p>{@$message|newlineToBreak}</p>]]></item>
-               <item name="wcf.user.mail.message"><![CDATA[Nachricht]]></item>
-               <item name="wcf.user.mail.senderEmail"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} E-Mail-Adresse]]></item>
-               <item name="wcf.user.mail.sent"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Deine{else}Ihre{/if} Nachricht an {$user->username} wurde erfolgreich versandt.]]></item>
-               <item name="wcf.user.mail.showAddress"><![CDATA[Meine E-Mail-Adresse als Absender-Adresse benutzen. Der Empfänger kann direkt auf die Nachricht antworten.]]></item>
-               <item name="wcf.user.mail.subject"><![CDATA[Betreff]]></item>
        </category>
        <category name="wcf.user.rank">
                <item name="wcf.user.rank.administrator"><![CDATA[Administrator]]></item>
index 362104bdff7ee3d5feb9d24fb3ffa835e765c3ce..dc857cce66dcbbdb66172e8bf61a4e75c47eb839 100644 (file)
                <item name="wcf.acp.article.views"><![CDATA[Views]]></item>
                <item name="wcf.acp.article.lastVersion"><![CDATA[There are <a href="{link controller='VersionTrackerList' objectType='com.woltlab.wcf.article' objectID=$article->articleID isACP=true}{/link}">previous versions</a> of this article, the last change was by “{$lastVersion->username}” ({@$lastVersion->time|time}).]]></item>
                <item name="wcf.acp.article.isDeleted"><![CDATA[Deleted]]></item>
+               <item name="wcf.acp.article.metaTitle"><![CDATA[Meta Title]]></item>
+               <item name="wcf.acp.article.metaDescription"><![CDATA[Meta Description]]></item>
        </category>
        <category name="wcf.acp.attachment">
                <item name="wcf.acp.attachment.list"><![CDATA[Attachments]]></item>
                <item name="wcf.acp.dataImport.cli.configure.data.error.noSelection"><![CDATA[You did not specify any data for importing, the import has been aborted.]]></item>
                <item name="wcf.acp.dataImport.cli.configure.data.error.invalid"><![CDATA[The selected data type is invalid.]]></item>
                <item name="wcf.acp.dataImport.cli.configure.data.selectAll"><![CDATA[All data]]></item>
-               <item name="wcf.acp.dataImport.cli.info.wcf"><![CDATA[You did not load any application through --packageID={PACKAGE_ID}. If you wish to import application-specific data, you must call this script along with the desired package ID. Do you wish to continue the import? [YN]]]></item>
                <item name="wcf.acp.dataImport.cli.selection"><![CDATA[Selection? [{if $minSelection == $maxSelection}{$minSelection}{else}{$minSelection}-{$maxSelection}{/if}]]]></item>
                <item name="wcf.acp.dataImport.completed"><![CDATA[Import completed.]]></item>
                <item name="wcf.acp.dataImport.configure.data"><![CDATA[Data]]></item>
                <item name="wcf.acp.devtools.project.edit.error.brokenPath"><![CDATA[There is no <kbd>package.xml</kbd> in the given directory. The package files have either been deleted or moved.]]></item>
                <item name="wcf.acp.devtools.project.edit.warning.missingElements"><![CDATA[The following information is missing from the <kbd>package.xml</kbd> file: {implode from=$missingElements item=missingElement}<kbd>{$missingElement}</kbd>{/implode}.]]></item>
                <item name="wcf.acp.devtools.project.license"><![CDATA[License]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.languageID"><![CDATA[Language]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.languageItem"><![CDATA[Name of Phrase]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.lastTime"><![CDATA[Time of Last Occurence]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.delete.confirmMessage"><![CDATA[Do you really want to delete the entry?]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.stackTrace"><![CDATA[Stacktrace]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.showStackTrace"><![CDATA[Show Stacktrace]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.clearLog"><![CDATA[Delete all entries]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.clearLog.confirmMessage"><![CDATA[Do you really want to delete all entries?]]></item>
+               <item name="wcf.acp.devtools.missingLanguageItem.stackTrace.toggleOutputFormat"><![CDATA[Toggle line breaks]]></item>
        </category>
        <category name="wcf.acp.email">
                <item name="wcf.acp.email.smtp.test"><![CDATA[SMTP Connection Test]]></item>
@@ -653,7 +663,7 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.group.option.admin.management.canViewLog"><![CDATA[Can view log files]]></item>
                <item name="wcf.acp.group.option.admin.configuration.canManageApplication"><![CDATA[Can manage apps]]></item>
                <item name="wcf.acp.group.option.admin.management.canManageCronjob"><![CDATA[Can manage cronjobs]]></item>
-               <item name="wcf.acp.group.option.admin.configuration.package.canEditServer"><![CDATA[Can edit update servers]]></item>
+               <item name="wcf.acp.group.option.admin.configuration.package.canEditServer"><![CDATA[Can edit package servers]]></item>
                <item name="wcf.acp.group.option.admin.configuration.package.canInstallPackage"><![CDATA[Can install packages]]></item>
                <item name="wcf.acp.group.option.admin.configuration.package.canUninstallPackage"><![CDATA[Can uninstall packages]]></item>
                <item name="wcf.acp.group.option.admin.configuration.package.canUpdatePackage"><![CDATA[Can update packages]]></item>
@@ -733,7 +743,6 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.group.option.user.profile.avatar.maxSize"><![CDATA[Maximum Image File Size]]></item>
                <item name="wcf.acp.group.option.user.profile.canChangeEmail"><![CDATA[Can change their email address]]></item>
                <item name="wcf.acp.group.option.user.profile.canEditUserTitle"><![CDATA[Can edit their user title]]></item>
-               <item name="wcf.acp.group.option.user.profile.canMail"><![CDATA[Can send emails to users]]></item>
                <item name="wcf.acp.group.option.user.profile.canQuit"><![CDATA[Can delete their user account]]></item>
                <item name="wcf.acp.group.option.user.profile.canRename"><![CDATA[Can change their username]]></item>
                <item name="wcf.acp.group.option.user.profile.canViewMembersList"><![CDATA[Can view members list]]></item>
@@ -744,8 +753,8 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.group.option.user.signature.disallowedBBCodes.description"><![CDATA[Selected BBCodes <em>cannot</em> be used in the signature.]]></item>
                <item name="wcf.acp.group.priority"><![CDATA[Priority]]></item>
                <item name="wcf.acp.group.priority.description"><![CDATA[Determines the display order on the team page, user rank, and ‘users online’ marking based on highest priority.]]></item>
-               <item name="wcf.acp.group.userOnlineMarking"><![CDATA[Users Online Marking]]></item>
-               <item name="wcf.acp.group.userOnlineMarking.description"><![CDATA[Adjust the HTML formatting for members of this user group in the ‘users online’ list. <em>&lt;strong&gt;%s&lt;/strong&gt;</em> results in a bolder appearance.]]></item>
+               <item name="wcf.acp.group.userOnlineMarking"><![CDATA[User Marking]]></item>
+               <item name="wcf.acp.group.userOnlineMarking.description"><![CDATA[Adjust the HTML formatting for members of this user group. <em>&lt;strong&gt;%s&lt;/strong&gt;</em> results in a bolder appearance.]]></item>
                <item name="wcf.acp.group.userOnlineMarking.error.invalid"><![CDATA[There must be an occurrence of “%s”.]]></item>
                <item name="wcf.acp.group.showOnTeamPage"><![CDATA[Display members on team page]]></item>
                <item name="wcf.acp.group.option.admin.user.canEnableUser"><![CDATA[Can approve users]]></item>
@@ -848,6 +857,8 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.group.option.user.profile.trophy.canSeeTrophies"><![CDATA[Can see trophies]]></item>
                <item name="wcf.acp.group.option.user.profile.trophy.maxUserSpecialTrophies"><![CDATA[Maximum number of special trophies]]></item>
                <item name="wcf.acp.group.option.user.profile.trophy.maxUserSpecialTrophies.description"><![CDATA[Special trophies can be individually selected by the user and displayed in the message sidebar and the user profile.]]></item>
+               <item name="wcf.acp.group.option.category.user.profile.payment"><![CDATA[Payment]]></item>
+               <item name="wcf.acp.group.option.user.profile.payment.canBuyPaidSubscription"><![CDATA[Can buy paid subscriptions]]></item>
                <item name="wcf.acp.group.option.category.user.profile.coverPhoto"><![CDATA[Cover Photos]]></item>
                <item name="wcf.acp.group.option.user.profile.coverPhoto.canSeeCoverPhotos"><![CDATA[Can view  users’ cover photos]]></item>
                <item name="wcf.acp.group.option.user.profile.coverPhoto.canUploadCoverPhoto"><![CDATA[Can upload their cover photo]]></item>
@@ -860,6 +871,7 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.group.option.user.contactForm.attachment.allowedExtensions.description"><![CDATA[Enter one extension per line.]]></item>
                <item name="wcf.acp.group.option.user.contactForm.attachment.maxCount"><![CDATA[Maximum Attachments per Message]]></item>
                <item name="wcf.acp.group.option.user.profile.canEditUserProfile"><![CDATA[Can edit their profile]]></item>
+               <item name="wcf.acp.group.option.user.profile.canHideOnlineStatus"><![CDATA[Can hide their online status]]></item>
                <item name="wcf.acp.group.allowMention"><![CDATA[User group can be mentioned]]></item>
                <item name="wcf.acp.group.type.owner"><![CDATA[Owner]]></item>
                <item name="wcf.acp.group.type.owner.description"><![CDATA[The owner group features a few irrevocable permissions and is protected from edits by other groups, only the owner group can edit itself. Members of this group can add other users to this group, but cannot remove themselves.]]></item>
@@ -878,7 +890,6 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.index.credits.productManager"><![CDATA[Product Manager]]></item>
                <item name="wcf.acp.index.credits.trademarks"><![CDATA[“WoltLab&reg;” and “Burning Board&reg;” are registered Community Trade Marks at The Office of Harmonization for the Internal Market (OHIM) in Alicante, Spain.]]></item>
                <item name="wcf.acp.index.credits.contributor.more"><![CDATA[More]]></item>
-               <item name="wcf.acp.index.innoDBWarning"><![CDATA[The MySQL configuration option “innodb_flush_log_at_trx_commit” is set to “1”, slowing down certain database queries. It is highly recommended to set its value to “2”.]]></item>
                <item name="wcf.acp.index.inRescueMode"><![CDATA[You are accessing this installation from an unknown domain, possibly caused by moving to a new host. Please update the settings on <a href="{link controller='ApplicationManagement'}{/link}">Manage Apps</a>.]]></item>
                <item name="wcf.acp.index.tmpBroken"><![CDATA[For proper operation the folder “{WCF_DIR|concat:'tmp/'}” must exist and it must be writable. Please also check the permissions of the “{'WCF_DIR'|constant}” folder.]]></item>
                <item name="wcf.acp.index.news"><![CDATA[News]]></item>
@@ -907,7 +918,7 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.index.woltlab.pluginStore"><![CDATA[Plugin Store]]></item>
                <item name="wcf.acp.index.tinyBuild"><![CDATA[The accelerated guest view improves the page responsiveness and loading times for both visitors and search engines alike, please consider <a href="{link controller='Option' id=1 optionName="visitor_use_tiny_build"}#category_module.system{/link}">enabling it</a>.]]></item>
                <item name="wcf.acp.index.recaptchaWithoutKey"><![CDATA[Using reCAPTCHA without an individual website key is no longer supported by Google.<br><br>For further use you need to <a href="{$recaptchaKeyLink}">provide a key in your options</a>, please follow the instructions below the input field to obtain a key.]]></item>
-               <item name="wcf.acp.index.missingLanguageItems"><![CDATA[Missing language items have been detected (last time: {@$missingLanguageItemsMTime|time}). Check the file <kbd>{'WCF_DIR'|constant}log/missingLanguageItems.txt</kbd> for more information.]]></item>
+               <item name="wcf.acp.index.missingLanguageItems"><![CDATA[Missing language items have been detected (last time: {@$missingLanguageItemsMTime|time}). Check the <a href="{link controller='DevtoolsMissingLanguageItemList'}{/link}">list of missing phrases</a> for more information.]]></item>
        </category>
        <category name="wcf.acp.label">
                <item name="wcf.acp.label.add"><![CDATA[Add Label]]></item>
@@ -1165,6 +1176,7 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.menu.link.reactionType.edit"><![CDATA[Edit Reaction Type]]></item>
                <item name="wcf.acp.menu.link.language.item.add"><![CDATA[Add Phrase]]></item>
                <item name="wcf.acp.menu.link.systemCheck"><![CDATA[System Check]]></item>
+               <item name="wcf.acp.menu.link.devtools.missingLanguageItem.list"><![CDATA[Missing Phrases]]></item>
        </category>
        <category name="wcf.acp.modificationLog">
                <item name="wcf.acp.modificationLog.list"><![CDATA[Global Modification Log]]></item>
@@ -1284,6 +1296,8 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.error.controllerReplacementUnknown"><![CDATA[The controller “{$urlControllerReplacementError}” is unknown.]]></item>
                <item name="wcf.acp.option.error.tooHigh"><![CDATA[Exceeds the maximum value{if $option->maxvalue !== null} of {#$option->maxvalue}{/if}.]]></item>
                <item name="wcf.acp.option.error.tooLow"><![CDATA[Under the minimum value{if $option->minvalue !== null} of {#$option->minvalue}{/if}.]]></item>
+               <item name="wcf.acp.option.error.tooLong"><![CDATA[The entered text is too long.]]></item>
+               <item name="wcf.acp.option.error.tooShort"><![CDATA[The entered text is too short.]]></item>
                <item name="wcf.acp.option.http_enable_gzip"><![CDATA[Enable gzip-compression]]></item>
                <item name="wcf.acp.option.http_enable_gzip.description"><![CDATA[Compresses content transferred to users, it also reduces traffic and page load times. It does not affect files, e.g. images.]]></item>
                <item name="wcf.acp.option.http_send_x_frame_options"><![CDATA[Disallow embedding in a frame]]></item>
@@ -1305,8 +1319,10 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.mail_send_method.debugFolder"><![CDATA[Use Debug (Folder with .eml files)]]></item>
                <item name="wcf.acp.option.mail_send_method.php"><![CDATA[Use PHP]]></item>
                <item name="wcf.acp.option.mail_send_method.smtp"><![CDATA[Use SMTP]]></item>
-               <item name="wcf.acp.option.mail_signature"><![CDATA[Sender’s Signature]]></item>
+               <item name="wcf.acp.option.mail_signature"><![CDATA[Sender’s Signature (Text)]]></item>
                <item name="wcf.acp.option.mail_signature.description"><![CDATA[The signature that will be appended to every message.]]></item>
+               <item name="wcf.acp.option.mail_signature_html"><![CDATA[Sender’s Signature (HTML)]]></item>
+               <item name="wcf.acp.option.mail_signature_html.description"><![CDATA[HTML formatted version of the Sender’s Signature. If this field is left empty the text based signature will be used.]]></item>
                <item name="wcf.acp.option.mail_smtp_host"><![CDATA[SMTP Server]]></item>
                <item name="wcf.acp.option.mail_smtp_host.description"><![CDATA[The SMTP port 465 requires the host to be prefixed with <kbd>ssl://</kbd>, for example, <kbd>ssl://mail.example.com</kbd> instead of <kbd>mail.example.com</kbd>.]]></item>
                <item name="wcf.acp.option.mail_smtp_port"><![CDATA[SMTP Port]]></item>
@@ -1352,13 +1368,11 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.enable_debug_mode.description"><![CDATA[Enables extensive error messages, it should always be disabled in production environments!]]></item>
                <item name="wcf.acp.option.enable_production_debug_mode"><![CDATA[Problem analysis in production environments]]></item>
                <item name="wcf.acp.option.enable_production_debug_mode.description"><![CDATA[Appends the current URL to database queries to assist looking them up in the database server’s log files.]]></item>
-               <item name="wcf.acp.option.external_link_rel_nofollow"><![CDATA[Append the attribute “rel="nofollow"” to all external links]]></item>
-               <item name="wcf.acp.option.external_link_rel_nofollow.description"><![CDATA[The attribute “rel="nofollow"” tells search engines to disregard external links.]]></item>
                <item name="wcf.acp.option.external_link_target_blank"><![CDATA[Open external links in a new window]]></item>
                <item name="wcf.acp.option.external_link_target_blank.description"><![CDATA[Appends the attribute “target="_blank"” to external links, causing the user’s browser to open the link in a new window.]]></item>
                <item name="wcf.acp.option.enable_benchmark"><![CDATA[Enable benchmark]]></item>
                <item name="wcf.acp.option.enable_benchmark.description"><![CDATA[Captures additional data on resource usage by individual components. It is strongly recommended to disable this option in production environments.]]></item>
-               <item name="wcf.acp.option.category.general.system.packageServer"><![CDATA[Update Server]]></item>
+               <item name="wcf.acp.option.category.general.system.packageServer"><![CDATA[Package Server]]></item>
                <item name="wcf.acp.option.package_server_auth_code"><![CDATA[Authentication Code]]></item>
                <item name="wcf.acp.option.package_server_auth_code.description"><![CDATA[Your authentication code is available in the customers area on woltlab.com.]]></item>
                <item name="wcf.acp.option.enable_woltlab_news"><![CDATA[Display WoltLab news]]></item>
@@ -1368,11 +1382,10 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.recaptcha_publickey.description"><![CDATA[You can request your own API-Key for using reCAPTCHA on the <a href="https://www.google.com/recaptcha/admin" class="externalURL">reCAPTCHA website</a>.]]></item>
                <item name="wcf.acp.option.recaptcha_privatekey"><![CDATA[Private API Key (reCAPTCHA v2)]]></item>
                <item name="wcf.acp.option.recaptcha_publickey_invisible"><![CDATA[Public API Key (Invisible reCAPTCHA)]]></item>
-               <item name="wcf.acp.option.recaptcha_publickey_invisible.description"><![CDATA[Enter the keys <b>in addition</b> to the keys above if you want to use the invisible variant of reCAPTCHA.]]></item>
+               <item name="wcf.acp.option.recaptcha_publickey_invisible.description"><![CDATA[Enter the keys <strong>in addition</strong> to the keys above if you want to use the invisible variant of reCAPTCHA.]]></item>
                <item name="wcf.acp.option.recaptcha_privatekey_invisible"><![CDATA[Private API Key (Invisible reCAPTCHA)]]></item>
                <item name="wcf.acp.option.category.message.attachment"><![CDATA[Attachments]]></item>
-               <item name="wcf.acp.option.attachment_enable_thumbnails"><![CDATA[Create thumbnails for attachment images]]></item>
-               <item name="wcf.acp.option.attachment_retain_dimensions"><![CDATA[Retain thumbnail dimensions]]></item>
+               <item name="wcf.acp.option.attachment_retain_dimensions"><![CDATA[Retain Thumbnail Aspect Ratio]]></item>
                <item name="wcf.acp.option.attachment_thumbnail_height"><![CDATA[Thumbnail Height]]></item>
                <item name="wcf.acp.option.attachment_thumbnail_width"><![CDATA[Thumbnail Width]]></item>
                <item name="wcf.acp.option.category.message.attachment.autoscale"><![CDATA[Automatic Image Scaling]]></item>
@@ -1385,7 +1398,6 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.attachment_image_autoscale_file_type"><![CDATA[File type]]></item>
                <item name="wcf.acp.option.attachment_image_autoscale_file_type.jpeg"><![CDATA[JPEG (lossy, usually the generated files are small)]]></item>
                <item name="wcf.acp.option.attachment_image_autoscale_file_type.keep"><![CDATA[Keep the file type]]></item>
-               <item name="wcf.acp.option.module_attachment"><![CDATA[Attachments]]></item>
                <item name="wcf.acp.option.module_smiley"><![CDATA[Smilies]]></item>
                <item name="wcf.acp.option.category.message.censorship"><![CDATA[Censorship]]></item>
                <item name="wcf.acp.option.censored_words"><![CDATA[Censored Words]]></item>
@@ -1436,13 +1448,11 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.module_user_rank"><![CDATA[User ranks]]></item>
                <item name="wcf.acp.option.module_user_signature"><![CDATA[Signatures]]></item>
                <item name="wcf.acp.option.module_team_page"><![CDATA[Staff list]]></item>
-               <item name="wcf.acp.option.register_enable_password_security_check"><![CDATA[Enable password validation]]></item>
-               <item name="wcf.acp.option.register_enable_password_security_check.description"><![CDATA[Password complexity will be validated, unsafe passwords will be rejected.]]></item>
-               <item name="wcf.acp.option.register_password_min_length"><![CDATA[Minimum Password Length]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_digit"><![CDATA[Password must contain digits]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_lower_case"><![CDATA[Password must contain lowercase characters]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_special_char"><![CDATA[Password must contain special characters]]></item>
-               <item name="wcf.acp.option.register_password_must_contain_upper_case"><![CDATA[Password must contain uppercase characters]]></item>
+               <item name="wcf.acp.option.password_min_score"><![CDATA[Security Level]]></item>
+               <item name="wcf.acp.option.password_min_score.description"><![CDATA[“Score” value of the <a href="https://github.com/dropbox/zxcvbn" class="externalURL">zxcvbn library</a> that passwords need to achive.]]></item>
+               <item name="wcf.acp.option.password_min_score.0"><![CDATA[0: Disabled]]></item>
+               <item name="wcf.acp.option.password_min_score.1"><![CDATA[1: Very guessable (1 million attempts)]]></item>
+               <item name="wcf.acp.option.password_min_score.2"><![CDATA[2: Somewhat guessable (100 million attempts)]]></item>
                <item name="wcf.acp.option.register_forbidden_usernames"><![CDATA[Reserved Usernames]]></item>
                <item name="wcf.acp.option.register_forbidden_usernames.description"><![CDATA[You can specify which usernames are unavailable for registration. Enter one username per line.]]></item>
                <item name="wcf.acp.option.register_forbidden_emails"><![CDATA[Reserved Email Addresses]]></item>
@@ -1462,6 +1472,7 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.register_activation_method"><![CDATA[Registration Approval Method]]></item>
                <item name="wcf.acp.option.register_activation_method.byAdmin"><![CDATA[Only administrators can approve registrations]]></item>
                <item name="wcf.acp.option.register_activation_method.byUser"><![CDATA[Registrations are approved through an email confirmation]]></item>
+               <item name="wcf.acp.option.register_activation_method.byUserAndAdmin"><![CDATA[Administrators can approve registrations after an email confirmation]]></item>
                <item name="wcf.acp.option.register_activation_method.disabled"><![CDATA[No approval required for registrations]]></item>
                <item name="wcf.acp.option.signature_max_image_height"><![CDATA[Maximum Image Height]]></item>
                <item name="wcf.acp.option.sitemap_index_time_frame"><![CDATA[Time frame of indexing]]></item>
@@ -1547,7 +1558,6 @@ ATTENTION: The messages listed above are greatly shortened. You can view details
                <item name="wcf.acp.option.google_maps_default_longitude"><![CDATA[Default Map Position (Longitude)]]></item>
                <item name="wcf.acp.option.google_maps_access_user_location"><![CDATA[Use current user location]]></item>
                <item name="wcf.acp.option.google_maps_access_user_location.description"><![CDATA[When entering a location, the current location of the user is used as start point on the map.]]></item>
-               <item name="wcf.acp.option.message_sidebar_enable_user_online_marking"><![CDATA[Apply the users online marking for usernames]]></item>
                <item name="wcf.acp.option.module_cookie_policy_page"><![CDATA[Enable explanation on cookie usage]]></item>
                <item name="wcf.acp.option.module_cookie_policy_page.description"><![CDATA[Displays a notice on cookie usage according to EU Directive 2009/136/EG upon first visit.]]></item>
                <item name="wcf.acp.option.show_update_notice_frontend"><![CDATA[Display a notice for outstanding updates on the frontend]]></item>
@@ -1648,13 +1658,13 @@ When prompted for the notification URL for the instant payment notifications, pl
                <item name="wcf.acp.option.language_use_informal_variant"><![CDATA[Use informal language variant]]></item>
                <item name="wcf.acp.option.category.cms.media.thumbnail"><![CDATA[Thumbnails]]></item>
                <item name="wcf.acp.option.media_large_thumbnail_height"><![CDATA[Large Thumbnail Height]]></item>
-               <item name="wcf.acp.option.media_large_thumbnail_retain_dimensions"><![CDATA[Retain thumbnail dimensions (large)]]></item>
+               <item name="wcf.acp.option.media_large_thumbnail_retain_dimensions"><![CDATA[Retain Thumbnail Aspect Ratio (large)]]></item>
                <item name="wcf.acp.option.media_large_thumbnail_width"><![CDATA[Large Thumbnail Width]]></item>
                <item name="wcf.acp.option.media_medium_thumbnail_height"><![CDATA[Medium Thumbnail Height]]></item>
-               <item name="wcf.acp.option.media_medium_thumbnail_retain_dimensions"><![CDATA[Retain thumbnail dimensions (medium)]]></item>
+               <item name="wcf.acp.option.media_medium_thumbnail_retain_dimensions"><![CDATA[Retain Thumbnail Aspect Ratio (medium)]]></item>
                <item name="wcf.acp.option.media_medium_thumbnail_width"><![CDATA[Medium Thumbnail Width]]></item>
                <item name="wcf.acp.option.media_small_thumbnail_height"><![CDATA[Small Thumbnail Height]]></item>
-               <item name="wcf.acp.option.media_small_thumbnail_retain_dimensions"><![CDATA[Retain thumbnail dimensions (small)]]></item>
+               <item name="wcf.acp.option.media_small_thumbnail_retain_dimensions"><![CDATA[Retain Thumbnail Aspect Ratio (small)]]></item>
                <item name="wcf.acp.option.media_small_thumbnail_width"><![CDATA[Small Thumbnail Width]]></item>
                <item name="wcf.acp.option.article_sort_order"><![CDATA[Sort Order]]></item>
                <item name="wcf.acp.option.article_sort_order.description"><![CDATA[Choose default sort order of articles.]]></item>
@@ -1674,7 +1684,7 @@ When prompted for the notification URL for the instant payment notifications, pl
                <item name="wcf.acp.option.enable_polling"><![CDATA[Enable Background Notifications]]></item>
                <item name="wcf.acp.option.enable_polling.description"><![CDATA[Periodically retrieves new notifications in the background, requests are dispatched every 5 minutes. Interval decreases down to 15 minutes on inactivity.]]></item>
                <item name="wcf.acp.option.enable_desktop_notifications"><![CDATA[Enable Desktop Notifications]]></item>
-               <item name="wcf.acp.option.enable_desktop_notifications.description"><![CDATA[Display a small window for new notifications that have been retrieved in the background. May not be supported in some browsers, e.g. Internet Explorer.]]></item>
+               <item name="wcf.acp.option.enable_desktop_notifications.description"><![CDATA[Display a small window for new notifications that have been retrieved in the background.]]></item>
                <item name="wcf.acp.option.module_contact_form"><![CDATA[Enable contact form]]></item>
                <item name="wcf.acp.option.module_contact_form.description"><![CDATA[Enables the contact form, once enabled you can customize the <a href="{link controller='ContactSettings'}{/link}">input fields and recipients</a> to better suit your needs.]]></item>
                <item name="wcf.acp.option.module_trophy"><![CDATA[Trophies]]></item>
@@ -1700,7 +1710,7 @@ When prompted for the notification URL for the instant payment notifications, pl
                <item name="wcf.acp.option.message_public_highlighters"><![CDATA[Selectable Syntax Highlighters]]></item>
                <item name="wcf.acp.option.message_public_highlighters.description"><![CDATA[The chosen syntax highlighters can easily be selected by the user using the editor. The other highlighters are still available, but their name needs to be known by the user.]]></item>
                <item name="wcf.acp.option.log_missing_language_items"><![CDATA[Log Missing Language Items]]></item>
-               <item name="wcf.acp.option.log_missing_language_items.description"><![CDATA[The missing language items are logged in the log file <kbd>{'WCF_DIR'|constant}log/missingLanguageItems.txt</kbd>.]]></item>
+               <item name="wcf.acp.option.log_missing_language_items.description"><![CDATA[The missing language items are listed on the <a href="{link controller='DevtoolsMissingLanguageItemList'}{/link}">Missing Phrases</a> page.]]></item>
                <item name="wcf.acp.option.category.general.system.ipAddress"><![CDATA[IP Addresses]]></item>
                <item name="wcf.acp.option.prune_ip_address"><![CDATA[Storage Time Period for IP Addresses]]></item>
                <item name="wcf.acp.option.prune_ip_address.description"><![CDATA[Stored IP addresses will be removed after the following days. Use 0 to disable.]]></item>
@@ -1739,6 +1749,11 @@ The database is carefully maintained, but there will be always be a margin of er
                <item name="wcf.acp.option.blacklist_sfs_action.block"><![CDATA[Block]]></item>
                <item name="wcf.acp.option.blacklist_sfs_action.description"><![CDATA[There is always the risk of a false-positive match, therefore it is highly recommended to set it to <strong>Disable and require manual approval</strong>.]]></item>
                <item name="wcf.acp.option.blacklist_sfs_action.disable"><![CDATA[Disable and require manual approval]]></item>
+               <item name="wcf.acp.option.module_amp"><![CDATA[AMP]]></item>
+               <item name="wcf.acp.option.module_amp.description"><![CDATA[Enables <abbr title="Accelerated Mobile Pages">AMP</abbr> versions of certain pages (e.g. articles).]]></item>
+               <item name="wcf.acp.option.message_enable_user_consent"><![CDATA[Prompt users before displaying content from external sources]]></item>
+               <item name="wcf.acp.option.modification_log_expiration"><![CDATA[Storage Time for Modification Logs]]></item>
+               <item name="wcf.acp.option.modification_log_expiration.description"><![CDATA[Modification logs will be deleted after the entered amount of days. To disable deleting old modification logs, enter “0”.]]></item>
        </category>
        <category name="wcf.acp.customOption">
                <item name="wcf.acp.customOption.list"><![CDATA[Option Fields]]></item>
@@ -1791,7 +1806,7 @@ The database is carefully maintained, but there will be always be a margin of er
                <item name="wcf.acp.package.description"><![CDATA[Description]]></item>
                <item name="wcf.acp.package.error.cli.installIsApplication"><![CDATA[Apps cannot be installed via CLI.]]></item>
                <item name="wcf.acp.package.error.exceedsPhpLimit"><![CDATA[The file exceeds the PHP limit “upload_max_filesize” and/or “post_max_size”.]]></item>
-               <item name="wcf.acp.package.error.noUniqueAbbrevation"><![CDATA[There is already an app installed which has the same abbreviation.]]></item>
+               <item name="wcf.acp.package.error.noUniqueAbbreviation"><![CDATA[There is already an app installed which has the same abbreviation.]]></item>
                <item name="wcf.acp.package.error.noValidPackage"><![CDATA[The uploaded archive is invalid.]]></item>
                <item name="wcf.acp.package.error.sql.createTable"><![CDATA[Overwrite Existing Tables]]></item>
                <item name="wcf.acp.package.error.sql.createTable.description"><![CDATA[The tables above already exist and will be replaced during the installation. Any contained data will be lost.]]></item>
@@ -1883,6 +1898,9 @@ The database is carefully maintained, but there will be always be a margin of er
                <item name="wcf.acp.package.update.excludedPackages.excluding.package"><![CDATA[“{$excludedPackage[packageName]}” in version “{$excludedPackage[packageVersion]}” cannot be installed because it is incompatible with the installed package “{$excludedPackage[existingPackageName]}”.]]></item>
                <item name="wcf.acp.package.update.path.incoherent"><![CDATA[The update requires the newer version {$newVersion} of the package “{$packageName}” (installed version: {$currentVersion}), but there is no such update available.]]></item>
                <item name="wcf.acp.package.update.path.unknown"><![CDATA[The update requires the newer version {$newVersion} of the package “{$packageName}” (installed version: {$currentVersion}), but no such update could be found. Perhaps you are missing the required package server?]]></item>
+               <item name="wcf.acp.package.update.purchaseRequired"><![CDATA[Paid Package]]></item>
+               <item name="wcf.acp.package.update.purchaseRequired.button.purchase"><![CDATA[Show in the Plugin-Store]]></item>
+               <item name="wcf.acp.package.update.purchaseRequired.description"><![CDATA[The paid package “{$packageName}” must be purchased in the Plugin-Store before you can install it.]]></item>
                <item name="wcf.acp.package.version"><![CDATA[Version]]></item>
                <item name="wcf.acp.package.packageDir.input"><![CDATA[Installation Directory]]></item>
                <item name="wcf.acp.package.upload"><![CDATA[Upload package]]></item>
@@ -1910,6 +1928,8 @@ The database is carefully maintained, but there will be always be a margin of er
                <item name="wcf.acp.package.validation.errorCode.13"><![CDATA[The API version “{$version}” is invalid.]]></item>
                <item name="wcf.acp.package.validation.errorCode.14"><![CDATA[This package was created for {if $isOlderVersion}an older{else}a newer{/if} version of WoltLab Suite and is not compatible.]]></item>
                <item name="wcf.acp.package.validation.errorCode.15"><![CDATA[This package does not contain any data on API compatibility, the installation is prevented while the developer tools are enabled.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.16"><![CDATA[In addition to the &lt;void/&gt; instruction additional Package Installation Plugins are used.]]></item>
+               <item name="wcf.acp.package.validation.errorCode.17"><![CDATA[The &lt;void/&gt; instruction may not be used in the install-instructions.]]></item>
                <item name="wcf.acp.package.validation.failed"><![CDATA[The package cannot be installed, please review the validation results below.]]></item>
                <item name="wcf.acp.package.evaluation.expired"><![CDATA[The evaluation period of <strong>{$packageName}</strong> has expired. For a legal use of this software, please update to the latest available version.{if $pluginStoreFileID || $isWoltLab}<br>The latest version can be purchased quickly and securely <strong>{if $pluginStoreFileID}<a href="https://pluginstore.woltlab.com/file/{$pluginStoreFileID}/">in the WoltLab Plugin-Store</a>{else}<a href="https://www.woltlab.com/purchase/">on WoltLab.com</a>{/if}</strong>.{/if}]]></item>
                <item name="wcf.acp.package.evaluation.pending"><![CDATA[The evaluation period of the apps listed below will expire on <strong>{$evaluationEndDate|plainTime}</strong> ({@$evaluationEndDate|dateDiff:TIME_NOW:true}). The apps will automatically disable themselves after this date and become unusable, you'll need to install the latest versions of the apps to active them again.
@@ -1925,6 +1945,7 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.package.search.status.loading"><![CDATA[Searching…]]></item>
                <item name="wcf.acp.package.search.status.noResults"><![CDATA[There were no matches.]]></item>
                <item name="wcf.acp.package.search.status.refreshDatabase"><![CDATA[Retrieving the package lists…]]></item>
+               <item name="wcf.acp.package.search.result.official"><![CDATA[{if $count === 0}No matches{elseif $count === 1}One match{else}{#$count} matches{/if} in official WoltLab® packages]]></item>
                <item name="wcf.acp.package.search.result.thirdParty"><![CDATA[{if $count === 0}No matches{elseif $count === 1}One match{else}{#$count} matches{/if} in package sources maintained by third parties]]></item>
                <item name="wcf.acp.package.search.result.trusted"><![CDATA[{if $count === 0}No matches{elseif $count === 1}One match{else}{#$count} matches{/if} in official package sources]]></item>
                <item name="wcf.acp.package.error.databaseChange"><![CDATA[The database layout could not be changed because of the following errors:
@@ -1947,6 +1968,8 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                The primary index {$error[tableName]} ({$error[columnNames]}) contains the column {$error[columnName]} whose values can be NULL.
        {else if $error[type] === 'foreignForeignKeyDrop'}
                The foreign key {$error[tableName]} ({$error[columnNames]}) belongs to a different package and thus cannot be dropped.
+       {else if $error[type] === 'unknownTableInForeignKey'}
+               The foreign key {$error[tableName]} ({$error[columnNames]}) references an unknown table {$error[referencedTableName]}.
        {else}
                Unknown error.
        {/if}
@@ -2005,14 +2028,14 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.pluginStore.purchasedItems"><![CDATA[Purchased Products (Plugin-Store)]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.noResults"><![CDATA[The search returned no results, because either you have not purchased any products yet, or your purchases are not compatible with this version.]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.status.update"><![CDATA[Newer Version Available]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.status.unavailable"><![CDATA[Update-Server not installed]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.status.unavailable"><![CDATA[Package server not installed]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.status.upToDate"><![CDATA[You already have the most recent version installed]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.status.requireUpdate"><![CDATA[Update-Server must be updated]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.status.requireUpdate"><![CDATA[Package server must be updated]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.status.install.confirmMessage"><![CDATA[Do you really want to install the product <span class="confirmationObject">{$product[packageName]}</span>?]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.disabled"><![CDATA[The Update-Server for “{$wcfMajorRelease}” (“http://store.woltlab.com/{$wcfMajorRelease}/”) is disabled and cannot be used for new installs or updates.]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.missing"><![CDATA[The Update-Server for “{$wcfMajorRelease}” does not exist in your installation. If you wish to install the packages below, you must <a href="{link controller='PackageUpdateServerAdd'}{/link}">add it</a>.<br>The server address is: “http://store.woltlab.com/{$wcfMajorRelease}/”]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.requireUpdate"><![CDATA[The Update-Server for “{$wcfMajorRelease}” has not been queried yet, please search for updates to fetch the package list.]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.wcfMajorRelease"><![CDATA[Update-Server for “{$wcfMajorRelease}”]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.disabled"><![CDATA[The package server for “{$wcfMajorRelease}” (“http://store.woltlab.com/{$wcfMajorRelease}/”) is disabled and cannot be used for new installs or updates.]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.missing"><![CDATA[The package server for “{$wcfMajorRelease}” does not exist in your installation. If you wish to install the packages below, you must <a href="{link controller='PackageUpdateServerAdd'}{/link}">add it</a>.<br>The server address is: “http://store.woltlab.com/{$wcfMajorRelease}/”]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.updateServer.requireUpdate"><![CDATA[The package servers have not been fetched yet, please search for available updates first.]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.wcfMajorRelease"><![CDATA[Package server for “{$wcfMajorRelease}”]]></item>
        </category>
        <category name="wcf.acp.pip">
                <item name="wcf.acp.pip.objectType.com.woltlab.wcf.adLocation.data.title"><![CDATA[Ad Location Data]]></item>
@@ -2329,11 +2352,11 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.pip.eventListener.listenerName.error.notUnique"><![CDATA[The entered identifier is already used by another event listener.]]></item>
                <item name="wcf.acp.pip.eventListener.eventClassName"><![CDATA[PHP Event Class]]></item>
                <item name="wcf.acp.pip.eventListener.eventClassName.description"><![CDATA[The entered class (without leading backslash) fires the event. Alternatively, the entered class inherits from the the class firing the event.]]></item>
-               <item name="wcf.acp.pip.eventListener.eventName"><![CDATA[Event Name]]></item>
-               <item name="wcf.acp.pip.eventListener.eventName.description"><![CDATA[Name of the event of the relevant class the event listener is listening to.]]></item>
+               <item name="wcf.acp.pip.eventListener.eventName"><![CDATA[Event Names]]></item>
+               <item name="wcf.acp.pip.eventListener.eventName.description"><![CDATA[Names of the event of the relevant class the event listener is listening to.]]></item>
                <item name="wcf.acp.pip.eventListener.listenerClassName"><![CDATA[PHP Event Listener Class]]></item>
                <item name="wcf.acp.pip.eventListener.environment"><![CDATA[Environment]]></item>
-               <item name="wcf.acp.pip.eventListener.environment.description"><![CDATA[The environment determines whether the event listener is executed in the frontend (<kbd>user</kbd>) or the ACP (<kbd>admin</kbd>).]]></item>
+               <item name="wcf.acp.pip.eventListener.environment.description"><![CDATA[The environment determines whether the event listener is executed in the frontend (<kbd>user</kbd>), the ACP (<kbd>admin</kbd>), or in both (<kbd>all</kbd>).]]></item>
                <item name="wcf.acp.pip.eventListener.inherit"><![CDATA[Support Inheritance]]></item>
                <item name="wcf.acp.pip.eventListener.inherit.description"><![CDATA[If inheritance is supported, the event listener is not only triggered if the event is fired by the class entered above, but it is also fired by classes inheriting from the entered class.]]></item>
                <item name="wcf.acp.pip.eventListener.niceValue"><![CDATA[Nice Value]]></item>
@@ -2553,8 +2576,6 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.poll.description"><![CDATA[Rebuilds the poll counters.]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.article"><![CDATA[Rebuild Articles]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.article.description"><![CDATA[Rebuilds the article search index.]]></item>
-               <item name="wcf.acp.rebuildData.com.woltlab.wcf.databaseConvertEncoding"><![CDATA[Convert Database Encoding]]></item>
-               <item name="wcf.acp.rebuildData.com.woltlab.wcf.databaseConvertEncoding.description"><![CDATA[Warning: This action may take a while to complete on large databases.]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.comment"><![CDATA[Rebuild Comments]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.comment.description"><![CDATA[Rebuilds the comments.]]></item>
                <item name="wcf.acp.rebuildData.com.woltlab.wcf.comment.response"><![CDATA[Rebuild Comment Responses]]></item>
@@ -2685,21 +2706,26 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.systemCheck.mysql.innodb.description"><![CDATA[InnoDB (XtraDB when using MariaDB) is a transaction storage engine for MySQL and is required for the operation of the software. This is a built-in feature of MySQL.]]></item>
                <item name="wcf.acp.systemCheck.directories.writable"><![CDATA[Writable Directories]]></item>
                <item name="wcf.acp.systemCheck.directories.writable.description"><![CDATA[Some directories are being written to during the normal operation. The user that runs the PHP process must have write access.]]></item>
+               <item name="wcf.acp.systemCheck.php.gd"><![CDATA[Supported formats of the GD library]]></item>
+               <item name="wcf.acp.systemCheck.php.gd.description"><![CDATA[The GD library must be installed with support for the formats “jpeg” and “png”.]]></item>
        </category>
        <category name="wcf.acp.updateServer">
                <item name="wcf.acp.updateServer.add"><![CDATA[Add Server]]></item>
                <item name="wcf.acp.updateServer.delete.sure"><![CDATA[Do you really want to delete the server <span class="confirmationObject">{$updateServer->serverURL}</span>?]]></item>
                <item name="wcf.acp.updateServer.edit"><![CDATA[Edit Server]]></item>
                <item name="wcf.acp.updateServer.errorMessage"><![CDATA[Error Message]]></item>
-               <item name="wcf.acp.updateServer.list"><![CDATA[Update-Servers]]></item>
+               <item name="wcf.acp.updateServer.list"><![CDATA[Package Servers]]></item>
                <item name="wcf.acp.updateServer.lastErrorMessage"><![CDATA[Errors occurred on last connection attempt:]]></item>
                <item name="wcf.acp.updateServer.loginPassword"><![CDATA[Password]]></item>
                <item name="wcf.acp.updateServer.loginPassword.description"><![CDATA[Enter your authentication password (optional).]]></item>
+               <item name="wcf.acp.updateServer.loginPassword.noChange"><![CDATA[(no change)]]></item>
                <item name="wcf.acp.updateServer.loginUsername"><![CDATA[Username]]></item>
                <item name="wcf.acp.updateServer.loginUsername.description"><![CDATA[Enter your authentication username (optional).]]></item>
                <item name="wcf.acp.updateServer.packages"><![CDATA[Packages]]></item>
                <item name="wcf.acp.updateServer.serverURL"><![CDATA[Address]]></item>
                <item name="wcf.acp.updateServer.serverURL.error.invalid"><![CDATA[The address is invalid.]]></item>
+               <item name="wcf.acp.updateServer.serverURL.error.woltlab"><![CDATA[The official servers are already set up and correctly configured.]]></item>
+               <item name="wcf.acp.updateServer.serverURL.error.duplicate"><![CDATA[The given server already exists. You can <a href="{link controller="PackageUpdateServerEdit" id=$errorType[duplicate]->packageUpdateServerID}{/link}"><strong>edit this server instead</strong></a>.]]></item>
                <item name="wcf.acp.updateServer.status"><![CDATA[Status]]></item>
                <item name="wcf.acp.updateServer.lastUpdateTime"><![CDATA[Last Access]]></item>
        </category>
@@ -2754,6 +2780,7 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.style.advanced.overrideScss.error.invalid"><![CDATA[The input for “{$error[text]}” invalid.]]></item>
                <item name="wcf.acp.style.advanced.overrideScss.error.predefined"><![CDATA[The variable “{$error[text]}” is already defined by the style editor.]]></item>
                <item name="wcf.acp.style.advanced.overrideScss.error.unknown"><![CDATA[The variable “{$error[text]}” is not recognized.]]></item>
+               <item name="wcf.acp.style.advanced.individualScss.error"><![CDATA[The SCSS code contains an error: {$errorType.message}.]]></item>
                <item name="wcf.acp.style.apiVersion"><![CDATA[Enable Compatibility Mode with WoltLab Suite]]></item>
                <item name="wcf.acp.style.apiVersion.deprecated"><![CDATA[deprecated]]></item>
                <item name="wcf.acp.style.apiVersion.description"><![CDATA[Disables selected style improvements in order to maximize compatibility with styles for earlier versions of WoltLab Suite.]]></item>
@@ -2793,6 +2820,8 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.style.coverPhoto"><![CDATA[Default Cover Photo]]></item>
                <item name="wcf.acp.style.coverPhoto.delete.confirmMessage"><![CDATA[Do you really want to delete the default cover photo? Once deleted, the global default photo will be used instead.]]></item>
                <item name="wcf.acp.style.coverPhoto.description"><![CDATA[The image must be at least {$coverPhotoMinWidth}×{$coverPhotoMinHeight} pixels large, acceptable image types are GIF, JPG, JPEG and PNG.]]></item>
+               <item name="wcf.acp.style.customAssets"><![CDATA[Additional Images]]></item>
+               <item name="wcf.acp.style.customAssets.description"><![CDATA[{literal}The uploaded images will be stored with the same file name within the <kbd>custom/</kbd> folder in the style’s image folder. You can retrieve the folder’s path within the CSS by using <kbd>#{$style_image_path}custom/</kbd>.{/literal}]]></item>
                <item name="wcf.acp.style.delete.confirmMessage"><![CDATA[Do you really want to delete the style <span class="confirmationObject">{$style->styleName}</span>?]]></item>
                <item name="wcf.acp.style.edit"><![CDATA[Edit Style]]></item>
                <item name="wcf.acp.style.exportAsPackage"><![CDATA[Export as package]]></item>
@@ -2820,6 +2849,7 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.style.globalValues"><![CDATA[Global CSS and SCSS]]></item>
                <item name="wcf.acp.style.globalValues.description"><![CDATA[The CSS and SCSS entered below is applied to all styles, but custom values in styles take precedence.]]></item>
                <item name="wcf.acp.style.globalValues.input"><![CDATA[Individual CSS and SCSS]]></item>
+               <item name="wcf.acp.style.globalValues.input.error"><![CDATA[The SCSS code contains an error: {$errorType.message}.]]></item>
                <item name="wcf.acp.style.image"><![CDATA[Preview Image]]></item>
                <item name="wcf.acp.style.image.description"><![CDATA[Upload a preview image for this style, acceptable image types are JPG and PNG. Dimensions should be 102×64 pixels, exceeding images will be scaled.]]></item>
                <item name="wcf.acp.style.image2x"><![CDATA[Preview Image (HD)]]></item>
@@ -2849,7 +2879,6 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.style.styleVersion"><![CDATA[Version]]></item>
                <item name="wcf.acp.style.templateGroupID"><![CDATA[Template Group]]></item>
                <item name="wcf.acp.style.users"><![CDATA[Users]]></item>
-               <item name="wcf.acp.style.image.error.invalidExtension"><![CDATA[The file extension is invalid.]]></item>
                <item name="wcf.acp.style.imagePath.error.invalid"><![CDATA[You have provided an invalid path.]]></item>
                <item name="wcf.acp.style.styleVersion.error.invalid"><![CDATA[You have provided an invalid version number.]]></item>
                <item name="wcf.acp.style.styleDate.error.invalid"><![CDATA[You have provided an invalid date.]]></item>
@@ -2864,13 +2893,14 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.style.globals.fontSizeHeadline"><![CDATA[Font Size (Headline)]]></item>
                <item name="wcf.acp.style.globals.fontSizeSection"><![CDATA[Font Size (Section)]]></item>
                <item name="wcf.acp.style.globals.fontSizeTitle"><![CDATA[Font Size (Page Title)]]></item>
-               <item name="wcf.acp.style.globals.useGoogleFont"><![CDATA[Use Google font face]]></item>
                <item name="wcf.acp.style.globals.fontFamilyGoogle"><![CDATA[Font Face]]></item>
+               <item name="wcf.acp.style.globals.fontFamilyGoogle.description"><![CDATA[The selected font face will be downloaded when saving the style and afterwards will be delivered as a web font to your users without connecting to external services.]]></item>
+               <item name="wcf.acp.style.globals.fontFamilyGoogle.error.downloadFailed"><![CDATA[Downloading the given font face failed.]]></item>
+               <item name="wcf.acp.style.globals.fontFamilyGoogle.error.downloadFailed.notFound"><![CDATA[The given font face could not be found.]]></item>
                <item name="wcf.acp.style.globals.fontFamilyFallback"><![CDATA[Font Face (Fallback)]]></item>
                <item name="wcf.acp.style.favicon"><![CDATA[Individual Favicon]]></item>
                <item name="wcf.acp.style.favicon.description"><![CDATA[Upload an 256×256 pixels image, acceptable image types are JPG and PNG. The uploaded image will be used to derive all required favicon sizes.]]></item>
                <item name="wcf.acp.style.favicon.error.dimensions"><![CDATA[The image must be exactly 256×256 pixels large.]]></item>
-               <item name="wcf.acp.style.favicon.error.invalidExtension"><![CDATA[The file extension is invalid.]]></item>
        </category>
        <category name="wcf.acp.tag">
                <item name="wcf.acp.tag.add"><![CDATA[Add Tag]]></item>
@@ -2969,7 +2999,6 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.user.search.display.itemsPerPage"><![CDATA[Users per Page]]></item>
                <item name="wcf.acp.user.search.display.sort"><![CDATA[Sort Order]]></item>
                <item name="wcf.acp.user.search.error.noMatches"><![CDATA[No users matched your criteria.]]></item>
-               <item name="wcf.acp.user.search.matches"><![CDATA[{#$items} result{if $items != 1}s{/if}]]></item>
                <item name="wcf.acp.user.sendMail"><![CDATA[Send Email to Users]]></item>
                <item name="wcf.acp.user.sendMail.all"><![CDATA[Email All Users]]></item>
                <item name="wcf.acp.user.sendMail.enableHTML"><![CDATA[Enable HTML code in email message]]></item>
@@ -3075,10 +3104,11 @@ You can define the default sender in “Configuration » Options » General » E
                <item name="wcf.acp.user.disableSignature.neverExpires"><![CDATA[Permanently Block]]></item>
                <item name="wcf.acp.user.disable"><![CDATA[Disable]]></item>
                <item name="wcf.acp.user.enable"><![CDATA[Approve]]></item>
-               <item name="wcf.acp.user.quickSearch.disabled"><![CDATA[Users awaiting approval]]></item>
+               <item name="wcf.acp.user.quickSearch.disabled"><![CDATA[Disabled Users]]></item>
+               <item name="wcf.acp.user.quickSearch.pendingActivation"><![CDATA[Users awaiting approval]]></item>
                <item name="wcf.acp.user.quickSearch.disabledAvatars"><![CDATA[Blocked avatars]]></item>
                <item name="wcf.acp.user.quickSearch.disabledSignatures"><![CDATA[Blocked signatures]]></item>
-               <item name="wcf.acp.user.usersAwaitingApprovalInfo"><![CDATA[<a href="{link controller='UserQuickSearch'}mode=disabled{/link}">{#$usersAwaitingApproval} User{if $usersAwaitingApproval != 1}s{/if}</a> {if $usersAwaitingApproval == 1}is{else}are{/if} awaiting your approval.]]></item>
+               <item name="wcf.acp.user.usersAwaitingApprovalInfo"><![CDATA[<a href="{link controller='UserQuickSearch'}mode=pendingActivation{/link}">{#$usersAwaitingApproval} User{if $usersAwaitingApproval != 1}s{/if}</a> {if $usersAwaitingApproval == 1}is{else}are{/if} awaiting your approval.]]></item>
                <item name="wcf.acp.user.search.conditions.state.enabled"><![CDATA[Approved]]></item>
                <item name="wcf.acp.user.search.conditions.state.disabled"><![CDATA[Awaiting Approval]]></item>
                <item name="wcf.acp.user.sendNewPassword.mail.subject"><![CDATA[New Password for your Account for Website: {@PAGE_TITLE|language}]]></item>
@@ -3133,6 +3163,8 @@ Your account on the website: {@PAGE_TITLE|language} [URL:{link isEmail=true}{/li
                <item name="wcf.acp.user.action.sendMail"><![CDATA[Send Email]]></item>
                <item name="wcf.acp.user.action.sendNewPassword"><![CDATA[Send New Password]]></item>
                <item name="wcf.acp.user.action.sendNewPassword.confirmMessage"><![CDATA[Do you really want to send a new password to this user?]]></item>
+               <item name="wcf.acp.user.action.confirmEmail"><![CDATA[Confirm Email Address]]></item>
+               <item name="wcf.acp.user.action.unconfirmEmail"><![CDATA[Unconfirm Email Address]]></item>
                <item name="wcf.acp.user.exportGdpr"><![CDATA[Export Personal Data (GDPR)]]></item>
                <item name="wcf.acp.user.coverPhoto.description"><![CDATA[You can upload a cover photo on their user profile page.]]></item>
        </category>
@@ -3179,9 +3211,13 @@ Your account on the website: {@PAGE_TITLE|language} [URL:{link isEmail=true}{/li
                <item name="wcf.article.search.results"><![CDATA[Search Results]]></item>
                <item name="wcf.article.publicationStatus.0"><![CDATA[This article has not been published yet.]]></item>
                <item name="wcf.article.publicationStatus.2"><![CDATA[This article will be published on {@$publicationDate|plainTime}.]]></item>
+               <item name="wcf.article.like.notification.title"><![CDATA[Reaction to your article]]></item>
+               <item name="wcf.article.like.notification.title.stacked"><![CDATA[{#$count} users reacted to your article]]></item>
+               <item name="wcf.article.like.notification.message"><![CDATA[<strong>{$author}</strong> reacted to your article <strong>{$article->getTitle()}</strong> ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
+               <item name="wcf.article.like.notification.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} reacted to article <strong>{$article->getTitle()}</strong> ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
        </category>
        <category name="wcf.attachment">
-               <item name="wcf.attachment.file.info"><![CDATA[({@$attachment->filesize|filesize}, downloaded <b>{#$attachment->downloads}</b> times{if $attachment->downloads > 0}, last: {@$attachment->lastDownloadTime|time}{/if})]]></item>
+               <item name="wcf.attachment.file.info"><![CDATA[({@$attachment->filesize|filesize}, downloaded <strong>{#$attachment->downloads}</strong> times{if $attachment->downloads > 0}, last: {@$attachment->lastDownloadTime|time}{/if})]]></item>
                <item name="wcf.attachment.image.info"><![CDATA[{@$attachment->filesize|filesize}, {#$attachment->width}×{#$attachment->height}, viewed {#$attachment->downloads} times]]></item>
                <item name="wcf.attachment.files"><![CDATA[Files]]></item>
                <item name="wcf.attachment.images"><![CDATA[Images]]></item>
@@ -3275,9 +3311,12 @@ Errors are:
 - Missing commands
 - Failing commands
 - Core errors]]></item>
-               <item name="wcf.cli.help.packageID"><![CDATA[The given package id will be used as a default for this session.]]></item>
                <item name="wcf.cli.worker.setParameter"><![CDATA[Sets a worker parameter e.g.: --setParameter param=value]]></item>
                <item name="wcf.cli.worker.list"><![CDATA[Lists all workers.]]></item>
+               <item name="wcf.cli.worker.threads"><![CDATA[Requested number of parallel processes.]]></item>
+               <item name="wcf.cli.worker.threads.windows"><![CDATA[Parallel processing using --threads is not available on Windows.]]></item>
+               <item name="wcf.cli.worker.threadId"><![CDATA[Specifies the thread id when processing in parallel. Used internally when --threads is given.]]></item>
+               <item name="wcf.cli.worker.threadId.invalid"><![CDATA[The given thread id is not valid.]]></item>
                <item name="wcf.cli.error.help.noArguments"><![CDATA[The command "{$command}" does not support any parameters.]]></item>
                <item name="wcf.cli.error.language.notFound"><![CDATA[The language with the language code "{$languageCode}" could not be found.]]></item>
                <item name="wcf.cli.error.command.notFound"><![CDATA[The command "{$command}" could not be found. Type in "commands" to list available commands.]]></item>
@@ -3313,6 +3352,8 @@ Errors are:
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendMail"><![CDATA[Send Email]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword"><![CDATA[Send New Password ({#$count})]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage"><![CDATA[Do you really want to send a new password to {#$count} user{if $count != 1}s{/if}?]]></item>
+               <item name="wcf.clipboard.item.com.woltlab.wcf.user.confirmEmail"><![CDATA[Confirm Email Address ({#$count})]]></item>
+               <item name="wcf.clipboard.item.com.woltlab.wcf.user.unconfirmEmail"><![CDATA[Unconfirm Email Address ({#$count})]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.article.marked"><![CDATA[{if $count == 1}One Article{else}{#$count} Articles{/if}]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.media.marked"><![CDATA[{if $count == 1}One File{else}{#$count} Files{/if}]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.tag.marked"><![CDATA[{if $count == 1}One Tag{else}{#$count} Tags{/if}]]></item>
@@ -3333,6 +3374,7 @@ Errors are:
                <item name="wcf.comment.guestDialog.title"><![CDATA[Guest Comment]]></item>
                <item name="wcf.comment.sortField.cumulativeLikes"><![CDATA[Reactions]]></item>
                <item name="wcf.comment.sortField.time"><![CDATA[Date]]></item>
+               <item name="wcf.comment.objectAuthor"><![CDATA[Author]]></item>
        </category>
        <category name="wcf.condition">
                <item name="wcf.condition.greaterThan"><![CDATA[greater than]]></item>
@@ -3794,6 +3836,7 @@ Attachments:
                <item name="wcf.global.filter.visibility.showAll"><![CDATA[Show all]]></item>
                <item name="wcf.global.success"><![CDATA[The action completed successfully.]]></item>
                <item name="wcf.global.success.add"><![CDATA[The entry has been saved.]]></item>
+               <item name="wcf.global.success.add.editCreatedObject"><![CDATA[You can create another one now or <a href="{$objectEditLink}">edit the previously created entry</a>.]]></item>
                <item name="wcf.global.success.edit"><![CDATA[Your changes have been saved.]]></item>
                <item name="wcf.global.language.noSelection"><![CDATA[No Selection]]></item>
                <item name="wcf.global.loading"><![CDATA[Loading …]]></item>
@@ -3830,7 +3873,7 @@ Attachments:
                <item name="wcf.global.button.showAll"><![CDATA[Display All]]></item>
                <item name="wcf.global.reason"><![CDATA[Reason]]></item>
                <item name="wcf.global.settings"><![CDATA[Settings]]></item>
-               <item name="wcf.global.bulkProcessing.warning"><![CDATA[Warning! The bulk processing will be processed <b>without further confirmation</b> for all items matching your criteria.]]></item>
+               <item name="wcf.global.bulkProcessing.warning"><![CDATA[Warning! The bulk processing will be processed <strong>without further confirmation</strong> for all items matching your criteria.]]></item>
                <item name="wcf.global.search"><![CDATA[Search]]></item>
                <item name="wcf.global.select"><![CDATA[Select]]></item>
                <item name="wcf.global.sorting"><![CDATA[Sorting]]></item>
@@ -3966,14 +4009,14 @@ Attachments:
                <item name="wcf.like.likes.noMoreEntries"><![CDATA[There are no new likes at the moment.]]></item>
                <item name="wcf.like.dislikes.more"><![CDATA[More Dislikes]]></item>
                <item name="wcf.like.dislikes.noMoreEntries"><![CDATA[There are no new dislikes at the moment.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on <a href="{$comment->getLink()}">{$user->username}’s wall</a>.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment.response"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the response by {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}a guest{/if} on the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on <a href="{$response->getLink()}">{$user->username}’s wall</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment"><![CDATA[Reacted with {@$reaction->render()} to the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on <a href="{$comment->getLink()}">{$user->username}’s wall</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.user.profileComment.response"><![CDATA[Reacted with {@$reaction->render()} to the response by {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}a guest{/if} on the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on <a href="{$response->getLink()}">{$user->username}’s wall</a>.]]></item>
                <item name="wcf.like.objectType.com.woltlab.wcf.likeableArticle"><![CDATA[Article]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.likeableArticle"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the article <a href="{$article->getLink()}">{$article->getTitle()}</a>.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.articleComment"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the article <a href="{$comment->getLink()}">{$articleContent->getTitle()}</a>.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.articleComment.response"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the response by {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}a guest{/if} on the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the article <a href="{$response->getLink()}">{$articleContent->getTitle()}</a>.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.pageComment"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the page <a href="{$comment->getLink()}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.like.title.com.woltlab.wcf.pageComment.response"><![CDATA[Reacted with <span title="{$like->getReactionType()->getTitle()}" class="jsTooltip">{@$like->getReactionType()->renderIcon()}</span> to the response by {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}a guest{/if} on the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the page <a href="{$response->getLink()}">{$page->getTitle()}</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.likeableArticle"><![CDATA[Reacted with {@$reaction->render()} to the article <a href="{$article->getLink()}">{$article->getTitle()}</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.articleComment"><![CDATA[Reacted with {@$reaction->render()} to the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the article <a href="{$comment->getLink()}">{$articleContent->getTitle()}</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.articleComment.response"><![CDATA[Reacted with {@$reaction->render()} to the response by {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}a guest{/if} on the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the article <a href="{$response->getLink()}">{$articleContent->getTitle()}</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.pageComment"><![CDATA[Reacted with {@$reaction->render()} to the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the page <a href="{$comment->getLink()}">{$page->getTitle()}</a>.]]></item>
+               <item name="wcf.like.title.com.woltlab.wcf.pageComment.response"><![CDATA[Reacted with {@$reaction->render()} to the response by {if $responseAuthor}<a href="{link controller='User' object=$responseAuthor}{/link}">{$responseAuthor->username}</a>{else}a guest{/if} on the comment by {if $commentAuthor}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}a guest{/if} on the page <a href="{$response->getLink()}">{$page->getTitle()}</a>.]]></item>
                <item name="wcf.like.reaction.label"><![CDATA[{#$reactions} reaction{if $reactions != 1}s{/if}]]></item>
                <item name="wcf.like.reaction.more"><![CDATA[More Reactions]]></item>
                <item name="wcf.like.reaction.noMoreEntries"><![CDATA[There are no new reactions at the moment.]]></item>
@@ -4001,6 +4044,7 @@ Attachments:
        <category name="wcf.media">
                <item name="wcf.media.altText"><![CDATA[Alternate Text]]></item>
                <item name="wcf.media.button.insert"><![CDATA[Insert]]></item>
+               <item name="wcf.media.button.replaceFile"><![CDATA[Replace File]]></item>
                <item name="wcf.media.button.select"><![CDATA[Select]]></item>
                <item name="wcf.media.caption"><![CDATA[Caption]]></item>
                <item name="wcf.media.caption.enableHtml"><![CDATA[Enable HTML code in caption]]></item>
@@ -4027,6 +4071,8 @@ Attachments:
                <item name="wcf.media.media.pageTitle"><![CDATA[{if $__wcf->session->getPermission('admin.content.cms.canOnlyAccessOwnMedia')}Own {/if}Media]]></item>
                <item name="wcf.media.search.cancel"><![CDATA[Cancel Search]]></item>
                <item name="wcf.media.search.placeholder"><![CDATA[Search Files]]></item>
+               <item name="wcf.media.upload.error.differentFileExtension"><![CDATA[The new file must have the same file extension as the current file.]]></item>
+               <item name="wcf.media.upload.error.differentFileType"><![CDATA[The new file must be of the same file type as the current file.]]></item>
                <item name="wcf.media.upload.error.noImage"><![CDATA[The uploaded file is no image.]]></item>
                <item name="wcf.media.upload.error.uploadFailed"><![CDATA[An unknown error occurred during the upload.]]></item>
                <item name="wcf.media.upload.success"><![CDATA[The file has been successfully uploaded.]]></item>
@@ -4056,7 +4102,7 @@ Attachments:
                <item name="wcf.message.quote.manageQuotes"><![CDATA[Manage Quotes]]></item>
                <item name="wcf.message.quote.quoteSelected"><![CDATA[Save Quote]]></item>
                <item name="wcf.message.quote.quoteAndReply"><![CDATA[Insert Quote]]></item>
-               <item name="wcf.message.quote.showQuotes"><![CDATA[Quotes (#count#)]]></item>
+               <item name="wcf.message.quote.showQuotes"><![CDATA[{if $count == 1}One Quote{else}{#$count} Quotes{/if}]]></item>
                <item name="wcf.message.quote.quoteMessage"><![CDATA[Quote]]></item>
                <item name="wcf.message.quote.removeAllQuotes"><![CDATA[Remove All Quotes]]></item>
                <item name="wcf.message.quote.removeSelectedQuotes"><![CDATA[Removed Marked Quotes]]></item>
@@ -4085,6 +4131,10 @@ Attachments:
                <item name="wcf.message.toc"><![CDATA[Contents]]></item>
                <item name="wcf.message.toc.hide"><![CDATA[hide]]></item>
                <item name="wcf.message.toc.show"><![CDATA[show]]></item>
+               <item name="wcf.message.user.consent.button.enable"><![CDATA[Display all external content]]></item>
+               <item name="wcf.message.user.consent.description"><![CDATA[Content embedded from external sources will not be displayed without your consent.]]></item>
+               <item name="wcf.message.user.consent.notice"><![CDATA[Through the activation of external content, you agree that personal data may be transferred to third party platforms. We have provided more information on this in our privacy policy.]]></item>
+               <item name="wcf.message.user.consent.title"><![CDATA[External Content]]></item>
        </category>
        <category name="wcf.menu">
                <!-- category for menus and menu items -->
@@ -4099,6 +4149,8 @@ Attachments:
                <item name="wcf.moderation.assignedUser.change"><![CDATA[Change Assigned User]]></item>
                <item name="wcf.moderation.assignedUser.error.notAffected"><![CDATA[This user does not have sufficient privileges.]]></item>
                <item name="wcf.moderation.assignedUser.nobody"><![CDATA[Nobody]]></item>
+               <item name="wcf.moderation.assignedUsername"><![CDATA[Assigned User]]></item>
+               <item name="wcf.moderation.filter"><![CDATA[Filter Items]]></item>
                <item name="wcf.moderation.filterByType"><![CDATA[Type]]></item>
                <item name="wcf.moderation.filterByUser"><![CDATA[Assigned User]]></item>
                <item name="wcf.moderation.filterByUser.allEntries"><![CDATA[All Items]]></item>
@@ -4111,16 +4163,16 @@ Attachments:
                <item name="wcf.moderation.noMoreItems"><![CDATA[You have no recent items.]]></item>
                <item name="wcf.moderation.notification.comment.title"><![CDATA[New comment (Moderation)]]></item>
                <item name="wcf.moderation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Moderation)]]></item>
-               <item name="wcf.moderation.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on the moderation entry <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote comments on the moderation entry <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.notification.comment.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the moderation entry {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.moderation.notification.comment.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the moderation entry <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.moderation.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on the moderation entry <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} commented on the moderation entry <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.notification.comment.mail.plaintext"><![CDATA[{@$authorList} commented on the moderation entry {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.moderation.notification.comment.mail.html"><![CDATA[<p>{@$authorList} commented on the moderation entry <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.moderation.notification.commentResponse.title"><![CDATA[New reply (Moderation)]]></item>
                <item name="wcf.moderation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (Moderation)]]></item>
-               <item name="wcf.moderation.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on the moderation entry <a href="{@$moderationQueue->getLink()}#comment{@$commentID}/response{@$responseID}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote replies to comments on the moderation entry <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on the moderation entry {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.moderation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on the moderation entry <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.moderation.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to a comment by <strong>{$commentAuthor}</strong> on the moderation entry <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to comments on the moderation entry <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on the moderation entry {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.moderation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} replied to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on the moderation entry <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.moderation.status"><![CDATA[Status]]></item>
                <item name="wcf.moderation.status.outstanding"><![CDATA[Pending]]></item>
                <item name="wcf.moderation.status.processing"><![CDATA[In Progress]]></item>
@@ -4148,6 +4200,9 @@ Attachments:
                <item name="wcf.moderation.jumpToContent"><![CDATA[Go to Related Content]]></item>
                <item name="wcf.moderation.markAllAsRead"><![CDATA[Mark All Items Read]]></item>
                <item name="wcf.moderation.markAsRead.doubleClick"><![CDATA[Double-Click to Mark This Item Read]]></item>
+               <item name="wcf.moderation.comments"><![CDATA[Comments]]></item>
+               <item name="wcf.moderation.username"><![CDATA[Author]]></item>
+               <item name="wcf.moderation.noEntries"><![CDATA[There are no items at the moment. <a href="#" class="jsStaticDialog" data-dialog-id="moderationListSortFilter" role="button">Change the filters.</a>{if $hasActiveFilter} <a href="{link controller='ModerationList'}{/link}">Reset the active filters.</a>{/if}]]></item>
        </category>
        <category name="wcf.moderation.activation">
                <item name="wcf.moderation.activation"><![CDATA[Approval]]></item>
@@ -4157,16 +4212,16 @@ Attachments:
                <item name="wcf.moderation.activation.enableContent.confirmMessage"><![CDATA[Do you really want to approve this content?]]></item>
                <item name="wcf.moderation.activation.notification.comment.title"><![CDATA[New comment (Approval)]]></item>
                <item name="wcf.moderation.activation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Approval)]]></item>
-               <item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
-               <item name="wcf.moderation.activation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote comments on <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
-               <item name="wcf.moderation.activation.notification.comment.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] waiting for approval{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.moderation.activation.notification.comment.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the moderation entry <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> waiting for approval:</p>]]></item>
+               <item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on <strong>{$moderationQueue}</strong> waiting for approval.]]></item>
+               <item name="wcf.moderation.activation.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} commented on <strong>{$moderationQueue}</strong> waiting for approval.]]></item>
+               <item name="wcf.moderation.activation.notification.comment.mail.plaintext"><![CDATA[{@$authorList} commented on {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] waiting for approval{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.moderation.activation.notification.comment.mail.html"><![CDATA[<p>{@$authorList} commented on the moderation entry <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a> waiting for approval:</p>]]></item>
                <item name="wcf.moderation.activation.notification.commentResponse.title"><![CDATA[New reply (Approval)]]></item>
                <item name="wcf.moderation.activation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (Approval)]]></item>
-               <item name="wcf.moderation.activation.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on <a href="{@$moderationQueue->getLink()}#comment{@$commentID}/response{@$responseID}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
-               <item name="wcf.moderation.activation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote replies to comments on <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
-               <item name="wcf.moderation.activation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] waiting for approval{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.moderation.activation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>  waiting for approval:</p>]]></item>
+               <item name="wcf.moderation.activation.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to a comment by <strong>{$commentAuthor}</strong> on <strong>{$moderationQueue}</strong> waiting for approval.]]></item>
+               <item name="wcf.moderation.activation.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to comments on <strong>{$moderationQueue}</strong> waiting for approval.]]></item>
+               <item name="wcf.moderation.activation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}] waiting for approval{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.moderation.activation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} replied to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>  waiting for approval:</p>]]></item>
                <item name="wcf.moderation.activation.removeContent"><![CDATA[Delete Content]]></item>
                <item name="wcf.moderation.activation.removeContent.confirmMessage"><![CDATA[Do you really want to delete this content?]]></item>
        </category>
@@ -4176,16 +4231,16 @@ Attachments:
                <item name="wcf.moderation.report.details"><![CDATA[Information]]></item>
                <item name="wcf.moderation.report.notification.comment.title"><![CDATA[New comment (Report)]]></item>
                <item name="wcf.moderation.report.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Report)]]></item>
-               <item name="wcf.moderation.report.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on the report <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.report.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote comments on the report <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.report.notification.comment.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the report {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.moderation.report.notification.comment.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the report <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.moderation.report.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on the report <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.report.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} commented on the report <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.report.notification.comment.mail.plaintext"><![CDATA[{@$authorList} commented on the report {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.moderation.report.notification.comment.mail.html"><![CDATA[<p>{@$authorList} commented on the report <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.moderation.report.notification.commentResponse.title"><![CDATA[New reply (Report)]]></item>
                <item name="wcf.moderation.report.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (Report)]]></item>
-               <item name="wcf.moderation.report.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on the report <a href="{@$moderationQueue->getLink()}#comment{@$commentID}/response{@$responseID}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.report.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote replies to comments on the report <a href="{@$moderationQueue->getLink()}#comment{@$commentID}">{$moderationQueue->getTitle()}</a>.]]></item>
-               <item name="wcf.moderation.report.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on the report {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.moderation.report.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on the report <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.moderation.report.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to a comment by <strong>{$commentAuthor->username}</strong> on the report <strong>{$moderationQueue}</strong>.]]></item>
+               <item name="wcf.moderation.report.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to comments on the report <strong>{$moderationQueue->getTitle()}</strong>.]]></item>
+               <item name="wcf.moderation.report.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on the report {@$notificationContent[variables][moderationQueue]->getTitle()} [URL:{@$notificationContent[variables][moderationQueue]->getLink()}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.moderation.report.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} replied to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on the report <a href="{$notificationContent[variables][moderationQueue]->getLink()}">{$notificationContent[variables][moderationQueue]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.moderation.report.reason"><![CDATA[Reason]]></item>
                <item name="wcf.moderation.report.reason.description"><![CDATA[This function is reserved for: spam, advertisement and other questionable (racism, glorification of violence, offending, or sexist) content.]]></item>
                <item name="wcf.moderation.report.removeContent"><![CDATA[Delete Content]]></item>
@@ -4320,7 +4375,7 @@ Attachments:
                <item name="wcf.paidSubscription.confirmTOS"><![CDATA[I agree to the <a href="{PAID_SUBSCRIPTION_TOS_URL}">Terms of Service</a>]]></item>
                <item name="wcf.paidSubscription.button.moreInformation"><![CDATA[More Details]]></item>
                <item name="wcf.paidSubscription.expiringSubscription.notification.title"><![CDATA[Expiring Subscription]]></item>
-               <item name="wcf.paidSubscription.expiringSubscription.notification.message"><![CDATA[Your subscription “{$userNotificationObject->getTitle()}” will expire {dateInterval start=$notification->time end=$userNotificationObject->endDate full=true format='sentence'} (on {$userNotificationObject->endDate|date:'F jS'}).]]></item>
+               <item name="wcf.paidSubscription.expiringSubscription.notification.message"><![CDATA[Your subscription <strong>{$userNotificationObject->getTitle()}</strong> will expire {dateInterval start=$notification->time end=$userNotificationObject->endDate full=true format='sentence'} (on {$userNotificationObject->endDate|date:'F jS'}).]]></item>
                <item name="wcf.paidSubscription.expiringSubscription.notification.mail.plaintext"><![CDATA[Your subscription “{@$subscription->getTitle()}” will expire {dateInterval start=$notification->time end=$subscription->endDate full=true format='sentence'} (on {@$subscription->endDate|date:'F jS'}).]]></item>
                <item name="wcf.paidSubscription.expiringSubscription.notification.mail.html"><![CDATA[Your subscription “{$subscription->getTitle()}” will expire <b>{dateInterval start=$notification->time end=$subscription->endDate full=true format='sentence'}</b> (on {$subscription->endDate|date:'F jS'}).]]></item>
        </category>
@@ -4360,6 +4415,7 @@ Attachments:
                <item name="wcf.reactions.summary.noReactions"><![CDATA[There are no reactions at the moment.]]></item>
                <item name="wcf.reactions.summary.listReactions"><![CDATA[List Reactions]]></item>
                <item name="wcf.reactions.react"><![CDATA[React]]></item>
+               <item name="wcf.reactions.reactionTypeCount"><![CDATA[{@$reaction->renderIcon()}&#x202F;×&#x202F;{#$count}]]></item>
        </category>
        <category name="wcf.reactionType">
                <item name="wcf.reactionType.title1"><![CDATA[Like]]></item>
@@ -4483,6 +4539,7 @@ Attachments:
                <item name="wcf.user.usernameOrEmail"><![CDATA[Username or Email Address]]></item>
                <item name="wcf.user.gender.male"><![CDATA[Male]]></item>
                <item name="wcf.user.gender.female"><![CDATA[Female]]></item>
+               <item name="wcf.user.gender.other"><![CDATA[Other]]></item>
                <item name="wcf.user.members"><![CDATA[Members]]></item>
                <item name="wcf.user.members.filter"><![CDATA[Filter Members]]></item>
                <item name="wcf.user.members.noMembers"><![CDATA[No members matched your criteria. <a href="{link controller='MembersList'}{/link}">Reset the applied filters.</a>]]></item>
@@ -4505,12 +4562,35 @@ Attachments:
                <item name="wcf.user.styles"><![CDATA[Styles]]></item>
                <item name="wcf.user.style.description"><![CDATA[Forces a specific style instead of the default one.]]></item>
                <item name="wcf.user.username.description"><![CDATA[Username must be {REGISTER_USERNAME_MIN_LENGTH} up to {REGISTER_USERNAME_MAX_LENGTH} characters long.]]></item>
-               <item name="wcf.user.password.description"><![CDATA[{if REGISTER_ENABLE_PASSWORD_SECURITY_CHECK}Due to security reasons every password must be at least {REGISTER_PASSWORD_MIN_LENGTH} characters long{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{*
-               *} and contain {*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}lower-case letters{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} and{/if} {/if}upper-case letters{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} and{/if} {/if}digits{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT} and {/if}special chars{/if}{/if}.{else}A secure password should be at least 8 characters long.{/if}]]></item>
+               <item name="wcf.user.password.description"><![CDATA[A secure password should be at least 10 characters long.]]></item>
+               <item name="wcf.user.password.strength"><![CDATA[Password Strength]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.use_words_avoid_common_phrases"><![CDATA[Use a few words, avoid common phrases.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.no_need_for_symbols_digits_uppercase"><![CDATA[No need for symbols, digits, or uppercase letters.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.add_word_uncommon_better"><![CDATA[Add another word or two. Uncommon words are better.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.use_longer_keyboard_pattern"><![CDATA[Use a longer keyboard pattern with more turns.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_repeat"><![CDATA[Avoid repeated words and characters.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_sequence"><![CDATA[Avoid sequences.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_recent_year"><![CDATA[Avoid recent years.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_associated_year"><![CDATA[Avoid years that are associated with you.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.avoid_date"><![CDATA[Avoid dates and years that are associated with you.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.start_upper"><![CDATA[Capitalization does not help very much.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.all_upper"><![CDATA[All-uppercase is almost as easy to guess as all-lowercase.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.reversed"><![CDATA[Reversed words aren’t much harder to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.suggestions.l33t"><![CDATA[Predictable substitutions like “@” instead of “a” don’t help very much.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.straight_row"><![CDATA[Straight rows of keys are easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.short_keyboard_pattern"><![CDATA[Short keyboard patterns are easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.repeat_single_char"><![CDATA[Repeats like “aaa” are easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.repeat"><![CDATA[Repeats like “abcabcabc” are only slightly harder to guess than “abc”.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.sequence"><![CDATA[Sequences like “abc” or “6543” are easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.recent_year"><![CDATA[Recent years are easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.date"><![CDATA[Dates are often easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.top_10"><![CDATA[This is a top-10 common password.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.top_100"><![CDATA[This is a top-100 common password.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.common"><![CDATA[This is a very common password.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.common_alike"><![CDATA[This is similar to a commonly used password.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.sole_word"><![CDATA[A word by itself is easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.sole_name"><![CDATA[Names and surnames by themselves are easy to guess.]]></item>
+               <item name="wcf.user.password.zxcvbn.warnings.name"><![CDATA[Common names and surnames are easy to guess.]]></item>
                <item name="wcf.user.lostPassword"><![CDATA[Lost Password]]></item>
                <item name="wcf.user.lostPassword.description"><![CDATA[You must provide your username or email address to request a new password. Contact the site’s administrator if you need assistance.]]></item>
                <item name="wcf.user.lostPassword.email.error.notFound"><![CDATA[“{$email}” is not used by any account.]]></item>
@@ -4557,12 +4637,7 @@ the website <a href="{link isHtmlEmail=true}{/link}">{@PAGE_TITLE|language}</a>.
                <item name="wcf.user.quit.success"><![CDATA[Your user account will be deleted on {TIME_NOW+7*86400|date}. During this time period you can abort the deletion on this page.]]></item>
                <item name="wcf.user.quit.cancel.success"><![CDATA[The account deletion has been aborted.]]></item>
                <item name="wcf.user.emailActivation"><![CDATA[Verify New Email Address]]></item>
-               <item name="wcf.user.password.error.notSecure"><![CDATA[Due to security reasons, every password must be at least {REGISTER_PASSWORD_MIN_LENGTH} characters long{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{*
-               *} and contain {*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}lower-case letters{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT || REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} and{/if} {/if}upper-case letters{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_DIGIT}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR},{else} and{/if} {/if}digits{/if}{*
-               *}{if REGISTER_PASSWORD_MUST_CONTAIN_SPECIAL_CHAR}{if REGISTER_PASSWORD_MUST_CONTAIN_LOWER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_UPPER_CASE || REGISTER_PASSWORD_MUST_CONTAIN_DIGIT} and {/if}special chars{/if}{/if}.]]></item>
+               <item name="wcf.user.password.error.notSecure"><![CDATA[Please select a more secure password.]]></item>
                <item name="wcf.user.changeUsername.success"><![CDATA[The username has been changed.]]></item>
                <item name="wcf.user.changeEmail.success"><![CDATA[The email address has been changed.]]></item>
                <item name="wcf.user.changeEmail.needReactivation"><![CDATA[Your new email address{if $newEmail|isset} (“{$newEmail}”){/if} must be verified first. You should have received an email which was sent to your new email address containing an activation link. Open the link to verify your new email address.]]></item>
@@ -4590,17 +4665,18 @@ If you have troubles confirming your email address, please contact the
 administrator at: {@MAIL_ADMIN_ADDRESS}. Please ignore this email if you did
 not register with us.]]></item>
                <item name="wcf.user.changePassword.success"><![CDATA[The password has been changed.]]></item>
-               <item name="wcf.user.activationCode"><![CDATA[9-digit Activation Code]]></item>
+               <item name="wcf.user.activationCode"><![CDATA[Activation Code]]></item>
                <item name="wcf.user.newActivationCode"><![CDATA[Request New Activation Code]]></item>
                <item name="wcf.user.registerActivation"><![CDATA[Complete Registration]]></item>
                <item name="wcf.user.registerActivation.error.userAlreadyEnabled"><![CDATA[The user is already activated.]]></item>
                <item name="wcf.user.registerActivation.success"><![CDATA[The user account has been activated.]]></item>
+               <item name="wcf.user.registerActivation.success.awaitAdminActivation"><![CDATA[The email address has been confirmed. Now your account must be activated by an administrator.]]></item>
                <item name="wcf.user.activationCode.error.invalid"><![CDATA[You have provided an invalid activation code. Click the link below if you wish to request a new activation code.]]></item>
                <item name="wcf.user.registerNewActivationCode.email.description"><![CDATA[You can provide a different email address or leave it empty to send the code to the same email address again.]]></item>
                <item name="wcf.user.newActivationCode.success"><![CDATA[The activation code has been sent to “{$email}”.]]></item>
                <item name="wcf.user.emailActivation.error.emailAlreadyEnabled"><![CDATA[The email address is already activated.]]></item>
                <item name="wcf.user.emailActivation.success"><![CDATA[The email address has been activated.]]></item>
-               <item name="wcf.user.registerActivation.info"><![CDATA[An email containing the 9-digit activation code has been sent to “{$__wcf->user->email}”.]]></item>
+               <item name="wcf.user.registerActivation.info"><![CDATA[An email containing the activation code has been sent to “{$__wcf->user->email}”.]]></item>
                <item name="wcf.user.username.error.alreadyRenamed"><![CDATA[The username was already changed within the last {#$__wcf->getSession()->getPermission('user.profile.renamePeriod')} days.]]></item>
                <item name="wcf.user.guest"><![CDATA[Guest]]></item>
                <item name="wcf.user.signature"><![CDATA[Signature]]></item>
@@ -4706,7 +4782,7 @@ not register with us.]]></item>
 user account to it’s full extent it is required that you confirm validity of your email address once:</p>]]></item>
                <item name="wcf.user.register.needActivation.mail.html.activate"><![CDATA[Confirm my email address]]></item>
                <item name="wcf.user.register.needActivation.mail.html.outro"><![CDATA[
-<p>Your activation code is: <kbd>{$mailbox->getUser()->activationCode}</kbd>.</p>
+<p>Your activation code is: <kbd>{$mailbox->getUser()->emailConfirmed}</kbd>.</p>
 <p>If you have trouble confirming your email address, please contact the administrator at:
 <a href="mailto:{MAIL_ADMIN_ADDRESS}">{MAIL_ADMIN_ADDRESS}</a>. Please ignore this email if
 you did not register an account with us.</p>]]></item>
@@ -4716,13 +4792,15 @@ Thank you for registering at: {@PAGE_TITLE|language} [URL:{link isEmail=true}{/l
 able to use your user account to it's full extent it is required that you
 confirm the validity of your email address once:
 
-    {link controller='RegisterActivation' isEmail=true}u={@$mailbox->getUser()->userID}&a={@$mailbox->getUser()->activationCode}{/link} {* this line ends with a space *}
+    {link controller='RegisterActivation' isEmail=true}u={@$mailbox->getUser()->userID}&a={@$mailbox->getUser()->emailConfirmed}{/link} {* this line ends with a space *}
 
-Your activation code is: {@$mailbox->getUser()->activationCode} {* this line ends with a space *}
+Your activation code is: {@$mailbox->getUser()->emailConfirmed} {* this line ends with a space *}
 
 If you have trouble confirming your email address, please contact the
 administrator at: {@MAIL_ADMIN_ADDRESS}. Please ignore this email if you did
 not register with us.]]></item>
+               <item name="wcf.user.register.needAdminActivation"><![CDATA[Your account must be activated by an administrator in order to use the full scope of the website.]]></item>
+               <item name="wcf.user.register.needEmailConfirmation"><![CDATA[Your email address is not activated yet. {if $__wcf->user->canEmailConfirm()}<a href="{link controller='RegisterNewActivationCode'}{/link}">Confirm your email address</a>{else}To activate your email address contact the administrator of this site{/if}.]]></item>
                <!-- Success Messages -->
                <item name="wcf.user.register.success"><![CDATA[Thank you for registering, {$user->username}.<br>
 Your registration is now completed.]]></item>
@@ -4736,12 +4814,12 @@ A notification will be sent once your account has been approved.]]></item>
                <!-- Administrator Notification -->
                <item name="wcf.user.register.notification.mail"><![CDATA[Dear Administrator,
 
-someone registered with your website {@PAGE_TITLE|language}: {@$user->username} 
+someone registered with your website {@PAGE_TITLE|language}: {@$user->username}.
 
-Email address used: {@$user->email} 
+Email address used: {@$user->email}.
 
 Open the link below to access the user profile:
-{link controller='User' object=$user isEmail=true}{/link} ]]></item>
+{link controller='User' object=$user isEmail=true}{/link}]]></item>
                <item name="wcf.user.register.notification.mail.subject"><![CDATA[New Registration with Your Website: {@PAGE_TITLE|language}]]></item>
                <!-- Disclaimer -->
                <item name="wcf.user.register.disclaimer.accept"><![CDATA[Accept]]></item>
@@ -4771,13 +4849,14 @@ Open the link below to access the user profile:
                <item name="wcf.user.trophy.dialogTitle"><![CDATA[Trophies of {$username}]]></item>
                <item name="wcf.user.trophy.trophies"><![CDATA[Trophies]]></item>
                <item name="wcf.user.trophy.specialTrophies"><![CDATA[Special Trophies]]></item>
-               <item name="wcf.user.trophy.specialTrophies.description"><![CDATA[Choose the special trophies that you want to be shown in your profile and in the message sidebar.]]></item>
+               <item name="wcf.user.trophy.specialTrophies.description"><![CDATA[Choose the special {if $__wcf->getSession()->getPermission('user.profile.trophy.maxUserSpecialTrophies') > 1}trophies{else}trophy{/if} that you want to be shown in your profile and in the message sidebar.{if $__wcf->getSession()->getPermission('user.profile.trophy.maxUserSpecialTrophies') > 1} You can select a maximum of {#$__wcf->getSession()->getPermission('user.profile.trophy.maxUserSpecialTrophies')} trophies.{/if}]]></item>
                <item name="wcf.user.trophy.specialTrophies.error.tooMany"><![CDATA[You can choose a maximum of {#$__wcf->session->getPermission('user.profile.trophy.maxUserSpecialTrophies')} trophies.]]></item>
                <item name="wcf.user.trophy.specialTrophies.error.invalid"><![CDATA[The selected trophies are invalid.]]></item>
                <item name="wcf.user.trophy.recentActivity.received"><![CDATA[Has received the trophy <a href="{$userTrophy->getTrophy()->getLink()}">{$userTrophy->getTrophy()->getTitle()}</a>.]]></item>
                <item name="wcf.user.trophy.condition.excludedTrophies"><![CDATA[Excluded Trophies]]></item>
                <item name="wcf.user.trophy.condition.excludedTrophyCategories"><![CDATA[Excluded Trophy Categories]]></item>
                <item name="wcf.user.trophy.trophyAwarded"><![CDATA[{if $items == 1}Awarded once{else}Awarded {#$items} times{/if}]]></item>
+               <item name="wcf.user.trophy.showMoreTrophies"><![CDATA[and {#$trophyCount} more]]></item>
        </category>
        <category name="wcf.acp.trophy">
                <item name="wcf.acp.trophy"><![CDATA[Trophy]]></item>
@@ -4815,17 +4894,11 @@ Open the link below to access the user profile:
        </category>
        <category name="wcf.user.usersOnline">
                <item name="wcf.user.usersOnline"><![CDATA[Users Online]]></item>
-               <item name="wcf.user.usersOnline.detail"><![CDATA[
-{if $usersOnlineList->stats[members] > 0}
-       {#$usersOnlineList->stats[members]} Member{if $usersOnlineList->stats[members] != 1}s{/if}
-{/if} 
-{if $usersOnlineList->stats[invisible] > 0}
-       ({#$usersOnlineList->stats[invisible]} invisible)
-{/if}
-{if $usersOnlineList->stats[guests] > 0 && $usersOnlineList->stats[members] > 0}and{/if}
-{if $usersOnlineList->stats[guests] > 0}
-       {#$usersOnlineList->stats[guests]} Guest{if $usersOnlineList->stats[guests] != 1}s{/if}
-{/if}]]></item>
+               <item name="wcf.user.usersOnline.detail"><![CDATA[{*
+*}{if $usersOnlineList->stats[members] > 0}{#$usersOnlineList->stats[members]} Member{if $usersOnlineList->stats[members] != 1}s{/if}{/if}{*
+*}{if $usersOnlineList->stats[invisible] > 0} ({#$usersOnlineList->stats[invisible]} invisible){/if}{*
+*}{if $usersOnlineList->stats[guests] > 0 && $usersOnlineList->stats[members] > 0} and {/if}{*
+*}{if $usersOnlineList->stats[guests] > 0}{#$usersOnlineList->stats[guests]} Guest{if $usersOnlineList->stats[guests] != 1}s{/if}{/if}]]></item>
                <item name="wcf.user.usersOnline.invisible"><![CDATA[ (invisible)]]></item>
                <item name="wcf.user.usersOnline.marking.legend"><![CDATA[Legend]]></item>
                <item name="wcf.user.usersOnline.guests"><![CDATA[Guests]]></item>
@@ -4946,12 +5019,25 @@ Open the link below to access the user profile:
                <item name="wcf.user.condition.state.isEnabled"><![CDATA[Approved]]></item>
                <item name="wcf.user.condition.state.isEnabled.error.conflict"><![CDATA[You cannot simultaneously select “Approved” and “Awaiting Approval”.]]></item>
                <item name="wcf.user.condition.state.isNotBanned"><![CDATA[Not Banned]]></item>
+               <item name="wcf.user.condition.state.isEmailConfirmed"><![CDATA[Has a confirmed email address]]></item>
+               <item name="wcf.user.condition.state.isEmailConfirmed.error.conflict"><![CDATA[You cannot simultaneously select “Has a confirmed email address” and “Has not a confirmed email address”.]]></item>
+               <item name="wcf.user.condition.state.isNotEmailConfirmed"><![CDATA[Has not a confirmed email address]]></item>
                <item name="wcf.user.condition.userTrophyIDs"><![CDATA[User has Trophy]]></item>
                <item name="wcf.user.condition.userTrophyIDs.description"><![CDATA[User has received the selected trophies.]]></item>
                <item name="wcf.user.condition.notUserTrophyIDs"><![CDATA[User does not have Trophy]]></item>
                <item name="wcf.user.condition.notUserTrophyIDs.description"><![CDATA[User has not received the selected trophies.]]></item>
                <item name="wcf.user.condition.notUserTrophyIDs.error.userTrophyIntersection"><![CDATA[The selected trophies in “User has Trophy” and “User does not have Trophy” are conflicting.]]></item>
                <item name="wcf.user.condition.trophyPoints"><![CDATA[Trophies]]></item>
+               <item name="wcf.user.condition.coverPhoto"><![CDATA[Cover Photo]]></item>
+               <item name="wcf.user.condition.coverPhoto.coverPhoto"><![CDATA[Has Cover Photo]]></item>
+               <item name="wcf.user.condition.coverPhoto.noCoverPhoto"><![CDATA[Has no Cover Photo]]></item>
+               <item name="wcf.user.condition.signature"><![CDATA[Signature]]></item>
+               <item name="wcf.user.condition.signature.signature"><![CDATA[Has Signature]]></item>
+               <item name="wcf.user.condition.signature.noSignature"><![CDATA[Has no Signature]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays"><![CDATA[Last Activity … Days Ago]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays.error.endBeforeStart"><![CDATA[The end value is less than the start value.]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays.error.invalidEnd"><![CDATA[The end value is invalid.]]></item>
+               <item name="wcf.user.condition.lastActivityTimeIntervalDays.error.invalidStart"><![CDATA[The start value is invalid.]]></item>
        </category>
        <category name="wcf.user.coverPhoto">
                <item name="wcf.user.coverPhoto"><![CDATA[Cover Photo]]></item>
@@ -4982,11 +5068,15 @@ Open the link below to access the user profile:
                <item name="wcf.user.notification.noMoreNotifications"><![CDATA[You have no recent notifications.]]></item>
                <item name="wcf.user.notification.noNotifications"><![CDATA[There are no notifications at the moment.]]></item>
                <item name="wcf.user.notification.notifications"><![CDATA[Notifications]]></item>
-               <item name="wcf.user.notification.notifications.description"><![CDATA[Email notifications may not be supported for every available notification]]></item>
                <item name="wcf.user.notification.notifications.disabled"><![CDATA[Disabled]]></item>
                <item name="wcf.user.notification.notifications.enabled"><![CDATA[Enabled]]></item>
                <item name="wcf.user.notification.showAll"><![CDATA[Display All Notifications]]></item>
                <item name="wcf.user.notification.mail.disabled"><![CDATA[Email notification has been disabled.]]></item>
+               <item name="wcf.user.notification.mail.disabled"><![CDATA[The selected email notifications have been unsubscribed.]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.confirm"><![CDATA[Unsubscribe selected email notifications]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.description"><![CDATA[Please select the email notifications you would like to unsubscribe.]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.event"><![CDATA[Notification Type]]></item>
+               <item name="wcf.user.notification.mail.unsubscribe.event.all"><![CDATA[All Email Notifications]]></item>
                <item name="wcf.user.notification.mailNotificationType.none"><![CDATA[No Email Notification]]></item>
                <item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Instant Email Notification]]></item>
                <item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Daily Email Notification]]></item>
@@ -5000,14 +5090,14 @@ Visit your notification settings [URL:{link controller='NotificationSettings' is
 your notifications on {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] as you wish.
 
 If you only wish to disable this type of notification you can do so by visiting:
-{link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}]]></item>
+{link controller='NotificationUnsubscribe' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}]]></item>
                <item name="wcf.user.notification.mail.html.intro"><![CDATA[<h2>Dear {$mailbox->getUser()->username},</h2>]]></item>
                <item name="wcf.user.notification.mail.html.outro"><![CDATA[<p>This is an automatic notification, <b>please do not reply to this email</b>!</p>
 
 <p>Visit your <a href="{link controller='NotificationSettings' isHtmlEmail=true}{/link}">notification settings</a> to configure
 your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> as you wish.</p>
 
-<p>You can <a href="{link controller='NotificationDisable' isHtmlEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">disable only this type of notification</a> as well.</p>]]></item>
+<p>You can <a href="{link controller='NotificationUnsubscribe' isHtmlEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">disable only this type of notification</a> as well.</p>]]></item>
                <item name="wcf.user.notification.mail.daily.subject"><![CDATA[{if $count == 1}New Notification{else}{#$count} New Notifications{/if}]]></item>
                <item name="wcf.user.notification.mail.daily.plaintext.intro"><![CDATA[Dear {@$mailbox->getUser()->username},
 
@@ -5020,7 +5110,7 @@ Visit your notification settings [URL:{link controller='NotificationSettings' is
 your notifications on {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] as you wish.
 
 If you wish to disable all email notifications you can do so by visiting:
-{link controller='NotificationDisable' isEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}]]></item>
+{link controller='NotificationUnsubscribe' isEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}]]></item>
                <item name="wcf.user.notification.mail.daily.html.intro"><![CDATA[<h2>Dear {$mailbox->getUser()->username},</h2>
 
 <p>You currently have {#$notifications|count} unread notification{if $notifications|count != 1}s{/if} older than 24 hours:</p>]]></item>
@@ -5031,44 +5121,46 @@ If you wish to disable all email notifications you can do so by visiting:
 <p>Visit your <a href="{link controller='NotificationSettings' isHtmlEmail=true}{/link}">notification settings</a> to configure
 your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a> as you wish.</p>
 
-<p>You can <a href="{link controller='NotificationDisable' isHtmlEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">disable all email notifications</a> as well.</p>]]></item>
+<p>You can <a href="{link controller='NotificationUnsubscribe' isHtmlEmail=true}userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">disable all email notifications</a> as well.</p>]]></item>
                <item name="wcf.user.notification.mail.authorList.plaintext"><![CDATA[{if !$event->getAuthor()->userID}{if $guestTimesTriggered > 1}Guests{else}A guest{/if}{else}{@$event->getAuthor()->username} [URL:{link controller='User' object=$event->getAuthor() isEmail=true}{/link}]{/if}{if $count > 1 && $count < 4}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->username} [URL:{link controller='User' object=$authors[1] isEmail=true}{/link}]{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if}{@$authors[2]->username} [URL:{link controller='User' object=$authors[2] isEmail=true}{/link}]{/if}{elseif $count >= 4}{if $guestTimesTriggered},{else} and{/if} {#$count-1} other users{/if}{if $event->getAuthor()->userID && $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}{#$guestTimesTriggered} guests{/if}{/if}]]></item>
                <item name="wcf.user.notification.mail.authorList.html"><![CDATA[{if !$event->getAuthor()->userID}{if $guestTimesTriggered > 1}Guests{else}A guest{/if}{else}<a href="{link controller='User' object=$event->getAuthor() isHtmlEmail=true}{/link}">{$event->getAuthor()->username}</a>{/if}{if $count > 1 && $count < 4}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}<a href="{link controller='User' object=$authors[1] isHtmlEmail=true}{/link}">{$authors[1]->username}</a>{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if}<a href="{link controller='User' object=$authors[2] isHtmlEmail=true}{/link}">{$authors[2]->username}</a>{/if}{elseif $count >= 4}{if $guestTimesTriggered},{else} and{/if} {#$count-1} other users{/if}{if $event->getAuthor()->userID && $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}{#$guestTimesTriggered} guests{/if}{/if}]]></item>
+               <item name="wcf.user.notification.stacked.authorList"><![CDATA[{if !$guestTimesTriggered|isset}{assign var=guestTimesTriggered value=0}{/if}{if $count < 4}<strong>{$authors[0]}</strong>{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}<strong>{$authors[1]}</strong>{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} <strong>{$authors[2]}</strong>{/if}{/if}{if $guestTimesTriggered} and {plural value=$guestTimesTriggered one='a guest' other='# guests'}{/if}{else}<strong>{$authors[0]}</strong>{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {plural value=$guestTimesTriggered one='a guest' other='# guests'}{/if}{/if}]]></item>
+               <item name="wcf.user.notification.mail.jumpToContent"><![CDATA[Jump To Content]]></item>
                <!-- Notifications -->
                <item name="wcf.user.notification.com.woltlab.wcf.user"><![CDATA[User Profiles]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.follow.following"><![CDATA[Notify me of new followers]]></item>
                <item name="wcf.user.notification.follow.title"><![CDATA[New Follower]]></item>
                <item name="wcf.user.notification.follow.title.stacked"><![CDATA[{#$count} new followers]]></item>
-               <item name="wcf.user.notification.follow.message"><![CDATA[{@$author->getAnchorTag()} follows you.]]></item>
-               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} follow you.]]></item>
+               <item name="wcf.user.notification.follow.message"><![CDATA[<strong>{$author}</strong> follows you.]]></item>
+               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} follow you.]]></item>
                <item name="wcf.user.notification.follow.mail.plaintext"><![CDATA[{@$authorList} {if $authors|count == 1}follows{else}follow{/if} you.]]></item>
                <item name="wcf.user.notification.follow.mail.html"><![CDATA[<p>{@$authorList} {if $authors|count == 1}follows{else}follow{/if} you:</p>]]></item>
                <item name="wcf.user.notification.comment.title"><![CDATA[New Comment (Wall)]]></item>
                <item name="wcf.user.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Wall)]]></item>
-               <item name="wcf.user.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">your wall</a>.]]></item>
-               <item name="wcf.user.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} wrote comments on <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">your wall</a>.]]></item>
-               <item name="wcf.user.notification.comment.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on your wall [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.comment.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}{/link}">your wall</a>:</p>]]></item>
+               <item name="wcf.user.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on your wall.]]></item>
+               <item name="wcf.user.notification.comment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} commented on your wall.]]></item>
+               <item name="wcf.user.notification.comment.mail.plaintext"><![CDATA[{@$authorList} commented on your wall [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.comment.mail.html"><![CDATA[<p>{@$authorList} commented on <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}{/link}">your wall</a>:</p>]]></item>
                <item name="wcf.user.notification.comment.like.title"><![CDATA[Reaction to a comment (Wall)]]></item>
                <item name="wcf.user.notification.comment.like.title.stacked"><![CDATA[{#$count} users reacted to your comment (Wall)]]></item>
-               <item name="wcf.user.notification.comment.like.message"><![CDATA[{@$author->getAnchorTag()} reacted to your comment on {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">your wall</a>{else}<a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">{$owner->username}’s wall</a>{/if} ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
-               <item name="wcf.user.notification.comment.like.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} reacted to your comment on {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">your wall</a>{else}<a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">{$owner->username}’s wall</a>{/if} ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
+               <item name="wcf.user.notification.comment.like.message"><![CDATA[<strong>{$author}</strong> reacted to your comment on {if $owner === null}your wall{else}<strong>{$owner}</strong>’s</a>{/if} ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
+               <item name="wcf.user.notification.comment.like.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} reacted to your comment on {if $owner === null}your wall{else}<strong>{$owner}</strong>’s wall{/if} ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
                <item name="wcf.user.notification.commentResponse.title"><![CDATA[New Reply (Wall)]]></item>
                <item name="wcf.user.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (Wall)]]></item>
-               <item name="wcf.user.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to your comment on <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if $owner->userID == $__wcf->getUser()->userID}your{else}{$owner->username}’s{/if} wall</a>.]]></item>
-               <item name="wcf.user.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} replied to your comment on <a href="{link controller='User' object=$owner}#wall/comment{@$commentID}{/link}">{if $owner->userID == $__wcf->getUser()->userID}your{else}{$owner->username}’s{/if} wall</a>.]]></item>
-               <item name="wcf.user.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to your comment on {if $mailbox->getUser()->userID == $notificationContent[variables][owner]->userID}your{else}{@$notificationContent[variables][owner]->username}’s{/if} wall [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to your comment on <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if $mailbox->getUser()->userID == $notificationContent[variables][owner]->userID}your{else}{$notificationContent[variables][owner]->username}’s{/if} wall</a>:</p>]]></item>
+               <item name="wcf.user.notification.commentResponse.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to your comment on {if $owner->userID == $__wcf->getUser()->userID}your{else}<strong>{$owner}</strong>’s{/if} wall.]]></item>
+               <item name="wcf.user.notification.commentResponse.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to your comment on {if $owner->userID == $__wcf->getUser()->userID}your{else}<strong>{$owner}</strong>’s{/if} wall.]]></item>
+               <item name="wcf.user.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} replied to your comment on {if $mailbox->getUser()->userID == $notificationContent[variables][owner]->userID}your{else}{@$notificationContent[variables][owner]->username}’s{/if} wall [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} replied to your comment on <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">{if $mailbox->getUser()->userID == $notificationContent[variables][owner]->userID}your{else}{$notificationContent[variables][owner]->username}’s{/if} wall</a>:</p>]]></item>
                <item name="wcf.user.notification.commentResponse.like.title"><![CDATA[Likes your reply to a comment (Wall)]]></item>
                <item name="wcf.user.notification.commentResponse.like.title.stacked"><![CDATA[{#$count} users reacted to your reply to a comment (Wall)]]></item>
-               <item name="wcf.user.notification.commentResponse.like.message"><![CDATA[{@$author->getAnchorTag()} reacted to your reply to a comment on {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}/response{@$responseID}{/link}">your wall</a>{else}<a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">{$owner->username}’s wall</a>{/if} ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
-               <item name="wcf.user.notification.commentResponse.like.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} reacted to your reply to a comment on {if $owner === null}<a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}/response{@$responseID}{/link}">your wall</a>{else}<a href="{link controller='User' object=$owner}#wall/comment{@$commentID}/response{@$responseID}{/link}">{$owner->username}’s wall</a>{/if} ({implode from=$reactions key=reactionID item=count}{@$__wcf->getReactionHandler()->getReactionTypeByID($reactionID)->renderIcon()}×{#$count}{/implode}).]]></item>
+               <item name="wcf.user.notification.commentResponse.like.message"><![CDATA[<strong>{$author}</strong> reacted to your reply to a comment on {if $owner === null}your wall{else}<strong>{$owner}</strong>’s wall{/if} ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
+               <item name="wcf.user.notification.commentResponse.like.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} reacted to your reply to a comment on {if $owner === null}your wall{else}<strong>{$owner}</strong>’s wall{/if} ({@$__wcf->getReactionHandler()->renderInlineList($reactions)}).]]></item>
                <item name="wcf.user.notification.commentResponseOwner.title"><![CDATA[New Reply (Wall)]]></item>
                <item name="wcf.user.notification.commentResponseOwner.title.stacked"><![CDATA[{#$timesTriggered} new replies (Wall)]]></item>
-               <item name="wcf.user.notification.commentResponseOwner.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to {$commentAuthor->username}’s comment on <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}/response{@$responseID}{/link}">your wall</a>.]]></item>
-               <item name="wcf.user.notification.commentResponseOwner.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} replied to the comment by {if $author->userID}<a href="{link controller='User' object=$author}{/link}" class="userLink" data-user-id="{@$author->userID}">{$author->username}</a>{else}{$author->username}{/if} on <a href="{link controller='User' object=$__wcf->getUser()}#wall/comment{@$commentID}{/link}">your wall</a>.]]></item>
-               <item name="wcf.user.notification.commentResponseOwner.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on your wall [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.commentResponseOwner.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">your wall</a>:</p>]]></item>
+               <item name="wcf.user.notification.commentResponseOwner.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to <strong>{$commentAuthor}</strong>’s comment on your wall.]]></item>
+               <item name="wcf.user.notification.commentResponseOwner.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to the comment by <strong>{$author}</strong> on your wall.]]></item>
+               <item name="wcf.user.notification.commentResponseOwner.mail.plaintext"><![CDATA[{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on your wall [URL:{link controller='User' object=$notificationContent[variables][owner] isEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.commentResponseOwner.mail.html"><![CDATA[<p>{@$authorList} replied to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on <a href="{link controller='User' object=$notificationContent[variables][owner] isHtmlEmail=true}#wall/comment{@$commentID}/response{@$responseID}{/link}">your wall</a>:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.notification.comment"><![CDATA[Notify me of new comments on my wall]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.response.notification.commentResponse"><![CDATA[Notify me of new replies to my comments]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.response.notification.commentResponseOwner"><![CDATA[Notify me of new replies to comments on my wall]]></item>
@@ -5077,7 +5169,7 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.notification.com.woltlab.wcf.paidSubscription.user.expiring"><![CDATA[Notify me before a subscription will expire]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.userTrophy.notification.received"><![CDATA[Notify me when I receive a trophy]]></item>
                <item name="wcf.user.notification.trophy.received.title"><![CDATA[Trophy received]]></item>
-               <item name="wcf.user.notification.trophy.received.message"><![CDATA[You received the trophy <a href="{$userTrophy->getTrophy()->getLink()}">{$userTrophy->getTrophy()->getTitle()}</a>.]]></item>
+               <item name="wcf.user.notification.trophy.received.message"><![CDATA[You received the trophy <strong>{$userTrophy->getTrophy()}</strong>.]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.administration"><![CDATA[Administration]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.registration.notification.registration"><![CDATA[Notify me of new user registrations]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.moderation"><![CDATA[Moderation]]></item>
@@ -5087,48 +5179,49 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.notification.com.woltlab.wcf.page.notification.comment"><![CDATA[Notify me when new comments are written on pages]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponse"><![CDATA[Notify me when new replies to comments are written on pages]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.page.response.notification.commentResponseOwner"><![CDATA[Notify me when someone replies to my comments on pages]]></item>
+               <item name="wcf.user.notification.com.woltlab.wcf.likeableArticle.notification.like"><![CDATA[Notify me when someone reacted to my articles]]></item>
                <item name="wcf.user.notification.pageComment.title"><![CDATA[New Comment (Page)]]></item>
                <item name="wcf.user.notification.pageComment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Page)]]></item>
-               <item name="wcf.user.notification.pageComment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on the page <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.pageComment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} wrote comments on the page <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.pageComment.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the page “{@$notificationContent[variables][page]->getTitle()}” [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.pageComment.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a comment{else}comments{/if} on the page <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.user.notification.pageComment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on the page <strong>{$page->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.pageComment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} commented on the page <strong>{$page->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.pageComment.mail.plaintext"><![CDATA[{@$authorList} commented on the page “{@$notificationContent[variables][page]->getTitle()}” [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.pageComment.mail.html"><![CDATA[<p>{@$authorList} commented on the page <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.pageComment.response.title"><![CDATA[New Reply (Page)]]></item>
                <item name="wcf.user.notification.pageComment.response.title.stacked"><![CDATA[{#$timesTriggered} new replies (Page)]]></item>
-               <item name="wcf.user.notification.pageComment.response.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if}’s comment on the page <a href="{$page->getLink()}#comment{@$commentID}/response{@$responseID}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.pageComment.response.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} replied to {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if}’s comment on the page <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.pageComment.response.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s comment on the page “{@$notificationContent[variables][page]->getTitle()}” [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.pageComment.response.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s comment on the page <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.user.notification.pageComment.response.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to <strong>{$commentAuthor}</strong>’s comment on the page {$page->getTitle()}.]]></item>
+               <item name="wcf.user.notification.pageComment.response.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to <strong>{$commentAuthor}</strong>’s comment on the page {$page->getTitle()}.]]></item>
+               <item name="wcf.user.notification.pageComment.response.mail.plaintext"><![CDATA[{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s comment on the page “{@$notificationContent[variables][page]->getTitle()}” [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.pageComment.response.mail.html"><![CDATA[<p>{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s comment on the page <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.pageComment.response.title"><![CDATA[New Reply (Page)]]></item>
                <item name="wcf.user.notification.pageComment.responseOwner.title.stacked"><![CDATA[{#$timesTriggered} new replies (Page)]]></item>
-               <item name="wcf.user.notification.pageComment.responseOwner.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to your comment on the page <a href="{$page->getLink()}#comment{@$commentID}/response{@$responseID}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.pageComment.responseOwner.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} replied to your comment on the page <a href="{$page->getLink()}#comment{@$commentID}">{$page->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.pageComment.responseOwner.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to your comment on the page “{@$notificationContent[variables][page]->getTitle()}” [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.pageComment.responseOwner.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to your comment on the page <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.user.notification.pageComment.responseOwner.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to your comment on the page <strong>{$page->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.pageComment.responseOwner.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to your comment on the page <strong>{$page->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.pageComment.responseOwner.mail.plaintext"><![CDATA[{@$authorList} replied to your comment on the page “{@$notificationContent[variables][page]->getTitle()}” [URL:{@$notificationContent[variables][page]->getLink()}#comment{@$commentID}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.pageComment.responseOwner.mail.html"><![CDATA[<p>{@$authorList} replied to your comment on the page <a href="{$notificationContent[variables][page]->getLink()}#comment{@$commentID}">{$notificationContent[variables][page]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.article.comment.notification.comment"><![CDATA[Notify me of new comments on my articles]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.article.comment.response.notification.commentResponse"><![CDATA[Notify me of new replies to my comments]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.article.comment.response.notification.commentResponseOwner"><![CDATA[Notify me of new replies to comments on my articles]]></item>
                <item name="wcf.user.notification.articleComment.title"><![CDATA[New Comment (Article)]]></item>
                <item name="wcf.user.notification.articleComment.title.stacked"><![CDATA[{#$timesTriggered} new Comments (Article)]]></item>
-               <item name="wcf.user.notification.articleComment.message"><![CDATA[{if $author->userID}{@$author->getAnchorTag()}{else}A guest{/if} commented on your article <a href="{link controller='Article' object=$article}#comments/comment{@$commentID}{/link}">{$article->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.articleComment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} commented on your article <a href="{link controller='Article' object=$article}{/link}">{$article->getTitle()}</a>.]]></item>
+               <item name="wcf.user.notification.articleComment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on your article <strong>{$article->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.articleComment.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} commented on your article <strong>{$article->getTitle()}</strong>.]]></item>
                <item name="wcf.user.notification.articleComment.mail.plaintext"><![CDATA[{@$authorList} commented on your article “{@$article->getTitle()}” [URL:{link controller='Article' object=$article isEmail=true}#comment{@$commentID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
                <item name="wcf.user.notification.articleComment.mail.html"><![CDATA[<p>{@$authorList} commented on your article <a href="{link controller='Article' object=$article isHtmlEmail=true}#comments/comment{@$commentID}{/link}">{$article->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.articleComment.response.title"><![CDATA[New Reply (Article)]]></item>
                <item name="wcf.user.notification.articleComment.response.title.stacked"><![CDATA[{#$timesTriggered} new Replies (Article)]]></item>
-               <item name="wcf.user.notification.articleComment.response.message"><![CDATA[{if $author->userID}{@$author->getAnchorTag()}{else}A guest{/if} replied to your comment on the article <a href="{link controller='Article' object=$article}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$article->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.articleComment.response.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} replied to your comment on the article <a href="{link controller='Article' object=$article}#comments/comment{@$commentID}{/link}">{$article->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.articleComment.response.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to your comment on the article “{@$article->getTitle()}” [URL:{link controller='Article' object=$article isEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.articleComment.response.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to your comment on the article <a href="{link controller='Article' object=$article isHtmlEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$article->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.user.notification.articleComment.response.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to your comment on the article <strong>{$article->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.articleComment.response.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to your comment on the article <strong>{$article->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.articleComment.response.mail.plaintext"><![CDATA[{@$authorList} replied to your comment on the article “{@$article->getTitle()}” [URL:{link controller='Article' object=$article isEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.articleComment.response.mail.html"><![CDATA[<p>{@$authorList} replied to your comment on the article <a href="{link controller='Article' object=$article isHtmlEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$article->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.articleComment.responseOwner.title"><![CDATA[New Reply (Article)]]></item>
                <item name="wcf.user.notification.articleComment.responseOwner.title.stacked"><![CDATA[{#$timesTriggered} new Replies (Article)]]></item>
-               <item name="wcf.user.notification.articleComment.responseOwner.message"><![CDATA[{if $author->userID}{@$author->getAnchorTag()}{else}A guest{/if} replied to a comment by {$commentAuthor->username} on your article <a href="{link controller='Article' object=$article}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$article->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.articleComment.responseOwner.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2 && !$guestTimesTriggered} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}{if !$guestTimesTriggered} and {else}, {/if} {@$authors[2]->getAnchorTag()}{/if}{/if}{if $guestTimesTriggered} and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users {if $guestTimesTriggered}and {if $guestTimesTriggered == 1}a guest{else}guests{/if}{/if}{/if} replied to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on your article <a href="{link controller='Article' object=$article}#comments/comment{@$commentID}{/link}">{$article->getTitle()}</a>.]]></item>
-               <item name="wcf.user.notification.articleComment.responseOwner.mail.plaintext"><![CDATA[{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on your article “{@$article->getTitle()}” [URL:{link controller='Article' object=$article isEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
-               <item name="wcf.user.notification.articleComment.responseOwner.mail.html"><![CDATA[<p>{@$authorList} wrote {if $count == 1 && !$guestTimesTriggered}a reply{else}replies{/if} to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on your article <a href="{link controller='Article' object=$article isHtmlEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$article->getTitle()}</a>:</p>]]></item>
+               <item name="wcf.user.notification.articleComment.responseOwner.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} replied to a comment by <strong>{$commentAuthor}</strong> on your article <strong>{$article->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.articleComment.responseOwner.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} replied to a comment by <strong>{$commentAuthor}</strong> on your article <strong>{$article->getTitle()}</strong>.]]></item>
+               <item name="wcf.user.notification.articleComment.responseOwner.mail.plaintext"><![CDATA[{@$authorList} replied to {@$notificationContent[variables][commentAuthor]->username}’s{if $notificationContent[variables][commentAuthor]->userID} [URL:{link controller='User' object=$notificationContent[variables][commentAuthor] isEmail=true}{/link}]{/if} comment on your article “{@$article->getTitle()}” [URL:{link controller='Article' object=$article isEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}]{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
+               <item name="wcf.user.notification.articleComment.responseOwner.mail.html"><![CDATA[<p>{@$authorList} replied to {if $notificationContent[variables][commentAuthor]->userID}<a href="{link controller='User' object=$notificationContent[variables][commentAuthor] isHtmlEmail=true}{/link}">{$notificationContent[variables][commentAuthor]->username}</a>{else}{$notificationContent[variables][commentAuthor]->username}{/if}’s comment on your article <a href="{link controller='Article' object=$article isHtmlEmail=true}#comments/comment{@$commentID}/response{@$responseID}{/link}">{$article->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.article.notification.article"><![CDATA[Notify me of new articles in watched categories]]></item>
                <item name="wcf.user.notification.article.title"><![CDATA[New Article]]></item>
-               <item name="wcf.user.notification.article.message"><![CDATA[{if $author->userID}{@$author->getAnchorTag()}{else}A guest{/if} wrote the article <a href="{$article->getLink()}">{$article->getTitle()}</a>.]]></item>
+               <item name="wcf.user.notification.article.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} wrote the article <strong>{$article->getTitle()}</strong>.]]></item>
                <item name="wcf.user.notification.article.mail.plaintext"><![CDATA[{if $event->getAuthor()->userID}{@$event->getAuthor()->username} [URL:{link controller='User' object=$event->getAuthor() isEmail=true}{/link}]{else}A guest{/if} wrote the article “{@$notificationContent[variables][articleContent]->getTitle()}” [URL:{link controller='Article' object=$notificationContent[variables][articleContent] isEmail=true}{/link}]:]]></item>
                <item name="wcf.user.notification.article.mail.html"><![CDATA[<p>{if $event->getAuthor()->userID}<a href="{link controller='User' object=$event->getAuthor() isHtmlEmail=true}{/link}">{$event->getAuthor()->username}</a>{else}A guest{/if} wrote the article <a href="{link controller='Article' object=$notificationContent[variables][articleContent] isHtmlEmail=true}{/link}">{$notificationContent[variables][articleContent]->getTitle()}</a>:</p>]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.articleComment.response.notification.commentResponseOwner"><![CDATA[Notify me of new replies to comments on my articles]]></item>
@@ -5137,10 +5230,12 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.notification.pageComment.responseOwner.title"><![CDATA[New reply (Page)]]></item>
                <item name="wcf.user.notification.userRegistration.title"><![CDATA[New user registration]]></item>
                <item name="wcf.user.notification.userRegistration.title.stacked"><![CDATA[{#$count} new user registrations]]></item>
-               <item name="wcf.user.notification.userRegistration.message"><![CDATA[{@$author->getAnchorTag()} has registered.]]></item>
-               <item name="wcf.user.notification.userRegistration.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} have registered.]]></item>
+               <item name="wcf.user.notification.userRegistration.message"><![CDATA[<strong>{$author}</strong> has registered.]]></item>
+               <item name="wcf.user.notification.userRegistration.message.stacked"><![CDATA[{@'wcf.user.notification.stacked.authorList'|language} have registered.]]></item>
                <item name="wcf.user.notification.userRegistration.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1}has{else}have{/if} registered.]]></item>
                <item name="wcf.user.notification.userRegistration.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1}has{else}have{/if} registered:</p>]]></item>
+               <item name="wcf.user.notification.status.active"><![CDATA[Active]]></item>
+               <item name="wcf.user.notification.status.email"><![CDATA[Email]]></item>
        </category>
        <category name="wcf.user.profile">
                <item name="wcf.user.profile.content.about.noPublicData"><![CDATA[{if $userID == $__wcf->getUser()->userID}You have not provided any details yet.{else}There are no details visible to you.{/if}]]></item>
@@ -5179,7 +5274,6 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.option.birthday"><![CDATA[Birthday]]></item>
                <item name="wcf.user.option.birthdayShowYear"><![CDATA[Display year of birth]]></item>
                <item name="wcf.user.option.birthdayShowYear.description"><![CDATA[Allows users to view your age.]]></item>
-               <item name="wcf.user.option.canMail"><![CDATA[Can Send Me Emails]]></item>
                <item name="wcf.user.option.canViewEmailAddress"><![CDATA[Can View My Email Address]]></item>
                <item name="wcf.user.option.canViewOnlineStatus"><![CDATA[Can View My Online Status]]></item>
                <item name="wcf.user.option.canViewProfile"><![CDATA[Can View My Profile]]></item>
@@ -5203,7 +5297,6 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.option.occupation"><![CDATA[Occupation]]></item>
                <item name="wcf.user.option.showSignature"><![CDATA[Display members’ signatures]]></item>
                <item name="wcf.user.option.timezone"><![CDATA[Timezone]]></item>
-               <item name="wcf.user.option.icq"><![CDATA[ICQ]]></item>
                <item name="wcf.user.option.skype"><![CDATA[Skype]]></item>
                <item name="wcf.user.option.facebook"><![CDATA[Facebook]]></item>
                <item name="wcf.user.option.twitter"><![CDATA[Twitter]]></item>
@@ -5213,10 +5306,9 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
                <item name="wcf.user.option.searchRadioButtonOption"><![CDATA[User’s selection for “{$option->getTitle()}”:]]></item>
                <item name="wcf.user.option.searchTextOption"><![CDATA[“{$option->getTitle()}” contains:]]></item>
                <item name="wcf.user.option.searchBooleanOption"><![CDATA[User’s selection for “{$option->getTitle()}”:]]></item>
+               <item name="wcf.user.option.enableEmbeddedMedia"><![CDATA[Display all external content]]></item>
        </category>
        <category name="wcf.user.mail">
-               <item name="wcf.user.mail.information"><![CDATA[Details]]></item>
-               <item name="wcf.user.mail.mail.subject"><![CDATA[Message From {@$username}: {@$subject}]]></item>
                <item name="wcf.user.mail.mail.plaintext"><![CDATA[Dear {@$mailbox->getUser()->username},
 
 “{@$username}” sent you a message on {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}]:
@@ -5227,11 +5319,6 @@ your notifications on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|langu
 <p>„{$username}“ sent you a message on <a href="{link isHtmlEmail=true}{/link}">{PAGE_TITLE|language}</a>:</p>
 
 <p>{@$message|newlineToBreak}</p>]]></item>
-               <item name="wcf.user.mail.message"><![CDATA[Message]]></item>
-               <item name="wcf.user.mail.senderEmail"><![CDATA[Your email address]]></item>
-               <item name="wcf.user.mail.sent"><![CDATA[The message has been sent to {$user->username}.]]></item>
-               <item name="wcf.user.mail.showAddress"><![CDATA[Use my email address as sender address, the recipient can directly reply to me.]]></item>
-               <item name="wcf.user.mail.subject"><![CDATA[Subject]]></item>
        </category>
        <category name="wcf.user.rank">
                <item name="wcf.user.rank.administrator"><![CDATA[Administrator]]></item>
index 50f717625dee0b40b565d92ad18d9fe795c9db83..65663347f3cb124e72e619ff7c58e838885eb5ba 100644 (file)
@@ -199,6 +199,8 @@ CREATE TABLE wcf1_article_content (
        imageID INT(10),
        teaserImageID INT(10),
        hasEmbeddedObjects TINYINT(1) NOT NULL DEFAULT 0,
+       metaTitle VARCHAR(255) NOT NULL DEFAULT '',
+       metaDescription VARCHAR(255) NOT NULL DEFAULT '',
        
        UNIQUE KEY (articleID, languageID)
 );
@@ -542,6 +544,17 @@ CREATE TABLE wcf1_devtools_project (
        UNIQUE KEY name (name)
 );
 
+DROP TABLE IF EXISTS wcf1_devtools_missing_language_item;
+CREATE TABLE wcf1_devtools_missing_language_item (
+       itemID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+       languageID INT(10),
+       languageItem VARCHAR(191) NOT NULL,
+       lastTime INT(10) NOT NULL,
+       stackTrace MEDIUMTEXT NOT NULL,
+       
+       UNIQUE KEY (languageID, languageItem)
+);
+
 DROP TABLE IF EXISTS wcf1_edit_history_entry;
 CREATE TABLE wcf1_edit_history_entry (
        entryID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
@@ -563,7 +576,7 @@ DROP TABLE IF EXISTS wcf1_event_listener;
 CREATE TABLE wcf1_event_listener (
        listenerID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        packageID INT(10) NOT NULL,
-       environment ENUM('user', 'admin') NOT NULL DEFAULT 'user',
+       environment ENUM('user', 'admin', 'all') NOT NULL DEFAULT 'user',
        listenerName VARCHAR(191) NOT NULL,
        eventClassName VARCHAR(255) NOT NULL DEFAULT '',
        eventName TEXT,
@@ -695,6 +708,7 @@ CREATE TABLE wcf1_media (
        fileType VARCHAR(255) NOT NULL DEFAULT '',
        fileHash VARCHAR(255) NOT NULL DEFAULT '',
        uploadTime INT(10) NOT NULL DEFAULT 0,
+       fileUpdateTime INT(10) NOT NULL DEFAULT 0,
        userID INT(10),
        username VARCHAR(255) NOT NULL,
        languageID INT(10),
@@ -1443,7 +1457,7 @@ CREATE TABLE wcf1_user (
        userID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(100) NOT NULL DEFAULT '',
        email VARCHAR(191) NOT NULL DEFAULT '',
-       password VARCHAR(100) NOT NULL DEFAULT '',
+       password VARCHAR(255) NOT NULL DEFAULT 'invalid:',
        accessToken CHAR(40) NOT NULL DEFAULT '',
        languageID INT(10) NOT NULL DEFAULT 0,
        registrationDate INT(10) NOT NULL DEFAULT 0,
@@ -1452,6 +1466,7 @@ CREATE TABLE wcf1_user (
        banReason MEDIUMTEXT NULL,
        banExpires INT(10) NOT NULL DEFAULT 0,
        activationCode INT(10) NOT NULL DEFAULT 0,
+       emailConfirmed CHAR(40) DEFAULT NULL,
        lastLostPasswordRequestTime INT(10) NOT NULL DEFAULT 0,
        lostPasswordKey CHAR(40) DEFAULT NULL,
        lastUsernameChange INT(10) NOT NULL DEFAULT 0,
@@ -1489,7 +1504,7 @@ CREATE TABLE wcf1_user (
        articles INT(10) NOT NULL DEFAULT 0,
        blacklistMatches VARCHAR(255) NOT NULL DEFAULT '',
        
-       KEY username (username),
+       UNIQUE KEY username (username),
        KEY email (email),
        KEY registrationDate (registrationDate),
        KEY styleID (styleID),
@@ -1939,6 +1954,8 @@ ALTER TABLE wcf1_cronjob ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (pa
 
 ALTER TABLE wcf1_cronjob_log ADD FOREIGN KEY (cronjobID) REFERENCES wcf1_cronjob (cronjobID) ON DELETE CASCADE;
 
+ALTER TABLE wcf1_devtools_missing_language_item ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE SET NULL;
+
 ALTER TABLE wcf1_edit_history_entry ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE;
 ALTER TABLE wcf1_edit_history_entry ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE SET NULL;
 ALTER TABLE wcf1_edit_history_entry ADD FOREIGN KEY (obsoletedByUserID) REFERENCES wcf1_user (userID) ON DELETE SET NULL;
@@ -2234,10 +2251,8 @@ INSERT INTO wcf1_user_group_option_value (groupID, optionID, optionValue) VALUES
 INSERT INTO wcf1_user_group_option_value (groupID, optionID, optionValue) VALUES (4, 3, '1');  -- Administrators
 
 -- default update servers
-INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://update.woltlab.com/2019/', 'online', 0, NULL, 0, '', '');
-INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://store.woltlab.com/2019/', 'online', 0, NULL, 0, '', '');
-INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://store.woltlab.com/vortex/', 'online', 0, NULL, 0, '', '');
-INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://store.woltlab.com/tornado/', 'online', 0, NULL, 0, '', '');
+INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://update.woltlab.com/5.3/', 'online', 0, NULL, 0, '', '');
+INSERT INTO wcf1_package_update_server (serverURL, status, isDisabled, errorMessage, lastUpdateTime, loginUsername, loginPassword) VALUES ('http://store.woltlab.com/5.3/', 'online', 0, NULL, 0, '', '');
 
 -- style default values
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('individualScss', '');
@@ -2248,7 +2263,6 @@ INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogoWi
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogoHeight', '40');
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('pageLogoMobile', '');
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('useFluidLayout', '1');
-INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('useGoogleFont', '1');
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('wcfButtonBackground', 'rgba(207, 216, 220, 1)');
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('wcfButtonBackgroundActive', 'rgba(120, 144, 156, 1)');
 INSERT INTO wcf1_style_variable (variableName, defaultValue) VALUES ('wcfButtonDisabledBackground', 'rgba(223, 223, 223, 1)');
index a68f251db71df5e472858669d650ad00e3faf10e..a5d7af280ede12c74b84582b233c53f48c120ccd 100644 (file)
                <item name="wcf.global.systemRequirements.memoryLimit.description"><![CDATA[Der PHP-Skripten zur Verfügung stehende Arbeitsspeicher ist für einen einwandfreien Betrieb der Software zu gering.]]></item>
                <item name="wcf.global.systemRequirements.openSSL"><![CDATA[„OpenSSL“ PHP-Erweiterung]]></item>
                <item name="wcf.global.systemRequirements.openSSL.description"><![CDATA[Ihre PHP-Version wurde ohne Unterstützung für OpenSSL kompiliert und kann daher keine sicheren Verbindungen aufbauen.]]></item>
+               <item name="wcf.global.systemRequirements.curl"><![CDATA[„curl“ PHP-Erweiterung]]></item>
+               <item name="wcf.global.systemRequirements.curl.description"><![CDATA[Ihre PHP-Version wurde ohne Unterstützung für cURL kompiliert. Die Unterstützung externer Verbindungen kann eingeschränkt sein.]]></item>
+               <item name="wcf.global.systemRequirements.hostname"><![CDATA[Hostname]]></item>
+               <item name="wcf.global.systemRequirements.hostname.requirement"><![CDATA[Korrekter Hostname]]></item>
+               <item name="wcf.global.systemRequirements.hostname.description"><![CDATA[Der vom Webserver ermittelte Hostname muss dem Hostnamen in der Adressleiste des Webbrowsers entsprechen.]]></item>
+               <item name="wcf.global.systemRequirements.cookie"><![CDATA[Cookies]]></item>
+               <item name="wcf.global.systemRequirements.cookie.description"><![CDATA[Gesetzte Cookies müssen vom Webbrowser zurück an den Server gesendet werden.]]></item>
                <item name="wcf.global.next"><![CDATA[Lade nächsten Schritt …]]></item>
                <item name="wcf.global.next.description"><![CDATA[Die Installation lädt im Moment den nächsten Schritt. Bitte haben Sie einen Augenblick Geduld.]]></item>
                <item name="wcf.global.languages"><![CDATA[Sprachen wählen]]></item>
index 40933e817af75e79236a1375e4fcc7eee63e0cc0..d86df05720f865c1b9311e9c69a90ed1e562c119 100644 (file)
                <item name="wcf.global.systemRequirements.memoryLimit.description"><![CDATA[The maximum available memory of PHP scripts is too low to properly run the software.]]></item>
                <item name="wcf.global.systemRequirements.openSSL"><![CDATA['OpenSSL' PHP extension]]></item>
                <item name="wcf.global.systemRequirements.openSSL.description"><![CDATA[Your PHP version has been compiled without OpenSSL support, it is required to establish secure connections.]]></item>
+               <item name="wcf.global.systemRequirements.curl"><![CDATA['curl' PHP extension]]></item>
+               <item name="wcf.global.systemRequirements.curl.description"><![CDATA[Your PHP version has been compiled without cURL support, outgoing connections might not be fully supported.]]></item>
+               <item name="wcf.global.systemRequirements.hostname"><![CDATA[Host Name]]></item>
+               <item name="wcf.global.systemRequirements.hostname.requirement"><![CDATA[Correct Host Name]]></item>
+               <item name="wcf.global.systemRequirements.hostname.description"><![CDATA[The host name determined by the web server must match the host name within the web browser's URL bar.]]></item>
+               <item name="wcf.global.systemRequirements.cookie"><![CDATA[Cookies]]></item>
+               <item name="wcf.global.systemRequirements.cookie.description"><![CDATA[The web browser must send cookies back to the web server.]]></item>
                <item name="wcf.global.next"><![CDATA[Loading next step …]]></item>
                <item name="wcf.global.next.description"><![CDATA[The installation is currently loading the next step, please wait.]]></item>
                <item name="wcf.global.languages"><![CDATA[Choose languages to install]]></item>
index 4f8a8a112afa25526ba071232877953da3665296..e8379057c5b9e65ebd8c911f57f54c8f7deb0c46 100644 (file)
                                </dl>
                        </div>
                </section>
+               
+               <section class="section">
+                       <h2 class="sectionTitle">{lang}wcf.global.systemRequirements.hostname{/lang}</h2>
+                       
+                       <div class="row rowColGap formGrid">
+                               <dl class="col-xs-12 col-md-6">
+                                       <dt>{lang}wcf.global.systemRequirements.element.required{/lang}</dt>
+                                       <dd>{lang}wcf.global.systemRequirements.hostname.requirement{/lang}</dd>
+                               </dl>
+                               
+                               <dl class="col-xs-12 col-md-6">
+                                       <dt>{lang}wcf.global.systemRequirements.element.yours{/lang}</dt>
+                                       <dd>
+                                               <span id="hostnameBadge" class="badge {if !$system.hostname.result}red{else}green{/if}">{$system.hostname.value}</span>
+                                               <small{if $system.hostname.result} style="display: none"{/if}>{lang}wcf.global.systemRequirements.hostname.description{/lang}</small>
+                                       </dd>
+                                       <script>
+                                               (function () {
+                                                       var badge = document.getElementById('hostnameBadge');
+                                                       if (badge.classList.contains('green')) {
+                                                               var serverHost = badge.textContent;
+                                                               var browserHost = window.location.host;
+                                                               if (serverHost != browserHost) {
+                                                                       badge.classList.remove('green');
+                                                                       badge.classList.add('red');
+                                                                       badge.nextElementSibling.style.display = '';
+                                                                       document.querySelector('.formSubmit input[type="submit"]').disabled = true;
+                                                               }
+                                                       }
+                                               })();
+                                       </script>
+                               </dl>
+                       </div>
+               </section>
+               
+               <section class="section">
+                       <h2 class="sectionTitle">{lang}wcf.global.systemRequirements.cookie{/lang}</h2>
+                       
+                       <div class="row rowColGap formGrid">
+                               <dl class="col-xs-12 col-md-6">
+                                       <dt>{lang}wcf.global.systemRequirements.element.required{/lang}</dt>
+                                       <dd>{lang}wcf.global.systemRequirements.active{/lang}</dd>
+                               </dl>
+                               
+                               <dl class="col-xs-12 col-md-6">
+                                       <dt>{lang}wcf.global.systemRequirements.element.yours{/lang}</dt>
+                                       <dd>
+                                               <span class="badge {if !$system.cookie.result}red{else}green{/if}">
+                                               {if !$system.cookie.result}{lang}wcf.global.systemRequirements.notActive{/lang}{else}
+                                                       {lang}wcf.global.systemRequirements.active{/lang}
+                                               {/if}</span>
+                                               {if !$system.cookie.result}<small>{lang}wcf.global.systemRequirements.cookie.description{/lang}</small>{/if}
+                                       </dd>
+                               </dl>
+                       </div>
+               </section>
        </section>
        
        <section class="section">
                                </dl>
                        </div>
                </section>
+               
+               <section class="section">
+                       <h2 class="sectionTitle">{lang}wcf.global.systemRequirements.curl{/lang}</h2>
+                       
+                       <div class="row rowColGap formGrid">
+                               <dl class="col-xs-12 col-md-6">
+                                       <dt>{lang}wcf.global.systemRequirements.element.recommended{/lang}</dt>
+                                       <dd>{lang}wcf.global.systemRequirements.active{/lang}</dd>
+                               </dl>
+                               
+                               <dl class="col-xs-12 col-md-6">
+                                       <dt>{lang}wcf.global.systemRequirements.element.yours{/lang}</dt>
+                                       <dd>
+                                               <span class="badge {if !$system.curl.result}red{else}green{/if}">
+                                               {if !$system.curl.result}{lang}wcf.global.systemRequirements.notActive{/lang}{else}
+                                                       {lang}wcf.global.systemRequirements.active{/lang}
+                                               {/if}</span>
+                                               {if !$system.curl.result}<small>{lang}wcf.global.systemRequirements.curl.description{/lang}</small>{/if}
+                                       </dd>
+                               </dl>
+                       </div>
+               </section>
        </section>
 
        <div class="formSubmit">
-               <input type="submit" value="{lang}wcf.global.button.next{/lang}"{if !$system.phpVersion.result || !$system.sql.result || !$system.memoryLimit.result || !$system.graphicsLibrary.result} disabled{/if} accesskey="s">
+               <input type="submit" value="{lang}wcf.global.button.next{/lang}"{if !$system.phpVersion.result || !$system.sql.result || !$system.memoryLimit.result || !$system.graphicsLibrary.result || !$system.hostname.result || !$system.cookie.result} disabled{/if} accesskey="s">
                <input type="hidden" name="step" value="{@$nextStep}">
                <input type="hidden" name="tmpFilePrefix" value="{@$tmpFilePrefix}">
                <input type="hidden" name="languageCode" value="{@$languageCode}">